Ejemplo n.º 1
0
 def receive_from_client(self, addr):
     try:
         msgs, e = recv_data(self.conns_to_clients[addr], addr)
         for msg in msgs:
             if msg['type'] == 'error_msg':
                 warnings.warn('Пришло сообщение об ошибке от игрока {}\n'
                               'Сообщение:\n'.format(addr) + msg['msg'])
             elif msg['type'] == 'event':
                 self.players_scenarios[addr].process_event(
                     addr, msg['event'])
             else:
                 warning_msg = "Сообщение неизвестного типа {} пришло "\
                     "от игрока {}.".format(repr(msg['type']), repr(addr))
                 warnings.warn(warning_msg)
                 msg = {
                     'type': 'error_msg',
                     'error_class': 'ValueError',
                     'addr': addr,
                     'msg': warning_msg,
                     'event': msg['event'],
                 }
                 send_data_quite(self.conns_to_clients[addr], addr, msg)
         if e is not None:
             raise e
     except CorruptedMessageError as e:
         warnings.warn(e.message)
     except BlockingIOError:
         pass
     except ConnectionResetError as e:
         warnings.warn(e)
         warnings.warn(CONNECTION_RESET_ERROR_WARNING_TMPL.format(addr))
         # FIXME
         # Непонятно когда возникает ошибка и потому не ясно следует ли
         # закрывать и удалять socket.
         self.conns_to_clients[addr].close()
         del self.conns_to_clients[addr]
         del self.players_scenarios[addr]
         self.main_frame.cube_canvas.release_player_cube(addr)
     except ConnectionAbortedError as e:
         warnings.warn(e)
         warnings.warn(CONNECTION_ABORTED_ERROR_WARNING_TMPL.format(addr))
         # FIXME
         # Неустановлено, в каких случаях возникает эта ошибка.
         # Она наблюдалась при выключении клиента, тогда закрытие и
         # удаление сокета -- правильное рещение. Однако, я наблюдал эту же
         # ошибку временном отключении wifi. В последнем случаем удаление
         # сокета приводит к необходимости перезапуска клиентской части
         # приложения.
         self.conns_to_clients[addr].close()
         del self.conns_to_clients[addr]
         del self.players_scenarios[addr]
         self.main_frame.cube_canvas.release_player_cube(addr)
     except Exception as e:
         warnings.warn(e)
         warnings.warn(
             "Для исключения типа {} не был написан обработчик. Возможно, "
             "стоит это сделать.".format(type(e)))
Ejemplo n.º 2
0
 def b1_motion(self, event):
     conn = self.get_root().conn_to_server
     msg = {
         'type': 'event',
         'event': {
             'type': '<B1-Motion>',
             'x': event.x,
             'y': event.y
         }
     }
     send_data_quite(conn, self.server_addr, msg)
Ejemplo n.º 3
0
 def button_release_1(self, event):
     conn = self.get_root().conn_to_server
     msg = {
         'type': 'event',
         'event': {
             'type': '<ButtonRelease-1>',
             'x': event.x,
             'y': event.y
         }
     }
     send_data_quite(conn, self.server_addr, msg)
Ejemplo n.º 4
0
 def warn_events_before_init(self, addr, event):
     warning_msg = "На сервер от игрока {} пришло сообщение до " \
         "инициализации этого игрока.\nevent = {}".format(repr(addr), event)
     warnings.warn(warning_msg)
     msg = {
         'type': 'error_msg',
         'error_class': 'ValueError',
         'addr': addr,
         'msg': warning_msg,
         'event': event,
     }
     send_data_quite(self.conns_to_clients[addr], addr, msg)
Ejemplo n.º 5
0
 def button_1(self, event):
     conn = self.cube_canvas.get_root().conn_to_server
     msg = {
         'type': 'event',
         'event': {
             'type': '<Button-1>',
             'id': self.server_id,
             'x': event.x,
             'y': event.y
         }
     }
     send_data_quite(conn, self.server_addr, msg)
Ejemplo n.º 6
0
 def init_player(self, addr):
     cubes = self.main_frame.cube_canvas.cubes
     for cube in cubes.values():
         msg = {
             'type': 'command',
             'command': {
                 "type": 'add_cube',
                 "id": cube.id,
                 "x": cube.x,
                 "y": cube.y,
                 "size": cube.size,
                 "color": cube.color
             }
         }
         send_data_quite(self.conns_to_clients[addr], addr, msg)
     msg = {'type': 'command', 'command': {"type": 'bind_all'}}
     send_data_quite(self.conns_to_clients[addr], addr, msg)
Ejemplo n.º 7
0
 def receive_from_server(self):
     try:
         msgs, e = recv_data(self.conn_to_server, self.server_addr)
         for msg in msgs:
             if msg['type'] == 'error_msg':
                 warnings.warn(
                     'Пришло сообщение об ошибке от сервера\n'
                     'Сообщение:\n' +
                     msg['msg']
                 )
             elif msg['type'] == 'command':
                 self.main_frame.process_server_command(msg['command'])
             else:
                 warning_msg = "Сообщение неизвестного типа {} " \
                     "пришло от сервера.".format(repr(msg['type']))
                 warnings.warn(warning_msg)
                 msg = {
                     'type': 'error_msg',
                     'error_class': 'ValueError',
                     'msg': warning_msg,
                     'event': msg['event'],
                 }
                 send_data_quite(
                     self.get_root().conn_to_server, self.server_addr, msg)
         if e is not None:
             raise e
     except CorruptedMessageError as e:
         warnings.warn(e.message)
     except BlockingIOError:
         pass
     except ConnectionRefusedError as e:
         # Вероятно, сервер не запущен
         warnings.warn(e)
     except ConnectionResetError as e:
         self.conn_to_server.close()
         self.receive_from_server_job = None
         warnings.warn(e)
         return
     except OSError as e:
         warnings.warn(e)
     self.receive_from_server_job = self.after(
         DT_MS, self.receive_from_server)
Ejemplo n.º 8
0
 def are_x_and_y_ok(self, addr, event):
     ok = not self.is_coord_missing(addr, event)
     if not (self.x <= event['x'] <= self.x + self.size
             and self.y <= event['y'] <= self.y + self.size):
         ok = False
         warning_msg = "У кубика с id {} разные координаты или размер " \
             "в клиентской и серверной частях программы. В результате " \
             "мышка не попадает по кубику из серверной части программы. " \
             "Захват кубика не будет осуществлен.".format(self.id)
         warnings.warn(warning_msg)
         conn = self.cube_canvas.get_root().conns_to_clients[addr]
         msg = {
             'type': 'error_msg',
             'error_class': 'ValueError',
             'addr': addr,
             'msg': warning_msg,
             'event': event,
             'cube_coords_on_server': (self.x, self.y),
             'cube_size_on_server': self.size
         }
         send_data_quite(conn, addr, msg)
     return ok
Ejemplo n.º 9
0
 def is_coord_missing(self, addr, event):
     missing_coords = []
     if 'x' not in event:
         missing_coords.append('x')
     if 'y' not in event:
         missing_coords.append('y')
     if missing_coords:
         warning_msg = "В описании события не хватает {}." \
             "Захват кубика не будет осуществлен.".format(
                 ' и '.join(map(repr, missing_coords))
             )
         warnings.warn(warning_msg)
         conn = self.cube_canvas.get_root().conns_to_clients[addr]
         msg = {
             'type': 'error_msg',
             'error_class': 'ValueError',
             'addr': addr,
             'msg': warning_msg,
             'event': event
         }
         send_data_quite(conn, addr, msg)
     return bool(missing_coords)
Ejemplo n.º 10
0
 def send_to_all_players(self, msg):
     for addr, conn in self.conns_to_clients.items():
         send_data_quite(conn, addr, msg)
Ejemplo n.º 11
0
 def is_id_address_eventtype_ok(self, addr, event):
     ok = True
     conn = self.get_root().conns_to_clients[addr]
     oblig_part = {
         'type': 'error_msg',
         'error_class': 'ValueError',
         'addr': addr,
         'event': event
     }
     if event['type'] == '<Button-1>':
         if 'id' not in event:
             ok = False
             warning_msg = "Без ключа 'id' могут быть только словари " \
                 "с описаниями событий типа <ButtonRelease-1> и " \
                 "<B1-Motion>. В то время как у данного события тип " \
                 "{}".format(event['type'])
             warnings.warn(warning_msg)
             msg = dict(**oblig_part, msg=warning_msg)
             send_data_quite(conn, addr, msg)
         if 'id' in event and addr in self.grabbed_cubes_ids:
             ok = False
             warning_msg = "Игрок {} не может схватить кубик с id " \
                 "{}, пока не отпустит кубик с id {}. Вероятно, или в " \
                 "или в серверной части программы ошибка. Такие ситуации " \
                 "не должны возникать".format(
                     addr, event['id'], self.grabbed_cubes_ids[addr]
                 )
             warnings.warn(warning_msg)
             msg = dict(**oblig_part,
                        msg=warning_msg,
                        grabbed_id=self.grabbed_cubes_ids[addr])
             send_data_quite(conn, addr, msg)
         if 'id' in event and event['id'] not in self.cubes:
             ok = False
             present_ids = list(self.cubes.keys())
             warning_msg = "В canvas нет элемента с id {}. Или в " \
                 "клиентской, или в серверной части программы ошибка. \n" \
                 "id в наличии: {}\n".format(event['id'], present_ids)
             warnings.warn(warning_msg)
             msg = dict(**oblig_part, msg=warning_msg)
             send_data_quite(conn, addr, msg)
     elif event['type'] in ['<ButtonRelease-1>', '<B1-Motion>']:
         if 'id' in event:
             ok = False
             warning_msg = "Ключ id может быть только в словарях с " \
                 "описаниями событий типа <Button-1>. В то время как" \
                 "у данного события тип {}. Вероятно, в клиентской " \
                 "части программы неправильно реализовано составление " \
                 "сообщений данного типа".format(event['type'])
             warnings.warn(warning_msg)
             msg = dict(**oblig_part, msg=warning_msg)
             send_data_quite(conn, addr, msg)
         if addr not in self.grabbed_cubes_ids:
             ok = False
             warning_msg = "Адрес клиента, отправившего описание события " \
                 "типа <ButtonRelease-1> или <B1-Motion>, должен быть " \
                 "ключом словаря `self.grabbed_cubes_ids`."
             warnings.warn(warning_msg)
             msg = dict(**oblig_part, msg=warning_msg)
             send_data_quite(conn, addr, msg)
     else:
         ok = False
         warning_msg = "Только события типов {} поддерживаются, в то " \
             "время как было принято описание события типа {}. Вероятно, " \
             "в клиентской части программы допущена ошибка.".format(
                 self.supported_incoming_event_types, event['type'])
         warnings.warn(warning_msg)
         msg = dict(
             **oblig_part,
             msg=warning_msg,
             supported_event_types=self.supported_incoming_event_types)
         send_data_quite(conn, addr, msg)
     return ok
Ejemplo n.º 12
0
    def is_command_ok(self, command):
        if command['type'] not in self.supported_command_types:
            warning_msg = "Команда неизвестного типа {} " \
                "пришла от сервера. Вероятно, в коде клиентской часть" \
                "ошибка, так как входные сообщения неправильного типа " \
                "должны фиксироваться в методе " \
                "`CubeGameClient.receive_from_server()`".format(
                    repr(command['type']))
            warnings.warn(warning_msg)

            msg = {
                'type': 'error_msg',
                'error_class': 'ValueError',
                'msg': warning_msg,
                'command': command,
            }
            send_data_quite(
                self.get_root().conn_to_server, self.server_addr, msg)
            return False
        if set(command.keys()) != self.command_keys[command['type']]:
            warning_msg = "В словаре с описанием команды есть лишние ключи " \
                "или не хватает ключей.\n" \
                "excess: {}\n" \
                "missing: {}\n" \
                "command: {}".format(
                    set(command.keys()) - self.command_keys[command['type']],
                    self.command_keys[command['type']] - set(command.keys()),
                    command
                )
            warnings.warn(warning_msg)
            msg = {
                'type': 'error_msg',
                'error_class': 'ValueError',
                'msg': warning_msg,
                'command': command,
            }
            send_data_quite(
                self.get_root().conn_to_server, self.server_addr, msg)
            return False
        if command['type'] == 'add_cube':
            if not (
                    isinstance(command['id'], int)
                    and isinstance(command['x'], (float, int))
                    and isinstance(command['y'], (float, int))
                    and isinstance(command['size'], (float, int))
                    and isinstance(command['color'], str)
                    and command['id'] not in self.cubes_by_server_ids
                    and command['size'] > 0
                    and command['color'] in colors.ALL_COLORS
            ):
                warning_msg = "Или значения, или типы значений в словаре с " \
                    "описанием команды неверны.\n" \
                    "command: {}\n" \
                    "Зарегистрированные у клиента " \
                    "id кубиков сервера: {}".format(
                        command, self.cubes_by_server_ids)
                warnings.warn(warning_msg)
                msg = {
                    'type': 'error_msg',
                    'error_class': 'ValueError',
                    'msg': warning_msg,
                    'command': command,
                    'registered_server_cubes': list(
                        self.cubes_by_server_ids)
                }
                send_data_quite(
                    self.get_root().conn_to_server, self.server_addr, msg)
                return False
        elif command['type'] == 'coords':
            if not (
                    isinstance(command['id'], int)
                    and isinstance(command['x1'], (float, int))
                    and isinstance(command['y1'], (float, int))
                    and isinstance(command['x2'], (float, int))
                    and isinstance(command['y2'], (float, int))
                    and command['id'] in self.cubes_by_server_ids
            ):
                warning_msg = "Или значения, или типы значений в словаре с " \
                    "описанием команды неверны."
                warnings.warn(warning_msg)
                msg = {
                    'type': 'error_msg',
                    'error_class': 'ValueError',
                    'msg': warning_msg,
                    'command': command,
                    'registered_server_cubes': list(
                        self.cubes_by_server_ids)
                }
                send_data_quite(
                    self.get_root().conn_to_server, self.server_addr, msg)
                return False
        return True