Launcher: add Discord links and generate yamls (#1716)
This commit is contained in:
parent
89ec31708e
commit
599cd2c82e
26
Launcher.py
26
Launcher.py
|
@ -14,10 +14,12 @@ import itertools
|
|||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
import webbrowser
|
||||
from os.path import isfile
|
||||
from shutil import which
|
||||
from typing import Sequence, Union, Optional
|
||||
|
||||
import Utils
|
||||
from worlds.LauncherComponents import Component, components, Type, SuffixIdentifier
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -38,7 +40,6 @@ def open_host_yaml():
|
|||
exe = which("open")
|
||||
subprocess.Popen([exe, file])
|
||||
else:
|
||||
import webbrowser
|
||||
webbrowser.open(file)
|
||||
|
||||
|
||||
|
@ -58,23 +59,36 @@ def open_patch():
|
|||
launch([*get_exe(component), file], component.cli)
|
||||
|
||||
|
||||
def generate_yamls():
|
||||
from Options import generate_yaml_templates
|
||||
|
||||
target = Utils.user_path("Players", "Templates")
|
||||
generate_yaml_templates(target, False)
|
||||
open_folder(target)
|
||||
|
||||
|
||||
def browse_files():
|
||||
file = user_path()
|
||||
open_folder(user_path())
|
||||
|
||||
|
||||
def open_folder(folder_path):
|
||||
if is_linux:
|
||||
exe = which('xdg-open') or which('gnome-open') or which('kde-open')
|
||||
subprocess.Popen([exe, file])
|
||||
subprocess.Popen([exe, folder_path])
|
||||
elif is_macos:
|
||||
exe = which("open")
|
||||
subprocess.Popen([exe, file])
|
||||
subprocess.Popen([exe, folder_path])
|
||||
else:
|
||||
import webbrowser
|
||||
webbrowser.open(file)
|
||||
webbrowser.open(folder_path)
|
||||
|
||||
|
||||
components.extend([
|
||||
# Functions
|
||||
Component('Open host.yaml', func=open_host_yaml),
|
||||
Component('Open Patch', func=open_patch),
|
||||
Component('Generate Template Settings', func=generate_yamls),
|
||||
Component('Discord Server', func=lambda: webbrowser.open("https://discord.gg/8Z65BR2")),
|
||||
Component('18+ Discord Server', func=lambda: webbrowser.open("https://discord.gg/fqvNCCRsu4")),
|
||||
Component('Browse Files', func=browse_files),
|
||||
])
|
||||
|
||||
|
|
59
Options.py
59
Options.py
|
@ -13,6 +13,7 @@ from Utils import get_fuzzy_results
|
|||
if typing.TYPE_CHECKING:
|
||||
from BaseClasses import PlandoOptions
|
||||
from worlds.AutoWorld import World
|
||||
import pathlib
|
||||
|
||||
|
||||
class AssembleOptions(abc.ABCMeta):
|
||||
|
@ -1022,6 +1023,64 @@ per_game_common_options = {
|
|||
"item_links": ItemLinks
|
||||
}
|
||||
|
||||
|
||||
def generate_yaml_templates(target_folder: typing.Union[str, "pathlib.Path"], generate_hidden: bool = True):
|
||||
import os
|
||||
|
||||
import yaml
|
||||
from jinja2 import Template
|
||||
|
||||
from worlds import AutoWorldRegister
|
||||
from Utils import local_path, __version__
|
||||
|
||||
full_path: str
|
||||
|
||||
os.makedirs(target_folder, exist_ok=True)
|
||||
|
||||
# clean out old
|
||||
for file in os.listdir(target_folder):
|
||||
full_path = os.path.join(target_folder, file)
|
||||
if os.path.isfile(full_path) and full_path.endswith(".yaml"):
|
||||
os.unlink(full_path)
|
||||
|
||||
def dictify_range(option: typing.Union[Range, 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
|
||||
|
||||
for game_name, world in AutoWorldRegister.world_types.items():
|
||||
if not world.hidden or generate_hidden:
|
||||
all_options: typing.Dict[str, AssembleOptions] = {
|
||||
**per_game_common_options,
|
||||
**world.option_definitions
|
||||
}
|
||||
|
||||
with open(local_path("data", "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, game_name + ".yaml"), "w", encoding="utf-8-sig") as f:
|
||||
f.write(res)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from worlds.alttp.Options import Logic
|
||||
|
|
|
@ -17,29 +17,8 @@ handled_in_js = {"start_inventory", "local_items", "non_local_items", "start_hin
|
|||
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
|
||||
Options.generate_yaml_templates(yaml_folder)
|
||||
|
||||
def get_html_doc(option_type: type(Options.Option)) -> str:
|
||||
if not option_type.__doc__:
|
||||
|
@ -61,18 +40,6 @@ def create():
|
|||
**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 = {
|
||||
|
|
8
setup.py
8
setup.py
|
@ -309,16 +309,12 @@ class BuildExeCommand(cx_Freeze.command.build_exe.BuildEXE):
|
|||
dirs_exist_ok=True)
|
||||
|
||||
os.makedirs(self.buildfolder / "Players" / "Templates", exist_ok=True)
|
||||
from WebHostLib.options import create
|
||||
create()
|
||||
from Options import generate_yaml_templates
|
||||
from worlds.AutoWorld import AutoWorldRegister
|
||||
assert not apworlds - set(AutoWorldRegister.world_types), "Unknown world designated for .apworld"
|
||||
folders_to_remove: typing.List[str] = []
|
||||
generate_yaml_templates(self.buildfolder / "Players" / "Templates", False)
|
||||
for worldname, worldtype in AutoWorldRegister.world_types.items():
|
||||
if not worldtype.hidden:
|
||||
file_name = worldname+".yaml"
|
||||
shutil.copyfile(os.path.join("WebHostLib", "static", "generated", "configs", file_name),
|
||||
self.buildfolder / "Players" / "Templates" / file_name)
|
||||
if worldname in apworlds:
|
||||
file_name = os.path.split(os.path.dirname(worldtype.__file__))[1]
|
||||
world_directory = self.libfolder / "worlds" / file_name
|
||||
|
|
|
@ -25,7 +25,7 @@ class TestFileGeneration(unittest.TestCase):
|
|||
for file in os.scandir(target):
|
||||
if file.is_file() and file.name.endswith(".yaml"):
|
||||
with self.subTest(file=file.name):
|
||||
with open(file) as f:
|
||||
with open(file, encoding="utf-8-sig") as f:
|
||||
for value in roll_options({file.name: f.read()})[0].values():
|
||||
self.assertTrue(value is True, f"Default Options for template {file.name} cannot be run.")
|
||||
|
||||
|
|
Loading…
Reference in New Issue