-1

I've been developing a discord bot for the game Counter Strike Global Offensive and upon me trying to widen its features i've come across something i've never seen before. I have been looking for the past 4 hours and can't find anything related close enough for me to make a connection. I am using this plugin for the game that places a text file in my servers directory that I will be FTPing to gain access to (I got that part down pretty easily). https://github.com/splewis/get5/wiki/Stats-system

I do have my users stats and soon to be settings that are stored on a json file, but thats with a format that I know of, this file is generated by the game server whenever I run a command (ill be doing it with another plugin at the end of each game automatically) so I have no control of changing the format.

What i'm trying to do: Read specific lines of data from a unknown structured text file and turn those into strings after each game.

My code (just reading the text file)

   with open('get5_matchstats.cfg', 'r') as file:
   data = file.read()
print(data)

Output (exact same as text file):

"Stats"
{
    "series_type"       "bo1"
    "map0"
    {
        "team1"
        {
            "76561628991367478"
            {
                "roundsplayed"      "7"
                "name"      "CoC Legende"
                "deaths"        "3"
                "damage"        "415"
                "kills"     "4"
                "headshot_kills"        "2"
                "1kill_rounds"      "4"
                "firstdeath_ct"     "2"
                "firstkill_ct"      "1"
            }
            "7655212110096592"
            {
                "roundsplayed"      "7"
                "name"      "payperview"
                "deaths"        "2"
                "firstdeath_ct"     "1"
                "damage"        "672"
                "kills"     "6"
                "1kill_rounds"      "1"
                "headshot_kills"        "3"
                "3kill_rounds"      "1"
                "firstkill_ct"      "1"
                "assists"       "1"
                "2kill_rounds"      "1"
            }
            "76561198821291593"
            {
                "roundsplayed"      "7"
                "name"      "dog"
                "damage"        "458"
                "deaths"        "3"
                "assists"       "1"
                "firstdeath_ct"     "1"
                "firstkill_ct"      "2"
                "kills"     "4"
                "1kill_rounds"      "1"
                "headshot_kills"        "2"
                "3kill_rounds"      "1"
            }
            "76561668131605879"
            {
                "roundsplayed"      "7"
                "name"      "Cat"
                "damage"        "640"
                "firstkill_ct"      "1"
                "kills"     "7"
                "2kill_rounds"      "1"
                "bomb_defuses"      "1"
                "1kill_rounds"      "5"
                "tradekill"     "1"
                "headshot_kills"        "1"
            }
            "76566648819479703"
            {
                "roundsplayed"      "7"
                "name"      "BackAndImBetter"
                "damage"        "801"
                "kills"     "9"
                "3kill_rounds"      "2"
                "firstkill_ct"      "1"
                "headshot_kills"        "3"
                "assists"       "1"
                "2kill_rounds"      "1"
                "deaths"        "1"
                "bomb_defuses"      "1"
                "1kill_rounds"      "1"
            }
            "score"     "6"
        }
        "team2"
        {
            "76561198120865213"
            {
                "roundsplayed"      "7"
                "name"      "Squid"
                "damage"        "231"
                "deaths"        "6"
                "firstdeath_t"      "2"
                "kills"     "1"
                "headshot_kills"        "1"
                "1kill_rounds"      "1"
            }
            "76561198355321210"
            {
                "roundsplayed"      "7"
                "name"      "Chub vc_0"
                "damage"        "106"
                "kills"     "1"
                "deaths"        "6"
                "1kill_rounds"      "1"
                "firstdeath_t"      "1"
            }
            "76561197963353523"
            {
                "roundsplayed"      "7"
                "name"      "Bravo"
                "damage"        "630"
                "assists"       "1"
                "deaths"        "6"
                "firstdeath_t"      "1"
                "bomb_plants"       "2"
                "kills"     "3"
                "1kill_rounds"      "1"
                "firstkill_t"       "1"
                "2kill_rounds"      "1"
            }
            "76561198111573735"
            {
                "roundsplayed"      "7"
                "name"      "Manager"
                "damage"        "255"
                "firstkill_t"       "2"
                "kills"     "3"
                "headshot_kills"        "1"
                "deaths"        "6"
                "2kill_rounds"      "1"
                "1kill_rounds"      "1"
                "firstdeath_t"      "2"
            }
            "76561198853686342"
            {
                "roundsplayed"      "7"
                "name"      "Compliment"
                "damage"        "282"
                "deaths"        "6"
                "assists"       "1"
                "firstkill_t"       "1"
                "kills"     "1"
                "headshot_kills"        "1"
                "1kill_rounds"      "1"
            }
            "score"     "0"
        }
        "mapname"       "de_season"
    }
}


Process finished with exit code 0

Before needing this information I will have their steam64ID (the large set of numbers) which I will use to create a link between their discord account and game stats.

The only thing I believe I need help with is figuring how specifically to get things like team score, user kills, deaths, damage etc.

Thanks a lot for your guys' time, having this bit of knowledge will help me progress my bot significantly.

Truemusic
  • 3
  • 1
  • 1
    This seems to be a ```VDF``` [https://developer.valvesoftware.com/wiki/KeyValues](https://developer.valvesoftware.com/wiki/KeyValues) And I found a Git repository to handle these files. https://github.com/gorgitko/valve-keyvalues-python – yabberth Feb 11 '20 at 08:06
  • Just briefly looking at it I think you're right! I couldn't find anything about it at all and having a lib for it really makes my life easier. Appreciate the help! – Truemusic Feb 11 '20 at 08:19

1 Answers1

0

From what I see, once you are inside the map object (curly braces), you could see a pattern which is similar to a json object.

The solution what I'm going to suggest should only be used if the file that has this stats is a small file otherwise there would be a lot of memory overhead.

Solution : Read the file and construct it into a object which has list and dictionary for querying.

def convert_file_into_object(file):
    team_object = {}
    team_name = ""
    player_id = ""
    for line in file.readlines():
        line = line.replace('"', '').strip()

        if "{" in line:
            continue
        if "}" in line:
            if player_id:
                player_id = ""
            continue

        if "team" in line:  # team object starts so add a new dict with team name
            team_name = line
            team_object[team_name] = []
            continue

        if line.isnumeric():  # we have hit player id, so add new player in current team
            player_id = line
            team_object[team_name].append({player_id: {}})
            continue

        player_stats = line.split()
        if len(player_stats) == 2 and team_name and player_id:  # we have players stats
            team_object[team_name][len(team_object[team_name]) - 1][player_id][player_stats[0]] = player_stats[1]

    return team_object


with open("data.txt", "r") as file:
    file_object = convert_file_into_object(file)

    from pprint import pprint as pp
    pp(file_object)

I have written this piece of code on the basis of file data you have shared. The code needs to be changed if the file has different structure.

Output in REPL when above code is saved in robo.py module.

 gaurishankarbadola@ubuntu:~/python_path$ python robo.py 
{'team1': [{'76561628991367478': {'1kill_rounds': '4',
                                  'damage': '415',
                                  'deaths': '3',
                                  'firstdeath_ct': '2',
                                  'firstkill_ct': '1',
                                  'headshot_kills': '2',
                                  'kills': '4',
                                  'roundsplayed': '7'}},
           {'7655212110096592': {'1kill_rounds': '1',
                                 '2kill_rounds': '1',
                                 '3kill_rounds': '1',
                                 'assists': '1',
                                 'damage': '672',
                                 'deaths': '2',
                                 'firstdeath_ct': '1',
                                 'firstkill_ct': '1',
                                 'headshot_kills': '3',
                                 'kills': '6',
                                 'name': 'payperview',
                                 'roundsplayed': '7'}},
           {'76561198821291593': {'1kill_rounds': '1',
                                  '3kill_rounds': '1',
                                  'assists': '1',
                                  'damage': '458',
                                  'deaths': '3',
                                  'firstdeath_ct': '1',
                                  'firstkill_ct': '2',
                                  'headshot_kills': '2',
                                  'kills': '4',
                                  'name': 'dog',
                                  'roundsplayed': '7'}},
           {'76561668131605879': {'1kill_rounds': '5',
                                  '2kill_rounds': '1',
                                  'bomb_defuses': '1',
                                  'damage': '640',
                                  'firstkill_ct': '1',
                                  'headshot_kills': '1',
                                  'kills': '7',
                                  'name': 'Cat',
                                  'roundsplayed': '7',
                                  'tradekill': '1'}},
           {'76566648819479703': {'1kill_rounds': '1',
                                  '2kill_rounds': '1',
                                  '3kill_rounds': '2',
                                  'assists': '1',
                                  'bomb_defuses': '1',
                                  'damage': '801',
                                  'deaths': '1',
                                  'firstkill_ct': '1',
                                  'headshot_kills': '3',
                                  'kills': '9',
                                  'name': 'BackAndImBetter',
                                  'roundsplayed': '7'}}],
 'team2': [{'76561198120865213': {'1kill_rounds': '1',
                                  'damage': '231',
                                  'deaths': '6',
                                  'firstdeath_t': '2',
                                  'headshot_kills': '1',
                                  'kills': '1',
                                  'name': 'Squid',
                                  'roundsplayed': '7'}},
           {'76561198355321210': {'1kill_rounds': '1',
                                  'damage': '106',
                                  'deaths': '6',
                                  'firstdeath_t': '1',
                                  'kills': '1',
                                  'roundsplayed': '7'}},
           {'76561197963353523': {'1kill_rounds': '1',
                                  '2kill_rounds': '1',
                                  'assists': '1',
                                  'bomb_plants': '2',
                                  'damage': '630',
                                  'deaths': '6',
                                  'firstdeath_t': '1',
                                  'firstkill_t': '1',
                                  'kills': '3',
                                  'name': 'Bravo',
                                  'roundsplayed': '7'}},
           {'76561198111573735': {'1kill_rounds': '1',
                                  '2kill_rounds': '1',
                                  'damage': '255',
                                  'deaths': '6',
                                  'firstdeath_t': '2',
                                  'firstkill_t': '2',
                                  'headshot_kills': '1',
                                  'kills': '3',
                                  'name': 'Manager',
                                  'roundsplayed': '7'}},
           {'76561198853686342': {'1kill_rounds': '1',
                                  'assists': '1',
                                  'damage': '282',
                                  'deaths': '6',
                                  'firstkill_t': '1',
                                  'headshot_kills': '1',
                                  'kills': '1',
                                  'name': 'Compliment',
                                  'roundsplayed': '7'}}]}

Once you have the object, you can query it accordingly.

gsb22
  • 1,566
  • 6
  • 16
  • Thank you very much for the detailed response. This is precisely what I was looking for as now I can query the data the same way I do my players config file! I appreciate the time you took helping me with this, now I can play with this and learn how to make a lib myself rather than depending on others to have made one for me! – Truemusic Feb 11 '20 at 18:47