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()
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)
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'))
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()
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()
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()
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)
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)
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)
def load_user(user_id: int) -> User: return User.get(user_id)
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()