Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: Add settings API ("auto settings") for host.yaml #1871

Merged
merged 11 commits into from
Jul 5, 2023
1 change: 1 addition & 0 deletions .github/workflows/unittests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ jobs:
python -m pip install --upgrade pip
pip install pytest pytest-subtests
python ModuleUpdate.py --yes --force --append "WebHostLib/requirements.txt"
python Launcher.py --update_settings # make sure host.yaml exists for tests
- name: Unittests
run: |
pytest
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ README.html
EnemizerCLI/
/Players/
/SNI/
/host.yaml
/options.yaml
/config.yaml
/logs/
Expand Down
40 changes: 20 additions & 20 deletions Generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,42 @@

ModuleUpdate.update()

import copy
import Utils
import Options
from BaseClasses import seeddigits, get_seed, PlandoOptions
from Main import main as ERmain
from settings import get_settings
from Utils import parse_yamls, version_tuple, __version__, tuplize_version, user_path
from worlds.alttp import Options as LttPOptions
from worlds.generic import PlandoConnection
from Utils import parse_yamls, version_tuple, __version__, tuplize_version, get_options, user_path
from worlds.alttp.EntranceRandomizer import parse_arguments
from Main import main as ERmain
from BaseClasses import seeddigits, get_seed, PlandoOptions
import Options
from worlds.alttp.Text import TextTable
from worlds.AutoWorld import AutoWorldRegister
import copy
from worlds.generic import PlandoConnection


def mystery_argparse():
options = get_options()
defaults = options["generator"]

def resolve_path(path: str, resolver: Callable[[str], str]) -> str:
return path if os.path.isabs(path) else resolver(path)
options = get_settings()
black-sliver marked this conversation as resolved.
Show resolved Hide resolved
defaults = options.generator

parser = argparse.ArgumentParser(description="CMD Generation Interface, defaults come from host.yaml.")
parser.add_argument('--weights_file_path', default=defaults["weights_file_path"],
parser.add_argument('--weights_file_path', default=defaults.weights_file_path,
help='Path to the weights file to use for rolling game settings, urls are also valid')
parser.add_argument('--samesettings', help='Rolls settings per weights file rather than per player',
action='store_true')
parser.add_argument('--player_files_path', default=resolve_path(defaults["player_files_path"], user_path),
parser.add_argument('--player_files_path', default=defaults.player_files_path,
help="Input directory for player files.")
parser.add_argument('--seed', help='Define seed number to generate.', type=int)
parser.add_argument('--multi', default=defaults["players"], type=lambda value: max(int(value), 1))
parser.add_argument('--spoiler', type=int, default=defaults["spoiler"])
parser.add_argument('--outputpath', default=resolve_path(options["general_options"]["output_path"], user_path),
parser.add_argument('--multi', default=defaults.players, type=lambda value: max(int(value), 1))
parser.add_argument('--spoiler', type=int, default=defaults.spoiler)
parser.add_argument('--outputpath', default=options.general_options.output_path,
help="Path to output folder. Absolute or relative to cwd.") # absolute or relative to cwd
parser.add_argument('--race', action='store_true', default=defaults["race"])
parser.add_argument('--meta_file_path', default=defaults["meta_file_path"])
parser.add_argument('--race', action='store_true', default=defaults.race)
parser.add_argument('--meta_file_path', default=defaults.meta_file_path)
parser.add_argument('--log_level', default='info', help='Sets log level')
parser.add_argument('--yaml_output', default=0, type=lambda value: max(int(value), 0),
help='Output rolled mystery results to yaml up to specified number (made for async multiworld)')
parser.add_argument('--plando', default=defaults["plando_options"],
parser.add_argument('--plando', default=defaults.plando_options,
help='List of options that can be set manually. Can be combined, for example "bosses, items"')
parser.add_argument("--skip_prog_balancing", action="store_true",
help="Skip progression balancing step during generation.")
Expand All @@ -71,6 +69,8 @@ def get_seed_name(random_source) -> str:
def main(args=None, callback=ERmain):
if not args:
args, options = mystery_argparse()
else:
options = get_settings()

seed = get_seed(args.seed)
Utils.init_logging(f"Generate_{seed}", loglevel=args.log_level)
Expand Down Expand Up @@ -137,7 +137,7 @@ def main(args=None, callback=ERmain):
erargs = parse_arguments(['--multi', str(args.multi)])
erargs.seed = seed
erargs.plando_options = args.plando
erargs.glitch_triforce = options["generator"]["glitch_triforce_room"]
erargs.glitch_triforce = options.generator.glitch_triforce_room
erargs.spoiler = args.spoiler
erargs.race = args.race
erargs.outputname = seed_name
Expand Down
23 changes: 18 additions & 5 deletions Launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from typing import Sequence, Union, Optional

import Utils
import settings
from worlds.LauncherComponents import Component, components, Type, SuffixIdentifier, icon_paths

if __name__ == "__main__":
Expand All @@ -33,7 +34,8 @@


def open_host_yaml():
file = user_path('host.yaml')
file = settings.get_settings().filename
assert file, "host.yaml missing"
if is_linux:
exe = which('sensible-editor') or which('gedit') or \
which('xdg-open') or which('gnome-open') or which('kde-open')
Expand Down Expand Up @@ -84,6 +86,11 @@ def open_folder(folder_path):
webbrowser.open(folder_path)


def update_settings():
from settings import get_settings
get_settings().save()


components.extend([
# Functions
Component("Open host.yaml", func=open_host_yaml),
Expand Down Expand Up @@ -256,11 +263,13 @@ def main(args: Optional[Union[argparse.Namespace, dict]] = None):
if not component:
logging.warning(f"Could not identify Component responsible for {args['Patch|Game|Component']}")

if args["update_settings"]:
update_settings()
if 'file' in args:
run_component(args["component"], args["file"], *args["args"])
elif 'component' in args:
run_component(args["component"], *args["args"])
else:
elif not args["update_settings"]:
run_gui()


Expand All @@ -269,9 +278,13 @@ def main(args: Optional[Union[argparse.Namespace, dict]] = None):
Utils.freeze_support()
multiprocessing.set_start_method("spawn") # if launched process uses kivy, fork won't work
parser = argparse.ArgumentParser(description='Archipelago Launcher')
parser.add_argument('Patch|Game|Component', type=str, nargs='?',
help="Pass either a patch file, a generated game or the name of a component to run.")
parser.add_argument('args', nargs="*", help="Arguments to pass to component.")
run_group = parser.add_argument_group("Run")
run_group.add_argument("--update_settings", action="store_true",
help="Update host.yaml and exit.")
run_group.add_argument("Patch|Game|Component", type=str, nargs="?",
help="Pass either a patch file, a generated game or the name of a component to run.")
run_group.add_argument("args", nargs="*",
help="Arguments to pass to component.")
main(parser.parse_args())

from worlds.LauncherComponents import processes
Expand Down
7 changes: 4 additions & 3 deletions Main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
from BaseClasses import CollectionState, Item, Location, LocationProgressType, MultiWorld, Region
from Fill import balance_multiworld_progression, distribute_items_restrictive, distribute_planned, flood_items
from Options import StartInventoryPool
from Utils import __version__, get_options, output_path, version_tuple
from settings import get_settings
from Utils import __version__, output_path, version_tuple
from worlds import AutoWorld
from worlds.generic.Rules import exclusion_rules, locality_rules

Expand All @@ -22,7 +23,7 @@

def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = None):
if not baked_server_options:
baked_server_options = get_options()["server_options"]
baked_server_options = get_settings().server_options
if args.outputpath:
os.makedirs(args.outputpath, exist_ok=True)
output_path.cached_path = args.outputpath
Expand Down Expand Up @@ -372,7 +373,7 @@ def precollect_hint(location):
"connect_names": {name: (0, player) for player, name in world.player_name.items()},
"locations": locations_data,
"checks_in_area": checks_in_area,
"server_options": baked_server_options,
"server_options": baked_server_options.as_dict(),
"er_hint_data": er_hint_data,
"precollected_items": precollected_items,
"precollected_hints": precollected_hints,
Expand Down
2 changes: 1 addition & 1 deletion MinecraftClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ def is_correct_forge(forge_dir) -> bool:

versions = get_minecraft_versions(data_version, channel)

forge_dir = Utils.user_path(options["minecraft_options"]["forge_directory"])
forge_dir = options["minecraft_options"]["forge_directory"]
max_heap = options["minecraft_options"]["max_heap_size"]
forge_version = args.forge or versions["forge"]
java_version = args.java or versions["java"]
Expand Down
2 changes: 0 additions & 2 deletions OoTClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,6 @@ async def patch_and_run_game(apz5_file):
comp_path = base_name + '.z64'
# Load vanilla ROM, patch file, compress ROM
rom_file_name = Utils.get_options()["oot_options"]["rom_file"]
if not os.path.exists(rom_file_name):
rom_file_name = Utils.user_path(rom_file_name)
rom = Rom(rom_file_name)

sub_file = None
Expand Down
Loading