Moved main.py to serve.py, implemented modularization and added control module

This commit is contained in:
Malasaur 2025-08-30 13:43:21 +02:00
parent ad6190b46a
commit e185786959
6 changed files with 138 additions and 21 deletions

View file

@ -1,9 +1,13 @@
from typing import Callable, Dict, List, Optional, Tuple
from subprocess import PIPE, STDOUT, Popen, run from subprocess import PIPE, STDOUT, Popen, run
from typing import Callable, List, Optional, Tuple from importlib import import_module
from typing import List, Tuple
from pathlib import Path
from sys import modules as _modules
from re import Pattern from re import Pattern
minecraftOutputBinds: List[Tuple[Pattern, Callable]] = [] minecraftOutputBinds: Dict[str, List[Tuple[Pattern, Callable]]] = {}
minecraftProc = None minecraftProc = None
@ -22,10 +26,47 @@ class Group:
return f'<Group "{self.name}" at "{self.id}">' return f'<Group "{self.name}" at "{self.id}">'
signalMessageBinds: List[Tuple[Optional[Group], Callable]] = [] signalMessageBinds: Dict[str, List[Tuple[Optional[Group], Callable]]] = {}
signalProc = None signalProc = None
def signalInit(cmd: str) -> None: def signalInit(cmd: str) -> None:
global signalProc global signalProc
signalProc = run(cmd.split(), stdout=PIPE) signalProc = run(cmd.split(), stdout=PIPE)
loadedMods = []
def listModules() -> Tuple[List[str], List[str], List[str]]:
modules = []
loaded_modules = []
unloaded_modules = []
for file in Path("modules").iterdir():
if file.name.endswith(".py"):
modules.append(file.name[:-3])
if file.name[:-3] in loadedMods:
loaded_modules.append(file.name[:-3])
else:
unloaded_modules.append(file.name[:-3])
return modules, loaded_modules, unloaded_modules
def loadModule(module: str):
global loadedMods
if module in listModules()[2]:
minecraftOutputBinds[module] = []
signalMessageBinds[module] = []
import_module("modules."+module)
loadedMods.append(module)
def unloadModule(module: str):
global loadedMods
if module in listModules()[1]:
del _modules["modules."+module]
loadedMods.remove(module)
del minecraftOutputBinds[module]
del signalMessageBinds[module]

View file

@ -1,5 +1,6 @@
from threading import Thread from threading import Thread
from typing import Callable from typing import Callable
from inspect import stack
from re import compile from re import compile
import libcommon import libcommon
@ -10,7 +11,9 @@ def reader() -> None:
for line in libcommon.minecraftProc.stdout: for line in libcommon.minecraftProc.stdout:
line = line.rstrip("\n") line = line.rstrip("\n")
print(line) print(line)
for pattern, func in libcommon.minecraftOutputBinds: for module in libcommon.loadedMods:
if module in libcommon.minecraftOutputBinds:
for pattern, func in libcommon.minecraftOutputBinds[module]:
match = pattern.match(line) match = pattern.match(line)
if match: if match:
func(*match.groups()) func(*match.groups())
@ -19,7 +22,8 @@ def reader() -> None:
def onConsoleOutput(pattern: str) -> Callable: def onConsoleOutput(pattern: str) -> Callable:
def decorator(func: Callable) -> Callable: def decorator(func: Callable) -> Callable:
libcommon.minecraftOutputBinds.append((compile(pattern), func)) module = stack()[1].filename.split("/")[-1][:-3]
libcommon.minecraftOutputBinds[module].append((compile(pattern), func))
return func return func
return decorator return decorator

View file

@ -2,6 +2,7 @@ from typing import Callable, List, Optional
from requests import post as _post from requests import post as _post
from sseclient import SSEClient from sseclient import SSEClient
from threading import Thread from threading import Thread
from inspect import stack
from time import sleep from time import sleep
from json import loads from json import loads
from uuid import uuid4 from uuid import uuid4
@ -31,7 +32,8 @@ def listGroups() -> List[libcommon.Group]:
def onMessage(group: Optional[libcommon.Group] = None) -> Callable: def onMessage(group: Optional[libcommon.Group] = None) -> Callable:
def decorator(func: Callable) -> Callable: def decorator(func: Callable) -> Callable:
libcommon.signalMessageBinds.append((group, func)) module = stack()[1].filename.split("/")[-1][:-3]
libcommon.signalMessageBinds[module].append((group, func))
return func return func
return decorator return decorator
@ -44,9 +46,13 @@ def main():
sleep(5) sleep(5)
for msg in SSEClient(url+"/api/v1/events"): for msg in SSEClient(url+"/api/v1/events"):
try:
data = loads(msg.data) data = loads(msg.data)
except:
data = {}
envelope = data.get("envelope", None) envelope = data.get("envelope", None)
if envelope: if envelope:
dataMessage = envelope.get("dataMessage", None) dataMessage = envelope.get("dataMessage", None)
if dataMessage: if dataMessage:
groupInfo = dataMessage.get("groupInfo", None) groupInfo = dataMessage.get("groupInfo", None)
@ -55,10 +61,27 @@ def main():
body = dataMessage["message"] body = dataMessage["message"]
groupId = groupInfo["groupId"] groupId = groupInfo["groupId"]
if body is not None: if body is not None:
for group, func in libcommon.signalMessageBinds: for module in libcommon.loadedMods:
if module in libcommon.signalMessageBinds:
for group, func in libcommon.signalMessageBinds[module]:
if group is None or group.id == groupId:
func(name, body)
syncMessage = envelope.get("syncMessage", None)
if syncMessage:
sentMessage = syncMessage.get("sentMessage", None)
if sentMessage:
groupInfo = sentMessage.get("groupInfo", None)
if groupInfo:
name = envelope["sourceName"]
body = sentMessage["message"]
groupId = groupInfo["groupId"]
if body is not None:
for module in libcommon.loadedMods:
if module in libcommon.signalMessageBinds:
for group, func in libcommon.signalMessageBinds[module]:
if group is None or group.id == groupId: if group is None or group.id == groupId:
func(name, body) func(name, body)
break
if __name__ == "__main__": if __name__ == "__main__":

47
modules/control.py Normal file
View file

@ -0,0 +1,47 @@
import libminecraft
import libsignal
import libcommon
RetardsServer = libcommon.Group(
"Retards Server", "5PlbXaPmWZQkhmuyyC/fkWTy8K+BqomjK7byVDyxmpo=")
@libsignal.onMessage(RetardsServer)
def signalControl(usr: str, msg: str):
if usr == "Malasaur" and msg.startswith("!"):
match msg.split():
case ["!modules", "list"]:
available_modules, loaded_modules, unloaded_modules = libcommon.listModules()
libsignal.sendMessage(
f"""Available modules: {" ".join(available_modules)}
Loaded modules: {" ".join(loaded_modules)}
Unloaded modules: {" ".join(unloaded_modules)}""", RetardsServer
)
case ["!modules", "load", *modules]:
for module in modules:
try:
libcommon.loadModule(module)
libsignal.sendMessage(
f"[Serve] '{module}' successfully loaded.", RetardsServer)
except Exception as e:
libsignal.sendMessage(
f"[Serve] Error loading '{module}': {e}", RetardsServer)
case ["!modules", "unload", *modules]:
for module in modules:
try:
libcommon.unloadModule(module)
libsignal.sendMessage(
f"[Serve] '{module}' successfully unloaded.", RetardsServer)
except Exception as e:
libsignal.sendMessage(
f"[Serve] Error unloading '{module}': {e}", RetardsServer)
case ["!modules", "reload", *modules]:
for module in modules:
try:
libcommon.unloadModule(module)
libcommon.loadModule(module)
libsignal.sendMessage(
f"[Serve] '{module}' successfully reloaded.", RetardsServer)
except Exception as e:
libsignal.sendMessage(
f"[Serve] Error reloading '{module}': {e}", RetardsServer)

5
modules/shazam.py Normal file
View file

@ -0,0 +1,5 @@
@libminecraft.onConsoleOutput(r"\[.*\] \[Server thread\/INFO\]: Set Malasaur's game mode to (.*) Mode")
def malasaurSetGamemode(gamemode: str):
global malasaurGamemode
malasaurGamemode = gamemode.lower()

View file

@ -1,10 +1,8 @@
from importlib import import_module
from threading import Thread from threading import Thread
from subprocess import run
from pathlib import Path
import libminecraft import libminecraft
import libsignal import libsignal
import libcommon
minecraftThread = Thread(target=libminecraft.main) minecraftThread = Thread(target=libminecraft.main)
@ -13,9 +11,8 @@ signalThread = Thread(target=libsignal.main)
minecraftThread.start() minecraftThread.start()
signalThread.start() signalThread.start()
for file in Path("modules").iterdir():
if file.name.endswith(".py"): libcommon.loadModule("control")
import_module("modules."+file.name[:-3])
minecraftThread.join() minecraftThread.join()
signalThread.join() signalThread.join()