2017-05-31 16:42:51 +00:00
|
|
|
#Preload Exception handler
|
|
|
|
import sys
|
|
|
|
def preloadExceptionHandler(exc_type, exc_value, tb):
|
|
|
|
import traceback
|
|
|
|
print("An error has occurred while initializing:")
|
|
|
|
traceback.print_exception(exc_type, exc_value, tb)
|
|
|
|
input("\nPress ENTER to exit.")
|
|
|
|
sys.exit(-1)
|
|
|
|
sys.excepthook = preloadExceptionHandler
|
|
|
|
|
|
|
|
#Imports and variables
|
2017-05-25 17:31:36 +00:00
|
|
|
import ctypes
|
|
|
|
import os
|
|
|
|
import shutil
|
|
|
|
import webbrowser
|
2017-05-31 16:42:51 +00:00
|
|
|
import time
|
|
|
|
import stat
|
2017-07-03 02:18:30 +00:00
|
|
|
|
2017-05-31 16:42:51 +00:00
|
|
|
scriptPath = os.path.dirname(os.path.realpath(__file__))
|
2017-07-03 02:18:30 +00:00
|
|
|
appPath = False
|
|
|
|
appName = False
|
|
|
|
originalAppPath = False
|
|
|
|
tmpAppPath = False
|
|
|
|
modPath = False
|
|
|
|
originalModPath = False
|
2017-05-25 17:31:36 +00:00
|
|
|
|
2017-05-31 16:42:51 +00:00
|
|
|
#Exception Handler
|
|
|
|
def openFileWithStandardApp(path):
|
|
|
|
# Windows
|
|
|
|
if os.name == "nt":
|
|
|
|
os.startfile(path)
|
|
|
|
# Macintosh
|
|
|
|
elif sys.platform == "darwin":
|
|
|
|
subprocess.call(['open', path])
|
|
|
|
# Generic Unix (X11)
|
|
|
|
else:
|
|
|
|
subprocess.call(['xdg-open', path])
|
|
|
|
|
|
|
|
def exceptionHandler(exc_type, exc_value, tb):
|
|
|
|
import traceback
|
|
|
|
while True:
|
|
|
|
clear()
|
|
|
|
print("An error has occurred:")
|
|
|
|
traceback.print_exception(exc_type, exc_value, tb)
|
|
|
|
choice = input("\nWould you like to log this exception? (y/n)\n")
|
|
|
|
if choice.lower() == "y":
|
|
|
|
errorFilePath = os.path.join(scriptPath,"error.log")
|
|
|
|
errorFile = open(errorFilePath,"w")
|
|
|
|
traceback.print_exception(exc_type, exc_value, tb, None, errorFile)
|
|
|
|
errorFile.close()
|
|
|
|
openFileWithStandardApp(errorFilePath)
|
|
|
|
sys.exit(-1)
|
|
|
|
elif choice.lower() == "n":
|
|
|
|
sys.exit(-1)
|
|
|
|
sys.excepthook = exceptionHandler
|
|
|
|
|
|
|
|
#Modloader
|
|
|
|
def cloneMods(modDir):
|
|
|
|
for root,dirs,files in walklevel(modDir,0):
|
|
|
|
for dir in dirs:
|
|
|
|
if dir[0] == "-": continue
|
|
|
|
if dir[0] == "[" and dir[-1:] == "]":
|
|
|
|
cloneMods(os.path.join(root,dir))
|
|
|
|
else:
|
2017-07-03 03:28:02 +00:00
|
|
|
if os.path.isfile(os.path.join(root,dir,"uml_installscript.py")) == True:
|
|
|
|
file = open(os.path.join(root,dir,"uml_installscript.py"))
|
|
|
|
exec(file.read(),globals(),locals())
|
|
|
|
file.close()
|
|
|
|
else:
|
|
|
|
cloneFolder(os.path.join(root,dir),tmpAppPath,True,False,True)
|
2017-05-31 16:42:51 +00:00
|
|
|
|
2017-05-25 17:31:36 +00:00
|
|
|
def loadMods(output = False):
|
|
|
|
if areModsLoaded():
|
|
|
|
if unloadMods() == False:
|
|
|
|
if output: print("Unloading mods failed!")
|
|
|
|
return False
|
|
|
|
|
2017-05-31 16:42:51 +00:00
|
|
|
claimFolder(appPath)
|
2017-05-25 17:31:36 +00:00
|
|
|
cloneFolder(appPath,tmpAppPath,False)
|
2017-05-31 16:42:51 +00:00
|
|
|
cloneMods(modPath)
|
2017-05-25 17:31:36 +00:00
|
|
|
|
|
|
|
os.rename(appPath,originalAppPath)
|
|
|
|
os.rename(tmpAppPath,appPath)
|
2017-07-03 02:18:30 +00:00
|
|
|
ctypes.windll.kernel32.SetFileAttributesW(originalAppPath,2)
|
2017-05-25 17:31:36 +00:00
|
|
|
|
|
|
|
if output: print("Mods have been loaded!")
|
|
|
|
return True
|
|
|
|
|
|
|
|
def unloadMods(output = False):
|
|
|
|
if areModsLoaded() == False:
|
|
|
|
if output: print("Mods are already unloaded.")
|
|
|
|
return True
|
|
|
|
|
|
|
|
shutil.rmtree(appPath)
|
|
|
|
os.rename(originalAppPath,appPath)
|
2017-07-03 02:18:30 +00:00
|
|
|
ctypes.windll.kernel32.SetFileAttributesW(appPath,128)
|
2017-05-25 17:31:36 +00:00
|
|
|
|
|
|
|
if output: print("Unloading mods successful.")
|
|
|
|
return True
|
|
|
|
|
|
|
|
def openModsFolder():
|
|
|
|
if areModsLoaded():
|
|
|
|
webbrowser.open("file:///" +originalModPath)
|
|
|
|
else:
|
|
|
|
webbrowser.open("file:///" +modPath)
|
|
|
|
|
|
|
|
def areModsLoaded():
|
|
|
|
if os.path.isdir(originalAppPath):
|
|
|
|
return True
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
2017-07-03 03:28:02 +00:00
|
|
|
def cloneFolder(src,dst,rpl,ignoreMods = True, isMod = False):
|
2017-05-25 17:31:36 +00:00
|
|
|
for root,dirs,files in os.walk(src):
|
|
|
|
newRoot = root.replace(src,dst)
|
|
|
|
if ignoreMods == True:
|
|
|
|
if root.replace(modPath,"") != root: continue
|
|
|
|
|
|
|
|
if os.path.isdir(newRoot) == False: os.makedirs(newRoot)
|
|
|
|
|
|
|
|
for file in files:
|
2017-07-03 03:28:02 +00:00
|
|
|
if isMod == True:
|
|
|
|
if file[:4] == "uml_": continue
|
2017-05-25 17:31:36 +00:00
|
|
|
fullFile = os.path.join(root,file)
|
|
|
|
newFile = os.path.join(newRoot,file)
|
|
|
|
|
|
|
|
if os.path.isfile(newFile):
|
|
|
|
if rpl == True:
|
|
|
|
os.remove(newFile)
|
|
|
|
os.link(fullFile,newFile)
|
|
|
|
else:
|
|
|
|
os.link(fullFile,newFile)
|
|
|
|
|
2017-05-31 16:42:51 +00:00
|
|
|
def claimFolder(path):
|
|
|
|
os.chmod(path, stat.S_IRWXU| stat.S_IRWXG| stat.S_IRWXO)
|
|
|
|
|
2017-05-25 17:31:36 +00:00
|
|
|
def walklevel(some_dir, level=1):
|
|
|
|
some_dir = some_dir.rstrip(os.path.sep)
|
|
|
|
assert os.path.isdir(some_dir)
|
|
|
|
num_sep = some_dir.count(os.path.sep)
|
|
|
|
for root, dirs, files in os.walk(some_dir):
|
|
|
|
yield root, dirs, files
|
|
|
|
num_sep_this = root.count(os.path.sep)
|
|
|
|
if num_sep + level <= num_sep_this:
|
|
|
|
del dirs[:]
|
|
|
|
|
|
|
|
def title(string):
|
|
|
|
if os.name == "nt":
|
|
|
|
os.system("title " +string)
|
|
|
|
else:
|
|
|
|
sys.stdout.write("\x1b]2;" +string+ "\x07")
|
|
|
|
|
|
|
|
def clear():
|
|
|
|
os.system('cls' if os.name=='nt' else 'clear')
|
|
|
|
|
|
|
|
def cleanUp():
|
|
|
|
if os.path.isdir(tmpAppPath):
|
|
|
|
shutil.rmtree(tmpAppPath)
|
|
|
|
|
|
|
|
def checkUp():
|
|
|
|
if areModsLoaded() == False:
|
|
|
|
if os.path.isdir(modPath) == False:
|
|
|
|
os.makedirs(modPath)
|
|
|
|
|
|
|
|
def mainMenu():
|
|
|
|
clear()
|
|
|
|
if areModsLoaded() == False:
|
|
|
|
print("Welcome to Fier's Universal Modloader.")
|
|
|
|
print("Mods are not loaded.")
|
|
|
|
print("")
|
|
|
|
print("Please choose an action:")
|
|
|
|
print("1) Load Mods")
|
|
|
|
print("2) Open Mods-Folder")
|
|
|
|
choice = input("Choice: ")
|
|
|
|
|
|
|
|
clear()
|
|
|
|
if choice == "1": loadMods(True); input("Press ENTER to continue.")
|
|
|
|
if choice == "2": openModsFolder()
|
|
|
|
else:
|
|
|
|
print("Welcome to Fier's Universal Modloader.")
|
|
|
|
print("Mods are loaded.")
|
|
|
|
print("")
|
|
|
|
print("Please choose an action:")
|
|
|
|
print("1) Reload Mods")
|
|
|
|
print("2) Unload Mods")
|
|
|
|
print("3) Open Mods-Folder")
|
|
|
|
choice = input("Choice: ")
|
|
|
|
|
|
|
|
clear()
|
|
|
|
if choice == "1": loadMods(True); input("Press ENTER to continue.")
|
|
|
|
if choice == "2": unloadMods(True); input("Press ENTER to continue.")
|
|
|
|
if choice == "3": openModsFolder()
|
|
|
|
|
2017-07-21 08:19:16 +00:00
|
|
|
def requestAppPath():
|
|
|
|
while True:
|
|
|
|
clear()
|
|
|
|
dir = input("Please insert a folder via Drag&Drop:\n")
|
|
|
|
dir = dir.replace('"',"")
|
|
|
|
if os.path.isdir(dir) == True:
|
|
|
|
return dir
|
|
|
|
|
2017-07-03 02:18:30 +00:00
|
|
|
def setupVariables():
|
|
|
|
global appPath
|
|
|
|
global appName
|
|
|
|
global originalAppPath
|
|
|
|
global tmpAppPath
|
|
|
|
global modPath
|
|
|
|
global originalModPath
|
|
|
|
|
2017-07-21 08:19:16 +00:00
|
|
|
if len(sys.argv) < 2:
|
|
|
|
appPath = requestAppPath()
|
|
|
|
else:
|
|
|
|
appPath = sys.argv[1]
|
|
|
|
|
|
|
|
if os.path.isdir(appPath) == False:
|
|
|
|
raise NameError("Folder not found: " +appPath)
|
|
|
|
|
2017-07-03 02:18:30 +00:00
|
|
|
if os.path.isdir(appPath.replace(" - umlOriginal","")): appPath = appPath.replace(" - umlOriginal","")
|
|
|
|
appName = appPath.replace(os.path.dirname(appPath)+ "\\","")
|
|
|
|
originalAppPath = appPath + " - umlOriginal"
|
|
|
|
tmpAppPath = appPath + " - umlTemp"
|
|
|
|
modPath = os.path.join(appPath,"umlMods")
|
|
|
|
originalModPath = os.path.join(originalAppPath,"umlMods")
|
|
|
|
|
2017-05-31 16:42:51 +00:00
|
|
|
#Init
|
2017-07-03 02:18:30 +00:00
|
|
|
setupVariables()
|
2017-05-25 17:31:36 +00:00
|
|
|
title("Fier's Universal Modloader: " +appName)
|
2017-07-03 02:18:30 +00:00
|
|
|
|
2017-05-25 17:31:36 +00:00
|
|
|
cleanUp()
|
|
|
|
checkUp()
|
|
|
|
while True:
|
2017-07-03 02:18:30 +00:00
|
|
|
mainMenu()
|