def open_direct(self, user_id): if user_id == self.user.id: raise ServiceError('cannot open direct-chat with oneself') other = self.db.query(User).filter_by(id=user_id).one() direct = self._direct_room(self.user, other) if direct.room.users.filter_by(user_id=self.user.id).count() == 0: self.db.add(RoomUser(room=direct.room, user=self.user)) self.db.commit() self._subscribe(direct.room.id) return { 'other_user_id': other.id, 'other_display': other.display, 'is_online': other.is_online, 'is_active': True, 'has_unread': direct.has_unread(self.user), 'room': direct.room.to_frontend(), 'room_logs': [m.to_frontend() for m in direct.room.recent_messages(self.db)] }
def create_demo_from_game(self, game_id): game = self.db.query(Game).get(game_id) if not game: raise ServiceError('game not found') room = Room(type='game') self.db.add(room) demo = Game(is_demo=True, is_ranked=False, room=room, board=game.board, komi=game.komi, stage='finished', black_display=game.black_display, white_display=game.white_display, demo_owner=self.user, demo_owner_display=self.user.display, demo_owner_rating=self.user.rating, demo_control=self.user, demo_control_display=self.user.display) self.db.add(demo) self.db.commit() return demo.id
def _game_move_demo(self, game, move): if not self.user == game.demo_control: raise InvalidPlayerError() if move == RESIGN: raise ServiceError('cannot resign in demo games') game.board.play(move)
def set_current_node(self, game_id, node_id): game = self.db.query(Game).get(game_id) if not game.demo_control == self.user: raise InvalidPlayerError() if node_id >= len(game.board.tree): raise ServiceError('invalid node_id') game.board.current_node_id = node_id game.apply_board_change() self.socket.publish('demo_current_node_id/'+str(game.id), { 'game_id': game.id, 'node_id': game.board.current_node_id, })
def confirm_score(self, game_id, result): with self._game_for_update(game_id) as game: if self.user not in [game.black_user, game.white_user]: raise InvalidPlayerError() if game.stage != 'counting': raise InvalidStageError() if result != game.result: raise ServiceError('got incorrect result: {}'.format(result)) if self.user == game.black_user: game.result_black_confirmed = game.result else: game.result_white_confirmed = game.result if game.result_black_confirmed == game.result_white_confirmed: game.stage = 'finished' self._finish_game(game)
def message(self, room_id, message): ru = self.db.query(RoomUser).filter_by(user=self.user, room_id=room_id).first() if not ru: raise ServiceError('user not in room') msg = RoomMessage(room=ru.room, user=self.user, user_display=self.user.display, user_rating=self.user.rating, message=message) self.db.add(msg) self.db.commit() if ru.room.type == 'direct': self._message_direct(ru.room, msg) else: self.socket.publish('room_message/' + str(room_id), msg.to_frontend())
def challenge(self, user_id, size, handicap, komi, owner_is_black, speed, timing, maintime, overtime, overtime_count, private=False, ranked=False): other = self.db.query(User).filter_by(id=user_id).one() correspondence = (speed == 'correspondence') if self.user == other: raise ServiceError('cannot challenge oneself') if (handicap is not None and handicap != 0) and owner_is_black is None: raise ServiceError('handicap defined but not black/white') if handicap is not None and (handicap < 0 or handicap > 9): raise InvalidHandicapError() if (ranked and size != 19) or size not in [9, 13, 19]: raise InvalidBoardSizeError() if correspondence: if not 24 <= maintime <= 24 * 5: raise ServiceError('invalid main time') if not 4 <= overtime <= 24 * 3: raise ServiceError('invalid overtime') else: if not 0 <= maintime <= 60: raise ServiceError('invalid main time') if not 0 <= overtime <= 60: raise ServiceError('invalid overtime') if private and ranked: raise ChallengePrivateCannotBeRankedError() if handicap is None or ranked: black, white, handicap = self.game_players_handicap( self.user, other) owner_is_black = (black == self.user) komi = (settings.DEFAULT_KOMI if handicap == 0 else settings.HANDICAP_KOMI) if owner_is_black is None: owner_is_black = (random.choice([0, 1]) == 0) self.db.query(Challenge).filter_by(owner=self.user, challengee=other).delete() if correspondence: expire_at = (datetime.utcnow() + settings.CORRESPONDENCE_CHALLENGE_EXPIRATION) maintime = timedelta(hours=maintime) overtime = timedelta(hours=overtime) else: expire_at = (datetime.utcnow() + settings.CHALLENGE_EXPIRATION) maintime = timedelta(minutes=maintime) overtime = timedelta(seconds=overtime) challenge = Challenge(expire_at=expire_at, owner=self.user, challengee=other, board_size=size, handicap=handicap, komi=komi, owner_is_black=owner_is_black, is_correspondence=correspondence, timing_system=timing, maintime=maintime, overtime=overtime, overtime_count=overtime_count, is_private=private, is_ranked=ranked) self.db.add(challenge) self.db.commit() self._publish_challenges(challenge)