def find_steam_info(game_dir): """Determine the steam ID and game name of this folder, if it has one. This only works on Source games! """ game_id = None name = None found_name = False found_id = False for folder in os.listdir(game_dir): info_path = os.path.join(game_dir, folder, 'gameinfo.txt') if os.path.isfile(info_path): with open(info_path) as file: for line in file: clean_line = srctools.clean_line(line).replace('\t', ' ') if not found_id and 'steamappid' in clean_line.casefold(): raw_id = clean_line.casefold().replace( 'steamappid', '').strip() if raw_id.isdigit(): game_id = raw_id elif not found_name and 'game ' in clean_line.casefold(): found_name = True ind = clean_line.casefold().rfind('game') + 4 name = clean_line[ind:].strip().strip('"') if found_name and found_id: break if found_name and found_id: break return game_id, name
def find_steam_info(game_dir): """Determine the steam ID and game name of this folder, if it has one. This only works on Source games! """ game_id = None name = None found_name = False found_id = False for folder in os.listdir(game_dir): info_path = os.path.join(game_dir, folder, "gameinfo.txt") if os.path.isfile(info_path): with open(info_path) as file: for line in file: clean_line = srctools.clean_line(line).replace("\t", " ") if not found_id and "steamappid" in clean_line.casefold(): raw_id = clean_line.casefold().replace("steamappid", "").strip() if raw_id.isdigit(): game_id = raw_id elif not found_name and "game " in clean_line.casefold(): found_name = True ind = clean_line.casefold().rfind("game") + 4 name = clean_line[ind:].strip().strip('"') if found_name and found_id: break if found_name and found_id: break return game_id, name
def edit_gameinfo(self, add_line=False) -> None: """Modify all gameinfo.txt files to add or remove our line. Add_line determines if we are adding or removing it. """ for folder in self.dlc_priority(): info_path = os.path.join(self.root, folder, 'gameinfo.txt') if os.path.isfile(info_path): with open(info_path, encoding='utf8') as file: data = list(file) for line_num, line in reversed(list(enumerate(data))): clean_line = srctools.clean_line(line) if add_line: if clean_line == GAMEINFO_LINE: break # Already added! elif '|gameinfo_path|' in clean_line: LOGGER.debug( "Adding gameinfo hook to {}", info_path, ) # Match the line's indentation data.insert( line_num + 1, utils.get_indent(line) + GAMEINFO_LINE + '\n', ) break else: if clean_line == GAMEINFO_LINE: LOGGER.debug("Removing gameinfo hook from {}", info_path) data.pop(line_num) break else: if add_line: LOGGER.warning( 'Failed editing "{}" to add our special folder!', info_path, ) continue with srctools.AtomicWriter(info_path) as file: for line in data: file.write(line) if not add_line: # Restore the original files! for name, file, ext in FILES_TO_BACKUP: item_path = self.abs_path(file + ext) backup_path = self.abs_path(file + '_original' + ext) old_version = self.abs_path(file + '_styles' + ext) if os.path.isfile(old_version): LOGGER.info('Restoring Stylechanger version of "{}"!', name) shutil.copy(old_version, item_path) elif os.path.isfile(backup_path): LOGGER.info('Restoring original "{}"!', name) shutil.move(backup_path, item_path) self.clear_cache()
def edit_gameinfo(self, add_line=False): """Modify all gameinfo.txt files to add or remove our line. Add_line determines if we are adding or removing it. """ for folder in self.dlc_priority(): info_path = os.path.join(self.root, folder, "gameinfo.txt") if os.path.isfile(info_path): with open(info_path) as file: data = list(file) for line_num, line in reversed(list(enumerate(data))): clean_line = srctools.clean_line(line) if add_line: if clean_line == GAMEINFO_LINE: break # Already added! elif "|gameinfo_path|" in clean_line: LOGGER.debug("Adding gameinfo hook to {}", info_path) # Match the line's indentation data.insert(line_num + 1, utils.get_indent(line) + GAMEINFO_LINE + "\n") break else: if clean_line == GAMEINFO_LINE: LOGGER.debug("Removing gameinfo hook from {}", info_path) data.pop(line_num) break else: if add_line: LOGGER.warning('Failed editing "{}" to add our special folder!', info_path) continue with srctools.AtomicWriter(info_path) as file: for line in data: file.write(line) if not add_line: # Restore the original files! for name, file, ext in FILES_TO_BACKUP: item_path = self.abs_path(file + ext) backup_path = self.abs_path(file + "_original" + ext) old_version = self.abs_path(file + "_styles" + ext) if os.path.isfile(old_version): LOGGER.info('Restoring Stylechanger version of "{}"!', name) shutil.copy(old_version, item_path) elif os.path.isfile(backup_path): LOGGER.info('Restoring original "{}"!', name) shutil.move(backup_path, item_path) self.clear_cache()
def parse_legacy(posfile, propfile, path): """Parse the original BEE2.2 palette format.""" props = Property.parse(propfile, path + ':properties.txt') name = props['name', 'Unnamed'] pos = [] for dirty_line in posfile: line = srctools.clean_line(dirty_line) if line: # Lines follow the form # "ITEM_BUTTON_FLOOR", 2 # for subtype 3 of the button if line.startswith('"'): val = line.split('",') if len(val) == 2: pos.append(( val[0][1:], # Item ID int(val[1].strip()), # Item subtype )) else: LOGGER.warning('Malformed row "{}"!', line) return None return Palette(name, pos)
def parse(cls, data: ParseData) -> 'PackList': """Read pack lists from packages.""" filesystem = data.fsys conf = data.info.find_key('Config', '') if 'AddIfMat' in data.info: LOGGER.warning( '{}:{}: AddIfMat is no ' 'longer used.', data.pak_id, data.id, ) files = [] if conf.has_children(): # Allow having a child block to define packlists inline files = [prop.value for prop in conf] elif conf.value: path = 'pack/' + conf.value + '.cfg' with filesystem, filesystem.open_str(path) as f: # Each line is a file to pack. # Skip blank lines, strip whitespace, and # allow // comments. for line in f: line = srctools.clean_line(line) if line: files.append(line) # Deprecated old option. for prop in data.info.find_all('AddIfMat'): files.append('materials/' + prop.value + '.vmt') if not files: raise ValueError('"{}" has no files to pack!'.format(data.id)) if CHECK_PACKFILE_CORRECTNESS: # Use normpath so sep differences are ignored, plus case. resources = { os.path.normpath(file.path).casefold() for file in filesystem.walk_folder('resources/') } for file in files: if file.startswith(('-#', 'precache_sound:')): # Used to disable stock soundscripts, and precache sounds # Not to pack - ignore. continue file = file.lstrip( '#') # This means to put in soundscript too... # Check to make sure the files exist... file = os.path.join('resources', os.path.normpath(file)).casefold() if file not in resources: LOGGER.warning( 'Warning: "{file}" not in zip! ({pak_id})', file=file, pak_id=data.pak_id, ) return cls(data.id, files)