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": [
"/(?<=\\[CHAT\\])(.*)(?=ULTRA|HERO|LEGEND|TITAN|ETERNAL|IMMORTAL|TRAINEE|MOD)/g"
"us.mineplex.com": {
"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 pathlib import Path
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
import re
import json
import platform
import getpass
import subprocess
import requests
# Chattycape daemon
class Chattycape(Thread):
@ -16,26 +15,91 @@ class Chattycape(Thread):
pollRate = 1 # Logfile pollrate
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)
self.stopped = event
self.params = (phpsessid,endpoint,logfile,me) # Create tuple from params
self.phpsessid = phpsessid
self.logfile = logfile
self.line = ""
self.server = None # Connected to server (hostname)
self.config = None # Chat config for current server
self.line = "[21:42:25] [main/INFO]: [CHAT] 725 IMMORTAL VicW test"
self.i = 0
# Poll last line from logfile
# Read last line from logfile
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
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):
print("\nRunning..")
self.loadConfig()
# Start the chat 'listener'
while not self.stopped.wait(Chattycape.pollRate):
self.linefeed() # Poll logfile
@ -53,10 +117,28 @@ class Main:
def __init__(self):
print("-- Labylib Chattycape --")
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()
# 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
def locate(self):
sys = platform.system() # Get operating system
@ -86,7 +168,7 @@ class Main:
# 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()):
return path + mclog
@ -98,12 +180,11 @@ class Main:
stop = Event()
# Start the daemon
chattycape = Chattycape(stop,self.phpsessid,self.logfile)
chattycape = Chattycape(stop,self.phpsessid,self.endpoint,self.logfile,self.me)
chattycape.start()
interrupt = input("\nRunning! Press enter to stop\n")
input("Press enter to stop the daemon")
stop.set() # Stop the daemon
print("Bye!")
print("Stopped!")
main = Main()
print(main.file)
Main()