def _receive_event(self, timeout=SERVER_TIMEOUT): """Receives next event of type NONE or RECEIVE.""" if self.server_peer is None: raise network.NotConnected() try: event = self.host.service(timeout) if event.type == enet.EVENT_TYPE_NONE: return None elif event.type == enet.EVENT_TYPE_DISCONNECT: self._reset() self.log.warning("Unexpected disconnect from %s", event.peer.address) raise network.CommandError( "Unexpected disconnect from {}".format(event.peer.address)) elif event.type == enet.EVENT_TYPE_CONNECT: self._reset() self.log.warning("Unexpected connection from %s", event.peer.address) raise network.CommandError( "Unexpected connection from {}".format(event.peer.address)) return event except IOError as e: raise network.FatalError(e)
def server_recv_event(self, timeout=SERVER_TIMEOUT): if self.serverpeer is None: raise network.NotConnected() event = self.host.service(timeout) if event.type == enet.EVENT_TYPE_NONE: return None elif event.type == enet.EVENT_TYPE_DISCONNECT: self.reset() self.log.warning("Unexpected disconnect from %s" % (event.peer.address)) raise network.CommandError("Unexpected disconnect from %s" % (event.peer.address)) elif event.type == enet.EVENT_TYPE_CONNECT: # ignore connect events during holepunching if self.game is not None: for player in self.game.players: if player.address == event.peer.address: self.log.debug("[HOLEPUNCH CONNECTION] %s" % (event.peer.address)) event.peer.disconnect() event.peer.reset() return None self.reset() self.log.warning("Unexpected connection from %s" % (event.peer.address)) raise network.CommandError("Unexpected connection from %s" % (event.peer.address)) return event
def sendraw(self, peer, data, channelid=0): if self.host is None: raise network.NotConnected("Server is not running") packet = enet.Packet(data, enet.PACKET_FLAG_RELIABLE) peer.send(channelid, packet) self.host.flush()
def send(self, peer: 'enet.Peer', packet: packets.packet): """ Sends a packet to a client. """ if self.host is None: raise network.NotConnected("Server is not running") self.send_raw(peer, packet.serialize())
def disconnect(self, later = False): if self.extport is not None: self.upnp_disconnect(self.extport) or self.natpmp_disconnect(self.extport, self.localport) self.extport = None if self.mode is ClientMode.Server: return self.server_disconnect(later) elif self.mode is ClientMode.Peer2Peer: return self.p2p_disconnect(later) raise network.NotConnected()
def server_ping(self): if self.serverpeer is None: raise network.NotConnected() packet = self.recv(0) if packet is not None: if not self.process_async_packet(packet): self.packetqueue.append(packet) return True return False
def chat(self, message): if self.mode is None: raise network.NotConnected() if self.mode is not ClientMode.Server: raise network.NotInServerMode("We are not in server mode") if self.game is None: raise network.NotInGameLobby("We are not in a game lobby") self.log.debug("[CHAT] %s" % (message)) self.send(packets.client.cmd_chatmsg(message)) return True
def send_packet(self, packet): """Send a packet to the server. packet has to be a subclass of `horizons.network.packets.packet`. """ if self.server_peer is None: raise network.NotConnected() packet = enet.Packet(packet.serialize(), enet.PACKET_FLAG_RELIABLE) self.server_peer.send(0, packet)
def send_raw(self, peer: 'enet.Peer', data: bytes): """ Sends raw data to a client. """ if self.host is None: raise network.NotConnected("Server is not running") packet = enet.Packet(data, enet.PACKET_FLAG_RELIABLE) peer.send(0, packet) self.host.flush()
def setprops(self, lang): if self.mode is None: raise network.NotConnected() if self.mode is not ClientMode.Server: raise network.NotInServerMode("We are not in server mode") self.log.debug("[SETPROPS]") self.send(packets.client.cmd_sessionprops(lang)) packet = self.recv_packet([packets.cmd_ok]) if packet is None: raise network.FatalError("No reply from server") elif not isinstance(packet[1], packets.cmd_ok): raise network.CommandError("Unexpected packet") return True
def listgames(self, mapname=None, maxplayers=None, only_this_version=False): if self.mode is None: raise network.NotConnected() if self.mode is not ClientMode.Server: raise network.NotInServerMode("We are not in server mode") self.log.debug("[LIST]") version = self.version if only_this_version else -1 self.send(packets.client.cmd_listgames(version, mapname, maxplayers)) packet = self.recv_packet([packets.server.data_gameslist]) if packet is None: raise network.FatalError("No reply from server") elif not isinstance(packet[1], packets.server.data_gameslist): raise network.CommandError("Unexpected packet") return packet[1].games
def _recv_event(self, timeout=SERVER_TIMEOUT): if self.serverpeer is None: raise network.NotConnected() event = self.host.service(timeout) if event.type == enet.EVENT_TYPE_NONE: return None elif event.type == enet.EVENT_TYPE_DISCONNECT: self.reset() self.log.warning("Unexpected disconnect from %s" % (event.peer.address)) raise network.CommandError("Unexpected disconnect from %s" % (event.peer.address)) elif event.type == enet.EVENT_TYPE_CONNECT: self.reset() self.log.warning("Unexpected connection from %s" % (event.peer.address)) raise network.CommandError("Unexpected connection from %s" % (event.peer.address)) return event
def ping(self): """Handle incoming packets. Enet doesn't need to send pings. Call this regularly. Incoming packets can be handled by process_async_packet, otherwise will be added to a queue. """ if not self.is_connected: raise network.NotConnected() packet = self._receive(0) if packet is not None: if not self.process_async_packet(packet): self.packetqueue.append(packet) return True return False
def leavegame(self, stealth=False): if self.mode is None: raise network.NotConnected() if self.mode is not ClientMode.Server: raise network.NotInServerMode("We are not in server mode") if self.game is None: raise network.NotInGameLobby("We are not in a game lobby") self.log.debug("[LEAVE]") if stealth: self.game = None return self.send(packets.client.cmd_leavegame()) packet = self.recv_packet([packets.cmd_ok]) if packet is None: raise network.FatalError("No reply from server") elif not isinstance(packet[1], packets.cmd_ok): raise network.CommandError("Unexpected packet") self.game = None return True
def joingame(self, uuid, password="", fetch=False): if self.mode is None: raise network.NotConnected() if self.mode is not ClientMode.Server: raise network.NotInServerMode("We are not in server mode") self.log.debug("[JOIN] %s" % (uuid)) self.send(packets.client.cmd_joingame( uuid = uuid, clientver = self.version, clientid = self.clientid, playername = self.name, playercolor = self.color, password = password, fetch = fetch)) packet = self.recv_packet([packets.server.data_gamestate]) if packet is None: raise network.FatalError("No reply from server") elif not isinstance(packet[1], packets.server.data_gamestate): raise network.CommandError("Unexpected packet") self.game = packet[1].game return self.game
def creategame(self, mapname, maxplayers, gamename, maphash="", password=""): if self.mode is None: raise network.NotConnected() if self.mode is not ClientMode.Server: raise network.NotInServerMode("We are not in server mode") self.log.debug("[CREATE] mapname=%s maxplayers=%d" % (mapname, maxplayers)) self.send(packets.client.cmd_creategame( clientver = self.version, clientid = self.clientid, playername = self.name, playercolor = self.color, gamename = gamename, mapname = mapname, maxplayers = maxplayers, maphash = maphash, password = password)) packet = self.recv_packet([packets.server.data_gamestate]) if packet is None: raise network.FatalError("No reply from server") elif not isinstance(packet[1], packets.server.data_gamestate): raise network.CommandError("Unexpected packet") self.game = packet[1].game return self.game
def send(self, peer, packet, channelid=0): if self.host is None: raise network.NotConnected("Server is not running") self.sendraw(peer, packet.serialize(), channelid)
def sendraw(self, peer, data, channelid=0): if self.host is None: raise network.NotConnected("Server is not running") packets.packet.sendraw(peer, data, channelid) self.host.flush()
def send(self, peer, packet, channelid=0): if self.host is None: raise network.NotConnected("Server is not running") packet.send(peer, None, channelid) self.host.flush()
def _assert_connection(self): if self._mode is None: raise network.NotConnected() if self._mode is not ClientMode.Server: raise network.NotInServerMode("We are not in server mode")
def server_send(self, packet, channelid = 0): if self.serverpeer is None: raise network.NotConnected() packet.send(self.serverpeer, channelid)
def disconnect(self, later = False): if self.mode is ClientMode.Server: return self.server_disconnect(later) elif self.mode is ClientMode.Peer2Peer: return self.p2p_disconnect(later) raise network.NotConnected()
def send(self, packet, channelid=0): if self.serverpeer is None: raise network.NotConnected() if self.mode is ClientMode.Game: packet = packets.client.game_data(packet) packet.send(self.serverpeer, self.sid, channelid)