]> git.xonotic.org Git - xonotic/xonstat.git/blobdiff - xonstat/views/submission.py
Properly account for Elo opt-outs.
[xonotic/xonstat.git] / xonstat / views / submission.py
index b4059e5ad06c2bbe3863587c7b3499ed0f5521b1..8b42dbc53ad031c9fb762674275a040fb6311ab4 100644 (file)
@@ -9,7 +9,7 @@ from sqlalchemy import Sequence
 from sqlalchemy.orm.exc import NoResultFound
 from xonstat.elo import EloProcessor
 from xonstat.models import DBSession, Server, Map, Game, PlayerGameStat, PlayerWeaponStat
 from sqlalchemy.orm.exc import NoResultFound
 from xonstat.elo import EloProcessor
 from xonstat.models import DBSession, Server, Map, Game, PlayerGameStat, PlayerWeaponStat
-from xonstat.models import PlayerRank, PlayerCaptime
+from xonstat.models import PlayerRank, PlayerCaptime, PlayerGameFragMatrix
 from xonstat.models import TeamGameStat, PlayerGameAnticheat, Player, Hashkey, PlayerNick
 from xonstat.util import strip_colors, qfont_decode, verify_request, weapon_map
 
 from xonstat.models import TeamGameStat, PlayerGameAnticheat, Player, Hashkey, PlayerNick
 from xonstat.util import strip_colors, qfont_decode, verify_request, weapon_map
 
@@ -79,6 +79,9 @@ class Submission(object):
         # bots who played in the match
         self.bots = []
 
         # bots who played in the match
         self.bots = []
 
+        # player indexes for those who played
+        self.player_indexes = set()
+
         # distinct weapons that we have seen fired
         self.weapons = set()
 
         # distinct weapons that we have seen fired
         self.weapons = set()
 
@@ -165,6 +168,9 @@ class Submission(object):
         played = self.played_in_game(player)
         human = self.is_human_player(player)
 
         played = self.played_in_game(player)
         human = self.is_human_player(player)
 
+        if played:
+            self.player_indexes.add(int(player["i"]))
+
         if played and human:
             self.humans.append(player)
 
         if played and human:
             self.humans.append(player)
 
@@ -606,7 +612,7 @@ def create_game(session, game_type_cd, server_id, map_id, match_id, start_dt, du
     game.mod = mod[:64]
 
     # There is some drift between start_dt (provided by app) and create_dt
     game.mod = mod[:64]
 
     # There is some drift between start_dt (provided by app) and create_dt
-    # (default in the database), so we'll make them the same until this is 
+    # (default in the database), so we'll make them the same until this is
     # resolved.
     game.create_dt = start_dt
 
     # resolved.
     game.create_dt = start_dt
 
@@ -1044,6 +1050,34 @@ def get_or_create_players(session, events_by_hashkey):
     return players_by_hashkey
 
 
     return players_by_hashkey
 
 
+def create_frag_matrix(session, player_indexes, pgstat, events):
+    """
+    Construct a PlayerFragMatrix object from the events of a given player.
+
+    :param session: The DBSession we're adding objects to.
+    :param player_indexes: The set of player indexes of those that actually played in the game.
+    :param pgstat: The PlayerGameStat object of the player whose frag matrix we want to create.
+    :param events: The raw player events of the above player.
+    :return: PlayerFragMatrix
+    """
+    player_index = int(events.get("i", None))
+
+    # "kills-4" -> 4
+    victim_index = lambda x: int(x.split("-")[1])
+
+    matrix = {victim_index(k): int(v) for (k, v) in events.items()
+              if k.startswith("kills-") and victim_index(k) in player_indexes}
+
+    if len(matrix) > 0:
+        pfm = PlayerGameFragMatrix(pgstat.game_id, pgstat.player_game_stat_id, pgstat.player_id,
+                                   player_index, matrix)
+
+        session.add(pfm)
+        return pfm
+    else:
+        return None
+
+
 def submit_stats(request):
     """
     Entry handler for POST stats submissions.
 def submit_stats(request):
     """
     Entry handler for POST stats submissions.
@@ -1107,11 +1141,17 @@ def submit_stats(request):
         hashkeys_by_player_id = {}
         for hashkey, player in players_by_hashkey.items():
             events = events_by_hashkey[hashkey]
         hashkeys_by_player_id = {}
         for hashkey, player in players_by_hashkey.items():
             events = events_by_hashkey[hashkey]
+
             pgstat = create_game_stat(session, game, gmap, player, events)
             pgstats.append(pgstat)
 
             pgstat = create_game_stat(session, game, gmap, player, events)
             pgstats.append(pgstat)
 
+            frag_matrix = create_frag_matrix(session, submission.player_indexes, pgstat, events)
+
             # player ranking opt-out
             # player ranking opt-out
-            if 'r' in events and events['r'] != '0':
+            if 'r' in events and events['r'] == '0':
+                log.debug("Excluding player {} from ranking calculations (opt-out)"
+                          .format(pgstat.player_id))
+            else:
                 elo_pgstats.append(pgstat)
 
             if player.player_id > 1:
                 elo_pgstats.append(pgstat)
 
             if player.player_id > 1: