Detect form type collisions automatically
This commit is contained in:
parent
4379f11539
commit
461405836d
@ -63,615 +63,6 @@ inline void CheckWorldspaces()
|
||||
}
|
||||
}
|
||||
|
||||
inline void CheckSkyrimCells()
|
||||
{
|
||||
// FormIDs of all Skyrim cells.
|
||||
// 9 of them are commented out, because they are cells in Enderal as well.
|
||||
|
||||
uint32_t formids[574] = {
|
||||
0x0004B8FB,
|
||||
0x000352C7,
|
||||
0x000161E7,
|
||||
0x00013A73,
|
||||
0x000BA599,
|
||||
0x00042BED,
|
||||
0x000361F9,
|
||||
0x00016A11,
|
||||
0x000152A1,
|
||||
0x0001523D,
|
||||
0x000A8B23,
|
||||
0x000918D3,
|
||||
0x0004761B,
|
||||
//0x0003CBCB,
|
||||
0x00016A07,
|
||||
0x00015233,
|
||||
0x000138CF,
|
||||
0x0009CCDD,
|
||||
0x0008B84D,
|
||||
0x0003EA9D,
|
||||
0x000198DD,
|
||||
0x000165B1,
|
||||
0x00015229,
|
||||
0x000D9DC7,
|
||||
0x000965B3,
|
||||
0x0006F3EB,
|
||||
0x000466CB,
|
||||
0x000165A7,
|
||||
0x00015283,
|
||||
0x000139E7,
|
||||
0x000EF325,
|
||||
0x000AD5A1,
|
||||
0x00016BDD,
|
||||
0x00015279,
|
||||
0x00015215,
|
||||
0x00013979,
|
||||
0x0007BEF7,
|
||||
0x0004E227,
|
||||
0x000240B7,
|
||||
0x00016BD3,
|
||||
0x00016787,
|
||||
0x0001526F,
|
||||
0x0005015D,
|
||||
0x0002E521,
|
||||
0x0001677D,
|
||||
0x00016205,
|
||||
0x00015265,
|
||||
0x00015201,
|
||||
0x00013901,
|
||||
0x0007BC27,
|
||||
0x0002D3E7,
|
||||
0x0001B147,
|
||||
0x0001A337,
|
||||
0x000196B7,
|
||||
0x000161FB,
|
||||
0x00013A87,
|
||||
0x00033779,
|
||||
0x0002D5D1,
|
||||
0x000161F1,
|
||||
0x00015251,
|
||||
0x00013A7D,
|
||||
//0x00030442,
|
||||
0x000152AA,
|
||||
0x00013A72,
|
||||
0x000571B4,
|
||||
0x00042BEC,
|
||||
0x00037EE0,
|
||||
0x00016A10,
|
||||
0x000152A0,
|
||||
0x0001523C,
|
||||
0x00013A68,
|
||||
0x00013810,
|
||||
0x0001DB4E,
|
||||
0x00016A06,
|
||||
0x00015296,
|
||||
0x000138CE,
|
||||
0x0001528C,
|
||||
0x000371DE,
|
||||
0x00036A72,
|
||||
0x000165A6,
|
||||
//0x00015282,
|
||||
0x00013856,
|
||||
0x000EF324,
|
||||
0x000EB440,
|
||||
0x0009B238,
|
||||
0x00081DEC,
|
||||
0x0007144C,
|
||||
0x0005DE24,
|
||||
0x000597D4,
|
||||
0x00016BDC,
|
||||
0x00013978,
|
||||
0x00065AB6,
|
||||
0x0001D09A,
|
||||
0x00016BD2,
|
||||
0x00016786,
|
||||
0x0001526E,
|
||||
0x0001520A,
|
||||
0x000139D2,
|
||||
0x000F39C4,
|
||||
0x000A9194,
|
||||
0x0005015C,
|
||||
0x00035604,
|
||||
0x00033D68,
|
||||
0x0001677C,
|
||||
0x00016204,
|
||||
0x00015200,
|
||||
0x000B6BE6,
|
||||
0x000A95D6,
|
||||
0x0009AA4A,
|
||||
0x0006C3B6,
|
||||
0x000152BE,
|
||||
0x000151F6,
|
||||
0x00013A86,
|
||||
0x0001382E,
|
||||
0x0001AB60,
|
||||
0x00019454,
|
||||
0x000161F0,
|
||||
0x000152B4,
|
||||
0x00013A7C,
|
||||
0x000F7631,
|
||||
0x00053081,
|
||||
0x000529DD,
|
||||
0x0003538D,
|
||||
0x00013A71,
|
||||
0x000138E1,
|
||||
0x001037E7,
|
||||
0x0005C483,
|
||||
0x00047817,
|
||||
0x00022F53,
|
||||
0x00016DF7,
|
||||
0x00016A0F,
|
||||
0x0001529F,
|
||||
0x00013A67,
|
||||
0x0001380F,
|
||||
0x00016A05,
|
||||
0x00015295,
|
||||
0x00015231,
|
||||
0x00013A5D,
|
||||
0x000138CD,
|
||||
0x0005B91B,
|
||||
0x000165AF,
|
||||
0x00015227,
|
||||
0x0001321F,
|
||||
0x0005D01D,
|
||||
0x000371DD,
|
||||
0x00025195,
|
||||
0x00016EA1,
|
||||
0x00015281,
|
||||
0x0007C98B,
|
||||
0x00052FEB,
|
||||
0x00028EDF,
|
||||
0x000243DF,
|
||||
0x0001F7B3,
|
||||
0x00016BDB,
|
||||
0x00015277,
|
||||
0x00065AB5,
|
||||
0x0005B5DD,
|
||||
0x0003B87D,
|
||||
0x0002D525,
|
||||
0x0002C779,
|
||||
0x00016BD1,
|
||||
0x00016785,
|
||||
0x0001526D,
|
||||
0x000139D1,
|
||||
0x00013909,
|
||||
//0x00000025,
|
||||
0x000AE783,
|
||||
0x000A0877,
|
||||
0x0006CCBB,
|
||||
0x000317E7,
|
||||
0x00016203,
|
||||
0x000A87C5,
|
||||
0x000A0359,
|
||||
0x000152BD,
|
||||
0x000151F5,
|
||||
0x00013A85,
|
||||
0x0001382D,
|
||||
0x00028ACF,
|
||||
0x0001AB5F,
|
||||
0x000161EF,
|
||||
0x00013A7B,
|
||||
0x000547F0,
|
||||
0x00021594,
|
||||
0x000213A0,
|
||||
0x00016E00,
|
||||
0x000152A8,
|
||||
0x00013818,
|
||||
0x00022F52,
|
||||
0x00016DF6,
|
||||
//0x00016A0E,
|
||||
0x00013A66,
|
||||
0x0001380E,
|
||||
0x000B64B4,
|
||||
0x00056E88,
|
||||
0x0001B7C0,
|
||||
0x00016A04,
|
||||
0x00015294,
|
||||
0x00015230,
|
||||
0x00013A5C,
|
||||
0x000138CC,
|
||||
0x00080C6A,
|
||||
0x0005A01A,
|
||||
0x0002031A,
|
||||
0x0001E11E,
|
||||
0x000165AE,
|
||||
0x0001528A,
|
||||
0x00015226,
|
||||
0x00075270,
|
||||
0x0003A184,
|
||||
0x00034B94,
|
||||
0x00015280,
|
||||
0x0001521C,
|
||||
0x00013A48,
|
||||
//0x0010CEEA,
|
||||
0x00016BDA,
|
||||
0x00015276,
|
||||
0x000DB070,
|
||||
0x0003DD34,
|
||||
0x0002D524,
|
||||
0x0002C778,
|
||||
0x0001CB84,
|
||||
0x00016BD0,
|
||||
0x00016784,
|
||||
0x0001526C,
|
||||
0x00015208,
|
||||
0x0001677A,
|
||||
0x00015262,
|
||||
0x00069858,
|
||||
0x00015258,
|
||||
0x000151F4,
|
||||
0x00013A84,
|
||||
0x000B29D6,
|
||||
0x000A6D8E,
|
||||
0x0008CDEE,
|
||||
0x00054D0E,
|
||||
0x000527F2,
|
||||
0x00027552,
|
||||
0x000193EE,
|
||||
0x000161EE,
|
||||
0x0001605E,
|
||||
0x00013A7A,
|
||||
0x000C9DAB,
|
||||
0x000A1793,
|
||||
0x00094BAB,
|
||||
//0x00030313,
|
||||
0x00016DFF,
|
||||
0x000152A7,
|
||||
0x0007FCDD,
|
||||
0x000414DD,
|
||||
0x000399D1,
|
||||
0x00016DF5,
|
||||
0x00016A0D,
|
||||
0x0001529D,
|
||||
0x00015239,
|
||||
0x00013871,
|
||||
0x000F2CAB,
|
||||
0x000A013B,
|
||||
0x0005A857,
|
||||
0x0001AEC3,
|
||||
0x00016A03,
|
||||
0x000165B7,
|
||||
0x0001522F,
|
||||
0x000138CB,
|
||||
0x00013867,
|
||||
0x000165AD,
|
||||
0x00056C1B,
|
||||
//0x000446BF,
|
||||
0x0004401B,
|
||||
0x0003A183,
|
||||
0x000263EF,
|
||||
0x000165A3,
|
||||
0x0001527F,
|
||||
0x0001521B,
|
||||
0x000AB531,
|
||||
0x00083559,
|
||||
0x0005912D,
|
||||
0x00016BD9,
|
||||
0x00015275,
|
||||
0x00015211,
|
||||
0x0003D62B,
|
||||
0x00016BCF,
|
||||
0x0001620B,
|
||||
0x0001526B,
|
||||
0x00015207,
|
||||
0x00013907,
|
||||
0x000A1BFD,
|
||||
0x00052CB5,
|
||||
0x00034B75,
|
||||
0x00016779,
|
||||
0x00015261,
|
||||
0x000EA28B,
|
||||
0x000BBB2F,
|
||||
0x000B1783,
|
||||
0x00079F9F,
|
||||
0x00039F67,
|
||||
0x0002BCD7,
|
||||
0x000270AB,
|
||||
0x000161F7,
|
||||
0x000152BB,
|
||||
0x00015257,
|
||||
0x000151F3,
|
||||
0x00013A83,
|
||||
0x000EEC55,
|
||||
0x000B29D5,
|
||||
0x000161ED,
|
||||
0x000152B1,
|
||||
0x00013A79,
|
||||
0x00016DFE,
|
||||
0x000133CA,
|
||||
0x0006DAA0,
|
||||
0x00052390,
|
||||
0x00016DF4,
|
||||
0x00016A0C,
|
||||
0x0001529C,
|
||||
0x00015238,
|
||||
0x00013870,
|
||||
//0x000B9BC6,
|
||||
0x0005A856,
|
||||
0x0002471A,
|
||||
0x000198E2,
|
||||
0x00016A02,
|
||||
0x000165B6,
|
||||
0x000138CA,
|
||||
0x00059398,
|
||||
0x0003E908,
|
||||
0x000165AC,
|
||||
0x00015288,
|
||||
0x00015224,
|
||||
0x000CAB92,
|
||||
0x0005F536,
|
||||
0x0002A976,
|
||||
0x00016D72,
|
||||
0x0001527E,
|
||||
0x000C7348,
|
||||
0x000AA20C,
|
||||
0x000A73F4,
|
||||
0x00095C44,
|
||||
0x0006E2AC,
|
||||
0x0005D010,
|
||||
0x00018BE0,
|
||||
0x00016BD8,
|
||||
0x0001678C,
|
||||
0x00015274,
|
||||
0x00015210,
|
||||
0x000C0BBA,
|
||||
0x000280C2,
|
||||
0x00016BCE,
|
||||
0x00016782,
|
||||
0x0001526A,
|
||||
0x00015206,
|
||||
0x000F5EDC,
|
||||
0x000ED8E0,
|
||||
0x0007DCFC,
|
||||
0x00018460,
|
||||
0x00016778,
|
||||
0x00016200,
|
||||
0x00015260,
|
||||
0x000151FC,
|
||||
0x00013A8C,
|
||||
0x0005554A,
|
||||
0x00054226,
|
||||
0x0003D35A,
|
||||
0x00037B76,
|
||||
0x000161F6,
|
||||
0x000152BA,
|
||||
0x000151F2,
|
||||
0x000B29D4,
|
||||
0x0003FF10,
|
||||
0x0002E760,
|
||||
0x000161EC,
|
||||
0x000152B0,
|
||||
0x00013A78,
|
||||
0x000ABD31,
|
||||
0x00055215,
|
||||
0x0002954D,
|
||||
0x00016DFD,
|
||||
0x000152A5,
|
||||
0x000133C9,
|
||||
0x0005EAC7,
|
||||
0x00058663,
|
||||
0x000336FB,
|
||||
0x00016DF3,
|
||||
0x00016A0B,
|
||||
0x00015237,
|
||||
0x00077289,
|
||||
0x00075669,
|
||||
//0x0002FD85,
|
||||
0x000165B5,
|
||||
0x0003FC8F,
|
||||
0x000165AB,
|
||||
0x00015223,
|
||||
0x000CAB91,
|
||||
0x00068B99,
|
||||
0x0004C6DD,
|
||||
0x00035299,
|
||||
0x00018BE9,
|
||||
0x0001527D,
|
||||
0x00043FAB,
|
||||
0x00016BD7,
|
||||
0x0001678B,
|
||||
0x00015273,
|
||||
0x000DEBCD,
|
||||
0x00078715,
|
||||
0x0001F359,
|
||||
0x00016781,
|
||||
0x00016209,
|
||||
0x00015269,
|
||||
0x0005B88B,
|
||||
0x0005723B,
|
||||
0x00016777,
|
||||
0x000161FF,
|
||||
0x000152C3,
|
||||
0x0001525F,
|
||||
0x000151FB,
|
||||
0x000A5A71,
|
||||
//0x000A1A61,
|
||||
0x000778F1,
|
||||
0x00045A1D,
|
||||
0x000161F5,
|
||||
0x00015255,
|
||||
0x00013A81,
|
||||
0x000EEC53,
|
||||
0x00081D5B,
|
||||
0x000161EB,
|
||||
0x000152AF,
|
||||
0x00054B70,
|
||||
0x0005258C,
|
||||
0x000471DC,
|
||||
0x0002954C,
|
||||
0x00016DFC,
|
||||
0x00013814,
|
||||
0x000133C8,
|
||||
0x000DBF12,
|
||||
0x000CCDAA,
|
||||
0x00091872,
|
||||
0x00036ED6,
|
||||
0x00016DF2,
|
||||
0x00034BA4,
|
||||
0x0002D4E4,
|
||||
0x00025E24,
|
||||
0x000198E0,
|
||||
0x00016A00,
|
||||
0x00015290,
|
||||
0x0001522C,
|
||||
0x0007947A,
|
||||
0x000165AA,
|
||||
0x00015286,
|
||||
0x000138BE,
|
||||
0x00087764,
|
||||
0x0003B698,
|
||||
0x000165A0,
|
||||
0x0001527C,
|
||||
0x00013850,
|
||||
0x0008E906,
|
||||
0x00071FFE,
|
||||
0x00016BD6,
|
||||
0x000C5AA0,
|
||||
0x0001F358,
|
||||
0x00016780,
|
||||
0x00015268,
|
||||
//0x0002F83E,
|
||||
0x0002529E,
|
||||
0x00016776,
|
||||
0x000161FE,
|
||||
0x000151FA,
|
||||
0x00013A8A,
|
||||
0x00078124,
|
||||
0x000362D8,
|
||||
0x00023FD4,
|
||||
0x0001FA4C,
|
||||
0x000161F4,
|
||||
0x00015254,
|
||||
0x00013A80,
|
||||
0x000BBCB2,
|
||||
0x000AC5D2,
|
||||
0x00081972,
|
||||
0x000261C6,
|
||||
0x000161EA,
|
||||
0x000152AE,
|
||||
0x00013A76,
|
||||
0x00054B6F,
|
||||
0x00032AE7,
|
||||
0x000216BB,
|
||||
0x00016DFB,
|
||||
0x0001523F,
|
||||
0x00013813,
|
||||
0x000133C7,
|
||||
0x00070469,
|
||||
0x00036ED5,
|
||||
0x00034955,
|
||||
0x00016A09,
|
||||
0x00015235,
|
||||
0x0009CCDF,
|
||||
0x0007B7AB,
|
||||
0x0002D4E3,
|
||||
0x000198DF,
|
||||
0x000165B3,
|
||||
0x00097299,
|
||||
0x00089D51,
|
||||
0x000681DD,
|
||||
0x00024771,
|
||||
0x000AF227,
|
||||
0x0007D033,
|
||||
0x00041777,
|
||||
0x00016BDF,
|
||||
0x0001527B,
|
||||
0x00058B4D,
|
||||
0x000275D9,
|
||||
0x000227B9,
|
||||
0x00016BD5,
|
||||
0x00016789,
|
||||
0x000FE47B,
|
||||
0x0001677F,
|
||||
0x00016207,
|
||||
0x00015267,
|
||||
0x001052FD,
|
||||
0x00104871,
|
||||
//0x0002F83D,
|
||||
0x00016775,
|
||||
0x000152C1,
|
||||
0x0001525D,
|
||||
0x000151F9,
|
||||
0x00013A89,
|
||||
0x000961FF,
|
||||
0x0007E00F,
|
||||
0x0004624F,
|
||||
0x000161F3,
|
||||
0x000152B7,
|
||||
0x00015253,
|
||||
0x00013A7F,
|
||||
0x000221B5,
|
||||
0x000161E9,
|
||||
0x000152AD,
|
||||
0x0009174E,
|
||||
0x0004A376,
|
||||
//0x000361FA,
|
||||
0x0002A03A,
|
||||
0x00016DFA,
|
||||
0x000152A2,
|
||||
0x00013812,
|
||||
0x000133C6,
|
||||
0x000DDF7C,
|
||||
0x000A8B24,
|
||||
0x00016A08,
|
||||
0x000138D0,
|
||||
0x0001386C,
|
||||
0x000BE46A,
|
||||
0x0009CCDE,
|
||||
//0x0007284E,
|
||||
0x00067F2A,
|
||||
//0x0003016A,
|
||||
0x000198DE,
|
||||
0x000169FE,
|
||||
0x000165B2,
|
||||
0x0001522A,
|
||||
0x00097298,
|
||||
0x0007614C,
|
||||
0x000165A8,
|
||||
0x00015284,
|
||||
0x00015220,
|
||||
0x000DD216,
|
||||
0x000563E2,
|
||||
0x00050F1E,
|
||||
0x0003F516,
|
||||
0x0003B696,
|
||||
0x00037CC6,
|
||||
0x0003486E,
|
||||
0x0001FC66,
|
||||
0x00016BDE,
|
||||
0x0007BEF8,
|
||||
0x00058B4C,
|
||||
0x00034864,
|
||||
0x000275D8,
|
||||
0x00016BD4,
|
||||
0x00016788,
|
||||
0x0001677E,
|
||||
0x0001383A,
|
||||
0x0002D3E8,
|
||||
0x00016774,
|
||||
0x000161FC,
|
||||
0x000152C0,
|
||||
0x0001525C,
|
||||
0x00013A88,
|
||||
0x00094322,
|
||||
0x000580A2,
|
||||
0x00027F1A,
|
||||
0x0001CE8A,
|
||||
0x00013A7E,
|
||||
0x00039850,
|
||||
0x00027D1C
|
||||
};
|
||||
|
||||
for (int i = 0; i < 574; i++) {
|
||||
const auto* form = RE::TESForm::LookupByID(formids[i]);
|
||||
if (form && form->Is(RE::FormType::Cell)) {
|
||||
logger::warn("Detected invalid cell: {:08X}", formids[i]);
|
||||
NotifyInvalidForm(form);
|
||||
}
|
||||
}
|
||||
|
||||
//memset(formids, 0, sizeof(formids));
|
||||
}
|
||||
|
||||
inline void CheckCCMods()
|
||||
{
|
||||
std::string filenames[73] = {
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "Patches/ForceBorderless.h"
|
||||
#include "Patches/AttachLightHitEffectCrash.h"
|
||||
#include "Patches/PluginsTxtPatch.h"
|
||||
#include "Patches/FormTypeCollisionDetector.h"
|
||||
|
||||
using namespace SKSE;
|
||||
|
||||
@ -133,7 +134,10 @@ namespace {
|
||||
RE::DebugMessageBox("E - Meshes.bsa is not loaded. Make sure Enderal - Forgotten Stories.esm is enabled and revalidate your files.");
|
||||
}
|
||||
|
||||
CheckIncompatibleMods();
|
||||
// Show any form type collision warnings collected during loading
|
||||
if (!FormTypeCollisionDetector::ShowCollisionWarning()) {
|
||||
CheckIncompatibleMods();
|
||||
}
|
||||
});
|
||||
} else if ((message->type == MessagingInterface::kPostLoadGame && message->data) || message->type == MessagingInterface::kNewGame) {
|
||||
NewGameCount(true);
|
||||
@ -186,6 +190,7 @@ SKSEPluginLoad(const LoadInterface* skse) {
|
||||
|
||||
Init(skse);
|
||||
InitializeMessaging();
|
||||
FormTypeCollisionDetector::Install();
|
||||
PluginsTxtPatch::Install();
|
||||
|
||||
RE::INISettingCollection::GetSingleton()->GetSetting("sIntroSequence:General")->data.s = nullptr;
|
||||
|
||||
143
source/Enderal DLL/src/Patches/FormTypeCollisionDetector.h
Normal file
143
source/Enderal DLL/src/Patches/FormTypeCollisionDetector.h
Normal file
@ -0,0 +1,143 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
|
||||
// Detects when a plugin overrides an existing form with a different type
|
||||
// This catches Skyrim mods that conflict with Enderal's repurposed form IDs
|
||||
//
|
||||
// Enderal modifies Skyrim.esm to repurpose many forms with different types.
|
||||
// For example, a Skyrim CELL might become an NPC in Enderal.
|
||||
// When a Skyrim mod loads, it may try to load form data expecting the original
|
||||
// Skyrim type, causing a type mismatch. The game silently skips these, but
|
||||
// this detector logs them to help users identify incompatible mods.
|
||||
namespace FormTypeCollisionDetector
|
||||
{
|
||||
inline std::unordered_set<std::string> flaggedMods;
|
||||
inline bool messageShown = false;
|
||||
|
||||
// Track collisions during loading
|
||||
struct CollisionInfo
|
||||
{
|
||||
RE::FormID formID;
|
||||
RE::FormType existingType;
|
||||
RE::FormType incomingType;
|
||||
std::string modName;
|
||||
};
|
||||
inline std::vector<CollisionInfo> detectedCollisions;
|
||||
|
||||
inline void NotifyCollision(RE::FormID formID, RE::FormType existingType, RE::FormType incomingType, const char* modName)
|
||||
{
|
||||
logger::error("Type collision: {:08X} is {} but {} tries to load it as {}",
|
||||
formID,
|
||||
RE::FormTypeToString(existingType),
|
||||
modName,
|
||||
RE::FormTypeToString(incomingType));
|
||||
|
||||
detectedCollisions.push_back({ formID, existingType, incomingType, modName });
|
||||
|
||||
if (!flaggedMods.contains(modName)) {
|
||||
flaggedMods.insert(modName);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool ShowCollisionWarning()
|
||||
{
|
||||
if (detectedCollisions.empty()) {
|
||||
logger::info("No form type collisions detected");
|
||||
return false;
|
||||
}
|
||||
|
||||
logger::warn("Detected {} form type collision(s) from {} mod(s)",
|
||||
detectedCollisions.size(), flaggedMods.size());
|
||||
|
||||
// Print to console
|
||||
if (auto* console = RE::ConsoleLog::GetSingleton()) {
|
||||
for (const auto& mod : flaggedMods) {
|
||||
console->Print(std::format("{} causes form type collisions (incompatible with Enderal)", mod).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Show message box for first mod only
|
||||
if (!messageShown && !flaggedMods.empty()) {
|
||||
messageShown = true;
|
||||
auto firstMod = *flaggedMods.begin();
|
||||
std::string message = std::format(
|
||||
"{} is incompatible with Enderal (form type collision).\n"
|
||||
"Check console for details.", firstMod);
|
||||
|
||||
if (flaggedMods.size() > 1) {
|
||||
message = std::format(
|
||||
"{} and {} other mod(s) are incompatible with Enderal.\n"
|
||||
"Check console for details.",
|
||||
firstMod, flaggedMods.size() - 1);
|
||||
}
|
||||
|
||||
RE::DebugMessageBox(message.c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Helper template for thunk-style call hooks (from po3-Tweaks)
|
||||
template <class T, std::size_t N = 5>
|
||||
void write_thunk_call(std::uintptr_t a_src)
|
||||
{
|
||||
SKSE::AllocTrampoline(14);
|
||||
auto& trampoline = SKSE::GetTrampoline();
|
||||
T::func = trampoline.write_call<N>(a_src, T::thunk);
|
||||
}
|
||||
|
||||
struct LoadFormFromFile
|
||||
{
|
||||
static inline bool firstLog = true;
|
||||
|
||||
static bool thunk(void* a_dataHandler, RE::TESFile* a_file, char a_flags, RE::TESForm* a_existingForm, std::int32_t a_unk)
|
||||
{
|
||||
// Check for type collisions before calling original
|
||||
if (a_file) {
|
||||
RE::FormID formID = a_file->currentform.formID;
|
||||
RE::FormType incomingType = a_file->GetFormType();
|
||||
|
||||
// Log first few calls for debugging
|
||||
if (firstLog) {
|
||||
logger::info("FormTypeCollisionDetector: First form from {} - ID {:08X}, type {}",
|
||||
a_file->fileName, formID, RE::FormTypeToString(incomingType));
|
||||
firstLog = false;
|
||||
}
|
||||
|
||||
// Only check Skyrim.esm forms (mod index 0 in the file)
|
||||
std::uint8_t modIndex = (formID >> 24) & 0xFF;
|
||||
|
||||
if (modIndex == 0 && formID != 0) {
|
||||
// Look up existing form
|
||||
auto* existingForm = a_existingForm ? a_existingForm : RE::TESForm::LookupByID(formID);
|
||||
|
||||
if (existingForm && existingForm->GetFormType() != incomingType) {
|
||||
// Type mismatch detected!
|
||||
const char* modName = a_file->fileName;
|
||||
NotifyCollision(formID, existingForm->GetFormType(), incomingType, modName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return func(a_dataHandler, a_file, a_flags, a_existingForm, a_unk);
|
||||
}
|
||||
|
||||
static inline REL::Relocation<decltype(thunk)> func;
|
||||
};
|
||||
}
|
||||
|
||||
inline void Install()
|
||||
{
|
||||
// Hook call to form loading function in the main loading loop
|
||||
// SE: ID 13652 (0x1700E0), call at offset 0x19D to sub_1401703F0
|
||||
// AE: ID 13760 (0x1BB6C0), call at offset 0x271 to sub_1401BBAA0
|
||||
REL::Relocation<std::uintptr_t> target{ REL::RelocationID(13652, 13760), REL::VariantOffset(0x19D, 0x271, 0) };
|
||||
detail::write_thunk_call<detail::LoadFormFromFile>(target.address());
|
||||
|
||||
logger::info("Form type collision detector installed at {:X}", target.address());
|
||||
}
|
||||
}
|
||||
@ -53,7 +53,6 @@ inline void CheckIncompatibleMods()
|
||||
|
||||
CheckWorldspaces();
|
||||
CheckUnconvertedMap();
|
||||
CheckSkyrimCells();
|
||||
}
|
||||
|
||||
inline bool PapyrusGlobalFunctionExists(const char* scriptName, const char* funcName)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user