mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-18 00:27:06 +02:00
96 lines
5.2 KiB
C++
96 lines
5.2 KiB
C++
#include "console_activity.h"
|
|
#include <format>
|
|
|
|
namespace dingosdk {
|
|
namespace {
|
|
enum class Phase { assets, profile, disconnected, unloading, loading, active, connecting,
|
|
sublevel_loading, sublevel_active, shutdown, idle };
|
|
Phase phase(unsigned state) {
|
|
switch (state) {
|
|
case 0: return Phase::assets;
|
|
case 1: return Phase::profile;
|
|
case 2: return Phase::disconnected;
|
|
case 3: case 14: case 22: return Phase::unloading;
|
|
case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: return Phase::loading;
|
|
case 13: return Phase::active;
|
|
case 15: case 23: return Phase::connecting;
|
|
case 16: case 17: case 18: case 19: case 20: return Phase::sublevel_loading;
|
|
case 21: return Phase::sublevel_active;
|
|
case 24: case 25: return Phase::shutdown;
|
|
default: return Phase::idle;
|
|
}
|
|
}
|
|
}
|
|
void ConsoleActivityFeed::update(const ConsoleActivity& a, Emit sink, std::uint64_t now_ms) {
|
|
const ConsoleActivity empty;
|
|
const auto& before = previous_ ? *previous_ : empty;
|
|
const auto emit = [&](ConsoleSource source, std::string text,
|
|
ConsoleSeverity severity = ConsoleSeverity::info) {
|
|
if (sink) sink(source, text, severity);
|
|
};
|
|
const auto current = phase(a.state);
|
|
const bool loading = current == Phase::loading || current == Phase::sublevel_loading;
|
|
const bool sublevel = current == Phase::sublevel_loading || current == Phase::sublevel_active;
|
|
const auto& destination = sublevel ? a.sublevel : a.level;
|
|
const bool changed = !previous_ || current != phase(before.state) || a.level != before.level ||
|
|
(sublevel && a.sublevel != before.sublevel);
|
|
if (changed && !a.native_loading_logging) {
|
|
const auto suffix = destination.empty() ? "." : ": " + destination;
|
|
if (loading) {
|
|
if (!load_started_ || current != phase(before.state)) load_started_ = now_ms;
|
|
waiting_reported_ = false;
|
|
preparation_reported_ = false;
|
|
emit(ConsoleSource::level, std::string(sublevel ? "Loading sublevel" : "Loading world") + suffix);
|
|
} else if (current == Phase::active || current == Phase::sublevel_active) {
|
|
const auto duration = load_started_ ? std::format(" (load took {:.1f}s)",
|
|
static_cast<double>(now_ms - *load_started_) / 1000.0) : "";
|
|
emit(ConsoleSource::level, std::string(sublevel ? "Sublevel active" : "World active") + suffix + duration,
|
|
ConsoleSeverity::success);
|
|
load_started_.reset();
|
|
} else {
|
|
load_started_.reset();
|
|
switch (current) {
|
|
case Phase::assets: emit(ConsoleSource::assets, "Loading shared game assets."); break;
|
|
case Phase::profile: emit(ConsoleSource::profile, "Applying profile options."); break;
|
|
case Phase::disconnected: emit(ConsoleSource::network, "Game reported a lost connection.", ConsoleSeverity::warning); break;
|
|
case Phase::unloading: emit(ConsoleSource::level, "Unloading world content" + suffix); break;
|
|
case Phase::connecting: emit(ConsoleSource::level, "Connecting to local world" + suffix); break;
|
|
case Phase::shutdown: emit(ConsoleSource::runtime, "Game is shutting down."); break;
|
|
default: break;
|
|
}
|
|
}
|
|
}
|
|
if (!a.native_loading_logging && loading && load_started_ && !waiting_reported_ && now_ms - *load_started_ >= 30000) {
|
|
emit(ConsoleSource::level, "Still loading after 30 seconds: " + a.state_name +
|
|
(destination.empty() ? "." : " - " + destination), ConsoleSeverity::warning);
|
|
waiting_reported_ = true;
|
|
}
|
|
if (!a.sublevel.empty() && a.sublevel_active && a.client_sublevel_present &&
|
|
current != Phase::sublevel_active && (a.sublevel != before.sublevel ||
|
|
!before.sublevel_active || !before.client_sublevel_present))
|
|
emit(ConsoleSource::level, "Sublevel content ready: " + a.sublevel, ConsoleSeverity::success);
|
|
if (a.players_available && (!before.players_available || a.players != before.players) &&
|
|
(a.players || before.players)) {
|
|
emit(ConsoleSource::player, a.players ? "Local player joined (" + std::to_string(a.players) + ")."
|
|
: "Local player left.");
|
|
}
|
|
if (a.players_available && a.controllables != before.controllables) {
|
|
emit(ConsoleSource::player, a.controllables ? "Controllable entity assigned to local player."
|
|
: "Local player released its controllable entity.");
|
|
}
|
|
if (a.setup_attempts > before.setup_attempts && !preparation_reported_) {
|
|
emit(ConsoleSource::skater, "Skater initialization started.");
|
|
preparation_reported_ = true;
|
|
}
|
|
if (a.skater != before.skater) {
|
|
if (a.skater) emit(ConsoleSource::skater,
|
|
std::format("Local skater entity available at ({:.1f}, {:.1f}, {:.1f}).",
|
|
a.position[0], a.position[1], a.position[2]), ConsoleSeverity::success);
|
|
else emit(ConsoleSource::skater, "Local skater entity no longer available.");
|
|
}
|
|
if (!a.flow.empty() && a.flow != before.flow)
|
|
emit(ConsoleSource::flow, a.flow, a.flow == "InGame" ? ConsoleSeverity::success : ConsoleSeverity::info);
|
|
previous_ = a;
|
|
}
|
|
}
|