pnxenopoulos / awpy

Python library to parse, analyze and visualize Counter-Strike 2 data
http://www.awpycs.com
MIT License
374 stars 57 forks source link

'KeyError' in main branch #247

Closed RunGuitarMan closed 1 year ago

RunGuitarMan commented 1 year ago

Describe the bug Bug in the version currently in 'main'. very similar KeyError, but I think it occurs when the player left the server after "endTick" but before "endOfficialTick" Version of awpy currently in PyPi does not cause this problem

Include Information to Reproduce Demo file: https://drive.google.com/file/d/1twVayyVeYNu6QoUYEZ0HQNxWhx3VIE09

Code

from awpy.parser import DemoParser
from awpy.analytics.stats import player_stats

parser = DemoParser(
    demofile='C:/1-a8917f91-390e-4479-807d-a672e9155be1-1-1.dem',
    demo_id='1-a8917f91-390e-4479-807d-a672e9155be1-1-1'
)

parse_data = parser.parse()
player_stats_json = player_stats(parse_data["gameRounds"])
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[3], line 10
      4 parser = DemoParser(
      5     demofile='C:/1-a8917f91-390e-4479-807d-a672e9155be1-1-1.dem',
      6     demo_id='1-a8917f91-390e-4479-807d-a672e9155be1-1-1'
      7 )
      9 parse_data = parser.parse()
---> 10 player_stats_json = player_stats(parse_data["gameRounds"])

File ~\AppData\Local\pypoetry\Cache\virtualenvs\bcl-rating-api-4C7xlnMJ-py3.11\Lib\site-packages\awpy\analytics\stats.py:655, in player_stats(game_rounds, return_type, selected_side)
    651 for game_round in game_rounds:
    652     # Add players
    653     round_statistics = initialize_round(game_round, player_statistics, active_sides)
--> 655     _handle_kills(game_round, player_statistics, round_statistics)
    656     _handle_damages(game_round, player_statistics, round_statistics)
    657     _handle_weapon_fires(game_round, player_statistics, round_statistics)

File ~\AppData\Local\pypoetry\Cache\virtualenvs\bcl-rating-api-4C7xlnMJ-py3.11\Lib\site-packages\awpy\analytics\stats.py:467, in _handle_kills(game_round, player_statistics, round_statistics)
    463     round_statistics["players_killed"][victim_side].add(victim_key)
    464 _handle_pure_killer_stats(
    465     killer_key, player_statistics, round_statistics, kill_action=k
    466 )
--> 467 _handle_pure_victim_stats(
    468     victim_key,
    469     player_statistics,
    470     round_statistics,
    471     kill_action=k,
    472     game_round=game_round,
    473 )
    474 _handle_trade_stats(
    475     killer_key, player_statistics, round_statistics, kill_action=k
    476 )
    477 _handle_assists(
    478     assister_key,
    479     flashthrower_key,
   (...)
    482     kill_action=k,
    483 )

File ~\AppData\Local\pypoetry\Cache\virtualenvs\bcl-rating-api-4C7xlnMJ-py3.11\Lib\site-packages\awpy\analytics\stats.py:372, in _handle_pure_victim_stats(victim_key, player_statistics, round_statistics, kill_action, game_round)
    370 if kill_action["isSuicide"]:
    371     player_statistics[victim_key]["suicides"] += 1
--> 372 _handle_clutching(kill_action, game_round, round_statistics, player_statistics)

File ~\AppData\Local\pypoetry\Cache\virtualenvs\bcl-rating-api-4C7xlnMJ-py3.11\Lib\site-packages\awpy\analytics\stats.py:350, in _handle_clutching(kill_action, game_round, round_statistics, player_statistics)
    348 if not proper_player_number(enemies_alive) or enemies_alive == 0:
    349     return
--> 350 player_statistics[clutcher_key][
    351     "attempts1v" + int_to_string_n_players(enemies_alive)
    352 ] += 1
    353 if game_round["winningSide"] == kill_action["victimSide"]:
    354     player_statistics[clutcher_key][
    355         "success1v" + int_to_string_n_players(enemies_alive)
    356     ] += 1

KeyError: ''
JanEricNitschke commented 1 year ago

The issue here is the player leaving in freezetime (which counts as a death) and then rejoining. When 3 of his teammates die during the round the clutching logic is triggered because (5-1) player have died in his team. When he dies again the logic is triggered again. But since his teammate is already clutching he wont be selected again as a clutcher and instead an empty string is returned.

This triggers the KeyError.

I have to think how to fix this properly. It worked in 1.2.3 because the assignment of the clutching player worked slightly differently. However the underlying problem that a reconnecting player triggers the clutching logic already at 2 players alive was already present and could lead to false entries into the clutching statistic.

JanEricNitschke commented 1 year ago

Clutching logic in case anyone wants to have a pass at improving/cleaning this.

https://github.com/pnxenopoulos/awpy/blob/main/awpy/analytics/stats.py#L318

JanEricNitschke commented 1 year ago

The KeyError should be adressed here: https://github.com/pnxenopoulos/awpy/pull/249

Underlying issue still remains.

JanEricNitschke commented 1 year ago

Closing this for now. Feel free to reopen if the underlying problem causes issues.