def single(self, mode, one=True): try: mint = int(mode) except TypeError: return None if mint not in list(range(len(redeclipse().modestr))): return None ret = { "id": mint, "name": redeclipse().modestr[mint], "corename": redeclipse().cmodestr[mint], "recentgames": {}, } ret["games"] = [r[0] for r in self.db.con.execute( """SELECT id FROM games WHERE mode = re_mode(id, '%s')""" % ret["corename"])] if one: for gid in list(reversed(ret["games"]))[ :self.server.cfgval("moderecent")]: gs = GameSelector(self) game = gs.single(gid, one=False) ret["recentgames"][gid] = game return ret
def multi(request, db): gs = dbselectors.get('game', db) gs.flags_none() gs.weakflags(["server"], True) games = gs.multi() pager = web.Pager(request, onpagecount, reversed(list(games.keys()))) table = web.Table( ["ID", "Mode", "Mutators", "Server", "Map", "Duration", "Played"]) for gid in pager.list(): game = games[gid] with table.tr as tr: tr(web.link('/game/', gid, "Game #%d" % gid)) tr(web.link('/mode/', game["mode"], redeclipse(game).modeimg(game["mode"]))) tr(redeclipse(game).mutslist(game, True) or '-') row = db.execute( "SELECT version FROM game_servers WHERE game = %d" % gid ).fetchone() version = row[0] tr("%s [%s]" % ( web.link('/server/', game["server"], game["server"]), version)) tr(web.link('/map/', game["map"], game["map"], True)) tr(timeutils.durstr(round(game["timeplayed"]))) tr(timeutils.agohtml(game["time"])) ret = """ <div class="center display-table"> <h2>Games</h2> <h3>{gamenum} Recorded</h3> {table} {pages} </div> """.format(table=table.html(), pages=pager.html(), gamenum=len(games)) return web.page(ret, title="Games")
def make_single(self, specific): if specific in redeclipse().modes: mint = redeclipse().modes[specific] else: try: mint = int(specific) except TypeError: return {'Error': 'Mode does not exist'} if mint not in list(range(len(redeclipse().modestr))): return {} ret = { "id": mint, "name": redeclipse().modestr[mint], "corename": redeclipse().cmodestr[mint], "recentgames": {}, } gamerows = list(self.db.execute( """SELECT * FROM games WHERE mode = re_mode(id, '%s')""" % ret["corename"])) ret["games"] = [r[0] for r in gamerows] gs = dbselectors.get("game", self.db) gs.flags_none() gs.weakflags(['players'], True) # Recent Games if self.flags['recentgames']: num = self.q.qint('recentgames', cfg.get('recent')) for row in utils.sliceneg(list(reversed(gamerows)), num): game = gs.fromrow(row) ret["recentgames"][game["id"]] = game return ret
def getdict(self): if self.pathid is not None: if self.pathid not in redeclipse().weaponlist: return {'error': 'Not Found'} return self.single(self.pathid) or {'error': 'Not Found'} ret = {} for w in redeclipse().weaponlist: ret[w] = self.single(w) return ret
def single(request, db, specific): ret = "" serverselector = dbselectors.get('server', db) serverselector.flags_none() serverselector.weakflags(["games"], True) server = serverselector.single(specific) if utils.sok(server): # Game List pager = web.Pager(request, onpagecount, reversed(server["games"])) recentgames = web.Table( ["ID", "Mode", "Mutators", "Map", "Duration", "Played"]) gs = dbselectors.get('game', db) gs.flags_none() firstgame = gs.single(server["games"][0]) for gid in pager.list(): game = gs.single(gid) with recentgames.tr as tr: tr(web.link("/game/", gid, "Game #%d" % gid)) tr(web.link("/mode/", game["mode"], redeclipse(game).modeimg(game["mode"]))) tr(redeclipse(game).mutslist(game, True) or '-') tr(web.link("/map/", game["map"], game["map"], True)) tr(timeutils.durstr(round(game["timeplayed"]))) tr(timeutils.agohtml(game["time"])) ret += """ <div class="center"> <h2>{server[desc]}</h2> <h3>{server[handle]} <i>[{server[authflags]}]</i>: Version {server[version]}</h3> <a href="redeclipse://{server[host]}:{server[port]}"> {server[host]}:{server[port]}</a><br> {servergames} games recorded.<br> First Recorded: {fgtime} with <a href="/game/{fgid}">Game #{fgid}</a>.<br> <div class='display-table'> <h3>Recent Games</h3> {recentgames} {pages} </div> </div> """.format(server=server, recentgames=recentgames.html(), servergames=len(server["games"]), fgtime=timeutils.agohtml(firstgame["time"]), fgid=firstgame["id"], pages=pager.html()) else: ret = "<div class='center'><h2>No such server.</h2></div>" return web.page(ret, title="Server %s" % specific)
def multi(request, db): ws = dbselectors.get('weapon', db, {'recentsums': [pastgames]}) weapons = ws.multi() totalwielded = sum(w['timewielded'] for w in list(weapons.values())) ret = web.displays.weaponstable( weapons, totalwielded, redeclipse().weaponlist, pastgames).html(True) return web.page(ret, title="Weapons")
def single(self, name): wr = {'name': name} wa = {'name': name} recentsum = lambda x: self.db.con.execute( """SELECT sum(%s) FROM (SELECT * FROM game_weapons WHERE weapon = ? AND %s AND game IN (SELECT id FROM games WHERE mode != re_mode(id, 'race')) ORDER by ROWID DESC LIMIT %d)""" % (x, self.vlimit(), self.server.cfgval("weaponrecentavg")), (name,)).fetchone()[0] allsum = lambda x: self.db.con.execute( """SELECT sum(%s) FROM game_weapons WHERE weapon = ? AND game IN (SELECT id FROM games WHERE mode != re_mode(id, 'race'))""" % ( x), (name,)).fetchone()[0] for t in redeclipse().weapcols: wr[t] = recentsum(t) or 0 wa[t] = allsum(t) or 0 return { 'recent': wr, 'alltime': wa, }
def getdict(self): if self.pathid is not None: return self.single(self.pathid) or {'error': 'Not Found'} muts = list(redeclipse().basemuts.keys())[:-1] ret = {} for mut in muts: r = self.single(mut, False) if r: ret[mut] = r return ret
def weaponstable(weapons, totalwielded, order, games=None, version=None): title = "Weapons" if len(order) == 1: title = weapons[order[0]]["name"].capitalize() if games is not None: title = "%s: Last %d games" % (title, games) table = web.Table( ["Weapon", "Loadout", "Wielded", '<abbr title="Damage Per Minute Wielded">DPM</abbr>', '<abbr title="Frags Per Minute Wielded">FPM</abbr>'], title, 'display-table small-table') for weapon in order: with table.tr as tr: weapon = weapons[weapon] if weapon["timeloadout"] is None: continue weap = weapon["name"] tr(web.link("/weapon/", weap, '%s %s' % (redeclipse().weaponimg(weap), weap))) tr("%d%%" % ( weapon["timeloadout"] / max(1, totalwielded) * 100)) nw = redeclipse(version).notwielded if (weap + '1') in nw and (weap + '2') in nw: tr("-") else: tr("%d%%" % ( weapon["timewielded"] / max(1, totalwielded) * 100)) psdiv = max(weapon["timeloadout"] if (weap + '1') in nw else weapon["timewielded"], 1) / 60 psdiv2 = max(weapon["timeloadout"] if (weap + '2') in nw else weapon["timewielded"], 1) / 60 tr("<span class='explain' title='%d %d'>%d</span>" % ( weapon["damage1"] / psdiv, weapon["damage2"] / psdiv2, weapon["damage1"] / psdiv + weapon["damage2"] / psdiv2)) tr("<span class='explain' title='%.1f %.1f'>%.1f</span></td>" % ( round(weapon["frags1"] / psdiv, 1), round(weapon["frags2"] / psdiv2, 1), round(weapon["frags1"] / psdiv + weapon["frags2"] / psdiv2, 1) )) return table
def single(request, db, specific): ps = dbselectors.get('player', db) ps.flags_none() ps.weakflags(['games'], True) gs = dbselectors.get('game', db) gs.flags_none() gs.weakflags(['players'], True) player = ps.single(specific) if utils.sok(player): table = web.Table(["Game", "Mode", "Mutators", "Map", "Time", "Played As", "Score", "Frags", "Deaths"]) pager = web.Pager(request, onpagecount, reversed(player["games"])) for gid in pager.list(): game = gs.single(gid) entry = [p for p in list(game["players"].values()) if p["handle"] == player["handle"]][0] with table.tr as tr: tr(web.link('/game/', gid, "Game #%d" % gid)) tr(web.link('/mode/', game["mode"], redeclipse(game).modeimg(game["mode"]))) tr(redeclipse(game).mutslist(game, True) or '-') tr(web.link("/map/", game["map"], game["map"], True)) tr(timeutils.agohtml(game["time"])) tr(cgi.escape(entry["name"])) tr(redeclipse(game).scorestr(game, entry["score"])) tr(entry["frags"]) tr(entry["deaths"]) ret = """ <div class="center"> <h2><a href="/player/{player[handle]}"> {player[handle]}</a>: Games</h2> <div class='display-table'> {table} {pages} </div> </div> """.format(player=player, table=table.html(), pages=pager.html()) else: ret = "<div class='center'><h2>No such player.</h2></div>" return web.page(ret, title="%s: Games" % specific)
def update(self): gs = dbselectors.get('game', self.db, {'gt-time': [time.time() - 60 * 60 * 24 * self.days]}) gs.flags_none() new = {} for game in list(gs.multi().values()): for idx in redeclipse(game).mutslist(game): if idx not in new: new[idx] = 0 new[idx] += 1 with self.lock: self.data = new
def single(request, db, specific): ret = "" mutselector = dbselectors.get('mut', db) mutselector.flags_none() mut = mutselector.single(specific) if utils.sok(mut): # Game List pager = web.Pager(request, onpagecount, reversed(mut["games"])) recentgames = web.Table( ["ID", "Mode", "Mutators", "Map", "Duration", "Played"]) gs = dbselectors.get('game', db) gs.flags_none() for gid in pager.list(): game = gs.single(gid) with recentgames.tr as tr: tr(web.link("/game/", gid, "Game #%d" % gid)) tr(web.link("/mode/", game["mode"], redeclipse(game).modeimg(game["mode"]))) tr(redeclipse(game).mutslist(game, True) or '-') tr(web.link("/map/", game["map"], game["map"], True)) tr(timeutils.durstr(round(game["timeplayed"]))) tr(timeutils.agohtml(game["time"])) ret += """ <div class="center"> <h2>{mut[id]}</h2> <div class='display-table'> <h3>Recent Games</h3> {recentgames} {pages} </div> </div> """.format(mut=mut, recentgames=recentgames.html(), pages=pager.html()) else: ret = "<div class='center'><h2>No such mutator.</h2></div>" return web.page(ret, title="Mutator %s" % specific)
def table(self, limit=5, pager=None): data = self.get() table = web.Table(["Mode", "Games"]) if pager is not None: indexes = pager.list() else: if limit is not None: indexes = sorted(data, key=lambda x: -data[x])[:limit] else: indexes = sorted(data, key=lambda x: -data[x]) for m in indexes: with table.tr as tr: tr(web.link('/mode/', m, redeclipse().modeimg(m))) tr(data[m]) return table
def table(self, limit=5, pager=None): data = self.get() table = web.Table(['<a href="/ranks/modes/%d">Mode</a>' % self.days, '<a href="/ranks/muts/%d">Mutators</a>' % self.days, "Games"]) if pager is not None: indexes = pager.list() else: if limit is not None: indexes = sorted(data, key=lambda x: -data[x])[:limit] else: indexes = sorted(data, key=lambda x: -data[x]) for m in indexes: with table.tr as tr: fakegame = { "mode": m[0], "mutators": m[1], "version": m[2], } tr(web.link('/mode/', m[0], redeclipse(fakegame).modeimg(m[0]))) tr(redeclipse(fakegame).mutslist( fakegame, True, True) or '-') tr(data[m]) return table
def single(self, mut, one=True): if mut not in list(redeclipse().basemuts.keys())[:-1]: return None ret = { "id": mut, "recentgames": {}, } ret["games"] = [r[0] for r in self.db.con.execute( """SELECT id FROM games WHERE mutators & re_mut(id, '%s')""" % ret["id"])] if one: for gid in list(reversed(ret["games"]))[ :self.server.cfgval("moderecent")]: gs = GameSelector(self) game = gs.single(gid, one=False) ret["recentgames"][gid] = game return ret
def multi(request, db): gs = dbselectors.get('games', db) gs.flags_none() gs.weakflags(['server'], True) #Top Weapons ws = dbselectors.get('weapons', db, {'recentsums': [5000]}) weapons = {} for name in redeclipse().loadoutweaponlist: weapon = ws.single(name) weapons[name] = weapon topweapons = { 'wield': (redeclipse().weaponlist[0], 0), 'dpm': (redeclipse().weaponlist[0], 0), 'totalwielded': 0, } if weapons: best = sorted(list(weapons.items()), key=lambda weapon: -( weapon[1]["damage1"] / (max(weapon[1]["timewielded"], 1) / 60) + weapon[1]["damage2"] / (max(weapon[1]["timewielded"], 1) / 60)))[0] topweapons['dpm'] = (best[0], (best[1]["damage1"] / (max(best[1]["timewielded"], 1) / 60) + best[1]["damage2"] / (max(best[1]["timewielded"], 1) / 60))) topweapons['totalwielded'] = sum([w['timewielded'] for w in list(weapons.values())]) best = sorted(list(weapons.items()), key=lambda weapon: -( max(weapon[1]["timewielded"], 1)))[0] topweapons['wield'] = (best[0], best[1]["timewielded"]) # Recent Games gamestable = web.Table( ["ID", "Mode", "Mutators", "Server", "Map", "Duration", "Played"]) games = gs.multi() for gid in sorted(list(games.keys()), reverse=True)[:10]: game = games[gid] with gamestable.tr as tr: tr(web.link('/game/', gid, "Game #%d" % gid)) tr(web.link('/mode/', game["mode"], redeclipse(game).modeimg(game["mode"]))) tr(redeclipse(game).mutslist(game, True) or '-') tr("%s [%s]" % ( web.link('/server/', game["server"], game["server"]), game["version"])) tr(web.link('/map/', game["map"], game["map"], True)) tr(timeutils.durstr(round(game["timeplayed"]))) tr(timeutils.agohtml(game["time"])) ranks = { "spf": rankselectors.get('spf', db, 7).table().html(), "captures": rankselectors.get('captures', db, 7).table().html(), "bombings": rankselectors.get('bombings', db, 7).table().html(), "affmvp": rankselectors.get('mvp', db, 7, "affmvp").table().html(), "dmmvp": rankselectors.get('mvp', db, 7, "dmmvp").table().html(), "sword": rankselectors.get('weapon', db, 7, {"weapon": ('sword', 0)}).best(), "sniper": rankselectors.get('weapon', db, 7, {"weapon": ('rifle', 2)}).best(), "spm": rankselectors.get('spm', db, 30).table().html(), "dpm": rankselectors.get('dpm', db, 30).table().html(), "fpm": rankselectors.get('fpm', db, 30).table().html(), "games": rankselectors.get('games', db, 30).table().html(), "maps": rankselectors.get('maps', db, 90).table().html(), "servers": rankselectors.get('servers', db, 90).table().html(), "ffa": rankselectors.get( 'winners', db, 90, 'ffa').table().html(), "ffasurv": rankselectors.get( 'winners', db, 90, 'ffasurv').table().html(), } ret = """ <h2>Recent Overview</h2> <h5><a href="/players">Players</a></h5> <h3>Last 7 Days</h3> <div class='display-table float-table'> <h5>Score/Frags</h5> {ranks[spf]} </div> <div class='display-table float-table'> <h5> <span class="explain" title="Most Flag Captures">Captures</span></h5> {ranks[captures]} </div> <div class='display-table float-table'> <h5> <span class="explain" title="Most Base Bombings">Bombings</span></h5> {ranks[bombings]} </div> <div class='display-table float-table'> <h5><span class="explain" title="Scores from CTF and BB">CTF/BB Team Scores</span></h5> {ranks[affmvp]} </div> <div class='display-table float-table'> <h5><span class="explain" title="Scores from DM">DM Team Scores</span></h5> {ranks[dmmvp]} </div> <div class='display-table float-table'> <h5>Best</h5> <table> <tr> <td><span class="explain" title="Best Damage and Frags with the Sword">Knight</span></td> <td>{ranks[sword]}</td> </tr> <tr> <td><span class="explain" title="Best Damage and Frags with the Rifle Secondary"> Sniper</span></td> <td>{ranks[sniper]}</td> </tr> </table> </div> <div style="clear: both;"></div> <h3>Last 30 Days</h3> <div class='display-table float-table'> <h5><a href="/ranks/spm/180" class="explain" title="Score per Minute">SPM</a></h5> {ranks[spm]} </div> <div class='display-table float-table'> <h5><a href="/ranks/dpm/180" class="explain" title="Damage per Minute">DPM</a></h5> {ranks[dpm]} </div> <div class='display-table float-table'> <h5><a href="/ranks/fpm/180" class="explain" title="Frags per Minute">FPM</a></h5> {ranks[fpm]} </div> <div class='display-table float-table'> <h5><a href="/ranks/games/365">Games</a></h5> {ranks[games]} </div> <div style="clear: both;"></div> <h3>Last 90 Days</h3> <div class='display-table float-table'> <h5><a href="/maps">Maps</a></h5> {ranks[maps]} </div> <div class='display-table float-table'> <h5><a href="/servers">Servers</a></h5> {ranks[servers]} </div> <div class='display-table float-table'> <h5><a href="/weapons">Weapons</a></h5> <table> <tr> <td>Best DPM</td> <td>{weapdpm}</td> </tr> <tr> <td>Most Wielded</td> <td>{weapwield}</td> </tr> </table> </div> <div class='display-table float-table'> <h5><a href="/ranks/winners/180?opts=ffa"> FFA Win Ratio</a></h5> {ranks[ffa]} </div> <div class='display-table float-table'> <h5><a href="/ranks/winners/180?&opts=ffasurv"> FFA Survivor Win Ratio</a></h5> {ranks[ffasurv]} </div> <div style="clear: both;"></div> <div class='display-table'> <h5><a href="/games">Latest Games</a></h5> {games} </div> <div style="clear: both;"></div> """.format( weapdpm="%s %s [%d DPM]" % ( redeclipse().weaponimg(topweapons['dpm'][0]), web.link('/weapon/', topweapons['dpm'][0], topweapons['dpm'][0]), topweapons['dpm'][1]), weapwield="%s %s [%d%%]" % ( redeclipse().weaponimg(topweapons['wield'][0]), web.link('/weapon/', topweapons['wield'][0], topweapons['wield'][0]), topweapons['wield'][1] / max(topweapons['totalwielded'], 1) * 100), games=gamestable.html(), ranks=ranks, ) return web.page(ret, title="Overview")
def single(self, handle, one=True): minimal = self.minimal if hasattr(self, 'minimal') else None row = self.db.con.execute( """SELECT * FROM game_players WHERE handle = ? ORDER BY ROWID DESC""", (handle,)).fetchone() if row is None: return None ret = { 'handle': row[2], "recentgames": {}, } dictfromrow(ret, row, [ "name" ], start=1) ret["games"] = [r[0] for r in self.db.con.execute( """SELECT game FROM game_players WHERE handle = ? AND game in (SELECT id FROM games)""", (handle,))] if minimal == "basic": return ret for gid in list(reversed(ret["games"]))[ :self.server.cfgval("playerrecent")]: gs = GameSelector(self) game = gs.single(gid, one=False) ffarounds = [] for ffaround_row in self.db.con.execute( """SELECT * FROM game_ffarounds WHERE playerhandle = ? AND game = %d""" % gid, (handle,)): ffaround = {} dictfromrow(ffaround, ffaround_row, ["game", None, None, "round", "winner"]) ffarounds.append(ffaround) if ffarounds: game['player_ffarounds'] = ffarounds ret["recentgames"][gid] = game #Data from games recentsum = lambda x: self.db.con.execute( """SELECT sum(%s) FROM (SELECT * FROM game_players WHERE game IN (SELECT id FROM games %s) AND %s AND handle = ? ORDER by ROWID DESC LIMIT %d)""" % (x, "WHERE mode != re_mode(id, 'race')" if x not in ['timeactive'] else "", self.vlimit(), self.server.cfgval("playerrecentavg")), (handle,)).fetchone()[0] allsum = lambda x: self.db.con.execute( """SELECT sum(%s) FROM game_players WHERE game IN (SELECT id FROM games %s) AND handle = ? AND %s""" % (x, "WHERE mode != re_mode(id, 'race')" if x not in ['timeactive'] else "", self.vlimit()), (handle,) ).fetchone()[0] alltime = { 'weapons': {}, } recent = { 'weapons': {}, } captures = [] for capture_row in self.db.con.execute( """SELECT * FROM game_captures WHERE playerhandle = ? AND game in (SELECT id FROM games)""", (handle,)): capture = {} dictfromrow(capture, capture_row, ["game", None, None, "capturing", "captured"]) captures.append(capture) if captures: ret['captures'] = captures bombings = [] for bombing_row in self.db.con.execute( """SELECT * FROM game_bombings WHERE playerhandle = ? AND game in (SELECT id FROM games)""", (handle,)): bombing = {} dictfromrow(bombing, bombing_row, ["game", None, None, "bombing", "bombed"]) bombings.append(bombing) if bombings: ret['bombings'] = bombings for t in ['frags', 'deaths', 'timealive', 'timeactive']: recent[t] = recentsum(t) alltime[t] = allsum(t) recent["damage"] = self.db.con.execute( """SELECT (sum(damage1) + sum(damage2)) FROM game_weapons WHERE %s AND playerhandle = ? AND game IN (SELECT id FROM games WHERE mode != re_mode(id, 'race')) ORDER by ROWID DESC LIMIT %d""" % (self.vlimit(), self.server.cfgval("playerrecentavg")), (ret["handle"],)).fetchone()[0] alltime["damage"] = self.db.con.execute( """SELECT (sum(damage1) + sum(damage2)) FROM game_weapons WHERE %s AND game IN (SELECT id FROM games WHERE mode != re_mode(id, 'race')) AND playerhandle = ?""" % (self.vlimit()), (ret["handle"],)).fetchone()[0] if one: #Weapon Data ##Individual Weapons for weapon in redeclipse().weaponlist: wr = {'name': weapon} wa = {'name': weapon} recentsum = lambda x: self.db.con.execute( """SELECT sum(%s) FROM (SELECT * FROM game_weapons WHERE weapon = ? AND playerhandle = ? AND game IN (SELECT id FROM games WHERE mode != re_mode(id, 'race')) AND %s ORDER by ROWID DESC LIMIT %d)""" % (x, self.vlimit(), self.server.cfgval("playerrecentavg")), (weapon, ret['handle'])).fetchone()[0] allsum = lambda x: self.db.con.execute( """SELECT sum(%s) FROM game_weapons WHERE weapon = ? AND playerhandle = ? AND %s AND game IN (SELECT id FROM games WHERE mode != re_mode(id, 'race'))""" % ( x, self.vlimit()), (weapon, ret['handle'])).fetchone()[0] for t in redeclipse().weapcols: wr[t] = recentsum(t) wa[t] = allsum(t) alltime['weapons'][weapon] = wa recent['weapons'][weapon] = wr ret["alltime"] = alltime ret["recent"] = recent return ret
def fromrow(self, row): if not row: return {} recentgames = self.q.qint('recentgames', cfg.get('recent')) recentsums = self.recent('recentsums') ret = { "recentgames": {}, } dbselectors.rowtodict(ret, row, [ "name", "handle" ], start=1) handle = ret['handle'] # Games if self.flags['games']: gamerows = list(self.db.execute( """SELECT * FROM games WHERE id in (SELECT game FROM game_players WHERE handle=?)""", (handle,))) ret["games"] = [r[0] for r in gamerows] # Recent Games if self.flags['recentgames']: gs = dbselectors.get("game", self.db) gs.flags_none() gs.weakflags(['players'], True) for row in utils.sliceneg( list(reversed(gamerows)), recentgames): game = gs.fromrow(row) game['player'] = [p for p in list(game["players"].values()) if p["handle"] == handle][0] # Count FFA rounds for this player in a new index ffarounds = [] for ffaround_row in self.db.execute( """SELECT * FROM game_ffarounds WHERE playerhandle = ? AND game = %d""" % game['id'], (handle,)): ffaround = {} dbselectors.rowtodict( ffaround, ffaround_row, ["game", None, None, "round", "winner"]) ffarounds.append(ffaround) if ffarounds: game['player_ffarounds'] = ffarounds ret["recentgames"][game["id"]] = game #Data from games recentsum = lambda x: self.db.execute( """SELECT sum(%s) FROM (SELECT * FROM game_players WHERE game IN (SELECT id FROM games %s) AND %s AND handle = ? %s)""" % (x, "WHERE mode != re_mode(id, 'race')" if x not in ['timeactive'] else "", self.vlimit(), recentsums), (ret['handle'],)).fetchone()[0] recent = { 'weapons': {}, } # Affinity data if self.flags['affinities']: captures = [] for capture_row in self.db.execute( """SELECT * FROM game_captures WHERE playerhandle = ? AND game in (SELECT id FROM games %s)""" % (recentsums), (handle,)): capture = {} dbselectors.rowtodict(capture, capture_row, ["game", None, None, "capturing", "captured"]) captures.append(capture) if captures: ret['captures'] = captures bombings = [] for bombing_row in self.db.execute( """SELECT * FROM game_bombings WHERE playerhandle = ? AND game in (SELECT id FROM games %s)""" % (recentsums), (handle,)): bombing = {} dbselectors.rowtodict(bombing, bombing_row, ["game", None, None, "bombing", "bombed"]) bombings.append(bombing) if bombings: ret['bombings'] = bombings # Sums of data if self.flags['recentsums']: for t in ['frags', 'deaths', 'timealive', 'timeactive']: recent[t] = recentsum(t) # Damage if self.flags['damage']: recent["damage"] = self.db.execute( """SELECT (sum(damage1) + sum(damage2)) FROM game_weapons WHERE %s AND playerhandle = ? AND game IN (SELECT id FROM games WHERE mode != re_mode(id, 'race')) %s""" % (self.vlimit(), recentsums), (ret["handle"],)).fetchone()[0] if self.flags['weapons']: #Weapon Data for weapon in redeclipse().weaponlist: wr = {'name': weapon} recentsum = lambda x: self.db.execute( """SELECT sum(%s) FROM (SELECT * FROM game_weapons WHERE weapon = ? AND playerhandle = ? AND game IN (SELECT id FROM games WHERE mode != re_mode(id, 'race')) AND %s %s)""" % (x, self.vlimit(), recentsums), (weapon, ret['handle'])).fetchone()[0] for t in redeclipse().weapcols: wr[t] = recentsum(t) recent['weapons'][weapon] = wr ret["recent"] = recent return ret
def single(request, db, specific): playerselector = dbselectors.get('player', db, {'recentsums': [-1]}) playerselector.flags_none() playerselector.weakflags( ['games', 'damage', 'recentgames', 'recentsums', 'weapons'], True) recentplayerselector = dbselectors.get('player', db, {'recentsums': [recentlimit]}) recentplayerselector.flags_none() recentplayerselector.weakflags( ['games', 'damage', 'recentsums', 'weapons'], True) gameselector = dbselectors.get('game', db) gameselector.flags_none() player = playerselector.single(specific) recentplayer = recentplayerselector.single(specific) if utils.sok(player) and utils.sok(recentplayer): #Top map topmap = "-" maps = {} for row in db.execute('''SELECT map FROM games WHERE id IN (SELECT game FROM game_players WHERE handle = ? ORDER by ROWID DESC LIMIT %d)''' % recentlimit, (player["handle"],)): if row[0] not in maps: maps[row[0]] = 0 maps[row[0]] += 1 if maps: t = sorted(maps, key=lambda x: -maps[x])[0] topmap = web.link('/map/', t, t) # Play time timeplayed = timeutils.durstr(player["recent"]["timeactive"], skip="s", skiplow=False, full=True) #DPM try: dpm = "%d" % (round(player["recent"]["damage"] / (player["recent"]["timealive"] / 60))) except TypeError: dpm = "-" #Frag ratio try: fratio = "%.2f [%d / %d]" % ((player["recent"]["frags"] / max(1, player["recent"]["deaths"])), player["recent"]["frags"], player["recent"]["deaths"]) except TypeError: fratio = "-" #Recent Games gamestable = web.Table(["Game", "Mode", "Mutators", "Map", "Time", "Played As", "Score", "Frags", "Deaths"]) for gid in sorted( list(player["recentgames"].keys()), reverse=True)[:5]: game = player["recentgames"][gid] entry = game["player"] with gamestable.tr as tr: tr(web.link('/game/', gid, "Game #%d" % gid)) tr(web.link('/mode/', game["mode"], redeclipse(game).modeimg(game["mode"]))) tr(redeclipse(game).mutslist(game, True) or '-') tr(web.link("/map/", game["map"], game["map"], True)) tr(timeutils.agohtml(game["time"])) tr(cgi.escape(entry["name"])) tr(redeclipse(game).scorestr(game, entry["score"])) tr(entry["frags"]) tr(entry["deaths"]) #Weapons totalwielded = sum([w['timewielded'] for w in list(recentplayer['recent']['weapons'].values()) if w['timewielded'] is not None]) weaponstable = web.displays.weaponstable( recentplayer['recent']['weapons'], totalwielded, redeclipse().weaponlist) ret = """ <div class="center"> <h2>{player[name]}</h2> <h3>{player[handle]}</h3> <div class="colcontainer"> <div class="leftcol"> First appeared: {firstago}<br> Last appeared: {lastago}<br> </div> <div class="rightcol"> Most played map: {topmap}<br> Playing time: {timeplayed}<br> </div> </div> <div style="clear: both;"></div> <h3>Last {recentnum} Games</h3> Frag Ratio: {fratio}<br> DPM: {dpm}<br> <div class='display-table'> {games} <h5 style="text-align: left;"> <a href="/playergames/{player[handle]}"> All Games...</a></h5> </div> <div class='display-table small-table'> <h3>Weapon Statistics</h3> {weapons} </div> </div> """.format( player=player, firstago=web.link("/game/", player["games"][0], timeutils.agohtml( gameselector.single(player["games"][0])["time"])), lastago=web.link("/game/", player["games"][-1], timeutils.agohtml( gameselector.single(player["games"][-1])["time"])), topmap=topmap, timeplayed=timeplayed, dpm=dpm, fratio=fratio, games=gamestable.html(), weapons=weaponstable.html(), recentnum=recentlimit, ) else: ret = "<div class='center'><h2>No such player.</h2></div>" return web.page(ret, title="Player %s" % specific)
def single(request, db, specific): ret = "" mapselector = dbselectors.get('map', db) mapselector.flags_none() mapselector.weakflags(["race"], True) gmap = mapselector.single(specific) if utils.sok(gmap): # Game List pager = web.Pager(request, onpagecount, reversed(gmap["games"])) recentgames = web.Table( ["ID", "Mode", "Mutators", "Duration", "Played"]) gs = dbselectors.get('game', db) gs.flags_none() for gid in pager.list(): game = gs.single(gid) with recentgames.tr as tr: tr(web.link("/game/", gid, "Game #%d" % gid)) tr(web.link("/mode/", game["mode"], redeclipse(game).modeimg(game["mode"]))) tr(redeclipse(game).mutslist(game, True) or '-') tr(timeutils.durstr(round(game["timeplayed"]))) tr(timeutils.agohtml(game["time"])) # Race Times racetable = web.Table(["Time", "Player", "Handle", "Game", "When"]) for race in gmap["topraces"][:3]: with racetable.tr as tr: tr(timeutils.durstr(race["time"] / 1000, dec=True, full=True)) tr(web.linkif('/player/', race["gameplayer"]["handle"], race["gameplayer"]["name"])) tr(web.linkif('/player/', race["gameplayer"]["handle"], race["gameplayer"]["handle"] or '-')) tr(web.link('/game/', race["game"]["id"], "Game #%d" % race["game"]["id"])) tr(timeutils.agohtml(race["game"]["time"])) racetimes = """ <div class='display-table small-table'> <h3>Top Race Times</h3> %s </div> """ % racetable.html() eracetable = web.Table(["Time", "Player", "Handle", "Game", "When"]) for race in gmap["toperaces"][:3]: with eracetable.tr as tr: tr(timeutils.durstr(race["time"] / 1000, dec=True, full=True)) tr(web.linkif('/player/', race["gameplayer"]["handle"], race["gameplayer"]["name"])) tr(web.linkif('/player/', race["gameplayer"]["handle"], race["gameplayer"]["handle"] or '-')) tr(web.link('/game/', race["game"]["id"], "Game #%d" % race["game"]["id"])) tr(timeutils.agohtml(race["game"]["time"])) eracetimes = """ <div class='display-table small-table'> <h3>Top Endurance Race Times</h3> %s </div> """ % eracetable.html() ret += """ <div class="center"> <h2>{map[name]}</h2> {racetimes} {eracetimes} <div class='display-table'> <h3>Recent Games</h3> {recentgames} {pages} </div> </div> """.format(map=gmap, recentgames=recentgames.html(), racetimes=racetimes if gmap["toprace"]["time"] else '', eracetimes=eracetimes if gmap["toperace"]["time"] else '', pages=pager.html()) else: ret = "<div class='center'><h2>No such map.</h2></div>" return web.page(ret, title="Map %s" % specific)
def page(sel): recentgames = "" gs = dbselectors.GameSelector() gs.copyfrom(sel) gs.pathid = None gs.qopt = api.Qopt({ "recent": [True], }) games = gs.getdict(last=10) for gid, game in sorted(list(games.items()), key=lambda x: -x[0]): recentgames += '<tr>' recentgames += tdlink("game", gid, "Game #%d" % gid) recentgames += tdlink("mode", game["mode"], redeclipse(game).modeimg(game["mode"]), e=False) recentgames += "<td>%s</td>" % ( redeclipse(game).mutslist(game, True) or '-') ss = dbselectors.ServerSelector() ss.copyfrom(sel) desc = ss.single(game["server"])["desc"] recentgames += tdlink('server', game["server"], desc) recentgames += tdlink('map', game["map"], game["map"]) recentgames += '<td>%s</td>' % timeutils.durstr(round( game["timeplayed"])) recentgames += '<td>%s</td>' % timeutils.agohtml(game["time"]) recentgames += '</tr>' ws = dbselectors.WeaponSelector() ws.copyfrom(sel) ws.pathid = None weapons = {} for name in redeclipse().loadoutweaponlist: if sel.server.dbexists: weapon = ws.single(name)["recent"] weapons[name] = weapon topweapons = { 'wield': ('melee', 0), 'dpm': ('melee', 0), 'totalwielded': 0, } if weapons: best = sorted(list(weapons.items()), key=lambda weapon: -( weapon[1]["damage1"] / (max(weapon[1]["timewielded"], 1) / 60) + weapon[1]["damage2"] / (max(weapon[1]["timewielded"], 1) / 60)))[0] topweapons['dpm'] = (best[0], (best[1]["damage1"] / (max(best[1]["timewielded"], 1) / 60) + best[1]["damage2"] / (max(best[1]["timewielded"], 1) / 60))) topweapons['totalwielded'] = sum([w['timewielded'] for w in list(weapons.values())]) best = sorted(list(weapons.items()), key=lambda weapon: -( max(weapon[1]["timewielded"], 1)))[0] topweapons['wield'] = (best[0], best[1]["timewielded"]) def makeweapbest(e): if not e: return "" return alink("player", e[0][0], e[0][0]) ptcounters = { "captures": pt.gamelist(caches.caches["plsingle"].get( "captures", 7), num=5), "bombings": pt.gamelist(caches.caches["plsingle"].get( "bombings", 7), num=5), "spf": pt.gamelist(caches.caches["spm"].get("spf", 7), num=5), "affmvp": pt.gamelist(caches.caches["mvp"].get( "affmvp", 7), num=5), "dmmvp": pt.gamelist(caches.caches["mvp"].get( "dmmvp", 7), num=5), "games": pt.gamelist(caches.caches["plsingle"].get( "games", 30), num=5), "dpm": pt.gamelist(caches.caches["spm"].get("dpm", 30), num=5), "spm": pt.gamelist(caches.caches["spm"].get("spm", 30), num=5), "fpm": pt.gamelist(caches.caches["spm"].get("fpm", 30), num=5), "maps": pt.mapnum(sel, 90), "servers": pt.servernum(sel, 90), "ffa": pt.gamedivlist(caches.caches["plwinner"].get( "ffa", 90), num=5), "ffasurv": pt.gamedivlist(caches.caches["plwinner"].get( "ffasurv", 90), num=5), "sword": makeweapbest( caches.caches['plweapon'].get(('sword', 0), 7)), "sniper": makeweapbest( caches.caches['plweapon'].get(('rifle', 2), 7)) } ret = """ <h2>Recent Overview</h2> <h5><a href="/players">Players</a></h5> <h3>Last 7 Days</h3> <div class='display-table float-table'> <h5>Score/Frags</h5> <table> <tr> <th>Name</th> <th>S/F Ratio</th> </tr> {ptcounters[spf]} </table> </div> <div class='display-table float-table'> <h5> <span class="explain" title="Most Flag Captures">Captures</span></h5> <table> <tr> <th>Name</th> <th>Captures</th> </tr> {ptcounters[captures]} </table> </div> <div class='display-table float-table'> <h5> <span class="explain" title="Most Base Bombings">Bombings</span></h5> <table> <tr> <th>Name</th> <th>Bombings</th> </tr> {ptcounters[bombings]} </table> </div> <div class='display-table float-table'> <h5><span class="explain" title="Scores from CTF and BB">CTF/BB Team Scores</span></h5> <table> <tr> <th>Name</th> <th>Score</th> </tr> {ptcounters[affmvp]} </table> </div> <div class='display-table float-table'> <h5><span class="explain" title="Scores from DM">DM Team Scores</span></h5> <table> <tr> <th>Name</th> <th>Score</th> </tr> {ptcounters[dmmvp]} </table> </div> <div class='display-table float-table'> <h5>Best</h5> <table> <tr> <td><span class="explain" title="Best Damage and Frags with the Sword per minute">Knight</span></td> <td>{ptcounters[sword]}</td> </tr> <tr> <td><span class="explain" title="Best Damage and Frags with the Rifle Secondary per minute"> Sniper</span></td> <td>{ptcounters[sniper]}</td> </tr> </table> </div> <div style="clear: both;"></div> <h3>Last 30 Days</h3> <div class='display-table float-table'> <h5><a href="/ranks/spm" class="explain" title="Score Per Minute">SPM</a></h5> <table> <tr> <th>Name</th> <th>SPM</th> </tr> {ptcounters[spm]} </table> </div> <div class='display-table float-table'> <h5><a href="/ranks/dpm" class="explain" title="Damage Per Minute">DPM</a></h5> <table> <tr> <th>Name</th> <th>DPM</th> </tr> {ptcounters[dpm]} </table> </div> <div class='display-table float-table'> <h5><a class="explain" href="/ranks/fpm" title="Frags Per Minute">FPM</a></h5> <table> <tr> <th>Name</th> <th>FPM</th> </tr> {ptcounters[fpm]} </table> </div> <div class='display-table float-table'> <h5><a href="/ranks/games">Games</a></h5> <table> <tr> <th>Name</th> <th>Games</th> </tr> {ptcounters[games]} </table> </div> <div style="clear: both;"></div> <h3>Last 90 Days</h3> <div class='display-table float-table'> <h5><a href="/maps">Maps</a></h5> <table> <tr> <th>Name</th> <th>Games</th> </tr> {ptcounters[maps]} </table> </div> <div class='display-table float-table'> <h5><a href="/servers">Servers</a></h5> <table> <tr> <th>Name</th> <th>Games</th> </tr> {ptcounters[servers]} </table> </div> <div class='display-table float-table'> <h5><a href="/weapons">Weapons</a></h5> <table> <tr> <td>Best DPM</td> <td>{weapdpm}</td> </tr> <tr> <td>Most Wielded</td> <td>{weapwield}</td> </tr> </table> </div> <div class='display-table float-table'> <h5><a href="/ranks/ffa">FFA Win Ratio</a></h5> <table> <tr> <th>Name</th> <th>Games</th> </tr> {ptcounters[ffa]} </table> </div> <div class='display-table float-table'> <h5><a href="/ranks/ffasurv">FFA Survivor Win Ratio</a></h5> <table> <tr> <th>Name</th> <th>Games</th> </tr> {ptcounters[ffasurv]} </table> </div> <div style="clear: both;"></div> <div class='display-table'> <h5><a href="/games">Latest Games</a></h5> <table> <tr> <th>ID</th> <th>Mode</th> <th>Mutators</th> <th>Server</th> <th>Map</th> <th>Duration</th> <th>Played</th> </tr> {recentgames} </table> </div> <div style="clear: both;"></div> """.format(recentgames=recentgames, ptcounters=ptcounters, topweapon="\n".join(topweapons), weapdpm="%s %s [%d DPM]" % ( redeclipse().weaponimg(topweapons['dpm'][0]), alink('weapon', topweapons['dpm'][0], topweapons['dpm'][0]), topweapons['dpm'][1]), weapwield="%s %s [%d%%]" % ( redeclipse().weaponimg(topweapons['wield'][0]), alink('weapon', topweapons['wield'][0], topweapons['wield'][0]), topweapons['wield'][1] / max(topweapons['totalwielded'], 1) * 100)) return base.page(sel, ret, title="Overview")
def fromrow(self, row): if not row: return {} ret = { "teams": {}, "players": {}, "weapons": {}, } # Base dbselectors.rowtodict(ret, row, ["id", "time", "map", "mode", "mutators", "timeplayed"]) ret["version"] = self.db.execute( """SELECT version FROM game_servers WHERE game = %d""" % ret['id']).fetchone()[0] # Server handle if self.flags["server"]: ret["server"] = self.db.execute( """SELECT handle FROM game_servers WHERE game = %d""" % ret['id']).fetchone()[0] # Teams if self.flags["teams"]: for team_row in self.db.execute( "SELECT * FROM game_teams WHERE game = %d" % row[0]): team = {} dbselectors.rowtodict(team, team_row, [None, "team", "score", "name"]) ret["teams"][team["name"]] = team # Affinities captures = [] bombings = [] if self.flags["affinities"]: # Flag Captures for capture_row in self.db.execute( "SELECT * FROM game_captures WHERE game = %d" % row[0]): capture = {} dbselectors.rowtodict(capture, capture_row, [None, "player", "playerhandle", "capturing", "captured"]) captures.append(capture) if captures: ret['captures'] = captures # Base Bombings for bombing_row in self.db.execute( "SELECT * FROM game_bombings WHERE game = %d" % row[0]): bombing = {} dbselectors.rowtodict(bombing, bombing_row, [None, "player", "playerhandle", "bombing", "bombed"]) bombings.append(bombing) if bombings: ret['bombings'] = bombings # FFA Rounds if self.flags["rounds"]: ffarounds = [] for ffaround_row in self.db.execute( "SELECT * FROM game_ffarounds WHERE game = %d" % row[0]): ffaround = {} dbselectors.rowtodict(ffaround, ffaround_row, [None, "player", "playerhandle", "round", "winner"]) ffarounds.append(ffaround) if ffarounds: ret['ffarounds'] = ffarounds # Players if self.flags["players"]: for player_row in self.db.execute( "SELECT * FROM game_players WHERE game = %d" % row[0]): player = { "weapons": {}, "captures": [], "bombings": [], } dbselectors.rowtodict(player, player_row, [None, "name", "handle", "score", "timealive", "frags", "deaths", "id", "timeactive"]) #Player total damage if self.flags["playerdamage"]: player["damage"] = self.db.execute( """SELECT (sum(damage1) + sum(damage2)) FROM game_weapons WHERE game = %d AND player = %s""" % ( row[0], player["id"])).fetchone()[0] or 0 if self.flags["playeraffinities"]: for capture in captures: if capture["player"] == player["id"]: player["captures"].append(capture) for bombing in bombings: if bombing["player"] == player["id"]: player["bombings"].append(bombing) if self.flags["playerweapons"]: cols = ["weapon"] + redeclipse(ret).weapcols for wrow in self.db.execute(""" SELECT %s FROM game_weapons WHERE game = %d AND player = %d""" % ( ','.join(cols), ret['id'], player_row[7] )): weapon = wrow[0] w = {'name': weapon} for colidx in range(len(cols) - 1): colidx += 1 t = cols[colidx] try: w[t] = wrow[colidx] except TypeError: w[t] = 0 player["weapons"][weapon] = w ret["players"][player['id']] = player # Weapons if self.flags["weapons"]: for weapon in redeclipse(ret).weaponlist: w = {'name': weapon} gameweapsum = lambda x: self.db.execute( """SELECT sum(%s) FROM game_weapons WHERE weapon = ? AND game = %d""" % ( x, ret['id']), (weapon,)).fetchone()[0] for t in redeclipse(ret).weapcols: w[t] = gameweapsum(t) ret['weapons'][weapon] = w return ret
def single(request, db, specific): gs = dbselectors.get('game', db) gs.flags_none() gs.weakflags(["server", "teams", "affinities", "rounds", "players", "playerdamage", "weapons"], True) ss = dbselectors.get('server', db) ss.flags_none() game = gs.single(specific) ret = "" if utils.sok(game): server = ss.single(game["server"]) # Display the server's desc & version from this game. serverrow = db.execute( """SELECT version,desc,host,port FROM game_servers WHERE game = %d""" % game["id"] ).fetchone() server["version"] = serverrow[0] server["desc"] = cgi.escape(serverrow[1]) or cgi.escape( "%s:%d" % (serverrow[2], serverrow[3])) playerstable = web.Table( ["Name", "Score", "Handle", "Alive", "Frags", "Deaths"], "Players", "display-table") for player in sorted( list(game["players"].values()), key=lambda x: ( redeclipse(game).scorenum(game, x["score"]))): with playerstable.tr as tr: tr(web.linkif('/player/', player["handle"], player["name"])) tr(redeclipse(game).scorestr(game, player["score"])) tr(web.linkif('/player/', player["handle"], player["handle"])) tr(timeutils.durstr(player["timealive"])) tr(player["frags"]) tr(player["deaths"]) teamstable = None teamlist = {} if len(game["teams"]) > 1: teamstable = web.Table( ["Name", "Score"], "Teams", "display-table small-table") # Sort depending on score, counting race times for team in sorted(sorted(game["teams"], key=lambda x: game["teams"][x]["score"] * ( 1 if game["mode"] == redeclipse(game).modes["race"] and (game["mutators"] & redeclipse(game).mutators["timed"]) else -1 )), key=lambda x: game["teams"][x]["score"] == 0): team = game["teams"][team] teamlist[team["team"]] = team with teamstable.tr as tr: tr("%s %s" % ( redeclipse(game).teamimg(team["team"]), cgi.escape(team["name"]) )) tr(redeclipse(game).scorestr(game, team["score"])) ffarounds = web.Table(["Round", "Winner", "Versus"], "Rounds", "display-table small-table") if "ffarounds" in game: donerounds = [] for ffaround in sorted(game["ffarounds"], key=lambda x: x["round"]): if ffaround["round"] in donerounds: continue haswinner = False for ffaround_s in game["ffarounds"]: if (ffaround_s["round"] == ffaround["round"] and ffaround_s["winner"]): haswinner = True break versuslist = [] for ffaround_s in game["ffarounds"]: if (ffaround_s["round"] == ffaround["round"] and not ffaround_s["winner"]): versuslist.append(web.linkif( "/player/", ffaround_s["playerhandle"], game["players"][ffaround_s["player"]]["name"])) with ffarounds.tr as tr: if haswinner and ffaround["winner"]: tr(ffaround["round"]) tr(web.linkif( "/player/", ffaround["playerhandle"], game["players"][ffaround["player"]]["name"])) if versuslist: tr(", ".join(versuslist)) else: tr("<i>AI</i>") elif not haswinner: donerounds.append(ffaround["round"]) if len(versuslist) == 1: tr(ffaround["round"]) tr('<i>AI</i>') tr(", ".join(versuslist)) else: tr(ffaround["round"]) tr('<i>Epic fail!</i>') tr(", ".join(versuslist)) affinitiestable = None if "captures" in game: affinitiestable = web.Table( ["Player", "Capturing Team", "Captured Flag"], "Flag Captures", "display-table" ) for capture in game["captures"]: with affinitiestable.tr as tr: tr(web.linkif('/player/', capture["playerhandle"], game["players"][capture["player"]]["name"])) tr(cgi.escape(teamlist[capture["capturing"]]["name"])) tr(cgi.escape(teamlist[capture["captured"]]["name"])) elif "bombings" in game: affinitiestable = web.Table( ["Player", "Bombing Team", "Bombed Base"], "Base Bombings", "display-table" ) for bombing in game["bombings"]: with affinitiestable.tr as tr: tr(web.linkif('/player/', bombing["playerhandle"], game["players"][bombing["player"]]["name"])) tr(cgi.escape(teamlist[bombing["bombing"]]["name"])) tr(cgi.escape(teamlist[bombing["bombed"]]["name"])) totalwielded = sum([w['timewielded'] for w in list(game['weapons'].values()) if w['timewielded'] is not None]) weaponstable = web.displays.weaponstable(game['weapons'], totalwielded, redeclipse(game).weaponlist, version=game) if game["mode"] == redeclipse(game).modes['race']: weaponstable = None ret = """ <div class="center"> <h2>Game #{game[id]}: {modestr} on {mapstr}</h2> {mutsstr} Duration: {duration}<br> Played: {agohtml}<br> Server: <a href="/server/{server[handle]}">{server[desc]} [{server[version]}] [{server[handle]}]</a> {teams} {players} {affinities} {ffarounds} {weapons} </div> """.format( game=game, modestr=web.link('/mode/', game["mode"], redeclipse(game).modeimg(game["mode"], 32)), mutsstr=("Mutators: %s<br>" % redeclipse(game).mutslist( game, True, True)) if game['mutators'] else '', mapstr=web.link('/map/', game["map"], game["map"]), server=server, agohtml=timeutils.agohtml(game["time"]), duration=timeutils.durstr(game["timeplayed"]), players=playerstable.html(True), teams=teamstable.html(True) if teamstable is not None else "", affinities=affinitiestable.html(True) if affinitiestable is not None else "", ffarounds=ffarounds.html(True) if "ffarounds" in game else "", weapons=weaponstable.html(True) if weaponstable is not None else "", ) else: ret = "<div class='center'><h2>No such game.</h2></div>" return web.page(ret, title="Game %s" % specific)
def single(self, num, one=True): if not hasattr(self, 'minimal'): self.minimal = False row = self.db.con.execute( """SELECT * FROM games WHERE id = ?""", (num,)).fetchone() if not row: return None ret = { "teams": {}, "players": [], "weapons": {}, } dictfromrow(ret, row, ["id", "time", "map", "mode", "mutators", "timeplayed"]) ret["version"] = self.db.con.execute( """SELECT version FROM game_servers WHERE game = %d""" % ret['id']).fetchone()[0] if self.minimal == "basic": return ret ret["server"] = self.db.con.execute( """SELECT handle FROM game_servers WHERE game = %d""" % ret['id']).fetchone()[0] # Minimal Sets if self.minimal == "basicserver": return ret if self.minimal in ["basicplayer", "basicplayer2"]: for player_row in self.db.con.execute( "SELECT * FROM game_players WHERE game = %d" % row[0]): player = {} dictfromrow(player, player_row, [None, "name", "handle", "score", "timealive", "frags", "deaths", "id", "timeactive"]) if self.minimal == 'basicplayer2': player["damage"] = self.db.con.execute( """SELECT (sum(damage1) + sum(damage2)) FROM game_weapons WHERE game = %d AND player = %s""" % ( row[0], player["id"])).fetchone()[0] ret["players"].append(player) return ret # Teams for team_row in self.db.con.execute( "SELECT * FROM game_teams WHERE game = %d" % row[0]): team = {} dictfromrow(team, team_row, [None, "team", "score", "name"]) ret["teams"][team["name"]] = team #Affinities captures = [] for capture_row in self.db.con.execute( "SELECT * FROM game_captures WHERE game = %d" % row[0]): capture = {} dictfromrow(capture, capture_row, [None, "player", "playerhandle", "capturing", "captured"]) captures.append(capture) if captures: ret['captures'] = captures bombings = [] for bombing_row in self.db.con.execute( "SELECT * FROM game_bombings WHERE game = %d" % row[0]): bombing = {} dictfromrow(bombing, bombing_row, [None, "player", "playerhandle", "bombing", "bombed"]) bombings.append(bombing) if bombings: ret['bombings'] = bombings #Rounds if one: ffarounds = [] for ffaround_row in self.db.con.execute( "SELECT * FROM game_ffarounds WHERE game = %d" % row[0]): ffaround = {} dictfromrow(ffaround, ffaround_row, [None, "player", "playerhandle", "round", "winner"]) ffarounds.append(ffaround) if ffarounds: ret['ffarounds'] = ffarounds #Full Players for player_row in self.db.con.execute( "SELECT * FROM game_players WHERE game = %d" % row[0]): player = { "weapons": {}, "captures": [], "bombings": [], } dictfromrow(player, player_row, [None, "name", "handle", "score", "timealive", "frags", "deaths", "id", "timeactive"]) player["damage"] = self.db.con.execute( """SELECT (sum(damage1) + sum(damage2)) FROM game_weapons WHERE game = %d AND player = %s""" % ( row[0], player["id"])).fetchone()[0] for capture in captures: if capture["player"] == player["id"]: player["captures"].append(capture) for bombing in bombings: if bombing["player"] == player["id"]: player["bombings"].append(bombing) if one: for weapon in redeclipse(ret).weaponlist: w = {'name': weapon} for t in redeclipse(ret).weapcols: try: w[t] = self.db.con.execute(""" SELECT %s FROM game_weapons WHERE game = %d AND player = %d AND weapon = ?""" % ( t, ret['id'], player_row[7] ), (weapon,)).fetchone()[0] except TypeError: w[t] = 0 player["weapons"][weapon] = w ret["players"].append(player) if one: for weapon in redeclipse(ret).weaponlist: w = {'name': weapon} gameweapsum = lambda x: self.db.con.execute( """SELECT sum(%s) FROM game_weapons WHERE weapon = ? AND game = %d""" % ( x, ret['id']), (weapon,)).fetchone()[0] for t in redeclipse(ret).weapcols: w[t] = gameweapsum(t) ret['weapons'][weapon] = w return ret
def make_multi(self): ret = {} self.weakflags(['recentgames'], False, True) for mode in list(redeclipse().modes.values()): ret[mode] = self.single(mode) return ret