7163D

c3mm.py

Oct 3rd, 2016
170
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Cossacks 3 (Text) Mod Manager version 1.3.1
  2. # Require python 3.5.x to work : https://python.org/downloads
  3. # Get all update at http://www.cossacks3.com/forum/index.php?threads/cossacks-3-text-mod-manager.17753
  4.  
  5. """
  6. # === News in 1.3.1 === #
  7.     >Change functionement of file-check. Now, if a file is modified, the program will test instalation of mods, and if mod are affected it uninstall it.
  8. """
  9.  
  10.  
  11. """
  12. Structur uses
  13. Mod  := {'name':name, 'version':version, 'info':info, 'file':{name => list of (str old, str new)}}
  14. Data := {'mod':{name => mod mod}, 'file':{name => list of str mod}}
  15. """
  16.  
  17. import json, sys, os, time
  18. from random import randrange
  19.  
  20. CONFIG_PATH = "c3mm/"
  21. MOD_PATH    = "mod/"
  22. COPY_PATH   = "c3mm/copy/"
  23. BCKUP_PATH  = "c3mm/bckup/"
  24. INFO_PATH   = "c3mm/c3mm.json"
  25. LOG_PATH    = "c3mm/log.txt"
  26. HELP = """
  27. Cossacks3 (text) Mod Manager Version 1.3.0.
  28. Type python c3mm.py action [parameter]
  29.     action:
  30.         install modname   -> intall a mod find by name
  31.         uninstall modname -> unintall a mod find by name
  32.         help              -> show this message
  33.         uninstall_all     -> uninstall all mod
  34. """
  35.  
  36. PATH = [CONFIG_PATH, MOD_PATH, COPY_PATH, BCKUP_PATH]
  37. FILE = [INFO_PATH, LOG_PATH]
  38. for path in PATH:
  39.     try:
  40.         os.mkdir(path)
  41.     except:
  42.         pass
  43. for file in FILE:
  44.     try:
  45.         open(file, 'r')
  46.     except:
  47.         open(file, 'w')
  48.  
  49. class Alert:
  50.     linfo = []
  51.     lerror = []
  52.  
  53.     def info(i):
  54.         Alert.linfo.append(i)
  55.         print(i)
  56.  
  57.     def error(e, data):
  58.         Alert.lerror.append(e)
  59.         print(e)
  60.         quit(data)
  61.  
  62.     def input(m):
  63.         return input(m)
  64.  
  65.     def list(l):
  66.         for i in l:
  67.             print(i)
  68.  
  69. def loadjson(path):
  70.     return json.loads(open(path, 'r').read())
  71.  
  72. def savejson(path, data):
  73.     open(path, "w").write(json.dumps(data))
  74.  
  75. def mkPath(path):
  76.     rpath = ""
  77.     for dir in path.split('/')[:-1]:
  78.         rpath += dir
  79.         try:
  80.             os.mkdir(rpath)
  81.         except:
  82.             pass
  83.         rpath += '/'
  84.  
  85. def copyFile(file, path):
  86.     mkPath(path)
  87.     open(path, "w").write(open(file, 'r').read())
  88.  
  89. def checkMod(mod):
  90.     """
  91.     checkMod function, use to check if a mod is valid
  92.     Mod mod     -> mod to check
  93.     Bool return -> is the mod valid?
  94.     """
  95.     for file in mod['file']:
  96.         Alert.info("Check existence of '" + file + "'")
  97.         try:
  98.             f = open(file, 'r').read()
  99.             Alert.info("'" + file + "' exist.")
  100.         except:
  101.             Alert.info("'" + file + "' don't exist.")
  102.             return False
  103.  
  104.         for old in mod['file'][file]:
  105.             Alert.info("Check exsitence of '" + old + "' in '" + file + "'")
  106.             if not old in f:
  107.                 Alert.info("Not found.")
  108.                 return False
  109.             else:
  110.                 Alert.info("Found.")
  111.     return True
  112.  
  113. def apply(mod):
  114.     """
  115.     apply function, use to modify files
  116.     Mod mod -> mod that contain all modifications
  117.     None return
  118.     """
  119.     mfile = {}
  120.     for file in mod['file']:
  121.         Alert.info("Patching '" + file + '"')
  122.         f = open(file, 'r').read()
  123.  
  124.         #Calculate modifications
  125.         for old in mod['file'][file]:
  126.             new = mod['file'][file][old]
  127.             f = f.replace(old, new)
  128.  
  129.         mfile[file] = f
  130.    
  131.     #Apply mod
  132.     for file in mfile:
  133.         open(file, 'w').write(mfile[file])
  134.  
  135. def install(mod, data):
  136.     """
  137.     install function, use to add a mod.
  138.     Mod mod   -> mod to install
  139.     Data data -> c3mm main data
  140.     None return
  141.     """
  142.     if not checkMod(mod):
  143.         Alert.error("'" + mod['name'] + "' mod version " + mod['version'] + " isn't valid", data)
  144.  
  145.     Alert.info("Install '" + mod['name'] + "' version " + mod['version'])
  146.  
  147.     #Add some "signature"
  148.     for file in mod['file']:
  149.         for old in mod['file'][file]:
  150.             mod['file'][file][old] = mod['file'][file][old] + "//" + str(randrange(100000, 999999))
  151.  
  152.     #Add mod to list of installed mod
  153.     data['mod'][mod['name']] = mod
  154.  
  155.     #Adding mod in list of file modification
  156.     for file in mod['file']:
  157.         if not file in data['file']:
  158.             data['file'][file] = [mod['name']]
  159.             #backup file
  160.             copyFile(file, BCKUP_PATH + file)
  161.         else:
  162.             data['file'][file].append(mod['name'])
  163.  
  164.     apply(mod)
  165.  
  166.     for file in mod['file']:
  167.         #make a save of the file
  168.         copyFile(file, COPY_PATH + file)
  169.  
  170. def uninstall(mod, data):
  171.     """
  172.     uninstall function, use to delete a mod.
  173.     Mod mod   -> mod to uninstall
  174.     Data data -> c3mm main data
  175.     None return
  176.     """
  177.     uninstallmod = mkuninstallmod(mod)
  178.  
  179.     if not checkMod(uninstallmod):
  180.         Alert.info("'" + mod['name'] + "' mod uninstaller isn't valid.")
  181.         Alert.info("Do you want restore all files concerned by this mod?")
  182.         Alert.info("List of mod will uninstalled in this case:")
  183.         modlist = []
  184.         for file in mod['file']:
  185.             for mod in data['file'][file]:
  186.                 if not mod in modlist:
  187.                     modlist.append(mod)
  188.                     Alert.info(mod)
  189.         choice = Alert.chocie("Restore all file? yes/no:")
  190.         if choice == 'no':
  191.             quit(data)
  192.  
  193.         filelist = [file for file in mod['file']]
  194.         for file in filelist:
  195.             Alert("Restore '" + file + "'")
  196.             copyFile(BCKUP_PATH + file, file)
  197.             data['mod'][mod]['file'].remove(file)
  198.  
  199.         for mod in modlist():
  200.             uninstall(mod, data)
  201.  
  202.        
  203.  
  204.     #Delete mod to list of installed mod
  205.     del data['mod'][mod['name']]
  206.  
  207.     #Delete mod of list of file modification
  208.     for file in data['file']:
  209.         if mod['name'] in data['file'][file]:
  210.             data['file'][file].remove(mod['name'])
  211.  
  212.     Alert.info("Uninstall '" + mod['name'] + "' version " + mod['version'])
  213.  
  214.     apply(uninstallmod)
  215.  
  216. def mkuninstallmod(mod):
  217.     """
  218.     mkuninstallmod function, use to make an uninstalator from a mod
  219.     Mod mod    -> mod to uninstall
  220.     Mod return -> uninstalator mod
  221.     """
  222.     uninstallmod = {}
  223.     uninstallmod['file'] = {}
  224.  
  225.     for file in mod['file']:
  226.         uninstallmod['file'][file] = {}
  227.         for old in mod['file'][file]:
  228.             new = mod['file'][file][old]
  229.             #For each modification of mod, inverse new and old
  230.             uninstallmod['file'][file][new] = old
  231.  
  232.     return uninstallmod
  233.  
  234. def checkStatu(data):
  235.     """
  236.     checkStatu funtion, check if a modded file has been modified since last launch of this program
  237.     Data data   -> main data
  238.     Bool return ->
  239.     """
  240.     badfile = []
  241.     #Check all modded file
  242.     for file in data['file']:
  243.         if open(file, 'r').read() != open(COPY_PATH + file, 'r').read():
  244.             Alert.info("File '" + file + "' has been modified since last launch of c3mm.")
  245.             badfile.append(file)
  246.  
  247.     badmod = []
  248.     #Uninstall all mod concerned by these files
  249.     for file in badfile:
  250.         for mod in data['file'][file]:
  251.             if not mod in badmod and not checkMod(mkuninstallmod(data['mod'][mod])):
  252.                 badmod.append(mod)
  253.  
  254.     for mod in badmod:
  255.         _mod = data['mod'][mod]
  256.         for file in badfile:
  257.             if file in _mod['file']:
  258.                 del _mod['file'][file]
  259.         uninstall(_mod, data)
  260.  
  261.     return len(badmod) == 0
  262.  
  263. def quit(data):
  264.  
  265.     dfile = []
  266.     for file in data['file']:
  267.         if data['file'][file] == []:
  268.             dfile.append(file)
  269.  
  270.     for file in dfile:
  271.         del data['file'][file]
  272.  
  273.     savejson(INFO_PATH, data)
  274.  
  275.     logs = time.strftime('%D %H:%M\n',time.localtime())
  276.     for info in Alert.linfo:
  277.         logs += info + '\n'
  278.     for error in Alert.lerror:
  279.         logs += error + '\n'
  280.  
  281.     open(LOG_PATH, "a").write(logs)
  282.     exit()
  283.  
  284. def main(argc, argv):
  285.  
  286.     try:
  287.         data = loadjson(INFO_PATH)
  288.     except:
  289.         open(INFO_PATH, "w").write('{"mod":{}, "file":{}}')
  290.         data = loadjson(INFO_PATH)
  291.  
  292.     if not checkStatu(data):
  293.         quit(data)
  294.  
  295.     elif argc == 1 or argv[1] == "help":
  296.         print(HELP)
  297.  
  298.     elif argv[1] == 'install':
  299.  
  300.         if argc < 3:
  301.             Alert.error("You must give a mod name", data)
  302.  
  303.         mod = loadjson(MOD_PATH + argv[2] + '.json')
  304.         modname = mod['name']
  305.  
  306.         if modname in data['mod']:
  307.             if mod["version"] == data["mod"][modname]["version"]:
  308.                 Alert.error("Mod '" + modname + "' version " + mod["version"] + " is already install.", data)
  309.             else:
  310.                 Alert.info("Mod '" + modname + "' version " + data["mod"][modname]["version"] + " is already install. Do you want change it for version " + mod["version"] + "?")
  311.                 choice = Alert.input("yes/no:")
  312.                 if choice == "no":
  313.                     quit()
  314.  
  315.                 uninstall(data['mod'][modname], data)
  316.  
  317.         install(mod, data)
  318.  
  319.     elif argv[1] == 'uninstall':
  320.  
  321.         if argc < 3:
  322.             Alert.error("You must give a mod name", data)
  323.  
  324.         mod = loadjson(MOD_PATH + argv[2] + '.json')
  325.         modname = mod['name']
  326.         uninstall(data['mod'][modname], data)
  327.  
  328.     elif argv[1] == 'uninstall_all':
  329.  
  330.         Alert.info("Restore all files")
  331.         for file in data['file']:
  332.             Alert.info("Restore '" + file + "'")
  333.             copyFile(BCKUP_PATH + file, file)
  334.  
  335.         data['file'] = {}
  336.         data['mod'] = {}
  337.  
  338.     elif argv[1] == 'giveall':
  339.         Alert.list([mod + " version " + data['mod'][mod]['version'] for mod in data['mod']])
  340.  
  341.     quit(data)
  342.  
  343. if __name__ == '__main__':
  344.     main(len(sys.argv), sys.argv)
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×