def _handle_player(player): stats = PlayerStats.query.filter_by( player=player, server_id=app.config.get('MAIN_SERVER_ID') ).first() if stats and stats.last_seen > datetime.utcnow() - timedelta(days=1): # ignore players that have joined since the job started return False try: actual_username = minecraft_uuid.lookup_latest_username_by_uuid(player.uuid) except requests.RequestException as e: rollbar.report_message('Exception looking up uuid, skipping group', level='warning', extra_data={ 'exception': unicode(e) }) return False if not actual_username: rollbar.report_message('Error getting actual username, skipping', level='warning', extra_data={ 'uuid': player.uuid }) return False if actual_username != player.username: h.avoid_duplicate_username(actual_username, player.uuid) player.set_username(actual_username) player.save(commit=True) return True return False
def _handle_player(player): stats = PlayerStats.query.filter_by( player=player, server_id=app.config.get('MAIN_SERVER_ID') ).first() if stats and stats.last_seen > datetime.utcnow() - timedelta(days=1): # ignore players that have joined since the job started return False try: actual_username = minecraft_uuid.lookup_latest_username_by_uuid(player.uuid) except requests.RequestException as e: rollbar.report_message('Exception looking up uuid, skipping group', level='warning', extra_data={ 'exception': unicode(e) }) return False if not actual_username: rollbar.report_message('Error getting actual username, skipping', level='warning', extra_data={ 'uuid': player.uuid }) return False if actual_username != player.username: h.avoid_duplicate_username(actual_username) player.set_username(actual_username) player.save(commit=True) return True return False
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 = [] 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', []))