def saveWorlds(self): Logger.debug("Starting Attempt to Save All Worlds", module="world-save") if self.persistant and (self.server.config.worldSaveLocation is not None): Logger.info("Saving All Worlds...", module="world-save") # Loop through all worlds and attempt to save! for worldName, world in self.worlds.items(): Logger.debug(f"Trying To Save World {worldName}", module="world-save") # Check persistance if world.persistant: try: # Saving World Logger.info(f"Saving World {worldName}", module="world-save") world.saveMap() except Exception as e: Logger.error( f"Error While Saving World {worldName} - {type(e).__name__}: {e}", module="world-save") else: Logger.warn( f"World {worldName} Is Non Persistant! Skipping World Save!", module="world-save") else: Logger.warn( "World Manager Is Non Persistant! Skipping World Save!", module="world-save")
def closeWorlds(self): Logger.debug("Starting Attempt to Close All Worlds", module="world-close") # Loop through all worlds and attempt to close for worldName in list(self.worlds.keys( )): # Setting as list so dict size can change mid execution try: Logger.info(f"Closing World {worldName}", module="world-close") # Getting world obj world = self.worlds[worldName] # Removing world from dict Logger.debug("Removed world from dict", module="world-close") del self.worlds[worldName] # Checking if World and Server is Persistant if self.persistant and (self.server.config.worldSaveLocation is not None) and world.persistant: # Closing worlds fileIO Logger.debug("Closing World FileIO", module="world-close") world.fileIO.close() except Exception as e: Logger.error( f"Error While Closing World {worldName} - {type(e).__name__}: {e}", module="world-close")
async def spawnCurrentPlayers(self, playerSelf: Player): # Update Joining Players of The Currently In-Game Players # Loop Through All Players for player in self.players: # Checking if Player Exists if player is None: continue # Checking if player is not self if player is playerSelf: continue # Attempting to Send Packet try: await playerSelf.networkHandler.dispacher.sendPacket( Packets.Response.SpawnPlayer, player.playerId, player.name, player.posX, player.posY, player.posZ, player.posYaw, player.posPitch, ) except Exception as e: if e not in CRITICAL_RESPONSE_ERRORS: # Something Broke! Logger.error(f"An Error Occurred While Sending World Packet {Packets.Response.SpawnPlayer.NAME} To {player.networkHandler.ip} - {type(e).__name__}: {e}", module="world-packet-dispatcher") else: # Bad Timing with Connection Closure. Ignoring Logger.verbose(f"Ignoring Error While Sending World Packet {Packets.Response.SpawnPlayer.NAME} To {player.networkHandler.ip}", module="world-packet-dispatcher")
def reload(self): Logger.debug("Reloading Config", "config") # Check If File Exists configPath = os.path.join(SERVERPATH, self.configPath) # Load File If File if os.path.isfile(configPath): Logger.debug("Config File Exists! Loading Config.", "config") try: with open(configPath, "r") as configFile: self._load(configFile) # Save Config After Load (To Update And Fix Any Issues) if self.saveAfterConfigLoad: with open(configPath, "w") as configFile: self._save(configFile) else: Logger.warn("Skipping Save After Config Load", "config") except json.decoder.JSONDecodeError as e: Logger.error( f"Failed To Load Json File! - {type(e).__name__}: {e}", "config") Logger.askConfirmation( message="Override Old Config With Default Values?") with open(configPath, "w") as configFile: self._save(configFile) else: Logger.debug("Config File Does Not Exist! Creating Config File.", "config") with open(configPath, "w") as configFile: self._save(configFile)
async def handlePlayerMovement(self, posX: int, posY: int, posZ: int, posYaw: int, posPitch: int): # Format, Process, and Handle incoming player movement requests. Logger.verbose(f"Handling Player Movement From Player {self.name}", module="player") # Checking If Player Is Joined To A World if self.worldPlayerManager is None: Logger.error(f"Player {self.name} Trying To handleBlockUpdate When No World Is Joined", module="player") return None # Skip Rest # Updating Current Player Position self.posX = posX self.posY = posY self.posZ = posZ self.posYaw = posYaw self.posPitch = posPitch # Sending Player Position Update Packet To All Players await self.worldPlayerManager.sendWorldPacket( Packets.Response.PlayerPositionUpdate, self.playerId, posX, posY, posZ, posYaw, posPitch, ignoreList=[self] # not sending to self as that may cause some de-sync issues )
def generateTable(self): try: table = PrettyTableLite() # Create Pretty List Class table.field_names = [ "Direction", "Packet", "Id", "Player Loop", "Module" ] # Loop Through All Request Modules And Add Value for _, packet in self.RequestManager._packet_list.items(): # Adding Row To Table table.add_row([ "Request", packet.NAME, packet.ID, packet.PLAYERLOOP, packet.MODULE.NAME ]) # Loop Through All Response Modules And Add Value for _, packet in self.ResponseManager._packet_list.items(): table.add_row([ "Response", packet.NAME, packet.ID, "N/A", packet.MODULE.NAME ]) return table except FatalError as e: # Pass Down Fatal Error To Base Server raise e except Exception as e: Logger.error( f"Error While Printing Table - {type(e).__name__}: {e}", module="table")
async def handleBlockUpdate(self, blockX: int, blockY: int, blockZ: int, blockType: AbstractBlock): # Format, Process, and Handle incoming block update requests. Logger.debug(f"Handling Block Placement From Player {self.name}", module="player") # Checking If Player Is Joined To A World if self.worldPlayerManager is None: Logger.error(f"Player {self.name} Trying To handleBlockUpdate When No World Is Joined", module="player") return None # Skip Rest # Trying To Update Block On Player World try: await blockType.placeBlock(self, blockX, blockY, blockZ) except ClientError as e: # Setting Player-Attempted Block Back To Original originalBlock = self.worldPlayerManager.world.getBlock(blockX, blockY, blockZ) await self.networkHandler.dispacher.sendPacket( Packets.Response.SetBlock, blockX, blockY, blockZ, originalBlock.ID ) # Send Error Message To await self.sendMessage(f"&c{e}&f")
async def initConnection(self, *args, **kwargs): try: return await self._initConnection(*args, **kwargs) except ClientError as e: Logger.warn( f"Client Error, Disconnecting Ip {self.ip} - {type(e).__name__}: {e}", module="network") await self.closeConnection(reason=str(e), notifyPlayer=True) except BrokenPipeError: Logger.warn(f"Ip {self.ip} Broken Pipe. Closing Connection.", module="network") await self.closeConnection(reason="Broken Pipe") except ConnectionResetError: Logger.warn(f"Ip {self.ip} Connection Reset. Closing Connection.", module="network") await self.closeConnection(reason="Connection Reset") except asyncio.IncompleteReadError: Logger.warn( f"Ip {self.ip} Incomplete Read Error. Closing Connection.", module="network") await self.closeConnection(reason="Incomplete Read Error") except Exception as e: Logger.error( f"Error While Handling Connection {self.ip} - {type(e).__name__}: {e}", module="network") try: await self.closeConnection(reason="Internal Server Error", notifyPlayer=True) except Exception as e: Logger.error( f"Close Connected Failed To Complete Successfully - {type(e).__name__}: {e}", module="network")
def deallocateId(self, playerId: int): # Check If Id Is Already Deallocated if self.players[playerId] is None: Logger.error(f"Trying To Deallocate Non Allocated Id {playerId}", module="id-allocator", printTb=False) self.players[playerId] = None Logger.debug(f"Deallocated Id {playerId}", module="id-allocator")
def _postInit(self): for module_name, module_obj in list(self._module_list.items()): try: Logger.debug( f"Running Post-Initialization for Module {module_name}", module=f"{module_name}-postinit") # Calling the Final Init function module_obj.postInit() except FatalError as e: # Pass Down Fatal Error To Base Server raise e except Exception as e: # Handle Exception if Error Occurs self._error_list.append( (module_name, "Init-Final")) # Module Loaded WITH Errors # If the Error is an Postinit Error (raised on purpose), Don't print out TB if type(e) is PostInitError: printTb = False else: printTb = True Logger.error( f"Error While Running Post-Initialization For {module_name} - {type(e).__name__}: {e}\n", module="postinit", printTb=printTb) Logger.warn( "!!! Module Errors May Cause Compatibility Issues And/Or Data Corruption !!!\n", module="postinit") Logger.warn(f"Skipping Module {module_name}?", module="postinit") Logger.askConfirmation() # Remove Module Logger.warn(f"Removing Module {module_name} From Loader!", module="postinit") del self._module_list[module_name]
def _importModules(self): # Initialize Temporary List of Files Imported _module_files = [] # Walk Through All Packages And Import Library for _, module_name, _ in pkgutil.walk_packages( [os.path.join(SERVERPATH, MODULESFOLDER)]): # Load Modules Logger.debug(f"Detected Module {module_name}", module="module-import") if module_name not in self._module_blacklist: try: Logger.verbose( f"Module {module_name} Not In Blacklist. Adding!", module="module-import") # Import Module _module = importlib.import_module(MODULESIMPORT + module_name) # Appending To A List of Module Files to be Used Later _module_files.append(module_name) # Set the Imported Module into the Global Scope globals()[module_name] = _module except FatalError as e: # Pass Down Fatal Error To Base Server raise e except Exception as e: # Handle Exception if Error Occurs self._error_list.append( (module_name, "PreInit-Import")) # Module Loaded WITH Errors # If the Error is a Register Error (raised on purpose), Don't print out TB if type(e) is InitRegisterError: printTb = False else: printTb = True Logger.error( f"Error While Importing Module {module_name} - {type(e).__name__}: {e}\n", module="module-import", printTb=printTb) Logger.warn( "!!! Fatal Module Errors May Cause Compatibility Issues And/Or Data Corruption !!!\n", module="module-import") Logger.askConfirmation() else: Logger.verbose( f"Skipping Module {module_name} Due To Blacklist", module="module-import") Logger.verbose(f"Detected and Imported Module Files {_module_files}", module="module-import") # Check If Core Was Loaded if self._ensure_core: if "core" not in self._module_list.keys(): self._error_list.append( ("core", "PreInit-EnsureCore")) # Module Loaded WITH Errors raise FatalError( "Error While Loading Module core - Critical Module Not Found" )
def _resolveDependencyCycles(self): # Helper Function To Run Down Module Dependency Tree To Check For Cycles def _ensureNoCycles(current: Type[AbstractModule], previous: List[str]): Logger.verbose( f"Travelling Down Dependency Tree. CUR: {current} PREV: {previous}", module="cycle-check") # If Current Name Appears In Any Previous Dependency, There Is An Infinite Cycle if current.NAME in previous: raise DependencyError( f"Circular dependency Detected: {' -> '.join([*previous, current.NAME])}" ) Logger.verbose( f"Current Modules Has Dependencies {current.DEPENDENCIES}", module="cycle-check") # Run DFS through All Dependencies for dependency in current.DEPENDENCIES: _ensureNoCycles(dependency.MODULE, [*previous, current.NAME]) for module_name, module_obj in list(self._module_list.items()): try: Logger.debug( f"Ensuring No Circular Dependencies For Module {module_name}", module="module-verify") # Run DFS Through All Decencies To Check If Cycle Exists _ensureNoCycles(module_obj, []) except FatalError as e: # Pass Down Fatal Error To Base Server raise e except Exception as e: # Handle Exception if Error Occurs self._error_list.append( (module_name, "PreInit-Dependency")) # Module Loaded WITH Errors # If the Error is a Dependency Error (raised on purpose), Don't print out TB if type(e) is DependencyError: printTb = False else: printTb = True Logger.error( f"Error While Resolving Dependency Cycles For {module_name} - {type(e).__name__}: {e}\n", module="module-verify", printTb=printTb) Logger.warn( "!!! Module Errors May Cause Compatibility Issues And/Or Data Corruption !!!\n", module="module-verify") Logger.warn(f"Skipping Module {module_name}?", module="module-verify") Logger.askConfirmation() # Remove Module Logger.warn(f"Removing Module {module_name} From Loader!", module="module-verify") del self._module_list[module_name]
async def sendGlobalPacket(self, packet: AbstractResponsePacket, *args, ignoreList: List[Player] = [], **kwargs): # Send packet to ALL members connected to server (all worlds) Logger.verbose(f"Sending Packet {packet.NAME} To All Connected Players", module="global-packet-dispatcher") # Loop Through All Players for player in self.players: # Checking if player is not in ignoreList if player not in ignoreList: try: # Sending Packet To Player await player.networkHandler.dispacher.sendPacket(packet, *args, **kwargs) except Exception as e: if e not in CRITICAL_RESPONSE_ERRORS: # Something Broke! Logger.error(f"An Error Occurred While Sending Global Packet {packet.NAME} To {player.networkHandler.ip} - {type(e).__name__}: {e}", module="global-packet-dispatcher") else: # Bad Timing with Connection Closure. Ignoring Logger.verbose(f"Ignoring Error While Sending Global Packet {packet.NAME} To {player.networkHandler.ip}", module="global-packet-dispatcher")
def _initSubmodules(self): # Loop through all the submodules in the order of the sorted graph for module in self._sorted_module_graph: try: # Loop Through All Items within Module Logger.debug(f"Checking All Items in {module.NAME}", module=f"{module.NAME}-submodule-init") # Loop Through All Items In Class for _, item in module.__dict__.items(): # Check If Item Has "obsidian_submodule" Flag if hasattr(item, "obsidian_submodule"): Logger.verbose( f"{item} Is A Submodule! Adding As {module.NAME} Submodule.", module=f"{module.NAME}-submodule-init") # Register Submodule Using information Provided by Submodule Class item.MANAGER.register(item, module) except FatalError as e: # Pass Down Fatal Error To Base Server raise e except Exception as e: # Handle Exception if Error Occurs self._error_list.append( (module.NAME, "Init-Submodule")) # Module Loaded WITH Errors # If the Error is an Init Error (raised on purpose), Don't print out TB if type(e) is InitError: printTb = False else: printTb = True Logger.error( f"Error While Initializing Submodules For {module.NAME} - {type(e).__name__}: {e}\n", module="submodule-init", printTb=printTb) Logger.warn( "!!! Module Errors May Cause Compatibility Issues And/Or Data Corruption !!!\n", module="submodule-init") Logger.warn(f"Skipping Module {module.NAME}?", module="submodule-init") Logger.askConfirmation() # Remove Module Logger.warn(f"Removing Module {module.NAME} From Loader!", module="submodule-init") del self._module_list[module.NAME]
def gzipMap(self, compressionLevel: int = -1, includeSizeHeader: bool = False): # If Gzip Compression Level Is -1, Use Default! # includeSizeHeader Dictates If Output Should Include Map Size Header Used For Level Init # Check If Compression Is -1 (Use Server gzipCompressionLevel) if compressionLevel == -1: compressionLevel = self.worldManager.server.config.gzipCompressionLevel # Check If Compression Level Is Valid elif compressionLevel >= 0 and compressionLevel <= 9: pass # Invalid Compression Level! else: Logger.error( f"Invalid GZIP Compression Level Of {compressionLevel}!!!", module="world") Logger.askConfirmation() Logger.warn("Using Fallback Compression Level Of 0", module="world") compressionLevel = 0 Logger.debug( f"Compressing Map {self.name} With Compression Level {compressionLevel}", module="world") # Create File Buffer buf = io.BytesIO() # Check If Size Header Is Needed (Using Bytes For '+' Capabilities) header = bytes() if includeSizeHeader: Logger.debug("Packing Size Header", module="world") header = header + bytes(struct.pack('!I', len(self.mapArray))) # Gzip World with gzip.GzipFile(fileobj=buf, mode='wb', compresslevel=compressionLevel) as f: f.write(header + bytes(self.mapArray)) # Extract and Return Gzip Data gzipData = buf.getvalue() Logger.debug(f"GZipped Map! GZ SIZE: {len(gzipData)}", module="world") return gzipData
def generateTable(self): try: table = PrettyTableLite() # Create Pretty List Class table.field_names = ["Command", "Activators", "Version", "Module"] # Loop Through All Commands And Add Value for _, command in self._command_list.items(): # Add Row To Table table.add_row([ command.NAME, command.ACTIVATORS, command.VERSION, command.MODULE.NAME ]) return table except FatalError as e: # Pass Down Fatal Error To Base Server raise e except Exception as e: Logger.error( f"Error While Printing Table - {type(e).__name__}: {e}", module="table")
def generateTable(self): try: table = PrettyTableLite() # Create Pretty List Class table.field_names = ["World Format", "Version", "Module"] # Loop Through All World Formats And Add Value for _, worldFormat in self._format_list.items(): # Add Row To Table table.add_row([ worldFormat.NAME, worldFormat.VERSION, worldFormat.MODULE.NAME ]) return table except FatalError as e: # Pass Down Fatal Error To Base Server raise e except Exception as e: Logger.error( f"Error While Printing Table - {type(e).__name__}: {e}", module="table")
def _initModules(self): for module in self._sorted_module_graph: try: Logger.debug(f"Initializing Module {module.NAME}", module=f"{module.NAME}-init") # Initialize Module initializedModule = module() # Initialize and Transfer Module Variables initializedModule.NAME = module.NAME initializedModule.DESCRIPTION = module.DESCRIPTION initializedModule.AUTHOR = module.AUTHOR initializedModule.VERSION = module.VERSION initializedModule.DEPENDENCIES = module.DEPENDENCIES # Replacing Item in _module_list with the Initialized Version! self._module_list[module.NAME] = initializedModule except FatalError as e: # Pass Down Fatal Error To Base Server raise e except Exception as e: # Handle Exception if Error Occurs self._error_list.append( (module.NAME, "Init-Module")) # Module Loaded WITH Errors # If the Error is an Init Error (raised on purpose), Don't print out TB if type(e) is InitError: printTb = False else: printTb = True Logger.error( f"Error While Initializing Modules For {module.NAME} - {type(e).__name__}: {e}\n", module="module-init", printTb=printTb) Logger.warn( "!!! Module Errors May Cause Compatibility Issues And/Or Data Corruption !!!\n", module="module-init") Logger.warn(f"Skipping Module {module.NAME}?", module="module-init") Logger.askConfirmation() # Remove Module Logger.warn(f"Removing Module {module.NAME} From Loader!", module="module-init") del self._module_list[module.NAME]
async def handlePlayerCommand(self, cmdMessage: str): # Format, Process, and Handle incoming player commands. Logger.debug(f"Handling Command From Player {self.name}", module="command") # Splitting Command Data cmdName, *cmdArgs = cmdMessage.split(" ") Logger.info(f"Command {cmdName} Received From Player {self.name}", module="command") Logger.debug(f"Handling Command {cmdName} With Arguments {cmdArgs}", module="command") # Get Command Object command = Commands.getCommandFromName(cmdName) # Parse Command Arguments parsedArguments, parsedKwArgs = _parseArgs(command, cmdArgs) # Run Command try: await command.execute(self, *parsedArguments, **parsedKwArgs) except Exception as e: Logger.error(f"Command {command.NAME} Raised Error {str(e)}", module="command") await self.sendMessage("&cAn Unknown Internal Server Error Has Occurred!")
def generateTable(self): try: table = PrettyTableLite() # Create Pretty List Class table.field_names = ["Map Generator", "Version", "Module"] # Loop Through All Map Generators And Add Value for _, generator in self._generator_list.items(): # Adding Special Characters And Handlers if generator.VERSION is None: generator.VERSION = "Unknown" # Add Row To Table table.add_row( [generator.NAME, generator.VERSION, generator.MODULE.NAME]) return table except FatalError as e: # Pass Down Fatal Error To Base Server raise e except Exception as e: Logger.error( f"Error While Printing Table - {type(e).__name__}: {e}", module="table")
async def sendWorldPacket(self, packet: Type[AbstractResponsePacket], *args, ignoreList: List[Player] = [], **kwargs): # Send packet to all members in world Logger.verbose(f"Sending Packet {packet.NAME} To All Players On {self.world.name}", module="world-packet-dispatcher") # Loop Through All Players for player in self.players: # Checking if Player Exists if player is None: continue # Checking if player is not in ignoreList if player in ignoreList: continue # Attempting to Send Packet try: await player.networkHandler.dispacher.sendPacket(packet, *args, **kwargs) except Exception as e: if e not in CRITICAL_RESPONSE_ERRORS: # Something Broke! Logger.error(f"An Error Occurred While Sending World Packet {packet.NAME} To {player.networkHandler.ip} - {type(e).__name__}: {e}", module="world-packet-dispatcher") else: # Bad Timing with Connection Closure. Ignoring Logger.verbose(f"Ignoring Error While Sending World Packet {packet.NAME} To {player.networkHandler.ip}", module="world-packet-dispatcher")
def _initDependencies(self): for module_name, module_obj in list(self._module_list.items()): try: Logger.debug(f"Checking Dependencies for Module {module_name}", module="module-resolve") # Loop through all dependencies, check type, then check if exists for dependency in module_obj.DEPENDENCIES: # Get Variables dep_name = dependency.NAME dep_ver = dependency.VERSION Logger.verbose(f"Checking if Dependency {dep_name} Exists", module="module-resolve") # Check if Dependency is "Loaded" if dep_name in self._module_list.keys(): # Check if Version should be checked if dep_ver is None: Logger.verbose( f"Skipping Version Check For Dependency {dependency}", module="module-resolve") pass # No Version Check Needed elif dep_ver == self._module_list[ dependency.NAME].VERSION: Logger.verbose( f"Dependencies {dependency} Statisfied!", module="module-resolve") pass else: raise DependencyError( f"Dependency '{dependency}' Has Unmatched Version! (Requirement: {dep_ver} | Has: {self._module_list[dependency.NAME].VERSION})" ) # If All Passes, Link Module Class dependency.MODULE = self._module_list[dependency.NAME] else: raise DependencyError( f"Dependency '{dependency}' Not Found!") except FatalError as e: # Pass Down Fatal Error To Base Server raise e except Exception as e: # Handle Exception if Error Occurs self._error_list.append( (module_name, "PreInit-Dependency")) # Module Loaded WITH Errors # If the Error is a Dependency Error (raised on purpose), Don't print out TB if type(e) is DependencyError: printTb = False else: printTb = True Logger.error( f"Error While Initializing Dependencies For {module_name} - {type(e).__name__}: {e}\n", module="module-resolve", printTb=printTb) Logger.warn( "!!! Module Errors May Cause Compatibility Issues And/Or Data Corruption !!!\n", module="module-resolve") Logger.warn(f"Skipping Module {module_name}?", module="module-resolve") Logger.askConfirmation() # Remove Module Logger.warn(f"Removing Module {module_name} From Loader!", module="module-resolve") del self._module_list[module_name]
def __init__(self, worldManager: WorldManager, name: str, sizeX: int, sizeY: int, sizeZ: int, mapArray: bytearray, spawnX: Optional[int] = None, spawnY: Optional[int] = None, spawnZ: Optional[int] = None, spawnYaw: Optional[int] = None, spawnPitch: Optional[int] = None, generator: AbstractMapGenerator = None, persistant: bool = False, fileIO: Optional[io.BufferedRandom] = None, canEdit: bool = True, maxPlayers: int = 250, displayName: str = None, uuid: str = None): # Y is the height self.worldManager = worldManager self.name = name self.generator = generator self.sizeX = sizeX self.sizeY = sizeY self.sizeZ = sizeZ self.spawnX = spawnX self.spawnZ = spawnZ self.spawnY = spawnY self.spawnYaw = spawnYaw self.spawnPitch = spawnPitch self.mapArray = mapArray self.persistant = persistant self.fileIO = fileIO self.canEdit = canEdit self.maxPlayers = maxPlayers self.displayName = displayName # Displayname for CW Capability self.uuid = uuid # UUID for CW Capability # Check if file IO was given if persistant if self.persistant: if self.fileIO is None: # Setting persistance to false because fileIO was not given self.persistant = False Logger.error( f"World Format {self.worldManager.worldFormat.NAME} Created Persistant World Without Providing FileIO! Please Report To Author! Setting World As Non-Persistant.", "world-load") Logger.askConfirmation() else: Logger.debug(f"Persistant World Has FileIO {self.fileIO}", "world-load") # Generate/Set Spawn Coords # Set spawnX if self.spawnX is None: # Generate SpawnX (Set to middle of map) self.spawnX = (self.sizeX // 2) * 32 + 51 Logger.verbose( f"spawnX was not provided. Generated to {self.spawnX}", "world-load") # Set spawnZ if self.spawnZ is None: # Generate SpawnZ (Set to middle of map) self.spawnZ = (self.sizeZ // 2) * 32 + 51 Logger.verbose( f"spawnZ was not provided. Generated to {self.spawnZ}", "world-load") # Set spawnY if self.spawnY is None: # Kinda hacky to get the block coords form the in-game coords self.spawnY = (self.getHighestBlock(round( (self.spawnX - 51) / 32), round( (self.spawnZ - 51) / 32)) + 1) * 32 + 51 Logger.verbose( f"spawnY was not provided. Generated to {self.spawnY}", "world-load") # Set spawnYaw if spawnYaw is None: # Generate SpawnYaw (0) self.spawnYaw = 0 Logger.verbose( f"spawnYaw was not provided. Generated to {self.spawnYaw}", "world-load") # Set spawnPitch if spawnPitch is None: # Generate SpawnPitch (0) self.spawnPitch = 0 Logger.verbose( f"spawnYaw was not provided. Generated to {self.spawnYaw}", "world-load") # Initialize WorldPlayerManager Logger.info("Initializing World Player Manager", module="init-world") self.playerManager = WorldPlayerManager(self)
def onError(self, error: str): Logger.error(f"Packet {self.NAME} Raised Error {error}", module="packet")
def loadWorlds(self): Logger.debug("Starting Attempt to Load All Worlds", module="world-load") if self.persistant and (self.server.config.worldSaveLocation is not None): Logger.debug( f"Beginning To Scan Through {self.server.config.worldSaveLocation} Dir", module="world-load") # Loop Through All Files Given In World Folder for filename in os.listdir( os.path.join(SERVERPATH, self.server.config.worldSaveLocation)): # Get Pure File Name (No Extentions) saveName = os.path.splitext(os.path.basename(filename))[0] Logger.verbose( f"Checking Extention and Status of World File {filename}", module="world-load") # Check If File Type Matches With The Extentions Provided By worldFormat if not any([ filename.endswith(ext) for ext in self.worldFormat.EXTENTIONS ]): Logger.debug( f"Ignoring World File {filename}. File Extention Not Known!", module="world-load") # Also Check If World Is Blacklisted elif saveName in self.server.config.worldBlacklist: Logger.info( f"Ignoring World File {filename}. World Name Is Blacklisted!", module="world-load") # Also Check If World Name Is Already Loaded (Same File Names with Different Extentions) elif saveName in self.worlds.keys(): Logger.warn( f"Ignoring World File {filename}. World With Similar Name Has Already Been Registered!", module="world-load") Logger.warn( f"World File {os.path.basename(self.worlds[saveName].fileIO.name)} Conflicts With World File {filename}!", module="world-load") Logger.askConfirmation() else: Logger.debug( f"Detected World File {filename}. Attempting To Load World", module="world-load") # (Attempt) To Load Up World try: Logger.info(f"Loading World {saveName}", module="world-load") fileIO = open( os.path.join(SERVERPATH, self.server.config.worldSaveLocation, filename), "rb+") self.worlds[saveName] = self.worldFormat.loadWorld( fileIO, self, persistant=self.persistant) except Exception as e: Logger.error( f"Error While Loading World {filename} - {type(e).__name__}: {e}", module="world-load") Logger.askConfirmation() # Check If Default World Is Loaded if self.server.config.defaultWorld not in self.worlds.keys(): # Check if other worlds were loaded as well if len(self.worlds.keys()) > 0: Logger.warn( f"Default World {self.server.config.defaultWorld} Not Loaded.", module="world-load") Logger.warn( "Consider Checking If World Exists. Consider Changing The Default World and/or File Format In Config.", module="world-load") # Ask User If They Want To Continue With World Generation Logger.warn( f"Other Worlds Were Detected. Generate New World With Name {self.server.config.defaultWorld}?", module="world-load") Logger.askConfirmation(message="Generate New World?") else: Logger.warn( "No Existing Worlds Were Detected. Generating New World!", module="world-load") # Generate New World defaultWorldName = self.server.config.defaultWorld defaultGenerator = MapGenerators[ self.server.config.defaultGenerator] Logger.debug(f"Creating World {defaultWorldName}", module="world-load") self.createWorld( defaultWorldName, self.server.config.defaultWorldSizeX, self.server.config.defaultWorldSizeY, self.server.config.defaultWorldSizeZ, defaultGenerator, persistant=self.persistant, grassHeight=self.server.config.defaultWorldSizeY // 2) else: Logger.debug("World Manager Is Non Persistant!", module="world-load") # Create Non-Persistant Temporary World defaultWorldName = self.server.config.defaultWorld defaultGenerator = MapGenerators[ self.server.config.defaultGenerator] Logger.debug(f"Creating Temporary World {defaultWorldName}", module="world-load") self.createWorld( defaultWorldName, self.server.config.defaultWorldSizeX, self.server.config.defaultWorldSizeY, self.server.config.defaultWorldSizeZ, defaultGenerator, persistant=False, maxPlayers=self.server.config.worldMaxPlayers, grassHeight=self.server.config.defaultWorldSizeY // 2)