Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- import sys
- import glob
- import fileinput
- import shutil
- # Don't touch these imports, or else, I'll export you into a black hole! :|
- # Script collaboration between Vas, Artex, Anoyomouse, Harag (In no particular order)
- # Will try to comment as much of it as we can to explain it for those who want to learn from it.
- # Short Description: This script asks user for save location, then asks what saves to fix,
- # and then fixes them according to the words listed below, currently
- # only handles up to 10 words, but I can expand it later to do more easily.
- #
- # Last update: 26-Jul-2015 @ 4:17 AM GMT-6
- #
- # I will edit this script to make it easier for mod authors who don't know python or coding really,
- # to be able to make it work easily for them. Simply edit the values below, if you need help,
- # contact me on the forums via https://ludeon.com/forums/index.php?action=profile;u=2872
- replacements = [
- ('HydroponicsBasinModularPotent', 'HydroponicsBasin4S'), # Enter the words you want replaced
- ('HydroponicsBasinModularFertile', 'HydroponicsBasin3S'), # in these slots.
- ('HydroponicsBasinModularRich', 'HydroponicsBasin2S'), # "ReplaceWord", "ReplaceWith"
- ('HydroponicsBasinModular', 'HydroponicsBasin1S'), # and you can copy the entire
- ('', ''), # line below the next to add more, supports any amount of replacements.
- ('', ''), # Copy the line without the comment, and place it below the last line before the ]
- ('', ''),
- ]
- finalMsgSuccess = "Your save file(s) should now be functional with the new modular hydroponics mod update. Press enter to exit."
- # Please note, the script searches for the text, nothing past it. What I mean is that if you were
- # to search "me" and replace with "of", every instance of "me" will become "of" even if it's in a
- # word like "mean" making iit "ofan". Look at how mine works, I left "HydroponicsBasinModular" as
- # the last one to replace, because the first 3 also have that same word in them, and therefor if
- # I had done it first, it would have broken all those words, like "HydroponicsBasin1SPotent".
- # This is why you should always try to make your defNames very unique in your items, to avoid issues.
- # Beyond this line is the actual script, do not edit unless you are knowledgable in Python!
- # Ask if the script is in the saves directory
- print 'Is the script in the Rimworld save directory?'
- print 'It\'s not a requirement, so don\'t worry!'
- scriptDir = raw_input('Yes|No > ')
- scriptDir = scriptDir.strip(' \t\r\n').lower()
- if scriptDir == 'yes':
- directory = os.getcwd()
- answered = True
- else:
- print 'Oh, alright, that\'s fine.'
- if scriptDir == 'no':
- # Ask if the rimworld save directory is the default
- answered = False
- while not answered:
- print 'Are you using the default Rimworld directory?'
- dirAns = raw_input('Yes|No|Quit > ')
- # clean up the string we get from the user, it might have an enter on the end
- dirAns = dirAns.strip(' \t\r\n').lower()
- if dirAns == 'yes':
- # Grab the user's App Data directory, slice off the "Roaming" part
- the_directory = os.path.split(os.getenv("APPDATA"))[0]
- # Append on the directory where Rimworld saves it's data, should be fine
- directory = os.path.join(the_directory, 'LocalLow', "Ludeon Studios", "RimWorld", "Saves")
- # Then check it exists, in case there was an error getting the default directory
- if os.path.exists(directory):
- print 'Ok, I will use the default directory. For validation, I will display it for you:'
- print directory
- answered = True
- else:
- print 'Path does not seem to exist. For debugging, I will now display the path for you.'
- print directory
- elif dirAns == 'no':
- # Because \ is a special character, we have to put a \ before it (and other specials) to null them out,
- # So when it shows "\\Rimworld\\Saves\\" it actually translates to "\Rimworld\Saves\".
- print 'Please give me the directory you wish me to read files from. Here are two examples;'
- print 'C:\\Users\\Username\\Rimworld\\Saves\\ - To give an exact location.'
- print '\\Rimworld\\Saves\\ - If the files are two directories down from the script\'s current location.'
- directory = raw_input('Dir: ')
- if directory.startswith('\\'):
- directory = os.getcwd() + directory
- # We need to check this path exists as well, in case the user put it in wrong.
- if os.path.exists(directory):
- print 'Ok, I will use the directory you gave. For validation, I will display it for you:'
- print directory
- answered = True
- else:
- print 'Path does not seem to exist. For ease of use, I will now display the path for you.'
- print directory
- elif dirAns.startswith('q'):
- # Just in case someone forgot to not run the script, or they remembered something else!
- print 'So you asked to quit, okay!'
- sys.exit(0)
- else:
- print 'Something happened, looping back to the beginning of this block.'
- else:
- print 'You\'ve chosen to edit files in the same directory as the script.'
- print 'Chosen directory = ' + directory
- # At this point in the script we have a single variable that should be correct: directory
- # Get the input file
- print 'Here are a list of files in the directory you have listed:'
- fileList = filter(os.path.isfile, glob.glob(os.path.join(directory, '*.rws')))
- # Glob is nice, but the list it returns is unsorted, so we sort it here
- fileList.sort()
- cntr = 1
- for i in fileList:
- print str(cntr) + ') ' + os.path.split(i)[1]
- cntr += 1
- print 'Enter a number, or a list of numbers seperated by a space or type "all" if you want to process all RimWorld Save files'
- inputFileNumbers = raw_input('Files > ')
- # Clean up the string we get from the user, it might have an enter on the end
- inputFileNumbers = inputFileNumbers.strip(' \t\r\n')
- # Define a list to keep all the files we want to process, even if it's a single file
- inputFileNames = []
- # Did the user want all files done? If not, we move on.
- if inputFileNumbers.lower() == 'all':
- inputFileNames = fileList
- else:
- # Split the string into a list of "words" and filter out:
- isNonEmptyString = bool
- isNonNegativeNumber = str.isdigit
- isInRange = lambda val: 1 <= val <= len(fileList)
- # same as: def isInRange(val): return 1 <= val <= len(fileList)
- # What we have left are valid indices for fileList (offset by 1)
- lst = filter(isInRange,
- map(int,
- filter(isNonNegativeNumber,
- filter(isNonEmptyString,
- inputFileNumbers.split(' ')))))
- # Make a list of only the relevant filenames based on the extracted indices
- inputFileNames = [fileList[index-1] for index in lst]
- # Redundant, but if we want to notify them of illegal values:
- illegal = filter(isNonEmptyString, inputFileNumbers.split(' '))
- illegal = filter(lambda value: value not in map(str, lst), illegal)
- for v in illegal:
- print " * Ignored illegal value:", v
- # Alternative, for those wanting to know another way of doing the list.
- # Same as lines 81 to 93, only in one line.
- # lst = [x for x in inputFileNumbers.split(' ') if x.isdigit and int(x) > 0 and int(z) <= len(fileList)]
- # inputFileNames = [fileList[y] for y in [int(x) for x in inputFileNumbers.split(' ') if x and x.isdigit and int(x) > 0 and int(x) <= len(fileList)]]
- if len(inputFileNames) > 0:
- if len(inputFileNames) == 1:
- print 'Ok, I will edit ' + os.path.split(inputFileNames[0])[1] + ' for you.'
- else:
- print 'Ok, I will edit the following files for you:'
- for i in inputFileNames:
- print ' ' + os.path.split(i)[1]
- else:
- print 'You did not select any valid file to exit, so we cannot edit anything, killing the script!'
- sys.exit(-1)
- # Ask if I should edit the auto saves
- answered = False
- while not answered:
- print 'Would you also like me to edit your auto saves? (Yes|No)'
- autoSaves = raw_input('Yes|No > ')
- # Clean up the string we get from the user, it might have an enter on the end
- autoSaves = autoSaves.strip(' \t\r\n').lower()
- if autoSaves == 'yes':
- print 'Ok, I will fix the auto saves as well.'
- answered = True
- elif autoSaves == 'no':
- print 'Ok, I will ignore the auto saves.'
- answered = True
- else:
- print 'I\'m sorry, I didn\'t understand that. You need to type Yes, or No.'
- def processFile(srcFile):
- autoData = None
- # Do magic here!
- bakFile = srcFile + '.bak'
- os.rename(srcFile, bakFile)
- inputFileObj = open(bakFile, 'r')
- print 'Writing file: ', os.path.split(srcFile)[1]
- outputFileObj = open(srcFile, 'w')
- while 1:
- autoData = inputFileObj.readline()
- if not autoData:
- break
- for replaced, replacement in replacements: # Harag's Replacement
- autoData = autoData.replace(replaced, replacement) # Harag's Replacement
- outputFileObj.write(autoData)
- # outputFileObj.flush() - Not really needed
- inputFileObj.close()
- outputFileObj.close()
- print "Last chance to back out here, the files will be modified past this point"
- res = raw_input('Press enter to continue.')
- if res != '':
- print 'This ' + res + ' was not valid, so I\'m stopping'
- sys.exit(2)
- # Read the files into memory, tehcnically only a single line at a time, so this can modify huge files
- # You checked for a case insensitive 'yes' in the variable autoSaves on line 116
- autoSaveProcessed = 0
- if autoSaves.lower() == 'yes':
- # We got asked to modify the saved games
- # NOTE: range(1,6) => [1, 2, 3, 4, 5]
- for autoGroup in range(1,6):
- autoData = None
- # Process 5 autosave files
- saveFileName = os.path.join(directory, 'Autosave-' + str(autoGroup) + '.rws')
- # The following check makes sure we don't double up on the work and
- # if there's a backup we overwrite it with the changed data, so things break
- if saveFileName in inputFileNames:
- inputFileNames.remove(saveFileName)
- if os.path.exists(saveFileName):
- processFile(saveFileName)
- autoSaveProcessed += 1
- else:
- print 'Can\'t find any autosave files:', saveFileName
- else:
- print 'Skipping autosaves'
- print 'Doing the main file(s) now'
- # So loop over the input file names and edit the files, by this time the files should still exist
- for i in inputFileNames:
- processFile(i)
- print str((len(inputFileNames) + autoSaveProcessed)) + ' files processed.'
- # Move the backups now that we finished.
- os.chdir(directory)
- if not os.path.isdir('backups'):
- os.mkdir('backups')
- for fName in glob.glob('*.bak'):
- shutil.move(fName, os.path.join('backups', fName))
- fd = os.path.join(directory, 'backups')
- for f in os.listdir('backups'):
- if not f.startswith('.'):
- os.rename(os.path.join(fd, f), os.path.join(fd, f.replace('.bak', '')))
- print 'Backups have been moved into their own folder now.'
- print '\n\n' + finalMsgSuccess
- raw_input('> ')
Add Comment
Please, Sign In to add comment