Beispiel #1
0
def search_game(user_id: int, seconds: int) -> None:
    '''If there is appropriate game request, it starts a new game.
       Else it makes the game request and adds it to the database.'''
    user = User.get(user_id)
    with rom.util.EntityLock(user, 10, 10):
        game_requests = \
                rom.query.Query(GameRequest).filter(time=seconds).all()

        added_to_existed = False
        if game_requests:
            accepted_request = \
                min(game_requests,
                    key=lambda x: abs(User.get(x.user_id).rating - user.rating))
            if abs(user.rating -
                   User.get(accepted_request.user_id).rating) <= 200:
                added_to_existed = True

                accepted_request.delete()
                user_to_play_with = User.get(accepted_request.user_id)

                game = Game(
                    white_user=user,
                    black_user=user_to_play_with,
                    white_rating=user.rating,
                    black_rating=user_to_play_with.rating,
                    is_started=0,
                )
                tdelta = timedelta(seconds=seconds)
                game.total_clock = tdelta
                game.white_clock = tdelta
                game.black_clock = tdelta
                game.save()

                user.cur_game_id = game.id
                user.save()

                with rom.util.EntityLock(user_to_play_with, 10, 10):
                    user_to_play_with.cur_game_id = game.id
                    user_to_play_with.in_search = False
                    user_to_play_with.save()

                sio.emit(
                    'redirect',
                    {'url': f'/game/{game.id}'},
                    room=user.sid,
                )
                sio.emit(
                    'redirect',
                    {'url': f'/game/{game.id}'},
                    room=user_to_play_with.sid,
                )
                start_game.delay(game.id)

        if added_to_existed is False:
            user.in_search = True
            user.save()

            game_request = GameRequest(time=seconds, user_id=user_id)
            game_request.save()
Beispiel #2
0
def user_profile(nickname: str):
    user = User.get_by(login=nickname)
    if not user:
        return render_template('404.html'), 404
    return render_template('user_profile.html',
                           title=f"{user.login}'s profile - Hydra Chess",
                           nickname=user.login,
                           rating=user.rating,
                           avatar_hash=user.avatar_hash)
Beispiel #3
0
def login_content_validator(form, field):
    login = field.data

    if re.search(r'[^a-zA-Z0-9_]', login) is not None:
        raise StopValidation(message=('Only letters, digits and '
                                      'underscore are allowed'))

    if User.get_by(login=login.encode()):
        raise StopValidation(message=('Login already taken'))
Beispiel #4
0
    def tearDown(self):
        for game_id in self.used_game_ids:
            game = Game.get(game_id)
            game.delete()
        self.used_game_ids.clear()

        for user_id in self.used_user_ids:
            user = User.get(user_id)
            user.delete()
        self.used_user_ids.clear()
Beispiel #5
0
def update_k_factor(user_id: int) -> None:
    '''Updates k_factor by FIDE rules (after 2014)'''
    user = User.get(user_id)

    with rom.util.EntityLock(user, 10, 10):
        if user.k_factor == 40 and user.games_played >= 30:
            user.k_factor = 20
            user.save()

        if (user.k_factor == 20 and user.games_played >= 3
                and user.rating >= 2400):
            user.k_factor = 10
            user.save()
Beispiel #6
0
def cancel_search(user_id: int):
    '''Cancel game search, if it's possible'''
    user = User.get(user_id)

    if not user.in_search:
        return

    with rom.util.EntityLock(user, 10, 10):
        user.in_search = False
        user.save()

    game_request = GameRequest.get_by(user_id=user_id, _limit=(0, 1))
    if game_request:
        game_request[0].delete()
Beispiel #7
0
def sign_in():
    if current_user.is_authenticated:
        return redirect('/')

    form = LoginForm()
    if form.validate_on_submit():
        user = User.get_by(login=form.login.data)
        if user and user.check_password(form.password.data):
            login_user(user, remember=form.remember_me.data)
            return redirect("/")
        return render_template('sign_in.html',
                               title="Sign in",
                               message="Wrong login or password",
                               form=form)
    return render_template('sign_in.html', title="Sign in", form=form)
Beispiel #8
0
def register():
    if current_user.is_authenticated:
        return redirect('/')
    form = RegisterForm()
    if form.validate_on_submit():
        user = User(login=form.login.data)
        user.set_password(form.password.data)
        user.save()

        login_user(user)
        return redirect('/')

    return render_template('register.html', title='Register', form=form)
Beispiel #9
0
def on_connect(*args, **kwargs) -> None:
    game_id = request.args.get('game_id')
    game = None
    try:
        game_id = int(game_id)
    except (ValueError, TypeError):
        pass

    if isinstance(game_id, int):
        game = Game.get(game_id)

    if current_user.is_authenticated:
        cur_user = User.get(current_user.id)
        with EntityLock(cur_user, 10, 10):
            cur_user.sid = request.sid
            cur_user.save()

        if not game:
            if cur_user.cur_game_id:
                sio.emit(
                    'redirect',
                    {'url': f'/game/{cur_user.cur_game_id}'},
                    room=cur_user.sid,
                )
            return

    is_player = current_user.is_authenticated and\
        current_user.id in (game.white_user.id, game.black_user.id)

    #  If the user is player and game isn't finished, we update user sid and
    #   reconnect him to the game.
    #  If the game is finished, we only send game info to the user.
    #  If the game isn't finished and user isn't player, we send him the game
    #   info and join him to the game room.

    if is_player and not game.is_finished:
        game_management.reconnect.delay(current_user.id, game_id)
    elif game.is_finished:
        game_management.send_game_info.delay(game_id, request.sid, is_player)
        # TODO: disconnect here
    else:
        game_management.send_game_info.delay(game_id, request.sid, False)
        join_room(game_id)
Beispiel #10
0
def load_user(user_id: int) -> User:
    return User.get(user_id)
Beispiel #11
0
def update_rating(user_id: int, rating_delta: int) -> None:
    '''Update database info about user's rating'''
    user = User.get(user_id)
    with rom.util.EntityLock(user, 10, 10):
        user.rating += rating_delta
        user.save()