Ejemplo n.º 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)
Ejemplo n.º 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)
Ejemplo n.º 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)
Ejemplo n.º 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)
Ejemplo n.º 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)
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 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()
Ejemplo n.º 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
Ejemplo n.º 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()
Ejemplo n.º 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
Ejemplo n.º 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
Ejemplo n.º 13
0
    def handshake(self, protocol, container):
        packet = make_packet("handshake", username="******")
        protocol.transport.write(packet)

        reactor.callLater(0, protocol.challenged)
Ejemplo n.º 14
0
 def update_time(self):
     packet = make_packet("time", timestamp=int(self.factory.time))
     self.transport.write(packet)
Ejemplo n.º 15
0
 def update_ping(self):
     packet = make_packet("ping")
     self.transport.write(packet)
Ejemplo n.º 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)
Ejemplo n.º 17
0
 def dispatch(self, factory, parameters):
     message = "[Server] %s" % parameters
     yield message
     packet = make_packet("chat", message=message)
     factory.broadcast(packet)