Example #1
0
    def __init__(self):
        BetaServerProtocol.__init__(self)

        log.msg("Registering client hooks...")
        names = configuration.getlist("bravo", "build_hooks")
        self.build_hooks = retrieve_named_plugins(IBuildHook, names)
        names = configuration.getlist("bravo", "dig_hooks")
        self.dig_hooks = retrieve_named_plugins(IDigHook, names)

        self.last_dig_build_timer = time()
Example #2
0
    def configure_services(self, configuration):
        read_configuration()

        for section in configuration.sections():
            if section.startswith("world "):
                # Bravo worlds. Grab a list of endpoints and load them.
                factory = BravoFactory(section[6:])
                interfaces = configuration.getlist(section, "interfaces")

                for service in services_for_endpoints(interfaces, factory):
                    self.addService(service)

                self.factorylist.append(factory)
            elif section == "web":
                try:
                    from bravo.web import bravo_site
                except ImportError:
                    log.msg("Couldn't import web stuff!")
                else:
                    factory = bravo_site(self.namedServices)
                    factory.name = "web"
                    interfaces = configuration.getlist("web", "interfaces")

                    for service in services_for_endpoints(interfaces, factory):
                        self.addService(service)
            elif section.startswith("irc "):
                try:
                    from bravo.irc import BravoIRC
                except ImportError:
                    log.msg("Couldn't import IRC stuff!")
                else:
                    self.irc = True
                    self.ircbots.append(section)
            elif section.startswith("infiniproxy "):
                factory = BetaProxyFactory(section[12:])
                interfaces = configuration.getlist(section, "interfaces")

                for service in services_for_endpoints(interfaces, factory):
                    self.addService(service)
            elif section.startswith("infininode "):
                factory = InfiniNodeFactory(section[11:])
                interfaces = configuration.getlist(section, "interfaces")

                for service in services_for_endpoints(interfaces, factory):
                    self.addService(service)
        if self.irc:
            for section in self.ircbots:
                factory = BravoIRC(self.factorylist, section[4:])
                client = TCPClient(factory.host, factory.port, factory)
                client.setName(factory.config)
                self.addService(client)
Example #3
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: Deferred that will be called with the Chunk
        """

        if not async:
            return deferLater(reactor, 0.000001, self.factory.world.load_chunk,
                x, z)

        if (x, z) in self.chunk_cache:
            return succeed(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            return succeed(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            return fork_deferred(self._pending_chunks[x, z])

        chunk = Chunk(x, z)
        self.serializer.load_chunk(chunk)

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            return succeed(chunk)

        d = deferToAMPProcess(MakeChunk, x=x, z=z, seed=self.seed,
            generators=configuration.getlist("bravo", "generators"))
        self._pending_chunks[x, z] = d

        def pp(kwargs):
            chunk.blocks = fromstring(kwargs["blocks"],
                dtype=uint8).reshape(chunk.blocks.shape)
            chunk.heightmap = fromstring(kwargs["heightmap"],
                dtype=uint8).reshape(chunk.heightmap.shape)
            chunk.metadata = fromstring(kwargs["metadata"],
                dtype=uint8).reshape(chunk.metadata.shape)
            chunk.skylight = fromstring(kwargs["skylight"],
                dtype=uint8).reshape(chunk.skylight.shape)
            chunk.blocklight = fromstring(kwargs["blocklight"],
                dtype=uint8).reshape(chunk.blocklight.shape)

            chunk.populated = True
            chunk.dirty = True

            self.postprocess_chunk(chunk)

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)
        # Multiple people might be subscribed to this pending callback. We're
        # going to keep it for ourselves and fork off another Deferred for our
        # caller.
        return fork_deferred(d)
Example #4
0
    def startFactory(self):
        log.msg("Initializing factory for world '%s'..." % self.name)

        self.world = World(self.name)
        self.world.factory = self
        if configuration.has_option(self.config_name, "perm_cache"):
            cache_level = configuration.getint(self.config_name, "perm_cache")
            self.world.enable_cache(cache_level)

        self.protocols = dict()

        log.msg("Starting timekeeping...")
        self.timestamp = time()
        self.time = self.world.time
        self.update_season()
        self.time_loop = LoopingCall(self.update_time)
        self.time_loop.start(2)

        authenticator = configuration.get(self.config_name, "authenticator")
        selected = retrieve_named_plugins(IAuthenticator, [authenticator])[0]

        log.msg("Using authenticator %s" % selected.name)
        self.handshake_hook = selected.handshake
        self.login_hook = selected.login

        generators = configuration.getlist(self.config_name, "generators")
        generators = retrieve_sorted_plugins(ITerrainGenerator, generators)

        log.msg("Using generators %s" % ", ".join(i.name for i in generators))
        self.world.pipeline = generators

        automatons = configuration.getlist(self.config_name, "automatons")
        automatons = retrieve_named_plugins(IAutomaton, automatons)

        log.msg("Using automatons %s" % ", ".join(i.name for i in automatons))
        self.automatons = automatons

        self.chat_consumers = set()

        log.msg("Factory successfully initialized for world '%s'!" % self.name)
Example #5
0
    def startFactory(self):
        log.msg("Initializing factory for world '%s'..." % self.name)

        self.world = World(self.name)
        self.world.factory = self
        if configuration.has_option(self.config_name, "perm_cache"):
            cache_level = configuration.getint(self.config_name, "perm_cache")
            self.world.enable_cache(cache_level)

        self.protocols = dict()

        log.msg("Starting timekeeping...")
        self.timestamp = time()
        self.time = self.world.time
        self.update_season()
        self.time_loop = LoopingCall(self.update_time)
        self.time_loop.start(2)

        authenticator = configuration.get(self.config_name, "authenticator")
        selected = retrieve_named_plugins(IAuthenticator, [authenticator])[0]

        log.msg("Using authenticator %s" % selected.name)
        self.handshake_hook = selected.handshake
        self.login_hook = selected.login

        generators = configuration.getlist(self.config_name, "generators")
        generators = retrieve_sorted_plugins(ITerrainGenerator, generators)

        log.msg("Using generators %s" % ", ".join(i.name for i in generators))
        self.world.pipeline = generators

        automatons = configuration.getlist(self.config_name, "automatons")
        automatons = retrieve_named_plugins(IAutomaton, automatons)

        log.msg("Using automatons %s" % ", ".join(i.name for i in automatons))
        self.automatons = automatons

        self.chat_consumers = set()

        log.msg("Factory successfully initialized for world '%s'!" % self.name)
Example #6
0
    def __init__(self, name):
        """
        Create a factory and world.

        ``name`` is the string used to look up factory-specific settings from
        the configuration.

        :param str name: internal name of this factory
        """

        log.msg("Initializing factory for world '%s'..." % name)

        self.name = name
        self.config_name = "world %s" % name

        self.port = configuration.getint(self.config_name, "port")
        self.interface = configuration.getdefault(self.config_name, "host",
            "")

        self.world = World(name)
        self.world.factory = self
        if configuration.has_option(self.config_name, "perm_cache"):
            cache_level = configuration.getint(self.config_name, "perm_cache")
            self.world.enable_cache(cache_level)

        self.protocols = dict()

        self.eid = 1

        self.time = self.world.time
        self.time_loop = LoopingCall(self.update_time)
        self.time_loop.start(2)

        authenticator = configuration.get(self.config_name, "authenticator")
        selected = retrieve_named_plugins(IAuthenticator, [authenticator])[0]

        log.msg("Using authenticator %s" % selected.name)
        self.handshake_hook = selected.handshake
        self.login_hook = selected.login

        generators = configuration.getlist(self.config_name, "generators")
        generators = retrieve_sorted_plugins(ITerrainGenerator, generators)

        log.msg("Using generators %s" % ", ".join(i.name for i in generators))
        self.world.pipeline = generators

        self.chat_consumers = set()

        log.msg("Factory successfully initialized for world '%s'!" % name)
Example #7
0
File: beta.py Project: Mortal/bravo
    def __init__(self, name):
        """
        Create a factory and world.

        ``name`` is the string used to look up factory-specific settings from
        the configuration.

        :param str name: internal name of this factory
        """

        log.msg("Initializing factory for world '%s'..." % name)

        self.name = name
        self.config_name = "world %s" % name

        self.port = configuration.getint(self.config_name, "port")
        self.interface = configuration.getdefault(self.config_name, "host",
            "")

        self.world = World(name)
        self.world.factory = self
        if configuration.has_option(self.config_name, "perm_cache"):
            cache_level = configuration.getint(self.config_name, "perm_cache")
            self.world.enable_cache(cache_level)

        self.protocols = dict()

        self.eid = 1

        self.time = self.world.time
        self.time_loop = LoopingCall(self.update_time)
        self.time_loop.start(2)

        authenticator = configuration.get(self.config_name, "authenticator")
        selected = retrieve_named_plugins(IAuthenticator, [authenticator])[0]

        log.msg("Using authenticator %s" % selected.name)
        self.handshake_hook = selected.handshake
        self.login_hook = selected.login

        generators = configuration.getlist(self.config_name, "generators")
        generators = retrieve_sorted_plugins(ITerrainGenerator, generators)

        log.msg("Using generators %s" % ", ".join(i.name for i in generators))
        self.world.pipeline = generators

        self.chat_consumers = set()

        log.msg("Factory successfully initialized for world '%s'!" % name)
Example #8
0
def pipeline():

    generators = configuration.getlist("bravo", "generators")
    generators = retrieve_named_plugins(ITerrainGenerator, generators)

    before = time.time()

    for i in range(10):
        chunk = Chunk(i, i)
        for generator in generators:
            generator.populate(chunk, 0)

    after = time.time()

    return after - before
Example #9
0
def pipeline():

    generators = configuration.getlist("bravo", "generators")
    generators = retrieve_named_plugins(ITerrainGenerator, generators)

    before = time.time()

    for i in range(10):
        chunk = Chunk(i, i)
        for generator in generators:
            generator.populate(chunk, 0)

    after = time.time()

    return after - before
Example #10
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: ``Deferred`` that will be called with the ``Chunk``
        """

        if (x, z) in self.chunk_cache:
            returnValue(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            returnValue(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            retval = yield self._pending_chunks[x, z].deferred()
            returnValue(retval)

        chunk = Chunk(x, z)
        yield maybeDeferred(self.serializer.load_chunk, chunk)

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            self.postprocess_chunk(chunk)
            #self.factory.scan_chunk(chunk)
            returnValue(chunk)

        if self.async:
            from ampoule import deferToAMPProcess
            from bravo.remote import MakeChunk

            d = deferToAMPProcess(MakeChunk,
                x=x,
                z=z,
                seed=self.seed,
                generators=configuration.getlist(self.config_name, "generators")
            )

            # Get chunk data into our chunk object.
            def fill_chunk(kwargs):
                chunk.blocks = fromstring(kwargs["blocks"],
                    dtype=uint8).reshape(chunk.blocks.shape)
                chunk.heightmap = fromstring(kwargs["heightmap"],
                    dtype=uint8).reshape(chunk.heightmap.shape)
                chunk.metadata = fromstring(kwargs["metadata"],
                    dtype=uint8).reshape(chunk.metadata.shape)
                chunk.skylight = fromstring(kwargs["skylight"],
                    dtype=uint8).reshape(chunk.skylight.shape)
                chunk.blocklight = fromstring(kwargs["blocklight"],
                    dtype=uint8).reshape(chunk.blocklight.shape)

                return chunk
            d.addCallback(fill_chunk)
        else:
            # Populate the chunk the slow way. :c
            for stage in self.pipeline:
                stage.populate(chunk, self.seed)

            chunk.regenerate()
            d = succeed(chunk)

        # Set up our event and generate our return-value Deferred. It has to
        # be done early becaues PendingEvents only fire exactly once and it
        # might fire immediately in certain cases.
        pe = PendingEvent()
        # This one is for our return value.
        retval = pe.deferred()
        # This one is for scanning the chunk for automatons.
        #pe.deferred().addCallback(self.factory.scan_chunk)
        self._pending_chunks[x, z] = pe

        def pp(chunk):
            chunk.populated = True
            chunk.dirty = True

            self.postprocess_chunk(chunk)

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)
        d.chainDeferred(pe)

        # Because multiple people might be attached to this callback, we're
        # going to do something magical here. We will yield a forked version
        # of our Deferred. This means that we will wait right here, for a
        # long, long time, before actually returning with the chunk, *but*,
        # when we actually finish, we'll be ready to return the chunk
        # immediately. Our caller cannot possibly care because they only see a
        # Deferred either way.
        retval = yield retval
        returnValue(retval)
Example #11
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: Deferred that will be called with the Chunk
        """

        if not async:
            return deferLater(reactor, 0.000001, self.factory.world.load_chunk,
                              x, z)

        if (x, z) in self.chunk_cache:
            return succeed(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            return succeed(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            return fork_deferred(self._pending_chunks[x, z])

        chunk = Chunk(x, z)
        self.serializer.load_chunk(chunk)

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            return succeed(chunk)

        d = deferToAMPProcess(MakeChunk,
                              x=x,
                              z=z,
                              seed=self.seed,
                              generators=configuration.getlist(
                                  "bravo", "generators"))
        self._pending_chunks[x, z] = d

        def pp(kwargs):
            chunk.blocks = fromstring(kwargs["blocks"],
                                      dtype=uint8).reshape(chunk.blocks.shape)
            chunk.heightmap = fromstring(kwargs["heightmap"],
                                         dtype=uint8).reshape(
                                             chunk.heightmap.shape)
            chunk.metadata = fromstring(
                kwargs["metadata"], dtype=uint8).reshape(chunk.metadata.shape)
            chunk.skylight = fromstring(
                kwargs["skylight"], dtype=uint8).reshape(chunk.skylight.shape)
            chunk.blocklight = fromstring(kwargs["blocklight"],
                                          dtype=uint8).reshape(
                                              chunk.blocklight.shape)

            chunk.populated = True
            chunk.dirty = True

            self.postprocess_chunk(chunk)

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)
        # Multiple people might be subscribed to this pending callback. We're
        # going to keep it for ourselves and fork off another Deferred for our
        # caller.
        return fork_deferred(d)
Example #12
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: ``Deferred`` that will be called with the ``Chunk``
        """

        if (x, z) in self.chunk_cache:
            returnValue(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            returnValue(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            retval = yield fork_deferred(self._pending_chunks[x, z])
            returnValue(retval)

        chunk = Chunk(x, z)
        yield maybeDeferred(self.serializer.load_chunk, chunk)

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            self.postprocess_chunk(chunk)
            returnValue(chunk)

        if self.async:
            from ampoule import deferToAMPProcess
            from bravo.remote import MakeChunk

            d = deferToAMPProcess(MakeChunk,
                x=x,
                z=z,
                seed=self.seed,
                generators=configuration.getlist(self.config_name, "generators")
            )
            self._pending_chunks[x, z] = d

            # Get chunk data into our chunk object.
            def fill_chunk(kwargs):
                chunk.blocks = fromstring(kwargs["blocks"],
                    dtype=uint8).reshape(chunk.blocks.shape)
                chunk.heightmap = fromstring(kwargs["heightmap"],
                    dtype=uint8).reshape(chunk.heightmap.shape)
                chunk.metadata = fromstring(kwargs["metadata"],
                    dtype=uint8).reshape(chunk.metadata.shape)
                chunk.skylight = fromstring(kwargs["skylight"],
                    dtype=uint8).reshape(chunk.skylight.shape)
                chunk.blocklight = fromstring(kwargs["blocklight"],
                    dtype=uint8).reshape(chunk.blocklight.shape)

                return chunk
            d.addCallback(fill_chunk)
        else:
            self.populate_chunk(chunk)
            d = succeed(chunk)
            self._pending_chunks[x, z] = d

        def pp(chunk):
            chunk.populated = True
            chunk.dirty = True

            self.postprocess_chunk(chunk)

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)

        # Multiple people might be subscribed to this pending callback. We're
        # going to keep it for ourselves and fork off another Deferred for our
        # caller.
        retval = yield fork_deferred(d)
        returnValue(retval)
Example #13
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: Deferred that will be called with the Chunk
        """

        if not async:
            return deferLater(reactor, 0.000001, self.factory.world.load_chunk,
                x, z)

        if (x, z) in self.chunk_cache:
            return succeed(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            return succeed(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            d = Deferred()
            self._pending_chunks[x, z].chainDeferred(d)
            return d

        chunk = Chunk(x, z)

        first, second, filename = names_for_chunk(x, z)
        f = self.folder.child(first).child(second)
        if not f.exists():
            f.makedirs()
        f = f.child(filename)
        if f.exists() and f.getsize():
            chunk.load_from_tag(read_from_file(f.open("r")))

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            return succeed(chunk)

        d = deferToAMPProcess(MakeChunk, x=x, z=z, seed=self.seed,
            generators=configuration.getlist("bravo", "generators"))
        self._pending_chunks[x, z] = d

        def pp(kwargs):
            chunk.blocks = fromstring(kwargs["blocks"],
                dtype=uint8).reshape(chunk.blocks.shape)
            chunk.heightmap = fromstring(kwargs["heightmap"],
                dtype=uint8).reshape(chunk.heightmap.shape)
            chunk.metadata = fromstring(kwargs["metadata"],
                dtype=uint8).reshape(chunk.metadata.shape)
            chunk.skylight = fromstring(kwargs["skylight"],
                dtype=uint8).reshape(chunk.skylight.shape)
            chunk.blocklight = fromstring(kwargs["blocklight"],
                dtype=uint8).reshape(chunk.blocklight.shape)

            chunk.populated = True
            chunk.dirty = True

            # Apply the current season to the chunk.
            if self.season:
                self.season.transform(chunk)

            # Since this chunk hasn't been given to any player yet, there's no
            # conceivable way that any meaningful damage has been accumulated;
            # anybody loading any part of this chunk will want the entire thing.
            # Thus, it should start out undamaged.
            chunk.clear_damage()

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)
        # Multiple people might be subscribed to this pending callback. We're
        # going to keep it for ourselves and fork off another Deferred for our
        # caller.
        forked = Deferred()
        d.chainDeferred(forked)
        forked.addCallback(lambda none: chunk)
        return forked
Example #14
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: ``Deferred`` that will be called with the ``Chunk``
        """

        if (x, z) in self.chunk_cache:
            returnValue(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            returnValue(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            retval = yield fork_deferred(self._pending_chunks[x, z])
            returnValue(retval)

        chunk = Chunk(x, z)
        yield maybeDeferred(self.serializer.load_chunk, chunk)

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            self.postprocess_chunk(chunk)
            returnValue(chunk)

        if self. async:
            from ampoule import deferToAMPProcess
            from bravo.remote import MakeChunk

            d = deferToAMPProcess(MakeChunk,
                                  x=x,
                                  z=z,
                                  seed=self.seed,
                                  generators=configuration.getlist(
                                      self.config_name, "generators"))
            self._pending_chunks[x, z] = d

            # Get chunk data into our chunk object.
            def fill_chunk(kwargs):
                chunk.blocks = fromstring(
                    kwargs["blocks"], dtype=uint8).reshape(chunk.blocks.shape)
                chunk.heightmap = fromstring(kwargs["heightmap"],
                                             dtype=uint8).reshape(
                                                 chunk.heightmap.shape)
                chunk.metadata = fromstring(kwargs["metadata"],
                                            dtype=uint8).reshape(
                                                chunk.metadata.shape)
                chunk.skylight = fromstring(kwargs["skylight"],
                                            dtype=uint8).reshape(
                                                chunk.skylight.shape)
                chunk.blocklight = fromstring(kwargs["blocklight"],
                                              dtype=uint8).reshape(
                                                  chunk.blocklight.shape)

                return chunk

            d.addCallback(fill_chunk)
        else:
            self.populate_chunk(chunk)
            d = succeed(chunk)
            self._pending_chunks[x, z] = d

        def pp(chunk):
            chunk.populated = True
            chunk.dirty = True

            self.postprocess_chunk(chunk)

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)

        # Multiple people might be subscribed to this pending callback. We're
        # going to keep it for ourselves and fork off another Deferred for our
        # caller.
        retval = yield fork_deferred(d)
        returnValue(retval)