Parsing CS: GO script file in Python

I am working with some script files from CS: GO, I need to get useful information from this file and import this data into my python application.

Here is an example txt data format:

https://steamcdn-a.akamaihd.net/apps/730/scripts/items/items_game.83a9ad4690388868ab33c627af730c43d4b0f0d9.txt

Values ​​are in arbitrary formats (Color \ Pos \ String), but I only need a string containing all the values. I need to get this information in a dictionary, for example:

print(global_dict['items_game']['game_info']['first_valid_class']) <<2 

Now I am working on a parser, but I had a lot of problems. Are there any ready-made solutions for this format?

+1
source share
2 answers

Here is a pyparsing based parser that will parse this format:

 from pyparsing import Suppress, QuotedString, Forward, Group, Dict, ZeroOrMore LBRACE,RBRACE = map(Suppress, "{}") qs = QuotedString('"') # forward-declare value, since this expression will be recursive # (will contain expressions which use contain value's) value = Forward() key_value = Group(qs + value) struct = LBRACE + Dict(ZeroOrMore(key_value)) + RBRACE # define content of value using <<= operator value <<= qs | struct # define top-level parser parser = Dict(key_value) 

Load the configuration into a line and call parser.parseString() :

 sample = open('cs_go_sample.txt').read() config = parser.parseString(sample) print config.keys() for k in config.items_game.keys(): print '-', k config.items_game.pprint() 

Print

 ['items_game'] - sticker_kits - client_loot_lists - prefabs - quest_definitions - alternate_icons2 - music_definitions - rarities - colors - campaign_definitions - player_loadout_slots - quest_schedule - item_levels - revolving_loot_lists - game_info - pro_players - recipes - items_game_live - paint_kits_rarity - paint_kits - qualities - items - attributes - item_sets - quest_reward_loot_lists - kill_eater_score_types [['game_info', ['first_valid_class', '2'], ['last_valid_class', '3'], ['first_valid_item_slot', '0'], ['last_valid_item_slot', '54'], ['num_item_presets', '4']], ['rarities', ['default', ['value', '0'], ... etc. ... 

EDIT

If you want integer values ​​to be converted to int during parsing, you can define the parsing action for this. But you want to attach this (I think) only to quoted strings, which are values, not those that are keys.

 # use this code to convert integer values to ints at parse time key_qs = qs.copy() value_qs = qs.copy() def convert_integers(tokens): if tokens[0].isdigit(): tokens[0] = int(tokens[0]) value_qs.setParseAction(convert_integers) value = Forward() key_value = Group(key_qs + value) struct = LBRACE + Dict(ZeroOrMore(key_value)) + RBRACE value <<= value_qs | struct parser = Dict(key_value) 

Now the output values ​​look like this:

 [['game_info', ['first_valid_class', 2], ['last_valid_class', 3], ['first_valid_item_slot', 0], ['last_valid_item_slot', 54], ['num_item_presets', 4]], ['rarities', ['default', ['value', 0], ['loc_key', 'Rarity_Default'], ['loc_key_weapon', 'Rarity_Default_Weapon'], 

Note that integer values ​​are no longer displayed as strings, but as valid Python ints.

+3
source

As CoryKramer noted, the file is almost JSON.

So, I wrote my own parser below, which parses the file, reading the source configuration line by line and writing the corrected JSON format to the output file.

I even tested the output using JSONLint , and the file passed the validation successfully.

Note. This code was written to analyze any of the files located in:

%STEAMINSTALL%/SteamApps/common/Counter-Strike Global Offensive/csgo/scripts


To use the following script, run:

  $ ConfigParser.py -h usage: ConfigParser.py [-h] [-s SRC] dest positional arguments: dest file where the parsed JSON will be written to optional arguments: -h, --help show this help message and exit -s SRC, --src SRC source config file 
 #!/usr/bin/env python3 """ConfigParser.py: Parses a Valve configuration file. The configuration file for the CS:GO game items is read line-by-line and written to an output file. The missing colons and commas are added to their appropriate places. The output file passed JSLint validation. """ from argparse import ArgumentParser from shlex import split __author__ = "Mr. Polywhirl" __copyright__ = "Copyright 2016, Stack Overflow" __credits__ = [] __license__ = "GPLv3" __version__ = "1.1.0" __maintainer__ = "Mr. Polywhirl" __email__ = "https://stackoverflow.com/users/1762224" __status__ = "Production" # This is the default file that is parsed. DEFAULT_CONFIG_FILE = 'C:/Program Files (x86)/Steam/steamapps/common/\ Counter-Strike Global Offensive/csgo/scripts/items/items_game.txt' def parseConfig(src_filename, dest_filename): out_file = open(dest_filename, 'w') indent_ch = '\t' curr_level = 1 out_file.write('{\n') with open(src_filename, 'r') as f: for line in f.readlines(): if line.strip().startswith('//'): continue # Skip comments. level = line.find('"') + 1 if level < 1: continue # Skip lines without tokens. values = ['"' + v + '"' for v in split(line)] indent = indent_ch * level if level != curr_level: delta = curr_level - level curr_level = level if delta > 0: for i in range(delta, 0, -1): out_file.write('\n' + (indent_ch * (level + i - 1)) + '}') if i == 1: out_file.write(',') out_file.write('\n') elif level == curr_level and level > 1: out_file.write(',\n') if len(values) == 1: out_file.write(indent + values[0] + ' : {\n') else: out_file.write(indent + ' : '.join(values)) for i in range(curr_level, 0, -1): out_file.write('\n' + (indent_ch * (level + i - 1)) + '}') out_file.close() if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('-s', '--src', default=DEFAULT_CONFIG_FILE, help="config file") parser.add_argument('dest', help="file where the parsed JSON will be written to") args = parser.parse_args() parseConfig(args.src, args.dest) 

Additional notes

It looks like there is a CS: GO parser written in Java that uses Antlr grammar to parse files.

Link to the GitHub project: https://github.com/valx76/CSGO-Config-Parser

+4
source

Source: https://habr.com/ru/post/1209514/


All Articles