def ensure_valid_user():
    if request.method == "POST" and g.user and geoip.is_nok(request.remote_addr):
        user = g.user
        player = user.player

        if not user.forum_ban:
            ban = ForumBan(user_id=g.user.id)
            ban.save(commit=True)

        if player and not player.banned:
            libplayer.ban_player(player, source='invalid_user', commit=True)
Esempio n. 2
0
def ban_player(uuid):
    player = Player.query.filter_by(uuid=uuid).first()
    if not player:
        abort(404)

    reason = request.form.get('reason') or None

    libplayer.ban_player(player,
                         reason=reason,
                         with_ip=True,
                         by_user_id=g.user.id,
                         source='user_ban_player',
                         commit=True)

    return jsonify({'err': 0})
Esempio n. 3
0
def ban_player(uuid):
    player = Player.query.filter_by(uuid=uuid).first()
    if not player:
        abort(404)

    reason = request.form.get('reason') or None

    libplayer.ban_player(
        player,
        reason=reason,
        with_ip=True,
        by_user_id=g.user.id,
        source='user_ban_player',
        commit=True
    )

    return jsonify({
        'err': 0
    })
Esempio n. 4
0
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', []))
Esempio n. 5
0
def send_message(username):
    user = g.user
    player = user.player

    if user.forum_ban or (player and player.banned):
        rollbar.report_message('User blocked from sending a message', level='warning', request=request)
        return jsonify({
            'err': 1,
            'message': 'Oops, you are blocked from sending any messages. Awkward...'
        })

    body = request.form.get('body')

    to_user = User.query.outerjoin(Player).options(
        joinedload(User.player)
    ).filter(
        or_(Player.username == username, User.username == username)
    ).first()

    if to_user:
        to_player = to_user.player
    else:
        # for cases of messages sent to players with no users created yet
        to_player = Player.query.filter_by(username=username).first()

        if not to_player:
            rollbar.report_message('to_player None', request=request)
            return jsonify({
                'err': 1
            })

    if libmessages.is_sender_spamming(user, to_user, to_player):
        can_post = libforums.can_user_post(user)

        rollbar.report_message('User blocked from spamming messages', request=request, extra_data={
            'to_user_id': to_user.id if to_user else None,
            'to_player_id': to_player.id if to_player else None,
            'can-Post': can_post
        })

        if not can_post and not user.forum_ban:
            player = user.player
            libplayer.ban_player(player, source='message_spamming', commit=False)

            ban = ForumBan(user_id=user.id)
            ban.save(commit=True)

        return jsonify({
            'err': 1,
            'message': 'Whoa there, you sent too many messages recently! Try sending a bit later.'
        })

    message = Message(
        from_user=user,
        to_user=to_user,
        to_player=to_player,
        body=body,
        user_ip=request.remote_addr
    )

    message.save()

    notify_new_message(message)

    stats.incr('messages.created')

    return jsonify({
        'err': 0,
        'message': message.to_dict()
    })
Esempio n. 6
0
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', []))
Esempio n. 7
0
def send_message(username):
    user = g.user
    player = user.player

    if user.forum_ban or (player and player.banned):
        rollbar.report_message('User blocked from sending a message',
                               level='warning',
                               request=request)
        return jsonify({
            'err':
            1,
            'message':
            'Oops, you are blocked from sending any messages. Awkward...'
        })

    body = request.form.get('body')

    to_user = User.query.outerjoin(Player).options(joinedload(
        User.player)).filter(
            or_(Player.username == username,
                User.username == username)).first()

    if to_user:
        to_player = to_user.player
    else:
        # for cases of messages sent to players with no users created yet
        to_player = Player.query.filter_by(username=username).first()

        if not to_player:
            rollbar.report_message('to_player None', request=request)
            return jsonify({'err': 1})

    if libmessages.is_sender_spamming(user, to_user, to_player):
        can_post = libforums.can_user_post(user)

        rollbar.report_message('User blocked from spamming messages',
                               request=request,
                               extra_data={
                                   'to_user_id':
                                   to_user.id if to_user else None,
                                   'to_player_id':
                                   to_player.id if to_player else None,
                                   'can-Post': can_post
                               })

        if not can_post and not user.forum_ban:
            player = user.player
            libplayer.ban_player(player,
                                 source='message_spamming',
                                 commit=False)

            ban = ForumBan(user_id=user.id)
            ban.save(commit=True)

        return jsonify({
            'err':
            1,
            'message':
            'Whoa there, you sent too many messages recently! Try sending a bit later.'
        })

    message = Message(from_user=user,
                      to_user=to_user,
                      to_player=to_player,
                      body=body,
                      user_ip=request.remote_addr)

    message.save()

    notify_new_message(message)

    stats.incr('messages.created')

    return jsonify({'err': 0, 'message': message.to_dict()})