Пример #1
0
    def position_look(self, container):
        oldx, chaff, oldz, chaff = split_coords(self.player.location.x,
            self.player.location.z)

        self.player.location.load_from_packet(container)

        pos = (self.player.location.x, self.player.location.y,
            self.player.location.z)

        x, chaff, z, chaff = split_coords(pos[0], pos[2])

        if oldx != x or oldz != z:
            self.update_chunks()

        for entity in self.factory.entities_near(pos[0] * 32,
            self.player.location.y * 32, pos[2] * 32, 64):

            packet = make_packet("pickup", type=entity.entity_type,
                quantity=entity.quantity, wear=0)
            self.transport.write(packet)

            packet = make_packet("destroy", id=entity.id)
            self.transport.write(packet)

            self.factory.destroy_entity(entity)
Пример #2
0
    def get_damage_packet(self):
        """
        Make a packet representing the current damage on this chunk.

        This method is not private, but some care should be taken with it,
        since it wraps some fairly cryptic internal data structures.

        If this chunk is currently undamaged, this method will return an empty
        string, which should be safe to treat as a packet. Please check with
        `is_damaged()` before doing this if you need to optimize this case.

        To avoid extra overhead, this method should really be used in
        conjunction with `Factory.broadcast_for_chunk()`.

        Do not forget to clear this chunk's damage! Callers are responsible
        for doing this.

        >>> packet = chunk.get_damage_packet()
        >>> factory.broadcast_for_chunk(packet, chunk.x, chunk.z)
        >>> chunk.clear_damage()

        :returns: str representing a packet
        """

        if len(self.damaged) == 0:
            return ""
        elif len(self.damaged) == 1:
            # Use a single block update packet.
            x, y, z = next(iter(self.damaged))
            index = triplet_to_index((x, y, z))
            x += self.x * 16
            z += self.z * 16
            return make_packet("block", x=x, y=y, z=z,
                type=self.blocks[index], meta=self.metadata[index])
        else:
            # Use a batch update.
            coords = []
            types = []
            metadata = []
            for x, y, z in self.damaged:
                index = triplet_to_index((x, y, z))
                # Coordinates are not quite packed in the same system as the
                # indices for chunk data structures.
                # Chunk data structures are ((x * 16) + z) * 128) + y, or in
                # bit-twiddler's parlance, x << 11 | z << 7 | y. However, for
                # this, we need x << 12 | z << 8 | y, so repack accordingly.
                packed = x << 12 | z << 8 | y
                coords.append(packed)
                types.append(self.blocks[index])
                metadata.append(self.metadata[index])
            return make_packet("batch", x=self.x, z=self.z,
                length=len(coords), coords=coords, types=types,
                metadata=metadata)
Пример #3
0
    def chat(self, container):
        if container.message.startswith("/"):
            coiterate(
                self.transport.write(make_packet("chat", message=line))
                for line in self.factory.run_command(container.message[1:])
            )
        else:
            message = "<%s> %s" % (self.username, container.message)
            print message

            packet = make_packet("chat", message=message)
            self.factory.broadcast(packet)
Пример #4
0
    def login(self, protocol, container):
        protocol.username = container.username

        packet = make_packet("login", protocol=protocol.entity.id, username="", unused="", unknown1=0, unknown2=0)
        protocol.transport.write(packet)

        super(OfflineAuthenticator, self).login(protocol, container)
Пример #5
0
    def give(self, coords, block, quantity):
        """
        Spawn a pickup at the specified coordinates.

        The coordinates need to be in pixels, not blocks.
        """

        x, y, z = coords

        entity = self.create_entity(x, y, z, block, quantity)

        packet = make_packet("spawn-pickup", entity=Container(id=entity.id),
            item=block, count=quantity, x=x, y=y, z=z, yaw=0, pitch=0, roll=0)
        self.broadcast(packet)

        packet = make_packet("create", id=entity.id)
        self.broadcast(packet)
Пример #6
0
    def save_to_packet(self):
        tag = self.save_to_tag()
        sio = StringIO.StringIO()
        tag._render_buffer(sio)

        packet = make_packet("tile", x=self.x, y=self.y, z=self.z,
            nbt=sio.getvalue())
        return packet
Пример #7
0
    def save_to_packet(self):
        """
        Returns a position/look/flying packet.
        """

        position = Container(x=self.x, y=self.y, z=self.z, stance=self.stance)
        look = Container(rotation=degrees(self.theta), pitch=self.pitch)
        flying = Container(flying=self.midair)

        packet = make_packet("location", position=position, look=look, flying=flying)

        return packet
Пример #8
0
    def dispatch(self, factory, parameters):
        # XXX Do save stuff here

        # Then let's shutdown!
        message = "Server shutting down."
        yield message

        # Use an error packet to kick clients cleanly.
        packet = make_packet("error", message=message)
        factory.broadcast(packet)

        reactor.stop()
Пример #9
0
    def save_to_packet(self):
        """
        Generate a chunk packet.
        """

        array = [chr(i) for i in self.blocks]
        array += pack_nibbles(self.metadata)
        array += pack_nibbles(self.lightmap)
        array += pack_nibbles(self.skylight)
        packet = make_packet("chunk", x=self.x * 16, y=0, z=self.z * 16,
            x_size=15, y_size=127, z_size=15, data="".join(array))
        return packet
Пример #10
0
    def authenticated(self):
        self.state = STATE_AUTHENTICATED

        self.player = Player()
        self.factory.players[self.username] = self

        packet = make_packet("chat",
            message="%s is joining the game..." % self.username)
        self.factory.broadcast(packet)

        spawn = self.factory.world.spawn
        packet = make_packet("spawn", x=spawn[0], y=spawn[1], z=spawn[2])
        self.transport.write(packet)

        self.player.location.x = spawn[0]
        self.player.location.y = spawn[1]
        self.player.location.stance = spawn[1]
        self.player.location.z = spawn[2]

        tag = self.factory.world.load_player(self.username)
        if tag:
            self.player.load_from_tag(tag)

        packet = self.player.inventory.save_to_packet()
        self.transport.write(packet)
        packet = self.player.crafting.save_to_packet()
        self.transport.write(packet)
        packet = self.player.armor.save_to_packet()
        self.transport.write(packet)

        self.send_initial_chunk_and_location()

        self.ping_loop = LoopingCall(self.update_ping)
        self.ping_loop.start(5)

        self.time_loop = LoopingCall(self.update_time)
        self.time_loop.start(10)

        self.update_chunks()
Пример #11
0
    def save_to_packet(self):
        lc = ListContainer()
        for item in self.items:
            if item is None:
                lc.append(Container(id=-1))
            else:
                lc.append(Container(id=item[0], damage=item[1],
                        count=item[2]))

        packet = make_packet("inventory", unknown1=self.unknown1, length=len(lc),
            items=lc)

        return packet
Пример #12
0
    def enable_chunk(self, x, z):
        if (x, z) in self.chunks:
            return

        chunk = self.factory.world.load_chunk(x, z)

        packet = make_packet("prechunk", x=x, z=z, enabled=1)
        self.transport.write(packet)

        packet = chunk.save_to_packet()
        self.transport.write(packet)

        for entity in chunk.tileentities:
            packet = entity.save_to_packet()
            #self.transport.write(packet)

        self.chunks[x, z] = chunk
Пример #13
0
    def handshake(self, protocol, container):
        packet = make_packet("handshake", username="******")
        protocol.transport.write(packet)

        reactor.callLater(0, protocol.challenged)
Пример #14
0
 def update_time(self):
     packet = make_packet("time", timestamp=int(self.factory.time))
     self.transport.write(packet)
Пример #15
0
 def update_ping(self):
     packet = make_packet("ping")
     self.transport.write(packet)
Пример #16
0
    def disable_chunk(self, x, z):
        del self.chunks[x, z]

        packet = make_packet("prechunk", x=x, z=z, enabled=0)
        self.transport.write(packet)
Пример #17
0
 def dispatch(self, factory, parameters):
     message = "[Server] %s" % parameters
     yield message
     packet = make_packet("chat", message=message)
     factory.broadcast(packet)