Files
AyeZeeBB 4ac1343b95 Crash reports: self-hosted Sentry instead of Backtrace, and opt-in performance timings
Crash dumps now go to the project's own Sentry server. The launcher's
out-of-process helper is unchanged; only where it posts and what it expects
back are:

- The default endpoint is the Sentry project's minidump URL. Report
  attributes travel as Sentry tags, with the release as reskate@<version>.
- An upload counts as accepted when the server answers with an event ID.
- "backtrace" is "crash_report" throughout: the namespace, files, CMake
  targets, DINGOSDK_CRASH_REPORT_URL, DINGOSDK_BUILD_CRASH_REPORT_TESTS and
  the RESKATE_CRASH_REPORT_URL override.

Performance timings are new, and off unless "Send performance timings" is
ticked in the launcher's settings (RESKATE_TRACING=1). A small tracer
(Engine/Core/Debug/trace.h) posts each finished step to Sentry as a
transaction from a background thread; the launcher and the game it starts
share one trace. Timed: the update check, the Steam download, Thunderstore
installs, the mod merge, starting the game, the launch up to the first
playable level, each level load, joining a session, fetching the identity
lists, and the time spent in each level with its average frame rate and
long frames. Turning crash reports off turns timings off too.
2026-10-12 23:24:33 -05:00

58 lines
2.4 KiB
C++

#pragma once
#include "Engine/Game/Multiplayer/session_model.h"
#include <cstdint>
#include <map>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
namespace dingosdk::multiplayer {
// Parses a dedicated server's game tags (Server/steam_server.cpp) into a
// browser row. Empty when the tags are not a compatible ReSkate server.
std::optional<MultiplayerLobby> read_server_tags(std::string_view tags, std::uint64_t steam_id);
// Dedicated ReSkate servers from Steam's server list for Skate. Rows come from
// Steam's master list, so a server shows even when a NAT hides its query port;
// what a server answers directly (name, ping) replaces the tag copy.
// Not shown: a server the ReSkate team has blocked, and, while the team requires login
// tokens (developer_identity.h), one that signed in to Steam without one, unless it is on
// the player's own network.
// Steam answers a search made soon after another with an empty internet list (seen
// 2026-10-06: every refresh within about 40 s of a full one). A search that lists no
// internet server therefore keeps the servers the last one found, for a while.
class SteamServerBrowser {
public:
~SteamServerBrowser();
// Starts a new search, dropping one still running. The caller limits how often.
void refresh(std::uint64_t now);
void tick(std::uint64_t now);
bool searching() const { return !searches_.empty(); }
const std::vector<MultiplayerLobby> &rows() const { return rows_; }
const MultiplayerLobby *find(std::uint64_t id) const;
private:
struct Search {
void *request{}, *response{};
bool internet{};
};
struct Found {
MultiplayerLobby row;
// Every address it was listed at: its public one, and a LAN one nearby.
std::vector<std::pair<std::uint32_t, std::uint16_t>> addresses;
bool answered{};
std::uint64_t search{}, listed{}; // the search that last listed it, and when
bool lan{}; // answered on the player's own network
};
void *servers_{};
std::vector<Search> searches_; // the internet and LAN lists
std::map<std::uint64_t, Found> found_;
std::uint64_t started_{}, next_poll_{};
std::uint64_t search_{}; // counts refreshes
bool internet_listed_{}; // this search's internet list had a server in it
std::vector<MultiplayerLobby> rows_;
void release();
void read(std::uint64_t now);
};
} // namespace dingosdk::multiplayer