Пример #1
0
    def position_changed(self):
        x, chaff, z, chaff = split_coords(self.location.x, self.location.z)

        # Inform everybody of our new location.
        packet = make_packet("teleport",
            eid=self.player.eid,
            x=self.location.x * 32,
            y=self.location.y * 32,
            z=self.location.z * 32,
            yaw=int(self.location.theta * 255 / (2 * pi)) % 256,
            pitch=int(self.location.phi * 255 / (2 * pi)) % 256,
        )
        self.factory.broadcast_for_others(packet, self)

        self.update_chunks()

        for entity in self.entities_near(2):
            if entity.name != "Item":
                continue

            if self.player.inventory.add(entity.item, entity.quantity):
                packet = make_packet("collect", eid=entity.eid,
                    destination=self.player.eid)
                self.factory.broadcast(packet)

                packet = make_packet("destroy", eid=entity.eid)
                self.factory.broadcast(packet)

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

                self.factory.destroy_entity(entity)
Пример #2
0
    def position_changed(self):
        x, chaff, z, chaff = split_coords(self.location.x, self.location.z)

        # Inform everybody of our new location.
        packet = make_packet("teleport",
            eid=self.player.eid,
            x=self.location.x * 32,
            y=self.location.y * 32,
            z=self.location.z * 32,
            yaw=int(self.location.theta * 255 / (2 * pi)) % 256,
            pitch=int(self.location.phi * 255 / (2 * pi)) % 256,
        )
        self.factory.broadcast_for_others(packet, self)

        self.update_chunks()

        for entity in self.entities_near(2):
            if entity.name != "Item":
                continue

            if self.player.inventory.add(entity.item, entity.quantity):
                packet = make_packet("collect", eid=entity.eid,
                    destination=self.player.eid)
                self.factory.broadcast(packet)

                packet = make_packet("destroy", eid=entity.eid)
                self.factory.broadcast(packet)

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

                self.factory.destroy_entity(entity)
Пример #3
0
    def throw_slot(self, slot_no, count=1, item=None):
        """
        throw an item in a slot

        not sure if this is the correct way to do this.
        simulates a player opening the inventory, clicking an item
        then closing the window with the item in the cursor

        seems to bug out once in a while
        if slot is empty, there will be no error
        """

        if item == None:
            print "must incl item no"
            return

        count = item[2]

        action_no, d = self._get_next_action_no(sys.exit, None)
        
        clickit = make_packet("window-action", wid=0, slot=slot_no, button=0, \
            token=action_no, primary=item[0], secondary=item[1] , count=count)

        # send the data over the wire
        self.transport.write(clickit)

        # closing the window actualy preforms the throw
        closeit = make_packet("window-close", wid=0)

        self.transport.write(closeit)
Пример #4
0
    def authenticated(self):
        BetaServerProtocol.authenticated(self)

        self.factory.protocols[self.username] = self

        self.player = self.factory.world.load_player(self.username)
        self.player.eid = self.eid
        self.factory.entities.add(self.player)

        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)

        packet = self.player.inventory.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)
Пример #5
0
    def chat(self, container):
        if container.message.startswith("/"):

            commands = retrieve_plugins(IChatCommand)
            # Register aliases.
            for plugin in commands.values():
                for alias in plugin.aliases:
                    commands[alias] = plugin

            params = container.message[1:].split(" ")
            command = params.pop(0).lower()

            if command and command in commands:
                try:
                    for line in commands[command].chat_command(self.factory,
                        self.username, params):
                        self.transport.write(
                            make_packet("chat", message=line)
                        )
                except Exception, e:
                    self.transport.write(
                        make_packet("chat", message="Error: %s" % e)
                    )
            else:
                self.transport.write(
                    make_packet("chat",
                        message="Unknown command: %s" % command)
                )
Пример #6
0
    def hold_item(self, item):
        """
        Put an item in the bots hand.

        If the item is not in the lower panel (holdables), then it will move
        the item to an available slot in holdables.  If there are no open
        slots in holdables, some item will be swapped out and the new item
        placed in the hand, then equipted.
        """

        try:
            l, item_slot = self.bot.inventory.get_slot(item)
        except:
            print "item not found in enventory"
            return

        # item is not in holdables.  move it.
        if l != self.bot.inventory.holdables:
            try:
                holding_slot = self.bot.inventory.holdables.index(None)
            except ValueError:
                # there is no open slot in holdables
                # just use slot 40
                holding_slot = 40

            self.swap_slots(0, item_slot, holding_slot)

        # finally, change the item in the hand
        make_packet("holding_change", slot=slot_no)
Пример #7
0
    def disable_chunk(self, x, z):
        # Remove the chunk from cache.
        chunk = self.chunks.pop(x, z)

        for entity in chunk.entities:
            packet = make_packet("destroy", eid=entity.eid)
            self.transport.write(packet)

        packet = make_packet("prechunk", x=x, z=z, enabled=0)
        self.transport.write(packet)
Пример #8
0
    def disable_chunk(self, x, z):
        # Remove the chunk from cache.
        chunk = self.chunks.pop(x, z)

        for entity in chunk.entities:
            packet = make_packet("destroy", eid=entity.eid)
            self.transport.write(packet)

        packet = make_packet("prechunk", x=x, z=z, enabled=0)
        self.transport.write(packet)
Пример #9
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 self.all_damaged:
            # Resend the entire chunk!
            return self.save_to_packet()
        elif not self.damaged.any():
            return ""
        elif self.damaged.sum() == 1:
            # Use a single block update packet.
            x, z, y = [int(i) for i in zip(*self.damaged.nonzero())[0]]
            return make_packet(
                "block",
                x=x + self.x * 16,
                y=y,
                z=z + self.x * 16,
                type=int(self.blocks[x, z, y]),
                meta=int(self.metadata[x, z, y]),
            )
        else:
            # Use a batch update.
            damaged = self.damaged.nonzero()
            # 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.
            coords = [int(x << 12 | z << 8 | y) for x, z, y in zip(*damaged)]
            types = [int(i) for i in self.blocks[damaged]]
            metadata = [int(i) for i in self.metadata[damaged]]

            return make_packet(
                "batch", x=self.x, z=self.z, length=len(coords), coords=coords, types=types, metadata=metadata
            )
Пример #10
0
    def position_look(self, container):
        oldx, chaff, oldz, chaff = split_coords(self.player.location.x,
            self.player.location.z)

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

        self.player.location.load_from_packet(container)

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

        if oldpos == pos:
            # We haven't actually moved...
            return

        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,
            pos[1] * 32, pos[2] * 32, 2 * 32):
            if entity.name != "Pickup":
                continue

            if self.player.inventory.add(entity.block, entity.quantity):
                packet = self.player.inventory.save_to_packet()
                self.transport.write(packet)

                packet = make_packet("collect", eid=entity.eid,
                    destination=self.player.eid)
                self.transport.write(packet)

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

                self.factory.destroy_entity(entity)

        for entity in self.factory.entities_near(pos[0] * 32,
            pos[1] * 32, pos[2] * 32, 160 * 32):

            if (entity is self.player or
                entity.name != "Player" or
                entity.eid in self.entities):
                continue

            self.entities.add(entity.eid)

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

            packet = make_packet("create", eid=entity.eid)
            self.transport.write(packet)
Пример #11
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 self.all_damaged:
            # Resend the entire chunk!
            return self.save_to_packet()
        elif not self.damaged.any():
            return ""
        elif self.damaged.sum() == 1:
            # Use a single block update packet.
            x, z, y = [int(i) for i in zip(*self.damaged.nonzero())[0]]
            return make_packet("block",
                    x=x + self.x * 16,
                    y=y,
                    z=z + self.z * 16,
                    type=int(self.blocks[x, z, y]),
                    meta=int(self.metadata[x, z, y]))
        else:
            # Use a batch update.
            damaged = self.damaged.nonzero()
            # 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.
            coords = [int(x << 12 | z << 8 | y) for x, z, y in zip(*damaged)]
            types = [int(i) for i in self.blocks[damaged]]
            metadata = [int(i) for i in self.metadata[damaged]]

            return make_packet("batch", x=self.x, z=self.z,
                length=len(coords), coords=coords, types=types,
                metadata=metadata)
Пример #12
0
    def give(self, coords, block, quantity):
        """
        Spawn a pickup at the specified coordinates.

        The coordinates need to be in pixels, not blocks.

        :param tuple coords: coordinates, in pixels
        :param tuple block: key of block or item to drop
        :param int quantity: number of blocks to drop in the stack
        """

        x, y, z = coords

        entity = self.create_entity(x // 32,
                                    y // 32,
                                    z // 32,
                                    "Item",
                                    item=block,
                                    quantity=quantity)

        packet = entity.save_to_packet()
        self.broadcast(packet)

        packet = make_packet("create", eid=entity.eid)
        self.broadcast(packet)
Пример #13
0
    def send_initial_chunk_and_location(self):
        bigx, smallx, bigz, smallz = split_coords(self.location.x,
            self.location.z)

        # Spawn the 25 chunks in a square around the spawn, *before* spawning
        # the player. Otherwise, there's a funky Beta 1.2 bug which causes the
        # player to not be able to move.
        d = cooperate(
            self.enable_chunk(i, j)
            for i, j in product(
                xrange(bigx - 3, bigx + 3),
                xrange(bigz - 3, bigz + 3)
            )
        ).whenDone()

        # Don't dare send more chunks beyond the initial one until we've
        # spawned.
        d.addCallback(lambda none: self.update_location())
        d.addCallback(lambda none: self.position_changed())

        # Send the MOTD.
        if self.motd:
            packet = make_packet("chat",
                message=self.motd.replace("<tagline>", get_motd()))
            d.addCallback(lambda none: self.transport.write(packet))

        # Finally, start the secondary chunk loop.
        d.addCallback(lambda none: self.update_chunks())
Пример #14
0
    def sign(self, container):
        bigx, smallx, bigz, smallz = split_coords(container.x, container.z)

        try:
            chunk = self.chunks[bigx, bigz]
        except KeyError:
            self.error("Couldn't handle sign in chunk (%d, %d)!" %
                       (bigx, bigz))
            return

        if (smallx, container.y, smallz) in chunk.tiles:
            new = False
            s = chunk.tiles[smallx, container.y, smallz]
        else:
            new = True
            s = Sign(smallx, container.y, smallz)
            chunk.tiles[smallx, container.y, smallz] = s

        s.text1 = container.line1
        s.text2 = container.line2
        s.text3 = container.line3
        s.text4 = container.line4

        chunk.dirty = True

        # The best part of a sign isn't making one, it's showing everybody
        # else on the server that you did.
        packet = make_packet("sign", container)
        self.factory.broadcast_for_chunk(packet, bigx, bigz)

        # Run sign hooks.
        for hook in self.sign_hooks:
            hook.sign_hook(self.factory, chunk, container.x, container.y,
                           container.z, [s.text1, s.text2, s.text3, s.text4],
                           new)
Пример #15
0
 def animate(self, container):
     # Broadcast the animation of the entity to everyone else. Only swing
     # arm is send by notchian clients.
     packet = make_packet("animate",
                          eid=self.player.eid,
                          animation=container.animation)
     self.factory.broadcast_for_others(packet, self)
Пример #16
0
    def give(self, coords, block, quantity):
        """
        Spawn a pickup at the specified coordinates.

        The coordinates need to be in pixels, not blocks.

        If the size of the stack is too big, multiple stacks will be dropped.

        :param tuple coords: coordinates, in pixels
        :param tuple block: key of block or item to drop
        :param int quantity: number of blocks to drop in the stack
        """

        x, y, z = coords

        while quantity > 0:
            entity = self.create_entity(x // 32,
                                        y // 32,
                                        z // 32,
                                        "Item",
                                        item=block,
                                        quantity=min(quantity, 64))

            packet = entity.save_to_packet()
            packet += make_packet("create", eid=entity.eid)
            self.broadcast(packet)

            quantity -= 64
Пример #17
0
 def chat_command(self, factory, username, parameters):
     player = parse_player(factory, username)
     protocol = factory.protocols[username]
     l = protocol.player.location
     locMsg = "Your location is <%d, %d, %d>" % (l.x, l.y, l.z)
     packet = make_packet("chat", message=locMsg)
     player.transport.write(packet)
Пример #18
0
    def sign(self, container):
        bigx, smallx, bigz, smallz = split_coords(container.x, container.z)

        try:
            chunk = self.chunks[bigx, bigz]
        except KeyError:
            self.error("Couldn't handle sign in chunk (%d, %d)!" % (bigx, bigz))
            return

        if (smallx, container.y, smallz) in chunk.tiles:
            s = chunk.tiles[smallx, container.y, smallz]
        else:
            s = Sign()

        s.x = smallx
        s.y = container.y
        s.z = smallz

        s.text1 = container.line1
        s.text2 = container.line2
        s.text3 = container.line3
        s.text4 = container.line4

        chunk.tiles[smallx, container.y, smallz] = s
        chunk.dirty = True

        # The best part of a sign isn't making one, it's showing everybody
        # else on the server that you did.
        packet = make_packet("sign", container)
        self.factory.broadcast_for_chunk(packet, bigx, bigz)
Пример #19
0
    def sign(self, container):
        bigx, smallx, bigz, smallz = split_coords(container.x, container.z)

        try:
            chunk = self.chunks[bigx, bigz]
        except KeyError:
            self.error("Couldn't handle sign in chunk (%d, %d)!" % (bigx, bigz))
            return

        if (smallx, container.y, smallz) in chunk.tiles:
            new = False
            s = chunk.tiles[smallx, container.y, smallz]
        else:
            new = True
            s = Sign(smallx, container.y, smallz)
            chunk.tiles[smallx, container.y, smallz] = s

        s.text1 = container.line1
        s.text2 = container.line2
        s.text3 = container.line3
        s.text4 = container.line4

        chunk.dirty = True

        # The best part of a sign isn't making one, it's showing everybody
        # else on the server that you did.
        packet = make_packet("sign", container)
        self.factory.broadcast_for_chunk(packet, bigx, bigz)

        # Run sign hooks.
        for hook in self.sign_hooks:
            hook.sign_hook(self.factory, chunk, container.x, container.y,
                container.z, [s.text1, s.text2, s.text3, s.text4], new)
Пример #20
0
    def use_hook(self, factory, player, target, button):
        # Block coordinates.
        x, y, z = target.location.x, target.location.y, target.location.z

        # Offset coords according to direction. A painting does not
        # occupy a block, therefore we drop the pickup right in front of the
        # block it is attached to.
        face = direction_to_face[target.direction]
        if face == "-x":
            x -= 1
        elif face == "+x":
            x += 1
        elif face == "-z":
            z -= 1
        elif face == "+z":
            z += 1

        # Pixel coordinates.
        coords = (x * 32 + 16, y * 32, z * 32 + 16)

        factory.destroy_entity(target)
        factory.give(coords, (items["paintings"].slot, 0), 1)

        packet = make_packet("destroy", eid=target.eid)
        factory.broadcast(packet)

        # Force the chunk (with its entities) to be saved to disk.
        factory.world.mark_dirty((x, y, z))
Пример #21
0
    def update_ping(self):
        """
        Send a keepalive to the client.
        """

        packet = make_packet("ping")
        self.transport.write(packet)
Пример #22
0
    def build(self, container):
        # Is the target being selected?
        bigx, smallx, bigz, smallz = split_coords(container.x, container.z)
        try:
            chunk = self.chunks[bigx, bigz]
        except KeyError:
            self.error("Couldn't select in chunk (%d, %d)!" % (bigx, bigz))
            return

        if (chunk.get_block((smallx, container.y, smallz)) ==
            blocks["workbench"].slot):
            i = Workbench()
            sync_inventories(self.player.inventory, i)
            self.windows[self.wid] = i
            packet = make_packet("window-open", wid=self.wid, type="workbench",
                title="Hurp", slots=2)
            self.wid += 1
            self.transport.write(packet)
            return

        # Ignore clients that think -1 is placeable.
        if container.primary == -1:
            return

        # Special case when face is "noop": Update the status of the currently
        # held block rather than placing a new block.
        if container.face == "noop":
            return

        if container.primary in blocks:
            block = blocks[container.primary]
        elif container.primary in items:
            block = items[container.primary]
        else:
            log.err("Ignoring request to place unknown block %d" %
                container.primary)
            return

        if time() - self.last_dig_build_timer < 0.2:
            self.error("You are building too fast.")

        self.last_dig_build_timer = time()

        builddata = BuildData(block, 0x0, container.x, container.y,
            container.z, container.face)

        for hook in self.build_hooks:
            cont, builddata = hook.build_hook(self.factory, self.player,
                builddata)
            if not cont:
                break

        # Re-send inventory.
        # XXX this could be optimized if/when inventories track damage.
        packet = self.player.inventory.save_to_packet()
        self.transport.write(packet)

        # Flush damaged chunks.
        for chunk in self.chunks.itervalues():
            self.factory.flush_chunk(chunk)
Пример #23
0
    def update_ping(self):
        """
        Send a keepalive to the client.
        """

        packet = make_packet("ping")
        self.transport.write(packet)
Пример #24
0
    def the_real_write(self, text):
        """
        Send text back to the client as a chat packet.
        """

        for line in text.strip().split("\n"):
            line = line[:100]
            self.output.write(make_packet("chat", message=line))
Пример #25
0
    def server_login(self):
        # it might look funny abt "unused".  b/c MAD's packet use this name
        # but a client uses this space for a password

        # send "login packet" (3)
        p = make_packet("login", protocol=8, username=self.username, \
            unused=self.bot.password, seed=0, dimension=0)
        self.transport.write(p)
Пример #26
0
    def login(self, protocol, container):
        protocol.username = container.username

        packet = make_packet("login", protocol=protocol.eid, username="",
            unused="", seed=0, dimension=0)
        protocol.transport.write(packet)

        return succeed(None)
Пример #27
0
 def orientation_changed(self):
     # Bang your head!
     packet = make_packet("entity-orientation",
         eid=self.player.eid,
         yaw=int(self.location.theta * 255 / (2 * pi)) % 256,
         pitch=int(self.location.phi * 255 / (2 * pi)) % 256,
     )
     self.factory.broadcast_for_others(packet, self)
Пример #28
0
    def login(self, protocol, container):
        protocol.username = container.username

        packet = make_packet("login", protocol=protocol.eid, username="",
            unused="", seed=0, dimension=0)
        protocol.transport.write(packet)

        super(OfflineAuthenticator, self).login(protocol, container)
Пример #29
0
    def waction(self, container):
        if container.wid == 0:
            # Inventory.
            i = self.player.inventory
        elif container.wid in self.windows:
            i = self.windows[container.wid]
        else:
            self.error("Couldn't find window %d" % container.wid)

        selected = i.select(container.slot, bool(container.button))

        if selected:
            # XXX should be if there's any damage to the inventory
            packet = i.save_to_packet()
            self.transport.write(packet)

            # Inform other players about changes to this player's equipment.
            if container.wid == 0 and (container.slot in range(5, 9)
                                       or container.slot == 36):

                # Armor changes.
                if container.slot in range(5, 9):
                    item = i.armor[container.slot - 5]
                    # Order of slots is reversed in the equipment package.
                    slot = 4 - (container.slot - 5)
                # Currently equipped item changes.
                elif container.slot == 36:
                    item = i.holdables[0]
                    slot = 0

                if item is None:
                    primary, secondary = 65535, 0
                else:
                    primary, secondary, count = item
                packet = make_packet("entity-equipment",
                                     eid=self.player.eid,
                                     slot=slot,
                                     primary=primary,
                                     secondary=secondary)
                self.factory.broadcast_for_others(packet, self)

        packet = make_packet("window-token",
                             wid=0,
                             token=container.token,
                             acknowledged=selected)
        self.transport.write(packet)
Пример #30
0
 def orientation_changed(self):
     # Bang your head!
     packet = make_packet("entity-orientation",
         eid=self.player.eid,
         yaw=int(self.location.theta * 255 / (2 * pi)) % 256,
         pitch=int(self.location.phi * 255 / (2 * pi)) % 256,
     )
     self.factory.broadcast_for_others(packet, self)
Пример #31
0
 def animate(self, container):
     # Broadcast the animation of the entity to everyone else. Only swing
     # arm is send by notchian clients.
     packet = make_packet("animate",
         eid=self.player.eid,
         animation=container.animation
     )
     self.factory.broadcast_for_others(packet, self)
Пример #32
0
    def write(self, text):
        """
        Send text back to the client.
        """

        for line in text.strip().split("\n"):
            line = line[:100]
            self.stdout.write(make_packet("chat", message=line))
Пример #33
0
    def waction(self, container):
        if container.wid == 0:
            # Inventory.
            i = self.player.inventory
        elif container.wid in self.windows:
            i = self.windows[container.wid]
        else:
            self.error("Couldn't find window %d" % container.wid)

        selected = i.select(container.slot, bool(container.button))

        if selected:
            # XXX should be if there's any damage to the inventory
            packet = i.save_to_packet()
            self.transport.write(packet)

            # Inform other players about changes to this player's equipment.
            if container.wid == 0 and (container.slot in range(5, 9) or
                                       container.slot == 36):

                # Armor changes.
                if container.slot in range(5, 9):
                    item = i.armor[container.slot - 5]
                    # Order of slots is reversed in the equipment package.
                    slot = 4 - (container.slot - 5)
                # Currently equipped item changes.
                elif container.slot == 36:
                    item = i.holdables[0]
                    slot = 0

                if item is None:
                    primary, secondary = 65535, 0
                else:
                    primary, secondary, count = item
                packet = make_packet("entity-equipment",
                    eid=self.player.eid,
                    slot=slot,
                    primary=primary,
                    secondary=secondary
                )
                self.factory.broadcast_for_others(packet, self)

        packet = make_packet("window-token", wid=0, token=container.token,
            acknowledged=selected)
        self.transport.write(packet)
Пример #34
0
    def success(self, response, protocol, container):

        if response != "YES":
            protocol.error("Authentication server didn't like you.")
            return

        packet = make_packet("login", protocol=protocol.eid, username="",
            unused="", seed=0, dimension=0)
        protocol.transport.write(packet)
Пример #35
0
    def login(self, protocol, container):
        protocol.username = container.username

        packet = make_packet("login", protocol=protocol.eid, username="",
            unused="", seed=protocol.factory.world.seed,
            dimension=protocol.factory.world.dimension)
        protocol.transport.write(packet)

        return succeed(None)
Пример #36
0
    def authenticated(self):
        BetaServerProtocol.authenticated(self)

        # Init player, and copy data into it.
        self.player = yield self.factory.world.load_player(self.username)
        self.player.eid = self.eid
        self.location = self.player.location

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

        # Craft our avatar and send it to already-connected other players.
        packet = self.player.save_to_packet()
        packet += make_packet("create", eid=self.player.eid)
        self.factory.broadcast_for_others(packet, self)

        # And of course spawn all of those players' avatars in our client as
        # well. Note that, at this point, we are not listed in the factory's
        # list of protocols, so we won't accidentally send one of these to
        # ourselves.
        for protocol in self.factory.protocols.itervalues():
            packet = protocol.player.save_to_packet()
            self.transport.write(packet)
            packet = protocol.player.save_equipment_to_packet()
            self.transport.write(packet)
            packet = make_packet("create", eid=protocol.player.eid)
            self.transport.write(packet)

        self.factory.protocols[self.username] = self

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

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

        self.send_initial_chunk_and_location()

        self.time_loop = LoopingCall(self.update_time)
        self.time_loop.start(10)
Пример #37
0
 def save_to_packet(self):
     return make_packet(
         "painting",
         eid=self.eid,
         title=self.motive,
         x=self.location.x,
         y=self.location.y,
         z=self.location.z,
         direction=self.direction,
     )
Пример #38
0
    def authenticated(self):
        BetaServerProtocol.authenticated(self)

        # Init player, and copy data into it.
        self.player = yield self.factory.world.load_player(self.username)
        self.player.eid = self.eid
        self.location = self.player.location

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

        # Craft our avatar and send it to already-connected other players.
        packet = self.player.save_to_packet()
        packet += make_packet("create", eid=self.player.eid)
        self.factory.broadcast_for_others(packet, self)

        # And of course spawn all of those players' avatars in our client as
        # well. Note that, at this point, we are not listed in the factory's
        # list of protocols, so we won't accidentally send one of these to
        # ourselves.
        for protocol in self.factory.protocols.itervalues():
            packet = protocol.player.save_to_packet()
            self.transport.write(packet)
            packet = protocol.player.save_equipment_to_packet()
            self.transport.write(packet)
            packet = make_packet("create", eid=protocol.player.eid)
            self.transport.write(packet)

        self.factory.protocols[self.username] = self

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

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

        self.send_initial_chunk_and_location()

        self.time_loop = LoopingCall(self.update_time)
        self.time_loop.start(10)
Пример #39
0
    def success(self, response, protocol, container):

        if response != "YES":
            protocol.error("Authentication server didn't like you.")
            return

        packet = make_packet("login", protocol=protocol.eid, username="",
            unused="", seed=protocol.factory.world.seed,
            dimension=protocol.factory.world.dimension)
        protocol.transport.write(packet)
Пример #40
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, "Pickup")
        entity.block = block
        entity.quantity = quantity

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

        packet = make_packet("create", eid=entity.eid)
        self.broadcast(packet)
Пример #41
0
 def save_to_packet(self):
     packet = make_packet("sign",
                          x=self.x,
                          y=self.y,
                          z=self.z,
                          line1=self.text1,
                          line2=self.text2,
                          line3=self.text3,
                          line4=self.text4)
     return packet
Пример #42
0
 def dispatch(self, factory, parameters):
     player = parse_player(factory, parameters[0])
     if len(parameters) == 1:
         msg = "%s has been kicked." % parameters[0]
     elif len(parameters) > 1:
         reason = " ".join(parameters[1:])
         msg = "%s has been kicked for %s" % (parameters[0], reason)
     packet = make_packet("error", message=msg)
     player.transport.write(packet)
     yield msg
Пример #43
0
 def dispatch(self, factory, parameters):
     player = parse_player(factory, parameters[0])
     if len(parameters) == 1:
         msg = "%s has been kicked." % parameters[0]
     elif len(parameters) > 1:
         reason = " ".join(parameters[1:])
         msg = "%s has been kicked for %s" % (parameters[0],reason)
     packet = make_packet("error", message=msg)
     player.transport.write(packet)
     yield msg
Пример #44
0
    def send_chunk(self, chunk):
        packet = make_packet("prechunk", x=chunk.x, z=chunk.z, enabled=1)
        self.transport.write(packet)

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

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

            packet = make_packet("create", eid=entity.eid)
            self.transport.write(packet)

        for entity in chunk.tiles.itervalues():
            if entity.name == "Sign":
                packet = entity.save_to_packet()
                self.transport.write(packet)

        self.chunks[chunk.x, chunk.z] = chunk
Пример #45
0
    def send_chunk(self, chunk):
        packet = make_packet("prechunk", x=chunk.x, z=chunk.z, enabled=1)
        self.transport.write(packet)

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

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

            packet = make_packet("create", eid=entity.eid)
            self.transport.write(packet)

        for entity in chunk.tiles.itervalues():
            if entity.name == "Sign":
                packet = entity.save_to_packet()
                self.transport.write(packet)

        self.chunks[chunk.x, chunk.z] = chunk
Пример #46
0
    def login(self, container):
        self.username = container.username

        packet = make_packet("login", protocol=0, username="", unused="",
            seed=0, dimension=0)
        self.transport.write(packet)

        url = urlunparse(("http", self.gateway, "/node/0/0/", None, None,
            None))
        d = getPage(url)
        d.addCallback(self.start_proxy)
Пример #47
0
    def login(self, container):
        self.username = container.username

        packet = make_packet("login", protocol=0, username="", unused="",
            seed=0, dimension=0)
        self.transport.write(packet)

        url = urlunparse(("http", self.gateway, "/node/0/0/", None, None,
            None))
        d = getPage(url)
        d.addCallback(self.start_proxy)
Пример #48
0
 def save_to_packet(self):
     return make_packet("pickup",
                        eid=self.eid,
                        primary=self.item[0],
                        secondary=self.item[1],
                        count=self.quantity,
                        x=self.location.x * 32 + 16,
                        y=self.location.y * 32,
                        z=self.location.z * 32 + 16,
                        yaw=0,
                        pitch=0,
                        roll=0)
Пример #49
0
    def save_to_packet(self):
        """
        Generate a chunk packet.
        """

        array = self.blocks.tostring()
        array += pack_nibbles(self.metadata)
        array += pack_nibbles(self.blocklight)
        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=array)
        return packet
Пример #50
0
    def save_to_packet(self):
        """
        Returns a position/look/grounded packet.
        """

        position = Container(x=self.x, y=self.stance, z=self.z, stance=self.y)
        orientation = Container(rotation=self.yaw, pitch=self.pitch)
        grounded = Container(grounded=self.grounded)

        packet = make_packet("location", position=position,
            orientation=orientation, grounded=grounded)

        return packet
Пример #51
0
    def login(self, protocol, container):
        if container.password != configuration.get("bravo", "password"):
            protocol.error("Wrong password.")
            return fail()

        protocol.username = container.username

        packet = make_packet("login", protocol=protocol.eid, username="",
            unused="", seed=protocol.factory.world.seed,
            dimension=protocol.factory.world.dimension)
        protocol.transport.write(packet)

        return succeed(None)
Пример #52
0
    def handshake(self, protocol, container):
        """
        Handle a handshake with an online challenge.
        """

        challenge = "%x" % random.randint(0, sys.maxint)
        self.challenges[protocol] = challenge

        packet = make_packet("handshake", username=challenge)

        d = deferLater(reactor, 0, protocol.challenged)
        d.addCallback(lambda none: protocol.transport.write(packet))

        return True
Пример #53
0
    def console_command(self, factory, parameters):
        # 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)

        yield "Saving all chunks to disk..."
        for chunk in factory.world.dirty_chunk_cache.itervalues():
            factory.world.save_chunk(chunk)

        yield "Halting."
        reactor.stop()
Пример #54
0
    def chat(self, container):
        if container.message.startswith("/"):

            commands = retrieve_plugins(IChatCommand)
            # Register aliases.
            for plugin in commands.values():
                for alias in plugin.aliases:
                    commands[alias] = plugin

            params = container.message[1:].split(" ")
            command = params.pop(0).lower()

            if command and command in commands:
                try:
                    for line in commands[command].chat_command(
                            self.factory, self.username, params):
                        self.transport.write(make_packet("chat", message=line))
                except Exception, e:
                    self.transport.write(
                        make_packet("chat", message="Error: %s" % e))
            else:
                self.transport.write(
                    make_packet("chat",
                                message="Unknown command: %s" % command))
Пример #55
0
    def handshake(self, protocol, container):
        """
        Handle a handshake with an offline challenge.

        This will authenticate just about anybody.
        """

        packet = make_packet("handshake", username="******")

        # Order is important here; the challenged callback *must* fire before
        # we send anything back to the client, because otherwise we won't have
        # a valid entity ready to use.
        d = deferLater(reactor, 0, protocol.challenged)
        d.addCallback(lambda none: protocol.transport.write(packet))

        return True
Пример #56
0
    def handshake(self, protocol, container):
        """
        Handle a handshake with a server-specific password.

        This doesn't work with Notchian clients.
        """

        packet = make_packet("handshake", username="******")

        # Order is important here; the challenged callback *must* fire before
        # we send anything back to the client, because otherwise we won't have
        # a valid entity ready to use.
        d = deferLater(reactor, 0, protocol.challenged)
        d.addCallback(lambda none: protocol.transport.write(packet))

        return True
Пример #57
0
    def equip(self, container):
        self.player.equipped = container.item

        # Inform everyone about the item the player is holding now.
        item = self.player.inventory.holdables[self.player.equipped]
        if item is None:
            # Empty slot. Use signed short -1 == unsigned 65535.
            primary, secondary = 65535, 0
        else:
            primary, secondary, count = item

        packet = make_packet("entity-equipment",
                             eid=self.player.eid,
                             slot=0,
                             primary=primary,
                             secondary=secondary)
        self.factory.broadcast_for_others(packet, self)
Пример #58
0
    def save_to_packet(self):
        lc = ListContainer()
        for item in chain(self.crafted, self.crafting, self.armor,
                          self.storage, self.holdables):
            if item is None:
                lc.append(Container(primary=-1))
            else:
                lc.append(
                    Container(primary=item[0],
                              secondary=item[1],
                              count=item[2]))

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

        return packet
Пример #59
0
    def chat(self, message):
        """
        Relay chat messages.

        Chat messages are sent to all connected clients, as well as to anybody
        consuming this factory.
        """

        for consumer in self.chat_consumers:
            consumer.write((self, message))

        # Prepare the message for chat packeting.
        for user in self.protocols:
            message = message.replace(user, chat_name(user))
        message = sanitize_chat(message)

        packet = make_packet("chat", message=message)
        self.broadcast(packet)
Пример #60
0
    def connectionLost(self, reason):
        if self.time_loop:
            self.time_loop.stop()

        if self.chunk_tasks:
            for task in self.chunk_tasks:
                try:
                    task.stop()
                except (TaskDone, TaskFailed):
                    pass

        if self.player:
            self.factory.world.save_player(self.username, self.player)
            self.factory.destroy_entity(self.player)
            packet = make_packet("destroy", eid=self.player.eid)
            self.factory.broadcast(packet)

        if self.username in self.factory.protocols:
            del self.factory.protocols[self.username]