mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-20 00:35:22 +02:00
Changing a setting in the game's menu did not stick. The camera went
back to high on leaving the menu, grind assist and lean exit stayed at
20 / on, the compass and scoring ticker kept their old state, and the
Experimental tab's "reset to default" returned to whatever was set at
launch.
b763631 gave the settings hooks per-thread caches of saved values that
look a value up again only when profile::Store::changes() advances.
Only whole-profile commits advanced it. Every single save (a setting,
an option, an outfit) goes through Store::Update::commit(), which did
not, so the caches answered with launch-time values for the rest of
the session. native_setting_get also wrote the cached value back over
the new one when the two differed. The saves themselves reached the
database, so profiles are intact.
- Update::commit() advances the counter through Store::note_change(),
after value_ holds the new values and before the lock is released.
Store::commit() and the constructor use it too.
- A cache hit needs the whole key text, not the key's address and first
8 bytes. Many keys share those bytes (egf_enable..., egf_exp_...,
CRAS_HasSeen...Tab), so a reused address could answer for another
setting. Still no heap string, store lock or map walk on a hit.
- An outfit that is not loaded or not saved is logged as a warning with
its reason and preset (local_cosmetic_loadout_rejected). It was a
debug event, so a player's log never said why an outfit was refused.
Routine cases stay at debug.
- dingosdk_profile_change_tests (with the park editor tests): each kind
of save advances changes(), an unchanged save does not, and saved
values keep their types across a restart.
61 lines
2.9 KiB
C++
61 lines
2.9 KiB
C++
// The game's settings hooks cache saved values per thread and look them up again only when
|
|
// profile::Store::changes() advances, so every save that changes the profile must advance it.
|
|
// Runs on a scratch save it makes in the temporary folder.
|
|
#include "Extension/Profile/local_profile.h"
|
|
#include <iostream>
|
|
|
|
namespace {
|
|
int failures = 0;
|
|
void check(bool condition, const char* message) {
|
|
if (!condition) { std::cerr << "FAIL: " << message << '\n'; ++failures; }
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
using namespace dingosdk;
|
|
const auto folder = std::filesystem::temp_directory_path() / "reskate-profile-change-tests";
|
|
const auto save = folder / "reskate.sqlite3";
|
|
std::error_code error;
|
|
std::filesystem::remove_all(folder, error);
|
|
{
|
|
profile::Store store(save);
|
|
auto seen = profile::Store::changes();
|
|
const auto announced = [&] {
|
|
const auto now = profile::Store::changes();
|
|
const bool changed = now != seen;
|
|
seen = now;
|
|
return changed;
|
|
};
|
|
store.set_native_profile_option(2, "UseHighCam", true);
|
|
check(announced(), "a first native option save is announced");
|
|
store.set_native_profile_option(2, "UseHighCam", false);
|
|
check(announced() && store.native_profile_option(2, "UseHighCam") == Json(false),
|
|
"a changed native option is announced");
|
|
store.set_native_profile_option(2, "UseHighCam", false);
|
|
check(!announced(), "saving the same native option again announces nothing");
|
|
store.set_user_value("enableCompass", false);
|
|
check(announced() && store.user_value("enableCompass") == Json(false), "a Boolean setting save is announced");
|
|
store.set_user_value("grindAssist", 20.0);
|
|
check(announced() && store.user_value("grindAssist") == Json(20.0), "a number setting save is announced");
|
|
store.set_user_values({{"cameraMode", 2}, {"enableScoringTicker", false}});
|
|
check(announced(), "several settings saved together are announced");
|
|
store.set_bool_option("gp_use_high_cam", false);
|
|
check(announced(), "a profile option save is announced");
|
|
store.set_selected_cosmetic_preset(3);
|
|
check(announced(), "a save outside the settings is announced");
|
|
}
|
|
{
|
|
// A restart: the saved values and their types (a whole number saved as a float stays one).
|
|
profile::Store store(save);
|
|
const auto number = store.user_value("grindAssist");
|
|
check(store.native_profile_option(2, "UseHighCam") == Json(false) &&
|
|
store.user_value("enableCompass") == Json(false) && store.user_value("cameraMode") == Json(2) &&
|
|
number && number->is_number_float() && number->get<double>() == 20.0 &&
|
|
store.selected_cosmetic_preset() == 3, "saved settings come back after a restart");
|
|
}
|
|
std::filesystem::remove_all(folder, error);
|
|
if (failures) return 1;
|
|
std::cout << "profile changes: ok\n";
|
|
return 0;
|
|
}
|