def listen_gamer_command(self, queue): self.Socket.settimeout(None) # todo:监听循环退出机制补充 while True: msg = self.recv_cmd(decode=False) if msg != b'': logger.debug('server.game_thread', 'receiving msg: {}'.format(msg)) queue.put(msg)
def handle_host_begin_game_cmd(self, host_index=0): logger.debug('handle_host_cmd', 'host handling threading start!') while True: if len(self.UnloggedGamers) != 0: cmd, body = self.UnloggedGamers[host_index].recv_cmd() logger.debug('handle_host_cmd', f'cmd: {cmd}, body:{body}') handler = get_handler(S_LOGIN_STATE, cmd, supress_log=True) handler(self, gamer=self.UnloggedGamers[host_index], **body) # 该线程如果接收到了主机有关游戏开始的命令后就退出 if cmd == CMD_BEGIN_GAME: return else: time.sleep(1)
def get_handler(state, cmd, supress_log=False): logger.debug('server.handlers', 'getting handler of {}'.format(cmd)) try: handler = __handler_switch[state][cmd] return handler except KeyError: if not supress_log: logger.warning( 'server.handlers.get_handler', 'can not get handler for {c} in {s}'.format(c=cmd, s=state)) return handle_none except Exception as e: if not supress_log: logger.error('server.handlers.get_handler', 'unknown err: {}'.format(e)) return handle_none
def game_state(self): logger.debug('server.gamer_state', 'entering game state') # 初始化游戏逻辑 self.GameLogic = GameLogic(len(self.Gamers)) for round_index in range(self.GameRoundPerGamer): # 游戏循环次数等于玩家数量 for cur_gamer_index in range(len(self.Gamers)): cur_gamer = self.Gamers[cur_gamer_index] self.GameLogic.init_game_state(cur_gamer.Id) self.send_all_cmd(**make_newround_command()) # 将当前出题者加入到已回答玩家列表中,防止其自己猜自己 self.GameLogic.add_answered_gamer_id(cur_gamer.Id) # 发送开始画图和通告画图者的通知 paint_message = self.ServerMessage.make_paint_inform_message( cur_gamer.UserName) self.send_all_cmd(**make_inform_command(paint_message)) # 当前画图者发出开始画图指令 cur_gamer.send_cmd(**make_begin_paint_command()) # 进入指令处理循环 self.MessageLoopFlag = True while self.MessageLoopFlag: msg = self.CmdQueue.get() # 阻塞队列,处理接受到的命令 try: cmd, cmd_body = decode_msg(msg, raise_exception=True) handler = get_handler(S_GAME_STATE, cmd) handler(self, cur_gamer=cur_gamer, raw_message=msg, **cmd_body) except DecodeError as de: logger.error( 'server.game_state', f'decoding error in game message loop: {de}') except Exception as e: she = ServerHandlingError(cmd, cmd_body, e) logger.error( 'server.game_state', f'unknown error when handling in game state: {she}' ) # 关闭游戏 self.close()
def process_answer(self, answer, answer_gamer_id, gamer_group): logger.debug('GameLogic.process_answer', f'state: {self.IsAnswerValid}, {answer} : {self.Answer}') # 问题处于无效状态时不做判断 if not self.IsAnswerValid: return False, len(self.AnsweredGamerIds) if not self.check_gamer_is_answered( answer_gamer_id) and self.check_answer(answer): ans_gamer = gamer_group.get_gamer_by_id(answer_gamer_id) pat_gamer = gamer_group.get_gamer_by_id( self.CurrentPaintingGamerId) logger.info( 'handlers.handle_game_chat', f'gamer {ans_gamer.UserName} has answered this puzzle') # 将答对的玩家的id加入到已完成回答的列表中 self.add_answered_gamer_id(answer_gamer_id) # 答题玩家和画图玩家都得分 ans_gamer.score(self.get_next_point()) pat_gamer.score(config.game.DrawPoint) return True, len(self.AnsweredGamerIds) else: return False, len(self.AnsweredGamerIds)