171 lines
6.7 KiB
Python
171 lines
6.7 KiB
Python
import json
|
|
import logging
|
|
import os
|
|
import typing
|
|
|
|
import yaml
|
|
from jinja2 import Template
|
|
|
|
import Options
|
|
from Utils import __version__, local_path
|
|
from worlds.AutoWorld import AutoWorldRegister
|
|
|
|
handled_in_js = {"start_inventory", "local_items", "non_local_items", "start_hints", "start_location_hints",
|
|
"exclude_locations"}
|
|
|
|
|
|
def create():
|
|
target_folder = local_path("WebHostLib", "static", "generated")
|
|
yaml_folder = os.path.join(target_folder, "configs")
|
|
os.makedirs(yaml_folder, exist_ok=True)
|
|
|
|
for file in os.listdir(yaml_folder):
|
|
full_path: str = os.path.join(yaml_folder, file)
|
|
if os.path.isfile(full_path):
|
|
os.unlink(full_path)
|
|
|
|
def dictify_range(option: typing.Union[Options.Range, Options.SpecialRange]):
|
|
data = {option.default: 50}
|
|
for sub_option in ["random", "random-low", "random-high"]:
|
|
if sub_option != option.default:
|
|
data[sub_option] = 0
|
|
|
|
notes = {}
|
|
for name, number in getattr(option, "special_range_names", {}).items():
|
|
notes[name] = f"equivalent to {number}"
|
|
if number in data:
|
|
data[name] = data[number]
|
|
del data[number]
|
|
else:
|
|
data[name] = 0
|
|
|
|
return data, notes
|
|
|
|
def get_html_doc(option_type: type(Options.Option)) -> str:
|
|
if not option_type.__doc__:
|
|
return "Please document me!"
|
|
return "\n".join(line.strip() for line in option_type.__doc__.split("\n")).strip()
|
|
|
|
weighted_settings = {
|
|
"baseOptions": {
|
|
"description": "Generated by https://archipelago.gg/",
|
|
"name": "Player",
|
|
"game": {},
|
|
},
|
|
"games": {},
|
|
}
|
|
|
|
for game_name, world in AutoWorldRegister.world_types.items():
|
|
|
|
all_options: typing.Dict[str, Options.AssembleOptions] = {
|
|
**Options.per_game_common_options,
|
|
**world.option_definitions
|
|
}
|
|
with open(local_path("WebHostLib", "templates", "options.yaml")) as f:
|
|
file_data = f.read()
|
|
res = Template(file_data).render(
|
|
options=all_options,
|
|
__version__=__version__, game=game_name, yaml_dump=yaml.dump,
|
|
dictify_range=dictify_range,
|
|
)
|
|
|
|
del file_data
|
|
|
|
with open(os.path.join(target_folder, "configs", game_name + ".yaml"), "w", encoding="utf-8") as f:
|
|
f.write(res)
|
|
|
|
# Generate JSON files for player-settings pages
|
|
player_settings = {
|
|
"baseOptions": {
|
|
"description": "Generated by https://archipelago.gg/",
|
|
"game": game_name,
|
|
"name": "Player",
|
|
},
|
|
}
|
|
|
|
game_options = {}
|
|
for option_name, option in all_options.items():
|
|
if option_name in handled_in_js:
|
|
pass
|
|
|
|
elif option.options:
|
|
game_options[option_name] = this_option = {
|
|
"type": "select",
|
|
"displayName": option.display_name if hasattr(option, "display_name") else option_name,
|
|
"description": get_html_doc(option),
|
|
"defaultValue": None,
|
|
"options": []
|
|
}
|
|
|
|
for sub_option_id, sub_option_name in option.name_lookup.items():
|
|
this_option["options"].append({
|
|
"name": option.get_option_name(sub_option_id),
|
|
"value": sub_option_name,
|
|
})
|
|
|
|
if sub_option_id == option.default:
|
|
this_option["defaultValue"] = sub_option_name
|
|
|
|
if option.default == "random":
|
|
this_option["defaultValue"] = "random"
|
|
|
|
elif issubclass(option, Options.Range):
|
|
game_options[option_name] = {
|
|
"type": "range",
|
|
"displayName": option.display_name if hasattr(option, "display_name") else option_name,
|
|
"description": get_html_doc(option),
|
|
"defaultValue": option.default if hasattr(
|
|
option, "default") and option.default != "random" else option.range_start,
|
|
"min": option.range_start,
|
|
"max": option.range_end,
|
|
}
|
|
|
|
if issubclass(option, Options.SpecialRange):
|
|
game_options[option_name]["type"] = 'special_range'
|
|
game_options[option_name]["value_names"] = {}
|
|
for key, val in option.special_range_names.items():
|
|
game_options[option_name]["value_names"][key] = val
|
|
|
|
elif getattr(option, "verify_item_name", False):
|
|
game_options[option_name] = {
|
|
"type": "items-list",
|
|
"displayName": option.display_name if hasattr(option, "display_name") else option_name,
|
|
"description": get_html_doc(option),
|
|
}
|
|
|
|
elif getattr(option, "verify_location_name", False):
|
|
game_options[option_name] = {
|
|
"type": "locations-list",
|
|
"displayName": option.display_name if hasattr(option, "display_name") else option_name,
|
|
"description": get_html_doc(option),
|
|
}
|
|
|
|
elif issubclass(option, Options.OptionList) or issubclass(option, Options.OptionSet):
|
|
if option.valid_keys:
|
|
game_options[option_name] = {
|
|
"type": "custom-list",
|
|
"displayName": option.display_name if hasattr(option, "display_name") else option_name,
|
|
"description": get_html_doc(option),
|
|
"options": list(option.valid_keys),
|
|
}
|
|
|
|
else:
|
|
logging.debug(f"{option} not exported to Web Settings.")
|
|
|
|
player_settings["gameOptions"] = game_options
|
|
|
|
os.makedirs(os.path.join(target_folder, 'player-settings'), exist_ok=True)
|
|
|
|
with open(os.path.join(target_folder, 'player-settings', game_name + ".json"), "w") as f:
|
|
json.dump(player_settings, f, indent=2, separators=(',', ': '))
|
|
|
|
if not world.hidden and world.web.settings_page is True:
|
|
weighted_settings["baseOptions"]["game"][game_name] = 0
|
|
weighted_settings["games"][game_name] = {}
|
|
weighted_settings["games"][game_name]["gameSettings"] = game_options
|
|
weighted_settings["games"][game_name]["gameItems"] = tuple(world.item_names)
|
|
weighted_settings["games"][game_name]["gameLocations"] = tuple(world.location_names)
|
|
|
|
with open(os.path.join(target_folder, 'weighted-settings.json'), "w") as f:
|
|
json.dump(weighted_settings, f, indent=2, separators=(',', ': '))
|