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 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 __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 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 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 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 saveScenario(): global filename print('saveScenario') _tso = TabSettings() _ = _tso.getAllSettings() _text = json.dumps(settings, sort_keys=True, indent=4) writeFile(filename, _text)
def saveDefaultScenario(): global filename filename = os.path.join(scenarioFilesFolder, 'lastScenario' + scenarioFilesExtension) _tso = TabSettings() _ = _tso.getAllSettings() _text = json.dumps(settings, sort_keys=True, indent=4) writeFile(filename, _text)
def test_executeCmd(self): test_text = 'Hello world\n' bat = os.path.join(os.getcwd(), 'x.bat') writeFile(bat, '@echo ' + test_text) cmd = bat retcode, rpt = executeCmd(cmd) os.remove(bat) assert retcode == 0, retcode assert rpt.strip() == bytearray(test_text, 'utf8').strip(), rpt pass
def createFile(self): """ The Create File button pressed """ modSelection = tabs.o_tabs['Mod Selection'].getSettings() car_list = [] for _car in modSelection['cars']: car_list.append('Vehicle=' + _car + '\n') car_list = list(set(car_list)) # dedupe the list (in case) print(car_list) track_list = [] for _track in modSelection['tracks']: track_list.append('Location=' + _track + '\n') # dedupe the list (e.g. F1_1988_Tracks) track_list = list(set(track_list)) print(track_list) if car_list == []: messagebox.askokcancel( 'Error', 'No vehicles selected') return if track_list == []: messagebox.askokcancel( 'Error', 'No tracks selected') return _filepath = filedialog.asksaveasfilename( title='Save ModMaker file as...', initialdir=modMakerFilesFolder, initialfile=self.tkStrVarModMakerFile.get(), defaultextension='.txt', filetypes=[('Modmaker files', 'txt')]) if not _filepath: return self.modmaker_file = _filepath self.tkStrVarModMakerFile.set(os.path.basename(_filepath)) # May have more than one .ext # e.g.sample.modfile.txt name = 'Name=%s\n\n' % os.path.basename(_filepath).split('.')[0] text = ['# Created by rFactoryModManager\n\n'] text.append(name) text.append(F'rf2dir={rF2root}\n'.format()) text.append(F'SteamCmd={SteamExe}\n\n'.format()) text += car_list text.append('\n') text += track_list writeFile(_filepath, text) messagebox.askokcancel( 'File %s written' % _filepath, '%s' % text)
def new_config_file(): """ Make sure we have a fresh config by deleting any existing one """ os.remove(config_filename) config = { # rF2 items '# %ProgramFiles(x86)% will be expanded to your Windows setting but you can write it explicitly if you want': "", '# Same for %LOCALAPPDATA%': "", '# Use / not backslash': "", 'rF2root': '%ProgramFiles(x86)%/Steam/steamapps/common/rFactor 2', 'SteamExe': "%ProgramFiles(x86)%/Steam/steam.exe", 'SteamDelaySeconds': 10, '#SteamDelaySeconds: How long it takes Steam to start up before we can start rF2': "", # 'DiscordExe' : '"%APPDATA%/Microsoft/Windows/Start Menu/Programs/Discord Inc/Discord.lnk"', # '#DiscordExe: had to use short cut as the command wouldn\'t work' : '', 'DiscordExe': '%LOCALAPPDATA%/Discord/Update.exe', 'DiscordArgs': '--processStart Discord.exe', 'CrewChiefExe': "%ProgramFiles(x86)%/Britton IT Ltd/CrewChiefV4/CrewChiefV4.exe", 'CrewChiefArgs': 'RF2_64BIT', 'VolumeControlExe': "%ProgramFiles(x86)%/VolumeControl/VolumeControl.exe", 'TeamSpeakExe': "%ProgramFiles(x86)%/TeamSpeak 3 Client/ts3client_win64.exe", '#MyPreCommand: use this call a program or batch file before rF2 runs': "", 'MyPreCommand': '', 'MyPreCommandArgs': '', '#MyPostCommand: use this call a program or batch file after rF2 runs': "", 'MyPostCommand': '', 'MyPostCommandArgs': '', 'UserData player': 'player' } _text = json.dumps(config, sort_keys=True, indent=4) writeFile(config_filename, _text) return config
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'
_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"'] _edited = __edit(_text3, [_edit3], doubleSlash=False) writeFile(_allTracks, _edited) PlayerJSON = os.path.join(rF2root, r'UserData\player\Player.JSON') _text4, error = readFile(PlayerJSON) # NOTE THE \\ BEFORE rFactor doubleSlashed_rF2root = r'C:\\Program Files (x86)\\Steam\\steamapps\\common\\rFactor 2' _edit4 = [ r'( *"Scene File" *:).*', '\\1"' + os.path.join( rF2root, r'Installed\Locations\F1_1988_Tracks\0.941\HOCKENHEIM_1988_C4.SCN",' ).replace('\\', '\\\\\\\\') ] # _edit4 = [r'( *"Scene File" *:).*', '\\1"' + # os.path.join(rF2root, # r'Installed\Locations\OULTON_PARK_CIRCUIT_2015\1.25\OULTONPARK_INT.SCN",').replace('\\', # '\\\\\\\\')]
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