mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-27 19:47:08 +01:00
Crashes: the Trainer no longer writes into freed memory, throwdown models go before a level unload, and a gone texture draws nothing instead of crashing
From the first 6k Sentry reports of 55a7342 (2026-10-24), whose top sites were all new since 2.1.1:
- Trainer: scale_underflip_bands wrote the underflip rate bands' MinScale and MaxScale every tick on
every copy it had ever found, checking only that the address was readable. A level's copies go back
to the game's heap with it, so 1.0 and 0.6 landed in the upper half of whatever the game made there
next (Skate.exe+0x157f930, +0x12a1549, +0x10084de, +0x11ef49e, +0x3db81ea, +0x12c21ca: about a
third of the crashes, every dump with a pointer whose high dword is one of those floats). A copy is
now written only while it still is that band and holds the game's band or the last one written;
any other is forgotten.
- Throwdowns: models the page released were destroyed 3 s later by the menu tick, which does not run
while a level loads, so the game's own flush of the unloaded level's types destroyed them after
their assets were freed (Skate.exe+0x3dc5eaa, 18%). Before a level unload they are destroyed at
once, as the native menu's own are.
- Textures: the guard's "default for the id" is the entry itself, so for a dead entry resolve gave a
null texture, and the texture view cache asked it for its key (Skate.exe+0x3e6ddc1, 17%, every
report with TheVlixOne-Nike_Pack). A stub at the cache insert hands back the empty view the cache
already built when the texture is null; the guard is on only when that patch applies.
- Physics: the wake guard widens every pass because ReSkate raises the owner pool to 160000; its log
line now says so once instead of claiming a prevented crash thousands of times a session.
Built; not yet checked in the game.
This commit is contained in:
1 parent
55a7342dc6
commit
7dabd99a40
9 files changed
+142
-23
No files matched your search
@@ -2276,14 +2276,28 @@ void prepare_native_throwdown_match_panel() noexcept {
|
||||
"Throwdowns: native Details presentation preparation deferred: {}",e.what());
|
||||
}
|
||||
}
|
||||
bool release_native_throwdown_menu(std::uintptr_t base) noexcept {
|
||||
bool release_native_throwdown_menu(std::uintptr_t base,bool before_unload) noexcept {
|
||||
overlay::capture_challenge_menu_input(false);
|
||||
sync_custom_activity_ui_presence(false);
|
||||
auto& s=state(); if(s.owned.empty()) { s.owner.store(0); s.setup_open.store(false); return true; }
|
||||
auto& s=state(); if(s.owned.empty() && (!before_unload || s.doomed.empty())) { s.owner.store(0); s.setup_open.store(false); return true; }
|
||||
try { const auto ui=read<Address>(base+build::engine::ui_manager); const auto manager=ui?read<Address>(ui+0x140):0;
|
||||
require(manager!=0,"Throwdowns UI manager unavailable during cleanup.");
|
||||
if(manager!=s.manager) { forget_manager(); return true; }
|
||||
const Context c(base,manager); game::ModelWriteLock lock(manager); release(c); s.generations.clear(); return true;
|
||||
const Context c(base,manager); game::ModelWriteLock lock(manager);
|
||||
if(!s.owned.empty()) { release(c); s.generations.clear(); }
|
||||
else { s.owner.store(0); s.setup_open.store(false); }
|
||||
// Before a level unload the released models go now, not 3 s later: the tick does not run while
|
||||
// the level loads, and the game's own flush of the unloaded level's types destroyed them after
|
||||
// the assets they name were freed (Skate.exe+0x3dc5eaa, the most reported crash of 55a7342;
|
||||
// 2026-10-24). The native menu's own models go the same way (native_menu.cpp).
|
||||
if(before_unload && !s.doomed.empty()) {
|
||||
logging::log(logging::Level::info,logging::Channel::ui,
|
||||
"Throwdowns: {} released native model(s) destroyed before the level unload.",s.doomed.size());
|
||||
for(const auto& entry:s.doomed)
|
||||
if(c.type_of(entry.first.handle)==entry.first.type)c.destroy(entry.first);
|
||||
s.doomed.clear();
|
||||
}
|
||||
return true;
|
||||
} catch(const std::exception& e) { logging::log(logging::Level::warning,logging::Channel::ui,"Throwdowns native menu cleanup: {}",e.what()); return false; }
|
||||
}
|
||||
// A document prompt's input pressed while its prompt shows: the plugin hears panel_command.
|
||||
@@ -2410,7 +2424,7 @@ void tick_native_throwdown_menu(std::uintptr_t base,bool loading,bool in_menu) n
|
||||
gameplay_hud(c,now);
|
||||
} catch(const std::exception& e) {
|
||||
logging::log(logging::Level::warning,logging::Channel::ui,"Throwdowns native menu: {}",e.what());
|
||||
s.next_tick=now+5000; release_native_throwdown_menu(base);
|
||||
s.next_tick=now+5000; release_native_throwdown_menu(base,false);
|
||||
}
|
||||
}
|
||||
} // namespace dingosdk::multiplayer
|
||||
Reference in new issue
Block a user