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 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
minecraftOutputBinds: List[Tuple[Pattern, Callable]] = []
minecraftOutputBinds: Dict[str, List[Tuple[Pattern, Callable]]] = {}
minecraftProc = None
@ -22,10 +26,47 @@ class Group:
return f'<Group "{self.name}" at "{self.id}">'
signalMessageBinds: List[Tuple[Optional[Group], Callable]] = []
signalMessageBinds: Dict[str, List[Tuple[Optional[Group], Callable]]] = {}
signalProc = None
def signalInit(cmd: str) -> None:
global signalProc
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 typing import Callable
from inspect import stack
from re import compile
import libcommon
@ -10,7 +11,9 @@ def reader() -> None:
for line in libcommon.minecraftProc.stdout:
line = line.rstrip("\n")
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)
if match:
func(*match.groups())
@ -19,7 +22,8 @@ def reader() -> None:
def onConsoleOutput(pattern: str) -> 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 decorator

View file

@ -2,6 +2,7 @@ from typing import Callable, List, Optional
from requests import post as _post
from sseclient import SSEClient
from threading import Thread
from inspect import stack
from time import sleep
from json import loads
from uuid import uuid4
@ -31,7 +32,8 @@ def listGroups() -> List[libcommon.Group]:
def onMessage(group: Optional[libcommon.Group] = None) -> 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 decorator
@ -44,9 +46,13 @@ def main():
sleep(5)
for msg in SSEClient(url+"/api/v1/events"):
try:
data = loads(msg.data)
except:
data = {}
envelope = data.get("envelope", None)
if envelope:
dataMessage = envelope.get("dataMessage", None)
if dataMessage:
groupInfo = dataMessage.get("groupInfo", None)
@ -55,10 +61,27 @@ def main():
body = dataMessage["message"]
groupId = groupInfo["groupId"]
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:
func(name, body)
break
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 subprocess import run
from pathlib import Path
import libminecraft
import libsignal
import libcommon
minecraftThread = Thread(target=libminecraft.main)
@ -13,9 +11,8 @@ signalThread = Thread(target=libsignal.main)
minecraftThread.start()
signalThread.start()
for file in Path("modules").iterdir():
if file.name.endswith(".py"):
import_module("modules."+file.name[:-3])
libcommon.loadModule("control")
minecraftThread.join()
signalThread.join()