示例#1
0
 def add_block(self,
               position,
               block,
               sync=True,
               force=True,
               check_spread=True):
     if position in self:
         if not force:
             return
         self.remove_block(position, sync=sync, check_spread=check_spread)
     if hasattr(block, 'entity_type'):
         self[position] = type(block)()
         self[position].entity = self[position].entity_type(self, position)
     elif block.sub_id_as_metadata:
         self[position] = type(block)()
         self[position].set_metadata(block.get_metadata())
     else:
         self[position] = block
     self.sectors[sectorize(position)].append(position)
     if sync:
         self.server.show_block(position, block)
     if check_spread:
         if self.is_exposed(position):
             self.check_spreading_mutable(position, block)
         self.check_neighbors(position)
示例#2
0
 def update_sector(self, dt):
     sector = sectorize(self.player.position)
     if sector != self.sector:
         self.world.change_sectors(sector)
         # When the world is loaded, show every visible sector.
         if self.sector is None:
             self.world.process_entire_queue()
         self.sector = sector
示例#3
0
 def update_sector(self, dt):
     sector = sectorize(self.player.position)
     if sector != self.sector:
         self.world.change_sectors(sector)
         # When the world is loaded, show every visible sector.
         if self.sector is None:
             self.world.process_entire_queue()
         self.sector = sector
示例#4
0
 def hide_sectors(self, dt, player):
     unload = G.DELOAD_SECTORS_RADIUS
     player_sector = sectorize(player.position)
     if player.last_sector != player_sector:
         px, py, pz = player_sector
         for sector in self.sectors:
             x, y, z = sector
             if abs(px - x) > unload or abs(py - y) > unload or abs(pz - z) > unload:
                 self.enqueue_sector(False, sector)
示例#5
0
 def hide_sectors(self, dt, player):
     #TODO: This is pretty laggy, I feel an FPS drop once a second while sector changing because of this
     deload = G.DELOAD_SECTORS_RADIUS
     plysector = sectorize(player.position)
     if player.last_sector != plysector:
         px, py, pz = plysector
         for sector in self.sectors:
             x,y,z = sector
             if abs(px-x) > deload or abs(py-y) > deload or abs(pz-z) > deload:
                 self.enqueue_sector(False, sector)
示例#6
0
文件: world.py 项目: boskee/Minecraft
 def hide_sectors(self, dt, player):
     #TODO: This is pretty laggy, I feel an FPS drop once a second while sector changing because of this
     deload = G.DELOAD_SECTORS_RADIUS
     plysector = sectorize(player.position)
     if player.last_sector != plysector:
         px, py, pz = plysector
         for sector in self.sectors:
             x,y,z = sector
             if abs(px-x) > deload or abs(py-y) > deload or abs(pz-z) > deload:
                 self.enqueue_sector(False, sector)
示例#7
0
 def remove_block(self, position, sync=True, check_spread=True):
     del self[position]
     sector_position = sectorize(position)
     try:
         self.sectors[sector_position].remove(position)
     except ValueError:
         warnings.warn('Block %s was unexpectedly not found in sector %s;'
                       'your save is probably corrupted'
                       % (position, sector_position))
     if sync:
         self.server.hide_block(position)
     if check_spread:
         self.check_neighbors(position)
示例#8
0
文件: world.py 项目: boskee/Minecraft
 def _remove_block(self, position: iVector, sync: bool = True):
     del self[position]
     sector_position = sectorize(position)
     try:
         self.sectors[sector_position].remove(position)
     except ValueError:
         warnings.warn('Block %s was unexpectedly not found in sector %s;'
                       'your save is probably corrupted'
                       % (position, sector_position))
     if sync:
         if position in self.shown:
             self.hide_block(position)
         self.check_neighbors(position)
         self.inform_neighbors_of_block_change(position)
示例#9
0
 def _remove_block(self, position, sync=True):
     del self[position]
     sector_position = sectorize(position)
     try:
         self.sectors[sector_position].remove(position)
     except ValueError:
         warnings.warn('Block %s was unexpectedly not found in sector %s;'
                       'your save is probably corrupted' %
                       (position, sector_position))
     if sync:
         if position in self.shown:
             self.hide_block(position)
         self.check_neighbors(position)
         self.inform_neighbors_of_block_change(position)
示例#10
0
 def remove_block(self,
                  position: iVector,
                  sync: bool = True,
                  check_spread: bool = True):
     del self[position]
     sector_position = sectorize(position)
     try:
         self.sectors[sector_position].remove(position)
     except ValueError:
         pass
     if sync:
         self.server.hide_block(position)
     if check_spread:
         self.check_neighbors(position)
示例#11
0
 def add_block(self, position, block, sync=True, force=True, check_spread=True):
     if position in self:
         if not force:
             return
         self.remove_block(position, sync=sync, check_spread=check_spread)
     if hasattr(block, 'entity_type'):
         self[position] = type(block)()
         self[position].entity = self[position].entity_type(self, position)
     else:
         self[position] = block
     self.sectors[sectorize(position)].append(position)
     if sync:
         self.server.show_block(position, block)
     if check_spread:
         if self.is_exposed(position):
             self.check_spreading_mutable(position, block)
         self.check_neighbors(position)
示例#12
0
    def _add_block(self, position, block):
        if position in self:
            self._remove_block(position, sync=True)
        if hasattr(block, 'entity_type'):
            # in world_server we have to create its entity to handle some tasks(growing, etc.)
            # but in client's world, we only create a TileEntity that contains the position
            # and the world to allow the block update itself and server will handle the task
            # and tell us
            self[position] = type(block)()
            self[position].entity = TileEntity(self, position)
        elif block.sub_id_as_metadata:
            self[position] = type(block)()
            self[position].set_metadata(block.get_metadata())
        else:
            self[position] = block

        self.sectors[sectorize(position)].append(position)
        if self.is_exposed(position):
            self.show_block(position)
        self.inform_neighbors_of_block_change(position)
示例#13
0
文件: world.py 项目: boskee/Minecraft
    def _add_block(self, position: iVector, block):
        if position in self:
            self._remove_block(position, sync=True)
        if hasattr(block, 'entity_type'):
            # in world_server we have to create its entity to handle some tasks(growing, etc.)
            # but in client's world, we only create a TileEntity that contains the position
            # and the world to allow the block update itself and server will handle the task
            # and tell us
            self[position] = type(block)()
            self[position].entity = TileEntity(self, position)
        elif block.sub_id_as_metadata:
            self[position] = type(block)()
            self[position].set_metadata(block.get_metadata())
        else:
            self[position] = block

        self.sectors[sectorize(position)].append(position)
        if self.is_exposed(position):
            self.show_block(position)
        self.inform_neighbors_of_block_change(position)
示例#14
0
                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.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]
示例#15
0
    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, b"\2" + struct.pack("iii",*sector))
                else:
                    msg = struct.pack("iii",*sector) + save_sector_to_bytes(world, sector) + world.get_exposed_sector(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 = 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, b"\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, b"\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 as e:
                    self.sendchat(str(e), COMMAND_ERROR_COLOR)
            elif packettype == 6:  # Player Inventory Update
                self.inventory = self.request.recv(4*40)
                #TODO: All player's inventories should be autosaved at a regular interval.
            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)
                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(38, b"\x08" + struct.pack("H", self.id) + mom_bytes + pos_bytes)
            elif packettype == 9:  # Player Jump
                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(2, b"\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))
            elif packettype == 255:  # Initial Login
                txtlen = struct.unpack("i", self.request.recv(4))[0]
                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(2 + len(name), b'\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.values():
                    if player is self: continue
                    player.sendpacket(2 + len(name), b'\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_bytes(world, sector) + world.get_exposed_sector(sector)
                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(12 + len(seed_packet), struct.pack("B",255) + struct.pack("iii", *position) + seed_packet)
                self.sendpacket(4*40, b"\6" + self.inventory)
            else:
                print("Received unknown packettype", packettype)
示例#16
0
    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)
示例#17
0
    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, b"\2" + struct.pack("iii", *sector))
                else:
                    msg = struct.pack("iii", *sector) + save_sector_to_bytes(
                        world, sector) + world.get_exposed_sector(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 = 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, b"\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, b"\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 as e:
                    self.sendchat(str(e), COMMAND_ERROR_COLOR)
            elif packettype == 6:  # Player Inventory Update
                self.inventory = self.request.recv(4 * 40)
                #TODO: All player's inventories should be autosaved at a regular interval.
            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)
                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(
                        38, b"\x08" + struct.pack("H", self.id) + mom_bytes +
                        pos_bytes)
            elif packettype == 9:  # Player Jump
                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(
                        2, b"\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))
            elif packettype == 255:  # Initial Login
                txtlen = struct.unpack("i", self.request.recv(4))[0]
                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(2 + len(name),
                                    b'\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.values():
                    if player is self: continue
                    player.sendpacket(2 + len(name),
                                      b'\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_bytes(
                    world, sector) + world.get_exposed_sector(sector)
                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(str(G.SEED))
                self.sendpacket(
                    12 + len(seed_packet),
                    struct.pack("B", 255) + struct.pack("iii", *position) +
                    seed_packet)
                self.sendpacket(4 * 40, b"\6" + self.inventory)
            else:
                print("Received unknown packettype", packettype)
                position = (0,self.server.world.terraingen.get_height(0,0)+2,0)

                # Send list of current players to the newcomer
                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]
示例#19
0
    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))