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

WebHost: fixup WebHostLib/options.py #3332

Merged
merged 4 commits into from
May 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 30 additions & 26 deletions WebHostLib/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,35 +70,39 @@ def generate(race=False):
flash(options)
else:
meta = get_meta(request.form, race)
results, gen_options = roll_options(options, set(meta["plando_options"]))

if any(type(result) == str for result in results.values()):
return render_template("checkResult.html", results=results)
elif len(gen_options) > app.config["MAX_ROLL"]:
flash(f"Sorry, generating of multiworlds is limited to {app.config['MAX_ROLL']} players. "
f"If you have a larger group, please generate it yourself and upload it.")
elif len(gen_options) >= app.config["JOB_THRESHOLD"]:
gen = Generation(
options=pickle.dumps({name: vars(options) for name, options in gen_options.items()}),
# convert to json compatible
meta=json.dumps(meta),
state=STATE_QUEUED,
owner=session["_id"])
commit()
return start_generation(options, meta)

return redirect(url_for("wait_seed", seed=gen.id))
else:
try:
seed_id = gen_game({name: vars(options) for name, options in gen_options.items()},
meta=meta, owner=session["_id"].int)
except BaseException as e:
from .autolauncher import handle_generation_failure
handle_generation_failure(e)
return render_template("seedError.html", seed_error=(e.__class__.__name__ + ": " + str(e)))
return render_template("generate.html", race=race, version=__version__)

return redirect(url_for("view_seed", seed=seed_id))

return render_template("generate.html", race=race, version=__version__)
def start_generation(options: Dict[str, Union[dict, str]], meta: Dict[str, Any]):
results, gen_options = roll_options(options, set(meta["plando_options"]))

if any(type(result) == str for result in results.values()):
return render_template("checkResult.html", results=results)
elif len(gen_options) > app.config["MAX_ROLL"]:
flash(f"Sorry, generating of multiworlds is limited to {app.config['MAX_ROLL']} players. "
f"If you have a larger group, please generate it yourself and upload it.")
elif len(gen_options) >= app.config["JOB_THRESHOLD"]:
gen = Generation(
options=pickle.dumps({name: vars(options) for name, options in gen_options.items()}),
# convert to json compatible
meta=json.dumps(meta),
state=STATE_QUEUED,
owner=session["_id"])
commit()

return redirect(url_for("wait_seed", seed=gen.id))
else:
try:
seed_id = gen_game({name: vars(options) for name, options in gen_options.items()},
meta=meta, owner=session["_id"].int)
except BaseException as e:
from .autolauncher import handle_generation_failure
handle_generation_failure(e)
return render_template("seedError.html", seed_error=(e.__class__.__name__ + ": " + str(e)))

return redirect(url_for("view_seed", seed=seed_id))


def gen_game(gen_options: dict, meta: Optional[Dict[str, Any]] = None, owner=None, sid=None):
Expand Down
63 changes: 22 additions & 41 deletions WebHostLib/options.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import collections.abc
import json
import os
from textwrap import dedent
from typing import Dict, Union

import yaml
import requests
import json
import flask
from flask import redirect, render_template, request, Response

import Options
from Options import Visibility
from flask import redirect, render_template, request, Response
from worlds.AutoWorld import AutoWorldRegister
from Utils import local_path
from textwrap import dedent
from worlds.AutoWorld import AutoWorldRegister
from . import app, cache


def create():
def create() -> None:
target_folder = local_path("WebHostLib", "static", "generated")
yaml_folder = os.path.join(target_folder, "configs")

Options.generate_yaml_templates(yaml_folder)


def get_world_theme(game_name: str):
def get_world_theme(game_name: str) -> str:
if game_name in AutoWorldRegister.world_types:
return AutoWorldRegister.world_types[game_name].web.theme
return 'grass'


def render_options_page(template: str, world_name: str, is_complex: bool = False):
def render_options_page(template: str, world_name: str, is_complex: bool = False) -> Union[Response, str]:
visibility_flag = Options.Visibility.complex_ui if is_complex else Options.Visibility.simple_ui
world = AutoWorldRegister.world_types[world_name]
if world.hidden or world.web.options_page is False:
return redirect("games")
Expand All @@ -39,13 +39,8 @@ def render_options_page(template: str, world_name: str, is_complex: bool = False
grouped_options = {group: {} for group in ordered_groups}
for option_name, option in world.options_dataclass.type_hints.items():
# Exclude settings from options pages if their visibility is disabled
if not is_complex and option.visibility < Visibility.simple_ui:
continue

if is_complex and option.visibility < Visibility.complex_ui:
continue

grouped_options[option_groups.get(option, "Game Options")][option_name] = option
if visibility_flag in option.visibility:
grouped_options[option_groups.get(option, "Game Options")][option_name] = option

return render_template(
template,
Expand All @@ -58,34 +53,20 @@ def render_options_page(template: str, world_name: str, is_complex: bool = False
)


def generate_game(player_name: str, formatted_options: dict):
payload = {
"race": 0,
"hint_cost": 10,
"forfeit_mode": "auto",
"remaining_mode": "disabled",
"collect_mode": "goal",
"weights": {
player_name: formatted_options,
},
}
r = requests.post("https://archipelago.gg/api/generate", json=payload)
if 200 <= r.status_code <= 299:
response_data = r.json()
return redirect(response_data["url"])
else:
return r.text


def send_yaml(player_name: str, formatted_options: dict):
def generate_game(options: Dict[str, Union[dict, str]]) -> Union[Response, str]:
from .generate import start_generation
return start_generation(options, {"plando_options": ["items", "connections", "texts", "bosses"]})


def send_yaml(player_name: str, formatted_options: dict) -> Response:
response = Response(yaml.dump(formatted_options, sort_keys=False))
response.headers["Content-Type"] = "text/yaml"
response.headers["Content-Disposition"] = f"attachment; filename={player_name}.yaml"
return response


@app.template_filter("dedent")
def filter_dedent(text: str):
def filter_dedent(text: str) -> str:
return dedent(text).strip("\n ")


Expand All @@ -111,7 +92,7 @@ def default(self, obj):
return json.JSONEncoder.default(self, obj)

json_data = json.dumps(presets, cls=SetEncoder)
response = flask.Response(json_data)
response = Response(json_data)
response.headers["Content-Type"] = "application/json"
return response

Expand Down Expand Up @@ -169,7 +150,7 @@ def generate_weighted_yaml(game: str):
}

if intent_generate:
return generate_game(player_name, formatted_options)
return generate_game({player_name: formatted_options})

else:
return send_yaml(player_name, formatted_options)
Expand Down Expand Up @@ -243,7 +224,7 @@ def generate_yaml(game: str):
}

if intent_generate:
return generate_game(player_name, formatted_options)
return generate_game({player_name: formatted_options})

else:
return send_yaml(player_name, formatted_options)
Loading