Example #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()
Example #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')
class CommandsTest(unittest.TestCase):

    def setUp(self):
        self.parser = CommandParser()
        
    def test_add_command(self):
        self.parser.add_command('plus', plus)
        self.assertEqual({'plus': plus}, self.parser._CommandParser__commands)

    def test_parse_arguments(self):
        result = self.parser.parse_arguments('(1, 2)')
        # ToDo
                
    def test_execute_key_error(self):
        self.parser.add_command('plus', plus)
        result = self.parser.execute('minus; 3')
        self.assertEqual('No such command', result)

    def test_execute(self):
        self.parser.add_command('plus', plus)
        result = self.parser.execute('plus; (1, 2)')
        self.assertEqual(3, result)
Example #4
0
class IRCBotFactory(protocol.ClientFactory):
    protocol = IRCBot

    def __init__(self, hostname, port, channel, path):
        self.hostname = hostname
        self.port = port
        self.channel = channel
        self.path = path
        self.commands = CommandParser()

    def clientConnectionLost(self, connector, reason):
        print "Connection lost: {}".format(reason)
        print "Reconnecting..."
        connector.connect()

    def clientConnectionFailed(self, connector, reason):
        print "Connection failed: {}".format(reason)
        reactor.stop()

    def command(self, pattern):
        return self.commands.command(pattern)
Example #5
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:
Example #6
0
class GameController(Controller):
    def __init__(self, window):
        super(GameController, self).__init__(window)
        self.sector = None
        self.time_of_day = 0.0
        self.count = 0
        self.clock = 6
        self.light_y = 1.0
        self.light_z = 1.0
        self.bg_red = 0.0
        self.bg_green = 0.0
        self.bg_blue = 0.0
        self.hour_deg = 15.0
        self.highlighted_block = None
        self.block_damage = 0
        self.crack = None
        self.mouse_pressed = False
        self.last_key = None
        self.sorted = False

    def update(self, dt):
        sector = sectorize(self.player.position)
        if sector != self.sector:
            self.model.change_sectors(self.sector, sector)
            # When the world is loaded, show every visible sector.
            if self.sector is None:
                self.model.process_entire_queue()
            self.sector = sector

        self.model.content_update(dt)

        m = 8
        df = min(dt, 0.2)
        for _ in xrange(m):
            self.player.update(df / m, self)
        if self.mouse_pressed:
            vector = self.player.get_sight_vector()
            block, previous = self.model.hit_test(self.player.position, vector, self.player.attack_range)
            if block:
                if self.highlighted_block != block:
                    self.set_highlighted_block(block)
            else:
                self.set_highlighted_block(None)

            if self.highlighted_block:
                hit_block = self.model[self.highlighted_block]
                if hit_block.hardness >= 0:

                    multiplier = 1
                    current_item = self.item_list.get_current_block()
                    if current_item is not None:
                        if isinstance(current_item, Tool):  # tool
                            if current_item.tool_type == hit_block.digging_tool:
                                multiplier = current_item.multiplier

                    self.block_damage += self.player.attack_power * dt * multiplier
                    if self.block_damage >= hit_block.hardness:
                        self.model.remove_block(self.player, self.highlighted_block)
                        self.set_highlighted_block(None)
                        if hit_block.drop_id is not None and self.player.add_item(hit_block.drop_id):
                            self.item_list.update_items()
                            self.inventory_list.update_items()
        self.update_time()
        self.camera.update(dt)

    def setup(self):
        glClearColor(self.bg_red, self.bg_green, self.bg_blue, 1)
        glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)
        glEnable(GL_LIGHT1)
        glEnable(GL_LIGHT2)
        glEnable(GL_ALPHA_TEST)
        glAlphaFunc(GL_GREATER, 0.1)
        glEnable(GL_BLEND)
        glEnable(GL_LINE_SMOOTH)

        if G.FOG_ENABLED:
            glEnable(GL_FOG)
            glFogfv(GL_FOG_COLOR, vec(self.bg_red, self.bg_green, self.bg_blue, 1))
            glHint(GL_FOG_HINT, GL_DONT_CARE)
            glFogi(GL_FOG_MODE, GL_LINEAR)
            glFogf(GL_FOG_DENSITY, 0.35)
            glFogf(GL_FOG_START, 20.0)
            glFogf(GL_FOG_END, G.DRAW_DISTANCE)  # 80)

        self.focus_block = Block(width=1.05, height=1.05)
        self.earth = vec(0.8, 0.8, 0.8, 1.0)
        self.white = vec(1.0, 1.0, 1.0, 1.0)
        self.ambient = vec(1.0, 1.0, 1.0, 1.0)
        self.polished = GLfloat(100.0)
        self.crack_batch = pyglet.graphics.Batch()
        if G.DISABLE_SAVE and world_exists(G.game_dir, G.SAVE_FILENAME):
            open_world(self, G.game_dir, G.SAVE_FILENAME)
        else:
            self.model = Model()
            self.player = Player((0, 0, 0), (-20, 0), game_mode=G.GAME_MODE)
        print("Game mode: " + self.player.game_mode)
        self.item_list = ItemSelector(self, self.player, self.model)
        self.inventory_list = InventorySelector(self, self.player, self.model)
        self.item_list.on_resize(self.window.width, self.window.height)
        self.inventory_list.on_resize(self.window.width, self.window.height)
        self.text_input = TextWidget(self.window, "", 0, 0, self.window.width, visible=False, font_name="Arial")
        self.text_input.push_handlers(on_toggled=self.on_text_input_toggled, key_released=self.text_input_callback)
        self.chat_box = TextWidget(
            self.window,
            "",
            0,
            self.text_input.y + self.text_input.height + 50,
            self.window.width / 2,
            height=min(300, self.window.height / 3),
            visible=False,
            multi_line=True,
            readonly=True,
            font_size=14,
            font_name="Arial",
            background_color=(64, 64, 64, 200),
        )
        self.command_parser = CommandParser()
        self.camera = Camera3D(target=self.player)
        if G.HUD_ENABLED:
            self.label = pyglet.text.Label(
                "",
                font_name="Arial",
                font_size=8,
                x=10,
                y=self.window.height - 10,
                anchor_x="left",
                anchor_y="top",
                color=(255, 255, 255, 255),
            )
        pyglet.clock.schedule_interval_soft(self.model.process_queue, 1.0 / G.MAX_FPS)

    def update_time(self):
        """
        The idle function advances the time of day.
        The day has 24 hours, from sunrise to sunset and from sunrise to
        second sunset.
        The time of day is converted to degrees and then to radians.
        """

        if not self.window.exclusive:
            return

        time_of_day = self.time_of_day if self.time_of_day < 12.0 else 24.0 - self.time_of_day

        if time_of_day <= 2.5:
            self.time_of_day += 1.0 / G.TIME_RATE
            time_of_day += 1.0 / G.TIME_RATE
            self.count += 1
        else:
            self.time_of_day += 20.0 / G.TIME_RATE
            time_of_day += 20.0 / G.TIME_RATE
            self.count += 1.0 / 20.0
        if self.time_of_day > 24.0:
            self.time_of_day = 0.0
            time_of_day = 0.0

        side = len(self.model.sectors) * 2.0

        self.light_y = 2.0 * side * sin(time_of_day * self.hour_deg * G.DEG_RAD)
        self.light_z = 2.0 * side * cos(time_of_day * self.hour_deg * G.DEG_RAD)
        if time_of_day <= 2.5:
            ambient_value = 1.0
        else:
            ambient_value = 1 - (time_of_day - 2.25) / 9.5
        self.ambient = vec(ambient_value, ambient_value, ambient_value, 1.0)

        # Calculate sky colour according to time of day.
        sin_t = sin(pi * time_of_day / 12.0)
        self.bg_red = 0.1 * (1.0 - sin_t)
        self.bg_green = 0.9 * sin_t
        self.bg_blue = min(sin_t + 0.4, 0.8)

        if fmod(self.count / 2, G.TIME_RATE) == 0:
            if self.clock == 18:
                self.clock = 6
            else:
                self.clock += 1

    def set_highlighted_block(self, block):
        self.highlighted_block = block
        self.block_damage = 0
        if self.crack:
            self.crack.delete()
        self.crack = None

    def save_to_file(self):
        if G.DISABLE_SAVE:
            save_world(self, G.game_dir, G.SAVE_FILENAME)

    def on_mouse_press(self, x, y, button, modifiers):
        if self.window.exclusive:
            vector = self.player.get_sight_vector()
            block, previous = self.model.hit_test(self.player.position, vector, self.player.attack_range)
            if button == pyglet.window.mouse.LEFT:
                if block:
                    self.mouse_pressed = True
                    self.set_highlighted_block(None)
            else:
                if previous:
                    hit_block = self.model[block]

                    # show craft table gui
                    if hit_block.id == craft_block.id:
                        self.inventory_list.mode = 1
                        self.inventory_list.toggle(False)
                        return

                    if hit_block.id == furnace_block.id:
                        self.inventory_list.mode = 2
                        self.inventory_list.toggle(False)
                        return

                    if hit_block.density >= 1:
                        current_block = self.item_list.get_current_block()
                        if current_block is not None:
                            # if current block is an item,
                            # call its on_right_click() method to handle this event
                            if current_block.id >= G.ITEM_ID_MIN:
                                current_block.on_right_click()
                            else:
                                localx, localy, localz = map(operator.sub, previous, normalize(self.player.position))
                                if localx != 0 or localz != 0 or (localy != 0 and localy != -1):
                                    self.model.add_block(previous, current_block)
                                    self.item_list.remove_current_block()
                elif (
                    self.item_list.get_current_block()
                    and self.item_list.get_current_block().regenerated_health != 0
                    and self.player.health < self.player.max_health
                ):
                    self.player.change_health(self.item_list.get_current_block().regenerated_health)
                    self.item_list.get_current_block_item().change_amount(-1)
                    self.item_list.update_health()
                    self.item_list.update_items()
        else:
            self.window.set_exclusive_mouse(True)

    def on_mouse_release(self, x, y, button, modifiers):
        if self.window.exclusive:
            self.set_highlighted_block(None)
            self.mouse_pressed = False

    def on_mouse_motion(self, x, y, dx, dy):
        if self.window.exclusive:
            m = 0.15
            x, y = self.player.rotation
            x, y = x + dx * m, y + dy * m
            y = max(-90, min(90, y))
            self.player.rotation = (x, y)
            self.camera.rotate(x, y)

    def on_mouse_drag(self, x, y, dx, dy, button, modifiers):
        if button == pyglet.window.mouse.LEFT:
            self.on_mouse_motion(x, y, dx, dy)

    def on_key_press(self, symbol, modifiers):
        if symbol == G.TOGGLE_HUD_KEY:
            G.HUD_ENABLED = not G.HUD_ENABLED
        elif symbol == G.SAVE_KEY:
            self.save_to_file()
        elif symbol == G.INVENTORY_SORT_KEY:
            if self.last_key == symbol and not self.sorted:
                self.player.quick_slots.sort()
                self.player.inventory.sort()
                self.sorted = True
            else:
                self.player.quick_slots.change_sort_mode()
                self.player.inventory.change_sort_mode()
                self.item_list.update_items()
                self.inventory_list.update_items()
        elif symbol == G.INVENTORY_KEY:
            self.set_highlighted_block(None)
            self.mouse_pressed = False
            self.inventory_list.toggle()
        elif symbol == G.SOUND_UP_KEY:
            G.EFFECT_VOLUME = min(G.EFFECT_VOLUME + 0.1, 1)
        elif symbol == G.SOUND_DOWN_KEY:
            G.EFFECT_VOLUME = max(G.EFFECT_VOLUME - 0.1, 0)
        self.last_key = symbol

    def on_key_release(self, symbol, modifiers):
        if symbol == G.TALK_KEY:
            self.toggle_text_input()
            return pyglet.event.EVENT_HANDLED

    def on_resize(self, width, height):
        if G.HUD_ENABLED:
            self.label.y = height - 10
        self.text_input.resize(x=0, y=0, width=self.window.width)
        self.chat_box.resize(
            x=0,
            y=self.text_input.y + self.text_input.height + 50,
            width=self.window.width / 2,
            height=min(300, self.window.height / 3),
        )

    def set_3d(self):
        width, height = self.window.get_size()
        if G.FOG_ENABLED:
            glFogfv(GL_FOG_COLOR, vec(self.bg_red, self.bg_green, self.bg_blue, 1.0))
        glEnable(GL_DEPTH_TEST)
        glViewport(0, 0, width, height)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(G.FOV, width / float(height), G.NEAR_CLIP_DISTANCE, G.FAR_CLIP_DISTANCE)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        self.camera.transform()
        glEnable(GL_LIGHTING)
        glLightfv(GL_LIGHT0, GL_DIFFUSE, vec(0.9, 0.9, 0.9, 1.0))
        glLightfv(GL_LIGHT0, GL_SPECULAR, vec(0.9, 0.9, 0.9, 1.0))
        glLightfv(GL_LIGHT0, GL_POSITION, vec(1.0, self.light_y, self.light_z, 1.0))
        glLightfv(GL_LIGHT1, GL_AMBIENT, self.ambient)
        glLightfv(GL_LIGHT2, GL_AMBIENT, self.ambient)
        glMaterialfv(GL_FRONT, GL_AMBIENT, self.earth)
        glMaterialfv(GL_FRONT, GL_DIFFUSE, self.white)
        glMaterialfv(GL_FRONT, GL_SHININESS, self.polished)

    def clear(self):
        glClearColor(self.bg_red, self.bg_green, self.bg_blue, 1.0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    def on_draw(self):
        self.clear()
        self.set_3d()
        glColor3d(1, 1, 1)
        self.model.batch.draw()
        self.model.transparency_batch.draw()
        self.crack_batch.draw()
        self.draw_focused_block()
        self.set_2d()
        if G.HUD_ENABLED:
            self.draw_label()
            self.item_list.draw()
            self.inventory_list.draw()
        self.text_input.draw()
        self.chat_box.draw()

    def show_cracks(self, hit_block, vertex_data):
        if self.block_damage:  # also show the cracks
            crack_level = int(CRACK_LEVELS * self.block_damage / hit_block.hardness)  # range: [0, CRACK_LEVELS[
            if crack_level >= CRACK_LEVELS:
                return
            texture_data = crack_textures.texture_data[crack_level]
            count = len(texture_data) / 2
            if self.crack:
                self.crack.delete()
            self.crack = self.crack_batch.add(
                count, GL_QUADS, self.model.group, ("v3f/static", vertex_data), ("t2f/static", texture_data)
            )

    def draw_focused_block(self):
        glDisable(GL_LIGHTING)
        vector = self.player.get_sight_vector()
        position = self.model.hit_test(self.player.position, vector, self.player.attack_range)[0]
        if position:
            hit_block = self.model[position]
            if hit_block.density >= 1:
                self.focus_block.width = hit_block.width * 1.05
                self.focus_block.height = hit_block.height * 1.05
                vertex_data = self.focus_block.get_vertices(*position)

                if hit_block.hardness > 0.0:
                    self.show_cracks(hit_block, vertex_data)

                glColor3d(0, 0, 0)
                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
                pyglet.graphics.draw(24, GL_QUADS, ("v3f/static", vertex_data))
                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)

    def draw_label(self):
        x, y, z = self.player.position
        self.label.text = "%.1f %02d (%.2f, %.2f, %.2f) %d / %d" % (
            self.time_of_day if (self.time_of_day < 12.0) else (24.0 - self.time_of_day),
            pyglet.clock.get_fps(),
            x,
            y,
            z,
            len(self.model._shown),
            len(self.model),
        )
        self.label.draw()

    def write_line(self, text, **kwargs):
        self.chat_box.write_line(text, **kwargs)

    def text_input_callback(self, symbol, modifier):
        if symbol == G.VALIDATE_KEY:
            txt = self.text_input.text.replace("\n", "")
            try:
                ex = self.command_parser.execute(txt, controller=self, user=self.player, world=self.model)
                if ex != COMMAND_HANDLED:
                    # Not a command
                    self.write_line("> %s" % txt, color=(255, 255, 255, 255))
                self.text_input.clear()
            except CommandException, e:
                error = str(e)
                self.write_line(error, color=COMMAND_ERROR_COLOR)
            return pyglet.event.EVENT_HANDLED
Example #7
0
    def setup(self):
        glClearColor(self.bg_red, self.bg_green, self.bg_blue, 1)
        glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)
        glEnable(GL_LIGHT1)
        glEnable(GL_LIGHT2)
        glEnable(GL_ALPHA_TEST)
        glAlphaFunc(GL_GREATER, 0.1)
        glEnable(GL_BLEND)
        glEnable(GL_LINE_SMOOTH)

        if G.FOG_ENABLED:
            glEnable(GL_FOG)
            glFogfv(GL_FOG_COLOR, vec(self.bg_red, self.bg_green, self.bg_blue, 1))
            glHint(GL_FOG_HINT, GL_DONT_CARE)
            glFogi(GL_FOG_MODE, GL_LINEAR)
            glFogf(GL_FOG_DENSITY, 0.35)
            glFogf(GL_FOG_START, 20.0)
            glFogf(GL_FOG_END, G.DRAW_DISTANCE)  # 80)

        self.focus_block = Block(width=1.05, height=1.05)
        self.earth = vec(0.8, 0.8, 0.8, 1.0)
        self.white = vec(1.0, 1.0, 1.0, 1.0)
        self.ambient = vec(1.0, 1.0, 1.0, 1.0)
        self.polished = GLfloat(100.0)
        self.crack_batch = pyglet.graphics.Batch()
        if G.DISABLE_SAVE and world_exists(G.game_dir, G.SAVE_FILENAME):
            open_world(self, G.game_dir, G.SAVE_FILENAME)
        else:
            self.model = Model()
            self.player = Player((0, 0, 0), (-20, 0), game_mode=G.GAME_MODE)
        print("Game mode: " + self.player.game_mode)
        self.item_list = ItemSelector(self, self.player, self.model)
        self.inventory_list = InventorySelector(self, self.player, self.model)
        self.item_list.on_resize(self.window.width, self.window.height)
        self.inventory_list.on_resize(self.window.width, self.window.height)
        self.text_input = TextWidget(self.window, "", 0, 0, self.window.width, visible=False, font_name="Arial")
        self.text_input.push_handlers(on_toggled=self.on_text_input_toggled, key_released=self.text_input_callback)
        self.chat_box = TextWidget(
            self.window,
            "",
            0,
            self.text_input.y + self.text_input.height + 50,
            self.window.width / 2,
            height=min(300, self.window.height / 3),
            visible=False,
            multi_line=True,
            readonly=True,
            font_size=14,
            font_name="Arial",
            background_color=(64, 64, 64, 200),
        )
        self.command_parser = CommandParser()
        self.camera = Camera3D(target=self.player)
        if G.HUD_ENABLED:
            self.label = pyglet.text.Label(
                "",
                font_name="Arial",
                font_size=8,
                x=10,
                y=self.window.height - 10,
                anchor_x="left",
                anchor_y="top",
                color=(255, 255, 255, 255),
            )
        pyglet.clock.schedule_interval_soft(self.model.process_queue, 1.0 / G.MAX_FPS)
Example #8
0
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)
Example #9
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")
 def start(self):
     cp = CommandParser()
     cp.add_command('show_movies', self.show_all_movies)
     cp.add_command('add_movie', self.add_movie)
     cp.add_command('add_projection', self.add_movie_projection)
     cp.add_command('show_projections', self.show_projections)
     cp.add_command('add_reservation', self.add_reservation)
     
     while True:
         user_input = input()
         if user_input == 'exit':
             break
         else:
             print(cp.execute(user_input))
Example #11
0
 def __init__(self, hostname, port, channel, path):
     self.hostname = hostname
     self.port = port
     self.channel = channel
     self.path = path
     self.commands = CommandParser()
 def setUp(self):
     self.parser = CommandParser()