mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-17 18:37:07 +02:00
180 lines
8.7 KiB
C++
180 lines
8.7 KiB
C++
#pragma once
|
|
#include "request_scheduler.h"
|
|
#include "Engine/Core/Console/console_activity.h"
|
|
#include "Engine/Core/Platform/memory.h"
|
|
#include "Engine/Game/Build/addresses.h"
|
|
#include "Engine/Game/Build/20260929/engine.h"
|
|
#include "Engine/Game/Build/20260929/runtime.h"
|
|
#include "Engine/Game/Input/controller_bindings.h"
|
|
#include "Engine/Game/Settings/named_settings.h"
|
|
#include "Engine/Game/World/custom_level_manifest.h"
|
|
#include "Engine/Game/World/world_model.h"
|
|
#include "Extension/Multiplayer/Session/session.h"
|
|
#include "Extension/UI/Overlay/overlay.h"
|
|
#include <Windows.h>
|
|
#include <array>
|
|
#include <atomic>
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <vector>
|
|
|
|
namespace dingosdk {
|
|
struct SkaterSlotOverrideObservation;
|
|
struct MainMissionOverrideObservation;
|
|
struct FixedStopEntitlementProviderObservation;
|
|
struct NeighborhoodUnlockOverrideObservation;
|
|
}
|
|
|
|
// Shared by the runtime's translation units only. Everything here runs inside
|
|
// the one Runtime instance guarded by Runtime::mutex.
|
|
namespace dingosdk::runtime::detail {
|
|
namespace engine = dingosdk::addr::engine;
|
|
namespace rt = dingosdk::addr::runtime;
|
|
inline constexpr std::uintptr_t highest = memory::highest_user_address;
|
|
using memory::read;
|
|
using Tick = void (*)(std::uintptr_t, std::uintptr_t);
|
|
using Request = dingosdk::runtime::LoadRequest;
|
|
using ConsoleRequest = dingosdk::runtime::ConsoleRequest;
|
|
|
|
using NamedSettings = std::vector<dingosdk::NamedSettingModel>;
|
|
struct Runtime {
|
|
std::uintptr_t base{};
|
|
Tick original_tick{};
|
|
std::mutex mutex;
|
|
dingosdk::overlay::Model model;
|
|
dingosdk::runtime::RequestScheduler requests;
|
|
dingosdk::overlay::DebugModel debug_model;
|
|
dingosdk::overlay::OfflineFeatureModel offline_model;
|
|
// Increased under the mutex with every write of model, debug_model and
|
|
// offline_model: readers holding a copy skip the parts that have not changed.
|
|
std::uint64_t model_revision{1}, debug_revision{1}, offline_revision{1};
|
|
// Engine settings as the menu and console last received them: an immutable
|
|
// snapshot (thousands of rows) that readers copy outside the mutex. Its
|
|
// revision is named_settings_revision() at publication.
|
|
std::shared_ptr<const NamedSettings> named_settings;
|
|
std::uint64_t named_settings_revision{};
|
|
// Game thread only: the previous snapshot, refilled in place once no reader holds it.
|
|
std::shared_ptr<NamedSettings> named_settings_spare;
|
|
ULONGLONG next_named_settings_publish{};
|
|
// Set by the overlay while it shows the menu or console: until then the game
|
|
// thread refreshes engine settings quickly and publishes them.
|
|
std::atomic<ULONGLONG> named_settings_wanted_until{};
|
|
bool named_context_ready{};
|
|
dingosdk::CustomLevelManifest custom_levels;
|
|
// Patch/reskate-levels.json beside the DLL and under the data root, read after the mods'.
|
|
std::vector<std::filesystem::path> patch_level_manifests;
|
|
ULONGLONG next_debug{}, flight_unavailable_since{};
|
|
std::string flight_unavailable_issue, flight_unavailable_logged;
|
|
dingosdk::ControllerComboLatch noclip_bind_latch;
|
|
dingosdk::ControllerComboLatch forward_velocity_bind_latch;
|
|
dingosdk::ControllerComboLatch up_velocity_bind_latch;
|
|
ULONGLONG next_offline{};
|
|
bool transition_seen{}, initialized{}, catalog_logged{},
|
|
native_tick_ready{}, native_loading_logging{}, fixed_stop_entitlement_route_ready{}, menu_load_queued{}, startup_load_queued{};
|
|
std::atomic<bool> menu_splash_ready{};
|
|
std::atomic<bool> observer_failed{};
|
|
// Refreshed with the 500 ms world model; the spectate camera reads it every tick.
|
|
bool spectate_ready{};
|
|
std::uintptr_t spectate_client{};
|
|
std::atomic<DWORD> engine_thread{};
|
|
DWORD previous_state{~DWORD{0}}, requested_from{13};
|
|
ULONGLONG next_model{}, request_started{};
|
|
std::string last_request, last_start, last_lm_level, last_lm_start, last_level, load_result, last_sublevels;
|
|
std::string multiplayer_map;
|
|
// Game thread only. The native level registry changes only with a mod apply
|
|
// or a level load, and the server's sublevels settle during loads: both are
|
|
// read again then, and otherwise at a slower pace than the 500 ms model.
|
|
std::optional<dingosdk::WorldCatalog> native_catalog;
|
|
std::optional<dingosdk::SublevelCatalog> sublevel_catalog;
|
|
std::string catalog_level;
|
|
ULONGLONG next_catalog_read{}, next_sublevel_read{};
|
|
std::atomic<bool> overlay_confirmed{false};
|
|
std::string last_readiness, last_client_content, last_gameplay_settings_override_observation,
|
|
last_skater_slot_override_observation,
|
|
last_main_mission_override_observation,
|
|
last_fixed_stop_entitlement_provider_observation,
|
|
last_neighborhood_unlock_override_observation;
|
|
std::uint64_t console_delivered_sequence{}; // Single, serialized overlay reader.
|
|
dingosdk::ConsoleActivityFeed console_activity;
|
|
};
|
|
Runtime& runtime();
|
|
dingosdk::CustomLevelManifest read_custom_levels(const std::vector<std::filesystem::path>& mod_manifests);
|
|
dingosdk::runtime::RequestContext request_context(const Runtime& value);
|
|
// Game thread: hands the menu and console the current engine settings, if they
|
|
// changed since the last snapshot (runtime_state.cpp).
|
|
void publish_named_settings(Runtime& value);
|
|
struct ScheduledWorkScope {
|
|
Runtime& value;
|
|
bool active;
|
|
~ScheduledWorkScope() {
|
|
if (active) { std::lock_guard lock(value.mutex); value.requests.finish_work(); }
|
|
}
|
|
};
|
|
|
|
template<std::size_t N> bool matches(std::uintptr_t address, const std::array<unsigned char, N>& expected) {
|
|
std::array<unsigned char, N> actual{};
|
|
return read(address, actual) && actual == expected;
|
|
}
|
|
void record(const std::string& json);
|
|
void console_line(std::string_view text);
|
|
void activity_line(dingosdk::ConsoleSource source, std::string_view text,
|
|
dingosdk::ConsoleSeverity severity = dingosdk::ConsoleSeverity::info);
|
|
bool equals(std::string a, std::string b);
|
|
|
|
// Offline feature model assembly (runtime_state.cpp).
|
|
void merge_skater_slot_observation(
|
|
dingosdk::overlay::OfflineFeatureModel& model,
|
|
const dingosdk::SkaterSlotOverrideObservation& slots);
|
|
void merge_main_mission_observation(
|
|
dingosdk::overlay::OfflineFeatureModel& model,
|
|
const dingosdk::MainMissionOverrideObservation& missions);
|
|
void merge_progression_provider_observations(
|
|
dingosdk::overlay::OfflineFeatureModel& model,
|
|
const dingosdk::FixedStopEntitlementProviderObservation& fixed_stops,
|
|
const dingosdk::NeighborhoodUnlockOverrideObservation& neighborhoods,
|
|
bool fixed_stop_route_ready);
|
|
|
|
// Native client reads (client_context.cpp).
|
|
struct ClientContent {
|
|
bool sublevels_available{}, requested_sublevel_present{}, player_manager_present{}, players_available{};
|
|
std::uint32_t sublevel_count{}, local_player_count{}, controllable_reference_count{};
|
|
};
|
|
ClientContent read_client_content(std::uintptr_t base, std::uintptr_t client, const std::string& requested);
|
|
bool native_context(std::uintptr_t base, std::uintptr_t client, DWORD game_type);
|
|
|
|
// Game update thread (client_tick.cpp).
|
|
void tick(std::uintptr_t client, std::uintptr_t update);
|
|
|
|
// Level requests (level_requests.cpp).
|
|
bool registered_request(const dingosdk::WorldCatalog& catalog, const Request& request);
|
|
void submit_local(std::uintptr_t base, std::uintptr_t client, const Request& request, std::uint8_t flag);
|
|
dingosdk::multiplayer::MapLoadResult load_multiplayer_map(std::string_view destination, bool submitted,
|
|
std::string& detail);
|
|
bool queue_load(void*, const char* asset, const char* start, const char* lm_level, const char* lm_start,
|
|
char* result, std::size_t size);
|
|
bool queue_location_travel(const char* map);
|
|
bool queue_menu_bam();
|
|
|
|
// Overlay and native menu callbacks (overlay_callbacks.cpp).
|
|
void read_model(void*, dingosdk::overlay::Model& output);
|
|
void read_native_menu_model(void*, dingosdk::overlay::Model& output);
|
|
bool queue_debug(void*, const dingosdk::overlay::DebugRequest& request, char* result, std::size_t size);
|
|
bool queue_offline_feature(void*, const dingosdk::overlay::OfflineFeatureRequest& request,
|
|
char* result, std::size_t size);
|
|
bool queue_multiplayer_command(const char* action, const char* argument, const char* password,
|
|
char* result, std::size_t size);
|
|
bool queue_console_command(void*, const char* command, char* result, std::size_t size);
|
|
|
|
// Scheduled console commands (console_bridge.cpp).
|
|
void execute_console_command(const std::string& command);
|
|
|
|
// Main-menu expression hook (menu_entry_hook.cpp).
|
|
void observe_player_card_expression(std::uintptr_t graph, std::uintptr_t runtime_graph, void** inputs);
|
|
void start_menu_entry();
|
|
void start_frame_timing();
|
|
}
|