mirror of
https://codeberg.org/vlw/labylib.git
synced 2025-09-13 17:43:41 +02:00
Pre-Release 0.1.0
First proof of concept pre-release.
This commit is contained in:
parent
f799d1d714
commit
566ccc4a54
6 changed files with 27 additions and 192 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1 @@
|
||||||
animated-textures/*
|
|
||||||
*__pycache__
|
*__pycache__
|
BIN
2.png
BIN
2.png
Binary file not shown.
Before Width: | Height: | Size: 239 B |
|
@ -2,16 +2,16 @@ import requests
|
||||||
import hashlib
|
import hashlib
|
||||||
import time
|
import time
|
||||||
|
|
||||||
class BadRequestError(Exception): pass
|
class RequestError(Exception): pass
|
||||||
|
|
||||||
class Cape:
|
class Texture:
|
||||||
|
|
||||||
endpoint = "https://www.labymod.net/page/php/cape.php"
|
endpoint = "https://www.labymod.net/page/php/cape.php"
|
||||||
|
|
||||||
def __init__(self,cookie,img):
|
def __init__(self,cookie,img):
|
||||||
self.validate(cookie,img)
|
self.validate(cookie,img)
|
||||||
|
|
||||||
self.body = "" # Initialize request body
|
self.body = b"" # Initialize request body
|
||||||
self.cookies = dict(PHPSESSID = cookie)
|
self.cookies = dict(PHPSESSID = cookie)
|
||||||
self.boundary = self.boundary()
|
self.boundary = self.boundary()
|
||||||
|
|
||||||
|
@ -32,9 +32,8 @@ class Cape:
|
||||||
"Content-Type": "multipart/form-data; boundary=" + self.boundary
|
"Content-Type": "multipart/form-data; boundary=" + self.boundary
|
||||||
}
|
}
|
||||||
|
|
||||||
self.addFormData("cosmetic","cape")
|
self.appendBinaryFormData(b"cosmetic",b"cape")
|
||||||
self.addFormData("file",self.bOpen(img))
|
self.appendBinaryFormData(b"file",self.bOpen(img))
|
||||||
self.closeFormData()
|
|
||||||
|
|
||||||
# -----------------------------------
|
# -----------------------------------
|
||||||
|
|
||||||
|
@ -52,46 +51,48 @@ class Cape:
|
||||||
# Open and return file binary as string
|
# Open and return file binary as string
|
||||||
def bOpen(self,file):
|
def bOpen(self,file):
|
||||||
f = open(file,"rb")
|
f = open(file,"rb")
|
||||||
content = str(f.read())
|
content = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
length = len(content) - 1
|
|
||||||
content = content[2:length]
|
|
||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
# Append form-data to request body and boundary header
|
# Append form-data to request body and boundary header
|
||||||
def addFormData(self,name,payload):
|
def appendBinaryFormData(self,name,payload):
|
||||||
body = contentType = ""
|
body = contentType = b""
|
||||||
eol = "\r\n"
|
eol = b"\r\n"
|
||||||
|
|
||||||
disposition = f'name="{name}"'
|
disposition = b'name="' + name + b'"'
|
||||||
if(name == "file"):
|
if(name == b"file"):
|
||||||
contentType = "Content-Type: image/png" + eol
|
contentType = b"Content-Type: image/png" + eol
|
||||||
|
|
||||||
# Use current epoch as filename. It has to be different from last request
|
# Use current epoch as filename. It has to be different from last request
|
||||||
filename = str(round(time.time())) + ".png"
|
filename = str(round(time.time())) + ".png"
|
||||||
disposition += f'; filename="{filename}"'
|
filename = filename.encode()
|
||||||
|
disposition += b'; filename="' + filename + b'"'
|
||||||
|
|
||||||
body += f"--{self.boundary}" + eol # Init data header
|
body += b"--" + self.boundary.encode() + eol # Init data header
|
||||||
body += f"Content-Disposition: form-data; {disposition}" + eol
|
body += b"Content-Disposition: form-data; " + disposition + eol
|
||||||
body += contentType + eol + eol
|
body += contentType + eol
|
||||||
body += payload + eol
|
body += payload + eol
|
||||||
|
|
||||||
self.body += body
|
self.body += body
|
||||||
|
|
||||||
# Last form-data has been set, add final post width for boundary header
|
# Last form-data has been set, add final post width for boundary header
|
||||||
def closeFormData(self):
|
def closeBinaryFormData(self):
|
||||||
self.body += f"--{self.boundary}--\r\n\r\n"
|
self.body += b"--" + self.boundary.encode() + b"--\r\n\r\n"
|
||||||
|
|
||||||
# -----------------------------------
|
# -----------------------------------
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
request = requests.post(Cape.endpoint,
|
self.closeBinaryFormData() # Add final boundary header
|
||||||
|
|
||||||
|
request = requests.post(Texture.endpoint,
|
||||||
headers = self.headers,
|
headers = self.headers,
|
||||||
cookies = self.cookies,
|
cookies = self.cookies,
|
||||||
data = self.body
|
data = self.body
|
||||||
)
|
)
|
||||||
|
|
||||||
if(request.text != "OK"):
|
# Raise exception if request fails
|
||||||
raise BadRequestError(request.text)
|
# Use [3:5] to clean up junk chars from reponse body
|
||||||
|
if(str(request.text)[3:5] != "OK"):
|
||||||
|
raise RequestError(str(request.text))
|
5
lib.py
5
lib.py
|
@ -1,5 +0,0 @@
|
||||||
from labylib import Cape
|
|
||||||
|
|
||||||
cape = Cape.Cape("76eppb9t0vg3saftu42vf1e223","2.png")
|
|
||||||
cape.update()
|
|
||||||
print(cape.body)
|
|
160
start.py
160
start.py
|
@ -1,160 +0,0 @@
|
||||||
import re
|
|
||||||
import json
|
|
||||||
import importlib
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from labylib import Cape
|
|
||||||
|
|
||||||
# Don't forget to reflect in .gitignore if you change this
|
|
||||||
name = "animated-textures"
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
|
|
||||||
textures = f"./{name}/" # Cosmetic textures path
|
|
||||||
f = f"./{name}/config.json" # JSON Config file
|
|
||||||
default = '{"PHPSESSID": "","cosmetics": {"cape": {"interval": "15","randomOrder": "False"}}}' # Default config
|
|
||||||
pattern = "^[-,a-zA-Z0-9]{1,128}$" # PHPSESSID pattern
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.config = None
|
|
||||||
self.exists = True # Config file already exists
|
|
||||||
self.load()
|
|
||||||
|
|
||||||
# Example: getCosmetic("cape")
|
|
||||||
def getCosmetic(self,key):
|
|
||||||
return self.config["cosmetics"][key]
|
|
||||||
|
|
||||||
# Example: setCosmetic("cape","interval",30)
|
|
||||||
def setCosmetic(self,cosmetic,key,value):
|
|
||||||
self.config["cosmetics"][cosmetic][key] = value
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
def setPHPSESSID(self,phpsessid):
|
|
||||||
self.config["PHPSESSID"] = phpsessid
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
# -----------------------------------------------------
|
|
||||||
|
|
||||||
# (Over)write config file
|
|
||||||
def save(self):
|
|
||||||
f = open(Config.f,"w")
|
|
||||||
f.write(json.dumps(self.config))
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
# Create config file from default template
|
|
||||||
def create(self):
|
|
||||||
self.exists = False
|
|
||||||
|
|
||||||
Path(Config.textures).mkdir(parents=True,exist_ok=True)
|
|
||||||
|
|
||||||
f = open(Config.f,"w")
|
|
||||||
f.write(Config.default)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
# Load the config file from disk into memory
|
|
||||||
def load(self):
|
|
||||||
# Create config file if absent
|
|
||||||
if(Path(Config.f).is_file() == False):
|
|
||||||
self.create()
|
|
||||||
|
|
||||||
f = open(Config.f,"r")
|
|
||||||
self.config = json.load(f)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
class Main:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.config = Config()
|
|
||||||
self.init()
|
|
||||||
|
|
||||||
# Guided step-by-step setup
|
|
||||||
def wizard(self):
|
|
||||||
# +-----------+
|
|
||||||
# | Labylib |
|
|
||||||
# +-----------+
|
|
||||||
def box(string):
|
|
||||||
charset = ["+","-","|"] # Corner,borderX,borderY
|
|
||||||
string = f" {string} " # Text padding
|
|
||||||
|
|
||||||
box = charset[0]
|
|
||||||
# Repeat 'borderX' char for string length
|
|
||||||
for x in string:
|
|
||||||
box += charset[1]
|
|
||||||
box += charset[0]
|
|
||||||
|
|
||||||
# Stitch it all together
|
|
||||||
string = f"{charset[2]}{string}{charset[2]}"
|
|
||||||
string = f"{box}\n{string}\n{box}"
|
|
||||||
|
|
||||||
return string
|
|
||||||
|
|
||||||
msgDone = "Done! Closing Wizard"
|
|
||||||
|
|
||||||
print(box("Labylib Setup Wizard"))
|
|
||||||
print("Make sure you read the README before you begin\n")
|
|
||||||
|
|
||||||
self.config.setPHPSESSID(input("Paste your PHPSESSID here:\n"))
|
|
||||||
|
|
||||||
advanced = input("\nDo you wish to modify the default cosmetic settings? 'y/n'[n]: ")
|
|
||||||
if(advanced != "y"):
|
|
||||||
print(box(msgDone))
|
|
||||||
self.start()
|
|
||||||
return
|
|
||||||
|
|
||||||
wizard = self.config.config["cosmetics"]
|
|
||||||
|
|
||||||
# Iterate over all cosmetics in config
|
|
||||||
for cosmetic in wizard:
|
|
||||||
print(box("Cosmetic > " + cosmetic.capitalize()))
|
|
||||||
|
|
||||||
# Iterate over every cosmetic setting
|
|
||||||
for key, default in wizard[cosmetic].items():
|
|
||||||
value = input(f"Set value for '{key}'[{default}]: ")
|
|
||||||
# Ignore input if empty or data type doesn't match default
|
|
||||||
if(len(value) < 1):
|
|
||||||
print(f"Input error: Expected data type '{type(default)}'. Falling back to default")
|
|
||||||
value = default
|
|
||||||
|
|
||||||
self.config.setCosmetic(cosmetic,key,value)
|
|
||||||
|
|
||||||
print(box(msgDone))
|
|
||||||
self.start()
|
|
||||||
|
|
||||||
#for cosmetic in wizard:
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
phpsessid = self.config.config["PHPSESSID"]
|
|
||||||
start = input(f"\nStart Labylib for PHPSESSID '{phpsessid}'? 'y/n/config'[y]: ")
|
|
||||||
|
|
||||||
if(start == "n"):
|
|
||||||
return
|
|
||||||
|
|
||||||
if(start == "config"):
|
|
||||||
self.wizard()
|
|
||||||
return
|
|
||||||
|
|
||||||
# TODO: Attach labylib hook here
|
|
||||||
|
|
||||||
def init(self):
|
|
||||||
print("Labylib 0.0.1\n")
|
|
||||||
|
|
||||||
if(self.config.exists and len(self.config.config["PHPSESSID"]) > 1):
|
|
||||||
self.start()
|
|
||||||
return
|
|
||||||
|
|
||||||
for cosmetic in self.config.config["cosmetics"]:
|
|
||||||
Path(Config.textures + cosmetic).mkdir(parents=True,exist_ok=True)
|
|
||||||
|
|
||||||
# Prompt if user wants to use guided setup
|
|
||||||
print("-- Labylib Animated Textures --\nSince this is your first time here, would you like to walk through the setup process?\n")
|
|
||||||
wizard = input("Start guided setup? 'y/n':[y] ")
|
|
||||||
if(wizard == "n"):
|
|
||||||
print(f"A config file '{Config.f}' has been created for you. Run this command again when you're ready")
|
|
||||||
return
|
|
||||||
|
|
||||||
self.wizard()
|
|
||||||
|
|
||||||
# Start Labylib
|
|
||||||
labylib = Main()
|
|
0
test.txt
0
test.txt
Loading…
Add table
Reference in a new issue