def loop(self): world, players = self.server.world, self.server.players while 1: byte = self.request.recv(1) if not byte: return # The client has disconnected intentionally packettype = struct.unpack("B", byte)[0] # Client Packet Type if packettype == 1: # Sector request sector = struct.unpack("iii", self.request.recv(4*3)) if sector not in world.sectors: with world.server_lock: world.open_sector(sector) if not world.sectors[sector]: #Empty sector, send packet 2 self.sendpacket(12, "\2" + struct.pack("iii",*sector)) else: msg = struct.pack("iii",*sector) + save_sector_to_string(world, sector) + world.get_exposed_sector(sector) self.sendpacket(len(msg), "\1" + msg) elif packettype == 3: # Add block positionbytes = self.request.recv(4*3) blockbytes = self.request.recv(2) position = struct.unpack("iii", positionbytes) blockid = G.BLOCKS_DIR[struct.unpack("BB", blockbytes)] with world.server_lock: world.add_block(position, blockid, sync=False) for address in players: if address is self.client_address: continue # He told us, we don't need to tell him players[address].sendpacket(14, "\3" + positionbytes + blockbytes) elif packettype == 4: # Remove block positionbytes = self.request.recv(4*3) with world.server_lock: world.remove_block(struct.unpack("iii", positionbytes), sync=False) for address in players: if address is self.client_address: continue # He told us, we don't need to tell him players[address].sendpacket(12, "\4" + positionbytes) elif packettype == 5: # Receive chat text txtlen = struct.unpack("i", self.request.recv(4))[0] raw_txt = self.request.recv(txtlen).decode('utf-8') txt = "%s: %s" % (self.username, raw_txt) try: if raw_txt[0] == '/': ex = self.command_parser.execute(raw_txt, user=self, world=world) if ex != COMMAND_HANDLED: self.sendchat('$$rUnknown command.') else: # Not a command, send the chat to all players for address in players: players[address].sendchat(txt) print txt # May as well let console see it too except CommandException, e: self.sendchat(str(e), COMMAND_ERROR_COLOR) elif packettype == 6: # Player Inventory Update self.inventory = self.request.recv(4*40)
for player in self.server.players.itervalues(): if player is self: continue name = player.username.encode('utf-8') self.sendpacket(2 + len(name), '\7' + struct.pack("H", player.id) + name) # Send the newcomer's name to all current players name = self.username.encode('utf-8') for player in self.server.players.itervalues(): if player is self: continue player.sendpacket(2 + len(name), '\7' + struct.pack("H", self.id) + name) #Send them the sector under their feet first so they don't fall sector = sectorize(position) if sector not in world.sectors: with world.server_lock: world.open_sector(sector) msg = struct.pack("iii",*sector) + save_sector_to_string(world, sector) + world.get_exposed_sector(sector) self.sendpacket(len(msg), "\1" + msg) #Send them their spawn position and world seed(for client side biome generator) seed_packet = make_string_packet(G.SEED) self.sendpacket(12 + len(seed_packet), struct.pack("B",255) + struct.pack("iii", *position) + seed_packet) self.sendpacket(4*40, "\6" + self.inventory) else: print "Received unknown packettype", packettype def finish(self): print "Client disconnected,", self.client_address, self.username try: del self.server.players[self.client_address] except KeyError: pass for player in self.server.players.itervalues(): player.sendchat("%s has disconnected." % self.username) # Send user list
def loop(self): world, players = self.server.world, self.server.players package_system = PackageSystem(self.request) while 1: # byte = self.request.recv(1) try: data = package_system.recv() except ValueError: return # print("Server recieved packet: %s" % data) packettype = data["packetType"] packet = data["packet"] # print(f"SERVERPACKET:", data) if packettype != 1 else None # if not byte: return # The client has disconnected intentionally # packettype = struct.unpack("B", byte)[0] # Client Packet Type if packettype == 1: # Sector request # sector = struct.unpack("iii", self.request.recv(4 * 3)) sector = packet["sector"] # print("SECTORCHANGE_CURRENT:", sector) # print("SECTORCHANGE_ALL:", world.sectors) # print("SECTORIZE_NEW:", sector in world.sectors) if sector not in world.sectors: with world.server_lock: world.open_sector(sector) if not world.sectors[sector]: # Empty sector, send packet 2 self.sendpacket(None, { "packetType": 2, "packet": { "sector": sector } }) # self.sendpacket(12, b"\2" + struct.pack("iii", *sector)) else: # py_000005 = save_sector_to_string(world, sector) # py_000003 = (py_000005.encode("utf-8") if type(py_000005) == str else py_000005) # py_000004 = world.get_exposed_sector(sector).encode("utf-8") # msg = struct.pack("iii", *sector) + py_000003 + py_000004 self.sendpacket( None, { "packetType": 1, "packet": { "sector": sector, "exposedSector": world.get_exposed_sector(sector), "sectorData": save_sector_to_string( world, sector) } }) # self.sendpacket(len(msg), b"\1" + msg) elif packettype == 3: # Add block # positionbytes = self.request.recv(4 * 3) # blockbytes = self.request.recv(2) position = packet["position"] blockid = G.BLOCKS_DIR[packet["block"]] # position = struct.unpack("iii", positionbytes) # blockid = G.BLOCKS_DIR[struct.unpack("BB", blockbytes)] with world.server_lock: world.add_block(position, blockid, sync=False) for address in players: if address is self.client_address: continue # He told us, we don't need to tell him players[address].packageSystem.send({ "packetType": 3, "packet": { "position": position, "block": blockid } }) # players[address].sendpacket(14, "\3" + positionbytes + blockbytes) elif packettype == 4: # Remove block # positionbytes = self.request.recv(4 * 3) with world.server_lock: world.remove_block(packet["position"], sync=False) for address in players: if address is self.client_address: continue # He told us, we don't need to tell him players[address].sendpacket(12, "\4" + positionbytes) elif packettype == 5: # Receive chat text # txtlen = struct.unpack("i", self.request.recv(4))[0] # raw_txt = self.request.recv(txtlen).decode('utf-8') raw_txt = packet["message"].decode() txt = "%s: %s" % (self.username.decode(), raw_txt) try: if raw_txt[0] == '/': ex = self.command_parser.execute(raw_txt, user=self, world=world) if ex != COMMAND_HANDLED: self.sendchat('$$rUnknown command.') else: # Not a command, send the chat to all players for address in players: players[address].sendchat(txt) print(txt) # May as well let console see it too except CommandException as e: self.sendchat(str(e), COMMAND_ERROR_COLOR) elif packettype == 6: # Player Inventory Update print("SERVER_PACKET06:", packet) self.inventory = packet["items"] # TODO: All player's inventories should be autosaved at a regular interval. pass elif packettype == 8: # Player Movement # mom_bytes, pos_bytes = self.request.recv(4 * 3), self.request.recv(8 * 3) # self.momentum = struct.unpack("fff", mom_bytes) # self.position = struct.unpack("ddd", pos_bytes) self.momentum = packet["momentum"] self.position = packet["position"] for address in players: if address is self.client_address: continue # He told us, we don't need to tell him # TODO: Only send to nearby players self.sendpacket( None, { "packetType": 8, "packet": { "playerID": self.id, "momentum": self.momentum, "position": self.position } }) # players[address].sendpacket(38, "\x08" + struct.pack("H", self.id) + mom_bytes + pos_bytes) elif packettype == 9: # Player Jump # raise NotImplementedError("Player Jump not implemented") for address in players: if address is self.client_address: continue # He told us, we don't need to tell him # TODO: Only send to nearby players players[address].sendpacket(None, { "packetType": 9, "package": { "playerID": self.id } }) # players[address].sendpacket(2, "\x09" + struct.pack("H", self.id)) elif packettype == 10: # Update Tile Entity # block_pos = struct.unpack("iii", self.request.recv(4 * 3)) # ent_size = struct.unpack("i", self.request.recv(4))[0] # world[block_pos].update_tile_entity(self.request.recv(ent_size)) pass elif packettype == 255: # Initial Login # txtlen = struct.unpack("i", self.request.recv(4))[0] # data2 = package_system.recv() self.username = packet["username"] # position = packet["position"] # self.username = self.request.recv(txtlen).decode('utf-8') self.position = None load_player(self, "world") for player in self.server.players.values(): player.sendchat("$$y%s has connected." % self.username) print("%s's username is %s" % (self.client_address, self.username)) position = (0, self.server.world.terraingen.get_height(0, 0) + 2, 0) if self.position is None: self.position = position # New player, set initial position # Send list of current players to the newcomer for player in self.server.players.values(): if player is self: continue name = player.username.encode('utf-8') self.sendpacket( None, { "packetType": 7, "packet": { "playerID": player.id, "username": name } }) # self.sendpacket(2 + len(name), '\7' + struct.pack("H", player.id) + name) # Send the newcomer's name to all current players name = self.username for player in self.server.players.values(): if player is self: continue player.sendpacket( None, { "packetType": 7, "packet": { "playerID": self.id, "username": name } }) # player.sendpacket(2 + len(name), '\7' + struct.pack("H", self.id) + name) # Send them the sector under their feet first so they don't fall sector = sectorize(position) if sector not in world.sectors: with world.server_lock: world.open_sector(sector) py_000001 = struct.pack("iii", *sector) sector_string = save_sector_to_string(world, sector) exposed_sector = world.get_exposed_sector(sector) # print(py_000001, sector_string, exposed_sector) msg = py_000001 + sector_string + exposed_sector.encode( 'utf-8') self.sendpacket( None, { "packetType": 1, "packet": { "sector": sector, "exposedSector": exposed_sector, "sectorData": sector_string } }) # self.sendpacket(len(msg), b"\1" + msg) # Send them their spawn position and world seed(for client side biome generator) seed_packet = make_string_packet(G.SEED) self.sendpacket( None, { "packetType": 255, "packet": { "position": position, "seed": G.SEED } }) # self.sendpacket(12 + len(seed_packet), # struct.pack("B", 255) + struct.pack("iii", *position) + seed_packet) print("IMPORTANT0004:", self.inventory) print("IMPORTANT0005:", len(self.inventory) + 1) self.sendpacket(None, { "packetType": 6, "packet": { "items": self.inventory } }) # self.sendpacket(len(self.inventory)+1, "\6" + self.inventory) else: print("Received unknown packettype", packettype)
def loop(self): world, players = self.server.world, self.server.players while 1: byte = self.request.recv(1) if not byte: return # The client has disconnected intentionally packettype = struct.unpack("B", byte)[0] # Client Packet Type if packettype == 1: # Sector request sector = struct.unpack("iii", self.request.recv(4*3)) if sector not in world.sectors: with world.server_lock: world.open_sector(sector) if not world.sectors[sector]: #Empty sector, send packet 2 self.sendpacket(12, "\2" + struct.pack("iii",*sector)) else: msg = struct.pack("iii",*sector) + save_sector_to_string(world, sector) + world.get_exposed_sector(sector) self.sendpacket(len(msg), "\1" + msg) elif packettype == 3: # Add block positionbytes = self.request.recv(4*3) blockbytes = self.request.recv(2) position = struct.unpack("iii", positionbytes) blockid = G.BLOCKS_DIR[blocks.BlockID(struct.unpack("BB", blockbytes))] with world.server_lock: world.add_block(position, blockid, sync=False) for address in players: if address is self.client_address: continue # He told us, we don't need to tell him players[address].sendpacket(14, "\3" + positionbytes + blockbytes) elif packettype == 4: # Remove block positionbytes = self.request.recv(4*3) with world.server_lock: world.remove_block(struct.unpack("iii", positionbytes), sync=False) for address in players: if address is self.client_address: continue # He told us, we don't need to tell him players[address].sendpacket(12, "\4" + positionbytes) elif packettype == 5: # Receive chat text txtlen = struct.unpack("i", self.request.recv(4))[0] txt = "%s: %s" % (self.client_address[0], self.request.recv(txtlen)) try: #TODO: Enable the command parser again. This'll need some serverside controller object and player object #ex = self.command_parser.execute(txt, controller=self, user=self.player, world=self.world) ex = None if ex != COMMAND_HANDLED: # Not a command, send the chat to all players for address in players: players[address].sendchat(txt) print txt # May as well let console see it too except CommandException, e: self.sendchat(str(e), COMMAND_ERROR_COLOR) elif packettype == 255: # Initial Login position = (0,self.server.world.terraingen.get_height(0,0)+2,0) #Send them the sector under their feet first so they don't fall sector = sectorize(position) if sector not in world.sectors: with world.server_lock: world.open_sector(sector) msg = struct.pack("iii",*sector) + save_sector_to_string(world, sector) + world.get_exposed_sector(sector) self.sendpacket(len(msg), "\1" + msg) #Send them their spawn position self.sendpacket(12, struct.pack("B",255) + struct.pack("iii", *position))