def main(): """Main Program """ print("Dennis 2D Database Updater v1 -> v2") # Check command line arguments, and give help if needed. if len(sys.argv) != 2 or sys.argv[1] in [ "help", "-h", "--help", "-help", "?", "-?" ]: print( "This updater adds entrance records to rooms for the `list entrances` command." ) print("Usage: {0} <database>".format(sys.argv[0])) return 0 # Make sure the database file exists. if not path.exists(sys.argv[1]): print("Database file does not exist: {0}".format(sys.argv[1])) return 1 # Start up DatabaseManager and tell it we're accepting a v1 database for migration. dbman = database.DatabaseManager(sys.argv[1], Log()) dbman._UPDATE_FROM_VERSION = 1 sres = dbman._startup() if not sres: return 1 # Run the updates for this migration. dbupdate_v1_to_v2(dbman) # Finished. print("Successfully updated database from v1 to v2: {0}".format( sys.argv[1])) dbman._unlock()
def main(): """Main Program """ print("Dennis 2D Database Updater v3 -> v4") # Check command line arguments, and give help if needed. if len(sys.argv) != 2 or sys.argv[1] in [ "help", "-h", "--help", "-help", "?", "-?" ]: print( "This updater adds neutral pronouns fields to users for formatting posturing text." ) print("Usage: {0} <database>".format(sys.argv[0])) return 0 # Make sure the database file exists. if not path.exists(sys.argv[1]): print("Database file does not exist: {0}".format(sys.argv[1])) return 2 # Start up DatabaseManager and tell it we're accepting a v3 database for migration to v4. dbman = database.DatabaseManager(sys.argv[1], Log()) dbman._UPDATE_FROM_VERSION = 3 sres = dbman._startup() if not sres: return 3 # Run the updates for this migration. print("Performing database updates...") dbupdate_v3_to_v4(dbman) # Finished. print("Successfully updated database from v3 to v4: {0}".format( sys.argv[1])) dbman._unlock()
def main(): """Startup tasks, mainloop entry, and shutdown tasks. """ # Load the configuration. config = _config.ConfigManager(single=False) builtins.CONFIG = config print("Welcome to {0}, Multi-Player Server.".format(_config.VERSION)) print("Starting up...") # Initialize the logger. logger.init(config) log = logger.Logger("server") # Rotate database backups, if enabled. # Unfortunately this has to be done before loading the database, because Windows. if os.path.exists(config["database"]["filename"]): try: if config["database"]["backups"]: backupnumbers = sorted(range(1, config["database"]["backups"]), reverse=True) for bn in backupnumbers: if os.path.exists("{0}.bk{1}".format( config["database"]["filename"], bn)): shutil.copyfile( "{0}.bk{1}".format(config["database"]["filename"], bn), "{0}.bk{1}".format(config["database"]["filename"], bn + 1)) shutil.copyfile( config["database"]["filename"], "{0}.bk1".format(config["database"]["filename"])) except: log.error("Could not finish rotating backups for database: {file}", file=config["database"]["filename"]) log.error(traceback.format_exc(1)) # Initialize the Database Manager and load the world database. log.info("Initializing database manager...") dbman = database.DatabaseManager(config["database"]["filename"], config.defaults) _dbres = dbman._startup() if not _dbres: # On failure, only remove the lockfile if its existence wasn't the cause. if _dbres is not None: dbman._unlock() return 3 log.info("Finished initializing database manager.") # Initialize the router. router = Router(config, dbman) # initialize the command shell. command_shell = shell.Shell(dbman, router) router.shell = command_shell # Start the services. log.info("Initializing services...") if not init_services(config, router, log): dbman._unlock() return 4 log.info("Finished initializing services.") # Graceful shutdown on SIGINT (ctrl-c). # The shutdown command does the same thing. # To shut down quickly but cleanly, send the TERM signal. def shutdown(signal_received, frame): if not router.shutting_down: if config["shutdown_delay"]: command_shell.broadcast( "<<<DENNIS IS SHUTTING DOWN IN {0} SECONDS>>>".format( config["shutdown_delay"])) else: command_shell.broadcast("<<<DENNIS IS SHUTTING DOWN>>>") reactor.callLater(config["shutdown_delay"], reactor.stop) router.shutting_down = True signal.signal(signal.SIGINT, shutdown) # Start the Twisted Reactor. log.info("Finished startup tasks.") router._reactor = reactor reactor.run() # Shutting down. dbman._unlock() print("End Program.") return 0
def main(): # When this is False, Dennis will shut down. _running = True # Load the configuration. config = _config.ConfigManager(single=True) builtins.CONFIG = config print("Welcome to {0}, Single User Mode.".format(_config.VERSION)) print("Starting up...") # Initialize the logger. logger.init(config) log = logger.Logger("singleuser") # Rotate database backups, if enabled. # Unfortunately this has to be done before loading the database, because Windows. if os.path.exists(config["database"]["filename"]): try: if config["database"]["backups"]: backupnumbers = sorted(range(1, config["database"]["backups"]), reverse=True) for bn in backupnumbers: if os.path.exists("{0}.bk{1}".format(config["database"]["filename"], bn)): shutil.copyfile("{0}.bk{1}".format(config["database"]["filename"], bn), "{0}.bk{1}".format(config["database"]["filename"], bn + 1)) shutil.copyfile(config["database"]["filename"], "{0}.bk1".format(config["database"]["filename"])) except: log.error("Could not finish rotating backups for database: {0}".format(config["database"]["filename"])) log.error(traceback.format_exc(1)) # Initialize the database manager, and create the "database" alias for use in Debug Mode. log.info("Initializing database manager...") dbman = _database.DatabaseManager(config["database"]["filename"], config.defaults) if not dbman._startup(): return 3 log.info("Finished initializing database manager.") database = dbman # Initialize the router. router = Router(log) # Initialize the command shell, and create the "shell" alias for use in Debug Mode. command_shell = _shell.Shell(dbman, router) router.shell = command_shell shell = command_shell # Initialize the command console, and log in as the root user. Promote to wizard if it was somehow demoted. # Create the "console" alias for use in Debug Mode. Also add us to the current room. dennis = _console.Console(router, command_shell, "<world>", dbman, log) dennis.user = dbman.user_by_name("<world>") dbman._users_online.append("<world>") thisroom = dbman.room_by_id(dennis.user["room"]) if thisroom and "<world>" not in thisroom["users"]: thisroom["users"].append("<world>") dbman.upsert_room(thisroom) if not dennis.user["wizard"]: dennis.user["wizard"] = True dbman.upsert_user(dennis.user) console = dennis # Register our console with the router. router.users["<world>"] = {"service": "singleuser", "console": dennis} # Try to start a command prompt session with a history file. # Otherwise start a sessionless prompt without history. try: command_prompt = PromptSession(history=FileHistory(config["prompt"]["history"])).prompt except: log.error("Could not open prompt history file: {0}".format(config["prompt"]["history"])) log.error(traceback.format_exc(1)) command_prompt = prompt # Stop Dennis. We use this instead of just a variable so that Dennis can be stopped from within a Python file # executed by load() in debug mode. def shutdown(): """Stop Dennis.""" nonlocal _running _running = False # Insert a simplified wrapper around dennis.shell.call() here so that it can access the current console # without us having to pass it as an argument. def call(command, args): """Simplified wrapper around dennis.shell.call(). This shorthand function allows calling a command from Debug Mode without having to pass the current console as an argument. It can also take either a list or a string for args. :param command: The name of the command to call. :param args: A list or string of args to pass. :return: True if succeeded, False if failed. """ if type(args) is str: args = args.split(' ') return dennis.shell.call(dennis, command, args) # Save the main scope for load(). mainscope = locals() # Insert a function for Debug Mode to load and execute a Python file inside the main scope. def load(filename): """Load and execute a Python file inside the main scope. This is the same as running a series of lines in Debug mode. It can be called as a function from Debug mode, or as a command. Usage: `load <filename>`. :param filename: The filename of the Python file to execute. :return: True if succeeded, False if failed. """ # Try to evaluate the given file. try: file = open(filename) except: log.write("[singleuser#error] load: Failed to load Python file: {0}".format(filename)) log.write(traceback.format_exc(1)) return False try: exec(file.read(), globals(), mainscope) except: log.write("[singleuser#error] load: Execution error inside file: {0}".format(filename)) log.write(traceback.format_exc(1)) return False return True # Welcome! log.write("You are now logged in as the administrative user \"<world>\".") # # # # # # # # # # # This is the command loop for the Single User Mode Command Line Interface. It works almost the same as connecting # to a Multi User server through Telnet, with a few differences: # * The return status of commands will echo in the console. # * You play as the system administrator user <world>, who is always a wizard, and owns the first room. # * Other users can't share the session with you. # * You have access to the following special commands: # - `quit` : Quits the CLI. # - `debug` : Enters a PDB Debug Mode session inside the main scope. # - `load <filename>` : Loads and executes an external Python file inside the main scope. # # * You have access to the following special functions inside Debug Mode: # - shutdown() : Cleanly shuts down the engine. # - call(command, args) : Calls the named command with a string or list of arguments. # - load(filename) : Same as the `load <filename>` command. # # * You have access to the following special keypress actions: # - Ctrl+C : Cleanly shuts down the engine. # - Ctrl+D : Enters a PDB Debug Mode session inside the main scope. # # * You can return from Debug Mode to normal operation by entering "continue". # # # # # # # # # # while _running: try: cmd = command_prompt("> ") if cmd == "quit": break elif cmd.startswith("quit ") or cmd == "help quit": log.write("Usage: quit") continue elif cmd == "debug": pdb.set_trace() continue elif cmd.startswith("debug ") or cmd == "help debug": log.write("Usage: debug") continue elif cmd.startswith("load "): log.write(load(cmd[5:])) continue elif cmd == "load" or cmd == "help load": log.write("Usage: load <filename>") continue log.write(command_shell.command(dennis, cmd)) except KeyboardInterrupt: break except EOFError: pdb.set_trace() continue # Just before shutdown. dbman._unlock() log.write("End Program.") return 0