コード例 #1
0
    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)]
        }
コード例 #2
0
    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
コード例 #3
0
    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)
コード例 #4
0
    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,
        })
コード例 #5
0
    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)
コード例 #6
0
    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())
コード例 #7
0
    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)