Skip to content

Commit

Permalink
1.05
Browse files Browse the repository at this point in the history
  • Loading branch information
robbyz512 committed Sep 23, 2022
1 parent 1f70a73 commit efef59e
Show file tree
Hide file tree
Showing 63 changed files with 211 additions and 102 deletions.
23 changes: 0 additions & 23 deletions bin/modpaths/Hide Ranks/blacklist.txt

This file was deleted.

8 changes: 0 additions & 8 deletions bin/modpaths/Hide Ranks/styling.txt

This file was deleted.

Empty file.
Empty file.
1 change: 1 addition & 0 deletions bin/modpaths/Misc Optimization/blacklist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ particles\world_outpost\world_outpost_radiant_ambient_debris.vpcf_c
particles\world_outpost\world_outpost_radiant_ambient_embers.vpcf_c
particles\world_outpost\world_outpost_radiant_ambient_light.vpcf_c
particles\world_outpost\world_outpost_radiant_ambient_mist.vpcf_c

#minified-illusions
particles\generic_gameplay\illusion_killed_c.vpcf_c
particles\generic_gameplay\illusion_killed_dust.vpcf_c
Expand Down
Empty file.
Empty file.
117 changes: 84 additions & 33 deletions gui.pyw
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import traceback
import threading
import subprocess
import tkinter as tk
from tkinter.messagebox import askyesno
from functools import partial
from idlelib.tooltip import Hovertip
from shutil import copytree, ignore_patterns
Expand All @@ -22,12 +23,13 @@ import mpaths
import validatefiles
import helper

version = "1.04.22"
version = "1.05.22"

# button size
btnXpad = 5
# widget vars
btnXpad = 8
btnYpad = 8
btnW = 8
hoverDelay = 250

patching = False
checkboxes = {}
Expand Down Expand Up @@ -91,7 +93,7 @@ class App():
# -------------------------------- widgets -------------------------------- #

self.checkboxesFrame = tk.Frame(self.root)
self.checkboxesFrame.grid(row=0, column=0, sticky='w')
self.checkboxesFrame.grid(row=0, column=0, padx=btnXpad, sticky='w')

self.buttonsFrame = tk.Frame(self.root)
self.buttonsFrame.grid(row=1, column=0, pady=13, sticky='nsew')
Expand All @@ -108,6 +110,7 @@ class App():
self.current_box.grid(row=index, column=0, sticky='w')
checkboxes[self.current_box] = self.name # so checkbutton object is the key and value is string

# details label
mod_path = os.path.join(mpaths.mods_dir, self.name)
notes_txt = os.path.join(mod_path, 'notes.txt')
if os.path.exists(notes_txt) and os.stat(notes_txt).st_size != 0:
Expand All @@ -118,34 +121,52 @@ class App():
self.modLabel.bind("<Button-1>", partial(helper.modInfo, self.modLabel, self.name, mod_path))
self.modLabel.grid(row=index, column=1, sticky='w')

# patreon mods
color = '#E5BA78'
patreon_txt = os.path.join(mod_path, 'files\patreon.txt')
self.patreonTip = Hovertip(self.current_box, text='')
if self.name in mpaths.patreon_mods:
self.current_box.config(fg=color, activeforeground=color)
if not os.path.exists(patreon_txt):
helper.patreon_enabled = False
self.current_box.config(state='disable', disabledforeground=color)
self.patreonTip.text = 'If you are a Patreon member go download your ZIP file on #downloads in discord to enable this.'
self.patreonTip.hover_delay = hoverDelay
else:
self.patreonTip.hover_delay = 500000
else:
self.patreonTip.hover_delay = 500000

# Buttons
self.patchBtn = tk.Button(self.buttonsFrame, text='Patch', state=tk.NORMAL, width=btnW, takefocus=False, command=lambda:threading.Thread(target=self.patcher, daemon=True).start())
self.patchBtn.grid(row=10, column=0, pady=btnYpad, padx=btnXpad)
self.patchBtn.grid(row=10, column=0, pady=btnYpad, padx=btnXpad, sticky='w')
self.helpBtn = tk.Button(self.buttonsFrame, text='Help', state=tk.NORMAL, width=btnW, takefocus=False, command=lambda:threading.Thread(target=helper.urlDispatcher(mpaths.help_url), daemon=True).start())
self.helpBtn.grid(row=10, column=1, pady=btnYpad, padx=btnXpad)
self.helpBtn.grid(row=10, column=1, pady=btnYpad, padx=btnXpad, sticky='w')
self.updateBtn = tk.Button(self.buttonsFrame, text='Update', state=tk.NORMAL, width=btnW, takefocus=False, command=lambda:threading.Thread(target=helper.urlDispatcher(mpaths.update_url), daemon=True).start())
self.updateBtn.grid(row=11, column=0, pady=btnYpad, padx=btnXpad)
self.updateBtn.grid(row=11, column=0, pady=btnYpad, padx=btnXpad, sticky='w')
self.updateBtnTip = Hovertip(self.updateBtn, text='')
self.uninstallBtn = tk.Button(self.buttonsFrame, text='Uninstall', width=btnW, takefocus=False, command=lambda:threading.Thread(target=self.uninstaller, daemon=True).start())
self.uninstallBtn.grid(row=11, column=1, pady=btnYpad, padx=btnXpad)
self.uninstallBtn.grid(row=11, column=1, pady=btnYpad, padx=btnXpad, sticky='w')
self.versionLabel = tk.Label(self.buttonsFrame, font=("None", 8), width=20)
self.versionLabel.grid(row=12, column=0)
self.versionLabel.grid(row=12, column=0, sticky='w')
self.newVersionLabel = tk.Label(self.buttonsFrame, font=("None", 8), width=20)
self.newVersionLabel.grid(row=13, column=0, sticky='w')
self.patreonBtn = tk.Button(self.buttonsFrame, text='Patreon', width=btnW, takefocus=False, command=lambda:threading.Thread(target=helper.urlDispatcher(mpaths.patreon_url), daemon=True).start())
self.patreonBtn.grid(row=14, column=0, pady=btnYpad, padx=btnXpad)
self.patreonBtn.grid(row=14, column=0, pady=btnYpad, padx=btnXpad, sticky='w')
self.discordBtn = tk.Button(self.buttonsFrame, text='Discord', width=btnW, takefocus=False, command=lambda:threading.Thread(target=helper.urlDispatcher(mpaths.discord_url), daemon=True).start())
self.discordBtn.grid(row=14, column=1, pady=btnYpad, padx=btnXpad)
self.discordBtn.grid(row=14, column=1, pady=btnYpad, padx=btnXpad, sticky='w')
self.exitBtn = tk.Button(self.buttonsFrame, text='Exit', width=btnW, takefocus=False, command=self.exit)
self.exitBtn.grid(row=15, column=0, pady=btnYpad, padx=btnXpad)
self.exitBtn.grid(row=15, column=0, pady=btnYpad, padx=btnXpad, sticky='w')

# Other Widget
self.consoleText = tk.Text(self.consoleFrame, wrap=tk.WORD, state=tk.DISABLED, width=72, borderwidth=2, bg="#FFFFF7", relief="groove")
self.consoleText = tk.Text(self.consoleFrame, wrap=tk.WORD, state=tk.DISABLED, width=65, borderwidth=2, bg="#FFFFF7", relief="groove")
self.consoleText.grid(row=0,column=0)
self.consoleText.configure(font=("Fixedsys"))
self.devLabel = tk.Label(self.consoleFrame, font=("Tahoma", 8), width=40)
self.devLabel = tk.Label(self.consoleFrame, font=("Tahoma", 8))
self.devLabel.config(text="Want to create Dota2 mods with Minify?")
self.devLabel.place(x=340,y=390)
self.devLabel.grid(row=1, column=0, sticky='e')
self.devbtn = tk.Button(self.consoleFrame, text='Download Developer Version', width=22, height=1, font=("None", 7), takefocus=False, command=lambda:threading.Thread(target=helper.urlDispatcher(mpaths.dev_version), daemon=True).start())
self.devbtn.place(x=420,y=412)
self.devbtn.grid(row=2, column=0, sticky='e')

# redirects stdout and stderror to text box widget, which means print statements will not appear in the gui until these two lines are ran
sys.stdout = TextRedirector(self.consoleText, "stdout")
Expand All @@ -154,7 +175,7 @@ class App():
welcomeMsg()

def setupSystem(self):
x = validatefiles.MyClass(checkboxes)
x = validatefiles.MyClass(checkboxes, self.root)
public_methods = [method for method in dir(x) if callable(getattr(x, method)) if not method.startswith('_')] # private methods start with _
try:
for method in public_methods:
Expand Down Expand Up @@ -185,25 +206,36 @@ class App():
self.versionLabel.config(fg="#0cb6b3")
self.versionLabel.config(text=f"Latest version {version}")
self.updateBtnTip.text = 'You are using the latest version'
self.updateBtnTip.hover_delay = 250
self.updateBtnTip.hover_delay = hoverDelay
else:
self.updateBtn.config(state='normal')
self.versionLabel.config(fg="#DE3163")
self.versionLabel.config(text="New version available!")
self.updateBtn.config(state='normal', fg='#0cb6b3', activeforeground='#0cb6b3')
self.updateBtnTip.text = ''
self.updateBtnTip.hover_delay = 500000 # .text='' showing pixelated whitespace, just set hover delay to forever

self.newVersionLabel.config(fg='red')
self.newVersionLabel.config(text=f"New version! {mpaths.latest_version_url}")

self.versionLabel.config(fg="#0cb6b3")
self.versionLabel.config(text=f"Your version {version}")

def uninstaller(self):
with open(mpaths.gameinfo_dir, "r") as file:
contents = file.readlines()
with open(mpaths.gameinfo_dir, 'w') as file:
for line in contents:
if 'minify' not in line:
file.write(line)

fullPath = os.path.join(mpaths.dota_minify, 'pak01_dir.vpk')
if os.path.exists(fullPath): os.remove(fullPath)
print("All Minify mods have been removed.")

root = tk.Tk()
root.title('Tkinter Yes/No Dialog')
root.geometry('300x150')
answer = askyesno(title='confirmation',
message='Remove all mods?')
if answer:
with open(mpaths.gameinfo_dir, "r") as file:
contents = file.readlines()
with open(mpaths.gameinfo_dir, 'w') as file:
for line in contents:
if 'minify' not in line:
file.write(line)

fullPath = os.path.join(mpaths.dota_minify, 'pak01_dir.vpk')
if os.path.exists(fullPath): os.remove(fullPath)
print("All Minify mods have been removed.")
# ---------------------------------------------------------------------------- #
# Main #
# ---------------------------------------------------------------------------- #
Expand All @@ -224,14 +256,18 @@ class App():
try:
# clean up previous patching data
helper.cleanFolders(mpaths.build_dir, mpaths.logs_dir, mpaths.content_dir, mpaths.game_dir, mpaths.minify_dir)

# patch playXML warning
helper.patchPlayXML(mpaths.build_dir)

styling_dictionary = {}
# blacklist_dictionary = {}
helper.warnings = []

blank_file_extensions = helper.getBlankFileExtensions(mpaths.blank_files_dir) # list of extensions in bin/blank-files
blacklist_data = [] # path from every blacklist.txt
styling_data = [] # path and style from every styling.txt

for folder in mpaths.mods_folders:
try:
mod_path = os.path.join(mpaths.mods_dir, folder)
Expand All @@ -242,6 +278,21 @@ class App():
for box in checkboxes:
if box.var.get() == 1 and checkboxes[box] == folder: # step into folders that have ticked checkboxes only
print("→ Installing " + folder)

# temporary workaround to install patreon mods, will be refactored later.
if helper.isSanctumChecked(checkboxes):
if checkboxes[box] == 'Dark Terrain':
shutil.copytree(os.path.join(mpaths.mods_dir, 'Terrain - Sanctum of the Divine\\Dark Terrain'), mpaths.game_dir, dirs_exist_ok=True)
continue
if checkboxes[box] == 'Misc Optimization':
shutil.copytree(os.path.join(mpaths.mods_dir, 'Terrain - Sanctum of the Divine\\Misc Optimization'), mpaths.game_dir, dirs_exist_ok=True)
continue
if checkboxes[box] == 'Remove Foilage':
shutil.copytree(os.path.join(mpaths.mods_dir, 'Terrain - Sanctum of the Divine\\Remove Foilage'), mpaths.game_dir, dirs_exist_ok=True)
continue
if checkboxes[box] == 'Tree Mod':
shutil.copytree(os.path.join(mpaths.mods_dir, 'Terrain - Sanctum of the Divine\\Tree Mod'), mpaths.game_dir, dirs_exist_ok=True)
continue
# ----------------------------------- files ---------------------------------- #
# if files_total == 0: pass
# elif files_total == 1: print(f" files: Found {files_total} file")
Expand Down Expand Up @@ -378,7 +429,7 @@ class App():
newpak.save(os.path.join(mpaths.dota_minify, 'pak01_dir.vpk'))

patching = False
helper.toggleFrameOn(self.checkboxesFrame, self.buttonsFrame, mpaths.mods_dir, mpaths.mods_folders, checkboxes)
helper.toggleFrameOn(self.checkboxesFrame, self.buttonsFrame, mpaths.mods_dir, mpaths.mods_folders, mpaths.patreon_mods, checkboxes)
print("→ Done!")
print("-------------------------------------------------")
print("→ Remember to use dota2patcher and patch gameinfo")
Expand Down
52 changes: 48 additions & 4 deletions helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
from urllib.request import urlopen

workshop_installed = False
patreon_enabled = None

# ---------------------------------------------------------------------------- #
# Warnings #
# ---------------------------------------------------------------------------- #
# Output can be passed here to display as warnings at the end of patching.
# Output can be passed here to display as warnings at the end of patching.

warnings = []

Expand Down Expand Up @@ -44,10 +45,36 @@ def patchGameInfo(gameinfo_dir):
with open(gameinfo_dir, "w") as file:
file.writelines(contents)
break

def patchPlayXML(build_dir):
data = []
path = os.path.join(build_dir, 'panorama\\layout')
url = "https://raw.githubusercontent.com/SteamDatabase/GameTracking-Dota2/master/game/dota/pak01_dir/panorama/layout/play.xml"

for line in urlopen(url):
line = line.decode('utf-8').strip()

if '#DOTA_VAC_Verification_Header' in line:
new_line = line.replace('title', 'body').replace('#DOTA_VAC_Verification_Header', 'Minify')
data.append(new_line)
continue

if '#dota_play_disabled_local_mods' in line:
new_line = line.replace('#dota_play_disabled_local_mods', 'Gameinfo outdated. Close Dota2 and patch gameinfo with dota2patcher.')
data.append(new_line)
continue

data.append(line)

if not os.path.exists(path): os.makedirs(path)

with open(os.path.join(path, 'play.xml'), 'w') as file:
for line in data:
file.write(line)
# ---------------------------------------------------------------------------- #
# GUI #
# ---------------------------------------------------------------------------- #
# when you add new arguments to bind in tkinter event must be the last parameter.
# when you add new arguments to bind function tkinter seems to expect event as the last argument.
def modLabelColorConfig(widget, color, event):
widget.configure(foreground=color)

Expand Down Expand Up @@ -77,7 +104,21 @@ def disableWorkshopMods(mods_dir, mods_folders, checkboxes):
if os.stat(styling_txt).st_size != 0:
box.configure(state='disable')

def toggleFrameOn(frame_checkbox, frame_buttons, mods_dir, mods_folders, checkboxes):
# this has become a mess with redundant loops and individual checks
# next version will be focused on refactoring into a state machine

def isSanctumChecked(checkboxes):
for box in checkboxes:
if box.var.get() == 1 and checkboxes[box] == 'Terrain - Sanctum of the Divine':
return True

def disablePatreonMods(patreon_mods, checkboxes):
for box in checkboxes:
for mod in patreon_mods:
if checkboxes[box] == mod:
box.configure(state='disable')

def toggleFrameOn(frame_checkbox, frame_buttons, mods_dir, mods_folders, patreon_mods, checkboxes):
for widget in frame_checkbox.winfo_children():
widget.configure(state='normal')

Expand All @@ -89,6 +130,9 @@ def toggleFrameOn(frame_checkbox, frame_buttons, mods_dir, mods_folders, checkbo

if workshop_installed == False:
disableWorkshopMods(mods_dir, mods_folders, checkboxes)

if patreon_enabled == False:
disablePatreonMods(patreon_mods, checkboxes)

def toggleFrameOff(frame_checkbox, frame_buttons):
for widget in frame_checkbox.winfo_children():
Expand All @@ -101,7 +145,7 @@ def toggleFrameOff(frame_checkbox, frame_buttons):
widget.configure(state='disable')

def getAppHeight(mods_folders):
height = 445
height = 460

num_of_mods = len(mods_folders)
i = 10
Expand Down
6 changes: 0 additions & 6 deletions logs/resourcecompiler.txt
Original file line number Diff line number Diff line change
@@ -1,6 +0,0 @@
NvAPI initialized: NVidia Complete Version 1.10
NVIDIA Driver Version: 516.59 r515_00
-----------------------------------------------------------------
WARNING: 0 compiled, 0 failed, 0 skipped, 0m:00s
-----------------------------------------------------------------
ID3D11Device has 2 outstanding references indicating leaked D3D11 resources.
2 changes: 1 addition & 1 deletion mods/Dark Terrain/notes.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Makes the entire floor dark tiles.

- ONLY works on default terrain you cannot use a custom terrain like desert, immortal gardens..etc
- ONLY works on default terrain and Sanctum of Divine.
- You can turn on "Normal Maps" in graphics settings to make the tiles look like a grid.
Empty file added mods/Ink Shader/blacklist.txt
Empty file.
Binary file not shown.
3 changes: 3 additions & 0 deletions mods/Ink Shader/notes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Black outline for more detailed map and models. Check 'preview.jpg' in mods/Ink Shader

Does not lower your FPS or affect the interface such as 3rd party software like ReShade do because I created this using Steams post processing materials.
Binary file added mods/Ink Shader/preview.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file added mods/Ink Shader/styling.txt
Empty file.

0 comments on commit efef59e

Please sign in to comment.