Ready for backend hook

Client-side script 'start.py' is now ready for a backend hook.

The only thing remaining to do on the client-side is to add the actual initializer of labylib.

Added support for "us.mineplex.com" in 'servers.json'
This commit is contained in:
Victor Westerlund 2020-11-17 05:17:14 +01:00
parent b45ebba4b4
commit ed7cd2077b
19 changed files with 138 additions and 22 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.cache.png

BIN
backend/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B

0
backend/render.php Normal file
View file

0
backend/servers.json Normal file
View file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 B

View file

@ -1,5 +1,39 @@
{ {
"us.mineplex.net": [ "us.mineplex.com": {
"/(?<=\\[CHAT\\])(.*)(?=ULTRA|HERO|LEGEND|TITAN|ETERNAL|IMMORTAL|TRAINEE|MOD)/g" "pattern": "([abcef0-9])\\w+ ",
"lookup": {
"start": 1,
"ignore": [
"MPS",
"Host",
"Co-Host",
"el?"
],
"tag": [
"ULTRA",
"HERO",
"LEGEND",
"TITAN",
"ETERNAL",
"IMMORTAL",
"YT",
"STREAM",
"YOUTUBE",
"TRAINEE",
"MOD",
"SR.MOD",
"ADMIN",
"LEADER",
"OWNER"
] ]
}
},
"vanilla": {
"pattern": "\\<(?s)(.*)\\>",
"lookup": {
"start": 0,
"ignore": [],
"tag": []
}
}
} }

119
start.py
View file

@ -2,13 +2,12 @@ from labylib import Cape
from threading import Thread, Event from threading import Thread, Event
from pathlib import Path from pathlib import Path
from PIL import Image import re
from PIL import ImageFont import json
from PIL import ImageDraw
import platform import platform
import getpass import getpass
import subprocess import subprocess
import requests
# Chattycape daemon # Chattycape daemon
class Chattycape(Thread): class Chattycape(Thread):
@ -16,26 +15,91 @@ class Chattycape(Thread):
pollRate = 1 # Logfile pollrate pollRate = 1 # Logfile pollrate
updateRate = 1 # Update rate of Labylib cosmetic updateRate = 1 # Update rate of Labylib cosmetic
def __init__(self,event,phpsessid,logfile): def __init__(self,event,phpsessid,endpoint,logfile,me = "None"):
Thread.__init__(self) Thread.__init__(self)
self.stopped = event self.stopped = event
self.params = (phpsessid,endpoint,logfile,me) # Create tuple from params
self.phpsessid = phpsessid self.server = None # Connected to server (hostname)
self.logfile = logfile self.config = None # Chat config for current server
self.line = ""
self.line = "[21:42:25] [main/INFO]: [CHAT] 725 IMMORTAL VicW test"
self.i = 0 self.i = 0
# Poll last line from logfile # Read last line from logfile
def linefeed(self): def linefeed(self):
self.line = subprocess.check_output(['tail','-1',self.logfile]) # tail last line from logfile
line = subprocess.check_output(['tail','-1',self.params[2]]).decode("utf-8","ignore")[:-2]
match = re.search(self.config["pattern"],line)
if match:
self.line = line
return
# Extract Minecraft username and tag from current line
def getUser(self):
line = self.line[31:].split() # Split current line. Offset (31) for log-prefixes
username = tag = "None"
start = self.config["lookup"]["start"] # List offset for iterator
ignoreList = self.config["lookup"]["ignore"] # Jumps to next index if match
tagList = self.config["lookup"]["tag"] # 'tag' set if match
for substr in line[start:]: # Start at offset
if substr in ignoreList:
continue
if substr in tagList:
tag = substr
continue
# Not ignored, and not a tag, so assume we've reached the username
username = substr
break
return (username,tag)
# Update labylib cosmetic # Update labylib cosmetic
def update(self): def update(self):
print(self.line) args = self.getUser() # Get minecraft username and tag
urlparams = f"?server={self.server}&ign={args[0]}&rank={args[1]}"
# Save cape texture from endpoint to disk
with open(".cache.png","wb") as handle:
fetch = requests.get(self.params[1] + urlparams,stream=True)
if not fetch.ok:
print(fetch)
for block in fetch.iter_content(1024):
if not block:
break
handle.write(block)
# TODO: Labylib here
# ----------------------------
# Import RegEx patterns for current server
def loadConfig(self):
self.server = "us.mineplex.com"
with open("./servers.json") as config:
data = json.load(config)
self.config = data[self.server]
self.config["pattern"] = r"\[CHAT\]+ " + self.config["pattern"]
# Start the thread
def run(self): def run(self):
print("\nRunning..")
self.loadConfig()
# Start the chat 'listener'
while not self.stopped.wait(Chattycape.pollRate): while not self.stopped.wait(Chattycape.pollRate):
self.linefeed() # Poll logfile self.linefeed() # Poll logfile
@ -53,10 +117,28 @@ class Main:
def __init__(self): def __init__(self):
print("-- Labylib Chattycape --") print("-- Labylib Chattycape --")
self.logfile = self.locate() self.logfile = self.locate()
self.phpsessid = input("\nhttps://github.com/VictorWesterlund/labylib#find-your-phpsessid-cookie\nPaste your PHPSESSID here:\n")
self.endpoint = self.prompt("Cape render endpoint","http://192.168.86.21/victor-westerlund/labylib-chattycape/back-end/render.php")
self.me = self.prompt("My Minecraft in-game name (Case Sensitive)","Don't exclude me")
self.phpsessid = self.prompt("PHPSESSID cookie")
self.start() self.start()
# Prompt user to enter information
def prompt(self,message,default = "None"):
# Add '[default]' flag if present
if(default != "None"):
message += f" [{default}]"
message += ":"
value = default
userinput = input(message + "\n")
if(userinput):
value = userinput
return value
# Attempt to locate '.minecraft' automatically, otherwise prompt user # Attempt to locate '.minecraft' automatically, otherwise prompt user
def locate(self): def locate(self):
sys = platform.system() # Get operating system sys = platform.system() # Get operating system
@ -86,7 +168,7 @@ class Main:
# Failed to locate Minecraft-installation automatically # Failed to locate Minecraft-installation automatically
path = input("Please paste the path to your '.minecraft'-folder:\n") path = self.prompt("Path to your '.minecraft'-folder","/mnt/c/Users/victo/AppData/Roaming/.minecraft")
if(Path(path).exists()): if(Path(path).exists()):
return path + mclog return path + mclog
@ -98,12 +180,11 @@ class Main:
stop = Event() stop = Event()
# Start the daemon # Start the daemon
chattycape = Chattycape(stop,self.phpsessid,self.logfile) chattycape = Chattycape(stop,self.phpsessid,self.endpoint,self.logfile,self.me)
chattycape.start() chattycape.start()
interrupt = input("\nRunning! Press enter to stop\n") input("Press enter to stop the daemon")
stop.set() # Stop the daemon stop.set() # Stop the daemon
print("Bye!") print("Stopped!")
main = Main() Main()
print(main.file)