-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
set the lua base for modding, setup basic mods
- Loading branch information
1 parent
77f28bf
commit e917868
Showing
9 changed files
with
200 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
FROM python:3.12 | ||
FROM python:3.11 | ||
|
||
WORKDIR /app | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import inspect | ||
import os.path | ||
import json | ||
import pygameextra as pe | ||
from lupa.lua54 import LuaRuntime, unpacks_lua_table | ||
|
||
|
||
class MalformedModError(Exception): | ||
pass | ||
|
||
|
||
class Mod: | ||
package: str | ||
name: str | ||
author: str | ||
description: str | ||
mod_version: str | ||
|
||
def __init__(self, directory: str, version: int): | ||
self.directory = directory | ||
self.version = version | ||
try: | ||
self.load() | ||
except FileNotFoundError as e: | ||
raise MalformedModError(f"Mod at {directory} is missing {e.filename}") | ||
|
||
def load(self): | ||
with open(os.path.join(self.directory, 'mod.json'), 'r') as f: | ||
self.mod_info = json.load(f) | ||
if (mod_version := self.mod_info.get('version')) != self.version: | ||
if mod_version is None: | ||
raise MalformedModError(f"Mod at {self.directory} is missing a version key") | ||
elif mod_version < self.version: | ||
raise MalformedModError(f"Mod at {self.directory} is outdated") | ||
else: | ||
raise MalformedModError(f"Your game is outdated for mod at {self.directory}") | ||
if (mod_package := self.mod_info.get('package')) is None: | ||
raise MalformedModError(f"Mod at {self.directory} is missing a package key") | ||
else: | ||
self.package = mod_package | ||
self.name = self.mod_info.get('name', self.package) | ||
self.author = self.mod_info.get('author', '<tr>no_author</tr>') | ||
self.description = self.mod_info.get('description', '<tr>no_description</tr>') | ||
self.mod_version = self.mod_info.get('mod_version', '-') | ||
|
||
@property | ||
def hooks_dir(self): | ||
return os.path.join(self.directory, 'hooks') | ||
|
||
|
||
class Hook: | ||
def __init__(self, hook_name: str, hook_code: str, lua: LuaRuntime): | ||
self.function = lua.eval(hook_code) | ||
|
||
def __call__(self, *args, **kwargs): | ||
return self.function(*args, **kwargs) | ||
|
||
|
||
class LuaGenerator: | ||
def __init__(self, generator): | ||
self.generator = generator | ||
|
||
def __call__(self, *args): | ||
try: | ||
return next(self.generator) | ||
except StopIteration: | ||
return None | ||
|
||
|
||
class HookManager: | ||
SUPPORT_VERSION = 0 | ||
GLOBAL_LUA = """LOADING_SCREEN_BG = {255, 255, 255}""" | ||
|
||
def __init__(self): | ||
self.hooks = {} | ||
self.mods = {} | ||
self.lua = LuaRuntime() | ||
self.lua.execute(self.GLOBAL_LUA) | ||
self.load_global_hooks() | ||
for hook_name, hook_function in self.hooks.items(): | ||
self.lua.globals()[hook_name] = hook_function | ||
|
||
def register(self, hook_name, hook_code, special: str = None): | ||
if special is None: | ||
self.hooks[hook_name] = Hook(hook_name, hook_code, self.lua) | ||
elif hook_name == f'__{special}__': | ||
if False: | ||
pass | ||
else: | ||
self.lua.execute(hook_code) | ||
|
||
def register_mod_hooks(self, package: str, special: str = None): | ||
mod = self.mods[package] | ||
self.register_hooks_folder(mod.hooks_dir, special) | ||
|
||
def register_hooks_folder(self, folder: str, special: str = None): | ||
for hook in os.listdir(folder): | ||
item = os.path.join(folder, hook) | ||
if special is None and hook.endswith('__.lua'): | ||
continue | ||
if os.path.isfile(item): | ||
with open(item, 'r') as f: | ||
self.register(hook.rsplit('.', 1)[0], f.read(), special) | ||
elif os.path.isdir(item): | ||
self.register_hooks_folder(item, special) | ||
|
||
def load_mod(self, mod: str): | ||
if os.path.isdir(mod): | ||
mod = Mod(mod, self.SUPPORT_VERSION) | ||
if mod.package in self.mods: | ||
return | ||
self.mods[mod.package] = mod | ||
self.register_mod_hooks(mod.package, 'pre_initialize') | ||
print(f"Loaded mod {mod.name} by {mod.author} ({mod.package})") | ||
|
||
def __getattr__(self, item): | ||
if item in self.hooks: | ||
return self.hooks[item] | ||
else: | ||
return super().__getattribute__(item) | ||
|
||
def lua_wrap(self, function): | ||
return unpacks_lua_table(function) | ||
|
||
def load_global_hooks(self): | ||
self.hooks['fill_screen'] = lambda r, g, b: pe.fill.full((r, g, b)) | ||
|
||
for hook_name, hook_function in self.hooks.items(): | ||
self.hooks[hook_name] = self.lua_wrap(hook_function) | ||
|
||
self.hooks['load_mod'] = self.load_mod | ||
self.hooks['print'] = print | ||
|
||
self.hooks['get_all_mods'] = lambda: LuaGenerator( | ||
(os.path.join('mods', mod) for mod in os.listdir('mods'))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from os.path import join | ||
|
||
import pygameextra as pe | ||
from client import Client | ||
from hook_manager import HookManager | ||
|
||
pe.init() | ||
|
||
class GameContext(pe.GameContext): | ||
AREA = (500, 500) | ||
FPS = 60 | ||
|
||
def __init__(self): | ||
# Initialize other things first | ||
super().__init__() | ||
|
||
self.client = Client() | ||
self.client.thread_receive() | ||
self.hooks = HookManager() | ||
|
||
# Load the base mod | ||
self.hooks.load_mod(join('mods', 'base')) | ||
self.hooks.register_mod_hooks('com.redttg.p2p_base') | ||
|
||
# Initialize the game | ||
self.screen = 'loading_screen' | ||
self.screen_map = { | ||
'loading_screen': self.hooks.loading_screen | ||
} | ||
|
||
def loop(self): | ||
try: | ||
self.screen_map[self.screen]() | ||
except KeyError: | ||
raise NotImplementedError(f"Screen {self.screen} not implemented") | ||
|
||
|
||
game_context = GameContext() | ||
|
||
while True: | ||
game_context() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
PRE_REGISTERED_ALL_MODS = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
function() | ||
fill_screen(LOADING_SCREEN_BG) | ||
if not PRE_REGISTERED_ALL_MODS then | ||
for mod in get_all_mods() do | ||
load_mod(mod) | ||
end | ||
PRE_REGISTERED_ALL_MODS = true | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"package": "com.redttg.p2p_base", | ||
"version": 0, | ||
"mod_version": 0, | ||
"author": "RedTTG" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
LOADING_SCREEN_BG = {20, 20, 20} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"package": "com.redttg.p2p_dark", | ||
"version": 0, | ||
"mod_version": 0, | ||
"author": "RedTTG" | ||
} |
Binary file not shown.