from sqlalchemy import Sequence
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
from xonstat.d0_blind_id import d0_blind_id_verify
+from xonstat.elo import process_elos
from xonstat.models import *
from xonstat.util import strip_colors, qfont_decode
real_players = num_real_players(player_events)
- #TODO: put this into a config setting in the ini file?
if real_players < minimum_required_players:
flg_has_min_real_players = False
def create_player_weapon_stats(session=None, player=None,
- game=None, pgstat=None, player_events=None):
+ game=None, pgstat=None, player_events=None, game_meta=None):
"""
Creates accuracy records for each weapon used by a given player in a
given game. Parameters:
pgstat - Corresponding PlayerGameStat record for these weapon stats
player_events - dictionary containing the raw weapon values that need to be
transformed
+ game_meta - dictionary of game metadata (only used for stats version info)
"""
pwstats = []
+ # Version 1 of stats submissions doubled the data sent.
+ # To counteract this we divide the data by 2 only for
+ # POSTs coming from version 1.
+ try:
+ version = int(game_meta['V'])
+ if version == 1:
+ is_doubled = True
+ log.debug('NOTICE: found a version 1 request, halving the weapon stats...')
+ else:
+ is_doubled = False
+ except:
+ is_doubled = False
+
for (key,value) in player_events.items():
matched = re.search("acc-(.*?)-cnt-fired", key)
if matched:
if 'acc-' + weapon_cd + '-cnt-fired' in player_events:
pwstat.fired = int(round(float(
player_events['acc-' + weapon_cd + '-cnt-fired'])))
+ if is_doubled:
+ pwstat.fired = pwstat.fired/2
if 'acc-' + weapon_cd + '-fired' in player_events:
pwstat.max = int(round(float(
player_events['acc-' + weapon_cd + '-fired'])))
+ if is_doubled:
+ pwstat.max = pwstat.max/2
if 'acc-' + weapon_cd + '-cnt-hit' in player_events:
pwstat.hit = int(round(float(
player_events['acc-' + weapon_cd + '-cnt-hit'])))
+ if is_doubled:
+ pwstat.hit = pwstat.hit/2
if 'acc-' + weapon_cd + '-hit' in player_events:
pwstat.actual = int(round(float(
player_events['acc-' + weapon_cd + '-hit'])))
+ if is_doubled:
+ pwstat.actual = pwstat.actual/2
if 'acc-' + weapon_cd + '-frags' in player_events:
pwstat.frags = int(round(float(
player_events['acc-' + weapon_cd + '-frags'])))
+ if is_doubled:
+ pwstat.frags = pwstat.frags/2
session.add(pwstat)
pwstats.append(pwstat)
def create_player_stats(session=None, player=None, game=None,
- player_events=None):
+ player_events=None, game_meta=None):
"""
Creates player game and weapon stats according to what type of player
"""
if not re.search('^bot#\d+$', player_events['P']):
create_player_weapon_stats(session=session,
player=player, game=game, pgstat=pgstat,
- player_events=player_events)
+ player_events=player_events, game_meta=game_meta)
def stats_submit(request):
Entry handler for POST stats submissions.
"""
try:
- session = DBSession()
+ # placeholder for the actual session
+ session = None
log.debug("\n----- BEGIN REQUEST BODY -----\n" + request.body +
"----- END REQUEST BODY -----\n\n")
log.debug("ERROR: Unverified request")
raise pyramid.httpexceptions.HTTPUnauthorized("Unverified request")
- (game_meta, players) = parse_body(request)
+ (game_meta, players) = parse_body(request)
if not has_required_metadata(game_meta):
log.debug("ERROR: Required game meta missing")
except:
revision = "unknown"
+ #----------------------------------------------------------------------
+ # This ends the "precondition" section of sanity checks. All
+ # functions not requiring a database connection go ABOVE HERE.
+ #----------------------------------------------------------------------
+ session = DBSession()
+
server = get_or_create_server(session=session, hashkey=idfp,
name=game_meta['S'], revision=revision,
ip_addr=get_remote_addr(request))
hashkey=player_events['P'], nick=nick)
log.debug('Creating stats for %s' % player_events['P'])
create_player_stats(session=session, player=player, game=game,
- player_events=player_events)
+ player_events=player_events, game_meta=game_meta)
# update elos
try:
- game.process_elos(session)
+ process_elos(game, session)
except Exception as e:
log.debug('Error (non-fatal): elo processing failed.')
log.debug('Success! Stats recorded.')
return Response('200 OK')
except Exception as e:
- session.rollback()
+ if session:
+ session.rollback()
return e