def __init__(self, name): BetaServerProtocol.__init__(self) self.config_name = "world %s" % name log.msg("Registering client hooks...") names = configuration.getlistdefault(self.config_name, "build_hooks", []) self.build_hooks = retrieve_sorted_plugins(IBuildHook, names) names = configuration.getlistdefault(self.config_name, "dig_hooks", []) self.dig_hooks = retrieve_sorted_plugins(IDigHook, names) names = configuration.getlistdefault(self.config_name, "sign_hooks", []) self.sign_hooks = retrieve_sorted_plugins(ISignHook, names) names = configuration.getlistdefault(self.config_name, "use_hooks", []) self.use_hooks = defaultdict(list) for plugin in retrieve_named_plugins(IUseHook, names): for target in plugin.targets: self.use_hooks[target].append(plugin) # Retrieve the MOTD. Only needs to be done once. self.motd = configuration.getdefault(self.config_name, "motd", None) self.last_dig_build_timer = time()
def __init__(self, name): BetaServerProtocol.__init__(self) self.config_name = "world %s" % name log.msg("Registering client hooks...") names = configuration.getlistdefault(self.config_name, "pre_build_hooks", []) self.pre_build_hooks = retrieve_sorted_plugins(IPreBuildHook, names) names = configuration.getlistdefault(self.config_name, "post_build_hooks", []) self.post_build_hooks = retrieve_sorted_plugins(IPostBuildHook, names) names = configuration.getlistdefault(self.config_name, "dig_hooks", []) self.dig_hooks = retrieve_sorted_plugins(IDigHook, names) names = configuration.getlistdefault(self.config_name, "sign_hooks", []) self.sign_hooks = retrieve_sorted_plugins(ISignHook, names) names = configuration.getlistdefault(self.config_name, "use_hooks", []) self.use_hooks = defaultdict(list) for plugin in retrieve_named_plugins(IUseHook, names): for target in plugin.targets: self.use_hooks[target].append(plugin) log.msg("Registering policies...") self.dig_policy = dig_policies["notchy"] # Retrieve the MOTD. Only needs to be done once. self.motd = configuration.getdefault(self.config_name, "motd", None)
def __init__(self): BetaServerProtocol.__init__(self) log.msg("Registering client hooks...") names = configuration.getlistdefault("bravo", "build_hooks", []) self.build_hooks = retrieve_sorted_plugins(IBuildHook, names) names = configuration.getlistdefault("bravo", "dig_hooks", []) self.dig_hooks = retrieve_sorted_plugins(IDigHook, names) names = configuration.getlistdefault("bravo", "sign_hooks", []) self.sign_hooks = retrieve_sorted_plugins(ISignHook, names) self.last_dig_build_timer = time()
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)
def register_plugins(self): """ Setup plugin hooks. """ log.msg("Registering client plugin hooks...") plugin_types = { "automatons": IAutomaton, "generators": ITerrainGenerator, "seasons": ISeason, "open_hooks": IWindowOpenHook, "click_hooks": IWindowClickHook, "close_hooks": IWindowCloseHook, "pre_build_hooks": IPreBuildHook, "post_build_hooks": IPostBuildHook, "pre_dig_hooks": IPreDigHook, "dig_hooks": IDigHook, "sign_hooks": ISignHook, "use_hooks": IUseHook, } pp = {"factory": self, "furnaces": self.furnace_manager} for t, interface in plugin_types.iteritems(): l = configuration.getlistdefault(self.config_name, t, []) if issubclass(interface, ISortedPlugin): plugins = retrieve_sorted_plugins(interface, l, parameters=pp) else: plugins = retrieve_named_plugins(interface, l, parameters=pp) log.msg("Using %s: %s" % (t.replace("_", " "), ", ".join(plugin.name for plugin in plugins))) setattr(self, t, plugins) # Assign generators to the world pipeline. self.world.pipeline = self.generators # Use hooks have special funkiness. uh = self.use_hooks self.use_hooks = defaultdict(list) for plugin in uh: for target in plugin.targets: self.use_hooks[target].append(plugin)
def make_chunk(self, x, z, seed, generators): """ Create a chunk using the given parameters. """ generators = retrieve_sorted_plugins(ITerrainGenerator, generators) chunk = Chunk(x, z) for stage in generators: stage.populate(chunk, seed) return { "blocks": chunk.blocks.tostring(), "metadata": chunk.metadata.tostring(), "skylight": chunk.skylight.tostring(), "blocklight": chunk.blocklight.tostring(), "heightmap": chunk.heightmap.tostring(), }
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)
class BravoFactory(Factory): """ A ``Factory`` that creates ``BravoProtocol`` objects when connected to. """ implements(IPushProducer) protocol = BravoProtocol timestamp = None time = 0 day = 0 eid = 1 handshake_hook = None login_hook = None interfaces = [] def __init__(self, config, 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 """ self.name = name self.config = config self.config_name = "world %s" % name self.world = World(self.config, self.name) self.world.factory = self self.protocols = dict() self.connectedIPs = defaultdict(int) self.mode = self.config.get(self.config_name, "mode") if self.mode not in ("creative", "survival"): raise Exception("Unsupported mode %s" % self.mode) self.limitConnections = self.config.getintdefault( self.config_name, "limitConnections", 0) self.limitPerIP = self.config.getintdefault(self.config_name, "limitPerIP", 0) self.vane = WeatherVane(self) def startFactory(self): log.msg("Initializing factory for world '%s'..." % self.name) authenticator = self.config.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 # Get our plugins set up. self.register_plugins() log.msg("Starting world...") self.world.start() # Start up the permanent cache. # has_option() is not exactly desirable, but it's appropriate here # because we don't want to take any action if the key is unset. if self.config.has_option(self.config_name, "perm_cache"): cache_level = self.config.getint(self.config_name, "perm_cache") self.world.enable_cache(cache_level) log.msg("Starting timekeeping...") self.timestamp = reactor.seconds() self.time = self.world.time self.update_season() self.time_loop = LoopingCall(self.update_time) self.time_loop.start(2) log.msg("Starting entity updates...") # Start automatons. for automaton in self.automatons: automaton.start() self.chat_consumers = set() log.msg("Factory successfully initialized for world '%s'!" % self.name) def stopFactory(self): """ Called before factory stops listening on ports. Used to perform shutdown tasks. """ log.msg("Shutting down world...") # Stop automatons. Technically, they may not actually halt until their # next iteration, but that is close enough for us, probably. # Automatons are contracted to not access the world after stop() is # called. for automaton in self.automatons: automaton.stop() # Evict plugins as soon as possible. Can't be done before stopping # automatons. self.unregister_plugins() self.time_loop.stop() # Write back current world time. This must be done before stopping the # world. self.world.time = self.time # And now stop the world. self.world.stop() log.msg("World data saved!") def buildProtocol(self, addr): """ Create a protocol. This overriden method provides early player entity registration, as a solution to the username/entity race that occurs on login. """ banned = self.world.serializer.load_plugin_data("banned_ips") # Do IP bans first. for ip in banned.split(): if addr.host == ip: # Use KickedProtocol with extreme prejudice. log.msg("Kicking banned IP %s" % addr.host) p = KickedProtocol("Sorry, but your IP address is banned.") p.factory = self return p # We are ignoring values less that 1, but making sure not to go over # the connection limit. if (self.limitConnections and len(self.protocols) >= self.limitConnections): log.msg("Reached maximum players, turning %s away." % addr.host) p = KickedProtocol("The player limit has already been reached." " Please try again later.") p.factory = self return p # Do our connection-per-IP check. if (self.limitPerIP and self.connectedIPs[addr.host] >= self.limitPerIP): log.msg("At maximum connections for %s already, dropping." % addr.host) p = KickedProtocol( "There are too many players connected from this IP.") p.factory = self return p else: self.connectedIPs[addr.host] += 1 # If the player wasn't kicked, let's continue! log.msg("Starting connection for %s" % addr) p = self.protocol(self.config, self.name) p.host = addr.host p.factory = self self.register_entity(p) # Copy our hooks to the protocol. p.register_hooks() return p def teardown_protocol(self, protocol): """ Do internal bookkeeping on behalf of a protocol which has been disconnected. Did you know that "bookkeeping" is one of the few words in English which has three pairs of double letters in a row? """ username = protocol.username host = protocol.host if username in self.protocols: del self.protocols[username] self.connectedIPs[host] -= 1 def set_username(self, protocol, username): """ Attempt to set a new username for a protocol. :returns: whether the username was changed """ # If the username's already taken, refuse it. if username in self.protocols: return False if protocol.username in self.protocols: # This protocol's known under another name, so remove it. del self.protocols[protocol.username] # Set the username. self.protocols[username] = protocol protocol.username = username return True def register_plugins(self): """ Setup plugin hooks. """ log.msg("Registering client plugin hooks...") plugin_types = { "automatons": IAutomaton, "generators": ITerrainGenerator, "seasons": ISeason, "open_hooks": IWindowOpenHook, "click_hooks": IWindowClickHook, "close_hooks": IWindowCloseHook, "pre_build_hooks": IPreBuildHook, "post_build_hooks": IPostBuildHook, "pre_dig_hooks": IPreDigHook, "dig_hooks": IDigHook, "sign_hooks": ISignHook, "use_hooks": IUseHook, } pp = {"factory": self} packs = self.config.getlistdefault(self.config_name, "packs", []) try: packs = [available_packs[pack] for pack in packs] except KeyError, e: raise Exception("Couldn't find plugin pack %s" % e.args) for t, interface in plugin_types.iteritems(): l = self.config.getlistdefault(self.config_name, t, []) # Grab extra plugins from the pack. Order doesn't really matter # since the plugin loader sorts things anyway. for pack in packs: if t in pack: l += pack[t] if issubclass(interface, ISortedPlugin): plugins = retrieve_sorted_plugins(interface, l, parameters=pp) else: plugins = retrieve_named_plugins(interface, l, parameters=pp) log.msg("Using %s: %s" % (t.replace("_", " "), ", ".join(plugin.name for plugin in plugins))) setattr(self, t, plugins) # Assign generators to the world pipeline. self.world.pipeline = self.generators # Use hooks have special funkiness. uh = self.use_hooks self.use_hooks = defaultdict(list) for plugin in uh: for target in plugin.targets: self.use_hooks[target].append(plugin)