Esempio n. 1
0
def reset(data):
    data = json.loads(data)
    game_id = data['gameId']
    player_key = data['playerKey']
    print 'reset', data

    if game_id not in game_states:
        emit('notfound')
        return

    game_state = game_states[game_id]
    auth_player = get_auth_player(game_state, player_key)

    # can't reset an in-progress multiplayer game
    if game_state.level is None and not game_state.game.finished:
        return

    # only authenticated players can reset game
    if auth_player is not None:
        db_service.remove_active_game(context.SERVER, game_id)

        board = None
        if game_state.level is not None:
            campaign_level = campaign.get_level(game_state.level)
            board = Board.from_str(campaign_level.board)

        old_game = game_state.game
        game = Game(old_game.speed,
                    old_game.players,
                    num_players=old_game.num_players,
                    board=board,
                    is_campaign=old_game.is_campaign,
                    debug=old_game.debug)
        for player in game_state.bots:
            game.mark_ready(player)
        game_state.game = game

        emit('resetack', {
            'game': game.to_json_obj(),
        },
             room=game_id,
             json=True)
Esempio n. 2
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. 3
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]