Skip to content

Commit

Permalink
Fix unsafe VFE-Core GetHashCode calls (#427)
Browse files Browse the repository at this point in the history
Biomes! Core had the same issue until its special terrain got a rework.
  • Loading branch information
SokyranTheDragon authored Feb 8, 2024
1 parent f310845 commit b2ed542
Showing 1 changed file with 27 additions and 1 deletion.
28 changes: 27 additions & 1 deletion Source/Mods/VanillaExpandedFramework.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public VanillaExpandedFramework(ModContentPack mod)
(PatchVanillaGenesExpanded, "Vanilla Genes Expanded", false),
(PatchVanillaCookingExpanded, "Vanilla Cooking Expanded", true),
(PatchDoorTeleporter, "Teleporter Doors", true),
(PatchSpecialTerrain, "Special Terrain", false),
(PatchSpecialTerrain, "Special Terrain", true),
(PatchWeatherOverlayEffects, "Weather Overlay Effects", false),
(PatchExtraPregnancyApproaches, "Extra Pregnancy Approaches", false),
(PatchWorkGiverDeliverResources, "Building stuff requiring non-construction skill", false),
Expand Down Expand Up @@ -1079,10 +1079,22 @@ private static void SyncDialogRenameDoorTeleporter(SyncWorker sync, ref Dialog_R

#region Special Terrain

private static Type terrainCompType;
private static AccessTools.FieldRef<object, object> terrainCompParentField;
private static AccessTools.FieldRef<object, IntVec3> terrainInstancePositionField;

private static void PatchSpecialTerrain()
{
MpCompat.harmony.Patch(AccessTools.DeclaredMethod("VFECore.SpecialTerrainList:TerrainUpdate"),
prefix: new HarmonyMethod(typeof(VanillaExpandedFramework), nameof(RemoveTerrainUpdateTimeBudget)));

// Fix unsafe GetHashCode call
terrainCompType = AccessTools.TypeByName("VFECore.TerrainComp");
terrainCompParentField = AccessTools.FieldRefAccess<object>(terrainCompType, "parent");
terrainInstancePositionField = AccessTools.FieldRefAccess<IntVec3>("VFECore.TerrainInstance:positionInt");

MpCompat.harmony.Patch(AccessTools.DeclaredMethod("VFECore.ActiveTerrainUtility:HashCodeToMod"),
prefix: new HarmonyMethod(MpMethodUtil.MethodOf(SaferGetHashCode)));
}

private static void RemoveTerrainUpdateTimeBudget(ref long timeBudget)
Expand All @@ -1095,6 +1107,20 @@ private static void RemoveTerrainUpdateTimeBudget(ref long timeBudget)
// base it around amount of terrain updates per tick, instead of basing it on actual time.
}

private static void SaferGetHashCode(ref object obj)
{
if (!MP.IsInMultiplayer || obj is IntVec3)
return;
if (terrainCompType.IsInstanceOfType(obj))
{
// Use parent IntVec3 position, since it'll be safe to call GetHashCode on
obj = terrainInstancePositionField(terrainCompParentField(obj));
return;
}

Log.ErrorOnce($"Potentially unsupported type for HashCodeToMod call in Multiplayer, desyncs likely to happen. Object type: {obj.GetType()}", obj.GetHashCode());
}

#endregion

#region Patch Weather Overlay Effects
Expand Down

0 comments on commit b2ed542

Please sign in to comment.