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 ( " \n Press 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 ] )
2017-07-21 12:23:23 +00:00
def exceptionCleanup ( ) :
success = True
logtext = " "
logtext = logtext + " Attempting cleanup. \n "
logtext = logtext + " Making folders visible... \n "
try :
ctypes . windll . kernel32 . SetFileAttributesW ( appPath , 128 )
ctypes . windll . kernel32 . SetFileAttributesW ( originalAppPath , 128 )
except Exception as e :
success = False
logtext = logtext + str ( e ) + " \n "
logtext = logtext + " Unloading mods... \n "
try :
unloadMods ( )
except Exception as e :
success = False
logtext = logtext + str ( e ) + " \n "
logtext = logtext + " Cleaning up temporary files... \n "
try :
cleanUp ( )
except Exception as e :
success = False
logtext = logtext + str ( e ) + " \n "
if success == False :
logtext = logtext + " \n Cleanup not fully successful. Please review the errors, and go to X for a guide on how to reset your game manually. Sorry for the inconvenience, I tried :( "
return logtext
2017-05-31 16:42:51 +00:00
def exceptionHandler ( exc_type , exc_value , tb ) :
import traceback
while True :
clear ( )
2017-07-21 12:23:23 +00:00
print ( " An exception has occurred: " )
2017-05-31 16:42:51 +00:00
traceback . print_exception ( exc_type , exc_value , tb )
2017-07-21 12:23:23 +00:00
cleanupLog = exceptionCleanup ( )
print ( " \n " + cleanupLog )
2017-05-31 16:42:51 +00:00
choice = input ( " \n Would you like to log this exception? (y/n) \n " )
if choice . lower ( ) == " y " :
2017-07-21 12:23:23 +00:00
success = False
fileCreated = False
2017-05-31 16:42:51 +00:00
errorFilePath = os . path . join ( scriptPath , " error.log " )
2017-07-21 12:23:23 +00:00
try :
errorFile = open ( errorFilePath , " w " )
fileCreated = True
try :
traceback . print_exception ( exc_type , exc_value , tb , None , errorFile )
errorFile . write ( " \n " + cleanupLog )
success = True
except :
input ( " Writing to errorlog-file failed. Press ENTER to continue. " )
except :
input ( " Creating errorlog-file failed. Press ENTER to continue. " )
if fileCreated : errorFile . close ( )
if success :
try :
openFileWithStandardApp ( errorFilePath )
except :
input ( " Opening errorlog-file failed. You can find it at ' " + errorFilePath + " ' . Press ENTER to continue. " )
elif choice . lower ( ) != " n " :
continue
sys . exit ( - 1 )
2017-05-31 16:42:51 +00:00
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 :
2017-07-21 12:23:23 +00:00
while True :
clear ( )
print ( " You selected the following path: ' " + appPath + " ' " )
choice = input ( " Do you wish to set up that folder for mod-use? (y/n) \n " )
if choice == " y " :
os . makedirs ( modPath )
return
if choice == " n " : sys . exit ( - 1 )
2017-05-25 17:31:36 +00:00
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 ( )