#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 import ctypes import os import shutil import webbrowser import time import stat scriptPath = os.path.dirname(os.path.realpath(__file__)) appPath = False appName = False originalAppPath = False tmpAppPath = False modPath = False originalModPath = False #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: cloneFolder(os.path.join(root,dir),tmpAppPath,True,False) def loadMods(output = False): if areModsLoaded(): if unloadMods() == False: if output: print("Unloading mods failed!") return False claimFolder(appPath) cloneFolder(appPath,tmpAppPath,False) cloneMods(modPath) os.rename(appPath,originalAppPath) os.rename(tmpAppPath,appPath) ctypes.windll.kernel32.SetFileAttributesW(originalAppPath,2) 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) ctypes.windll.kernel32.SetFileAttributesW(appPath,128) 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 def cloneFolder(src,dst,rpl,ignoreMods = True): 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: 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) def claimFolder(path): os.chmod(path, stat.S_IRWXU| stat.S_IRWXG| stat.S_IRWXO) 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() def setupVariables(): global appPath global appName global originalAppPath global tmpAppPath global modPath global originalModPath appPath = sys.argv[1] 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") #Init setupVariables() title("Fier's Universal Modloader: " +appName) cleanUp() checkUp() while True: mainMenu()