mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-10-21 10:51:32 -04:00
Fix anchor issues (#7362)
Avoid use-after-free with dummy players, Sync silver rupees, sync autoplanted beans
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include "soh/Enhancements/randomizer/fishsanity.h"
|
||||
#include "soh/Enhancements/randomizer/static_data.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/SohGui/ImGuiUtils.h"
|
||||
#include "soh/Notification/Notification.h"
|
||||
#include "soh/SaveManager.h"
|
||||
@@ -478,6 +479,9 @@ static void PlantAllBeans() {
|
||||
gSaveContext.sceneFlags[patch.scene].swch |= 1 << patch.swchFlag;
|
||||
if (gPlayState->sceneNum == patch.scene) {
|
||||
Flags_SetSwitch(gPlayState, patch.swchFlag);
|
||||
} else {
|
||||
// Flags_SetSwitch fires this for the current scene, other scenes need it so Anchor syncs them
|
||||
GameInteractor_ExecuteOnSceneFlagSet(patch.scene, FLAG_SCENE_SWITCH, patch.swchFlag);
|
||||
}
|
||||
}
|
||||
ObjBean* bean = (ObjBean*)Actor_Find(&gPlayState->actorCtx, ACTOR_OBJ_BEAN, ACTORCAT_BG);
|
||||
|
||||
@@ -254,4 +254,10 @@ void DummyPlayer_Destroy(Actor* actor, PlayState* play) {
|
||||
// asserts. Set the id back to ACTOR_PLAYER so that `numLoaded` will be decremented
|
||||
// correctly.
|
||||
actor->id = ACTOR_PLAYER;
|
||||
|
||||
// Drop client's pointer so packet handlers don't use after free
|
||||
uint32_t clientId = Anchor::Instance->GetDummyPlayerClientId(actor);
|
||||
if (Anchor::Instance->clients.contains(clientId) && Anchor::Instance->clients[clientId].player == (Player*)actor) {
|
||||
Anchor::Instance->clients[clientId].player = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,18 +104,50 @@ inline void from_json(const json& j, SohStats& sohStats) {
|
||||
j.at("fileCreatedAt").get_to(sohStats.fileCreatedAt);
|
||||
}
|
||||
|
||||
#define SILVER_RUPEE_FIELDS(X) \
|
||||
X(silverShadowBlades) \
|
||||
X(silverShadowPit) \
|
||||
X(silverShadowSpikes) \
|
||||
X(silverSpiritChild) \
|
||||
X(silverSpiritSun) \
|
||||
X(silverSpiritBoulders) \
|
||||
X(silverBotw) \
|
||||
X(silverIceCavernBlades) \
|
||||
X(silverIceCavernBlock) \
|
||||
X(silverGtgSlope) \
|
||||
X(silverGtgLava) \
|
||||
X(silverGtgWater) \
|
||||
X(silverGanonLight) \
|
||||
X(silverGanonForest) \
|
||||
X(silverGanonFire) \
|
||||
X(silverGanonSpirit) \
|
||||
X(silverMqDodongosCavern) \
|
||||
X(silverMqShadowInvisibleBlades) \
|
||||
X(silverMqSpiritLobby) \
|
||||
X(silverMqSpiritBigWall) \
|
||||
X(silverMqGanonWater) \
|
||||
X(silverMqGanonShadow)
|
||||
|
||||
inline void to_json(json& j, const ShipRandomizerSaveContextData& shipRandomizerSaveContextData) {
|
||||
j = json{
|
||||
{ "triforcePiecesCollected", shipRandomizerSaveContextData.triforcePiecesCollected },
|
||||
{ "bombchuUpgradeLevel", shipRandomizerSaveContextData.bombchuUpgradeLevel },
|
||||
};
|
||||
#define SILVER_TO_JSON(field) j[#field] = shipRandomizerSaveContextData.field;
|
||||
SILVER_RUPEE_FIELDS(SILVER_TO_JSON)
|
||||
#undef SILVER_TO_JSON
|
||||
}
|
||||
|
||||
inline void from_json(const json& j, ShipRandomizerSaveContextData& shipRandomizerSaveContextData) {
|
||||
j.at("triforcePiecesCollected").get_to(shipRandomizerSaveContextData.triforcePiecesCollected);
|
||||
j.at("bombchuUpgradeLevel").get_to(shipRandomizerSaveContextData.bombchuUpgradeLevel);
|
||||
#define SILVER_FROM_JSON(field) shipRandomizerSaveContextData.field = j.value(#field, (s8)0);
|
||||
SILVER_RUPEE_FIELDS(SILVER_FROM_JSON)
|
||||
#undef SILVER_FROM_JSON
|
||||
}
|
||||
|
||||
#undef SILVER_RUPEE_FIELDS
|
||||
|
||||
inline void to_json(json& j, const ShipQuestSpecificSaveContextData& shipQuestSpecificSaveContextData) {
|
||||
j = json{
|
||||
{ "randomizer", shipQuestSpecificSaveContextData.randomizer },
|
||||
|
||||
Reference in New Issue
Block a user