diff --git a/.github/workflows/pyinstaller-linux.yml b/.github/workflows/pyinstaller-linux.yml index d0cf26e..1b74f54 100644 --- a/.github/workflows/pyinstaller-linux.yml +++ b/.github/workflows/pyinstaller-linux.yml @@ -1,4 +1,4 @@ -name: PyInstaller Action Linux +name: PyInstaller Action (3.13.2) on: [push] jobs: pyinstaller-build: @@ -14,18 +14,15 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.12.7' + python-version: '3.13.2' - name: Install dependencies run: | - sudo apt install cmake build-essential tcl-dev tk-dev python3-tk python -m pip install --upgrade pip pip install pyinstaller pip install jsoncparser - pip install scikit-build - pip install tksvg - name: Run PyInstaller run: | - pyinstaller --noconfirm --onedir --console --name "Snark" --add-data "version.txt:." --add-data "activities.txt:." --add-data "icon-linux.svg:." --add-data "logo128.png:." --add-data "icon-win32.ico:." --add-data "icon-linux.png:." --add-data "LICENSE:." --add-data "README.md:." --add-data "save:save/" --add-data "themes:themes/" --add-data "third_party:third_party/" --add-data "images:images/" --add-data "logs:logs/" "GUI.py" + pyinstaller --noconfirm --onedir --console --name "Snark" --add-data "version.txt:." --add-data "activities.txt:." --add-data "logo128.png:." --add-data "icon-win32.ico:." --add-data "icon-linux.png:." --add-data "icon-linux.svg:." --add-data "LICENSE:." --add-data "README.md:." --add-data "save:save/" --add-data "themes:themes/" --add-data "third_party:third_party/" --add-data "images:images/" --add-data "logs:logs/" "GUI.py" - name: Upload artifact uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/pyinstaller.yml b/.github/workflows/pyinstaller.yml index 3b07522..e8ce4ac 100644 --- a/.github/workflows/pyinstaller.yml +++ b/.github/workflows/pyinstaller.yml @@ -14,7 +14,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.12.7' + python-version: '3.12.9' - name: Install dependencies run: | python -m pip install --upgrade pip @@ -22,7 +22,7 @@ jobs: pip install jsoncparser - name: Run PyInstaller run: | - pyinstaller --noconfirm --onedir --console --name "Snark" --add-data "version.txt:." --add-data "activities.txt:." --add-data "logo128.png:." --add-data "icon-win32.ico:." --add-data "icon-linux.png:." --add-data "LICENSE:." --add-data "README.md:." --add-data "save:save/" --add-data "themes:themes/" --add-data "third_party:third_party/" --add-data "images:images/" --add-data "logs:logs/" "GUI.py" + pyinstaller --noconfirm --onedir --console --name "Snark" --add-data "version.txt:." --add-data "activities.txt:." --add-data "logo128.png:." --add-data "icon-win32.ico:." --add-data "icon-linux.png:." --add-data "icon-linux.svg:." --add-data "LICENSE:." --add-data "README.md:." --add-data "save:save/" --add-data "themes:themes/" --add-data "third_party:third_party/" --add-data "images:images/" --add-data "logs:logs/" "GUI.py" - name: Upload artifact uses: actions/upload-artifact@v4 with: diff --git a/.gitignore b/.gitignore index 511b903..5040a31 100644 --- a/.gitignore +++ b/.gitignore @@ -162,4 +162,5 @@ cython_debug/ back.bmp Snark.code-workspace *.mdl -scripts/ +# scripts/ +WinSize.txt \ No newline at end of file diff --git a/GUI.py b/GUI.py index 8e37ef3..0a3b34a 100644 --- a/GUI.py +++ b/GUI.py @@ -2,10 +2,6 @@ from tkinter import * from tkinter.filedialog import askopenfilename, askdirectory from tkinter import font -try: - import tksvg -except: - pass import os from os.path import * import importlib.machinery @@ -287,17 +283,14 @@ def __init__(self): self.selTheme = self.options["theme"] winSizeFile = False - if sys.platform == "linux" and os.path.exists("save/WinSize.txt"): - wsFile = open("save/WinSize.txt", "r") + if sys.platform == "linux" and os.path.exists("WinSize.txt"): + wsFile = open("WinSize.txt", "r") ws = wsFile.readlines() wsFile.close() winSizeFile = True # Loading in window icon - try: - ico = tksvg.SvgImage(file="icon-linux.svg") - except: - ico = PhotoImage(file="icon-linux.png") + ico = PhotoImage(file="icon-linux.png") self.iconphoto(True, ico) thCol = {} @@ -477,8 +470,8 @@ def __init__(self): else: self.geometry("501x443") - if not os.path.exists("save/WinSize.txt"): - wsf = open("save/WinSize.txt", "w") + if not os.path.exists("WinSize.txt"): + wsf = open("WinSize.txt", "w") wsf.write(f"{self.goodWidth}\n{self.goodHeight}") wsf.close() diff --git a/menus.py b/menus.py index fcb9024..b85161d 100644 --- a/menus.py +++ b/menus.py @@ -430,7 +430,7 @@ def openHLAM(self): # If "Half-Life Asset Manager" is selected if self.options["gsMV"]["selectedMV"] == 1: if sys.platform == "linux": - a = subprocess.getoutput(f"hlam \"{self.name.get()}\"") + a = subprocess.getoutput(f"XDG_SESSION_TYPE=x11 hlam \"{self.name.get()}\"") else: a = subprocess.getoutput(f"\"C:/Program Files (x86)/Half-Life Asset Manager/hlam.exe\" \"{self.name.get()}\"") # If "Other" option is selected @@ -672,7 +672,6 @@ def __init__(self, template, master, startHidden:bool=False): self.hitboxB = BooleanVar(self.advOpt, value=False) self.hitboxChk = Checkbutton(self.advOpt, text="-h", variable=self.hitboxB) self.keepBonesB = BooleanVar(self.advOpt, value=False) - self.keepBonesChk = Checkbutton(self.advOpt, text="-k", variable=self.keepBonesB) if self.advOptFix: self.ignoreB = BooleanVar(self.advOpt, value=False) self.ignoreChk = Checkbutton(self.advOpt, text="-i", variable=self.ignoreB) @@ -686,6 +685,7 @@ def __init__(self, template, master, startHidden:bool=False): self.groupSB.entry.config(width=4) self.pf2B = BooleanVar(self.advOpt, value=False) self.pf2Chk = Checkbutton(self.advOpt, text="-p", variable=self.pf2B) + self.keepBonesChk = Checkbutton(self.advOpt, text="-k", variable=self.keepBonesB) else: self.ignoreB = BooleanVar(self.advOpt, value=False) self.ignoreChk = Checkbutton(self.advOpt, text="-i", variable=self.ignoreB) @@ -699,6 +699,7 @@ def __init__(self, template, master, startHidden:bool=False): self.groupSB.entry.config(width=4) self.pf2B = BooleanVar(self.advOpt2, value=False) self.pf2Chk = Checkbutton(self.advOpt2, text="-p", variable=self.pf2B) + self.keepBonesChk = Checkbutton(self.advOpt2, text="-k", variable=self.keepBonesB) # Tooltips self.logChkTT = ToolTip(self.logChk, "Writes the log in the terminal below as a text file inside the logs folder.", background=thme["tt"], foreground=thme["txt"]) self.dashTChkTT = ToolTip(self.dashTChk, "Specify a texture to replace while compiling, you can globally replace all textures by specifying one bitmap or replace a single texture by following this format: \'tex1.bmp,tex2.bmp\'.", background=thme["tt"], foreground=thme["txt"]) @@ -713,6 +714,9 @@ def __init__(self, template, master, startHidden:bool=False): self.pf2ChkTT = ToolTip(self.pf2Chk, "Forces power of 2 textures when enabled", background=thme["tt"], foreground=thme["txt"]) self.mdlTT = ToolTip(self.mdlBrowse, "REQUIRED, specifies the QC file used to compile your model, you cannot leave this blank.", background=thme["tt"], foreground=thme["txt"]) self.outputTT = ToolTip(self.outBrowse, "OPTIONAL, if an output folder is not specified, then it will place the compiled model in a subfolder of where the QC file is located.", background=thme["tt"], foreground=thme["txt"]) + + # Checking if the default compiler has the engine type Svengine. + self.compilerStuff() self.decomp = Button(master, text='Compile', command=self.startCompile, cursor="hand2") self.console = Console(master, 'Currently no warnings or errors!', 0, 5, self.conFix, 12) @@ -779,7 +783,7 @@ def groupSBhandler(self): else: self.groupSB.lock() - def compilerStuff(self, event): + def compilerStuff(self, event=None): self.compJS = self.fullCJS["compilers"][self.compSel.get()] if self.compJS["type"].lower() == "svengine": self.svengine = True @@ -801,7 +805,7 @@ def openHLAM(self): # If "Half-Life Asset Manager" is selected if self.options["gsMV"]["selectedMV"] == 1: if sys.platform == "linux": - a = subprocess.getoutput(f"hlam \"{self.mdlPath}\"") + a = subprocess.getoutput(f"XDG_SESSION_TYPE=x11 hlam \"{self.mdlPath}\"") else: a = subprocess.getoutput(f"\"C:/Program Files (x86)/Half-Life Asset Manager/hlam.exe\" \"{self.mdlPath}\"") # If "Other" option is selected @@ -879,6 +883,7 @@ def updateOpt(self, key, value): # Doing specific things for specific options if key == "defComp": self.compSel.current(self.options[key]) + self.compilerStuff() elif key == "defGame": self.gameSel.current(self.options[key]) # Doing this since the gsMV option needs two square bracket data things in order to update stuff properly, @@ -1377,7 +1382,7 @@ def __init__(self, template, master, thmecallback, updFunc, startHidden:bool=Fal cOptions.pop(len(cOptions)-1) self.compSel = ttk.Combobox(master, values=cOptions) self.compSel.bind("<>", self.setCmp) - self.compSel.current(self.options["defGame"]) + self.compSel.current(self.options["defComp"]) gList = open("save/games.txt", "r") self.gOptions = gList.read().split('\n') self.gOptions.pop(len(self.gOptions)-1) @@ -1387,16 +1392,16 @@ def __init__(self, template, master, thmecallback, updFunc, startHidden:bool=Fal self.gameSel.bind("<>", self.setGame) self.gameSel.current(self.options["defGame"]) # Checking if anything is exceeding the width of the "safe zone" - self.show() + """self.show() self.checkWidth() - self.hide() + self.hide()""" # Tooltips self.themeTT = ToolTip(self.themeCBox, "Changes the program's theme, the built-in themes are: Freeman, Shephard, Calhoun and Cross.", background=thme["tt"], foreground=thme["txt"]) self.startFolderTT = ToolTip(self.startFent, "Sets the directory that the built-in file explorer will start in, the default is the documents folder.", background=thme["tt"], foreground=thme["txt"]) self.startFolderTT2 = ToolTip(self.setSF, "Sets the directory that the built-in file explorer will start in, the default is the documents folder.", background=thme["tt"], foreground=thme["txt"]) self.forceDefTT = ToolTip(self.forceDefault, "By default, Snark prioritises the custom path you set over the default paths for compilers, enabling this will prioritise the default paths instead, meaning that Snark won't use the custom path if it finds the compiler in its default path.", background=thme["tt"], foreground=thme["txt"]) self.hlmvTT = ToolTip(self.hlmvCBox, "Sets the model viewer you want to use when clicking the \"Open model in HLMV\" button, if this is set to None, the button will not show up!", background=thme["tt"], foreground=thme["txt"]) - self.mvPathTT = ToolTip(self.mvPathEnt.entry, "Sets the path to the model viewer you want to use if you select \"Other\"", background=thme["tt"], foreground=thme["txt"]) + self.setMVPtt = ToolTip(self.setMVP, "Sets the path to the model viewer you want to use if you select \"Other\"", background=thme["tt"], foreground=thme["txt"]) if not startHidden: self.show() @@ -1458,6 +1463,7 @@ def genPg(self): self.startFent.grid(column=2, row=2, sticky="w") self.setSF.grid(column=3, row=2, sticky="w") self.fdLabel.grid(column=1, row=3, sticky="w") + self.forceDefault.grid(column=2, row=3, sticky="w") self.defCLabel.grid(column=1, row=4, sticky="w") self.compSel.grid(column=2, row=4, sticky="w") self.defGLabel.grid(column=1, row=5, sticky="w") @@ -1624,6 +1630,7 @@ def show(self): self.startFent.grid(column=2, row=2, sticky="w") self.setSF.grid(column=3, row=2, sticky="w") self.fdLabel.grid(column=1, row=3, sticky="w") + self.forceDefault.grid(column=2, row=3, sticky="w") self.defCLabel.grid(column=1, row=4, sticky="w") self.compSel.grid(column=2, row=4, sticky="w") self.defGLabel.grid(column=1, row=5, sticky="w") @@ -1640,16 +1647,21 @@ def __init__(self, template, master, startHidden:bool=False): self.curFont = font.nametofont('TkDefaultFont').actual() self.widthFix = 74 self.conFix = 46 + self.conHeight = 11 self.logOutput = False if self.curFont["family"].lower() == "nimbus sans l" or sys.platform == "win32": self.widthFix = 81 self.conFix = 59 + self.conHeight = 13 else: pass self.hidden = startHidden self.master = master thme = template.thme self.thme, self.safeWidth = thme, template.safeWidth + if self.safeWidth > 609: + n = 3 + self.widthFix, self.conFix = self.widthFix-n, self.conFix-n # Setting up options js = open("save/options.json", 'r') self.options = json.loads(js.read()) @@ -1669,7 +1681,7 @@ def __init__(self, template, master, startHidden:bool=False): count += 1 self.scr_list.insert(count, self.scripts[count]) self.runBtn = Button(master, text="Run script", cursor="hand2") - self.console = Console(master, 'Run a script and an output of the script\'s progress will appear here!', 0, 2, self.conFix, 12) + self.console = Console(master, 'Run a script and an output of the script\'s progress will appear here!', 0, 2, self.conFix, self.conHeight) if not startHidden: self.show() diff --git a/scripts/template.sst b/scripts/template.sst new file mode 100644 index 0000000..9cf6370 --- /dev/null +++ b/scripts/template.sst @@ -0,0 +1,34 @@ +- +version 1 +format jsonc +- +{ + "name": "Template Script", + // You can specify a global output folder for every task + "globalOutput": "path/to/output/folder", + "tasks": [ + { + // This specifies the name of the task, this will show up in the console when the task has been started. + // Task names cannot have slashes in their name, otherwise it will confuse the interpreter. + "name": "Decompile MDL", + // Valid values for tasks are compile, decompile and view. + "task": "decompile", + "file": "absolute/path/to/mdl/file", + // You can use this key to specify an output folder for this specific task. + "output": "path/to/output/folder" + }, + { + "name": "Compile MDL", + "task": "compile", + "file": "absolute/path/to/qc/file", + // Please note that with compile tasks, the output will not be put in a subfolder of the output folder. + "output": "path/to/output/folder" + }, + { + "name": "View Compiled Model", + "task": "view", + // For the file key in view tasks, you can specify the file you want to open, or specify a compile task to open a MDL file of your choice! + "file": "Compile MDL" + } + ] +} \ No newline at end of file diff --git a/version.txt b/version.txt index 12bda4c..e2c9a17 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v0.1.3-(OS)-alpha +v0.1.4-(OS)-alpha