mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-17 15:07:06 +02:00
Map downloader - A host or dedicated server now tells joiners which Thunderstore package its map comes from (the Mods folder name plus manifest.json). - A player without the map gets a card: icon, name, author, version and description, with DOWNLOAD and CANCEL. It works with mouse, keyboard and controller. - Only packages listed as Maps in the ReSkate community are offered, and never deprecated, rejected or NSFW ones. - On yes the package is downloaded, installed into Mods and applied as a live mod, then the session loads the map. A small card on the right shows the progress, so the player can keep skating. - The player stays connected while it downloads: the host gives a player who says they are fetching the map up to 45 minutes instead of the usual load time. - When the server changes map with the player in it, the card says so. - Protocol version 47: map package on map_offer and world_state, and a "fetching the map" flag on map_request and world_ready. Joining - The pause-menu server browser shows a CONNECTING card over the page while a join is under way, and a COULDN'T CONNECT card with the reason when it does not get in. - The session and voice tabs no longer show before the player is in. - Leaving without the map (declined or cancelled download) no longer counts towards the failed-join limit, on servers and player hosts. Input - A card that asks something holds the game's input until the buttons are released. - Steam's overlay hooks XInput in front of ReSkate and answers the game itself, so a controller reached the game behind menus. ReSkate now hooks that hook as well. Mod merging - Mods are read on several threads, at launch and for live merges. A live merge runs below the game's priority. - The paid-cosmetics check reads the game's files and the mods on several threads. - A live merge reuses the paid-cosmetics verdicts it already has and reports its progress and timings. Launcher - NSFW mods and their categories are not shown in the mod browser.
70 lines
3.5 KiB
C++
70 lines
3.5 KiB
C++
#pragma once
|
|
#include "Engine/Vfs/mod_list.h"
|
|
#include <filesystem>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
// Live mods: applying Mods/ and mods.json while the game runs, so a change
|
|
// takes effect at the next level load instead of the next launch.
|
|
//
|
|
// The engine re-reads the root level, customization, buildkititems and each
|
|
// destination's superbundle TOC at every load, and opens an archive only when
|
|
// it first reads from it (sharing it with writers). The launch's merge places
|
|
// every installed mod's archives, disabled ones included, so a live merge
|
|
// only rewrites TOCs and appends manifests; a superbundle the game did not
|
|
// know at launch is registered with it and listed under its install chunk.
|
|
// Globals and items are read once at launch; the merged patch always carries
|
|
// its own copy of both, which a live apply hands to the game in memory, so
|
|
// maps, loading screens and cosmetics (the ownables system reloads its bundle
|
|
// at every level load) change too. The UI and language packs still need a
|
|
// restart.
|
|
namespace dingosdk::live_mods {
|
|
// Re-reads mods.json and starts a merge of the enabled mods on a worker
|
|
// thread. Returns what happened to the request; the outcome is logged.
|
|
// With reload_level, the level being played is loaded again once the merge
|
|
// finishes (see take_reload), so the change shows straight away; it is not
|
|
// when only maps changed, which show up in the level list instead.
|
|
std::string apply(bool reload_level = false);
|
|
// True once per apply that asked to reload the level and needed to, after it
|
|
// succeeded. Handed out together with take_level_manifests.
|
|
bool take_reload();
|
|
// What applying the pending changes in `list` will do to the level being
|
|
// played, for the overlay's apply button.
|
|
enum class ApplyEffect {
|
|
maps_only, // only maps added or taken away; nothing to reload
|
|
reload_level, // something the level shows changed (cosmetics, settings)
|
|
leave_level, // the map being played goes away, so San Van is loaded
|
|
};
|
|
ApplyEffect preview(const mods::ModList& list);
|
|
// The apply button's label for an effect, shared by the overlay and native menu.
|
|
inline const char* apply_label(ApplyEffect effect) {
|
|
return effect == ApplyEffect::maps_only ? "Apply"
|
|
: effect == ApplyEffect::leave_level ? "Apply and go to San Van" : "Apply and reload level";
|
|
}
|
|
// The level being played (its level-manager destination, else the level),
|
|
// kept current by the client tick.
|
|
void set_current_level(std::string level);
|
|
// True while a live merge runs.
|
|
bool busy() noexcept;
|
|
// How far it is: steps done of all, and the step in hand ("Merging items from 12 mods").
|
|
struct Progress {
|
|
std::size_t done{}, total{};
|
|
std::string step;
|
|
};
|
|
Progress progress();
|
|
// The last live apply's outcome for the overlay, or empty before the first.
|
|
std::string status();
|
|
// Folder names of the mods in effect now: the launch's, or the last live apply's.
|
|
std::vector<std::string> applied_mods();
|
|
// True when the launch's merge placed this mod's archives (enabled or not),
|
|
// so it can be enabled without a restart.
|
|
bool placed_at_launch(const std::string& name);
|
|
// Whether a mod folder holds maps and nothing else: level bundles and the two files maps
|
|
// register themselves in (its layout and globals). Reads the folder; not cached.
|
|
bool only_maps(const std::filesystem::path& directory);
|
|
// reskate-levels.json of every mod a live apply left enabled, highest
|
|
// priority first; handed out once per successful apply.
|
|
std::optional<std::vector<std::filesystem::path>> take_level_manifests();
|
|
}
|