Skip to content

Commit

Permalink
plugin versioning more like sfse
Browse files Browse the repository at this point in the history
  • Loading branch information
ianpatt committed Apr 30, 2024
1 parent d3173ef commit 8f8d220
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 18 deletions.
25 changes: 19 additions & 6 deletions f4se/PluginAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,16 +288,20 @@ struct F4SEPluginVersionData

enum
{
// set this if you are using a post-1.10.980 version of the Address Library
kVersionIndependent_AddressLibraryPost1_10_980 = 1 << 0,
// set this if you exclusively use signature matching to find your addresses and have NO HARDCODED ADDRESSES
kVersionIndependent_Signatures = 1 << 1,
kAddressIndependence_Signatures = 1 << 0,

// set this if you are using a 1.10.980+ version of the Address Library
kAddressIndependence_AddressLibrary_1_10_980 = 1 << 1,
};

enum
{
// set this if your plugin doesn't use any game structures
kVersionIndependentEx_NoStructUse = 1 << 0,
kStructureIndependence_NoStructs = 1 << 0,

// works with the structure layout in 1.10.980+
kStructureIndependence_1_10_980Layout = 1 << 1,
};

UInt32 dataVersion; // set to kVersion
Expand All @@ -307,13 +311,15 @@ struct F4SEPluginVersionData
char author[256]; // null-terminated ASCII plugin author name (can be empty)

// version compatibility
UInt32 versionIndependence; // set to one of the kVersionIndependent_ enums or zero
UInt32 versionIndependenceEx; // set to one of the kVersionIndependentEx_ enums or zero
UInt32 addressIndependence; // bitfield. describe how you find your addresses using the kAddressIndependence_ enums
UInt32 structureIndependence; // bitfield. describe how you handle structure layout using the kStructureIndependence_ enums
UInt32 compatibleVersions[16]; // zero-terminated list of RUNTIME_VERSION_ defines your plugin is compatible with

UInt32 seVersionRequired; // minimum version of the script extender required, compared against PACKED_SKSE_VERSION
// you probably should just set this to 0 unless you know what you are doing

UInt32 reservedNonBreaking; // bitfield. set to 0
UInt32 reservedBreaking; // bitfield. set to 0
UInt8 reserved[512]; // set to 0
};

Expand All @@ -339,4 +345,11 @@ struct F4SEPluginVersionData
* added to the end, and all old fields will remain compatible with their
* previous implementations.
*
* If your plugin needs to make modifications before global initializers, add
* and export this:
*
* bool F4SEPlugin_Preload(const F4SEInterface * f4se)
*
* Game and F4SE functionality may be limited during preload.
*
******************************************************************************/
25 changes: 13 additions & 12 deletions f4se/PluginManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,22 +652,23 @@ const char * PluginManager::CheckPluginCompatibility(const F4SEPluginVersionData
}

// version compatibility
const UInt32 kCurrentAddressLibrary = F4SEPluginVersionData::kAddressIndependence_AddressLibrary_1_10_980;

bool hasAddressIndependence = version.addressIndependence &
(F4SEPluginVersionData::kAddressIndependence_Signatures |
kCurrentAddressLibrary);
bool hasStructureIndependence = version.structureIndependence &
(F4SEPluginVersionData::kStructureIndependence_NoStructs |
F4SEPluginVersionData::kStructureIndependence_1_10_980Layout);

const UInt32 kKnownVersionIndependent =
F4SEPluginVersionData::kVersionIndependent_AddressLibraryPost1_10_980 |
F4SEPluginVersionData::kVersionIndependent_Signatures;

// bail out on unknown flags, handles future breaking API changes in the runtime
if(version.versionIndependence & ~kKnownVersionIndependent)
{
return "disabled, unsupported version independence method";
}
bool versionIndependent = hasAddressIndependence && hasStructureIndependence;

// any claim of version independence?
bool versionIndependent = version.versionIndependence & (F4SEPluginVersionData::kVersionIndependent_AddressLibraryPost1_10_980 | F4SEPluginVersionData::kVersionIndependent_Signatures);
// currently anything in the "breaking change" field means that compatibility has been broken by an update
if(version.reservedBreaking)
versionIndependent = false;

// verify the address library is there to centralize error message
if(version.versionIndependence & F4SEPluginVersionData::kVersionIndependent_AddressLibraryPost1_10_980)
if(version.addressIndependence & kCurrentAddressLibrary)
{
const char * result = CheckAddressLibrary();
if(result) return result;
Expand Down

0 comments on commit 8f8d220

Please sign in to comment.