Files
ReSkate/Launcher/problem.h
T
AyeZeeBB aef269497e Rebuild the launcher's mod manager, settings and status tile
The mod browser was a 960x620 panel inside a 1180x680 window, reached from
a tile the same size as SETTINGS. People could not find it, and once they
did there was room for about six mods.

Window
- The design size is 1440x840. Everything is laid out in design units and
  multiplied by g_scale, which now scales down when that would not fit the
  screen's work area, so a small laptop or a high DPI no longer gets a
  window running off under the taskbar.
- The MODS tile is MOD MANAGER: taller than SETTINGS, directly above PLAY,
  with the pending update count as a pill on its subtitle line.
- background.jpg is 1920x1027, so the bigger window is not upscaling a
  1280x720 photo.

Mod manager, a page rather than a panel
- begin_page fills the window and draws its own minimise and close, since
  it covers the main screen's. BACK or Escape leaves it.
- A nav rail holds MY MODS and GET MODS (count badges, blue for the open
  one), the install actions and BACK. Refresh sits with what it refreshes,
  top right of the content.
- Every mod is a full-width row: icon, name, author, description, version
  and downloads, with a blue INSTALL or UPDATE and a tick box on the right.
  Ticking several installs them in one run.
- Clicking a row opens that mod's overview in a popup, replacing the
  side-by-side details pane that halved the list's width.
- virtual_rows draws only the rows a scrolling child actually shows.
  ImGuiListClipper cannot do this, as it assumes every row is a fixed
  height.
- Installing is a centred panel over a dimmed page with the activity, a
  striped bar and Cancel, instead of a progress bar in the footer.

Settings
- The same page and rail: GAME, DISPLAY, KEYS and ADVANCED are nav tiles
  rather than a row of tab buttons, and the content keeps to a 760 px
  column so the explanations stay a readable measure.
- The Steam sign-in, Steam Guard and QR dialogs stay centred panels. They
  are prompts, not pages.

Status and failures
- The STATUS tile carries its state in a coloured edge and a pill (WORKING,
  READY, ACTION NEEDED, PROBLEM), its headline is 22 pt over muted detail,
  and the standing facts (game build, ReSkate version) sit under a rule
  instead of competing with the live status as equal rows.
- Launcher::fail keeps the raw message for the log, and problem.h turns it
  into a headline and the next thing to try. The injection and PE-identity
  failures ("VirtualAllocEx failed", "Injected ReSkate.dll is not present
  in the child module list") all become "ReSkate could not attach to
  Skate", with the anti-virus and overlay advice that actually fixes it;
  the Steam download, a missing or damaged ReSkate.dll, the content cache
  and a shared menu/console key each get their own. Anything unmatched
  keeps its raw text.
- A failed tile grows Open logs and Copy details. Copy details puts the raw
  message and the versions on the clipboard, ready to paste into Discord.
2026-10-03 16:10:55 -05:00

88 lines
5.0 KiB
C++

#pragma once
#include <string>
#include <string_view>
// Failures are logged in the words that help whoever reads ReSkate.log, which
// are rarely the words that help whoever is trying to skate. This turns one
// into the other: what went wrong, and what to do about it. The raw message
// stays in the log, and the STATUS tile can still copy it.
namespace dingosdk::launcher_problem {
struct Problem {
std::string headline; // what went wrong, in a line
std::string advice; // the next thing to try
};
inline bool mentions(std::string_view raw, std::string_view needle) {
return raw.find(needle) != std::string_view::npos;
}
// Anti-virus and overlays are behind most injection failures, so they share
// one piece of advice.
inline constexpr std::string_view attach_advice =
"Anti-virus software usually blocks this. Add your skate. folder as an exclusion, close overlays "
"(Discord, MSI Afterburner, RTSS), then press RETRY.";
inline Problem explain(std::string_view raw) {
// Most specific first: the later rules match whole families of failures.
if (mentions(raw, "must be beside ReSkateLauncher.exe"))
return {"ReSkate is not in your skate. folder",
"Put ReSkateLauncher.exe and ReSkate.dll beside Skate.exe, in the folder Steam opens with "
"skate. > Manage > Browse local files."};
if (mentions(raw, "ReSkate.dll is missing"))
return {"ReSkate.dll is missing",
"Extract ReSkateLauncher.exe and ReSkate.dll from the same release zip into this folder, "
"then press RETRY."};
if (mentions(raw, "ReSkate.dll is not an x64") || mentions(raw, "DingoSDKDebugInitialize is outside"))
return {"ReSkate.dll is damaged",
"Download the release zip again and extract both files over this folder. Your anti-virus may "
"also have quarantined part of it."};
if (mentions(raw, "Skate.exe is missing"))
return {"Skate.exe is not in this folder",
"Run the launcher from your skate. folder, or press INSTALL to download the game here."};
if (mentions(raw, "steam_api64.dll is missing") || mentions(raw, "steam_api64"))
return {"The original steam_api64.dll is missing",
"Verify the game files in Steam, or press DOWNLOAD to fetch the supported build again."};
if (mentions(raw, "This launcher is out of date"))
return {"This launcher is out of date",
"Download the newest ReSkate release from GitHub and extract it over this folder."};
if (mentions(raw, "update server could not be reached"))
return {"The ReSkate update server could not be reached",
"Check your internet connection and press RETRY. If the game files are already correct you can "
"turn on Offline mode in Settings and play without the check."};
if (mentions(raw, "not supported"))
return {"This copy of skate. is not the supported build",
"Press DOWNLOAD to get the supported build with your Steam account. Only the files that differ "
"are downloaded."};
if (mentions(raw, "Steam download did not finish"))
return {"The Steam download did not finish",
"Check that the account you signed in with owns skate. and that you have about 14 GB free, "
"then press DOWNLOAD again. Signing in again often clears it."};
if (mentions(raw, "installing the game content cache"))
return {"Another ReSkate launcher is busy",
"It is installing the game data this build needs. Wait for it to finish, then press RETRY."};
if (mentions(raw, "content cache"))
return {"The one-time game data download failed",
"ReSkate downloads the game's catalogues once per build. Check your internet connection and "
"press RETRY."};
if (mentions(raw, "need different keys"))
return {"The menu and console share a key",
"Open Settings > KEYS and pick a different key for one of them."};
if (mentions(raw, "Skate closed while it was starting"))
return {"Skate closed while it was starting", std::string(attach_advice)};
if (mentions(raw, "timed out after"))
return {"Skate took too long to start",
"A slow disk or an anti-virus scan usually causes this. Press RETRY; if it keeps happening, add "
"your skate. folder as an exclusion."};
if (mentions(raw, "validated Skate.exe") || mentions(raw, "loaded-image") || mentions(raw, "DOS header") ||
mentions(raw, "module list") || mentions(raw, "VirtualAllocEx") || mentions(raw, "NtQueryInformationProcess") ||
mentions(raw, "DingoSDKDebugInitialize") || mentions(raw, "Remote "))
return {"ReSkate could not attach to Skate", std::string(attach_advice)};
return {std::string(raw),
"Press RETRY. If it keeps happening, copy the details below and share them with logs\\ReSkate.log "
"on the ReSkate Discord."};
}
} // namespace dingosdk::launcher_problem