* autoworld: don't load files/folders starting with '.' The imports fail if the folder has a '.' in the name, with a somewhat obscure error, and adding a '.' in front of it is what a linux user might expect to use when disabling a world temporarily. * autoworld: use tuple to filter .* and _*
		
			
				
	
	
		
			75 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import importlib
 | 
						|
import zipimport
 | 
						|
import os
 | 
						|
import typing
 | 
						|
 | 
						|
folder = os.path.dirname(__file__)
 | 
						|
 | 
						|
__all__ = {
 | 
						|
    "lookup_any_item_id_to_name",
 | 
						|
    "lookup_any_location_id_to_name",
 | 
						|
    "network_data_package",
 | 
						|
    "AutoWorldRegister",
 | 
						|
    "world_sources",
 | 
						|
    "folder",
 | 
						|
}
 | 
						|
 | 
						|
if typing.TYPE_CHECKING:
 | 
						|
    from .AutoWorld import World
 | 
						|
 | 
						|
 | 
						|
class WorldSource(typing.NamedTuple):
 | 
						|
    path: str  # typically relative path from this module
 | 
						|
    is_zip: bool = False
 | 
						|
 | 
						|
 | 
						|
# find potential world containers, currently folders and zip-importable .apworld's
 | 
						|
world_sources: typing.List[WorldSource] = []
 | 
						|
file: os.DirEntry  # for me (Berserker) at least, PyCharm doesn't seem to infer the type correctly
 | 
						|
for file in os.scandir(folder):
 | 
						|
    # prevent loading of __pycache__ and allow _* for non-world folders, disable files/folders starting with "."
 | 
						|
    if not file.name.startswith(("_", ".")):
 | 
						|
        if file.is_dir():
 | 
						|
            world_sources.append(WorldSource(file.name))
 | 
						|
        elif file.is_file() and file.name.endswith(".apworld"):
 | 
						|
            world_sources.append(WorldSource(file.name, is_zip=True))
 | 
						|
 | 
						|
# import all submodules to trigger AutoWorldRegister
 | 
						|
world_sources.sort()
 | 
						|
for world_source in world_sources:
 | 
						|
    if world_source.is_zip:
 | 
						|
        importer = zipimport.zipimporter(os.path.join(folder, world_source.path))
 | 
						|
        importer.load_module(world_source.path.split(".", 1)[0])
 | 
						|
    else:
 | 
						|
        importlib.import_module(f".{world_source.path}", "worlds")
 | 
						|
 | 
						|
lookup_any_item_id_to_name = {}
 | 
						|
lookup_any_location_id_to_name = {}
 | 
						|
games = {}
 | 
						|
 | 
						|
from .AutoWorld import AutoWorldRegister
 | 
						|
 | 
						|
for world_name, world in AutoWorldRegister.world_types.items():
 | 
						|
    games[world_name] = {
 | 
						|
        "item_name_to_id": world.item_name_to_id,
 | 
						|
        "location_name_to_id": world.location_name_to_id,
 | 
						|
        "version": world.data_version,
 | 
						|
        # seems clients don't actually want this. Keeping it here in case someone changes their mind.
 | 
						|
        # "item_name_groups": {name: tuple(items) for name, items in world.item_name_groups.items()}
 | 
						|
    }
 | 
						|
    lookup_any_item_id_to_name.update(world.item_id_to_name)
 | 
						|
    lookup_any_location_id_to_name.update(world.location_id_to_name)
 | 
						|
 | 
						|
network_data_package = {
 | 
						|
    "version": sum(world.data_version for world in AutoWorldRegister.world_types.values()),
 | 
						|
    "games": games,
 | 
						|
}
 | 
						|
 | 
						|
# Set entire datapackage to version 0 if any of them are set to 0
 | 
						|
if any(not world.data_version for world in AutoWorldRegister.world_types.values()):
 | 
						|
    network_data_package["version"] = 0
 | 
						|
    import logging
 | 
						|
 | 
						|
    logging.warning(f"Datapackage is in custom mode. Custom Worlds: "
 | 
						|
                    f"{[world for world in AutoWorldRegister.world_types.values() if not world.data_version]}")
 |