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 shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import webbrowser
|
||||||
from os.path import isfile
|
from os.path import isfile
|
||||||
from shutil import which
|
from shutil import which
|
||||||
from typing import Sequence, Union, Optional
|
from typing import Sequence, Union, Optional
|
||||||
|
|
||||||
|
import Utils
|
||||||
from worlds.LauncherComponents import Component, components, Type, SuffixIdentifier
|
from worlds.LauncherComponents import Component, components, Type, SuffixIdentifier
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -38,7 +40,6 @@ def open_host_yaml():
|
||||||
exe = which("open")
|
exe = which("open")
|
||||||
subprocess.Popen([exe, file])
|
subprocess.Popen([exe, file])
|
||||||
else:
|
else:
|
||||||
import webbrowser
|
|
||||||
webbrowser.open(file)
|
webbrowser.open(file)
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,23 +59,36 @@ def open_patch():
|
||||||
launch([*get_exe(component), file], component.cli)
|
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():
|
def browse_files():
|
||||||
file = user_path()
|
open_folder(user_path())
|
||||||
|
|
||||||
|
|
||||||
|
def open_folder(folder_path):
|
||||||
if is_linux:
|
if is_linux:
|
||||||
exe = which('xdg-open') or which('gnome-open') or which('kde-open')
|
exe = which('xdg-open') or which('gnome-open') or which('kde-open')
|
||||||
subprocess.Popen([exe, file])
|
subprocess.Popen([exe, folder_path])
|
||||||
elif is_macos:
|
elif is_macos:
|
||||||
exe = which("open")
|
exe = which("open")
|
||||||
subprocess.Popen([exe, file])
|
subprocess.Popen([exe, folder_path])
|
||||||
else:
|
else:
|
||||||
import webbrowser
|
webbrowser.open(folder_path)
|
||||||
webbrowser.open(file)
|
|
||||||
|
|
||||||
|
|
||||||
components.extend([
|
components.extend([
|
||||||
# Functions
|
# Functions
|
||||||
Component('Open host.yaml', func=open_host_yaml),
|
Component('Open host.yaml', func=open_host_yaml),
|
||||||
Component('Open Patch', func=open_patch),
|
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),
|
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:
|
if typing.TYPE_CHECKING:
|
||||||
from BaseClasses import PlandoOptions
|
from BaseClasses import PlandoOptions
|
||||||
from worlds.AutoWorld import World
|
from worlds.AutoWorld import World
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
|
||||||
class AssembleOptions(abc.ABCMeta):
|
class AssembleOptions(abc.ABCMeta):
|
||||||
|
@ -1022,6 +1023,64 @@ per_game_common_options = {
|
||||||
"item_links": ItemLinks
|
"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__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
from worlds.alttp.Options import Logic
|
from worlds.alttp.Options import Logic
|
||||||
|
|
|
@ -17,29 +17,8 @@ handled_in_js = {"start_inventory", "local_items", "non_local_items", "start_hin
|
||||||
def create():
|
def create():
|
||||||
target_folder = local_path("WebHostLib", "static", "generated")
|
target_folder = local_path("WebHostLib", "static", "generated")
|
||||||
yaml_folder = os.path.join(target_folder, "configs")
|
yaml_folder = os.path.join(target_folder, "configs")
|
||||||
os.makedirs(yaml_folder, exist_ok=True)
|
|
||||||
|
|
||||||
for file in os.listdir(yaml_folder):
|
Options.generate_yaml_templates(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:
|
def get_html_doc(option_type: type(Options.Option)) -> str:
|
||||||
if not option_type.__doc__:
|
if not option_type.__doc__:
|
||||||
|
@ -61,18 +40,6 @@ def create():
|
||||||
**Options.per_game_common_options,
|
**Options.per_game_common_options,
|
||||||
**world.option_definitions
|
**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
|
# Generate JSON files for player-settings pages
|
||||||
player_settings = {
|
player_settings = {
|
||||||
|
|
8
setup.py
8
setup.py
|
@ -309,16 +309,12 @@ class BuildExeCommand(cx_Freeze.command.build_exe.BuildEXE):
|
||||||
dirs_exist_ok=True)
|
dirs_exist_ok=True)
|
||||||
|
|
||||||
os.makedirs(self.buildfolder / "Players" / "Templates", exist_ok=True)
|
os.makedirs(self.buildfolder / "Players" / "Templates", exist_ok=True)
|
||||||
from WebHostLib.options import create
|
from Options import generate_yaml_templates
|
||||||
create()
|
|
||||||
from worlds.AutoWorld import AutoWorldRegister
|
from worlds.AutoWorld import AutoWorldRegister
|
||||||
assert not apworlds - set(AutoWorldRegister.world_types), "Unknown world designated for .apworld"
|
assert not apworlds - set(AutoWorldRegister.world_types), "Unknown world designated for .apworld"
|
||||||
folders_to_remove: typing.List[str] = []
|
folders_to_remove: typing.List[str] = []
|
||||||
|
generate_yaml_templates(self.buildfolder / "Players" / "Templates", False)
|
||||||
for worldname, worldtype in AutoWorldRegister.world_types.items():
|
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:
|
if worldname in apworlds:
|
||||||
file_name = os.path.split(os.path.dirname(worldtype.__file__))[1]
|
file_name = os.path.split(os.path.dirname(worldtype.__file__))[1]
|
||||||
world_directory = self.libfolder / "worlds" / file_name
|
world_directory = self.libfolder / "worlds" / file_name
|
||||||
|
|
|
@ -25,7 +25,7 @@ class TestFileGeneration(unittest.TestCase):
|
||||||
for file in os.scandir(target):
|
for file in os.scandir(target):
|
||||||
if file.is_file() and file.name.endswith(".yaml"):
|
if file.is_file() and file.name.endswith(".yaml"):
|
||||||
with self.subTest(file=file.name):
|
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():
|
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.")
|
self.assertTrue(value is True, f"Default Options for template {file.name} cannot be run.")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue