Exemple #1
0
    def __init__(self, *args, **kwargs):
        socketserver.ThreadingTCPServer.__init__(self, *args, **kwargs)
        self._stop = threading.Event()

        self.world = WorldServer(self)
        self.players = {}  # Dict of all players connected. {ipaddress: requesthandler,}
        self.player_ids = []  # List of all players this session, indexes are their ID's [0: first requesthandler,]

        self.command_parser = CommandParser()
Exemple #2
0
async def on_ready():
    '''Triggers once the bot is connected'''
    bot.channel = bot.get_channel(args.channel)
    bot.parser = CommandParser(bot)
    await bot.change_presence(status=discord.Status.offline, afk=True)
    if bot.channel is None:
        if args.channel is not None:
            cprint('Invalid channel ID provided.', 'red')

        cprint('\n'.join(('Logged in as {0.user} in no specified channel.'.format(bot),
                          'Send a channel ID to start the program')), 'green')
    else:
        cprint('Logged in as {0.user} in #{0.channel.name}'.format(bot), 'green')
Exemple #3
0

def command_BLINK(argv):
    global blink_delay
    nargs = len(argv)
    if nargs == 0:
        blink_delay = 1.0
    elif nargs == 1:
        blink_delay = float(argv[0])
    else:
        raise TypeError("%s takes up to 1 argument (%d given)" %
                        (__name__, nargs))
    print("# set blink_delay=%f" % blink_delay)


CP = CommandParser()
CP.attach("BLINK", command_BLINK)

################################################################################
# MAIN LOOP

time0 = time.monotonic()
while True:
    #handle incoming commands
    num_rx = physcomp.get_usb_rx_count()
    if num_rx > 0:
        data = sys.stdin.read(num_rx)
        CP.feed(data)
    #handle the blinking
    time1 = time.monotonic()
    if time1 - time0 > blink_delay:
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
    inventory = "\0" * (
        4 * 40
    )  # Currently, is serialized to be 4 bytes * (27 inv + 9 quickbar + 4 armor) = 160 bytes
    command_parser = CommandParser()

    operator = False

    def sendpacket(self, size, packet):
        self.request.sendall(struct.pack("i", 5 + size) + packet)

    def sendchat(self, txt, color=(255, 255, 255, 255)):
        txt = txt.encode('utf-8')
        self.sendpacket(len(txt) + 4, "\5" + txt + struct.pack("BBBB", *color))

    def sendinfo(self, info, color=(255, 255, 255, 255)):
        info = info.encode('utf-8')
        self.sendpacket(
            len(info) + 4, "\5" + info + struct.pack("BBBB", *color))

    def broadcast(self, txt):
        for player in self.server.players.itervalues():
            player.sendchat(txt)

    def sendpos(self, pos_bytes, mom_bytes):
        self.sendpacket(
            38, "\x08" + struct.pack("H", self.id) + mom_bytes + pos_bytes)

    def lookup_player(self, playername):
        # find player by name
        for player in self.server.players.values():
            if player.username == playername:
                return player
        return None

    def handle(self):
        self.username = str(self.client_address)
        print "Client connecting...", self.client_address
        self.server.players[self.client_address] = self
        self.server.player_ids.append(self)
        self.id = len(self.server.player_ids) - 1
        try:
            self.loop()
        except socket.error as e:
            if self.server._stop.isSet():
                return  # Socket error while shutting down doesn't matter
            if e[0] in (10053, 10054):
                print "Client %s %s crashed." % (self.username,
                                                 self.client_address)
            else:
                raise e

    def loop(self):
        world, players = self.server.world, self.server.players
        while 1:
            byte = self.request.recv(1)
            if not byte: return  # The client has disconnected intentionally

            packettype = struct.unpack("B", byte)[0]  # Client Packet Type
            if packettype == 1:  # Sector request
                sector = struct.unpack("iii", self.request.recv(4 * 3))

                if sector not in world.sectors:
                    with world.server_lock:
                        world.open_sector(sector)

                if not world.sectors[sector]:
                    #Empty sector, send packet 2
                    self.sendpacket(12, "\2" + struct.pack("iii", *sector))
                else:
                    msg = struct.pack("iii", *sector) + save_sector_to_string(
                        world, sector) + world.get_exposed_sector(sector)
                    self.sendpacket(len(msg), "\1" + msg)
            elif packettype == 3:  # Add block
                positionbytes = self.request.recv(4 * 3)
                blockbytes = self.request.recv(2)

                position = struct.unpack("iii", positionbytes)
                blockid = G.BLOCKS_DIR[struct.unpack("BB", blockbytes)]
                with world.server_lock:
                    world.add_block(position, blockid, sync=False)

                for address in players:
                    if address is self.client_address:
                        continue  # He told us, we don't need to tell him
                    players[address].sendpacket(
                        14, "\3" + positionbytes + blockbytes)
            elif packettype == 4:  # Remove block
                positionbytes = self.request.recv(4 * 3)

                with world.server_lock:
                    world.remove_block(struct.unpack("iii", positionbytes),
                                       sync=False)

                for address in players:
                    if address is self.client_address:
                        continue  # He told us, we don't need to tell him
                    players[address].sendpacket(12, "\4" + positionbytes)
            elif packettype == 5:  # Receive chat text
                txtlen = struct.unpack("i", self.request.recv(4))[0]
                raw_txt = self.request.recv(txtlen).decode('utf-8')
                txt = "%s: %s" % (self.username, raw_txt)
                try:
                    if raw_txt[0] == '/':
                        ex = self.command_parser.execute(raw_txt,
                                                         user=self,
                                                         world=world)
                        if ex != COMMAND_HANDLED:
                            self.sendchat('$$rUnknown command.')
                    else:
                        # Not a command, send the chat to all players
                        for address in players:
                            players[address].sendchat(txt)
                        print txt  # May as well let console see it too
                except CommandException, e:
                    self.sendchat(str(e), COMMAND_ERROR_COLOR)
            elif packettype == 6:  # Player Inventory Update
                self.inventory = self.request.recv(4 * 40)
                #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, "\x08" + struct.pack("H", self.id) + mom_bytes +
                        pos_bytes)
Exemple #5
0
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
    inv = None

    def get_inv(self):
        global inv
        return inv

    def set_inv(self, value):
        global inv
        inv = value
        # if type(value[1]) == bytes:
        # raise Exception("")
        print("INVENTORY_EX:", value)

    inventory = property(
        get_inv, set_inv
    )  # "\0" * (4 * 40)  # Currently, is serialized to be 4 bytes * (27 inv + 9 quickbar + 4 armor) = 160 bytes
    command_parser = CommandParser()

    operator = False

    def __init__(self, *args, **kwargs):
        super(ThreadedTCPRequestHandler, self).__init__(*args, **kwargs)
        self.packageSystem = PackageSystem(self.request)

    def sendpacket(self, size, packet):
        # py_000002 = struct.pack("i", 5 + size)
        # print(py_000002, packet)
        # if type(packet) == str:
        #     packet = packet.encode("utf-8")
        # self.request.sendall(py_000002 + packet)
        if not hasattr(self, "packageSystem"):
            self.packageSystem = PackageSystem(self.request)
        # print("SENDPACKET_SERVER:", packet) if packet["packetType"] != 1 and packet["packetType"] != 2 else None
        # if packet["packetType"] == 6:
        #     exit(0)
        self.packageSystem: PackageSystem
        self.packageSystem.sendall(packet)

    def sendchat(self, txt, color=(255, 255, 255, 255)):
        txt = txt.encode('utf-8')
        self.sendpacket(None, {
            "packetType": 5,
            "packet": {
                "message": txt,
                "color": color
            }
        })
        # self.sendpacket(len(txt) + 4, b"\5" + txt + struct.pack("BBBB", *color))

    def sendinfo(self, info, color=(255, 255, 255, 255)):
        info = info.encode('utf-8')
        self.sendpacket(None, {
            "packetType": 5,
            "packet": {
                "message": info,
                "color": color
            }
        })
        # self.sendpacket(len(info) + 4, "\5" + info + struct.pack("BBBB", *color))

    def broadcast(self, txt):
        for player in self.server.players.values():
            player.sendchat(txt)

    def sendpos(self, pos_bytes, mom_bytes, *, momentum, position):
        self.sendpacket(
            None, {
                "packetType": 8,
                "packet": {
                    "playerID": self.id,
                    "momentum": momentum,
                    "position": position
                }
            })
        # self.sendpacket(38, "\x08" + struct.pack("H", self.id) + mom_bytes + pos_bytes)

    def lookup_player(self, playername):
        # find player by name
        for player in list(self.server.players.values()):
            if player.username == playername:
                return player
        return None

    def handle(self):
        self.username = str(self.client_address)
        print("Client connecting...", self.client_address)
        self.server.players[self.client_address] = self
        self.server.player_ids.append(self)
        self.id = len(self.server.player_ids) - 1
        try:
            self.loop()
        except socket.error as e:
            if self.server._stop.isSet():
                return  # Socket error while shutting down doesn't matter
            if e[0] in (10053, 10054):
                print("Client %s %s crashed." %
                      (self.username, self.client_address))
            else:
                raise e

    def loop(self):
        world, players = self.server.world, self.server.players
        package_system = PackageSystem(self.request)
        while 1:
            # byte = self.request.recv(1)
            try:
                data = package_system.recv()
            except ValueError:
                return
            # print("Server recieved packet: %s" % data)
            packettype = data["packetType"]
            packet = data["packet"]
            # print(f"SERVERPACKET:", data) if packettype != 1 else None
            # if not byte: return  # The client has disconnected intentionally

            # packettype = struct.unpack("B", byte)[0]  # Client Packet Type
            if packettype == 1:  # Sector request
                # sector = struct.unpack("iii", self.request.recv(4 * 3))
                sector = packet["sector"]

                # print("SECTORCHANGE_CURRENT:", sector)
                # print("SECTORCHANGE_ALL:", world.sectors)
                # print("SECTORIZE_NEW:", sector in world.sectors)

                if sector not in world.sectors:
                    with world.server_lock:
                        world.open_sector(sector)

                if not world.sectors[sector]:
                    # Empty sector, send packet 2
                    self.sendpacket(None, {
                        "packetType": 2,
                        "packet": {
                            "sector": sector
                        }
                    })
                    # self.sendpacket(12, b"\2" + struct.pack("iii", *sector))
                else:
                    # py_000005 = save_sector_to_string(world, sector)
                    # py_000003 = (py_000005.encode("utf-8") if type(py_000005) == str else py_000005)
                    # py_000004 = world.get_exposed_sector(sector).encode("utf-8")
                    # msg = struct.pack("iii", *sector) + py_000003 + py_000004
                    self.sendpacket(
                        None, {
                            "packetType": 1,
                            "packet": {
                                "sector": sector,
                                "exposedSector":
                                world.get_exposed_sector(sector),
                                "sectorData": save_sector_to_string(
                                    world, sector)
                            }
                        })
                    # self.sendpacket(len(msg), b"\1" + msg)
            elif packettype == 3:  # Add block
                # positionbytes = self.request.recv(4 * 3)
                # blockbytes = self.request.recv(2)
                position = packet["position"]
                blockid = G.BLOCKS_DIR[packet["block"]]

                # position = struct.unpack("iii", positionbytes)
                # blockid = G.BLOCKS_DIR[struct.unpack("BB", blockbytes)]
                with world.server_lock:
                    world.add_block(position, blockid, sync=False)

                for address in players:
                    if address is self.client_address:
                        continue  # He told us, we don't need to tell him
                    players[address].packageSystem.send({
                        "packetType": 3,
                        "packet": {
                            "position": position,
                            "block": blockid
                        }
                    })
                    # players[address].sendpacket(14, "\3" + positionbytes + blockbytes)
            elif packettype == 4:  # Remove block
                # positionbytes = self.request.recv(4 * 3)

                with world.server_lock:
                    world.remove_block(packet["position"], sync=False)

                for address in players:
                    if address is self.client_address:
                        continue  # He told us, we don't need to tell him
                    players[address].sendpacket(12, "\4" + positionbytes)
            elif packettype == 5:  # Receive chat text
                # txtlen = struct.unpack("i", self.request.recv(4))[0]
                # raw_txt = self.request.recv(txtlen).decode('utf-8')
                raw_txt = packet["message"].decode()
                txt = "%s: %s" % (self.username.decode(), raw_txt)
                try:
                    if raw_txt[0] == '/':
                        ex = self.command_parser.execute(raw_txt,
                                                         user=self,
                                                         world=world)
                        if ex != COMMAND_HANDLED:
                            self.sendchat('$$rUnknown command.')
                    else:
                        # Not a command, send the chat to all players
                        for address in players:
                            players[address].sendchat(txt)
                        print(txt)  # May as well let console see it too
                except CommandException as e:
                    self.sendchat(str(e), COMMAND_ERROR_COLOR)
            elif packettype == 6:  # Player Inventory Update
                print("SERVER_PACKET06:", packet)
                self.inventory = packet["items"]
                # TODO: All player's inventories should be autosaved at a regular interval.
                pass
            elif packettype == 8:  # Player Movement
                # mom_bytes, pos_bytes = self.request.recv(4 * 3), self.request.recv(8 * 3)
                # self.momentum = struct.unpack("fff", mom_bytes)
                # self.position = struct.unpack("ddd", pos_bytes)
                self.momentum = packet["momentum"]
                self.position = packet["position"]
                for address in players:
                    if address is self.client_address:
                        continue  # He told us, we don't need to tell him
                    # TODO: Only send to nearby players
                    self.sendpacket(
                        None, {
                            "packetType": 8,
                            "packet": {
                                "playerID": self.id,
                                "momentum": self.momentum,
                                "position": self.position
                            }
                        })
                    # players[address].sendpacket(38, "\x08" + struct.pack("H", self.id) + mom_bytes + pos_bytes)
            elif packettype == 9:  # Player Jump
                # raise NotImplementedError("Player Jump not implemented")
                for address in players:
                    if address is self.client_address:
                        continue  # He told us, we don't need to tell him
                    # TODO: Only send to nearby players
                    players[address].sendpacket(None, {
                        "packetType": 9,
                        "package": {
                            "playerID": self.id
                        }
                    })
                    # players[address].sendpacket(2, "\x09" + struct.pack("H", self.id))
            elif packettype == 10:  # Update Tile Entity
                # block_pos = struct.unpack("iii", self.request.recv(4 * 3))
                # ent_size = struct.unpack("i", self.request.recv(4))[0]
                # world[block_pos].update_tile_entity(self.request.recv(ent_size))
                pass
            elif packettype == 255:  # Initial Login
                # txtlen = struct.unpack("i", self.request.recv(4))[0]
                # data2 = package_system.recv()
                self.username = packet["username"]
                # position = packet["position"]

                # self.username = self.request.recv(txtlen).decode('utf-8')
                self.position = None
                load_player(self, "world")

                for player in self.server.players.values():
                    player.sendchat("$$y%s has connected." % self.username)
                print("%s's username is %s" %
                      (self.client_address, self.username))

                position = (0,
                            self.server.world.terraingen.get_height(0, 0) + 2,
                            0)
                if self.position is None:
                    self.position = position  # New player, set initial position

                # Send list of current players to the newcomer
                for player in self.server.players.values():
                    if player is self: continue
                    name = player.username.encode('utf-8')
                    self.sendpacket(
                        None, {
                            "packetType": 7,
                            "packet": {
                                "playerID": player.id,
                                "username": name
                            }
                        })

                    # self.sendpacket(2 + len(name), '\7' + struct.pack("H", player.id) + name)
                # Send the newcomer's name to all current players
                name = self.username
                for player in self.server.players.values():
                    if player is self: continue
                    player.sendpacket(
                        None, {
                            "packetType": 7,
                            "packet": {
                                "playerID": self.id,
                                "username": name
                            }
                        })

                    # player.sendpacket(2 + len(name), '\7' + struct.pack("H", self.id) + name)

                # Send them the sector under their feet first so they don't fall
                sector = sectorize(position)
                if sector not in world.sectors:
                    with world.server_lock:
                        world.open_sector(sector)
                py_000001 = struct.pack("iii", *sector)
                sector_string = save_sector_to_string(world, sector)
                exposed_sector = world.get_exposed_sector(sector)

                # print(py_000001, sector_string, exposed_sector)
                msg = py_000001 + sector_string + exposed_sector.encode(
                    'utf-8')
                self.sendpacket(
                    None, {
                        "packetType": 1,
                        "packet": {
                            "sector": sector,
                            "exposedSector": exposed_sector,
                            "sectorData": sector_string
                        }
                    })
                # self.sendpacket(len(msg), b"\1" + msg)

                # Send them their spawn position and world seed(for client side biome generator)
                seed_packet = make_string_packet(G.SEED)

                self.sendpacket(
                    None, {
                        "packetType": 255,
                        "packet": {
                            "position": position,
                            "seed": G.SEED
                        }
                    })
                # self.sendpacket(12 + len(seed_packet),
                #                 struct.pack("B", 255) + struct.pack("iii", *position) + seed_packet)

                print("IMPORTANT0004:", self.inventory)
                print("IMPORTANT0005:", len(self.inventory) + 1)
                self.sendpacket(None, {
                    "packetType": 6,
                    "packet": {
                        "items": self.inventory
                    }
                })
                # self.sendpacket(len(self.inventory)+1, "\6" + self.inventory)
            else:
                print("Received unknown packettype", packettype)

    def finish(self):
        print("Client disconnected,", self.client_address, self.username)
        try:
            del self.server.players[self.client_address]
        except KeyError:
            pass
        for player in self.server.players.values():
            player.sendchat("%s has disconnected." % self.username)
        # Send user list
        for player in self.server.players.values():
            player.sendpacket(2 + 1, '\7' + struct.pack("H", self.id) + '\0')
        save_player(self, "world")