def get_player_list_data(server): server_status = api.get_server_status(server, minimal=True) if not server_status: return None server_status['players'].sort( key=lambda x: (x.get('nickname') or x['username']).lower()) usernames = [x['username'] for x in server_status['players']] players = Player.query.filter(Player.username.in_(usernames)).all() # Create player objects for players that don't exist on the server yet missing_usernames = set(usernames) - set(player.username for player in players) for username in missing_usernames: players.append(Player(username=username)) players.sort(key=lambda p: p.displayname.lower()) try: tps = int(math.ceil(float(server_status['tps']))) except ValueError: tps = 'N/A' return { 'players': players, 'server_id': server.id, 'num_players': server_status['numplayers'], 'max_players': server_status['maxplayers'], 'tps': tps }
def get_player_list_data(server): server_status = api.get_server_status(server, minimal=True) if not server_status: return None server_status['players'].sort(key=lambda x: (x.get('nickname') or x['username']).lower()) usernames = [x['username'] for x in server_status['players']] players = Player.query.filter( Player.username.in_(usernames) ).all() # Create player objects for players that don't exist on the server yet missing_usernames = set(usernames) - set(player.username for player in players) for username in missing_usernames: players.append( Player(username=username) ) players.sort(key=lambda p: p.displayname.lower()) try: tps = int(math.ceil(float(server_status['tps']))) except ValueError: tps = 'N/A' return { 'players': players, 'server_id': server.id, 'num_players': server_status['numplayers'], 'max_players': server_status['maxplayers'], 'tps': tps }
def player_list(request, server_id=None): stats = cache.get('minecraft-stats') if not stats: try: server_id = int(server_id or settings.MAIN_SERVER_ID) server = Server.objects.get(id=server_id) server_status = api.get_server_status(server) server_status['players'].sort(key=lambda x: (x.get('nickname') or x['username']).lower()) player_info = [] top10_player_ids = PlayerStats.objects.filter(server=server).order_by('-time_spent')[:10].values_list('player', flat=True) usernames = [x['username'] for x in server_status['players']] players = MinecraftPlayer.objects.filter(username__in=usernames) for player in players: rank = None if player.id in top10_player_ids: for index, top10player_id in enumerate(top10_player_ids): if player.id == top10player_id: rank = index + 1 player_info.append((player, rank)) # Create player objects for players that don't exist on the server yet missing_usernames = set(usernames) - set(player.username for player in players) missing_players = [MinecraftPlayer.factory(username=username) for username in missing_usernames] for player in missing_players: player_info.append((player, None)) player_info.sort(key=lambda x: x[0].displayname.lower()) stats = { 'player_info': player_info, 'num_players': server_status['numplayers'], 'max_players': server_status['maxplayers'], 'tps': server_status['tps'] } cache.set('minecraft-stats', stats, 5) except: pass return render_to_response('includes/playerlist.html', { 'stats': stats }, context_instance=RequestContext(request))
def _query_server(server, mojang_status): server_status = api.get_server_status(server) or {} player_stats = [] players_to_sync_ban = Player.query.filter( Player.uuid.in_(server_status.get('banned_uuids', [])), Player.banned == False).all() if players_to_sync_ban: player_ids_to_sync_ban = [x.id for x in players_to_sync_ban] Player.query.filter(Player.id.in_(player_ids_to_sync_ban)).update( { 'banned': True, }, synchronize_session=False) for player in players_to_sync_ban: AuditLog.create(AuditLog.PLAYER_BAN, player_id=player.id, username=player.username, source='server_sync', commit=False) online_player_ids = [] for player_info in server_status.get('players', []): username = player_info['username'] uuid = player_info['uuid'] player = Player.query.options(joinedload( Player.titles)).filter_by(uuid=uuid).first() if player: if player.username != username: h.avoid_duplicate_username(username) player.set_username(username) player.save(commit=False) else: h.avoid_duplicate_username(username) player = Player(username=username, uuid=uuid) player.save(commit=False) statsd.incr('player.created') online_player_ids.append(player.id) last_activity = PlayerActivity.query.filter_by( server=server, player=player).order_by(PlayerActivity.timestamp.desc()).first() # if the last activity for this player is an 'exit' activity (or there isn't an activity), # create a new 'enter' activity since they just joined this minute if not last_activity or last_activity.activity_type == PLAYER_ACTIVITY_TYPES[ 'exit']: enter = PlayerActivity( server=server, player=player, activity_type=PLAYER_ACTIVITY_TYPES['enter']) enter.save(commit=False) if server.id == app.config['MAIN_SERVER_ID']: if player.banned: player.banned = False AuditLog.create(AuditLog.PLAYER_UNBAN, player_id=player.id, username=player.username, source='server_sync', commit=False) nickname_ansi = player_info.get('nickname_ansi') nickname = player_info.get('nickname') player.nickname_ansi = nickname_ansi player.nickname = nickname player.save(commit=False) ip = player_info.get('address') if ip: if not IPTracking.query.filter_by(ip=ip, player=player).first(): existing_player_ip = IPTracking(ip=ip, player=player) existing_player_ip.save(commit=False) if geoip.is_nok(ip): libplayer.ban_player(player, with_ip=True, source='query', ip=ip, commit=False) stats = PlayerStats.query.filter_by(server=server, player=player).first() if not stats: stats = PlayerStats(server=server, player=player) stats.last_seen = datetime.utcnow() stats.pvp_logs = player_info.get('pvp_logs') stats.time_spent = (stats.time_spent or 0) + 1 stats.save(commit=False) titles = [{ 'name': x.name, 'broadcast': x.broadcast } for x in player.titles] player_stats.append({ 'username': player.username, 'uuid': player.uuid, 'minutes': stats.time_spent, 'rank': stats.rank, 'titles': titles }) five_minutes_ago = datetime.utcnow() - timedelta(minutes=10) result = PlayerStats.query.filter(PlayerStats.server == server, PlayerStats.last_seen > five_minutes_ago) recent_player_ids = [x.player_id for x in result] # find all players that have recently left and insert an 'exit' activity for them # if their last activity was an 'enter' for player_id in set(recent_player_ids) - set(online_player_ids): latest_activity = PlayerActivity.query.filter_by(server=server, player_id=player_id)\ .order_by(PlayerActivity.timestamp.desc()).first() if latest_activity and latest_activity.activity_type == PLAYER_ACTIVITY_TYPES[ 'enter']: ex = PlayerActivity(server=server, player_id=player_id, activity_type=PLAYER_ACTIVITY_TYPES['exit']) ex.save(commit=False) player_count = server_status.get('numplayers', 0) or 0 cpu_load = server_status.get('load', 0) or 0 tps = server_status.get('tps', 0) or 0 status = ServerStatus(server=server, player_count=player_count, cpu_load=cpu_load, tps=tps) status.save(commit=True) api.send_stats( server, { 'player_stats': player_stats, 'session': mojang_status.session, 'account': mojang_status.account, 'auth': mojang_status.auth }) _handle_groups(server, server_status.get('groups', []))
def _query_server(server, mojang_status): server_status = api.get_server_status(server) or {} player_stats = [] online_player_ids = [] for player_info in server_status.get('players', []): username = player_info['username'] uuid = player_info['uuid'] player = Player.query.options( joinedload(Player.titles) ).filter_by(uuid=uuid).first() if player: if player.username != username: AuditLog.create( AuditLog.PLAYER_RENAME, player_id=player.id, old_name=player.username, new_name=username, commit=False ) player.username = username player.save(commit=False) else: player = Player(username=username, uuid=uuid) player.save(commit=False) online_player_ids.append(player.id) last_activity = PlayerActivity.query.filter_by(server=server, player=player)\ .order_by(PlayerActivity.timestamp.desc()).first() # if the last activity for this player is an 'exit' activity (or there isn't an activity), # create a new 'enter' activity since they just joined this minute if not last_activity or last_activity.activity_type == PLAYER_ACTIVITY_TYPES['exit']: enter = PlayerActivity(server=server, player=player, activity_type=PLAYER_ACTIVITY_TYPES['enter']) enter.save(commit=False) # respect nicknames from the main server if server.id == app.config['MAIN_SERVER_ID']: nickname_ansi = player_info.get('nickname_ansi') nickname = player_info.get('nickname') player.nickname_ansi = nickname_ansi player.nickname = nickname player.save(commit=False) ip = player_info.get('address') if ip: if not IPTracking.query.filter_by(ip=ip, player=player).first(): existing_player_ip = IPTracking(ip=ip, player=player) existing_player_ip.save(commit=False) stats = PlayerStats.query.filter_by(server=server, player=player).first() if not stats: stats = PlayerStats(server=server, player=player) stats.last_seen = datetime.utcnow() stats.pvp_logs = player_info.get('pvp_logs') stats.time_spent = (stats.time_spent or 0) + 1 stats.save(commit=False) titles = [{'name': x.name, 'broadcast': x.broadcast} for x in player.titles] player_stats.append({ 'username': player.username, 'uuid': player.uuid, 'minutes': stats.time_spent, 'rank': stats.rank, 'titles': titles }) five_minutes_ago = datetime.utcnow() - timedelta(minutes=10) result = PlayerStats.query.filter(PlayerStats.server == server, PlayerStats.last_seen > five_minutes_ago) recent_player_ids = [x.player_id for x in result] # find all players that have recently left and insert an 'exit' activity for them # if their last activity was an 'enter' for player_id in set(recent_player_ids) - set(online_player_ids): latest_activity = PlayerActivity.query.filter_by(server=server, player_id=player_id)\ .order_by(PlayerActivity.timestamp.desc()).first() if latest_activity and latest_activity.activity_type == PLAYER_ACTIVITY_TYPES['enter']: ex = PlayerActivity(server=server, player_id=player_id, activity_type=PLAYER_ACTIVITY_TYPES['exit']) ex.save(commit=False) player_count = server_status.get('numplayers', 0) or 0 cpu_load = server_status.get('load', 0) or 0 tps = server_status.get('tps', 0) or 0 status = ServerStatus(server=server, player_count=player_count, cpu_load=cpu_load, tps=tps) status.save(commit=True) api.send_stats(server, { 'player_stats': player_stats, 'session': mojang_status.session, 'account': mojang_status.account, 'auth': mojang_status.auth }) _handle_groups(server, server_status.get('groups', []))
def _query_server(server, mojang_status): try: server_status = api.get_server_status(server) except: server_status = {} player_stats = [] online_player_ids = [] for player_info in server_status.get('players', []): try: player = MinecraftPlayer.objects.get( username=player_info.get('username')) except: player = MinecraftPlayer(username=player_info.get('username')) player.save() online_player_ids.append(player.id) try: last_activity = PlayerActivity.objects.filter( server=server, player=player).latest('timestamp') except: last_activity = None # if the last activity for this player is an 'exit' activity (or there isn't an activity), # create a new 'enter' activity since they just joined this minute if not last_activity or last_activity.activity_type == PLAYER_ACTIVITY_TYPES[ 'exit']: enter = PlayerActivity( server=server, player=player, activity_type=PLAYER_ACTIVITY_TYPES['enter']) enter.save() # respect nicknames from the main server if server.id == settings.MAIN_SERVER_ID: nickname_ansi = player_info.get('nickname_ansi') nickname = player_info.get('nickname') player.nickname_ansi = nickname_ansi player.nickname = nickname player.save() ip = player_info.get('address') if ip: try: IPTracking.objects.get(ip=ip, player=player) except: existing_player_ip = IPTracking(ip=ip, player=player) existing_player_ip.save() try: stats = PlayerStats.objects.get(server=server, player=player) stats.last_seen = datetime.utcnow() except: stats = PlayerStats(server=server, player=player) stats.pvp_logs = player_info.get('pvp_logs') stats.time_spent += 1 stats.save() player_stats.append({ 'username': player.username, 'minutes': stats.time_spent, 'rank': stats.get_rank() }) five_minutes_ago = datetime.utcnow() - timedelta(minutes=5) query = PlayerStats.objects.filter(server=server, last_seen__gt=five_minutes_ago) recent_player_ids = [x[0] for x in query.values_list('player_id')] # find all players that have recently left and insert an 'exit' activity for them # if their last activity was an 'enter' for player_id in set(recent_player_ids) - set(online_player_ids): try: latest_activity = PlayerActivity.objects.filter( server=server, player=player_id).latest('timestamp') except: latest_activity = None if latest_activity and latest_activity.activity_type == PLAYER_ACTIVITY_TYPES[ 'enter']: ex = PlayerActivity(server=server, player_id=player_id, activity_type=PLAYER_ACTIVITY_TYPES['exit']) ex.save() banned_players = server_status.get('banned_players', []) PlayerStats.objects.filter( server=server, player__username__in=banned_players).update(banned=True) PlayerStats.objects.filter(server=server).exclude( player__username__in=banned_players).update(banned=False) player_count = server_status.get('numplayers', 0) or 0 cpu_load = server_status.get('load', 0) or 0 tps = server_status.get('tps', 0) or 0 status = ServerStatus(server=server, player_count=player_count, cpu_load=cpu_load, tps=tps) status.save() api.send_stats( server, { 'player_stats': player_stats, 'login': mojang_status.login, 'session': mojang_status.session, 'account': mojang_status.account, 'auth': mojang_status.auth })
def _query_server(server, mojang_status): server_status = api.get_server_status(server) or {} player_stats = [] players_to_sync_ban = Player.query.filter( Player.uuid.in_(server_status.get('banned_uuids', [])), Player.banned == False ).all() if players_to_sync_ban: player_ids_to_sync_ban = [x.id for x in players_to_sync_ban] Player.query.filter( Player.id.in_(player_ids_to_sync_ban) ).update({ 'banned': True, }, synchronize_session=False) for player in players_to_sync_ban: AuditLog.create( AuditLog.PLAYER_BAN, player_id=player.id, username=player.username, source='server_sync', commit=False ) players = server_status.get('players', []) online_player_ids = [] players_to_nok_ban = [] for player_info in players: username = player_info['username'] uuid = player_info['uuid'] player = Player.query.options( joinedload(Player.titles) ).filter_by(uuid=uuid).first() if player: if player.username != username: h.avoid_duplicate_username(username) player.set_username(username) player.save(commit=False) else: h.avoid_duplicate_username(username) player = Player(username=username, uuid=uuid) player.save(commit=False) statsd.incr('player.created') online_player_ids.append(player.id) last_activity = PlayerActivity.query.filter_by( server=server, player=player ).order_by( PlayerActivity.timestamp.desc() ).first() # if the last activity for this player is an 'exit' activity (or there isn't an activity), # create a new 'enter' activity since they just joined this minute if not last_activity or last_activity.activity_type == PLAYER_ACTIVITY_TYPES['exit']: enter = PlayerActivity(server=server, player=player, activity_type=PLAYER_ACTIVITY_TYPES['enter']) enter.save(commit=False) if server.id == app.config['MAIN_SERVER_ID']: if player.banned: player.banned = False AuditLog.create( AuditLog.PLAYER_UNBAN, player_id=player.id, username=player.username, source='server_sync', commit=False ) nickname_ansi = player_info.get('nickname_ansi') nickname = player_info.get('nickname') player.nickname_ansi = nickname_ansi player.nickname = nickname player.save(commit=False) ip = player_info.get('address') if ip: if not IPTracking.query.filter_by(ip=ip, player=player).first(): existing_player_ip = IPTracking(ip=ip, player=player) existing_player_ip.save(commit=False) if geoip.is_nok(ip): players_to_nok_ban.append((player, ip)) stats = PlayerStats.query.filter_by(server=server, player=player).first() if not stats: stats = PlayerStats(server=server, player=player) stats.last_seen = datetime.utcnow() stats.pvp_logs = player_info.get('pvp_logs') stats.time_spent = (stats.time_spent or 0) + 1 stats.save(commit=False) titles = [{'name': x.name, 'broadcast': x.broadcast} for x in player.titles] player_stats.append({ 'username': player.username, 'uuid': player.uuid, 'minutes': stats.time_spent, 'rank': stats.rank, 'titles': titles }) if len(players) and (float(len(players_to_nok_ban)) / float(len(players))) < 0.5: for player, ip in players_to_nok_ban: libplayer.ban_player(player, with_ip=True, source='query', ip=ip, commit=False) five_minutes_ago = datetime.utcnow() - timedelta(minutes=10) result = PlayerStats.query.filter(PlayerStats.server == server, PlayerStats.last_seen > five_minutes_ago) recent_player_ids = [x.player_id for x in result] # find all players that have recently left and insert an 'exit' activity for them # if their last activity was an 'enter' for player_id in set(recent_player_ids) - set(online_player_ids): latest_activity = PlayerActivity.query.filter_by(server=server, player_id=player_id)\ .order_by(PlayerActivity.timestamp.desc()).first() if latest_activity and latest_activity.activity_type == PLAYER_ACTIVITY_TYPES['enter']: ex = PlayerActivity(server=server, player_id=player_id, activity_type=PLAYER_ACTIVITY_TYPES['exit']) ex.save(commit=False) player_count = server_status.get('numplayers', 0) or 0 cpu_load = server_status.get('load', 0) or 0 tps = server_status.get('tps', 0) or 0 status = ServerStatus(server=server, player_count=player_count, cpu_load=cpu_load, tps=tps) status.save(commit=True) api.send_stats(server, { 'player_stats': player_stats, 'session': mojang_status.session, 'account': mojang_status.account, 'auth': mojang_status.auth }) _handle_groups(server, server_status.get('groups', []))
def _query_server(server, mojang_status): try: server_status = api.get_server_status(server) except: server_status = {} player_stats = [] online_player_ids = [] for player_info in server_status.get('players', []): try: player = MinecraftPlayer.objects.get(username=player_info.get('username')) except: player = MinecraftPlayer(username=player_info.get('username')) player.save() online_player_ids.append(player.id) try: last_activity = PlayerActivity.objects.filter(server=server, player=player).latest('timestamp') except: last_activity = None # if the last activity for this player is an 'exit' activity (or there isn't an activity), # create a new 'enter' activity since they just joined this minute if not last_activity or last_activity.activity_type == PLAYER_ACTIVITY_TYPES['exit']: enter = PlayerActivity(server=server, player=player, activity_type=PLAYER_ACTIVITY_TYPES['enter']) enter.save() # respect nicknames from the main server if server.id == settings.MAIN_SERVER_ID: nickname_ansi = player_info.get('nickname_ansi') nickname = player_info.get('nickname') player.nickname_ansi = nickname_ansi player.nickname = nickname player.save() ip = player_info.get('address') if ip: try: IPTracking.objects.get(ip=ip, player=player) except: existing_player_ip = IPTracking(ip=ip, player=player) existing_player_ip.save() try: stats = PlayerStats.objects.get(server=server, player=player) stats.last_seen = datetime.utcnow() except: stats = PlayerStats(server=server, player=player) stats.pvp_logs = player_info.get('pvp_logs') stats.time_spent += 1 stats.save() player_stats.append({ 'username': player.username, 'minutes': stats.time_spent, 'rank': stats.get_rank() }) five_minutes_ago = datetime.utcnow() - timedelta(minutes=5) query = PlayerStats.objects.filter(server=server, last_seen__gt=five_minutes_ago) recent_player_ids = [x[0] for x in query.values_list('player_id')] # find all players that have recently left and insert an 'exit' activity for them # if their last activity was an 'enter' for player_id in set(recent_player_ids) - set(online_player_ids): try: latest_activity = PlayerActivity.objects.filter(server=server, player=player_id).latest('timestamp') except: latest_activity = None if latest_activity and latest_activity.activity_type == PLAYER_ACTIVITY_TYPES['enter']: ex = PlayerActivity(server=server, player_id=player_id, activity_type=PLAYER_ACTIVITY_TYPES['exit']) ex.save() banned_players = server_status.get('banned_players', []) PlayerStats.objects.filter(server=server, player__username__in=banned_players).update(banned=True) PlayerStats.objects.filter(server=server).exclude(player__username__in=banned_players).update(banned=False) player_count = server_status.get('numplayers', 0) or 0 cpu_load = server_status.get('load', 0) or 0 tps = server_status.get('tps', 0) or 0 status = ServerStatus(server=server, player_count=player_count, cpu_load=cpu_load, tps=tps) status.save() api.send_stats(server, { 'player_stats': player_stats, 'login': mojang_status.login, 'session': mojang_status.session, 'account': mojang_status.account, 'auth': mojang_status.auth })