示例#1
0
 async def on_spectate(self, sid: SpectatorSID,
                       msg: SpectateMessage) -> Tuple[str, Dict]:
     room, _ = get_room_player(sid, msg.roomid, None, check_server=False)
     self.enter_room(sid, room.broadcast_sid)
     self.enter_room(sid, room.spectator_sid)
     return (
         "message",
         {
             "board":
             room.board,
             "status":
             room.status,
             "players": {player.id: player.name
                         for player in room.players},
             "turn":
             room.turn,
             "states": [{
                 "id": state.id,
                 "timestamp": state.timestamp.isoformat(),
                 "epoch": state.epoch,
                 "move": state.move,
                 "board": state.board,
                 "turn": state.turn,
             } for state in room.states],
         },
     )
示例#2
0
 async def on_joinsuccess(self, sid: GameServerSID,
                          msg: JoinSuccessMessage) -> None:
     """
     Server confirmed a player joining the lobby
     """
     room, player = get_room_player(sid, msg.roomid, msg.playerid)
     assert player is not None
     player.update(joined=True, gamerole=msg.gamerole)
     self.enter_room(player.sid, room.broadcast_sid)
     await JoinedMessage(
         roomid=msg.roomid,
         playerid=msg.playerid,
         name=player.name,
         gamerole=msg.gamerole,
         broadcast=False,
     ).send(
         self,
         to=player.sid,
         callback=partial(self.acknowledge_join,
                          room_id=msg.roomid,
                          player_id=msg.playerid),
     )
     await JoinedMessage(
         roomid=msg.roomid,
         playerid=msg.playerid,
         name=player.name,
         gamerole=msg.gamerole,
         broadcast=True,
     ).send(
         self,
         to=room.broadcast_sid,
     )
示例#3
0
 async def on_joinfail(self, sid: GameServerSID,
                       msg: JoinFailMessage) -> None:
     """
     Server responds that a player failed to join the lobby
     """
     room, player = get_room_player(sid, msg.roomid, msg.playerid)
     assert player is not None
     await self.emit(
         "fail",
         {
             "error": "registrationFailed",
             "reason": msg.reason
         },
         room=player.sid,
     )
示例#4
0
 async def on_move(self, sid: PlayerSID, msg: MoveMessage) -> None:
     """
     Player sends a move request
     """
     room, player = get_room_player(sid,
                                    msg.roomid,
                                    msg.playerid,
                                    check_server=False)
     if room.status != "playing":
         raise GameNotRunning
     elif room.turn != msg.playerid:
         raise NotPlayersTurn
     else:
         state = GameState.create(player_id=msg.playerid,
                                  room=msg.roomid,
                                  move=msg.move)
         await PlayerMoveMessage(
             roomid=msg.roomid,
             playerid=msg.playerid,
             move=msg.move,
             stateid=state.id,
         ).send(self, to=room.server_sid)
示例#5
0
 async def on_gameupdate(self, sid: GameServerSID,
                         msg: GameUpdateMessage) -> None:
     """
     Server notifies of a game state change
     """
     if msg.visibility == "private":
         if msg.playerid is None:
             raise InputValidationError(
                 details=
                 "error: 'playerid' must be provided when visibility is private"
             )
     else:
         if msg.playerid is not None:
             raise InputValidationError(
                 details=
                 "error: 'playerid' cannot be provided unless visibility is private"
             )
         if msg.epoch is None:
             raise InputValidationError(
                 details=
                 "error: 'epoch' is required for non-private messages")
     room, player = get_room_player(sid, msg.roomid, msg.playerid)
     with room.lock(timeout=0.5, sleep=0.02):
         if msg.finish is not None:
             logger.info("Game finished")
             await GamestateMessage.parse_obj(msg.to_dict()
                                              ).send(self,
                                                     to=room.broadcast_sid)
             room.update(status="finished")
         new_status = "finished" if room.status == "finished" else "playing"
         if msg.visibility == "private":
             room.update(status=new_status, turn=msg.turn)
             assert player is not None
             await GamestateMessage(
                 board=msg.board,
                 turn=msg.turn,
                 roomid=msg.roomid,
                 playerid=msg.playerid,
                 epoch=msg.epoch,
             ).send(self, to=player.sid)
         else:
             if room.status == "finished":
                 room.update(board=msg.board, turn=None)
             else:
                 room.update(status=new_status, turn=msg.turn)
             if msg.visibility == "broadcast":
                 r = GamestateMessage(
                     board=msg.board,
                     turn=msg.turn,
                     roomid=msg.roomid,
                     playerid=msg.playerid,
                     epoch=msg.epoch,
                 )
                 logger.debug(
                     f"room.id={room.id}, room.broadcast_sid={room.broadcast_sid}"
                 )
                 await r.send(sio=self, to=room.broadcast_sid)
             try:
                 state = GameState.get(msg.stateid)
                 if state.room is not None and state.room.id != msg.roomid:
                     raise InstanceNotFound
             except InstanceNotFound:
                 state_args = {
                     "room_id": msg.roomid,
                     "epoch": msg.epoch,
                     "board": msg.board,
                     "turn": msg.turn,
                 }
                 GameState.create(
                     **{k: v
                        for k, v in state_args.items() if v is None})
             else:
                 state.update(epoch=msg.epoch,
                              board=msg.board,
                              turn=msg.turn)
             room.update(
                 status=new_status,
                 board=msg.board,
                 turn=msg.turn,
             )