diff --git a/subfiles/comunic.py b/subfiles/comunic.py index f867ff4..c483d16 100644 --- a/subfiles/comunic.py +++ b/subfiles/comunic.py @@ -3,16 +3,21 @@ import requests import json from hashlib import sha256 +from pathlib import Path +from shutil import copyfileobj from . import helpers, savetools from websockets.sync.client import connect from subprocess import Popen, PIPE from sys import platform from os import listdir from os.path import isfile, join, exists +import os from pathlib import Path import subprocess - +def startClient(self, id): + cmd = f"steam://rungameid/{id}" + Popen(['steam', cmd]) def downloadLatestDll(self, filepath): x = requests.get('https://openwf.io/supplementals/client%20drop-in/meta') @@ -22,6 +27,7 @@ def downloadLatestDll(self, filepath): hashofdll = sha256() hashofdll.update(content)# if hashofdll.hexdigest() == meta['sha256']: + print(filepath) with open(filepath + "dwmapi.dll", "wb") as out_file: out_file.write(content) helpers.messageBox(self=self,title="Bootstrapper Downloaded", message="Bootstrapper Downloaded!", type="info") @@ -58,46 +64,46 @@ def getLatestVersions(self, cacheFile, value): value[0].set("Latest Server Version: " + server) value[1].set("Latest Client Version: " + client) - - - - - - -def serverBackground(self, cd, logArea): # To my knowledge, running the server in the main thread would stall the gui, fuck that lol - logmax = helpers.getLogMax() - logarr=[] - def mongo(): - sysctl = Popen(['systemctl', 'start', 'mongodb']) - sysctl.wait()# - def execute(cd): - popen = Popen(['npm', 'run', 'dev'], stdin=PIPE, stdout=PIPE, universal_newlines=True, cwd=cd) - for stdout_line in iter(popen.stdout.readline, ""): - yield stdout_line - popen.stdout.close() - return_code = popen.wait() - if return_code: - raise subprocess.CalledProcessError(return_code)# - if platform == "linux": - helpers.messageBox(self, title="MongoDB", message="The mongodb server is required to start SNS\nYou will need to give sudo permission for this.", type="info") - mongo() - - for path in execute(cd): - if len(logarr) < logmax: - logarr.append(path) - else: - logarr.pop(0) - logarr.append(path) - if logArea: - logArea.configure(state="normal") - logArea.delete(1.0, "end") - for element in logarr: - pass - logArea.configure(state="disabled") - +def startServer(self, cd, logArea): # To my knowledge, running the server in the main thread would stall the gui, fuck that lol + logmax = helpers.getLogMax(self, self.configFile) + logarr=[] + def mongo(): + sysctl = Popen(['systemctl', 'start', 'mongodb']) + sysctl.wait()# + def execute(cd): + popen = Popen(['npm', 'run', 'dev'], stdin=PIPE, stdout=PIPE, universal_newlines=True, cwd=cd, preexec_fn=os.setsid) + self.popenThreads.append(popen) + for stdout_line in iter(popen.stdout.readline, ""): + yield stdout_line + popen.stdout.close() + return_code = popen.wait() + if return_code: + raise subprocess.CalledProcessError(return_code)# + def start(cd, logArea): + for path in execute(cd): + if len(logarr) < logmax: + logarr.append(path) + else: + logarr.pop(0) + logarr.append(path) + if logArea: + logArea.configure(state="normal") + logArea.delete(1.0, "end") + for element in logarr: + logArea.insert("end", element) + logArea.configure(state="disabled") + + if platform == "linux": + if not self.popenThreads: + helpers.messageBox(self, title="MongoDB", message="The mongodb server is required to start SNS\nYou will need to give sudo permission for this.", type="info") + mongo() + start(cd, logArea) + else: + helpers.messageBox(self, title="Already Running!", message="The Server is already running!", type="info") + def getClientResponse(): try: - with connect("ws://localhost:61558") as websocket: + with connect("ws://localhost:6155") as websocket: message = json.loads(websocket.recv()) except: message=False @@ -110,24 +116,27 @@ def checkForClient(clientpath): else: return False -def runPluto(name, plutolist, conffile): - openwfpath = helpers.getclientpath(conffile) + "/OpenWF/scripts/" +def runPluto(self, name, runningList): + openwfpath = self.clientPath + "/OpenWF/scripts/" onlyfiles = [f for f in listdir(openwfpath) if isfile(join(openwfpath, f))] - if helpers.getclientresponse(): + print("called " + name) + if getClientResponse(): running = [] - print(helpers.getclientresponse()["running_scripts"]) + print(getClientResponse()["running_scripts"]) if name in running: - requests.get(url=("http://localhost:61558/stop_script?OpenWF/scripts/" + name)) + requests.get(url=("http://localhost:6155/stop_script?OpenWF/scripts/" + name)) else: - requests.get(url=("http://localhost:61558/start_script?OpenWF/scripts/" + name)) + requests.get(url=("http://localhost:6155/start_script?OpenWF/scripts/" + name)) - for script in helpers.getclientresponse()["running_scripts"]: + for script in getClientesponse()["running_scripts"]: running.append(script.removeprefix("OpenWF/scripts/"))# for file in onlyfiles: if file in running: - if plutolist[file]: plutolist[file].set("Running") + if runningList[file]: runningList[file].set(True) else: - if plutolist[file]: plutolist[file].set("Not Running") + if runningList[file]: runningList[file].set(False) + else: + if runningList[name]: runningList[name].set(False) def getSnPath(file): if Path(file).is_file(): @@ -137,14 +146,61 @@ def getSnPath(file): else: return False +def openClientLogs(self, platform): + if platform=="linux": + print("ok") + helpers.messageBox(self, "") +def pushWeapon(self, string, slot): + if type(string) is list: + i=0 + for part in string: + print(i) + pluto = f"gRegion:GetLocalPlayerAvatar():InventoryControl():RemoveItem({slot[i]}, true) gRegion:GetLocalPlayerAvatar():GiveItem(Type(\"{part}\"), true)" + requests.get(f"http://localhost:61558/start_script_inline?{pluto}") + if slot[i] == 3: + level = f"gRegion:GetLocalPlayerAvatar():InventoryControl():GetActivePowerSuit():SetXP(1600000)" + else: + level = f"gRegion:GetLocalPlayerAvatar():InventoryControl():GetWeaponInHand({slot[i]}):SetXP(1600000)" + requests.get(f"http://localhost:61558/start_script_inline?{level}") + i+=1 + else: + pluto = f"gRegion:GetLocalPlayerAvatar():InventoryControl():RemoveItem({slot}, true) gRegion:GetLocalPlayerAvatar():GiveItem(Type(\"{string}\"), true) gRegion:GetLocalPlayerAvatar():InventoryControl():GetWeaponInHand({slot}):SetXP(1600000)" + requests.get(f"http://localhost:61558/start_script_inline?{pluto}") +def pushInline(self, Area): + #format + formatted = Area.get(0.0, "end").replace("\n", ' ') + requests.get(f"http://localhost:61558/start_script_inline?{formatted}") +def getWarframeExports(self, path): + exportList = { + "weapons":"https://raw.githubusercontent.com/calamity-inc/warframe-public-export/refs/heads/senpai/ExportWeapons_en.json", + "powersuits":"https://raw.githubusercontent.com/calamity-inc/warframe-public-export/refs/heads/senpai/ExportWarframes_en.json" + } + for export in exportList.keys(): + helpers.folderExist(path) + with open(path + f"{export}.json", "wb") as out_file: + content = requests.get(exportList[export], stream=True).content + out_file.write(content) + +def getWarframeExportsPlus(self, path): + exportList = { + "weapons":"https://raw.githubusercontent.com/calamity-inc/warframe-public-export-plus/refs/heads/senpai/ExportWeapons.json", + "powersuits":"https://raw.githubusercontent.com/calamity-inc/warframe-public-export-plus/refs/heads/senpai/ExportWarframes.json" + } + for export in exportList.keys(): + helpers.folderExist((path+"/plus/").replace("//", "/")) + with open((path + f"/plus/{export}.json").replace('//', '/'), "wb") as out_file: + content = requests.get(exportList[export], stream=True).content + out_file.write(content) +def getIconDownload(self, path, savePath): + if not exists("./cache/items/icons" + savePath.rsplit('/', 1)[0]): + Path("./cache/items/icons" + savePath.rsplit('/', 1)[0]).mkdir(parents=True, exist_ok=True) + with open("./cache/items/icons" + savePath, "wb+") as out_file: + print(f"https://browse.wf{savePath}") + out_file.write(requests.get(f"https://browse.wf{savePath}").content) - - - - - \ No newline at end of file + print(f"Saved {path} Icon") \ No newline at end of file diff --git a/subfiles/helpers.py b/subfiles/helpers.py index 95d0c67..b59e598 100644 --- a/subfiles/helpers.py +++ b/subfiles/helpers.py @@ -1,12 +1,24 @@ from CTkMessagebox import CTkMessagebox import threading from .savetools import loadFile +from pathlib import Path +from .comunic import getIconDownload +import os +import signal +import json +from PIL import Image + try: from os import startfile except: from os import system from sys import platform +def killPopen(popen): #jesus + os.kill(os.getpgid(popen.pid), signal.SIGTERM) + +def folderExist(path): + Path(path).mkdir(parents=True, exist_ok=True) def check(): print("Save Good") @@ -17,7 +29,6 @@ def removeChildren(frame): def bgThread(func, args): th = threading.Thread(target=func, args=args) - th.daemon = True th.start() def openLocation(self, location): @@ -26,8 +37,7 @@ def openLocation(self, location): elif platform == "windows": startfile(foldername) - -def messageBox(self, title, message, type): #type will be implemented at a later point when required +def messageBox(self, title, message, type): #type will be implemented at a later point when required. for now, just fill it in irregardless. CTkMessagebox(title=title, message=message) def getLogMax(self, save): @@ -42,17 +52,89 @@ def isNumber(data): return False return True +def formatExportWeapons(self, file1): + log = open("log.txt", "a") + testfile = open("test1.json", 'w') + if open(file1): + print("opened") + with open(file1, 'r') as file: + data=json.load(file)["ExportWeapons"] + redund = [] + for diction in range(len(data)): + + for key in list(data[diction].keys()): + if key not in ["name", "slot", "uniqueName"]: + del data[diction][key] + print("deleted " + str(data[diction]["name"] + ' ' + key)) + if 'slot' not in data[diction].keys(): + redund.append(diction) + + i=0 + for diction in redund: + + i+=1 + print("Removed Unneeded Modular " + str(data[diction-i]["name"]), file=log) + del data[diction-i] + + def sortFunc(e): + return e["name"] + data.sort(key=sortFunc) + + json.dump(data, testfile, indent=2) + return data + +def formatExportPowersuits(self, file1): + log = open("log.txt", "a") + testfile = open("test2.json", 'w') + if open(file1): + print("opened") + with open(file1, 'r') as file: + data=json.load(file)["ExportWarframes"] + redund = [] + for diction in range(len(data)): + + for key in list(data[diction].keys()): + if key not in ["name", "productCategory", "uniqueName"]: + del data[diction][key] + print("deleted " + str(data[diction]["name"] + ' ' + key)) + + + def sortFunc(e): + return e["name"] + + data.sort(key=sortFunc) + + json.dump(data, testfile, indent=2) + return data + +def formatExportPlus(self, file1): + with open(file1, 'r') as file: + data=json.load(file) + write = False + for item in data.keys(): + print(data[item]) + if type(data[item]) is dict: + icon = data[item]["icon"] + print(data[item]) + data[item] = icon + write=True + + if write == True: + with open(file1, 'w') as file: + json.dump(data, file, indent=2) + + return data + +def getIcon(self, path, savePath): + try: + image = Image.open("./cache/items/icons" + savePath) + return image + except: + getIconDownload(self, path, savePath) + return Image.open("./cache/items/icons" + savePath) #Old Helper options, left here for future reference. Shitty code, but it works, and it may be useful in the future - - - - - - - - # def getlogmax(): # file = 'sngconfig.json' # if Path(file).is_file(): @@ -66,6 +148,7 @@ def isNumber(data): # def check4sn(configfile): # file = helpers.getsnpath(configfile) + "package.json" + # if Path(file).is_file(): # with open(file) as f: # d = json.load(f) diff --git a/subfiles/savetools.py b/subfiles/savetools.py index d6746e6..1880bea 100644 --- a/subfiles/savetools.py +++ b/subfiles/savetools.py @@ -10,13 +10,46 @@ def loadFile(self, file1): data = json.load(file) return data -#Data should be recived in [[data, position], [data, position]] format -def saveFile(self, fileP, data): - with open(fileP, 'r') as file: - data = json.load(file) - for subData in data: - data[subData[1]] = subData[0] - with open(fileP, 'w'): - json.dump(file, indent=2) +def saveFile(self, newData, file): + with open(file, "r") as file1: + data = json.load(file1) + def anotherRecusion(data, newData): + if type(data) is dict: + for key in newData: + match data[key]: + case str(): + data[key]=newData[key].get() + case bool(): + data[key]=newData[key].get() + case int(): + data[key]=int(newData[key].get()) + case dict(): + data[key] = anotherRecusion(data[key], newData[key]) + case list(): + data[key]= anotherRecusion(data[key], newData[key]) + elif type(data) is list: + for key in range(len(newData)): + match data[key]: + case str(): + data[key]=newData[key].get() + case bool(): + data[key]=newData[key].get() + case int(): + data[key]=int(newData[key].get()) + case dict(): + data[key] = anotherRecusion(data[key], newData[key]) + case list(): + data[key]= anotherRecusion(data[key], newData[key]) + return data + data = anotherRecusion(data, newData) + print(data) + with open(file, "w") as file1: + json.dump(data, file1, indent=2) + + + + + + diff --git a/subfiles/themes.py b/subfiles/themes.py index df067f0..25788a0 100644 --- a/subfiles/themes.py +++ b/subfiles/themes.py @@ -7,6 +7,38 @@ def getThemes(self): "border_color" : "#14213D", "highlight_color" : '#FCA311', "text_color" : "" + }, + "kiln" : { + "fg_color" : "#5A2901", + "bg_color" : "#AE6F3B", + "bg_deep" : "#885599", + "border_color" : "#AE6F3B", + "highlight_color" : '#246868', + "text_color" : "" + }, + "mint_nebula" : { + "fg_color" : "#15001F", + "bg_color" : "#2F0047", + "bg_deep" : "#440066", + "border_color" : "#6B3E00", + "highlight_color" : '#00683E', + "text_color" : "" + }, + "antimatter" : { + "fg_color" : "#13002C", + "bg_color" : "#2F036A", + "bg_deep" : "#22014E", + "border_color" : "#2F026A", + "highlight_color" : '#9C8E00', + "text_color" : "" + }, + "fenix" : { + "fg_color" : "#451D08", + "bg_color" : "#73300D", + "bg_deep" : "#73300D", + "border_color" : "##A14312", + "highlight_color" : '#083045', + "text_color" : "" } } return themes \ No newline at end of file