2022-07-31 18:55:11 +00:00
# pragma once
# include "CheckInvalidForms.h"
# include <SimpleIni.h>
2022-09-14 17:33:20 +00:00
# include <regex>
2022-07-31 18:55:11 +00:00
inline const SKSE : : LoadInterface * GetLoadInterface ( const SKSE : : LoadInterface * loadInterface = nullptr )
{
const static SKSE : : LoadInterface * singleton ;
if ( loadInterface ) {
singleton = loadInterface ;
}
return singleton ;
}
inline uint8_t NewGameCount ( bool increment = false )
{
static uint8_t g_NewGameStarted = 0 ;
if ( increment ) {
g_NewGameStarted + + ;
}
return g_NewGameStarted ;
}
inline bool IsSE ( )
{
return GetLoadInterface ( ) - > RuntimeVersion ( ) . minor ( ) = = 5 ;
}
2022-09-07 22:58:18 +00:00
inline bool IsVR ( )
{
return GetLoadInterface ( ) - > RuntimeVersion ( ) = = SKSE : : RUNTIME_VR_1_4_15 | | GetLoadInterface ( ) - > RuntimeVersion ( ) = = SKSE : : RUNTIME_LATEST_VR ;
}
2022-07-31 18:55:11 +00:00
inline void CheckIncompatibleMods ( )
{
2022-09-14 17:33:20 +00:00
bool bPrinted = false ;
if ( std : : filesystem : : exists ( " Data \\ SKSE \\ Plugins \\ EnderalVersion.ini " ) ) {
CSimpleIniA ini ;
ini . SetUnicode ( false ) ;
ini . SetMultiKey ( false ) ;
ini . LoadFile ( " Data/SKSE/Plugins/EnderalVersion.ini " ) ;
const char * version = ini . GetValue ( " " , " version " , " 2.0.x " ) ;
std : : regex version_expr ( " ^[ \\ d \\ .]+$ " ) ;
if ( std : : regex_match ( version , version_expr ) ) {
RE : : ConsoleLog : : GetSingleton ( ) - > Print ( std : : format ( " Loaded SureAI's Enderal: Forgotten Stories | Special Edition v{} by Eddoursul and contributors " , version ) . c_str ( ) ) ;
bPrinted = true ;
}
}
if ( ! bPrinted ) {
RE : : ConsoleLog : : GetSingleton ( ) - > Print ( " Loaded SureAI's Enderal: Forgotten Stories | Special Edition v2.0.x by Eddoursul and contributors " ) ;
}
2022-07-31 18:55:11 +00:00
CheckWorldspaces ( ) ;
2022-08-08 11:07:07 +00:00
CheckUnconvertedMap ( ) ;
2022-07-31 18:55:11 +00:00
CheckSkyrimCells ( ) ;
CheckEnderalCells ( ) ;
2022-09-08 09:24:27 +00:00
CheckEnderalContainers ( ) ;
CheckEnderalNPCs ( ) ;
2022-09-29 20:23:14 +00:00
CheckEnderalActivators ( ) ;
CheckEnderalStatics ( ) ;
2022-07-31 18:55:11 +00:00
}
2023-10-26 19:22:14 +00:00
inline bool PapyrusGlobalFunctionExists ( const char * scriptName , const char * funcName )
{
RE : : BSTSmartPointer < RE : : BSScript : : ObjectTypeInfo > typeInfoPtr ;
RE : : BSScript : : Internal : : VirtualMachine : : GetSingleton ( ) - > GetScriptObjectType ( RE : : BSFixedString ( scriptName ) , typeInfoPtr ) ;
auto functionCount = typeInfoPtr - > GetNumGlobalFuncs ( ) ;
auto functions = typeInfoPtr - > GetGlobalFuncIter ( ) ;
for ( uint32_t i = 0 ; i < functionCount ; i + + ) {
if ( functions [ i ] . func - > GetName ( ) . c_str ( ) = = funcName ) {
return true ;
}
}
return false ;
}
inline void CheckScriptVersions ( )
{
class ScriptVersionCallback : public RE : : BSScript : : IStackCallbackFunctor
{
private :
std : : uint32_t expectedVersion ;
const RE : : BSFixedString scriptName ;
const RE : : BSFixedString funcName = " _GetScriptVersion " ;
public :
ScriptVersionCallback ( const RE : : BSFixedString a_scriptName , int a_version ) :
scriptName ( a_scriptName ) ,
expectedVersion ( a_version )
{
if ( PapyrusGlobalFunctionExists ( scriptName . c_str ( ) , funcName . c_str ( ) ) ) {
const auto vm = RE : : BSScript : : Internal : : VirtualMachine : : GetSingleton ( ) ;
auto callbackPtr = RE : : BSTSmartPointer < RE : : BSScript : : IStackCallbackFunctor > ( this ) ;
vm - > DispatchStaticCall ( scriptName , funcName , RE : : MakeFunctionArguments ( ) , callbackPtr ) ;
} else {
auto a_script = scriptName ;
auto a_version = expectedVersion ;
SKSE : : GetTaskInterface ( ) - > AddTask ( [ a_script , a_version ] ( ) {
RE : : DebugMessageBox ( std : : format ( " Script {} is overwritten by a mod, incompatible with current version of Enderal. Expected version: {}, installed version: N/A. " , a_script . c_str ( ) , a_version ) . c_str ( ) ) ;
} ) ;
}
}
void operator ( ) ( RE : : BSScript : : Variable a_result )
{
if ( a_result . GetUInt ( ) ! = expectedVersion ) {
RE : : DebugMessageBox ( std : : format ( " Script {} is overwritten by a mod, incompatible with current version of Enderal. Expected version: {}, installed version: {}. " , scriptName . c_str ( ) , expectedVersion , a_result . GetUInt ( ) ) . c_str ( ) ) ;
}
}
bool CanSave ( ) { return false ; }
void SetObject ( const RE : : BSTSmartPointer < RE : : BSScript : : Object > & ) { }
} ;
RE : : BSTSmartPointer < ScriptVersionCallback > {
new ScriptVersionCallback ( " _00E_PlayerSetUpScript " , 1 )
} ;
RE : : BSTSmartPointer < ScriptVersionCallback > {
new ScriptVersionCallback ( " _00E_QuestFunctions " , 1 )
} ;
RE : : BSTSmartPointer < ScriptVersionCallback > {
new ScriptVersionCallback ( " _00E_Game_SkillmenuSC " , 1 )
} ;
RE : : BSTSmartPointer < ScriptVersionCallback > {
new ScriptVersionCallback ( " _00E_Theriantrophist_AlchemyControl " , 1 )
} ;
}
2022-07-31 18:55:11 +00:00
inline void LoadINI ( std : : map < std : : string , bool > * settings , const char * iniPath )
{
for ( auto it = settings - > begin ( ) ; it ! = settings - > end ( ) ; it + + ) {
logger : : info ( " [DEFAULT] {} = {} " , it - > first , it - > second ) ;
}
if ( ! std : : filesystem : : exists ( iniPath ) ) {
logger : : warn ( " {} does not exist, using default values. " , iniPath ) ;
return ;
}
try {
CSimpleIniA ini ;
ini . SetUnicode ( false ) ;
ini . SetMultiKey ( false ) ;
ini . LoadFile ( iniPath ) ;
std : : list < CSimpleIniA : : Entry > keysList ;
ini . GetAllKeys ( " " , keysList ) ;
bool bUpdateINI = false ;
for ( auto it = settings - > begin ( ) ; it ! = settings - > end ( ) ; it + + ) {
bool bExists = false ;
for ( const auto & k : keysList ) {
if ( it - > first = = k . pItem ) {
settings - > insert_or_assign ( k . pItem , ini . GetBoolValue ( " " , k . pItem , settings - > at ( k . pItem ) ) ) ;
logger : : info ( " [INI] {} = {} " , k . pItem , settings - > at ( k . pItem ) ) ;
bExists = true ;
break ;
}
}
if ( ! bExists ) {
ini . SetBoolValue ( " " , it - > first . c_str ( ) , it - > second ) ;
bUpdateINI = true ;
}
}
if ( bUpdateINI ) {
2023-10-25 23:18:56 +00:00
logger : : info ( " New settings detected, adding to EnderalSE.ini " ) ;
2022-07-31 18:55:11 +00:00
ini . SaveFile ( iniPath ) ;
}
} catch ( const std : : exception & e ) {
2022-09-01 09:20:08 +00:00
logger : : error ( " {} " , e . what ( ) ) ;
2022-07-31 18:55:11 +00:00
}
}