]> de.git.xonotic.org Git - xonotic/xonstat.git/blobdiff - xonstat/views/submission.py
Should be ready to go now!
[xonotic/xonstat.git] / xonstat / views / submission.py
index 4d969b8395028498154ef19e3231a4d4c582574f..7f011fbfa4df988a937e1050d3d7acd1c1b70ecc 100755 (executable)
@@ -13,11 +13,33 @@ from xonstat.util import strip_colors, qfont_decode
 \r
 log = logging.getLogger(__name__)\r
 \r
+\r
+def is_blank_game(players):\r
+    """Determine if this is a blank game or not. A blank game is either:\r
+\r
+    1) a match that ended in the warmup stage, where accuracy events are not\r
+    present\r
+\r
+    2) a match in which no player made a positive or negative score AND was\r
+    on the scoreboard\r
+    """\r
+    r = re.compile(r'acc-.*-cnt-fired')\r
+    flg_nonzero_score = False\r
+    flg_acc_events = False\r
+\r
+    for events in players:\r
+        if is_real_player(events):\r
+            for (key,value) in events.items():\r
+                if key == 'scoreboard-score' and value != '0':\r
+                    flg_nonzero_score = True\r
+                if r.search(key):\r
+                    flg_acc_events = True\r
+\r
+    return not (flg_nonzero_score and flg_acc_events)\r
+\r
 def get_remote_addr(request):\r
     """Get the Xonotic server's IP address"""\r
-    if 'X-Server-IP' in request.headers:\r
-        return request.headers['X-Server-IP']\r
-    elif 'X-Forwarded-For' in request.headers:\r
+    if 'X-Forwarded-For' in request.headers:\r
         return request.headers['X-Forwarded-For']\r
     else:\r
         return request.remote_addr\r
@@ -48,7 +70,7 @@ def verify_request(request):
     return (idfp, status)\r
 \r
 \r
-def num_real_players(player_events):\r
+def num_real_players(player_events, count_bots=False):\r
     """\r
     Returns the number of real players (those who played \r
     and are on the scoreboard).\r
@@ -56,7 +78,7 @@ def num_real_players(player_events):
     real_players = 0\r
 \r
     for events in player_events:\r
-        if is_real_player(events):\r
+        if is_real_player(events, count_bots):\r
             real_players += 1\r
 \r
     return real_players\r
@@ -102,7 +124,7 @@ def has_required_metadata(metadata):
     return flg_has_req_metadata\r
 \r
 \r
-def is_real_player(events):\r
+def is_real_player(events, count_bots=False):\r
     """\r
     Determines if a given set of player events correspond with a player who\r
 \r
@@ -114,9 +136,10 @@ def is_real_player(events):
     """\r
     flg_is_real = False\r
 \r
-    if not events['P'].startswith('bot'):\r
-        # removing 'joins' here due to bug, but it should be here\r
-        if 'matches' in events and 'scoreboardvalid' in events:\r
+    # removing 'joins' here due to bug, but it should be here\r
+    if 'matches' in events and 'scoreboardvalid' in events:\r
+        if (events['P'].startswith('bot') and count_bots) or \\r
+            not events['P'].startswith('bot'):\r
             flg_is_real = True\r
 \r
     return flg_is_real\r
@@ -252,7 +275,7 @@ def create_game(session=None, start_dt=None, game_type_cd=None,
                 filter(Game.match_id==match_id).one()\r
         # if a game under the same server and match_id found, \r
         # this is a duplicate game and can be ignored\r
-        raise pyramid.httpexceptions.HTTPOk\r
+        raise pyramid.httpexceptions.HTTPOk('OK')\r
     except NoResultFound, e:\r
         # server_id/match_id combination not found. game is ok to insert\r
         session.add(game)\r
@@ -539,10 +562,15 @@ def stats_submit(request):
             log.debug("ERROR: Not enough real players")\r
             raise pyramid.httpexceptions.HTTPOk("OK")\r
 \r
+        if is_blank_game(players):\r
+            log.debug("ERROR: Blank game")\r
+            raise pyramid.httpexceptions.HTTPOk("OK")\r
+\r
         # FIXME: if we have two players and game type is 'dm',\r
         # change this into a 'duel' gametype. This should be\r
         # removed when the stats actually send 'duel' instead of 'dm'\r
-        if num_real_players(players) == 2 and game_meta['G'] == 'dm':\r
+        if num_real_players(players, count_bots=True) == 2 and \\r
+                game_meta['G'] == 'dm':\r
             game_meta['G'] = 'duel'\r
 \r
         server = get_or_create_server(session=session, hashkey=idfp, \r
@@ -577,6 +605,12 @@ def stats_submit(request):
                 create_player_stats(session=session, player=player, game=game, \r
                         player_events=player_events)\r
 \r
+        # update elos\r
+        try:\r
+            game.process_elos(session)\r
+        except Exception as e:\r
+            log.debug('Error (non-fatal): elo processing failed.')\r
+\r
         session.commit()\r
         log.debug('Success! Stats recorded.')\r
         return Response('200 OK')\r