pythondiscord.pyread-data

How to read specific data in this oddly structured text file? Python


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.


Solution

  • 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.