Compare commits
2 commits
f045967591
...
ceccdf818b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ceccdf818b | ||
|
|
49a9964ec5 |
7 changed files with 150 additions and 33 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,3 +1,3 @@
|
||||||
__pycache__
|
__pycache__
|
||||||
modules
|
venv
|
||||||
program.py
|
program.py
|
||||||
12
data.py
12
data.py
|
|
@ -1,12 +0,0 @@
|
||||||
from subprocess import PIPE, STDOUT, Popen
|
|
||||||
from typing import Callable, List, Tuple
|
|
||||||
from re import Pattern
|
|
||||||
|
|
||||||
output_binds: List[Tuple[Pattern, Callable]] = []
|
|
||||||
proc = None
|
|
||||||
|
|
||||||
|
|
||||||
def initializeProc(cmd):
|
|
||||||
global proc
|
|
||||||
proc = Popen(cmd.split(), stdin=PIPE, stdout=PIPE,
|
|
||||||
stderr=STDOUT, text=True, bufsize=1)
|
|
||||||
31
libcommon.py
Normal file
31
libcommon.py
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
from subprocess import PIPE, STDOUT, Popen, run
|
||||||
|
from typing import Callable, List, Optional, Tuple
|
||||||
|
from re import Pattern
|
||||||
|
|
||||||
|
|
||||||
|
minecraftOutputBinds: List[Tuple[Pattern, Callable]] = []
|
||||||
|
minecraftProc = None
|
||||||
|
|
||||||
|
|
||||||
|
def minecraftInit(cmd: str) -> None:
|
||||||
|
global minecraftProc
|
||||||
|
minecraftProc = Popen(cmd.split(), stdin=PIPE, stdout=PIPE,
|
||||||
|
stderr=STDOUT, text=True, bufsize=1)
|
||||||
|
|
||||||
|
|
||||||
|
class Group:
|
||||||
|
def __init__(self, name: str, id: str):
|
||||||
|
self.name = name
|
||||||
|
self.id = id
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f'<Group "{self.name}" at "{self.id}">'
|
||||||
|
|
||||||
|
|
||||||
|
signalMessageBinds: List[Tuple[Optional[Group], Callable]] = []
|
||||||
|
signalProc = None
|
||||||
|
|
||||||
|
|
||||||
|
def signalInit(cmd: str) -> None:
|
||||||
|
global signalProc
|
||||||
|
signalProc = run(cmd.split(), stdout=PIPE)
|
||||||
|
|
@ -1,19 +1,16 @@
|
||||||
from subprocess import PIPE, STDOUT, Popen
|
|
||||||
from importlib import import_module
|
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
from pathlib import Path
|
|
||||||
from re import compile
|
from re import compile
|
||||||
|
|
||||||
import data
|
import libcommon
|
||||||
|
|
||||||
|
|
||||||
def reader() -> None:
|
def reader() -> None:
|
||||||
if data.proc.stdout:
|
if libcommon.minecraftProc.stdout:
|
||||||
for line in data.proc.stdout:
|
for line in libcommon.minecraftProc.stdout:
|
||||||
line = line.rstrip("\n")
|
line = line.rstrip("\n")
|
||||||
print(line)
|
print(line)
|
||||||
for pattern, func in data.output_binds:
|
for pattern, func in libcommon.minecraftOutputBinds:
|
||||||
match = pattern.match(line)
|
match = pattern.match(line)
|
||||||
if match:
|
if match:
|
||||||
func(*match.groups())
|
func(*match.groups())
|
||||||
|
|
@ -22,30 +19,30 @@ def reader() -> None:
|
||||||
|
|
||||||
def onConsoleOutput(pattern: str) -> Callable:
|
def onConsoleOutput(pattern: str) -> Callable:
|
||||||
def decorator(func: Callable) -> Callable:
|
def decorator(func: Callable) -> Callable:
|
||||||
data.output_binds.append((compile(pattern), func))
|
libcommon.minecraftOutputBinds.append((compile(pattern), func))
|
||||||
return func
|
return func
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
def sendCommand(cmd: str) -> None:
|
def sendCommand(cmd: str) -> None:
|
||||||
if data.proc.stdin:
|
if libcommon.minecraftProc.stdin:
|
||||||
data.proc.stdin.write(cmd+"\n")
|
libcommon.minecraftProc.stdin.write(cmd+"\n")
|
||||||
data.proc.stdin.flush()
|
libcommon.minecraftProc.stdin.flush()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def main() -> None:
|
||||||
data.initializeProc("python -u program.py")
|
libcommon.minecraftInit("sudo ./start.sh")
|
||||||
|
|
||||||
for file in Path("modules").iterdir():
|
|
||||||
if file.name.endswith(".py"):
|
|
||||||
import_module("modules."+file.name[:-3])
|
|
||||||
|
|
||||||
t = Thread(target=reader, daemon=True)
|
t = Thread(target=reader, daemon=True)
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while data.proc.poll() is None:
|
while libcommon.minecraftProc.poll() is None:
|
||||||
sendCommand(input())
|
sendCommand(input())
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
sendCommand("stop")
|
sendCommand("stop")
|
||||||
data.proc.wait()
|
libcommon.minecraftProc.wait()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
63
libsignal.py
Normal file
63
libsignal.py
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
from typing import Callable, List, Optional
|
||||||
|
from requests import post as _post
|
||||||
|
from sseclient import SSEClient
|
||||||
|
from threading import Thread
|
||||||
|
from time import sleep
|
||||||
|
from json import loads
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
|
import libcommon
|
||||||
|
|
||||||
|
url = "http://localhost:42069"
|
||||||
|
|
||||||
|
|
||||||
|
def post(method: str, **params):
|
||||||
|
return _post(url+"/api/v1/rpc", json={"jsonrpc": "2.0", "method": method, "params": params, "id": str(uuid4())}).json()
|
||||||
|
|
||||||
|
|
||||||
|
def sendMessage(message: str, recipient: str | libcommon.Group):
|
||||||
|
if isinstance(recipient, libcommon.Group):
|
||||||
|
return post("send", message=message, groupId=recipient.id)
|
||||||
|
return post("send", message=message, recipient=recipient)
|
||||||
|
|
||||||
|
|
||||||
|
def listGroups() -> List[libcommon.Group]:
|
||||||
|
grps = post("listGroups")["result"]
|
||||||
|
groups = []
|
||||||
|
for group in grps:
|
||||||
|
groups.append(libcommon.Group(group["name"], group["id"]))
|
||||||
|
return groups
|
||||||
|
|
||||||
|
|
||||||
|
def onMessage(group: Optional[libcommon.Group] = None) -> Callable:
|
||||||
|
def decorator(func: Callable) -> Callable:
|
||||||
|
libcommon.signalMessageBinds.append((group, func))
|
||||||
|
return func
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
cli = Thread(target=libcommon.signalInit, args=(
|
||||||
|
"signal-cli daemon --http localhost:42069",))
|
||||||
|
cli.start()
|
||||||
|
|
||||||
|
sleep(5)
|
||||||
|
|
||||||
|
for msg in SSEClient(url+"/api/v1/events"):
|
||||||
|
data = loads(msg.data)
|
||||||
|
envelope = data.get("envelope", None)
|
||||||
|
if envelope:
|
||||||
|
dataMessage = envelope.get("dataMessage", None)
|
||||||
|
if dataMessage:
|
||||||
|
name = envelope["sourceName"]
|
||||||
|
body = dataMessage["message"]
|
||||||
|
groupId = dataMessage["groupInfo"]["groupId"]
|
||||||
|
if body is not None:
|
||||||
|
for group, func in libcommon.signalMessageBinds:
|
||||||
|
if group is None or group.id == groupId:
|
||||||
|
func(name, body)
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
21
main.py
Normal file
21
main.py
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
from importlib import import_module
|
||||||
|
from threading import Thread
|
||||||
|
from subprocess import run
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import libminecraft
|
||||||
|
import libsignal
|
||||||
|
|
||||||
|
|
||||||
|
minecraftThread = Thread(target=libminecraft.main)
|
||||||
|
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])
|
||||||
|
|
||||||
|
minecraftThread.join()
|
||||||
|
signalThread.join()
|
||||||
17
modules/minecraft_signal_bridge.py
Normal file
17
modules/minecraft_signal_bridge.py
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import libminecraft
|
||||||
|
import libsignal
|
||||||
|
import libcommon
|
||||||
|
|
||||||
|
RSBeta = libcommon.Group(
|
||||||
|
"RS Beta", "25a58sEeccxAs7Ka27HZW5Sm3R8zJQcyndLKR6FO7sM=")
|
||||||
|
|
||||||
|
|
||||||
|
@libminecraft.onConsoleOutput(r"\[.*\] \[Server thread\/INFO\]: <(.*)> (.*)")
|
||||||
|
def minecraftToSignal(usr: str, msg: str):
|
||||||
|
libsignal.sendMessage(f"[{usr}] {msg}", RSBeta)
|
||||||
|
|
||||||
|
|
||||||
|
@libsignal.onMessage(RSBeta)
|
||||||
|
def signalToMinecraft(usr: str, msg: str):
|
||||||
|
print(usr, msg)
|
||||||
|
libminecraft.sendCommand(f"tellraw @a [{usr}] {msg}")
|
||||||
Loading…
Add table
Add a link
Reference in a new issue