def __init__(self, parentFrame): """ Put this into the parent frame """ pass self.tkListbox = tk.Listbox(parentFrame, selectmode=tk.SINGLE) self.tkListbox.grid(column=1, row=1, columnspan=3) self.settings = {} self.vars = {} filename = os.path.join( favouriteServersFilesFolder, 'favouriteServers' + favouriteServersFilesExtension) _text, error = readFile(filename) try: self.settings = json.loads(''.join(_text)) except BaseException: # No favourites file, create one self.settings = {'Descriptive name': ('Server name', 'Password')} _text = json.dumps(self.settings, sort_keys=True, indent=4) writeFile(filename, _text) for descriptiveName, address in self.settings.items(): if descriptiveName != 'Descriptive name': # that's just a comment in the data file self.tkListbox.insert(tk.END, descriptiveName) #player_count,max_players,password_protected = getServerInfo(address[0], retries=1) pass self.tkListbox.activate(1) if _main: # Double click selects the server self.tkListbox.bind("<Double-Button-1>", self.ok)
def test_run_ModMgr(self): """ Minimal test that ModMgr runs """ ModMgr = os.path.join(rF2root, r'Bin32\ModMgr.exe') temporaryFile = 'temporaryFile' car = vehicle(r"SuperCharged_Miata_Level1\1.32\SPCL1Miata_car.mas") cmd = F'"{ModMgr}" -q -l"{car}"'.format() \ + F' 2>&1 {temporaryFile} > nul 2>&1'.format() # Put the command in a temp batch file and it works bat = os.path.join(os.getcwd(), 'x.bat') writeFile(bat, cmd) retcode, rsp = executeCmd(bat) assert retcode == 0, retcode text, __error = readFile(temporaryFile) assert text != '' os.remove(bat) # tidy up os.remove(temporaryFile) # But executing ModMgr directly doesn't work (it used to!) retcode, rsp = executeCmd(cmd) assert retcode == 0, retcode assert rsp == b'' try: os.remove(temporaryFile) assert True, F"Didn't expect {temporaryFile} to have been created".format( ) except BaseException: pass # no file created, this confirmatory test passed. pass
def changeCar(vehPath=r'Norma_M30-LMP3_2017\1.51', vehName='NORMAM30_08'): if vehName == '': return "VehFile not in rFactory's car data file.\nPlease edit entry" # if vehPath is for example Installed\vehicles\Norma_M30-LMP3_2017\1.50 # check for Installed\vehicles\Norma_M30-LMP3_2017\1.51 # which is an update. We have to use that. try: _vehFile = os.path.join(rF2root, vehPath) _vehPath, __ = os.path.split(_vehFile) _versions = getListOfFiles(_vehPath, '*.*') _vehPath = _versions[-1][0] except BaseException: return "Data file error '%s'" % _vehFile _vehFile = os.path.join(_vehPath, vehName).replace( '\\', '\\\\\\\\') # +'.veh' no longer required allTracks = os.path.join(rF2root, r'UserData\player\All Tracks & Cars.cch') _text3, error = readFile(allTracks) _edit3 = [r'( *SinglePlayerVehicle *=).*', r'\1"' + _vehFile + '"'] _edit5 = [r'( *SinglePlayerFilter *=).*', r'\1""'] # blank it _edited = __edit(_text3, [_edit3, _edit5], doubleSlash=False) writeFile(allTracks, _edited) return 'OK'
def parse(mod_file): """ # Created by rFactoryModManager Name=text Vehicle=1975EMBASSY Vehicle=1975LOTUS Vehicle=1975MAKI Vehicle=1975FERRARI Vehicle=1975HESKETH Location=2013_INDIA Location=2013_Interlagos Location=2013_HUNGARORING Location=2013_KOREA """ modSelection = dict() modSelection['cars'] = list() modSelection['tracks'] = list() text, error = readFile(mod_file) for line in text: if line.startswith('Vehicle'): modSelection['cars'].append(line.split('=')[1].strip()) if line.startswith('Location'): modSelection['tracks'].append(line.split('=')[1].strip()) return modSelection
def mas_file(self, mas, _filename, tags, keywords): """ Extract file from mas file and add any keywords to tags """ if not mas + '\n' in self.unusable_mas_files: cmd = '"' + self.ModMgr + '" -q -x"%s" "%s" > nul 2>&1' \ % (mas, _filename) retcode, rsp = executeCmdInBatchFile(cmd) lines, error = readFile(_filename) for line in lines: line = line.strip() for kw in keywords: if line.startswith(f'{kw}'): _val = re.split('[= /\t]+', line)[1].strip() # Hacking to write tyre names to a file if '.tbc' in _filename: _filepath = "c:/temp/rf2_tyres.txt" with open(_filepath, "a") as f: f.writelines([ 'MAS file: %s Tyre name: %s\n' % (mas, line) ]) tags[kw] = _val try: os.remove(_filename) # delete extracted file except BaseException: self.unusable_mas_files.append(mas + '\n') writeFile(unusableMasFilesFile, self.unusable_mas_files) print('Failed to extract %s from %s' % (_filename, mas)) else: pass # Already identified as encrypted return tags
def changeOpponents(opponents="|1971|AC_427_1954_Endurance|DPi"): allTracks = os.path.join(rF2root, r'UserData\player\All Tracks & Cars.cch') _text3, error = readFile(allTracks) _edit3 = [r'( *SinglePlayerFilter *=).*', r'\1"' + opponents + '"'] _edited = __edit(_text3, [_edit3], doubleSlash=False) writeFile(allTracks, _edited) return 'OK'
def mas_file(self, mas, _filename, tags, keywords): """ Extract file from mas file and add any keywords to tags """ if not mas + '\n' in self.unusable_mas_files: cmd = '"' + self.ModMgr + '" -q -x"%s" "%s" > nul 2>&1' \ % (mas, _filename) retcode, rsp = executeCmdInBatchFile(cmd) lines, error = readFile(_filename) for line in lines: line = line.strip() for kw in keywords: if line.startswith(f'{kw}'): _val = re.split('[= /\t]+', line)[1].strip() # tbd: Hacking to get an idea of tyre names: Not really tested if kw in tags: kw = kw + _val tags[kw] = _val try: os.remove(_filename) # delete extracted file except BaseException: self.unusable_mas_files.append(mas + '\n') writeFile(unusableMasFilesFile, self.unusable_mas_files) print('Failed to extract %s from %s' % (_filename, mas)) else: pass # Already identified as encrypted return tags
def readCar(): allTracks = os.path.join(rF2root, r'UserData\player\All Tracks & Cars.cch') _strip = 'SinglePlayerVehicle=%s' % os.path.normpath( os.path.join(rF2root, r'Installed\Vehicles')) _lines, error = readFile(allTracks) for line in _lines: if 'SinglePlayerVehicle' in line: car = line[len(_strip) + 2:-2] break return car
def _get_mft_tags(self, mft): """ Get the tags from the MFT file """ text, error = readFile(mft) _tags = getTags(text) for requiredTag in [ 'Name', 'Version', 'Type', 'Author', 'Origin', 'Category', 'ID', 'URL', 'Desc', 'Date', 'Flags', 'RefCount', '#Signature', '#MASFile', 'MinVersion', '#BaseSignature' ]: # MASFile, Signature and BaseSignature filtered out if requiredTag in _tags: """filter out boilerplate Author=Mod Team URL=www.YourModSite.com Desc=Your new mod. """ if _tags[requiredTag] in [ 'Mod Team', 'www.YourModSite.com', 'Your new mod.' ]: _tags[requiredTag] = '' #print('%s=%s' % (requiredTag, _tags[requiredTag])) if requiredTag == 'Name': _tags['strippedName'] = cleanTrackName(_tags['Name']) _tags['Year'], _tags['Decade'], _tags[ 'strippedName'] = extractYear(_tags['strippedName']) # Title Case The Name _tags['strippedName'] = _tags['strippedName'].title() # We need the original data folder to assemble the .SCN file path to put in # "Player.JSON" to force rF2 to switch tracks. We also need the .SCN # file names and that's a bit more difficult. # To select the track we also need the "Scene Description" _tags['originalFolder'], _ = os.path.split( mft[len(rF2root) + 1:]) # strip the root if 'Scene Description' not in _tags or _tags[ 'Scene Description'] == '': # if scn file name is available in scnNames.txt use it scnNames = getVehScnNames('scnNames.txt') if 'Name' in _tags and _tags['Name'] in scnNames: _tags['Scene Description'] = scnNames[_tags['Name']] else: _tags['Name'] = 'No track name' if 'Category' in _tags and _tags['Category'] in trackCategories: _tags['tType'] = trackCategories[_tags['Category']] tag = 'Track Name' if 'strippedName' in _tags: val = _tags['strippedName'].replace('_', ' ').strip() # default _tags[tag] = val else: _tags[tag] = 'No track name' return _tags
def __init__(self): self.all_vehicles_ini = os.path.join(playerPath, 'all_vehicles.ini') all_vehicles_text, error = readFile(self.all_vehicles_ini) for line in all_vehicles_text: if line.startswith('File='): _path, _veh = os.path.split(line[len('File="'):]) _path, _rev = os.path.split(_path) _path, _car = os.path.split(_path) if _car not in self.vehDict: # lose the trailing " self.vehDict[_car] = _veh.strip()[:-1]
def openDefaultScenario(): global filename filename = os.path.join(scenarioFilesFolder, 'lastScenario' + scenarioFilesExtension) _text, error = readFile(filename) if os.path.exists(filename): settings = json.loads(''.join(_text)) print(settings) _tso = TabSettings() _tso.setAllSettings(settings) return
def readOpponents(): allTracks = os.path.join(rF2root, r'UserData\player\All Tracks & Cars.cch') _strip = 'SinglePlayerFilter=%s' % os.path.normpath( os.path.join(rF2root, r'Installed\Vehicles')) _lines, error = readFile(allTracks) for line in _lines: if 'SinglePlayerFilter' in line: opponents = line[len(_strip) + 2:-2] _o = opponents.split('|') opponents = ' '.join(_o) break return opponents
def dir_files_in_single_mas_file(self, mas): files = list() if not mas + '\n' in self.unusable_mas_files: temporaryFile = os.path.join(r'c:\temp', 'temporaryFile') cmd = F'"{self.ModMgr}" -q -l"{mas}" 2>&1 {temporaryFile} > nul 2>&1'.format( ) executeCmdInBatchFile(cmd) files, error = readFile(temporaryFile) try: os.remove(temporaryFile) except BaseException: pass # temp file wasn't created return files
def getVehScnNames(dataFilepath): """ Read the data file containing Name xxxxx.veh pairs Also for xxxxx.scn pairs """ _dict = {} text, error = readFile(dataFilepath) for line in text: if line.startswith('#'): continue # comment line _split = line.split() if len(_split) == 2: name, vehScn = _split _dict[name] = vehScn return _dict
def _get_mft_tags(self, mft): """ Get the tags from the MFT file """ text, error = readFile(mft) if error: return dict() _tags = getTags(text) for requiredTag in [ 'Name', 'Version', 'Type', 'Author', 'Origin', 'Category', 'ID', 'URL', 'Desc', 'Date', 'Flags', 'RefCount', '#Signature', '#MASFile', 'MinVersion', '#BaseSignature' ]: # MASFile, Signature and BaseSignature filtered out - NO THEY AREN'T, # _tags[] still contains them. tagsToBeWritten filters them out. # Not sure what this for loop is, er, for. if requiredTag in _tags: """filter out boilerplate Author=Mod Team URL=www.YourModSite.com Desc=Your new mod. """ if _tags[requiredTag] in [ 'Mod Team', 'www.YourModSite.com', 'Your new mod.' ]: _tags[requiredTag] = '' if _tags[requiredTag] in [ 'Slow Motion', 'Slow Motion Modding Group' ]: # make up your minds boys! _tags[requiredTag] = 'Slow Motion Group' if _tags[requiredTag] in ['Virtua_LM Modding Team' ]: # make up your minds boys! _tags[requiredTag] = 'Virtua_LM' if _tags['Category'] in carCategories: _tags['tType'] = carCategories[_tags['Category']] # We need the original data folder to assemble the .VEH file path to put in # "All Tracks & Cars.cch" to force rF2 to switch cars. We also need the .VEH # file names and that's a bit more difficult. # Not difficult, they're in all_vehicles.ini _tags['originalFolder'], _ = os.path.split(mft[len(rF2root) + 1:]) # strip the root # if veh file name is available in vehNames.txt use it _tags['vehFile'] = self.vehNames.veh(_tags['Name']) _tags = parse_name(_tags) _tags = parse_mfr_model(_tags) return _tags
def openScenario(): global filename print('openScenario') #root = tk.Tk() filename = filedialog.askopenfilename( initialdir=scenarioFilesFolder, title="Select file", filetypes=(("rFactory Scenario files", "*%s" % scenarioFilesExtension), ("all files", "*.*")) ) _text, error = readFile(filename) settings = json.loads(''.join(_text)) print(settings) _tso = TabSettings() _tso.setAllSettings(settings)
def changeTrack(scnPath=r'F1_1988_Tracks\0.941', scnName='HOCKENHEIM_1988_C4', SceneDescription='HOCKENHEIM_1988_C4'): if scnName == '': return "Scene Description for %s not in rFactory's track data file.\nPlease edit entry" % scnPath _scnFile = os.path.join(rF2root, scnPath, scnName + '.scn').replace('\\', '\\\\\\\\') PlayerJSON = os.path.join(rF2root, r'UserData\player\Player.JSON') _text4, error = readFile(PlayerJSON) _edit4 = [r'( *"Scene File" *:).*', '\\1"' + _scnFile + '",'] _edit5 = [r'( *"AI Database File" *:).*', r'\1"",'] # blank it _edit6 = [r'( *"Scene Description" *:).*', r'\1"%s",' % SceneDescription] _edit7 = [r'( *"Scene Signature" *:).*', r'\1""'] # blank it NOTE NO COMMA _edited = __edit(_text4, [_edit4, _edit5, _edit6, _edit7], doubleSlash=True) writeFile(PlayerJSON, _edited) return 'OK'
class DataFiles: installed_folder = None datafiles_folder = None mfts_and_timestamps = None data_files_and_timestamps = None newer_mfts = None newFiles = list() _tags = dict() cache_o = None unusable_mas_files, error = readFile(unusableMasFilesFile) if error: unusable_mas_files = list() ModMgr = os.path.join(rF2root, r'Bin32\ModMgr.exe') def __getitem__(self, key): return self._tags[key] def __setitem__(self, key, value): """ Only set tag if it does not already have a value """ if type(value) != str: raise TypeError("tag must be string") if key not in self._tags or self._tags[key] == '': self._tags[key] = value def make_datafile_name(self, folder): r""" e.g. c:\Program Files (x86)\Steam\steamapps\common\rFactor 2\Installed\Vehicles\USF2000_2016\1.94\USF2000_2016.mft to dataFiles\Cars\USF2000_2016.rFactory.txt """ _mft = os.path.basename(folder).split('.')[0] if 'vehicles' in folder.lower(): _res = f'datafiles\\cars\\{_mft}.rfactory.txt'.format() else: _res = f'datafiles\\tracks\\{_mft}.rfactory.txt'.format() return _res def find_single_mod_folders(self): """ Find ALL folders with .MFT files then subtract multi-mod folders Looks like none of the multifold rF2 installed_folder: 'vehicles' or 'locations' """ rF2_dir = os.path.join(rF2root, 'Installed') all_mfts = getListOfFiles(os.path.join(rF2_dir, self.installed_folder), pattern='*.mft', recurse=True) self.multis, multi_mfts = self.find_multi_mod_folders() # all_mfts, list of folder, mft tuples # self.multis, list of folders # multi_mfts, list of folder, mft tuples for mmft in multi_mfts: for i, mft in enumerate(all_mfts): if mft[1] == mmft[1]: del all_mfts[i] return all_mfts def find_multi_mod_folders(self): """ Some mods contain many mas files in a folder, e.g. F1_1988_Tracks Try to spot them by checking the number of mas files in a revision folder. Mod folder structure is <mod name>\<revision>\*.mas The REAL test is to look for more than one .SCN file for tracks and .VEH files for cars (also found in all_vehicles.ini) rF2 installed_folder: 'vehicles' or 'locations' """ rF2_dir = os.path.join(rF2root, 'Installed') _mods = getListOfFiles(os.path.join(rF2_dir, self.installed_folder), pattern='*', recurse=False) multi_mas = list() multi_mfts = list() for _mod_folder, _mod in _mods: _revs = getListOfFiles(_mod_folder, pattern='*', recurse=False) for _rev in _revs: _mas_files = getListOfFiles(_rev[0], pattern='*.mas', recurse=True) if len(_mas_files) > 10: multi_mas.append(_mod) _mft_files = getListOfFiles(_rev[0], pattern='*.mft', recurse=True) multi_mfts += _mft_files pass return multi_mas, multi_mfts def get_mfts_and_timestamps(self): """ rF2 installed_folder: 'vehicles' or 'locations' """ rF2_dir = os.path.join(rF2root, 'Installed') _mft_files = getListOfFiles(os.path.join(rF2_dir, self.installed_folder), pattern='*.mft', recurse=True) self.mfts_and_timestamps = dict() for folder in _mft_files: _folder = folder[0].lower() # os.path.dirname( _timestamp = os.path.getmtime(_folder) self.mfts_and_timestamps[_folder] = _timestamp return self.mfts_and_timestamps def get_data_files_and_timestamps(self): """ rFactory datafiles_folder: 'CarDatafilesFolder' or 'TrackDatafilesFolder' """ _mft_files = getListOfFiles(self.datafiles_folder, pattern='*.txt', recurse=False) self.data_files_and_timestamps = dict() for folder in _mft_files: _timestamp = os.path.getmtime(folder[0]) self.data_files_and_timestamps[folder[0].lower()] = _timestamp return self.data_files_and_timestamps def get_newer_mfts(self): """ Get a list of MFT files that haven't been processed before or are a new version """ if not self.mfts_and_timestamps: self.get_mfts_and_timestamps() if not self.data_files_and_timestamps: self.get_data_files_and_timestamps() self.newer_mfts = list() for folder, timestamp in self.mfts_and_timestamps.items(): # nope, we need to make # c:\Users\tony_\source\repos\rFactory\dataFiles\Cars\USF2000_2016.rFactory.txt _datafile = self.make_datafile_name(folder) if _datafile in self.data_files_and_timestamps: if timestamp > self.data_files_and_timestamps[_datafile]: self.newer_mfts.append(folder) else: self.newer_mfts.append(folder) return self.newer_mfts def dir_files_in_mas_files(self, folder): """ Dict of mas files and the files they contain """ masFiles = getListOfFiles(folder, '*.mas') _pop = os.getcwd() # save current directory files = dict() if masFiles: os.chdir(os.path.dirname(masFiles[0][0])) for mas in masFiles: # We need to record mas file name as well files[mas[1]] = self.dir_files_in_single_mas_file(mas[1]) os.chdir(_pop) return files def dir_files_in_single_mas_file(self, mas): files = list() if not mas + '\n' in self.unusable_mas_files: temporaryFile = os.path.join(r'c:\temp', 'temporaryFile') cmd = F'"{self.ModMgr}" -q -l"{mas}" 2>&1 {temporaryFile} > nul 2>&1'.format( ) executeCmdInBatchFile(cmd) files, error = readFile(temporaryFile) try: os.remove(temporaryFile) except BaseException: pass # temp file wasn't created return files def mas_file(self, mas, _filename, tags, keywords): """ Extract file from mas file and add any keywords to tags """ if not mas + '\n' in self.unusable_mas_files: cmd = '"' + self.ModMgr + '" -q -x"%s" "%s" > nul 2>&1' \ % (mas, _filename) retcode, rsp = executeCmdInBatchFile(cmd) lines, error = readFile(_filename) for line in lines: line = line.strip() for kw in keywords: if line.startswith(f'{kw}'): _val = re.split('[= /\t]+', line)[1].strip() # Hacking to write tyre names to a file if '.tbc' in _filename: _filepath = "c:/temp/rf2_tyres.txt" with open(_filepath, "a") as f: f.writelines([ 'MAS file: %s Tyre name: %s\n' % (mas, line) ]) tags[kw] = _val try: os.remove(_filename) # delete extracted file except BaseException: self.unusable_mas_files.append(mas + '\n') writeFile(unusableMasFilesFile, self.unusable_mas_files) print('Failed to extract %s from %s' % (_filename, mas)) else: pass # Already identified as encrypted return tags def new_data(self, _mft, new_cache=False): """ Create new rFactory data entry in the spreadsheet new_cache=False: First check if there is cached data in the spreadsheet Read the tags in the .MFT file Read the tags in a set of files in .mas files Return The tags If it was a new entry """ cache_write = False _mft_tags = self._get_mft_tags(_mft) # Get the name cached_tag_name = _mft_tags['Name'] if 'Date' in _mft_tags: _mft_tags['Date'] = translate_date(_mft_tags['Date']) else: _mft_tags['Date'] = '' if new_cache: cached_tags = dict() else: cached_tags = self.cache_o.get_values(cached_tag_name) if not cached_tags: # Newly-installed mod cache_write = True for _tag, _val in _mft_tags.items(): cached_tags[_tag] = _val cached_tags['Rating'] = '***' # Default cached_tags = self.read_mas_files(cached_tags, os.path.dirname(_mft)) for tag, val in cached_tags.items(): self.cache_o.set_value(cached_tag_name, tag, val) for tag, val in _mft_tags.items(): self.cache_o.set_value(cached_tag_name, tag, val) for _tag in ['Desc', 'Name', 'strippedName']: if _tag in _mft_tags: cached_tags[_tag] = _mft_tags[_tag] else: cached_tags[_tag] = '' return cached_tags, cache_write def multi_mod(self, folder): """ Multiple mods in one folder with a single MFT file Generator function, returns one mod each time Generator version broke when run in VS debugger, OK when run as Python file or exe for _tags, cache_write in tdf.multi_mod(folder): """ rF2_dir = os.path.join(rF2root, 'Installed') mft_files = getListOfFiles(os.path.join(rF2_dir, self.installed_folder, folder), pattern='*.mft', recurse=True) mas_files = getListOfFiles(os.path.join(rF2_dir, self.installed_folder, folder), pattern='*.mas', recurse=True) results = list() for _mod in mas_files: cache_write = False _mft_tags = self._get_mft_tags(mft_files[0][0]) # Get the name if 'Date' in _mft_tags: _mft_tags['Date'] = translate_date(_mft_tags['Date']) else: _mft_tags['Date'] = '' _mft_tags['Name'] = _mod[1][:-4] cached_tag_name = _mft_tags['Name'] cached_tags = self.cache_o.get_values(cached_tag_name) if not cached_tags: # Newly-installed mod files = self.dir_files_in_single_mas_file(_mod[0]) if 'Track Name' in _mft_tags: del _mft_tags['Track Name'] for _tag, _val in _mft_tags.items(): cached_tags[_tag] = _val cached_tags['Rating'] = '***' # Default cached_tags, cache_write = self._read_mas_file( cached_tags, _mod[0], files) if cache_write: cached_tags['strippedName'] = cached_tags['Name'] cached_tags = parse_name(cached_tags) cached_tags = parse_mfr_model(cached_tags) for tag, val in cached_tags.items(): self.cache_o.set_value(cached_tag_name, tag, val) if 'Latitude' in cached_tags: # It's a track tag = 'Track Name' val = cached_tags['strippedName'].replace('_', ' ').strip() cached_tags[tag] = val self.cache_o.set_value(cached_tag_name, tag, val) else: if not _mod[0] + '\n' in self.unusable_mas_files: self.unusable_mas_files.append(_mod[0] + '\n') writeFile(unusableMasFilesFile, self.unusable_mas_files) if cache_write: for tag, val in _mft_tags.items(): self.cache_o.set_value(cached_tag_name, tag, val) for _tag in []: # ['Desc', 'Name', 'strippedName']: if _tag in _mft_tags: cached_tags[_tag] = _mft_tags[_tag] results.append([cached_tags, cache_write]) return results def cache_write(self): """ Write any new data to the spreadsheet """ self.cache_o.write() def get_tags(self): self.cache_o.l def read_mas_files(self, tags, mas_dir): return dict() # Pylint - it's defined in subclass def _read_mas_file(self, tags, mas, files): return dict() # Pylint - it's defined in subclass def _get_mft_tags(self, mft): return dict() # Pylint - it's defined in subclass '''
_text1 = '"AI Database File":"C:\\Program Files (x86)\\Steam\\steamapps\\common\\rFactor 2\\Installed\\Locations\\Road America 2016\\1.4\\RA2016.AIW",\n' _edit1 = [r'( *"AI Database File" *:).*', r'\1"FRED"'] _edited = __edit([_text1], [_edit1], doubleSlash=True) assert _edited[0] == '"AI Database File":"FRED"\n' _text2 = r'SinglePlayerVehicle="%ProgramFiles(x86)%\Steam\steamapps\common\rFactor 2\Installed\Vehicles\Porsche_991RSR_GTE_2017\1.49\991RSR_911.VEH"\n' _edit2 = [r'( *SinglePlayerVehicle *=).*', r'\1"\\rF2\CHARLIE"'] _edited = __edit([_text1, _text2], [_edit1, _edit2], doubleSlash=False) assert _edited[0] == '"AI Database File":"FRED"\n' assert _edited[1] == 'SinglePlayerVehicle="\\rF2\\CHARLIE"\n' _allTracks = os.path.join(rF2root, r'UserData\player\All Tracks & Cars.cch') _text3, error = readFile(_allTracks) # NOTE THE \\ BEFORE rFactor _edit3 = [ r'( *SinglePlayerVehicle *=).*', r'\1"' + os.path.join( rF2root, r'Installed\Vehicles\Oreca_07_LMP2_2017\1.41\ORECA07PREE6ED8B36.VEH"' ).replace('\\', '\\\\') ] _edit3 = [ r'( *SinglePlayerVehicle *=).*', r'\1"' + os.path.join( rF2root, r'Installed\Vehicles\Norma_M30-LMP3_2017\1.51\NORMAM30_08.VEH"'). replace('\\', '\\\\') ] #_edit3 = [r'( *SinglePlayerVehicle *=).*', r'\1' '"%ProgramFiles(x86)%\Steam\steamapps\common\\rFactor 2\Installed\Vehicles\Oreca_07_LMP2_2017\1.41\ORECA07PREE6ED8B36.VEH"']
} scenarioFilesFolder = 'Datafiles/scenarioFiles' scenarioFilesExtension = '.rFactoryScenarioJSON' favouriteServersFilesFolder = 'Datafiles/favourites' favouriteServersFilesExtension = '.JSON' rFactoryConfigFileFolder = 'Datafiles/favourites' rFactoryConfigFileExtension = '.JSON' # Editable items in config file config_filename = os.path.join(rFactoryConfigFileFolder, 'rFactoryConfig' + rFactoryConfigFileExtension) _text, error = readFile(config_filename) try: config = json.loads(''.join(_text)) except BaseException: # No rFactoryConfig file, create one config = new_config_file() # rF2 items rF2root = os.path.normpath( os.path.expandvars(getKey(config_filename, 'rF2root'))) SteamExe = os.path.normpath( os.path.expandvars(getKey(config_filename, 'SteamExe'))) DiscordExe = os.path.normpath( os.path.expandvars(getKey(config_filename, 'DiscordExe'))) DiscordCmd = DiscordExe + ' ' + getKey(config_filename, 'DiscordArgs') CrewChiefExe = os.path.normpath( os.path.expandvars(getKey(config_filename, 'CrewChiefExe')))