Esempio n. 1
0
def upload_pic():
    file_bytes = request.data
    print 'upload pic', len(file_bytes)

    if not current_user.is_authenticated:
        return json.dumps({
            'success': False,
            'message': 'User is not logged in.',
        })

    user_id = current_user.user_id
    user = db_service.get_user_by_id(user_id)
    if user is None:
        return json.dumps({
            'success': False,
            'message': 'User does not exist.',
        })

    if len(file_bytes) > PROFILE_PIC_SIZE_LIMIT:
        return json.dumps({
            'success': False,
            'message': 'File is too large (max size 64KB).',
        })

    try:
        key = 'profile-pics/' + str(uuid.uuid4())
        s3.upload_data('com-kfchess-public',
                       key,
                       file_bytes,
                       ACL='public-read')
        url = s3.get_public_url('com-kfchess-public', key)
        print 's3 upload', key, url

        db_service.update_user(user_id, user.username, url)
        user = db_service.get_user_by_id(user_id)
        response = {
            'success': True,
            'user': user.to_json_obj(),
        }
    except:
        traceback.print_exc()
        response = {
            'success': False,
            'message': 'Failed to upload profile picture.',
        }

    return json.dumps(response)
Esempio n. 2
0
def update():
    data = json.loads(request.data)
    print 'user update', data

    if not current_user.is_authenticated:
        return json.dumps({
            'success': False,
            'message': 'User is not logged in.',
        })

    user_id = current_user.user_id
    user = db_service.get_user_by_id(user_id)
    if user is None:
        return json.dumps({
            'success': False,
            'message': 'User does not exist.',
        })

    user.username = data.get('username', user.username)

    if len(user.username) < 3:
        return json.dumps({
            'success': False,
            'message': 'Username too short.',
        })
    elif len(user.username) > 24:
        return json.dumps({
            'success': False,
            'message': 'Username too long.',
        })

    try:
        db_service.update_user(user_id, user.username, user.picture_url)
        user = db_service.get_user_by_id(user_id)
        response = {
            'success': True,
            'user': user.to_json_obj(),
        }
    except IntegrityError:
        response = {
            'success': False,
            'message': 'Username already taken.',
        }

    return json.dumps(response)
Esempio n. 3
0
def uping(data):
    data = json.loads(data)
    user_id = int(data['userId']) if data['userId'] is not None else None
    print 'uping', data

    if user_id:
        user = db_service.get_user_by_id(user_id)
        if user:
            # check if current game is still valid
            game_id = user.current_game and user.current_game['gameId']
            if game_id and game_id not in game_states:
                db_service.update_user_current_game(user_id, None, None)

            db_service.update_user_last_online(user_id)

    _emit_online_users(user_id)
Esempio n. 4
0
def check():
    game_id = request.args['gameId']
    print 'check', request.args

    if not current_user.is_authenticated:
        return json.dumps({
            'success': False,
            'message': 'User is not logged in.'
        })

    if game_id in game_states:
        return json.dumps({
            'success': True,
        })

    db_service.update_user_current_game(current_user.user_id, None, None)
    user = db_service.get_user_by_id(current_user.user_id)

    return json.dumps({
        'success': False,
        'user': user.to_json_obj(),
    })
Esempio n. 5
0
def new():
    data = json.loads(request.data)
    speed = data['speed']
    bots = data.get('bots', {})
    bots = {
        int(player): ai.get_bot(difficulty)
        for player, difficulty in bots.iteritems()
    }
    username = data.get('username')
    print 'new game', data

    # generate game ID and player keys
    game_id = generate_game_id()
    player_keys = {i: str(uuid.uuid4()) for i in xrange(1, 3) if i not in bots}

    # if logged in, add current user to game
    players = {i: 'b:%s' % bot.difficulty for i, bot in bots.iteritems()}
    if current_user.is_authenticated:
        players[1] = 'u:%s' % current_user.user_id

        user = db_service.get_user_by_id(current_user.user_id)
        if user.current_game:
            return json.dumps({
                'success': False,
                'message': 'User already in game.',
            })

        db_service.update_user_current_game(current_user.user_id, game_id,
                                            player_keys[1])

    # check opponent
    if username is not None:
        user = db_service.get_user_by_username(username)
        if user is None:
            return json.dumps({
                'success': False,
                'message': 'User to invite does not exist.',
            })

        if user.current_game is not None:
            return json.dumps({
                'success':
                False,
                'message':
                'User to invite is already in a game.',
            })

        players[2] = 'u:%s' % user.user_id
        db_service.update_user_current_game(user.user_id, game_id,
                                            player_keys[2])

        socketio.emit('invite', '', room=user.user_id)

    for i in xrange(1, 3):
        if i not in players:
            players[i] = 'o'

    # create game and add to game states
    game = Game(Speed(speed), players)
    for player in bots:
        game.mark_ready(player)

    game_states[game_id] = GameState(game_id, game, player_keys, bots)

    return json.dumps({
        'success': True,
        'gameId': game_id,
        'playerKeys': player_keys,
    })
Esempio n. 6
0
    def tick():
        start = time.time()
        tick_number = 0
        while True:
            try:
                # adjust sleep amount to avoid drift
                tick_number += 1
                next_tick = start + TICK_PERIOD * tick_number
                sleep_amount = next_tick - time.time()
                if sleep_amount > 0:
                    eventlet.sleep(sleep_amount)

                if tick_number % 600 == 0:
                    # log extra info and flush every minute
                    print 'game tick', tick_number
                    sys.stdout.flush()

                randnum = random.randint(0, 9999)

                current_time = time.time()
                expired_games = set()
                for game_id, game_state in game_states.iteritems():
                    game = game_state.game

                    if tick_number % 600 == 0:
                        # log extra info every minute
                        print 'game status', game_id, game.current_tick, game.players, game.finished

                    # keep games around for 10 min
                    if current_time - game.last_tick_time > 60 * 10:
                        expired_games.add(game_id)
                        continue

                    if not game.started or game.finished:
                        continue

                    moved = False

                    try:
                        # add to active games
                        if game.current_tick == 0 and game_state.replay is None:
                            db_service.add_active_game(
                                context.SERVER, game_id, {
                                    'players': game.players,
                                    'speed': game.speed.value,
                                    'startTime': str(
                                        datetime.datetime.utcnow()),
                                })
                    except:
                        traceback.print_exc()

                    try:
                        # check for bot moves (after game has been running for 1s)
                        if game.current_tick >= 10:
                            for player, bot in game_state.bots.iteritems():
                                move = bot.get_move(game, player, randnum)
                                if move:
                                    piece, row, col = move
                                    game.move(piece.id, player, row, col)
                                    moved = True
                    except:
                        traceback.print_exc()

                    try:
                        # check for replay moves
                        if game_state.replay:
                            for replay_move in game_state.replay.moves_by_tick[
                                    game.current_tick]:
                                game.move(replay_move.piece_id,
                                          replay_move.player, replay_move.row,
                                          replay_move.col)
                                moved = True
                    except:
                        traceback.print_exc()

                    try:
                        # tick game; if there are updates (or a bot/replay move), emit to room
                        status, updates = game.tick()
                        if status != 0 or updates or moved:
                            socketio.emit('update', {
                                'game': game.to_json_obj(),
                                'updates': updates,
                            },
                                          room=game_id,
                                          json=True)
                    except:
                        traceback.print_exc()

                    try:
                        # remove from active games and add to history
                        if game.finished and game_state.replay is None:
                            db_service.remove_active_game(
                                context.SERVER, game_id)

                            history_id = db_service.add_game_history(
                                Replay.from_game(game))
                            user_id1, user_id2 = None, None
                            for player, value in game.players.iteritems():
                                if not value.startswith('u:'):
                                    continue

                                user_id = int(value[2:])
                                if player == 1:
                                    user_id1 = user_id
                                elif player == 2:
                                    user_id2 = user_id

                                opponents = [
                                    v for k, v in game.players.iteritems()
                                    if k != player
                                ]
                                db_service.add_user_game_history(
                                    user_id, game.start_time, {
                                        'speed': game.speed.value,
                                        'player': player,
                                        'winner': game.finished,
                                        'historyId': history_id,
                                        'ticks': game.current_tick,
                                        'opponents': opponents,
                                    })

                            # update elo if two logged in users
                            if user_id1 and user_id2:
                                user1 = db_service.get_user_by_id(user_id1)
                                user2 = db_service.get_user_by_id(user_id2)

                                r1 = user1.ratings.get(game.speed.value,
                                                       DEFAULT_RATING)
                                r2 = user2.ratings.get(game.speed.value,
                                                       DEFAULT_RATING)
                                nr1, nr2 = elo.update_ratings(
                                    r1, r2, game.finished)

                                user1.ratings[game.speed.value] = nr1
                                user2.ratings[game.speed.value] = nr2
                                db_service.update_user_ratings(
                                    user_id1, user1.ratings)
                                db_service.update_user_ratings(
                                    user_id2, user2.ratings)

                                data = {
                                    '1': {
                                        'oldRating': r1,
                                        'newRating': nr1,
                                    },
                                    '2': {
                                        'oldRating': r2,
                                        'newRating': nr2,
                                    },
                                }

                                print 'new ratings', game_id, data
                                socketio.emit('newratings',
                                              data,
                                              room=game_id,
                                              json=True)

                            # update campaign progress
                            if game_state.level is not None and game.finished == 1:
                                progress = db_service.get_campaign_progress(
                                    user_id1)
                                progress.levels_completed[str(
                                    game_state.level)] = True

                                # check if belt is completed
                                belt = game_state.level / 8 + 1
                                belt_levels = xrange(8 * belt - 8, 8 * belt)
                                if (not progress.belts_completed.get(str(belt))
                                        and all(
                                            progress.levels_completed.get(
                                                str(level))
                                            for level in belt_levels)):
                                    progress.belts_completed[str(belt)] = True

                                    data = {
                                        'belt': belt,
                                    }

                                    print 'new belt', game_id, data
                                    socketio.emit('newbelt',
                                                  data,
                                                  room=game_id,
                                                  json=True)

                                db_service.update_campaign_progress(
                                    user_id1, progress)
                    except:
                        traceback.print_exc()

                # remove expired games
                for game_id in expired_games:
                    try:
                        print 'expiring', game_id
                        db_service.remove_active_game(context.SERVER, game_id)

                        game = game_states[game_id].game
                        for player, value in game.players.iteritems():
                            if not value.startswith('u:'):
                                continue

                            user_id = int(value[2:])
                            if player == 1:
                                user_id1 = user_id
                            elif player == 2:
                                user_id2 = user_id

                        if user_id1:
                            db_service.update_user_current_game(
                                user_id1, None, None)
                        if user_id2:
                            db_service.update_user_current_game(
                                user_id2, None, None)

                        del game_states[game_id]
                    except:
                        traceback.print_exc()
            except:
                traceback.print_exc()
Esempio n. 7
0
def campaign_start():
    data = json.loads(request.data)
    level = data['level']
    print 'campaign start', data

    if not current_user.is_authenticated:
        return json.dumps({
            'success': False,
            'message': 'User is not logged in.',
        })

    # check if user is already in game
    user_id = current_user.user_id
    user = db_service.get_user_by_id(user_id)
    if user.current_game:
        game_id = user.current_game['gameId']
        if game_id in game_states:
            game_state = game_states[game_id]
            if not game_state.game.started or game_state.game.finished:
                del game_states[game_id]
            else:
                return json.dumps({
                    'success': False,
                    'message': 'User already in game.',
                })

    # check that user has access to this level
    progress = db_service.get_campaign_progress(user_id)
    belt = level / 8 + 1
    if belt > 1 and not progress.belts_completed[str(belt - 1)]:
        return json.dumps({
            'success':
            False,
            'message':
            'User does not have access to this level.',
        })

    # create game and add to game states
    campaign_level = campaign.get_level(level)
    players = {1: 'u:%s' % user_id, 2: 'c:%s' % level}
    game = Game(Speed(campaign_level.speed),
                players,
                board=Board.from_str(campaign_level.board),
                is_campaign=True)
    game.mark_ready(2)

    game_id = generate_game_id()
    player_keys = {1: str(uuid.uuid4())}
    bots = {2: ai.get_bot('campaign')}
    game_states[game_id] = GameState(game_id,
                                     game,
                                     player_keys,
                                     bots,
                                     level=level)

    # update user current game
    db_service.update_user_current_game(user_id, game_id, player_keys[1])

    return json.dumps({
        'success': True,
        'gameId': game_id,
        'playerKeys': player_keys,
    })
Esempio n. 8
0
    def tick():
        start = time.time()
        tick_number = 0
        while True:
            # adjust sleep amount to avoid drift
            tick_number += 1
            next_tick = start + TICK_PERIOD * tick_number
            sleep_amount = next_tick - time.time()
            if sleep_amount > 0:
                eventlet.sleep(sleep_amount)

            randnum = random.randint(0, 9999)

            current_time = time.time()
            expired_games = set()
            for game_id, game_state in game_states.iteritems():
                game = game_state.game

                # keep games around for 10 min
                if current_time - game.last_tick_time > 60 * 10:
                    expired_games.add(game_id)
                    continue

                if not game.started or game.finished:
                    continue

                moved = False

                try:
                    # add to active games
                    if game.current_tick == 0 and game_state.replay is None:
                        db_service.add_active_game(
                            context.SERVER, game_id, {
                                'players': game.players,
                                'speed': game.speed.value,
                                'startTime': str(datetime.datetime.utcnow()),
                            })
                except:
                    traceback.print_exc()

                try:
                    # check for bot moves (after game has been running for 1s)
                    if game.current_tick >= 10:
                        for player, bot in game_state.bots.iteritems():
                            move = bot.get_move(game, player, randnum)
                            if move:
                                piece, row, col = move
                                game.move(piece.id, player, row, col)
                                moved = True
                except:
                    traceback.print_exc()

                try:
                    # check for replay moves
                    if game_state.replay:
                        for replay_move in game_state.replay.moves_by_tick[
                                game.current_tick]:
                            game.move(replay_move.piece_id, replay_move.player,
                                      replay_move.row, replay_move.col)
                            moved = True
                except:
                    traceback.print_exc()

                try:
                    # tick game; if there are updates (or a bot/replay move), emit to room
                    status, updates = game.tick()
                    if status != 0 or updates or moved:
                        socketio.emit('update', {
                            'game': game.to_json_obj(),
                            'updates': updates,
                        },
                                      room=game_id,
                                      json=True)
                except:
                    traceback.print_exc()

                try:
                    # remove from active games and add to history
                    if game.finished and game_state.replay is None:
                        db_service.remove_active_game(context.SERVER, game_id)

                        history_id = db_service.add_game_history(
                            Replay.from_game(game))
                        user_id1, user_id2 = None, None
                        for player, value in game.players.iteritems():
                            if not value.startswith('u:'):
                                continue

                            user_id = int(value[2:])
                            if player == 1:
                                user_id1 = user_id
                            elif player == 2:
                                user_id2 = user_id

                            opponents = [
                                v for k, v in game.players.iteritems()
                                if k != player
                            ]
                            db_service.add_user_game_history(
                                user_id, game.start_time, {
                                    'speed': game.speed.value,
                                    'player': player,
                                    'winner': game.finished,
                                    'historyId': history_id,
                                    'ticks': game.current_tick,
                                    'opponents': opponents,
                                })

                        # update elo if two logged in users
                        if user_id1 and user_id2:
                            user1 = db_service.get_user_by_id(user_id1)
                            user2 = db_service.get_user_by_id(user_id2)

                            r1 = user1.ratings.get(game.speed.value,
                                                   DEFAULT_RATING)
                            r2 = user2.ratings.get(game.speed.value,
                                                   DEFAULT_RATING)
                            nr1, nr2 = elo.update_ratings(
                                r1, r2, game.finished)

                            user1.ratings[game.speed.value] = nr1
                            user2.ratings[game.speed.value] = nr2
                            db_service.update_user_ratings(
                                user_id1, user1.ratings)
                            db_service.update_user_ratings(
                                user_id2, user2.ratings)

                            socketio.emit('newratings', {
                                '1': {
                                    'oldRating': r1,
                                    'newRating': nr1,
                                },
                                '2': {
                                    'oldRating': r2,
                                    'newRating': nr2,
                                },
                            },
                                          room=game_id,
                                          json=True)
                except:
                    traceback.print_exc()

            # remove expired games
            for game_id in expired_games:
                db_service.remove_active_game(context.SERVER, game_id)
                del game_states[game_id]
Esempio n. 9
0
def load_user(user_id):
    return db_service.get_user_by_id(user_id)