diff --git a/UE4SS/generated_include/MacroSetter.hpp b/UE4SS/generated_include/MacroSetter.hpp index c776ad2ec..6a0eb0afa 100644 --- a/UE4SS/generated_include/MacroSetter.hpp +++ b/UE4SS/generated_include/MacroSetter.hpp @@ -1,892 +1,903 @@ -if (auto val = parser.get_int64(STR("UObjectBase"), STR("Class"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UObjectBase"), SYSSTR("Class"), -1); val != -1) Unreal::UObjectBase::MemberOffsets.emplace(STR("Class"), static_cast(val)); -if (auto val = parser.get_int64(STR("UObjectBase"), STR("ClassPrivate"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UObjectBase"), SYSSTR("ClassPrivate"), -1); val != -1) Unreal::UObjectBase::MemberOffsets.emplace(STR("ClassPrivate"), static_cast(val)); -if (auto val = parser.get_int64(STR("UObjectBase"), STR("InternalIndex"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UObjectBase"), SYSSTR("InternalIndex"), -1); val != -1) Unreal::UObjectBase::MemberOffsets.emplace(STR("InternalIndex"), static_cast(val)); -if (auto val = parser.get_int64(STR("UObjectBase"), STR("Name"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UObjectBase"), SYSSTR("Name"), -1); val != -1) Unreal::UObjectBase::MemberOffsets.emplace(STR("Name"), static_cast(val)); -if (auto val = parser.get_int64(STR("UObjectBase"), STR("NamePrivate"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UObjectBase"), SYSSTR("NamePrivate"), -1); val != -1) Unreal::UObjectBase::MemberOffsets.emplace(STR("NamePrivate"), static_cast(val)); -if (auto val = parser.get_int64(STR("UObjectBase"), STR("ObjectFlags"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UObjectBase"), SYSSTR("ObjectFlags"), -1); val != -1) Unreal::UObjectBase::MemberOffsets.emplace(STR("ObjectFlags"), static_cast(val)); -if (auto val = parser.get_int64(STR("UObjectBase"), STR("Outer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UObjectBase"), SYSSTR("Outer"), -1); val != -1) Unreal::UObjectBase::MemberOffsets.emplace(STR("Outer"), static_cast(val)); -if (auto val = parser.get_int64(STR("UObjectBase"), STR("OuterPrivate"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UObjectBase"), SYSSTR("OuterPrivate"), -1); val != -1) Unreal::UObjectBase::MemberOffsets.emplace(STR("OuterPrivate"), static_cast(val)); -if (auto val = parser.get_int64(STR("UScriptStruct::ICppStructOps"), STR("Alignment"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UScriptStruct::ICppStructOps"), SYSSTR("Alignment"), -1); val != -1) Unreal::UScriptStruct::ICppStructOps::MemberOffsets.emplace(STR("Alignment"), static_cast(val)); -if (auto val = parser.get_int64(STR("UScriptStruct::ICppStructOps"), STR("Size"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UScriptStruct::ICppStructOps"), SYSSTR("Size"), -1); val != -1) Unreal::UScriptStruct::ICppStructOps::MemberOffsets.emplace(STR("Size"), static_cast(val)); -if (auto val = parser.get_int64(STR("FProperty"), STR("ArrayDim"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FProperty"), SYSSTR("ArrayDim"), -1); val != -1) Unreal::FProperty::MemberOffsets.emplace(STR("ArrayDim"), static_cast(val)); -if (auto val = parser.get_int64(STR("FProperty"), STR("DestructorLinkNext"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FProperty"), SYSSTR("DestructorLinkNext"), -1); val != -1) Unreal::FProperty::MemberOffsets.emplace(STR("DestructorLinkNext"), static_cast(val)); -if (auto val = parser.get_int64(STR("FProperty"), STR("ElementSize"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FProperty"), SYSSTR("ElementSize"), -1); val != -1) Unreal::FProperty::MemberOffsets.emplace(STR("ElementSize"), static_cast(val)); -if (auto val = parser.get_int64(STR("FProperty"), STR("NextRef"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FProperty"), SYSSTR("NextRef"), -1); val != -1) Unreal::FProperty::MemberOffsets.emplace(STR("NextRef"), static_cast(val)); -if (auto val = parser.get_int64(STR("FProperty"), STR("Offset_Internal"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FProperty"), SYSSTR("Offset_Internal"), -1); val != -1) Unreal::FProperty::MemberOffsets.emplace(STR("Offset_Internal"), static_cast(val)); -if (auto val = parser.get_int64(STR("FProperty"), STR("PostConstructLinkNext"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FProperty"), SYSSTR("PostConstructLinkNext"), -1); val != -1) Unreal::FProperty::MemberOffsets.emplace(STR("PostConstructLinkNext"), static_cast(val)); -if (auto val = parser.get_int64(STR("FProperty"), STR("PropertyFlags"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FProperty"), SYSSTR("PropertyFlags"), -1); val != -1) Unreal::FProperty::MemberOffsets.emplace(STR("PropertyFlags"), static_cast(val)); -if (auto val = parser.get_int64(STR("FProperty"), STR("PropertyLinkNext"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FProperty"), SYSSTR("PropertyLinkNext"), -1); val != -1) Unreal::FProperty::MemberOffsets.emplace(STR("PropertyLinkNext"), static_cast(val)); -if (auto val = parser.get_int64(STR("FProperty"), STR("RepIndex"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FProperty"), SYSSTR("RepIndex"), -1); val != -1) Unreal::FProperty::MemberOffsets.emplace(STR("RepIndex"), static_cast(val)); -if (auto val = parser.get_int64(STR("FProperty"), STR("RepNotifyFunc"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FProperty"), SYSSTR("RepNotifyFunc"), -1); val != -1) Unreal::FProperty::MemberOffsets.emplace(STR("RepNotifyFunc"), static_cast(val)); -if (auto val = parser.get_int64(STR("FSoftClassProperty"), STR("MetaClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FSoftClassProperty"), SYSSTR("MetaClass"), -1); val != -1) Unreal::FSoftClassProperty::MemberOffsets.emplace(STR("MetaClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameModeBase"), STR("DefaultPlayerName"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameModeBase"), SYSSTR("DefaultPlayerName"), -1); val != -1) Unreal::AGameModeBase::MemberOffsets.emplace(STR("DefaultPlayerName"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameModeBase"), STR("GameSession"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameModeBase"), SYSSTR("GameSession"), -1); val != -1) Unreal::AGameModeBase::MemberOffsets.emplace(STR("GameSession"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameModeBase"), STR("GameSessionClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameModeBase"), SYSSTR("GameSessionClass"), -1); val != -1) Unreal::AGameModeBase::MemberOffsets.emplace(STR("GameSessionClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameModeBase"), STR("HUDClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameModeBase"), SYSSTR("HUDClass"), -1); val != -1) Unreal::AGameModeBase::MemberOffsets.emplace(STR("HUDClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameModeBase"), STR("OptionsString"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameModeBase"), SYSSTR("OptionsString"), -1); val != -1) Unreal::AGameModeBase::MemberOffsets.emplace(STR("OptionsString"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameModeBase"), STR("PlayerStateClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameModeBase"), SYSSTR("PlayerStateClass"), -1); val != -1) Unreal::AGameModeBase::MemberOffsets.emplace(STR("PlayerStateClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameModeBase"), STR("ServerStatReplicator"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameModeBase"), SYSSTR("ServerStatReplicator"), -1); val != -1) Unreal::AGameModeBase::MemberOffsets.emplace(STR("ServerStatReplicator"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameModeBase"), STR("ServerStatReplicatorClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameModeBase"), SYSSTR("ServerStatReplicatorClass"), -1); val != -1) Unreal::AGameModeBase::MemberOffsets.emplace(STR("ServerStatReplicatorClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameModeBase"), STR("SpectatorClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameModeBase"), SYSSTR("SpectatorClass"), -1); val != -1) Unreal::AGameModeBase::MemberOffsets.emplace(STR("SpectatorClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameModeBase"), STR("bPauseable"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameModeBase"), SYSSTR("bPauseable"), -1); val != -1) Unreal::AGameModeBase::MemberOffsets.emplace(STR("bPauseable"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameModeBase"), STR("bStartPlayersAsSpectators"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameModeBase"), SYSSTR("bStartPlayersAsSpectators"), -1); val != -1) Unreal::AGameModeBase::MemberOffsets.emplace(STR("bStartPlayersAsSpectators"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameModeBase"), STR("bUseSeamlessTravel"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameModeBase"), SYSSTR("bUseSeamlessTravel"), -1); val != -1) Unreal::AGameModeBase::MemberOffsets.emplace(STR("bUseSeamlessTravel"), static_cast(val)); -if (auto val = parser.get_int64(STR("FOutputDevice"), STR("bAutoEmitLineTerminator"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FOutputDevice"), SYSSTR("bAutoEmitLineTerminator"), -1); val != -1) Unreal::FOutputDevice::MemberOffsets.emplace(STR("bAutoEmitLineTerminator"), static_cast(val)); -if (auto val = parser.get_int64(STR("FOutputDevice"), STR("bSuppressEventTag"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FOutputDevice"), SYSSTR("bSuppressEventTag"), -1); val != -1) Unreal::FOutputDevice::MemberOffsets.emplace(STR("bSuppressEventTag"), static_cast(val)); -if (auto val = parser.get_int64(STR("UFunction"), STR("EventGraphCallOffset"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UFunction"), SYSSTR("EventGraphCallOffset"), -1); val != -1) Unreal::UFunction::MemberOffsets.emplace(STR("EventGraphCallOffset"), static_cast(val)); -if (auto val = parser.get_int64(STR("UFunction"), STR("EventGraphFunction"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UFunction"), SYSSTR("EventGraphFunction"), -1); val != -1) Unreal::UFunction::MemberOffsets.emplace(STR("EventGraphFunction"), static_cast(val)); -if (auto val = parser.get_int64(STR("UFunction"), STR("FirstPropertyToInit"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UFunction"), SYSSTR("FirstPropertyToInit"), -1); val != -1) Unreal::UFunction::MemberOffsets.emplace(STR("FirstPropertyToInit"), static_cast(val)); -if (auto val = parser.get_int64(STR("UFunction"), STR("Func"), -1); val != -1) Unreal::UFunction::MemberOffsets.emplace(STR("Func"), static_cast(val)); -if (auto val = parser.get_int64(STR("UFunction"), STR("FunctionFlags"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UFunction"), SYSSTR("Func"), -1); val != -1) + Unreal::UFunction::MemberOffsets.emplace(STR("Func"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("UFunction"), SYSSTR("FunctionFlags"), -1); val != -1) Unreal::UFunction::MemberOffsets.emplace(STR("FunctionFlags"), static_cast(val)); -if (auto val = parser.get_int64(STR("UFunction"), STR("NumParms"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UFunction"), SYSSTR("NumParms"), -1); val != -1) Unreal::UFunction::MemberOffsets.emplace(STR("NumParms"), static_cast(val)); -if (auto val = parser.get_int64(STR("UFunction"), STR("ParmsSize"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UFunction"), SYSSTR("ParmsSize"), -1); val != -1) Unreal::UFunction::MemberOffsets.emplace(STR("ParmsSize"), static_cast(val)); -if (auto val = parser.get_int64(STR("UFunction"), STR("RPCId"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UFunction"), SYSSTR("RPCId"), -1); val != -1) Unreal::UFunction::MemberOffsets.emplace(STR("RPCId"), static_cast(val)); -if (auto val = parser.get_int64(STR("UFunction"), STR("RPCResponseId"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UFunction"), SYSSTR("RPCResponseId"), -1); val != -1) Unreal::UFunction::MemberOffsets.emplace(STR("RPCResponseId"), static_cast(val)); -if (auto val = parser.get_int64(STR("UFunction"), STR("RepOffset"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UFunction"), SYSSTR("RepOffset"), -1); val != -1) Unreal::UFunction::MemberOffsets.emplace(STR("RepOffset"), static_cast(val)); -if (auto val = parser.get_int64(STR("UFunction"), STR("ReturnValueOffset"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UFunction"), SYSSTR("ReturnValueOffset"), -1); val != -1) Unreal::UFunction::MemberOffsets.emplace(STR("ReturnValueOffset"), static_cast(val)); -if (auto val = parser.get_int64(STR("UField"), STR("Next"), -1); val != -1) Unreal::UField::MemberOffsets.emplace(STR("Next"), static_cast(val)); -if (auto val = parser.get_int64(STR("FEnumProperty"), STR("Enum"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UField"), SYSSTR("Next"), -1); val != -1) Unreal::UField::MemberOffsets.emplace(STR("Next"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("FEnumProperty"), SYSSTR("Enum"), -1); val != -1) Unreal::FEnumProperty::MemberOffsets.emplace(STR("Enum"), static_cast(val)); -if (auto val = parser.get_int64(STR("FEnumProperty"), STR("UnderlyingProp"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FEnumProperty"), SYSSTR("UnderlyingProp"), -1); val != -1) Unreal::FEnumProperty::MemberOffsets.emplace(STR("UnderlyingProp"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("ChildProperties"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("ChildProperties"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("ChildProperties"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("Children"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("Children"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("Children"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("DestructorLink"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("DestructorLink"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("DestructorLink"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("MinAlignment"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("MinAlignment"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("MinAlignment"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("PostConstructLink"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("PostConstructLink"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("PostConstructLink"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("PropertiesSize"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("PropertiesSize"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("PropertiesSize"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("PropertyLink"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("PropertyLink"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("PropertyLink"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("RefLink"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("RefLink"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("RefLink"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("Script"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("Script"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("ScriptAndPropertyObjectReferences"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("Script"), -1); val != -1) + Unreal::UStruct::MemberOffsets.emplace(STR("Script"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("ScriptAndPropertyObjectReferences"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("ScriptAndPropertyObjectReferences"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("ScriptObjectReferences"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("ScriptObjectReferences"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("ScriptObjectReferences"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("SuperStruct"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("SuperStruct"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("SuperStruct"), static_cast(val)); -if (auto val = parser.get_int64(STR("UStruct"), STR("UnresolvedScriptProperties"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UStruct"), SYSSTR("UnresolvedScriptProperties"), -1); val != -1) Unreal::UStruct::MemberOffsets.emplace(STR("UnresolvedScriptProperties"), static_cast(val)); -if (auto val = parser.get_int64(STR("FDelegateProperty"), STR("SignatureFunction"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FDelegateProperty"), SYSSTR("SignatureFunction"), -1); val != -1) Unreal::FDelegateProperty::MemberOffsets.emplace(STR("SignatureFunction"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("ActiveSplitscreenType"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("ActiveSplitscreenType"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("ActiveSplitscreenType"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("AudioDeviceHandle"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("AudioDeviceHandle"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("AudioDeviceHandle"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("CurrentBufferVisualizationMode"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("CurrentBufferVisualizationMode"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("CurrentBufferVisualizationMode"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("CurrentLumenVisualizationMode"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("CurrentLumenVisualizationMode"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("CurrentLumenVisualizationMode"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("CurrentNaniteVisualizationMode"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("CurrentNaniteVisualizationMode"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("CurrentNaniteVisualizationMode"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("CurrentVirtualShadowMapVisualizationMode"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("CurrentVirtualShadowMapVisualizationMode"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("CurrentVirtualShadowMapVisualizationMode"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("DebugProperties"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("DebugProperties"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("DebugProperties"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("EngineShowFlags"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("EngineShowFlags"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("EngineShowFlags"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("GameLayerManagerPtr"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("GameLayerManagerPtr"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("GameLayerManagerPtr"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("HighResScreenshotDialog"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("HighResScreenshotDialog"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("HighResScreenshotDialog"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("MaxSplitscreenPlayers"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("MaxSplitscreenPlayers"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("MaxSplitscreenPlayers"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("MouseCaptureMode"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("MouseCaptureMode"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("MouseCaptureMode"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("MouseLockMode"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("MouseLockMode"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("MouseLockMode"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("SplitscreenInfo"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("SplitscreenInfo"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("SplitscreenInfo"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("StatHitchesData"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("StatHitchesData"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("StatHitchesData"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("StatUnitData"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("StatUnitData"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("StatUnitData"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("TitleSafeZone"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("TitleSafeZone"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("TitleSafeZone"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("ViewModeIndex"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("ViewModeIndex"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("ViewModeIndex"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("Viewport"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("Viewport"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("Viewport"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("ViewportConsole"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("ViewportConsole"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("ViewportConsole"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("ViewportFrame"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("ViewportFrame"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("ViewportFrame"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("ViewportOverlayWidget"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("ViewportOverlayWidget"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("ViewportOverlayWidget"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("Window"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("Window"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("Window"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("World"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("World"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("World"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("bDisableSplitScreenOverride"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("bDisableSplitScreenOverride"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("bDisableSplitScreenOverride"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("bDisableWorldRendering"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("bDisableWorldRendering"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("bDisableWorldRendering"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("bHasAudioFocus"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("bHasAudioFocus"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("bHasAudioFocus"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("bHideCursorDuringCapture"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("bHideCursorDuringCapture"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("bHideCursorDuringCapture"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("bIgnoreInput"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("bIgnoreInput"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("bIgnoreInput"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("bIsMouseOverClient"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("bIsMouseOverClient"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("bIsMouseOverClient"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("bIsPlayInEditorViewport"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("bIsPlayInEditorViewport"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("bIsPlayInEditorViewport"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("bLockDuringCapture"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("bLockDuringCapture"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("bLockDuringCapture"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("bShowTitleSafeZone"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("bShowTitleSafeZone"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("bShowTitleSafeZone"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("bSuppressTransitionMessage"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("bSuppressTransitionMessage"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("bSuppressTransitionMessage"), static_cast(val)); -if (auto val = parser.get_int64(STR("UGameViewportClient"), STR("bUseSoftwareCursorWidgets"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UGameViewportClient"), SYSSTR("bUseSoftwareCursorWidgets"), -1); val != -1) Unreal::UGameViewportClient::MemberOffsets.emplace(STR("bUseSoftwareCursorWidgets"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArAllowLazyLoading"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArAllowLazyLoading"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArAllowLazyLoading"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArContainsCode"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArContainsCode"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArContainsCode"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArContainsMap"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArContainsMap"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArContainsMap"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArCustomPropertyList"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArCustomPropertyList"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArCustomPropertyList"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArEngineNetVer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArEngineNetVer"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArEngineNetVer"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArEngineVer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArEngineVer"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArEngineVer"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArForceByteSwapping"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArForceByteSwapping"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArForceByteSwapping"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArForceUnicode"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArForceUnicode"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArForceUnicode"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArGameNetVer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArGameNetVer"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArGameNetVer"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIgnoreArchetypeRef"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIgnoreArchetypeRef"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIgnoreArchetypeRef"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIgnoreClassGeneratedByRef"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIgnoreClassGeneratedByRef"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIgnoreClassGeneratedByRef"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIgnoreClassRef"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIgnoreClassRef"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIgnoreClassRef"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIgnoreOuterRef"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIgnoreOuterRef"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIgnoreOuterRef"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsCountingMemory"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsCountingMemory"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsCountingMemory"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsCriticalError"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsCriticalError"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsCriticalError"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsError"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsError"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsError"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsFilterEditorOnly"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsFilterEditorOnly"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsFilterEditorOnly"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsLoading"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsLoading"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsLoading"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsModifyingWeakAndStrongReferences"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsModifyingWeakAndStrongReferences"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsModifyingWeakAndStrongReferences"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsNetArchive"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsNetArchive"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsNetArchive"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsObjectReferenceCollector"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsObjectReferenceCollector"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsObjectReferenceCollector"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsPersistent"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsPersistent"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsPersistent"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsSaveGame"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsSaveGame"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsSaveGame"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsSaving"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsSaving"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsSaving"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsTextFormat"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsTextFormat"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsTextFormat"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArIsTransacting"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArIsTransacting"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArIsTransacting"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArLicenseeUE4Ver"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArLicenseeUE4Ver"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArLicenseeUE4Ver"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArMaxSerializeSize"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArMaxSerializeSize"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArMaxSerializeSize"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArNetVer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArNetVer"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArNetVer"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArNoDelta"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArNoDelta"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArNoDelta"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArNoIntraPropertyDelta"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArNoIntraPropertyDelta"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArNoIntraPropertyDelta"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArPortFlags"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArPortFlags"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArPortFlags"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArRequiresLocalizationGather"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArRequiresLocalizationGather"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArRequiresLocalizationGather"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArSerializingDefaults"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArSerializingDefaults"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArSerializingDefaults"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArShouldSkipBulkData"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArShouldSkipBulkData"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArShouldSkipBulkData"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArUE4Ver"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArUE4Ver"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArUE4Ver"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArUseCustomPropertyList"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArUseCustomPropertyList"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArUseCustomPropertyList"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("ArWantBinaryPropertySerialization"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("ArWantBinaryPropertySerialization"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("ArWantBinaryPropertySerialization"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("CookingTargetPlatform"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("CookingTargetPlatform"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("CookingTargetPlatform"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("CustomVersionContainer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("CustomVersionContainer"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("CustomVersionContainer"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("SerializedProperty"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("SerializedProperty"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("SerializedProperty"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchive"), STR("bCustomVersionsAreReset"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchive"), SYSSTR("bCustomVersionsAreReset"), -1); val != -1) Unreal::FArchive::MemberOffsets.emplace(STR("bCustomVersionsAreReset"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("CurrentID"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("CurrentID"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("CurrentID"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("DefaultPlayerName"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("DefaultPlayerName"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("DefaultPlayerName"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("EngineMessageClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("EngineMessageClass"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("EngineMessageClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("GameModeClassAliases"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("GameModeClassAliases"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("GameModeClassAliases"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("GameSession"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("GameSession"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("GameSession"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("HUDClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("HUDClass"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("HUDClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("InactivePlayerArray"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("InactivePlayerArray"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("InactivePlayerArray"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("InactivePlayerStateLifeSpan"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("InactivePlayerStateLifeSpan"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("InactivePlayerStateLifeSpan"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("MatchState"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("MatchState"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("MatchState"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("MaxInactivePlayers"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("MaxInactivePlayers"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("MaxInactivePlayers"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("MinRespawnDelay"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("MinRespawnDelay"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("MinRespawnDelay"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("NumBots"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("NumBots"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("NumBots"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("NumPlayers"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("NumPlayers"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("NumPlayers"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("NumSpectators"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("NumSpectators"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("NumSpectators"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("NumTravellingPlayers"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("NumTravellingPlayers"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("NumTravellingPlayers"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("OptionsString"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("OptionsString"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("OptionsString"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("PlayerStateClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("PlayerStateClass"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("PlayerStateClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("SpectatorClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("SpectatorClass"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("SpectatorClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("bDelayedStart"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("bDelayedStart"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("bDelayedStart"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("bHandleDedicatedServerReplays"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("bHandleDedicatedServerReplays"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("bHandleDedicatedServerReplays"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("bPauseable"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("bPauseable"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("bPauseable"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("bStartPlayersAsSpectators"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("bStartPlayersAsSpectators"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("bStartPlayersAsSpectators"), static_cast(val)); -if (auto val = parser.get_int64(STR("AGameMode"), STR("bUseSeamlessTravel"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AGameMode"), SYSSTR("bUseSeamlessTravel"), -1); val != -1) Unreal::AGameMode::MemberOffsets.emplace(STR("bUseSeamlessTravel"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("AttachmentReplication"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("AttachmentReplication"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("AttachmentReplication"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("AutoReceiveInput"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("AutoReceiveInput"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("AutoReceiveInput"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("CachedLastRenderTime"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("CachedLastRenderTime"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("CachedLastRenderTime"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("ControllingMatineeActors"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("ControllingMatineeActors"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("ControllingMatineeActors"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("CreationTime"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("CreationTime"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("CreationTime"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("CustomTimeDilation"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("CustomTimeDilation"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("CustomTimeDilation"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("DefaultUpdateOverlapsMethodDuringLevelStreaming"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("DefaultUpdateOverlapsMethodDuringLevelStreaming"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("DefaultUpdateOverlapsMethodDuringLevelStreaming"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("DetachFence"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("DetachFence"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("DetachFence"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("HiddenEditorViews"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("HiddenEditorViews"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("HiddenEditorViews"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("InitialLifeSpan"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("InitialLifeSpan"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("InitialLifeSpan"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("InputComponent"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("InputComponent"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("InputComponent"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("InputConsumeOption_DEPRECATED"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("InputConsumeOption_DEPRECATED"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("InputConsumeOption_DEPRECATED"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("InputPriority"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("InputPriority"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("InputPriority"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("LastNetUpdateTime"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("LastNetUpdateTime"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("LastNetUpdateTime"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("LastRenderTime"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("LastRenderTime"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("LastRenderTime"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("Layers"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("Layers"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("MinNetUpdateFrequency"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("Layers"), -1); val != -1) + Unreal::AActor::MemberOffsets.emplace(STR("Layers"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("MinNetUpdateFrequency"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("MinNetUpdateFrequency"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("NetCullDistanceSquared"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("NetCullDistanceSquared"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("NetCullDistanceSquared"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("NetDormancy"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("NetDormancy"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("NetDormancy"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("NetDriverName"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("NetDriverName"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("NetDriverName"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("NetPriority"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("NetPriority"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("NetPriority"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("NetTag"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("NetTag"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("NetUpdateFrequency"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("NetTag"), -1); val != -1) + Unreal::AActor::MemberOffsets.emplace(STR("NetTag"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("NetUpdateFrequency"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("NetUpdateFrequency"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("NetUpdateTime"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("NetUpdateTime"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("NetUpdateTime"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnActorBeginOverlap"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnActorBeginOverlap"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnActorBeginOverlap"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnActorEndOverlap"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnActorEndOverlap"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnActorEndOverlap"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnActorHit"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnActorHit"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnActorHit"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnBeginCursorOver"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnBeginCursorOver"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnBeginCursorOver"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnClicked"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnClicked"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnClicked"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnDestroyed"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnDestroyed"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnDestroyed"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnEndCursorOver"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnEndCursorOver"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnEndCursorOver"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnEndPlay"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnEndPlay"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnEndPlay"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnInputTouchBegin"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnInputTouchBegin"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnInputTouchBegin"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnInputTouchEnd"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnInputTouchEnd"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnInputTouchEnd"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnInputTouchEnter"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnInputTouchEnter"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnInputTouchEnter"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnInputTouchLeave"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnInputTouchLeave"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnInputTouchLeave"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnReleased"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnReleased"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnReleased"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnTakeAnyDamage"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnTakeAnyDamage"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnTakeAnyDamage"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnTakePointDamage"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnTakePointDamage"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnTakePointDamage"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("OnTakeRadialDamage"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("OnTakeRadialDamage"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("OnTakeRadialDamage"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("ParentComponent"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("ParentComponent"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("ParentComponent"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("PrimaryActorTick"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("PrimaryActorTick"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("PrimaryActorTick"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("RayTracingGroupId"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("RayTracingGroupId"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("RayTracingGroupId"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("RemoteRole"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("RemoteRole"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("RemoteRole"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("ReplicatedComponentsInfo"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("ReplicatedComponentsInfo"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("ReplicatedComponentsInfo"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("ReplicatedMovement"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("ReplicatedMovement"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("ReplicatedMovement"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("ReplicatedSubObjects"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("ReplicatedSubObjects"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("ReplicatedSubObjects"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("Role"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("Role"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("RootComponent"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("Role"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("Role"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("RootComponent"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("RootComponent"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("SpawnCollisionHandlingMethod"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("SpawnCollisionHandlingMethod"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("SpawnCollisionHandlingMethod"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("Tags"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("Tags"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("TimerHandle_LifeSpanExpired"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("Tags"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("Tags"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("TimerHandle_LifeSpanExpired"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("TimerHandle_LifeSpanExpired"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("UpdateOverlapsMethodDuringLevelStreaming"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("UpdateOverlapsMethodDuringLevelStreaming"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("UpdateOverlapsMethodDuringLevelStreaming"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bActorBeginningPlayFromLevelStreaming"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bActorBeginningPlayFromLevelStreaming"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bActorBeginningPlayFromLevelStreaming"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bActorEnableCollision"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bActorEnableCollision"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bActorEnableCollision"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bActorInitialized"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bActorInitialized"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bActorInitialized"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bActorIsBeingConstructed"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bActorIsBeingConstructed"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bActorIsBeingConstructed"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bActorIsBeingDestroyed"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bActorIsBeingDestroyed"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bActorIsBeingDestroyed"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bActorSeamlessTraveled"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bActorSeamlessTraveled"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bActorSeamlessTraveled"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bActorWantsDestroyDuringBeginPlay"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bActorWantsDestroyDuringBeginPlay"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bActorWantsDestroyDuringBeginPlay"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bAllowReceiveTickEventOnDedicatedServer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bAllowReceiveTickEventOnDedicatedServer"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bAllowReceiveTickEventOnDedicatedServer"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bAllowTickBeforeBeginPlay"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bAllowTickBeforeBeginPlay"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bAllowTickBeforeBeginPlay"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bAlwaysRelevant"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bAlwaysRelevant"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bAlwaysRelevant"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bAsyncPhysicsTickEnabled"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bAsyncPhysicsTickEnabled"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bAsyncPhysicsTickEnabled"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bAutoDestroyWhenFinished"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bAutoDestroyWhenFinished"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bAutoDestroyWhenFinished"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bBlockInput"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bBlockInput"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bBlockInput"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bCallPreReplication"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bCallPreReplication"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bCallPreReplication"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bCallPreReplicationForReplay"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bCallPreReplicationForReplay"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bCallPreReplicationForReplay"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bCanBeDamaged"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bCanBeDamaged"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bCanBeDamaged"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bCanBeInCluster"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bCanBeInCluster"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bCanBeInCluster"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bCollideWhenPlacing"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bCollideWhenPlacing"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bCollideWhenPlacing"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bEnableAutoLODGeneration"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bEnableAutoLODGeneration"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bEnableAutoLODGeneration"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bExchangedRoles"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bExchangedRoles"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bExchangedRoles"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bFindCameraComponentWhenViewTarget"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bFindCameraComponentWhenViewTarget"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bFindCameraComponentWhenViewTarget"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bForceNetAddressable"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bForceNetAddressable"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bForceNetAddressable"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bGenerateOverlapEventsDuringLevelStreaming"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bGenerateOverlapEventsDuringLevelStreaming"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bGenerateOverlapEventsDuringLevelStreaming"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bHasDeferredComponentRegistration"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bHasDeferredComponentRegistration"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bHasDeferredComponentRegistration"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bHasFinishedSpawning"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bHasFinishedSpawning"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bHasFinishedSpawning"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bHasRegisteredAllComponents"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bHasRegisteredAllComponents"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bHasRegisteredAllComponents"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bHidden"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bHidden"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bIgnoresOriginShifting"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bHidden"), -1); val != -1) + Unreal::AActor::MemberOffsets.emplace(STR("bHidden"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bIgnoresOriginShifting"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bIgnoresOriginShifting"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bIsEditorOnlyActor"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bIsEditorOnlyActor"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bIsEditorOnlyActor"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bNetCheckedInitialPhysicsState"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bNetCheckedInitialPhysicsState"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bNetCheckedInitialPhysicsState"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bNetLoadOnClient"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bNetLoadOnClient"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bNetLoadOnClient"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bNetStartup"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bNetStartup"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bNetStartup"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bNetTemporary"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bNetTemporary"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bNetTemporary"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bNetUseOwnerRelevancy"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bNetUseOwnerRelevancy"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bNetUseOwnerRelevancy"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bOnlyRelevantToOwner"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bOnlyRelevantToOwner"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bOnlyRelevantToOwner"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bPendingNetUpdate"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bPendingNetUpdate"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bPendingNetUpdate"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bRelevantForLevelBounds"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bRelevantForLevelBounds"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bRelevantForLevelBounds"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bRelevantForNetworkReplays"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bRelevantForNetworkReplays"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bRelevantForNetworkReplays"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bReplayRewindable"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bReplayRewindable"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bReplayRewindable"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bReplicateMovement"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bReplicateMovement"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bReplicateMovement"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bReplicateUsingRegisteredSubObjectList"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bReplicateUsingRegisteredSubObjectList"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bReplicateUsingRegisteredSubObjectList"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bReplicates"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bReplicates"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bReplicates"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bRunningUserConstructionScript"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bRunningUserConstructionScript"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bRunningUserConstructionScript"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bTearOff"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bTearOff"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bTearOff"), static_cast(val)); -if (auto val = parser.get_int64(STR("AActor"), STR("bTickFunctionsRegistered"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("AActor"), SYSSTR("bTickFunctionsRegistered"), -1); val != -1) Unreal::AActor::MemberOffsets.emplace(STR("bTickFunctionsRegistered"), static_cast(val)); -if (auto val = parser.get_int64(STR("UPlayer"), STR("ConfiguredInternetSpeed"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UPlayer"), SYSSTR("ConfiguredInternetSpeed"), -1); val != -1) Unreal::UPlayer::MemberOffsets.emplace(STR("ConfiguredInternetSpeed"), static_cast(val)); -if (auto val = parser.get_int64(STR("UPlayer"), STR("ConfiguredLanSpeed"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UPlayer"), SYSSTR("ConfiguredLanSpeed"), -1); val != -1) Unreal::UPlayer::MemberOffsets.emplace(STR("ConfiguredLanSpeed"), static_cast(val)); -if (auto val = parser.get_int64(STR("UPlayer"), STR("CurrentNetSpeed"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UPlayer"), SYSSTR("CurrentNetSpeed"), -1); val != -1) Unreal::UPlayer::MemberOffsets.emplace(STR("CurrentNetSpeed"), static_cast(val)); -if (auto val = parser.get_int64(STR("FByteProperty"), STR("Enum"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FByteProperty"), SYSSTR("Enum"), -1); val != -1) Unreal::FByteProperty::MemberOffsets.emplace(STR("Enum"), static_cast(val)); -if (auto val = parser.get_int64(STR("ULocalPlayer"), STR("AspectRatioAxisConstraint"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("ULocalPlayer"), SYSSTR("AspectRatioAxisConstraint"), -1); val != -1) Unreal::ULocalPlayer::MemberOffsets.emplace(STR("AspectRatioAxisConstraint"), static_cast(val)); -if (auto val = parser.get_int64(STR("ULocalPlayer"), STR("ControllerId"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("ULocalPlayer"), SYSSTR("ControllerId"), -1); val != -1) Unreal::ULocalPlayer::MemberOffsets.emplace(STR("ControllerId"), static_cast(val)); -if (auto val = parser.get_int64(STR("ULocalPlayer"), STR("LastViewLocation"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("ULocalPlayer"), SYSSTR("LastViewLocation"), -1); val != -1) Unreal::ULocalPlayer::MemberOffsets.emplace(STR("LastViewLocation"), static_cast(val)); -if (auto val = parser.get_int64(STR("ULocalPlayer"), STR("ViewportClient"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("ULocalPlayer"), SYSSTR("ViewportClient"), -1); val != -1) Unreal::ULocalPlayer::MemberOffsets.emplace(STR("ViewportClient"), static_cast(val)); -if (auto val = parser.get_int64(STR("ULocalPlayer"), STR("bSentSplitJoin"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("ULocalPlayer"), SYSSTR("bSentSplitJoin"), -1); val != -1) Unreal::ULocalPlayer::MemberOffsets.emplace(STR("bSentSplitJoin"), static_cast(val)); -if (auto val = parser.get_int64(STR("FMulticastDelegateProperty"), STR("SignatureFunction"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FMulticastDelegateProperty"), SYSSTR("SignatureFunction"), -1); val != -1) Unreal::FMulticastDelegateProperty::MemberOffsets.emplace(STR("SignatureFunction"), static_cast(val)); -if (auto val = parser.get_int64(STR("FObjectPropertyBase"), STR("PropertyClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FObjectPropertyBase"), SYSSTR("PropertyClass"), -1); val != -1) Unreal::FObjectPropertyBase::MemberOffsets.emplace(STR("PropertyClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArAllowLazyLoading"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArAllowLazyLoading"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArAllowLazyLoading"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArContainsCode"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArContainsCode"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArContainsCode"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArContainsMap"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArContainsMap"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArContainsMap"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArCustomPropertyList"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArCustomPropertyList"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArCustomPropertyList"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArEngineNetVer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArEngineNetVer"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArEngineNetVer"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArEngineVer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArEngineVer"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArEngineVer"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArForceByteSwapping"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArForceByteSwapping"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArForceByteSwapping"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArForceUnicode"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArForceUnicode"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArForceUnicode"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArGameNetVer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArGameNetVer"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArGameNetVer"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIgnoreArchetypeRef"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIgnoreArchetypeRef"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIgnoreArchetypeRef"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIgnoreClassGeneratedByRef"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIgnoreClassGeneratedByRef"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIgnoreClassGeneratedByRef"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIgnoreClassRef"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIgnoreClassRef"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIgnoreClassRef"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIgnoreOuterRef"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIgnoreOuterRef"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIgnoreOuterRef"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsCountingMemory"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsCountingMemory"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsCountingMemory"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsCriticalError"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsCriticalError"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsCriticalError"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsError"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsError"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsError"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsFilterEditorOnly"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsFilterEditorOnly"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsFilterEditorOnly"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsLoading"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsLoading"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsLoading"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsLoadingFromCookedPackage"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsLoadingFromCookedPackage"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsLoadingFromCookedPackage"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsModifyingWeakAndStrongReferences"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsModifyingWeakAndStrongReferences"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsModifyingWeakAndStrongReferences"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsNetArchive"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsNetArchive"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsNetArchive"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsObjectReferenceCollector"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsObjectReferenceCollector"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsObjectReferenceCollector"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsPersistent"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsPersistent"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsPersistent"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsSaveGame"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsSaveGame"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsSaveGame"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsSaving"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsSaving"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsSaving"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsTextFormat"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsTextFormat"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsTextFormat"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArIsTransacting"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArIsTransacting"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArIsTransacting"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArLicenseeUE4Ver"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArLicenseeUE4Ver"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArLicenseeUE4Ver"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArLicenseeUEVer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArLicenseeUEVer"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArLicenseeUEVer"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArMaxSerializeSize"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArMaxSerializeSize"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArMaxSerializeSize"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArNoDelta"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArNoDelta"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArNoDelta"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArNoIntraPropertyDelta"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArNoIntraPropertyDelta"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArNoIntraPropertyDelta"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArPortFlags"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArPortFlags"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArPortFlags"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArRequiresLocalizationGather"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArRequiresLocalizationGather"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArRequiresLocalizationGather"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArSerializingDefaults"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArSerializingDefaults"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArSerializingDefaults"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArShouldSkipBulkData"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArShouldSkipBulkData"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArShouldSkipBulkData"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArShouldSkipCompilingAssets"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArShouldSkipCompilingAssets"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArShouldSkipCompilingAssets"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArUE4Ver"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArUE4Ver"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArUE4Ver"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArUEVer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArUEVer"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArUEVer"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArUseCustomPropertyList"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArUseCustomPropertyList"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArUseCustomPropertyList"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArUseUnversionedPropertySerialization"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArUseUnversionedPropertySerialization"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArUseUnversionedPropertySerialization"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("ArWantBinaryPropertySerialization"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("ArWantBinaryPropertySerialization"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("ArWantBinaryPropertySerialization"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("CookingTargetPlatform"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("CookingTargetPlatform"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("CookingTargetPlatform"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("CustomVersionContainer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("CustomVersionContainer"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("CustomVersionContainer"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("SerializedProperty"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("SerializedProperty"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("SerializedProperty"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArchiveState"), STR("bCustomVersionsAreReset"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArchiveState"), SYSSTR("bCustomVersionsAreReset"), -1); val != -1) Unreal::FArchiveState::MemberOffsets.emplace(STR("bCustomVersionsAreReset"), static_cast(val)); -if (auto val = parser.get_int64(STR("FField"), STR("ClassPrivate"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FField"), SYSSTR("ClassPrivate"), -1); val != -1) Unreal::FField::MemberOffsets.emplace(STR("ClassPrivate"), static_cast(val)); -if (auto val = parser.get_int64(STR("FField"), STR("FlagsPrivate"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FField"), SYSSTR("FlagsPrivate"), -1); val != -1) Unreal::FField::MemberOffsets.emplace(STR("FlagsPrivate"), static_cast(val)); -if (auto val = parser.get_int64(STR("FField"), STR("NamePrivate"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FField"), SYSSTR("NamePrivate"), -1); val != -1) Unreal::FField::MemberOffsets.emplace(STR("NamePrivate"), static_cast(val)); -if (auto val = parser.get_int64(STR("FField"), STR("Next"), -1); val != -1) Unreal::FField::MemberOffsets.emplace(STR("Next"), static_cast(val)); -if (auto val = parser.get_int64(STR("FField"), STR("Owner"), -1); val != -1) Unreal::FField::MemberOffsets.emplace(STR("Owner"), static_cast(val)); -if (auto val = parser.get_int64(STR("FClassProperty"), STR("MetaClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FField"), SYSSTR("Next"), -1); val != -1) Unreal::FField::MemberOffsets.emplace(STR("Next"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("FField"), SYSSTR("Owner"), -1); val != -1) + Unreal::FField::MemberOffsets.emplace(STR("Owner"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("FClassProperty"), SYSSTR("MetaClass"), -1); val != -1) Unreal::FClassProperty::MemberOffsets.emplace(STR("MetaClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("FBoolProperty"), STR("ByteMask"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FBoolProperty"), SYSSTR("ByteMask"), -1); val != -1) Unreal::FBoolProperty::MemberOffsets.emplace(STR("ByteMask"), static_cast(val)); -if (auto val = parser.get_int64(STR("FBoolProperty"), STR("ByteOffset"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FBoolProperty"), SYSSTR("ByteOffset"), -1); val != -1) Unreal::FBoolProperty::MemberOffsets.emplace(STR("ByteOffset"), static_cast(val)); -if (auto val = parser.get_int64(STR("FBoolProperty"), STR("FieldMask"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FBoolProperty"), SYSSTR("FieldMask"), -1); val != -1) Unreal::FBoolProperty::MemberOffsets.emplace(STR("FieldMask"), static_cast(val)); -if (auto val = parser.get_int64(STR("FBoolProperty"), STR("FieldSize"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FBoolProperty"), SYSSTR("FieldSize"), -1); val != -1) Unreal::FBoolProperty::MemberOffsets.emplace(STR("FieldSize"), static_cast(val)); -if (auto val = parser.get_int64(STR("UScriptStruct"), STR("CppStructOps"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UScriptStruct"), SYSSTR("CppStructOps"), -1); val != -1) Unreal::UScriptStruct::MemberOffsets.emplace(STR("CppStructOps"), static_cast(val)); -if (auto val = parser.get_int64(STR("UScriptStruct"), STR("StructFlags"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UScriptStruct"), SYSSTR("StructFlags"), -1); val != -1) Unreal::UScriptStruct::MemberOffsets.emplace(STR("StructFlags"), static_cast(val)); -if (auto val = parser.get_int64(STR("UScriptStruct"), STR("bCppStructOpsFromBaseClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UScriptStruct"), SYSSTR("bCppStructOpsFromBaseClass"), -1); val != -1) Unreal::UScriptStruct::MemberOffsets.emplace(STR("bCppStructOpsFromBaseClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("UScriptStruct"), STR("bPrepareCppStructOpsCompleted"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UScriptStruct"), SYSSTR("bPrepareCppStructOpsCompleted"), -1); val != -1) Unreal::UScriptStruct::MemberOffsets.emplace(STR("bPrepareCppStructOpsCompleted"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("ActiveLevelCollectionIndex"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("ActiveLevelCollectionIndex"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("ActiveLevelCollectionIndex"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("AudioDeviceHandle"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("AudioDeviceHandle"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("AudioDeviceHandle"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("AudioTimeSeconds"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("AudioTimeSeconds"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("AudioTimeSeconds"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("BlockTillLevelStreamingCompletedEpoch"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("BlockTillLevelStreamingCompletedEpoch"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("BlockTillLevelStreamingCompletedEpoch"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("BuildStreamingDataTimer"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("BuildStreamingDataTimer"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("BuildStreamingDataTimer"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("CachedViewInfoRenderedLastFrame"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("CachedViewInfoRenderedLastFrame"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("CachedViewInfoRenderedLastFrame"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("CleanupWorldTag"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("CleanupWorldTag"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("CleanupWorldTag"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("CommittedPersistentLevelName"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("CommittedPersistentLevelName"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("CommittedPersistentLevelName"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("ContentBundleManager"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("ContentBundleManager"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("ContentBundleManager"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("DebugDrawTraceTag"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("DebugDrawTraceTag"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("DebugDrawTraceTag"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("DeltaRealTimeSeconds"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("DeltaRealTimeSeconds"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("DeltaRealTimeSeconds"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("DeltaTimeSeconds"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("DeltaTimeSeconds"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("DeltaTimeSeconds"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("ExtraReferencedObjects"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("ExtraReferencedObjects"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("ExtraReferencedObjects"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("FullPurgeTriggered"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("FullPurgeTriggered"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("FullPurgeTriggered"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("IsInBlockTillLevelStreamingCompleted"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("IsInBlockTillLevelStreamingCompleted"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("IsInBlockTillLevelStreamingCompleted"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("LWILastAssignedUID"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("LWILastAssignedUID"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("LWILastAssignedUID"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("LastRenderTime"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("LastRenderTime"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("LastRenderTime"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("LastTimeUnbuiltLightingWasEncountered"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("LastTimeUnbuiltLightingWasEncountered"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("LastTimeUnbuiltLightingWasEncountered"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("LevelSequenceActors"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("LevelSequenceActors"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("LevelSequenceActors"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("NextSwitchCountdown"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("NextSwitchCountdown"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("NextSwitchCountdown"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("NextURL"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("NextURL"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("NumInvalidReflectionCaptureComponents"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("NextURL"), -1); val != -1) + Unreal::UWorld::MemberOffsets.emplace(STR("NextURL"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("NumInvalidReflectionCaptureComponents"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("NumInvalidReflectionCaptureComponents"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("NumLightingUnbuiltObjects"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("NumLightingUnbuiltObjects"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("NumLightingUnbuiltObjects"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("NumStreamingLevelsBeingLoaded"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("NumStreamingLevelsBeingLoaded"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("NumStreamingLevelsBeingLoaded"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("NumTextureStreamingDirtyResources"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("NumTextureStreamingDirtyResources"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("NumTextureStreamingDirtyResources"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("NumTextureStreamingUnbuiltComponents"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("NumTextureStreamingUnbuiltComponents"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("NumTextureStreamingUnbuiltComponents"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("NumUnbuiltReflectionCaptures"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("NumUnbuiltReflectionCaptures"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("NumUnbuiltReflectionCaptures"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("OnWorldPartitionInitializedEvent"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("OnWorldPartitionInitializedEvent"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("OnWorldPartitionInitializedEvent"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("OnWorldPartitionUninitializedEvent"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("OnWorldPartitionUninitializedEvent"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("OnWorldPartitionUninitializedEvent"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("OriginLocation"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("OriginLocation"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("OriginLocation"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("OriginOffsetThisFrame"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("OriginOffsetThisFrame"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("OriginOffsetThisFrame"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("PauseDelay"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("PauseDelay"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("PauseDelay"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("PerModuleDataObjects"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("PerModuleDataObjects"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("PerModuleDataObjects"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("PlayerNum"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("PlayerNum"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("PlayerNum"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("PreparingLevelNames"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("PreparingLevelNames"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("PreparingLevelNames"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("RealTimeSeconds"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("RealTimeSeconds"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("RealTimeSeconds"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("RequestedOriginLocation"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("RequestedOriginLocation"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("RequestedOriginLocation"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("ServerStreamingLevelsVisibility"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("ServerStreamingLevelsVisibility"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("ServerStreamingLevelsVisibility"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("StreamingLevelsPrefix"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("StreamingLevelsPrefix"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("StreamingLevelsPrefix"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("StreamingVolumeUpdateDelay"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("StreamingVolumeUpdateDelay"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("StreamingVolumeUpdateDelay"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("TimeSeconds"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("TimeSeconds"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("TimeSeconds"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("TimeSinceLastPendingKillPurge"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("TimeSinceLastPendingKillPurge"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("TimeSinceLastPendingKillPurge"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("UnpausedTimeSeconds"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("UnpausedTimeSeconds"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("UnpausedTimeSeconds"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("ViewLocationsRenderedLastFrame"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("ViewLocationsRenderedLastFrame"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("ViewLocationsRenderedLastFrame"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bActorsInitialized"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bActorsInitialized"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bActorsInitialized"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bAggressiveLOD"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bAggressiveLOD"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bAggressiveLOD"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bAllowAudioPlayback"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bAllowAudioPlayback"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bAllowAudioPlayback"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bAllowDeferredPhysicsStateCreation"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bAllowDeferredPhysicsStateCreation"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bAllowDeferredPhysicsStateCreation"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bAreConstraintsDirty"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bAreConstraintsDirty"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bAreConstraintsDirty"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bBegunPlay"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bBegunPlay"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bBegunPlay"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bCleanedUpWorld"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bCleanedUpWorld"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bCleanedUpWorld"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bCreateRenderStateForHiddenComponents"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bCreateRenderStateForHiddenComponents"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bCreateRenderStateForHiddenComponents"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bDebugDrawAllTraceTags"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bDebugDrawAllTraceTags"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bDebugDrawAllTraceTags"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bDebugFrameStepExecution"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bDebugFrameStepExecution"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bDebugFrameStepExecution"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bDebugPauseExecution"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bDebugPauseExecution"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bDebugPauseExecution"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bDoDelayedUpdateCullDistanceVolumes"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bDoDelayedUpdateCullDistanceVolumes"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bDoDelayedUpdateCullDistanceVolumes"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bDropDetail"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bDropDetail"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bDropDetail"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bHack_Force_UsesGameHiddenFlags_True"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bHack_Force_UsesGameHiddenFlags_True"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bHack_Force_UsesGameHiddenFlags_True"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bHasEverBeenInitialized"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bHasEverBeenInitialized"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bHasEverBeenInitialized"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bInTick"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bInTick"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bInitializedAndNeedsCleanup"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bInTick"), -1); val != -1) + Unreal::UWorld::MemberOffsets.emplace(STR("bInTick"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bInitializedAndNeedsCleanup"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bInitializedAndNeedsCleanup"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bIsBuilt"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bIsBuilt"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bIsBuilt"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bIsCameraMoveableWhenPaused"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bIsCameraMoveableWhenPaused"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bIsCameraMoveableWhenPaused"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bIsDefaultLevel"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bIsDefaultLevel"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bIsDefaultLevel"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bIsLevelStreamingFrozen"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bIsLevelStreamingFrozen"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bIsLevelStreamingFrozen"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bIsRunningConstructionScript"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bIsRunningConstructionScript"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bIsRunningConstructionScript"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bIsTearingDown"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bIsTearingDown"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bIsTearingDown"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bIsWorldInitialized"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bIsWorldInitialized"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bIsWorldInitialized"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bKismetScriptError"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bKismetScriptError"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bKismetScriptError"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bMarkedObjectsPendingKill"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bMarkedObjectsPendingKill"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bMarkedObjectsPendingKill"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bMatchStarted"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bMatchStarted"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bMatchStarted"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bMaterialParameterCollectionInstanceNeedsDeferredUpdate"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bMaterialParameterCollectionInstanceNeedsDeferredUpdate"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bMaterialParameterCollectionInstanceNeedsDeferredUpdate"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bOriginOffsetThisFrame"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bOriginOffsetThisFrame"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bOriginOffsetThisFrame"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bPlayersOnly"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bPlayersOnly"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bPlayersOnly"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bPlayersOnlyPending"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bPlayersOnlyPending"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bPlayersOnlyPending"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bPostTickComponentUpdate"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bPostTickComponentUpdate"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bPostTickComponentUpdate"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bRequestedBlockOnAsyncLoading"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bRequestedBlockOnAsyncLoading"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bRequestedBlockOnAsyncLoading"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bRequiresHitProxies"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bRequiresHitProxies"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bRequiresHitProxies"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bShouldDelayGarbageCollect"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bShouldDelayGarbageCollect"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bShouldDelayGarbageCollect"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bShouldForceUnloadStreamingLevels"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bShouldForceUnloadStreamingLevels"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bShouldForceUnloadStreamingLevels"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bShouldForceVisibleStreamingLevels"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bShouldForceVisibleStreamingLevels"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bShouldForceVisibleStreamingLevels"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bShouldSimulatePhysics"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bShouldSimulatePhysics"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bShouldSimulatePhysics"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bShouldTick"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bShouldTick"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bShouldTick"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bStartup"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bStartup"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bStartup"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bStreamingDataDirty"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bStreamingDataDirty"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bStreamingDataDirty"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bSupportsMakingInvisibleTransactionRequests"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bSupportsMakingInvisibleTransactionRequests"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bSupportsMakingInvisibleTransactionRequests"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bSupportsMakingVisibleTransactionRequests"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bSupportsMakingVisibleTransactionRequests"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bSupportsMakingVisibleTransactionRequests"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bTickNewlySpawned"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bTickNewlySpawned"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bTickNewlySpawned"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bTriggerPostLoadMap"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bTriggerPostLoadMap"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bTriggerPostLoadMap"), static_cast(val)); -if (auto val = parser.get_int64(STR("UWorld"), STR("bWorldWasLoadedThisTick"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UWorld"), SYSSTR("bWorldWasLoadedThisTick"), -1); val != -1) Unreal::UWorld::MemberOffsets.emplace(STR("bWorldWasLoadedThisTick"), static_cast(val)); -if (auto val = parser.get_int64(STR("FSetProperty"), STR("ElementProp"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FSetProperty"), SYSSTR("ElementProp"), -1); val != -1) Unreal::FSetProperty::MemberOffsets.emplace(STR("ElementProp"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("ClassAddReferencedObjects"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("ClassAddReferencedObjects"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("ClassAddReferencedObjects"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("ClassCastFlags"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("ClassCastFlags"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("ClassCastFlags"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("ClassConfigName"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("ClassConfigName"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("ClassConfigName"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("ClassConstructor"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("ClassConstructor"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("ClassConstructor"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("ClassDefaultObject"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("ClassDefaultObject"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("ClassDefaultObject"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("ClassFlags"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("ClassFlags"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("ClassFlags"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("ClassGeneratedBy"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("ClassGeneratedBy"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("ClassGeneratedBy"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("ClassUnique"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("ClassUnique"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("ClassUnique"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("ClassVTableHelperCtorCaller"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("ClassVTableHelperCtorCaller"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("ClassVTableHelperCtorCaller"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("ClassWithin"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("ClassWithin"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("ClassWithin"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("CppClassStaticFunctions"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("CppClassStaticFunctions"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("CppClassStaticFunctions"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("FirstOwnedClassRep"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("FirstOwnedClassRep"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("FirstOwnedClassRep"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("Interfaces"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("Interfaces"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("Interfaces"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("NetFields"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("NetFields"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("NetFields"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("SparseClassData"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("SparseClassData"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("SparseClassData"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("SparseClassDataStruct"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("SparseClassDataStruct"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("SparseClassDataStruct"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("UberGraphFramePointerProperty"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("UberGraphFramePointerProperty"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("UberGraphFramePointerProperty"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("bCooked"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("bCooked"), static_cast(val)); -if (auto val = parser.get_int64(STR("UClass"), STR("bLayoutChanging"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("bCooked"), -1); val != -1) + Unreal::UClass::MemberOffsets.emplace(STR("bCooked"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("UClass"), SYSSTR("bLayoutChanging"), -1); val != -1) Unreal::UClass::MemberOffsets.emplace(STR("bLayoutChanging"), static_cast(val)); -if (auto val = parser.get_int64(STR("UEnum"), STR("CppForm"), -1); val != -1) Unreal::UEnum::MemberOffsets.emplace(STR("CppForm"), static_cast(val)); -if (auto val = parser.get_int64(STR("UEnum"), STR("CppType"), -1); val != -1) Unreal::UEnum::MemberOffsets.emplace(STR("CppType"), static_cast(val)); -if (auto val = parser.get_int64(STR("UEnum"), STR("EnumDisplayNameFn"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UEnum"), SYSSTR("CppForm"), -1); val != -1) + Unreal::UEnum::MemberOffsets.emplace(STR("CppForm"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("UEnum"), SYSSTR("CppType"), -1); val != -1) + Unreal::UEnum::MemberOffsets.emplace(STR("CppType"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("UEnum"), SYSSTR("EnumDisplayNameFn"), -1); val != -1) Unreal::UEnum::MemberOffsets.emplace(STR("EnumDisplayNameFn"), static_cast(val)); -if (auto val = parser.get_int64(STR("UEnum"), STR("EnumFlags_Internal"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UEnum"), SYSSTR("EnumFlags_Internal"), -1); val != -1) Unreal::UEnum::MemberOffsets.emplace(STR("EnumFlags_Internal"), static_cast(val)); -if (auto val = parser.get_int64(STR("UEnum"), STR("EnumPackage"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UEnum"), SYSSTR("EnumPackage"), -1); val != -1) Unreal::UEnum::MemberOffsets.emplace(STR("EnumPackage"), static_cast(val)); -if (auto val = parser.get_int64(STR("UEnum"), STR("Names"), -1); val != -1) Unreal::UEnum::MemberOffsets.emplace(STR("Names"), static_cast(val)); -if (auto val = parser.get_int64(STR("FMapProperty"), STR("KeyProp"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("UEnum"), SYSSTR("Names"), -1); val != -1) Unreal::UEnum::MemberOffsets.emplace(STR("Names"), static_cast(val)); +if (auto val = parser.get_int64(SYSSTR("FMapProperty"), SYSSTR("KeyProp"), -1); val != -1) Unreal::FMapProperty::MemberOffsets.emplace(STR("KeyProp"), static_cast(val)); -if (auto val = parser.get_int64(STR("FMapProperty"), STR("ValueProp"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FMapProperty"), SYSSTR("ValueProp"), -1); val != -1) Unreal::FMapProperty::MemberOffsets.emplace(STR("ValueProp"), static_cast(val)); -if (auto val = parser.get_int64(STR("FStructProperty"), STR("Struct"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FStructProperty"), SYSSTR("Struct"), -1); val != -1) Unreal::FStructProperty::MemberOffsets.emplace(STR("Struct"), static_cast(val)); -if (auto val = parser.get_int64(STR("FArrayProperty"), STR("Inner"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FArrayProperty"), SYSSTR("Inner"), -1); val != -1) Unreal::FArrayProperty::MemberOffsets.emplace(STR("Inner"), static_cast(val)); -if (auto val = parser.get_int64(STR("FInterfaceProperty"), STR("InterfaceClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FInterfaceProperty"), SYSSTR("InterfaceClass"), -1); val != -1) Unreal::FInterfaceProperty::MemberOffsets.emplace(STR("InterfaceClass"), static_cast(val)); -if (auto val = parser.get_int64(STR("FFieldPathProperty"), STR("PropertyClass"), -1); val != -1) +if (auto val = parser.get_int64(SYSSTR("FFieldPathProperty"), SYSSTR("PropertyClass"), -1); val != -1) Unreal::FFieldPathProperty::MemberOffsets.emplace(STR("PropertyClass"), static_cast(val)); diff --git a/UE4SS/include/ExceptionHandling.hpp b/UE4SS/include/ExceptionHandling.hpp index c6745b158..ee87974a2 100644 --- a/UE4SS/include/ExceptionHandling.hpp +++ b/UE4SS/include/ExceptionHandling.hpp @@ -8,11 +8,11 @@ #define UE4SS_ERROR_OUTPUTTER() \ if (!Output::has_internal_error()) \ { \ - Output::send(STR("Error: {}\n"), to_wstring(e.what())); \ + Output::send(SYSSTR("Error: {}\n"), to_system(e.what())); \ } \ else \ { \ - printf_s("Internal Error: %s\n", e.what()); \ + fprintf(stderr, "Internal Error: %s\n", e.what()); \ } namespace RC diff --git a/UE4SS/include/GUI/ConsoleOutputDevice.hpp b/UE4SS/include/GUI/ConsoleOutputDevice.hpp index d1fdf58d6..f05768c88 100644 --- a/UE4SS/include/GUI/ConsoleOutputDevice.hpp +++ b/UE4SS/include/GUI/ConsoleOutputDevice.hpp @@ -30,7 +30,7 @@ namespace RC::Output public: auto has_optional_arg() const -> bool override; - auto receive(File::StringViewType fmt) const -> void override; - auto receive_with_optional_arg(File::StringViewType fmt, int32_t optional_arg = 0) const -> void override; + auto receive(SystemStringViewType fmt) const -> void override; + auto receive_with_optional_arg(SystemStringViewType fmt, int32_t optional_arg = 0) const -> void override; }; } // namespace RC::Output diff --git a/UE4SS/include/GUI/GUITab.hpp b/UE4SS/include/GUI/GUITab.hpp index 455e22567..c6a87cbfd 100644 --- a/UE4SS/include/GUI/GUITab.hpp +++ b/UE4SS/include/GUI/GUITab.hpp @@ -22,12 +22,12 @@ namespace RC::GUI private: RenderFunctionType render_function{}; CppUserModBase* owner{}; - StringType tab_name{}; + UEStringType tab_name{}; public: GUITab() = delete; - GUITab(StringViewType name, RenderFunctionType render_function) : tab_name(name), render_function(render_function){}; - GUITab(StringViewType name, RenderFunctionType render_function, CppUserModBase* owner) + GUITab(UEStringViewType name, RenderFunctionType render_function) : tab_name(name), render_function(render_function){}; + GUITab(UEStringViewType name, RenderFunctionType render_function, CppUserModBase* owner) : tab_name(name), render_function(render_function), owner(owner){}; ~GUITab() = default; diff --git a/UE4SS/include/GUI/LiveView.hpp b/UE4SS/include/GUI/LiveView.hpp index 1929cf773..3ac0306c0 100644 --- a/UE4SS/include/GUI/LiveView.hpp +++ b/UE4SS/include/GUI/LiveView.hpp @@ -61,9 +61,9 @@ namespace RC::GUI Output::Targets output{}; FProperty* property{}; UObject* container{}; - StringType object_name{}; - StringType property_name{}; - StringType property_value{}; + UEStringType object_name{}; + UEStringType property_name{}; + UEStringType property_value{}; size_t hash{}; std::string history{}; float history_previous_max_scroll_y{}; @@ -77,7 +77,7 @@ namespace RC::GUI std::pair function_hook_ids{}; Watch() = delete; - Watch(StringType&& object_name, StringType&& property_name); + Watch(UEStringType&& object_name, UEStringType&& property_name); }; private: diff --git a/UE4SS/include/GUI/LiveView/Filter/ClassNamesFilter.hpp b/UE4SS/include/GUI/LiveView/Filter/ClassNamesFilter.hpp index e4206c495..e3df573bb 100644 --- a/UE4SS/include/GUI/LiveView/Filter/ClassNamesFilter.hpp +++ b/UE4SS/include/GUI/LiveView/Filter/ClassNamesFilter.hpp @@ -8,9 +8,9 @@ namespace RC::GUI::Filter class ClassNamesFilter { public: - static inline StringType s_debug_name{STR("ClassNamesFilter")}; + static inline UEStringType s_debug_name{STR("ClassNamesFilter")}; static inline std::string s_internal_class_names{}; - static inline std::vector list_class_names; + static inline std::vector list_class_names; static inline bool b_is_exclude{true}; static auto post_eval(UObject* object) -> bool diff --git a/UE4SS/include/GUI/LiveView/Filter/DefaultObjectsOnly.hpp b/UE4SS/include/GUI/LiveView/Filter/DefaultObjectsOnly.hpp index 121d01312..b8bfd3123 100644 --- a/UE4SS/include/GUI/LiveView/Filter/DefaultObjectsOnly.hpp +++ b/UE4SS/include/GUI/LiveView/Filter/DefaultObjectsOnly.hpp @@ -7,7 +7,7 @@ namespace RC::GUI::Filter class DefaultObjectsOnly { public: - static inline StringType s_debug_name{STR("DefaultObjectsOnly")}; + static inline UEStringType s_debug_name{STR("DefaultObjectsOnly")}; static inline bool s_enabled{}; static auto pre_eval(UObject* object) -> bool diff --git a/UE4SS/include/GUI/LiveView/Filter/ExcludeClassName.hpp b/UE4SS/include/GUI/LiveView/Filter/ExcludeClassName.hpp new file mode 100644 index 000000000..6bf97062e --- /dev/null +++ b/UE4SS/include/GUI/LiveView/Filter/ExcludeClassName.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +namespace RC::GUI::Filter +{ + class ExcludeClassName + { + public: + static inline UEStringType s_debug_name{STR("ExcludeClassName")}; + static inline UEStringType s_value{}; + static inline std::string s_internal_value{}; + + static auto post_eval(UObject* object) -> bool + { + if (!s_value.empty()) + { + auto class_name = object->GetClassPrivate()->GetName(); + auto pos = class_name.find(s_value); + return pos != class_name.npos; + } + else + { + return false; + } + } + }; +} // namespace RC::GUI::Filter diff --git a/UE4SS/include/GUI/LiveView/Filter/FunctionParamFlags.hpp b/UE4SS/include/GUI/LiveView/Filter/FunctionParamFlags.hpp index 3880d367a..be64a26aa 100644 --- a/UE4SS/include/GUI/LiveView/Filter/FunctionParamFlags.hpp +++ b/UE4SS/include/GUI/LiveView/Filter/FunctionParamFlags.hpp @@ -9,7 +9,7 @@ namespace RC::GUI::Filter class FunctionParamFlags { public: - static inline StringType s_debug_name{STR("FunctionParamFlags")}; + static inline UEStringType s_debug_name{STR("FunctionParamFlags")}; static inline bool s_enabled{}; static inline std::array s_checkboxes{}; static inline EPropertyFlags s_value{}; diff --git a/UE4SS/include/GUI/LiveView/Filter/HasProperty.hpp b/UE4SS/include/GUI/LiveView/Filter/HasProperty.hpp index 3f2f6ce4a..e5b19b921 100644 --- a/UE4SS/include/GUI/LiveView/Filter/HasProperty.hpp +++ b/UE4SS/include/GUI/LiveView/Filter/HasProperty.hpp @@ -8,9 +8,9 @@ namespace RC::GUI::Filter class HasProperty { public: - static inline StringType s_debug_name{STR("HasProperty")}; + static inline UEStringType s_debug_name{STR("HasProperty")}; static inline std::string s_internal_properties{}; - static inline std::vector list_properties{}; + static inline std::vector list_properties{}; static auto post_eval(UObject* object) -> bool { diff --git a/UE4SS/include/GUI/LiveView/Filter/HasPropertyType.hpp b/UE4SS/include/GUI/LiveView/Filter/HasPropertyType.hpp index 97484ba7a..44af3a079 100644 --- a/UE4SS/include/GUI/LiveView/Filter/HasPropertyType.hpp +++ b/UE4SS/include/GUI/LiveView/Filter/HasPropertyType.hpp @@ -10,7 +10,7 @@ namespace RC::GUI::Filter class HasPropertyType { public: - static inline StringType s_debug_name{STR("HasPropertyType")}; + static inline UEStringType s_debug_name{STR("HasPropertyType")}; static inline std::string s_internal_property_types{}; static inline std::vector list_property_types{}; diff --git a/UE4SS/include/GUI/LiveView/Filter/IncludeDefaultObjects.hpp b/UE4SS/include/GUI/LiveView/Filter/IncludeDefaultObjects.hpp index 2dc3f3b9a..655d870c5 100644 --- a/UE4SS/include/GUI/LiveView/Filter/IncludeDefaultObjects.hpp +++ b/UE4SS/include/GUI/LiveView/Filter/IncludeDefaultObjects.hpp @@ -7,7 +7,7 @@ namespace RC::GUI::Filter class IncludeDefaultObjects { public: - static inline StringType s_debug_name{STR("IncludeDefaultObjects")}; + static inline UEStringType s_debug_name{STR("IncludeDefaultObjects")}; static inline bool s_enabled{true}; static auto pre_eval(UObject* object) -> bool diff --git a/UE4SS/include/GUI/LiveView/Filter/InstancesOnly.hpp b/UE4SS/include/GUI/LiveView/Filter/InstancesOnly.hpp index 298afae00..c36be7839 100644 --- a/UE4SS/include/GUI/LiveView/Filter/InstancesOnly.hpp +++ b/UE4SS/include/GUI/LiveView/Filter/InstancesOnly.hpp @@ -7,7 +7,7 @@ namespace RC::GUI::Filter class InstancesOnly { public: - static inline StringType s_debug_name{STR("InstancesOnly")}; + static inline UEStringType s_debug_name{STR("InstancesOnly")}; static inline bool s_enabled{}; static auto pre_eval(UObject* object) -> bool { diff --git a/UE4SS/include/GUI/LiveView/Filter/NonInstancesOnly.hpp b/UE4SS/include/GUI/LiveView/Filter/NonInstancesOnly.hpp index 23bfb47ef..9716d8a2b 100644 --- a/UE4SS/include/GUI/LiveView/Filter/NonInstancesOnly.hpp +++ b/UE4SS/include/GUI/LiveView/Filter/NonInstancesOnly.hpp @@ -8,7 +8,7 @@ namespace RC::GUI::Filter class NonInstancesOnly { public: - static inline StringType s_debug_name{STR("NonInstancesOnly")}; + static inline UEStringType s_debug_name{STR("NonInstancesOnly")}; static inline bool s_enabled{}; static auto pre_eval(UObject* object) -> bool diff --git a/UE4SS/include/LuaCustomMemberFunctions.hpp b/UE4SS/include/LuaCustomMemberFunctions.hpp index d3f8c5b3f..2c6bdae6a 100644 --- a/UE4SS/include/LuaCustomMemberFunctions.hpp +++ b/UE4SS/include/LuaCustomMemberFunctions.hpp @@ -49,9 +49,9 @@ namespace RC::LuaBackCompat // Backwards compatibility with UE4SS 1.3. - auto StaticFindObject(UClass* ObjectClass, UObject* InObjectPackage, const wchar_t* OrigInName, bool bExactClass = false) -> UObject*; - auto StaticFindObject(const wchar_t* OrigInName) -> UObject*; - auto NotifyOnNewObject(const wchar_t* class_name, std::function& callable) -> void; + auto StaticFindObject(UClass* ObjectClass, UObject* InObjectPackage, const UECharType* OrigInName, bool bExactClass = false) -> UObject*; + auto StaticFindObject(const UECharType* OrigInName) -> UObject*; + auto NotifyOnNewObject(const UECharType* class_name, std::function& callable) -> void; auto lua_RegisterHook_wrapper(lua_State*) -> int; auto lua_UObjectBase_IsA_wrapper(lua_State*) -> int; diff --git a/UE4SS/include/LuaType/LuaCustomProperty.hpp b/UE4SS/include/LuaType/LuaCustomProperty.hpp index b19edc7e2..c69903742 100644 --- a/UE4SS/include/LuaType/LuaCustomProperty.hpp +++ b/UE4SS/include/LuaType/LuaCustomProperty.hpp @@ -4,6 +4,8 @@ #include #include +#include + namespace RC::Unreal { class UObject; @@ -17,11 +19,11 @@ namespace RC::LuaType class LuaCustomProperty { public: - std::wstring m_name{}; + SystemStringType m_name{}; std::unique_ptr m_property; public: - LuaCustomProperty(std::wstring name, std::unique_ptr property); + LuaCustomProperty(SystemStringType name, std::unique_ptr property); private: class PropertyList @@ -30,9 +32,9 @@ namespace RC::LuaType std::vector properties; public: - auto add(std::wstring property_name, std::unique_ptr) -> void; + auto add(SystemStringType property_name, std::unique_ptr) -> void; auto clear() -> void; - auto find_or_nullptr(Unreal::UObject* base, std::wstring property_name) -> Unreal::FProperty*; + auto find_or_nullptr(Unreal::UObject* base, SystemStringType property_name) -> Unreal::FProperty*; }; public: diff --git a/UE4SS/include/LuaType/LuaUObject.hpp b/UE4SS/include/LuaType/LuaUObject.hpp index ea81196a3..4fcc724c9 100644 --- a/UE4SS/include/LuaType/LuaUObject.hpp +++ b/UE4SS/include/LuaType/LuaUObject.hpp @@ -462,7 +462,7 @@ namespace RC::LuaType { lua.throw_error("Function 'GetProperty' requires a string as the first parameter"); } - std::wstring property_name = to_wstring(lua.get_string(2)); + auto property_name = to_system(lua.get_string(2)); auto reflection_table = lua.get_table(); const auto& reflected_object = reflection_table.get_userdata_field("ReflectedObject").get_remote_cpp_object(); @@ -478,7 +478,7 @@ namespace RC::LuaType { obj_as_struct = reflected_object->GetClassPrivate(); } - auto* property = obj_as_struct->FindProperty(Unreal::FName(property_name)); + auto* property = obj_as_struct->FindProperty(Unreal::FName(to_ue(property_name))); construct_xproperty(lua, property); return 1; @@ -586,7 +586,7 @@ No overload found for function 'UObject.ProcessConsoleExec'. { lua.throw_error(error_overload_not_found); } - auto cmd = to_wstring(lua.get_string()); + auto cmd = to_system(lua.get_string()); if (lua.get_stack_size() < 2) { @@ -601,7 +601,7 @@ No overload found for function 'UObject.ProcessConsoleExec'. auto executor = lua.get_userdata(); auto ar = Unreal::FOutputDevice{}; - auto return_value = lua_object.get_remote_cpp_object()->ProcessConsoleExec(cmd.c_str(), ar, executor.get_remote_cpp_object()); + auto return_value = lua_object.get_remote_cpp_object()->ProcessConsoleExec(to_ue_string(cmd).c_str(), ar, executor.get_remote_cpp_object()); lua.set_bool(return_value); return 1; @@ -641,7 +641,7 @@ No overload found for function 'UObject.ProcessConsoleExec'. { auto& lua_object = lua.get_userdata(); - const std::wstring& member_name = to_const_wstring(lua.get_string()); + auto member_name = to_system_string(lua.get_string()); // If nullptr then we assume the UObject wasn't found so lets return an invalid UObject to Lua // This allows the safe chaining of "__index" as long as the Lua script checks ":IsValid()" before using the object @@ -656,17 +656,17 @@ No overload found for function 'UObject.ProcessConsoleExec'. SelfType::construct(lua, static_cast(nullptr)); break; case Operation::Set: - Output::send(STR("[Lua][Error] Tried setting member variable '{}' but UObject instance is nullptr\n"), member_name); + Output::send(SYSSTR("[Lua][Error] Tried setting member variable '{}' but UObject instance is nullptr\n"), member_name); break; default: - Output::send(STR("[Lua][Error] The UObject instance is nullptr & operation type was invalid\n")); + Output::send(SYSSTR("[Lua][Error] The UObject instance is nullptr & operation type was invalid\n")); break; } return; } - Unreal::FName property_name = Unreal::FName(member_name); + Unreal::FName property_name = Unreal::FName(to_ue(member_name)); Unreal::FField* field = LuaCustomProperty::StaticStorage::property_list.find_or_nullptr(lua_object.get_remote_cpp_object(), member_name); if (!field) @@ -777,10 +777,10 @@ No overload found for function 'UObject.ProcessConsoleExec'. { // We can either throw an error and kill the execution /**/ - std::wstring property_type_name = property_type.ToString(); + auto property_type_name = to_string(property_type.ToString()); lua.throw_error(std::format( "[LocalUnrealParam::prepare_to_handle] Tried accessing unreal property without a registered handler. Property type '{}' not supported.", - to_string(property_type_name))); + property_type_name)); //*/ // Or we can treat unhandled property types as some sort of generic type diff --git a/UE4SS/include/Mod/CppMod.hpp b/UE4SS/include/Mod/CppMod.hpp index 92d90e147..3c0839ec9 100644 --- a/UE4SS/include/Mod/CppMod.hpp +++ b/UE4SS/include/Mod/CppMod.hpp @@ -22,7 +22,7 @@ namespace RC typedef void (*uninstall_type)(CppUserModBase*); private: - std::wstring m_dlls_path; + SystemStringType m_dlls_path; HMODULE m_main_dll_module = NULL; DLL_DIRECTORY_COOKIE m_dlls_path_cookie = NULL; @@ -32,7 +32,7 @@ namespace RC CppUserModBase* m_mod = nullptr; public: - CppMod(UE4SSProgram&, std::wstring&& mod_name, std::wstring&& mod_path); + CppMod(UE4SSProgram&, SystemStringType&& mod_name, SystemStringType&& mod_path); CppMod(CppMod&) = delete; CppMod(CppMod&&) = delete; ~CppMod() override; @@ -41,7 +41,7 @@ namespace RC auto start_mod() -> void override; auto uninstall() -> void override; - auto fire_on_lua_start(StringViewType mod_name, + auto fire_on_lua_start(SystemStringViewType mod_name, LuaMadeSimple::Lua& lua, LuaMadeSimple::Lua& main_lua, LuaMadeSimple::Lua& async_lua, @@ -50,7 +50,7 @@ namespace RC auto fire_on_lua_start(LuaMadeSimple::Lua& lua, LuaMadeSimple::Lua& main_lua, LuaMadeSimple::Lua& async_lua, std::vector& hook_luas) -> void; - auto fire_on_lua_stop(StringViewType mod_name, + auto fire_on_lua_stop(SystemStringViewType mod_name, LuaMadeSimple::Lua& lua, LuaMadeSimple::Lua& main_lua, LuaMadeSimple::Lua& async_lua, @@ -63,6 +63,6 @@ namespace RC auto fire_ui_init() -> void override; auto fire_program_start() -> void override; auto fire_update() -> void override; - auto fire_dll_load(std::wstring_view dll_name) -> void; + auto fire_dll_load(SystemStringViewType dll_name) -> void; }; } // namespace RC diff --git a/UE4SS/include/Mod/CppUserModBase.hpp b/UE4SS/include/Mod/CppUserModBase.hpp index 710f17210..c01435d20 100644 --- a/UE4SS/include/Mod/CppUserModBase.hpp +++ b/UE4SS/include/Mod/CppUserModBase.hpp @@ -12,11 +12,11 @@ namespace RC { struct ModMetadata { - const StringType ModName{}; - const StringType ModVersion{}; - const StringType ModDescription{}; - const StringType ModAuthors{}; - const StringType ModIntendedSDKVersion{}; + const UEStringType ModName{}; + const UEStringType ModVersion{}; + const UEStringType ModDescription{}; + const UEStringType ModAuthors{}; + const UEStringType ModIntendedSDKVersion{}; }; namespace LuaMadeSimple @@ -32,11 +32,11 @@ namespace RC std::vector> GUITabs{}; public: - StringType ModName{}; - StringType ModVersion{}; - StringType ModDescription{}; - StringType ModAuthors{}; - StringType ModIntendedSDKVersion{}; + UEStringType ModName{}; + UEStringType ModVersion{}; + UEStringType ModDescription{}; + UEStringType ModAuthors{}; + UEStringType ModIntendedSDKVersion{}; public: RC_UE4SS_API CppUserModBase(); @@ -72,7 +72,7 @@ namespace RC * @param async_lua This is the Lua instance for asynchronous things like ExecuteAsync and ExecuteWithDelay. * @param hook_luas This is a container of Lua instances that are used for game-thread hooks like ExecuteInGameThread. */ - RC_UE4SS_API virtual auto on_lua_start(StringViewType mod_name, + RC_UE4SS_API virtual auto on_lua_start(SystemStringViewType mod_name, LuaMadeSimple::Lua& lua, LuaMadeSimple::Lua& main_lua, LuaMadeSimple::Lua& async_lua, @@ -103,7 +103,7 @@ namespace RC * @param async_lua This is the Lua instance for asynchronous things like ExecuteAsync and ExecuteWithDelay. * @param hook_luas This is a container of Lua instances that are used for game-thread hooks like ExecuteInGameThread. */ - RC_UE4SS_API virtual auto on_lua_stop(StringViewType mod_name, + RC_UE4SS_API virtual auto on_lua_stop(SystemStringViewType mod_name, LuaMadeSimple::Lua& lua, LuaMadeSimple::Lua& main_lua, LuaMadeSimple::Lua& async_lua, @@ -125,14 +125,14 @@ namespace RC { } - RC_UE4SS_API virtual auto on_dll_load(std::wstring_view dll_name) -> void + RC_UE4SS_API virtual auto on_dll_load(SystemStringViewType dll_name) -> void { } RC_UE4SS_API virtual auto render_tab() -> void{}; protected: - RC_UE4SS_API auto register_tab(std::wstring_view tab_name, GUI::GUITab::RenderFunctionType) -> void; + RC_UE4SS_API auto register_tab(UEStringViewType tab_name, GUI::GUITab::RenderFunctionType) -> void; RC_UE4SS_API auto register_keydown_event(Input::Key, const Input::EventCallbackCallable&, uint8_t custom_data = 0) -> void; RC_UE4SS_API auto register_keydown_event(Input::Key, const Input::Handler::ModifierKeyArray&, const Input::EventCallbackCallable&, uint8_t custom_data = 0) -> void; diff --git a/UE4SS/include/Mod/LuaMod.hpp b/UE4SS/include/Mod/LuaMod.hpp index 31ad8435c..029e94987 100644 --- a/UE4SS/include/Mod/LuaMod.hpp +++ b/UE4SS/include/Mod/LuaMod.hpp @@ -26,7 +26,7 @@ namespace RC class LuaMod : public Mod { private: - std::wstring m_scripts_path; + SystemStringType m_scripts_path; LuaMadeSimple::Lua& m_lua; public: @@ -97,19 +97,19 @@ namespace RC static inline std::vector m_call_function_by_name_with_arguments_post_callbacks; static inline std::vector m_local_player_exec_pre_callbacks; static inline std::vector m_local_player_exec_post_callbacks; - static inline std::unordered_map m_global_command_lua_callbacks; - static inline std::unordered_map m_custom_command_lua_pre_callbacks; + static inline std::unordered_map m_global_command_lua_callbacks; + static inline std::unordered_map m_custom_command_lua_pre_callbacks; static inline std::vector m_game_thread_actions{}; // This is storage that persists through hot-reloads. - static inline std::unordered_map m_shared_lua_variables{}; - static inline std::unordered_map m_custom_event_callbacks{}; + static inline std::unordered_map m_shared_lua_variables{}; + static inline std::unordered_map m_custom_event_callbacks{}; static inline std::vector m_load_map_pre_callbacks{}; static inline std::vector m_load_map_post_callbacks{}; static inline std::vector m_init_game_state_pre_callbacks{}; static inline std::vector m_init_game_state_post_callbacks{}; static inline std::vector m_begin_play_pre_callbacks{}; static inline std::vector m_begin_play_post_callbacks{}; - static inline std::unordered_map m_script_hook_callbacks{}; + static inline std::unordered_map m_script_hook_callbacks{}; static inline std::unordered_map m_generic_hook_id_to_native_hook_id{}; // Generic hook ids are generated incrementally so the first one is 0 and the next one is always +1 from the last id. static inline int32_t m_last_generic_hook_id{}; @@ -124,7 +124,7 @@ namespace RC std::mutex m_actions_lock{}; public: - LuaMod(UE4SSProgram&, std::wstring&& mod_name, std::wstring&& mod_path); + LuaMod(UE4SSProgram&, SystemStringType&& mod_name, SystemStringType&& mod_path); ~LuaMod() override = default; private: diff --git a/UE4SS/include/Mod/Mod.hpp b/UE4SS/include/Mod/Mod.hpp index 0f22559b4..19d8f145d 100644 --- a/UE4SS/include/Mod/Mod.hpp +++ b/UE4SS/include/Mod/Mod.hpp @@ -26,8 +26,9 @@ namespace RC protected: #pragma warning(disable : 4251) - std::wstring m_mod_name; - std::wstring m_mod_path; + // we almost never use this to interact with UE + SystemStringType m_mod_name; + SystemStringType m_mod_path; #pragma warning(default : 4251) protected: @@ -45,11 +46,11 @@ namespace RC }; public: - Mod(UE4SSProgram&, std::wstring&& mod_name, std::wstring&& mod_path); + Mod(UE4SSProgram&, SystemStringType&& mod_name, SystemStringType&& mod_path); virtual ~Mod() = default; public: - auto get_name() const -> std::wstring_view; + auto get_name() const -> SystemStringViewType; virtual auto start_mod() -> void = 0; virtual auto uninstall() -> void = 0; diff --git a/UE4SS/include/ObjectDumper/ObjectToString.hpp b/UE4SS/include/ObjectDumper/ObjectToString.hpp index 0b0525a2b..e4f72a78d 100644 --- a/UE4SS/include/ObjectDumper/ObjectToString.hpp +++ b/UE4SS/include/ObjectDumper/ObjectToString.hpp @@ -8,11 +8,11 @@ namespace RC::ObjectDumper { using ToStringHash = size_t; - using ObjectToStringDecl = std::function; + using ObjectToStringDecl = std::function; extern std::unordered_map object_to_string_functions; using ObjectToStringComplexDeclCallable = const std::function&; - using ObjectToStringComplexDecl = std::function; + using ObjectToStringComplexDecl = std::function; extern std::unordered_map object_to_string_complex_functions; auto get_to_string(size_t hash) -> ObjectToStringDecl; @@ -20,33 +20,33 @@ namespace RC::ObjectDumper auto to_string_exists(size_t hash) -> bool; auto to_string_complex_exists(size_t hash) -> bool; - auto object_trivial_dump_to_string(void* p_this, std::wstring& out_line, const wchar_t* post_delimiter = L".") -> void; - auto object_to_string(void* p_this, std::wstring& out_line) -> void; + auto object_trivial_dump_to_string(void* p_this, SystemStringType& out_line, const SystemCharType* post_delimiter = SYSSTR(".")) -> void; + auto object_to_string(void* p_this, SystemStringType& out_line) -> void; - auto property_trivial_dump_to_string(void* p_this, std::wstring& out_line) -> void; - auto property_to_string(void* p_this, std::wstring& out_line) -> void; + auto property_trivial_dump_to_string(void* p_this, SystemStringType& out_line) -> void; + auto property_to_string(void* p_this, SystemStringType& out_line) -> void; - auto arrayproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto arrayproperty_to_string_complex(void* p_this, std::wstring& out_line, ObjectToStringComplexDeclCallable callable) -> void; + auto arrayproperty_to_string(void* p_this, SystemStringType& out_line) -> void; + auto arrayproperty_to_string_complex(void* p_this, SystemStringType& out_line, ObjectToStringComplexDeclCallable callable) -> void; - auto mapproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto mapproperty_to_string_complex(void* p_this, std::wstring& out_line, ObjectToStringComplexDeclCallable callable) -> void; + auto mapproperty_to_string(void* p_this, SystemStringType& out_line) -> void; + auto mapproperty_to_string_complex(void* p_this, SystemStringType& out_line, ObjectToStringComplexDeclCallable callable) -> void; - auto classproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto delegateproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto fieldpathproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto interfaceproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto multicastdelegateproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto objectproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto structproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto enumproperty_to_string(void* p_this, std::wstring& out_line) -> void; - auto boolproperty_to_string(void* p_this, std::wstring& out_line) -> void; + auto classproperty_to_string(void* p_this, SystemStringType& out_line) -> void; + auto delegateproperty_to_string(void* p_this, SystemStringType& out_line) -> void; + auto fieldpathproperty_to_string(void* p_this, SystemStringType& out_line) -> void; + auto interfaceproperty_to_string(void* p_this, SystemStringType& out_line) -> void; + auto multicastdelegateproperty_to_string(void* p_this, SystemStringType& out_line) -> void; + auto objectproperty_to_string(void* p_this, SystemStringType& out_line) -> void; + auto structproperty_to_string(void* p_this, SystemStringType& out_line) -> void; + auto enumproperty_to_string(void* p_this, SystemStringType& out_line) -> void; + auto boolproperty_to_string(void* p_this, SystemStringType& out_line) -> void; - auto enum_to_string(void* p_this, std::wstring& out_line) -> void; - auto struct_to_string(void* p_this, std::wstring& out_line) -> void; - auto function_to_string(void* p_this, std::wstring& out_line) -> void; + auto enum_to_string(void* p_this, SystemStringType& out_line) -> void; + auto struct_to_string(void* p_this, SystemStringType& out_line) -> void; + auto function_to_string(void* p_this, SystemStringType& out_line) -> void; - auto scriptstruct_to_string_complex(void* p_this, std::wstring& out_line, ObjectToStringComplexDeclCallable callable) -> void; + auto scriptstruct_to_string_complex(void* p_this, SystemStringType& out_line, ObjectToStringComplexDeclCallable callable) -> void; auto init() -> void; } // namespace RC::ObjectDumper diff --git a/UE4SS/include/Platform.hpp b/UE4SS/include/Platform.hpp new file mode 100644 index 000000000..8ec568f2a --- /dev/null +++ b/UE4SS/include/Platform.hpp @@ -0,0 +1,5 @@ +#pragma once +#include + +std::filesystem::path get_executable_path(); +void add_dlsearch_folder(std::filesystem::path& path); diff --git a/UE4SS/include/SDKGenerator/Common.hpp b/UE4SS/include/SDKGenerator/Common.hpp index ce5793824..5280e7d88 100644 --- a/UE4SS/include/SDKGenerator/Common.hpp +++ b/UE4SS/include/SDKGenerator/Common.hpp @@ -31,19 +31,19 @@ namespace RC }; auto is_integral_type(Unreal::FProperty* property) -> bool; - auto get_native_enum_name(Unreal::UEnum* uenum, bool include_type = true) -> File::StringType; + auto get_native_enum_name(Unreal::UEnum* uenum, bool include_type = true) -> SystemStringType; auto generate_property_cxx_name(Unreal::FProperty* property, bool is_top_level_declaration, Unreal::UObject* class_context, - EnableForwardDeclarations = EnableForwardDeclarations::No) -> File::StringType; - auto generate_property_lua_name(Unreal::FProperty* property, bool is_top_level_declaration, Unreal::UObject* class_context) -> File::StringType; - auto sanitize_property_name(const File::StringType& property_name) -> File::StringType; - auto generate_delegate_name(Unreal::FProperty* property, const File::StringType& context_name) -> File::StringType; - auto get_native_class_name(Unreal::UClass* uclass, bool interface_name = false) -> File::StringType; - auto get_native_struct_name(Unreal::UScriptStruct* script_struct) -> File::StringType; + EnableForwardDeclarations = EnableForwardDeclarations::No) -> SystemStringType; + auto generate_property_lua_name(Unreal::FProperty* property, bool is_top_level_declaration, Unreal::UObject* class_context) -> SystemStringType; + auto sanitize_property_name(const SystemStringType& property_name) -> SystemStringType; + auto generate_delegate_name(Unreal::FProperty* property, const SystemStringType& context_name) -> SystemStringType; + auto get_native_class_name(Unreal::UClass* uclass, bool interface_name = false) -> SystemStringType; + auto get_native_struct_name(Unreal::UScriptStruct* script_struct) -> SystemStringType; auto get_native_delegate_type_name(Unreal::UFunction* signature_function, Unreal::UClass* current_class = nullptr, bool strip_outer_name = false) - -> File::StringType; + -> SystemStringType; auto is_delegate_signature_function(Unreal::UFunction* signature_function) -> bool; - auto strip_delegate_signature_postfix(Unreal::UFunction* signature_function) -> File::StringType; + auto strip_delegate_signature_postfix(Unreal::UFunction* signature_function) -> SystemStringType; } // namespace UEGenerator } // namespace RC diff --git a/UE4SS/include/SDKGenerator/JSONDumper.hpp b/UE4SS/include/SDKGenerator/JSONDumper.hpp index fea36c867..1a117118c 100644 --- a/UE4SS/include/SDKGenerator/JSONDumper.hpp +++ b/UE4SS/include/SDKGenerator/JSONDumper.hpp @@ -9,5 +9,5 @@ namespace RC namespace RC::UEGenerator::JSONDumper { - auto dump_to_json(File::StringViewType file_name) -> void; + auto dump_to_json(SystemStringType file_name) -> void; } diff --git a/UE4SS/include/SDKGenerator/UEHeaderGenerator.hpp b/UE4SS/include/SDKGenerator/UEHeaderGenerator.hpp index 59cf49670..b86224015 100644 --- a/UE4SS/include/SDKGenerator/UEHeaderGenerator.hpp +++ b/UE4SS/include/SDKGenerator/UEHeaderGenerator.hpp @@ -65,14 +65,14 @@ namespace RC::UEGenerator struct PropertyTypeDeclarationContext { - std::wstring context_name; + SystemStringType context_name; class GeneratedSourceFile* source_file; bool is_top_level_declaration; bool* out_is_bitmask_bool; - PropertyTypeDeclarationContext(const std::wstring& context_name, + PropertyTypeDeclarationContext(const SystemStringType& context_name, GeneratedSourceFile* source_file = NULL, bool is_top_level_declaration = false, bool* out_is_bitmask_bool = NULL) @@ -91,21 +91,21 @@ namespace RC::UEGenerator struct StringInsensitiveCompare { - auto operator()(const std::wstring& a, const std::wstring& b) const -> bool + auto operator()(const SystemStringType& a, const SystemStringType& b) const -> bool { return _wcsicmp(a.c_str(), b.c_str()) < 0; } }; - using CaseInsensitiveSet = std::set; + using CaseInsensitiveSet = ::std::set; class GeneratedFile { protected: - std::wstring m_file_base_name; + SystemStringType m_file_base_name; FFilePath m_full_file_path; - std::wstring m_file_contents_buffer; + SystemStringType m_file_contents_buffer; int32_t m_current_indent_count; public: @@ -117,34 +117,52 @@ namespace RC::UEGenerator GeneratedFile(GeneratedFile&&) = default; auto operator=(const GeneratedFile&) -> void = delete; - auto append_line(const std::wstring& line) -> void; - auto append_line_no_indent(const std::wstring& line) -> void; + auto append_line(const SystemStringType& line) -> void; + auto append_line_no_indent(const SystemStringType& line) -> void; auto begin_indent_level() -> void; auto end_indent_level() -> void; auto serialize_file_content_to_disk() -> bool; virtual auto has_content_to_save() const -> bool; - virtual auto generate_file_contents() -> std::wstring; + virtual auto generate_file_contents() -> SystemStringType; }; class GeneratedSourceFile : public GeneratedFile { private: - std::wstring m_file_module_name; + SystemStringType m_file_module_name; std::map m_dependencies; - std::set m_extra_includes; - mutable std::set m_dependency_module_names; + std::set m_extra_includes; + mutable std::set m_dependency_module_names; UObject* m_object; GeneratedSourceFile* m_header_file; bool m_is_implementation_file; bool m_needs_get_type_hash; public: - std::wstring m_implementation_constructor; - std::unordered_set parent_property_names{}; - std::map> attachments{}; - - GeneratedSourceFile(const FFilePath& file_path, const std::wstring& file_module_name, bool is_implementation_file, UObject* object); + // workaround for clang tuple bug + // https://github.com/llvm/llvm-project/issues/17042 + struct attachment_data + { + SystemStringType property_type; // <0> + SystemStringType attach_string; // <1> + bool access_type; // <2> + + attachment_data(const SystemStringType& property_type, const SystemStringType& attach_string, bool access_type) + : property_type(property_type), attach_string(attach_string), access_type(access_type) + { + } + + attachment_data(const attachment_data& other) = default; + attachment_data(attachment_data&& other) = default; + auto operator=(const attachment_data&) -> attachment_data& = default; + auto operator=(attachment_data&&) -> attachment_data& = default; + }; + SystemStringType m_implementation_constructor; + std::unordered_set parent_property_names{}; + std::map attachments{}; + + GeneratedSourceFile(const FFilePath& file_path, const SystemStringType& file_module_name, bool is_implementation_file, UObject* object); // Delete copy and move constructors and assignment operator GeneratedSourceFile(const GeneratedSourceFile&) = delete; @@ -153,9 +171,9 @@ namespace RC::UEGenerator auto set_header_file(GeneratedSourceFile* header_file) -> void; auto add_dependency_object(UObject* object, DependencyLevel dependency_level) -> void; - auto add_extra_include(const std::wstring& included_file_name) -> void; + auto add_extra_include(const SystemStringType& included_file_name) -> void; - auto get_header_module_name() const -> const std::wstring& + auto get_header_module_name() const -> const SystemStringType& { return m_file_module_name; } @@ -179,30 +197,30 @@ namespace RC::UEGenerator virtual auto has_content_to_save() const -> bool override; - auto copy_dependency_module_names(std::set& out_dependency_module_names) const -> void + auto copy_dependency_module_names(std::set& out_dependency_module_names) const -> void { out_dependency_module_names.insert(m_dependency_module_names.begin(), m_dependency_module_names.end()); } auto static create_source_file(const FFilePath& root_dir, - const std::wstring& module_name, - const std::wstring& base_name, + const SystemStringType& module_name, + const SystemStringType& base_name, bool is_implementation_file, UObject* object) -> GeneratedSourceFile; - virtual auto generate_file_contents() -> std::wstring override; + virtual auto generate_file_contents() -> SystemStringType override; protected: auto has_dependency(UObject* object, DependencyLevel dependency_level) -> bool; - auto generate_pre_declarations_string() const -> std::wstring; - auto generate_includes_string() const -> std::wstring; + auto generate_pre_declarations_string() const -> SystemStringType; + auto generate_includes_string() const -> SystemStringType; }; struct UniqueName { static constexpr int32_t HAS_NO_DUPLICATES = 1; - File::StringType name{}; + SystemStringType name{}; int32_t usable_id{HAS_NO_DUPLICATES}; }; @@ -210,26 +228,26 @@ namespace RC::UEGenerator { private: FFilePath m_root_directory; - std::wstring m_primary_module_name; + SystemStringType m_primary_module_name; - std::set m_forced_module_dependencies; - std::set m_ignored_module_names; - std::set m_classes_with_object_initializer; + std::set m_forced_module_dependencies; + std::set m_ignored_module_names; + std::set m_classes_with_object_initializer; - std::unordered_map m_underlying_enum_types; - std::set m_blueprint_visible_enums; - std::set m_blueprint_visible_structs; - std::map>> m_module_dependencies; + std::unordered_map m_underlying_enum_types; + std::set m_blueprint_visible_enums; + std::set m_blueprint_visible_structs; + std::map>> m_module_dependencies; std::vector m_header_files; std::unordered_set m_structs_that_need_get_type_hash; // Storage to ensure that we don't have duplicate file names - static std::map m_used_file_names; + static std::map m_used_file_names; static std::map m_dependency_object_to_unique_id; // Storage for class defaultsubojects when populating property initializers - std::unordered_map m_class_subobjects; + std::unordered_map m_class_subobjects; public: UEHeaderGenerator(const FFilePath& root_directory); @@ -243,8 +261,8 @@ namespace RC::UEGenerator auto dump_native_packages() -> void; auto generate_object_description_file(UObject* object) -> bool; - auto generate_module_build_file(const std::wstring& module_name) -> void; - auto generate_module_implementation_file(const std::wstring& module_name) -> void; + auto generate_module_build_file(const SystemStringType& module_name) -> void; + auto generate_module_implementation_file(const SystemStringType& module_name) -> void; private: auto generate_interface_definition(UClass* function, GeneratedSourceFile& header_data) -> void; @@ -264,7 +282,7 @@ namespace RC::UEGenerator const CaseInsensitiveSet& blacklisted_property_names, bool generate_as_override = false) -> void; - auto generate_property_value(UStruct* ustruct, FProperty* property, void* object, GeneratedSourceFile& implementation_file, const std::wstring& property_scope) + auto generate_property_value(UStruct* ustruct, FProperty* property, void* object, GeneratedSourceFile& implementation_file, const SystemStringType& property_scope) -> void; auto generate_function_implementation(UClass* uclass, UFunction* function, @@ -272,49 +290,50 @@ namespace RC::UEGenerator bool is_generating_interface, const CaseInsensitiveSet& blacklisted_property_names) -> void; - auto generate_interface_flags(UClass* uinterface) const -> std::wstring; - auto generate_class_flags(UClass* uclass) const -> std::wstring; - auto generate_struct_flags(UScriptStruct* script_struct) const -> std::wstring; - auto generate_enum_flags(UEnum* uenum) const -> std::wstring; - auto generate_property_type_declaration(FProperty* property, const PropertyTypeDeclarationContext& context) -> std::wstring; - auto generate_property_flags(FProperty* property) const -> std::wstring; - auto generate_function_argument_flags(FProperty* property) const -> std::wstring; - auto generate_function_flags(UFunction* function, bool is_function_pure_virtual = false) const -> std::wstring; + auto generate_interface_flags(UClass* uinterface) const -> SystemStringType; + auto generate_class_flags(UClass* uclass) const -> SystemStringType; + auto generate_struct_flags(UScriptStruct* script_struct) const -> SystemStringType; + auto generate_enum_flags(UEnum* uenum) const -> SystemStringType; + auto generate_property_type_declaration(FProperty* property, const PropertyTypeDeclarationContext& context) -> SystemStringType; + auto generate_property_flags(FProperty* property) const -> SystemStringType; + auto generate_function_argument_flags(FProperty* property) const -> SystemStringType; + auto generate_function_flags(UFunction* function, bool is_function_pure_virtual = false) const -> SystemStringType; auto generate_function_parameter_list(UClass* property, UFunction* function, GeneratedSourceFile& header_data, bool generate_comma_before_name, - const std::wstring& context_name, + const SystemStringType& context_name, const CaseInsensitiveSet& blacklisted_property_names, - int32_t* out_num_params = NULL) -> std::wstring; - auto generate_default_property_value(FProperty* property, GeneratedSourceFile& header_data, const std::wstring& ContextName) -> std::wstring; + int32_t* out_num_params = NULL) -> SystemStringType; + auto generate_default_property_value(FProperty* property, GeneratedSourceFile& header_data, const SystemStringType& ContextName) -> SystemStringType; - auto generate_enum_value(UEnum* uenum, int64_t enum_value) -> std::wstring; + auto generate_enum_value(UEnum* uenum, int64_t enum_value) -> SystemStringType; auto generate_simple_assignment_expression(FProperty* property, - const std::wstring& value, + const SystemStringType& value, GeneratedSourceFile& implementation_file, - const std::wstring& property_scope, - const std::wstring& operator_type = STR(" = ")) -> void; + const SystemStringType& property_scope, + const SystemStringType& operator_type = SYSSTR(" = ")) -> void; auto generate_advanced_assignment_expression(FProperty* property, - const std::wstring& value, + const SystemStringType& value, GeneratedSourceFile& implementation_file, - const std::wstring& property_scope, - const std::wstring& property_type, - const std::wstring& operator_type = STR(" = ")) -> void; + const SystemStringType& property_scope, + const SystemStringType& property_type, + const SystemStringType& operator_type = SYSSTR(" = ")) -> void; - auto static generate_parameter_count_string(int32_t parameter_count) -> std::wstring; - auto static determine_primary_game_module_name() -> std::wstring; + auto static generate_parameter_count_string(int32_t parameter_count) -> SystemStringType; + auto static determine_primary_game_module_name() -> SystemStringType; public: - auto add_module_and_sub_module_dependencies(std::set& out_module_dependencies, const std::wstring& module_name, bool add_self_module = true) - -> void; + auto add_module_and_sub_module_dependencies(::std::set& out_module_dependencies, + const SystemStringType& module_name, + bool add_self_module = true) -> void; auto static collect_blacklisted_property_names(UObject* property) -> CaseInsensitiveSet; - auto static generate_object_pre_declaration(UObject* object) -> std::vector>; + auto static generate_object_pre_declaration(UObject* object) -> ::std::vector<::std::vector>; - auto static convert_module_name_to_api_name(const std::wstring& module_name) -> std::wstring; - auto static get_module_name_for_package(UObject* package) -> std::wstring; - auto static sanitize_enumeration_name(const std::wstring& enumeration_name) -> std::wstring; + auto static convert_module_name_to_api_name(const SystemStringType& module_name) -> SystemStringType; + auto static get_module_name_for_package(UObject* package) -> SystemStringType; + auto static sanitize_enumeration_name(const SystemStringType& enumeration_name) -> SystemStringType; auto static get_highest_enum(UEnum* uenum) -> int64_t; auto static get_lowest_enum(UEnum* uenum) -> int64_t; @@ -325,8 +344,8 @@ namespace RC::UEGenerator auto static append_access_modifier(GeneratedSourceFile& header_data, AccessModifier needed_access, AccessModifier& current_access) -> void; auto static get_property_access_modifier(FProperty* property) -> AccessModifier; auto static get_function_access_modifier(UFunction* function) -> AccessModifier; - auto static create_string_literal(const std::wstring& string) -> std::wstring; - auto static get_header_name_for_object(UObject* object, bool get_existing_header = false) -> std::wstring; - auto static generate_cross_module_include(UObject* object, const std::wstring& module_name, const std::wstring& fallback_name) -> std::wstring; + auto static create_string_literal(const SystemStringType& string) -> SystemStringType; + auto static get_header_name_for_object(UObject* object, bool get_existing_header = false) -> SystemStringType; + auto static generate_cross_module_include(UObject* object, const SystemStringType& module_name, const SystemStringType& fallback_name) -> SystemStringType; }; } // namespace RC::UEGenerator diff --git a/UE4SS/include/SettingsManager.hpp b/UE4SS/include/SettingsManager.hpp index 321497282..bdd8dec2a 100644 --- a/UE4SS/include/SettingsManager.hpp +++ b/UE4SS/include/SettingsManager.hpp @@ -14,7 +14,7 @@ namespace RC public: struct SectionOverrides { - File::StringType ModsFolderPath{}; + SystemStringType ModsFolderPath{}; } Overrides; struct SectionGeneral @@ -25,6 +25,7 @@ namespace RC bool EnableDebugKeyBindings{false}; int64_t SecondsToScanBeforeGivingUp{30}; bool UseUObjectArrayCache{true}; + SystemStringType InputSource{SYSSTR("Default")}; } General; struct SectionEngineVersionOverride diff --git a/UE4SS/include/Signatures.hpp b/UE4SS/include/Signatures.hpp index f2951bc79..e5e7f2174 100644 --- a/UE4SS/include/Signatures.hpp +++ b/UE4SS/include/Signatures.hpp @@ -21,7 +21,7 @@ namespace RC using LuaScriptMatchFoundFunc = const std::function; using LuaScriptScanCompleteFunc = const std::function; - auto scan_from_lua_script(std::wstring& script_file_path_and_name, + auto scan_from_lua_script(SystemStringType& script_file_path_and_name, std::vector&, LuaScriptMatchFoundFunc& match_found_func, LuaScriptScanCompleteFunc& scan_complete_func = &scan_complete_default_func) -> void; diff --git a/UE4SS/include/UE4SSProgram.hpp b/UE4SS/include/UE4SSProgram.hpp index 672e92ec6..c2f657121 100644 --- a/UE4SS/include/UE4SSProgram.hpp +++ b/UE4SS/include/UE4SSProgram.hpp @@ -11,7 +11,10 @@ #include #include #include +#ifdef HAS_INPUT #include +#endif + #include #include #include @@ -84,9 +87,9 @@ namespace RC friend class CppUserModBase; // m_input_handler public: - constexpr static wchar_t m_settings_file_name[] = L"UE4SS-settings.ini"; - constexpr static wchar_t m_log_file_name[] = L"UE4SS.log"; - constexpr static wchar_t m_object_dumper_file_name[] = L"UE4SS_ObjectDump.txt"; + constexpr static SystemCharType m_settings_file_name[] = SYSSTR("UE4SS-settings.ini"); + constexpr static SystemCharType m_log_file_name[] = SYSSTR("UE4SS.log"); + constexpr static SystemCharType m_object_dumper_file_name[] = SYSSTR("UE4SS_ObjectDump.txt"); public: RC_UE4SS_API static SettingsManager settings_manager; @@ -96,7 +99,9 @@ namespace RC bool m_is_program_started; protected: - Input::Handler m_input_handler{L"ConsoleWindowClass", L"UnrealWindow"}; +#ifdef HAS_INPUT + Input::Handler m_input_handler; +#endif std::jthread m_event_loop; public: @@ -111,6 +116,12 @@ namespace RC std::filesystem::path m_module_file_path; std::filesystem::path m_working_directory; std::filesystem::path m_mods_directory; + + SystemStringType m_module_file_path_str; + SystemStringType m_working_directory_str; + SystemStringType m_game_executable_str; + SystemStringType m_mods_directory_str; + std::filesystem::path m_game_executable_directory; std::filesystem::path m_log_directory; std::filesystem::path m_object_dumper_output_directory; @@ -168,19 +179,19 @@ namespace RC }; public: - UE4SSProgram(const std::wstring& ModuleFilePath, std::initializer_list options); + UE4SSProgram(const SystemStringType& ModuleFilePath, std::initializer_list options); ~UE4SSProgram(); UE4SSProgram(const UE4SSProgram&) = delete; UE4SSProgram(UE4SSProgram&&) = delete; private: - auto setup_paths(const std::wstring& moduleFilePath) -> void; + auto setup_paths(const SystemStringType& moduleFilePath) -> void; enum class FunctionStatus { Success, Failure, }; - auto create_emergency_console_for_early_error(File::StringViewType error_message) -> void; + auto create_emergency_console_for_early_error(SystemStringViewType error_message) -> void; auto setup_mod_directory_path() -> void; auto create_simple_console() -> void; auto setup_unreal() -> void; @@ -204,21 +215,27 @@ namespace RC auto fire_unreal_init_for_cpp_mods() -> void; auto fire_ui_init_for_cpp_mods() -> void; auto fire_program_start_for_cpp_mods() -> void; - auto fire_dll_load_for_cpp_mods(std::wstring_view dll_name) -> void; + auto fire_dll_load_for_cpp_mods(SystemStringViewType dll_name) -> void; public: auto init() -> void; auto is_program_started() -> bool; auto reinstall_mods() -> void; - auto get_object_dumper_output_directory() -> const File::StringType; - RC_UE4SS_API auto get_module_directory() -> File::StringViewType; - RC_UE4SS_API auto get_game_executable_directory() -> File::StringViewType; - RC_UE4SS_API auto get_working_directory() -> File::StringViewType; - RC_UE4SS_API auto get_mods_directory() -> File::StringViewType; - RC_UE4SS_API auto get_legacy_root_directory() -> File::StringViewType; + auto get_object_dumper_output_directory() -> const SystemStringType; + RC_UE4SS_API auto get_module_directory() -> SystemStringViewType; + RC_UE4SS_API auto get_working_directory() -> SystemStringViewType; + RC_UE4SS_API auto get_mods_directory() -> SystemStringViewType; + RC_UE4SS_API auto get_legacy_root_directory() -> SystemStringViewType; + RC_UE4SS_API auto get_game_executable_directory() -> SystemStringViewType; RC_UE4SS_API auto generate_uht_compatible_headers() -> void; RC_UE4SS_API auto generate_cxx_headers(const std::filesystem::path& output_dir) -> void; RC_UE4SS_API auto generate_lua_types(const std::filesystem::path& output_dir) -> void; +#ifdef HAS_INPUT + auto get_input_handler() -> Input::Handler& + { + return m_input_handler; + } +#endif auto get_debugging_ui() -> GUI::DebuggingGUI& { return m_debugging_gui; @@ -242,6 +259,7 @@ namespace RC } public: +#ifdef HAS_INPUT // API pass-through for use outside the private scope of UE4SSProgram RC_UE4SS_API auto register_keydown_event(Input::Key, const Input::EventCallbackCallable&, uint8_t custom_data = 0, void* custom_data2 = nullptr) -> void; RC_UE4SS_API auto register_keydown_event(Input::Key, @@ -251,60 +269,48 @@ namespace RC void* custom_data2 = nullptr) -> void; RC_UE4SS_API auto is_keydown_event_registered(Input::Key) -> bool; RC_UE4SS_API auto is_keydown_event_registered(Input::Key, const Input::Handler::ModifierKeyArray&) -> bool; +#endif private: static auto install_cpp_mods() -> void; static auto install_lua_mods() -> void; using FMBNI_ExtraPredicate = std::function; - static auto find_mod_by_name_internal(std::wstring_view mod_name, + static auto find_mod_by_name_internal(SystemStringViewType mod_name, IsInstalled = IsInstalled::No, IsStarted = IsStarted::No, FMBNI_ExtraPredicate extra_predicate = {}) -> Mod*; public: - RC_UE4SS_API static auto dump_uobject(Unreal::UObject* object, std::unordered_set* dumped_fields, StringType& out_line, bool is_below_425) + RC_UE4SS_API static auto dump_uobject(Unreal::UObject* object, std::unordered_set* dumped_fields, SystemStringType& out_line, bool is_below_425) -> void; - RC_UE4SS_API static auto dump_xproperty(Unreal::FProperty* property, StringType& out_line) -> void; - RC_UE4SS_API static auto dump_all_objects_and_properties(const File::StringType& output_path_and_file_name) -> void; + RC_UE4SS_API static auto dump_xproperty(Unreal::FProperty* property, SystemStringType& out_line) -> void; + RC_UE4SS_API static auto dump_all_objects_and_properties(const SystemStringType& output_path_and_file_name) -> void; template - static auto find_mod_by_name(std::wstring_view mod_name, IsInstalled = IsInstalled::No, IsStarted = IsStarted::No) -> T* + static auto find_mod_by_name(SystemStringType mod_name, IsInstalled is_installed = IsInstalled::No, IsStarted is_started = IsStarted::No) -> T* { - std::abort(); + return static_cast(find_mod_by_name_internal(mod_name, is_installed, is_started, [](auto elem) -> bool { + return dynamic_cast(elem); + })); }; + template - static auto find_mod_by_name(std::string_view mod_name, IsInstalled = IsInstalled::No, IsStarted = IsStarted::No) -> T* + static auto find_mod_by_name(SystemStringViewType mod_name, IsInstalled is_installed = IsInstalled::No, IsStarted is_started = IsStarted::No) -> T* { - std::abort(); + return find_mod_by_name(to_system_string(mod_name), is_installed, is_started); }; - template <> - auto find_mod_by_name(std::wstring_view mod_name, IsInstalled is_installed, IsStarted is_started) -> LuaMod* - { - return static_cast(find_mod_by_name_internal(mod_name, is_installed, is_started, [](auto elem) -> bool { - return dynamic_cast(elem); - })); - } - template <> - auto find_mod_by_name(std::wstring_view mod_name, IsInstalled is_installed, IsStarted is_started) -> CppMod* - { - return static_cast(find_mod_by_name_internal(mod_name, is_installed, is_started, [](auto elem) -> bool { - return dynamic_cast(elem); - })); - } - template <> - auto find_mod_by_name(std::string_view mod_name, IsInstalled is_installed, IsStarted is_started) -> LuaMod* - { - return find_mod_by_name(to_wstring(mod_name), is_installed, is_started); - } - template <> - auto find_mod_by_name(std::string_view mod_name, IsInstalled is_installed, IsStarted is_started) -> CppMod* + + static RC_UE4SS_API auto find_lua_mod_by_name_internal(SystemStringType mod_name, IsInstalled is_installed = IsInstalled::No, IsStarted is_started = IsStarted::No) -> LuaMod*; + + // no need to mark this as api + template + static auto find_lua_mod_by_name(S mod_name, IsInstalled is_installed = IsInstalled::No, IsStarted is_started = IsStarted::No) -> LuaMod* { - return find_mod_by_name(to_wstring(mod_name), is_installed, is_started); + auto mod_name_str = to_system_string(mod_name); + return find_lua_mod_by_name_internal(mod_name_str, is_installed, is_started); } - - RC_UE4SS_API static auto find_lua_mod_by_name(std::wstring_view mod_name, IsInstalled = IsInstalled::No, IsStarted = IsStarted::No) -> LuaMod*; - RC_UE4SS_API static auto find_lua_mod_by_name(std::string_view mod_name, IsInstalled = IsInstalled::No, IsStarted = IsStarted::No) -> LuaMod*; + static auto static_cleanup() -> void; RC_UE4SS_API static auto get_program() -> UE4SSProgram& { diff --git a/UE4SS/proxy_generator/main.cpp b/UE4SS/proxy_generator/main.cpp index 8feee84e8..44701910b 100644 --- a/UE4SS/proxy_generator/main.cpp +++ b/UE4SS/proxy_generator/main.cpp @@ -170,10 +170,10 @@ int _tmain(int argc, TCHAR* argv[]) cpp_file << "void load_original_dll()" << endl; cpp_file << "{" << endl; - cpp_file << " File::CharType path[MAX_PATH];" << endl; + cpp_file << " SystemCharType path[MAX_PATH];" << endl; cpp_file << " GetSystemDirectory(path, MAX_PATH);" << endl; cpp_file << endl; - cpp_file << std::format(" File::StringType dll_path = File::StringType(path) + STR(\"\\\\{}\");", input_dll_name.string()) << endl; + cpp_file << std::format(" SystemStringType dll_path = SystemStringType(path) + SYSSTR(\"\\\\{}\");", input_dll_name.string()) << endl; cpp_file << endl; cpp_file << " SOriginalDll = LoadLibrary(dll_path.c_str());" << endl; cpp_file << " if (!SOriginalDll)" << endl; diff --git a/UE4SS/src/GUI/BPMods.cpp b/UE4SS/src/GUI/BPMods.cpp index b5507c6ba..25428ae20 100644 --- a/UE4SS/src/GUI/BPMods.cpp +++ b/UE4SS/src/GUI/BPMods.cpp @@ -16,6 +16,9 @@ #include +#undef min +#undef max + namespace RC::GUI::BPMods { using namespace RC::Unreal; @@ -113,7 +116,7 @@ namespace RC::GUI::BPMods const auto& mod_button = mod_info.ModButtons[i2]; if (ImGui::Button(std::format("{}", mod_button).c_str())) { - Output::send(STR("Mod button {} hit.\n"), to_wstring(mod_button)); + Output::send(SYSSTR("Mod button {} hit.\n"), mod_button); mod_info.ModActor->ModMenuButtonPressed(static_cast(i2)); } } diff --git a/UE4SS/src/GUI/Console.cpp b/UE4SS/src/GUI/Console.cpp index b0150c9a5..aa781d920 100644 --- a/UE4SS/src/GUI/Console.cpp +++ b/UE4SS/src/GUI/Console.cpp @@ -107,14 +107,14 @@ namespace RC::GUI bool reclaim_focus{}; ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory; auto text_edit_callback_wrapper = [](ImGuiInputTextCallbackData* data) -> int { Console* console = - static_cast(data->UserData); Output::send(STR("text_edit_callback_wrapper\n")); + static_cast(data->UserData); Output::send(SYSSTR("text_edit_callback_wrapper\n")); //return console->text_edit_callback(data); return 0; }; ImGui::PushItemWidth(-12.0f); if (ImGui::InputText("##console_input_buffer", m_input_buffer, IM_ARRAYSIZE(m_input_buffer), input_text_flags, text_edit_callback_wrapper, this)) { - Output::send(STR("ConsoleInput\n")); + Output::send(SYSSTR("ConsoleInput\n")); reclaim_focus = true; } ImGui::PopItemWidth(); diff --git a/UE4SS/src/GUI/ConsoleOutputDevice.cpp b/UE4SS/src/GUI/ConsoleOutputDevice.cpp index 7e0ac8e67..dd6ee6145 100644 --- a/UE4SS/src/GUI/ConsoleOutputDevice.cpp +++ b/UE4SS/src/GUI/ConsoleOutputDevice.cpp @@ -11,17 +11,17 @@ namespace RC::Output return true; } - auto ConsoleDevice::receive(File::StringViewType fmt) const -> void + auto ConsoleDevice::receive(SystemStringViewType fmt) const -> void { receive_with_optional_arg(fmt, Color::NoColor); } - auto ConsoleDevice::receive_with_optional_arg(File::StringViewType fmt, [[maybe_unused]] int32_t optional_arg) const -> void + auto ConsoleDevice::receive_with_optional_arg(SystemStringViewType fmt, [[maybe_unused]] int32_t optional_arg) const -> void { #if ENABLE_OUTPUT_DEVICE_DEBUG_MODE - printf_s("ConsoleDevice received: %S", m_formatter(fmt).c_str()); + printf_s("ConsoleDevice received: " SystemStringPrint, m_formatter(fmt).c_str()); #else - auto fmt_copy = File::StringType{fmt}; + auto fmt_copy = SystemStringType{fmt}; if (fmt_copy.ends_with(STR('\n'))) { fmt_copy.pop_back(); diff --git a/UE4SS/src/GUI/Dumpers.cpp b/UE4SS/src/GUI/Dumpers.cpp index a2ddc0028..86bde5c70 100644 --- a/UE4SS/src/GUI/Dumpers.cpp +++ b/UE4SS/src/GUI/Dumpers.cpp @@ -25,6 +25,9 @@ #include #include +#undef min +#undef max + namespace RC::GUI::Dumpers { using namespace ::RC::Unreal; @@ -79,9 +82,9 @@ namespace RC::GUI::Dumpers FMeshUVChannelInfo UVChannelData; }; - auto generate_root_component_csv(UObject* root_component) -> StringType + auto generate_root_component_csv(UObject* root_component) -> SystemStringType { - StringType root_actor_buffer{}; + SystemStringType root_actor_buffer{}; static auto location_property = root_component->GetPropertyByNameInChain(STR("RelativeLocation")); static auto rotation_property = root_component->GetPropertyByNameInChain(STR("RelativeRotation")); @@ -90,26 +93,26 @@ namespace RC::GUI::Dumpers auto location = root_component->GetValuePtrByPropertyNameInChain(STR("RelativeLocation")); FString location_string{}; location_property->ExportTextItem(location_string, location, nullptr, nullptr, 0); - root_actor_buffer.append(std::format(STR("\"{}\","), location_string.GetCharArray())); + root_actor_buffer.append(std::format(SYSSTR("\"{}\","), to_system(location_string.GetCharArray()))); auto rotation = root_component->GetValuePtrByPropertyNameInChain(STR("RelativeRotation")); FString rotation_string{}; rotation_property->ExportTextItem(rotation_string, rotation, nullptr, nullptr, 0); - root_actor_buffer.append(std::format(STR("\"{}\","), rotation_string.GetCharArray())); + root_actor_buffer.append(std::format(SYSSTR("\"{}\","), to_system(rotation_string.GetCharArray()))); auto scale = root_component->GetValuePtrByPropertyNameInChain(STR("RelativeScale3D")); FString scale_string{}; scale_property->ExportTextItem(scale_string, scale, nullptr, nullptr, 0); - root_actor_buffer.append(std::format(STR("\"{}\","), scale_string.GetCharArray())); + root_actor_buffer.append(std::format(SYSSTR("\"{}\","), to_system(scale_string.GetCharArray()))); return root_actor_buffer; } - static auto generate_actors_csv_file(UClass* dump_actor_class) -> StringType + static auto generate_actors_csv_file(UClass* dump_actor_class) -> SystemStringType { - StringType file_buffer{}; + SystemStringType file_buffer{}; - file_buffer.append(STR("---,Actor,Location,Rotation,Scale,Meshes\n")); + file_buffer.append(SYSSTR("---,Actor,Location,Rotation,Scale,Meshes\n")); size_t actor_count{}; FindObjectSearcher(dump_actor_class, AnySuperStruct::StaticClass()).ForEach([&](UObject* object) { @@ -126,30 +129,30 @@ namespace RC::GUI::Dumpers return LoopAction::Continue; } - StringType actor_buffer{}; + SystemStringType actor_buffer{}; - actor_buffer.append(std::format(STR("Row_{},"), actor_count)); + actor_buffer.append(std::format(SYSSTR("Row_{},"), actor_count)); static auto game_mode_base = UObjectGlobals::FindFirstOf(STR("GameModeBase")); static auto class_property = game_mode_base->GetPropertyByNameInChain(STR("GameStateClass")); FString actor_class_string{}; class_property->ExportTextItem(actor_class_string, &actor->GetClassPrivate(), nullptr, nullptr, 0); - actor_buffer.append(std::format(STR("{},"), actor_class_string.GetCharArray())); + actor_buffer.append(std::format(SYSSTR("{},"), to_system(actor_class_string.GetCharArray()))); // TODO: build system to handle other types of components - possibly including a way to specify which components to dump and which properties are important via a config file actor_buffer.append(generate_root_component_csv(*root_component)); - actor_buffer.append(STR("\"")); + actor_buffer.append(SYSSTR("\"")); static auto static_mesh_component_class = UObjectGlobals::StaticFindObject(nullptr, nullptr, STR("/Script/Engine.StaticMeshComponent")); const auto& static_mesh_components = actor->K2_GetComponentsByClass(static_mesh_component_class); if (static_mesh_components.Num() > 0) { - actor_buffer.append(STR("(")); + actor_buffer.append(SYSSTR("(")); for (auto [static_mesh_component_ptr, static_mesh_component_index] : static_mesh_components | views::enumerate) { const auto mesh = *static_mesh_component_ptr->GetValuePtrByPropertyNameInChain(STR("StaticMesh")); if (!mesh) { - Output::send(STR("SKIPPING COMPONENT! StaticMeshComponent '{}' has no mesh.\n"), + Output::send(SYSSTR("SKIPPING COMPONENT! StaticMeshComponent '{}' has no mesh.\n"), static_mesh_component_ptr->GetOuterPrivate()->GetName()); continue; } @@ -157,7 +160,7 @@ namespace RC::GUI::Dumpers static auto mesh_property = static_mesh_component_ptr->GetPropertyByNameInChain(STR("StaticMesh")); FString mesh_string{}; mesh_property->ExportTextItem(mesh_string, &mesh, nullptr, nullptr, 0); - actor_buffer.append(std::format(STR("(StaticMesh={}',"), mesh_string.GetCharArray())); + actor_buffer.append(std::format(SYSSTR("(StaticMesh={}',"), to_system(mesh_string.GetCharArray()))); auto materials_for_each_body = [&](const UObject* material_interface) { if (material_interface) @@ -166,8 +169,9 @@ namespace RC::GUI::Dumpers const auto material_type_space_location = material_full_name.find(STR(" ")); if (material_type_space_location == material_full_name.npos) { - Output::send(STR("SKIPPING MATERIAL! Was unable to find space in full material name in component: '{}'.\n"), - material_full_name); + Output::send( + SYSSTR("SKIPPING MATERIAL! Was unable to find space in full material name in component: '{}'.\n"), + material_full_name); return; } @@ -175,12 +179,12 @@ namespace RC::GUI::Dumpers { throw std::runtime_error{"integer overflow when converting material_type_space_location signed\n"}; } - auto material_typeless_name = StringViewType{material_full_name.begin() + static_cast(material_type_space_location) + 1, - material_full_name.end()}; + auto material_typeless_name = UEStringViewType{material_full_name.begin() + static_cast(material_type_space_location) + 1, + material_full_name.end()}; - actor_buffer.append(std::format(STR("{}'"), material_interface->GetClassPrivate()->GetName())); - actor_buffer.append(std::format(STR("\"\"{}"), material_typeless_name)); - actor_buffer.append(STR("\"\"'")); + actor_buffer.append(std::format(SYSSTR("{}'"), to_system(material_interface->GetClassPrivate()->GetName()))); + actor_buffer.append(std::format(SYSSTR("\"\"{}"), to_system(material_typeless_name))); + actor_buffer.append(SYSSTR("\"\"'")); } }; @@ -189,18 +193,18 @@ namespace RC::GUI::Dumpers const auto materials = *mesh->GetValuePtrByPropertyName>(STR("StaticMaterials")); if (materials.GetData()) { - actor_buffer.append(STR("Materials=(")); + actor_buffer.append(SYSSTR("Materials=(")); } for (auto [material, material_index] : materials | views::enumerate) { materials_for_each_body(material.MaterialInterface); if (material_index + 1 < materials.Num()) { - actor_buffer.append(STR(",")); + actor_buffer.append(SYSSTR(",")); } else { - actor_buffer.append(STR(")")); + actor_buffer.append(SYSSTR(")")); } } } @@ -209,31 +213,31 @@ namespace RC::GUI::Dumpers const auto& materials = *mesh->GetValuePtrByPropertyName>(STR("StaticMaterials")); if (materials.GetData()) { - actor_buffer.append(STR("Materials=(")); + actor_buffer.append(SYSSTR("Materials=(")); } for (auto [material, material_index] : materials | views::enumerate) { materials_for_each_body(material.MaterialInterface); if (material_index + 1 < materials.Num()) { - actor_buffer.append(STR(",")); + actor_buffer.append(SYSSTR(",")); } else { - actor_buffer.append(STR(")")); + actor_buffer.append(SYSSTR(")")); } } } - actor_buffer.append(STR(")")); + actor_buffer.append(SYSSTR(")")); if (static_mesh_component_index + 1 < static_mesh_components.Num()) { - actor_buffer.append(STR(",")); + actor_buffer.append(SYSSTR(",")); } } - actor_buffer.append(STR(")")); + actor_buffer.append(SYSSTR(")")); } - actor_buffer.append(STR("\"\n")); + actor_buffer.append(SYSSTR("\"\n")); file_buffer.append(actor_buffer); ++actor_count; @@ -243,7 +247,7 @@ namespace RC::GUI::Dumpers return file_buffer; } - static auto generate_actors_json_file(UClass* class_to_dump) -> StringType + static auto generate_actors_json_file(UClass* class_to_dump) -> SystemStringType { auto global_json_array = JSON::Array{}; @@ -264,37 +268,37 @@ namespace RC::GUI::Dumpers auto& actor_json_object = global_json_array.new_object(); - actor_json_object.new_string(STR("Name"), std::format(STR("Row_{}"), actor_count)); + actor_json_object.new_string(SYSSTR("Name"), std::format(SYSSTR("Row_{}"), actor_count)); static auto game_mode_base = UObjectGlobals::FindFirstOf(STR("GameModeBase")); static auto class_property = game_mode_base->GetPropertyByNameInChain(STR("GameStateClass")); FString actor_class_string{}; class_property->ExportTextItem(actor_class_string, &actor->GetClassPrivate(), nullptr, nullptr, 0); - actor_json_object.new_string(STR("Actor"), std::format(STR("{}"), StringViewType{actor_class_string.GetCharArray()})); + actor_json_object.new_string(SYSSTR("Actor"), std::format(SYSSTR("{}"), to_system(actor_class_string.GetCharArray()))); - auto& root_component_json_object = actor_json_object.new_object(STR("RootComponent")); + auto& root_component_json_object = actor_json_object.new_object(SYSSTR("RootComponent")); FString root_component_class_string{}; class_property->ExportTextItem(root_component_class_string, &(*root_component)->GetClassPrivate(), nullptr, nullptr, 0); - root_component_json_object.new_string(STR("SceneComponentClass"), std::format(STR("{}"), StringViewType{root_component_class_string.GetCharArray()})); + root_component_json_object.new_string(SYSSTR("SceneComponentClass"), std::format(SYSSTR("{}"), to_system(root_component_class_string.GetCharArray()))); - auto& location_json_object = root_component_json_object.new_object(STR("Location")); + auto& location_json_object = root_component_json_object.new_object(SYSSTR("Location")); auto location = (*root_component)->GetValuePtrByPropertyNameInChain(STR("RelativeLocation")); - location_json_object.new_number(STR("X"), location->X()); - location_json_object.new_number(STR("Y"), location->Y()); - location_json_object.new_number(STR("Z"), location->Z()); + location_json_object.new_number(SYSSTR("X"), location->X()); + location_json_object.new_number(SYSSTR("Y"), location->Y()); + location_json_object.new_number(SYSSTR("Z"), location->Z()); - auto& rotation_json_object = root_component_json_object.new_object(STR("Rotation")); + auto& rotation_json_object = root_component_json_object.new_object(SYSSTR("Rotation")); auto rotation = (*root_component)->GetValuePtrByPropertyNameInChain(STR("RelativeRotation")); - rotation_json_object.new_number(STR("Pitch"), rotation->GetPitch()); - rotation_json_object.new_number(STR("Yaw"), rotation->GetYaw()); - rotation_json_object.new_number(STR("Roll"), rotation->GetRoll()); + rotation_json_object.new_number(SYSSTR("Pitch"), rotation->GetPitch()); + rotation_json_object.new_number(SYSSTR("Yaw"), rotation->GetYaw()); + rotation_json_object.new_number(SYSSTR("Roll"), rotation->GetRoll()); - auto& scale_json_object = root_component_json_object.new_object(STR("Scale")); + auto& scale_json_object = root_component_json_object.new_object(SYSSTR("Scale")); auto scale = (*root_component)->GetValuePtrByPropertyNameInChain(STR("RelativeScale3D")); - scale_json_object.new_number(STR("X"), scale->X()); - scale_json_object.new_number(STR("Y"), scale->Y()); - scale_json_object.new_number(STR("Z"), scale->Z()); + scale_json_object.new_number(SYSSTR("X"), scale->X()); + scale_json_object.new_number(SYSSTR("Y"), scale->Y()); + scale_json_object.new_number(SYSSTR("Z"), scale->Z()); ++actor_count; return LoopAction::Continue; @@ -308,30 +312,27 @@ namespace RC::GUI::Dumpers void call_generate_static_mesh_file() { - Output::send(STR("Dumping CSV of all loaded static mesh actors, positions and mesh properties\n")); + Output::send(SYSSTR("Dumping CSV of all loaded static mesh actors, positions and mesh properties\n")); static auto dump_actor_class = UObjectGlobals::StaticFindObject(nullptr, nullptr, STR("/Script/Engine.StaticMeshActor")); - std::wstring file_buffer{}; + SystemStringType file_buffer{}; file_buffer.append(generate_actors_csv_file(dump_actor_class)); - auto file = - File::open(std::format(STR("{}\\{}-ue4ss_static_mesh_data.csv"), UE4SSProgram::get_program().get_working_directory(), long(std::time(nullptr))), - File::OpenFor::Writing, - File::OverwriteExistingFile::Yes, - File::CreateIfNonExistent::Yes); - file.write_string_to_file(file_buffer); - Output::send(STR("Finished dumping CSV of all loaded static mesh actors, positions and mesh properties\n")); + auto path = std::filesystem::path{UE4SSProgram::get_program().get_working_directory()} / + std::format(SYSSTR("{}-ue4ss_static_mesh_data.csv"), long(std::time(nullptr))); + auto file = File::open(path, File::OpenFor::Writing, File::OverwriteExistingFile::Yes, File::CreateIfNonExistent::Yes); + file.write_file_string_to_file(to_file(file_buffer)); + Output::send(SYSSTR("Finished dumping CSV of all loaded static mesh actors, positions and mesh properties\n")); } void call_generate_all_actor_file() { - Output::send(STR("Dumping CSV of all loaded actor types, positions and mesh properties\n")); - std::wstring file_buffer{}; + Output::send(SYSSTR("Dumping CSV of all loaded actor types, positions and mesh properties\n")); + SystemStringType file_buffer{}; + auto path = std::filesystem::path{UE4SSProgram::get_program().get_working_directory()} / + std::format(SYSSTR("{}-ue4ss_actor_data.csv"), long(std::time(nullptr))); file_buffer.append(generate_actors_csv_file(AActor::StaticClass())); - auto file = File::open(std::format(STR("{}\\{}-ue4ss_actor_data.csv"), UE4SSProgram::get_program().get_working_directory(), long(std::time(nullptr))), - File::OpenFor::Writing, - File::OverwriteExistingFile::Yes, - File::CreateIfNonExistent::Yes); - file.write_string_to_file(file_buffer); - Output::send(STR("Finished dumping CSV of all loaded actor types, positions and mesh properties\n")); + auto file = File::open(path, File::OpenFor::Writing, File::OverwriteExistingFile::Yes, File::CreateIfNonExistent::Yes); + file.write_file_string_to_file(to_file(file_buffer)); + Output::send(SYSSTR("Finished dumping CSV of all loaded actor types, positions and mesh properties\n")); } auto render() -> void @@ -395,14 +396,14 @@ namespace RC::GUI::Dumpers if (ImGui::Button("Dump CXX Headers\n")) { - File::StringType working_dir{UE4SSProgram::get_program().get_working_directory()}; - UE4SSProgram::get_program().generate_cxx_headers(working_dir + STR("\\CXXHeaderDump")); + std::filesystem::path working_dir{UE4SSProgram::get_program().get_working_directory()}; + UE4SSProgram::get_program().generate_cxx_headers(working_dir / SYSSTR("CXXHeaderDump")); } if (ImGui::Button("Generate Lua Types\n")) { - File::StringType working_dir{UE4SSProgram::get_program().get_working_directory()}; - UE4SSProgram::get_program().generate_lua_types(working_dir + STR("\\Mods\\shared\\types")); + std::filesystem::path working_dir{UE4SSProgram::get_program().get_working_directory()}; + UE4SSProgram::get_program().generate_lua_types(working_dir / SYSSTR("Mods") / SYSSTR("shared") SYSSTR("types")); } } } // namespace RC::GUI::Dumpers diff --git a/UE4SS/src/GUI/GUI.cpp b/UE4SS/src/GUI/GUI.cpp index e770705c0..a7de04dba 100644 --- a/UE4SS/src/GUI/GUI.cpp +++ b/UE4SS/src/GUI/GUI.cpp @@ -333,7 +333,7 @@ namespace RC::GUI { if (!Output::has_internal_error()) { - Output::send(STR("Error: {}\n"), to_wstring(e.what())); + Output::send(SYSSTR("Error: {}\n"), to_system(e.what())); } else { @@ -458,7 +458,7 @@ namespace RC::GUI IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); - m_imgui_ini_file = to_string(StringType{UE4SSProgram::get_program().get_working_directory()} + STR("\\imgui.ini")); + m_imgui_ini_file = to_string_path(std::filesystem::path {UE4SSProgram::get_program().get_working_directory()} / SYSSTR("imgui.ini")); io.IniFilename = m_imgui_ini_file.c_str(); // Add .ini handle for UserData type @@ -550,7 +550,7 @@ namespace RC::GUI if (!debugging_ui) { - Output::send(STR("Could not start GUI render thread because 'debugging_ui' was nullptr.")); + Output::send(SYSSTR("Could not start GUI render thread because 'debugging_ui' was nullptr.")); return; } debugging_ui->setup(std::move(stop_token)); diff --git a/UE4SS/src/GUI/ImGuiUtility.cpp b/UE4SS/src/GUI/ImGuiUtility.cpp index 858516299..2dcb620bf 100644 --- a/UE4SS/src/GUI/ImGuiUtility.cpp +++ b/UE4SS/src/GUI/ImGuiUtility.cpp @@ -98,12 +98,12 @@ namespace RC::GUI static auto dump_json_integer_value(const JSON::Number& element) -> void; static int indent_level{}; - static auto indent() -> std::wstring + static auto indent() -> SystemStringType { - std::wstring indents{}; + SystemStringType indents{}; for (int i = 0; i < indent_level; ++i) { - indents.append(STR(" ")); + indents.append(SYSSTR(" ")); } return indents; } @@ -150,7 +150,7 @@ namespace RC::GUI static auto dump_json_object_pair(const JSON::TypedKeyValuePair element) -> void { - Output::send(STR("{}Object: {}\n"), indent(), element.key); + Output::send(SYSSTR("{}Object: {}\n"), indent(), element.key); const auto& object = element.value->get(); for (const auto& [_, inner_element] : object) @@ -163,7 +163,7 @@ namespace RC::GUI static auto dump_json_array_pair(const JSON::TypedKeyValuePair element) -> void { - Output::send(STR("{}Array: {}\n"), indent(), element.key); + Output::send(SYSSTR("{}Array: {}\n"), indent(), element.key); const auto& array = element.value->get(); for (const auto& inner_element : array) @@ -176,18 +176,18 @@ namespace RC::GUI static auto dump_json_string_pair(const JSON::TypedKeyValuePair element) -> void { - Output::send(STR("{}String: {} == {}\n"), indent(), element.key, element.value->get_view()); + Output::send(SYSSTR("{}String: {} == {}\n"), indent(), element.key, element.value->get_view()); } static auto dump_json_integer_pair(const JSON::TypedKeyValuePair element) -> void { - Output::send(STR("{}Integer: {} == {}\n"), indent(), element.key, element.value->get()); + Output::send(SYSSTR("{}Integer: {} == {}\n"), indent(), element.key, element.value->get()); } static auto dump_json_object_value(const JSON::Object& element) -> void { ++indent_level; - Output::send(STR("{}Object \n"), indent()); + Output::send(SYSSTR("{}Object \n"), indent()); const auto& object = element.get(); for (const auto& [_, inner_element] : object) @@ -203,7 +203,7 @@ namespace RC::GUI static auto dump_json_array_value(const JSON::Array& element) -> void { ++indent_level; - Output::send(STR("{}Array \n"), indent()); + Output::send(SYSSTR("{}Array \n"), indent()); const auto& array = element.get(); for (const auto& inner_element : array) @@ -218,11 +218,11 @@ namespace RC::GUI static auto dump_json_string_value(const JSON::String& element) -> void { - Output::send(STR("{}String: {}\n"), indent(), element.get_view()); + Output::send(SYSSTR("{}String: {}\n"), indent(), element.get_view()); } static auto dump_json_integer_value(const JSON::Number& element) -> void { - Output::send(STR("{}Integer: {}\n"), indent(), element.get()); + Output::send(SYSSTR("{}Integer: {}\n"), indent(), element.get()); } } // namespace RC::GUI diff --git a/UE4SS/src/GUI/LiveView.cpp b/UE4SS/src/GUI/LiveView.cpp index 70cbaec79..9c45bd25b 100644 --- a/UE4SS/src/GUI/LiveView.cpp +++ b/UE4SS/src/GUI/LiveView.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -49,6 +50,9 @@ #include #include +#undef max +#undef min + namespace RC::GUI { using namespace Unreal; @@ -278,28 +282,28 @@ namespace RC::GUI }; FLiveViewDeleteListener FLiveViewDeleteListener::LiveViewDeleteListener{}; - static auto add_bool_filter_to_json(JSON::Array& json_filters, const StringType& filter_name, bool is_enabled) -> void + static auto add_bool_filter_to_json(JSON::Array& json_filters, const SystemStringType& filter_name, bool is_enabled) -> void { auto& json_object = json_filters.new_object(); - json_object.new_string(STR("FilterName"), filter_name); - auto& filter_data = json_object.new_object(STR("FilterData")); - filter_data.new_bool(STR("Enabled"), is_enabled); + json_object.new_string(SYSSTR("FilterName"), filter_name); + auto& filter_data = json_object.new_object(SYSSTR("FilterData")); + filter_data.new_bool(SYSSTR("Enabled"), is_enabled); } template - static auto add_array_filter_to_json(JSON::Array& json_filters, const StringType& filter_name, const ContainerType& container, const StringType& array_name) -> void + static auto add_array_filter_to_json(JSON::Array& json_filters, const SystemStringType& filter_name, const ContainerType& container, const SystemStringType& array_name) -> void { auto& json_object = json_filters.new_object(); - json_object.new_string(STR("FilterName"), filter_name); - auto& filter_data = json_object.new_object(STR("FilterData")); + json_object.new_string(SYSSTR("FilterName"), filter_name); + auto& filter_data = json_object.new_object(SYSSTR("FilterData")); - if (array_name == STR("ClassNames")) + if (array_name == SYSSTR("ClassNames")) { - filter_data.new_bool(STR("IsExclude"), Filter::ClassNamesFilter::b_is_exclude); + filter_data.new_bool(SYSSTR("IsExclude"), Filter::ClassNamesFilter::b_is_exclude); } - else if (array_name == STR("FunctionParamFlags")) + else if (array_name == SYSSTR("FunctionParamFlags")) { - filter_data.new_bool(STR("IncludeReturnProperty"), Filter::FunctionParamFlags::s_include_return_property); + filter_data.new_bool(SYSSTR("IncludeReturnProperty"), Filter::FunctionParamFlags::s_include_return_property); } auto& values_array = filter_data.new_array(array_name); @@ -307,7 +311,7 @@ namespace RC::GUI { if constexpr (std::is_same_v) { - values_array.new_string(value.ToString()); + values_array.new_string(to_system(value.ToString())); } else if constexpr (std::is_same_v) { @@ -315,7 +319,7 @@ namespace RC::GUI } else { - values_array.new_string(value); + values_array.new_string(to_system(value)); } } } @@ -323,30 +327,30 @@ namespace RC::GUI static auto internal_save_filters_to_disk() -> void { auto json = JSON::Object{}; - auto& json_filters = json.new_array(STR("Filters")); + auto& json_filters = json.new_array(SYSSTR("Filters")); { - add_bool_filter_to_json(json_filters, STR("IncludeInheritance"), LiveView::s_include_inheritance); - add_bool_filter_to_json(json_filters, STR("UseRegexForSearch"), LiveView::s_use_regex_for_search); - add_bool_filter_to_json(json_filters, STR("ApplySearchFiltersWhenNotSearching"), LiveView::s_apply_search_filters_when_not_searching); - add_bool_filter_to_json(json_filters, Filter::DefaultObjectsOnly::s_debug_name, Filter::DefaultObjectsOnly::s_enabled); - add_bool_filter_to_json(json_filters, Filter::IncludeDefaultObjects::s_debug_name, Filter::IncludeDefaultObjects::s_enabled); - add_bool_filter_to_json(json_filters, Filter::InstancesOnly::s_debug_name, Filter::InstancesOnly::s_enabled); - add_bool_filter_to_json(json_filters, Filter::NonInstancesOnly::s_debug_name, Filter::NonInstancesOnly::s_enabled); + add_bool_filter_to_json(json_filters, SYSSTR("IncludeInheritance"), LiveView::s_include_inheritance); + add_bool_filter_to_json(json_filters, SYSSTR("UseRegexForSearch"), LiveView::s_use_regex_for_search); + add_bool_filter_to_json(json_filters, SYSSTR("ApplySearchFiltersWhenNotSearching"), LiveView::s_apply_search_filters_when_not_searching); + add_bool_filter_to_json(json_filters, to_system(Filter::DefaultObjectsOnly::s_debug_name), Filter::DefaultObjectsOnly::s_enabled); + add_bool_filter_to_json(json_filters, to_system(Filter::IncludeDefaultObjects::s_debug_name), Filter::IncludeDefaultObjects::s_enabled); + add_bool_filter_to_json(json_filters, to_system(Filter::InstancesOnly::s_debug_name), Filter::InstancesOnly::s_enabled); + add_bool_filter_to_json(json_filters, to_system(Filter::NonInstancesOnly::s_debug_name), Filter::NonInstancesOnly::s_enabled); } { - add_array_filter_to_json(json_filters, Filter::ClassNamesFilter::s_debug_name, Filter::ClassNamesFilter::list_class_names, STR("ClassNames")); - add_array_filter_to_json(json_filters, Filter::HasProperty::s_debug_name, Filter::HasProperty::list_properties, STR("Properties")); - add_array_filter_to_json(json_filters, Filter::HasPropertyType::s_debug_name, Filter::HasPropertyType::list_property_types, STR("PropertyTypes")); - add_array_filter_to_json(json_filters, Filter::FunctionParamFlags::s_debug_name, Filter::FunctionParamFlags::s_checkboxes, STR("FunctionParamFlags")); + add_array_filter_to_json(json_filters, to_system(Filter::ClassNamesFilter::s_debug_name), Filter::ClassNamesFilter::list_class_names, SYSSTR("ClassNames")); + add_array_filter_to_json(json_filters, to_system(Filter::HasProperty::s_debug_name), Filter::HasProperty::list_properties, SYSSTR("Properties")); + add_array_filter_to_json(json_filters, to_system(Filter::HasPropertyType::s_debug_name), Filter::HasPropertyType::list_property_types, SYSSTR("PropertyTypes")); + add_array_filter_to_json(json_filters, to_system(Filter::FunctionParamFlags::s_debug_name), Filter::FunctionParamFlags::s_checkboxes, SYSSTR("FunctionParamFlags")); } auto json_file = - File::open(StringType{UE4SSProgram::get_program().get_working_directory()} + std::format(STR("\\liveview\\filters.meta.json")), + File::open(std::filesystem::path{UE4SSProgram::get_program().get_working_directory()} / SYSSTR("UE4SS-config") SYSSTR("liveview")SYSSTR("filters.meta.json"), File::OpenFor::Writing, File::OverwriteExistingFile::Yes, File::CreateIfNonExistent::Yes); int32_t json_indent_level{}; - json_file.write_string_to_file(json.serialize(JSON::ShouldFormat::Yes, &json_indent_level)); + json_file.write_file_string_to_file(to_file(json.serialize(JSON::ShouldFormat::Yes, &json_indent_level))); } static auto save_filters_to_disk() -> void @@ -356,17 +360,27 @@ namespace RC::GUI }); } + template + static auto to_dest_string(T&& input) { + STRING_DISPATCH_NOERR(std::decay_t, to_string, to_wstring, to_u16string) + else if constexpr(std::is_same_v, FName>) { + return to_ue(input); + } + STRING_DISPATCH_ERROR(Dest) + } + template - static auto json_array_to_filters_list(JSON::Array& json_array, std::vector& list, StringType type, std::string& internal_value) -> void + static auto json_array_to_filters_list(JSON::Array& json_array, std::vector& list, SystemStringType type, std::string& internal_value) -> void { list.clear(); - internal_value.clear(); + internal_value.clear(); json_array.for_each([&](JSON::Value& item) { if (!item.is()) { throw std::runtime_error{std::format("Invalid {} in 'filters.meta.json'", to_string(type))}; } - list.emplace_back(item.as()->get_view()); + list.emplace_back(to_dest_string(item.as()->get_view())); + return LoopAction::Continue; }); for (const auto& class_name : list) @@ -390,7 +404,7 @@ namespace RC::GUI static auto internal_load_filters_from_disk() -> void { const auto json_file = - File::open(StringType{UE4SSProgram::get_program().get_working_directory()} + std::format(STR("\\liveview\\filters.meta.json")), + File::open(std::filesystem::path{UE4SSProgram::get_program().get_working_directory()} / SYSSTR("UE4SS-config") / SYSSTR("liveview") / SYSSTR("filters.meta.json"), File::OpenFor::Reading, File::OverwriteExistingFile::No, File::CreateIfNonExistent::Yes); @@ -401,68 +415,68 @@ namespace RC::GUI } const auto json_global_object = JSON::Parser::parse(json_file_contents); - const auto& json_filters = json_global_object->get(STR("Filters")); + const auto& json_filters = json_global_object->get(SYSSTR("Filters")); json_filters.for_each([&](const JSON::Value& filter) { if (!filter.is()) { throw std::runtime_error{"Invalid filter in 'filters.meta.json'"}; } auto& json_object = *filter.as(); - auto filter_name = json_object.get(STR("FilterName")).get_view(); - auto& filter_data = json_object.get(STR("FilterData")); + auto filter_name = json_object.get(SYSSTR("FilterName")).get_view(); + auto& filter_data = json_object.get(SYSSTR("FilterData")); - if (filter_name == STR("IncludeInheritance")) + if (filter_name == SYSSTR("IncludeInheritance")) { - LiveView::s_include_inheritance = filter_data.get(STR("Enabled")).get(); + LiveView::s_include_inheritance = filter_data.get(SYSSTR("Enabled")).get(); } - else if (filter_name == STR("UseRegexForSearch")) + else if (filter_name == SYSSTR("UseRegexForSearch")) { - LiveView::s_use_regex_for_search = filter_data.get(STR("Enabled")).get(); + LiveView::s_use_regex_for_search = filter_data.get(SYSSTR("Enabled")).get(); } - else if (filter_name == STR("ApplySearchFiltersWhenNotSearching")) + else if (filter_name == SYSSTR("ApplySearchFiltersWhenNotSearching")) { - LiveView::s_apply_search_filters_when_not_searching = filter_data.get(STR("Enabled")).get(); + LiveView::s_apply_search_filters_when_not_searching = filter_data.get(SYSSTR("Enabled")).get(); } - else if (filter_name == Filter::DefaultObjectsOnly::s_debug_name) + else if (filter_name == to_system(Filter::DefaultObjectsOnly::s_debug_name)) { - Filter::DefaultObjectsOnly::s_enabled = filter_data.get(STR("Enabled")).get(); + Filter::DefaultObjectsOnly::s_enabled = filter_data.get(SYSSTR("Enabled")).get(); } - else if (filter_name == Filter::IncludeDefaultObjects::s_debug_name) + else if (filter_name == to_system(Filter::IncludeDefaultObjects::s_debug_name)) { - Filter::IncludeDefaultObjects::s_enabled = filter_data.get(STR("Enabled")).get(); + Filter::IncludeDefaultObjects::s_enabled = filter_data.get(SYSSTR("Enabled")).get(); } - else if (filter_name == Filter::InstancesOnly::s_debug_name) + else if (filter_name == to_system(Filter::InstancesOnly::s_debug_name)) { - Filter::InstancesOnly::s_enabled = filter_data.get(STR("Enabled")).get(); + Filter::InstancesOnly::s_enabled = filter_data.get(SYSSTR("Enabled")).get(); } - else if (filter_name == Filter::NonInstancesOnly::s_debug_name) + else if (filter_name == to_system(Filter::NonInstancesOnly::s_debug_name)) { - Filter::NonInstancesOnly::s_enabled = filter_data.get(STR("Enabled")).get(); + Filter::NonInstancesOnly::s_enabled = filter_data.get(SYSSTR("Enabled")).get(); } - else if (filter_name == Filter::ClassNamesFilter::s_debug_name) + else if (filter_name == to_system(Filter::ClassNamesFilter::s_debug_name)) { - Filter::ClassNamesFilter::b_is_exclude = filter_data.get(STR("IsExclude")).get(); - auto& class_names = filter_data.get(STR("ClassNames")); - json_array_to_filters_list(class_names, Filter::ClassNamesFilter::list_class_names, STR("class name"), Filter::ClassNamesFilter::s_internal_class_names); + Filter::ClassNamesFilter::b_is_exclude = filter_data.get(SYSSTR("IsExclude")).get(); + auto& class_names = filter_data.get(SYSSTR("ClassNames")); + json_array_to_filters_list(class_names, Filter::ClassNamesFilter::list_class_names, SYSSTR("class name"), Filter::ClassNamesFilter::s_internal_class_names); } - else if (filter_name == Filter::HasProperty::s_debug_name) + else if (filter_name == to_system(Filter::HasProperty::s_debug_name)) { - auto& properties = filter_data.get(STR("Properties")); - json_array_to_filters_list(properties, Filter::HasProperty::list_properties, STR("property"), Filter::HasProperty::s_internal_properties); + auto& properties = filter_data.get(SYSSTR("Properties")); + json_array_to_filters_list(properties, Filter::HasProperty::list_properties, SYSSTR("property"), Filter::HasProperty::s_internal_properties); } - else if (filter_name == Filter::HasPropertyType::s_debug_name) + else if (filter_name == to_system(Filter::HasPropertyType::s_debug_name)) { - auto& property_types = filter_data.get(STR("PropertyTypes")); + auto& property_types = filter_data.get(SYSSTR("PropertyTypes")); json_array_to_filters_list(property_types, Filter::HasPropertyType::list_property_types, - STR("property type"), + SYSSTR("property type"), Filter::HasPropertyType::s_internal_property_types); } - else if (filter_name == Filter::FunctionParamFlags::s_debug_name) + else if (filter_name == to_system(Filter::FunctionParamFlags::s_debug_name)) { - Filter::FunctionParamFlags::s_include_return_property = filter_data.get(STR("IncludeReturnProperty")).get(); + Filter::FunctionParamFlags::s_include_return_property = filter_data.get(SYSSTR("IncludeReturnProperty")).get(); Filter::FunctionParamFlags::s_checkboxes.fill(false); - auto& function_param_flags = filter_data.get(STR("FunctionParamFlags")); + auto& function_param_flags = filter_data.get(SYSSTR("FunctionParamFlags")); if (function_param_flags.get().size() != Filter::FunctionParamFlags::s_checkboxes.size()) { throw std::runtime_error{"Invalid number of function param flag entires in 'filters.meta.json'"}; @@ -560,17 +574,17 @@ namespace RC::GUI case LiveView::Watch::AcquisitionMethod::StaticFindObject: { auto object_full_name = watch.container->GetFullName(); auto object_type_space_location = object_full_name.find(STR(" ")); - auto object_typeless_name = StringType{object_full_name.begin() + object_type_space_location + 1, object_full_name.end()}; - json_object->new_string(STR("AcquisitionID"), object_typeless_name); + auto object_typeless_name = UEStringType{object_full_name.begin() + object_type_space_location + 1, object_full_name.end()}; + json_object->new_string(SYSSTR("AcquisitionID"), to_system(object_typeless_name)); break; } case LiveView::Watch::AcquisitionMethod::FindFirstOf: - json_object->new_string(STR("AcquisitionID"), watch.container->GetClassPrivate()->GetName()); + json_object->new_string(SYSSTR("AcquisitionID"), to_system(watch.container->GetClassPrivate()->GetName())); break; } - json_object->new_string(STR("PropertyName"), watch.property_name); - json_object->new_number(STR("AcquisitionMethod"), static_cast(watch.acquisition_method)); - json_object->new_number(STR("WatchType"), + json_object->new_string(SYSSTR("PropertyName"), to_system(watch.property_name)); + json_object->new_number(SYSSTR("AcquisitionMethod"), static_cast(watch.acquisition_method)); + json_object->new_number(SYSSTR("WatchType"), watch.container->IsA() ? static_cast(LiveView::Watch::Type::Function) : static_cast(LiveView::Watch::Type::Property)); return json_object; @@ -578,31 +592,30 @@ namespace RC::GUI static auto internal_load_watches_from_disk() -> void { - auto working_directory_path = StringType{UE4SSProgram::get_program().get_working_directory()} + std::format(STR("\\watches\\watches.meta.json")); - auto legacy_root_directory_path = StringType{UE4SSProgram::get_program().get_legacy_root_directory()} + std::format(STR("\\watches\\watches.meta.json")); + auto working_directory_path = SystemStringType{UE4SSProgram::get_program().get_working_directory()} + std::format(SYSSTR("\\watches\\watches.meta.json")); + auto legacy_root_directory_path = SystemStringType{UE4SSProgram::get_program().get_legacy_root_directory()} + std::format(SYSSTR("\\watches\\watches.meta.json")); - StringType json_file_contents; bool is_legacy = !std::filesystem::exists(working_directory_path) && std::filesystem::exists(legacy_root_directory_path); auto json_file = File::open(is_legacy ? legacy_root_directory_path : working_directory_path, File::OpenFor::Reading, File::OverwriteExistingFile::No, File::CreateIfNonExistent::Yes); - + auto json_file_contents = json_file.read_file_all(); if (json_file_contents.empty()) { return; } auto json_global_object = JSON::Parser::parse(json_file_contents); - const auto& elements = json_global_object->get(STR("Watches")); + const auto& elements = json_global_object->get(SYSSTR("Watches")); elements.for_each([](JSON::Value& element) { if (!element.is()) { throw std::runtime_error{"Invalid watch in 'watches.meta.json'"}; } auto& json_watch_object = *element.as(); - auto acquisition_id = json_watch_object.get(STR("AcquisitionID")).get_view(); - auto property_name = json_watch_object.get(STR("PropertyName")).get_view(); + auto acquisition_id = to_ue(json_watch_object.get(SYSSTR("AcquisitionID")).get_view()); + auto property_name = to_ue(json_watch_object.get(SYSSTR("PropertyName")).get_view()); auto acquisition_method = - static_cast(json_watch_object.get(STR("AcquisitionMethod")).get()); - auto watch_type = static_cast(json_watch_object.get(STR("WatchType")).get()); + static_cast(json_watch_object.get(SYSSTR("AcquisitionMethod")).get()); + auto watch_type = static_cast(json_watch_object.get(SYSSTR("WatchType")).get()); UObject* object{}; switch (acquisition_method) @@ -659,7 +672,7 @@ namespace RC::GUI static auto internal_save_watches_to_disk() -> void { auto json = JSON::Object{}; - auto& json_uobjects = json.new_array(STR("Watches")); + auto& json_uobjects = json.new_array(SYSSTR("Watches")); { std::lock_guard lock{LiveView::Watch::s_watch_lock}; @@ -673,12 +686,12 @@ namespace RC::GUI } } - auto json_file = File::open(StringType{UE4SSProgram::get_program().get_working_directory()} + std::format(STR("\\watches\\watches.meta.json")), + auto json_file = File::open(std::filesystem::path{UE4SSProgram::get_program().get_working_directory()} / "watches" / "watches.meta.json", File::OpenFor::Writing, File::OverwriteExistingFile::Yes, File::CreateIfNonExistent::Yes); int32_t json_indent_level{}; - json_file.write_string_to_file(json.serialize(JSON::ShouldFormat::Yes, &json_indent_level)); + json_file.write_file_string_to_file(to_file(json.serialize(JSON::ShouldFormat::Yes, &json_indent_level))); } static auto save_watches_to_disk() -> void @@ -710,14 +723,14 @@ namespace RC::GUI UObjectArray::RemoveUObjectDeleteListener(&FLiveViewDeleteListener::LiveViewDeleteListener); } - LiveView::Watch::Watch(StringType&& object_name, StringType&& property_name) : object_name(object_name), property_name(property_name) + LiveView::Watch::Watch(UEStringType&& object_name, UEStringType&& property_name) : object_name(object_name), property_name(property_name) { auto& file_device = output.get_device(); - file_device.set_file_name_and_path(StringType{UE4SSProgram::get_program().get_working_directory()} + - std::format(STR("\\watches\\ue4ss_watch_{}_{}.txt"), object_name, property_name)); - file_device.set_formatter([](File::StringViewType string) -> File::StringType { - const auto when_as_string = std::format(STR("{:%Y-%m-%d %H:%M:%S}"), std::chrono::system_clock::now()); - return std::format(STR("[{}] {}"), when_as_string, string); + file_device.set_file_name_and_path(to_system_string(std::filesystem::path{UE4SSProgram::get_program().get_working_directory()} / "watches" / + std::format("ue4ss_watch_{}_{}.txt", to_string(object_name), to_string(property_name)))); + file_device.set_formatter([](SystemStringViewType string) -> SystemStringType { + const auto when_as_string = std::format(SYSSTR("{:%Y-%m-%d %H:%M:%S}"), std::chrono::system_clock::now()); + return std::format(SYSSTR("[{}] {}"), when_as_string, string); }); } @@ -1531,7 +1544,7 @@ namespace RC::GUI auto LiveView::search_by_name() -> void { - Output::send(STR("Searching by name...\n")); + Output::send(SYSSTR("Searching by name...\n")); s_name_search_results.clear(); s_name_search_results_set.clear(); UObjectGlobals::ForEachUObject([&](UObject* object, ...) { @@ -1569,14 +1582,14 @@ namespace RC::GUI std::string search_buffer{m_search_by_name_buffer}; if (search_buffer.empty() || s_apply_search_filters_when_not_searching) { - Output::send(STR("Search all chunks\n")); + Output::send(SYSSTR("Search all chunks\n")); s_name_to_search_by.clear(); m_object_iterator = &LiveView::guobjectarray_iterator; m_is_searching_by_name = false; } else { - Output::send(STR("Search for: {}\n"), search_buffer.empty() ? STR("") : to_wstring(search_buffer)); + Output::send(SYSSTR("Search for: {}\n"), search_buffer.empty() ? SYSSTR("") : to_system(search_buffer)); s_name_to_search_by = search_buffer; m_object_iterator = &LiveView::guobjectarray_by_name_iterator; m_is_searching_by_name = true; @@ -1685,14 +1698,14 @@ namespace RC::GUI } } - Output::send(STR("{}\n"), uclass->GetFullName()); + Output::send(SYSSTR("{}\n"), uclass->GetFullName()); ImGui::Text("Properties"); for (FProperty* property : uclass->ForEachProperty()) { if (ImGui::TreeNode(to_string(property->GetFullName()).c_str())) { - Output::send(STR("Show property: {}\n"), property->GetFullName()); + Output::send(SYSSTR("Show property: {}\n"), property->GetFullName()); } } } @@ -1717,7 +1730,7 @@ namespace RC::GUI { if (ImGui::IsItemClicked()) { - printf_s("Clicked: %S\n", ustruct->GetFullName().c_str()); + printf_s("Clicked: " SystemStringPrint "\n", to_system(ustruct->GetFullName()).c_str()); select_object(0, ustruct->GetObjectItem(), ustruct, AffectsHistory::Yes); } } @@ -1956,13 +1969,13 @@ namespace RC::GUI } auto value_as_string = Unreal::UKismetNodeHelperLibrary::GetEnumeratorUserFriendlyName(uenum, enum_index); ImGui::SameLine(); - ImGui::Text("%S", value_as_string.c_str()); + ImGui::Text(SystemStringPrint, to_system(value_as_string).c_str()); render_property_value_context_menu(); } else { ImGui::SameLine(); - ImGui::Text("%S", property_text.GetCharArray()); + ImGui::Text(SystemStringPrint, to_system_string(property_text.GetCharArray()).c_str()); render_property_value_context_menu(); } @@ -1974,7 +1987,7 @@ namespace RC::GUI if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); - ImGui::Text("%S", property->GetFullName().c_str()); + ImGui::Text(SystemStringPrint, to_system_string(property->GetFullName()).c_str()); ImGui::Separator(); ImGui::Text("Offset: 0x%X", property->GetOffset_Internal()); ImGui::Text("Size: 0x%X", property->GetSize()); @@ -1982,12 +1995,13 @@ namespace RC::GUI } auto obj = container_type == ContainerType::Array ? *static_cast(container) : static_cast(container); - StringType parent_name{}; + UEStringType parent_name{}; if (container_type == ContainerType::Object) { parent_name = obj ? obj->GetName() : STR("None"); } - auto edit_property_value_modal_name = to_string(std::format(STR("Edit value of property: {}->{}"), parent_name, property->GetName())); + auto edit_property_value_modal_name = + to_string(std::format(SYSSTR("Edit value of property: {}->{}"), to_system(parent_name), to_system(property->GetName()))); if (open_edit_value_popup) { @@ -2009,7 +2023,7 @@ namespace RC::GUI if (ImGui::Button("Apply")) { FOutputDevice placeholder_device{}; - if (!property->ImportText(to_wstring(m_current_property_value_buffer).c_str(), property->ContainerPtrToValuePtr(container), NULL, obj, &placeholder_device)) + if (!property->ImportText(to_ue(m_current_property_value_buffer).c_str(), property->ContainerPtrToValuePtr(container), NULL, obj, &placeholder_device)) { m_modal_edit_property_value_error_unable_to_edit = true; ImGui::OpenPopup("UnableToSetNewPropertyValueError"); @@ -2076,8 +2090,8 @@ namespace RC::GUI ++index; ImGui::TableNextColumn(); - ImGui::Text("%S", enum_name.c_str()); - if (ImGui::BeginPopupContextItem(to_string(std::format(STR("context-menu-{}"), enum_name)).c_str())) + ImGui::Text(SystemStringPrint, to_system(enum_name).c_str()); + if (ImGui::BeginPopupContextItem(to_string(std::format(SYSSTR("context-menu-{}"), to_system(enum_name))).c_str())) { if (ImGui::MenuItem("Copy name")) { @@ -2092,11 +2106,11 @@ namespace RC::GUI } ImGui::TableNextColumn(); - ImGui::Text("%S", enum_friendly_name.c_str()); + ImGui::Text(SystemStringPrint, to_system(enum_friendly_name).c_str()); ImGui::TableNextColumn(); ImGui::Text("%lld", name.Value); - if (ImGui::BeginPopupContextItem(to_string(std::format(STR("context-menu-{}-{}"), enum_name, name.Value)).c_str())) + if (ImGui::BeginPopupContextItem(to_string(std::format(SYSSTR("context-menu-{}-{}"), to_system(enum_name), to_system(name.Value))).c_str())) { if (ImGui::MenuItem("Copy value")) { @@ -2111,7 +2125,7 @@ namespace RC::GUI } ImGui::TableNextColumn(); - ImGui::PushID(to_string(std::format(STR("button_add_{}"), enum_name)).c_str()); + ImGui::PushID(to_string(std::format(SYSSTR("button_add_{}"), to_system(enum_name))).c_str()); if (ImGui::Button("+")) { open_add_name_popup = true; @@ -2119,18 +2133,18 @@ namespace RC::GUI } ImGui::PopID(); ImGui::SameLine(); - ImGui::PushID(to_string(std::format(STR("button_remove_{}"), enum_name)).c_str()); + ImGui::PushID(to_string(std::format(SYSSTR("button_remove_{}"), to_system(enum_name))).c_str()); if (ImGui::Button("-")) { uenum->RemoveFromNamesAt(index, 1); } ImGui::PopID(); - std::string edit_enum_name_modal_name = to_string(std::format(STR("Edit enum name for: {}"), name.Key.ToString())); + std::string edit_enum_name_modal_name = to_string(std::format(SYSSTR("Edit enum name for: {}"), to_system(name.Key.ToString()))); - std::string edit_enum_value_modal_name = to_string(std::format(STR("Edit enum value for: {}"), name.Key.ToString())); + std::string edit_enum_value_modal_name = to_string(std::format(SYSSTR("Edit enum value for: {}"), to_system(name.Key.ToString()))); - std::string add_enum_name_modal_name = to_string(std::format(STR("Enter new enum name after: {}"), name.Key.ToString())); + std::string add_enum_name_modal_name = to_string(std::format(SYSSTR("Enter new enum name after: {}"), to_system(name.Key.ToString()))); if (open_edit_name_popup) { @@ -2177,7 +2191,7 @@ namespace RC::GUI if (ImGui::Button("Apply")) { FOutputDevice placeholder_device{}; - StringType new_name = to_wstring(m_current_property_value_buffer); + UEStringType new_name = to_ue(m_current_property_value_buffer); FName new_key = FName(new_name, FNAME_Add); uenum->EditNameAt(index, new_key); if (uenum->GetEnumNames()[index].Key.ToString() != new_name) @@ -2261,7 +2275,7 @@ namespace RC::GUI if (ImGui::Button("Apply")) { FOutputDevice placeholder_device{}; - StringType new_name = to_wstring(m_current_property_value_buffer); + auto new_name = to_ue(m_current_property_value_buffer); FName new_key = FName(new_name, FNAME_Add); int64 value = names[index].Value; @@ -2538,7 +2552,7 @@ namespace RC::GUI ImGui::EndPopup(); } ImGui::Text("ClassPrivate: %s", to_string(object->GetClassPrivate()->GetName()).c_str()); - ImGui::Text("Path: %S", object->GetPathName().c_str()); + ImGui::Text("Path: " SystemStringPrint, to_system(object->GetPathName()).c_str()); render_flags(object, "ObjectFlags"); if (auto as_class = Cast(object); as_class) { @@ -2582,7 +2596,7 @@ namespace RC::GUI auto supers_super = *supers_super_it; super_size -= supers_super->GetPropertiesSize(); } - ImGui::Text("%S: 0x%X (0x%X)", super->GetName().c_str(), super_size, super->GetPropertiesSize()); + ImGui::Text(SystemStringPrint ": 0x%X (0x%X)", to_system(super->GetName()).c_str(), super_size, super->GetPropertiesSize()); } ImGui::Unindent(); @@ -2612,7 +2626,7 @@ namespace RC::GUI bool tried_to_open_nullptr_property{}; auto property_full_name = property->GetFullName(); - ImGui::Text("Selected: %S", property->GetName().c_str()); + ImGui::Text("Selected: " SystemStringPrint, to_system(property->GetName()).c_str()); ImGui::Text("Address: %016llX", std::bit_cast(property)); if (ImGui::BeginPopupContextItem(to_string(property_full_name).c_str())) { @@ -2622,8 +2636,8 @@ namespace RC::GUI } ImGui::EndPopup(); } - ImGui::Text("Class: %S", property->GetClass().GetName().c_str()); - ImGui::Text("Path: %S", property->GetPathName().c_str()); + ImGui::Text("Class: " SystemStringPrint, to_system(property->GetClass().GetName()).c_str()); + ImGui::Text("Path: " SystemStringPrint, to_system(property->GetPathName()).c_str()); ImGui::Separator(); @@ -2687,7 +2701,7 @@ namespace RC::GUI ImGui::Unindent(); ImGui::Text("RepIndex: %i (0x%X)", property->GetRepIndex(), property->GetRepIndex()); ImGui::Text("OffsetInternal: %i (0x%X)", property->GetOffset_Internal(), property->GetOffset_Internal()); - ImGui::Text("RepNotifyFunc: %S", property->GetRepNotifyFunc().ToString().c_str()); + ImGui::Text("RepNotifyFunc: " SystemStringPrint, to_system(property->GetRepNotifyFunc().ToString()).c_str()); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); @@ -2696,7 +2710,7 @@ namespace RC::GUI } auto render_property_pointer = [](std::string_view pointer_name, FProperty* property) { - ImGui::Text("%s: %p %S", pointer_name.data(), property, property ? property->GetFullName().c_str() : STR("None")); + ImGui::Text("%s: %p " SystemStringPrint, pointer_name.data(), property, property ? to_system(property->GetFullName()).c_str() : SYSSTR("None")); return property; }; int go_to_property_menu_count{}; @@ -2898,7 +2912,7 @@ namespace RC::GUI { FString live_value_fstring{}; watch.property->ExportTextItem(live_value_fstring, watch.property->ContainerPtrToValuePtr(watch.container), nullptr, nullptr, 0); - auto live_value_string = StringType{live_value_fstring.GetCharArray()}; + auto live_value_string = UEStringType{live_value_fstring.GetCharArray()}; if (watch.property_value == live_value_string) { @@ -2907,12 +2921,12 @@ namespace RC::GUI watch.property_value = std::move(live_value_string); - const auto when_as_string = std::format(STR("{:%H:%M:%S}"), std::chrono::system_clock::now()); - watch.history.append(to_string(when_as_string + STR(" ") + watch.property_value + STR("\n"))); + const auto when_as_string = std::format("{:%H:%M:%S}", std::chrono::system_clock::now()); + watch.history.append(when_as_string + " " + to_string(watch.property_value) + "\n"); if (watch.write_to_file) { - watch.output.send(STR("{}\n"), watch.property_value); + watch.output.send(SYSSTR("{}\n"), watch.property_value); } } @@ -2943,12 +2957,12 @@ namespace RC::GUI auto num_params = function->GetNumParms(); - const auto when_as_string = std::format(STR("{:%H:%M:%S}"), std::chrono::system_clock::now()); - StringType buffer{std::format(STR("Received call @ {}.\n"), when_as_string)}; + const auto when_as_string = std::format(SYSSTR("{:%H:%M:%S}"), std::chrono::system_clock::now()); + auto buffer{std::format(SYSSTR("Received call @ {}.\n"), when_as_string)}; - buffer.append(std::format(STR(" Context:\n {}\n"), context.Context->GetFullName())); + buffer.append(std::format(SYSSTR(" Context:\n {}\n"), to_system(context.Context->GetFullName()))); - buffer.append(STR(" Locals:\n")); + buffer.append(SYSSTR(" Locals:\n")); bool has_local_params{}; for (const auto& param : function->ForEachProperty()) { @@ -2960,15 +2974,15 @@ namespace RC::GUI FString param_text{}; auto container_ptr = param->ContainerPtrToValuePtr(context.TheStack.Locals()); param->ExportTextItem(param_text, container_ptr, container_ptr, std::bit_cast(function), NULL); - buffer.append(std::format(STR(" {} = {}\n"), param->GetName(), param_text.GetCharArray())); + buffer.append(std::format(SYSSTR(" {} = {}\n"), to_system(param->GetName()), to_system(param_text.GetCharArray()))); } if (!has_local_params) { - buffer.append(STR(" \n")); + buffer.append(SYSSTR(" \n")); } bool has_out_params{}; - buffer.append(STR(" Out:\n")); + buffer.append(SYSSTR(" Out:\n")); for (const auto& param : function->ForEachProperty()) { if (param->HasAnyPropertyFlags(CPF_ReturnParm)) @@ -2983,33 +2997,33 @@ namespace RC::GUI FString param_text{}; auto container_ptr = FindOutParamValueAddress(context.TheStack, param); param->ExportTextItem(param_text, container_ptr, container_ptr, std::bit_cast(function), NULL); - buffer.append(std::format(STR(" {} = {}\n"), param->GetName(), param_text.GetCharArray())); + buffer.append(std::format(SYSSTR(" {} = {}\n"), to_system(param->GetName()), to_system(param_text.GetCharArray()))); } if (!has_out_params) { - buffer.append(STR(" \n")); + buffer.append(SYSSTR(" \n")); } - buffer.append(STR(" ReturnValue\n")); + buffer.append(SYSSTR(" ReturnValue\n")); auto return_property = function->GetReturnProperty(); if (return_property) { FString return_property_text{}; auto container_ptr = context.RESULT_DECL; return_property->ExportTextItem(return_property_text, container_ptr, container_ptr, std::bit_cast(function), NULL); - buffer.append(std::format(STR(" {}"), return_property_text.GetCharArray())); + buffer.append(std::format(SYSSTR(" {}"), to_system(return_property_text.GetCharArray()))); } else { - buffer.append(STR(" ")); + buffer.append(SYSSTR(" ")); } - buffer.append(STR("\n\n")); + buffer.append(SYSSTR("\n\n")); watch.history.append(to_string(buffer)); if (watch.write_to_file) { - watch.output.send(STR("{}"), buffer); + watch.output.send(SYSSTR("{}"), buffer); } } @@ -3200,7 +3214,7 @@ namespace RC::GUI while (std::getline(ss, class_name, ',')) { std::erase_if(class_name, isspace); - Filter::ClassNamesFilter::list_class_names.emplace_back(to_wstring(class_name)); + Filter::ClassNamesFilter::list_class_names.emplace_back(to_ue(class_name)); } } } @@ -3217,7 +3231,7 @@ namespace RC::GUI while (std::getline(ss, class_name, ',')) { std::erase_if(class_name, isspace); - Filter::ClassNamesFilter::list_class_names.emplace_back(to_wstring(class_name)); + Filter::ClassNamesFilter::list_class_names.emplace_back(to_ue(class_name)); } } } @@ -3238,7 +3252,7 @@ namespace RC::GUI while (std::getline(ss, property_name, ',')) { std::erase_if(property_name, isspace); - Filter::HasProperty::list_properties.emplace_back(to_wstring(property_name)); + Filter::HasProperty::list_properties.emplace_back(to_ue(property_name)); } } } @@ -3261,7 +3275,7 @@ namespace RC::GUI std::erase_if(property_type_name, isspace); if (!property_type_name.empty()) { - Filter::HasPropertyType::list_property_types.emplace_back(FName(to_wstring(property_type_name), FNAME_Add)); + Filter::HasPropertyType::list_property_types.emplace_back(FName(to_ue(property_type_name), FNAME_Add)); } } } @@ -3415,7 +3429,7 @@ namespace RC::GUI // Remember to update text width calculations for the last ImGui::PushItemWidth call if this text gets updated. if (ImGui::Button(ICON_FA_COPY " Copy search result")) { - StringType result{}; + SystemStringType result{}; auto is_below_425 = Version::IsBelow(4, 25); for (const auto& search_result : s_name_search_results) { @@ -3446,7 +3460,7 @@ namespace RC::GUI { if (ImGui::MenuItem(ICON_FA_COPY " Copy Full Name")) { - Output::send(STR("Copy Full Name: {}\n"), object->GetFullName()); + Output::send(SYSSTR("Copy Full Name: {}\n"), object->GetFullName()); ImGui::SetClipboardText(tree_node_name.c_str()); } if (object->IsA()) @@ -3584,7 +3598,7 @@ namespace RC::GUI auto& watch = *watch_ptr; ImGui::TableNextRow(); ImGui::TableNextColumn(); - if (ImGui::Checkbox(to_string(std::format(STR("##watch-on-off-{}"), watch.hash)).c_str(), &watch.enabled)) + if (ImGui::Checkbox(to_string(std::format(SYSSTR("##watch-on-off-{}"), watch.hash)).c_str(), &watch.enabled)) { if (watch.container->IsA()) { @@ -3598,7 +3612,7 @@ namespace RC::GUI ImGui::EndTooltip(); } ImGui::SameLine(0.0f, 2.0f); - ImGui::Checkbox(to_string(std::format(STR("##watch-write-to-file-{}"), watch.hash)).c_str(), &watch.write_to_file); + ImGui::Checkbox(to_string(std::format(SYSSTR("##watch-write-to-file-{}"), watch.hash)).c_str(), &watch.write_to_file); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); @@ -3613,7 +3627,7 @@ namespace RC::GUI ImGui::PopStyleVar(); ImGui::TableNextColumn(); - ImGui::Text("%S.%S", watch.object_name.c_str(), watch.property_name.c_str()); + ImGui::Text(SystemStringPrint "." SystemStringPrint, to_system(watch.object_name).c_str(), to_system(watch.property_name).c_str()); if (watch.show_history) { ImGui::PushID(std::format("history_{}", watch.hash).c_str()); @@ -3625,12 +3639,12 @@ namespace RC::GUI ImGui::PopID(); } ImGui::TableNextColumn(); - if (ImGui::Checkbox(to_string(std::format(STR("##watch-from-disk-{}"), watch.hash)).c_str(), &watch.load_on_startup)) + if (ImGui::Checkbox(to_string(std::format(SYSSTR("##watch-from-disk-{}"), watch.hash)).c_str(), &watch.load_on_startup)) { save_watches_to_disk(); } ImGui::SetNextWindowSize({690.0f, 0.0f}); - if (ImGui::BeginPopupContextItem(to_string(std::format(STR("##watch-from-disk-settings-popup-{}"), watch.hash)).c_str())) + if (ImGui::BeginPopupContextItem(to_string(std::format(SYSSTR("##watch-from-disk-settings-popup-{}"), watch.hash)).c_str())) { ImGui::Text("Acquisition Method"); ImGui::Text("This determines how the watch will be reacquired."); diff --git a/UE4SS/src/GUI/DX11.cpp b/UE4SS/src/GUI/Platform/D3D11/DX11.cpp similarity index 100% rename from UE4SS/src/GUI/DX11.cpp rename to UE4SS/src/GUI/Platform/D3D11/DX11.cpp diff --git a/UE4SS/src/GUI/GLFW3_OpenGL3.cpp b/UE4SS/src/GUI/Platform/GLFW/GLFW3_OpenGL3.cpp similarity index 77% rename from UE4SS/src/GUI/GLFW3_OpenGL3.cpp rename to UE4SS/src/GUI/Platform/GLFW/GLFW3_OpenGL3.cpp index 24727ba9a..663becc37 100644 --- a/UE4SS/src/GUI/GLFW3_OpenGL3.cpp +++ b/UE4SS/src/GUI/Platform/GLFW/GLFW3_OpenGL3.cpp @@ -10,13 +10,23 @@ #include #include +#include + +#ifdef LINUX +#include +#endif + namespace RC::GUI { static void glfw_error_callback(int error, const char* description) { - Output::send(STR("Glfw Error {}: {}\n"), error, to_wstring(description)); + Output::send(SYSSTR("Glfw Error {}: {}\n"), error, description); } +#ifdef LINUX + static std::shared_ptr g_input_source; +#endif + auto Backend_GLFW3_OpenGL3::init() -> void { // Setup window @@ -46,6 +56,25 @@ namespace RC::GUI throw std::runtime_error{"Was unable to initialize glad"}; } + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) + { + throw std::runtime_error{"Was unable to initialize glad"}; + } + +#ifdef LINUX + if (auto source = Input::Handler::get_input_source("GLFW3")) + { + g_input_source = std::dynamic_pointer_cast(source); + glfwSetKeyCallback(m_window, [](GLFWwindow* window, int key, int scancode, int action, int mods) { + // map keys to windows'definition + if (g_input_source) + { + g_input_source->receive_input(key, action, mods); + } + }); + } +#endif + int left, top, right, bottom; glfwGetWindowFrameSize(m_window, &left, &top, &right, &bottom); glfwSetWindowSize(m_window, 1280 - left - right, 800 - top - bottom); @@ -80,6 +109,12 @@ namespace RC::GUI { ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); + glfwDestroyWindow(m_window); + m_window = nullptr; + +#ifdef LINUX + g_input_source = nullptr; +#endif } auto Backend_GLFW3_OpenGL3::cleanup() -> void diff --git a/UE4SS/src/GUI/Windows.cpp b/UE4SS/src/GUI/Platform/Windows/Windows.cpp similarity index 97% rename from UE4SS/src/GUI/Windows.cpp rename to UE4SS/src/GUI/Platform/Windows/Windows.cpp index 486654ef4..26cee4cdd 100644 --- a/UE4SS/src/GUI/Windows.cpp +++ b/UE4SS/src/GUI/Platform/Windows/Windows.cpp @@ -36,10 +36,10 @@ namespace RC::GUI auto Backend_Windows::create_window(int loc_x, int loc_y, int size_x, int size_y) -> void { - StringType title_bar_text{STR("UE4SS Debugging Tools")}; + SystemStringType title_bar_text{SYSSTR("UE4SS Debugging Tools")}; if (dynamic_cast(m_gfx_backend)) { - title_bar_text.append(STR(" (DX11)")); + title_bar_text.append(SYSSTR(" (DX11)")); } // ImGui_ImplWin32_EnableDpiAwareness() diff --git a/UE4SS/src/GUI/SearcherWidget.cpp b/UE4SS/src/GUI/SearcherWidget.cpp index 2cb338cc8..214a68a92 100644 --- a/UE4SS/src/GUI/SearcherWidget.cpp +++ b/UE4SS/src/GUI/SearcherWidget.cpp @@ -55,7 +55,7 @@ namespace RC::GUI std::string search_buffer{m_search_by_name_buffer}; if (search_buffer.empty()) { - // Output::send(STR("Search all functions\n")); + // Output::send(SYSSTR("Search all functions\n")); m_name_to_search_by.clear(); m_current_iterator = m_all_iterator; m_is_searching_by_name = false; @@ -63,7 +63,7 @@ namespace RC::GUI } else { - // Output::send(STR("Search for: {}\n"), search_buffer.empty() ? STR("") : to_wstring(search_buffer)); + // Output::send(SYSSTR("Search for: {}\n"), search_buffer.empty() ? STR("") : to_wstring(search_buffer)); m_name_to_search_by = search_buffer; m_current_iterator = m_search_iterator; m_is_searching_by_name = true; diff --git a/UE4SS/src/GUI/UFunctionCallerWidget.cpp b/UE4SS/src/GUI/UFunctionCallerWidget.cpp index e072e6332..b898a3608 100644 --- a/UE4SS/src/GUI/UFunctionCallerWidget.cpp +++ b/UE4SS/src/GUI/UFunctionCallerWidget.cpp @@ -18,6 +18,9 @@ #include #include +#undef min +#undef max + namespace RC::GUI { UFunctionCallerWidget::UFunctionCallerWidget() = default; @@ -139,7 +142,7 @@ namespace RC::GUI static bool s_do_call{}; static UObject* s_instance{}; - static StringType s_cmd{}; + static SystemStringType s_cmd{}; static FOutputDevice s_ar{}; static UFunction* s_function{}; static UObject* s_executor{}; @@ -150,9 +153,9 @@ namespace RC::GUI s_do_call = false; auto& function_flags = s_function->GetFunctionFlags(); function_flags |= FUNC_Exec; - Output::send(STR("Processing command: {}\n"), s_cmd); - bool call_succeeded = s_instance->ProcessConsoleExec(s_cmd.c_str(), s_ar, s_executor); - Output::send(STR("call_succeeded: {}\n"), call_succeeded); + Output::send(SYSSTR("Processing command: {}\n"), s_cmd); + bool call_succeeded = s_instance->ProcessConsoleExec(to_ue(s_cmd).c_str(), s_ar, s_executor); + Output::send(SYSSTR("call_succeeded: {}\n"), call_succeeded); function_flags &= ~FUNC_Exec; } } @@ -164,13 +167,13 @@ namespace RC::GUI } auto function = m_currently_selected_function->function; - auto cmd = std::format(STR("{}"), function->GetName()); + auto cmd = std::format(SYSSTR("{}"), to_system(function->GetName())); for (const auto& param : m_params_for_selected_function) { - cmd.append(std::format(STR(" {}"), to_wstring(param.value_from_ui))); + cmd.append(std::format(SYSSTR(" {}"), to_system(param.value_from_ui))); } - Output::send(STR("Queueing command: {}\n"), cmd); + Output::send(SYSSTR("Queueing command: {}\n"), cmd); s_cmd = cmd; s_instance = instance; @@ -223,41 +226,49 @@ namespace RC::GUI { if (auto as_struct_property = CastField(param.unreal_param); as_struct_property) { - ImGui::Text("%S (%S)", param.unreal_param->GetClass().GetName().c_str(), as_struct_property->GetStruct()->GetName().c_str()); + ImGui::Text(SystemStringPrint " (" SystemStringPrint ")", + to_system(param.unreal_param->GetClass().GetName()).c_str(), + to_system(as_struct_property->GetStruct()->GetName()).c_str()); } else if (auto as_array_property = CastField(param.unreal_param); as_array_property) { - ImGui::Text("%S (%S)", param.unreal_param->GetClass().GetName().c_str(), as_array_property->GetInner()->GetName().c_str()); + ImGui::Text(SystemStringPrint " (" SystemStringPrint ")", + to_system(param.unreal_param->GetClass().GetName()).c_str(), + to_system(as_array_property->GetInner()->GetName()).c_str()); } else if (auto as_object_property = CastField(param.unreal_param); as_object_property) { - ImGui::Text("%S (%S)", param.unreal_param->GetClass().GetName().c_str(), as_object_property->GetPropertyClass()->GetName().c_str()); + ImGui::Text(SystemStringPrint " (" SystemStringPrint ")", + to_system(param.unreal_param->GetClass().GetName()).c_str(), + to_system(as_object_property->GetPropertyClass()->GetName()).c_str()); } else if (auto as_class_property = CastField(param.unreal_param); as_class_property) { - ImGui::Text("%S (%S)", param.unreal_param->GetClass().GetName().c_str(), as_class_property->GetMetaClass()->GetName().c_str()); + ImGui::Text(SystemStringPrint " (" SystemStringPrint ")", + to_system(param.unreal_param->GetClass().GetName()).c_str(), + to_system(as_class_property->GetMetaClass()->GetName()).c_str()); } else { - ImGui::Text("%S", param.unreal_param->GetClass().GetName().c_str()); + ImGui::Text(SystemStringPrint, to_system(param.unreal_param->GetClass().GetName()).c_str()); } } static auto get_typeless_object_name(UObject* object) -> std::string { - auto object_name = to_string(object->GetFullName()); - auto object_name_type_space_location = object_name.find(" "); + auto object_name = to_system(object->GetFullName()); + auto object_name_type_space_location = object_name.find(SYSSTR(" ")); if (object_name_type_space_location == object_name.npos) { - Output::send(STR("Could not copy name of PlayerController, was unable to find space in full PlayerController name: '{}'."), - to_wstring(object_name)); + Output::send(SYSSTR("Could not copy name of PlayerController, was unable to find space in full PlayerController name: '{}'."), + object_name); return {}; } else { if (object_name_type_space_location > static_cast(std::numeric_limits::max())) { - Output::send(STR("integer overflow when converting pc_name_type_space_location to signed")); + Output::send(SYSSTR("integer overflow when converting pc_name_type_space_location to signed")); return {}; } else @@ -283,7 +294,7 @@ namespace RC::GUI return params.ReturnValue; } - static auto render_other_list(std::string_view menu_name, StringViewType class_name, UFunctionParam& param) -> void + static auto render_other_list(std::string_view menu_name, UEStringViewType class_name, UFunctionParam& param) -> void { if (ImGui::BeginMenu(menu_name.data())) { @@ -313,7 +324,7 @@ namespace RC::GUI { m_prev_instance = instance; - auto popup_modal_id = to_string(std::format(STR("##functions-for-{}"), instance->HashObject())); + auto popup_modal_id = to_string(std::format(SYSSTR("##functions-for-{}"), instance->HashObject())); auto& is_open = is_widget_open(); if (is_open) { diff --git a/UE4SS/src/LuaLibrary.cpp b/UE4SS/src/LuaLibrary.cpp index 2d5e608e2..da6add597 100644 --- a/UE4SS/src/LuaLibrary.cpp +++ b/UE4SS/src/LuaLibrary.cpp @@ -33,13 +33,13 @@ namespace RC::LuaLibrary { auto* output_device = get_outputdevice_ref(lua); - StringType formatted_string = STR("[Lua] "); - StringType outdevice_string; + SystemStringType formatted_string = SYSSTR("[Lua] "); + SystemStringType outdevice_string; if (output_device) { // Remove stack item from get_outputdevice_ref's lua_getglobal lua.discard_value(-1); - outdevice_string = STR("[Lua] "); + outdevice_string = SYSSTR("[Lua] "); } int32_t stack_size = lua.get_stack_size(); @@ -47,13 +47,13 @@ namespace RC::LuaLibrary { // lua_tostring (macro of lua_tolstring) is NOT the same as luaL_tolstring // luaL_tolstring provides tostring()-ish conversion for any value - auto lua_str = to_generic_string(luaL_tolstring(lua.get_lua_state(), i, nullptr)); + auto lua_str = to_system(luaL_tolstring(lua.get_lua_state(), i, nullptr)); if (i > 1) { // Use double tab, as single tab might make the spacing too thin in the console - formatted_string.append(STR("\t\t")); - if (output_device) outdevice_string.append(STR(" ")); + formatted_string.append(SYSSTR("\t\t")); + if (output_device) outdevice_string.append(SYSSTR(" ")); } formatted_string.append(lua_str); if (output_device) outdevice_string.append(lua_str); @@ -64,7 +64,7 @@ namespace RC::LuaLibrary Output::send(formatted_string); - if (output_device) output_device->Log(outdevice_string.c_str()); + if (output_device) output_device->Log(to_ue_string(outdevice_string).c_str()); return 0; } @@ -73,7 +73,7 @@ namespace RC::LuaLibrary { if (lua.get_stack_size() != 1 || !lua.is_integer()) { - Output::send(STR("[Fatal] Lua function 'DerefToInt32' must have only 1 parameter and it must be of type 'int'.\n")); + Output::send(SYSSTR("[Fatal] Lua function 'DerefToInt32' must have only 1 parameter and it must be of type 'int'.\n")); lua.set_nil(); return 1; } @@ -83,7 +83,7 @@ namespace RC::LuaLibrary if (int32_val == 0) { - Output::send(STR("[Fatal] Address passed to Lua function 'DerefToInt32' was not a valid pointer.\n")); + Output::send(SYSSTR("[Fatal] Address passed to Lua function 'DerefToInt32' was not a valid pointer.\n")); lua.set_nil(); return 1; } @@ -98,7 +98,7 @@ namespace RC::LuaLibrary // Logging will only happen to the debug console but it's something at least if (!Output::has_internal_error()) { - Output::send(STR("Error: {}\n"), to_wstring(e)); + Output::send(SYSSTR("Error: {}\n"), e); } else { @@ -106,31 +106,31 @@ namespace RC::LuaLibrary } } - static auto exported_function_status_to_string(ExportedFunctionStatus status) -> std::wstring_view + static auto exported_function_status_to_string(ExportedFunctionStatus status) -> SystemStringViewType { switch (status) { case ExportedFunctionStatus::NO_ERROR_TO_EXPORT: - return L"NO_ERROR_TO_EXPORT | 0"; + return SYSSTR("NO_ERROR_TO_EXPORT | 0"); case ExportedFunctionStatus::UNKNOWN_ERROR: - return L"UNKNOWN_ERROR | 7"; + return SYSSTR("UNKNOWN_ERROR | 7"); case ExportedFunctionStatus::SUCCESS: - return L"SUCCESS | 1"; + return SYSSTR("SUCCESS | 1"); case ExportedFunctionStatus::VARIABLE_NOT_FOUND: - return L"VARIABLE_NOT_FOUND | 2"; + return SYSSTR("VARIABLE_NOT_FOUND | 2"); case ExportedFunctionStatus::MOD_IS_NULLPTR: - return L"MOD_IS_NULLPTR | 3"; + return SYSSTR("MOD_IS_NULLPTR | 3"); case ExportedFunctionStatus::SCRIPT_FUNCTION_RETURNED_FALSE: - return L"SCRIPT_FUNCTION_RETURNED_FALSE | 4"; + return SYSSTR("SCRIPT_FUNCTION_RETURNED_FALSE | 4"); case ExportedFunctionStatus::UNABLE_TO_CALL_SCRIPT_FUNCTION: - return L"UNABLE_TO_CALL_SCRIPT_FUNCTION | 5"; + return SYSSTR("UNABLE_TO_CALL_SCRIPT_FUNCTION | 5"); case ExportedFunctionStatus::SCRIPT_FUNCTION_NOT_FOUND: - return L"SCRIPT_FUNCTION_NOT_FOUND | 6"; + return SYSSTR("SCRIPT_FUNCTION_NOT_FOUND | 6"); case ExportedFunctionStatus::UE4SS_NOT_INITIALIZED: - return L"UE4SS_NOT_INITIALIZED | 8"; + return SYSSTR("UE4SS_NOT_INITIALIZED | 8"); } - return L"Missed switch case"; + return SYSSTR("Missed switch case"); } auto get_lua_state_by_mod_name(const char* mod_name) -> lua_State* @@ -184,7 +184,7 @@ namespace RC::LuaLibrary if (!Unreal::UnrealInitializer::StaticStorage::bIsInitialized) { return_struct.status = ExportedFunctionStatus::UE4SS_NOT_INITIALIZED; - Output::send(STR("set_script_variable_int32 | UE4SS is not initialized\n")); + Output::send(SYSSTR("set_script_variable_int32 | UE4SS is not initialized\n")); return; } @@ -194,14 +194,14 @@ namespace RC::LuaLibrary const std::wstring variable_name_wide = std::wstring(tmp_var_name.begin(), tmp_var_name.end()); const std::string tmp_mod_name = mod_name; const std::wstring mod_name_wide = std::wstring(tmp_mod_name.begin(), tmp_mod_name.end()); - Output::send(STR("Setting variable '{}' in mod '{}' to {}\n"), variable_name_wide, mod_name_wide, new_value); + Output::send(SYSSTR("Setting variable '{}' in mod '{}' to {}\n"), variable_name_wide, mod_name_wide, new_value); //*/ auto mod = UE4SSProgram::find_lua_mod_by_name(mod_name, UE4SSProgram::IsInstalled::Yes, UE4SSProgram::IsStarted::Yes); if (!mod) { return_struct.status = ExportedFunctionStatus::MOD_IS_NULLPTR; - Output::send(STR("set_script_variable_int32 | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); + Output::send(SYSSTR("set_script_variable_int32 | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); return; } @@ -213,7 +213,7 @@ namespace RC::LuaLibrary if (type == LUA_TNIL) { return_struct.status = ExportedFunctionStatus::VARIABLE_NOT_FOUND; - Output::send(STR("set_script_variable_int32 | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); + Output::send(SYSSTR("set_script_variable_int32 | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); return; } @@ -221,7 +221,7 @@ namespace RC::LuaLibrary lua_setglobal(lua.get_lua_state(), variable_name); return_struct.status = ExportedFunctionStatus::SUCCESS; - Output::send(STR("set_script_variable_int32 | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); + Output::send(SYSSTR("set_script_variable_int32 | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); } catch (std::runtime_error& e) { @@ -240,7 +240,7 @@ namespace RC::LuaLibrary if (!Unreal::UnrealInitializer::StaticStorage::bIsInitialized) { return_struct.status = ExportedFunctionStatus::UE4SS_NOT_INITIALIZED; - Output::send(STR("set_script_variable_default_data | UE4SS is not initialized\n")); + Output::send(SYSSTR("set_script_variable_default_data | UE4SS is not initialized\n")); return; } @@ -257,11 +257,11 @@ namespace RC::LuaLibrary { const std::string tmp_data1_value_ansi = external_data.data1.as_string; const std::wstring data1_value_wide = std::wstring(tmp_data1_value_ansi.begin(), tmp_data1_value_ansi.end()); - Output::send(STR("Setting '{}.data1' as string to '{}' in mod '{}'"), variable_name_wide, data1_value_wide, mod_name_wide); + Output::send(SYSSTR("Setting '{}.data1' as string to '{}' in mod '{}'"), variable_name_wide, data1_value_wide, mod_name_wide); break; } case DefaultDataType::Float: - Output::send(STR("Setting '{}.data1' as float to '{}' in mod '{}'"), variable_name_wide, external_data.data1.as_float, mod_name_wide); + Output::send(SYSSTR("Setting '{}.data1' as float to '{}' in mod '{}'"), variable_name_wide, external_data.data1.as_float, mod_name_wide); break; } //*/ @@ -270,7 +270,7 @@ namespace RC::LuaLibrary if (!mod) { return_struct.status = ExportedFunctionStatus::MOD_IS_NULLPTR; - Output::send(STR("set_script_variable_default_data | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); + Output::send(SYSSTR("set_script_variable_default_data | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); return; } @@ -347,7 +347,7 @@ namespace RC::LuaLibrary if (!Unreal::UnrealInitializer::StaticStorage::bIsInitialized) { return_struct.status = ExportedFunctionStatus::UE4SS_NOT_INITIALIZED; - Output::send(STR("call_script_function | UE4SS is not initialized\n")); + Output::send(SYSSTR("call_script_function | UE4SS is not initialized\n")); return; } @@ -357,14 +357,14 @@ namespace RC::LuaLibrary const std::wstring func_name_wide = std::wstring(tmp_func_name.begin(), tmp_func_name.end()); const std::string tmp_mod_name = mod_name; const std::wstring mod_name_wide = std::wstring(tmp_mod_name.begin(), tmp_mod_name.end()); - Output::send(STR("Calling script function '{}' in mod '{}'\n"), func_name_wide, mod_name_wide); + Output::send(SYSSTR("Calling script function '{}' in mod '{}'\n"), func_name_wide, mod_name_wide); //*/ auto mod = UE4SSProgram::find_lua_mod_by_name(mod_name, UE4SSProgram::IsInstalled::Yes, UE4SSProgram::IsStarted::Yes); if (!mod) { return_struct.status = ExportedFunctionStatus::MOD_IS_NULLPTR; - Output::send(STR("call_script_function | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); + Output::send(SYSSTR("call_script_function | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); return; } @@ -377,7 +377,7 @@ namespace RC::LuaLibrary catch (std::runtime_error&) { return_struct.status = ExportedFunctionStatus::SCRIPT_FUNCTION_NOT_FOUND; - Output::send(STR("call_script_function | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); + Output::send(SYSSTR("call_script_function | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); return; } @@ -414,7 +414,7 @@ namespace RC::LuaLibrary return_struct.status = ExportedFunctionStatus::SUCCESS; } - Output::send(STR("call_script_function | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); + Output::send(SYSSTR("call_script_function | return_struct.status: {}\n"), exported_function_status_to_string(return_struct.status)); } catch (std::runtime_error& e) { diff --git a/UE4SS/src/LuaType/LuaCustomProperty.cpp b/UE4SS/src/LuaType/LuaCustomProperty.cpp index 90b4be840..e029e458b 100644 --- a/UE4SS/src/LuaType/LuaCustomProperty.cpp +++ b/UE4SS/src/LuaType/LuaCustomProperty.cpp @@ -12,11 +12,12 @@ namespace RC::LuaType { LuaCustomProperty::PropertyList LuaCustomProperty::StaticStorage::property_list; - LuaCustomProperty::LuaCustomProperty(std::wstring name, std::unique_ptr property) : m_name(name), m_property(std::move(property)) + LuaCustomProperty::LuaCustomProperty(SystemStringType name, std::unique_ptr property) + : m_name(name), m_property(std::move(property)) { } - auto LuaCustomProperty::PropertyList::add(std::wstring property_name, std::unique_ptr property) -> void + auto LuaCustomProperty::PropertyList::add(SystemStringType property_name, std::unique_ptr property) -> void { (void)properties.emplace_back(LuaCustomProperty{property_name, std::move(property)}).m_property.get(); } @@ -26,7 +27,7 @@ namespace RC::LuaType properties.clear(); } - auto LuaCustomProperty::PropertyList::find_or_nullptr(Unreal::UObject* base, std::wstring property_name) -> Unreal::FProperty* + auto LuaCustomProperty::PropertyList::find_or_nullptr(Unreal::UObject* base, SystemStringType property_name) -> Unreal::FProperty* { Unreal::FProperty* custom_property_found{}; diff --git a/UE4SS/src/LuaType/LuaFName.cpp b/UE4SS/src/LuaType/LuaFName.cpp index 207ecc3e8..9353a175c 100644 --- a/UE4SS/src/LuaType/LuaFName.cpp +++ b/UE4SS/src/LuaType/LuaFName.cpp @@ -60,11 +60,11 @@ No overload found for function 'FName'. } int64_t name_comparison_index{}; - StringType name_string{}; + SystemStringType name_string{}; Unreal::EFindName find_type{Unreal::EFindName::FNAME_Add}; if (lua.is_string()) { - name_string = to_wstring(lua.get_string()); + name_string = to_system(lua.get_string()); } else if (lua.is_integer()) { @@ -94,7 +94,7 @@ No overload found for function 'FName'. } else { - LuaType::FName::construct(lua, Unreal::FName(name_string, find_type)); + LuaType::FName::construct(lua, Unreal::FName(to_ue(name_string), find_type)); } return 1; diff --git a/UE4SS/src/LuaType/LuaFOutputDevice.cpp b/UE4SS/src/LuaType/LuaFOutputDevice.cpp index 105c59ce2..e6f68c15e 100644 --- a/UE4SS/src/LuaType/LuaFOutputDevice.cpp +++ b/UE4SS/src/LuaType/LuaFOutputDevice.cpp @@ -65,7 +65,7 @@ No overload found for function 'Log'. } auto message = lua.get_string(); - lua_object.get_remote_cpp_object()->Log(to_wstring(message).c_str()); + lua_object.get_remote_cpp_object()->Log(to_ue_string(message).c_str()); return 0; }); diff --git a/UE4SS/src/LuaType/LuaFString.cpp b/UE4SS/src/LuaType/LuaFString.cpp index ad412aa01..0b4bdcbe2 100644 --- a/UE4SS/src/LuaType/LuaFString.cpp +++ b/UE4SS/src/LuaType/LuaFString.cpp @@ -54,10 +54,10 @@ namespace RC::LuaType table.add_pair("ToString", [](const LuaMadeSimple::Lua& lua) -> int { auto& lua_object = lua.get_userdata(); - const wchar_t* string_data = lua_object.get_local_cpp_object().GetCharArray(); + const UECharType* string_data = lua_object.get_local_cpp_object().GetCharArray(); if (string_data) { - lua.set_string(to_string(string_data)); + lua.set_string(to_string(UEStringType(string_data))); } else { diff --git a/UE4SS/src/LuaType/LuaFText.cpp b/UE4SS/src/LuaType/LuaFText.cpp index d28a91ef6..48a94bb07 100644 --- a/UE4SS/src/LuaType/LuaFText.cpp +++ b/UE4SS/src/LuaType/LuaFText.cpp @@ -58,17 +58,17 @@ No overload found for function 'FText'. lua.discard_value(); } - StringType text_string{}; + SystemStringType text_string{}; if (lua.is_string()) { - text_string = to_wstring(lua.get_string()); + text_string = to_system(lua.get_string()); } else { lua.throw_error(error_overload_not_found); } - LuaType::FText::construct(lua, Unreal::FText(text_string)); + LuaType::FText::construct(lua, Unreal::FText(to_ue(text_string))); return 1; }); diff --git a/UE4SS/src/LuaType/LuaModRef.cpp b/UE4SS/src/LuaType/LuaModRef.cpp index ee9fa4b15..75fddb7f7 100644 --- a/UE4SS/src/LuaType/LuaModRef.cpp +++ b/UE4SS/src/LuaType/LuaModRef.cpp @@ -50,7 +50,7 @@ No overload found for function 'SetSharedVariable'. { throw std::runtime_error{error_overload_not_found}; } - auto variable_name = std::string{lua.get_string()}; + auto variable_name = to_system_string(lua.get_string()); RC::LuaMod::SharedLuaVariable* currently_stored_value{}; if (auto it = RC::LuaMod::m_shared_lua_variables.find(variable_name); it != RC::LuaMod::m_shared_lua_variables.end()) @@ -159,7 +159,7 @@ No overload found for function 'GetSharedVariable'. { throw std::runtime_error{error_overload_not_found}; } - auto variable_name = std::string{lua.get_string()}; + auto variable_name = to_system_string(lua.get_string()); if (auto it = RC::LuaMod::m_shared_lua_variables.find(variable_name); it != RC::LuaMod::m_shared_lua_variables.end()) { diff --git a/UE4SS/src/LuaType/LuaTArray.cpp b/UE4SS/src/LuaType/LuaTArray.cpp index af33b8553..2003507e9 100644 --- a/UE4SS/src/LuaType/LuaTArray.cpp +++ b/UE4SS/src/LuaType/LuaTArray.cpp @@ -23,7 +23,7 @@ namespace RC::LuaType if (!lua_object.m_inner_property) { - Output::send(STR("TArray::construct: m_inner_property is nullptr for {}"), lua_object.m_property->GetFullName()); + Output::send(SYSSTR("TArray::construct: m_inner_property is nullptr for {}"), to_system(lua_object.m_property->GetFullName())); } auto metatable_name = ClassName::ToString(); diff --git a/UE4SS/src/LuaType/LuaUClass.cpp b/UE4SS/src/LuaType/LuaUClass.cpp index 21ece9996..f4046201b 100644 --- a/UE4SS/src/LuaType/LuaUClass.cpp +++ b/UE4SS/src/LuaType/LuaUClass.cpp @@ -63,7 +63,7 @@ namespace RC::LuaType if (!lua_object.get_remote_cpp_object()) { LuaType::UObject::construct(lua, nullptr); - Output::send(STR("[Lua][Error] Tried getting the CDO but the UClass instance is nullptr\n")); + Output::send(SYSSTR("[Lua][Error] Tried getting the CDO but the UClass instance is nullptr\n")); } else { diff --git a/UE4SS/src/LuaType/LuaUEnum.cpp b/UE4SS/src/LuaType/LuaUEnum.cpp index f25a8a15d..ea4bcaa95 100644 --- a/UE4SS/src/LuaType/LuaUEnum.cpp +++ b/UE4SS/src/LuaType/LuaUEnum.cpp @@ -1,6 +1,7 @@ #include #include #include +#include namespace RC::LuaType { @@ -153,7 +154,7 @@ No overload found for function 'UEnum.InsertIntoNames'. lua.throw_error("Function 'UEnum.InsertIntoNames' cannot be called with 0 parameters."); } - StringType param_name{}; + SystemStringType param_name{}; int64_t param_value = 0; int32_t param_index = 0; bool param_shift = false; @@ -161,7 +162,7 @@ No overload found for function 'UEnum.InsertIntoNames'. // P1 (Name), string if (lua.is_string()) { - param_name = to_wstring(lua.get_string()); + param_name = to_system(lua.get_string()); } else { @@ -194,8 +195,8 @@ No overload found for function 'UEnum.InsertIntoNames'. param_shift = lua.get_bool(); } - const Unreal::FName key{param_name, Unreal::FNAME_Add}; - const auto pair = Unreal::TPair{key, param_value}; + const Unreal::FName key{to_ue(param_name), Unreal::FNAME_Add}; + const auto pair = Unreal::TPair{key, param_value}; lua_object.get_remote_cpp_object()->InsertIntoNames(pair, param_index, param_shift); return 1; @@ -242,7 +243,7 @@ No overload found for function 'UEnum.EditNameAt'. lua.throw_error("'UEnum.EditNameAt' could not load parameter for \"NewName\""); } - Unreal::FName new_key = Unreal::FName(to_wstring(param_new_name), Unreal::FNAME_Add); + Unreal::FName new_key = Unreal::FName(to_ue_string(param_new_name), Unreal::FNAME_Add); lua_object.get_remote_cpp_object()->EditNameAt(param_index, new_key); return 0; diff --git a/UE4SS/src/LuaType/LuaUObject.cpp b/UE4SS/src/LuaType/LuaUObject.cpp index 03d588ebe..fb0e32796 100644 --- a/UE4SS/src/LuaType/LuaUObject.cpp +++ b/UE4SS/src/LuaType/LuaUObject.cpp @@ -216,8 +216,8 @@ namespace RC::LuaType } else { - std::string parameter_type_name = to_string(property_type_fname.ToString()); - std::string parameter_name = to_string(param_next->GetName()); + auto parameter_type_name = to_string(property_type_fname.ToString()); + auto parameter_name = to_string(param_next->GetName()); lua.throw_error( std::format("Tried calling UFunction without a registered handler for parameter. Parameter '{}' of type '{}' not supported.", parameter_name, @@ -249,7 +249,7 @@ namespace RC::LuaType auto reuse_same_table = param->IsA() || param->IsA(); if (!reuse_same_table) { - lua_table.add_key(to_string(param->GetName()).c_str()); + lua_table.add_key(to_lua(param->GetName()).c_str()); } Unreal::FName param_type_fname = param->GetClass().GetFName(); @@ -271,7 +271,7 @@ namespace RC::LuaType } else { - std::string param_type_name = to_string(param_type_fname.ToString()); + auto param_type_name = to_string(param_type_fname.ToString()); lua.throw_error(std::format("Tried calling UFunction without a registered handler 'Out' param. Type '{}' not supported.", param_type_name)); } @@ -537,7 +537,7 @@ namespace RC::LuaType // return LoopAction::Continue; //} - std::string field_name = to_string(field->GetName()); + auto field_name = to_lua(field->GetName()); Unreal::FName field_type = field->GetClass().GetFName(); int32_t name_comparison_index = field_type.GetComparisonIndex(); @@ -562,10 +562,10 @@ namespace RC::LuaType } else { - std::string field_type_name = to_string(field_type.ToString()); + auto field_type_name = to_string(field_type.ToString()); lua.throw_error(std::format("Tried getting without a registered handler. 'StructProperty'.'{}' not supported. Field: '{}'", field_type_name, - field_name)); + to_string(field_name))); } }; @@ -581,7 +581,7 @@ namespace RC::LuaType for (Unreal::FProperty* field : script_struct->ForEachPropertyInChain()) { Unreal::FName field_type_fname = field->GetClass().GetFName(); - const std::string field_name = to_string(field->GetName()); + const auto field_name = to_lua(field->GetName()); // At the top of the stack now: table that has struct data @@ -622,10 +622,10 @@ namespace RC::LuaType } else { - std::string field_type_name = to_string(field_type_fname.ToString()); + auto field_type_name = to_string(field_type_fname.ToString()); params.lua.throw_error(std::format("Tried pushing (Operation::Set) StructProperty without a registered handler for field '{} {}'.", field_type_name, - field_name)); + to_string(field_name))); } }; @@ -724,7 +724,7 @@ namespace RC::LuaType } else { - std::string property_type_name = to_string(property_type_fname.ToString()); + auto property_type_name = to_string(property_type_fname.ToString()); lua.throw_error( std::format("Tried interacting with an array but the inner property has no registered handler. Property type '{}' not supported.", property_type_name)); @@ -739,7 +739,7 @@ namespace RC::LuaType int32_t name_comparison_index = inner_type_fname.GetComparisonIndex(); if (!StaticState::m_property_value_pushers.contains(name_comparison_index)) { - std::string inner_type_name = to_string(inner_type_fname.ToString()); + auto inner_type_name = to_string(inner_type_fname.ToString()); params.lua.throw_error(std::format("Tried pushing (Operation::Set) ArrayProperty with unsupported inner type of '{}'", inner_type_name)); } @@ -958,11 +958,11 @@ namespace RC::LuaType // Make global table to store enum name/value pairs -> START auto table = params.lua.prepare_new_table(); - std::string prop_name = to_string(params.property->GetName()); + auto prop_name = to_lua(params.property->GetName()); for (const auto& elem : enum_ptr->ForEachName()) { - std::string elem_name = to_string(elem.Key.ToString()); + auto elem_name = to_lua(elem.Key.ToString()); table.add_pair(elem_name.c_str(), elem.Value); } @@ -1016,7 +1016,7 @@ namespace RC::LuaType } case Operation::Set: // For now, doing nothing just to get past the error - Output::send(STR("[push_weakobjectproperty] Operation::Set is not supported\n")); + Output::send(SYSSTR("[push_weakobjectproperty] Operation::Set is not supported\n")); return; case Operation::GetParam: params.lua.throw_error("[push_weakobjectproperty] Operation::GetParam is not supported"); @@ -1107,7 +1107,7 @@ namespace RC::LuaType if (params.lua.is_string()) { auto lua_string = params.lua.get_string(); - auto fstring = Unreal::FString{to_wstring(lua_string).c_str()}; + auto fstring = Unreal::FString{to_ue(lua_string).c_str()}; *string = fstring; } else if (params.lua.is_userdata()) @@ -1233,7 +1233,7 @@ No overload found for function 'IsA'. } else if (lua.is_string()) { - auto* object_class = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, to_wstring(lua.get_string())); + auto* object_class = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, to_ue_string(lua.get_string())); lua.set_bool(is_a_internal(lua, object, object_class)); } else @@ -1297,7 +1297,7 @@ No overload found for function 'IsA'. { // We can either throw an error and kill the execution /**/ - std::string property_type_name = to_string(property_type.ToString()); + auto property_type_name = to_string(property_type.ToString()); lua.throw_error(std::format( "[handle_unreal_property_value] Tried accessing unreal property without a registered handler. Property type '{}' not supported.", property_type_name)); @@ -1422,7 +1422,7 @@ No overload found for function 'IsA'. { // We can either throw an error and kill the execution /**/ - std::string property_type_name = to_string(lua_object.m_type.ToString()); + auto property_type_name = to_string(lua_object.m_type.ToString()); lua.throw_error(std::format( "[RemoteUnrealParam::prepare_to_handle] Tried accessing unreal property without a registered handler. Property type '{}' not supported.", property_type_name)); diff --git a/UE4SS/src/LuaType/LuaUScriptStruct.cpp b/UE4SS/src/LuaType/LuaUScriptStruct.cpp index b0474fe7d..27043f813 100644 --- a/UE4SS/src/LuaType/LuaUScriptStruct.cpp +++ b/UE4SS/src/LuaType/LuaUScriptStruct.cpp @@ -196,7 +196,7 @@ namespace RC::LuaType { auto& lua_object = lua.get_userdata(); - Unreal::FName property_name = Unreal::FName(to_wstring(lua.get_string())); + Unreal::FName property_name = Unreal::FName(to_ue_string(lua.get_string())); // Check if property_name is 'NONE' if (property_name.GetComparisonIndex() == 0) diff --git a/UE4SS/src/LuaType/LuaXProperty.cpp b/UE4SS/src/LuaType/LuaXProperty.cpp index dc9944626..47c82de33 100644 --- a/UE4SS/src/LuaType/LuaXProperty.cpp +++ b/UE4SS/src/LuaType/LuaXProperty.cpp @@ -224,10 +224,10 @@ No overload found for function 'ImportText'. const auto& lua_object = lua.get_userdata(); - File::StringType buffer; + SystemStringType buffer; if (lua.is_string()) { - buffer = to_wstring(lua.get_string()); + buffer = to_system(lua.get_string()); } else { @@ -261,7 +261,7 @@ No overload found for function 'ImportText'. } auto* owner_object = lua.get_userdata().get_remote_cpp_object(); - lua_object.get_remote_cpp_object()->ImportText(buffer.c_str(), data, port_flags, owner_object, nullptr); + lua_object.get_remote_cpp_object()->ImportText(to_ue(buffer).c_str(), data, port_flags, owner_object, nullptr); return 0; }); diff --git a/UE4SS/src/Mod/CppMod.cpp b/UE4SS/src/Mod/CppMod.cpp index b8a7b4904..dd95a30f2 100644 --- a/UE4SS/src/Mod/CppMod.cpp +++ b/UE4SS/src/Mod/CppMod.cpp @@ -8,25 +8,29 @@ namespace RC { - CppMod::CppMod(UE4SSProgram& program, std::wstring&& mod_name, std::wstring&& mod_path) : Mod(program, std::move(mod_name), std::move(mod_path)) + CppMod::CppMod(UE4SSProgram& program, SystemStringType&& mod_name, SystemStringType&& mod_path) : Mod(program, std::move(mod_name), std::move(mod_path)) { - m_dlls_path = m_mod_path + L"\\dlls"; +#define STRINGIFY(x) #x +#define CONCATENATE_WIDE_STRING(name, ext) SYSSTR(name) STRINGIFY(ext) if (!std::filesystem::exists(m_dlls_path)) { - Output::send(STR("Could not find the dlls folder for mod {}\n"), m_mod_name); + Output::send(SYSSTR("Could not find the dlls folder for mod {}\n"), m_mod_name); set_installable(false); return; } - auto dll_path = m_dlls_path + L"\\main.dll"; + auto dll_path = m_dlls_path + SYSSTR("\\main.dll"); // Add mods dlls directory to search path for dynamic/shared linked libraries in mods m_dlls_path_cookie = AddDllDirectory(m_dlls_path.c_str()); m_main_dll_module = LoadLibraryExW(dll_path.c_str(), NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); if (!m_main_dll_module) { - Output::send(STR("Failed to load dll <{}> for mod {}, error code: 0x{:x}\n"), dll_path, m_mod_name, GetLastError()); + Output::send(SYSSTR("Failed to load dll <{}> for mod {}, error code: 0x{:x}\n"), + to_system_string(dll_path), + m_mod_name, + GetLastError()); set_installable(false); return; } @@ -36,7 +40,7 @@ namespace RC if (!m_start_mod_func || !m_uninstall_mod_func) { - Output::send(STR("Failed to find exported mod lifecycle functions for mod {}\n"), m_mod_name); + Output::send(SYSSTR("Failed to find exported mod lifecycle functions for mod {}\n"), m_mod_name); FreeLibrary(m_main_dll_module); m_main_dll_module = NULL; @@ -57,10 +61,10 @@ namespace RC { if (!Output::has_internal_error()) { - Output::send(STR("Failed to load dll <{}> for mod {}, because: {}\n"), - m_dlls_path + L"\\main.dll\n", + Output::send(SYSSTR("Failed to load dll <{}> for mod {}, because: {}\n"), + to_system_string(std::filesystem::path{m_dlls_path} / CONCATENATE_WIDE_STRING("main", DLLEXT)), m_mod_name, - to_wstring(e.what())); + e.what()); } else { @@ -71,14 +75,14 @@ namespace RC auto CppMod::uninstall() -> void { - Output::send(STR("Stopping C++ mod '{}' for uninstall\n"), m_mod_name); + Output::send(SYSSTR("Stopping C++ mod '{}' for uninstall\n"), m_mod_name); if (m_mod && m_uninstall_mod_func) { m_uninstall_mod_func(m_mod); } } - auto CppMod::fire_on_lua_start(StringViewType mod_name, + auto CppMod::fire_on_lua_start(SystemStringViewType mod_name, LuaMadeSimple::Lua& lua, LuaMadeSimple::Lua& main_lua, LuaMadeSimple::Lua& async_lua, @@ -99,7 +103,7 @@ namespace RC } } - auto CppMod::fire_on_lua_stop(StringViewType mod_name, + auto CppMod::fire_on_lua_stop(SystemStringViewType mod_name, LuaMadeSimple::Lua& lua, LuaMadeSimple::Lua& main_lua, LuaMadeSimple::Lua& async_lua, @@ -152,7 +156,7 @@ namespace RC } } - auto CppMod::fire_dll_load(std::wstring_view dll_name) -> void + auto CppMod::fire_dll_load(SystemStringViewType dll_name) -> void { if (m_mod) { diff --git a/UE4SS/src/Mod/CppUserModBase.cpp b/UE4SS/src/Mod/CppUserModBase.cpp index 8d93279d4..705182197 100644 --- a/UE4SS/src/Mod/CppUserModBase.cpp +++ b/UE4SS/src/Mod/CppUserModBase.cpp @@ -2,13 +2,15 @@ #include #include +#include + namespace RC { CppUserModBase::CppUserModBase() { if (ModIntendedSDKVersion.empty()) { - ModIntendedSDKVersion = std::format(STR("{}.{}.{}"), UE4SS_LIB_VERSION_MAJOR, UE4SS_LIB_VERSION_MINOR, UE4SS_LIB_VERSION_HOTFIX); + ModIntendedSDKVersion = to_ue(std::format(SYSSTR("{}.{}.{}"), UE4SS_LIB_VERSION_MAJOR, UE4SS_LIB_VERSION_MINOR, UE4SS_LIB_VERSION_HOTFIX)); } } @@ -23,12 +25,11 @@ namespace RC } GUITabs.clear(); - auto& key_events = UE4SSProgram::get_program().m_input_handler.get_events(); - std::erase_if(key_events, [&](Input::KeySet& input_event) -> bool { - bool were_all_events_registered_from_this_mod = true; - for (auto& [key, vector_of_key_data] : input_event.key_data) - { - std::erase_if(vector_of_key_data, [&](Input::KeyData& key_data) -> bool { + UE4SSProgram::get_program().m_input_handler.get_events_safe([&](auto& key_set) { + std::erase_if(key_set.key_data, [&](auto& item) -> bool { + auto& [_, key_data] = item; + bool were_all_events_registered_from_this_mod = true; + std::erase_if(key_data, [&](Input::KeyData& key_data) -> bool { // custom_data == 1: Bind came from Lua, and custom_data2 is nullptr. // custom_data == 2: Bind came from C++, and custom_data2 is a pointer to KeyDownEventData. Must free it. auto event_data = static_cast(key_data.custom_data2); @@ -43,13 +44,13 @@ namespace RC return false; } }); - } - return were_all_events_registered_from_this_mod; + return were_all_events_registered_from_this_mod; + }); }); } - auto CppUserModBase::register_tab(std::wstring_view tab_name, GUI::GUITab::RenderFunctionType render_function) -> void + auto CppUserModBase::register_tab(UEStringViewType tab_name, GUI::GUITab::RenderFunctionType render_function) -> void { auto& tab = GUITabs.emplace_back(std::make_shared(tab_name, render_function, this)); UE4SSProgram::get_program().add_gui_tab(tab); diff --git a/UE4SS/src/Mod/LuaMod.cpp b/UE4SS/src/Mod/LuaMod.cpp index b3bb5ed3b..cc5d0d64d 100644 --- a/UE4SS/src/Mod/LuaMod.cpp +++ b/UE4SS/src/Mod/LuaMod.cpp @@ -11,7 +11,11 @@ #include #include #include + +#ifdef HAS_INPUT #include +#endif + #include #include #include @@ -254,14 +258,14 @@ namespace RC // If the type wasn't supported then we simply clean the Lua stack, output a warning and then do nothing lua_data.lua.discard_value(); - std::wstring parameter_type_name = property_type_name.ToString(); - std::wstring parameter_name = lua_data.return_property->GetName(); + auto parameter_type_name = to_system(property_type_name.ToString()); + auto parameter_name = to_system(lua_data.return_property->GetName()); - Output::send( - STR("Tried altering return value of a hooked UFunction without a registered handler for return type Return property '{}' of type " - "'{}' not supported."), - parameter_name, - parameter_type_name); + Output::send(SYSSTR("Tried altering return value of a hooked UFunction without a registered handler for return type Return property '{}' " + "of type " + "'{}' not supported."), + parameter_name, + parameter_type_name); } } }; @@ -629,12 +633,12 @@ namespace RC efindname_table.make_global("EFindName"); } - LuaMod::LuaMod(UE4SSProgram& program, std::wstring&& mod_name, std::wstring&& mod_path) + LuaMod::LuaMod(UE4SSProgram& program, SystemStringType&& mod_name, SystemStringType&& mod_path) : Mod(program, std::move(mod_name), std::move(mod_path)), m_lua(LuaMadeSimple::new_state()) { // Verify that there's a 'Scripts' directory // Give the full path to the 'Scripts' directory to the mod container - m_scripts_path = m_mod_path + L"\\scripts"; + m_scripts_path = m_mod_path + SYSSTR("\\scripts"); // If the 'Scripts' directory doesn't exist then mark the mod as non-installable and move on to the next mod if (!std::filesystem::exists(m_scripts_path)) @@ -859,7 +863,7 @@ No overload found for function 'StaticFindObject'. // Ignores any params after P1 if (lua.is_string()) { - Unreal::UObject* object = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, to_wstring(lua.get_string())); + Unreal::UObject* object = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, to_ue_string(lua.get_string())); // Construct a Lua object of type 'UObject' // Auto constructing is nullptr safe @@ -883,7 +887,7 @@ No overload found for function 'StaticFindObject'. Unreal::UClass* param_class{}; Unreal::UObject* param_in_outer{}; - std::wstring param_name{}; + SystemStringType param_name{}; bool param_exact_class{}; // P1 (Class), userdata @@ -919,7 +923,7 @@ No overload found for function 'StaticFindObject'. // P3 (Name), string if (lua.is_string()) { - param_name = to_wstring(lua.get_string()); + param_name = to_system(lua.get_string()); } else { @@ -933,7 +937,7 @@ No overload found for function 'StaticFindObject'. } // There's no error if P4 isn't a bool, simply ignore all parameters after P3 - Unreal::UObject* object = Unreal::UObjectGlobals::StaticFindObject(param_class, param_in_outer, param_name, param_exact_class); + Unreal::UObject* object = Unreal::UObjectGlobals::StaticFindObject(param_class, param_in_outer, to_ue(param_name), param_exact_class); // Construct a Lua object of type 'UObject' // Auto constructing is nullptr safe @@ -961,7 +965,7 @@ No overload found for function 'FindFirstOf'. // Ignores any params after P1 if (lua.is_string()) { - Unreal::UObject* object = Unreal::UObjectGlobals::FindFirstOf(to_wstring(lua.get_string())); + Unreal::UObject* object = Unreal::UObjectGlobals::FindFirstOf(to_ue_string(lua.get_string())); // Construct a Lua object of type 'UObject' // Auto constructing is nullptr safe @@ -1045,6 +1049,7 @@ No overload found for function 'FindAllOf'. if (is_true_mod == Mod::IsTrueMod::Yes) { +#ifdef HAS_INPUT lua.register_function("IsKeyBindRegistered", [](const LuaMadeSimple::Lua& lua) -> int { std::string error_overload_not_found{R"( No overload found for function 'IsKeyBindRegistered'. @@ -1137,7 +1142,7 @@ No overload found for function 'RegisterKeyBindAsync'. } catch (std::runtime_error& e) { - Output::send(STR("{}\n"), to_wstring(lua.handle_error(e.what()))); + Output::send(SYSSTR("{}\n"), lua.handle_error(e.what())); } }; @@ -1256,7 +1261,7 @@ No overload found for function 'RegisterKeyBind'. } catch (std::runtime_error& e) { - Output::send(STR("{}\n"), to_wstring(lua.handle_error(e.what()))); + Output::send(SYSSTR("{}\n"), lua.handle_error(e.what())); } }; @@ -1342,6 +1347,7 @@ No overload found for function 'RegisterKeyBind'. return 0; }); +#endif lua.register_function("UnregisterHook", [](const LuaMadeSimple::Lua& lua) -> int { std::lock_guard guard{LuaMod::m_thread_actions_mutex}; @@ -1355,8 +1361,8 @@ No overload found for function 'UnregisterHook'. lua.throw_error(error_overload_not_found); } - std::wstring function_name = to_wstring(lua.get_string()); - std::wstring function_name_no_prefix = function_name.substr(function_name.find_first_of(L" ") + 1, function_name.size()); + auto function_name = to_ue(lua.get_string()); + auto function_name_no_prefix = function_name.substr(function_name.find_first_of(STR(" ")) + 1, function_name.size()); Unreal::UFunction* unreal_function = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, function_name_no_prefix); if (!unreal_function) @@ -1392,9 +1398,9 @@ No overload found for function 'UnregisterHook'. if (native_hook_pre_id_it != LuaMod::m_generic_hook_id_to_native_hook_id.end() && native_hook_post_id_it != LuaMod::m_generic_hook_id_to_native_hook_id.end()) { - Output::send(STR("Unregistering native hook with pre-id: {}\n"), native_hook_pre_id_it->first); + Output::send(SYSSTR("Unregistering native hook with pre-id: {}\n"), native_hook_pre_id_it->first); unreal_function->UnregisterHook(static_cast(native_hook_pre_id_it->second)); - Output::send(STR("Unregistering native hook with post-id: {}\n"), native_hook_post_id_it->first); + Output::send(SYSSTR("Unregistering native hook with post-id: {}\n"), native_hook_post_id_it->first); unreal_function->UnregisterHook(static_cast(native_hook_post_id_it->second)); // LuaUnrealScriptFunctionData contains the hook's lua registry references, captured in RegisterHook in two different lua states. @@ -1417,10 +1423,10 @@ No overload found for function 'UnregisterHook'. } else { - if (auto callback_data_it = LuaMod::m_script_hook_callbacks.find(unreal_function->GetFullName()); + if (auto callback_data_it = LuaMod::m_script_hook_callbacks.find(to_system(unreal_function->GetFullName())); callback_data_it != LuaMod::m_script_hook_callbacks.end()) { - Output::send(STR("Unregistering script hook with id: {}\n"), post_id); + Output::send(SYSSTR("Unregistering script hook with id: {}\n"), post_id); auto& registry_indexes = callback_data_it->second.registry_indexes; std::erase_if(registry_indexes, [&](const auto& pair) -> bool { return post_id == pair.second.identifier; @@ -1437,15 +1443,15 @@ No overload found for function 'UnregisterHook'. { lua.throw_error("Could not dump objects and properties because the pointer to 'Mod' was nullptr"); } - UE4SSProgram::dump_all_objects_and_properties(mod->m_program.get_object_dumper_output_directory() + STR("\\") + - UE4SSProgram::m_object_dumper_file_name); + UE4SSProgram::dump_all_objects_and_properties( + to_system_string(std::filesystem::path{mod->m_program.get_object_dumper_output_directory()} / UE4SSProgram::m_object_dumper_file_name)); return 0; }); lua.register_function("GenerateSDK", []([[maybe_unused]] const LuaMadeSimple::Lua& lua) -> int { const Mod* mod = get_mod_ref(lua); - File::StringType working_dir{mod->m_program.get_working_directory()}; - mod->m_program.generate_cxx_headers(working_dir + STR("\\CXXHeaderDump")); + std::filesystem::path working_dir{mod->m_program.get_working_directory()}; + mod->m_program.generate_cxx_headers(working_dir / SYSSTR("CXXHeaderDump")); return 0; }); @@ -1617,9 +1623,9 @@ No overload found for function 'RegisterCustomProperty'. struct PropertyInfo { - std::wstring name{}; + SystemStringType name{}; PropertyTypeInfo type{}; // Figure out what to do here, it shouldn't be just a string - std::wstring belongs_to_class{}; + SystemStringType belongs_to_class{}; int32_t offset_internal{-1}; int32_t element_size{-1}; // Is this required for trivial types like integers and floats ? @@ -1718,12 +1724,12 @@ No overload found for function 'RegisterCustomProperty'. }; // Always required, for all property types - property_info.name = to_wstring(lua_table.get_string_field("Name")); + property_info.name = to_system(lua_table.get_string_field("Name")); property_info.type.name = lua_table.get_table_field("Type").get_string_field("Name"); property_info.type.size = verify_and_convert_int64_to_int32("Type", "Size"); property_info.type.ffieldclass_pointer = reinterpret_cast(lua_table.get_table_field("Type").get_int_field("FFieldClassPointer")); property_info.type.static_pointer = reinterpret_cast(lua_table.get_table_field("Type").get_int_field("StaticPointer")); - property_info.belongs_to_class = to_wstring(lua_table.get_string_field("BelongsToClass")); + property_info.belongs_to_class = to_system(lua_table.get_string_field("BelongsToClass")); std::string oi_property_name; int32_t oi_relative_offset{}; @@ -1766,7 +1772,7 @@ No overload found for function 'RegisterCustomProperty'. lua.throw_error("Parameter #1 for function 'RegisterCustomProperty'. The table is missing required fields."); } - Unreal::UClass* belongs_to_class = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, property_info.belongs_to_class); + Unreal::UClass* belongs_to_class = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, to_ue(property_info.belongs_to_class)); if (!belongs_to_class) { lua.throw_error("Tried to 'RegisterCustomProperty' but 'BelongsToClass' could not be found"); @@ -1774,7 +1780,7 @@ No overload found for function 'RegisterCustomProperty'. if (property_info.offset_internal_is_table) { - auto name = Unreal::FName(to_wstring(oi_property_name)); + auto name = Unreal::FName(to_ue(oi_property_name)); Unreal::FProperty* oi_property = belongs_to_class->FindProperty(name); if (!oi_property) { @@ -1811,14 +1817,14 @@ No overload found for function 'RegisterCustomProperty'. printf_s("Registered Custom Property\n"); printf_s("PropertyInfo {\n"); - printf_s("\tName: %S\n", property_info.name.c_str()); + printf_s("\tName: " SystemStringPrint "\n", property_info.name.c_str()); printf_s("\tType {\n"); printf_s("\t\tName: %s\n", property_info.type.name.data()); printf_s("\t\tSize: 0x%X\n", property_info.type.size); printf_s("\t\tFFieldClassPointer: 0x%p\n", property_info.type.ffieldclass_pointer); printf_s("\t\tStaticPointer: 0x%p\n", property_info.type.static_pointer); printf_s("\t}\n"); - printf_s("\tBelongsToClass: %S\n", property_info.belongs_to_class.c_str()); + printf_s("\tBelongsToClass: " SystemStringPrint "\n", property_info.belongs_to_class.c_str()); printf_s("\tOffsetInternal: 0x%X\n", property_info.offset_internal); if (property_info.is_array_property) @@ -1870,7 +1876,7 @@ No overload found for function 'NotifyOnNewObject'. lua.throw_error(error_overload_not_found); } - std::wstring class_name = to_wstring(lua.get_string()); + auto class_name = to_system(lua.get_string()); if (!lua.is_function()) { @@ -1888,7 +1894,7 @@ No overload found for function 'NotifyOnNewObject'. const auto func_ref = hook_lua->registry().make_ref(); const auto thread_ref = mod->lua().registry().make_ref(); - Unreal::UClass* instance_of_class = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, class_name); + Unreal::UClass* instance_of_class = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, to_ue(class_name)); LuaMod::m_static_construct_object_lua_callbacks.emplace_back(LuaMod::LuaCancellableCallbackData{hook_lua, instance_of_class, func_ref, thread_ref}); @@ -1906,7 +1912,7 @@ No overload found for function 'RegisterCustomEvent'. lua.throw_error(error_overload_not_found); } - std::wstring event_name = to_wstring(lua.get_string()); + auto event_name = to_system(lua.get_string()); if (!lua.is_function()) { @@ -1942,7 +1948,7 @@ No overload found for function 'UnregisterCustomEvent'. { lua.throw_error(error_overload_not_found); } - auto custom_event_name = to_wstring(lua.get_string()); + auto custom_event_name = to_system_string(lua.get_string()); LuaMod::m_custom_event_callbacks.erase(custom_event_name); @@ -2125,8 +2131,8 @@ No overload found for function 'IterateGameDirectories'. auto game_content_dir = game_executable_directory.parent_path().parent_path() / "Content"; if (!std::filesystem::exists(game_content_dir)) { - Output::send(STR("IterateGameDirectories: Could not locate the root directory because the directory structure is unknown " - "(not /Game/Binaries/Win64)\n")); + Output::send(SYSSTR("IterateGameDirectories: Could not locate the root directory because the directory structure is unknown " + "(not /Game/Binaries/Win64)\n")); lua.set_nil(); return 1; } @@ -2244,23 +2250,23 @@ No overload found for function 'CreateLogicModsDirectory'. lua.throw_error("CreateLogicModsDirectory: Could not locate the \"Content\" directory because the directory structure is unknown (not " "/Game/Content)\n"); } - auto logic_mods_dir = game_content_dir / "Paks/LogicMods"; + auto logic_mods_dir = game_content_dir / "Paks" / "LogicMods"; if (std::filesystem::exists(logic_mods_dir)) { Output::send( - STR("CreateLogicModsDirectory: \"LogicMods\" directory already exists. Cancelling creation of new directory.\n")); + SYSSTR("CreateLogicModsDirectory: \"LogicMods\" directory already exists. Cancelling creation of new directory.\n")); lua.set_bool(false); return 1; } - Output::send(STR("CreateLogicModsDirectory: LogicMods directory not found. Creating LogicMods directory.\n")); + Output::send(SYSSTR("CreateLogicModsDirectory: LogicMods directory not found. Creating LogicMods directory.\n")); auto new_logic_mods_dir = std::filesystem::create_directory(logic_mods_dir); if (!new_logic_mods_dir) { lua.throw_error("CreateLogicModsDirectory: Unable to create \"LogicMods\" directory. Try creating manually.\n"); } - Output::send(STR("CreateLogicModsDirectory: LogicMods directory created.\n")); + Output::send(SYSSTR("CreateLogicModsDirectory: LogicMods directory created.\n")); lua.set_bool(true); return 1; @@ -2486,7 +2492,7 @@ No overload found for function 'RegisterConsoleCommandGlobalHandler'. { throw std::runtime_error{error_overload_not_found}; } - auto command_name = to_wstring(lua.get_string()); + auto command_name = to_system_string(lua.get_string()); if (!lua.is_function()) { @@ -2521,7 +2527,7 @@ No overload found for function 'RegisterConsoleCommandHandler'. { throw std::runtime_error{error_overload_not_found}; } - auto command_name = to_wstring(lua.get_string()); + auto command_name = to_system_string(lua.get_string()); if (!lua.is_function()) { @@ -2561,7 +2567,7 @@ No overload found for function 'LoadAsset'. { throw std::runtime_error{error_overload_not_found}; } - auto asset_path_and_name = Unreal::FName(to_wstring(lua.get_string()), Unreal::FNAME_Add); + auto asset_path_and_name = Unreal::FName(to_ue(lua.get_string()), Unreal::FNAME_Add); auto* asset_registry = static_cast(Unreal::UAssetRegistryHelpers::GetAssetRegistry().ObjectPointer); if (!asset_registry) @@ -2580,11 +2586,11 @@ No overload found for function 'LoadAsset'. if (loaded_asset) { did_asset_load = true; - Output::send(STR("Asset loaded\n")); + Output::send(SYSSTR("Asset loaded\n")); } else { - Output::send(STR("Asset was found but not loaded, could be a package\n")); + Output::send(SYSSTR("Asset was found but not loaded, could be a package\n")); } } @@ -2612,7 +2618,7 @@ No overload found for function 'FindObject'. bool could_be_in_class{}; if (lua.is_string()) { - object_class_name = Unreal::FName(to_wstring(lua.get_string()), Unreal::FNAME_Add); + object_class_name = Unreal::FName(to_ue(lua.get_string()), Unreal::FNAME_Add); } else if (lua.is_userdata()) { @@ -2655,7 +2661,7 @@ No overload found for function 'FindObject'. bool could_be_object_short_name{}; if (lua.is_string()) { - object_short_name = Unreal::FName(to_wstring(lua.get_string()), Unreal::FNAME_Add); + object_short_name = Unreal::FName(to_ue(lua.get_string()), Unreal::FNAME_Add); could_be_object_short_name = true; } else if (lua.is_userdata()) @@ -2739,7 +2745,7 @@ No overload found for function 'FindObject'. if (could_be_in_class && could_be_in_outer && could_be_in_name) { - LuaType::auto_construct_object(lua, Unreal::UObjectGlobals::FindObject(in_class, in_outer, to_wstring(in_name), exact_class)); + LuaType::auto_construct_object(lua, Unreal::UObjectGlobals::FindObject(in_class, in_outer, to_ue(in_name), exact_class)); } else { @@ -2786,7 +2792,7 @@ No overload found for function 'FindObjects'. bool object_class_name_supplied{true}; if (lua.is_string()) { - object_class_name = Unreal::FName(to_wstring(lua.get_string()), Unreal::FNAME_Add); + object_class_name = Unreal::FName(to_ue(lua.get_string()), Unreal::FNAME_Add); } else if (lua.is_userdata()) { @@ -2824,7 +2830,7 @@ No overload found for function 'FindObjects'. Unreal::FName object_short_name{}; if (lua.is_string()) { - object_short_name = Unreal::FName(to_wstring(lua.get_string()), Unreal::FNAME_Add); + object_short_name = Unreal::FName(to_ue(lua.get_string()), Unreal::FNAME_Add); } else if (lua.is_userdata()) { @@ -2966,8 +2972,8 @@ No overload found for function 'RegisterHook'. lua.throw_error(error_overload_not_found); } - std::wstring function_name = to_wstring(lua.get_string()); - std::wstring function_name_no_prefix = function_name.substr(function_name.find_first_of(L"/"), function_name.size()); + auto function_name = to_system(lua.get_string()); + auto function_name_no_prefix = function_name.substr(function_name.find_first_of(SYSSTR("/")), function_name.size()); if (!lua.is_function()) { @@ -2997,7 +3003,7 @@ No overload found for function 'RegisterHook'. has_post_callback = true; } - Unreal::UFunction* unreal_function = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, function_name_no_prefix); + Unreal::UFunction* unreal_function = Unreal::UObjectGlobals::StaticFindObject(nullptr, nullptr, to_ue(function_name_no_prefix)); if (!unreal_function) { lua.throw_error("Tried to register a hook with Lua function 'RegisterHook' but no UFunction with the specified name was found."); @@ -3020,24 +3026,24 @@ No overload found for function 'RegisterHook'. generic_pre_id = m_last_generic_hook_id; m_generic_hook_id_to_native_hook_id.emplace(++m_last_generic_hook_id, post_id); generic_post_id = m_last_generic_hook_id; - Output::send(STR("[RegisterHook] Registered native hook ({}, {}) for {}\n"), + Output::send(SYSSTR("[RegisterHook] Registered native hook ({}, {}) for {}\n"), generic_pre_id, generic_post_id, - unreal_function->GetFullName()); + to_system(unreal_function->GetFullName())); } else if (func_ptr && func_ptr == Unreal::UObject::ProcessInternalInternal.get_function_address() && !unreal_function->HasAnyFunctionFlags(Unreal::EFunctionFlags::FUNC_Native)) { ++m_last_generic_hook_id; - auto [callback_data, _] = LuaMod::m_script_hook_callbacks.emplace(unreal_function->GetFullName(), LuaCallbackData{*hook_lua, nullptr, {}}); + auto [callback_data, _] = LuaMod::m_script_hook_callbacks.emplace(to_system(unreal_function->GetFullName()), LuaCallbackData{lua, nullptr, {}}); callback_data->second.registry_indexes.emplace_back(hook_lua, LuaMod::LuaCallbackData::RegistryIndex{lua_callback_registry_index, m_last_generic_hook_id}); generic_pre_id = m_last_generic_hook_id; generic_post_id = m_last_generic_hook_id; - Output::send(STR("[RegisterHook] Registered script hook ({}, {}) for {}\n"), + Output::send(SYSSTR("[RegisterHook] Registered script hook ({}, {}) for {}\n"), generic_pre_id, generic_post_id, - unreal_function->GetFullName()); + to_system(unreal_function->GetFullName())); } else { @@ -3249,8 +3255,8 @@ No overload found for function 'FPackageName:IsShortPackageName'. { lua.throw_error(error_overload_not_found); } - - File::StringType PossiblyLongName = to_wstring(lua.get_string()); + auto local_str = to_ue(lua.get_string()); + UEStringViewType PossiblyLongName = local_str; lua.set_bool(Unreal::FPackageName::IsShortPackageName(PossiblyLongName)); return 1; @@ -3266,8 +3272,8 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. { lua.throw_error(error_overload_not_found); } - - File::StringType InLongPackageName = to_wstring(lua.get_string()); + auto local_str = to_ue(lua.get_string()); + UEStringViewType InLongPackageName = local_str; lua.set_bool(Unreal::FPackageName::IsValidLongPackageName(InLongPackageName)); return 1; @@ -3364,11 +3370,11 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. // Don't crash on syntax errors. try { - main_lua()->execute_file(m_scripts_path + L"\\main.lua"); + main_lua()->execute_file(to_system_string(std::filesystem::path{m_scripts_path} / SYSSTR("main.lua"))); } catch (std::runtime_error& e) { - Output::send(STR("{}\n"), to_wstring(e.what())); + Output::send(SYSSTR("{}\n"), to_system(e.what())); } } @@ -3377,7 +3383,7 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. // ProcessEvent hook may try to run, and the lua state will not be valid std::lock_guard guard{LuaMod::m_thread_actions_mutex}; - Output::send(STR("Stopping mod '{}' for uninstall\n"), m_mod_name); + Output::send(SYSSTR("Stopping mod '{}' for uninstall\n"), m_mod_name); fire_on_lua_stop_for_cpp_mods(); @@ -3408,8 +3414,14 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. std::erase_if(g_hooked_script_function_data, [&](std::unique_ptr& item) -> bool { if (item->mod == this) { - Output::send(STR("\tUnregistering hook by id '{}#{}' for mod {}\n"), item->unreal_function->GetName(), item->pre_callback_id, item->mod->get_name()); - Output::send(STR("\tUnregistering hook by id '{}#{}' for mod {}\n"), item->unreal_function->GetName(), item->post_callback_id, item->mod->get_name()); + Output::send(SYSSTR("\tUnregistering hook by id '{}#{}' for mod {}\n"), + to_system(item->unreal_function->GetName()), + item->pre_callback_id, + item->mod->get_name()); + Output::send(SYSSTR("\tUnregistering hook by id '{}#{}' for mod {}\n"), + to_system(item->unreal_function->GetName()), + item->post_callback_id, + item->mod->get_name()); item->unreal_function->UnregisterHook(item->pre_callback_id); item->unreal_function->UnregisterHook(item->post_callback_id); return true; @@ -3465,12 +3477,13 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. { std::lock_guard guard{LuaMod::m_thread_actions_mutex}; - auto execute_hook = [&](std::unordered_map& callback_container, bool precise_name_match) { + auto execute_hook = [&](std::unordered_map& callback_container, bool precise_name_match) { if (callback_container.empty()) { return; } - if (auto it = callback_container.find(precise_name_match ? Stack.Node()->GetFullName() : Stack.Node()->GetName()); it != callback_container.end()) + if (auto it = callback_container.find(precise_name_match ? to_system(Stack.Node()->GetFullName()) : to_system(Stack.Node()->GetName())); + it != callback_container.end()) { const auto& callback_data = it->second; for (const auto& [lua_ptr, registry_index] : callback_data.registry_indexes) @@ -3564,13 +3577,10 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. } else { - std::wstring return_property_type_name = return_property_type.ToString(); - std::wstring return_property_name = return_property->GetName(); - - Output::send(STR("Tried altering return value of a custom BP function without a registered handler for return type Return " - "property '{}' of type '{}' not supported."), - return_property_name, - return_property_type_name); + Output::send(SYSSTR("Tried altering return value of a custom BP function without a registered handler for return type Return " + "property '{}' of type '{}' not supported."), + return_property->GetName(), + return_property_type.ToString()); } } } @@ -3779,7 +3789,7 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. } catch (std::runtime_error& e) { - Output::send(STR("{}\n"), to_wstring(e.what())); + Output::send(SYSSTR("{}\n"), e.what()); } if (cancel) @@ -3798,8 +3808,10 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. return constructed_object; }); - Unreal::Hook::RegisterULocalPlayerExecPreCallback([](Unreal::ULocalPlayer* context, Unreal::UWorld* in_world, const TCHAR* cmd, Unreal::FOutputDevice& ar) - -> Unreal::Hook::ULocalPlayerExecCallbackReturnValue { + Unreal::Hook::RegisterULocalPlayerExecPreCallback([](Unreal::ULocalPlayer* context, + Unreal::UWorld* in_world, + const RC::Unreal::TCHAR* cmd, + Unreal::FOutputDevice& ar) -> Unreal::Hook::ULocalPlayerExecCallbackReturnValue { return TRY([&] { for (const auto& callback_data : m_local_player_exec_pre_callbacks) { @@ -3814,7 +3826,7 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. static auto s_object_property_name = Unreal::FName(STR("ObjectProperty")); LuaType::RemoteUnrealParam::construct(callback_data.lua, &context, s_object_property_name); LuaType::RemoteUnrealParam::construct(callback_data.lua, &in_world, s_object_property_name); - callback_data.lua.set_string(to_string(cmd)); + callback_data.lua.set_string(to_string((UECharType*)cmd)); LuaType::FOutputDevice::construct(callback_data.lua, &ar); callback_data.lua.call_function(4, 2); @@ -3858,8 +3870,10 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. }); }); - Unreal::Hook::RegisterULocalPlayerExecPostCallback([](Unreal::ULocalPlayer* context, Unreal::UWorld* in_world, const TCHAR* cmd, Unreal::FOutputDevice& ar) - -> Unreal::Hook::ULocalPlayerExecCallbackReturnValue { + Unreal::Hook::RegisterULocalPlayerExecPostCallback([](Unreal::ULocalPlayer* context, + Unreal::UWorld* in_world, + const RC::Unreal::TCHAR* cmd, + Unreal::FOutputDevice& ar) -> Unreal::Hook::ULocalPlayerExecCallbackReturnValue { return TRY([&] { for (const auto& callback_data : m_local_player_exec_post_callbacks) { @@ -3874,7 +3888,7 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. static auto s_object_property_name = Unreal::FName(STR("ObjectProperty")); LuaType::RemoteUnrealParam::construct(callback_data.lua, &context, s_object_property_name); LuaType::RemoteUnrealParam::construct(callback_data.lua, &in_world, s_object_property_name); - callback_data.lua.set_string(to_string(cmd)); + callback_data.lua.set_string(to_string((UECharType*)cmd)); LuaType::FOutputDevice::construct(callback_data.lua, &ar); callback_data.lua.call_function(4, 2); @@ -3919,7 +3933,7 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. }); Unreal::Hook::RegisterCallFunctionByNameWithArgumentsPreCallback( - [](Unreal::UObject* context, const TCHAR* str, Unreal::FOutputDevice& ar, Unreal::UObject* executor, bool b_force_call_with_non_exec) + [](Unreal::UObject* context, const RC::Unreal::TCHAR* str, Unreal::FOutputDevice& ar, Unreal::UObject* executor, bool b_force_call_with_non_exec) -> std::pair { return TRY([&] { for (const auto& callback_data : m_call_function_by_name_with_arguments_pre_callbacks) @@ -3934,7 +3948,7 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. static auto s_object_property_name = Unreal::FName(STR("ObjectProperty")); LuaType::RemoteUnrealParam::construct(callback_data.lua, &context, s_object_property_name); - callback_data.lua.set_string(to_string(str)); + callback_data.lua.set_string(to_string((UECharType*)str)); LuaType::FOutputDevice::construct(callback_data.lua, &ar); LuaType::RemoteUnrealParam::construct(callback_data.lua, &executor, s_object_property_name); callback_data.lua.set_bool(b_force_call_with_non_exec); @@ -3967,7 +3981,7 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. }); Unreal::Hook::RegisterCallFunctionByNameWithArgumentsPostCallback( - [](Unreal::UObject* context, const TCHAR* str, Unreal::FOutputDevice& ar, Unreal::UObject* executor, bool b_force_call_with_non_exec) + [](Unreal::UObject* context, const RC::Unreal::TCHAR* str, Unreal::FOutputDevice& ar, Unreal::UObject* executor, bool b_force_call_with_non_exec) -> std::pair { return TRY([&] { for (const auto& callback_data : m_call_function_by_name_with_arguments_post_callbacks) @@ -3982,7 +3996,7 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. static auto s_object_property_name = Unreal::FName(STR("ObjectProperty")); LuaType::RemoteUnrealParam::construct(callback_data.lua, &context, s_object_property_name); - callback_data.lua.set_string(to_string(str)); + callback_data.lua.set_string(to_string((UECharType*)str)); LuaType::FOutputDevice::construct(callback_data.lua, &ar); LuaType::RemoteUnrealParam::construct(callback_data.lua, &executor, s_object_property_name); callback_data.lua.set_bool(b_force_call_with_non_exec); @@ -4015,91 +4029,92 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. }); // Lua from the in-game console. - Unreal::Hook::RegisterProcessConsoleExecCallback([](Unreal::UObject* context, const TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> bool { - auto logln = [&ar](const File::StringType& log_message) { - Output::send(std::format(STR("{}\n"), log_message)); - ar.Log(log_message.c_str()); - }; + Unreal::Hook::RegisterProcessConsoleExecCallback( + [](Unreal::UObject* context, const RC::Unreal::TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> bool { + auto logln = [&ar](const SystemStringType& log_message) { + Output::send(std::format(SYSSTR("{}\n"), log_message)); + ar.Log((const RC::Unreal::TCHAR*)log_message.c_str()); + }; - if (!LuaStatics::console_executor_enabled && String::iequal(File::StringViewType{cmd}, STR("luastart"))) - { - start_console_lua_executor(); - logln(STR("Console Lua executor started")); - return true; - } - else if (LuaStatics::console_executor_enabled && String::iequal(File::StringViewType{cmd}, STR("luastop"))) - { - stop_console_lua_executor(); - logln(STR("Console Lua executor stopped")); - return true; - } - else if (LuaStatics::console_executor_enabled && String::iequal(File::StringViewType{cmd}, STR("luarestart"))) - { - stop_console_lua_executor(); - start_console_lua_executor(); - logln(STR("Console Lua executor restarted")); - return true; - } - else if (String::iequal(File::StringViewType{cmd}, STR("clear"))) - { - // TODO: Replace with proper implementation when we have UGameViewportClient and UConsole. - // This should be fairly cross-game & cross-engine-version compatible even without the proper implementation. - // This is because I don't think they've changed the layout here and we have a reflected property right before the unreflected one that we're looking for. - Unreal::UObject** console = static_cast(context->GetValuePtrByPropertyName(STR("ViewportConsole"))); - auto* default_texture_white = std::bit_cast*>( - static_cast((*console)->GetValuePtrByPropertyNameInChain(STR("DefaultTexture_White"))) + 0x8); - auto* scrollback = std::bit_cast(std::bit_cast(default_texture_white) + 0x10); - default_texture_white->SetNum(0); - default_texture_white->SetMax(0); - *scrollback = 0; - return true; - } - else if (LuaStatics::console_executor_enabled) - { - if (!LuaStatics::console_executor) - { - logln(STR("Console Lua executor is enabled but the Lua instance is nullptr. Please try run RC_LUA_START again.")); - return true; - } + if (!LuaStatics::console_executor_enabled && String::iequal(UEStringViewType{(UECharType*)cmd}, STR("luastart"))) + { + start_console_lua_executor(); + logln(SYSSTR("Console Lua executor started")); + return true; + } + else if (LuaStatics::console_executor_enabled && String::iequal(UEStringViewType{(UECharType*)cmd}, STR("luastop"))) + { + stop_console_lua_executor(); + logln(SYSSTR("Console Lua executor stopped")); + return true; + } + else if (LuaStatics::console_executor_enabled && String::iequal(UEStringViewType{(UECharType*)cmd}, STR("luarestart"))) + { + stop_console_lua_executor(); + start_console_lua_executor(); + logln(SYSSTR("Console Lua executor restarted")); + return true; + } + else if (String::iequal(UEStringViewType{(UECharType*)cmd}, STR("clear"))) + { + // TODO: Replace with proper implementation when we have UGameViewportClient and UConsole. + // This should be fairly cross-game & cross-engine-version compatible even without the proper implementation. + // This is because I don't think they've changed the layout here and we have a reflected property right before the unreflected one that we're looking for. + Unreal::UObject** console = static_cast(context->GetValuePtrByPropertyName(STR("ViewportConsole"))); + auto* default_texture_white = std::bit_cast*>( + static_cast((*console)->GetValuePtrByPropertyNameInChain(STR("DefaultTexture_White"))) + 0x8); + auto* scrollback = std::bit_cast(std::bit_cast(default_texture_white) + 0x10); + default_texture_white->SetNum(0); + default_texture_white->SetMax(0); + *scrollback = 0; + return true; + } + else if (LuaStatics::console_executor_enabled) + { + if (!LuaStatics::console_executor) + { + logln(SYSSTR("Console Lua executor is enabled but the Lua instance is nullptr. Please try run RC_LUA_START again.")); + return true; + } - LuaLibrary::set_outputdevice_ref(*LuaStatics::console_executor, &ar); + LuaLibrary::set_outputdevice_ref(*LuaStatics::console_executor, &ar); - // logln(std::format(STR("Executing '{}' as Lua"), cmd)); + // logln(std::format(SYSSTR("Executing '{}' as Lua"), cmd)); - try - { - if (int status = luaL_loadstring(LuaStatics::console_executor->get_lua_state(), to_string(cmd).c_str()); status != LUA_OK) - { - LuaStatics::console_executor->throw_error( - std::format("luaL_loadstring returned {}", LuaStatics::console_executor->resolve_status_message(status, true))); - } + try + { + if (int status = luaL_loadstring(LuaStatics::console_executor->get_lua_state(), to_string((UECharType*)cmd).c_str()); status != LUA_OK) + { + LuaStatics::console_executor->throw_error( + std::format("luaL_loadstring returned {}", LuaStatics::console_executor->resolve_status_message(status, true))); + } - if (int status = lua_pcall(LuaStatics::console_executor->get_lua_state(), 0, LUA_MULTRET, 0); status != LUA_OK) + if (int status = lua_pcall(LuaStatics::console_executor->get_lua_state(), 0, LUA_MULTRET, 0); status != LUA_OK) + { + LuaStatics::console_executor->throw_error( + std::format("lua_pcall returned {}", LuaStatics::console_executor->resolve_status_message(status, true))); + } + } + catch (std::runtime_error& e) + { + logln(to_system_string(e.what())); + } + + // We always return true when the console Lua executor is enabled in order to suppress other handlers + return true; + } + else { - LuaStatics::console_executor->throw_error( - std::format("lua_pcall returned {}", LuaStatics::console_executor->resolve_status_message(status, true))); + return false; } - } - catch (std::runtime_error& e) - { - logln(to_wstring(e.what())); - } - - // We always return true when the console Lua executor is enabled in order to suppress other handlers - return true; - } - else - { - return false; - } - }); + }); // RegisterProcessConsoleExecPreHook Unreal::Hook::RegisterProcessConsoleExecGlobalPreCallback( - [](Unreal::UObject* context, const TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> std::pair { + [](Unreal::UObject* context, const RC::Unreal::TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> std::pair { return TRY([&] { - auto command = File::StringViewType{cmd}; - auto command_parts = explode_by_occurrence(cmd, ' '); + auto command = UEStringViewType{(const UECharType*)cmd}; + auto command_parts = explode_by_occurrence((const UECharType*)cmd, ' '); for (const auto& callback_data : m_process_console_exec_pre_callbacks) { @@ -4152,10 +4167,10 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. // RegisterProcessConsoleExecPostHook Unreal::Hook::RegisterProcessConsoleExecGlobalPostCallback( - [](Unreal::UObject* context, const TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> std::pair { + [](Unreal::UObject* context, const RC::Unreal::TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> std::pair { return TRY([&] { - auto command = File::StringViewType{cmd}; - auto command_parts = explode_by_occurrence(cmd, ' '); + auto command = UEStringViewType{(const UECharType*)cmd}; + auto command_parts = explode_by_occurrence((const UECharType*)cmd, ' '); for (const auto& callback_data : m_process_console_exec_post_callbacks) { @@ -4207,138 +4222,140 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. }); // RegisterConsoleCommandHandler - Unreal::Hook::RegisterProcessConsoleExecCallback([](Unreal::UObject* context, const TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> bool { - (void)executor; + Unreal::Hook::RegisterProcessConsoleExecCallback( + [](Unreal::UObject* context, const RC::Unreal::TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> bool { + (void)executor; - if (!Unreal::Cast(context)) - { - return false; - } + if (!Unreal::Cast(context)) + { + return false; + } - return TRY([&] { - auto command = File::StringViewType{cmd}; - auto command_parts = explode_by_occurrence(cmd, ' '); - File::StringType command_name; - if (command_parts.size() > 1) - { - command_name = command_parts[0]; - } - else - { - command_name = command; - } + return TRY([&] { + auto command = to_system_string(cmd); + auto command_parts = explode_by_occurrence(command, ' '); + SystemStringType command_name; + if (command_parts.size() > 1) + { + command_name = command_parts[0]; + } + else + { + command_name = command; + } - if (auto it = m_custom_command_lua_pre_callbacks.find(command_name); it != m_custom_command_lua_pre_callbacks.end()) - { - const auto& callback_data = it->second; + if (auto it = m_custom_command_lua_pre_callbacks.find(command_name); it != m_custom_command_lua_pre_callbacks.end()) + { + const auto& callback_data = it->second; - // This is a promise that we're in the game thread, used by other functions to ensure that we don't execute when unsafe - set_is_in_game_thread(callback_data.lua, true); + // This is a promise that we're in the game thread, used by other functions to ensure that we don't execute when unsafe + set_is_in_game_thread(callback_data.lua, true); - bool return_value{}; + bool return_value{}; - for (const auto& [lua, registry_index] : callback_data.registry_indexes) - { - callback_data.lua.registry().get_function_ref(registry_index.lua_index); - callback_data.lua.set_string(to_string(command)); + for (const auto& [lua, registry_index] : callback_data.registry_indexes) + { + callback_data.lua.registry().get_function_ref(registry_index.lua_index); + callback_data.lua.set_string(to_string(command)); - auto params_table = callback_data.lua.prepare_new_table(); - for (size_t i = 1; i < command_parts.size(); ++i) - { - const auto& command_part = command_parts[i]; - params_table.add_pair(i, to_string(command_part).c_str()); - } + auto params_table = callback_data.lua.prepare_new_table(); + for (size_t i = 1; i < command_parts.size(); ++i) + { + const auto& command_part = command_parts[i]; + params_table.add_pair(i, to_string(command_part).c_str()); + } - LuaType::FOutputDevice::construct(callback_data.lua, &ar); + LuaType::FOutputDevice::construct(callback_data.lua, &ar); - callback_data.lua.call_function(3, 1); + callback_data.lua.call_function(3, 1); - if (!callback_data.lua.is_bool()) - { - throw std::runtime_error{"A custom console command handle must return true or false"}; - } + if (!callback_data.lua.is_bool()) + { + throw std::runtime_error{"A custom console command handle must return true or false"}; + } - return_value = callback_data.lua.get_bool(); - } - // No longer promising to be in the game thread - set_is_in_game_thread(callback_data.lua, false); + return_value = callback_data.lua.get_bool(); + } + // No longer promising to be in the game thread + set_is_in_game_thread(callback_data.lua, false); - return return_value; - } + return return_value; + } - return false; - }); - }); + return false; + }); + }); // RegisterConsoleCommandGlobalHandler - Unreal::Hook::RegisterProcessConsoleExecCallback([](Unreal::UObject* context, const TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> bool { - (void)context; - (void)executor; + Unreal::Hook::RegisterProcessConsoleExecCallback( + [](Unreal::UObject* context, const RC::Unreal::TCHAR* cmd, Unreal::FOutputDevice& ar, Unreal::UObject* executor) -> bool { + (void)context; + (void)executor; - return TRY([&] { - auto command = File::StringViewType{cmd}; - auto command_parts = explode_by_occurrence(cmd, ' '); - File::StringType command_name; - if (command_parts.size() > 1) - { - command_name = command_parts[0]; - } - else - { - command_name = command; - } + return TRY([&] { + auto command = to_system_string(cmd); + auto command_parts = explode_by_occurrence(command, SYSSTR(' ')); + SystemStringType command_name; + if (command_parts.size() > 1) + { + command_name = command_parts[0]; + } + else + { + command_name = command; + } - if (auto it = m_global_command_lua_callbacks.find(command_name); it != m_global_command_lua_callbacks.end()) - { - const auto& callback_data = it->second; + if (auto it = m_global_command_lua_callbacks.find(command_name); it != m_global_command_lua_callbacks.end()) + { + const auto& callback_data = it->second; - // This is a promise that we're in the game thread, used by other functions to ensure that we don't execute when unsafe - set_is_in_game_thread(callback_data.lua, true); + // This is a promise that we're in the game thread, used by other functions to ensure that we don't execute when unsafe + set_is_in_game_thread(callback_data.lua, true); - bool return_value{}; + bool return_value{}; - for (const auto& [lua, registry_index] : callback_data.registry_indexes) - { - callback_data.lua.registry().get_function_ref(registry_index.lua_index); - callback_data.lua.set_string(to_string(command)); + for (const auto& [lua, registry_index] : callback_data.registry_indexes) + { + callback_data.lua.registry().get_function_ref(registry_index.lua_index); + callback_data.lua.set_string(to_string(command)); - auto params_table = callback_data.lua.prepare_new_table(); - for (size_t i = 1; i < command_parts.size(); ++i) - { - const auto& command_part = command_parts[i]; - params_table.add_pair(i, to_string(command_part).c_str()); - } + auto params_table = callback_data.lua.prepare_new_table(); + for (size_t i = 1; i < command_parts.size(); ++i) + { + const auto& command_part = command_parts[i]; + params_table.add_pair(i, to_string(command_part).c_str()); + } - LuaType::FOutputDevice::construct(callback_data.lua, &ar); + LuaType::FOutputDevice::construct(callback_data.lua, &ar); - callback_data.lua.call_function(3, 1); + callback_data.lua.call_function(3, 1); - if (!callback_data.lua.is_bool()) - { - throw std::runtime_error{"A custom console command handle must return true or false"}; - } + if (!callback_data.lua.is_bool()) + { + throw std::runtime_error{"A custom console command handle must return true or false"}; + } - return_value = callback_data.lua.get_bool(); - } + return_value = callback_data.lua.get_bool(); + } - // No longer promising to be in the game thread - set_is_in_game_thread(callback_data.lua, false); + // No longer promising to be in the game thread + set_is_in_game_thread(callback_data.lua, false); - return return_value; - } + return return_value; + } - return false; - }); - }); + return false; + }); + }); if (Unreal::UObject::ProcessLocalScriptFunctionInternal.is_ready() && Unreal::Version::IsAtLeast(4, 22)) { - Output::send(STR("Enabling custom events\n")); + Output::send(SYSSTR("Enabling custom events\n")); Unreal::Hook::RegisterProcessLocalScriptFunctionPostCallback(script_hook); } else if (Unreal::UObject::ProcessInternalInternal.is_ready() && Unreal::Version::IsBelow(4, 22)) { - Output::send(STR("Enabling custom events\n")); + Output::send(SYSSTR("Enabling custom events\n")); Unreal::Hook::RegisterProcessInternalPostCallback(script_hook); } } @@ -4395,9 +4412,10 @@ No overload found for function 'FPackageName:IsValidLongPackageName'. } catch (std::runtime_error& e) { - Output::send(STR("[{}] {}\n"), - to_wstring(action.type == LuaMod::ActionType::Loop ? "LoopAsync" : "DelayedAction"), - to_wstring(e.what())); + Output::send(SYSSTR("[{}] {}\n"), + to_system(action.type == LuaMod::ActionType::Loop ? SYSSTR("LoopAsync") + : SYSSTR("DelayedAction")), + to_system(e.what())); } return result; diff --git a/UE4SS/src/Mod/Mod.cpp b/UE4SS/src/Mod/Mod.cpp index 65550fa71..933c04107 100644 --- a/UE4SS/src/Mod/Mod.cpp +++ b/UE4SS/src/Mod/Mod.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -52,11 +51,11 @@ namespace RC { - Mod::Mod(UE4SSProgram& program, std::wstring&& mod_name, std::wstring&& mod_path) : m_program(program), m_mod_name(mod_name), m_mod_path(mod_path) + Mod::Mod(UE4SSProgram& program, SystemStringType&& mod_name, SystemStringType&& mod_path) : m_program(program), m_mod_name(mod_name), m_mod_path(mod_path) { } - auto Mod::get_name() const -> std::wstring_view + auto Mod::get_name() const -> SystemStringViewType { return m_mod_name; } diff --git a/UE4SS/src/ObjectDumper/ObjectToString.cpp b/UE4SS/src/ObjectDumper/ObjectToString.cpp index 22784d9e3..332874e4a 100644 --- a/UE4SS/src/ObjectDumper/ObjectToString.cpp +++ b/UE4SS/src/ObjectDumper/ObjectToString.cpp @@ -56,54 +56,54 @@ namespace RC::ObjectDumper return object_to_string_complex_functions.contains(hash); } - auto object_trivial_dump_to_string(void* p_this, std::wstring& out_line, const wchar_t* post_delimiter) -> void + auto object_trivial_dump_to_string(void* p_this, SystemStringType& out_line, const SystemCharType* post_delimiter) -> void { UObject* p_typed_this = static_cast(p_this); - out_line.append(std::format(L"[{:016X}] ", reinterpret_cast(p_this))); - out_line.append(p_typed_this->GetFullName()); - out_line.append(std::format(L" [n: {:X}] [c: {:016X}] [or: {:016X}]", + out_line.append(std::format(SYSSTR("[{:016X}] "), reinterpret_cast(p_this))); + out_line.append(to_system(p_typed_this->GetFullName())); + out_line.append(std::format(SYSSTR(" [n: {:X}] [c: {:016X}] [or: {:016X}]"), p_typed_this->GetNamePrivate().GetComparisonIndex(), reinterpret_cast(p_typed_this->GetClassPrivate()), reinterpret_cast(p_typed_this->GetOuterPrivate()))); } - auto object_to_string(void* p_this, std::wstring& out_line) -> void + auto object_to_string(void* p_this, SystemStringType& out_line) -> void { object_trivial_dump_to_string(p_this, out_line); } - auto property_trivial_dump_to_string(void* p_this, std::wstring& out_line) -> void + auto property_trivial_dump_to_string(void* p_this, SystemStringType& out_line) -> void { FProperty* p_typed_this = static_cast(p_this); - out_line.append(std::format(L"[{:016X}] ", reinterpret_cast(p_this))); - out_line.append(p_typed_this->GetFullName()); - out_line.append(std::format(L" [o: {:X}] ", p_typed_this->GetOffset_Internal())); + out_line.append(std::format(SYSSTR("[{:016X}] "), reinterpret_cast(p_this))); + out_line.append(to_system(p_typed_this->GetFullName())); + out_line.append(std::format(SYSSTR(" [o: {:X}] "), p_typed_this->GetOffset_Internal())); auto property_class = p_typed_this->GetClass(); - out_line.append(std::format(L"[n: {:X}] [c: {:016X}]", p_typed_this->GetFName().GetComparisonIndex(), property_class.HashObject())); + out_line.append(std::format(SYSSTR("[n: {:X}] [c: {:016X}]"), p_typed_this->GetFName().GetComparisonIndex(), property_class.HashObject())); if (Version::IsAtLeast(4, 25)) { - out_line.append(std::format(L" [owr: {:016X}]", p_typed_this->GetOwnerVariant().HashObject())); + out_line.append(std::format(SYSSTR(" [owr: {:016X}]"), p_typed_this->GetOwnerVariant().HashObject())); } } - auto property_to_string(void* p_this, std::wstring& out_line) -> void + auto property_to_string(void* p_this, SystemStringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); } - auto arrayproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto arrayproperty_to_string(void* p_this, SystemStringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); FArrayProperty* p_typed_this = static_cast(p_this); - out_line.append(std::format(L" [ai: {:016X}]", reinterpret_cast(p_typed_this->GetInner()))); + out_line.append(std::format(SYSSTR(" [ai: {:016X}]"), reinterpret_cast(p_typed_this->GetInner()))); } - auto arrayproperty_to_string_complex(void* p_this, std::wstring& out_line, ObjectToStringComplexDeclCallable callable) -> void + auto arrayproperty_to_string_complex(void* p_this, SystemStringType& out_line, ObjectToStringComplexDeclCallable callable) -> void { FProperty* array_inner = static_cast(p_this)->GetInner(); auto array_inner_class = array_inner->GetClass().HashObject(); @@ -116,7 +116,7 @@ namespace RC::ObjectDumper { // If this code is executed then we'll be having another line before we return to the dumper, so we need to explicitly add a new line // If this code is not executed then we'll not be having another line and the dumper will add the new line - out_line.append(L"\n"); + out_line.append(SYSSTR("\n")); get_to_string_complex(array_inner_class)(array_inner, out_line, [&]([[maybe_unused]] void* prop) { // It's possible that a new line is supposed to be appended here @@ -127,22 +127,23 @@ namespace RC::ObjectDumper } else { - out_line.append(array_inner->GetFullName()); + out_line.append(to_system(array_inner->GetFullName())); callable(array_inner); } } - auto mapproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto mapproperty_to_string(void* p_this, SystemStringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); FMapProperty* typed_this = static_cast(p_this); FProperty* key_property = typed_this->GetKeyProp(); FProperty* value_property = typed_this->GetValueProp(); - out_line.append(std::format(L" [kp: {:016X}] [vp: {:016X}]", reinterpret_cast(key_property), reinterpret_cast(value_property))); + out_line.append( + std::format(SYSSTR(" [kp: {:016X}] [vp: {:016X}]"), reinterpret_cast(key_property), reinterpret_cast(value_property))); } - auto mapproperty_to_string_complex(void* p_this, std::wstring& out_line, ObjectToStringComplexDeclCallable callable) -> void + auto mapproperty_to_string_complex(void* p_this, SystemStringType& out_line, ObjectToStringComplexDeclCallable callable) -> void { FMapProperty* typed_this = static_cast(p_this); FProperty* key_property = typed_this->GetKeyProp(); @@ -159,7 +160,7 @@ namespace RC::ObjectDumper { // If this code is executed then we'll be having another line before we return to the dumper, so we need to explicitly add a new line // If this code is not executed then we'll not be having another line and the dumper will add the new line - out_line.append(L"\n"); + out_line.append(SYSSTR("\n")); get_to_string_complex(property_class)(property, out_line, [&]([[maybe_unused]] void* prop) {}); } @@ -168,7 +169,7 @@ namespace RC::ObjectDumper } else { - out_line.append(property->GetFullName()); + out_line.append(to_system(property->GetFullName())); callable(property); } }; @@ -177,83 +178,83 @@ namespace RC::ObjectDumper dump_property(value_property, value_property_class); } - auto classproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto classproperty_to_string(void* p_this, SystemStringType& out_line) -> void { FClassProperty* typed_this = static_cast(p_this); property_trivial_dump_to_string(p_this, out_line); // mc = MetaClass - out_line.append(std::format(L" [mc: {:016X}]", reinterpret_cast(typed_this->GetMetaClass()))); + out_line.append(std::format(SYSSTR(" [mc: {:016X}]"), reinterpret_cast(typed_this->GetMetaClass()))); } - auto delegateproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto delegateproperty_to_string(void* p_this, SystemStringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); FDelegateProperty* p_typed_this = static_cast(p_this); - out_line.append(std::format(L" [df: {:016X}]", reinterpret_cast(p_typed_this->GetSignatureFunction()))); + out_line.append(std::format(SYSSTR(" [df: {:016X}]"), reinterpret_cast(p_typed_this->GetSignatureFunction()))); } - auto fieldpathproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto fieldpathproperty_to_string(void* p_this, SystemStringType& out_line) -> void { FFieldPathProperty* typed_this = static_cast(p_this); property_trivial_dump_to_string(p_this, out_line); - out_line.append(std::format(L" [pc: {:016X}]", reinterpret_cast(typed_this->GetPropertyClass()))); + out_line.append(std::format(SYSSTR(" [pc: {:016X}]"), reinterpret_cast(typed_this->GetPropertyClass()))); } - auto interfaceproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto interfaceproperty_to_string(void* p_this, SystemStringType& out_line) -> void { FInterfaceProperty* typed_this = static_cast(p_this); property_trivial_dump_to_string(p_this, out_line); - out_line.append(std::format(L" [ic: {:016X}]", reinterpret_cast(typed_this->GetInterfaceClass()))); + out_line.append(std::format(SYSSTR(" [ic: {:016X}]"), reinterpret_cast(typed_this->GetInterfaceClass()))); } - auto multicastdelegateproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto multicastdelegateproperty_to_string(void* p_this, SystemStringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); FMulticastDelegateProperty* p_typed_this = static_cast(p_this); - out_line.append(std::format(L" [df: {:016X}]", reinterpret_cast(p_typed_this->GetSignatureFunction()))); + out_line.append(std::format(SYSSTR(" [df: {:016X}]"), reinterpret_cast(p_typed_this->GetSignatureFunction()))); } - auto objectproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto objectproperty_to_string(void* p_this, SystemStringType& out_line) -> void { FObjectProperty* typed_this = static_cast(p_this); property_trivial_dump_to_string(p_this, out_line); - out_line.append(std::format(L" [pc: {:016X}]", reinterpret_cast(typed_this->GetPropertyClass()))); + out_line.append(std::format(SYSSTR(" [pc: {:016X}]"), reinterpret_cast(typed_this->GetPropertyClass()))); } - auto structproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto structproperty_to_string(void* p_this, SystemStringType& out_line) -> void { FStructProperty* typed_this = static_cast(p_this); property_trivial_dump_to_string(p_this, out_line); - out_line.append(std::format(L" [ss: {:016X}]", reinterpret_cast(typed_this->GetStruct()))); + out_line.append(std::format(SYSSTR(" [ss: {:016X}]"), reinterpret_cast(typed_this->GetStruct()))); } - auto enumproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto enumproperty_to_string(void* p_this, SystemStringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); auto* typed_this = static_cast(p_this); - out_line.append(std::format(L" [em: {:016X}]", reinterpret_cast(typed_this->GetEnum()))); + out_line.append(std::format(SYSSTR(" [em: {:016X}]"), reinterpret_cast(typed_this->GetEnum()))); } - auto boolproperty_to_string(void* p_this, std::wstring& out_line) -> void + auto boolproperty_to_string(void* p_this, SystemStringType& out_line) -> void { property_trivial_dump_to_string(p_this, out_line); auto* typed_this = static_cast(p_this); if (typed_this->GetFieldMask() != 255) { - out_line.append(std::format(L" [fm: {:X}] [bm: {:X}]", typed_this->GetFieldMask(), typed_this->GetByteMask())); + out_line.append(std::format(SYSSTR(" [fm: {:X}] [bm: {:X}]"), typed_this->GetFieldMask(), typed_this->GetByteMask())); } } - auto enum_to_string(void* p_this, std::wstring& out_line) -> void + auto enum_to_string(void* p_this, SystemStringType& out_line) -> void { object_trivial_dump_to_string(p_this, out_line); @@ -261,24 +262,24 @@ namespace RC::ObjectDumper for (auto& Elem : typed_this->ForEachName()) { - out_line.append(std::format(L"\n[{:016X}] {} [n: {:X}] [v: {}]", 0, Elem.Key.ToString(), Elem.Key.GetComparisonIndex(), Elem.Value)); + out_line.append(std::format(SYSSTR("\n[{:016X}] {} [n: {:X}] [v: {}]"), 0, to_system(Elem.Key.ToString()), Elem.Key.GetComparisonIndex(), Elem.Value)); } } - auto struct_to_string(void* p_this, std::wstring& out_line) -> void + auto struct_to_string(void* p_this, SystemStringType& out_line) -> void { UStruct* typed_this = static_cast(p_this); object_trivial_dump_to_string(p_this, out_line); - out_line.append(std::format(L" [sps: {:016X}]", reinterpret_cast(typed_this->GetSuperStruct()))); + out_line.append(std::format(SYSSTR(" [sps: {:016X}]"), reinterpret_cast(typed_this->GetSuperStruct()))); } - auto function_to_string(void* p_this, std::wstring& out_line) -> void + auto function_to_string(void* p_this, SystemStringType& out_line) -> void { - object_trivial_dump_to_string(p_this, out_line, L":"); + object_trivial_dump_to_string(p_this, out_line, SYSSTR(":")); } - auto scriptstruct_to_string_complex(void* p_this, std::wstring& out_line, ObjectToStringComplexDeclCallable callable) -> void + auto scriptstruct_to_string_complex(void* p_this, SystemStringType& out_line, ObjectToStringComplexDeclCallable callable) -> void { UScriptStruct* script_struct = static_cast(p_this); diff --git a/UE4SS/src/CrashDumper.cpp b/UE4SS/src/Platform/Win32/CrashDumper.cpp similarity index 97% rename from UE4SS/src/CrashDumper.cpp rename to UE4SS/src/Platform/Win32/CrashDumper.cpp index 5e35de5f9..95054f573 100644 --- a/UE4SS/src/CrashDumper.cpp +++ b/UE4SS/src/Platform/Win32/CrashDumper.cpp @@ -27,7 +27,7 @@ namespace RC LONG WINAPI ExceptionHandler(_EXCEPTION_POINTERS* exception_pointers) { const auto now = time_point_cast(system_clock::now()); - const std::wstring dump_path = std::format(L"{}\\crash_{:%Y_%m_%d_%H_%M_%S}.dmp", StringType{UE4SSProgram::get_program().get_working_directory()}, now); + const std::wstring dump_path = std::format(L"{}\\crash_{:%Y_%m_%d_%H_%M_%S}.dmp", SystemStringType{UE4SSProgram::get_program().get_working_directory()}, now); const HANDLE file = CreateFileW(dump_path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); diff --git a/UE4SS/src/main_ue4ss_rewritten.cpp b/UE4SS/src/Platform/Win32/EntryWin32.cpp similarity index 87% rename from UE4SS/src/main_ue4ss_rewritten.cpp rename to UE4SS/src/Platform/Win32/EntryWin32.cpp index a6b836933..1c17c80d2 100644 --- a/UE4SS/src/main_ue4ss_rewritten.cpp +++ b/UE4SS/src/Platform/Win32/EntryWin32.cpp @@ -7,6 +7,8 @@ #include #include "UE4SSProgram.hpp" +#include "Platform.hpp" + #include #include @@ -29,7 +31,7 @@ auto thread_dll_start(UE4SSProgram* program) -> unsigned long // Logging will only happen to the debug console but it's something at least if (!Output::has_internal_error()) { - Output::send(STR("Fatal Error: {}\n"), to_wstring(e->get_message())); + Output::send(SYSSTR("Fatal Error: {}\n"), to_wstring(e->get_message())); } else { @@ -131,4 +133,18 @@ auto WIN_API_FUNCTION_NAME(HMODULE hModule, DWORD ul_reason_for_call, [[maybe_un break; } return TRUE; -} \ No newline at end of file +} + +std::filesystem::path get_executable_path() +{ + wchar_t exe_path_buffer[1024]; + GetModuleFileNameW(GetModuleHandle(nullptr), exe_path_buffer, 1023); + return std::filesystem::path(exe_path_buffer); +} + +void add_dlsearch_folder(std::filesystem::path& path) +{ + SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + // Make sure game directory DLLs are also included + AddDllDirectory(path.c_str()); +} diff --git a/UE4SS/src/SDKGenerator/Common.cpp b/UE4SS/src/SDKGenerator/Common.cpp index 3948dbf5d..2bc9d5db2 100644 --- a/UE4SS/src/SDKGenerator/Common.cpp +++ b/UE4SS/src/SDKGenerator/Common.cpp @@ -27,36 +27,38 @@ #include #include #include +#include #pragma warning(default : 4005) #define DELEGATE_SIGNATURE_POSTFIX STR("__DelegateSignature") +#define DELEGATE_SIGNATURE_POSTFIX_SYS SYSSTR("__DelegateSignature") namespace RC::UEGenerator { using namespace Unreal; - auto get_native_class_name(UClass* uclass, bool interface_name) -> File::StringType + auto get_native_class_name(UClass* uclass, bool interface_name) -> SystemStringType { - File::StringType result_string; + SystemStringType result_string; if (interface_name) { - result_string.append(STR("I")); + result_string.append(SYSSTR("I")); } else if (uclass->IsChildOf()) { - result_string.append(STR("A")); + result_string.append(SYSSTR("A")); } else { - result_string.append(STR("U")); + result_string.append(SYSSTR("U")); } if ((uclass->GetClassFlags() & Unreal::CLASS_Deprecated) != 0) { - result_string.append(STR("DEPRECATED_")); + result_string.append(SYSSTR("DEPRECATED_")); } - result_string.append(uclass->GetName()); + result_string.append(to_system(uclass->GetName())); return result_string; } @@ -72,43 +74,43 @@ namespace RC::UEGenerator } } - auto get_native_enum_name(UEnum* uenum, bool include_type) -> File::StringType + auto get_native_enum_name(UEnum* uenum, bool include_type) -> SystemStringType { - std::wstring result_string; + SystemStringType result_string; // Seems to be not needed, because enum objects, unlike classes or structs, retain their normal E prefix - // ResultString.append(STR("E")); - result_string.append(uenum->GetName()); + // ResultString.append(SYSSTR("E")); + result_string.append(to_system(uenum->GetName())); // Namespaced enums need to have ::Type appended for the type if (uenum->GetCppForm() == UEnum::ECppForm::Namespaced && include_type) { - result_string.append(STR("::Type")); + result_string.append(SYSSTR("::Type")); } return result_string; } - auto get_native_struct_name(UScriptStruct* script_struct) -> File::StringType + auto get_native_struct_name(UScriptStruct* script_struct) -> SystemStringType { - std::wstring result_string; + SystemStringType result_string; - result_string.append(STR("F")); - result_string.append(script_struct->GetName()); + result_string.append(SYSSTR("F")); + result_string.append(to_system(script_struct->GetName())); return result_string; } - auto sanitize_property_name(const File::StringType& property_name) -> File::StringType + auto sanitize_property_name(const SystemStringType& property_name) -> SystemStringType { - std::wstring resulting_name = property_name; + SystemStringType resulting_name = property_name; // Remove heading underscore, used by private variables in some games - if (resulting_name.length() >= 2 && resulting_name[0] == '_') + if (resulting_name.length() >= 2 && resulting_name[0] == STR('_')) { resulting_name.erase(0, 1); } // Remove heading m if it is followed by uppercase letter, used by variables in some games - if (resulting_name.length() >= 2 && resulting_name[0] == 'm' && towupper(resulting_name[1]) == resulting_name[1]) + if (resulting_name.length() >= 2 && resulting_name[0] == STR('m') && towupper(resulting_name[1]) == resulting_name[1]) { resulting_name.erase(0, 1); } @@ -121,16 +123,16 @@ namespace RC::UEGenerator return resulting_name; } - auto generate_delegate_name(FProperty* property, const File::StringType& context_name) -> File::StringType + auto generate_delegate_name(FProperty* property, const SystemStringType& context_name) -> SystemStringType { - const std::wstring property_name = sanitize_property_name(property->GetName()); - return std::format(STR("F{}{}"), context_name, property_name); + const auto property_name = sanitize_property_name(to_system_string(property->GetName())); + return std::format(SYSSTR("F{}{}"), to_system(context_name), to_system(property_name)); } auto generate_property_cxx_name(FProperty* property, bool is_top_level_declaration, UObject* class_context, EnableForwardDeclarations enable_forward_declarations) - -> File::StringType + -> SystemStringType { - const std::wstring field_class_name = property->GetClass().GetName(); + const auto field_class_name = to_system(property->GetClass().GetName()); // Byte Property if (property->IsA()) @@ -141,10 +143,10 @@ namespace RC::UEGenerator if (enum_value != NULL) { // Non-EnumClass enumerations should be wrapped into TEnumAsByte according to UHT - const std::wstring enum_type_name = get_native_enum_name(enum_value); - return std::format(STR("TEnumAsByte<{}>"), enum_type_name); + const SystemStringType enum_type_name = to_system(get_native_enum_name(enum_value)); + return std::format(SYSSTR("TEnumAsByte<{}>"), enum_type_name); } - return STR("uint8"); + return SYSSTR("uint8"); } // Enum Property @@ -155,10 +157,10 @@ namespace RC::UEGenerator if (uenum == NULL) { - throw std::runtime_error(RC::fmt("EnumProperty %S does not have a valid Enum value", property->GetName().c_str())); + throw std::runtime_error(RC::fmt("EnumProperty {} does not have a valid Enum value", property->GetName())); } - const std::wstring enum_type_name = get_native_enum_name(uenum); + const SystemStringType enum_type_name = get_native_enum_name(uenum); return enum_type_name; } @@ -168,47 +170,47 @@ namespace RC::UEGenerator FBoolProperty* bool_property = static_cast(property); if (is_top_level_declaration && bool_property->GetFieldMask() != 255) { - return STR("uint8"); + return SYSSTR("uint8"); } - return STR("bool"); + return SYSSTR("bool"); } // Standard Numeric Properties if (property->IsA()) { - return STR("int8"); + return SYSSTR("int8"); } else if (property->IsA()) { - return STR("int16"); + return SYSSTR("int16"); } else if (property->IsA()) { - return STR("int32"); + return SYSSTR("int32"); } else if (property->IsA()) { - return STR("int64"); + return SYSSTR("int64"); } else if (property->IsA()) { - return STR("uint16"); + return SYSSTR("uint16"); } else if (property->IsA()) { - return STR("uint32"); + return SYSSTR("uint32"); } else if (property->IsA()) { - return STR("uint64"); + return SYSSTR("uint64"); } else if (property->IsA()) { - return STR("float"); + return SYSSTR("float"); } else if (property->IsA()) { - return STR("double"); + return SYSSTR("double"); } // Class Properties @@ -219,22 +221,22 @@ namespace RC::UEGenerator if (meta_class == NULL || meta_class == UObject::StaticClass()) { - return STR("UClass*"); + return SYSSTR("UClass*"); } - File::StringType meta_class_name{}; + SystemStringType meta_class_name{}; if (enable_forward_declarations == EnableForwardDeclarations::Yes) { - meta_class_name = STR("class "); + meta_class_name = SYSSTR("class "); } meta_class_name.append(get_native_class_name(meta_class, false)); - return std::format(STR("TSubclassOf<{}>"), meta_class_name); + return std::format(SYSSTR("TSubclassOf<{}>"), meta_class_name); } if (auto* class_property = CastField(property); class_property) { // TODO: Confirm that this is accurate - return STR("TObjectPtr"); + return SYSSTR("TObjectPtr"); } if (property->IsA()) @@ -244,15 +246,15 @@ namespace RC::UEGenerator if (meta_class == NULL) { - return STR("TSoftClassPtr"); + return SYSSTR("TSoftClassPtr"); } else if (meta_class == UObject::StaticClass()) { - return STR("TSoftClassPtr"); + return SYSSTR("TSoftClassPtr"); } - - const std::wstring meta_class_name = get_native_class_name(meta_class, false); - return std::format(STR("TSoftClassPtr<{}>"), meta_class_name); + + const SystemStringType meta_class_name = get_native_class_name(meta_class, false); + return std::format(SYSSTR("TSoftClassPtr<{}>"), meta_class_name); } // Object Properties @@ -265,11 +267,11 @@ namespace RC::UEGenerator if (property_class == NULL) { - return STR("UObject*"); + return SYSSTR("UObject*"); } - const std::wstring property_class_name = get_native_class_name(property_class, false); - return std::format(STR("{}*"), property_class_name); + const SystemStringType property_class_name = get_native_class_name(property_class, false); + return std::format(SYSSTR("{}*"), property_class_name); } if (auto* object_property = CastField(property); object_property) @@ -278,12 +280,12 @@ namespace RC::UEGenerator if (!property_class) { - return STR("TObjectPtr"); + return SYSSTR("TObjectPtr"); } else { const auto property_class_name = get_native_class_name(property_class, false); - return std::format(STR("TObjectPtr<{}>"), property_class_name); + return std::format(SYSSTR("TObjectPtr<{}>"), property_class_name); } } @@ -294,16 +296,16 @@ namespace RC::UEGenerator if (property_class == NULL) { - return STR("TWeakObjectPtr"); + return SYSSTR("TWeakObjectPtr"); } - File::StringType property_class_name{}; + SystemStringType property_class_name{}; if (enable_forward_declarations == EnableForwardDeclarations::Yes) { - property_class_name = std::format(STR("class ")); + property_class_name = std::format(SYSSTR("class ")); } property_class_name.append(get_native_class_name(property_class, false)); - return std::format(STR("TWeakObjectPtr<{}>"), property_class_name); + return std::format(SYSSTR("TWeakObjectPtr<{}>"), property_class_name); } if (property->IsA()) @@ -313,16 +315,16 @@ namespace RC::UEGenerator if (property_class == NULL) { - return STR("TLazyObjectPtr"); + return SYSSTR("TLazyObjectPtr"); } - File::StringType property_class_name{}; + SystemStringType property_class_name{}; if (enable_forward_declarations == EnableForwardDeclarations::Yes) { - property_class_name = STR("class "); + property_class_name = SYSSTR("class "); } property_class_name.append(get_native_class_name(property_class, false)); - return std::format(STR("TLazyObjectPtr<{}>"), property_class_name); + return std::format(SYSSTR("TLazyObjectPtr<{}>"), property_class_name); } if (property->IsA()) @@ -332,11 +334,11 @@ namespace RC::UEGenerator if (property_class == NULL) { - return STR("TSoftObjectPtr"); + return SYSSTR("TSoftObjectPtr"); } - const std::wstring property_class_name = get_native_class_name(property_class, false); - return std::format(STR("TSoftObjectPtr<{}>"), property_class_name); + const SystemStringType property_class_name = get_native_class_name(property_class, false); + return std::format(SYSSTR("TSoftObjectPtr<{}>"), property_class_name); } // Interface Property @@ -347,16 +349,16 @@ namespace RC::UEGenerator if (interface_class == NULL || interface_class == UInterface::StaticClass()) { - return STR("FScriptInterface"); + return SYSSTR("FScriptInterface"); } - File::StringType interface_class_name{}; + SystemStringType interface_class_name{}; if (enable_forward_declarations == EnableForwardDeclarations::Yes) { - interface_class_name = STR("class "); + interface_class_name = SYSSTR("class "); } interface_class_name.append(get_native_class_name(interface_class, true)); - return std::format(STR("TScriptInterface<{}>"), interface_class_name); + return std::format(SYSSTR("TScriptInterface<{}>"), interface_class_name); } // Struct Property @@ -367,10 +369,10 @@ namespace RC::UEGenerator if (script_struct == NULL) { - throw std::runtime_error(RC::fmt("Struct is NULL for StructProperty %S", property->GetName().c_str())); + throw std::runtime_error(RC::fmt("Struct is NULL for StructProperty {}", property->GetName())); } - const std::wstring native_struct_name = get_native_struct_name(script_struct); + const SystemStringType native_struct_name = get_native_struct_name(script_struct); return native_struct_name; } @@ -379,7 +381,7 @@ namespace RC::UEGenerator { FDelegateProperty* delegate_property = static_cast(property); - const std::wstring delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); + const auto delegate_type_name = generate_delegate_name(delegate_property, to_system(class_context->GetName())); return delegate_type_name; } @@ -389,7 +391,7 @@ namespace RC::UEGenerator { FMulticastInlineDelegateProperty* delegate_property = static_cast(property); - const std::wstring delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); + const auto delegate_type_name = generate_delegate_name(delegate_property, to_system(class_context->GetName())); return delegate_type_name; } @@ -397,7 +399,7 @@ namespace RC::UEGenerator { FMulticastSparseDelegateProperty* delegate_property = static_cast(property); - const std::wstring delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); + const auto delegate_type_name = generate_delegate_name(delegate_property, to_system(class_context->GetName())); return delegate_type_name; } @@ -405,8 +407,8 @@ namespace RC::UEGenerator if (property->IsA()) { FFieldPathProperty* field_path_property = static_cast(property); - const std::wstring property_class_name = field_path_property->GetPropertyClass()->GetName(); - return std::format(STR("TFieldPath"), property_class_name); + const auto property_class_name = to_system(field_path_property->GetPropertyClass()->GetName()); + return std::format(SYSSTR("TFieldPath"), property_class_name); } // Collection and Map Properties @@ -416,16 +418,16 @@ namespace RC::UEGenerator FArrayProperty* array_property = static_cast(property); FProperty* inner_property = array_property->GetInner(); - File::StringType inner_property_type{}; + SystemStringType inner_property_type{}; if (enable_forward_declarations == EnableForwardDeclarations::Yes && !is_integral_type(inner_property)) { if (inner_property->IsA()) { - inner_property_type = STR("class "); + inner_property_type = SYSSTR("class "); } } inner_property_type.append(generate_property_cxx_name(inner_property, is_top_level_declaration, class_context)); - return std::format(STR("TArray<{}>"), inner_property_type); + return std::format(SYSSTR("TArray<{}>"), inner_property_type); } if (property->IsA()) @@ -433,8 +435,8 @@ namespace RC::UEGenerator FSetProperty* set_property = static_cast(property); FProperty* element_prop = set_property->GetElementProp(); - const std::wstring element_property_type = generate_property_cxx_name(element_prop, is_top_level_declaration, class_context); - return std::format(STR("TSet<{}>"), element_property_type); + const SystemStringType element_property_type = generate_property_cxx_name(element_prop, is_top_level_declaration, class_context); + return std::format(SYSSTR("TSet<{}>"), element_property_type); } // TODO: This is missing support for freeze image map properties because XMapProperty is incomplete. (low priority) @@ -444,48 +446,48 @@ namespace RC::UEGenerator FProperty* key_property = map_property->GetKeyProp(); FProperty* value_property = map_property->GetValueProp(); - File::StringType key_type{}; - File::StringType value_type{}; + SystemStringType key_type{}; + SystemStringType value_type{}; if (enable_forward_declarations == EnableForwardDeclarations::Yes && !is_integral_type(key_property) && !is_integral_type(value_property)) { if (!key_property->IsA()) { - key_type = STR("class "); + key_type = SYSSTR("class "); } if (!value_property->IsA()) { - value_type = STR("class "); + value_type = SYSSTR("class "); } } key_type.append(generate_property_cxx_name(key_property, is_top_level_declaration, class_context)); value_type.append(generate_property_cxx_name(value_property, is_top_level_declaration, class_context)); - return std::format(STR("TMap<{}, {}>"), key_type, value_type); + return std::format(SYSSTR("TMap<{}, {}>"), key_type, value_type); } // Standard properties that do not have any special attributes if (property->IsA()) { - return STR("FName"); + return SYSSTR("FName"); } else if (property->IsA()) { - return STR("FString"); + return SYSSTR("FString"); } else if (property->IsA()) { - return STR("FText"); + return SYSSTR("FText"); } - throw std::runtime_error(RC::fmt("Unsupported property class %S", field_class_name.c_str())); + throw std::runtime_error(RC::fmt("Unsupported property class " SystemStringPrint, field_class_name)); } - auto generate_property_lua_name(FProperty* property, bool is_top_level_declaration, UObject* class_context) -> File::StringType + auto generate_property_lua_name(FProperty* property, bool is_top_level_declaration, UObject* class_context) -> SystemStringType { - const std::wstring field_class_name = property->GetClass().GetName(); + const auto field_class_name = to_system(property->GetClass().GetName()); // Byte Property - if (field_class_name == STR("ByteProperty")) + if (field_class_name == SYSSTR("ByteProperty")) { FByteProperty* byte_property = static_cast(property); UEnum* enum_value = byte_property->GetEnum(); @@ -493,86 +495,86 @@ namespace RC::UEGenerator if (enum_value != NULL) { // Non-EnumClass enumerations should be wrapped into TEnumAsByte according to UHT - const std::wstring enum_type_name = get_native_enum_name(enum_value); - return std::format(STR("{}"), enum_type_name); + const SystemStringType enum_type_name = get_native_enum_name(enum_value); + return std::format(SYSSTR("{}"), enum_type_name); } - return STR("uint8"); + return SYSSTR("uint8"); } // Enum Property - if (field_class_name == STR("EnumProperty")) + if (field_class_name == SYSSTR("EnumProperty")) { FEnumProperty* enum_property = static_cast(property); UEnum* uenum = enum_property->GetEnum(); if (uenum == NULL) { - throw std::runtime_error(RC::fmt("EnumProperty %S does not have a valid Enum value", property->GetName().c_str())); + throw std::runtime_error(RC::fmt("EnumProperty {} does not have a valid Enum value", property->GetName())); } - const std::wstring enum_type_name = get_native_enum_name(uenum); + const SystemStringType enum_type_name = get_native_enum_name(uenum); return enum_type_name; } // Bool Property - if (field_class_name == STR("BoolProperty")) + if (field_class_name == SYSSTR("BoolProperty")) { - return STR("boolean"); + return SYSSTR("boolean"); } // Standard Numeric Properties - if (field_class_name == STR("Int8Property")) + if (field_class_name == SYSSTR("Int8Property")) { - return STR("int8"); + return SYSSTR("int8"); } - else if (field_class_name == STR("Int16Property")) + else if (field_class_name == SYSSTR("Int16Property")) { - return STR("int16"); + return SYSSTR("int16"); } - else if (field_class_name == STR("IntProperty")) + else if (field_class_name == SYSSTR("IntProperty")) { - return STR("int32"); + return SYSSTR("int32"); } - else if (field_class_name == STR("Int64Property")) + else if (field_class_name == SYSSTR("Int64Property")) { - return STR("int64"); + return SYSSTR("int64"); } - else if (field_class_name == STR("UInt16Property")) + else if (field_class_name == SYSSTR("UInt16Property")) { - return STR("uint16"); + return SYSSTR("uint16"); } - else if (field_class_name == STR("UInt32Property")) + else if (field_class_name == SYSSTR("UInt32Property")) { - return STR("uint32"); + return SYSSTR("uint32"); } - else if (field_class_name == STR("UInt64Property")) + else if (field_class_name == SYSSTR("UInt64Property")) { - return STR("uint64"); + return SYSSTR("uint64"); } - else if (field_class_name == STR("FloatProperty")) + else if (field_class_name == SYSSTR("FloatProperty")) { - return STR("float"); + return SYSSTR("float"); } - else if (field_class_name == STR("DoubleProperty")) + else if (field_class_name == SYSSTR("DoubleProperty")) { - return STR("double"); + return SYSSTR("double"); } // Object Properties // TODO: Verify that the syntax for 'AssetObjectProperty' is the same as for 'ObjectProperty'. // If it's not, then add another branch here after you figure out what the syntax should be. - if (field_class_name == STR("ObjectProperty") || field_class_name == STR("AssetObjectProperty")) + if (field_class_name == SYSSTR("ObjectProperty") || field_class_name == SYSSTR("AssetObjectProperty")) { FObjectProperty* object_property = static_cast(property); UClass* property_class = object_property->GetPropertyClass(); if (property_class == NULL) { - return STR("UObject"); + return SYSSTR("UObject"); } - const std::wstring property_class_name = get_native_class_name(property_class, false); - return std::format(STR("{}"), property_class_name); + const SystemStringType property_class_name = get_native_class_name(property_class, false); + return std::format(SYSSTR("{}"), property_class_name); } if (auto* object_property = CastField(property); object_property) @@ -581,223 +583,223 @@ namespace RC::UEGenerator if (!property_class) { - return STR("TObjectPtr"); + return SYSSTR("TObjectPtr"); } else { const auto property_class_name = get_native_class_name(property_class, false); - return std::format(STR("TObjectPtr<{}>"), property_class_name); + return std::format(SYSSTR("TObjectPtr<{}>"), property_class_name); } } - if (field_class_name == STR("WeakObjectProperty")) + if (field_class_name == SYSSTR("WeakObjectProperty")) { FWeakObjectProperty* weak_object_property = static_cast(property); UClass* property_class = weak_object_property->GetPropertyClass(); if (property_class == NULL) { - return STR("TWeakObjectPtr"); + return SYSSTR("TWeakObjectPtr"); } - File::StringType property_class_name{}; + SystemStringType property_class_name{}; property_class_name.append(get_native_class_name(property_class, false)); - return std::format(STR("TWeakObjectPtr<{}>"), property_class_name); + return std::format(SYSSTR("TWeakObjectPtr<{}>"), property_class_name); } - if (field_class_name == STR("LazyObjectProperty")) + if (field_class_name == SYSSTR("LazyObjectProperty")) { FLazyObjectProperty* lazy_object_property = static_cast(property); UClass* property_class = lazy_object_property->GetPropertyClass(); if (property_class == NULL) { - return STR("TLazyObjectPtr"); + return SYSSTR("TLazyObjectPtr"); } - File::StringType property_class_name{}; + SystemStringType property_class_name{}; property_class_name.append(get_native_class_name(property_class, false)); - return std::format(STR("TLazyObjectPtr<{}>"), property_class_name); + return std::format(SYSSTR("TLazyObjectPtr<{}>"), property_class_name); } - if (field_class_name == STR("SoftObjectProperty")) + if (field_class_name == SYSSTR("SoftObjectProperty")) { FSoftObjectProperty* soft_object_property = static_cast(property); UClass* property_class = soft_object_property->GetPropertyClass(); if (property_class == NULL) { - return STR("TSoftObjectPtr"); + return SYSSTR("TSoftObjectPtr"); } - const std::wstring property_class_name = get_native_class_name(property_class, false); - return std::format(STR("TSoftObjectPtr<{}>"), property_class_name); + const SystemStringType property_class_name = get_native_class_name(property_class, false); + return std::format(SYSSTR("TSoftObjectPtr<{}>"), property_class_name); } // Class Properties - if (field_class_name == STR("ClassProperty") || field_class_name == STR("AssetClassProperty")) + if (field_class_name == SYSSTR("ClassProperty") || field_class_name == SYSSTR("AssetClassProperty")) { FClassProperty* class_property = static_cast(property); UClass* meta_class = class_property->GetMetaClass(); if (meta_class == NULL || meta_class == UObject::StaticClass()) { - return STR("UClass"); + return SYSSTR("UClass"); } - File::StringType meta_class_name{}; + SystemStringType meta_class_name{}; meta_class_name.append(get_native_class_name(meta_class, false)); - return std::format(STR("TSubclassOf<{}>"), meta_class_name); + return std::format(SYSSTR("TSubclassOf<{}>"), meta_class_name); } if (auto* class_property = CastField(property); class_property) { // TODO: Confirm that this is accurate - return STR("TObjectPtr"); + return SYSSTR("TObjectPtr"); } - if (field_class_name == STR("SoftClassProperty")) + if (field_class_name == SYSSTR("SoftClassProperty")) { FSoftClassProperty* soft_class_property = static_cast(property); UClass* meta_class = soft_class_property->GetMetaClass(); if (meta_class == NULL || meta_class == UObject::StaticClass()) { - return STR("TSoftClassPtr"); + return SYSSTR("TSoftClassPtr"); } - const std::wstring meta_class_name = get_native_class_name(meta_class, false); - return std::format(STR("TSoftClassPtr<{}>"), meta_class_name); + const SystemStringType meta_class_name = get_native_class_name(meta_class, false); + return std::format(SYSSTR("TSoftClassPtr<{}>"), meta_class_name); } // Interface Property - if (field_class_name == STR("InterfaceProperty")) + if (field_class_name == SYSSTR("InterfaceProperty")) { FInterfaceProperty* interface_property = static_cast(property); UClass* interface_class = interface_property->GetInterfaceClass(); if (interface_class == NULL || interface_class == UInterface::StaticClass()) { - return STR("FScriptInterface"); + return SYSSTR("FScriptInterface"); } - File::StringType interface_class_name{}; + SystemStringType interface_class_name{}; interface_class_name.append(get_native_class_name(interface_class, true)); - return std::format(STR("TScriptInterface<{}>"), interface_class_name); + return std::format(SYSSTR("TScriptInterface<{}>"), interface_class_name); } // Struct Property - if (field_class_name == STR("StructProperty")) + if (field_class_name == SYSSTR("StructProperty")) { FStructProperty* struct_property = static_cast(property); UScriptStruct* script_struct = struct_property->GetStruct(); if (script_struct == NULL) { - throw std::runtime_error(RC::fmt("Struct is NULL for StructProperty %S", property->GetName().c_str())); + throw std::runtime_error(RC::fmt("Struct is NULL for StructProperty {}", property->GetName())); } - const std::wstring native_struct_name = get_native_struct_name(script_struct); + const SystemStringType native_struct_name = get_native_struct_name(script_struct); return native_struct_name; } // Delegate Properties - if (field_class_name == STR("DelegateProperty")) + if (field_class_name == SYSSTR("DelegateProperty")) { FDelegateProperty* delegate_property = static_cast(property); - const std::wstring delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); + const auto delegate_type_name = generate_delegate_name(delegate_property, to_system(class_context->GetName())); return delegate_type_name; } // In 4.23, they replaced 'MulticastDelegateProperty' with 'Inline' & 'Sparse' variants // It looks like the delegate macro might be the same as the 'Inline' variant in later versions, so we'll use the same branch here - if (field_class_name == STR("MulticastInlineDelegateProperty") || field_class_name == STR("MulticastDelegateProperty")) + if (field_class_name == SYSSTR("MulticastInlineDelegateProperty") || field_class_name == SYSSTR("MulticastDelegateProperty")) { FMulticastInlineDelegateProperty* delegate_property = static_cast(property); - const std::wstring delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); + const auto delegate_type_name = generate_delegate_name(delegate_property, to_system(class_context->GetName())); return delegate_type_name; } - if (field_class_name == STR("MulticastSparseDelegateProperty")) + if (field_class_name == SYSSTR("MulticastSparseDelegateProperty")) { FMulticastSparseDelegateProperty* delegate_property = static_cast(property); - const std::wstring delegate_type_name = generate_delegate_name(delegate_property, class_context->GetName()); + const auto delegate_type_name = generate_delegate_name(delegate_property, to_system(class_context->GetName())); return delegate_type_name; } // Field path property - if (field_class_name == STR("FieldPathProperty")) + if (field_class_name == SYSSTR("FieldPathProperty")) { FFieldPathProperty* field_path_property = static_cast(property); - const std::wstring property_class_name = field_path_property->GetPropertyClass()->GetName(); - return std::format(STR("TFieldPath"), property_class_name); + const auto property_class_name = to_system(field_path_property->GetPropertyClass()->GetName()); + return std::format(SYSSTR("TFieldPath"), property_class_name); } // Collection and Map Properties // TODO: This is missing support for freeze image array properties because XArrayProperty is incomplete. (low priority) - if (field_class_name == STR("ArrayProperty")) + if (field_class_name == SYSSTR("ArrayProperty")) { FArrayProperty* array_property = static_cast(property); FProperty* inner_property = array_property->GetInner(); - File::StringType inner_property_type{}; + SystemStringType inner_property_type{}; inner_property_type.append(generate_property_lua_name(inner_property, is_top_level_declaration, class_context)); - return std::format(STR("TArray<{}>"), inner_property_type); + return std::format(SYSSTR("TArray<{}>"), inner_property_type); } - if (field_class_name == STR("SetProperty")) + if (field_class_name == SYSSTR("SetProperty")) { FSetProperty* set_property = static_cast(property); FProperty* element_prop = set_property->GetElementProp(); - const std::wstring element_property_type = generate_property_lua_name(element_prop, is_top_level_declaration, class_context); - return std::format(STR("TSet<{}>"), element_property_type); + const SystemStringType element_property_type = generate_property_lua_name(element_prop, is_top_level_declaration, class_context); + return std::format(SYSSTR("TSet<{}>"), element_property_type); } // TODO: This is missing support for freeze image map properties because XMapProperty is incomplete. (low priority) - if (field_class_name == STR("MapProperty")) + if (field_class_name == SYSSTR("MapProperty")) { FMapProperty* map_property = static_cast(property); FProperty* key_property = map_property->GetKeyProp(); FProperty* value_property = map_property->GetValueProp(); - File::StringType key_type{}; - File::StringType value_type{}; + SystemStringType key_type{}; + SystemStringType value_type{}; key_type.append(generate_property_lua_name(key_property, is_top_level_declaration, class_context)); value_type.append(generate_property_lua_name(value_property, is_top_level_declaration, class_context)); - return std::format(STR("TMap<{}, {}>"), key_type, value_type); + return std::format(SYSSTR("TMap<{}, {}>"), key_type, value_type); } // Standard properties that do not have any special attributes - if (field_class_name == STR("NameProperty")) + if (field_class_name == SYSSTR("NameProperty")) { - return STR("FName"); + return SYSSTR("FName"); } - else if (field_class_name == STR("StrProperty")) + else if (field_class_name == SYSSTR("StrProperty")) { - return STR("FString"); + return SYSSTR("FString"); } - else if (field_class_name == STR("TextProperty")) + else if (field_class_name == SYSSTR("TextProperty")) { - return STR("FText"); + return SYSSTR("FText"); } - throw std::runtime_error(RC::fmt("Unsupported property class %S", field_class_name.c_str())); + throw std::runtime_error(RC::fmt("Unsupported property class {}", field_class_name)); } - auto get_native_delegate_type_name(Unreal::UFunction* signature_function, Unreal::UClass* current_class, bool strip_outer_name) -> File::StringType + auto get_native_delegate_type_name(Unreal::UFunction* signature_function, Unreal::UClass* current_class, bool strip_outer_name) -> SystemStringType { if (!is_delegate_signature_function(signature_function)) { - throw std::runtime_error(RC::fmt("Function %S is not a delegate signature function", signature_function->GetName().c_str())); + throw std::runtime_error(RC::fmt("Function {} is not a delegate signature function", signature_function->GetName())); } // Delegate names always start with F and have __DelegateSignature postfix - File::StringType delegate_type_name = strip_delegate_signature_postfix(signature_function); - delegate_type_name.insert(0, STR("F")); + SystemStringType delegate_type_name = strip_delegate_signature_postfix(signature_function); + delegate_type_name.insert(0, SYSSTR("F")); // Return the delegate name without the outer name if we have been requested to strip it if (strip_outer_name) @@ -816,16 +818,16 @@ namespace RC::UEGenerator { // For interface, delegates are declared inside the interface definition bool is_class_interface = delegate_outer_class->IsChildOf(); - const File::StringType outer_class_name = get_native_class_name(delegate_outer_class, is_class_interface); + const SystemStringType outer_class_name = get_native_class_name(delegate_outer_class, is_class_interface); - delegate_type_name.insert(0, STR("::")); + delegate_type_name.insert(0, SYSSTR("::")); delegate_type_name.insert(0, outer_class_name); } } else if (!delegate_outer->IsA()) { // Delegate signature functions should never exist outside the UPackage or UClass - throw std::runtime_error(RC::fmt("Delegate signature function %S does not have class or package as outer", delegate_outer->GetName().c_str())); + throw std::runtime_error(RC::fmt("Delegate signature function {} does not have class or package as outer", delegate_outer->GetName())); } return delegate_type_name; } @@ -835,17 +837,17 @@ namespace RC::UEGenerator return (function->GetFunctionFlags() & Unreal::FUNC_Delegate) != 0 && function->GetName().ends_with(DELEGATE_SIGNATURE_POSTFIX); } - auto strip_delegate_signature_postfix(Unreal::UFunction* signature_function) -> File::StringType + auto strip_delegate_signature_postfix(Unreal::UFunction* signature_function) -> SystemStringType { if (!is_delegate_signature_function(signature_function)) { - throw std::runtime_error(RC::fmt("Function %S is not a delegate signature function", signature_function->GetName().c_str())); + throw std::runtime_error(RC::fmt("Function {} is not a delegate signature function", signature_function->GetName())); } // Delegate names always start with F and have __DelegateSignature postfix - const File::StringType delegate_signature_postfix = DELEGATE_SIGNATURE_POSTFIX; + const SystemStringType delegate_signature_postfix = DELEGATE_SIGNATURE_POSTFIX_SYS; - File::StringType delegate_name = signature_function->GetName(); + auto delegate_name = to_system(signature_function->GetName()); delegate_name.erase(delegate_name.length() - delegate_signature_postfix.length()); return delegate_name; } diff --git a/UE4SS/src/SDKGenerator/Generator.cpp b/UE4SS/src/SDKGenerator/Generator.cpp index 6980cd161..81be14545 100644 --- a/UE4SS/src/SDKGenerator/Generator.cpp +++ b/UE4SS/src/SDKGenerator/Generator.cpp @@ -71,38 +71,38 @@ namespace RC::UEGenerator { std::filesystem::path primary_file_name; std::filesystem::path secondary_file_name; - std::vector ordered_primary_file_contents; - std::vector ordered_secondary_file_contents; - File::StringType package_name; + std::vector ordered_primary_file_contents; + std::vector ordered_secondary_file_contents; + SystemStringType package_name; File::Handle primary_file; File::Handle secondary_file; bool primary_file_has_no_contents; bool secondary_file_has_no_contents; }; - auto generate_tab(size_t num_tabs = 1) -> File::StringType + auto generate_tab(size_t num_tabs = 1) -> SystemStringType { - File::StringType tab_storage{}; + SystemStringType tab_storage{}; for (size_t i = 0; i < num_tabs; ++i) { - tab_storage += STR(" "); + tab_storage += SYSSTR(" "); } return tab_storage; } - auto generate_prefix(UStruct* obj) -> File::StringType + auto generate_prefix(UStruct* obj) -> SystemStringType { UClass* obj_class = obj->GetClassPrivate(); if (obj_class->IsChildOf()) { - return STR("struct"); + return SYSSTR("struct"); } else { - return STR("class"); + return SYSSTR("class"); } } - auto generate_class_name(UStruct* class_to_generate) -> File::StringType + auto generate_class_name(UStruct* class_to_generate) -> SystemStringType { if (class_to_generate->GetClassPrivate()->IsChildOf()) { @@ -134,7 +134,7 @@ namespace RC::UEGenerator // Map of FName.ComparisonIndex -> File::Handle std::unordered_map m_files{}; - std::unordered_map m_file_names{}; + std::unordered_map m_file_names{}; std::unordered_map m_classes_dumped{}; public: @@ -146,7 +146,7 @@ namespace RC::UEGenerator auto create_all_files() -> void { - Output::send(STR("Creating all files...\n")); + Output::send(SYSSTR("Creating all files...\n")); for (auto& [comparison_index, generated_file] : m_files) { if (!generated_file.ordered_primary_file_contents.empty()) @@ -158,7 +158,7 @@ namespace RC::UEGenerator sort_files(generated_file.ordered_primary_file_contents); - File::StringType combined_file_contents; + SystemStringType combined_file_contents; for (auto& line : generated_file.ordered_primary_file_contents) { combined_file_contents.append(line); @@ -166,11 +166,11 @@ namespace RC::UEGenerator if (combined_file_contents.empty()) { - Output::send(STR("Empty primary file contents in '{}'\n"), generated_file.package_name); + Output::send(SYSSTR("Empty primary file contents in '{}'\n"), generated_file.package_name); } else { - generated_file.primary_file.write_string_to_file(combined_file_contents); + generated_file.primary_file.write_file_string_to_file(to_file(combined_file_contents)); } specification.generate_file_footer(generated_file); @@ -185,7 +185,7 @@ namespace RC::UEGenerator sort_files(generated_file.ordered_secondary_file_contents); - File::StringType combined_file_contents; + SystemStringType combined_file_contents; for (auto& line : generated_file.ordered_secondary_file_contents) { combined_file_contents.append(line); @@ -193,11 +193,11 @@ namespace RC::UEGenerator if (combined_file_contents.empty()) { - Output::send(STR("Empty secondary file contents in '{}'\n"), generated_file.package_name); + Output::send(SYSSTR("Empty secondary file contents in '{}'\n"), generated_file.package_name); } else { - generated_file.secondary_file.write_string_to_file(combined_file_contents); + generated_file.secondary_file.write_file_string_to_file(to_file(combined_file_contents)); } generated_file.secondary_file.close(); @@ -205,18 +205,18 @@ namespace RC::UEGenerator } } - auto sort_files(std::vector& content) -> void + auto sort_files(std::vector& content) -> void { - std::vector struct_content; - std::vector class_content; - std::vector other_content; + std::vector struct_content; + std::vector class_content; + std::vector other_content; for (auto& line : content) { - if (line.starts_with(STR("struct"))) + if (line.starts_with(SYSSTR("struct"))) { struct_content.push_back(line); } - else if (line.starts_with(STR("class"))) + else if (line.starts_with(SYSSTR("class"))) { class_content.push_back(line); } @@ -237,7 +237,7 @@ namespace RC::UEGenerator content.insert(content.end(), other_content.begin(), other_content.end()); } - auto sort_types(std::vector& content) -> void + auto sort_types(std::vector& content) -> void { std::sort(content.begin(), content.end(), [&](const auto& a, const auto& b) { auto a_class_name = get_class_name(a); @@ -246,16 +246,16 @@ namespace RC::UEGenerator }); } - auto get_class_name(const auto& x) -> std::wstring + auto get_class_name(const auto& x) -> SystemStringType { // Using this method instead of regex because it is extremely slow - auto class_name = x.substr(x.find(STR(' ')) + 1); - class_name = class_name.substr(0, class_name.find(STR(' '))); - if (class_name == STR("class")) + auto class_name = x.substr(x.find(SYSSTR(' ')) + 1); + class_name = class_name.substr(0, class_name.find(SYSSTR(' '))); + if (class_name == SYSSTR("class")) { // Case for enum class - class_name = x.substr(x.find(STR(' ')) + 7); - class_name = class_name.substr(0, class_name.find(STR(' '))); + class_name = x.substr(x.find(SYSSTR(' ')) + 7); + class_name = class_name.substr(0, class_name.find(SYSSTR(' '))); } return class_name; } @@ -265,11 +265,11 @@ namespace RC::UEGenerator return object->GetClassPrivate()->GetNamePrivate().Equals(Unreal::GPackageName); } - auto generate_offset_comment(XProperty* property, File::StringType& line) -> File::StringType + auto generate_offset_comment(XProperty* property, SystemStringType& line) -> SystemStringType { if (UE4SSProgram::settings_manager.CXXHeaderGenerator.DumpOffsetsAndSizes) { - return std::format(STR("{:85} // 0x{:04X} (size: 0x{:X})"), line, property->GetOffset_Internal(), property->GetSize()); + return std::format(SYSSTR("{:85} // 0x{:04X} (size: 0x{:X})"), line, property->GetOffset_Internal(), property->GetSize()); } else { @@ -323,7 +323,7 @@ namespace RC::UEGenerator auto generate_function_declaration(ObjectInfo& owner, const FunctionInfo& function_info, GeneratedFile& generated_file, - File::StringType& out_current_class_content, + SystemStringType& out_current_class_content, IsDelegateFunction is_delegate_function = IsDelegateFunction::No) -> void { std::optional return_property_info = [&]() -> std::optional { @@ -342,14 +342,14 @@ namespace RC::UEGenerator return return_property_info.has_value() ? return_property_info.value().property : nullptr; }(); - File::StringType function_name{function_info.function->GetName()}; + SystemStringType function_name{to_system(function_info.function->GetName())}; if (is_delegate_function == IsDelegateFunction::Yes) { // Remove the last 19 characters, which is always '__DelegateSignature' for delegates function_name.erase(function_name.size() - 19, 19); } - StringType current_class_content{}; + SystemStringType current_class_content{}; specification.generate_function_declaration(this, current_class_content, owner, function_info, function_name, return_property, return_property_info); // Commenting out this code because all network replicated functions are events @@ -357,14 +357,14 @@ namespace RC::UEGenerator /* if ((function->get_function_flags() & Unreal::EFunctionFlags::FUNC_Event) != 0) { - current_class_content.append(STR(" // EVENT")); + current_class_content.append(SYSSTR(" // EVENT")); } //*/ - current_class_content.append(STR("\n")); + current_class_content.append(SYSSTR("\n")); out_current_class_content.append(current_class_content); } - auto generate_class_dependency(ObjectInfo& owner, UStruct* inherited_class, File::StringType& current_class_content) -> void + auto generate_class_dependency(ObjectInfo& owner, UStruct* inherited_class, SystemStringType& current_class_content) -> void { if (!inherited_class) { @@ -377,7 +377,7 @@ namespace RC::UEGenerator if (package_file_for_inherited_class) { auto& inherited_object_info = m_classes_dumped.emplace(inherited_class, ObjectInfo{inherited_class, &owner}).first->second; - File::StringType new_class_content{}; + SystemStringType new_class_content{}; generate_class(inherited_object_info, *package_file_for_inherited_class, new_class_content); if (!package_file_for_inherited_class->primary_file_has_no_contents) { @@ -389,7 +389,7 @@ namespace RC::UEGenerator } } - auto generate_class_dependency_from_property(ObjectInfo& owner, XProperty* property, File::StringType& current_class_content) -> bool + auto generate_class_dependency_from_property(ObjectInfo& owner, XProperty* property, SystemStringType& current_class_content) -> bool { if (property->IsA()) { @@ -441,7 +441,7 @@ namespace RC::UEGenerator return false; } - auto make_function_info(ObjectInfo& owner, UFunction* function, File::StringType& current_class_content) -> FunctionInfo + auto make_function_info(ObjectInfo& owner, UFunction* function, SystemStringType& current_class_content) -> FunctionInfo { FunctionInfo function_info{ .function = function, @@ -461,7 +461,7 @@ namespace RC::UEGenerator return function_info; } - auto generate_class(ObjectInfo object_info, GeneratedFile& generated_file, File::StringType& current_class_content) -> XProperty* + auto generate_class(ObjectInfo object_info, GeneratedFile& generated_file, SystemStringType& current_class_content) -> XProperty* { UStruct* native_class = static_cast(object_info.object); if (specification.should_generate_class(native_class)) @@ -477,7 +477,7 @@ namespace RC::UEGenerator { generated_file.secondary_file_has_no_contents = false; - File::StringType content_buffer; + SystemStringType content_buffer; UEnum* uenum = static_cast(native_object); specification.generate_enum_declaration(content_buffer, uenum); @@ -488,17 +488,17 @@ namespace RC::UEGenerator size_t colon_pos = enum_value_full_name.rfind(STR(":")); auto enum_value_name = colon_pos == enum_value_full_name.npos ? enum_value_full_name : enum_value_full_name.substr(colon_pos + 1); - specification.generate_enum_member(content_buffer, uenum, enum_value_name, elem); + specification.generate_enum_member(content_buffer, uenum, to_system(enum_value_name), elem); } specification.generate_enum_end(content_buffer, uenum); - content_buffer.append(STR("\n\n")); + content_buffer.append(SYSSTR("\n\n")); generated_file.ordered_secondary_file_contents.push_back(content_buffer); } - auto generate_package(UObject* package, File::StringType& out) -> void + auto generate_package(UObject* package, SystemStringType& out) -> void { UObjectGlobals::ForEachUObject([&](void* object, [[maybe_unused]] int32_t chunk_index, [[maybe_unused]] int32_t object_index) { return LoopAction::Continue; @@ -538,10 +538,10 @@ namespace RC::UEGenerator else { // Get rid of everything before the last slash + the last slash, leaving only the actual name - File::StringType package_name = package->GetNamePrivate().ToString(); - package_name = package_name.substr(package_name.rfind(STR("/")) + 1); - File::StringType package_name_all_lower = package_name; - std::transform(package_name_all_lower.begin(), package_name_all_lower.end(), package_name_all_lower.begin(), [](File::CharType c) { + SystemStringType package_name = to_system(package->GetNamePrivate().ToString()); + package_name = package_name.substr(package_name.rfind(SYSSTR("/")) + 1); + SystemStringType package_name_all_lower = package_name; + std::transform(package_name_all_lower.begin(), package_name_all_lower.end(), package_name_all_lower.begin(), [](SystemCharType c) { return std::towlower(c); }); @@ -549,25 +549,29 @@ namespace RC::UEGenerator { // File name collision auto& file_name = m_file_names[package_name_all_lower]; - package_name.append(std::format(STR("_DUPL_{}"), ++file_name.num_collisions)); - Output::send(STR("File name collision, renamed to '{}'\n"), package_name); + package_name.append(std::format(SYSSTR("_DUPL_{}"), ++file_name.num_collisions)); + Output::send(SYSSTR("File name collision, renamed to '{}'\n"), package_name); } else { m_file_names.emplace(package_name_all_lower, FileName{}); } - // The '\\?\' at the beginning of the string unlocks path size restriction from MAX_PATH to 32k +// The '\\?\' at the beginning of the string unlocks path size restriction from MAX_PATH to 32k +#ifdef WIN32 std::filesystem::path directory_to_generate_in = std::filesystem::path("\\\\?\\"); directory_to_generate_in += (m_directory_to_generate_in); +#else + std::filesystem::path directory_to_generate_in = (m_directory_to_generate_in); +#endif - File::StringType ext = specification.get_file_extension(); + SystemStringType ext = specification.get_file_extension(); std::filesystem::path primary_file_path_and_name = directory_to_generate_in; primary_file_path_and_name.append(package_name); primary_file_path_and_name.replace_extension(ext); std::filesystem::path secondary_file_path_and_name = directory_to_generate_in; - secondary_file_path_and_name.append(package_name + STR("_enums")); + secondary_file_path_and_name.append(package_name + SYSSTR("_enums")); secondary_file_path_and_name.replace_extension(ext); GeneratedFile generated_file{ @@ -612,9 +616,9 @@ namespace RC::UEGenerator public: auto generate() -> void { - Output::send(STR("Cleaning up old SDK files...\n")); + Output::send(SYSSTR("Cleaning up old SDK files...\n")); cleanup_old_sdk(); - Output::send(STR("Generating SDK...\n")); + Output::send(SYSSTR("Generating SDK...\n")); // 400k should be enough for most games, and it's highly unlikely to cause more than one reallocation even if the game is huge m_classes_dumped.reserve(400000); @@ -643,7 +647,7 @@ namespace RC::UEGenerator { // Generate a class for this object auto& object_info = m_classes_dumped.emplace(object, ObjectInfo{object}).first->second; - File::StringType class_content{}; + SystemStringType class_content{}; generate_class(object_info, *package_file, class_content); if (!package_file->primary_file_has_no_contents) { @@ -667,66 +671,67 @@ namespace RC::UEGenerator class CXXHeaderGenerator { public: - auto get_file_extension() -> File::StringType + auto get_file_extension() -> SystemStringType { - return STR(".hpp"); + return SYSSTR(".hpp"); } auto generate_file_header(GeneratedFile& generated_file) -> void { - generated_file.primary_file.write_string_to_file( - std::format(STR("#ifndef UE4SS_SDK_{}_HPP\n#define UE4SS_SDK_{}_HPP\n\n"), generated_file.package_name, generated_file.package_name)); + generated_file.primary_file.write_file_string_to_file(to_file( + std::format(SYSSTR("#ifndef UE4SS_SDK_{}_HPP\n#define UE4SS_SDK_{}_HPP\n\n"), generated_file.package_name, generated_file.package_name))); if (!generated_file.secondary_file_has_no_contents) { - generated_file.primary_file.write_string_to_file(std::format(STR("#include \"{}\"\n\n"), generated_file.secondary_file_name.filename().c_str())); + generated_file.primary_file.write_file_string_to_file( + to_file(std::format(SYSSTR("#include \"{}\"\n\n"), generated_file.secondary_file_name.filename().c_str()))); } } auto generate_file_footer(GeneratedFile& generated_file) -> void { - generated_file.primary_file.write_string_to_file(std::format(STR("#endif\n"))); + generated_file.primary_file.write_file_string_to_file(IOSTR("#endif\n")); } - auto generate_enum_declaration(File::StringType& content_buffer, UEnum* uenum) -> void + auto generate_enum_declaration(SystemStringType& content_buffer, UEnum* uenum) -> void { const auto cpp_form = uenum->GetCppForm(); if (cpp_form == UEnum::ECppForm::Regular) { - content_buffer.append(std::format(STR("enum {} {{\n"), get_native_enum_name(uenum, false))); + content_buffer.append(std::format(SYSSTR("enum {} {{\n"), get_native_enum_name(uenum, false))); } else if (cpp_form == UEnum::ECppForm::Namespaced) { - content_buffer.append(std::format(STR("namespace {} {{\n{}enum Type {{\n"), get_native_enum_name(uenum, false), generate_tab())); + content_buffer.append(std::format(SYSSTR("namespace {} {{\n{}enum Type {{\n"), get_native_enum_name(uenum, false), generate_tab())); } else if (cpp_form == UEnum::ECppForm::EnumClass) { - content_buffer.append(std::format(STR("enum class {} {{\n"), get_native_enum_name(uenum, false))); + content_buffer.append(std::format(SYSSTR("enum class {} {{\n"), get_native_enum_name(uenum, false))); } } - auto generate_enum_member(File::StringType& content_buffer, UEnum* uenum, const File::StringType& enum_value_name, const Unreal::FEnumNamePair& elem) -> void + auto generate_enum_member(SystemStringType& content_buffer, UEnum* uenum, const SystemStringType& enum_value_name, const Unreal::FEnumNamePair& elem) -> void { - content_buffer.append(std::format(STR("{}{}{} = {},\n"), + content_buffer.append(std::format(SYSSTR("{}{}{} = {},\n"), generate_tab(), - uenum->GetCppForm() == UEnum::ECppForm::Namespaced ? generate_tab() : STR(""), + uenum->GetCppForm() == UEnum::ECppForm::Namespaced ? generate_tab() : SYSSTR(""), enum_value_name, elem.Value)); } - auto generate_enum_end(File::StringType& content_buffer, UEnum* uenum) -> void + auto generate_enum_end(SystemStringType& content_buffer, UEnum* uenum) -> void { const auto cpp_form = uenum->GetCppForm(); - content_buffer.append(std::format(STR("{}}};"), cpp_form == UEnum::ECppForm::Namespaced ? generate_tab() : STR(""))); + content_buffer.append(std::format(SYSSTR("{}}};"), cpp_form == UEnum::ECppForm::Namespaced ? generate_tab() : SYSSTR(""))); if (cpp_form == UEnum::ECppForm::Namespaced) { - content_buffer.append(STR("\n}")); + content_buffer.append(SYSSTR("\n}")); } } auto should_generate_class(UStruct* native_class) { return true; } - auto generate_class(TypeGenerator* generator, ObjectInfo& object_info, GeneratedFile& generated_file, File::StringType& current_class_content) + auto generate_class(TypeGenerator* generator, ObjectInfo& object_info, GeneratedFile& generated_file, SystemStringType& current_class_content) { UStruct* native_class = static_cast(object_info.object); - File::StringType content_buffer{}; + SystemStringType content_buffer{}; UStruct* inherits_from_class = native_class->GetSuperStruct(); @@ -772,22 +777,24 @@ namespace RC::UEGenerator int32_t current_property_offset = property->GetOffset_Internal(); int32_t current_property_size = property->GetSize(); - StringType part_one{}; + SystemStringType part_one{}; try { - part_one = std::format(STR("{}{}{} {};"), + part_one = std::format(SYSSTR("{}{}{} {};"), generate_tab(), - property_info.should_forward_declare ? STR("class ") : STR(""), + property_info.should_forward_declare ? SYSSTR("class ") : SYSSTR(""), generate_property_cxx_name(property, true, native_class, EnableForwardDeclarations::Yes), - property->GetName()); + to_system(property->GetName())); } catch (std::exception& e) { - Output::send(STR("Could not generate property '{}' because: {}\n"), property->GetFullName(), to_wstring(e.what())); + Output::send(SYSSTR("Could not generate property '{}' because: {}\n"), + to_system(property->GetFullName()), + to_system(e.what())); continue; } - content_buffer.append(std::format(STR("{}\n"), generator->generate_offset_comment(property, part_one))); + content_buffer.append(std::format(SYSSTR("{}\n"), generator->generate_offset_comment(property, part_one))); if (property->IsA()) { @@ -839,12 +846,12 @@ namespace RC::UEGenerator int32_t padding_property_offset = current_property_end_location; int32_t padding_property_size = next_property_offset - padding_property_offset; - auto padding_part_one = std::format(STR("{}char {}[0x{:X}];"), + auto padding_part_one = std::format(SYSSTR("{}char {}[0x{:X}];"), generate_tab(), - std::format(STR("padding_{}"), num_padding_elements++), + std::format(SYSSTR("padding_{}"), num_padding_elements++), padding_property_size); content_buffer.append( - std::format(STR("{:85} // 0x{:04X} (size: 0x{:X})\n"), padding_part_one, padding_property_offset, padding_property_size)); + std::format(SYSSTR("{:85} // 0x{:04X} (size: 0x{:X})\n"), padding_part_one, padding_property_offset, padding_property_size)); } } } @@ -858,7 +865,7 @@ namespace RC::UEGenerator // Functions if (native_class->HasChildren()) { - content_buffer.append(STR("\n")); + content_buffer.append(SYSSTR("\n")); for (const auto& function_info : functions_to_generate) { generator->generate_function_declaration(object_info, function_info, generated_file, content_buffer); @@ -867,26 +874,26 @@ namespace RC::UEGenerator generate_class_end(content_buffer, class_size); - content_buffer.append(STR("\n\n")); + content_buffer.append(SYSSTR("\n\n")); current_class_content.append(content_buffer); } - auto generate_class_declaration(File::StringType& content_buffer, UStruct* native_class, UStruct* inherits_from_class) -> void + auto generate_class_declaration(SystemStringType& content_buffer, UStruct* native_class, UStruct* inherits_from_class) -> void { auto class_name = generate_class_name(native_class); if (inherits_from_class) { content_buffer.append( - std::format(STR("{} {} : public {}\n{{\n"), generate_prefix(native_class), class_name, generate_class_name(inherits_from_class))); + std::format(SYSSTR("{} {} : public {}\n{{\n"), generate_prefix(native_class), class_name, generate_class_name(inherits_from_class))); } else { - content_buffer.append(std::format(STR("{} {}\n{{\n"), generate_prefix(native_class), class_name)); + content_buffer.append(std::format(SYSSTR("{} {}\n{{\n"), generate_prefix(native_class), class_name)); } } - auto generate_class_struct_end(File::StringType& content_buffer, - const File::StringType& class_name, + auto generate_class_struct_end(SystemStringType& content_buffer, + const SystemStringType& class_name, size_t class_size, int32_t num_padding_elements, XProperty* last_property_in_this_class) -> void @@ -912,8 +919,9 @@ namespace RC::UEGenerator printf_s("last_property_offset: %X\n", last_property_offset); printf_s("first_property_offset: %X\n", first_property_offset); - auto padding_part_one = std::format(STR("{}char {}[0x{:X}];"), generate_tab(), std::format(STR("padding_{}"), num_padding_elements), padding_size); - out.append(std::format(STR("{:85} // 0x{:04X} (size: 0x{:X})\n"), padding_part_one, last_property_offset + last_property_size, padding_size)); + auto padding_part_one = std::format(SYSSTR("{}char {}[0x{:X}];"), generate_tab(), std::format(SYSSTR("padding_{}"), + num_padding_elements), padding_size); out.append(std::format(SYSSTR("{:85} // 0x{:04X} (size: 0x{:X})\n"), padding_part_one, + last_property_offset + last_property_size, padding_size)); } } //*/ @@ -923,32 +931,32 @@ namespace RC::UEGenerator // No reflected member variables exist but there are non-reflected member variables // Add padding for non-reflected member variables, for alignment purposes auto padding_part_one = - std::format(STR("{}char {}[0x{:X}];"), generate_tab(), std::format(STR("padding_{}"), num_padding_elements), class_size); - content_buffer.append(std::format(STR("{:85} // 0x0000 (size: 0x{:X})\n"), padding_part_one, 0x0)); + std::format(SYSSTR("{}char {}[0x{:X}];"), generate_tab(), std::format(SYSSTR("padding_{}"), num_padding_elements), class_size); + content_buffer.append(std::format(SYSSTR("{:85} // 0x0000 (size: 0x{:X})\n"), padding_part_one, 0x0)); } } } - auto generate_class_end(File::StringType& content_buffer, size_t class_size) -> void + auto generate_class_end(SystemStringType& content_buffer, size_t class_size) -> void { if (UE4SSProgram::settings_manager.CXXHeaderGenerator.DumpOffsetsAndSizes) { - content_buffer.append(std::format(STR("}}; // Size: 0x{:X}"), class_size)); + content_buffer.append(std::format(SYSSTR("}}; // Size: 0x{:X}"), class_size)); } else { - content_buffer.append(STR("};")); + content_buffer.append(SYSSTR("};")); } } auto generate_function_declaration(TypeGenerator* generator, - File::StringType& current_class_content, + SystemStringType& current_class_content, ObjectInfo& owner, const FunctionInfo& function_info, - File::StringType function_name, + SystemStringType function_name, XProperty* return_property, std::optional return_property_info) -> void { - File::StringType function_type_name{}; + SystemStringType function_type_name{}; if (return_property) { try @@ -957,23 +965,23 @@ namespace RC::UEGenerator } catch (std::exception& e) { - Output::send(STR("Could not generate function '{}' because: {}\n"), - function_info.function->GetFullName(), - to_wstring(e.what())); + Output::send(SYSSTR("Could not generate function '{}' because: {}\n"), + to_system(function_info.function->GetFullName()), + to_system(e.what())); return; } if (return_property_info.value().should_forward_declare && !generator->check_ignore_forward_declaration(owner, return_property)) { - function_type_name.insert(0, STR("class ")); + function_type_name.insert(0, SYSSTR("class ")); } } else { - function_type_name = STR("void"); + function_type_name = SYSSTR("void"); } - current_class_content.append(std::format(STR("{}{} {}("), generate_tab(), function_type_name, function_name)); + current_class_content.append(std::format(SYSSTR("{}{} {}("), generate_tab(), function_type_name, function_name)); for (size_t i = 0; i < function_info.params.size(); ++i) { @@ -983,18 +991,18 @@ namespace RC::UEGenerator try { current_class_content.append( - std::format(STR("{}{}{}{} {}"), - param_info.property->HasAnyPropertyFlags(Unreal::CPF_ConstParm) ? STR("const ") : STR(""), - param_info.should_forward_declare ? STR("class ") : STR(""), + std::format(SYSSTR("{}{}{}{} {}"), + param_info.property->HasAnyPropertyFlags(Unreal::CPF_ConstParm) ? SYSSTR("const ") : SYSSTR(""), + param_info.should_forward_declare ? SYSSTR("class ") : SYSSTR(""), generate_property_cxx_name(param_info.property, true, function_info.function, EnableForwardDeclarations::Yes), - param_info.property->HasAnyPropertyFlags(Unreal::CPF_ReferenceParm | Unreal::CPF_OutParm) ? STR("&") : STR(""), - param_info.property->GetName())); + param_info.property->HasAnyPropertyFlags(Unreal::CPF_ReferenceParm | Unreal::CPF_OutParm) ? SYSSTR("&") : SYSSTR(""), + to_system(param_info.property->GetName()))); } catch (std::exception& e) { - Output::send(STR("Could not generate function '{}' because: {}\n"), - function_info.function->GetFullName(), - to_wstring(e.what())); + Output::send(SYSSTR("Could not generate function '{}' because: {}\n"), + to_system(function_info.function->GetFullName()), + to_system(e.what())); return; } @@ -1003,24 +1011,25 @@ namespace RC::UEGenerator auto* next_param = function_info.params[i + 1].property; if (next_param && (!next_param->HasAnyPropertyFlags(Unreal::CPF_ReturnParm) || i + 2 < function_info.params.size())) { - current_class_content.append(STR(", ")); + current_class_content.append(SYSSTR(", ")); } } } } - current_class_content.append(STR(");")); + current_class_content.append(SYSSTR(");")); } }; class LuaTypesGenerator { private: - auto is_valid_lua_symbol(const File::StringType& str) -> bool + auto is_valid_lua_symbol(const SystemStringType& str) -> bool { - static const std::set keywords = {STR("and"), STR("break"), STR("do"), STR("else"), STR("elseif"), STR("end"), - STR("false"), STR("for"), STR("function"), STR("if"), STR("in"), STR("local"), - STR("nil"), STR("not"), STR("or"), STR("repeat"), STR("return"), STR("then"), - STR("true"), STR("until"), STR("while")}; + static const std::set keywords = {SYSSTR("and"), SYSSTR("break"), SYSSTR("do"), SYSSTR("else"), SYSSTR("elseif"), + SYSSTR("end"), SYSSTR("false"), SYSSTR("for"), SYSSTR("function"), SYSSTR("if"), + SYSSTR("in"), SYSSTR("local"), SYSSTR("nil"), SYSSTR("not"), SYSSTR("or"), + SYSSTR("repeat"), SYSSTR("return"), SYSSTR("then"), SYSSTR("true"), SYSSTR("until"), + SYSSTR("while")}; if (keywords.contains(str)) { return false; @@ -1042,9 +1051,9 @@ namespace RC::UEGenerator } return true; } - auto quote_lua_symbol(const File::StringType& symbol) -> File::StringType + auto quote_lua_symbol(const SystemStringType& symbol) -> SystemStringType { - File::StringType quoted; + SystemStringType quoted; quoted.reserve(symbol.size() + 2); quoted.push_back('\''); for (auto it = symbol.begin(); it != symbol.end(); ++it) @@ -1059,9 +1068,9 @@ namespace RC::UEGenerator quoted.push_back('\''); return quoted; } - auto make_valid_symbol(const File::StringType& symbol) -> File::StringType + auto make_valid_symbol(const SystemStringType& symbol) -> SystemStringType { - File::StringType valid; + SystemStringType valid; valid.reserve(symbol.size()); auto it = symbol.begin(); if (it == symbol.end() || std::isdigit(*it)) @@ -1077,29 +1086,29 @@ namespace RC::UEGenerator } public: - auto get_file_extension() -> File::StringType + auto get_file_extension() -> SystemStringType { - return STR(".lua"); + return SYSSTR(".lua"); } auto generate_file_header(GeneratedFile& generated_file) -> void { - generated_file.primary_file.write_string_to_file(STR("---@meta\n\n")); + generated_file.primary_file.write_file_string_to_file(IOSTR("---@meta\n\n")); } auto generate_file_footer(GeneratedFile& generated_file) -> void { } - auto generate_enum_declaration(File::StringType& content_buffer, UEnum* uenum) -> void + auto generate_enum_declaration(SystemStringType& content_buffer, UEnum* uenum) -> void { - auto enum_name = uenum->GetName(); - content_buffer.append(std::format(STR("---@enum {}\n{} = {{\n"), enum_name, enum_name)); + auto enum_name = to_system(uenum->GetName()); + content_buffer.append(std::format(SYSSTR("---@enum {}\n{} = {{\n"), enum_name, enum_name)); } - auto generate_enum_member(File::StringType& content_buffer, UEnum* uenum, const File::StringType& enum_value_name, const Unreal::FEnumNamePair& elem) -> void + auto generate_enum_member(SystemStringType& content_buffer, UEnum* uenum, const SystemStringType& enum_value_name, const Unreal::FEnumNamePair& elem) -> void { - content_buffer.append(std::format(STR("{}{} = {},\n"), generate_tab(), enum_value_name, elem.Value)); + content_buffer.append(std::format(SYSSTR("{}{} = {},\n"), generate_tab(), enum_value_name, elem.Value)); } - auto generate_enum_end(File::StringType& content_buffer, UEnum* uenum) -> void + auto generate_enum_end(SystemStringType& content_buffer, UEnum* uenum) -> void { - content_buffer.append(STR("}")); + content_buffer.append(SYSSTR("}")); } auto should_generate_class(UStruct* native_class) @@ -1107,10 +1116,10 @@ namespace RC::UEGenerator // skip UObject to define externally return native_class != UObject::StaticClass(); } - auto generate_class(TypeGenerator* generator, ObjectInfo& object_info, GeneratedFile& generated_file, File::StringType& current_class_content) + auto generate_class(TypeGenerator* generator, ObjectInfo& object_info, GeneratedFile& generated_file, SystemStringType& current_class_content) { UStruct* native_class = static_cast(object_info.object); - File::StringType content_buffer{}; + SystemStringType content_buffer{}; UStruct* inherits_from_class = native_class->GetSuperStruct(); @@ -1158,20 +1167,23 @@ namespace RC::UEGenerator try { - const auto& property_name = property->GetName(); + const auto& property_name = to_system(property->GetName()); if (is_valid_lua_symbol(property_name)) { - content_buffer.append(std::format(STR("---@field {} {}\n"), property_name, generate_property_lua_name(property, true, native_class))); + content_buffer.append(std::format(SYSSTR("---@field {} {}\n"), property_name, generate_property_lua_name(property, true, native_class))); } else { - content_buffer.append( - std::format(STR("---@field [{}] {}\n"), quote_lua_symbol(property_name), generate_property_lua_name(property, true, native_class))); + content_buffer.append(std::format(SYSSTR("---@field [{}] {}\n"), + quote_lua_symbol(property_name), + generate_property_lua_name(property, true, native_class))); } } catch (std::exception& e) { - Output::send(STR("Could not generate property '{}' because: {}\n"), property->GetFullName(), to_wstring(e.what())); + Output::send(SYSSTR("Could not generate property '{}' because: {}\n"), + to_system(property->GetFullName()), + to_system(e.what())); continue; } @@ -1186,7 +1198,7 @@ namespace RC::UEGenerator // Functions if (native_class->HasChildren()) { - content_buffer.append(STR("\n")); + content_buffer.append(SYSSTR("\n")); for (const auto& function_info : functions_to_generate) { generator->generate_function_declaration(object_info, function_info, generated_file, content_buffer); @@ -1195,39 +1207,39 @@ namespace RC::UEGenerator generate_class_end(content_buffer, class_size); - content_buffer.append(STR("\n\n")); + content_buffer.append(SYSSTR("\n\n")); current_class_content.append(content_buffer); } - auto generate_class_declaration(File::StringType& content_buffer, UStruct* native_class, UStruct* inherits_from_class) -> void + auto generate_class_declaration(SystemStringType& content_buffer, UStruct* native_class, UStruct* inherits_from_class) -> void { auto class_name = generate_class_name(native_class); if (inherits_from_class) { - content_buffer.append(std::format(STR("---@class {} : {}\n"), class_name, generate_class_name(inherits_from_class))); + content_buffer.append(std::format(SYSSTR("---@class {} : {}\n"), class_name, generate_class_name(inherits_from_class))); } else { - content_buffer.append(std::format(STR("---@class {}\n"), class_name)); + content_buffer.append(std::format(SYSSTR("---@class {}\n"), class_name)); } } - auto generate_class_struct_end(File::StringType& content_buffer, - const File::StringType& class_name, + auto generate_class_struct_end(SystemStringType& content_buffer, + const SystemStringType& class_name, size_t class_size, int32_t num_padding_elements, XProperty* last_property_in_this_class) -> void { - content_buffer.append(std::format(STR("{} = {{}}\n"), class_name)); + content_buffer.append(std::format(SYSSTR("{} = {{}}\n"), class_name)); } - auto generate_class_end(File::StringType& content_buffer, size_t class_size) -> void + auto generate_class_end(SystemStringType& content_buffer, size_t class_size) -> void { } auto generate_function_declaration(TypeGenerator* generator, - File::StringType& current_class_content, + SystemStringType& current_class_content, ObjectInfo& owner, const FunctionInfo& function_info, - File::StringType function_name, + SystemStringType function_name, XProperty* return_property, std::optional return_property_info) -> void { @@ -1238,17 +1250,17 @@ namespace RC::UEGenerator { try { - auto param_name = param_info.property->GetName(); + auto param_name = to_system(param_info.property->GetName()); // TODO disambiguate param renames - current_class_content.append(std::format(STR("---@param {} {}\n"), + current_class_content.append(std::format(SYSSTR("---@param {} {}\n"), make_valid_symbol(param_name), generate_property_lua_name(param_info.property, true, function_info.function))); } catch (std::exception& e) { - Output::send(STR("Could not generate function '{}' because: {}\n"), - function_info.function->GetFullName(), - to_wstring(e.what())); + Output::send(SYSSTR("Could not generate function '{}' because: {}\n"), + to_system(function_info.function->GetFullName()), + to_system(e.what())); return; } } @@ -1258,13 +1270,13 @@ namespace RC::UEGenerator { try { - current_class_content.append(std::format(STR("---@return {}\n"), generate_property_lua_name(return_property, true, function_info.function))); + current_class_content.append(std::format(SYSSTR("---@return {}\n"), generate_property_lua_name(return_property, true, function_info.function))); } catch (std::exception& e) { - Output::send(STR("Could not generate function '{}' because: {}\n"), - function_info.function->GetFullName(), - to_wstring(e.what())); + Output::send(SYSSTR("Could not generate function '{}' because: {}\n"), + to_system(function_info.function->GetFullName()), + to_system(e.what())); return; } } @@ -1273,11 +1285,11 @@ namespace RC::UEGenerator if (is_valid_lua_symbol(function_name)) { - current_class_content.append(std::format(STR("function {}:{}("), class_name, function_name)); + current_class_content.append(std::format(SYSSTR("function {}:{}("), class_name, function_name)); } else { - current_class_content.append(std::format(STR("{}[{}] = function("), class_name, quote_lua_symbol(function_name))); + current_class_content.append(std::format(SYSSTR("{}[{}] = function("), class_name, quote_lua_symbol(function_name))); } for (size_t i = 0; i < function_info.params.size(); ++i) @@ -1285,21 +1297,21 @@ namespace RC::UEGenerator const auto& param_info = function_info.params[i]; if (!param_info.property->HasAnyPropertyFlags(Unreal::CPF_ReturnParm)) { - auto param_name = param_info.property->GetName(); + auto param_name = to_system(param_info.property->GetName()); // TODO disambiguate param renames - current_class_content.append(std::format(STR("{}"), make_valid_symbol(param_name))); + current_class_content.append(std::format(SYSSTR("{}"), make_valid_symbol(param_name))); if (i + 1 < function_info.params.size()) { auto* next_param = function_info.params[i + 1].property; if (next_param && (!next_param->HasAnyPropertyFlags(Unreal::CPF_ReturnParm) || i + 2 < function_info.params.size())) { - current_class_content.append(STR(", ")); + current_class_content.append(SYSSTR(", ")); } } } } - current_class_content.append(STR(") end")); + current_class_content.append(SYSSTR(") end")); } }; diff --git a/UE4SS/src/SDKGenerator/JSONDumper.cpp b/UE4SS/src/SDKGenerator/JSONDumper.cpp index a8163d063..0b98a75e0 100644 --- a/UE4SS/src/SDKGenerator/JSONDumper.cpp +++ b/UE4SS/src/SDKGenerator/JSONDumper.cpp @@ -15,7 +15,7 @@ namespace RC::UEGenerator::JSONDumper { using namespace ::RC::Unreal; - auto static is_valid_class_to_dump(File::StringViewType class_name, UObject* object) -> bool + auto static is_valid_class_to_dump(SystemStringViewType class_name, UObject* object) -> bool { static bool is_below_425 = Unreal::Version::IsBelow(4, 25); if (is_below_425 && Unreal::TypeChecker::is_property(object)) @@ -41,31 +41,31 @@ namespace RC::UEGenerator::JSONDumper return false; } - if (class_name.find(STR("BP_")) != class_name.npos) + if (class_name.find(SYSSTR("BP_")) != class_name.npos) { return true; } - if (class_name.find(STR("ENE_")) != class_name.npos) + if (class_name.find(SYSSTR("ENE_")) != class_name.npos) { return true; } - if (class_name.find(STR("BPL_")) != class_name.npos) + if (class_name.find(SYSSTR("BPL_")) != class_name.npos) { return true; } - if (class_name.find(STR("OBJ_")) != class_name.npos) + if (class_name.find(SYSSTR("OBJ_")) != class_name.npos) { return true; } - if (class_name.find(STR("LIB_")) != class_name.npos) + if (class_name.find(SYSSTR("LIB_")) != class_name.npos) { return true; } - if (class_name.find(STR("PRJ_")) != class_name.npos) + if (class_name.find(SYSSTR("PRJ_")) != class_name.npos) { return true; } - if (class_name.find(STR("WPN_")) != class_name.npos) + if (class_name.find(SYSSTR("WPN_")) != class_name.npos) { return true; } @@ -177,21 +177,21 @@ namespace RC::UEGenerator::JSONDumper return should_skip_general_function(function); } - auto static should_skip_event(File::StringViewType event_name) -> bool + auto static should_skip_event(SystemStringViewType event_name) -> bool { - if (event_name.find(STR("BndEvt")) != event_name.npos) + if (event_name.find(SYSSTR("BndEvt")) != event_name.npos) { return true; } return false; } - auto dump_to_json(File::StringViewType file_name) -> void + auto dump_to_json(SystemStringViewType file_name) -> void { - Output::send(STR("Loading all assets...\n")); + Output::send(SYSSTR("Loading all assets...\n")); UAssetRegistry::LoadAllAssets(); - Output::send(STR("Dumping to JSON file\n")); + Output::send(SYSSTR("Dumping to JSON file\n")); auto json = JSON::Array{}; UObjectGlobals::ForEachUObject([&](void* raw_object, int32_t chunk_index, int32_t object_index) { @@ -201,7 +201,7 @@ namespace RC::UEGenerator::JSONDumper } UObject* object = static_cast(raw_object); - auto object_name = object->GetName(); + auto object_name = to_system(object->GetName()); if (!is_valid_class_to_dump(object_name, object)) { return LoopAction::Continue; @@ -211,17 +211,17 @@ namespace RC::UEGenerator::JSONDumper object_name.erase(object_name.size() - 2, 2); auto& bp_class = json.new_object(); - bp_class.new_string(STR("bp_class"), object_name); + bp_class.new_string(SYSSTR("bp_class"), object_name); if (auto* super_struct = object_as_class->GetSuperStruct(); super_struct) { - bp_class.new_string(STR("inherits"), super_struct->GetName()); + bp_class.new_string(SYSSTR("inherits"), to_system(super_struct->GetName())); } else { - bp_class.new_null(STR("inherits")); + bp_class.new_null(SYSSTR("inherits")); } - auto& events = bp_class.new_array(STR("events")); + auto& events = bp_class.new_array(SYSSTR("events")); for (UFunction* event_function : object_as_class->ForEachFunction()) { if (should_skip_general_function(event_function)) @@ -233,16 +233,16 @@ namespace RC::UEGenerator::JSONDumper continue; } - auto event_name = event_function->GetName(); + auto event_name = to_system(event_function->GetName()); if (should_skip_event(event_name)) { continue; } auto& bp_events = events.new_object(); - bp_events.new_string(STR("name"), event_name); + bp_events.new_string(SYSSTR("name"), event_name); - auto& bp_event_args = bp_events.new_array(STR("args")); + auto& bp_event_args = bp_events.new_array(SYSSTR("args")); for (FProperty* param : event_function->ForEachProperty()) { if (should_skip_property(param)) @@ -251,15 +251,15 @@ namespace RC::UEGenerator::JSONDumper } auto& bp_event_arg = bp_event_args.new_object(); - bp_event_arg.new_string(STR("name"), param->GetName()); - bp_event_arg.new_string(STR("type"), generate_property_cxx_name(param, true, event_function)); + bp_event_arg.new_string(SYSSTR("name"), to_system(param->GetName())); + bp_event_arg.new_string(SYSSTR("type"), generate_property_cxx_name(param, true, event_function)); bool is_out = param->HasAnyPropertyFlags(EPropertyFlags::CPF_OutParm) && !param->HasAnyPropertyFlags(EPropertyFlags::CPF_ConstParm); - bp_event_arg.new_bool(STR("is_out"), is_out); - bp_event_arg.new_bool(STR("is_return"), param->HasAnyPropertyFlags(Unreal::EPropertyFlags::CPF_ReturnParm)); + bp_event_arg.new_bool(SYSSTR("is_out"), is_out); + bp_event_arg.new_bool(SYSSTR("is_return"), param->HasAnyPropertyFlags(Unreal::EPropertyFlags::CPF_ReturnParm)); } } - auto& functions = bp_class.new_array(STR("functions")); + auto& functions = bp_class.new_array(SYSSTR("functions")); for (UFunction* function : object_as_class->ForEachFunction()) { if (should_skip_function(function)) @@ -268,9 +268,9 @@ namespace RC::UEGenerator::JSONDumper } auto& bp_function = functions.new_object(); - bp_function.new_string(STR("name"), function->GetName()); + bp_function.new_string(SYSSTR("name"), to_system(function->GetName())); - auto& bp_function_args = bp_function.new_array(STR("args")); + auto& bp_function_args = bp_function.new_array(SYSSTR("args")); for (FProperty* param : function->ForEachProperty()) { if (should_skip_property(param)) @@ -279,15 +279,15 @@ namespace RC::UEGenerator::JSONDumper } auto& bp_function_arg = bp_function_args.new_object(); - bp_function_arg.new_string(STR("name"), param->GetName()); - bp_function_arg.new_string(STR("type"), generate_property_cxx_name(param, true, function)); + bp_function_arg.new_string(SYSSTR("name"), to_system(param->GetName())); + bp_function_arg.new_string(SYSSTR("type"), generate_property_cxx_name(param, true, function)); bool is_out = param->HasAnyPropertyFlags(EPropertyFlags::CPF_OutParm) && !param->HasAnyPropertyFlags(EPropertyFlags::CPF_ConstParm); - bp_function_arg.new_bool(STR("is_out"), is_out); - bp_function_arg.new_bool(STR("is_return"), param->HasAnyPropertyFlags(Unreal::EPropertyFlags::CPF_ReturnParm)); + bp_function_arg.new_bool(SYSSTR("is_out"), is_out); + bp_function_arg.new_bool(SYSSTR("is_return"), param->HasAnyPropertyFlags(Unreal::EPropertyFlags::CPF_ReturnParm)); } } - auto& properties = bp_class.new_array(STR("properties")); + auto& properties = bp_class.new_array(SYSSTR("properties")); for (FProperty* property : object_as_class->ForEachProperty()) { if (should_skip_property(property)) @@ -296,11 +296,11 @@ namespace RC::UEGenerator::JSONDumper } auto& bp_property = properties.new_object(); - bp_property.new_string(STR("name"), property->GetName()); - bp_property.new_string(STR("type"), generate_property_cxx_name(property, true, object_as_class)); + bp_property.new_string(SYSSTR("name"), to_system(property->GetName())); + bp_property.new_string(SYSSTR("type"), generate_property_cxx_name(property, true, object_as_class)); } - auto& delegates = bp_class.new_array(STR("delegates")); + auto& delegates = bp_class.new_array(SYSSTR("delegates")); for (UFunction* delegate_function : object_as_class->ForEachFunction()) { if (should_skip_general_function(delegate_function)) @@ -313,9 +313,9 @@ namespace RC::UEGenerator::JSONDumper } auto& bp_delegate = delegates.new_object(); - bp_delegate.new_string(STR("name"), delegate_function->GetName()); + bp_delegate.new_string(SYSSTR("name"), to_system(delegate_function->GetName())); - auto& bp_delegate_args = bp_delegate.new_array(STR("args")); + auto& bp_delegate_args = bp_delegate.new_array(SYSSTR("args")); for (FProperty* param : delegate_function->ForEachProperty()) { if (should_skip_property(param)) @@ -324,11 +324,11 @@ namespace RC::UEGenerator::JSONDumper } auto& bp_delegate_arg = bp_delegate_args.new_object(); - bp_delegate_arg.new_string(STR("name"), param->GetName()); - bp_delegate_arg.new_string(STR("type"), generate_property_cxx_name(param, true, delegate_function)); + bp_delegate_arg.new_string(SYSSTR("name"), to_system(param->GetName())); + bp_delegate_arg.new_string(SYSSTR("type"), generate_property_cxx_name(param, true, delegate_function)); bool is_out = param->HasAnyPropertyFlags(EPropertyFlags::CPF_OutParm) && !param->HasAnyPropertyFlags(EPropertyFlags::CPF_ConstParm); - bp_delegate_arg.new_bool(STR("is_out"), is_out); - bp_delegate_arg.new_bool(STR("is_return"), param->HasAnyPropertyFlags(Unreal::EPropertyFlags::CPF_ReturnParm)); + bp_delegate_arg.new_bool(SYSSTR("is_out"), is_out); + bp_delegate_arg.new_bool(SYSSTR("is_return"), param->HasAnyPropertyFlags(Unreal::EPropertyFlags::CPF_ReturnParm)); } } @@ -337,10 +337,10 @@ namespace RC::UEGenerator::JSONDumper auto json_file = File::open(file_name, File::OpenFor::Writing, File::OverwriteExistingFile::Yes, File::CreateIfNonExistent::Yes); int32_t indent_level{}; - json_file.write_string_to_file(json.serialize(JSON::ShouldFormat::Yes, &indent_level)); + json_file.write_file_string_to_file(to_file(json.serialize(JSON::ShouldFormat::Yes, &indent_level))); json_file.close(); - Output::send(STR("Unloading all forcefully loaded assets\n")); + Output::send(SYSSTR("Unloading all forcefully loaded assets\n")); UAssetRegistry::FreeAllForcefullyLoadedAssets(); } } // namespace RC::UEGenerator::JSONDumper diff --git a/UE4SS/src/SDKGenerator/TMapOverrideGen.cpp b/UE4SS/src/SDKGenerator/TMapOverrideGen.cpp index 5b9440038..9516d89a0 100644 --- a/UE4SS/src/SDKGenerator/TMapOverrideGen.cpp +++ b/UE4SS/src/SDKGenerator/TMapOverrideGen.cpp @@ -25,7 +25,7 @@ namespace RC::UEGenerator auto TMapOverrideGenerator::generate_tmapoverride() -> void { - Output::send(STR("Dumping TMap Property Overrides\n")); + Output::send(SYSSTR("Dumping TMap Property Overrides\n")); auto fm_object = JSON::Object{}; auto uaapi_object = JSON::Object{}; @@ -53,7 +53,7 @@ namespace RC::UEGenerator MapProperties.insert(property->GetFName()); - auto property_name = property->GetFName().ToString(); + auto property_name = to_system(property->GetFName().ToString()); auto key_as_struct_property = CastField(static_cast(property)->GetKeyProp()); auto key_struct_type = key_as_struct_property ? key_as_struct_property->GetStruct() : nullptr; @@ -67,32 +67,32 @@ namespace RC::UEGenerator { continue; } - Output::send(STR("Found Relevant TMap Property: {} in Class: {}\n"), property_name, object->GetName()); + Output::send(SYSSTR("Found Relevant TMap Property: {} in Class: {}\n"), property_name, object->GetName()); auto& fm_json_object = fm_object.new_object(property_name); auto& uaapi_array = uaapi_object.new_array(property_name); if (is_key_valid) { - auto key_name = key_as_struct_property->GetStruct()->GetName(); - fm_json_object.new_string(STR("Key"), key_name); + auto key_name = to_system(key_as_struct_property->GetStruct()->GetName()); + fm_json_object.new_string(SYSSTR("Key"), key_name); uaapi_array.new_string(key_name); } else { - fm_json_object.new_string(STR("Key"), STR("")); + fm_json_object.new_string(SYSSTR("Key"), SYSSTR("")); uaapi_array.new_null(); } if (is_value_valid) { - auto value_name = value_as_struct_property->GetStruct()->GetName(); - fm_json_object.new_string(STR("Value"), value_name); + auto value_name = to_system(value_as_struct_property->GetStruct()->GetName()); + fm_json_object.new_string(SYSSTR("Value"), value_name); uaapi_array.new_string(value_name); } else { - fm_json_object.new_string(STR("Value"), STR("")); + fm_json_object.new_string(SYSSTR("Value"), SYSSTR("")); uaapi_array.new_null(); } @@ -110,17 +110,17 @@ namespace RC::UEGenerator // Retrieve JSON as a string. int32_t indent_level{}; - auto uaapifile = open(StringType{UE4SSProgram::get_program().get_working_directory()} + STR("\\UAssetAPITMapOverrides.json"), + auto uaapifile = open(std::filesystem::path{UE4SSProgram::get_program().get_working_directory()} / SYSSTR("UAssetAPITMapOverrides.json"), File::OpenFor::Writing, File::OverwriteExistingFile::Yes, File::CreateIfNonExistent::Yes); - auto fmodelfile = open(StringType{UE4SSProgram::get_program().get_working_directory()} + STR("\\FModelTMapOverrides.json"), + auto fmodelfile = open(std::filesystem::path{UE4SSProgram::get_program().get_working_directory()} / SYSSTR("FModelTMapOverrides.json"), File::OpenFor::Writing, File::OverwriteExistingFile::Yes, File::CreateIfNonExistent::Yes); - uaapifile.write_string_to_file(uaapi_object.serialize(JSON::ShouldFormat::Yes, &indent_level)); - fmodelfile.write_string_to_file(fm_object.serialize(JSON::ShouldFormat::Yes, &indent_level)); - Output::send(STR("Finished Dumping {} TMap Properties\n"), num_objects_generated); + uaapifile.write_file_string_to_file(to_file(uaapi_object.serialize(JSON::ShouldFormat::Yes, &indent_level))); + fmodelfile.write_file_string_to_file(to_file(fm_object.serialize(JSON::ShouldFormat::Yes, &indent_level))); + Output::send(SYSSTR("Finished Dumping {} TMap Properties\n"), num_objects_generated); MapProperties.clear(); } } // namespace RC::UEGenerator \ No newline at end of file diff --git a/UE4SS/src/SDKGenerator/UEHeaderGenerator.cpp b/UE4SS/src/SDKGenerator/UEHeaderGenerator.cpp index 4c1cb29b1..1787aa145 100644 --- a/UE4SS/src/SDKGenerator/UEHeaderGenerator.cpp +++ b/UE4SS/src/SDKGenerator/UEHeaderGenerator.cpp @@ -48,13 +48,14 @@ #include #include #include +#include #pragma warning(default : 4005) namespace RC::UEGenerator { using namespace RC::Unreal; - std::map UEHeaderGenerator::m_used_file_names{}; + std::map UEHeaderGenerator::m_used_file_names{}; std::map UEHeaderGenerator::m_dependency_object_to_unique_id{}; auto static is_subtype_struct_valid(UScriptStruct* subtype) -> bool @@ -132,7 +133,7 @@ namespace RC::UEGenerator } } - auto string_to_uppercase(std::wstring s) -> std::wstring + auto string_to_uppercase(SystemStringType s) -> SystemStringType { std::transform(s.begin(), s.end(), s.begin(), [](wchar_t c) { return towupper(c); @@ -142,8 +143,8 @@ namespace RC::UEGenerator class FlagFormatHelper { - std::set m_switches; - std::map> m_parameters; + std::set m_switches; + std::map> m_parameters; std::shared_ptr m_meta_helper; FlagFormatHelper(bool is_root_helper) @@ -159,14 +160,14 @@ namespace RC::UEGenerator { } - auto add_switch(const std::wstring& switch_name) -> void + auto add_switch(const SystemStringType& switch_name) -> void { m_switches.insert(switch_name); } - auto add_parameter(const std::wstring& parameter_name, const std::wstring& parameter_value) -> void + auto add_parameter(const SystemStringType& parameter_name, const SystemStringType& parameter_value) -> void { - if (parameter_name == STR("meta")) + if (parameter_name == SYSSTR("meta")) { throw std::invalid_argument("Use get_meta() to add metadata to the flag declaration"); } @@ -187,54 +188,54 @@ namespace RC::UEGenerator return m_meta_helper.get(); } - auto build_flag_string() const -> std::wstring + auto build_flag_string() const -> SystemStringType { - std::wstring resulting_string; + SystemStringType resulting_string; - for (const std::wstring& switch_name : m_switches) + for (const SystemStringType& switch_name : m_switches) { resulting_string.append(switch_name); - resulting_string.append(STR(", ")); + resulting_string.append(SYSSTR(", ")); } for (const auto& parameter_pair : m_parameters) { resulting_string.append(parameter_pair.first); - resulting_string.append(STR("=")); - const std::set& parameter_values = parameter_pair.second; + resulting_string.append(SYSSTR("=")); + const std::set& parameter_values = parameter_pair.second; if (parameter_values.size() != 1) { - resulting_string.append(STR("(")); + resulting_string.append(SYSSTR("(")); - for (const std::wstring& parameter_value : parameter_values) + for (const SystemStringType& parameter_value : parameter_values) { resulting_string.append(parameter_value); - resulting_string.append(STR(", ")); + resulting_string.append(SYSSTR(", ")); } if (parameter_values.size() != 0) { resulting_string.erase(resulting_string.size() - 1, 1); } - resulting_string.append(STR(")")); + resulting_string.append(SYSSTR(")")); } else { resulting_string.append(*parameter_values.begin()); } - resulting_string.append(STR(", ")); + resulting_string.append(SYSSTR(", ")); } if (m_meta_helper) { - const std::wstring meta_flag_string = m_meta_helper->build_flag_string(); + const SystemStringType meta_flag_string = m_meta_helper->build_flag_string(); if (!meta_flag_string.empty()) { - resulting_string.append(STR("meta=(")); + resulting_string.append(SYSSTR("meta=(")); resulting_string.append(meta_flag_string); - resulting_string.append(STR(")")); - resulting_string.append(STR(", ")); + resulting_string.append(SYSSTR(")")); + resulting_string.append(SYSSTR(", ")); } } @@ -246,69 +247,71 @@ namespace RC::UEGenerator } }; - auto UEHeaderGenerator::generate_module_build_file(const std::wstring& module_name) -> void + auto UEHeaderGenerator::generate_module_build_file(const SystemStringType& module_name) -> void { - const FFilePath module_file_path = m_root_directory / module_name / std::format(STR("{}.Build.cs"), module_name); + auto module_name_sys = to_system(module_name); + const FFilePath module_file_path = m_root_directory / module_name_sys / std::format(SYSSTR("{}.Build.cs"), module_name_sys); GeneratedFile module_build_file = GeneratedFile(module_file_path); - module_build_file.append_line(STR("using UnrealBuildTool;")); - module_build_file.append_line(STR("")); + module_build_file.append_line(SYSSTR("using UnrealBuildTool;")); + module_build_file.append_line(SYSSTR("")); - module_build_file.append_line(std::format(STR("public class {} : ModuleRules {{"), module_name)); + module_build_file.append_line(std::format(SYSSTR("public class {} : ModuleRules {{"), module_name_sys)); module_build_file.begin_indent_level(); - module_build_file.append_line(std::format(STR("public {}(ReadOnlyTargetRules Target) : base(Target) {{"), module_name)); + module_build_file.append_line(std::format(SYSSTR("public {}(ReadOnlyTargetRules Target) : base(Target) {{"), module_name_sys)); module_build_file.begin_indent_level(); - module_build_file.append_line(STR("PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;")); + module_build_file.append_line(SYSSTR("PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;")); if (Version::IsAtLeast(4, 24)) { - module_build_file.append_line(STR("bLegacyPublicIncludePaths = false;")); - module_build_file.append_line(STR("ShadowVariableWarningLevel = WarningLevel.Warning;")); + module_build_file.append_line(SYSSTR("bLegacyPublicIncludePaths = false;")); + module_build_file.append_line(SYSSTR("ShadowVariableWarningLevel = WarningLevel.Warning;")); } - module_build_file.append_line(STR("")); - module_build_file.append_line(STR("PublicDependencyModuleNames.AddRange(new string[] {")); + module_build_file.append_line(SYSSTR("")); + module_build_file.append_line(SYSSTR("PublicDependencyModuleNames.AddRange(new string[] {")); module_build_file.begin_indent_level(); - std::set all_module_dependencies = this->m_forced_module_dependencies; - std::set clean_module_dependencies{}; + std::set all_module_dependencies = this->m_forced_module_dependencies; + std::set clean_module_dependencies{}; add_module_and_sub_module_dependencies(clean_module_dependencies, module_name, false); all_module_dependencies.insert(clean_module_dependencies.begin(), clean_module_dependencies.end()); - for (const std::wstring& other_module_name : all_module_dependencies) + for (const SystemStringType& other_module_name : all_module_dependencies) { - module_build_file.append_line(std::format(STR("\"{}\","), other_module_name)); + module_build_file.append_line(std::format(SYSSTR("\"{}\","), to_system(other_module_name))); } module_build_file.end_indent_level(); - module_build_file.append_line(STR("});")); + module_build_file.append_line(SYSSTR("});")); module_build_file.end_indent_level(); - module_build_file.append_line(STR("}")); + module_build_file.append_line(SYSSTR("}")); module_build_file.end_indent_level(); - module_build_file.append_line(STR("}")); + module_build_file.append_line(SYSSTR("}")); module_build_file.serialize_file_content_to_disk(); } - auto UEHeaderGenerator::generate_module_implementation_file(const std::wstring& module_name) -> void + auto UEHeaderGenerator::generate_module_implementation_file(const SystemStringType& module_name) -> void { - const FFilePath module_file_path = m_root_directory / module_name / STR("Private") / std::format(STR("{}Module.cpp"), module_name); + auto module_name_sys = to_system(module_name); + const FFilePath module_file_path = m_root_directory / module_name_sys / SYSSTR("Private") / std::format(SYSSTR("{}Module.cpp"), module_name_sys); GeneratedFile module_impl_file = GeneratedFile(module_file_path); - module_impl_file.append_line(STR("#include \"Modules/ModuleManager.h\"")); - module_impl_file.append_line(STR("")); + module_impl_file.append_line(SYSSTR("#include \"Modules/ModuleManager.h\"")); + module_impl_file.append_line(SYSSTR("")); if (module_name != m_primary_module_name) { - module_impl_file.append_line(std::format(STR("IMPLEMENT_MODULE(FDefaultGameModuleImpl, {});"), module_name)); + module_impl_file.append_line(std::format(SYSSTR("IMPLEMENT_MODULE(FDefaultGameModuleImpl, {});"), module_name_sys)); } else { - module_impl_file.append_line(std::format(STR("IMPLEMENT_PRIMARY_GAME_MODULE(FDefaultGameModuleImpl, {}, {});"), module_name, module_name)); + module_impl_file.append_line(std::format(SYSSTR("IMPLEMENT_PRIMARY_GAME_MODULE(FDefaultGameModuleImpl, {}, {});"), module_name_sys, module_name_sys)); } module_impl_file.serialize_file_content_to_disk(); @@ -316,40 +319,40 @@ namespace RC::UEGenerator auto UEHeaderGenerator::generate_interface_definition(UClass* uclass, GeneratedSourceFile& header_data) -> void { - const std::wstring interface_class_native_name = get_native_class_name(uclass); - const std::wstring interface_flags_string = generate_interface_flags(uclass); + const SystemStringType interface_class_native_name = get_native_class_name(uclass); + const SystemStringType interface_flags_string = generate_interface_flags(uclass); - std::wstring maybe_api_name; + SystemStringType maybe_api_name; if ((uclass->GetClassFlags() & CLASS_RequiredAPI) != 0) { maybe_api_name.append(convert_module_name_to_api_name(header_data.get_header_module_name())); - maybe_api_name.append(STR(" ")); + maybe_api_name.append(SYSSTR(" ")); } UClass* super_class = uclass->GetSuperClass(); header_data.add_dependency_object(super_class, DependencyLevel::Include); - std::wstring parent_interface_class_name = get_native_class_name(super_class); + SystemStringType parent_interface_class_name = get_native_class_name(super_class); // Generate interface UCLASS declaration - header_data.append_line(std::format(STR("UINTERFACE({})"), interface_flags_string)); - header_data.append_line(std::format(STR("class {}{} : public {} {{"), maybe_api_name, interface_class_native_name, parent_interface_class_name)); + header_data.append_line(std::format(SYSSTR("UINTERFACE({})"), interface_flags_string)); + header_data.append_line(std::format(SYSSTR("class {}{} : public {} {{"), maybe_api_name, interface_class_native_name, parent_interface_class_name)); header_data.begin_indent_level(); - header_data.append_line(STR("GENERATED_BODY()")); + header_data.append_line(SYSSTR("GENERATED_BODY()")); header_data.end_indent_level(); - header_data.append_line(STR("};")); - header_data.append_line(STR("")); + header_data.append_line(SYSSTR("};")); + header_data.append_line(SYSSTR("")); // Generate interface real class declaration - const std::wstring interface_native_name = get_native_class_name(uclass, true); - const std::wstring parent_interface_name = get_native_class_name(super_class, true); + const SystemStringType interface_native_name = get_native_class_name(uclass, true); + const SystemStringType parent_interface_name = get_native_class_name(super_class, true); - header_data.append_line(std::format(STR("class {}{} : public {} {{"), maybe_api_name, interface_native_name, parent_interface_name)); + header_data.append_line(std::format(SYSSTR("class {}{} : public {} {{"), maybe_api_name, interface_native_name, parent_interface_name)); header_data.begin_indent_level(); - header_data.append_line(STR("GENERATED_BODY()")); + header_data.append_line(SYSSTR("GENERATED_BODY()")); AccessModifier current_access_modifier = AccessModifier::None; append_access_modifier(header_data, AccessModifier::Public, current_access_modifier); @@ -366,7 +369,7 @@ namespace RC::UEGenerator } if (NumDelegatesGenerated) { - header_data.append_line(STR("")); + header_data.append_line(SYSSTR("")); } // Generate interface functions @@ -380,30 +383,30 @@ namespace RC::UEGenerator } header_data.end_indent_level(); - header_data.append_line(STR("};")); + header_data.append_line(SYSSTR("};")); } auto UEHeaderGenerator::generate_object_definition(UClass* uclass, GeneratedSourceFile& header_data) -> void { - const std::wstring class_native_name = get_native_class_name(uclass); - const std::wstring class_flags_string = generate_class_flags(uclass); + const SystemStringType class_native_name = get_native_class_name(uclass); + const SystemStringType class_flags_string = generate_class_flags(uclass); - std::wstring maybe_api_name; + SystemStringType maybe_api_name; if ((uclass->GetClassFlags() & CLASS_RequiredAPI) != 0) { maybe_api_name.append(convert_module_name_to_api_name(header_data.get_header_module_name())); - maybe_api_name.append(STR(" ")); + maybe_api_name.append(SYSSTR(" ")); } UClass* super_class = uclass->GetSuperClass(); - std::wstring parent_class_name; + SystemStringType parent_class_name; if (super_class) { parent_class_name = get_native_class_name(super_class); } else { - parent_class_name = STR("UObjectBaseUtility"); + parent_class_name = SYSSTR("UObjectBaseUtility"); } if (super_class) @@ -411,23 +414,23 @@ namespace RC::UEGenerator header_data.add_dependency_object(super_class, DependencyLevel::Include); } - std::wstring interface_list_string; + SystemStringType interface_list_string; auto implemented_interfaces = uclass->GetInterfaces(); for (const RC::Unreal::FImplementedInterface& uinterface : implemented_interfaces) { header_data.add_dependency_object(uinterface.Class, DependencyLevel::Include); - const std::wstring interface_name = get_native_class_name(uinterface.Class, true); + const SystemStringType interface_name = get_native_class_name(uinterface.Class, true); - interface_list_string.append(STR(", public ")); + interface_list_string.append(SYSSTR(", public ")); interface_list_string.append(interface_name); } - header_data.append_line(std::format(STR("UCLASS({})"), class_flags_string)); - header_data.append_line(std::format(STR("class {}{} : public {}{} {{"), maybe_api_name, class_native_name, parent_class_name, interface_list_string)); + header_data.append_line(std::format(SYSSTR("UCLASS({})"), class_flags_string)); + header_data.append_line(std::format(SYSSTR("class {}{} : public {}{} {{"), maybe_api_name, class_native_name, parent_class_name, interface_list_string)); header_data.begin_indent_level(); - header_data.append_line(STR("GENERATED_BODY()")); + header_data.append_line(SYSSTR("GENERATED_BODY()")); AccessModifier current_access_modifier = AccessModifier::None; append_access_modifier(header_data, AccessModifier::Public, current_access_modifier); @@ -447,7 +450,7 @@ namespace RC::UEGenerator } if (NumDelegatesGenerated) { - header_data.append_line(STR("")); + header_data.append_line(SYSSTR("")); } // Generate properties @@ -471,19 +474,19 @@ namespace RC::UEGenerator append_access_modifier(header_data, AccessModifier::Public, current_access_modifier); // Generate constructor - std::wstring constructor_string; + SystemStringType constructor_string; if (uclass->IsChildOf() || uclass->IsChildOf()) { - constructor_string.append(STR("const FObjectInitializer& ObjectInitializer")); + constructor_string.append(SYSSTR("const FObjectInitializer& ObjectInitializer")); } - header_data.append_line(std::format(STR("{}({});"), class_native_name, constructor_string)); - header_data.append_line_no_indent(STR("")); + header_data.append_line(std::format(SYSSTR("{}({});"), class_native_name, constructor_string)); + header_data.append_line_no_indent(SYSSTR("")); // Generate GetLifetimeReplicatedProps override if we have encountered replicated properties if (encountered_replicated_properties) { - header_data.append_line(STR("virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override;")); - header_data.append_line_no_indent(STR("")); + header_data.append_line(SYSSTR("virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override;")); + header_data.append_line_no_indent(SYSSTR("")); } // Generate functions @@ -501,8 +504,8 @@ namespace RC::UEGenerator // Generate overrides for all inherited virtual functions if (implemented_interfaces.Num() > 0) { - header_data.append_line_no_indent(STR("")); - header_data.append_line(STR("// Fix for true pure virtual functions not being implemented")); + header_data.append_line_no_indent(SYSSTR("")); + header_data.append_line(SYSSTR("// Fix for true pure virtual functions not being implemented")); } for (const RC::Unreal::FImplementedInterface& uinterface : implemented_interfaces) { @@ -519,33 +522,34 @@ namespace RC::UEGenerator } header_data.end_indent_level(); - header_data.append_line(STR("};")); + header_data.append_line(SYSSTR("};")); } auto UEHeaderGenerator::generate_struct_definition(UScriptStruct* script_struct, GeneratedSourceFile& header_data) -> void { - const std::wstring struct_native_name = get_native_struct_name(script_struct); - const std::wstring struct_flags_string = generate_struct_flags(script_struct); + const SystemStringType struct_native_name = get_native_struct_name(script_struct); + const SystemStringType struct_flags_string = generate_struct_flags(script_struct); - std::wstring api_macro_name = convert_module_name_to_api_name(header_data.get_header_module_name()); - api_macro_name.append(STR(" ")); + SystemStringType api_macro_name = convert_module_name_to_api_name(header_data.get_header_module_name()); + api_macro_name.append(SYSSTR(" ")); bool is_struct_exported = (script_struct->GetStructFlags() & STRUCT_RequiredAPI) != 0; UScriptStruct* super_struct = script_struct->GetSuperScriptStruct(); - std::wstring parent_struct_declaration; + SystemStringType parent_struct_declaration; if (super_struct) { header_data.add_dependency_object(super_struct, DependencyLevel::Include); - const std::wstring super_struct_native_name = get_native_struct_name(super_struct); - parent_struct_declaration.append(std::format(STR(" : public {}"), super_struct_native_name)); + const SystemStringType super_struct_native_name = get_native_struct_name(super_struct); + parent_struct_declaration.append(std::format(SYSSTR(" : public {}"), super_struct_native_name)); } - header_data.append_line(std::format(STR("USTRUCT({})"), struct_flags_string)); - header_data.append_line(std::format(STR("struct {}{}{} {{"), is_struct_exported ? api_macro_name : STR(""), struct_native_name, parent_struct_declaration)); + header_data.append_line(std::format(SYSSTR("USTRUCT({})"), struct_flags_string)); + header_data.append_line( + std::format(SYSSTR("struct {}{}{} {{"), is_struct_exported ? api_macro_name : SYSSTR(""), struct_native_name, parent_struct_declaration)); header_data.begin_indent_level(); - header_data.append_line(STR("GENERATED_BODY()")); + header_data.append_line(SYSSTR("GENERATED_BODY()")); AccessModifier current_access_modifier = AccessModifier::None; append_access_modifier(header_data, AccessModifier::Public, current_access_modifier); @@ -568,34 +572,34 @@ namespace RC::UEGenerator // Generate constructor and make sure it's public append_access_modifier(header_data, AccessModifier::Public, current_access_modifier); - header_data.append_line(std::format(STR("{}{}();"), !is_struct_exported ? api_macro_name : STR(""), struct_native_name)); + header_data.append_line(std::format(SYSSTR("{}{}();"), !is_struct_exported ? api_macro_name : SYSSTR(""), struct_native_name)); header_data.end_indent_level(); - header_data.append_line(STR("};")); + header_data.append_line(SYSSTR("};")); } auto UEHeaderGenerator::generate_enum_definition(UEnum* uenum, GeneratedSourceFile& header_data) -> void { - const StringType native_enum_name = get_native_enum_name(uenum, false); + const SystemStringType native_enum_name = get_native_enum_name(uenum, false); const int64 highest_enum_value = get_highest_enum(uenum); const bool can_use_uint8_override = (highest_enum_value <= 255 && get_lowest_enum(uenum) >= 0); - const StringType enum_flags_string = generate_enum_flags(uenum); + const SystemStringType enum_flags_string = generate_enum_flags(uenum); const auto underlying_type = m_underlying_enum_types.find(native_enum_name); const bool has_known_underlying_type = underlying_type != m_underlying_enum_types.end(); UEnum::ECppForm cpp_form = uenum->GetCppForm(); bool enum_is_uint8{false}; - header_data.append_line(std::format(STR("UENUM({})"), enum_flags_string)); + header_data.append_line(std::format(SYSSTR("UENUM({})"), enum_flags_string)); if (cpp_form == UEnum::ECppForm::Namespaced) { - header_data.append_line(std::format(STR("namespace {} {{"), native_enum_name)); + header_data.append_line(std::format(SYSSTR("namespace {} {{"), native_enum_name)); header_data.begin_indent_level(); - header_data.append_line(STR("enum Type {")); + header_data.append_line(SYSSTR("enum Type {")); } else if (cpp_form == UEnum::ECppForm::Regular) { - header_data.append_line(std::format(STR("enum {} {{"), native_enum_name)); + header_data.append_line(std::format(SYSSTR("enum {} {{"), native_enum_name)); } else if (cpp_form == UEnum::ECppForm::EnumClass) { @@ -603,34 +607,34 @@ namespace RC::UEGenerator { if (UE4SSProgram::settings_manager.UHTHeaderGenerator.MakeEnumClassesBlueprintType && can_use_uint8_override) { - header_data.append_line(std::format(STR("enum class {} : uint8 {{"), native_enum_name)); + header_data.append_line(std::format(SYSSTR("enum class {} : uint8 {{"), native_enum_name)); enum_is_uint8 = true; } else { // Enum has never been used in any native classes or structures, go with implicit type - header_data.append_line(std::format(STR("enum class {} {{"), native_enum_name)); + header_data.append_line(std::format(SYSSTR("enum class {} {{"), native_enum_name)); } } else { - std::wstring underlying_type_string = underlying_type->second; + SystemStringType underlying_type_string = underlying_type->second; - header_data.append_line(std::format(STR("enum class {} : {} {{"), native_enum_name, underlying_type_string)); + header_data.append_line(std::format(SYSSTR("enum class {} : {} {{"), native_enum_name, underlying_type_string)); } } header_data.begin_indent_level(); - StringType enum_prefix = uenum->GenerateEnumPrefix(); + auto enum_prefix = uenum->GenerateEnumPrefix(); int64 expected_next_enum_value = 0; bool last_value_was_negative_one{false}; - std::set enum_name_set{}; + std::set enum_name_set{}; for (auto [Name, Value] : uenum->ForEachName()) { - StringType enum_name = Name.ToString(); - StringType result_enumeration_line = sanitize_enumeration_name(enum_name); - StringType pre_append_result_line = result_enumeration_line; + auto enum_name = Name.ToString(); + auto result_enumeration_line = sanitize_enumeration_name(to_system_string(enum_name)); + auto pre_append_result_line = result_enumeration_line; // If an enum name is listed in the array twice, that likely means it is used as the value for another enum. Long story short, don't print it. if (enum_name_set.contains(enum_name)) @@ -641,73 +645,74 @@ namespace RC::UEGenerator { enum_name_set.emplace(enum_name); } - + // Taking advantage of GetNameByValue returning the first result for the value to determine if there are any enumerator names that // reference an already declared value/name. - StringType first_name_with_value = uenum->GetNameByValue(Value).ToString(); + auto first_name_with_value = uenum->GetNameByValue(Value).ToString(); if (first_name_with_value != Name.ToString()) { - result_enumeration_line.append(std::format(STR(" = {}"), sanitize_enumeration_name(first_name_with_value))); + result_enumeration_line.append(std::format(SYSSTR(" = {}"), sanitize_enumeration_name(to_system_string(first_name_with_value)))); } else if (Value != expected_next_enum_value || last_value_was_negative_one) { - const StringType CastString = (enum_is_uint8 && Value < 0) ? STR("(uint8)") : STR(""); - const StringType MinusSign = Value < 0 ? STR("-") : STR(""); - result_enumeration_line.append(std::format(STR(" = {}{}{}"), CastString, MinusSign, std::abs(Value))); + const auto CastString = (enum_is_uint8 && Value < 0) ? SYSSTR("(uint8)") : SYSSTR(""); + const auto MinusSign = Value < 0 ? SYSSTR("-") : SYSSTR(""); + result_enumeration_line.append(std::format(SYSSTR(" = {}{}{}"), CastString, MinusSign, Value < 0 ? -Value : Value)); } expected_next_enum_value = Value + 1; last_value_was_negative_one = (Value == -1); - StringType pre_append_result_line_lower = pre_append_result_line; + SystemStringType pre_append_result_line_lower = pre_append_result_line; std::transform(pre_append_result_line_lower.begin(), pre_append_result_line_lower.end(), pre_append_result_line_lower.begin(), ::towlower); - if (pre_append_result_line_lower.ends_with(STR("_max"))) + if (pre_append_result_line_lower.ends_with(SYSSTR("_max"))) { - const StringType expected_full_constant_name = std::format(STR("{}_MAX"), enum_prefix); - StringType expected_full_constant_name_lower = expected_full_constant_name; + const auto expected_full_constant_name = std::format(SYSSTR("{}_MAX"), to_system(enum_prefix)); + SystemStringType expected_full_constant_name_lower = expected_full_constant_name; std::transform(expected_full_constant_name_lower.begin(), expected_full_constant_name_lower.end(), expected_full_constant_name_lower.begin(), ::towlower); - + int64_t expected_max_value = highest_enum_value + 1; // Skip enum _MAX constant if it has a matching name and is 1 greater than the highest value used, which means it has been autogenerated - if ((pre_append_result_line_lower == expected_full_constant_name_lower || pre_append_result_line_lower == sanitize_enumeration_name(expected_full_constant_name_lower)) && + if ((pre_append_result_line_lower == expected_full_constant_name_lower || + pre_append_result_line_lower == sanitize_enumeration_name(expected_full_constant_name_lower)) && Value == expected_max_value) { continue; } // Otherwise, just make sure it's hidden and not visible to the end user - result_enumeration_line.append(STR(" UMETA(Hidden)")); + result_enumeration_line.append(SYSSTR(" UMETA(Hidden)")); } - result_enumeration_line.append(STR(",")); + result_enumeration_line.append(SYSSTR(",")); header_data.append_line(result_enumeration_line); } header_data.end_indent_level(); - header_data.append_line(STR("};")); + header_data.append_line(SYSSTR("};")); if (cpp_form == UEnum::ECppForm::Namespaced) { header_data.end_indent_level(); - header_data.append_line(STR("}")); + header_data.append_line(SYSSTR("}")); } } auto UEHeaderGenerator::generate_delegate_type_declaration(UFunction* signature_function, UClass* delegate_class, GeneratedSourceFile& header_data) -> void { - std::wstring owning_class; + SystemStringType owning_class; if (delegate_class == nullptr) { - owning_class = STR("UObject*"); + owning_class = SYSSTR("UObject*"); } else { - owning_class = delegate_class->GetNamePrivate().ToString(); + owning_class = to_system(delegate_class->GetNamePrivate().ToString()); } auto function_flags = signature_function->GetFunctionFlags(); if ((function_flags & Unreal::FUNC_Delegate) == 0) { - throw std::runtime_error(RC::fmt("Delegate Signature function %S is missing FUNC_Delegate flag", signature_function->GetName().c_str())); + throw std::runtime_error(RC::fmt("Delegate Signature function {} is missing FUNC_Delegate flag", signature_function->GetName())); } // TODO not particularly nice or reliable, but will do for now @@ -716,85 +721,86 @@ namespace RC::UEGenerator const bool is_multicast = (function_flags & Unreal::FUNC_MulticastDelegate) != 0; const bool declared_const = (function_flags & FUNC_Const) != 0; - const std::wstring delegate_type_name = get_native_delegate_type_name(signature_function, nullptr, true); + const SystemStringType delegate_type_name = get_native_delegate_type_name(signature_function, nullptr, true); FProperty* return_value_property = signature_function->GetReturnProperty(); - std::wstring delegate_macro_string; + SystemStringType delegate_macro_string; // Delegate macro declaration is only allowed on the top level delegates, class-based types are limited to being implicit if (signature_function->GetOuterPrivate()->IsA()) { - delegate_macro_string.append(STR("UDELEGATE(")); + delegate_macro_string.append(SYSSTR("UDELEGATE(")); delegate_macro_string.append(generate_function_flags(signature_function)); - delegate_macro_string.append(STR(") ")); + delegate_macro_string.append(SYSSTR(") ")); } PropertyTypeDeclarationContext context(delegate_type_name, &header_data); int32_t num_delegate_parameters = 0; - std::wstring delegate_parameter_list = + SystemStringType delegate_parameter_list = generate_function_parameter_list(nullptr, signature_function, header_data, true, context.context_name, {}, &num_delegate_parameters); if (num_delegate_parameters > 0) { - delegate_parameter_list.insert(0, STR(", ")); + delegate_parameter_list.insert(0, SYSSTR(", ")); } if (num_delegate_parameters > 9) { - Output::send(STR("Invalid delegate parameter count in Delegate: {}. Using _TooMany\n"), delegate_type_name); + Output::send(SYSSTR("Invalid delegate parameter count in Delegate: {}. Using _TooMany\n"), delegate_type_name); } - std::wstring return_value_declaration; + SystemStringType return_value_declaration; if (return_value_property != NULL) { return_value_declaration = generate_property_type_declaration(return_value_property, context); - return_value_declaration.append(STR(", ")); - } - - std::wstring delegate_declaration_string = std::format(STR("{}DECLARE_DYNAMIC{}{}_DELEGATE{}{}{}({}{}{}{});"), - delegate_macro_string, - is_multicast ? STR("_MULTICAST") : STR(""), - is_sparse ? STR("_SPARSE") : STR(""), - return_value_property ? STR("_RetVal") : STR(""), - generate_parameter_count_string(num_delegate_parameters), - declared_const ? STR("_Const") : STR(""), - return_value_declaration, - delegate_type_name, - // TODO: Actually get delegate property name. - is_sparse ? std::format(STR("{}, {}"), owning_class, STR("EnterPropertyName")) : STR(""), - delegate_parameter_list); + return_value_declaration.append(SYSSTR(", ")); + } + + SystemStringType delegate_declaration_string = + std::format(SYSSTR("{}DECLARE_DYNAMIC{}{}_DELEGATE{}{}{}({}{}{}{});"), + delegate_macro_string, + is_multicast ? SYSSTR("_MULTICAST") : SYSSTR(""), + is_sparse ? SYSSTR("_SPARSE") : SYSSTR(""), + return_value_property ? SYSSTR("_RetVal") : SYSSTR(""), + generate_parameter_count_string(num_delegate_parameters), + declared_const ? SYSSTR("_Const") : SYSSTR(""), + return_value_declaration, + delegate_type_name, + // TODO: Actually get delegate property name. + is_sparse ? std::format(SYSSTR("{}, {}"), owning_class, SYSSTR("EnterPropertyName")) : SYSSTR(""), + delegate_parameter_list); header_data.append_line(delegate_declaration_string); } auto UEHeaderGenerator::generate_object_implementation(UClass* uclass, GeneratedSourceFile& implementation_file) -> void { - const std::wstring class_native_name = get_native_class_name(uclass); + auto class_native_name = get_native_class_name(uclass); - std::wstring constructor_content_string; - std::wstring constructor_postfix_string; + SystemStringType constructor_content_string; + SystemStringType constructor_postfix_string; UClass* super_class = uclass->GetSuperClass(); - const std::wstring native_parent_class_name = super_class ? get_native_class_name(super_class) : STR("UObjectUtility"); + const SystemStringType native_parent_class_name = super_class ? get_native_class_name(super_class) : SYSSTR("UObjectUtility"); // Generate constructor implementation except for overrides. // If class is a child of AActor we add the UObjectInitializer constructor. // This may not be required in all cases, but is necessary to override subcomponents and does not hurt anything. - std::wstring object_initializer_overrides; + SystemStringType object_initializer_overrides; if (uclass->IsChildOf() || uclass->IsChildOf()) { - constructor_content_string.append(STR("const FObjectInitializer& ObjectInitializer")); - constructor_postfix_string.append(std::format(STR(") : Super(ObjectInitializer{}"), object_initializer_overrides)); + constructor_content_string.append(SYSSTR("const FObjectInitializer& ObjectInitializer")); + constructor_postfix_string.append(std::format(SYSSTR(") : Super(ObjectInitializer{}"), object_initializer_overrides)); } // If parent class contains the UObjectInitializer constructor without default value, // we need to create the explicit call to such constructor and pass UObjectInitializer::Get() as the argument. else if (m_classes_with_object_initializer.contains(native_parent_class_name)) { - constructor_postfix_string.append(std::format(STR(") : {}(FObjectInitializer::Get()"), native_parent_class_name)); + constructor_postfix_string.append(std::format(SYSSTR(") : {}(FObjectInitializer::Get()"), native_parent_class_name)); } implementation_file.m_implementation_constructor.append( - std::format(STR("{}::{}({}{}"), class_native_name, class_native_name, constructor_content_string, constructor_postfix_string)); + std::format(SYSSTR("{}::{}({}{}"), class_native_name, class_native_name, constructor_content_string, constructor_postfix_string)); implementation_file.begin_indent_level(); @@ -805,34 +811,39 @@ namespace RC::UEGenerator { for (FProperty* property : uclass->OrderedForEachPropertyInChain()) { - generate_property_value(uclass, property, class_default_object, implementation_file, STR("this->")); + generate_property_value(uclass, property, class_default_object, implementation_file, SYSSTR("this->")); } } else { - implementation_file.append_line(STR("// Null default object.")); + implementation_file.append_line(SYSSTR("// Null default object.")); } m_class_subobjects.clear(); // Generate component attachments for (auto attachment : implementation_file.attachments) { - if (get<2>(attachment.second) == false) + if ((attachment.second).access_type == false) { - generate_simple_assignment_expression(attachment.first, get<1>(attachment.second), implementation_file, STR("this->"), STR("->")); + generate_simple_assignment_expression(attachment.first, (attachment.second).attach_string, implementation_file, SYSSTR("this->"), SYSSTR("->")); } else { - generate_advanced_assignment_expression(attachment.first, get<1>(attachment.second), implementation_file, STR("this->"), get<0>(attachment.second), STR("->")); + generate_advanced_assignment_expression(attachment.first, + (attachment.second).attach_string, + implementation_file, + SYSSTR("this->"), + (attachment.second).property_type, + SYSSTR("->")); } } - + implementation_file.end_indent_level(); - implementation_file.append_line(STR("}\n")); + implementation_file.append_line(SYSSTR("}\n")); // Finalize constructor. We do this after the property generation because we need information from the properties // to determine the required overrides within the constructor. - implementation_file.m_implementation_constructor.append(STR(") {")); + implementation_file.m_implementation_constructor.append(SYSSTR(") {")); CaseInsensitiveSet blacklisted_property_names = collect_blacklisted_property_names(uclass); @@ -842,7 +853,7 @@ namespace RC::UEGenerator if (!is_delegate_signature_function(function)) { generate_function_implementation(uclass, function, implementation_file, false, blacklisted_property_names); - implementation_file.append_line(STR("")); + implementation_file.append_line(SYSSTR("")); } } @@ -856,35 +867,35 @@ namespace RC::UEGenerator // Generate replicated properties implementation if we really need it if (encountered_replicated_properties) { - implementation_file.add_extra_include(STR("Net/UnrealNetwork.h")); + implementation_file.add_extra_include(SYSSTR("Net/UnrealNetwork.h")); implementation_file.append_line( - std::format(STR("void {}::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const {{"), class_native_name)); + std::format(SYSSTR("void {}::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const {{"), class_native_name)); implementation_file.begin_indent_level(); - implementation_file.append_line(STR("Super::GetLifetimeReplicatedProps(OutLifetimeProps);")); - implementation_file.append_line(STR("")); + implementation_file.append_line(SYSSTR("Super::GetLifetimeReplicatedProps(OutLifetimeProps);")); + implementation_file.append_line(SYSSTR("")); for (FProperty* property : uclass->ForEachProperty()) { if ((property->GetPropertyFlags() & CPF_Net) != 0) { - implementation_file.append_line(std::format(STR("DOREPLIFETIME({}, {});"), class_native_name, property->GetName())); + implementation_file.append_line(std::format(SYSSTR("DOREPLIFETIME({}, {});"), class_native_name, to_system(property->GetName()))); } } implementation_file.end_indent_level(); - implementation_file.append_line(STR("}")); - implementation_file.append_line(STR("")); + implementation_file.append_line(SYSSTR("}")); + implementation_file.append_line(SYSSTR("")); } } auto UEHeaderGenerator::generate_struct_implementation(UScriptStruct* script_struct, GeneratedSourceFile& implementation_file) -> void { - const std::wstring struct_native_name = get_native_struct_name(script_struct); + const SystemStringType struct_native_name = get_native_struct_name(script_struct); // Generate constructor implementation and initialize properties inside - implementation_file.m_implementation_constructor.append(std::format(STR("{}::{}() {{"), struct_native_name, struct_native_name)); + implementation_file.m_implementation_constructor.append(std::format(SYSSTR("{}::{}() {{"), struct_native_name, struct_native_name)); implementation_file.begin_indent_level(); // Generate properties @@ -895,26 +906,26 @@ namespace RC::UEGenerator for (FProperty* property : script_struct->OrderedForEachPropertyInChain()) { - generate_property_value(script_struct, property, struct_default_object, implementation_file, STR("this->")); + generate_property_value(script_struct, property, struct_default_object, implementation_file, SYSSTR("this->")); } // TODO: ScriptStruct->DestroyStruct(StructDefaultObject); free(struct_default_object); implementation_file.end_indent_level(); - implementation_file.append_line(STR("}")); + implementation_file.append_line(SYSSTR("}")); } auto UEHeaderGenerator::generate_property(UObject* uclass, FProperty* property, GeneratedSourceFile& header_data) -> void { - const std::wstring property_flags_string = generate_property_flags(property); + const SystemStringType property_flags_string = generate_property_flags(property); bool is_bitmask_bool = false; - PropertyTypeDeclarationContext Context(uclass->GetName(), &header_data, true, &is_bitmask_bool); + PropertyTypeDeclarationContext Context(to_system(uclass->GetName()), &header_data, true, &is_bitmask_bool); - std::wstring property_type_string{}; + SystemStringType property_type_string{}; bool type_is_valid = true; - std::wstring error_string{}; + SystemStringType error_string{}; try { property_type_string = generate_property_type_declaration(property, Context); @@ -922,34 +933,34 @@ namespace RC::UEGenerator catch (std::exception& e) { type_is_valid = false; - error_string = to_wstring(e.what()); + error_string = to_system(e.what()); } if (!type_is_valid) { - Output::send(STR("Warning: {}\n"), error_string); - header_data.append_line(std::format(STR("// UPROPERTY({})"), property_flags_string)); - header_data.append_line(std::format(STR("// Missed Property: {}"), property->GetName())); - header_data.append_line(std::format(STR("// {}"), error_string)); - header_data.append_line(STR("")); + Output::send(SYSSTR("Warning: {}\n"), error_string); + header_data.append_line(std::format(SYSSTR("// UPROPERTY({})"), property_flags_string)); + header_data.append_line(std::format(SYSSTR("// Missed Property: {}"), to_system(property->GetName()))); + header_data.append_line(std::format(SYSSTR("// {}"), error_string)); + header_data.append_line(SYSSTR("")); return; } - std::wstring property_extra_declaration; + SystemStringType property_extra_declaration; if (property->GetArrayDim() != 1) { - property_extra_declaration.append(STR("[")); - property_extra_declaration.append(std::to_wstring(property->GetArrayDim())); - property_extra_declaration.append(STR("]")); + property_extra_declaration.append(SYSSTR("[")); + property_extra_declaration.append(to_system(std::to_string(property->GetArrayDim()))); + property_extra_declaration.append(SYSSTR("]")); } else if (is_bitmask_bool) { - property_extra_declaration.append(STR(": 1")); + property_extra_declaration.append(SYSSTR(": 1")); } - header_data.append_line(std::format(STR("UPROPERTY({})"), property_flags_string)); - header_data.append_line(std::format(STR("{} {}{};"), property_type_string, property->GetName(), property_extra_declaration)); - header_data.append_line(STR("")); + header_data.append_line(std::format(SYSSTR("UPROPERTY({})"), property_flags_string)); + header_data.append_line(std::format(SYSSTR("{} {}{};"), property_type_string, to_system(property->GetName()), property_extra_declaration)); + header_data.append_line(SYSSTR("")); } // TODO FUNC_Final is not properly handled (should be always set except some weird cases) @@ -961,90 +972,91 @@ namespace RC::UEGenerator bool generate_as_override) -> void { auto function_flags = function->GetFunctionFlags(); - const std::wstring context_name = uclass->GetName(); + const auto context_name = uclass->GetName(); bool is_function_pure_virtual = generate_as_override; - std::wstring function_modifier_string; + SystemStringType function_modifier_string; if ((function_flags & FUNC_Static) != 0) { - function_modifier_string.append(STR("static ")); + function_modifier_string.append(SYSSTR("static ")); } else if ((function_flags & FUNC_BlueprintEvent) == 0 && is_generating_interface) { // When we have a blueprint function that is not blueprint event inside the interface, // it means we are dealing with the native interface that cannot be implemented via blueprints // and uses pure virtual functions implemented through native code - function_modifier_string.append(STR("virtual ")); + function_modifier_string.append(SYSSTR("virtual ")); is_function_pure_virtual = true; } FProperty* return_property = function->GetReturnProperty(); - std::wstring return_property_string; + SystemStringType return_property_string; if (return_property != NULL) { - PropertyTypeDeclarationContext context(uclass->GetName(), &header_data); + PropertyTypeDeclarationContext context(to_system(uclass->GetName()), &header_data); return_property_string = generate_property_type_declaration(return_property, context); } else { - return_property_string = STR("void"); + return_property_string = SYSSTR("void"); } - std::wstring function_extra_postfix_string; + SystemStringType function_extra_postfix_string; if ((function_flags & FUNC_Const) != 0) { - function_extra_postfix_string.append(STR(" const")); + function_extra_postfix_string.append(SYSSTR(" const")); } if (is_function_pure_virtual) { - std::wstring return_statement_string; + SystemStringType return_statement_string; if (return_property != NULL) { - const std::wstring default_property_value = generate_default_property_value(return_property, header_data, context_name); - return_statement_string = std::format(STR(" return {};"), default_property_value); + const auto default_property_value = generate_default_property_value(return_property, header_data, to_system_string(context_name)); + return_statement_string = std::format(SYSSTR(" return {};"), default_property_value); } if (generate_as_override) { - function_extra_postfix_string.append(STR(" override")); + function_extra_postfix_string.append(SYSSTR(" override")); } - function_extra_postfix_string.append(std::format(STR(" PURE_VIRTUAL({},{})"), function->GetName(), return_statement_string)); + function_extra_postfix_string.append(std::format(SYSSTR(" PURE_VIRTUAL({},{})"), to_system(function->GetName()), return_statement_string)); } - std::wstring function_argument_list = generate_function_parameter_list(uclass, function, header_data, false, context_name, blacklisted_property_names); + auto function_argument_list = + generate_function_parameter_list(uclass, function, header_data, false, to_system_string(context_name), blacklisted_property_names); - const std::wstring function_flags_string = generate_function_flags(function, is_function_pure_virtual); - header_data.append_line(std::format(STR("UFUNCTION({})"), function_flags_string)); + const auto function_flags_string = generate_function_flags(function, is_function_pure_virtual); + header_data.append_line(std::format(SYSSTR("UFUNCTION({})"), function_flags_string)); // Format for virtual functions // virtual () PURE_VIRTUAL(, ) - header_data.append_line(std::format(STR("{}{} {}({}){};"), + header_data.append_line(std::format(SYSSTR("{}{} {}({}){};"), function_modifier_string, return_property_string, - function->GetName(), + to_system(function->GetName()), function_argument_list, function_extra_postfix_string)); - header_data.append_line(STR("")); + header_data.append_line(SYSSTR("")); } - auto UEHeaderGenerator::generate_enum_value(UEnum* uenum, int64_t enum_value) -> std::wstring + auto UEHeaderGenerator::generate_enum_value(UEnum* uenum, int64_t enum_value) -> SystemStringType { UEnum::ECppForm cpp_form = uenum->GetCppForm(); - const std::wstring enum_native_name = get_native_enum_name(uenum, false); + const SystemStringType enum_native_name = get_native_enum_name(uenum, false); - std::wstring enum_constant_name; + SystemStringType enum_constant_name; for (auto [Name, Value] : uenum->ForEachName()) { if (Value == enum_value) { - enum_constant_name = sanitize_enumeration_name(Name.ToString()); + enum_constant_name = sanitize_enumeration_name(to_system_string(Name.ToString())); } } if (enum_constant_name.empty()) { - Output::send(STR("Warning: Invalid value for enum '{}', casting instead of using enum name. Value '{}' will be cast to the enum.\n"), + Output::send(SYSSTR("Warning: Invalid value for enum '{}', casting instead of using enum name. Value '{}' will be cast to the enum.\n"), enum_native_name, enum_value); - return std::format(STR("({}){}"), enum_native_name, enum_value); + return std::format(SYSSTR("({}){}"), enum_native_name, enum_value); } else { @@ -1053,65 +1065,74 @@ namespace RC::UEGenerator { return enum_constant_name; } - return std::format(STR("{}::{}"), enum_native_name, enum_constant_name); + return std::format(SYSSTR("{}::{}"), enum_native_name, enum_constant_name); } } auto UEHeaderGenerator::generate_simple_assignment_expression(FProperty* property, - const std::wstring& value, + const SystemStringType& value, GeneratedSourceFile& implementation_file, - const std::wstring& property_scope, - const std::wstring& operator_type) -> void + const SystemStringType& property_scope, + const SystemStringType& operator_type) -> void { - const std::wstring field_class_name = property->GetName(); + const auto field_class_name = to_system(property->GetName()); if (property->GetArrayDim() == 1) { - implementation_file.append_line(std::format(STR("{}{}{}{};"), property_scope, field_class_name, operator_type, value)); + implementation_file.append_line(std::format(SYSSTR("{}{}{}{};"), property_scope, field_class_name, operator_type, value)); } else { for (int32_t i = 0; i < property->GetArrayDim(); i++) { - implementation_file.append_line(std::format(STR("{}{}[{}]{}{};"), property_scope, field_class_name, i, operator_type, value)); + implementation_file.append_line(std::format(SYSSTR("{}{}[{}]{}{};"), property_scope, field_class_name, i, operator_type, value)); } } } auto UEHeaderGenerator::generate_advanced_assignment_expression(FProperty* property, - const std::wstring& value, + const SystemStringType& value, GeneratedSourceFile& implementation_file, - const std::wstring& property_scope, - const std::wstring& property_type, - const std::wstring& operator_type) -> void + const SystemStringType& property_scope, + const SystemStringType& property_type, + const SystemStringType& operator_type) -> void { - const std::wstring field_class_name = property->GetName(); - implementation_file.append_line(std::format(STR("const FProperty* p_{} = GetClass()->FindPropertyByName(\"{}\");"), field_class_name, field_class_name)); + const auto field_class_name = to_system(property->GetName()); + implementation_file.append_line(std::format(SYSSTR("const FProperty* p_{} = GetClass()->FindPropertyByName(\"{}\");"), field_class_name, field_class_name)); if (property->GetArrayDim() == 1) { - implementation_file.append_line(std::format(STR("(*p_{}->ContainerPtrToValuePtr<{}>(this)){}{};"), field_class_name, property_type, operator_type, value)); + implementation_file.append_line( + std::format(SYSSTR("(*p_{}->ContainerPtrToValuePtr<{}>(this)){}{};"), field_class_name, property_type, operator_type, value)); } else { for (int32_t i = 0; i < property->GetArrayDim(); i++) { - implementation_file.append_line( - std::format(STR("*p_{}->ContainerPtrToValuePtr<{}>(this){}[{}]{}{};"), field_class_name, property_scope, field_class_name, i, operator_type, value)); + implementation_file.append_line(std::format(SYSSTR("*p_{}->ContainerPtrToValuePtr<{}>(this){}[{}]{}{};"), + field_class_name, + property_scope, + field_class_name, + i, + operator_type, + value)); } } } auto UEHeaderGenerator::generate_property_value( - UStruct* ustruct, FProperty* property, void* object, GeneratedSourceFile& implementation_file, const std::wstring& property_scope) -> void + UStruct* ustruct, FProperty* property, void* object, GeneratedSourceFile& implementation_file, const SystemStringType& property_scope) -> void { - const std::wstring property_name = property->GetName(); - if (property_name == STR("NativeClass") || property_name == STR("hudClass")) { return; } + const auto property_name = property->GetName(); + if (property_name == STR("NativeClass") || property_name == STR("hudClass")) + { + return; + } const bool private_access_modifier = get_property_access_modifier(property) == AccessModifier::Private; bool super_and_no_access = false; // Populate super for checks to ensure values are only initialized if they are overriden in the child class UStruct* super; void* super_object = nullptr; FProperty* super_property = nullptr; - const std::wstring property_type = generate_property_cxx_name(property, true, ustruct); + const auto property_type = generate_property_cxx_name(property, true, ustruct); auto as_class = Cast(ustruct); if (as_class) { @@ -1152,15 +1173,19 @@ namespace RC::UEGenerator } UEnum* uenum = byte_property->GetEnum(); - std::wstring result_property_value; + SystemStringType result_property_value; if (uenum != NULL) { - const std::wstring enum_type_name = get_native_enum_name(uenum); + const SystemStringType enum_type_name = get_native_enum_name(uenum); result_property_value = generate_enum_value(uenum, *byte_property_value); } else { +#ifdef WIN32 result_property_value = std::to_wstring(*byte_property_value); +#else + result_property_value = std::to_string(*byte_property_value); +#endif } if (!super_and_no_access) @@ -1181,7 +1206,7 @@ namespace RC::UEGenerator UEnum* uenum = p_enum_property->GetEnum(); if (uenum == NULL) { - throw std::runtime_error(RC::fmt("EnumProperty %S does not have a valid Enum value", property->GetName().c_str())); + throw std::runtime_error(RC::fmt("EnumProperty {} does not have a valid Enum value", property->GetName())); } FNumericProperty* underlying_property = p_enum_property->GetUnderlyingProperty(); @@ -1200,7 +1225,7 @@ namespace RC::UEGenerator } implementation_file.add_dependency_object(uenum, DependencyLevel::Include); - std::wstring result_property_value = generate_enum_value(uenum, value); + SystemStringType result_property_value = generate_enum_value(uenum, value); if (!super_and_no_access) { generate_simple_assignment_expression(property, result_property_value, implementation_file, property_scope); @@ -1242,7 +1267,7 @@ namespace RC::UEGenerator super_and_no_access = private_access_modifier; } - const std::wstring result_property_value = result_bool_value ? STR("true") : STR("false"); + const SystemStringType result_property_value = result_bool_value ? SYSSTR("true") : SYSSTR("false"); if (!super_and_no_access) { generate_simple_assignment_expression(property, result_property_value, implementation_file, property_scope); @@ -1250,7 +1275,10 @@ namespace RC::UEGenerator else { // Skip private bitmask bools TODO: Fix setting these - if (bool_property->GetFieldMask() != 255) { return; } + if (bool_property->GetFieldMask() != 255) + { + return; + } generate_advanced_assignment_expression(property, result_property_value, implementation_file, property_scope, property_type); } return; @@ -1260,13 +1288,13 @@ namespace RC::UEGenerator if (property->IsA()) { FName* name_value = property->ContainerPtrToValuePtr(object); - const std::wstring name_value_string = name_value->ToString(); + const auto name_value_string = (name_value->ToString()); // Ensure property either does not exist in parent class or is overriden in the CDO for the child class if (super_property != nullptr) { FName* super_name_value = super_property->ContainerPtrToValuePtr(super_object); - const std::wstring super_name_value_string = super_name_value->ToString(); + const auto super_name_value_string = (super_name_value->ToString()); if (name_value_string == super_name_value_string) { return; @@ -1276,7 +1304,7 @@ namespace RC::UEGenerator if (name_value_string != STR("None")) { - const std::wstring result_property_value = std::format(STR("TEXT(\"{}\")"), name_value_string); + const auto result_property_value = std::format(SYSSTR("TEXT(\"{}\")"), to_system(name_value_string)); if (!super_and_no_access) { generate_simple_assignment_expression(property, result_property_value, implementation_file, property_scope); @@ -1293,13 +1321,13 @@ namespace RC::UEGenerator if (property->IsA()) { FString* string_value = property->ContainerPtrToValuePtr(object); - const std::wstring string_value_string = string_value->GetCharArray(); + const auto string_value_string = (to_system(string_value->GetCharArray())); // Ensure property either does not exist in parent class or is overriden in the CDO for the child class if (super_property != nullptr) { FString* super_string_value = super_property->ContainerPtrToValuePtr(super_object); - const std::wstring super_string_value_string = super_string_value->GetCharArray(); + const auto super_string_value_string = (to_system(super_string_value->GetCharArray())); if (string_value_string == super_string_value_string) { return; @@ -1307,9 +1335,9 @@ namespace RC::UEGenerator super_and_no_access = private_access_modifier; } - if (string_value_string != STR("")) + if (string_value_string != SYSSTR("")) { - const std::wstring result_value = create_string_literal(string_value_string); + const auto result_value = create_string_literal(to_system_string(string_value_string)); if (!super_and_no_access) { generate_simple_assignment_expression(property, result_value, implementation_file, property_scope); @@ -1342,7 +1370,7 @@ namespace RC::UEGenerator if (text_value_string != STR("")) { - const std::wstring result_property_value = std::format(STR("FText::FromString({})"), create_string_literal(text_value_string)); + const auto result_property_value = std::format(SYSSTR("FText::FromString({})"), create_string_literal(to_system(text_value_string))); if (!super_and_no_access) { generate_simple_assignment_expression(property, result_property_value, implementation_file, property_scope); @@ -1378,11 +1406,11 @@ namespace RC::UEGenerator // If class value is NULL, generate a simple NULL assignment if (!super_and_no_access) { - generate_simple_assignment_expression(property, STR("NULL"), implementation_file, property_scope); + generate_simple_assignment_expression(property, SYSSTR("NULL"), implementation_file, property_scope); } else { - generate_advanced_assignment_expression(property, STR("NULL"), implementation_file, property_scope, property_type); + generate_advanced_assignment_expression(property, SYSSTR("NULL"), implementation_file, property_scope, property_type); } } else if ((class_value->GetClassFlags() & CLASS_Native) != 0) @@ -1390,8 +1418,8 @@ namespace RC::UEGenerator implementation_file.add_dependency_object(class_value, DependencyLevel::Include); // Otherwise, generate StaticClass call, assuming the class is native - const std::wstring object_class_name = get_native_class_name(class_value); - const std::wstring initializer = std::format(STR("{}::StaticClass()"), object_class_name); + const SystemStringType object_class_name = get_native_class_name(class_value); + const SystemStringType initializer = std::format(SYSSTR("{}::StaticClass()"), object_class_name); if (!super_and_no_access) { @@ -1405,7 +1433,7 @@ namespace RC::UEGenerator else { // Unhandled case, reference to the non-native blueprint class potentially? - Output::send(STR("Unhandled default value of the FClassProperty {}: {}\n"), property->GetFullName(), class_value->GetFullName()); + Output::send(SYSSTR("Unhandled default value of the FClassProperty {}: {}\n"), (property->GetFullName()), (class_value->GetFullName())); } return; } @@ -1436,11 +1464,11 @@ namespace RC::UEGenerator // TODO: Needs additional checks to see if the class is abstract to potentially change this to a default object init if (!super_and_no_access) { - generate_simple_assignment_expression(property, STR("NULL"), implementation_file, property_scope); + generate_simple_assignment_expression(property, SYSSTR("NULL"), implementation_file, property_scope); } else { - generate_advanced_assignment_expression(property, STR("NULL"), implementation_file, property_scope, property_type); + generate_advanced_assignment_expression(property, SYSSTR("NULL"), implementation_file, property_scope, property_type); } return; } @@ -1448,14 +1476,14 @@ namespace RC::UEGenerator if (sub_object_value->HasAnyFlags(EObjectFlags::RF_DefaultSubObject)) { UClass* object_class_type = sub_object_value->GetClassPrivate(); - const std::wstring object_name = sub_object_value->GetName(); + const auto object_name = (sub_object_value->GetName()); UClass* super_object_class_type{}; // Additional checks to ensure this property needs to be initialized in the current class if (super_sub_object_value) { super_object_class_type = super_sub_object_value->GetClassPrivate(); - const std::wstring super_object_name = super_sub_object_value->GetName(); + const auto super_object_name = (super_sub_object_value->GetName()); if ((object_class_type == super_object_class_type) && (object_name == super_object_name)) { return; @@ -1464,7 +1492,7 @@ namespace RC::UEGenerator } bool parent_component_found = false; - std::wstring prior_property_variable{}; + SystemStringType prior_property_variable{}; // Check to see if any other property in the super initialized a component with the same name to ensure // we are not creating the subobject in a child class unnecessarily. @@ -1478,7 +1506,7 @@ namespace RC::UEGenerator UObject* check_super_sub_object_value = *check_super_object_property->ContainerPtrToValuePtr(super_object); if (check_super_sub_object_value) { - std::wstring check_super_object_name = check_super_sub_object_value->GetName(); + auto check_super_object_name = (check_super_sub_object_value->GetName()); if (check_super_object_name == object_name) { parent_component_found = true; @@ -1491,33 +1519,33 @@ namespace RC::UEGenerator // Generate an initializer by either setting this property to a pre-existing property // overriding the object class of an existing component, or creating a new default subobject - std::wstring initializer{}; + SystemStringType initializer{}; if (auto it = m_class_subobjects.find(object_name); it != m_class_subobjects.end()) { // Set property to equal previous property referencing the same object - initializer = it->second; - FProperty* prior_property = ustruct->GetPropertyByNameInChain(initializer.c_str()); + initializer = to_system(it->second); + FProperty* prior_property = ustruct->GetPropertyByNameInChain(it->second.c_str()); bool prior_private = get_property_access_modifier(prior_property) == AccessModifier::Private; if (prior_private) { UObject* check_sub_object_value = *prior_property->ContainerPtrToValuePtr(object); - std::wstring prior_prop_class_name = STR("NULL"); + SystemStringType prior_prop_class_name = SYSSTR("NULL"); if (check_sub_object_value->GetClassPrivate() != nullptr) { prior_prop_class_name = get_native_class_name(check_sub_object_value->GetClassPrivate()); } implementation_file.append_line( - std::format(STR("FProperty* p_{}_Prior = GetClass()->FindPropertyByName(\"{}\");"), initializer, initializer)); - initializer = std::format(STR("*p_{}_Prior->ContainerPtrToValuePtr<{}*>(this)"), initializer, prior_prop_class_name); + std::format(SYSSTR("FProperty* p_{}_Prior = GetClass()->FindPropertyByName(\"{}\");"), initializer, initializer)); + initializer = std::format(SYSSTR("*p_{}_Prior->ContainerPtrToValuePtr<{}*>(this)"), initializer, prior_prop_class_name); } if (!super_and_no_access) { - initializer = std::format(STR("({}*){}"), get_native_class_name(object_property->GetPropertyClass()), initializer); + initializer = std::format(SYSSTR("({}*){}"), get_native_class_name(object_property->GetPropertyClass()), initializer); generate_simple_assignment_expression(property, initializer, implementation_file, property_scope); } else { - initializer = std::format(STR("({}*){}"), get_native_class_name(object_property->GetPropertyClass()), initializer); + initializer = std::format(SYSSTR("({}*){}"), get_native_class_name(object_property->GetPropertyClass()), initializer); generate_advanced_assignment_expression(property, initializer, implementation_file, property_scope, property_type); } } @@ -1526,16 +1554,16 @@ namespace RC::UEGenerator // Add an objectinitializer default subobject class override to the constructor implementation_file.add_dependency_object(object_class_type, DependencyLevel::Include); implementation_file.m_implementation_constructor.append( - std::format(STR(".SetDefaultSubobjectClass<{}>(TEXT(\"{}\"))"), get_native_class_name(object_class_type), object_name)); - m_class_subobjects.try_emplace(object_name, property->GetName()); + std::format(SYSSTR(".SetDefaultSubobjectClass<{}>(TEXT(\"{}\"))"), get_native_class_name(object_class_type), to_system(object_name))); + m_class_subobjects.try_emplace(object_name, (property->GetName())); } else { // Generate a CreateDefaultSubobject function call implementation_file.add_dependency_object(object_class_type, DependencyLevel::Include); - const std::wstring object_class_name = get_native_class_name(object_class_type); - initializer = std::format(STR("CreateDefaultSubobject<{}>(TEXT(\"{}\"))"), object_class_name, object_name); - m_class_subobjects.try_emplace(object_name, property->GetName()); + const SystemStringType object_class_name = get_native_class_name(object_class_type); + initializer = std::format(SYSSTR("CreateDefaultSubobject<{}>(TEXT(\"{}\"))"), object_class_name, to_system(object_name)); + m_class_subobjects.try_emplace(object_name, (property->GetName())); if (!super_and_no_access) { generate_simple_assignment_expression(property, initializer, implementation_file, property_scope); @@ -1554,14 +1582,14 @@ namespace RC::UEGenerator } if (attach_parent_object_value != NULL) { - const std::wstring attach_parent_object_name = attach_parent_object_value->GetName(); - const std::wstring operator_type = STR("->"); + const auto attach_parent_object_name = (attach_parent_object_value->GetName()); + const SystemStringType operator_type = SYSSTR("->"); bool parent_found = false; - std::wstring attach_string; + SystemStringType attach_string; if (auto it = m_class_subobjects.find(attach_parent_object_name); it != m_class_subobjects.end()) { // Set property to equal previous property referencing the same object - attach_string = std::format(STR("SetupAttachment({})"), it->second); + attach_string = std::format(SYSSTR("SetupAttachment({})"), to_system(it->second)); parent_found = true; } else if (as_class) @@ -1574,25 +1602,26 @@ namespace RC::UEGenerator UObject* check_sub_object_value = *check_object_property->ContainerPtrToValuePtr(object); if (check_sub_object_value) { - std::wstring check_object_name = check_sub_object_value->GetName(); + auto check_object_name = (check_sub_object_value->GetName()); if (check_object_name == attach_parent_object_name) { if (get_property_access_modifier(check_object_property) != AccessModifier::Private) { - attach_string = std::format(STR("SetupAttachment({})"), check_property->GetName()); + attach_string = std::format(SYSSTR("SetupAttachment({})"), to_system(check_property->GetName())); } else { - StringType parent_property_name = std::format(STR("const FProperty* p_{}_Parent = GetClass()->FindPropertyByName(\"{}\");"), - check_property->GetName(), - check_property->GetName()); + auto parent_property_name = + std::format(SYSSTR("const FProperty* p_{}_Parent = GetClass()->FindPropertyByName(\"{}\");"), + to_system(check_property->GetName()), + to_system(check_property->GetName())); if (!implementation_file.parent_property_names.contains(parent_property_name)) { implementation_file.parent_property_names.emplace(parent_property_name); implementation_file.append_line(parent_property_name); } - attach_string = std::format(STR("SetupAttachment(p_{}_Parent->ContainerPtrToValuePtr<{}>(this))"), - check_property->GetName(), + attach_string = std::format(SYSSTR("SetupAttachment(p_{}_Parent->ContainerPtrToValuePtr<{}>(this))"), + to_system(check_property->GetName()), get_native_class_name(check_sub_object_value->GetClassPrivate())); implementation_file.add_dependency_object(check_sub_object_value->GetClassPrivate(), DependencyLevel::Include); } @@ -1607,11 +1636,11 @@ namespace RC::UEGenerator { if (!super_and_no_access) { - implementation_file.attachments.try_emplace(property, std::tuple{property_type, attach_string, false}); + implementation_file.attachments.try_emplace(property, GeneratedSourceFile::attachment_data{property_type, attach_string, false}); } else { - implementation_file.attachments.try_emplace(property, std::tuple{property_type, attach_string, true}); + implementation_file.attachments.try_emplace(property, GeneratedSourceFile::attachment_data{property_type, attach_string, true}); } } } @@ -1634,8 +1663,8 @@ namespace RC::UEGenerator // Generate a ::StaticClass call if this object represents a class implementation_file.add_dependency_object(sub_object_as_class, DependencyLevel::Include); - const std::wstring object_class_name = get_native_class_name(sub_object_as_class); - const std::wstring initializer = std::format(STR("{}::StaticClass()"), object_class_name); + const SystemStringType object_class_name = get_native_class_name(sub_object_as_class); + const SystemStringType initializer = std::format(SYSSTR("{}::StaticClass()"), object_class_name); if (!super_and_no_access) { generate_simple_assignment_expression(property, initializer, implementation_file, property_scope); @@ -1648,14 +1677,14 @@ namespace RC::UEGenerator } // Unhandled case, might be some external object reference - Output::send(STR("Unhandled default value of the FObjectProperty {}: {}\n"), property->GetFullName(), sub_object_value->GetFullName()); + Output::send(SYSSTR("Unhandled default value of the FObjectProperty {}: {}\n"), (property->GetFullName()), (sub_object_value->GetFullName())); return; } // Struct properties are serialization as normal struct constructors with custom scope // TODO there are a lot of issues with that regarding member access, unnecessary assignments and so on - /*if (FieldClassName == STR("StructProperty")) { + /*if (FieldClassName == SYSSTR("StructProperty")) { XStructProperty* StructProperty = static_cast(Property); UScriptStruct* ScriptStruct = StructProperty->get_script_struct(); @@ -1664,7 +1693,7 @@ namespace RC::UEGenerator } void* StructDataPointer = StructProperty->container_ptr_to_value_ptr(Object); - const std::wstring NewPropertyScope = std::format(STR("{}{}."), PropertyScope, StructProperty->GetName()); + const SystemStringType NewPropertyScope = std::format(SYSSTR("{}{}."), PropertyScope, StructProperty->GetName()); //Generate values for each struct property //TODO we do not really need to generate assignments for each struct member, we only really need members that are different from the constructor set @@ -1694,7 +1723,8 @@ namespace RC::UEGenerator { if (!super_and_no_access) { - implementation_file.append_line(std::format(STR("{}{}.AddDefaulted({});"), property_scope, property->GetName(), property_value->Num())); + implementation_file.append_line( + std::format(SYSSTR("{}{}.AddDefaulted({});"), property_scope, to_system(property->GetName()), (int32_t)property_value->Num())); } else { @@ -1729,16 +1759,16 @@ namespace RC::UEGenerator super_and_no_access = private_access_modifier; } - std::wstring number_constant_string; + SystemStringType number_constant_string; if (!numeric_property->IsFloatingPoint()) { int64 value = numeric_property->GetSignedIntPropertyValue(numeric_property->ContainerPtrToValuePtr(object)); - number_constant_string = std::to_wstring(value); + number_constant_string = to_system(ToString(value)); } else { double value = numeric_property->GetFloatingPointPropertyValue(numeric_property->ContainerPtrToValuePtr(object)); - number_constant_string = std::format(STR("{:.2f}f"), value); + number_constant_string = std::format(SYSSTR("{:.2f}f"), value); } if (!super_and_no_access) { @@ -1758,24 +1788,24 @@ namespace RC::UEGenerator bool is_generating_interface, const CaseInsensitiveSet& blacklisted_property_names) -> void { - const std::wstring class_native_name = get_native_class_name(uclass, is_generating_interface); - const std::wstring raw_function_name = function->GetName(); + const auto class_native_name = get_native_class_name(uclass, is_generating_interface); + const auto raw_function_name = to_system(function->GetName()); auto function_flags = function->GetFunctionFlags(); - PropertyTypeDeclarationContext context(uclass->GetName(), &implementation_file); + PropertyTypeDeclarationContext context(to_system(uclass->GetName()), &implementation_file); - std::wstring function_implementation_name; - std::wstring net_validate_function_name; + SystemStringType function_implementation_name; + SystemStringType net_validate_function_name; bool is_input_function_const = ((function_flags)&FUNC_Const) != 0; if ((function_flags & FUNC_Net) != 0) { // Network functions always have the implementation inside the _Implementation function - function_implementation_name = std::format(STR("{}::{}_Implementation"), class_native_name, raw_function_name); + function_implementation_name = std::format(SYSSTR("{}::{}_Implementation"), class_native_name, raw_function_name); // Validated network functions by default have their validation function name set to _Validate if ((function_flags & FUNC_NetValidate) != 0) { - net_validate_function_name = std::format(STR("{}::{}_Validate"), class_native_name, raw_function_name); + net_validate_function_name = std::format(SYSSTR("{}::{}_Validate"), class_native_name, raw_function_name); } } else if ((function_flags & FUNC_BlueprintEvent) != 0) @@ -1784,16 +1814,16 @@ namespace RC::UEGenerator // BlueprintImplementableEvents do not have any native functions at all, they're just thunks if ((function_flags & FUNC_Native) != 0) { - function_implementation_name = std::format(STR("{}::{}_Implementation"), class_native_name, raw_function_name); + function_implementation_name = std::format(SYSSTR("{}::{}_Implementation"), class_native_name, raw_function_name); } } else { // Otherwise, normal UFunctions get a standard name matching the function in question - function_implementation_name = std::format(STR("{}::{}"), class_native_name, raw_function_name); + function_implementation_name = std::format(SYSSTR("{}::{}"), class_native_name, raw_function_name); } - std::wstring function_parameter_list; + SystemStringType function_parameter_list; if (!function_implementation_name.empty() || !net_validate_function_name.empty()) { function_parameter_list = @@ -1804,63 +1834,63 @@ namespace RC::UEGenerator { FProperty* return_value_property = function->GetReturnProperty(); - const std::wstring return_value_type = return_value_property ? generate_property_type_declaration(return_value_property, context) : STR("void"); + const SystemStringType return_value_type = return_value_property ? generate_property_type_declaration(return_value_property, context) : SYSSTR("void"); - implementation_file.append_line(std::format(STR("{} {}({}){} {{"), + implementation_file.append_line(std::format(SYSSTR("{} {}({}){} {{"), return_value_type, function_implementation_name, function_parameter_list, - is_input_function_const ? STR(" const") : STR(""))); + is_input_function_const ? SYSSTR(" const") : SYSSTR(""))); implementation_file.begin_indent_level(); if (return_value_property != NULL) { - const std::wstring default_value = generate_default_property_value(return_value_property, implementation_file, context.context_name); - implementation_file.append_line(std::format(STR("return {};"), default_value)); + const SystemStringType default_value = generate_default_property_value(return_value_property, implementation_file, context.context_name); + implementation_file.append_line(std::format(SYSSTR("return {};"), default_value)); } implementation_file.end_indent_level(); - implementation_file.append_line(STR("}")); + implementation_file.append_line(SYSSTR("}")); } if (!net_validate_function_name.empty()) { - implementation_file.append_line(std::format(STR("bool {}({}) {{"), net_validate_function_name, function_parameter_list)); + implementation_file.append_line(std::format(SYSSTR("bool {}({}) {{"), net_validate_function_name, function_parameter_list)); implementation_file.begin_indent_level(); - implementation_file.append_line(STR("return true;")); + implementation_file.append_line(SYSSTR("return true;")); implementation_file.end_indent_level(); - implementation_file.append_line(STR("}")); + implementation_file.append_line(SYSSTR("}")); } } - auto UEHeaderGenerator::generate_parameter_count_string(int32_t parameter_count) -> std::wstring + auto UEHeaderGenerator::generate_parameter_count_string(int32_t parameter_count) -> SystemStringType { switch (parameter_count) { case 0: - return STR(""); + return SYSSTR(""); case 1: - return STR("_OneParam"); + return SYSSTR("_OneParam"); case 2: - return STR("_TwoParams"); + return SYSSTR("_TwoParams"); case 3: - return STR("_ThreeParams"); + return SYSSTR("_ThreeParams"); case 4: - return STR("_FourParams"); + return SYSSTR("_FourParams"); case 5: - return STR("_FiveParams"); + return SYSSTR("_FiveParams"); case 6: - return STR("_SixParams"); + return SYSSTR("_SixParams"); case 7: - return STR("_SevenParams"); + return SYSSTR("_SevenParams"); case 8: - return STR("_EightParams"); + return SYSSTR("_EightParams"); case 9: - return STR("_NineParams"); + return SYSSTR("_NineParams"); default: - return STR("_TooMany"); + return SYSSTR("_TooMany"); } } @@ -1872,15 +1902,15 @@ namespace RC::UEGenerator if (needed_access == AccessModifier::Public) { - header_data.append_line_no_indent(STR("public:")); + header_data.append_line_no_indent(SYSSTR("public:")); } else if (needed_access == AccessModifier::Protected) { - header_data.append_line_no_indent(STR("protected:")); + header_data.append_line_no_indent(SYSSTR("protected:")); } else if (needed_access == AccessModifier::Private) { - header_data.append_line_no_indent(STR("private:")); + header_data.append_line_no_indent(SYSSTR("private:")); } } } @@ -1923,40 +1953,40 @@ namespace RC::UEGenerator return AccessModifier::Public; } - auto UEHeaderGenerator::create_string_literal(const std::wstring& string) -> std::wstring + auto UEHeaderGenerator::create_string_literal(const SystemStringType& string) -> SystemStringType { - std::wstring result; - result.append(STR("TEXT(\"")); + SystemStringType result; + result.append(SYSSTR("TEXT(\"")); bool previous_character_was_hex = false; - const wchar_t* ptr = string.c_str(); - while (wchar_t ch = *ptr++) + const SystemCharType* ptr = string.c_str(); + while (SystemCharType ch = *ptr++) { switch (ch) { - case STR('\r'): { + case SYSSTR('\r'): { continue; } - case STR('\n'): { - result.append(STR("\\n")); + case SYSSTR('\n'): { + result.append(SYSSTR("\\n")); previous_character_was_hex = false; break; } - case STR('\\'): { - result.append(STR("\\\\")); + case SYSSTR('\\'): { + result.append(SYSSTR("\\\\")); previous_character_was_hex = false; break; } - case STR('\"'): { - result.append(STR("\\\"")); + case SYSSTR('\"'): { + result.append(SYSSTR("\\\"")); previous_character_was_hex = false; break; } default: { - if (ch < 31 || ch >= 128) + if ((unsigned char)ch < 31 || (unsigned char)ch >= 128) { - result.append(std::format(STR("\\x{:04X}"), ch)); + result.append(std::format(SYSSTR("\\x{:04X}"), ch)); previous_character_was_hex = true; } else @@ -1965,7 +1995,7 @@ namespace RC::UEGenerator // appended to the hex sequence, causing a different number if (previous_character_was_hex && iswxdigit(ch) != 0) { - result.append(STR("\")TEXT(\"")); + result.append(SYSSTR("\")TEXT(\"")); } previous_character_was_hex = false; result.push_back(ch); @@ -1974,19 +2004,19 @@ namespace RC::UEGenerator } } } - result.append(STR("\")")); + result.append(SYSSTR("\")")); return result; } - auto UEHeaderGenerator::convert_module_name_to_api_name(const std::wstring& module_name) -> std::wstring + auto UEHeaderGenerator::convert_module_name_to_api_name(const SystemStringType& module_name) -> SystemStringType { - std::wstring uppercase_string = string_to_uppercase(module_name); - uppercase_string.append(STR("_API")); + SystemStringType uppercase_string = string_to_uppercase(module_name); + uppercase_string.append(SYSSTR("_API")); return uppercase_string; } - auto UEHeaderGenerator::add_module_and_sub_module_dependencies(std::set& out_module_dependencies, - const std::wstring& module_name, + auto UEHeaderGenerator::add_module_and_sub_module_dependencies(std::set& out_module_dependencies, + const SystemStringType& module_name, bool add_self_module) -> void { // Prevent infinite recursion @@ -2002,7 +2032,7 @@ namespace RC::UEGenerator const auto iterator = m_module_dependencies.find(module_name); if (iterator != m_module_dependencies.end()) { - for (const std::wstring& DependencyModuleName : *iterator->second) + for (const SystemStringType& DependencyModuleName : *iterator->second) { out_module_dependencies.insert(DependencyModuleName); } @@ -2019,12 +2049,12 @@ namespace RC::UEGenerator for (FProperty* property : class_object->ForEachProperty()) { - result_set.insert(property->GetName()); + result_set.insert(to_system(property->GetName())); } for (UFunction* function : class_object->ForEachFunction()) { - result_set.insert(function->GetName()); + result_set.insert(to_system(function->GetName())); } } else if (uclass->GetClassPrivate()->IsChildOf(UScriptStruct::StaticClass())) @@ -2033,7 +2063,7 @@ namespace RC::UEGenerator for (FProperty* property : script_struct->ForEachProperty()) { - result_set.insert(property->GetName()); + result_set.insert(to_system(property->GetName())); } } return result_set; @@ -2041,7 +2071,7 @@ namespace RC::UEGenerator // TODO CannotImplementInterfaceInBlueprint is not exactly right, // TODO you can have interface with no implementable blueprint methods but that you can still implement in blueprint - auto UEHeaderGenerator::generate_interface_flags(UClass* uinterface) const -> std::wstring + auto UEHeaderGenerator::generate_interface_flags(UClass* uinterface) const -> SystemStringType { FlagFormatHelper flag_format_helper{}; @@ -2053,7 +2083,7 @@ namespace RC::UEGenerator if ((class_own_flags & CLASS_MinimalAPI) != 0) { - flag_format_helper.add_switch(STR("MinimalAPI")); + flag_format_helper.add_switch(SYSSTR("MinimalAPI")); } ClassBlueprintInfo blueprint_info = get_class_blueprint_info(uinterface); @@ -2063,22 +2093,22 @@ namespace RC::UEGenerator { if (!parent_blueprint_info.is_blueprintable) { - flag_format_helper.add_switch(STR("Blueprintable")); + flag_format_helper.add_switch(SYSSTR("Blueprintable")); } } else if (blueprint_info.is_blueprint_type) { if (!parent_blueprint_info.is_blueprint_type) { - flag_format_helper.add_switch(STR("BlueprintType")); + flag_format_helper.add_switch(SYSSTR("BlueprintType")); } - flag_format_helper.get_meta()->add_switch(STR("CannotImplementInterfaceInBlueprint")); + flag_format_helper.get_meta()->add_switch(SYSSTR("CannotImplementInterfaceInBlueprint")); } return flag_format_helper.build_flag_string(); } - auto UEHeaderGenerator::generate_class_flags(UClass* uclass) const -> std::wstring + auto UEHeaderGenerator::generate_class_flags(UClass* uclass) const -> SystemStringType { FlagFormatHelper flag_format_helper{}; @@ -2090,7 +2120,7 @@ namespace RC::UEGenerator if ((class_own_flags & CLASS_MinimalAPI) != 0) { - flag_format_helper.add_switch(STR("MinimalAPI")); + flag_format_helper.add_switch(SYSSTR("MinimalAPI")); } ClassBlueprintInfo blueprint_info = get_class_blueprint_info(uclass); @@ -2102,7 +2132,7 @@ namespace RC::UEGenerator if (UE4SSProgram::settings_manager.UHTHeaderGenerator.MakeAllPropertyBlueprintsReadWrite) { - flag_format_helper.add_switch(STR("Blueprintable")); + flag_format_helper.add_switch(SYSSTR("Blueprintable")); } else { @@ -2110,97 +2140,97 @@ namespace RC::UEGenerator { if (!parent_blueprint_info.is_blueprintable) { - flag_format_helper.add_switch(STR("Blueprintable")); + flag_format_helper.add_switch(SYSSTR("Blueprintable")); } } else if (blueprint_info.is_blueprint_type) { if (!parent_blueprint_info.is_blueprint_type) { - flag_format_helper.add_switch(STR("BlueprintType")); + flag_format_helper.add_switch(SYSSTR("BlueprintType")); } } } if ((class_own_flags & CLASS_Deprecated) != 0) { - flag_format_helper.add_switch(STR("Deprecated")); + flag_format_helper.add_switch(SYSSTR("Deprecated")); } if ((class_own_flags & CLASS_Abstract) != 0) { - flag_format_helper.add_switch(STR("Abstract")); + flag_format_helper.add_switch(SYSSTR("Abstract")); } if ((class_own_flags & CLASS_MinimalAPI) != 0) { - flag_format_helper.add_switch(STR("MinimalAPI")); + flag_format_helper.add_switch(SYSSTR("MinimalAPI")); } if ((class_own_flags & CLASS_NoExport) != 0) { - flag_format_helper.add_switch(STR("NoExport")); + flag_format_helper.add_switch(SYSSTR("NoExport")); } // TODO not quite the case, because UHT boilerplate implicitly marks every native class as CLASS_Intrinsic // if ((ClassOwnFlags & CLASS_Intrinsic) != 0) { - // FlagFormatHelper.AddSwitch(STR("Intrinsic")); + // FlagFormatHelper.AddSwitch(SYSSTR("Intrinsic")); // } if ((class_own_flags & CLASS_Const) != 0) { - flag_format_helper.add_switch(STR("Const")); + flag_format_helper.add_switch(SYSSTR("Const")); } if ((class_own_flags & CLASS_DefaultToInstanced) != 0) { - flag_format_helper.add_switch(STR("DefaultToInstanced")); + flag_format_helper.add_switch(SYSSTR("DefaultToInstanced")); } UClass* class_within = uclass->GetClassWithin(); if (class_within != NULL && class_within != UObject::StaticClass() && (super_class == NULL || class_within != super_class->GetClassWithin())) { - flag_format_helper.add_parameter(STR("Within"), class_within->GetName()); + flag_format_helper.add_parameter(SYSSTR("Within"), to_system(class_within->GetName())); } if ((class_own_flags & CLASS_Transient) != 0) { - flag_format_helper.add_switch(STR("Transient")); + flag_format_helper.add_switch(SYSSTR("Transient")); } else if ((parent_class_flags & CLASS_Transient) != 0) { - flag_format_helper.add_switch(STR("NonTransient")); + flag_format_helper.add_switch(SYSSTR("NonTransient")); } if ((class_own_flags & CLASS_EditInlineNew) != 0) { - flag_format_helper.add_switch(STR("EditInlineNew")); + flag_format_helper.add_switch(SYSSTR("EditInlineNew")); } else if ((class_flags & CLASS_EditInlineNew) == 0 && (parent_class_flags & CLASS_EditInlineNew) != 0) { - flag_format_helper.add_switch(STR("NotEditInlineNew")); + flag_format_helper.add_switch(SYSSTR("NotEditInlineNew")); } if ((class_own_flags & CLASS_NotPlaceable) != 0) { - flag_format_helper.add_switch(STR("NotPlaceable")); + flag_format_helper.add_switch(SYSSTR("NotPlaceable")); } else if ((class_flags & CLASS_NotPlaceable) == 0 && (parent_class_flags & CLASS_NotPlaceable) != 0) { - flag_format_helper.add_switch(STR("Placeable")); + flag_format_helper.add_switch(SYSSTR("Placeable")); } bool add_config_name{false}; if ((class_own_flags & CLASS_DefaultConfig) != 0) { - flag_format_helper.add_switch(STR("DefaultConfig")); + flag_format_helper.add_switch(SYSSTR("DefaultConfig")); add_config_name = true; } if ((class_own_flags & CLASS_GlobalUserConfig) != 0) { - flag_format_helper.add_switch(STR("GlobalUserConfig")); + flag_format_helper.add_switch(SYSSTR("GlobalUserConfig")); add_config_name = true; } if ((class_own_flags & CLASS_ProjectUserConfig) != 0) { - flag_format_helper.add_switch(STR("ProjectUserConfig")); + flag_format_helper.add_switch(SYSSTR("ProjectUserConfig")); add_config_name = true; } @@ -2212,65 +2242,65 @@ namespace RC::UEGenerator } } - const std::wstring class_config_name = uclass->GetClassConfigName().ToString(); + const auto class_config_name = uclass->GetClassConfigName().ToString(); if (super_class == NULL || class_config_name != super_class->GetClassConfigName().ToString()) { - flag_format_helper.add_parameter(STR("Config"), class_config_name); + flag_format_helper.add_parameter(SYSSTR("Config"), to_system(class_config_name)); // Don't add our override config if we add the real one here add_config_name = false; } if (UE4SSProgram::settings_manager.UHTHeaderGenerator.MakeAllConfigsEngineConfig && add_config_name) { - flag_format_helper.add_parameter(STR("Config"), STR("Engine")); + flag_format_helper.add_parameter(SYSSTR("Config"), SYSSTR("Engine")); } if ((class_own_flags & CLASS_PerObjectConfig) != 0) { - flag_format_helper.add_switch(STR("PerObjectConfig")); + flag_format_helper.add_switch(SYSSTR("PerObjectConfig")); } if ((class_own_flags & CLASS_ConfigDoNotCheckDefaults) != 0) { - flag_format_helper.add_switch(STR("ConfigDoNotCheckDefaults")); + flag_format_helper.add_switch(SYSSTR("ConfigDoNotCheckDefaults")); } if ((class_own_flags & CLASS_HideDropDown) != 0) { - flag_format_helper.add_switch(STR("HideDropdown")); + flag_format_helper.add_switch(SYSSTR("HideDropdown")); } if ((class_own_flags & CLASS_CollapseCategories) != 0) { - flag_format_helper.add_switch(STR("CollapseCategories")); + flag_format_helper.add_switch(SYSSTR("CollapseCategories")); } else if ((parent_class_flags & CLASS_CollapseCategories) != 0) { - flag_format_helper.add_switch(STR("DontCollapseCategories")); + flag_format_helper.add_switch(SYSSTR("DontCollapseCategories")); } // Mark all UActorComponent derived classes as BlueprintSpawnableComponent by default // This will allow using them inside the Simple Construction Script of the blueprint assets if (uclass->IsChildOf()) { - flag_format_helper.get_meta()->add_switch(STR("BlueprintSpawnableComponent")); - flag_format_helper.add_parameter(STR("ClassGroup"), STR("Custom")); + flag_format_helper.get_meta()->add_switch(SYSSTR("BlueprintSpawnableComponent")); + flag_format_helper.add_parameter(SYSSTR("ClassGroup"), SYSSTR("Custom")); } return flag_format_helper.build_flag_string(); } /**/ - auto UEHeaderGenerator::generate_property_type_declaration(FProperty* property, const PropertyTypeDeclarationContext& context) -> std::wstring + auto UEHeaderGenerator::generate_property_type_declaration(FProperty* property, const PropertyTypeDeclarationContext& context) -> SystemStringType { UClass* current_class = Unreal::Cast(property->GetOutermostOwner()); - const std::wstring field_class_name = property->GetClass().GetName(); + const auto field_class_name = property->GetClass().GetName(); // Byte Property if (property->IsA()) { FByteProperty* byte_property = static_cast(property); UEnum* enum_value = byte_property->GetEnum(); - + if (enum_value != NULL) { if (context.source_file != NULL) @@ -2278,7 +2308,7 @@ namespace RC::UEGenerator context.source_file->add_dependency_object(enum_value, DependencyLevel::Include); } - const std::wstring enum_type_name = get_native_enum_name(enum_value); + const SystemStringType enum_type_name = get_native_enum_name(enum_value); if ((property->GetPropertyFlags() & CPF_BlueprintVisible) != 0) { @@ -2286,9 +2316,9 @@ namespace RC::UEGenerator } // Non-EnumClass enumerations should be wrapped into TEnumAsByte according to UHT, but implicit uint8s should not use TEnumAsByte - return std::format(STR("TEnumAsByte<{}>"), enum_type_name); + return std::format(SYSSTR("TEnumAsByte<{}>"), enum_type_name); } - return STR("uint8"); + return SYSSTR("uint8"); } // Enum Property @@ -2299,20 +2329,20 @@ namespace RC::UEGenerator UEnum* uenum = enum_property->GetEnum(); if (uenum == NULL) { - throw std::runtime_error(RC::fmt("EnumProperty %S does not have a valid Enum value", property->GetName().c_str())); + throw std::runtime_error(RC::fmt("EnumProperty {} does not have a valid Enum value", property->GetName())); } if (context.source_file != NULL) { context.source_file->add_dependency_object(uenum, DependencyLevel::Include); } - const std::wstring enum_type_name = get_native_enum_name(uenum); + const SystemStringType enum_type_name = get_native_enum_name(uenum); if ((property->GetPropertyFlags() & CPF_BlueprintVisible) != 0) { this->m_blueprint_visible_enums.insert(enum_type_name); } - const std::wstring underlying_enum_type = generate_property_type_declaration(underlying_property, context); + const SystemStringType underlying_enum_type = generate_property_type_declaration(underlying_property, context); this->m_underlying_enum_types.insert({enum_type_name, underlying_enum_type}); return enum_type_name; } @@ -2326,48 +2356,48 @@ namespace RC::UEGenerator if (bool_property->GetFieldMask() != 255) { *context.out_is_bitmask_bool = true; - return STR("uint8"); + return SYSSTR("uint8"); } } - return STR("bool"); + return SYSSTR("bool"); } // Standard Numeric Properties if (property->IsA()) { - return STR("int8"); + return SYSSTR("int8"); } else if (property->IsA()) { - return STR("int16"); + return SYSSTR("int16"); } else if (property->IsA()) { - return STR("int32"); + return SYSSTR("int32"); } else if (property->IsA()) { - return STR("int64"); + return SYSSTR("int64"); } else if (property->IsA()) { - return STR("uint16"); + return SYSSTR("uint16"); } else if (property->IsA()) { - return STR("uint32"); + return SYSSTR("uint32"); } else if (property->IsA()) { - return STR("uint64"); + return SYSSTR("uint64"); } else if (property->IsA()) { - return STR("float"); + return SYSSTR("float"); } else if (property->IsA()) { - return STR("double"); + return SYSSTR("double"); } // Class Properties @@ -2378,23 +2408,23 @@ namespace RC::UEGenerator if (meta_class == NULL || meta_class == UObject::StaticClass()) { - return STR("UClass*"); + return SYSSTR("UClass*"); } if (context.source_file != NULL) { context.source_file->add_dependency_object(meta_class, DependencyLevel::PreDeclaration); - context.source_file->add_extra_include(STR("Templates/SubclassOf.h")); + context.source_file->add_extra_include(SYSSTR("Templates/SubclassOf.h")); } - const std::wstring meta_class_name = get_native_class_name(meta_class, false); + const SystemStringType meta_class_name = get_native_class_name(meta_class, false); - return std::format(STR("TSubclassOf<{}>"), meta_class_name); + return std::format(SYSSTR("TSubclassOf<{}>"), meta_class_name); } if (auto* class_property = CastField(property); class_property) { // TODO: Confirm that this is accurate - return STR("TClassPtr"); + return SYSSTR("TClassPtr"); } if (property->IsA()) @@ -2404,16 +2434,16 @@ namespace RC::UEGenerator if (meta_class == NULL || meta_class == UObject::StaticClass()) { - return STR("TSoftClassPtr"); + return SYSSTR("TSoftClassPtr"); } if (context.source_file != NULL) { context.source_file->add_dependency_object(meta_class, DependencyLevel::PreDeclaration); } - const std::wstring meta_class_name = get_native_class_name(meta_class, false); + const SystemStringType meta_class_name = get_native_class_name(meta_class, false); - return std::format(STR("TSoftClassPtr<{}>"), meta_class_name); + return std::format(SYSSTR("TSoftClassPtr<{}>"), meta_class_name); } // Object Properties @@ -2426,15 +2456,15 @@ namespace RC::UEGenerator if (property_class == NULL) { - return STR("UObject*"); + return SYSSTR("UObject*"); } if (context.source_file != NULL) { context.source_file->add_dependency_object(property_class, DependencyLevel::PreDeclaration); } - const std::wstring property_class_name = get_native_class_name(property_class, false); + const SystemStringType property_class_name = get_native_class_name(property_class, false); - return std::format(STR("{}*"), property_class_name); + return std::format(SYSSTR("{}*"), property_class_name); } if (auto* object_property = CastField(property); object_property) @@ -2443,7 +2473,7 @@ namespace RC::UEGenerator if (!property_class) { - return STR("TObjectPtr"); + return SYSSTR("TObjectPtr"); } else { @@ -2453,7 +2483,7 @@ namespace RC::UEGenerator } const auto property_class_name = get_native_class_name(property_class, false); - return std::format(STR("TObjectPtr<{}>"), property_class_name); + return std::format(SYSSTR("TObjectPtr<{}>"), property_class_name); } } @@ -2464,16 +2494,16 @@ namespace RC::UEGenerator if (property_class == NULL) { - return STR("TWeakObjectPtr"); + return SYSSTR("TWeakObjectPtr"); } if (context.source_file != NULL) { context.source_file->add_dependency_object(property_class, DependencyLevel::PreDeclaration); } - const std::wstring property_class_name = get_native_class_name(property_class, false); + const SystemStringType property_class_name = get_native_class_name(property_class, false); - return std::format(STR("TWeakObjectPtr<{}>"), property_class_name); + return std::format(SYSSTR("TWeakObjectPtr<{}>"), property_class_name); } if (property->IsA()) @@ -2483,16 +2513,16 @@ namespace RC::UEGenerator if (property_class == NULL) { - return STR("TLazyObjectPtr"); + return SYSSTR("TLazyObjectPtr"); } if (context.source_file != NULL) { context.source_file->add_dependency_object(property_class, DependencyLevel::PreDeclaration); } - const std::wstring property_class_name = get_native_class_name(property_class, false); + const SystemStringType property_class_name = get_native_class_name(property_class, false); - return std::format(STR("TLazyObjectPtr<{}>"), property_class_name); + return std::format(SYSSTR("TLazyObjectPtr<{}>"), property_class_name); } if (property->IsA()) @@ -2502,16 +2532,16 @@ namespace RC::UEGenerator if (property_class == NULL) { - return STR("TSoftObjectPtr"); + return SYSSTR("TSoftObjectPtr"); } if (context.source_file != NULL) { context.source_file->add_dependency_object(property_class, DependencyLevel::PreDeclaration); } - const std::wstring property_class_name = get_native_class_name(property_class, false); + const SystemStringType property_class_name = get_native_class_name(property_class, false); - return std::format(STR("TSoftObjectPtr<{}>"), property_class_name); + return std::format(SYSSTR("TSoftObjectPtr<{}>"), property_class_name); } // Interface Property @@ -2522,16 +2552,16 @@ namespace RC::UEGenerator if (interface_class == NULL || interface_class == UInterface::StaticClass()) { - return STR("FScriptInterface"); + return SYSSTR("FScriptInterface"); } if (context.source_file != NULL) { context.source_file->add_dependency_object(interface_class, DependencyLevel::PreDeclaration); } - const std::wstring interface_class_name = get_native_class_name(interface_class, true); + const SystemStringType interface_class_name = get_native_class_name(interface_class, true); - return std::format(STR("TScriptInterface<{}>"), interface_class_name); + return std::format(SYSSTR("TScriptInterface<{}>"), interface_class_name); } // Struct Property @@ -2542,9 +2572,9 @@ namespace RC::UEGenerator if (script_struct == NULL) { - throw std::runtime_error(RC::fmt("Struct is NULL for StructProperty %S", property->GetName().c_str())); + throw std::runtime_error(RC::fmt("Struct is NULL for StructProperty {}", property->GetName())); } - const std::wstring native_struct_name = get_native_struct_name(script_struct); + const SystemStringType native_struct_name = get_native_struct_name(script_struct); if (context.source_file != NULL) { @@ -2613,8 +2643,8 @@ namespace RC::UEGenerator if (property->IsA()) { FFieldPathProperty* field_path_property = static_cast(property); - const std::wstring property_class_name = field_path_property->GetPropertyClass()->GetName(); - return std::format(STR("TFieldPath"), property_class_name); + const auto property_class_name = to_system(field_path_property->GetPropertyClass()->GetName()); + return std::format(SYSSTR("TFieldPath"), property_class_name); } // Collection and Map Properties @@ -2624,8 +2654,8 @@ namespace RC::UEGenerator FArrayProperty* array_property = static_cast(property); FProperty* inner_property = array_property->GetInner(); - const std::wstring inner_property_type = generate_property_type_declaration(inner_property, context.inner_context()); - return std::format(STR("TArray<{}>"), inner_property_type); + const SystemStringType inner_property_type = generate_property_type_declaration(inner_property, context.inner_context()); + return std::format(SYSSTR("TArray<{}>"), inner_property_type); } if (property->IsA()) @@ -2633,8 +2663,8 @@ namespace RC::UEGenerator FSetProperty* set_property = static_cast(property); FProperty* element_prop = set_property->GetElementProp(); - const std::wstring element_property_type = generate_property_type_declaration(element_prop, context.inner_context()); - return std::format(STR("TSet<{}>"), element_property_type); + const SystemStringType element_property_type = generate_property_type_declaration(element_prop, context.inner_context()); + return std::format(SYSSTR("TSet<{}>"), element_property_type); } // TODO: This is missing support for freeze image map properties because XMapProperty is incomplete. (low priority) @@ -2644,63 +2674,62 @@ namespace RC::UEGenerator FProperty* key_property = map_property->GetKeyProp(); FProperty* value_property = map_property->GetValueProp(); - const std::wstring key_type = generate_property_type_declaration(key_property, context.inner_context()); - const std::wstring value_type = generate_property_type_declaration(value_property, context.inner_context()); + const SystemStringType key_type = generate_property_type_declaration(key_property, context.inner_context()); + const SystemStringType value_type = generate_property_type_declaration(value_property, context.inner_context()); - return std::format(STR("TMap<{}, {}>"), key_type, value_type); + return std::format(SYSSTR("TMap<{}, {}>"), key_type, value_type); } // Standard properties that do not have any special attributes if (property->IsA()) { - return STR("FName"); + return SYSSTR("FName"); } else if (property->IsA()) { - return STR("FString"); + return SYSSTR("FString"); } else if (property->IsA()) { - return STR("FText"); + return SYSSTR("FText"); } - throw std::runtime_error(RC::fmt("[generate_property_type_declaration] Unsupported property class '%S', full name: '%S'", - field_class_name.c_str(), - property->GetFullName().c_str())); + throw std::runtime_error( + RC::fmt("[generate_property_type_declaration] Unsupported property class '{}', full name: '{}'", field_class_name, property->GetFullName())); } //*/ - auto UEHeaderGenerator::generate_function_argument_flags(FProperty* property) const -> std::wstring + auto UEHeaderGenerator::generate_function_argument_flags(FProperty* property) const -> SystemStringType { FlagFormatHelper flag_format_helper{}; auto property_flags = property->GetPropertyFlags(); // CPF_ConstParm is handled explicitly in the parameter list generator, it will generate const before parameter // if ((PropertyFlags & CPF_ConstParm) != 0) { - // FlagFormatHelper.AddSwitch(STR("Const")); + // FlagFormatHelper.AddSwitch(SYSSTR("Const")); // } // We only want to add UPARAM(Ref) when parameter is marked as reference AND output, // while not being marked as constant, because if it's marked as constant, it might be a parameter passed by const reference if ((property_flags & CPF_ReferenceParm) != 0 && (property_flags & CPF_OutParm) != 0 && (property_flags & CPF_ConstParm) == 0) { - flag_format_helper.add_switch(STR("Ref")); + flag_format_helper.add_switch(SYSSTR("Ref")); } if ((property_flags & CPF_RepSkip) != 0) { - flag_format_helper.add_switch(STR("NotReplicated")); + flag_format_helper.add_switch(SYSSTR("NotReplicated")); } return flag_format_helper.build_flag_string(); } - auto UEHeaderGenerator::generate_property_flags(FProperty* property) const -> std::wstring + auto UEHeaderGenerator::generate_property_flags(FProperty* property) const -> SystemStringType { FlagFormatHelper flag_format_helper{}; auto property_flags = property->GetPropertyFlags(); if (UE4SSProgram::settings_manager.UHTHeaderGenerator.MakeAllPropertyBlueprintsReadWrite) { - flag_format_helper.add_switch(STR("EditAnywhere")); + flag_format_helper.add_switch(SYSSTR("EditAnywhere")); } else if ((property_flags & CPF_Edit) != 0) { @@ -2708,97 +2737,97 @@ namespace RC::UEGenerator { if ((property_flags & CPF_DisableEditOnTemplate) != 0) { - flag_format_helper.add_switch(STR("VisibleInstanceOnly")); + flag_format_helper.add_switch(SYSSTR("VisibleInstanceOnly")); } else if ((property_flags & CPF_DisableEditOnInstance) != 0) { - flag_format_helper.add_switch(STR("VisibleDefaultsOnly")); + flag_format_helper.add_switch(SYSSTR("VisibleDefaultsOnly")); } else { - flag_format_helper.add_switch(STR("VisibleAnywhere")); + flag_format_helper.add_switch(SYSSTR("VisibleAnywhere")); } } else { if ((property_flags & CPF_DisableEditOnTemplate) != 0) { - flag_format_helper.add_switch(STR("EditInstanceOnly")); + flag_format_helper.add_switch(SYSSTR("EditInstanceOnly")); } else if ((property_flags & CPF_DisableEditOnInstance) != 0) { - flag_format_helper.add_switch(STR("EditDefaultsOnly")); + flag_format_helper.add_switch(SYSSTR("EditDefaultsOnly")); } else { - flag_format_helper.add_switch(STR("EditAnywhere")); + flag_format_helper.add_switch(SYSSTR("EditAnywhere")); } } } if ((property_flags & CPF_NoClear) != 0) { - flag_format_helper.add_switch(STR("NoClear")); + flag_format_helper.add_switch(SYSSTR("NoClear")); } if ((property_flags & CPF_EditFixedSize) != 0) { - flag_format_helper.add_switch(STR("EditFixedSize")); + flag_format_helper.add_switch(SYSSTR("EditFixedSize")); } if ((property_flags & CPF_SimpleDisplay) != 0) { - flag_format_helper.add_switch(STR("SimpleDisplay")); + flag_format_helper.add_switch(SYSSTR("SimpleDisplay")); } if ((property_flags & CPF_AdvancedDisplay) != 0) { - flag_format_helper.add_switch(STR("AdvancedDisplay")); + flag_format_helper.add_switch(SYSSTR("AdvancedDisplay")); } if (UE4SSProgram::settings_manager.UHTHeaderGenerator.MakeAllPropertyBlueprintsReadWrite) { if (property->GetArrayDim() == 1 && is_subtype_valid(property)) { - flag_format_helper.add_switch(STR("BlueprintReadWrite")); + flag_format_helper.add_switch(SYSSTR("BlueprintReadWrite")); } - flag_format_helper.get_meta()->add_parameter(STR("AllowPrivateAccess"), STR("true")); + flag_format_helper.get_meta()->add_parameter(SYSSTR("AllowPrivateAccess"), SYSSTR("true")); } else if ((property_flags & CPF_BlueprintVisible) != 0) { if ((property_flags & CPF_BlueprintReadOnly) != 0) { - flag_format_helper.add_switch(STR("BlueprintReadOnly")); + flag_format_helper.add_switch(SYSSTR("BlueprintReadOnly")); } else { - flag_format_helper.add_switch(STR("BlueprintReadWrite")); + flag_format_helper.add_switch(SYSSTR("BlueprintReadWrite")); } if ((property_flags & CPF_NativeAccessSpecifierPrivate) != 0) { - flag_format_helper.get_meta()->add_parameter(STR("AllowPrivateAccess"), STR("true")); + flag_format_helper.get_meta()->add_parameter(SYSSTR("AllowPrivateAccess"), SYSSTR("true")); } } if ((property_flags & CPF_BlueprintAssignable) != 0) { - flag_format_helper.add_switch(STR("BlueprintAssignable")); + flag_format_helper.add_switch(SYSSTR("BlueprintAssignable")); } if ((property_flags & CPF_BlueprintCallable) != 0) { - flag_format_helper.add_switch(STR("BlueprintCallable")); + flag_format_helper.add_switch(SYSSTR("BlueprintCallable")); } if ((property_flags & CPF_BlueprintAuthorityOnly) != 0) { - flag_format_helper.add_switch(STR("BlueprintAuthorityOnly")); + flag_format_helper.add_switch(SYSSTR("BlueprintAuthorityOnly")); } if ((property_flags & CPF_Config) != 0) { if ((property_flags & CPF_GlobalConfig) != 0) { - flag_format_helper.add_switch(STR("GlobalConfig")); + flag_format_helper.add_switch(SYSSTR("GlobalConfig")); } else { - flag_format_helper.add_switch(STR("Config")); + flag_format_helper.add_switch(SYSSTR("Config")); } } @@ -2806,55 +2835,55 @@ namespace RC::UEGenerator { if ((property_flags & CPF_RepNotify) != 0) { - const std::wstring rep_notify_func_name = property->GetRepNotifyFunc().ToString(); - flag_format_helper.add_parameter(STR("ReplicatedUsing"), rep_notify_func_name); + const auto rep_notify_func_name = to_system(property->GetRepNotifyFunc().ToString()); + flag_format_helper.add_parameter(SYSSTR("ReplicatedUsing"), rep_notify_func_name); } else { - flag_format_helper.add_switch(STR("Replicated")); + flag_format_helper.add_switch(SYSSTR("Replicated")); } } if ((property_flags & CPF_RepSkip) != 0) { - flag_format_helper.add_switch(STR("NotReplicated")); + flag_format_helper.add_switch(SYSSTR("NotReplicated")); } if ((property_flags & CPF_AssetRegistrySearchable) != 0) { - flag_format_helper.add_switch(STR("AssetRegistrySearchable")); + flag_format_helper.add_switch(SYSSTR("AssetRegistrySearchable")); } if ((property_flags & CPF_Interp) != 0) { - flag_format_helper.add_switch(STR("Interp")); + flag_format_helper.add_switch(SYSSTR("Interp")); } if ((property_flags & CPF_SaveGame) != 0) { - flag_format_helper.add_switch(STR("SaveGame")); + flag_format_helper.add_switch(SYSSTR("SaveGame")); } if ((property_flags & CPF_NonTransactional) != 0) { - flag_format_helper.add_switch(STR("NonTransactional")); + flag_format_helper.add_switch(SYSSTR("NonTransactional")); } if ((property_flags & CPF_Transient) != 0) { - flag_format_helper.add_switch(STR("Transient")); + flag_format_helper.add_switch(SYSSTR("Transient")); } if ((property_flags & CPF_DuplicateTransient) != 0) { - flag_format_helper.add_switch(STR("DuplicateTransient")); + flag_format_helper.add_switch(SYSSTR("DuplicateTransient")); } if ((property_flags & CPF_TextExportTransient) != 0) { - flag_format_helper.add_switch(STR("TextExportTransient")); + flag_format_helper.add_switch(SYSSTR("TextExportTransient")); } if ((property_flags & CPF_NonPIEDuplicateTransient) != 0) { - flag_format_helper.add_switch(STR("NonPIEDuplicateTransient")); + flag_format_helper.add_switch(SYSSTR("NonPIEDuplicateTransient")); } if ((property_flags & CPF_SkipSerialization) != 0) { - flag_format_helper.add_switch(STR("SkipSerialization")); + flag_format_helper.add_switch(SYSSTR("SkipSerialization")); } // Need to have all of these flags, otherwise we might accidentally get Instanced of delegate properties; CPF_ExportObject is not set for delegate properties @@ -2867,16 +2896,16 @@ namespace RC::UEGenerator (property->IsA() || (property->IsA() && static_cast(property)->GetInner()->IsA()) || (property->IsA() && static_cast(property)->GetValueProp()->IsA()))) { - flag_format_helper.add_switch(STR("Instanced")); + flag_format_helper.add_switch(SYSSTR("Instanced")); } else if ((property_flags & CPF_ExportObject) != 0) { - flag_format_helper.add_switch(STR("Export")); + flag_format_helper.add_switch(SYSSTR("Export")); } return flag_format_helper.build_flag_string(); } - auto UEHeaderGenerator::generate_struct_flags(UScriptStruct* script_struct) const -> std::wstring + auto UEHeaderGenerator::generate_struct_flags(UScriptStruct* script_struct) const -> SystemStringType { FlagFormatHelper flag_format_helper{}; @@ -2886,40 +2915,40 @@ namespace RC::UEGenerator EStructFlags struct_own_flags = (EStructFlags)(struct_flags & (~(parent_struct_flags & STRUCT_Inherit))); - const std::wstring native_struct_name = get_native_struct_name(script_struct); + const SystemStringType native_struct_name = get_native_struct_name(script_struct); if (is_struct_blueprint_type(script_struct) || m_blueprint_visible_structs.contains(native_struct_name) || UE4SSProgram::settings_manager.UHTHeaderGenerator.MakeAllPropertyBlueprintsReadWrite) { - flag_format_helper.add_switch(STR("BlueprintType")); + flag_format_helper.add_switch(SYSSTR("BlueprintType")); } if ((struct_own_flags & STRUCT_NoExport) != 0) { - flag_format_helper.add_switch(STR("NoExport")); + flag_format_helper.add_switch(SYSSTR("NoExport")); } if ((struct_own_flags & STRUCT_Atomic) != 0) { - flag_format_helper.add_switch(STR("Atomic")); + flag_format_helper.add_switch(SYSSTR("Atomic")); } if ((struct_own_flags & STRUCT_Immutable) != 0) { - flag_format_helper.add_switch(STR("Immutable")); + flag_format_helper.add_switch(SYSSTR("Immutable")); } return flag_format_helper.build_flag_string(); } - auto UEHeaderGenerator::generate_enum_flags(UEnum* uenum) const -> std::wstring + auto UEHeaderGenerator::generate_enum_flags(UEnum* uenum) const -> SystemStringType { - + FlagFormatHelper flag_format_helper{}; auto enum_flags = uenum->GetEnumFlags(); if ((((int32_t)enum_flags) & ((int32_t)EEnumFlags::Flags)) != 0) { - flag_format_helper.add_switch(STR("Flags")); + flag_format_helper.add_switch(SYSSTR("Flags")); } - const std::wstring enum_native_name = get_native_enum_name(uenum); + const SystemStringType enum_native_name = get_native_enum_name(uenum); if (UE4SSProgram::settings_manager.UHTHeaderGenerator.MakeEnumClassesBlueprintType) { @@ -2927,30 +2956,28 @@ namespace RC::UEGenerator if (cpp_form == UEnum::ECppForm::EnumClass) { const auto underlying_type = m_underlying_enum_types.find(enum_native_name); - if (underlying_type->second == STR("uint8") || - (underlying_type == m_underlying_enum_types.end() && - (get_highest_enum(uenum) <= 255 && - get_lowest_enum(uenum) >= 0))) + if ((underlying_type == m_underlying_enum_types.end() && (get_highest_enum(uenum) <= 255 && get_lowest_enum(uenum) >= 0)) || + ((underlying_type != m_underlying_enum_types.end()) && (underlying_type->second == SYSSTR("uint8")))) { // Underlying type is implicit or explicitly uint8. - flag_format_helper.add_switch(STR("BlueprintType")); + flag_format_helper.add_switch(SYSSTR("BlueprintType")); } } else { - flag_format_helper.add_switch(STR("BlueprintType")); + flag_format_helper.add_switch(SYSSTR("BlueprintType")); } } return flag_format_helper.build_flag_string(); } - auto UEHeaderGenerator::sanitize_enumeration_name(const std::wstring& enumeration_name) -> std::wstring + auto UEHeaderGenerator::sanitize_enumeration_name(const SystemStringType& enumeration_name) -> SystemStringType { - std::wstring result_enum_name = enumeration_name; + SystemStringType result_enum_name = enumeration_name; // Remove enumeration name from the string - size_t enum_name_string_split = enumeration_name.find(STR("::")); - if (enum_name_string_split != std::wstring::npos) + size_t enum_name_string_split = enumeration_name.find(SYSSTR("::")); + if (enum_name_string_split != SystemStringType::npos) { result_enum_name.erase(0, enum_name_string_split + 2); } @@ -2965,15 +2992,15 @@ namespace RC::UEGenerator } int64 highest_enum_value = 0; - const StringType enum_prefix = uenum->GenerateEnumPrefix(); - const StringType expected_max_name = std::format(STR("{}_MAX"), enum_prefix); - StringType expected_max_name_lower = expected_max_name; + const auto enum_prefix = to_system(uenum->GenerateEnumPrefix()); + const auto expected_max_name = std::format(SYSSTR("{}_MAX"), enum_prefix); + auto expected_max_name_lower = expected_max_name; std::transform(expected_max_name_lower.begin(), expected_max_name_lower.end(), expected_max_name_lower.begin(), ::towlower); - + for (auto [Name, Value] : uenum->ForEachName()) { - StringType enum_name = sanitize_enumeration_name(Name.ToString()); - StringType enum_name_lower = enum_name; + auto enum_name = sanitize_enumeration_name(to_system_string(Name.ToString())); + auto enum_name_lower = enum_name; std::transform(enum_name_lower.begin(), enum_name_lower.end(), enum_name_lower.begin(), ::towlower); if ((enum_name_lower != expected_max_name_lower && enum_name_lower != sanitize_enumeration_name(expected_max_name_lower)) && Value > highest_enum_value) { @@ -3001,7 +3028,7 @@ namespace RC::UEGenerator return lowest_enum_value; } - auto UEHeaderGenerator::generate_function_flags(UFunction* function, bool is_function_pure_virtual) const -> std::wstring + auto UEHeaderGenerator::generate_function_flags(UFunction* function, bool is_function_pure_virtual) const -> SystemStringType { FlagFormatHelper flag_format_helper{}; @@ -3022,7 +3049,7 @@ namespace RC::UEGenerator // Interface functions cannot be BlueprintPure if ((function_flags & FUNC_BlueprintPure) != 0 && !is_interface_function) { - flag_format_helper.add_switch(STR("BlueprintPure")); + flag_format_helper.add_switch(SYSSTR("BlueprintPure")); } else { @@ -3030,9 +3057,9 @@ namespace RC::UEGenerator // it has been explicitly marked as blueprint impure, and we need to preserve this behavior if ((function_flags & FUNC_Const) != 0 && !is_interface_function) { - flag_format_helper.add_parameter(STR("BlueprintPure"), STR("false")); + flag_format_helper.add_parameter(SYSSTR("BlueprintPure"), SYSSTR("false")); } - flag_format_helper.add_switch(STR("BlueprintCallable")); + flag_format_helper.add_switch(SYSSTR("BlueprintCallable")); blueprint_callable_added = true; } } @@ -3050,7 +3077,7 @@ namespace RC::UEGenerator if (!has_invalid_param) { - flag_format_helper.add_switch(STR("BlueprintCallable")); + flag_format_helper.add_switch(SYSSTR("BlueprintCallable")); } } @@ -3058,11 +3085,11 @@ namespace RC::UEGenerator { if ((function_flags & FUNC_Native) != 0) { - flag_format_helper.add_switch(STR("BlueprintNativeEvent")); + flag_format_helper.add_switch(SYSSTR("BlueprintNativeEvent")); } else { - flag_format_helper.add_switch(STR("BlueprintImplementableEvent")); + flag_format_helper.add_switch(SYSSTR("BlueprintImplementableEvent")); } } @@ -3070,50 +3097,50 @@ namespace RC::UEGenerator { if ((function_flags & FUNC_NetServer) != 0) { - flag_format_helper.add_switch(STR("Server")); + flag_format_helper.add_switch(SYSSTR("Server")); } else if ((function_flags & FUNC_NetClient) != 0) { - flag_format_helper.add_switch(STR("Client")); + flag_format_helper.add_switch(SYSSTR("Client")); } else if ((function_flags & FUNC_NetMulticast) != 0) { - flag_format_helper.add_switch(STR("NetMulticast")); + flag_format_helper.add_switch(SYSSTR("NetMulticast")); } else if ((function_flags & FUNC_NetRequest) != 0) { - flag_format_helper.add_switch(STR("ServiceRequest")); + flag_format_helper.add_switch(SYSSTR("ServiceRequest")); } else if ((function_flags & FUNC_NetResponse) != 0) { - flag_format_helper.add_switch(STR("ServiceResponse")); + flag_format_helper.add_switch(SYSSTR("ServiceResponse")); } if ((function_flags & FUNC_NetReliable) != 0) { - flag_format_helper.add_switch(STR("Reliable")); + flag_format_helper.add_switch(SYSSTR("Reliable")); } else { - flag_format_helper.add_switch(STR("Unreliable")); + flag_format_helper.add_switch(SYSSTR("Unreliable")); } if ((function_flags & FUNC_NetValidate) != 0) { - flag_format_helper.add_switch(STR("WithValidation")); + flag_format_helper.add_switch(SYSSTR("WithValidation")); } } if ((function_flags & FUNC_Exec) != 0) { - flag_format_helper.add_switch(STR("Exec")); + flag_format_helper.add_switch(SYSSTR("Exec")); } if ((function_flags & FUNC_BlueprintAuthorityOnly) != 0) { - flag_format_helper.add_switch(STR("BlueprintAuthorityOnly")); + flag_format_helper.add_switch(SYSSTR("BlueprintAuthorityOnly")); } if ((function_flags & FUNC_BlueprintCosmetic) != 0) { - flag_format_helper.add_switch(STR("BlueprintCosmetic")); + flag_format_helper.add_switch(SYSSTR("BlueprintCosmetic")); } static auto latent_action_info = UObjectGlobals::StaticFindObject(nullptr, nullptr, STR("/Script/Engine.LatentActionInfo")); @@ -3121,11 +3148,11 @@ namespace RC::UEGenerator bool bLAFound = false; for (FProperty* param : function->ForEachProperty()) { - auto param_name = param->GetName(); + auto param_name = to_system(param->GetName()); auto param_uc_name = string_to_uppercase(param_name); - if (param_uc_name.find(STR("WORLDCONTEXT")) != param_uc_name.npos) + if (param_uc_name.find(SYSSTR("WORLDCONTEXT")) != param_uc_name.npos) { - flag_format_helper.get_meta()->add_parameter(STR("WorldContext"), std::format(STR("\"{}\""), param_name)); + flag_format_helper.get_meta()->add_parameter(SYSSTR("WorldContext"), std::format(SYSSTR("\"{}\""), param_name)); bWCFound = true; } if (auto as_struct_property = CastField(param); as_struct_property) @@ -3133,8 +3160,8 @@ namespace RC::UEGenerator // We now know this is a StructProperty. if (as_struct_property->GetStruct()->IsChildOf(latent_action_info)) { - flag_format_helper.get_meta()->add_parameter(STR("LatentInfo"), std::format(STR("\"{}\""), param_name)); - flag_format_helper.get_meta()->add_switch(STR("Latent")); + flag_format_helper.get_meta()->add_parameter(SYSSTR("LatentInfo"), std::format(SYSSTR("\"{}\""), param_name)); + flag_format_helper.get_meta()->add_switch(SYSSTR("Latent")); bLAFound = true; } } @@ -3151,28 +3178,28 @@ namespace RC::UEGenerator UFunction* function, GeneratedSourceFile& header_data, bool generate_comma_before_name, - const std::wstring& context_name, + const SystemStringType& context_name, const CaseInsensitiveSet& blacklisted_property_names, - int32_t* out_num_params) -> std::wstring + int32_t* out_num_params) -> SystemStringType { - std::wstring function_arguments_string; + SystemStringType function_arguments_string; for (FProperty* property : function->ForEachProperty()) { auto property_flags = property->GetPropertyFlags(); if ((property_flags & CPF_Parm) != 0 && (property_flags & CPF_ReturnParm) == 0) { - std::wstring param_declaration; + SystemStringType param_declaration; // We only generate UPARAM declarations if we are not generating the implementation file if (!header_data.is_implementation_file()) { - const std::wstring parameter_flags_string = generate_function_argument_flags(property); + const SystemStringType parameter_flags_string = generate_function_argument_flags(property); if (!parameter_flags_string.empty()) { - param_declaration.append(STR("UPARAM(")); + param_declaration.append(SYSSTR("UPARAM(")); param_declaration.append(parameter_flags_string); - param_declaration.append(STR(") ")); + param_declaration.append(SYSSTR(") ")); } } @@ -3184,7 +3211,7 @@ namespace RC::UEGenerator // Append const keyword to the parameter declaration if it is marked as const parameter if ((property_flags & CPF_ConstParm) != 0 || should_force_const_ref) { - param_declaration.append(STR("const ")); + param_declaration.append(SYSSTR("const ")); } PropertyTypeDeclarationContext context(context_name, &header_data); @@ -3194,27 +3221,27 @@ namespace RC::UEGenerator // which would also be always set for output parameters if ((property_flags & (CPF_ReferenceParm | CPF_OutParm)) != 0 || should_force_const_ref) { - param_declaration.append(STR("&")); + param_declaration.append(SYSSTR("&")); } if (generate_comma_before_name) { - param_declaration.append(STR(",")); + param_declaration.append(SYSSTR(",")); } - param_declaration.append(STR(" ")); + param_declaration.append(SYSSTR(" ")); - std::wstring property_name = property->GetName(); + auto property_name = to_system_string(property->GetName()); // If property name is blacklisted, capitalize first letter and prepend New if ((uclass && is_function_parameter_shadowing(uclass, property)) || blacklisted_property_names.contains(property_name)) { property_name[0] = towupper(property_name[0]); - property_name.insert(0, STR("New")); + property_name.insert(0, SYSSTR("New")); } param_declaration.append(property_name); function_arguments_string.append(param_declaration); - function_arguments_string.append(STR(", ")); + function_arguments_string.append(SYSSTR(", ")); if (out_num_params) { (*out_num_params)++; @@ -3230,9 +3257,10 @@ namespace RC::UEGenerator return function_arguments_string; } - auto UEHeaderGenerator::generate_default_property_value(FProperty* property, GeneratedSourceFile& header_data, const std::wstring& ContextName) -> std::wstring + auto UEHeaderGenerator::generate_default_property_value(FProperty* property, GeneratedSourceFile& header_data, const SystemStringType& ContextName) + -> SystemStringType { - const std::wstring field_class_name = property->GetClass().GetName(); + const auto field_class_name = (property->GetClass().GetName()); PropertyTypeDeclarationContext context(ContextName, &header_data); // Byte Property @@ -3246,7 +3274,7 @@ namespace RC::UEGenerator const int64_t first_enum_constant_value = Enum->GetEnumNameByIndex(0).Value; return generate_enum_value(Enum, first_enum_constant_value); } - return STR("0"); + return SYSSTR("0"); } // Enum Property @@ -3257,7 +3285,7 @@ namespace RC::UEGenerator if (uenum == NULL) { - throw std::runtime_error(RC::fmt("EnumProperty %S does not have a valid Enum value", property->GetName().c_str())); + throw std::runtime_error(RC::fmt("EnumProperty {} does not have a valid Enum value", property->GetName())); } const int64_t first_enum_constant_value = uenum->GetEnumNameByIndex(0).Value; return generate_enum_value(uenum, first_enum_constant_value); @@ -3266,36 +3294,36 @@ namespace RC::UEGenerator // Bool Property if (field_class_name == STR("BoolProperty")) { - return STR("false"); + return SYSSTR("false"); } // Standard Numeric Properties if (field_class_name == STR("Int8Property") || field_class_name == STR("Int16Property") || field_class_name == STR("IntProperty") || field_class_name == STR("Int64Property") || field_class_name == STR("UInt16Property") || field_class_name == STR("UInt32Property") || field_class_name == STR("UInt64Property")) { - return STR("0"); + return SYSSTR("0"); } if (field_class_name == STR("FloatProperty")) { - return STR("0.0f"); + return SYSSTR("0.0f"); } if (field_class_name == STR("DoubleProperty")) { - return STR("0.0"); + return SYSSTR("0.0"); } // Object Properties if (field_class_name == STR("ObjectProperty") || field_class_name == STR("WeakObjectProperty") || field_class_name == STR("LazyObjectProperty") || field_class_name == STR("SoftObjectProperty") || field_class_name == STR("AssetObjectProperty") || property->IsA()) { - return STR("NULL"); + return SYSSTR("NULL"); } // Class Properties if (field_class_name == STR("ClassProperty") || field_class_name == STR("SoftClassProperty") || field_class_name == STR("InterfaceProperty") || field_class_name == STR("AssetClassProperty") || property->IsA()) { - return STR("NULL"); + return SYSSTR("NULL"); } // Struct Property @@ -3306,24 +3334,24 @@ namespace RC::UEGenerator if (script_struct == NULL) { - throw std::runtime_error(RC::fmt("Struct is NULL for StructProperty %S", property->GetName().c_str())); + throw std::runtime_error(RC::fmt("Struct is NULL for StructProperty {}", property->GetName())); } - const std::wstring native_struct_name = get_native_struct_name(script_struct); - return std::format(STR("{}{{}}"), native_struct_name); + const SystemStringType native_struct_name = get_native_struct_name(script_struct); + return std::format(SYSSTR("{}{{}}"), native_struct_name); } // Delegate Properties if (field_class_name == STR("DelegateProperty") || field_class_name == STR("MulticastInlineDelegateProperty") || field_class_name == STR("MulticastSparseDelegateProperty")) { - const std::wstring delegate_type_name = generate_delegate_name(property, context.context_name); - return std::format(STR("{}()"), delegate_type_name); + const SystemStringType delegate_type_name = generate_delegate_name(property, context.context_name); + return std::format(SYSSTR("{}()"), delegate_type_name); } // Field path property if (field_class_name == STR("FieldPathProperty")) { - return STR("FFieldPath()"); + return SYSSTR("FFieldPath()"); } // Collection and Map Properties @@ -3332,8 +3360,8 @@ namespace RC::UEGenerator FArrayProperty* array_property = static_cast(property); FProperty* inner_property = array_property->GetInner(); - const std::wstring inner_property_type = generate_property_type_declaration(inner_property, context); - return std::format(STR("TArray<{}>()"), inner_property_type); + const SystemStringType inner_property_type = generate_property_type_declaration(inner_property, context); + return std::format(SYSSTR("TArray<{}>()"), inner_property_type); } if (field_class_name == STR("SetProperty")) @@ -3341,8 +3369,8 @@ namespace RC::UEGenerator FSetProperty* set_property = static_cast(property); FProperty* element_prop = set_property->GetElementProp(); - const std::wstring element_property_type = generate_property_type_declaration(element_prop, context); - return std::format(STR("TSet<{}>()"), element_property_type); + const SystemStringType element_property_type = generate_property_type_declaration(element_prop, context); + return std::format(SYSSTR("TSet<{}>()"), element_property_type); } if (field_class_name == STR("MapProperty")) @@ -3351,28 +3379,27 @@ namespace RC::UEGenerator FProperty* key_property = map_property->GetKeyProp(); FProperty* value_property = map_property->GetValueProp(); - const std::wstring key_type = generate_property_type_declaration(key_property, context); - const std::wstring value_type = generate_property_type_declaration(value_property, context); + const auto key_type = generate_property_type_declaration(key_property, context); + const auto value_type = generate_property_type_declaration(value_property, context); - return std::format(STR("TMap<{}, {}>()"), key_type, value_type); + return std::format(SYSSTR("TMap<{}, {}>()"), key_type, value_type); } // Various string, name and text properties if (field_class_name == STR("NameProperty")) { - return STR("NAME_None"); + return SYSSTR("NAME_None"); } if (field_class_name == STR("StrProperty")) { - return STR("TEXT(\"\")"); + return SYSSTR("TEXT(\"\")"); } if (field_class_name == STR("TextProperty")) { - return STR("FText::GetEmpty()"); + return SYSSTR("FText::GetEmpty()"); } - throw std::runtime_error(RC::fmt("[generate_default_property_value] Unsupported property class '%S', full name: '%S'", - field_class_name.c_str(), - property->GetFullName().c_str())); + throw std::runtime_error( + RC::fmt("[generate_default_property_value] Unsupported property class '{}', full name: '{}'", field_class_name, property->GetFullName())); } auto UEHeaderGenerator::get_class_blueprint_info(UClass* uclass) -> ClassBlueprintInfo @@ -3462,18 +3489,18 @@ namespace RC::UEGenerator return is_shadowing; } - auto UEHeaderGenerator::get_module_name_for_package(UObject* package) -> std::wstring + auto UEHeaderGenerator::get_module_name_for_package(UObject* package) -> SystemStringType { if (package->GetOuterPrivate() != NULL) { throw std::invalid_argument("Encountered a package with an outer object set"); } - std::wstring package_name = package->GetName(); - if (!package_name.starts_with(STR("/Script/"))) + auto package_name = to_system_string(package->GetName()); + if (!package_name.starts_with(SYSSTR("/Script/"))) { - return STR(""); + return SYSSTR(""); } - package_name.erase(0, wcslen(STR("/Script/"))); + package_name.erase(0, SystemStringType(SYSSTR("/Script/")).length()); return package_name; } @@ -3483,22 +3510,22 @@ namespace RC::UEGenerator this->m_primary_module_name = determine_primary_game_module_name(); // Force inclusion of Core and CoreUObject into all the generated module build files - this->m_forced_module_dependencies.insert(STR("Core")); - this->m_forced_module_dependencies.insert(STR("CoreUObject")); + this->m_forced_module_dependencies.insert(SYSSTR("Core")); + this->m_forced_module_dependencies.insert(SYSSTR("CoreUObject")); // TODO not optimal, but still needed for the majority of the cases - this->m_forced_module_dependencies.insert(STR("Engine")); + this->m_forced_module_dependencies.insert(SYSSTR("Engine")); // Add few classes that require explicit UObjectInitializer constructor call, excluding classes inheriting from AActor. - this->m_classes_with_object_initializer.insert(STR("UUserWidget")); - this->m_classes_with_object_initializer.insert(STR("UListView")); - this->m_classes_with_object_initializer.insert(STR("UMovieSceneTrack")); - this->m_classes_with_object_initializer.insert(STR("USoundWaveProcedural")); - this->m_classes_with_object_initializer.insert(STR("URichTextBlock")); - this->m_classes_with_object_initializer.insert(STR("URichTextBlockImageDecorator")); - this->m_classes_with_object_initializer.insert(STR("URichTextBlockDecorator")); - this->m_classes_with_object_initializer.insert(STR("USkeletalMeshComponentBudgeted")); - this->m_classes_with_object_initializer.insert(STR("UIpNetDriver")); - this->m_classes_with_object_initializer.insert(STR("UAITask")); + this->m_classes_with_object_initializer.insert(SYSSTR("UUserWidget")); + this->m_classes_with_object_initializer.insert(SYSSTR("UListView")); + this->m_classes_with_object_initializer.insert(SYSSTR("UMovieSceneTrack")); + this->m_classes_with_object_initializer.insert(SYSSTR("USoundWaveProcedural")); + this->m_classes_with_object_initializer.insert(SYSSTR("URichTextBlock")); + this->m_classes_with_object_initializer.insert(SYSSTR("URichTextBlockImageDecorator")); + this->m_classes_with_object_initializer.insert(SYSSTR("URichTextBlockDecorator")); + this->m_classes_with_object_initializer.insert(SYSSTR("USkeletalMeshComponentBudgeted")); + this->m_classes_with_object_initializer.insert(SYSSTR("UIpNetDriver")); + this->m_classes_with_object_initializer.insert(SYSSTR("UAITask")); } auto UEHeaderGenerator::ignore_selected_modules() -> void @@ -3510,144 +3537,144 @@ namespace RC::UEGenerator if (UE4SSProgram::settings_manager.UHTHeaderGenerator.IgnoreEngineAndCoreUObject || UE4SSProgram::settings_manager.UHTHeaderGenerator.IgnoreAllCoreEngineModules) { - this->m_ignored_module_names.insert(STR("Engine")); - this->m_ignored_module_names.insert(STR("CoreUObject")); + this->m_ignored_module_names.insert(SYSSTR("Engine")); + this->m_ignored_module_names.insert(SYSSTR("CoreUObject")); } // Skip all core engine packages if requested if (UE4SSProgram::settings_manager.UHTHeaderGenerator.IgnoreAllCoreEngineModules) { - this->m_ignored_module_names.insert(STR("ActorLayerUtilities")); - this->m_ignored_module_names.insert(STR("ActorSequence")); - this->m_ignored_module_names.insert(STR("AIModule")); - this->m_ignored_module_names.insert(STR("AndroidPermission")); - this->m_ignored_module_names.insert(STR("AnimationCore")); - this->m_ignored_module_names.insert(STR("AnimationSharing")); - this->m_ignored_module_names.insert(STR("AnimGraphRuntime")); - this->m_ignored_module_names.insert(STR("AppleImageUtils")); - this->m_ignored_module_names.insert(STR("ArchVisCharacter")); - this->m_ignored_module_names.insert(STR("AssetRegistry")); - this->m_ignored_module_names.insert(STR("AssetTags")); - this->m_ignored_module_names.insert(STR("AudioAnalyzer")); - this->m_ignored_module_names.insert(STR("AudioCapture")); - this->m_ignored_module_names.insert(STR("AudioExtensions")); - this->m_ignored_module_names.insert(STR("AudioMixer")); - this->m_ignored_module_names.insert(STR("AudioPlatformConfiguration")); - this->m_ignored_module_names.insert(STR("AudioSynesthesia")); - this->m_ignored_module_names.insert(STR("AugmentedReality")); - this->m_ignored_module_names.insert(STR("AutomationUtils")); - this->m_ignored_module_names.insert(STR("AvfMediaFactory")); - this->m_ignored_module_names.insert(STR("BuildPatchServices")); - this->m_ignored_module_names.insert(STR("CableComponent")); - this->m_ignored_module_names.insert(STR("Chaos")); - this->m_ignored_module_names.insert(STR("ChaosCloth")); - this->m_ignored_module_names.insert(STR("ChaosNiagara")); - this->m_ignored_module_names.insert(STR("ChaosSolvers")); - this->m_ignored_module_names.insert(STR("ChaosSolverEngine")); - this->m_ignored_module_names.insert(STR("CinematicCamera")); - this->m_ignored_module_names.insert(STR("ClothingSystemRuntimeCommon")); - this->m_ignored_module_names.insert(STR("ClothingSystemRuntimeInterface")); - this->m_ignored_module_names.insert(STR("ClothingSystemRuntimeNv")); - this->m_ignored_module_names.insert(STR("CustomMeshComponent")); - this->m_ignored_module_names.insert(STR("DatasmithContent")); - this->m_ignored_module_names.insert(STR("DeveloperSettings")); - this->m_ignored_module_names.insert(STR("EditableMesh")); - this->m_ignored_module_names.insert(STR("EngineMessages")); - this->m_ignored_module_names.insert(STR("EngineSettings")); - this->m_ignored_module_names.insert(STR("EyeTracker")); - this->m_ignored_module_names.insert(STR("FacialAnimation")); - this->m_ignored_module_names.insert(STR("FieldSystemCore")); - this->m_ignored_module_names.insert(STR("FieldSystemEngine")); - this->m_ignored_module_names.insert(STR("Foliage")); - this->m_ignored_module_names.insert(STR("GameplayTags")); - this->m_ignored_module_names.insert(STR("GameplayTasks")); - this->m_ignored_module_names.insert(STR("GeometryCache")); - this->m_ignored_module_names.insert(STR("GeometryCacheTracks")); - this->m_ignored_module_names.insert(STR("GeometryCollectionCore")); - this->m_ignored_module_names.insert(STR("GeometryCollectionSimulationCore")); - this->m_ignored_module_names.insert(STR("GeometryCollectionEngine")); - this->m_ignored_module_names.insert(STR("GeometryCollectionTracks")); - this->m_ignored_module_names.insert(STR("GooglePAD")); - this->m_ignored_module_names.insert(STR("HeadMountedDisplay")); - this->m_ignored_module_names.insert(STR("ImageWrapper")); - this->m_ignored_module_names.insert(STR("ImageWriteQueue")); - this->m_ignored_module_names.insert(STR("ImgMedia")); - this->m_ignored_module_names.insert(STR("ImgMediaFactory")); - this->m_ignored_module_names.insert(STR("InputCore")); - this->m_ignored_module_names.insert(STR("InteractiveToolsFramework")); - this->m_ignored_module_names.insert(STR("JsonUtilities")); - this->m_ignored_module_names.insert(STR("Landscape")); - this->m_ignored_module_names.insert(STR("LevelSequence")); - this->m_ignored_module_names.insert(STR("LightPropagationVolumeRuntime")); - this->m_ignored_module_names.insert(STR("LiveLinkInterface")); - this->m_ignored_module_names.insert(STR("LocationServicesBPLibrary")); - this->m_ignored_module_names.insert(STR("LuminRuntimeSettings")); - this->m_ignored_module_names.insert(STR("MagicLeap")); - this->m_ignored_module_names.insert(STR("MagicLeapAR")); - this->m_ignored_module_names.insert(STR("MagicLeapARPin")); - this->m_ignored_module_names.insert(STR("MagicLeapAudio")); - this->m_ignored_module_names.insert(STR("MagicLeapController")); - this->m_ignored_module_names.insert(STR("MagicLeapEyeTracker")); - this->m_ignored_module_names.insert(STR("MagicLeapHandMeshing")); - this->m_ignored_module_names.insert(STR("MagicLeapHandTracking")); - this->m_ignored_module_names.insert(STR("MagicLeapIdentity")); - this->m_ignored_module_names.insert(STR("MagicLeapImageTracker")); - this->m_ignored_module_names.insert(STR("MagicLeapLightEstimation")); - this->m_ignored_module_names.insert(STR("MagicLeapPlanes")); - this->m_ignored_module_names.insert(STR("MagicLeapPrivileges")); - this->m_ignored_module_names.insert(STR("MagicLeapSecureStorage")); - this->m_ignored_module_names.insert(STR("MagicLeapSharedWorld")); - this->m_ignored_module_names.insert(STR("MaterialShaderQualitySettings")); - this->m_ignored_module_names.insert(STR("MediaAssets")); - this->m_ignored_module_names.insert(STR("MediaCompositing")); - this->m_ignored_module_names.insert(STR("MediaUtils")); - this->m_ignored_module_names.insert(STR("MeshDescription")); - this->m_ignored_module_names.insert(STR("MobilePatchingUtils")); - this->m_ignored_module_names.insert(STR("MotoSynth")); - this->m_ignored_module_names.insert(STR("MoviePlayer")); - this->m_ignored_module_names.insert(STR("MovieScene")); - this->m_ignored_module_names.insert(STR("MovieSceneCapture")); - this->m_ignored_module_names.insert(STR("MovieSceneTracks")); - this->m_ignored_module_names.insert(STR("MRMesh")); - this->m_ignored_module_names.insert(STR("NavigationSystem")); - this->m_ignored_module_names.insert(STR("NetCore")); - this->m_ignored_module_names.insert(STR("Niagara")); - this->m_ignored_module_names.insert(STR("NiagaraAnimNotifies")); - this->m_ignored_module_names.insert(STR("NiagaraCore")); - this->m_ignored_module_names.insert(STR("NiagaraShader")); - this->m_ignored_module_names.insert(STR("OculusHMD")); - this->m_ignored_module_names.insert(STR("OculusInput")); - this->m_ignored_module_names.insert(STR("OculusMR")); - this->m_ignored_module_names.insert(STR("OnlineSubsystem")); - this->m_ignored_module_names.insert(STR("OnlineSubsystemUtils")); - this->m_ignored_module_names.insert(STR("Overlay")); - this->m_ignored_module_names.insert(STR("PacketHandler")); - this->m_ignored_module_names.insert(STR("Paper2D")); - this->m_ignored_module_names.insert(STR("PhysicsCore")); - this->m_ignored_module_names.insert(STR("PhysXVehicles")); - this->m_ignored_module_names.insert(STR("ProceduralMeshComponent")); - this->m_ignored_module_names.insert(STR("PropertyAccess")); - this->m_ignored_module_names.insert(STR("PropertyPath")); - this->m_ignored_module_names.insert(STR("Renderer")); - this->m_ignored_module_names.insert(STR("Serialization")); - this->m_ignored_module_names.insert(STR("SessionMessages")); - this->m_ignored_module_names.insert(STR("SignificanceManager")); - this->m_ignored_module_names.insert(STR("Slate")); - this->m_ignored_module_names.insert(STR("SlateCore")); - this->m_ignored_module_names.insert(STR("SoundFields")); - this->m_ignored_module_names.insert(STR("StaticMeshDescription")); - this->m_ignored_module_names.insert(STR("SteamVR")); - this->m_ignored_module_names.insert(STR("SteamVRInputDevice")); - this->m_ignored_module_names.insert(STR("Synthesis")); - this->m_ignored_module_names.insert(STR("TcpMessaging")); - this->m_ignored_module_names.insert(STR("TemplateSequence")); - this->m_ignored_module_names.insert(STR("TimeManagement")); - this->m_ignored_module_names.insert(STR("UdpMessaging")); - this->m_ignored_module_names.insert(STR("UMG")); - this->m_ignored_module_names.insert(STR("UObjectPlugin")); - this->m_ignored_module_names.insert(STR("VariantManagerContent")); - this->m_ignored_module_names.insert(STR("VectorVM")); - this->m_ignored_module_names.insert(STR("WmfMediaFactory")); + this->m_ignored_module_names.insert(SYSSTR("ActorLayerUtilities")); + this->m_ignored_module_names.insert(SYSSTR("ActorSequence")); + this->m_ignored_module_names.insert(SYSSTR("AIModule")); + this->m_ignored_module_names.insert(SYSSTR("AndroidPermission")); + this->m_ignored_module_names.insert(SYSSTR("AnimationCore")); + this->m_ignored_module_names.insert(SYSSTR("AnimationSharing")); + this->m_ignored_module_names.insert(SYSSTR("AnimGraphRuntime")); + this->m_ignored_module_names.insert(SYSSTR("AppleImageUtils")); + this->m_ignored_module_names.insert(SYSSTR("ArchVisCharacter")); + this->m_ignored_module_names.insert(SYSSTR("AssetRegistry")); + this->m_ignored_module_names.insert(SYSSTR("AssetTags")); + this->m_ignored_module_names.insert(SYSSTR("AudioAnalyzer")); + this->m_ignored_module_names.insert(SYSSTR("AudioCapture")); + this->m_ignored_module_names.insert(SYSSTR("AudioExtensions")); + this->m_ignored_module_names.insert(SYSSTR("AudioMixer")); + this->m_ignored_module_names.insert(SYSSTR("AudioPlatformConfiguration")); + this->m_ignored_module_names.insert(SYSSTR("AudioSynesthesia")); + this->m_ignored_module_names.insert(SYSSTR("AugmentedReality")); + this->m_ignored_module_names.insert(SYSSTR("AutomationUtils")); + this->m_ignored_module_names.insert(SYSSTR("AvfMediaFactory")); + this->m_ignored_module_names.insert(SYSSTR("BuildPatchServices")); + this->m_ignored_module_names.insert(SYSSTR("CableComponent")); + this->m_ignored_module_names.insert(SYSSTR("Chaos")); + this->m_ignored_module_names.insert(SYSSTR("ChaosCloth")); + this->m_ignored_module_names.insert(SYSSTR("ChaosNiagara")); + this->m_ignored_module_names.insert(SYSSTR("ChaosSolvers")); + this->m_ignored_module_names.insert(SYSSTR("ChaosSolverEngine")); + this->m_ignored_module_names.insert(SYSSTR("CinematicCamera")); + this->m_ignored_module_names.insert(SYSSTR("ClothingSystemRuntimeCommon")); + this->m_ignored_module_names.insert(SYSSTR("ClothingSystemRuntimeInterface")); + this->m_ignored_module_names.insert(SYSSTR("ClothingSystemRuntimeNv")); + this->m_ignored_module_names.insert(SYSSTR("CustomMeshComponent")); + this->m_ignored_module_names.insert(SYSSTR("DatasmithContent")); + this->m_ignored_module_names.insert(SYSSTR("DeveloperSettings")); + this->m_ignored_module_names.insert(SYSSTR("EditableMesh")); + this->m_ignored_module_names.insert(SYSSTR("EngineMessages")); + this->m_ignored_module_names.insert(SYSSTR("EngineSettings")); + this->m_ignored_module_names.insert(SYSSTR("EyeTracker")); + this->m_ignored_module_names.insert(SYSSTR("FacialAnimation")); + this->m_ignored_module_names.insert(SYSSTR("FieldSystemCore")); + this->m_ignored_module_names.insert(SYSSTR("FieldSystemEngine")); + this->m_ignored_module_names.insert(SYSSTR("Foliage")); + this->m_ignored_module_names.insert(SYSSTR("GameplayTags")); + this->m_ignored_module_names.insert(SYSSTR("GameplayTasks")); + this->m_ignored_module_names.insert(SYSSTR("GeometryCache")); + this->m_ignored_module_names.insert(SYSSTR("GeometryCacheTracks")); + this->m_ignored_module_names.insert(SYSSTR("GeometryCollectionCore")); + this->m_ignored_module_names.insert(SYSSTR("GeometryCollectionSimulationCore")); + this->m_ignored_module_names.insert(SYSSTR("GeometryCollectionEngine")); + this->m_ignored_module_names.insert(SYSSTR("GeometryCollectionTracks")); + this->m_ignored_module_names.insert(SYSSTR("GooglePAD")); + this->m_ignored_module_names.insert(SYSSTR("HeadMountedDisplay")); + this->m_ignored_module_names.insert(SYSSTR("ImageWrapper")); + this->m_ignored_module_names.insert(SYSSTR("ImageWriteQueue")); + this->m_ignored_module_names.insert(SYSSTR("ImgMedia")); + this->m_ignored_module_names.insert(SYSSTR("ImgMediaFactory")); + this->m_ignored_module_names.insert(SYSSTR("InputCore")); + this->m_ignored_module_names.insert(SYSSTR("InteractiveToolsFramework")); + this->m_ignored_module_names.insert(SYSSTR("JsonUtilities")); + this->m_ignored_module_names.insert(SYSSTR("Landscape")); + this->m_ignored_module_names.insert(SYSSTR("LevelSequence")); + this->m_ignored_module_names.insert(SYSSTR("LightPropagationVolumeRuntime")); + this->m_ignored_module_names.insert(SYSSTR("LiveLinkInterface")); + this->m_ignored_module_names.insert(SYSSTR("LocationServicesBPLibrary")); + this->m_ignored_module_names.insert(SYSSTR("LuminRuntimeSettings")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeap")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapAR")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapARPin")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapAudio")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapController")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapEyeTracker")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapHandMeshing")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapHandTracking")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapIdentity")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapImageTracker")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapLightEstimation")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapPlanes")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapPrivileges")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapSecureStorage")); + this->m_ignored_module_names.insert(SYSSTR("MagicLeapSharedWorld")); + this->m_ignored_module_names.insert(SYSSTR("MaterialShaderQualitySettings")); + this->m_ignored_module_names.insert(SYSSTR("MediaAssets")); + this->m_ignored_module_names.insert(SYSSTR("MediaCompositing")); + this->m_ignored_module_names.insert(SYSSTR("MediaUtils")); + this->m_ignored_module_names.insert(SYSSTR("MeshDescription")); + this->m_ignored_module_names.insert(SYSSTR("MobilePatchingUtils")); + this->m_ignored_module_names.insert(SYSSTR("MotoSynth")); + this->m_ignored_module_names.insert(SYSSTR("MoviePlayer")); + this->m_ignored_module_names.insert(SYSSTR("MovieScene")); + this->m_ignored_module_names.insert(SYSSTR("MovieSceneCapture")); + this->m_ignored_module_names.insert(SYSSTR("MovieSceneTracks")); + this->m_ignored_module_names.insert(SYSSTR("MRMesh")); + this->m_ignored_module_names.insert(SYSSTR("NavigationSystem")); + this->m_ignored_module_names.insert(SYSSTR("NetCore")); + this->m_ignored_module_names.insert(SYSSTR("Niagara")); + this->m_ignored_module_names.insert(SYSSTR("NiagaraAnimNotifies")); + this->m_ignored_module_names.insert(SYSSTR("NiagaraCore")); + this->m_ignored_module_names.insert(SYSSTR("NiagaraShader")); + this->m_ignored_module_names.insert(SYSSTR("OculusHMD")); + this->m_ignored_module_names.insert(SYSSTR("OculusInput")); + this->m_ignored_module_names.insert(SYSSTR("OculusMR")); + this->m_ignored_module_names.insert(SYSSTR("OnlineSubsystem")); + this->m_ignored_module_names.insert(SYSSTR("OnlineSubsystemUtils")); + this->m_ignored_module_names.insert(SYSSTR("Overlay")); + this->m_ignored_module_names.insert(SYSSTR("PacketHandler")); + this->m_ignored_module_names.insert(SYSSTR("Paper2D")); + this->m_ignored_module_names.insert(SYSSTR("PhysicsCore")); + this->m_ignored_module_names.insert(SYSSTR("PhysXVehicles")); + this->m_ignored_module_names.insert(SYSSTR("ProceduralMeshComponent")); + this->m_ignored_module_names.insert(SYSSTR("PropertyAccess")); + this->m_ignored_module_names.insert(SYSSTR("PropertyPath")); + this->m_ignored_module_names.insert(SYSSTR("Renderer")); + this->m_ignored_module_names.insert(SYSSTR("Serialization")); + this->m_ignored_module_names.insert(SYSSTR("SessionMessages")); + this->m_ignored_module_names.insert(SYSSTR("SignificanceManager")); + this->m_ignored_module_names.insert(SYSSTR("Slate")); + this->m_ignored_module_names.insert(SYSSTR("SlateCore")); + this->m_ignored_module_names.insert(SYSSTR("SoundFields")); + this->m_ignored_module_names.insert(SYSSTR("StaticMeshDescription")); + this->m_ignored_module_names.insert(SYSSTR("SteamVR")); + this->m_ignored_module_names.insert(SYSSTR("SteamVRInputDevice")); + this->m_ignored_module_names.insert(SYSSTR("Synthesis")); + this->m_ignored_module_names.insert(SYSSTR("TcpMessaging")); + this->m_ignored_module_names.insert(SYSSTR("TemplateSequence")); + this->m_ignored_module_names.insert(SYSSTR("TimeManagement")); + this->m_ignored_module_names.insert(SYSSTR("UdpMessaging")); + this->m_ignored_module_names.insert(SYSSTR("UMG")); + this->m_ignored_module_names.insert(SYSSTR("UObjectPlugin")); + this->m_ignored_module_names.insert(SYSSTR("VariantManagerContent")); + this->m_ignored_module_names.insert(SYSSTR("VectorVM")); + this->m_ignored_module_names.insert(SYSSTR("WmfMediaFactory")); } } @@ -3655,20 +3682,20 @@ namespace RC::UEGenerator { ignore_selected_modules(); - Output::send(STR("Cleaning up previously generated SDK (if one exists)\n")); + Output::send(SYSSTR("Cleaning up previously generated SDK (if one exists)\n")); if (std::filesystem::exists(m_root_directory)) { std::filesystem::remove_all(m_root_directory); } - Output::send(STR("Initializing native packages dump\n")); + Output::send(SYSSTR("Initializing native packages dump\n")); std::vector native_classes_to_dump; std::vector native_structs_to_dump; std::vector native_enums_to_dump; std::vector native_delegates_to_dump; - Output::send(STR("Gathering native objects for dumping\n")); + Output::send(SYSSTR("Gathering native objects for dumping\n")); UObjectGlobals::ForEachUObject([&](void* raw_object, int32_t chunk_index, int32_t object_index) { UObject* typed_object = static_cast(raw_object); @@ -3713,37 +3740,37 @@ namespace RC::UEGenerator return RC::LoopAction::Continue; }); - Output::send(STR("Attempting to dump {} native classes\n"), native_classes_to_dump.size()); + Output::send(SYSSTR("Attempting to dump {} native classes\n"), native_classes_to_dump.size()); for (UFunction* delegate_signature_function : native_delegates_to_dump) { - // Output::send(STR("Dumping native delegate type {}\n"), global_delegate_signature->GetName()); + // Output::send(SYSSTR("Dumping native delegate type {}\n"), global_delegate_signature->GetName()); generate_object_description_file(delegate_signature_function); } for (UClass* class_to_dump : native_classes_to_dump) { - // Output::send(STR("Dumping native class {}\n"), class_to_dump->GetName()); + // Output::send(SYSSTR("Dumping native class {}\n"), class_to_dump->GetName()); generate_object_description_file(class_to_dump); } - Output::send(STR("Attempting to dump {} native structs\n"), native_structs_to_dump.size()); + Output::send(SYSSTR("Attempting to dump {} native structs\n"), native_structs_to_dump.size()); for (UScriptStruct* struct_to_dump : native_structs_to_dump) { - // Output::send(STR("Dumping native struct {}\n"), struct_to_dump->GetName()); + // Output::send(SYSSTR("Dumping native struct {}\n"), struct_to_dump->GetName()); generate_object_description_file(struct_to_dump); } - Output::send(STR("Attempting to dump {} native enums\n"), native_enums_to_dump.size()); + Output::send(SYSSTR("Attempting to dump {} native enums\n"), native_enums_to_dump.size()); for (UEnum* enum_to_dump : native_enums_to_dump) { - // Output::send(STR("Dumping native enum {}\n"), enum_to_dump->GetName()); + // Output::send(SYSSTR("Dumping native enum {}\n"), enum_to_dump->GetName()); generate_object_description_file(enum_to_dump); } - Output::send(STR("Writing stub module build files for {} modules\n"), m_module_dependencies.size()); + Output::send(SYSSTR("Writing stub module build files for {} modules\n"), m_module_dependencies.size()); for (const auto& module_pair : m_module_dependencies) { generate_module_implementation_file(module_pair.first); @@ -3758,7 +3785,7 @@ namespace RC::UEGenerator bool is_class = object->IsA(); if ((is_struct || is_class) && m_structs_that_need_get_type_hash.find(std::bit_cast(object)) != m_structs_that_need_get_type_hash.end()) { - File::StringType name{}; + SystemStringType name{}; if (is_class) { name = get_native_class_name(std::bit_cast(object)); @@ -3767,7 +3794,7 @@ namespace RC::UEGenerator { name = get_native_struct_name(std::bit_cast(object)); } - header_file.append_line(std::format(STR("FORCEINLINE uint32 GetTypeHash(const {}) {{ return 0; }}"), name)); + header_file.append_line(std::format(SYSSTR("FORCEINLINE uint32 GetTypeHash(const {}) {{ return 0; }}"), name)); } // Case for FTickFunction struct @@ -3777,32 +3804,32 @@ namespace RC::UEGenerator auto super_struct = struct_object->GetSuperScriptStruct(); if (super_struct) { - if (get_native_struct_name(super_struct) == STR("FTickFunction")) + if (get_native_struct_name(super_struct) == SYSSTR("FTickFunction")) { - File::StringType name{}; + SystemStringType name{}; name = get_native_struct_name(struct_object); - header_file.append_line(STR("")); - header_file.append_line(STR("template<>")); - header_file.append_line(std::format(STR("struct TStructOpsTypeTraits<{}> : public TStructOpsTypeTraitsBase2<{}>"), name, name)); - header_file.append_line(STR("{")); - header_file.append_line(STR(" enum")); - header_file.append_line(STR(" {")); - header_file.append_line(STR(" WithCopy = false")); - header_file.append_line(STR(" };")); - header_file.append_line(STR("};")); + header_file.append_line(SYSSTR("")); + header_file.append_line(SYSSTR("template<>")); + header_file.append_line(std::format(SYSSTR("struct TStructOpsTypeTraits<{}> : public TStructOpsTypeTraitsBase2<{}>"), name, name)); + header_file.append_line(SYSSTR("{")); + header_file.append_line(SYSSTR(" enum")); + header_file.append_line(SYSSTR(" {")); + header_file.append_line(SYSSTR(" WithCopy = false")); + header_file.append_line(SYSSTR(" };")); + header_file.append_line(SYSSTR("};")); } } } header_file.serialize_file_content_to_disk(); } - Output::send(STR("Done!\n")); + Output::send(SYSSTR("Done!\n")); } auto UEHeaderGenerator::generate_object_description_file(UObject* object) -> bool { - const std::wstring module_name = get_module_name_for_package(object->GetOutermost()); - const std::wstring file_base_name = get_header_name_for_object(object); + const SystemStringType module_name = get_module_name_for_package(object->GetOutermost()); + const SystemStringType file_base_name = get_header_name_for_object(object); if (module_name.empty()) { @@ -3843,24 +3870,23 @@ namespace RC::UEGenerator { if (!is_delegate_signature_function(function)) { - throw std::runtime_error(RC::fmt("Function %S is not a delegate signature function", function->GetName().c_str())); + throw std::runtime_error(RC::fmt("Function {} is not a delegate signature function", function->GetName())); } if (!function->GetOuterPrivate()->IsA()) { - throw std::runtime_error(RC::fmt("Delegate Signature Function %S does not have a UPackage as it's owner", function->GetName().c_str())); + throw std::runtime_error(RC::fmt("Delegate Signature Function {} does not have a UPackage as it's owner", function->GetName())); } generate_global_delegate_declaration(function, NULL, header_file); } else { - throw std::runtime_error( - RC::fmt("Provided object %S is not of a supported type: %S", object->GetName().c_str(), object->GetClassPrivate()->GetName().c_str())); + throw std::runtime_error(RC::fmt("Provided object {} is not of a supported type: {}", object->GetName(), object->GetClassPrivate()->GetName())); } auto iterator = this->m_module_dependencies.find(module_name); if (iterator == this->m_module_dependencies.end()) { - iterator = this->m_module_dependencies.insert({module_name, std::make_shared>()}).first; + iterator = this->m_module_dependencies.insert({module_name, std::make_shared>()}).first; } if (!header_file.has_content_to_save()) @@ -3875,16 +3901,16 @@ namespace RC::UEGenerator header_file.generate_file_contents(); // Record module names used in the headers - std::shared_ptr> out_dependency_module_names = iterator->second; + std::shared_ptr> out_dependency_module_names = iterator->second; header_file.copy_dependency_module_names(*out_dependency_module_names); implementation_file.copy_dependency_module_names(*out_dependency_module_names); return true; } - auto UEHeaderGenerator::generate_object_pre_declaration(UObject* object) -> std::vector> + auto UEHeaderGenerator::generate_object_pre_declaration(UObject* object) -> std::vector> { - std::vector> pre_declarations; + std::vector> pre_declarations; UClass* object_class = object->GetClassPrivate(); @@ -3894,15 +3920,15 @@ namespace RC::UEGenerator if (uclass->IsChildOf(UInterface::StaticClass())) { - pre_declarations.push_back({STR("class "), get_native_class_name(uclass, true), STR(";\n")}); + pre_declarations.push_back({SYSSTR("class "), get_native_class_name(uclass, true), SYSSTR(";\n")}); } - pre_declarations.push_back({STR("class "), get_native_class_name(uclass, false), STR(";\n")}); + pre_declarations.push_back({SYSSTR("class "), get_native_class_name(uclass, false), SYSSTR(";\n")}); } else if (object_class->IsChildOf(UScriptStruct::StaticClass())) { UScriptStruct* script_struct = static_cast(object); - pre_declarations.push_back({STR("struct "), get_native_struct_name(script_struct), STR(";\n")}); + pre_declarations.push_back({SYSSTR("struct "), get_native_struct_name(script_struct), SYSSTR(";\n")}); } else if (object_class->IsChildOf(UEnum::StaticClass())) { @@ -3917,22 +3943,22 @@ namespace RC::UEGenerator return pre_declarations; } - auto UEHeaderGenerator::get_header_name_for_object(UObject* object, bool get_existing_header) -> std::wstring + auto UEHeaderGenerator::get_header_name_for_object(UObject* object, bool get_existing_header) -> SystemStringType { - File::StringType header_name{}; + SystemStringType header_name{}; UObject* final_object{}; if (object->IsA() || object->IsA()) { // Class and struct headers follow the relevant object name - header_name = object->GetName(); + header_name = to_system(object->GetName()); final_object = object; } else if (object->IsA()) { // Enumeration usually have the E prefix which will be present in the header names // We do not strip it because there are some broken headers that do not follow that convention (e.g. funny Wwise) - header_name = object->GetName(); + header_name = to_system(object->GetName()); final_object = object; } else @@ -3952,8 +3978,8 @@ namespace RC::UEGenerator { // Otherwise, remove the postfix and use the function name as the header name // Also append the delegate postfix because apparently there can be conflicts - std::wstring DelegateName = strip_delegate_signature_postfix(signature_function); - DelegateName.append(STR("Delegate")); + SystemStringType DelegateName = strip_delegate_signature_postfix(signature_function); + DelegateName.append(SYSSTR("Delegate")); header_name = DelegateName; final_object = object; } @@ -3963,21 +3989,21 @@ namespace RC::UEGenerator if (header_name.empty()) { // Unsupported dependency object type - throw std::runtime_error(RC::fmt("Unsupported dependency object type %S: %S", object->GetClassPrivate()->GetName().c_str(), object->GetName().c_str())); + throw std::runtime_error(RC::fmt("Unsupported dependency object type {}: {}", object->GetClassPrivate()->GetName(), object->GetName())); } if (get_existing_header) { if (auto it2 = m_dependency_object_to_unique_id.find(final_object); it2 != m_dependency_object_to_unique_id.end()) { - header_name.append(std::format(STR("{}"), it2->second)); + header_name.append(std::format(SYSSTR("{}"), it2->second)); } } else { if (auto it = m_used_file_names.find(header_name); it != m_used_file_names.end()) { - header_name.append(std::format(STR("{}"), ++it->second.usable_id)); + header_name.append(std::format(SYSSTR("{}"), ++it->second.usable_id)); m_dependency_object_to_unique_id.emplace(final_object, it->second.usable_id); } else @@ -3994,26 +4020,30 @@ namespace RC::UEGenerator generate_delegate_type_declaration(signature_function, delegate_class, header_data); } - auto UEHeaderGenerator::determine_primary_game_module_name() -> std::wstring + auto UEHeaderGenerator::determine_primary_game_module_name() -> SystemStringType { + /* HMODULE primary_executable_module = GetModuleHandleW(NULL); wchar_t module_name_buffer[1024]{'\0'}; GetModuleFileNameW(primary_executable_module, module_name_buffer, ARRAYSIZE(module_name_buffer)); // Retrieve the filename from the full path, strip down the extension - FFilePath root_executable_path((std::wstring(module_name_buffer))); - std::wstring filename = root_executable_path.filename().replace_extension().wstring(); + FFilePath root_executable_path((SystemStringType(module_name_buffer))); + SystemStringType filename = root_executable_path.filename().replace_extension().wstring(); // Remove the shipping file postfix - std::wstring shipping_postfix = STR("-Win64-Shipping"); + SystemStringType shipping_postfix = SYSSTR("-Win64-Shipping"); if (filename.ends_with(shipping_postfix)) { filename.erase(filename.length() - shipping_postfix.length()); } return filename; + */ + return SYSSTR("Main"); } - auto UEHeaderGenerator::generate_cross_module_include(UObject* object, const std::wstring& module_name, const std::wstring& fallback_name) -> std::wstring + auto UEHeaderGenerator::generate_cross_module_include(UObject* object, const SystemStringType& module_name, const SystemStringType& fallback_name) + -> SystemStringType { // Retrieve the most top level object located inside the native package UObject* top_level_object = object; @@ -4023,31 +4053,35 @@ namespace RC::UEGenerator top_level_object = top_level_object->GetOuterPrivate(); } - const std::wstring object_name = top_level_object->GetName(); - return std::format(STR("//CROSS-MODULE INCLUDE V2: -ModuleName={} -ObjectName={} -FallbackName={}\n"), module_name, object_name, fallback_name); + const auto object_name = to_system(top_level_object->GetName()); + return std::format(SYSSTR("//CROSS-MODULE INCLUDE V2: -ModuleName={} -ObjectName={} -FallbackName={}\n"), + to_system(module_name), + object_name, + to_system(fallback_name)); } GeneratedFile::GeneratedFile(const FFilePath& full_file_path) { this->m_full_file_path = full_file_path; - this->m_file_base_name = full_file_path.filename().replace_extension().wstring(); + // [[keep]] + this->m_file_base_name = to_system_string(full_file_path.filename().replace_extension()); this->m_current_indent_count = 0; } - auto GeneratedFile::append_line(const std::wstring& line) -> void + auto GeneratedFile::append_line(const SystemStringType& line) -> void { for (int32_t i = 0; i < m_current_indent_count; i++) { - m_file_contents_buffer.append(STR(" ")); + m_file_contents_buffer.append(SYSSTR(" ")); } m_file_contents_buffer.append(line); - m_file_contents_buffer.append(STR("\n")); + m_file_contents_buffer.append(SYSSTR("\n")); } - auto GeneratedFile::append_line_no_indent(const std::wstring& line) -> void + auto GeneratedFile::append_line_no_indent(const SystemStringType& line) -> void { m_file_contents_buffer.append(line); - m_file_contents_buffer.append(STR("\n")); + m_file_contents_buffer.append(SYSSTR("\n")); } auto GeneratedFile::begin_indent_level() -> void @@ -4072,19 +4106,22 @@ namespace RC::UEGenerator } // TODO might be slow, maybe move it out into the header generator? std::filesystem::create_directories(this->m_full_file_path.parent_path()); - - std::wofstream file_output_stream; + auto file = File::open(m_full_file_path, File::OpenFor::Writing, File::OverwriteExistingFile::Yes, File::CreateIfNonExistent::Yes); + file.write_file_string_to_file(to_file(generate_file_contents())); + /* + UEOStreamType file_output_stream; file_output_stream.open(m_full_file_path); if (!file_output_stream.is_open()) { throw std::invalid_argument("Failed to open the header file"); } - file_output_stream << generate_file_contents(); - file_output_stream.close(); + // TODO: FIX STREAM + file_output_stream << generate_file_contents().c_str(); + file_output_stream.close();*/ return true; } - auto GeneratedFile::generate_file_contents() -> std::wstring + auto GeneratedFile::generate_file_contents() -> SystemStringType { return m_file_contents_buffer; } @@ -4095,24 +4132,24 @@ namespace RC::UEGenerator } auto GeneratedSourceFile::create_source_file(const FFilePath& root_dir, - const std::wstring& module_name, - const std::wstring& base_name, + const SystemStringType& module_name, + const SystemStringType& base_name, bool is_implementation_file, UObject* object) -> GeneratedSourceFile { FFilePath full_file_path; if (is_implementation_file) { - full_file_path = root_dir / module_name / STR("Private") / (base_name + STR(".cpp")); + full_file_path = root_dir / module_name / SYSSTR("Private") / (base_name + SYSSTR(".cpp")); } else { - full_file_path = root_dir / module_name / STR("Public") / (base_name + STR(".h")); + full_file_path = root_dir / module_name / SYSSTR("Public") / (base_name + SYSSTR(".h")); } return GeneratedSourceFile(full_file_path, module_name, is_implementation_file, object); } - GeneratedSourceFile::GeneratedSourceFile(const FFilePath& file_path, const std::wstring& file_module_name, bool is_implementation_file, UObject* object) + GeneratedSourceFile::GeneratedSourceFile(const FFilePath& file_path, const SystemStringType& file_module_name, bool is_implementation_file, UObject* object) : GeneratedFile(file_path) { this->m_file_module_name = file_module_name; @@ -4125,7 +4162,7 @@ namespace RC::UEGenerator this->m_header_file = header_file; } - auto GeneratedSourceFile::add_extra_include(const std::wstring& included_file_name) -> void + auto GeneratedSourceFile::add_extra_include(const SystemStringType& included_file_name) -> void { this->m_extra_includes.insert(included_file_name); } @@ -4141,44 +4178,44 @@ namespace RC::UEGenerator } } - auto GeneratedSourceFile::generate_file_contents() -> std::wstring + auto GeneratedSourceFile::generate_file_contents() -> SystemStringType { - std::wstring result_header_contents; + SystemStringType result_header_contents; result_header_contents.append(generate_includes_string()); - result_header_contents.append(STR("\n")); + result_header_contents.append(SYSSTR("\n")); - std::wstring pre_declarations_string = generate_pre_declarations_string(); + SystemStringType pre_declarations_string = generate_pre_declarations_string(); if (!pre_declarations_string.empty()) { result_header_contents.append(pre_declarations_string); - result_header_contents.append(STR("\n")); + result_header_contents.append(SYSSTR("\n")); } if (!m_implementation_constructor.empty()) { result_header_contents.append(m_implementation_constructor); - result_header_contents.append(STR("\n")); + result_header_contents.append(SYSSTR("\n")); } if (!m_file_contents_buffer.empty()) { result_header_contents.append(m_file_contents_buffer); - result_header_contents.append(STR("\n")); + result_header_contents.append(SYSSTR("\n")); } return result_header_contents; } - auto GeneratedSourceFile::generate_includes_string() const -> std::wstring + auto GeneratedSourceFile::generate_includes_string() const -> SystemStringType { - std::wstring result_include_string; - std::vector> include_lines; - std::vector cross_module_includes; + SystemStringType result_include_string; + std::vector> include_lines; + std::vector cross_module_includes; // For the header file, we generate the pragma and minimal core includes if (!m_is_implementation_file) { - result_include_string.append(STR("#pragma once\n")); - result_include_string.append(STR("#include \"CoreMinimal.h\"\n")); + result_include_string.append(SYSSTR("#pragma once\n")); + result_include_string.append(SYSSTR("#include \"CoreMinimal.h\"\n")); } // For CPP implementation file, we need to generate the header include if (m_is_implementation_file) @@ -4186,19 +4223,19 @@ namespace RC::UEGenerator if (m_header_file != NULL) { // Generate it if we have the correct header file set - result_include_string.append(std::format(STR("#include \"{}.h\"\n"), m_header_file->m_file_base_name)); + result_include_string.append(std::format(SYSSTR("#include \"{}.h\"\n"), m_header_file->m_file_base_name)); } else { // Otherwise, we generate a simple minimal core include - result_include_string.append(STR("#include \"CoreMinimal.h\"\n")); + result_include_string.append(SYSSTR("#include \"CoreMinimal.h\"\n")); } } // Generate extra includes we might need that do not represent objects - for (const std::wstring& extra_included_file : m_extra_includes) + for (const SystemStringType& extra_included_file : m_extra_includes) { - include_lines.push_back({STR("#include \""), extra_included_file, STR("\"\n")}); + include_lines.push_back({SYSSTR("#include \""), extra_included_file, SYSSTR("\"\n")}); } // Generate includes for the relevant object files @@ -4212,7 +4249,7 @@ namespace RC::UEGenerator continue; } - const std::wstring object_header_name = UEHeaderGenerator::get_header_name_for_object(dependency_object, true); + const SystemStringType object_header_name = UEHeaderGenerator::get_header_name_for_object(dependency_object, true); // Definitely skip include if object in question is placed into this header if (object_header_name == m_file_base_name) @@ -4229,7 +4266,7 @@ namespace RC::UEGenerator } } UObject* package = dependency_object->GetOutermost(); - std::wstring native_module_name = UEHeaderGenerator::get_module_name_for_package(package); + SystemStringType native_module_name = UEHeaderGenerator::get_module_name_for_package(package); if (!native_module_name.empty()) { @@ -4237,7 +4274,7 @@ namespace RC::UEGenerator // since generated headers are always located in the module root and follow one file per object convention if (m_file_module_name == native_module_name) { - include_lines.push_back({STR("#include \""), object_header_name, STR(".h\"\n")}); + include_lines.push_back({SYSSTR("#include \""), object_header_name, SYSSTR(".h\"\n")}); } else { @@ -4254,13 +4291,13 @@ namespace RC::UEGenerator // Remove duplicates - there are sometimes multiple instances of the same cross module include cross_module_includes.erase(std::unique(cross_module_includes.begin(), cross_module_includes.end()), cross_module_includes.end()); - for (const std::wstring& cross_module_include : cross_module_includes) + for (const SystemStringType& cross_module_include : cross_module_includes) { result_include_string.append(cross_module_include); } // Sort the includes by module name, since we want to make sure that they are always in the same order - std::sort(include_lines.begin(), include_lines.end(), [](const std::vector& a, const std::vector& b) { + std::sort(include_lines.begin(), include_lines.end(), [](const std::vector& a, const std::vector& b) { return a[1] < b[1]; }); @@ -4275,15 +4312,15 @@ namespace RC::UEGenerator // Last include of the header file should always be a generated one if (!m_is_implementation_file) { - result_include_string.append(std::format(STR("#include \"{}.generated.h\"\n"), m_file_base_name)); + result_include_string.append(std::format(SYSSTR("#include \"{}.generated.h\"\n"), m_file_base_name)); } return result_include_string; } - auto GeneratedSourceFile::generate_pre_declarations_string() const -> std::wstring + auto GeneratedSourceFile::generate_pre_declarations_string() const -> SystemStringType { - std::wstring result_declarations; - std::vector>> pre_declarations; + SystemStringType result_declarations; + std::vector>> pre_declarations; // Generate pre-declarations for the relevant object files for (const auto& dependency_pair : m_dependencies) @@ -4298,7 +4335,7 @@ namespace RC::UEGenerator // We still need to reference the object's owner module UObject* package = dependency_object->GetOutermost(); - std::wstring native_module_name = UEHeaderGenerator::get_module_name_for_package(package); + SystemStringType native_module_name = UEHeaderGenerator::get_module_name_for_package(package); if (!native_module_name.empty() && m_file_module_name != native_module_name) { @@ -4311,7 +4348,7 @@ namespace RC::UEGenerator // Sort the entries alphabetically by the class name std::sort(pre_declarations.begin(), pre_declarations.end(), - [](const std::vector>& a, const std::vector>& b) { + [](const std::vector>& a, const std::vector>& b) { return a[0][1] < b[0][1]; }); diff --git a/UE4SS/src/SettingsManager.cpp b/UE4SS/src/SettingsManager.cpp index 56557f7d4..ad29c752f 100644 --- a/UE4SS/src/SettingsManager.cpp +++ b/UE4SS/src/SettingsManager.cpp @@ -5,7 +5,7 @@ #define REGISTER_STRING_SETTING(member_var, section_name, key) \ try \ { \ - (member_var) = parser.get_string(section_name, STR(#key)); \ + (member_var) = parser.get_string(section_name, SYSSTR(#key)); \ } \ catch (std::exception&) \ { \ @@ -14,7 +14,7 @@ #define REGISTER_INT64_SETTING(member_var, section_name, key) \ try \ { \ - (member_var) = parser.get_int64(section_name, STR(#key)); \ + (member_var) = parser.get_int64(section_name, SYSSTR(#key)); \ } \ catch (std::exception&) \ { \ @@ -23,7 +23,7 @@ #define REGISTER_BOOL_SETTING(member_var, section_name, key) \ try \ { \ - (member_var) = parser.get_bool(section_name, STR(#key)); \ + (member_var) = parser.get_bool(section_name, SYSSTR(#key)); \ } \ catch (std::exception&) \ { \ @@ -32,7 +32,7 @@ #define REGISTER_FLOAT_SETTING(member_var, section_name, key) \ try \ { \ - (member_var) = parser.get_float(section_name, STR(#key)); \ + (member_var) = parser.get_float(section_name, SYSSTR(#key)); \ } \ catch (std::exception&) \ { \ @@ -46,31 +46,31 @@ namespace RC Ini::Parser parser; parser.parse(file); file.close(); - - constexpr static File::CharType section_overrides[] = STR("Overrides"); + constexpr static SystemCharType section_overrides[] = SYSSTR("Overrides"); REGISTER_STRING_SETTING(Overrides.ModsFolderPath, section_overrides, ModsFolderPath) - constexpr static File::CharType section_general[] = STR("General"); + constexpr static SystemCharType section_general[] = SYSSTR("General"); REGISTER_BOOL_SETTING(General.EnableHotReloadSystem, section_general, EnableHotReloadSystem) REGISTER_BOOL_SETTING(General.UseCache, section_general, UseCache) REGISTER_BOOL_SETTING(General.InvalidateCacheIfDLLDiffers, section_general, InvalidateCacheIfDLLDiffers) REGISTER_BOOL_SETTING(General.EnableDebugKeyBindings, section_general, EnableDebugKeyBindings) REGISTER_INT64_SETTING(General.SecondsToScanBeforeGivingUp, section_general, SecondsToScanBeforeGivingUp) REGISTER_BOOL_SETTING(General.UseUObjectArrayCache, section_general, bUseUObjectArrayCache) + REGISTER_STRING_SETTING(General.InputSource, section_general, InputSource) - constexpr static File::CharType section_engine_version_override[] = STR("EngineVersionOverride"); + constexpr static SystemCharType section_engine_version_override[] = SYSSTR("EngineVersionOverride"); REGISTER_INT64_SETTING(EngineVersionOverride.MajorVersion, section_engine_version_override, MajorVersion) REGISTER_INT64_SETTING(EngineVersionOverride.MinorVersion, section_engine_version_override, MinorVersion) - constexpr static File::CharType section_object_dumper[] = STR("ObjectDumper"); + constexpr static SystemCharType section_object_dumper[] = SYSSTR("ObjectDumper"); REGISTER_BOOL_SETTING(ObjectDumper.LoadAllAssetsBeforeDumpingObjects, section_object_dumper, LoadAllAssetsBeforeDumpingObjects) - constexpr static File::CharType section_cxx_header_generator[] = STR("CXXHeaderGenerator"); + constexpr static SystemCharType section_cxx_header_generator[] = SYSSTR("CXXHeaderGenerator"); REGISTER_BOOL_SETTING(CXXHeaderGenerator.DumpOffsetsAndSizes, section_cxx_header_generator, DumpOffsetsAndSizes) REGISTER_BOOL_SETTING(CXXHeaderGenerator.KeepMemoryLayout, section_cxx_header_generator, KeepMemoryLayout) REGISTER_BOOL_SETTING(CXXHeaderGenerator.LoadAllAssetsBeforeGeneratingCXXHeaders, section_cxx_header_generator, LoadAllAssetsBeforeGeneratingCXXHeaders) - constexpr static File::CharType section_uht_header_generator[] = STR("UHTHeaderGenerator"); + constexpr static SystemCharType section_uht_header_generator[] = SYSSTR("UHTHeaderGenerator"); REGISTER_BOOL_SETTING(UHTHeaderGenerator.IgnoreAllCoreEngineModules, section_uht_header_generator, IgnoreAllCoreEngineModules) REGISTER_BOOL_SETTING(UHTHeaderGenerator.IgnoreEngineAndCoreUObject, section_uht_header_generator, IgnoreEngineAndCoreUObject) REGISTER_BOOL_SETTING(UHTHeaderGenerator.MakeAllFunctionsBlueprintCallable, section_uht_header_generator, MakeAllFunctionsBlueprintCallable) @@ -78,34 +78,37 @@ namespace RC REGISTER_BOOL_SETTING(UHTHeaderGenerator.MakeEnumClassesBlueprintType, section_uht_header_generator, MakeEnumClassesBlueprintType) REGISTER_BOOL_SETTING(UHTHeaderGenerator.MakeAllConfigsEngineConfig, section_uht_header_generator, MakeAllConfigsEngineConfig) - constexpr static File::CharType section_debug[] = STR("Debug"); + constexpr static SystemCharType section_debug[] = SYSSTR("Debug"); REGISTER_BOOL_SETTING(Debug.SimpleConsoleEnabled, section_debug, ConsoleEnabled) REGISTER_BOOL_SETTING(Debug.DebugConsoleEnabled, section_debug, GuiConsoleEnabled) REGISTER_BOOL_SETTING(Debug.DebugConsoleVisible, section_debug, GuiConsoleVisible) REGISTER_FLOAT_SETTING(Debug.DebugGUIFontScaling, section_debug, GuiConsoleFontScaling) - StringType graphics_api_string{}; + SystemStringType graphics_api_string{}; REGISTER_STRING_SETTING(graphics_api_string, section_debug, GraphicsAPI) - if (String::iequal(graphics_api_string, STR("DX11")) || String::iequal(graphics_api_string, STR("D3D11"))) + if (false) + { + } + else if (String::iequal(graphics_api_string, SYSSTR("DX11")) || String::iequal(graphics_api_string, SYSSTR("D3D11"))) { Debug.GraphicsAPI = GUI::GfxBackend::DX11; } - else if (String::iequal(graphics_api_string, STR("OpenGL"))) + else if (String::iequal(graphics_api_string, SYSSTR("OpenGL"))) { Debug.GraphicsAPI = GUI::GfxBackend::GLFW3_OpenGL3; } - constexpr static File::CharType section_crash_dump[] = STR("CrashDump"); - REGISTER_BOOL_SETTING(CrashDump.EnableDumping, section_crash_dump, EnableDumping); - REGISTER_BOOL_SETTING(CrashDump.FullMemoryDump, section_crash_dump, FullMemoryDump); + /// constexpr static SystemCharType section_crash_dump[] = SSTR("CrashDump"); + /// REGISTER_BOOL_SETTING(CrashDump.EnableDumping, section_crash_dump, EnableDumping); + /// REGISTER_BOOL_SETTING(CrashDump.FullMemoryDump, section_crash_dump, FullMemoryDump); - constexpr static File::CharType section_threads[] = STR("Threads"); + constexpr static SystemCharType section_threads[] = SYSSTR("Threads"); REGISTER_INT64_SETTING(Threads.SigScannerNumThreads, section_threads, SigScannerNumThreads) REGISTER_INT64_SETTING(Threads.SigScannerMultithreadingModuleSizeThreshold, section_threads, SigScannerMultithreadingModuleSizeThreshold) - constexpr static File::CharType section_memory[] = STR("Memory"); + constexpr static SystemCharType section_memory[] = SYSSTR("Memory"); REGISTER_INT64_SETTING(Memory.MaxMemoryUsageDuringAssetLoading, section_memory, MaxMemoryUsageDuringAssetLoading) - constexpr static File::CharType section_hooks[] = STR("Hooks"); + constexpr static SystemCharType section_hooks[] = SYSSTR("Hooks"); REGISTER_BOOL_SETTING(Hooks.HookProcessInternal, section_hooks, HookProcessInternal) REGISTER_BOOL_SETTING(Hooks.HookProcessLocalScriptFunction, section_hooks, HookProcessLocalScriptFunction) REGISTER_BOOL_SETTING(Hooks.HookLoadMap, section_hooks, HookLoadMap) @@ -116,7 +119,7 @@ namespace RC REGISTER_BOOL_SETTING(Hooks.HookAActorTick, section_hooks, HookAActorTick) REGISTER_INT64_SETTING(Hooks.FExecVTableOffsetInLocalPlayer, section_hooks, FExecVTableOffsetInLocalPlayer) - constexpr static File::CharType section_experimental_features[] = STR("ExperimentalFeatures"); + constexpr static SystemCharType section_experimental_features[] = SYSSTR("ExperimentalFeatures"); REGISTER_BOOL_SETTING(Experimental.GUIUFunctionCaller, section_experimental_features, GUIUFunctionCaller) } } // namespace RC diff --git a/UE4SS/src/Signatures.cpp b/UE4SS/src/Signatures.cpp index 147feec75..e841b64bc 100644 --- a/UE4SS/src/Signatures.cpp +++ b/UE4SS/src/Signatures.cpp @@ -18,7 +18,7 @@ namespace RC { } - auto scan_from_lua_script(std::wstring& script_file_path_and_name, + auto scan_from_lua_script(SystemStringType& script_file_path_and_name, std::vector& signature_containers, LuaScriptMatchFoundFunc& match_found_func, LuaScriptScanCompleteFunc& scan_complete_func) -> void @@ -31,14 +31,14 @@ namespace RC lua.register_function("DerefToInt32", LuaLibrary::deref_to_int32); lua.register_function("dereftoint32", LuaLibrary::deref_to_int32); - lua.execute_file(script_file_path_and_name); + lua.execute_file(to_lua(script_file_path_and_name)); constexpr const char* global_register_func_name = "Register"; constexpr const char* global_on_match_found_func_name = "OnMatchFound"; if (!lua.is_global_function(global_register_func_name) || !lua.is_global_function(global_on_match_found_func_name)) { - Output::send(STR("Lua functions 'Register' and 'OnMatchFound' must be present in {}\n"), script_file_path_and_name); + Output::send(SYSSTR("Lua functions 'Register' and 'OnMatchFound' must be present in {}\n"), script_file_path_and_name); throw std::runtime_error{"See error message above"}; } @@ -91,7 +91,7 @@ namespace RC auto setup_lua_scan_overrides(std::filesystem::path& working_directory, Unreal::UnrealInitializer::Config& config) -> void { - std::wstring lua_guobjectarray_scan_script = working_directory / "UE4SS_Signatures/GUObjectArray.lua"; + auto lua_guobjectarray_scan_script = to_system(working_directory / "UE4SS_Signatures/GUObjectArray.lua"); if (std::filesystem::exists(lua_guobjectarray_scan_script)) { config.ScanOverrides.guobjectarray = [lua_guobjectarray_scan_script](std::vector& signature_containers, @@ -100,7 +100,7 @@ namespace RC lua_guobjectarray_scan_script, signature_containers, [](void* address) { - Output::send(STR("GUObjectArray address: {} <- Lua Script\n"), address); + Output::send(SYSSTR("GUObjectArray address: {} <- Lua Script\n"), address); Unreal::UObjectArray::SetupGUObjectArrayAddress(address); return DidLuaScanSucceed::Yes; }, @@ -113,7 +113,7 @@ namespace RC }; } - std::wstring lua_fts_scan_script = working_directory / "UE4SS_Signatures/FName_ToString.lua"; + auto lua_fts_scan_script = to_system(working_directory / "UE4SS_Signatures/FName_ToString.lua"); if (std::filesystem::exists(lua_fts_scan_script)) { config.ScanOverrides.fname_to_string = [lua_fts_scan_script](std::vector& signature_containers, @@ -122,7 +122,7 @@ namespace RC lua_fts_scan_script, signature_containers, [](void* address) { - Output::send(STR("FName::ToString address: {} <- Lua Script\n"), address); + Output::send(SYSSTR("FName::ToString address: {} <- Lua Script\n"), address); Unreal::FName::ToStringInternal.assign_address(address); return DidLuaScanSucceed::Yes; }, @@ -135,7 +135,7 @@ namespace RC }; } - std::wstring lua_fnc_scan_script = working_directory / "UE4SS_Signatures/FName_Constructor.lua"; + auto lua_fnc_scan_script = to_system(working_directory / "UE4SS_Signatures/FName_Constructor.lua"); if (std::filesystem::exists(lua_fnc_scan_script)) { config.ScanOverrides.fname_constructor = [lua_fnc_scan_script](std::vector& signature_containers, @@ -144,11 +144,11 @@ namespace RC lua_fnc_scan_script, signature_containers, [&scan_result](void* address) { - Unreal::FName name = Unreal::FName(L"bCanBeDamaged", Unreal::FNAME_Find, address); + Unreal::FName name = Unreal::FName(STR("bCanBeDamaged"), Unreal::FNAME_Find, address); - if (name == L"bCanBeDamaged") + if (name == STR("bCanBeDamaged")) { - Output::send(STR("FName::FName address: {} <- Lua Script\n"), address); + Output::send(SYSSTR("FName::FName address: {} <- Lua Script\n"), address); Unreal::FName::ConstructorInternal.assign_address(address); return DidLuaScanSucceed::Yes; } @@ -168,8 +168,8 @@ namespace RC } // For compatibility, we look for 'FMemory_Free.lua' if 'GMalloc.lua' doesn't exist. - std::wstring lua_ffree_scan_script_new = working_directory / "UE4SS_Signatures/GMalloc.lua"; - std::wstring lua_ffree_scan_script_compat = working_directory / "UE4SS_Signatures/FMemory_Free.lua"; + auto lua_ffree_scan_script_new = to_system(working_directory / "UE4SS_Signatures/GMalloc.lua"); + auto lua_ffree_scan_script_compat = to_system(working_directory / "UE4SS_Signatures/FMemory_Free.lua"); auto lua_ffree_scan_script = std::filesystem::exists(lua_ffree_scan_script_new) ? lua_ffree_scan_script_new : lua_ffree_scan_script_compat; if (std::filesystem::exists(lua_ffree_scan_script)) { @@ -179,7 +179,7 @@ namespace RC lua_ffree_scan_script, signature_containers, [](void* address) { - Output::send(STR("GMalloc address: {} <- Lua Script\n"), address); + Output::send(SYSSTR("GMalloc address: {} <- Lua Script\n"), address); Unreal::FMalloc::UnrealStaticGMalloc = static_cast(address); Unreal::GMalloc = *Unreal::FMalloc::UnrealStaticGMalloc; return DidLuaScanSucceed::Yes; @@ -193,7 +193,7 @@ namespace RC }; } - std::wstring lua_sco_scan_script = working_directory / "UE4SS_Signatures/StaticConstructObject.lua"; + auto lua_sco_scan_script = to_system(working_directory / "UE4SS_Signatures/StaticConstructObject.lua"); if (std::filesystem::exists(lua_sco_scan_script)) { config.ScanOverrides.static_construct_object = [lua_sco_scan_script](std::vector& signature_containers, @@ -202,7 +202,7 @@ namespace RC lua_sco_scan_script, signature_containers, [](void* address) { - Output::send(STR("StaticConstructObject_Internal address: {} <- Lua Script\n"), address); + Output::send(SYSSTR("StaticConstructObject_Internal address: {} <- Lua Script\n"), address); Unreal::UObjectGlobals::SetupStaticConstructObjectInternalAddress(address); return DidLuaScanSucceed::Yes; }, @@ -215,7 +215,7 @@ namespace RC }; } - std::wstring lua_ftc_scan_script = working_directory / "UE4SS_Signatures/FText_Constructor.lua"; + auto lua_ftc_scan_script = to_system(working_directory / "UE4SS_Signatures/FText_Constructor.lua"); if (std::filesystem::exists(lua_ftc_scan_script)) { config.ScanOverrides.ftext_constructor = [lua_ftc_scan_script](std::vector& signature_containers, @@ -224,11 +224,11 @@ namespace RC lua_ftc_scan_script, signature_containers, [&scan_result](void* address) { - Unreal::FText text = Unreal::FText(L"bCanBeDamaged", address); + Unreal::FText text = Unreal::FText(STR("bCanBeDamaged"), address); - if (text == L"bCanBeDamaged") + if (text == STR("bCanBeDamaged")) { - Output::send(STR("FText::FText address: {} <- Lua Script\n"), address); + Output::send(SYSSTR("FText::FText address: {} <- Lua Script\n"), address); Unreal::FText::ConstructorInternal.assign_address(address); return DidLuaScanSucceed::Yes; } diff --git a/UE4SS/src/UE4SSProgram.cpp b/UE4SS/src/UE4SSProgram.cpp index e753c31d3..1b18d6c39 100644 --- a/UE4SS/src/UE4SSProgram.cpp +++ b/UE4SS/src/UE4SSProgram.cpp @@ -94,12 +94,12 @@ namespace RC #define OUTPUT_MEMBER_OFFSETS_FOR_STRUCT(StructName) \ for (const auto& [name, offset] : Unreal::StructName::MemberOffsets) \ { \ - Output::send(STR(#StructName "::{} = 0x{:X}\n"), name, offset); \ + Output::send(SYSSTR(#StructName "::{} = 0x{:X}\n"), name, offset); \ } auto output_all_member_offsets() -> void { - Output::send(STR("\n##### MEMBER OFFSETS START #####\n\n")); + Output::send(SYSSTR("\n##### MEMBER OFFSETS START #####\n\n")); OUTPUT_MEMBER_OFFSETS_FOR_STRUCT(UObjectBase); OUTPUT_MEMBER_OFFSETS_FOR_STRUCT(UScriptStruct); OUTPUT_MEMBER_OFFSETS_FOR_STRUCT(UScriptStruct::ICppStructOps); @@ -126,14 +126,14 @@ namespace RC OUTPUT_MEMBER_OFFSETS_FOR_STRUCT(FSoftClassProperty); OUTPUT_MEMBER_OFFSETS_FOR_STRUCT(FInterfaceProperty); OUTPUT_MEMBER_OFFSETS_FOR_STRUCT(FFieldPathProperty); - Output::send(STR("\n##### MEMBER OFFSETS END #####\n\n")); + Output::send(SYSSTR("\n##### MEMBER OFFSETS END #####\n\n")); } void* HookedLoadLibraryA(const char* dll_name) { UE4SSProgram& program = UE4SSProgram::get_program(); HMODULE lib = PLH::FnCast(program.m_hook_trampoline_load_library_a, &LoadLibraryA)(dll_name); - program.fire_dll_load_for_cpp_mods(to_wstring(dll_name)); + program.fire_dll_load_for_cpp_mods(to_system(dll_name)); return lib; } @@ -141,7 +141,7 @@ namespace RC { UE4SSProgram& program = UE4SSProgram::get_program(); HMODULE lib = PLH::FnCast(program.m_hook_trampoline_load_library_ex_a, &LoadLibraryExA)(dll_name, file, flags); - program.fire_dll_load_for_cpp_mods(to_wstring(dll_name)); + program.fire_dll_load_for_cpp_mods(to_system(dll_name)); return lib; } @@ -176,7 +176,7 @@ namespace RC } catch (std::exception& e) { - create_emergency_console_for_early_error(std::format(STR("The IniParser failed to parse: {}"), to_wstring(e.what()))); + set_error("The IniParser failed to parse: %s", to_system(e.what()).data()); return; } @@ -198,8 +198,8 @@ namespace RC if (settings_manager.Debug.DebugConsoleEnabled) { m_console_device = &Output::set_default_devices(); - m_console_device->set_formatter([](File::StringViewType string) -> File::StringType { - return std::format(STR("[{}] {}"), std::format(STR("{:%X}"), std::chrono::system_clock::now()), string); + m_console_device->set_formatter([](SystemStringViewType string) -> SystemStringType { + return std::format(SYSSTR("[{}] {}"), std::format(SYSSTR("{:%X}"), std::chrono::system_clock::now()), string); }); if (settings_manager.Debug.DebugConsoleVisible) { @@ -213,56 +213,61 @@ namespace RC constexpr const wchar_t* str_to_find = STR("Allocator: %s"); void* string_address = SinglePassScanner::string_scan(str_to_find, ScanTarget::Core); - Output::send(STR("\n\nFound string '{}' at {}\n\n"), std::wstring_view{str_to_find}, string_address); + Output::send(SYSSTR("\n\nFound string '{}' at {}\n\n"), SystemStringViewType{str_to_find}, string_address); //*/ - Output::send(STR("Console created\n")); - Output::send(STR("UE4SS - v{}.{}.{}{}{} - Git SHA #{}\n"), + Output::send(SYSSTR("dir: {}\n"), (m_log_directory / m_log_file_name)); + + Output::send(SYSSTR("Console created\n")); + Output::send(SYSSTR("UE4SS - v{}.{}.{}{}{} - Git SHA #{}\n"), UE4SS_LIB_VERSION_MAJOR, UE4SS_LIB_VERSION_MINOR, UE4SS_LIB_VERSION_HOTFIX, - std::format(L"{}", UE4SS_LIB_VERSION_PRERELEASE == 0 ? L"" : std::format(L" PreRelease #{}", UE4SS_LIB_VERSION_PRERELEASE)), - std::format(L"{}", - UE4SS_LIB_BETA_STARTED == 0 ? L"" : (UE4SS_LIB_IS_BETA == 0 ? L" Beta #?" : std::format(L" Beta #{}", UE4SS_LIB_VERSION_BETA))), - to_wstring(UE4SS_LIB_BUILD_GITSHA)); + std::format(SYSSTR("{}"), + UE4SS_LIB_VERSION_PRERELEASE == 0 ? SYSSTR("") : std::format(SYSSTR(" PreRelease #{}"), UE4SS_LIB_VERSION_PRERELEASE)), + std::format(SYSSTR("{}"), + UE4SS_LIB_BETA_STARTED == 0 + ? SYSSTR("") + : (UE4SS_LIB_IS_BETA == 0 ? SYSSTR(" Beta #?") : std::format(SYSSTR(" Beta #{}"), UE4SS_LIB_VERSION_BETA))), + to_system(UE4SS_LIB_BUILD_GITSHA)); #ifdef __clang__ -#define UE4SS_COMPILER L"Clang" +#define UE4SS_COMPILER SYSSTR("Clang") #else -#define UE4SS_COMPILER L"MSVC" +#define UE4SS_COMPILER SYSSTR("MSVC") #endif - Output::send(STR("UE4SS Build Configuration: {} ({})\n"), to_wstring(UE4SS_CONFIGURATION), UE4SS_COMPILER); + Output::send(SYSSTR("UE4SS Build Configuration: {} ({})\n"), to_system(UE4SS_CONFIGURATION), UE4SS_COMPILER); m_load_library_a_hook = std::make_unique("kernel32.dll", "LoadLibraryA", std::bit_cast(&HookedLoadLibraryA), &m_hook_trampoline_load_library_a, - L""); + SYSSTR("")); m_load_library_a_hook->hook(); m_load_library_ex_a_hook = std::make_unique("kernel32.dll", "LoadLibraryExA", std::bit_cast(&HookedLoadLibraryExA), &m_hook_trampoline_load_library_ex_a, - L""); + SYSSTR("")); m_load_library_ex_a_hook->hook(); m_load_library_w_hook = std::make_unique("kernel32.dll", "LoadLibraryW", std::bit_cast(&HookedLoadLibraryW), &m_hook_trampoline_load_library_w, - L""); + SYSSTR("")); m_load_library_w_hook->hook(); m_load_library_ex_w_hook = std::make_unique("kernel32.dll", "LoadLibraryExW", std::bit_cast(&HookedLoadLibraryExW), &m_hook_trampoline_load_library_ex_w, - L""); + SYSSTR("")); m_load_library_ex_w_hook->hook(); - Unreal::UnrealInitializer::SetupUnrealModules(); + Unreal::UnrealInitializer::Platform::SetupUnrealModules(); setup_mods(); install_cpp_mods(); @@ -272,21 +277,21 @@ namespace RC if (m_has_game_specific_config) { - Output::send(STR("Found configuration for game: {}\n"), m_mods_directory.parent_path().filename().c_str()); + Output::send(SYSSTR("Found configuration for game: {}\n"), m_mods_directory.parent_path().filename().c_str()); } else { - Output::send(STR("No specific game configuration found, using default configuration file\n")); + Output::send(SYSSTR("No specific game configuration found, using default configuration file\n")); } - Output::send(STR("Config: {}\n\n"), m_settings_path_and_file.c_str()); - Output::send(STR("root directory: {}\n"), m_root_directory.c_str()); - Output::send(STR("working directory: {}\n"), m_working_directory.c_str()); - Output::send(STR("game executable directory: {}\n"), m_game_executable_directory.c_str()); - Output::send(STR("game executable: {} ({} bytes)\n\n\n"), m_game_path_and_exe_name.c_str(), std::filesystem::file_size(m_game_path_and_exe_name)); - Output::send(STR("mods directory: {}\n"), m_mods_directory.c_str()); - Output::send(STR("log directory: {}\n"), m_log_directory.c_str()); - Output::send(STR("object dumper directory: {}\n\n\n"), m_object_dumper_output_directory.c_str()); + Output::send(SYSSTR("Config: {}\n\n"), m_settings_path_and_file.c_str()); + Output::send(SYSSTR("root directory: {}\n"), m_root_directory.c_str()); + Output::send(SYSSTR("working directory: {}\n"), m_working_directory.c_str()); + Output::send(SYSSTR("game executable directory: {}\n"), m_game_executable_directory.c_str()); + Output::send(SYSSTR("game executable: {} ({} bytes)\n\n\n"), m_game_path_and_exe_name.c_str(), std::filesystem::file_size(m_game_path_and_exe_name)); + Output::send(SYSSTR("mods directory: {}\n"), m_mods_directory.c_str()); + Output::send(SYSSTR("log directory: {}\n"), m_log_directory.c_str()); + Output::send(SYSSTR("object dumper directory: {}\n\n\n"), m_object_dumper_output_directory.c_str()); } catch (std::runtime_error& e) { @@ -317,11 +322,13 @@ namespace RC ProfilerSetThreadName("UE4SS-InitThread"); ProfilerScope(); + Output::send(SYSSTR("Initializing ue4ss program\n")); + try { setup_unreal(); - Output::send(STR("Unreal Engine modules ({}):\n"), SigScannerStaticData::m_is_modular ? STR("modular") : STR("non-modular")); + Output::send(SYSSTR("Unreal Engine modules ({}):\n"), SigScannerStaticData::m_is_modular ? SYSSTR("modular") : SYSSTR("non-modular")); auto& main_exe_ptr = SigScannerStaticData::m_modules_info.array[static_cast(ScanTarget::MainExe)].lpBaseOfDll; for (size_t i = 0; i < static_cast(ScanTarget::Max); ++i) { @@ -329,8 +336,8 @@ namespace RC // only log modules with unique addresses (non-modular builds have everything in MainExe) if (i == static_cast(ScanTarget::MainExe) || main_exe_ptr != module.lpBaseOfDll) { - auto module_name = to_wstring(ScanTargetToString(i)); - Output::send(STR("{} @ {} size={:#x}\n"), module_name.c_str(), module.lpBaseOfDll, module.SizeOfImage); + auto module_name = to_system(ScanTargetToString(i)); + Output::send(SYSSTR("{} @ {} size={:#x}\n"), module_name.c_str(), module.lpBaseOfDll, module.SizeOfImage); } } @@ -367,12 +374,12 @@ namespace RC } } - auto UE4SSProgram::setup_paths(const std::wstring& moduleFilePathString) -> void + auto UE4SSProgram::setup_paths(const SystemStringType& moduleFilePathString) -> void { ProfilerScope(); const std::filesystem::path moduleFilePath = std::filesystem::path(moduleFilePathString); - m_root_directory = moduleFilePath.parent_path().wstring(); - m_module_file_path = moduleFilePath.wstring(); + m_root_directory = to_system(moduleFilePath.parent_path()); + m_module_file_path = to_system(moduleFilePath); // The default working directory is the root directory // Can be changed by creating a directory in the root directory @@ -406,7 +413,7 @@ namespace RC { m_has_game_specific_config = true; m_working_directory = item.path(); - m_mods_directory = item.path().wstring() + L"\\Mods"; + m_mods_directory = item.path() / SYSSTR("Mods"); m_settings_path_and_file = std::move(item.path()); m_log_directory = m_working_directory; m_object_dumper_output_directory = m_working_directory; @@ -429,11 +436,11 @@ namespace RC } } - auto UE4SSProgram::create_emergency_console_for_early_error(File::StringViewType error_message) -> void + auto UE4SSProgram::create_emergency_console_for_early_error(SystemStringViewType error_message) -> void { settings_manager.Debug.SimpleConsoleEnabled = true; create_simple_console(); - printf_s("%S\n", error_message.data()); + printf_s(SystemStringPrint "\n", error_message.data()); } auto UE4SSProgram::setup_mod_directory_path() -> void @@ -456,8 +463,8 @@ namespace RC { m_debug_console_device = &Output::set_default_devices(); Output::set_default_log_level(); - m_debug_console_device->set_formatter([](File::StringViewType string) -> File::StringType { - return std::format(STR("[{}] {}"), std::format(STR("{:%X}"), std::chrono::system_clock::now()), string); + m_debug_console_device->set_formatter([](SystemStringViewType string) -> SystemStringType { + return std::format(SYSSTR("[{}] {}"), std::format(SYSSTR("{:%X}"), std::chrono::system_clock::now()), string); }); if (AllocConsole()) @@ -478,10 +485,11 @@ namespace RC if (std::filesystem::exists(file_path)) { auto file = File::open(file_path); - if (auto file_contents = file.read_all(); !file_contents.empty()) + if (auto file_contents = file.read_file_all(); !file_contents.empty()) { Ini::Parser parser; - parser.parse(file_contents); + auto content = to_system_string(file_contents); + parser.parse(content); file.close(); // The following code is auto-generated. @@ -493,8 +501,10 @@ namespace RC auto UE4SSProgram::setup_unreal() -> void { ProfilerScope(); + Output::send(SYSSTR("Setting up unreal\n")); + // Retrieve offsets from the config file - const std::wstring offset_overrides_section{L"OffsetOverrides"}; + const SystemStringType offset_overrides_section{SYSSTR("OffsetOverrides")}; load_unreal_offsets_from_file(); @@ -562,7 +572,7 @@ namespace RC // Virtual function offset overrides TRY([&]() { ProfilerScopeNamed("loading virtual function offset overrides"); - static File::StringType virtual_function_offset_override_file{(m_working_directory / STR("VTableLayout.ini")).wstring()}; + static auto virtual_function_offset_override_file{m_working_directory / SYSSTR("VTableLayout.ini")}; if (std::filesystem::exists(virtual_function_offset_override_file)) { auto file = @@ -570,72 +580,75 @@ namespace RC Ini::Parser parser; parser.parse(file); - Output::send(STR("Getting ordered lists from ini file\n")); + Output::send(SYSSTR("Getting ordered lists from ini file\n")); auto calculate_virtual_function_offset = [](uint32_t current_index, BaseSizes... base_sizes) -> uint32_t { return current_index == 0 ? 0 : (current_index + (base_sizes + ...)) * 8; }; - auto retrieve_vtable_layout_from_ini = [&](const File::StringType& section_name, auto callable) -> uint32_t { + auto retrieve_vtable_layout_from_ini = [&](const SystemStringType& section_name, auto callable) -> uint32_t { auto list = parser.get_ordered_list(section_name); uint32_t vtable_size = list.size() - 1; - list.for_each([&](uint32_t index, File::StringType& item) { - callable(index, item); + list.for_each([&](uint32_t index, SystemStringType& item) { + auto ue_str = to_ue(item); + callable(index, item, ue_str); }); return vtable_size; }; - Output::send(STR("UObjectBase\n")); - uint32_t uobjectbase_size = retrieve_vtable_layout_from_ini(STR("UObjectBase"), [&](uint32_t index, File::StringType& item) { - uint32_t offset = calculate_virtual_function_offset(index, 0); - Output::send(STR("UObjectBase::{} = 0x{:X}\n"), item, offset); - Unreal::UObjectBase::VTableLayoutMap.emplace(item, offset); - }); - - Output::send(STR("UObjectBaseUtility\n")); - uint32_t uobjectbaseutility_size = retrieve_vtable_layout_from_ini(STR("UObjectBaseUtility"), [&](uint32_t index, File::StringType& item) { - uint32_t offset = calculate_virtual_function_offset(index, uobjectbase_size); - Output::send(STR("UObjectBaseUtility::{} = 0x{:X}\n"), item, offset); - Unreal::UObjectBaseUtility::VTableLayoutMap.emplace(item, offset); - }); - - Output::send(STR("UObject\n")); - uint32_t uobject_size = retrieve_vtable_layout_from_ini(STR("UObject"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("UObjectBase\n")); + uint32_t uobjectbase_size = + retrieve_vtable_layout_from_ini(SYSSTR("UObjectBase"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { + uint32_t offset = calculate_virtual_function_offset(index, 0); + Output::send(SYSSTR("UObjectBase::{} = 0x{:X}\n"), item, offset); + Unreal::UObjectBase::VTableLayoutMap.emplace(item_ue, offset); + }); + + Output::send(SYSSTR("UObjectBaseUtility\n")); + uint32_t uobjectbaseutility_size = + retrieve_vtable_layout_from_ini(SYSSTR("UObjectBaseUtility"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { + uint32_t offset = calculate_virtual_function_offset(index, uobjectbase_size); + Output::send(SYSSTR("UObjectBaseUtility::{} = 0x{:X}\n"), item, offset); + Unreal::UObjectBaseUtility::VTableLayoutMap.emplace(item_ue, offset); + }); + + Output::send(SYSSTR("UObject\n")); + uint32_t uobject_size = retrieve_vtable_layout_from_ini(SYSSTR("UObject"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, uobjectbase_size, uobjectbaseutility_size); - Output::send(STR("UObject::{} = 0x{:X}\n"), item, offset); - Unreal::UObject::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("UObject::{} = 0x{:X}\n"), item, offset); + Unreal::UObject::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("UField\n")); - uint32_t ufield_size = retrieve_vtable_layout_from_ini(STR("UField"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("UField\n")); + uint32_t ufield_size = retrieve_vtable_layout_from_ini(SYSSTR("UField"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, uobjectbase_size, uobjectbaseutility_size, uobject_size); - Output::send(STR("UField::{} = 0x{:X}\n"), item, offset); - Unreal::UField::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("UField::{} = 0x{:X}\n"), item, offset); + Unreal::UField::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("UEngine\n")); - uint32_t uengine_size = retrieve_vtable_layout_from_ini(STR("UEngine"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("UEngine\n")); + uint32_t uengine_size = retrieve_vtable_layout_from_ini(SYSSTR("UEngine"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, uobjectbase_size, uobjectbaseutility_size, uobject_size); - Output::send(STR("UEngine::{} = 0x{:X}\n"), item, offset); - Unreal::UEngine::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("UEngine::{} = 0x{:X}\n"), item, offset); + Unreal::UEngine::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("UScriptStruct::ICppStructOps\n")); - retrieve_vtable_layout_from_ini(STR("UScriptStruct::ICppStructOps"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("UScriptStruct::ICppStructOps\n")); + retrieve_vtable_layout_from_ini(SYSSTR("UScriptStruct::ICppStructOps"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, 0); - Output::send(STR("UScriptStruct::ICppStructOps::{} = 0x{:X}\n"), item, offset); - Unreal::UScriptStruct::ICppStructOps::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("UScriptStruct::ICppStructOps::{} = 0x{:X}\n"), item, offset); + Unreal::UScriptStruct::ICppStructOps::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("FField\n")); - uint32_t ffield_size = retrieve_vtable_layout_from_ini(STR("FField"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("FField\n")); + uint32_t ffield_size = retrieve_vtable_layout_from_ini(SYSSTR("FField"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, 0); - Output::send(STR("FField::{} = 0x{:X}\n"), item, offset); - Unreal::FField::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("FField::{} = 0x{:X}\n"), item, offset); + Unreal::FField::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("FProperty\n")); - uint32_t fproperty_size = retrieve_vtable_layout_from_ini(STR("FProperty"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("FProperty\n")); + uint32_t fproperty_size = retrieve_vtable_layout_from_ini(SYSSTR("FProperty"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset{}; if (Unreal::Version::IsBelow(4, 25)) { @@ -645,8 +658,8 @@ namespace RC { offset = calculate_virtual_function_offset(index, ffield_size); } - Output::send(STR("FProperty::{} = 0x{:X}\n"), item, offset); - Unreal::FProperty::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("FProperty::{} = 0x{:X}\n"), item, offset); + Unreal::FProperty::VTableLayoutMap.emplace(item_ue, offset); }); // If the engine version is <4.25 then the inheritance is different and we must take that into consideration. @@ -659,66 +672,67 @@ namespace RC fproperty_size = ffield_size + fproperty_size; } - Output::send(STR("FNumericProperty\n")); - retrieve_vtable_layout_from_ini(STR("FNumericProperty"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("FNumericProperty\n")); + retrieve_vtable_layout_from_ini(SYSSTR("FNumericProperty"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, fproperty_size); - Output::send(STR("FNumericProperty::{} = 0x{:X}\n"), item, offset); - Unreal::FNumericProperty::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("FNumericProperty::{} = 0x{:X}\n"), item, offset); + Unreal::FNumericProperty::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("FMulticastDelegateProperty\n")); - retrieve_vtable_layout_from_ini(STR("FMulticastDelegateProperty"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("FMulticastDelegateProperty\n")); + retrieve_vtable_layout_from_ini(SYSSTR("FMulticastDelegateProperty"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, fproperty_size); - Output::send(STR("FMulticastDelegateProperty::{} = 0x{:X}\n"), item, offset); - Unreal::FMulticastDelegateProperty::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("FMulticastDelegateProperty::{} = 0x{:X}\n"), item, offset); + Unreal::FMulticastDelegateProperty::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("FObjectPropertyBase\n")); - retrieve_vtable_layout_from_ini(STR("FObjectPropertyBase"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("FObjectPropertyBase\n")); + retrieve_vtable_layout_from_ini(SYSSTR("FObjectPropertyBase"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, fproperty_size); - Output::send(STR("FObjectPropertyBase::{} = 0x{:X}\n"), item, offset); - Unreal::FObjectPropertyBase::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("FObjectPropertyBase::{} = 0x{:X}\n"), item, offset); + Unreal::FObjectPropertyBase::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("UStruct\n")); - retrieve_vtable_layout_from_ini(STR("UStruct"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("UStruct\n")); + retrieve_vtable_layout_from_ini(SYSSTR("UStruct"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, uobjectbase_size, uobjectbaseutility_size, uobject_size, ufield_size); - Output::send(STR("UStruct::{} = 0x{:X}\n"), item, offset); - Unreal::UStruct::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("UStruct::{} = 0x{:X}\n"), item, offset); + Unreal::UStruct::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("FOutputDevice\n")); - retrieve_vtable_layout_from_ini(STR("FOutputDevice"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("FOutputDevice\n")); + retrieve_vtable_layout_from_ini(SYSSTR("FOutputDevice"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, 0); - Output::send(STR("FOutputDevice::{} = 0x{:X}\n"), item, offset); - Unreal::FOutputDevice::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("FOutputDevice::{} = 0x{:X}\n"), item, offset); + Unreal::FOutputDevice::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("FMalloc\n")); - retrieve_vtable_layout_from_ini(STR("FMalloc"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("FMalloc\n")); + retrieve_vtable_layout_from_ini(SYSSTR("FMalloc"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { // We don't support FExec, so we're manually telling it the size. static constexpr uint32_t fexec_size = 1; uint32_t offset = calculate_virtual_function_offset(index, fexec_size); - Output::send(STR("FMalloc::{} = 0x{:X}\n"), item, offset); - Unreal::FMalloc::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("FMalloc::{} = 0x{:X}\n"), item, offset); + Unreal::FMalloc::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("AActor\n")); - uint32_t aactor_size = retrieve_vtable_layout_from_ini(STR("AActor"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("AActor\n")); + uint32_t aactor_size = retrieve_vtable_layout_from_ini(SYSSTR("AActor"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, uobjectbase_size, uobjectbaseutility_size, uobject_size); - Output::send(STR("AActor::{} = 0x{:X}\n"), item, offset); - Unreal::AActor::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("AActor::{} = 0x{:X}\n"), item, offset); + Unreal::AActor::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("AGameModeBase\n")); - uint32_t agamemodebase_size = retrieve_vtable_layout_from_ini(STR("AGameModeBase"), [&](uint32_t index, File::StringType& item) { - uint32_t offset = calculate_virtual_function_offset(index, uobjectbase_size, uobjectbaseutility_size, uobject_size, aactor_size); - Output::send(STR("AGameModeBase::{} = 0x{:X}\n"), item, offset); - Unreal::AGameModeBase::VTableLayoutMap.emplace(item, offset); - }); + Output::send(SYSSTR("AGameModeBase\n")); + uint32_t agamemodebase_size = + retrieve_vtable_layout_from_ini(SYSSTR("AGameModeBase"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { + uint32_t offset = calculate_virtual_function_offset(index, uobjectbase_size, uobjectbaseutility_size, uobject_size, aactor_size); + Output::send(SYSSTR("AGameModeBase::{} = 0x{:X}\n"), item, offset); + Unreal::AGameModeBase::VTableLayoutMap.emplace(item_ue, offset); + }); - Output::send(STR("AGameMode\n")); - retrieve_vtable_layout_from_ini(STR("AGameMode"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("AGameMode\n")); + retrieve_vtable_layout_from_ini(SYSSTR("AGameMode"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, Unreal::Version::IsAtLeast(4, 14) ? uobjectbase_size, @@ -730,22 +744,22 @@ namespace RC uobjectbaseutility_size, uobject_size, aactor_size); - Output::send(STR("AGameMode::{} = 0x{:X}\n"), item, offset); - Unreal::AGameMode::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("AGameMode::{} = 0x{:X}\n"), item, offset); + Unreal::AGameMode::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("UPlayer\n")); - uint32_t uplayer_size = retrieve_vtable_layout_from_ini(STR("UPlayer"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("UPlayer\n")); + uint32_t uplayer_size = retrieve_vtable_layout_from_ini(SYSSTR("UPlayer"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, uobjectbase_size, uobjectbaseutility_size, uobject_size); - Output::send(STR("UPlayer::{} = 0x{:X}\n"), item, offset); - Unreal::UPlayer::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("UPlayer::{} = 0x{:X}\n"), item, offset); + Unreal::UPlayer::VTableLayoutMap.emplace(item_ue, offset); }); - Output::send(STR("ULocalPlayer\n")); - retrieve_vtable_layout_from_ini(STR("ULocalPlayer"), [&](uint32_t index, File::StringType& item) { + Output::send(SYSSTR("ULocalPlayer\n")); + retrieve_vtable_layout_from_ini(SYSSTR("ULocalPlayer"), [&](uint32_t index, SystemStringType& item, UEStringType& item_ue) { uint32_t offset = calculate_virtual_function_offset(index, uobjectbase_size, uobjectbaseutility_size, uobject_size, uplayer_size); - Output::send(STR("ULocalPlayer::{} = 0x{:X}\n"), item, offset); - Unreal::ULocalPlayer::VTableLayoutMap.emplace(item, offset); + Output::send(SYSSTR("ULocalPlayer::{} = 0x{:X}\n"), item, offset); + Unreal::ULocalPlayer::VTableLayoutMap.emplace(item_ue, offset); }); file.close(); @@ -768,16 +782,16 @@ namespace RC if (!UObject::ProcessLocalScriptFunctionInternal.is_ready() && Unreal::Version::IsAtLeast(4, 22)) { can_create_custom_events = false; - Output::send(STR("ProcessLocalScriptFunction is not available, the following features will be unavailable:\n")); + Output::send(SYSSTR("ProcessLocalScriptFunction is not available, the following features will be unavailable:\n")); } else if (!UObject::ProcessInternalInternal.is_ready() && Unreal::Version::IsBelow(4, 22)) { can_create_custom_events = false; - Output::send(STR("ProcessInternal is not available, the following features will be unavailable:\n")); + Output::send(SYSSTR("ProcessInternal is not available, the following features will be unavailable:\n")); } if (!can_create_custom_events) { - Output::send(STR("\n")); + Output::send(SYSSTR("\n")); } } @@ -787,7 +801,7 @@ namespace RC m_shared_functions.set_script_variable_default_data_function = &LuaLibrary::set_script_variable_default_data; m_shared_functions.call_script_function_function = &LuaLibrary::call_script_function; m_shared_functions.is_ue4ss_initialized_function = &LuaLibrary::is_ue4ss_initialized; - Output::send(STR("m_shared_functions: {}\n"), static_cast(&m_shared_functions)); + Output::send(SYSSTR("m_shared_functions: {}\n"), static_cast(&m_shared_functions)); } auto UE4SSProgram::on_program_start() -> void @@ -810,7 +824,7 @@ namespace RC { m_debugging_gui.get_live_view().set_listeners_allowed(false); } - +#ifdef HAS_INPUT m_input_handler.register_keydown_event(Input::Key::O, {Input::ModifierKey::CONTROL}, [&]() { TRY([&] { auto was_gui_open = get_debugging_ui().is_open(); @@ -822,6 +836,7 @@ namespace RC } }); }); +#endif } #ifdef TIME_FUNCTION_MACRO_ENABLED @@ -830,19 +845,19 @@ namespace RC { FunctionTimerFrame::stop_profiling(); FunctionTimerFrame::dump_profile(); - Output::send(STR("Profiler stopped & dumped\n")); + Output::send(SYSSTR("Profiler stopped & dumped\n")); } else { FunctionTimerFrame::start_profiling(); - Output::send(STR("Profiler started\n")); + Output::send(SYSSTR("Profiler started\n")); } }); #endif TRY([&] { ObjectDumper::init(); - +#ifdef HAS_INPUT if (settings_manager.General.EnableHotReloadSystem) { m_input_handler.register_keydown_event(Input::Key::R, {Input::ModifierKey::CONTROL}, [&]() { @@ -851,13 +866,27 @@ namespace RC }); }); } - +#endif if ((settings_manager.ObjectDumper.LoadAllAssetsBeforeDumpingObjects || settings_manager.CXXHeaderGenerator.LoadAllAssetsBeforeGeneratingCXXHeaders) && Unreal::Version::IsBelow(4, 17)) { Output::send( - STR("FAssetData not available in <4.17, ignoring 'LoadAllAssetsBeforeDumpingObjects' & 'LoadAllAssetsBeforeGeneratingCXXHeaders'.")); + SYSSTR("FAssetData not available in <4.17, ignoring 'LoadAllAssetsBeforeDumpingObjects' & 'LoadAllAssetsBeforeGeneratingCXXHeaders'.")); + } + +#ifdef HAS_INPUT + if (!settings_manager.General.InputSource.empty()) + { + if (m_input_handler.set_input_source(to_string(settings_manager.General.InputSource))) + { + Output::send(SYSSTR("Input source set to: {}\n"), m_input_handler.get_current_input_source()); + } + else + { + Output::send(SYSSTR("Failed to set input source to: {}\n"), settings_manager.General.InputSource); + } } +#endif install_lua_mods(); LuaMod::on_program_start(); @@ -865,12 +894,14 @@ namespace RC start_lua_mods(); }); +#ifdef HAS_INPUT if (settings_manager.General.EnableDebugKeyBindings) { m_input_handler.register_keydown_event(Input::Key::NUM_NINE, {Input::ModifierKey::CONTROL}, [&]() { generate_uht_compatible_headers(); }); } +#endif } auto UE4SSProgram::update() -> void @@ -879,7 +910,7 @@ namespace RC on_program_start(); - Output::send(STR("Event loop start\n")); + Output::send(SYSSTR("Event loop start\n")); for (m_processing_events = true; m_processing_events;) { if (m_pause_events_processing || UE4SSProgram::unreal_is_shutting_down) @@ -929,9 +960,9 @@ namespace RC } } //*/ - +#ifdef HAS_INPUT m_input_handler.process_event(); - +#endif { ProfilerScopeNamed("mod update processing"); @@ -947,40 +978,40 @@ namespace RC std::this_thread::sleep_for(std::chrono::milliseconds(5)); ProfilerFrameMark(); } - Output::send(STR("Event loop end\n")); + Output::send(SYSSTR("Event loop end\n")); } auto UE4SSProgram::setup_unreal_properties() -> void { - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"ObjectProperty").GetComparisonIndex(), &LuaType::push_objectproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"ClassProperty").GetComparisonIndex(), &LuaType::push_classproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"Int8Property").GetComparisonIndex(), &LuaType::push_int8property); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"Int16Property").GetComparisonIndex(), &LuaType::push_int16property); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"IntProperty").GetComparisonIndex(), &LuaType::push_intproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"Int64Property").GetComparisonIndex(), &LuaType::push_int64property); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"ByteProperty").GetComparisonIndex(), &LuaType::push_byteproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"UInt16Property").GetComparisonIndex(), &LuaType::push_uint16property); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"UInt32Property").GetComparisonIndex(), &LuaType::push_uint32property); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"UInt64Property").GetComparisonIndex(), &LuaType::push_uint64property); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"StructProperty").GetComparisonIndex(), &LuaType::push_structproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"ArrayProperty").GetComparisonIndex(), &LuaType::push_arrayproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"FloatProperty").GetComparisonIndex(), &LuaType::push_floatproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"DoubleProperty").GetComparisonIndex(), &LuaType::push_doubleproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"BoolProperty").GetComparisonIndex(), &LuaType::push_boolproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"EnumProperty").GetComparisonIndex(), &LuaType::push_enumproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"WeakObjectProperty").GetComparisonIndex(), &LuaType::push_weakobjectproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"NameProperty").GetComparisonIndex(), &LuaType::push_nameproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"TextProperty").GetComparisonIndex(), &LuaType::push_textproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"StrProperty").GetComparisonIndex(), &LuaType::push_strproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"SoftClassProperty").GetComparisonIndex(), &LuaType::push_softclassproperty); - LuaType::StaticState::m_property_value_pushers.emplace(FName(L"InterfaceProperty").GetComparisonIndex(), &LuaType::push_interfaceproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("ObjectProperty")).GetComparisonIndex(), &LuaType::push_objectproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("ClassProperty")).GetComparisonIndex(), &LuaType::push_classproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("Int8Property")).GetComparisonIndex(), &LuaType::push_int8property); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("Int16Property")).GetComparisonIndex(), &LuaType::push_int16property); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("IntProperty")).GetComparisonIndex(), &LuaType::push_intproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("Int64Property")).GetComparisonIndex(), &LuaType::push_int64property); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("ByteProperty")).GetComparisonIndex(), &LuaType::push_byteproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("UInt16Property")).GetComparisonIndex(), &LuaType::push_uint16property); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("UInt32Property")).GetComparisonIndex(), &LuaType::push_uint32property); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("UInt64Property")).GetComparisonIndex(), &LuaType::push_uint64property); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("StructProperty")).GetComparisonIndex(), &LuaType::push_structproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("ArrayProperty")).GetComparisonIndex(), &LuaType::push_arrayproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("FloatProperty")).GetComparisonIndex(), &LuaType::push_floatproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("DoubleProperty")).GetComparisonIndex(), &LuaType::push_doubleproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("BoolProperty")).GetComparisonIndex(), &LuaType::push_boolproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("EnumProperty")).GetComparisonIndex(), &LuaType::push_enumproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("WeakObjectProperty")).GetComparisonIndex(), &LuaType::push_weakobjectproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("NameProperty")).GetComparisonIndex(), &LuaType::push_nameproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("TextProperty")).GetComparisonIndex(), &LuaType::push_textproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("StrProperty")).GetComparisonIndex(), &LuaType::push_strproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("SoftClassProperty")).GetComparisonIndex(), &LuaType::push_softclassproperty); + LuaType::StaticState::m_property_value_pushers.emplace(FName(STR("InterfaceProperty")).GetComparisonIndex(), &LuaType::push_interfaceproperty); } auto UE4SSProgram::setup_mods() -> void { ProfilerScope(); - Output::send(STR("Setting up mods...\n")); + Output::send(SYSSTR("Setting up mods...\n")); if (!std::filesystem::exists(m_mods_directory)) { @@ -1001,10 +1032,10 @@ namespace RC set_error("is_directory ran into error %d", ec.value()); } - std::wstring directory_lowercase = sub_directory.path().stem().wstring(); + SystemStringType directory_lowercase = to_system_string(sub_directory.path().stem()); std::transform(directory_lowercase.begin(), directory_lowercase.end(), directory_lowercase.begin(), std::towlower); - if (directory_lowercase == L"shared") + if (directory_lowercase == SYSSTR("shared")) { // Do stuff when shared libraries have been implemented } @@ -1012,9 +1043,9 @@ namespace RC { // Create the mod but don't install it yet if (std::filesystem::exists(sub_directory.path() / "scripts")) - m_mods.emplace_back(std::make_unique(*this, sub_directory.path().stem().wstring(), sub_directory.path().wstring())); + m_mods.emplace_back(std::make_unique(*this, to_system_string(sub_directory.path().stem()), to_system_string(sub_directory.path()))); if (std::filesystem::exists(sub_directory.path() / "dlls")) - m_mods.emplace_back(std::make_unique(*this, sub_directory.path().stem().wstring(), sub_directory.path().wstring())); + m_mods.emplace_back(std::make_unique(*this, to_system_string(sub_directory.path().stem()), to_system_string(sub_directory.path()))); } } } @@ -1037,19 +1068,19 @@ namespace RC if (mod_name_is_taken) { mod->set_installable(false); - Output::send(STR("Mod name '{}' is already in use.\n"), mod->get_name()); + Output::send(SYSSTR("Mod name '{}' is already in use.\n"), mod->get_name()); continue; } if (mod->is_installed()) { - Output::send(STR("Tried to install a mod that was already installed, Mod: '{}'\n"), mod->get_name()); + Output::send(SYSSTR("Tried to install a mod that was already installed, Mod: '{}'\n"), mod->get_name()); continue; } if (!mod->is_installable()) { - Output::send(STR("Was unable to install mod '{}' for unknown reasons. Mod is not installable.\n"), mod->get_name()); + Output::send(SYSSTR("Was unable to install mod '{}' for unknown reasons. Mod is not installable.\n"), mod->get_name()); continue; } @@ -1106,7 +1137,7 @@ namespace RC } } - auto UE4SSProgram::fire_dll_load_for_cpp_mods(std::wstring_view dll_name) -> void + auto UE4SSProgram::fire_dll_load_for_cpp_mods(SystemStringViewType dll_name) -> void { for (const auto& mod : m_mods) { @@ -1122,24 +1153,25 @@ namespace RC { ProfilerScope(); // Part #1: Start all mods that are enabled in mods.txt. - Output::send(STR("Starting mods (from mods.txt load order)...\n")); + Output::send(SYSSTR("Starting mods (from mods.txt load order)...\n")); std::filesystem::path mods_directory = UE4SSProgram::get_program().get_mods_directory(); - std::wstring enabled_mods_file{mods_directory / "mods.txt"}; + // TODO NEXT COMMIT: auto enabled_mods_file = File::get_path_if_exists(mods_directory, "mods.txt"); + auto enabled_mods_file{mods_directory / "mods.txt"}; if (!std::filesystem::exists(enabled_mods_file)) { - Output::send(STR("No mods.txt file found...\n")); + Output::send(SYSSTR("No mods.txt file found...\n")); } else { // 'mods.txt' exists, lets parse it - std::wifstream mods_stream{enabled_mods_file}; + SystemStreamType mods_stream{enabled_mods_file}; - std::wstring current_line; + SystemStringType current_line; while (std::getline(mods_stream, current_line)) { // Don't parse any lines with ';' - if (current_line.find(L";") != current_line.npos) + if (current_line.find(SYSSTR(";")) != current_line.npos) { continue; } @@ -1151,12 +1183,12 @@ namespace RC } // Remove all spaces - auto end = std::remove(current_line.begin(), current_line.end(), L' '); + auto end = std::remove(current_line.begin(), current_line.end(), SYSSTR(' ')); current_line.erase(end, current_line.end()); // Parse the line into something that can be converted into proper data - std::wstring mod_name = explode_by_occurrence(current_line, L':', 1); - std::wstring mod_enabled = explode_by_occurrence(current_line, L':', ExplodeType::FromEnd); + SystemStringType mod_name = explode_by_occurrence(current_line, SYSSTR(':'), 1); + SystemStringType mod_enabled = explode_by_occurrence(current_line, SYSSTR(':'), ExplodeType::FromEnd); auto mod = UE4SSProgram::find_mod_by_name(mod_name, UE4SSProgram::IsInstalled::Yes); if (!mod || !dynamic_cast(mod)) @@ -1164,20 +1196,20 @@ namespace RC continue; } - if (!mod_enabled.empty() && mod_enabled[0] == L'1') + if (!mod_enabled.empty() && mod_enabled[0] == SYSSTR('1')) { - Output::send(STR("Starting {} mod '{}'\n"), std::is_same_v ? STR("Lua") : STR("C++"), mod->get_name().data()); + Output::send(SYSSTR("Starting {} mod '{}'\n"), std::is_same_v ? SYSSTR("Lua") : SYSSTR("C++"), mod->get_name().data()); mod->start_mod(); } else { - Output::send(STR("Mod '{}' disabled in mods.txt.\n"), mod_name); + Output::send(SYSSTR("Mod '{}' disabled in mods.txt.\n"), mod_name); } } } // Part #2: Start all mods that have enabled.txt present in the mod directory. - Output::send(STR("Starting mods (from enabled.txt, no defined load order)...\n")); + Output::send(SYSSTR("Starting mods (from enabled.txt, no defined load order)...\n")); for (const auto& mod_directory : std::filesystem::directory_iterator(mods_directory)) { @@ -1196,19 +1228,15 @@ namespace RC { continue; } - if (ec.value() != 0) - { - return std::format("exists ran into error {}", ec.value()); - } - auto mod = UE4SSProgram::find_mod_by_name(mod_directory.path().stem().c_str(), UE4SSProgram::IsInstalled::Yes); + auto mod = UE4SSProgram::find_mod_by_name(to_system_string(mod_directory.path().stem()), UE4SSProgram::IsInstalled::Yes); if (!dynamic_cast(mod)) { continue; } if (!mod) { - Output::send(STR("Found a mod with enabled.txt but mod has not been installed properly.\n")); + Output::send(SYSSTR("Found a mod with enabled.txt but mod has not been installed properly.\n")); continue; } @@ -1217,7 +1245,7 @@ namespace RC continue; } - Output::send(STR("Mod '{}' has enabled.txt, starting mod.\n"), mod->get_name().data()); + Output::send(SYSSTR("Mod '{}' has enabled.txt, starting mod.\n"), mod->get_name().data()); mod->start_mod(); } @@ -1292,20 +1320,20 @@ namespace RC auto UE4SSProgram::reinstall_mods() -> void { ProfilerScope(); - Output::send(STR("Re-installing all mods\n")); + Output::send(SYSSTR("Re-installing all mods\n")); // Stop processing events while stuff isn't properly setup m_pause_events_processing = true; uninstall_mods(); - // Remove key binds that were set from Lua scripts - auto& key_events = m_input_handler.get_events(); - std::erase_if(key_events, [](Input::KeySet& input_event) -> bool { - bool were_all_events_registered_from_lua = true; - for (auto& [key, vector_of_key_data] : input_event.key_data) - { - std::erase_if(vector_of_key_data, [&](Input::KeyData& key_data) -> bool { +// Remove key binds that were set from Lua scripts +#ifdef HAS_INPUT + m_input_handler.get_events_safe([&](auto& key_set) { + std::erase_if(key_set.key_data, [&](auto& item) -> bool { + auto& [_, key_data] = item; + bool were_all_events_registered_from_lua = true; + std::erase_if(key_data, [&](Input::KeyData& key_data) -> bool { // custom_data == 1: Bind came from Lua, and custom_data2 is nullptr. // custom_data == 2: Bind came from C++, and custom_data2 is a pointer to KeyDownEventData. Must free it. if (key_data.custom_data == 1) @@ -1318,10 +1346,11 @@ namespace RC return false; } }); - } - return were_all_events_registered_from_lua; + return were_all_events_registered_from_lua; + }); }); +#endif // Remove all custom properties // Uncomment when custom properties are working @@ -1348,38 +1377,42 @@ namespace RC fire_program_start_for_cpp_mods(); } - Output::send(STR("All mods re-installed\n")); + Output::send(SYSSTR("All mods re-installed\n")); } - auto UE4SSProgram::get_module_directory() -> File::StringViewType + auto UE4SSProgram::get_module_directory() -> SystemStringViewType { - return m_module_file_path.c_str(); + m_module_file_path_str = to_system_string(m_module_file_path); + return m_module_file_path_str; } - auto UE4SSProgram::get_game_executable_directory() -> File::StringViewType + auto UE4SSProgram::get_working_directory() -> SystemStringViewType { - return m_game_executable_directory.c_str(); + m_working_directory_str = to_system_string(m_working_directory); + return m_working_directory_str; } - auto UE4SSProgram::get_working_directory() -> File::StringViewType + auto UE4SSProgram::get_mods_directory() -> SystemStringViewType { - return m_working_directory.c_str(); + m_mods_directory_str = to_system_string(m_mods_directory); + return m_mods_directory_str; } - auto UE4SSProgram::get_mods_directory() -> File::StringViewType + auto UE4SSProgram::get_legacy_root_directory() -> SystemStringViewType { - return m_mods_directory.c_str(); + return m_legacy_root_directory.c_str(); } - - auto UE4SSProgram::get_legacy_root_directory() -> File::StringViewType + + auto UE4SSProgram::get_game_executable_directory() -> SystemStringViewType { - return m_legacy_root_directory.c_str(); + m_game_executable_str = to_system_string(m_game_executable_directory); + return m_game_executable_str; } auto UE4SSProgram::generate_uht_compatible_headers() -> void { ProfilerScope(); - Output::send(STR("Generating UHT compatible headers...\n")); + Output::send(SYSSTR("Generating UHT compatible headers...\n")); double generator_duration{}; { @@ -1390,7 +1423,7 @@ namespace RC HeaderGenerator.dump_native_packages(); } - Output::send(STR("Generating UHT compatible headers took {} seconds\n"), generator_duration); + Output::send(SYSSTR("Generating UHT compatible headers took {} seconds\n"), generator_duration); } auto UE4SSProgram::generate_cxx_headers(const std::filesystem::path& output_dir) -> void @@ -1398,7 +1431,7 @@ namespace RC ProfilerScope(); if (settings_manager.CXXHeaderGenerator.LoadAllAssetsBeforeGeneratingCXXHeaders) { - Output::send(STR("Loading all assets...\n")); + Output::send(SYSSTR("Loading all assets...\n")); double asset_loading_duration{}; { ProfilerScopeNamed("loading all assets"); @@ -1406,7 +1439,7 @@ namespace RC UAssetRegistry::LoadAllAssets(); } - Output::send(STR("Loading all assets took {} seconds\n"), asset_loading_duration); + Output::send(SYSSTR("Loading all assets took {} seconds\n"), asset_loading_duration); } double generator_duration; @@ -1416,11 +1449,11 @@ namespace RC UEGenerator::generate_cxx_headers(output_dir); - Output::send(STR("Unloading all forcefully loaded assets\n")); + Output::send(SYSSTR("Unloading all forcefully loaded assets\n")); } UAssetRegistry::FreeAllForcefullyLoadedAssets(); - Output::send(STR("SDK generated in {} seconds.\n"), generator_duration); + Output::send(SYSSTR("SDK generated in {} seconds.\n"), generator_duration); } auto UE4SSProgram::generate_lua_types(const std::filesystem::path& output_dir) -> void @@ -1428,7 +1461,7 @@ namespace RC ProfilerScope(); if (settings_manager.CXXHeaderGenerator.LoadAllAssetsBeforeGeneratingCXXHeaders) { - Output::send(STR("Loading all assets...\n")); + Output::send(SYSSTR("Loading all assets...\n")); double asset_loading_duration{}; { ProfilerScopeNamed("loading all assets"); @@ -1436,7 +1469,7 @@ namespace RC UAssetRegistry::LoadAllAssets(); } - Output::send(STR("Loading all assets took {} seconds\n"), asset_loading_duration); + Output::send(SYSSTR("Loading all assets took {} seconds\n"), asset_loading_duration); } double generator_duration; @@ -1446,11 +1479,11 @@ namespace RC UEGenerator::generate_lua_types(output_dir); - Output::send(STR("Unloading all forcefully loaded assets\n")); + Output::send(SYSSTR("Unloading all forcefully loaded assets\n")); } UAssetRegistry::FreeAllForcefullyLoadedAssets(); - Output::send(STR("SDK generated in {} seconds.\n"), generator_duration); + Output::send(SYSSTR("SDK generated in {} seconds.\n"), generator_duration); } auto UE4SSProgram::stop_render_thread() -> void @@ -1488,6 +1521,7 @@ namespace RC return m_queued_events.empty(); } +#ifdef HAS_INPUT auto UE4SSProgram::register_keydown_event(Input::Key key, const Input::EventCallbackCallable& callback, uint8_t custom_data, void* custom_data2) -> void { m_input_handler.register_keydown_event(key, callback, custom_data, custom_data2); @@ -1511,11 +1545,11 @@ namespace RC { return m_input_handler.is_keydown_event_registered(key, modifier_keys); } - - auto UE4SSProgram::find_mod_by_name_internal(std::wstring_view mod_name, IsInstalled is_installed, IsStarted is_started, FMBNI_ExtraPredicate extra_predicate) +#endif + auto UE4SSProgram::find_mod_by_name_internal(SystemStringViewType mod_name, IsInstalled is_installed, IsStarted is_started, FMBNI_ExtraPredicate extra_predicate) -> Mod* { - auto mod_exists_with_name = std::find_if(m_mods.begin(), m_mods.end(), [&](auto& elem) -> bool { + auto mod_exists_with_name = std::find_if(get_program().m_mods.begin(), get_program().m_mods.end(), [&](auto& elem) -> bool { bool found = true; if (!extra_predicate(elem.get())) @@ -1550,22 +1584,16 @@ namespace RC } } - auto UE4SSProgram::find_lua_mod_by_name(std::string_view mod_name, UE4SSProgram::IsInstalled installed_only, IsStarted is_started) -> LuaMod* - { - return static_cast(find_mod_by_name(mod_name, installed_only, is_started)); - } - - auto UE4SSProgram::find_lua_mod_by_name(std::wstring_view mod_name, UE4SSProgram::IsInstalled installed_only, IsStarted is_started) -> LuaMod* - { - return static_cast(find_mod_by_name(mod_name, installed_only, is_started)); + auto UE4SSProgram::find_lua_mod_by_name_internal(SystemStringType mod_name, IsInstalled is_installed, IsStarted is_started) -> LuaMod* { + return static_cast(find_mod_by_name(mod_name, is_installed, is_started)); } - auto UE4SSProgram::get_object_dumper_output_directory() -> const File::StringType + auto UE4SSProgram::get_object_dumper_output_directory() -> const SystemStringType { - return m_object_dumper_output_directory.c_str(); + return to_system_string(m_object_dumper_output_directory); } - auto UE4SSProgram::dump_uobject(UObject* object, std::unordered_set* in_dumped_fields, StringType& out_line, bool is_below_425) -> void + auto UE4SSProgram::dump_uobject(UObject* object, std::unordered_set* in_dumped_fields, SystemStringType& out_line, bool is_below_425) -> void { bool owns_dumped_fields{}; auto dumped_fields_ptr = [&] { @@ -1599,7 +1627,7 @@ namespace RC // Dump UObject ObjectDumper::get_to_string(typed_class)(object, out_line); - out_line.append(L"\n"); + out_line.append(SYSSTR("\n")); if (!is_below_425 && ObjectDumper::to_string_complex_exists(typed_class)) { @@ -1620,7 +1648,7 @@ namespace RC { // A type-specific implementation does not exist so lets call the default implementation for UObjects instead ObjectDumper::object_to_string(object, out_line); - out_line.append(L"\n"); + out_line.append(SYSSTR("\n")); } // If the UClass of the UObject has any properties then dump them @@ -1649,50 +1677,50 @@ namespace RC } } - auto UE4SSProgram::dump_xproperty(FProperty* property, StringType& out_line) -> void + auto UE4SSProgram::dump_xproperty(FProperty* property, SystemStringType& out_line) -> void { auto typed_prop_class = property->GetClass().HashObject(); if (ObjectDumper::to_string_exists(typed_prop_class)) { ObjectDumper::get_to_string(typed_prop_class)(property, out_line); - out_line.append(L"\n"); + out_line.append(SYSSTR("\n")); if (ObjectDumper::to_string_complex_exists(typed_prop_class)) { ObjectDumper::get_to_string_complex(typed_prop_class)(property, out_line, [&]([[maybe_unused]] void* prop) { - out_line.append(L"\n"); + out_line.append(SYSSTR("\n")); }); } } else { ObjectDumper::property_to_string(property, out_line); - out_line.append(L"\n"); + out_line.append(SYSSTR("\n")); } } - auto UE4SSProgram::dump_all_objects_and_properties(const File::StringType& output_path_and_file_name) -> void + auto UE4SSProgram::dump_all_objects_and_properties(const SystemStringType& output_path_and_file_name) -> void { /* - Output::send(STR("Test msg with no fmt args, and no optional arg\n")); - Output::send(STR("Test msg with no fmt args, and one optional arg [Normal]\n"), LogLevel::Normal); - Output::send(STR("Test msg with no fmt args, and one optional arg [Verbose]\n"), LogLevel::Verbose); - Output::send(STR("Test msg with one fmt arg [{}], and one optional arg [Warning]\n"), LogLevel::Warning, 33); - Output::send(STR("Test msg with two fmt args [{}, {}], and one optional arg [Error]\n"), LogLevel::Error, 33, 44); + Output::send(SYSSTR("Test msg with no fmt args, and no optional arg\n")); + Output::send(SYSSTR("Test msg with no fmt args, and one optional arg [Normal]\n"), LogLevel::Normal); + Output::send(SYSSTR("Test msg with no fmt args, and one optional arg [Verbose]\n"), LogLevel::Verbose); + Output::send(SYSSTR("Test msg with one fmt arg [{}], and one optional arg [Warning]\n"), LogLevel::Warning, 33); + Output::send(SYSSTR("Test msg with two fmt args [{}, {}], and one optional arg [Error]\n"), LogLevel::Error, 33, 44); //*/ // Object & Property Dumper -> START if (settings_manager.ObjectDumper.LoadAllAssetsBeforeDumpingObjects) { - Output::send(STR("Loading all assets...\n")); + Output::send(SYSSTR("Loading all assets...\n")); double asset_loading_duration{}; { ScopedTimer loading_timer{&asset_loading_duration}; UAssetRegistry::LoadAllAssets(); } - Output::send(STR("Loading all assets took {} seconds\n"), asset_loading_duration); + Output::send(SYSSTR("Loading all assets took {} seconds\n"), asset_loading_duration); } double dumper_duration{}; @@ -1718,16 +1746,16 @@ namespace RC Output::Targets scoped_dumper_out; auto& file_device = scoped_dumper_out.get_device(); file_device.set_file_name_and_path(output_path_and_file_name); - file_device.set_formatter([](File::StringViewType string) -> File::StringType { - return File::StringType{string}; + file_device.set_formatter([](SystemStringViewType string) -> SystemStringType { + return SystemStringType{string}; }); // Make string & reserve massive amounts of space to hopefully not reach the end of the string and require more // dynamic allocations - std::wstring out_line; + SystemStringType out_line; out_line.reserve(200000000); - Output::send(STR("Dumping all objects & properties in GUObjectArray\n")); + Output::send(SYSSTR("Dumping all objects & properties in GUObjectArray\n")); UObjectGlobals::ForEachUObject([&](void* object, [[maybe_unused]] int32_t chunk_index, [[maybe_unused]] int32_t object_index) { dump_uobject(static_cast(object), &dumped_fields, out_line, is_below_425); return LoopAction::Continue; @@ -1738,11 +1766,11 @@ namespace RC // Reset the dumped_fields set, otherwise no fields will be dumped in subsequent dumps dumped_fields.clear(); - Output::send(STR("Done iterating GUObjectArray\n")); + Output::send(SYSSTR("Done iterating GUObjectArray\n")); } UAssetRegistry::FreeAllForcefullyLoadedAssets(); - Output::send(STR("Dumping GUObjectArray took {} seconds\n"), dumper_duration); + Output::send(SYSSTR("Dumping GUObjectArray took {} seconds\n"), dumper_duration); // Object & Property Dumper -> END } diff --git a/UE4SS/src/USMapGenerator/Generator.cpp b/UE4SS/src/USMapGenerator/Generator.cpp index 78d5517c8..d1e783ec3 100644 --- a/UE4SS/src/USMapGenerator/Generator.cpp +++ b/UE4SS/src/USMapGenerator/Generator.cpp @@ -22,6 +22,8 @@ #include #include "UE4SSProgram.hpp" +#undef min +#undef max namespace RC::OutTheShade { @@ -200,8 +202,8 @@ namespace RC::OutTheShade auto generate_usmap() -> void { - Output::send(STR("Mappings Generator by OutTheShade\nAttempting to dump mappings...\nPort of https://github.com/OutTheShade/UnrealMappingsDumper " - "Commit SHA 4da8c66\n")); + Output::send(SYSSTR("Mappings Generator by OutTheShade\nAttempting to dump mappings...\nPort of https://github.com/OutTheShade/UnrealMappingsDumper " + "Commit SHA 4da8c66\n")); StreamWriter Buffer; std::unordered_map NameMap; @@ -299,11 +301,11 @@ namespace RC::OutTheShade if (Object->GetClassPrivate() == UClass::StaticClass() || Object->GetClassPrivate() == UScriptStruct::StaticClass() || Object->GetClassPrivate() == UEnum::StaticClass()) { - std::wstring RawPathName = Object->GetPathName(); - std::wstring::size_type PathNameStart = + UEStringType RawPathName = Object->GetPathName(); + UEStringType::size_type PathNameStart = 0; // include first bit (Script/Game) to avoid ambiguity; to drop it, replace with RawPathName.find_first_of('/', 1) + 1; - std::wstring::size_type PathNameLength = RawPathName.find_last_of('.') - PathNameStart; - std::wstring FinalPathStr = RawPathName.substr(PathNameStart, PathNameLength); + UEStringType::size_type PathNameLength = RawPathName.find_last_of('.') - PathNameStart; + UEStringType FinalPathStr = RawPathName.substr(PathNameStart, PathNameLength); FName FinalPathName = FName(FinalPathStr); NameMap.insert_or_assign(FinalPathName, 0); @@ -518,6 +520,6 @@ namespace RC::OutTheShade FileOutput.Write(UsmapData.data(), UsmapData.size()); - Output::send(STR("Mappings Generation Completed Successfully!\n")); + Output::send(SYSSTR("Mappings Generation Completed Successfully!\n")); } } // namespace RC::OutTheShade diff --git a/UE4SS/xmake.lua b/UE4SS/xmake.lua index 8ccee3fcf..059091a0a 100644 --- a/UE4SS/xmake.lua +++ b/UE4SS/xmake.lua @@ -23,6 +23,14 @@ option("ue4ssIsBeta") set_description("Is this a beta release") +option("ue4ssInput") + set_default(true) + set_showmenu(true) + + add_defines("HAS_INPUT") + + set_description("Enable the input system.") + local projectName = "UE4SS" local function parse_version_string(str) @@ -46,7 +54,7 @@ target(projectName) set_exceptions("cxx") set_default(true) add_rules("ue4ss.defines.exports") - add_options("ue4ssBetaIsStarted", "ue4ssIsBeta") + add_options("ue4ssBetaIsStarted", "ue4ssIsBeta", "ue4ssInput") add_includedirs("include", { public = true }) add_includedirs("generated_include", { public = true }) add_headerfiles("include/**.hpp") diff --git a/UVTD/include/UVTD/ExceptionHandling.hpp b/UVTD/include/UVTD/ExceptionHandling.hpp index ed3c0747f..a691a453d 100644 --- a/UVTD/include/UVTD/ExceptionHandling.hpp +++ b/UVTD/include/UVTD/ExceptionHandling.hpp @@ -21,7 +21,7 @@ namespace RC { if (!Output::has_internal_error()) { - Output::send(STR("Error: {}\n"), to_wstring(e.what())); + Output::send(SYSSTR("Error: {}\n"), to_wstring(e.what())); } else { diff --git a/UVTD/include/UVTD/Helpers.hpp b/UVTD/include/UVTD/Helpers.hpp index f1087eec0..ba9ab4377 100644 --- a/UVTD/include/UVTD/Helpers.hpp +++ b/UVTD/include/UVTD/Helpers.hpp @@ -32,7 +32,7 @@ namespace RC::UVTD struct ObjectItem { - File::StringType name{}; + UEStringType name{}; ValidForVTable valid_for_vtable{}; ValidForMemberVars valid_for_member_vars{}; }; @@ -105,7 +105,7 @@ namespace RC::UVTD {STR("FFixedUObjectArray"), ValidForVTable::No, ValidForMemberVars::Yes}, {STR("FUObjectItem"), ValidForVTable::No, ValidForMemberVars::Yes}}; - static inline std::unordered_map> s_private_variables{ + static inline std::unordered_map> s_private_variables{ {STR("FField"), { STR("ClassPrivate"), @@ -115,73 +115,73 @@ namespace RC::UVTD }}, }; - static std::unordered_set s_non_case_preserving_variants{ + static std::unordered_set s_non_case_preserving_variants{ {STR("4_27")}, }; - static std::unordered_set s_case_preserving_variants{ + static std::unordered_set s_case_preserving_variants{ {STR("4_27_CasePreserving")}, }; - static inline std::unordered_set s_valid_udt_names{STR("UScriptStruct::ICppStructOps"), - STR("UObjectBase"), - STR("UObjectBaseUtility"), - STR("UObject"), - STR("UStruct"), - STR("UGameViewportClient"), - STR("UScriptStruct"), - STR("FOutputDevice"), - // STR("UConsole"), - STR("FMalloc"), - STR("FArchive"), - STR("FArchiveState"), - STR("AGameModeBase"), - STR("AGameMode"), - STR("AActor"), - STR("AHUD"), - STR("UPlayer"), - STR("ULocalPlayer"), - STR("FExec"), - STR("UField"), - STR("FField"), - STR("FProperty"), - STR("UProperty"), - STR("FNumericProperty"), - STR("UNumericProperty"), - STR("FMulticastDelegateProperty"), - STR("UMulticastDelegateProperty"), - STR("FObjectPropertyBase"), - STR("UObjectPropertyBase"), - STR("UStructProperty"), - STR("FStructProperty"), - STR("UArrayProperty"), - STR("FArrayProperty"), - STR("UMapProperty"), - STR("FMapProperty"), - STR("UWorld"), - STR("UFunction"), - STR("FBoolProperty"), - STR("UClass"), - STR("UEnum"), - STR("UBoolProperty"), - STR("FByteProperty"), - STR("UByteProperty"), - STR("FEnumProperty"), - STR("UEnumProperty"), - STR("FClassProperty"), - STR("UClassProperty"), - STR("FSoftClassProperty"), - STR("USoftClassProperty"), - STR("FDelegateProperty"), - STR("UDelegateProperty"), - STR("FInterfaceProperty"), - STR("UInterfaceProperty"), - STR("FFieldPathProperty"), - STR("FSetProperty"), - STR("USetProperty"), - STR("FFrame")}; - - static inline std::vector s_uprefix_to_fprefix{ + static inline std::unordered_set s_valid_udt_names{STR("UScriptStruct::ICppStructOps"), + STR("UObjectBase"), + STR("UObjectBaseUtility"), + STR("UObject"), + STR("UStruct"), + STR("UGameViewportClient"), + STR("UScriptStruct"), + STR("FOutputDevice"), + // STR("UConsole"), + STR("FMalloc"), + STR("FArchive"), + STR("FArchiveState"), + STR("AGameModeBase"), + STR("AGameMode"), + STR("AActor"), + STR("AHUD"), + STR("UPlayer"), + STR("ULocalPlayer"), + STR("FExec"), + STR("UField"), + STR("FField"), + STR("FProperty"), + STR("UProperty"), + STR("FNumericProperty"), + STR("UNumericProperty"), + STR("FMulticastDelegateProperty"), + STR("UMulticastDelegateProperty"), + STR("FObjectPropertyBase"), + STR("UObjectPropertyBase"), + STR("UStructProperty"), + STR("FStructProperty"), + STR("UArrayProperty"), + STR("FArrayProperty"), + STR("UMapProperty"), + STR("FMapProperty"), + STR("UWorld"), + STR("UFunction"), + STR("FBoolProperty"), + STR("UClass"), + STR("UEnum"), + STR("UBoolProperty"), + STR("FByteProperty"), + STR("UByteProperty"), + STR("FEnumProperty"), + STR("UEnumProperty"), + STR("FClassProperty"), + STR("UClassProperty"), + STR("FSoftClassProperty"), + STR("USoftClassProperty"), + STR("FDelegateProperty"), + STR("UDelegateProperty"), + STR("FInterfaceProperty"), + STR("UInterfaceProperty"), + STR("FFieldPathProperty"), + STR("FSetProperty"), + STR("USetProperty"), + STR("FFrame")}; + + static inline std::vector s_uprefix_to_fprefix{ STR("UProperty"), STR("UMulticastDelegateProperty"), STR("UObjectPropertyBase"), @@ -200,17 +200,17 @@ namespace RC::UVTD }; // Any members by the name 'LHS' will instead use 'RHS' in generated code. - static inline std::unordered_map s_member_rename_map{ + static inline std::unordered_map s_member_rename_map{ {STR("Class"), STR("ClassPrivate")}, {STR("Name"), STR("NamePrivate")}, {STR("Outer"), STR("OuterPrivate")}, }; - auto to_string_type(const char* c_str) -> File::StringType; - auto change_prefix(File::StringType input, bool is_425_plus) -> std::optional; + auto to_string_type(const char* c_str) -> UEStringType; + auto change_prefix(UEStringType input, bool is_425_plus) -> std::optional; // Workaround that lets us have a unified 'TUObjectArray' struct regardless if the engine version uses a chunked or non-chunked variant of TUObjectArray. - auto unify_uobject_array_if_needed(StringType& out_variable_type) -> bool; + auto unify_uobject_array_if_needed(UEStringType& out_variable_type) -> bool; } // namespace RC::UVTD #endif diff --git a/UVTD/include/UVTD/MemberVarsDumper.hpp b/UVTD/include/UVTD/MemberVarsDumper.hpp index f6868fcf5..4637d4560 100644 --- a/UVTD/include/UVTD/MemberVarsDumper.hpp +++ b/UVTD/include/UVTD/MemberVarsDumper.hpp @@ -24,12 +24,12 @@ namespace RC::UVTD private: auto process_class(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::Record* class_record, - const File::StringType& class_name, + const UEStringType& class_name, const SymbolNameInfo& name_info) -> void; auto process_member(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::FieldList* field_record, Class& class_entry) -> void; private: - auto dump_member_variable_layouts(std::unordered_map& names) -> void; + auto dump_member_variable_layouts(std::unordered_map& names) -> void; public: auto generate_code() -> void; diff --git a/UVTD/include/UVTD/Symbols.hpp b/UVTD/include/UVTD/Symbols.hpp index dfcf8f577..4c1797b58 100644 --- a/UVTD/include/UVTD/Symbols.hpp +++ b/UVTD/include/UVTD/Symbols.hpp @@ -8,6 +8,9 @@ #include +#include +#include + #include #include #include @@ -45,25 +48,25 @@ namespace RC::UVTD struct MemberVariable { - File::StringType type; - File::StringType name; + UEStringType type; + UEStringType name; int32_t offset; }; struct FunctionParam { - File::StringType type; + UEStringType type; auto to_string() const -> File::StringType { - return std::format(STR("{}"), type); + return std::format(IOSTR("{}"), to_file(type)); } }; struct MethodSignature { - File::StringType return_type; - File::StringType name; + UEStringType return_type; + UEStringType name; std::vector params; bool const_qualifier; @@ -74,16 +77,16 @@ namespace RC::UVTD for (size_t i = 0; i < params.size(); i++) { bool should_add_comma = i < params.size() - 1; - params_string.append(std::format(STR("{}{}"), params[i].to_string(), should_add_comma ? STR(", ") : STR(""))); + params_string.append(fmtfile(IOSTR("{}{}"), params[i].to_string(), should_add_comma ? IOSTR(", ") : IOSTR(""))); } - return std::format(STR("{} {}({}){};"), return_type, name, params_string, const_qualifier ? STR("const") : STR("")); + return fmtfile(IOSTR("{} {}({}){};"), return_type, name, params_string, const_qualifier ? IOSTR("const") : IOSTR("")); } }; struct MethodBody { - File::StringType name; + UEStringType name; MethodSignature signature; uint32_t offset; bool is_overload; @@ -91,11 +94,11 @@ namespace RC::UVTD struct Class { - File::StringType class_name; - File::StringType class_name_clean; + UEStringType class_name; + UEStringType class_name_clean; std::map functions; // Key: Variable name - std::map variables; + std::map variables; uint32_t last_virtual_offset{}; ValidForVTable valid_for_vtable{ValidForVTable::No}; ValidForMemberVars valid_for_member_vars{ValidForMemberVars::No}; @@ -106,24 +109,24 @@ namespace RC::UVTD public: struct MemberVariable { - File::StringType type; + UEStringType type; int32_t offset; }; struct EnumEntry { - File::StringType name; - File::StringType name_clean; - std::map variables; + UEStringType name; + UEStringType name_clean; + std::map variables; }; struct Class { - File::StringType class_name; - File::StringType class_name_clean; + UEStringType class_name; + UEStringType class_name_clean; std::map functions; // Key: Variable name - std::map variables; + std::map variables; uint32_t last_virtual_offset; ValidForVTable valid_for_vtable{ValidForVTable::No}; ValidForMemberVars valid_for_member_vars{ValidForMemberVars::No}; @@ -151,18 +154,18 @@ namespace RC::UVTD Symbols& operator=(const Symbols& other); public: - auto get_or_create_enum_entry(const File::StringType& symbol_name, const File::StringType& symbol_name_clean) -> EnumEntry&; - auto get_or_create_class_entry(const File::StringType& symbol_name, const File::StringType& symbol_name_clean, const SymbolNameInfo& name_info) -> Class&; + auto get_or_create_enum_entry(const UEStringType& symbol_name, const UEStringType& symbol_name_clean) -> EnumEntry&; + auto get_or_create_class_entry(const UEStringType& symbol_name, const UEStringType& symbol_name_clean, const SymbolNameInfo& name_info) -> Class&; - auto generate_method_signature(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::Record* function_record, File::StringType method_name) + auto generate_method_signature(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::Record* function_record, UEStringType method_name) -> MethodSignature; public: - auto static get_type_name(const PDB::TPIStream& tpi_stream, uint32_t record_index, bool check_valid = false) -> File::StringType; - auto static get_method_name(const PDB::CodeView::TPI::FieldList* method_record) -> File::StringType; - auto static get_leaf_name(const char* data, PDB::CodeView::TPI::TypeRecordKind kind) -> File::StringType; + auto static get_type_name(const PDB::TPIStream& tpi_stream, uint32_t record_index, bool check_valid = false) -> UEStringType; + auto static get_method_name(const PDB::CodeView::TPI::FieldList* method_record) -> UEStringType; + auto static get_leaf_name(const char* data, PDB::CodeView::TPI::TypeRecordKind kind) -> UEStringType; - auto static clean_name(File::StringType name) -> File::StringType; + auto static clean_name(UEStringType name) -> UEStringType; auto static is_virtual(PDB::CodeView::TPI::MemberAttributes attributes) -> bool; diff --git a/UVTD/include/UVTD/TemplateClassParser.hpp b/UVTD/include/UVTD/TemplateClassParser.hpp index 1e6467747..f7ccf5e6f 100644 --- a/UVTD/include/UVTD/TemplateClassParser.hpp +++ b/UVTD/include/UVTD/TemplateClassParser.hpp @@ -9,14 +9,14 @@ namespace RC::UVTD { struct ParsedTemplateClass { - File::StringType class_name; - std::vector template_args; + UEStringType class_name; + std::vector template_args; }; class TemplateClassParser { public: - static ParsedTemplateClass Parse(File::StringViewType input); + static ParsedTemplateClass Parse(UEStringViewType input); }; } // namespace RC::UVTD diff --git a/UVTD/include/UVTD/TypeContainer.hpp b/UVTD/include/UVTD/TypeContainer.hpp index 21d483ce2..1106669f1 100644 --- a/UVTD/include/UVTD/TypeContainer.hpp +++ b/UVTD/include/UVTD/TypeContainer.hpp @@ -11,7 +11,7 @@ namespace RC::UVTD class TypeContainer { private: - using ClassEntries = std::unordered_map; + using ClassEntries = std::unordered_map; ClassEntries class_entries; @@ -25,7 +25,7 @@ namespace RC::UVTD } public: - auto get_or_create_class_entry(const File::StringType& symbol_name, const File::StringType& symbol_name_clean, const SymbolNameInfo& name_info) -> Class&; + auto get_or_create_class_entry(const UEStringType& symbol_name, const UEStringType& symbol_name_clean, const SymbolNameInfo& name_info) -> Class&; }; } // namespace RC::UVTD diff --git a/UVTD/include/UVTD/UnrealVirtualGenerator.hpp b/UVTD/include/UVTD/UnrealVirtualGenerator.hpp index a6a90df91..0a7547dfe 100644 --- a/UVTD/include/UVTD/UnrealVirtualGenerator.hpp +++ b/UVTD/include/UVTD/UnrealVirtualGenerator.hpp @@ -8,13 +8,13 @@ namespace RC::UVTD class UnrealVirtualGenerator { private: - File::StringType pdb_name; + SystemStringType pdb_name; TypeContainer type_container; public: UnrealVirtualGenerator() = delete; - explicit UnrealVirtualGenerator(File::StringType pdb_name, TypeContainer container) + explicit UnrealVirtualGenerator(SystemStringType pdb_name, TypeContainer container) : pdb_name(std::move(pdb_name)), type_container(std::move(container)) { } diff --git a/UVTD/include/UVTD/VTableDumper.hpp b/UVTD/include/UVTD/VTableDumper.hpp index e4993d7b3..f0c3848c8 100644 --- a/UVTD/include/UVTD/VTableDumper.hpp +++ b/UVTD/include/UVTD/VTableDumper.hpp @@ -39,14 +39,14 @@ namespace RC::UVTD private: auto process_class(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::Record* class_record, - const File::StringType& class_name, + const UEStringType& class_name, const SymbolNameInfo& name_info) -> void; auto process_method_overload_list(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::FieldList* method_record, Class& class_entry) -> void; auto process_onemethod(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::FieldList* onemethod_record, Class& class_entry) -> void; private: - auto dump_vtable_for_symbol(std::unordered_map& names) -> void; + auto dump_vtable_for_symbol(std::unordered_map& names) -> void; public: static auto output_cleanup() -> void; diff --git a/UVTD/src/Helpers.cpp b/UVTD/src/Helpers.cpp index ddb97c8d8..8f8baff47 100644 --- a/UVTD/src/Helpers.cpp +++ b/UVTD/src/Helpers.cpp @@ -5,26 +5,12 @@ namespace RC::UVTD { - auto to_string_type(const char* c_str) -> File::StringType + auto to_string_type(const char* c_str) -> UEStringType { -#if RC_IS_ANSI == 1 - return File::StringType(c_str); -#else - size_t count = strlen(c_str) + 1; - wchar_t* converted_method_name = new wchar_t[count]; - - size_t num_of_char_converted = 0; - mbstowcs_s(&num_of_char_converted, converted_method_name, count, c_str, count); - - auto converted = File::StringType(converted_method_name); - - delete[] converted_method_name; - - return converted; -#endif + return to_ue(c_str); } - auto change_prefix(File::StringType input, bool is_425_plus) -> std::optional + auto change_prefix(UEStringType input, bool is_425_plus) -> std::optional { for (const auto& prefixed : s_uprefix_to_fprefix) { @@ -39,16 +25,17 @@ namespace RC::UVTD return input; } - auto unify_uobject_array_if_needed(StringType& out_variable_type) -> bool + auto unify_uobject_array_if_needed(UEStringType& out_variable_type) -> bool { - static constexpr StringViewType fixed_uobject_array_string = STR("FFixedUObjectArray"); - static constexpr StringViewType chunked_fixed_uobject_array_string = STR("FChunkedFixedUObjectArray"); + static constexpr UEStringViewType fixed_uobject_array_string = STR("FFixedUObjectArray"); + static constexpr UEStringViewType chunked_fixed_uobject_array_string = STR("FChunkedFixedUObjectArray"); if (auto fixed_uobject_array_pos = out_variable_type.find(fixed_uobject_array_string); fixed_uobject_array_pos != out_variable_type.npos) { out_variable_type.replace(fixed_uobject_array_pos, fixed_uobject_array_string.length(), STR("TUObjectArray")); return true; } - else if (auto chunked_fixed_uobject_array_pos = out_variable_type.find(chunked_fixed_uobject_array_string); chunked_fixed_uobject_array_pos != out_variable_type.npos) + else if (auto chunked_fixed_uobject_array_pos = out_variable_type.find(chunked_fixed_uobject_array_string); + chunked_fixed_uobject_array_pos != out_variable_type.npos) { out_variable_type.replace(chunked_fixed_uobject_array_pos, chunked_fixed_uobject_array_string.length(), STR("TUObjectArray")); return true; diff --git a/UVTD/src/MemberVarsDumper.cpp b/UVTD/src/MemberVarsDumper.cpp index 5e6c8ab5f..faad159c0 100644 --- a/UVTD/src/MemberVarsDumper.cpp +++ b/UVTD/src/MemberVarsDumper.cpp @@ -7,7 +7,7 @@ namespace RC::UVTD { - static inline std::vector s_types_to_not_dump{ + static inline std::vector s_types_to_not_dump{ STR("FUnversionedStructSchema"), STR("ELifetimeCondition"), STR("UAISystemBase"), @@ -110,14 +110,14 @@ namespace RC::UVTD auto MemberVarsDumper::process_class(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::Record* class_record, - const File::StringType& name, + const UEStringType& name, const SymbolNameInfo& name_info) -> void { auto changed = change_prefix(name, symbols.is_425_plus); if (!changed.has_value()) return; - File::StringType class_name = *changed; - File::StringType class_name_clean = Symbols::clean_name(class_name); + auto class_name = *changed; + auto class_name_clean = Symbols::clean_name(class_name); auto& class_entry = type_container.get_or_create_class_entry(class_name, class_name_clean, name_info); auto fields = tpi_stream.GetTypeRecord(class_record->data.LF_CLASS.field); @@ -136,11 +136,11 @@ namespace RC::UVTD auto MemberVarsDumper::process_member(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::FieldList* field_record, Class& class_entry) -> void { - File::StringType member_name = Symbols::get_leaf_name(field_record->data.LF_STMEMBER.name, field_record->data.LF_MEMBER.lfEasy.kind); + auto member_name = Symbols::get_leaf_name(field_record->data.LF_STMEMBER.name, field_record->data.LF_MEMBER.lfEasy.kind); auto changed = change_prefix(Symbols::get_type_name(tpi_stream, field_record->data.LF_MEMBER.index), symbols.is_425_plus); if (!changed.has_value()) return; - File::StringType type_name = *changed; + auto type_name = *changed; for (const auto& type_to_not_dump : s_types_to_not_dump) { @@ -156,9 +156,9 @@ namespace RC::UVTD variable.offset = *(uint16_t*)field_record->data.LF_MEMBER.offset; } - auto MemberVarsDumper::dump_member_variable_layouts(std::unordered_map& names) -> void + auto MemberVarsDumper::dump_member_variable_layouts(std::unordered_map& names) -> void { - Output::send(STR("Dumping {} symbols for {}\n"), names.size(), symbols.pdb_file_path.filename().stem().wstring()); + Output::send(SYSSTR("Dumping {} symbols for {}\n"), names.size(), symbols.pdb_file_path.filename().stem().wstring()); const PDB::TPIStream tpi_stream = PDB::CreateTPIStream(symbols.pdb_file); @@ -169,7 +169,7 @@ namespace RC::UVTD { if (type_record->data.LF_CLASS.property.fwdref) continue; - const File::StringType class_name = Symbols::get_leaf_name(type_record->data.LF_CLASS.data, type_record->data.LF_CLASS.lfEasy.kind); + const SystemStringType class_name = Symbols::get_leaf_name(type_record->data.LF_CLASS.data, type_record->data.LF_CLASS.lfEasy.kind); if (!names.contains(class_name)) continue; const auto name_info = names.find(class_name); @@ -184,7 +184,7 @@ namespace RC::UVTD auto MemberVarsDumper::generate_code() -> void { - std::unordered_map member_vars_names; + std::unordered_map member_vars_names; for (ObjectItem& item : s_object_items) { @@ -197,28 +197,28 @@ namespace RC::UVTD auto MemberVarsDumper::generate_files() -> void { - File::StringType pdb_name = symbols.pdb_file_path.filename().stem(); + SystemStringType pdb_name = symbols.pdb_file_path.filename().stem(); auto default_template_file = std::filesystem::path{STR("MemberVariableLayout.ini")}; - Output::send(STR("Generating file '{}'\n"), default_template_file.wstring()); + Output::send(SYSSTR("Generating file '{}'\n"), default_template_file.wstring()); Output::Targets default_ini_dumper; auto& default_ini_file_device = default_ini_dumper.get_device(); default_ini_file_device.set_file_name_and_path(member_variable_layouts_templates_output_path / default_template_file); - default_ini_file_device.set_formatter([](File::StringViewType string) { - return File::StringType{string}; + default_ini_file_device.set_formatter([](SystemStringViewType string) { + return SystemStringType{string}; }); - auto template_file = std::format(STR("MemberVariableLayout_{}_Template.ini"), pdb_name); + auto template_file = std::format(SYSSTR("MemberVariableLayout_{}_Template.ini"), pdb_name); - Output::send(STR("Generating file '{}'\n"), template_file); + Output::send(SYSSTR("Generating file '{}'\n"), template_file); Output::Targets ini_dumper; auto& ini_file_device = ini_dumper.get_device(); ini_file_device.set_file_name_and_path(member_variable_layouts_templates_output_path / template_file); - ini_file_device.set_formatter([](File::StringViewType string) { - return File::StringType{string}; + ini_file_device.set_formatter([](SystemStringViewType string) { + return SystemStringType{string}; }); auto pdb_name_no_underscore = pdb_name; @@ -232,15 +232,15 @@ namespace RC::UVTD } auto default_setter_src_file = member_variable_layouts_gen_function_bodies_path / - std::format(STR("{}_MemberVariableLayout_DefaultSetter_{}.cpp"), pdb_name, class_entry.class_name_clean); + std::format(SYSSTR("{}_MemberVariableLayout_DefaultSetter_{}.cpp"), pdb_name, to_system(class_entry.class_name_clean)); - Output::send(STR("Generating file '{}'\n"), default_setter_src_file.wstring()); + Output::send(SYSSTR("Generating file '{}'\n"), default_setter_src_file.wstring()); Output::Targets default_setter_src_dumper; auto& default_setter_src_file_device = default_setter_src_dumper.get_device(); default_setter_src_file_device.set_file_name_and_path(default_setter_src_file); - default_setter_src_file_device.set_formatter([](File::StringViewType string) { - return File::StringType{string}; + default_setter_src_file_device.set_formatter([](SystemStringViewType string) { + return SystemStringType{string}; }); ini_dumper.send(STR("[{}]\n"), class_entry.class_name); @@ -251,8 +251,8 @@ namespace RC::UVTD ini_dumper.send(STR("{} = 0x{:X}\n"), variable.name, variable.offset); default_ini_dumper.send(STR("{} = -1\n"), variable.name); - File::StringType final_variable_name = variable.name; - File::StringType final_class_name = class_entry.class_name; + SystemStringType final_variable_name = variable.name; + SystemStringType final_class_name = class_entry.class_name; if (variable.name == STR("EnumFlags")) { diff --git a/UVTD/src/MemberVarsWrapperGenerator.cpp b/UVTD/src/MemberVarsWrapperGenerator.cpp index a408c9c6e..93670d3a0 100644 --- a/UVTD/src/MemberVarsWrapperGenerator.cpp +++ b/UVTD/src/MemberVarsWrapperGenerator.cpp @@ -10,13 +10,13 @@ namespace RC::UVTD { auto macro_setter_file = std::filesystem::path{STR("MacroSetter.hpp")}; - Output::send(STR("Generating file '{}'\n"), macro_setter_file.wstring()); + Output::send(SYSSTR("Generating file '{}'\n"), macro_setter_file.wstring()); Output::Targets macro_setter_dumper; auto& macro_setter_file_device = macro_setter_dumper.get_device(); macro_setter_file_device.set_file_name_and_path(macro_setter_file); - macro_setter_file_device.set_formatter([](File::StringViewType string) { - return File::StringType{string}; + macro_setter_file_device.set_formatter([](SystemStringViewType string) { + return SystemStringType{string}; }); for (const auto& [class_name, class_entry] : type_container.get_class_entries()) @@ -27,33 +27,33 @@ namespace RC::UVTD } auto wrapper_header_file = member_variable_layouts_gen_output_include_path / - std::format(STR("MemberVariableLayout_HeaderWrapper_{}.hpp"), class_entry.class_name_clean); + std::format(SYSSTR("MemberVariableLayout_HeaderWrapper_{}.hpp"), class_entry.class_name_clean); - Output::send(STR("Generating file '{}'\n"), wrapper_header_file.wstring()); + Output::send(SYSSTR("Generating file '{}'\n"), wrapper_header_file.wstring()); Output::Targets header_wrapper_dumper; auto& wrapper_header_file_device = header_wrapper_dumper.get_device(); wrapper_header_file_device.set_file_name_and_path(wrapper_header_file); - wrapper_header_file_device.set_formatter([](File::StringViewType string) { - return File::StringType{string}; + wrapper_header_file_device.set_formatter([](SystemStringViewType string) { + return SystemStringType{string}; }); - auto wrapper_src_file = - member_variable_layouts_gen_output_include_path / std::format(STR("MemberVariableLayout_SrcWrapper_{}.hpp"), class_entry.class_name_clean); + auto wrapper_src_file = member_variable_layouts_gen_output_include_path / + std::format(SYSSTR("MemberVariableLayout_SrcWrapper_{}.hpp"), class_entry.class_name_clean); - Output::send(STR("Generating file '{}'\n"), wrapper_src_file.wstring()); + Output::send(SYSSTR("Generating file '{}'\n"), wrapper_src_file.wstring()); Output::Targets wrapper_src_dumper; auto& wrapper_src_file_device = wrapper_src_dumper.get_device(); wrapper_src_file_device.set_file_name_and_path(wrapper_src_file); - wrapper_src_file_device.set_formatter([](File::StringViewType string) { - return File::StringType{string}; + wrapper_src_file_device.set_formatter([](SystemStringViewType string) { + return SystemStringType{string}; }); auto final_class_name = class_entry.class_name; unify_uobject_array_if_needed(final_class_name); - header_wrapper_dumper.send(STR("static std::unordered_map MemberOffsets;\n\n")); - wrapper_src_dumper.send(STR("std::unordered_map {}::MemberOffsets{{}};\n\n"), final_class_name); + header_wrapper_dumper.send(STR("static std::unordered_map MemberOffsets;\n\n")); + wrapper_src_dumper.send(STR("std::unordered_map {}::MemberOffsets{{}};\n\n"), final_class_name); auto private_variables_for_class = s_private_variables.find(class_entry.class_name); @@ -83,8 +83,8 @@ namespace RC::UVTD bool is_private{private_variables_for_class != s_private_variables.end() && private_variables_for_class->second.find(variable.name) != private_variables_for_class->second.end()}; - File::StringType final_variable_name = variable.name; - File::StringType final_type_name = variable.type; + UEStringType final_variable_name = variable.name; + UEStringType final_type_name = variable.type; if (variable.name == STR("EnumFlags")) { @@ -151,7 +151,7 @@ namespace RC::UVTD wrapper_src_dumper.send(STR("}\n\n")); } - macro_setter_dumper.send(STR("if (auto val = parser.get_int64(STR(\"{}\"), STR(\"{}\"), -1); val != -1)\n"), + macro_setter_dumper.send(STR("if (auto val = parser.get_int64(SYSSTR(\"{}\"), SYSSTR(\"{}\"), -1); val != -1)\n"), final_class_name, final_variable_name); macro_setter_dumper.send(STR(" Unreal::{}::MemberOffsets.emplace(STR(\"{}\"), static_cast(val));\n"), diff --git a/UVTD/src/SolBindingsGenerator.cpp b/UVTD/src/SolBindingsGenerator.cpp index 45e7f2206..d1ac24751 100644 --- a/UVTD/src/SolBindingsGenerator.cpp +++ b/UVTD/src/SolBindingsGenerator.cpp @@ -26,19 +26,19 @@ namespace RC::UVTD auto final_class_name = class_name; - auto wrapper_header_file = sol_bindings_output_path / std::format(STR("SolBindings_{}.hpp"), final_class_name_clean); + auto wrapper_header_file = sol_bindings_output_path / std::format(SYSSTR("SolBindings_{}.hpp"), to_system(final_class_name_clean)); - Output::send(STR("Generating file '{}'\n"), wrapper_header_file.wstring()); + Output::send(SYSSTR("Generating file '{}'\n"), wrapper_header_file); Output::Targets header_wrapper_dumper; auto& wrapper_header_file_device = header_wrapper_dumper.get_device(); wrapper_header_file_device.set_file_name_and_path(wrapper_header_file); - wrapper_header_file_device.set_formatter([](File::StringViewType string) { - return File::StringType{string}; + wrapper_header_file_device.set_formatter([](SystemStringViewType string) { + return SystemStringType{string}; }); - header_wrapper_dumper.send(STR("auto sol_class_{} = sol().new_usertype<{}>(\"{}\""), final_class_name, final_class_name, final_class_name); + header_wrapper_dumper.send(SYSSTR("auto sol_class_{} = sol().new_usertype<{}>(\"{}\""), final_class_name, final_class_name, final_class_name); for (const auto& [variable_name, variable] : class_entry.variables) { @@ -67,7 +67,7 @@ namespace RC::UVTD continue; } - File::StringType final_variable_name = variable.name; + UEStringType final_variable_name = variable.name; if (variable.name == STR("EnumFlags")) { diff --git a/UVTD/src/Symbols.cpp b/UVTD/src/Symbols.cpp index 59e43c2da..13fd5d233 100644 --- a/UVTD/src/Symbols.cpp +++ b/UVTD/src/Symbols.cpp @@ -56,7 +56,7 @@ namespace RC::UVTD return *this; } - auto Symbols::generate_method_signature(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::Record* function_record, File::StringType method_name) + auto Symbols::generate_method_signature(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::Record* function_record, SystemStringType method_name) -> MethodSignature { MethodSignature signature{}; @@ -81,7 +81,7 @@ namespace RC::UVTD return signature; } - auto Symbols::get_type_name(const PDB::TPIStream& tpi_stream, uint32_t record_index, bool check_valid) -> File::StringType + auto Symbols::get_type_name(const PDB::TPIStream& tpi_stream, uint32_t record_index, bool check_valid) -> UEStringType { if (record_index < tpi_stream.GetFirstTypeIndex()) { @@ -214,7 +214,7 @@ namespace RC::UVTD { case PDB::CodeView::TPI::TypeRecordKind::LF_CLASS: case PDB::CodeView::TPI::TypeRecordKind::LF_STRUCTURE: { - File::StringType name = get_leaf_name(record->data.LF_CLASS.data, record->data.LF_CLASS.lfEasy.kind); + UEStringType name = get_leaf_name(record->data.LF_CLASS.data, record->data.LF_CLASS.lfEasy.kind); ParsedTemplateClass parsed = TemplateClassParser::Parse(name); if (parsed.class_name == STR("TMap")) @@ -228,11 +228,11 @@ namespace RC::UVTD return to_string_type(record->data.LF_ENUM.name); case PDB::CodeView::TPI::TypeRecordKind::LF_MODIFIER: { const auto modifier_attr = record->data.LF_MODIFIER.attr; - std::vector modifiers{}; + std::vector modifiers{}; if (modifier_attr.MOD_volatile) modifiers.push_back(STR("volatile")); - File::StringType modifier_string{}; + UEStringType modifier_string{}; for (const auto& modifier : modifiers) { modifier_string += modifier + STR(" "); @@ -244,17 +244,18 @@ namespace RC::UVTD return get_type_name(tpi_stream, record->data.LF_POINTER.utype, check_valid) + STR("*"); case PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION: case PDB::CodeView::TPI::TypeRecordKind::LF_PROCEDURE: { - File::StringType return_type = get_type_name(tpi_stream, record->data.LF_PROCEDURE.rvtype, true); - File::StringType args = get_type_name(tpi_stream, record->data.LF_PROCEDURE.arglist, check_valid); - return std::format(STR("std::function<{}({})>"), return_type, args); + UEStringType return_type = get_type_name(tpi_stream, record->data.LF_PROCEDURE.rvtype, true); + UEStringType args = get_type_name(tpi_stream, record->data.LF_PROCEDURE.arglist, check_valid); + return std::format(SYSSTR("std::function<{}({})>"), return_type, args); } case PDB::CodeView::TPI::TypeRecordKind::LF_ARGLIST: { - File::StringType args{}; + UEStringType args{}; for (size_t i = 0; i < record->data.LF_ARGLIST.count; i++) { bool should_add_comma = i < record->data.LF_ARGLIST.count - 1; - args.append(std::format(STR("{}{}"), get_type_name(tpi_stream, record->data.LF_ARGLIST.arg[i], true), should_add_comma ? STR(", ") : STR(""))); + // args.append(std::format(SYSSTR("{}{}"), get_type_name(tpi_stream, record->data.LF_ARGLIST.arg[i], true), should_add_comma ? STR(", ") : STR(""))); + args.append(get_type_name(tpi_stream, record->data.LF_ARGLIST.arg[i], true) + (should_add_comma ? STR(", ") : STR(""))); } return args; @@ -267,7 +268,7 @@ namespace RC::UVTD } } - auto Symbols::get_method_name(const PDB::CodeView::TPI::FieldList* method_record) -> File::StringType + auto Symbols::get_method_name(const PDB::CodeView::TPI::FieldList* method_record) -> UEStringType { auto methodAttributes = static_cast(method_record->data.LF_ONEMETHOD.attributes.mprop); switch (methodAttributes) @@ -311,7 +312,7 @@ namespace RC::UVTD return 0; } - auto Symbols::get_leaf_name(const char* data, PDB::CodeView::TPI::TypeRecordKind kind) -> File::StringType + auto Symbols::get_leaf_name(const char* data, PDB::CodeView::TPI::TypeRecordKind kind) -> UEStringType { auto name = to_string_type(&data[get_leaf_size(kind)]); if (auto it = s_member_rename_map.find(name); it != s_member_rename_map.end()) @@ -324,7 +325,7 @@ namespace RC::UVTD } } - auto Symbols::clean_name(File::StringType name) -> File::StringType + auto Symbols::clean_name(UEStringType name) -> UEStringType { std::replace(name.begin(), name.end(), ':', '_'); std::replace(name.begin(), name.end(), '~', '$'); diff --git a/UVTD/src/TemplateClassParser.cpp b/UVTD/src/TemplateClassParser.cpp index f69004ccd..49f966fac 100644 --- a/UVTD/src/TemplateClassParser.cpp +++ b/UVTD/src/TemplateClassParser.cpp @@ -2,22 +2,22 @@ namespace RC::UVTD { - ParsedTemplateClass TemplateClassParser::Parse(File::StringViewType input) + ParsedTemplateClass TemplateClassParser::Parse(UEStringViewType input) { ParsedTemplateClass parsed{}; - for (const File::StringType::value_type character : input) + for (const UEStringType::value_type character : input) { if (character == STR('<')) break; parsed.class_name += character; } size_t nesting_level = 0; - File::StringType current_param{}; + UEStringType current_param{}; for (size_t i = parsed.class_name.size(); i < input.size(); i++) { - const File::StringType::value_type character = input[i]; + const UEStringType::value_type character = input[i]; bool is_nesting_character = false; if (character == STR('>') && nesting_level == 1) break; diff --git a/UVTD/src/TypeContainer.cpp b/UVTD/src/TypeContainer.cpp index 772aeceb5..dec0bba6c 100644 --- a/UVTD/src/TypeContainer.cpp +++ b/UVTD/src/TypeContainer.cpp @@ -21,22 +21,18 @@ namespace RC::UVTD } } - auto TypeContainer::get_or_create_class_entry(const File::StringType& symbol_name, const File::StringType& symbol_name_clean, const SymbolNameInfo& name_info) - -> Class& + auto TypeContainer::get_or_create_class_entry(const UEStringType& symbol_name, const UEStringType& symbol_name_clean, const SymbolNameInfo& name_info) -> Class& { - auto& class_entry = [&]() -> auto& - { + auto& class_entry = [&]() -> auto& { if (auto it = class_entries.find(symbol_name); it != class_entries.end()) { return it->second; } else { - return class_entries.emplace(symbol_name_clean, Class{.class_name = File::StringType{symbol_name}, .class_name_clean = symbol_name_clean}) - .first->second; + return class_entries.emplace(symbol_name_clean, Class{.class_name = UEStringType{symbol_name}, .class_name_clean = symbol_name_clean}).first->second; } - } - (); + }(); class_entry.valid_for_member_vars = name_info.valid_for_member_vars; class_entry.valid_for_vtable = name_info.valid_for_vtable; diff --git a/UVTD/src/UVTD.cpp b/UVTD/src/UVTD.cpp index b65488a5e..52464c910 100644 --- a/UVTD/src/UVTD.cpp +++ b/UVTD/src/UVTD.cpp @@ -25,7 +25,7 @@ namespace RC::UVTD { bool processing_events{false}; - Input::Handler input_handler{L"ConsoleWindowClass", L"UnrealWindow"}; + Input::Handler input_handler{}; auto static event_loop_update() -> void { @@ -38,6 +38,8 @@ namespace RC::UVTD auto main(DumpSettings dump_settings) -> void { + input_handler.init(); + input_handler.set_input_source("Win32Async"); static std::vector pdbs_to_dump{ "PDBs/4_10.pdb", "PDBs/4_11.pdb", @@ -111,13 +113,13 @@ namespace RC::UVTD generator.generate_files(); } - File::StringType pdb_name = pdb.filename().stem(); + SystemStringType pdb_name = pdb.filename().stem(); UnrealVirtualGenerator virtual_generator(pdb_name, run_container); virtual_generator.generate_files(); shared_container.join(run_container); - Output::send(STR("Code generated.\n")); + Output::send(SYSSTR("Code generated.\n")); } }); } @@ -128,9 +130,9 @@ namespace RC::UVTD MemberVarsWrapperGenerator wrapper_generator{std::move(shared_container)}; wrapper_generator.generate_files(); - Output::send(STR("Code generated.\n")); + Output::send(SYSSTR("Code generated.\n")); } - Output::send(STR("All done.\n")); + Output::send(SYSSTR("All done.\n")); } } // namespace RC::UVTD diff --git a/UVTD/src/UnrealVirtualGenerator.cpp b/UVTD/src/UnrealVirtualGenerator.cpp index f3ab28c48..2c77d96d7 100644 --- a/UVTD/src/UnrealVirtualGenerator.cpp +++ b/UVTD/src/UnrealVirtualGenerator.cpp @@ -10,26 +10,26 @@ namespace RC::UVTD auto pdb_name_no_underscore = pdb_name; pdb_name_no_underscore.replace(pdb_name_no_underscore.find(STR('_')), 1, STR("")); - auto virtual_header_file = virtual_gen_output_include_path / std::format(STR("UnrealVirtual{}.hpp"), pdb_name_no_underscore); + auto virtual_header_file = virtual_gen_output_include_path / std::format(SYSSTR("UnrealVirtual{}.hpp"), pdb_name_no_underscore); - Output::send(STR("Generating file '{}'\n"), virtual_header_file.wstring()); + Output::send(SYSSTR("Generating file '{}'\n"), virtual_header_file.wstring()); Output::Targets virtual_header_dumper; auto& virtual_header_file_device = virtual_header_dumper.get_device(); virtual_header_file_device.set_file_name_and_path(virtual_header_file); - virtual_header_file_device.set_formatter([](File::StringViewType string) { - return File::StringType{string}; + virtual_header_file_device.set_formatter([](SystemStringViewType string) { + return SystemStringType{string}; }); - auto virtual_src_file = virtual_gen_function_bodies_path / std::format(STR("UnrealVirtual{}.cpp"), pdb_name_no_underscore); + auto virtual_src_file = virtual_gen_function_bodies_path / std::format(SYSSTR("UnrealVirtual{}.cpp"), pdb_name_no_underscore); - Output::send(STR("Generating file '{}'\n"), virtual_src_file.wstring()); + Output::send(SYSSTR("Generating file '{}'\n"), virtual_src_file); Output::Targets virtual_src_dumper; auto& virtual_src_file_device = virtual_src_dumper.get_device(); virtual_src_file_device.set_file_name_and_path(virtual_src_file); - virtual_src_file_device.set_formatter([](File::StringViewType string) { - return File::StringType{string}; + virtual_src_file_device.set_formatter([](SystemStringViewType string) { + return SystemStringType{string}; }); bool is_case_preserving_pdb = !(s_case_preserving_variants.find(pdb_name) == s_case_preserving_variants.end()); @@ -37,77 +37,77 @@ namespace RC::UVTD if (!is_case_preserving_pdb) { - virtual_header_dumper.send(STR("#ifndef RC_UNREAL_UNREAL_VIRTUAL{}_HPP\n"), pdb_name_no_underscore); - virtual_header_dumper.send(STR("#define RC_UNREAL_UNREAL_VIRTUAL{}_HPP\n"), pdb_name_no_underscore); - virtual_header_dumper.send(STR("#include \n\n")); - virtual_header_dumper.send(STR("namespace RC::Unreal\n")); - virtual_header_dumper.send(STR("{\n")); - virtual_header_dumper.send(STR(" class UnrealVirtual{} : public UnrealVirtualBaseVC\n"), pdb_name_no_underscore); - virtual_header_dumper.send(STR(" {\n")); - virtual_header_dumper.send(STR(" auto set_virtual_offsets() -> void override;\n")); - virtual_header_dumper.send(STR(" };\n")); - virtual_header_dumper.send(STR("}\n\n\n")); - virtual_header_dumper.send(STR("#endif //RC_UNREAL_UNREAL_VIRTUAL{}_HPP\n"), pdb_name_no_underscore); - - virtual_src_dumper.send(STR("#include \n\n"), pdb_name_no_underscore); - virtual_src_dumper.send(STR("#include \n\n")); - virtual_src_dumper.send(STR("// These are all the structs that have virtuals that need to have their offset set\n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("#include \n")); - // virtual_src_dumper.send(STR("#include \n")); - virtual_src_dumper.send(STR("\n")); - virtual_src_dumper.send(STR("namespace RC::Unreal\n")); - virtual_src_dumper.send(STR("{\n")); - virtual_src_dumper.send(STR(" void UnrealVirtual{}::set_virtual_offsets()\n"), pdb_name_no_underscore); - virtual_src_dumper.send(STR(" {\n")); + virtual_header_dumper.send(SYSSTR("#ifndef RC_UNREAL_UNREAL_VIRTUAL{}_HPP\n"), pdb_name_no_underscore); + virtual_header_dumper.send(SYSSTR("#define RC_UNREAL_UNREAL_VIRTUAL{}_HPP\n"), pdb_name_no_underscore); + virtual_header_dumper.send(SYSSTR("#include \n\n")); + virtual_header_dumper.send(SYSSTR("namespace RC::Unreal\n")); + virtual_header_dumper.send(SYSSTR("{\n")); + virtual_header_dumper.send(SYSSTR(" class UnrealVirtual{} : public UnrealVirtualBaseVC\n"), pdb_name_no_underscore); + virtual_header_dumper.send(SYSSTR(" {\n")); + virtual_header_dumper.send(SYSSTR(" auto set_virtual_offsets() -> void override;\n")); + virtual_header_dumper.send(SYSSTR(" };\n")); + virtual_header_dumper.send(SYSSTR("}\n\n\n")); + virtual_header_dumper.send(SYSSTR("#endif //RC_UNREAL_UNREAL_VIRTUAL{}_HPP\n"), pdb_name_no_underscore); + + virtual_src_dumper.send(SYSSTR("#include \n\n"), pdb_name_no_underscore); + virtual_src_dumper.send(SYSSTR("#include \n\n")); + virtual_src_dumper.send(SYSSTR("// These are all the structs that have virtuals that need to have their offset set\n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("#include \n")); + // virtual_src_dumper.send(SYSSTR("#include \n")); + virtual_src_dumper.send(SYSSTR("\n")); + virtual_src_dumper.send(SYSSTR("namespace RC::Unreal\n")); + virtual_src_dumper.send(SYSSTR("{\n")); + virtual_src_dumper.send(SYSSTR(" void UnrealVirtual{}::set_virtual_offsets()\n"), pdb_name_no_underscore); + virtual_src_dumper.send(SYSSTR(" {\n")); } for (const auto& [class_name, class_entry] : type_container.get_class_entries()) { if (!class_entry.functions.empty() && class_entry.valid_for_vtable == ValidForVTable::Yes && !is_case_preserving_pdb) { - virtual_src_dumper.send(STR("#include \n"), pdb_name, class_name); + virtual_src_dumper.send(SYSSTR("#include \n"), pdb_name, class_name); } } if (!is_case_preserving_pdb) { - virtual_src_dumper.send(STR("\n")); + virtual_src_dumper.send(SYSSTR("\n")); // Second & third passes just to separate VTable includes and MemberOffsets includes. if (is_non_case_preserving_pdb) { - virtual_src_dumper.send(STR("#ifdef WITH_CASE_PRESERVING_NAME\n")); + virtual_src_dumper.send(SYSSTR("#ifdef WITH_CASE_PRESERVING_NAME\n")); for (const auto& [class_name, class_entry] : type_container.get_class_entries()) { if (class_entry.variables.empty()) @@ -117,7 +117,9 @@ namespace RC::UVTD if (class_entry.valid_for_member_vars == ValidForMemberVars::Yes) { - virtual_src_dumper.send(STR("#include \n"), pdb_name, class_name); + virtual_src_dumper.send(SYSSTR("#include \n"), + pdb_name, + class_name); } } virtual_src_dumper.send(STR("#else\n")); diff --git a/UVTD/src/VTableDumper.cpp b/UVTD/src/VTableDumper.cpp index 485c547cc..6b94bd71c 100644 --- a/UVTD/src/VTableDumper.cpp +++ b/UVTD/src/VTableDumper.cpp @@ -25,14 +25,14 @@ namespace RC::UVTD { auto VTableDumper::process_class(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::Record* class_record, - const File::StringType& name, + const UEStringType& name, const SymbolNameInfo& name_info) -> void { auto changed = change_prefix(name, symbols.is_425_plus); if (!changed.has_value()) return; - File::StringType class_name = *changed; - File::StringType class_name_clean = Symbols::clean_name(class_name); + UEStringType class_name = *changed; + UEStringType class_name_clean = Symbols::clean_name(class_name); auto& class_entry = type_container.get_or_create_class_entry(class_name, class_name_clean, name_info); @@ -65,8 +65,8 @@ namespace RC::UVTD { auto list = tpi_stream.GetTypeRecord(method_record->data.LF_METHOD.mList); - File::StringType method_name = Symbols::get_method_name(method_record); - File::StringType method_name_clean = Symbols::clean_name(method_name); + UEStringType method_name = Symbols::get_method_name(method_record); + UEStringType method_name_clean = Symbols::clean_name(method_name); // this is required because METHOD struct size is not constant :) size_t next_offset = 0; @@ -87,10 +87,10 @@ namespace RC::UVTD if (!Symbols::is_virtual(overload_record->METHOD.attributes)) continue; if (!function_record || function_record->header.kind != PDB::CodeView::TPI::TypeRecordKind::LF_MFUNCTION) continue; - File::StringType overload_name = method_name_clean; + UEStringType overload_name = method_name_clean; if (overload_index != 0) { - overload_name += std::format(STR("_{}"), overload_index); + overload_name += std::format(SYSSTR("_{}"), overload_index); } overload_index++; @@ -104,13 +104,13 @@ namespace RC::UVTD auto VTableDumper::process_onemethod(const PDB::TPIStream& tpi_stream, const PDB::CodeView::TPI::FieldList* method_record, Class& class_entry) -> void { - static std::unordered_map> functions_already_dumped{}; + static std::unordered_map> functions_already_dumped{}; const auto is_virtual = method_record->data.LF_ONEMETHOD.attributes.mprop == (uint16_t)PDB::CodeView::TPI::MethodProperty::Intro || method_record->data.LF_ONEMETHOD.attributes.mprop == (uint16_t)PDB::CodeView::TPI::MethodProperty::PureIntro; if (!is_virtual) return; - File::StringType method_name = Symbols::get_method_name(method_record); + UEStringType method_name = Symbols::get_method_name(method_record); int32_t vtable_offset = method_record->data.LF_ONEMETHOD.vbaseoff[0]; auto function_record = tpi_stream.GetTypeRecord(method_record->data.LF_ONEMETHOD.index); @@ -120,14 +120,14 @@ namespace RC::UVTD { if (auto it2 = it->second.find(method_name); it2 != it->second.end()) { - method_name.append(std::format(STR("_{}"), ++it2->second)); + method_name.append(std::format(SYSSTR("_{}"), ++it2->second)); is_overload = true; } } - Output::send(STR(" method {} offset {}\n"), method_name, vtable_offset); + Output::send(SYSSTR(" method {} offset {}\n"), method_name, vtable_offset); - File::StringType method_name_clean = Symbols::clean_name(method_name); + UEStringType method_name_clean = Symbols::clean_name(method_name); auto& function = class_entry.functions[vtable_offset]; function.name = method_name_clean; @@ -137,9 +137,9 @@ namespace RC::UVTD functions_already_dumped.emplace(method_name, 1); } - auto VTableDumper::dump_vtable_for_symbol(std::unordered_map& names) -> void + auto VTableDumper::dump_vtable_for_symbol(std::unordered_map& names) -> void { - Output::send(STR("Dumping {} struct symbols for {}\n"), names.size(), symbols.pdb_file_path.filename().stem().wstring()); + Output::send(SYSSTR("Dumping {} struct symbols for {}\n"), names.size(), symbols.pdb_file_path.filename().stem().wstring()); const PDB::TPIStream tpi_stream = PDB::CreateTPIStream(symbols.pdb_file); @@ -150,7 +150,7 @@ namespace RC::UVTD { if (type_record->data.LF_CLASS.property.fwdref) continue; - const File::StringType class_name = Symbols::get_leaf_name(type_record->data.LF_CLASS.data, type_record->data.LF_CLASS.lfEasy.kind); + const UEStringType class_name = Symbols::get_leaf_name(type_record->data.LF_CLASS.data, type_record->data.LF_CLASS.lfEasy.kind); if (!names.contains(class_name)) continue; const auto name_info = names.find(class_name); @@ -164,7 +164,7 @@ namespace RC::UVTD auto VTableDumper::generate_code() -> void { - std::unordered_map vtable_names; + std::unordered_map vtable_names; for (const auto& object_item : s_object_items) { if (object_item.valid_for_vtable != ValidForVTable::Yes) continue; @@ -177,17 +177,17 @@ namespace RC::UVTD auto VTableDumper::generate_files() -> void { - File::StringType pdb_name = symbols.pdb_file_path.filename().stem(); + UEStringType pdb_name = symbols.pdb_file_path.filename().stem(); for (const auto& [class_name, class_entry] : type_container.get_class_entries()) { - Output::send(STR("Generating file '{}_VTableOffsets_{}_FunctionBody.cpp'\n"), pdb_name, class_entry.class_name_clean); + Output::send(SYSSTR("Generating file '{}_VTableOffsets_{}_FunctionBody.cpp'\n"), pdb_name, class_entry.class_name_clean); Output::Targets function_body_dumper; auto& function_body_file_device = function_body_dumper.get_device(); function_body_file_device.set_file_name_and_path(vtable_gen_output_function_bodies_path / - std::format(STR("{}_VTableOffsets_{}_FunctionBody.cpp"), pdb_name, class_name)); - function_body_file_device.set_formatter([](File::StringViewType string) { - return File::StringType{string}; + std::format(SYSSTR("{}_VTableOffsets_{}_FunctionBody.cpp"), pdb_name, class_name)); + function_body_file_device.set_formatter([](SystemStringViewType string) { + return SystemStringType{string}; }); for (const auto& [function_index, function_entry] : class_entry.functions) @@ -198,39 +198,42 @@ namespace RC::UVTD local_class_name.replace(0, 1, STR("F")); } - function_body_dumper.send(STR("if (auto it = {}::VTableLayoutMap.find(STR(\"{}\")); it == {}::VTableLayoutMap.end())\n"), + function_body_dumper.send(SYSSTR("if (auto it = {}::VTableLayoutMap.find(STR(\"{}\")); it == {}::VTableLayoutMap.end())\n"), local_class_name, function_entry.name, local_class_name); - function_body_dumper.send(STR("{\n")); - function_body_dumper.send(STR(" {}::VTableLayoutMap.emplace(STR(\"{}\"), 0x{:X});\n"), local_class_name, function_entry.name, function_entry.offset); - function_body_dumper.send(STR("}\n\n")); + function_body_dumper.send(SYSSTR("{\n")); + function_body_dumper.send(SYSSTR(" {}::VTableLayoutMap.emplace(STR(\"{}\"), 0x{:X});\n"), + local_class_name, + function_entry.name, + function_entry.offset); + function_body_dumper.send(SYSSTR("}\n\n")); } } - auto template_file = std::format(STR("VTableLayout_{}_Template.ini"), pdb_name); - Output::send(STR("Generating file '{}'\n"), template_file); + auto template_file = std::format(SYSSTR("VTableLayout_{}_Template.ini"), pdb_name); + Output::send(SYSSTR("Generating file '{}'\n"), template_file); Output::Targets ini_dumper; auto& ini_file_device = ini_dumper.get_device(); ini_file_device.set_file_name_and_path(vtable_templates_output_path / template_file); - ini_file_device.set_formatter([](File::StringViewType string) { - return File::StringType{string}; + ini_file_device.set_formatter([](SystemStringViewType string) { + return SystemStringType{string}; }); for (const auto& [class_name, class_entry] : type_container.get_class_entries()) { - ini_dumper.send(STR("[{}]\n"), class_entry.class_name); + ini_dumper.send(SYSSTR("[{}]\n"), class_entry.class_name); for (const auto& [function_index, function_entry] : class_entry.functions) { if (function_entry.is_overload) { - ini_dumper.send(STR("; {}\n"), function_entry.signature.to_string()); + ini_dumper.send(SYSSTR("; {}\n"), function_entry.signature.to_string()); } - ini_dumper.send(STR("{}\n"), function_entry.name); + ini_dumper.send(SYSSTR("{}\n"), function_entry.name); } - ini_dumper.send(STR("\n")); + ini_dumper.send(SYSSTR("\n")); } } diff --git a/UVTD/src/main.cpp b/UVTD/src/main.cpp index 1a63c13c8..f5d65895a 100644 --- a/UVTD/src/main.cpp +++ b/UVTD/src/main.cpp @@ -12,12 +12,12 @@ using namespace RC; auto static get_user_selection() -> int32_t { - Output::send(STR("What would you like to do ?\n")); - Output::send(STR("1. Generate VTable layouts\n")); - Output::send(STR("2. Generate class/struct member variable layouts\n")); - Output::send(STR("3. Generate sol bindings\n")); - Output::send(STR("4. Everything\n")); - Output::send(STR("0. Exit\n")); + Output::send(SYSSTR("What would you like to do ?\n")); + Output::send(SYSSTR("1. Generate VTable layouts\n")); + Output::send(SYSSTR("2. Generate class/struct member variable layouts\n")); + Output::send(SYSSTR("3. Generate sol bindings\n")); + Output::send(SYSSTR("4. Everything\n")); + Output::send(SYSSTR("0. Exit\n")); int32_t selection{}; std::cin >> selection; @@ -53,7 +53,7 @@ auto thread_dll_start([[maybe_unused]] LPVOID thread_param) -> unsigned long try { - Output::send(STR("Unreal Virtual Table Dumper -> START\n")); + Output::send(SYSSTR("Unreal Virtual Table Dumper -> START\n")); for (int32_t selection = get_user_selection(); selection != 1337; selection = get_user_selection()) { @@ -64,22 +64,22 @@ auto thread_dll_start([[maybe_unused]] LPVOID thread_param) -> unsigned long } else if (selection == 1) { - Output::send(STR("Generating VTable layouts...\n")); + Output::send(SYSSTR("Generating VTable layouts...\n")); settings.should_dump_vtable = true; } else if (selection == 2) { - Output::send(STR("Generating class/struct member variable layouts...\n")); + Output::send(SYSSTR("Generating class/struct member variable layouts...\n")); settings.should_dump_member_vars = true; } else if (selection == 3) { - Output::send(STR("Generating sol bindings...\n")); + Output::send(SYSSTR("Generating sol bindings...\n")); settings.should_dump_sol_bindings = true; } else if (selection == 4) { - Output::send(STR("Generating VTable layouts and class/struct member variable layouts...\n")); + Output::send(SYSSTR("Generating VTable layouts and class/struct member variable layouts...\n")); settings.should_dump_vtable = true; settings.should_dump_member_vars = true; } @@ -89,7 +89,7 @@ auto thread_dll_start([[maybe_unused]] LPVOID thread_param) -> unsigned long } catch (std::exception& e) { - Output::send(STR("Exception caught: {}\n"), to_wstring(e.what())); + Output::send(SYSSTR("Exception caught: {}\n"), e.what()); } return 0; diff --git a/deps/first/ASMHelper/src/ASMHelper.cpp b/deps/first/ASMHelper/src/ASMHelper.cpp index bf59ba5cd..c89631d17 100644 --- a/deps/first/ASMHelper/src/ASMHelper.cpp +++ b/deps/first/ASMHelper/src/ASMHelper.cpp @@ -56,7 +56,7 @@ namespace RC::ASM } else { - Output::send(STR("Was unable to resolve JMP instruction @ {}\n"), instruction.address); + Output::send(SYSSTR("Was unable to resolve JMP instruction @ {}\n"), instruction.address); return nullptr; } } diff --git a/deps/first/Constructs/include/Constructs/Annotated.hpp b/deps/first/Constructs/include/Constructs/Annotated.hpp index c22380ebb..53ee07a4b 100644 --- a/deps/first/Constructs/include/Constructs/Annotated.hpp +++ b/deps/first/Constructs/include/Constructs/Annotated.hpp @@ -24,7 +24,7 @@ namespace RC * Annotated, int> annotated_integer(123); * * for (const auto& comment : comments) { - * Output::send(STR("{}\n"), comment); + * Output::send(SYSSTR("{}\n"), comment); * } * @endcode */ diff --git a/deps/first/DynamicOutput/include/DynamicOutput/DebugConsoleDevice.hpp b/deps/first/DynamicOutput/include/DynamicOutput/DebugConsoleDevice.hpp index b62cdf320..daa2620a7 100644 --- a/deps/first/DynamicOutput/include/DynamicOutput/DebugConsoleDevice.hpp +++ b/deps/first/DynamicOutput/include/DynamicOutput/DebugConsoleDevice.hpp @@ -34,8 +34,8 @@ namespace RC::Output public: auto has_optional_arg() const -> bool override; - auto receive(File::StringViewType fmt) const -> void override; - auto receive_with_optional_arg(File::StringViewType fmt, int32_t optional_arg = 0) const -> void override; + auto receive(SystemStringViewType fmt) const -> void override; + auto receive_with_optional_arg(SystemStringViewType fmt, int32_t optional_arg = 0) const -> void override; }; } // namespace RC::Output diff --git a/deps/first/DynamicOutput/include/DynamicOutput/FileDevice.hpp b/deps/first/DynamicOutput/include/DynamicOutput/FileDevice.hpp index a212e4080..ec649a39d 100644 --- a/deps/first/DynamicOutput/include/DynamicOutput/FileDevice.hpp +++ b/deps/first/DynamicOutput/include/DynamicOutput/FileDevice.hpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace RC::Output { @@ -72,7 +73,7 @@ namespace RC::Output // Due to the design of the Output system the opening of the file is done in receive instead of in the constructor // It's opened only once and stays open until the Output object (not the device) leaves scope // The destructor is responsible for closing the file - auto receive(File::StringViewType fmt) const -> void override + auto receive(SystemStringViewType fmt) const -> void override { if (!m_is_device_ready) { @@ -82,11 +83,11 @@ namespace RC::Output // Do file output stuff here // File should already be open & be ready for writing (happens in constructor) - m_file.write_string_to_file(m_formatter(fmt)); + m_file.write_file_string_to_file(to_file(m_formatter(fmt))); } // OutputDevice Interface -> END - auto set_file_name_and_path(const File::StringType& file_name_and_path) -> void + auto set_file_name_and_path(const SystemStringType& file_name_and_path) -> void { m_file_name_and_path = file_name_and_path; } diff --git a/deps/first/DynamicOutput/include/DynamicOutput/Output.hpp b/deps/first/DynamicOutput/include/DynamicOutput/Output.hpp index ee2e0c087..951bb4a3f 100644 --- a/deps/first/DynamicOutput/include/DynamicOutput/Output.hpp +++ b/deps/first/DynamicOutput/include/DynamicOutput/Output.hpp @@ -9,12 +9,17 @@ #include #include #include +#include #include #include #include #include #include +#include + +// #include +// #include #if RC_IS_ANSI == 1 #define RC_STD_MAKE_FORMAT_ARGS std::make_format_args @@ -29,6 +34,20 @@ namespace RC::Output using OutputDevicesContainerType = std::vector>; + static constexpr auto apply_formatting(auto&& content, auto&&... args) + { + // Must switch on the 'content' type at compile-time, otherwise std::string formatting + // won't work on Windows since RC_STD_MAKE_FORMAT_ARGS is set to std::wstring. + if constexpr (not_std_string_like_t>::value) + { + return std::vformat(content, std::make_wformat_args(args...)); + } + else + { + return std::vformat(content, std::make_format_args(args...)); + } + } + auto RC_DYNOUT_API has_internal_error() -> bool; template @@ -109,7 +128,7 @@ namespace RC::Output }; template - auto send(File::StringViewType content, OptionalArg optional_arg) -> void + auto send(SystemStringViewType content, OptionalArg optional_arg) -> void { if (m_opened_devices.empty()) { @@ -122,61 +141,65 @@ namespace RC::Output if (device->has_optional_arg()) { - device->receive_with_optional_arg(std::vformat(content), RC_STD_MAKE_FORMAT_ARGS(static_cast(optional_arg))); + device->receive_with_optional_arg(content, static_cast(optional_arg)); } else { - device->receive(std::vformat(content)); + device->receive(content); } } } template - auto send(File::StringViewType content, FmtArgs... fmt_args) -> void + auto send(SystemStringViewType&& content, FmtArgs&&... fmt_args) -> void { if (m_opened_devices.empty()) { THROW_INTERNAL_FILE_ERROR("[Output::send] Attempted to send but there were no opened devices."); } + auto formated = apply_formatting(content, to_system(std::forward(fmt_args))...); + for (const auto& device : m_opened_devices) { ASSERT_OUTPUT_DEVICE_IS_VALID(device) if (device->has_optional_arg()) { - device->receive_with_optional_arg(std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(fmt_args...)), 0); + device->receive_with_optional_arg(formated, 0); } else { - device->receive(std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(fmt_args...))); + device->receive(formated); } } } template - auto send(File::StringViewType content, OptionalArg optional_arg, FmtArgs... fmt_args) -> void + auto send(SystemStringViewType content, OptionalArg optional_arg, FmtArgs&&... fmt_args) -> void { if (m_opened_devices.empty()) { THROW_INTERNAL_FILE_ERROR("[Output::send] Attempted to send but there were no opened devices."); } + auto formated = apply_formatting(content, to_system(std::forward(fmt_args))...); + for (const auto& device : m_opened_devices) { ASSERT_OUTPUT_DEVICE_IS_VALID(device) if (device->has_optional_arg()) { - device->receive_with_optional_arg(std::vformat(content, fmt_args...), RC_STD_MAKE_FORMAT_ARGS(static_cast(optional_arg))); + device->receive_with_optional_arg(formated, static_cast(optional_arg)); } else { - device->receive(std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(fmt_args...))); + device->receive(formated); } } } - auto send(const File::StringType& content) -> void + auto send(const SystemStringType& content) -> void { if (m_opened_devices.empty()) { @@ -199,29 +222,31 @@ namespace RC::Output } template - auto send(File::StringViewType content, FmtArg fmt_arg, FmtArgs... fmt_args) -> void + auto send(SystemStringViewType content, FmtArg&& fmt_arg, FmtArgs&&... fmt_args) -> void { if (m_opened_devices.empty()) { THROW_INTERNAL_FILE_ERROR("[Output::send] Attempted to send but there were no opened devices."); } + auto formated = std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(to_system(std::forward(fmt_arg), std::forward(fmt_args))...)); + for (const auto& device : m_opened_devices) { ASSERT_OUTPUT_DEVICE_IS_VALID(device) if (device->has_optional_arg()) { - device->receive_with_optional_arg(std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(fmt_arg, fmt_args...)), optional_arg); + device->receive_with_optional_arg(formated, optional_arg); } else { - device->receive(std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(fmt_args...))); + device->receive(formated); } } } template - auto send(const File::StringType& content) -> void + auto send(const SystemStringType& content) -> void { if (m_opened_devices.empty()) { @@ -278,47 +303,52 @@ namespace RC::Output DefaultTargets::set_default_log_level(log_level); } - template - auto send(File::StringViewType content, FmtArgs... fmt_args) -> void + template + auto send(StringView _content, FmtArgs&&... fmt_args) -> void { + auto content = to_system(_content); + auto formated = apply_formatting(content, to_system(std::forward(fmt_args))...); for (const auto& device : DefaultTargets::get_default_devices_ref()) { ASSERT_DEFAULT_OUTPUT_DEVICE_IS_VALID(device) if (device->has_optional_arg()) { - device->receive_with_optional_arg(std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(fmt_args...)), 0); + device->receive_with_optional_arg(formated, 0); } else { - device->receive(std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(fmt_args...))); + device->receive(formated); } } } - template - auto send(File::StringViewType content, OptionalArg optional_arg, FmtArgs... fmt_args) -> void + template + auto send(StringView _content, OptionalArg optional_arg, FmtArgs&&... fmt_args) -> void { + auto content = to_system(_content); + auto formated = std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(to_system(std::forward(fmt_args))...)); for (const auto& device : DefaultTargets::get_default_devices_ref()) { ASSERT_DEFAULT_OUTPUT_DEVICE_IS_VALID(device) if (device->has_optional_arg()) { - device->receive_with_optional_arg(std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(fmt_args...)), static_cast(optional_arg)); + device->receive_with_optional_arg(formated, static_cast(optional_arg)); } else { - device->receive(std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(fmt_args...))); + device->receive(formated); } } } - auto RC_DYNOUT_API send(File::StringViewType content) -> void; + auto RC_DYNOUT_API send(SystemStringViewType content) -> void; - template - auto send(File::StringViewType content, OptionalArg optional_arg) -> void + template + auto send(StringView _content, OptionalArg optional_arg) -> void { + auto content = to_system(_content); for (const auto& device : DefaultTargets::get_default_devices_ref()) { ASSERT_DEFAULT_OUTPUT_DEVICE_IS_VALID(device) @@ -334,27 +364,30 @@ namespace RC::Output } } - template - auto send(File::StringViewType content, FmtArgs... fmt_args) -> void + template + auto send(StringView _content, FmtArgs&&... fmt_args) -> void { + auto content = to_system(_content); + auto formated = apply_formatting(content, to_system(std::forward(fmt_args))...); for (const auto& device : DefaultTargets::get_default_devices_ref()) { ASSERT_DEFAULT_OUTPUT_DEVICE_IS_VALID(device) if (device->has_optional_arg()) { - device->receive_with_optional_arg(std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(fmt_args...)), optional_arg); + device->receive_with_optional_arg(formated, optional_arg); } else { - device->receive(std::vformat(content, RC_STD_MAKE_FORMAT_ARGS(fmt_args...))); + device->receive(formated); } } } - template - auto send(File::StringViewType content) -> void + template + auto send(StringView _content) -> void { + auto content = to_system(_content); for (const auto& device : DefaultTargets::get_default_devices_ref()) { ASSERT_DEFAULT_OUTPUT_DEVICE_IS_VALID(device) diff --git a/deps/first/DynamicOutput/include/DynamicOutput/OutputDevice.hpp b/deps/first/DynamicOutput/include/DynamicOutput/OutputDevice.hpp index c7d65d6b0..5c69f46ba 100644 --- a/deps/first/DynamicOutput/include/DynamicOutput/OutputDevice.hpp +++ b/deps/first/DynamicOutput/include/DynamicOutput/OutputDevice.hpp @@ -46,7 +46,7 @@ namespace RC::Output mutable bool m_is_device_ready{}; // Formatter function - using Formatter = File::StringType (*)(File::StringViewType); + using Formatter = SystemStringType (*)(SystemStringViewType); Formatter m_formatter{&default_format_string}; public: @@ -55,10 +55,10 @@ namespace RC::Output public: virtual auto has_optional_arg() const -> bool; - virtual auto receive(File::StringViewType fmt) const -> void = 0; + virtual auto receive(SystemStringViewType fmt) const -> void = 0; // The 'optional_arg' type should be cast to the proper enum by the derived class - virtual auto receive_with_optional_arg(File::StringViewType fmt, int32_t optional_arg = 0) const -> void; + virtual auto receive_with_optional_arg(SystemStringViewType fmt, int32_t optional_arg = 0) const -> void; virtual auto lock() const -> void{}; @@ -68,8 +68,8 @@ namespace RC::Output auto set_formatter(Formatter new_formatter) -> void; protected: - auto static get_now_as_string() -> const File::StringType; - auto static default_format_string(File::StringViewType) -> File::StringType; + auto static get_now_as_string() -> const SystemStringType; + auto static default_format_string(SystemStringViewType) -> SystemStringType; }; } // namespace RC::Output diff --git a/deps/first/DynamicOutput/include/DynamicOutput/TestDevice.hpp b/deps/first/DynamicOutput/include/DynamicOutput/TestDevice.hpp index f8b8b371e..01859086e 100644 --- a/deps/first/DynamicOutput/include/DynamicOutput/TestDevice.hpp +++ b/deps/first/DynamicOutput/include/DynamicOutput/TestDevice.hpp @@ -38,12 +38,12 @@ namespace RC::Output return true; } - auto receive(File::StringViewType fmt) const -> void override + auto receive(SystemStringViewType fmt) const -> void override { receive_with_optional_arg(fmt, 0); } - auto receive_with_optional_arg(File::StringViewType fmt, int32_t optional_arg) const -> void override + auto receive_with_optional_arg(SystemStringViewType fmt, int32_t optional_arg) const -> void override { OptionalArgTest typed_optional_arg = static_cast(optional_arg); switch (typed_optional_arg) @@ -63,9 +63,9 @@ namespace RC::Output } #if ENABLE_OUTPUT_DEVICE_DEBUG_MODE - printf_s("TestDevice received: %S", fmt.c_str()); + printf_s("TestDevice received: " SystemStringPrint, fmt.c_str()); #else - printf_s("%S", fmt.data()); + printf_s(SystemStringPrint, fmt.data()); #endif } }; diff --git a/deps/first/DynamicOutput/src/DebugConsoleDevice.cpp b/deps/first/DynamicOutput/src/DebugConsoleDevice.cpp index 71ef287d6..a915af147 100644 --- a/deps/first/DynamicOutput/src/DebugConsoleDevice.cpp +++ b/deps/first/DynamicOutput/src/DebugConsoleDevice.cpp @@ -57,19 +57,19 @@ namespace RC::Output return true; } - auto DebugConsoleDevice::receive(File::StringViewType fmt) const -> void + auto DebugConsoleDevice::receive(SystemStringViewType fmt) const -> void { receive_with_optional_arg(fmt, Color::NoColor); } - auto DebugConsoleDevice::receive_with_optional_arg(File::StringViewType fmt, [[maybe_unused]] int32_t optional_arg) const -> void + auto DebugConsoleDevice::receive_with_optional_arg(SystemStringViewType fmt, [[maybe_unused]] int32_t optional_arg) const -> void { set_windows_console_out_mode_if_needed(); #if ENABLE_OUTPUT_DEVICE_DEBUG_MODE printf_s("DebugConsoleDevice received: %S", m_formatter(fmt).c_str()); #else - printf_s("%s%S\033[0m", log_level_to_color(static_cast(optional_arg)).c_str(), m_formatter(fmt).c_str()); + printf_s("%s" SystemStringPrint "\033[0m", log_level_to_color(static_cast(optional_arg)).c_str(), m_formatter(fmt).c_str()); #endif } } // namespace RC::Output diff --git a/deps/first/DynamicOutput/src/Output.cpp b/deps/first/DynamicOutput/src/Output.cpp index 1c6d7a73b..d2e2c9732 100644 --- a/deps/first/DynamicOutput/src/Output.cpp +++ b/deps/first/DynamicOutput/src/Output.cpp @@ -28,7 +28,7 @@ namespace RC::Output default_devices.clear(); } - auto send(File::StringViewType content) -> void + auto send(SystemStringViewType content) -> void { for (const auto& device : DefaultTargets::get_default_devices_ref()) { diff --git a/deps/first/DynamicOutput/src/OutputDevice.cpp b/deps/first/DynamicOutput/src/OutputDevice.cpp index 7f20019d3..df93faab6 100644 --- a/deps/first/DynamicOutput/src/OutputDevice.cpp +++ b/deps/first/DynamicOutput/src/OutputDevice.cpp @@ -10,7 +10,7 @@ namespace RC::Output return false; } - auto OutputDevice::receive_with_optional_arg([[maybe_unused]] File::StringViewType fmt, [[maybe_unused]] int32_t optional_arg) const -> void + auto OutputDevice::receive_with_optional_arg([[maybe_unused]] SystemStringViewType fmt, [[maybe_unused]] int32_t optional_arg) const -> void { // This only exists to make it not required to implement // Most devices probably won't use this @@ -22,15 +22,15 @@ namespace RC::Output m_formatter = new_formatter; } - auto OutputDevice::get_now_as_string() -> const File::StringType + auto OutputDevice::get_now_as_string() -> const SystemStringType { auto now = std::chrono::system_clock::now(); - const File::StringType when_as_string = std::format(STR("{:%Y-%m-%d %X}"), now); + const SystemStringType when_as_string = std::format(SYSSTR("{:%Y-%m-%d %X}"), now); return when_as_string; } - auto OutputDevice::default_format_string(File::StringViewType string_to_format) -> File::StringType + auto OutputDevice::default_format_string(SystemStringViewType string_to_format) -> SystemStringType { - return std::format(STR("[{}] {}"), get_now_as_string(), string_to_format); + return std::format(SYSSTR("[{}] {}"), get_now_as_string(), string_to_format); } } // namespace RC::Output diff --git a/deps/first/DynamicOutput/xmake.lua b/deps/first/DynamicOutput/xmake.lua index 52f91b97a..d40c98f0d 100644 --- a/deps/first/DynamicOutput/xmake.lua +++ b/deps/first/DynamicOutput/xmake.lua @@ -11,4 +11,4 @@ target(projectName) add_files("src/**.cpp") - add_deps("File") \ No newline at end of file + add_deps("File", "Helpers") diff --git a/deps/first/File/include/File/FileType/FileBase.hpp b/deps/first/File/include/File/FileType/FileBase.hpp index b648c3695..51332e3a7 100644 --- a/deps/first/File/include/File/FileType/FileBase.hpp +++ b/deps/first/File/include/File/FileType/FileBase.hpp @@ -74,7 +74,8 @@ namespace RC::File // Write a string to the currently opened file // Throws std::runtime_error if an error occurred - virtual auto write_string_to_file(StringViewType) -> void = 0; + // Keep this function use UEStringViewType so it's wstring_view and compatible with old FileInterface + virtual auto write_string_to_file(UEStringViewType) -> void = 0; // Returns whether the currently opened file is the same as another opened file // Throws std::runtime_error if an error occurred @@ -82,7 +83,8 @@ namespace RC::File // Returns the entire contents of the currently opened file as a string // Throws std::runtime_error if an error occurred - virtual auto read_all() const -> StringType = 0; + // Keep this function use UEStringViewType so it's wstring_view and compatible with old FileInterface + virtual auto read_all() const -> UEStringType = 0; virtual auto memory_map() -> std::span = 0; @@ -91,6 +93,16 @@ namespace RC::File // Throws std::runtime_error if an error occurred auto static open_file(const std::filesystem::path& file_name_and_path, const OpenProperties& open_properties) -> InternalFileType; */ + + // Write a string to the currently opened file + // Throws std::runtime_error if an error occurred + // This is the actual function uses StringType. + virtual auto write_file_string_to_file(StringViewType) -> void = 0; + + // Returns the entire contents of the currently opened file as a string + // Throws std::runtime_error if an error occurred + // This is the actual function uses StringType. + virtual auto read_file_all() const -> StringType = 0; }; template diff --git a/deps/first/File/include/File/FileType/WinFile.hpp b/deps/first/File/include/File/FileType/WinFile.hpp index 4c630dcb9..89d075330 100644 --- a/deps/first/File/include/File/FileType/WinFile.hpp +++ b/deps/first/File/include/File/FileType/WinFile.hpp @@ -75,11 +75,13 @@ namespace RC::File RC_FILE_API auto serialize_item(const GenericItemData& data, bool is_internal_item = false) -> void override; RC_FILE_API auto get_serialized_item(size_t data_size, bool is_internal_item = false) -> void* override; RC_FILE_API auto close_current_file() -> void override; - RC_FILE_API auto write_string_to_file(StringViewType string_to_write) -> void override; + RC_FILE_API auto write_string_to_file(UEStringViewType string_to_write) -> void override; + RC_FILE_API auto write_file_string_to_file(StringViewType string_to_write) -> void override; RC_FILE_API auto is_same_as(WinFile& other_file) -> bool override; - [[nodiscard]] RC_FILE_API auto read_all() const -> StringType override; + [[nodiscard]] RC_FILE_API auto read_all() const -> UEStringType override; [[nodiscard]] RC_FILE_API auto memory_map() -> std::span override; [[nodiscard]] RC_FILE_API auto static open_file(const std::filesystem::path& file_name_and_path, const OpenProperties& open_properties) -> WinFile; + [[nodiscard]] RC_FILE_API auto read_file_all() const -> StringType override; // File Interface -> END }; diff --git a/deps/first/File/include/File/HandleTemplate.hpp b/deps/first/File/include/File/HandleTemplate.hpp index 9cebc64a5..388a92194 100644 --- a/deps/first/File/include/File/HandleTemplate.hpp +++ b/deps/first/File/include/File/HandleTemplate.hpp @@ -159,16 +159,26 @@ namespace RC::File return *data; } - auto write_string_to_file(StringViewType string_to_write) -> void + auto write_string_to_file(UEStringViewType string_to_write) -> void { m_internal_handle.write_string_to_file(string_to_write); } - [[nodiscard]] auto read_all() const -> StringType + auto write_file_string_to_file(StringViewType string_to_write) -> void + { + m_internal_handle.write_file_string_to_file(string_to_write); + } + + [[nodiscard]] auto read_all() const -> UEStringType { return m_internal_handle.read_all(); } + [[nodiscard]] auto read_file_all() const -> StringType + { + return m_internal_handle.read_file_all(); + } + [[nodiscard]] auto memory_map() -> std::span { return m_internal_handle.memory_map(); diff --git a/deps/first/File/include/File/Macros.hpp b/deps/first/File/include/File/Macros.hpp index fb27b48a3..c8db3fd0c 100644 --- a/deps/first/File/include/File/Macros.hpp +++ b/deps/first/File/include/File/Macros.hpp @@ -1,14 +1,33 @@ #pragma once +#include +#include +#include + // Set this to 1 to use ANSI (char*) instead of wide strings (wchar_t*) #ifndef RC_IS_ANSI #define RC_IS_ANSI 0 #endif -#if RC_IS_ANSI == 1 +#ifdef LINUX +#define SYSSTR(str) str +#define IOSTR(str) str #define STR(str) u##str #else +#if RC_IS_ANSI == 0 +#define SYSSTR(str) L##str +#define IOSTR(str) str #define STR(str) L##str +#else +#define SYSSTR(str) str +#define IOSTR(str) str +#endif +#endif + +#ifdef S +static_assert(false, "UE4SS define 'S' is already defined, please solve this"); +#else +// #define S(str) STR(str) #endif #define THROW_INTERNAL_FILE_ERROR(msg) \ @@ -28,34 +47,93 @@ construct a Targets object and supply your own devices.") \ namespace RC::File { -#if RC_IS_ANSI == 1 using StringType = std::string; using StringViewType = std::string_view; using CharType = char; using StreamType = std::ifstream; - using ToString = std::tostring; + using IStreamType = std::ifstream; + using OStreamType = std::ofstream; + /* + #if RC_IS_ANSI == 1 + using StringType = std::string; + using StringViewType = std::string_view; + using CharType = char; + using StreamType = std::ifstream; + #else + // System String Types + #ifdef WIN32 + using StringType = std::wstring; + using StringViewType = std::wstring_view; + using CharType = std::wstring::value_type; + using StreamType = std::wifstream; + #else + // on linux, use utf8 + using StringType = std::string; + using StringViewType = std::string_view; + using CharType = char; + using StreamType = std::ifstream; + #endif // WIN32 + #endif // RC_IS_ANSI + */ +} // namespace RC::File +namespace RC +{ + // Should find a better place for these definitions + // System = C++ String Types +#if RC_IS_ANSI == 1 + using SystemStringType = std::string; + using SystemStringViewType = std::string_view; + using SystemCharType = char; + using SystemStreamType = std::ifstream; constexpr auto ToString = [](auto&& numeric_value) constexpr -> decltype(auto) { return std::to_string(std::forward(numeric_value)); }; +#define SystemStringPrint "%s" #else - using StringType = std::wstring; - using StringViewType = std::wstring_view; - using CharType = wchar_t; - using StreamType = std::wifstream; - +// System String Types +#ifdef WIN32 + using SystemStringType = std::wstring; + using SystemStringViewType = std::wstring_view; + using SystemCharType = std::wstring::value_type; + using SystemStreamType = std::wifstream; constexpr auto ToString = [](auto&& numeric_value) constexpr -> decltype(auto) { return std::to_wstring(std::forward(numeric_value)); }; +#define SystemStringPrint "%S" +#else + // on linux, use utf8 + using SystemStringType = std::string; + using SystemStringViewType = std::string_view; + using SystemCharType = char; + using SystemStreamType = std::ifstream; + constexpr auto ToString = [](auto&& numeric_value) constexpr -> decltype(auto) { + return std::to_string(std::forward(numeric_value)); + }; +#define SystemStringPrint "%s" +#endif // WIN32 #endif -} // namespace RC::File -namespace RC -{ - using StringType = File::StringType; - using StringViewType = File::StringViewType; - using CharType = File::CharType; - using StreamType = File::StreamType; +#if RC_IS_ANSI == 1 + using UEStringType = std::string; + using UEStringViewType = std::string_view; + using UECharType = std::string::value_type; +#define UEStringPrint "%s" +#else +#ifdef WIN32 + using UEStringType = std::wstring; + using UEStringViewType = std::wstring_view; + using UECharType = std::wstring::value_type; + using UEIStreamType = std::wifstream; + using UEOStreamType = std::wofstream; +#else + using UEStringType = std::u16string; + using UEStringViewType = std::u16string_view; + using UECharType = std::u16string::value_type; + using UEIStreamType = std::basic_ifstream; + using UEOStreamType = std::basic_ofstream; +#endif // WIN32 +#define UEStringPrint "%S" +#endif // RC_IS_ANSI - constexpr auto ToString = File::ToString; } // namespace RC diff --git a/deps/first/File/src/File.cpp b/deps/first/File/src/File.cpp index 6869475cb..678aa7c21 100644 --- a/deps/first/File/src/File.cpp +++ b/deps/first/File/src/File.cpp @@ -1,4 +1,7 @@ #include +#include + +#include namespace RC::File { diff --git a/deps/first/File/src/FileType/WinFile.cpp b/deps/first/File/src/FileType/WinFile.cpp index 0cbfd2f84..c1f247fa8 100644 --- a/deps/first/File/src/FileType/WinFile.cpp +++ b/deps/first/File/src/FileType/WinFile.cpp @@ -26,7 +26,7 @@ namespace RC::File auto WinFile::delete_file(const std::filesystem::path& file_path_and_name) -> void { - if constexpr (sizeof(CharType) > 1) + if constexpr (sizeof(SystemCharType) > 1) { if (DeleteFileW(file_path_and_name.wstring().c_str()) == 0) { @@ -35,7 +35,7 @@ namespace RC::File } else { - if (DeleteFileA(file_path_and_name.string().c_str()) != 0) + if (DeleteFileA(file_path_and_name.string().c_str()) == 0) { THROW_INTERNAL_FILE_ERROR(std::format("[WinFile::delete_file] Was unable to delete file, error: {}", GetLastError())) } @@ -380,7 +380,7 @@ namespace RC::File return m_is_file_open; } - auto WinFile::write_string_to_file(StringViewType string_to_write) -> void + auto WinFile::write_string_to_file(UEStringViewType string_to_write) -> void { int string_size = WideCharToMultiByte(CP_UTF8, 0, string_to_write.data(), static_cast(string_to_write.size()), NULL, 0, NULL, NULL); if (string_size == 0) @@ -399,6 +399,11 @@ namespace RC::File write_to_file(*this, string_converted_to_utf8.c_str(), string_size); } + auto WinFile::write_file_string_to_file(StringViewType string_to_write) -> void + { + write_to_file(*this, string_to_write.data(), string_to_write.length()); + } + auto WinFile::is_same_as(WinFile& other_file) -> bool { BY_HANDLE_FILE_INFORMATION file_info{}; @@ -452,38 +457,85 @@ namespace RC::File return true; } - auto WinFile::read_all() const -> StringType + auto WinFile::read_all() const -> UEStringType { - StreamType stream{get_file_path(), std::ios::in | std::ios::binary}; - if (!stream) + auto file_contents = read_file_all(); + int string_size = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)file_contents.c_str(), static_cast(file_contents.size()), NULL, 0); + if (string_size == 0) { - THROW_INTERNAL_FILE_ERROR(std::format("[WinFile::read_all] Tried to read entire file but returned error {}", errno)) + THROW_INTERNAL_FILE_ERROR(std::format("[WinFile::read_all] Tried reading entire file but could not convert to utf-16. Error: {}", GetLastError())) } - else + + UEStringType string_converted_to_utf16(string_size, 0); + if (MultiByteToWideChar(CP_UTF8, 0, (LPCCH)file_contents.c_str(), static_cast(file_contents.size()), &string_converted_to_utf16[0], string_size) == 0) + { + THROW_INTERNAL_FILE_ERROR(std::format("[WinFile::read_all] Tried reading entire file but could not convert to utf-16. Error: {}", GetLastError())) + } + + return string_converted_to_utf16; + } + + auto WinFile::read_file_all() const -> StringType + { + // get file handle, const_cast is safe here because we will restore the file pointer + auto handle = const_cast(this)->get_file(); + + // backup file pointer + auto file_pointer = SetFilePointer(handle, 0, nullptr, FILE_CURRENT); + + LONG file_size{}; + if (!GetFileSizeEx(handle, (PLARGE_INTEGER)&file_size)) { - // Strip the BOM if it exists - File::StreamType::off_type start{}; - File::CharType bom[3]{}; - stream.read(bom, 3); - if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) + THROW_INTERNAL_FILE_ERROR(std::format("[WinFile::read_file_all] Tried reading entire file but could not get file size. Error: {}", GetLastError())) + } + + // move pointer to begin + SetFilePointer(handle, 0, nullptr, FILE_BEGIN); + + if (file_size >= 3ul) + { + // check BOM + constexpr size_t bom_size = 3; + char bom[bom_size]; + DWORD bytes_read{}; + + if (!ReadFile(handle, bom, bom_size, &bytes_read, nullptr)) { - // BOM: UTF-8 - start = 3; + // try restoring file pointer + SetFilePointer(handle, file_pointer, nullptr, FILE_BEGIN); + THROW_INTERNAL_FILE_ERROR(std::format("[WinFile::read_file_all] Tried reading entire file but could not read BOM. Error: {}", GetLastError())) } - - StringType file_contents; - stream.seekg(0, std::ios::end); - auto size = stream.tellg(); - if (size == -1) + if (bytes_read != bom_size) + { + // try restoring file pointer + SetFilePointer(handle, file_pointer, nullptr, FILE_BEGIN); + THROW_INTERNAL_FILE_ERROR(std::format("[WinFile::read_file_all] Tried reading entire file but could not read BOM. Error: {}", GetLastError())) + } + if (bom[0] == '\xEF' && bom[1] == '\xBB' && bom[2] == '\xBF') { - return {}; + file_size -= 3; + } + else + { + // roll back + SetFilePointer(handle, 0, nullptr, FILE_BEGIN); } - file_contents.resize(size); - stream.seekg(start, std::ios::beg); - stream.read(&file_contents[0], file_contents.size()); - stream.close(); - return file_contents; } + + StringType file_contents(file_size, 0); + DWORD bytes_read{}; + if (!ReadFile(handle, &file_contents[0], file_size, &bytes_read, nullptr)) + { + // try restoring file pointer + SetFilePointer(handle, file_pointer, nullptr, FILE_BEGIN); + THROW_INTERNAL_FILE_ERROR(std::format("[WinFile::read_file_all] Tried reading entire file but could not read file contents. Error: {}", GetLastError())) + } + + file_contents[bytes_read] = 0; + + // restore file pointer + SetFilePointer(handle, file_pointer, nullptr, FILE_BEGIN); + return file_contents; } auto WinFile::memory_map() -> std::span @@ -572,7 +624,7 @@ namespace RC::File WinFile file{}; // This very badly named API may create a new file or it may not but it will always open a file (unless there's an error) - if constexpr (sizeof(CharType) > 1) + if constexpr (sizeof(SystemCharType) > 1) { file.set_file(CreateFileW(file_name_and_path.wstring().c_str(), desired_access, diff --git a/deps/first/File/xmake.lua b/deps/first/File/xmake.lua index 4d8b77072..b195e50f5 100644 --- a/deps/first/File/xmake.lua +++ b/deps/first/File/xmake.lua @@ -9,4 +9,9 @@ target(projectName) add_includedirs("include", { public = true }) add_headerfiles("include/**.hpp") - add_files("src/**.cpp") \ No newline at end of file + add_files("src/File.cpp") + + if is_plat("windows") then + add_files("src/FileType/WinFile.cpp") + end + add_deps("Helpers") diff --git a/deps/first/Helpers/include/Helpers/Format.hpp b/deps/first/Helpers/include/Helpers/Format.hpp index 329f91292..49b2858c0 100644 --- a/deps/first/Helpers/include/Helpers/Format.hpp +++ b/deps/first/Helpers/include/Helpers/Format.hpp @@ -1,56 +1,22 @@ #pragma once #include +#include + +#include +#include namespace RC { - template - auto static fmt(const char* fmt, Args... args) -> std::string + template + auto static fmt(const std::string_view&& fmt, FmtArgs&&... fmt_args) -> std::string { - constexpr size_t out_string_length = 1000; - char out_string[out_string_length]; - - size_t msg_len = strlen(fmt); - - // Attempt to give a hint if the buffer is too small - if (msg_len > out_string_length) - { - fmt = "An error occurred but the message was too long for the buffer."; - msg_len = strlen(fmt); - } - - // If the buffer is too small for the hint message then I guess we do nothing - // The default message will be used which can't be too small since it's calculated at compile-time - if (msg_len < out_string_length) - { - sprintf_s(out_string, out_string_length, fmt, args...); - } - - return out_string; + return Output::apply_formatting(fmt, to_stdstr(std::forward(fmt_args))...); } - template - auto static fmt(const wchar_t* fmt, Args... args) -> std::wstring + template + auto static fmtfile(const File::StringViewType&& fmt, FmtArgs&&... fmt_args) -> std::string { - constexpr size_t out_string_length = 1000; - wchar_t out_string[out_string_length]; - - size_t msg_len = wcslen(fmt); - - // Attempt to give a hint if the buffer is too small - if (msg_len > out_string_length) - { - fmt = L"An error occurred but the message was too long for the buffer."; - msg_len = wcslen(fmt); - } - - // If the buffer is too small for the hint message then I guess we do nothing - // The default message will be used which can't be too small since it's calculated at compile-time - if (msg_len < out_string_length) - { - swprintf_s(out_string, out_string_length, fmt, args...); - } - - return out_string; + return Output::apply_formatting(fmt, to_file(std::forward(fmt_args))...); } -} // namespace RC +} // namespace RC \ No newline at end of file diff --git a/deps/first/Helpers/include/Helpers/String.hpp b/deps/first/Helpers/include/Helpers/String.hpp index e8f964060..32cc44532 100644 --- a/deps/first/Helpers/include/Helpers/String.hpp +++ b/deps/first/Helpers/include/Helpers/String.hpp @@ -7,6 +7,10 @@ #include #include #include +#include +#include +#include +#include #include @@ -44,6 +48,23 @@ namespace RC return return_value; } + auto inline explode_by_occurrence(const std::u16string& in_str_wide, const char16_t delimiter, ExplodeType start_or_end) -> std::u16string + { + size_t occurrence = (start_or_end == ExplodeType::FromStart ? in_str_wide.find_first_of(delimiter) : in_str_wide.find_last_of(delimiter)); + + std::u16string return_value; + if (occurrence != std::wstring::npos) + { + return_value = start_or_end == ExplodeType::FromEnd ? in_str_wide.substr(occurrence + 1, std::u16string::npos) : in_str_wide.substr(0, occurrence); + } + else + { + return_value = in_str_wide; + } + + return return_value; + } + auto inline explode_by_occurrence(const std::string& in_str, const char delimiter, ExplodeType start_or_end) -> std::string { size_t occurrence = (start_or_end == ExplodeType::FromStart ? in_str.find_first_of(delimiter) : in_str.find_last_of(delimiter)); @@ -131,6 +152,33 @@ namespace RC return result; } + auto inline explode_by_occurrence(const std::u16string& in_str_wide, const char16_t delimiter) -> std::vector + { + std::vector result; + + size_t counter{}; + size_t start_offset{}; + + for (const char16_t* current_char = in_str_wide.c_str(); *current_char; ++current_char) + { + if (*current_char == delimiter || counter == in_str_wide.length() - 1) + { + std::u16string sub_str = in_str_wide.substr(start_offset, counter - start_offset + (counter == in_str_wide.length() - 1 ? 1 : 0)); + if (start_offset > 0) + { + sub_str.erase(0, 1); + } + result.emplace_back(sub_str); + + start_offset = counter; + } + + ++counter; + } + + return result; + } + auto inline explode_by_occurrence(const std::wstring& in_str, const wchar_t delimiter, const int32_t occurrence) -> std::wstring { size_t found_occurrence{}; @@ -148,12 +196,97 @@ namespace RC } /* explode_by_occurrence -> END */ - auto inline to_wstring(std::string& input) -> std::wstring + auto inline explode_by_occurrence(const std::u16string& in_str, const char16_t delimiter, const int32_t occurrence) -> std::u16string + { + size_t found_occurrence{}; + for (int64_t i = 0; i < std::count(in_str.begin(), in_str.end(), delimiter); i++) + { + found_occurrence = in_str.find(delimiter, found_occurrence + 1); + if (i + 1 == occurrence) + { + return in_str.substr(0, found_occurrence); + } + } + + // No occurrence was found, returning empty string for now + return {}; + } +/* explode_by_occurrence -> END */ + +// ----------------------------- // +#define STRING_DISPATCH_NOERR(STRING_T, ts, tw, tu16) \ + if constexpr (std::is_same_v) \ + { \ + return ts(std::forward(input)); \ + } \ + else if constexpr (std::is_same_v) \ + { \ + return tw(std::forward(input)); \ + } \ + else if constexpr (std::is_same_v) \ + { \ + return tu16(std::forward(input)); \ + } + +#define STRING_DISPATCH_ERROR(STRING_T) \ + else \ + { \ + static_assert(dependent_false::value, "Unsupported " #STRING_T "."); \ + } + +#define STRING_DISPATCH(STRING_T, ts, tw, tu16) \ + STRING_DISPATCH_NOERR(STRING_T, ts, tw, tu16) \ + STRING_DISPATCH_ERROR(STRING_T) + +// ----------------------------- // +#define PATH_QUIRK(STRINGT) \ + if constexpr (std::is_same_v, std::filesystem::path> || std::is_same_v, const std::filesystem::path>) \ + { \ + STRING_DISPATCH(STRINGT, to_string_path, to_wstring_path, to_u16string_path); \ + } + // ----------------------------- // + +#define TO_STRING_QUIRK_DISPATCH(STRINGT) \ + PATH_QUIRK(STRINGT) \ + else \ + { \ + STRING_DISPATCH(STRINGT, to_string, to_wstring, to_u16string); \ + } + // ----------------------------- // + + auto inline to_string_path(const std::filesystem::path& input) -> std::string + { + return input.string(); + } + + auto inline to_wstring_path(const std::filesystem::path& input) -> std::wstring + { + return input.wstring(); + } + + auto inline to_u16string_path(const std::filesystem::path& input) -> std::u16string + { + return input.u16string(); + } + + auto inline to_wstring(std::string_view input) -> std::wstring { +#if WIN32 #pragma warning(disable : 4996) static std::wstring_convert> converter{}; - return converter.from_bytes(input); + return converter.from_bytes(input.data(), input.data() + input.length()); #pragma warning(default : 4996) +#else +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + static std::wstring_convert> converter{}; + return converter.from_bytes(input.data(), input.data() + input.length()); +#endif +#if __clang__ +#pragma clang diagnostic pop +#endif } auto inline to_const_wstring(std::string_view input) -> const std::wstring& @@ -178,80 +311,424 @@ namespace RC } } - auto inline to_wstring(std::string_view input) -> std::wstring + auto inline to_wstring(std::wstring_view input) -> std::wstring { - auto temp_input = std::string{input}; - return to_wstring(temp_input); + return std::wstring{input}; + } + + auto inline to_wstring(std::wstring& input) -> std::wstring + { + return std::wstring{input}; } auto inline to_wstring(std::u16string& input) -> std::wstring { +#ifdef WIN32 return {input.begin(), input.end()}; +#else + throw std::runtime_error{"There is no reason to use this function on non-Windows platforms"}; +#endif } auto inline to_wstring(std::u16string_view input) -> std::wstring { - auto temp_input = std::u16string{input}; - return to_wstring(temp_input); +#ifdef WIN32 + return {input.begin(), input.end()}; +#else + throw std::runtime_error{"There is no reason to use this function on non-Windows platforms"}; +#endif } - auto inline to_string(std::wstring& input) -> std::string + /* + auto inline to_string(std::u16string& input) -> std::string { #pragma warning(disable : 4996) - static std::wstring_convert> converter{}; + static std::wstring_convert, char16_t> converter{}; return converter.to_bytes(input); #pragma warning(default : 4996) } + */ auto inline to_string(std::wstring_view input) -> std::string { - auto temp_input = std::wstring{input}; - return to_string(temp_input); +#ifdef WIN32 +#pragma warning(disable : 4996) + static std::wstring_convert> converter{}; + return converter.to_bytes(input.data(), input.data() + input.length()); +#pragma warning(default : 4996) +#else +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + static std::wstring_convert> converter{}; + return converter.to_bytes(input.data(), input.data() + input.length()); +#if __clang__ +#pragma clang diagnostic pop +#endif +#endif + } + + auto inline to_string(std::u16string_view input) -> std::string + { +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif +#pragma warning(disable : 4996) + static std::wstring_convert, char16_t> converter{}; + return converter.to_bytes(input.data(), input.data() + input.length()); +#pragma warning(default : 4996) +#if __clang__ +#pragma clang diagnostic pop +#endif + } + + auto inline to_string(std::string_view input) -> std::string + { + return std::string{input}; + } + + auto inline to_string(std::string& input) -> std::string + { + return std::string{input}; } auto inline to_u16string(std::wstring& input) -> std::u16string { +#ifdef WIN32 return {input.begin(), input.end()}; +#else + throw std::runtime_error{"There is no reason to use this function on non-Windows platforms"}; +#endif } auto inline to_u16string(std::wstring_view input) -> std::u16string { - auto temp_input = std::wstring{input}; - return to_u16string(temp_input); + return to_u16string(std::wstring(input)); } + /* auto inline to_u16string(std::string& input) -> std::u16string { - return {input.begin(), input.end()}; + // codecvt_utf8_utf16 + #pragma warning(disable : 4996) + static std::wstring_convert, char16_t> converter {}; + return converter.from_bytes(input); + #pragma warning(default : 4996) } + */ auto inline to_u16string(std::string_view input) -> std::u16string { + /* auto temp_input = std::string{input}; - return to_u16string(temp_input); + return to_u16string(temp_input);*/ + // codecvt_utf8_utf16 +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif +#pragma warning(disable : 4996) + static std::wstring_convert, char16_t> converter{}; + return converter.from_bytes(input.data(), input.data() + input.length()); +#pragma warning(default : 4996) +#if __clang__ +#pragma clang diagnostic pop +#endif + } + + auto inline to_u16string(std::u16string_view input) -> std::u16string + { + return std::u16string{input}; + } + + auto inline to_u16string(std::u16string& input) -> std::u16string + { + return std::u16string{input}; + } + + // Type traits to check if T is a string type that needs conversion + template + struct is_string_like_t : std::false_type + { + }; + + // Specializations for the types that need conversion + template <> + struct is_string_like_t : std::true_type + { + }; + template <> + struct is_string_like_t : std::true_type + { + }; + template <> + struct is_string_like_t : std::true_type + { + }; + template <> + struct is_string_like_t : std::true_type + { + }; + template <> + struct is_string_like_t : std::true_type + { + }; + template <> + struct is_string_like_t : std::true_type + { + }; + + template + struct dependent_false : std::false_type + { + }; + + template + struct dependent_ensure : std::true_type + { + }; + template + struct dependent_ensure : std::false_type + { + }; + + template + auto stringviewify(T&& tp) + { + if constexpr (std::is_same_v, char*> || std::is_same_v, const char*>) + { + return std::string_view{tp}; + } + else if constexpr (std::is_same_v, wchar_t*> || std::is_same_v, const wchar_t*>) + { + return std::wstring_view{tp}; + } + else if constexpr (std::is_same_v, char16_t*> || std::is_same_v, const char16_t*>) + { + return std::u16string_view{tp}; + } + else + { + return std::forward(tp); + } + } + + template + struct _can_be_string_view_t : std::false_type + { + }; + template <> + struct _can_be_string_view_t : std::true_type + { + }; + template <> + struct _can_be_string_view_t : std::true_type + { + }; + template <> + struct _can_be_string_view_t : std::true_type + { + }; + template <> + struct _can_be_string_view_t : std::true_type + { + }; + template <> + struct _can_be_string_view_t : std::true_type + { + }; + template <> + struct _can_be_string_view_t : std::true_type + { + }; + + template + struct can_be_string_view_t : _can_be_string_view_t> + { + }; + + template + struct is_file_string_type : std::disjunction, std::is_same> + { + }; + + template + struct not_file_string_like_t : std::conjunction>, std::negation>>> + { + }; + + template + auto inline to_file_string(T&& input) -> File::StringType + { + TO_STRING_QUIRK_DISPATCH(File::StringType); } - auto inline to_generic_string(const auto& input) -> StringType + template + auto to_file(T&& arg) { - if constexpr (std::is_same_v>>, StringViewType>) + if constexpr (std::is_same_v, std::filesystem::path> || std::is_same_v, const std::filesystem::path>) + { + return to_file_string(std::forward(arg)); + } + else if constexpr (can_be_string_view_t::value) { - return StringType{input}; + return to_file(stringviewify(std::forward(arg))); } - else if constexpr (std::is_same_v>>, StringType> || - std::is_same_v>>, CharType>) + else if constexpr (not_file_string_like_t>::value) { - return input; + return to_file_string(std::forward(arg)); } else { -#if RC_IS_ANSI == 1 - return to_string(input); -#else - return to_wstring(input); -#endif + return std::forward(arg); + } + } + + template + struct is_std_string_type : std::disjunction, std::is_same> + { + }; + + template + struct not_std_string_like_t : std::conjunction>, std::negation>>> + { + }; + + template + auto inline to_std_string(T&& input) -> std::string + { + return to_string(std::forward(input)); + } + + template + auto to_stdstr(T&& arg) + { + if constexpr (std::is_same_v, std::filesystem::path> || std::is_same_v, const std::filesystem::path>) + { + return to_std_string(std::forward(arg)); + } + else if constexpr (can_be_string_view_t::value) + { + return to_stdstr(stringviewify(std::forward(arg))); + } + else if constexpr (not_std_string_like_t>::value) + { + return to_std_string(std::forward(arg)); + } + else + { + return std::forward(arg); } } + template + struct is_system_string_type : std::disjunction, std::is_same> + { + }; + + template + struct not_system_string_like_t : std::conjunction>, std::negation>>> + { + }; + + template + auto inline to_system_string(T&& input) -> SystemStringType + { + TO_STRING_QUIRK_DISPATCH(SystemStringType); + } + + template + auto to_system(T&& arg) + { + if constexpr (std::is_same_v, std::filesystem::path> || std::is_same_v, const std::filesystem::path>) + { + return to_system_string(std::forward(arg)); + } + else if constexpr (can_be_string_view_t::value) + { + return to_system(stringviewify(std::forward(arg))); + } + else if constexpr (not_system_string_like_t>::value) + { + return to_system_string(std::forward(arg)); + } + else + { + return std::forward(arg); + } + } + + template + struct is_ue_string_type : std::disjunction, std::is_same> + { + }; + + template + struct not_ue_string_like_t : std::conjunction>, std::negation>>> + { + }; + + template + auto inline to_ue_string(T&& input) -> UEStringType + { + TO_STRING_QUIRK_DISPATCH(UEStringType); + } + + template + auto to_ue(T&& arg) + { + if constexpr (std::is_same_v, std::filesystem::path> || std::is_same_v, const std::filesystem::path>) + { + return to_ue_string(std::forward(arg)); + } + else if constexpr (can_be_string_view_t::value) + { + return to_ue(stringviewify(std::forward(arg))); + } + else if constexpr (not_ue_string_like_t>::value) + { + return to_ue_string(std::forward(arg)); + } + else + { + return std::forward(arg); + } + } + + template + struct is_lua_string_type : std::disjunction, std::is_same> + { + }; + + template + struct not_lua_string_like_t : std::negation>> + { + }; + + template + auto to_lua(T&& arg) + { + if constexpr (can_be_string_view_t::value || not_lua_string_like_t>::value) + { + return to_string(std::forward(arg)); + } + else + { + return std::forward(arg); + } + } + + // TODO: add an option to allow compile failure if to_XXXX failed. + // e.g., to_ue -> must be able to convert to uestring, not passthrough. + +#define csfor_lua(x) (to_lua((x)).c_str()) + +#undef TO_STRING_QUIRK_DISPATCH +#undef PATH_QUIRK +#undef STRING_DISPATCH + namespace String { auto inline iequal(std::wstring_view a, std::wstring_view b) @@ -261,16 +738,33 @@ namespace RC }); } + auto inline iequal(std::u16string_view a, std::u16string_view b) + { + return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin(), [](const char16_t a_char, const char16_t b_char) { + return std::towlower(a_char) == std::towlower(b_char); + }); + } + auto inline iequal(std::wstring& a, const wchar_t* b) { return iequal(a, std::wstring_view{b}); } + auto inline iequal(std::u16string& a, const char16_t* b) + { + return iequal(a, std::u16string_view{b}); + } + auto inline iequal(const wchar_t* a, std::wstring& b) { return iequal(std::wstring_view{a}, b); } + auto inline iequal(const char16_t* a, std::u16string& b) + { + return iequal(std::u16string_view{a}, b); + } + auto inline iequal(std::string_view a, std::string_view b) { return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin(), [](const char a_char, const char b_char) { diff --git a/deps/first/IniParser/include/IniParser/Experimental.hpp b/deps/first/IniParser/include/IniParser/Experimental.hpp index 38c8039eb..370640b7c 100644 --- a/deps/first/IniParser/include/IniParser/Experimental.hpp +++ b/deps/first/IniParser/include/IniParser/Experimental.hpp @@ -4,6 +4,8 @@ #include #include +#include + namespace RC::Parser::Experimental { enum TokenType : int @@ -24,47 +26,47 @@ namespace RC::Parser::Experimental class RuleOne : public Parser::TokenRule { public: - [[nodiscard]] auto to_string() const -> std::wstring override + [[nodiscard]] auto to_string() const -> SystemCharType override { - return L"RuleOne"; + return SYSSTR("RuleOne"); } }; class TokenMustEndWithOppositeToken : public Parser::TokenRule { public: - TokenMustEndWithOppositeToken() : TokenRule(L"TokenMustEndWithOppositeToken") + TokenMustEndWithOppositeToken() : TokenRule(SYSSTR("TokenMustEndWithOppositeToken")) { } - auto exec(const Parser::Token& token, const wchar_t* start_of_token, size_t current_cursor_location, Tokenizer& tokenizer) -> int override + auto exec(const Parser::Token& token, const SystemCharType* start_of_token, size_t current_cursor_location, Tokenizer& tokenizer) -> int override { - printf_s("TokenMustEndWithOppositeToken::exec [%S]\n", token.to_string().c_str()); + printf_s("TokenMustEndWithOppositeToken::exec [" SystemStringPrint "]\n", token.to_string().c_str()); return 0; } - [[nodiscard]] auto to_string() const -> std::wstring override + [[nodiscard]] auto to_string() const -> SystemStringType override { - return L"TokenMustEndWithOppositeToken"; + return SYSSTR("TokenMustEndWithOppositeToken"); } }; class TokenMustHaveCharsBeforeEnd : public Parser::TokenRule { public: - TokenMustHaveCharsBeforeEnd() : TokenRule(L"TokenMustHaveCharsBeforeEnd") + TokenMustHaveCharsBeforeEnd() : TokenRule(SYSSTR("TokenMustHaveCharsBeforeEnd")) { } - auto exec(const Parser::Token& token, const wchar_t* start_of_token, size_t current_cursor_location, Tokenizer& tokenizer) -> int override + auto exec(const Parser::Token& token, const SystemCharType* start_of_token, size_t current_cursor_location, Tokenizer& tokenizer) -> int override { - printf_s("TokenMustHaveCharsBeforeEnd::exec [%S]\n", token.to_string().c_str()); + printf_s("TokenMustHaveCharsBeforeEnd::exec [" SystemStringPrint "]\n", token.to_string().c_str()); return 0; } - [[nodiscard]] auto to_string() const -> std::wstring override + [[nodiscard]] auto to_string() const -> SystemStringType override { - return L"TokenMustHaveCharsBeforeEnd"; + return SYSSTR("TokenMustHaveCharsBeforeEnd"); } }; @@ -76,35 +78,35 @@ namespace RC::Parser::Experimental // Always use "ref->value" instead of "value" // That way it returns properly if this value is a refernece to another variable // The "ref->value" member is set to self if it doesn't refer to another variable - std::wstring value{}; + SystemStringType value{}; const Value* ref{}; }; struct Section { - std::unordered_map key_value_pairs{}; + std::unordered_map key_value_pairs{}; }; private: - using SectionContainer = std::unordered_map; + using SectionContainer = std::unordered_map; SectionContainer& m_output; Section* m_current_section{}; Value* m_variable_to_assign_to{}; - std::wstring m_temporary{}; + SystemStringType m_temporary{}; public: - ExperimentalTokenParser(const Parser::Tokenizer& tokenizer, std::wstring input, std::unordered_map& output) + ExperimentalTokenParser(const Parser::Tokenizer& tokenizer, SystemStringType input, std::unordered_map& output) : TokenParser(tokenizer, input), m_output(output) { } public: - auto static find_variable_by_name(Section* section, const std::wstring& name) -> std::optional>; - auto static find_variable_by_name(SectionContainer& sections, const std::wstring& name) -> std::optional>; + auto static find_variable_by_name(Section* section, const SystemStringType& name) -> std::optional>; + auto static find_variable_by_name(SectionContainer& sections, const SystemStringType& name) -> std::optional>; private: - auto find_variable_by_name(const std::wstring& name) -> std::optional>; + auto find_variable_by_name(const SystemStringType& name) -> std::optional>; auto try_set_section_value(Value& pair_value, const Parser::Token& token, bool is_space_valid = true) -> void; auto handle_operator_equals(const Parser::Token& token) -> void; auto handle_operator_plus(const Parser::Token& token) -> void; @@ -120,16 +122,16 @@ namespace RC::Parser::Experimental class ExperimentalParser { private: - std::unordered_map m_sections; + std::unordered_map m_sections; public: - ExperimentalParser(const std::wstring& input); + ExperimentalParser(const SystemStringType& input); private: auto create_available_tokens_for_tokenizer() -> Parser::TokenContainer; public: - auto get_string(const std::wstring& section, const std::wstring& key, const std::wstring& default_value) -> std::wstring; + auto get_string(const SystemStringType& section, const SystemStringType& key, const SystemStringType& default_value) -> SystemStringType; }; auto test() -> void; diff --git a/deps/first/IniParser/include/IniParser/Ini.hpp b/deps/first/IniParser/include/IniParser/Ini.hpp index fd9034aea..acfafbeae 100644 --- a/deps/first/IniParser/include/IniParser/Ini.hpp +++ b/deps/first/IniParser/include/IniParser/Ini.hpp @@ -23,32 +23,32 @@ namespace RC::Ini }; private: - std::unordered_map m_sections; + std::unordered_map m_sections; bool m_parsing_is_complete{false}; public: Parser() = default; private: - RC_INI_PARSER_API auto parse_internal(File::StringType& input) -> void; + RC_INI_PARSER_API auto parse_internal(SystemStringType& input) -> void; RC_INI_PARSER_API auto create_available_tokens_for_tokenizer() -> ParserBase::TokenContainer; - RC_INI_PARSER_API auto get_value(const File::StringType& section, const File::StringType& key, CanThrow = CanThrow::Yes) const + RC_INI_PARSER_API auto get_value(const SystemStringType& section, const SystemStringType& key, CanThrow = CanThrow::Yes) const -> std::optional>; public: - RC_INI_PARSER_API auto parse(File::StringType& input) -> void; + RC_INI_PARSER_API auto parse(SystemStringType& input) -> void; RC_INI_PARSER_API auto parse(const File::Handle&) -> void; - RC_INI_PARSER_API auto get_list(const File::StringType& section) -> List; - RC_INI_PARSER_API auto get_ordered_list(const File::StringType& section) -> List; - RC_INI_PARSER_API auto get_string(const File::StringType& section, const File::StringType& key, const File::StringType& default_value) const noexcept - -> const File::StringType&; - RC_INI_PARSER_API auto get_string(const File::StringType& section, const File::StringType& key) const -> const File::StringType&; + RC_INI_PARSER_API auto get_list(const SystemStringType& section) -> List; + RC_INI_PARSER_API auto get_ordered_list(const SystemStringType& section) -> List; + RC_INI_PARSER_API auto get_string(const SystemStringType& section, const SystemStringType& key, const SystemStringType& default_value) const noexcept + -> const SystemStringType&; + RC_INI_PARSER_API auto get_string(const SystemStringType& section, const SystemStringType& key) const -> const SystemStringType&; // Should there be more integer getters ? They'd confirm size and convert explicitly (or throw?), no implicit conversions. - RC_INI_PARSER_API auto get_int64(const File::StringType& section, const File::StringType& key, int64_t default_value) const noexcept -> int64_t; - RC_INI_PARSER_API auto get_int64(const File::StringType& section, const File::StringType& key) const -> int64_t; - RC_INI_PARSER_API auto get_float(const File::StringType& section, const File::StringType& key, float default_value) const noexcept -> float; - RC_INI_PARSER_API auto get_float(const File::StringType& section, const File::StringType& key) const -> float; - RC_INI_PARSER_API auto get_bool(const File::StringType& section, const File::StringType& key, bool default_value) const noexcept -> bool; - RC_INI_PARSER_API auto get_bool(const File::StringType& section, const File::StringType& key) const -> bool; + RC_INI_PARSER_API auto get_int64(const SystemStringType& section, const SystemStringType& key, int64_t default_value) const noexcept -> int64_t; + RC_INI_PARSER_API auto get_int64(const SystemStringType& section, const SystemStringType& key) const -> int64_t; + RC_INI_PARSER_API auto get_float(const SystemStringType& section, const SystemStringType& key, float default_value) const noexcept -> float; + RC_INI_PARSER_API auto get_float(const SystemStringType& section, const SystemStringType& key) const -> float; + RC_INI_PARSER_API auto get_bool(const SystemStringType& section, const SystemStringType& key, bool default_value) const noexcept -> bool; + RC_INI_PARSER_API auto get_bool(const SystemStringType& section, const SystemStringType& key) const -> bool; }; } // namespace RC::Ini diff --git a/deps/first/IniParser/include/IniParser/JSON.hpp b/deps/first/IniParser/include/IniParser/JSON.hpp index fc6d763bc..fd53a0a84 100644 --- a/deps/first/IniParser/include/IniParser/JSON.hpp +++ b/deps/first/IniParser/include/IniParser/JSON.hpp @@ -6,6 +6,8 @@ #include #include +#include + namespace RC::Parser { namespace JSONInternal @@ -24,31 +26,32 @@ namespace RC::Parser EndOfFile, }; - auto static token_type_to_string(const TokenType token_type) -> File::StringType + // Here we use std::string because it's used for printf + auto static token_type_to_string(const TokenType token_type) -> std::string { switch (token_type) { case Default: - return STR("Default"); + return std::string("Default"); case OpenCurlyBrace: - return STR("OpenCurlyBrace"); + return std::string("OpenCurlyBrace"); case CloseCurlyBrace: - return STR("CloseCurlyBrace"); + return std::string("CloseCurlyBrace"); case OpenSquareBracket: - return STR("OpenSquareBracket"); + return std::string("OpenSquareBracket"); case CloseSquareBracket: - return STR("CloseSquareBracket"); + return std::string("CloseSquareBracket"); case Colon: - return STR("Colon"); + return std::string("Colon"); case Comma: - return STR("Comma"); + return std::string("Comma"); break; case DoubleQuote: - return STR("DoubleQuote"); + return std::string("DoubleQuote"); case Characters: - return STR("Characters"); + return std::string("Characters"); case EndOfFile: - return STR("EndOfFile"); + return std::string("EndOfFile"); } } @@ -63,29 +66,29 @@ namespace RC::Parser class ItemBase { public: - File::StringType m_name{STR("--UNNAMED-ITEM--")}; + UEStringType m_name{STR("--UNNAMED-ITEM--")}; bool m_is_global_scope{false}; public: - auto get_name() -> File::StringViewType; + auto get_name() -> SystemStringType; virtual ~ItemBase() = default; - virtual auto to_string() -> File::StringType = 0; + virtual auto to_string() -> SystemStringType = 0; virtual auto get_type() -> ItemType = 0; }; class StringItem : public ItemBase { public: - File::StringType m_value{}; + SystemStringType m_value{}; public: StringItem() = default; - StringItem(const File::StringType& value) : m_value(value) + StringItem(const SystemStringType& value) : m_value(value) { } - auto to_string() -> File::StringType override; + auto to_string() -> SystemStringType override; auto get_type() -> ItemType override { return ItemType::String; @@ -100,7 +103,7 @@ namespace RC::Parser size_t m_previous_column_without_comma{}; public: - auto to_string() -> File::StringType override; + auto to_string() -> SystemStringType override; auto get_type() -> ItemType override { return ItemType::Object; @@ -113,7 +116,7 @@ namespace RC::Parser std::vector> m_members{}; public: - auto to_string() -> File::StringType override; + auto to_string() -> SystemStringType override; auto get_type() -> ItemType override { return ItemType::Array; @@ -160,18 +163,18 @@ namespace RC::Parser ItemType m_next_item_expected{}; TokenType m_next_token_expected{TokenType::Default}; TokenTypeStack m_processed_token_types{}; - File::StringType m_string_value_buffer{}; + SystemStringType m_string_value_buffer{}; bool m_double_quote_opened{false}; bool m_double_quote_successfully_closed{false}; public: - TokenParser(const Parser::Tokenizer& tokenizer, File::StringType& input) : Parser::TokenParser(tokenizer, input) + TokenParser(const Parser::Tokenizer& tokenizer, SystemStringType& input) : Parser::TokenParser(tokenizer, input) { } private: - auto token_to_string(const Token& token) -> File::StringType; + auto token_to_string(const Token& token) -> SystemStringType; auto skip_all_spaces() -> void; auto parse_open_curly_brace(const Token& token) -> void; @@ -198,10 +201,10 @@ namespace RC::Parser JSON() = default; private: - auto parse_internal(File::StringType& input) -> void; + auto parse_internal(SystemStringType& input) -> void; public: - auto parse(File::StringType& input) -> void; + auto parse(SystemStringType& input) -> void; auto parse(File::Handle&) -> void; auto release_contents() -> std::vector>; diff --git a/deps/first/IniParser/include/IniParser/Section.hpp b/deps/first/IniParser/include/IniParser/Section.hpp index b6d9797ff..18e7b170c 100644 --- a/deps/first/IniParser/include/IniParser/Section.hpp +++ b/deps/first/IniParser/include/IniParser/Section.hpp @@ -9,13 +9,13 @@ namespace RC::Ini { struct Section { - std::unordered_map key_value_pairs{}; - std::vector ordered_list{}; + std::unordered_map key_value_pairs{}; + std::vector ordered_list{}; bool is_ordered_list{}; }; template - concept CallableWithKeyValuePair = std::invocable; + concept CallableWithKeyValuePair = std::invocable; class List { diff --git a/deps/first/IniParser/include/IniParser/TokenParser.hpp b/deps/first/IniParser/include/IniParser/TokenParser.hpp index a7192852a..930377540 100644 --- a/deps/first/IniParser/include/IniParser/TokenParser.hpp +++ b/deps/first/IniParser/include/IniParser/TokenParser.hpp @@ -22,30 +22,30 @@ namespace RC::Ini SetSectionValue, }; - auto state_to_string(State) -> File::StringType; + auto state_to_string(State) -> SystemStringType; class TokenParser : public ParserBase::TokenParser { private: - using SectionContainer = std::unordered_map; + using SectionContainer = std::unordered_map; SectionContainer& m_output; Section* m_current_section{}; Value* m_current_value{}; - File::StringType m_current_character_data{}; + SystemStringType m_current_character_data{}; State m_current_state{State::StartOfFile}; public: - TokenParser(const ParserBase::Tokenizer& tokenizer, File::StringType& input, std::unordered_map& output) + TokenParser(const ParserBase::Tokenizer& tokenizer, SystemStringType& input, std::unordered_map& output) : ParserBase::TokenParser(tokenizer, input), m_output(output) { } public: - RC_INI_PARSER_API auto static find_variable_by_name(Section* section, const File::StringType& name) -> std::optional>; + RC_INI_PARSER_API auto static find_variable_by_name(Section* section, const SystemStringType& name) -> std::optional>; private: - RC_INI_PARSER_API auto find_variable_by_name(const File::StringType& name) -> std::optional>; - RC_INI_PARSER_API auto characters_to_string(const ParserBase::Token& characters_token) -> File::StringType; + RC_INI_PARSER_API auto find_variable_by_name(const SystemStringType& name) -> std::optional>; + RC_INI_PARSER_API auto characters_to_string(const ParserBase::Token& characters_token) -> SystemStringType; RC_INI_PARSER_API auto handle_opening_square_bracket_token(const ParserBase::Token& token) -> void; RC_INI_PARSER_API auto handle_closing_square_bracket_token(const ParserBase::Token& token) -> void; RC_INI_PARSER_API auto handle_space_token(const ParserBase::Token& token) -> void; diff --git a/deps/first/IniParser/include/IniParser/Value.hpp b/deps/first/IniParser/include/IniParser/Value.hpp index 9c302619c..dcd36b54b 100644 --- a/deps/first/IniParser/include/IniParser/Value.hpp +++ b/deps/first/IniParser/include/IniParser/Value.hpp @@ -26,7 +26,7 @@ namespace RC::Ini // Always use "m_ref->value" instead of "value" // That way it returns properly if this value is a reference to another variable // The "m_ref->value" member is set to self if it doesn't refer to another variable - File::StringType m_string_value; + SystemStringType m_string_value; int64_t m_int64_value{}; float m_float_value{}; bool m_bool_value{}; @@ -57,14 +57,14 @@ namespace RC::Ini return is_valid_type(); } - RC_INI_PARSER_API auto get_string_value() const -> const File::StringType&; + RC_INI_PARSER_API auto get_string_value() const -> const SystemStringType&; RC_INI_PARSER_API auto get_int64_value() const -> int64_t; RC_INI_PARSER_API auto get_float_value() const -> float; RC_INI_PARSER_API auto get_bool_value() const -> bool; - RC_INI_PARSER_API auto add_string_value(File::StringViewType data) -> void; - RC_INI_PARSER_API auto add_int64_value(const File::StringType& data, int base = 10) -> void; - RC_INI_PARSER_API auto add_float_value(const File::StringType& data) -> void; + RC_INI_PARSER_API auto add_string_value(SystemStringViewType data) -> void; + RC_INI_PARSER_API auto add_int64_value(const SystemStringType& data, int base = 10) -> void; + RC_INI_PARSER_API auto add_float_value(const SystemStringType& data) -> void; RC_INI_PARSER_API auto add_bool_value(bool data) -> void; private: diff --git a/deps/first/IniParser/src/Experimental.cpp b/deps/first/IniParser/src/Experimental.cpp index 9e143cb02..dd9855920 100644 --- a/deps/first/IniParser/src/Experimental.cpp +++ b/deps/first/IniParser/src/Experimental.cpp @@ -2,7 +2,7 @@ namespace RC::Parser::Experimental { - auto ExperimentalTokenParser::find_variable_by_name(Section* section, const std::wstring& name) -> std::optional> + auto ExperimentalTokenParser::find_variable_by_name(Section* section, const SystemStringType& name) -> std::optional> { auto const& var = section->key_value_pairs.find(name); if (var != section->key_value_pairs.end()) @@ -15,7 +15,7 @@ namespace RC::Parser::Experimental } } - auto ExperimentalTokenParser::find_variable_by_name(SectionContainer& sections, const std::wstring& name) -> std::optional> + auto ExperimentalTokenParser::find_variable_by_name(SectionContainer& sections, const SystemStringType& name) -> std::optional> { std::optional> value_found = [&]() -> std::optional> { for (auto& [_, section] : sections) @@ -33,7 +33,7 @@ namespace RC::Parser::Experimental return value_found; } - auto ExperimentalTokenParser::find_variable_by_name(const std::wstring& name) -> std::optional> + auto ExperimentalTokenParser::find_variable_by_name(const SystemStringType& name) -> std::optional> { size_t occurrence_of_dot = name.find_first_of(L'.'); if (occurrence_of_dot == name.npos || occurrence_of_dot + 1 > name.size()) @@ -49,7 +49,7 @@ namespace RC::Parser::Experimental } else { - const std::wstring requested_variable_name = name.substr(occurrence_of_dot + 1, name.size()); + const SystemStringType requested_variable_name = name.substr(occurrence_of_dot + 1, name.size()); return find_variable_by_name(&requested_section->second, requested_variable_name); } } @@ -60,12 +60,12 @@ namespace RC::Parser::Experimental const auto token_type = token.get_type(); if (token_type == TokenType::EndOfFile || token_type == TokenType::NewLine) { - pair_value.value = L""; + pair_value.value = SYSSTR(""); pair_value.ref = &pair_value; } else if (token_type == TokenType::Characters) { - std::wstring value_data{}; + SystemStringType value_data{}; consume_continually([&](const Parser::Token& token) { const auto token_type = token.get_type(); if (token_type == TokenType::EndOfFile || token_type == TokenType::NewLine) @@ -85,7 +85,7 @@ namespace RC::Parser::Experimental else if (token_type == TokenType::Space) { // Append space - value_data.append(L" "); + value_data.append(SYSSTR(" ")); // Consume another token return false; @@ -161,7 +161,7 @@ namespace RC::Parser::Experimental } else if (previous_token.get_type() == TokenType::Characters) { - std::wstring key_name = get_data(previous_token); + SystemStringType key_name = get_data(previous_token); const auto& key_value_pair_iter = m_current_section->key_value_pairs.find(key_name); if (key_value_pair_iter == m_current_section->key_value_pairs.end()) { @@ -188,7 +188,7 @@ namespace RC::Parser::Experimental } else if (characters_token.get_type() == TokenType::Characters) { - const std::wstring key_name = get_data(characters_token); + const SystemStringType key_name = get_data(characters_token); const auto& maybe_variable = find_variable_by_name(key_name); if (maybe_variable.has_value()) { @@ -250,7 +250,7 @@ namespace RC::Parser::Experimental // May be a variable or a temporary (Characters token) bool lhs_is_variable{}; bool lhs_is_temporary{}; - std::wstring lhs = [&]() { + SystemStringType lhs = [&]() { if (!m_temporary.empty()) { lhs_is_temporary = true; @@ -265,7 +265,7 @@ namespace RC::Parser::Experimental } else { - const std::wstring lhs_data = get_data(lhs_token); + const SystemStringType lhs_data = get_data(lhs_token); auto maybe_variable = find_variable_by_name(lhs_data); if (maybe_variable.has_value()) { @@ -306,8 +306,8 @@ namespace RC::Parser::Experimental // } // Find rhs - std::wstring rhs = [&]() { - std::wstring rhs_temporary{}; + SystemStringType rhs = [&]() { + SystemStringType rhs_temporary{}; const auto& next_token = peek(); if (next_token.get_type() == TokenType::EndOfFile) @@ -332,7 +332,7 @@ namespace RC::Parser::Experimental } else if (next_token.get_type() == TokenType::Space) { - rhs_temporary += L" "; + rhs_temporary += SYSSTR(" "); consume(); // Consume the first Space consume_until(TokenType::Characters, [&](const Parser::Token& token) { @@ -346,7 +346,7 @@ namespace RC::Parser::Experimental } else { - rhs_temporary += L" "; + rhs_temporary += SYSSTR(" "); return false; } } @@ -476,7 +476,7 @@ namespace RC::Parser::Experimental } }(); - std::wstring section_name = get_data(section_name_token); + SystemStringType section_name = get_data(section_name_token); if (auto section = m_output.find(section_name); section != m_output.end()) { m_current_section = §ion->second; @@ -515,7 +515,7 @@ namespace RC::Parser::Experimental } } - ExperimentalParser::ExperimentalParser(const std::wstring& input) + ExperimentalParser::ExperimentalParser(const SystemStringType& input) { // Tokenize -> START Parser::Tokenizer tokenizer; @@ -533,28 +533,29 @@ namespace RC::Parser::Experimental { Parser::TokenContainer tc; - tc.add(Parser::Token::create(TokenType::CarriageReturn, L"CarriageReturn", L"\r")); - tc.add(Parser::Token::create(TokenType::NewLine, L"NewLine", L"\n")); - tc.add(Parser::Token::create(TokenType::Space, L"Space", L" ")); + tc.add(Parser::Token::create(TokenType::CarriageReturn, SYSSTR("CarriageReturn"), SYSSTR("\r"))); + tc.add(Parser::Token::create(TokenType::NewLine, SYSSTR("NewLine"), SYSSTR("\n"))); + tc.add(Parser::Token::create(TokenType::Space, SYSSTR("Space"), SYSSTR(" "))); tc.add(Parser::Token::create(TokenType::Characters, - L"Characters", - L"", + SYSSTR("Characters"), + SYSSTR(""), Parser::Token::HasData::Yes)); // Empty identifier will match everything that no other token identifier matches - tc.add(Parser::Token::create(TokenType::Equals, L"Equals", L"=")); - // tc.add(Parser::Token::create(IniFileToken::Plus, L"Plus", L"+")); + tc.add(Parser::Token::create(TokenType::Equals, SYSSTR("Equals"), SYSSTR("="))); + // tc.add(Parser::Token::create(IniFileToken::Plus, SYSSTR("Plus"), SYSSTR("+"))); - auto close_square_bracket_token = tc.add(Parser::Token::create(TokenType::ClosingSquareBracket, L"CloseSquareBracket", L"]")); + auto close_square_bracket_token = tc.add(Parser::Token::create(TokenType::ClosingSquareBracket, SYSSTR("CloseSquareBracket"), SYSSTR("]"))); - auto token = - Parser::Token::create(TokenType::OpeningSquareBracket, L"OpenSquareBracket", L"["); + auto token = Parser::Token::create(TokenType::OpeningSquareBracket, + SYSSTR("OpenSquareBracket"), + SYSSTR("[")); tc.add(std::move(token)); - tc.add(Parser::Token::create(TokenType::SemiColon, L"SemiColon", L";")); + tc.add(Parser::Token::create(TokenType::SemiColon, SYSSTR("SemiColon"), SYSSTR(";"))); return tc; } - auto ExperimentalParser::get_string(const std::wstring& section, const std::wstring& key, const std::wstring& default_value) -> std::wstring + auto ExperimentalParser::get_string(const SystemStringType& section, const SystemStringType& key, const SystemStringType& default_value) -> SystemStringType { auto section_iter = m_sections.find(section); if (section_iter == m_sections.end()) @@ -590,7 +591,7 @@ var6 = hello + + world var7 = 1 + 2 + 3 + 4 */ - std::wstring config_str = LR"( + SystemStringType config_str = R"( [ SectionOne] ; This is a comment and as such should be ignored by the parser var1 = 2 @@ -624,30 +625,30 @@ var5 = a string with spaces printf_s("Creating experimental parser\n"); ExperimentalParser parser{config_str}; - constexpr wchar_t default_value[] = L""; - printf_s("SectionOne.var1 = %S\n", parser.get_string(L"SectionOne", L"var1", default_value).c_str()); - printf_s("SectionOne.var2 = %S\n", parser.get_string(L"SectionOne", L"var2", default_value).c_str()); - printf_s("SectionOne.var3 = %S\n", parser.get_string(L"SectionOne", L"var3", default_value).c_str()); - printf_s("SectionOne.var4 = %S\n", parser.get_string(L"SectionOne", L"var4", default_value).c_str()); - printf_s("SectionOne.var5 = %S\n", parser.get_string(L"SectionOne", L"var5", default_value).c_str()); - printf_s("SectionOne.var6 = %S\n", parser.get_string(L"SectionOne", L"var6", default_value).c_str()); - printf_s("SectionOne.var7 = %S\n", parser.get_string(L"SectionOne", L"var7", default_value).c_str()); + constexpr char16_t default_value[] = SYSSTR(""); + printf_s("SectionOne.var1 = %S\n", parser.get_string(SYSSTR("SectionOne"), SYSSTR("var1"), default_value).c_str()); + printf_s("SectionOne.var2 = %S\n", parser.get_string(SYSSTR("SectionOne"), SYSSTR("var2"), default_value).c_str()); + printf_s("SectionOne.var3 = %S\n", parser.get_string(SYSSTR("SectionOne"), SYSSTR("var3"), default_value).c_str()); + printf_s("SectionOne.var4 = %S\n", parser.get_string(SYSSTR("SectionOne"), SYSSTR("var4"), default_value).c_str()); + printf_s("SectionOne.var5 = %S\n", parser.get_string(SYSSTR("SectionOne"), SYSSTR("var5"), default_value).c_str()); + printf_s("SectionOne.var6 = %S\n", parser.get_string(SYSSTR("SectionOne"), SYSSTR("var6"), default_value).c_str()); + printf_s("SectionOne.var7 = %S\n", parser.get_string(SYSSTR("SectionOne"), SYSSTR("var7"), default_value).c_str()); printf_s("\n"); - printf_s("SectionTwo.var1 = %S\n", parser.get_string(L"SectionTwo", L"var1", default_value).c_str()); - printf_s("SectionTwo.var2 = %S\n", parser.get_string(L"SectionTwo", L"var2", default_value).c_str()); - printf_s("SectionTwo.var3 = %S\n", parser.get_string(L"SectionTwo", L"var3", default_value).c_str()); - printf_s("SectionTwo.var4 = %S\n", parser.get_string(L"SectionTwo", L"var4", default_value).c_str()); - printf_s("SectionTwo.var5 = %S\n", parser.get_string(L"SectionTwo", L"var5", default_value).c_str()); - printf_s("SectionTwo.var6 = %S\n", parser.get_string(L"SectionTwo", L"var6", default_value).c_str()); - printf_s("SectionTwo.var7 = %S\n", parser.get_string(L"SectionTwo", L"var7", default_value).c_str()); - printf_s("SectionTwo.var8 = %S\n", parser.get_string(L"SectionTwo", L"var8", default_value).c_str()); - printf_s("SectionTwo.var9 = %S\n", parser.get_string(L"SectionTwo", L"var9", default_value).c_str()); - printf_s("SectionTwo.var10 = %S\n", parser.get_string(L"SectionTwo", L"var10", default_value).c_str()); + printf_s("SectionTwo.var1 = %S\n", parser.get_string(SYSSTR("SectionTwo"), SYSSTR("var1"), default_value).c_str()); + printf_s("SectionTwo.var2 = %S\n", parser.get_string(SYSSTR("SectionTwo"), SYSSTR("var2"), default_value).c_str()); + printf_s("SectionTwo.var3 = %S\n", parser.get_string(SYSSTR("SectionTwo"), SYSSTR("var3"), default_value).c_str()); + printf_s("SectionTwo.var4 = %S\n", parser.get_string(SYSSTR("SectionTwo"), SYSSTR("var4"), default_value).c_str()); + printf_s("SectionTwo.var5 = %S\n", parser.get_string(SYSSTR("SectionTwo"), SYSSTR("var5"), default_value).c_str()); + printf_s("SectionTwo.var6 = %S\n", parser.get_string(SYSSTR("SectionTwo"), SYSSTR("var6"), default_value).c_str()); + printf_s("SectionTwo.var7 = %S\n", parser.get_string(SYSSTR("SectionTwo"), SYSSTR("var7"), default_value).c_str()); + printf_s("SectionTwo.var8 = %S\n", parser.get_string(SYSSTR("SectionTwo"), SYSSTR("var8"), default_value).c_str()); + printf_s("SectionTwo.var9 = %S\n", parser.get_string(SYSSTR("SectionTwo"), SYSSTR("var9"), default_value).c_str()); + printf_s("SectionTwo.var10 = %S\n", parser.get_string(SYSSTR("SectionTwo"), SYSSTR("var10"), default_value).c_str()); printf_s("\n"); - printf_s("AnotherSection.var1 = %S\n", parser.get_string(L"AnotherSection", L"var1", default_value).c_str()); - printf_s("AnotherSection.var2 = %S\n", parser.get_string(L"AnotherSection", L"var2", default_value).c_str()); - printf_s("AnotherSection.var3 = %S\n", parser.get_string(L"AnotherSection", L"var3", default_value).c_str()); - printf_s("AnotherSection.var4 = %S\n", parser.get_string(L"AnotherSection", L"var4", default_value).c_str()); - printf_s("AnotherSection.var5 = %S\n", parser.get_string(L"AnotherSection", L"var5", default_value).c_str()); + printf_s("AnotherSection.var1 = %S\n", parser.get_string(SYSSTR("AnotherSection"), SYSSTR("var1"), default_value).c_str()); + printf_s("AnotherSection.var2 = %S\n", parser.get_string(SYSSTR("AnotherSection"), SYSSTR("var2"), default_value).c_str()); + printf_s("AnotherSection.var3 = %S\n", parser.get_string(SYSSTR("AnotherSection"), SYSSTR("var3"), default_value).c_str()); + printf_s("AnotherSection.var4 = %S\n", parser.get_string(SYSSTR("AnotherSection"), SYSSTR("var4"), default_value).c_str()); + printf_s("AnotherSection.var5 = %S\n", parser.get_string(SYSSTR("AnotherSection"), SYSSTR("var5"), default_value).c_str()); } } // namespace RC::Parser::Experimental diff --git a/deps/first/IniParser/src/Ini.cpp b/deps/first/IniParser/src/Ini.cpp index 20670ccab..8d2bcf5ca 100644 --- a/deps/first/IniParser/src/Ini.cpp +++ b/deps/first/IniParser/src/Ini.cpp @@ -1,10 +1,11 @@ #include #include #include +#include namespace RC::Ini { - auto Parser::parse_internal(File::StringType& input) -> void + auto Parser::parse_internal(SystemStringType& input) -> void { // Tokenize -> START ParserBase::Tokenizer tokenizer; @@ -24,24 +25,24 @@ namespace RC::Ini { ParserBase::TokenContainer tc; - tc.add(ParserBase::Token::create(IniTokenType::CarriageReturn, STR("CarriageReturn"), STR("\r"))); - tc.add(ParserBase::Token::create(IniTokenType::NewLine, STR("NewLine"), STR("\n"))); - tc.add(ParserBase::Token::create(IniTokenType::Space, STR("Space"), STR(" "))); + tc.add(ParserBase::Token::create(IniTokenType::CarriageReturn, SYSSTR("CarriageReturn"), SYSSTR("\r"))); + tc.add(ParserBase::Token::create(IniTokenType::NewLine, SYSSTR("NewLine"), SYSSTR("\n"))); + tc.add(ParserBase::Token::create(IniTokenType::Space, SYSSTR("Space"), SYSSTR(" "))); tc.add(ParserBase::Token::create(IniTokenType::Characters, - STR("Characters"), - STR(""), + SYSSTR("Characters"), + SYSSTR(""), ParserBase::Token::HasData::Yes)); // Empty identifier will match everything that no other token identifier matches - tc.add(ParserBase::Token::create /**/ (IniTokenType::Equals, STR("Equals"), STR("="))); - tc.add(ParserBase::Token::create(IniTokenType::ClosingSquareBracket, STR("CloseSquareBracket"), STR("]"))); - tc.add(ParserBase::Token::create(IniTokenType::OpeningSquareBracket, STR("OpenSquareBracket"), STR("["))); - tc.add(ParserBase::Token::create(IniTokenType::SemiColon, STR("SemiColon"), STR(";"))); + tc.add(ParserBase::Token::create /**/ (IniTokenType::Equals, SYSSTR("Equals"), SYSSTR("="))); + tc.add(ParserBase::Token::create(IniTokenType::ClosingSquareBracket, SYSSTR("CloseSquareBracket"), SYSSTR("]"))); + tc.add(ParserBase::Token::create(IniTokenType::OpeningSquareBracket, SYSSTR("OpenSquareBracket"), SYSSTR("["))); + tc.add(ParserBase::Token::create(IniTokenType::SemiColon, SYSSTR("SemiColon"), SYSSTR(";"))); tc.set_eof_token(IniTokenType::EndOfFile); return tc; } - auto Parser::get_value(const File::StringType& section, const File::StringType& key, CanThrow can_throw) const + auto Parser::get_value(const SystemStringType& section, const SystemStringType& key, CanThrow can_throw) const -> std::optional> { if (!m_parsing_is_complete) @@ -76,18 +77,18 @@ namespace RC::Ini } } - auto Parser::parse(File::StringType& input) -> void + auto Parser::parse(SystemStringType& input) -> void { parse_internal(input); } auto Parser::parse(const File::Handle& file) -> void { - auto input = file.read_all(); + auto input = to_system_string(file.read_file_all()); parse_internal(input); } - auto Parser::get_list(const File::StringType& section) -> List + auto Parser::get_list(const SystemStringType& section) -> List { const auto& section_iter = m_sections.find(section); @@ -101,13 +102,13 @@ namespace RC::Ini } } - auto Parser::get_ordered_list(const File::StringType& section) -> List + auto Parser::get_ordered_list(const SystemStringType& section) -> List { return get_list(section); } - auto Parser::get_string(const File::StringType& section, const File::StringType& key, const File::StringType& default_value) const noexcept - -> const File::StringType& + auto Parser::get_string(const SystemStringType& section, const SystemStringType& key, const SystemStringType& default_value) const noexcept + -> const SystemStringType& { const auto maybe_value = get_value(section, key, CanThrow::No); if (!maybe_value.has_value()) @@ -128,7 +129,7 @@ namespace RC::Ini } } - auto Parser::get_string(const File::StringType& section, const File::StringType& key) const -> const File::StringType& + auto Parser::get_string(const SystemStringType& section, const SystemStringType& key) const -> const SystemStringType& { const auto maybe_value = get_value(section, key); if (!maybe_value.has_value()) @@ -149,7 +150,7 @@ namespace RC::Ini } } - auto Parser::get_int64(const File::StringType& section, const File::StringType& key, int64_t default_value) const noexcept -> int64_t + auto Parser::get_int64(const SystemStringType& section, const SystemStringType& key, int64_t default_value) const noexcept -> int64_t { const auto maybe_value = get_value(section, key, CanThrow::No); if (!maybe_value.has_value()) @@ -170,7 +171,7 @@ namespace RC::Ini } } - auto Parser::get_int64(const File::StringType& section, const File::StringType& key) const -> int64_t + auto Parser::get_int64(const SystemStringType& section, const SystemStringType& key) const -> int64_t { const auto maybe_value = get_value(section, key); if (!maybe_value.has_value()) @@ -191,7 +192,7 @@ namespace RC::Ini } } - auto Parser::get_float(const File::StringType& section, const File::StringType& key, float default_value) const noexcept -> float + auto Parser::get_float(const SystemStringType& section, const SystemStringType& key, float default_value) const noexcept -> float { const auto maybe_value = get_value(section, key, CanThrow::No); if (!maybe_value.has_value()) @@ -212,7 +213,7 @@ namespace RC::Ini } } - auto Parser::get_float(const File::StringType& section, const File::StringType& key) const -> float + auto Parser::get_float(const SystemStringType& section, const SystemStringType& key) const -> float { const auto maybe_value = get_value(section, key); if (!maybe_value.has_value()) @@ -233,7 +234,7 @@ namespace RC::Ini } } - auto Parser::get_bool(const File::StringType& section, const File::StringType& key, bool default_value) const noexcept -> bool + auto Parser::get_bool(const SystemStringType& section, const SystemStringType& key, bool default_value) const noexcept -> bool { const auto maybe_value = get_value(section, key, CanThrow::No); if (!maybe_value.has_value()) @@ -254,7 +255,7 @@ namespace RC::Ini } } - auto Parser::get_bool(const File::StringType& section, const File::StringType& key) const -> bool + auto Parser::get_bool(const SystemStringType& section, const SystemStringType& key) const -> bool { const auto maybe_value = get_value(section, key); if (!maybe_value.has_value()) diff --git a/deps/first/IniParser/src/JSON.cpp b/deps/first/IniParser/src/JSON.cpp index a0a71f85d..033e494a7 100644 --- a/deps/first/IniParser/src/JSON.cpp +++ b/deps/first/IniParser/src/JSON.cpp @@ -11,7 +11,7 @@ namespace RC::Parser return std::string{in.begin(), in.end()}; } - static auto has_only_spaces(const File::StringType& data) -> bool + static auto has_only_spaces(const UEStringType& data) -> bool { if (std::all_of(data.begin(), data.end(), [](File::CharType c) { return std::isspace(c) || c == '\n'; @@ -27,7 +27,7 @@ namespace RC::Parser } } - auto JSONInternal::ItemBase::get_name() -> File::StringViewType + auto JSONInternal::ItemBase::get_name() -> UEStringViewType { if (m_is_global_scope) { @@ -39,14 +39,14 @@ namespace RC::Parser } } - auto JSONInternal::StringItem::to_string() -> File::StringType + auto JSONInternal::StringItem::to_string() -> UEStringType { return std::format(STR("String = \"{}\""), m_value); } - auto JSONInternal::ObjectScope::to_string() -> File::StringType + auto JSONInternal::ObjectScope::to_string() -> UEStringType { - File::StringType str = std::format(STR("Object = \"{}\""), get_name()); + UEStringType str = std::format(STR("Object = \"{}\""), get_name()); for (const auto& member : m_members) { @@ -56,14 +56,14 @@ namespace RC::Parser return str; } - auto JSONInternal::ArrayScope::to_string() -> File::StringType + auto JSONInternal::ArrayScope::to_string() -> UEStringType { return std::format(STR("Array = \"{}\""), get_name()); } - auto JSONInternal::TokenParser::token_to_string(const Token& token) -> File::StringType + auto JSONInternal::TokenParser::token_to_string(const Token& token) -> UEStringType { - File::StringType string{}; + UEStringType string{}; // TODO: Support manual escaping of double quotes with '\' while (peek().get_type() != TokenType::DoubleQuote) @@ -342,7 +342,7 @@ namespace RC::Parser } } - auto JSON::parse_internal(File::StringType& input) -> void + auto JSON::parse_internal(UEStringType& input) -> void { Tokenizer tokenizer; TokenContainer tc; @@ -362,14 +362,14 @@ namespace RC::Parser m_token_parser->parse(); } - auto JSON::parse(File::StringType& input) -> void + auto JSON::parse(SystemStringType& input) -> void { parse_internal(input); } auto JSON::parse(File::Handle& file) -> void { - auto input = file.read_all(); + auto input = file.read_file_all(); parse_internal(input); } @@ -391,7 +391,7 @@ namespace RC::Parser */ /**/ - File::StringType input = LR"( + UEStringType input = LR"( { "my key": "my string, value", "my second key": "my other string value", diff --git a/deps/first/IniParser/src/TokenParser.cpp b/deps/first/IniParser/src/TokenParser.cpp index dd633366e..631cdf994 100644 --- a/deps/first/IniParser/src/TokenParser.cpp +++ b/deps/first/IniParser/src/TokenParser.cpp @@ -28,25 +28,25 @@ namespace RC::Ini bool is_bool{false}; }; - auto static is_int(File::StringViewType data) -> Int + auto static is_int(SystemStringType data) -> Int { bool has_0x_prefix = [&]() { - return (data.size() > 2 && data[0] == L'0' && (data[1] == L'x' || data[1] == L'X')); + return (data.size() > 2 && data[0] == SYSSTR('0') && (data[1] == SYSSTR('x') || data[1] == SYSSTR('X'))); }(); - if (!has_0x_prefix && data[0] != L'-' && std::iswdigit(data[0]) == 0) + if (!has_0x_prefix && data[0] != SYSSTR('-') && std::iswdigit(data[0]) == 0) { return Int{0, 10, false}; } else { - File::StringViewType string = has_0x_prefix ? File::StringViewType{data.begin() + 2, data.end()} : data; - if (!has_0x_prefix && data[0] == STR('-')) + SystemStringType string = has_0x_prefix ? SystemStringType{data.begin() + 2, data.end()} : data; + if (!has_0x_prefix && data[0] == SYSSTR('-')) { - string = File::StringViewType{string.begin() + 1, string.end()}; + string = SystemStringType{string.begin() + 1, string.end()}; } - bool is_int = std::ranges::all_of(string.begin(), string.end(), [&](const File::CharType c) { - if constexpr (std::is_same_v) + bool is_int = std::ranges::all_of(string.begin(), string.end(), [&](const UECharType c) { + if constexpr (std::is_same_v) { return has_0x_prefix ? std::iswxdigit(c) : std::iswdigit(c) != 0; } @@ -60,10 +60,10 @@ namespace RC::Ini } } - auto static is_float(File::StringViewType data) -> Float + auto static is_float(SystemStringType data) -> Float { bool has_decimal_or_negative_prefix = [&]() { - return data.size() > 1 && data[0] == L'.' || data[0] == L'-'; + return data.size() > 1 && data[0] == SYSSTR('.') || data[0] == SYSSTR('-'); }(); if (!has_decimal_or_negative_prefix && std::iswdigit(data[0]) == 0) @@ -72,19 +72,19 @@ namespace RC::Ini } else { - File::StringViewType string = data.ends_with(STR('f')) ? File::StringViewType{data.begin(), data.end() - 1} : data; + SystemStringType string = data.ends_with(SYSSTR('f')) ? SystemStringType{data.begin(), data.end() - 1} : data; if (has_decimal_or_negative_prefix) { - string = File::StringViewType{string.begin() + 1, string.end()}; + string = SystemStringType{string.begin() + 1, string.end()}; } - bool is_float = std::ranges::all_of(string.begin(), string.end(), [&](const File::CharType c) { - if constexpr (std::is_same_v) + bool is_float = std::ranges::all_of(string.begin(), string.end(), [&](const UECharType c) { + if constexpr (std::is_same_v) { - return has_decimal_or_negative_prefix ? std::iswxdigit(c) : std::iswdigit(c) != 0 || c == STR('.'); + return has_decimal_or_negative_prefix ? std::iswxdigit(c) : std::iswdigit(c) != 0 || c == SYSSTR('.'); } else { - return has_decimal_or_negative_prefix ? std::isxdigit(c) : std::isdigit(c) != 0 || c == STR('.'); + return has_decimal_or_negative_prefix ? std::isxdigit(c) : std::isdigit(c) != 0 || c == SYSSTR('.'); } }); @@ -92,20 +92,17 @@ namespace RC::Ini } } - auto static is_bool(const File::StringType& data) -> Bool + auto static is_bool(const SystemStringType& data) -> Bool { - File::StringType all_lower_string_data = data; - // TODO: This to_lower implementation is not string-type agnostic - // A code change would be required if 'File::StringType' is defined as a char instead of a wchar_t - // Solution: Make two overloads in the string helper library, one for 'std::string' and one for 'std::wstring' - std::transform(all_lower_string_data.begin(), all_lower_string_data.end(), all_lower_string_data.begin(), [](wchar_t c) { + SystemStringType all_lower_string_data = data; + std::transform(all_lower_string_data.begin(), all_lower_string_data.end(), all_lower_string_data.begin(), [](UECharType c) { return std::towlower(c); }); - if (all_lower_string_data == STR("true") || all_lower_string_data == STR("1")) + if (all_lower_string_data == SYSSTR("true") || all_lower_string_data == SYSSTR("1")) { return Bool{.value = true, .is_bool = true}; } - else if (all_lower_string_data == STR("false") || all_lower_string_data == STR("0")) + else if (all_lower_string_data == SYSSTR("false") || all_lower_string_data == SYSSTR("0")) { return Bool{.value = false, .is_bool = true}; } @@ -115,7 +112,7 @@ namespace RC::Ini } } - auto TokenParser::find_variable_by_name(Section* section, const RC::StringType& name) -> std::optional> + auto TokenParser::find_variable_by_name(Section* section, const RC::SystemStringType& name) -> std::optional> { auto const& var = section->key_value_pairs.find(name); if (var != section->key_value_pairs.end()) @@ -128,9 +125,9 @@ namespace RC::Ini } } - auto TokenParser::find_variable_by_name(const StringType& name) -> std::optional> + auto TokenParser::find_variable_by_name(const SystemStringType& name) -> std::optional> { - size_t occurrence_of_dot = name.find_first_of(L'.'); + size_t occurrence_of_dot = name.find_first_of(SYSSTR('.')); if (occurrence_of_dot == name.npos || occurrence_of_dot + 1 > name.size()) { return find_variable_by_name(m_current_section, name); @@ -144,38 +141,40 @@ namespace RC::Ini } else { - const File::StringType requested_variable_name = name.substr(occurrence_of_dot + 1, name.size()); + const SystemStringType requested_variable_name = name.substr(occurrence_of_dot + 1, name.size()); return find_variable_by_name(&requested_section->second, requested_variable_name); } } } - auto state_to_string(State state) -> File::StringType + // Maybe use std::string here instead of SystemStringType + // because it's only used for runtime_error + auto state_to_string(State state) -> SystemStringType { switch (state) { case State::StartOfFile: - return STR("StartOfFile"); + return SYSSTR("StartOfFile"); case State::SetSectionValue: - return STR("SetSectionValue"); + return SYSSTR("SetSectionValue"); case State::NewLineStarted: - return STR("NewLineStarted"); + return SYSSTR("NewLineStarted"); case State::CreateNewOrSetCurrentSection: - return STR("CreateNewOrSetCurrentSection"); + return SYSSTR("CreateNewOrSetCurrentSection"); case State::CreateSectionKey: - return STR("CreateSectionKey"); + return SYSSTR("CreateSectionKey"); case State::StoreSectionKey: - return STR("StoreSectionKey"); + return SYSSTR("StoreSectionKey"); } - return STR("UnknownState"); + return SYSSTR("UnknownState"); } - auto TokenParser::characters_to_string(const ParserBase::Token& characters_token) -> File::StringType + auto TokenParser::characters_to_string(const ParserBase::Token& characters_token) -> SystemStringType { auto* current_token = &characters_token; - File::StringType full_value{}; + SystemStringType full_value{}; while (true) { const auto token_type = current_token->get_type(); @@ -185,7 +184,7 @@ namespace RC::Ini } else if (token_type == IniTokenType::Space) { - full_value.append(STR(" ")); + full_value.append(SYSSTR(" ")); } else if (token_type == IniTokenType::Characters) { @@ -193,7 +192,7 @@ namespace RC::Ini } else if (token_type == IniTokenType::Equals) { - full_value.append(STR("=")); + full_value.append(SYSSTR("=")); } else if (token_type == IniTokenType::ClosingSquareBracket) { @@ -204,15 +203,15 @@ namespace RC::Ini // The next token is the last token on this line and since it's ] we don't want to include it in the string break; } - full_value.append(STR("]")); + full_value.append(SYSSTR("]")); } else if (token_type == IniTokenType::OpeningSquareBracket) { - full_value.append(STR("[")); + full_value.append(SYSSTR("[")); } else if (token_type == IniTokenType::SemiColon) { - full_value.append(STR(";")); + full_value.append(SYSSTR(";")); } // Exit early and let the state machine deal with the new line @@ -293,7 +292,7 @@ namespace RC::Ini { if (m_current_state == State::CreateNewOrSetCurrentSection) { - m_current_character_data.append(STR(" ")); + m_current_character_data.append(SYSSTR(" ")); } } @@ -384,7 +383,7 @@ namespace RC::Ini // Create the value with the correct key and an empty value and store a pointer to it so that the value can be set later m_current_value = &m_current_section->key_value_pairs.emplace(m_current_character_data, Value{}).first->second; - m_current_value->add_string_value(STR("")); + m_current_value->add_string_value(SYSSTR("")); m_current_value->set_ref(m_current_value); m_current_character_data.clear(); diff --git a/deps/first/IniParser/src/Value.cpp b/deps/first/IniParser/src/Value.cpp index 05e79ee57..36a23fa59 100644 --- a/deps/first/IniParser/src/Value.cpp +++ b/deps/first/IniParser/src/Value.cpp @@ -20,7 +20,7 @@ namespace RC::Ini m_ref = new_ref; } - auto Value::get_string_value() const -> const File::StringType& + auto Value::get_string_value() const -> const SystemStringType& { return m_string_value; } @@ -40,7 +40,7 @@ namespace RC::Ini return m_bool_value; } - auto Value::add_string_value(File::StringViewType data) -> void + auto Value::add_string_value(SystemStringViewType data) -> void { m_string_value = data; @@ -52,7 +52,7 @@ namespace RC::Ini add_type(); } - auto Value::add_int64_value(const StringType& data, int base) -> void + auto Value::add_int64_value(const SystemStringType& data, int base) -> void { m_int64_value = std::stoi(data, nullptr, base); @@ -64,7 +64,7 @@ namespace RC::Ini add_type(); } - auto Value::add_float_value(const StringType& data) -> void + auto Value::add_float_value(const SystemStringType& data) -> void { m_float_value = std::stof(data, nullptr); diff --git a/deps/first/Input/include/Input/Handler.hpp b/deps/first/Input/include/Input/Handler.hpp index ebc1ad592..53c428346 100644 --- a/deps/first/Input/include/Input/Handler.hpp +++ b/deps/first/Input/include/Input/Handler.hpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include #include @@ -15,12 +18,16 @@ namespace RC::Input { using EventCallbackCallable = std::function; - auto is_modifier_key_required(ModifierKey, std::vector) -> bool; + struct InputEvent + { + Key key; + ModifierKeys modifier_keys{}; + }; struct KeyData { - std::vector required_modifier_keys{}; - std::vector callbacks{}; + ModifierKeys required_modifier_keys{}; + EventCallbackCallable callback{}; uint8_t custom_data{}; void* custom_data2{}; bool requires_modifier_keys{}; @@ -32,48 +39,30 @@ namespace RC::Input std::unordered_map> key_data; }; + class PlatformInputSource; class RC_INPUT_API Handler { private: - std::vector m_active_window_classes{}; - std::vector m_key_sets{}; - std::unordered_map m_modifier_keys_down{}; - bool m_any_keys_are_down{}; + // std::vector m_key_sets{}; + KeySet m_key_set{}; bool m_allow_input{true}; + std::array m_subscribed_keys{}; - public: - Handler() = delete; - template - explicit Handler(WindowClasses... window_classes) - { - static_assert(std::conjunction...>::value, "WindowClasses must be of type const wchar_t*"); - - m_modifier_keys_down.emplace(ModifierKey::SHIFT, false); - m_modifier_keys_down.emplace(ModifierKey::CONTROL, false); - m_modifier_keys_down.emplace(ModifierKey::ALT, false); - - register_window_classes(window_classes...); - } + std::shared_ptr m_platform_handler; + std::mutex m_event_mutex; - private: - template - auto register_window_classes(WindowClass window_class) -> void - { - m_active_window_classes.emplace_back(window_class); - } - - template - auto register_window_classes(WindowClass window_class, WindowClasses... window_classes) -> void - { - m_active_window_classes.emplace_back(window_class); - register_window_classes(window_classes...); - } - - auto are_modifier_keys_down(const std::vector&) -> bool; - auto is_program_focused() -> bool; + public: + Handler(){}; + // Input source and event processing public: + auto set_input_source(std::string source) -> bool; auto process_event() -> void; + + // Interfaces for UE4SS and ModSystem for event registration + public: + auto init() -> void; + auto register_keydown_event(Input::Key, EventCallbackCallable, uint8_t custom_data = 0, void* custom_data2 = nullptr) -> void; using ModifierKeyArray = std::array; @@ -83,9 +72,34 @@ namespace RC::Input auto is_keydown_event_registered(Input::Key) -> bool; auto is_keydown_event_registered(Input::Key, const ModifierKeyArray&) -> bool; - auto get_events() -> std::vector&; + auto get_events_safe(std::function) -> void; + auto clear_subscribed_keys() -> void; + auto clear_subscribed_key(Key k) -> void; + + auto has_event_on_key(Input::Key key) -> bool; + auto get_subscribed_keys() const -> const std::array& + { + return m_subscribed_keys; + } + auto get_allow_input() -> bool; auto set_allow_input(bool new_value) -> void; + + auto get_current_input_source() -> std::string; + + private: + static std::unordered_map> m_input_sources_store; + static auto register_input_source(std::shared_ptr input_source) -> void; + + public: + static auto get_input_source(std::string source) -> std::shared_ptr + { + if (m_input_sources_store.find(source) != m_input_sources_store.end()) + { + return m_input_sources_store[source]; + } + return nullptr; + } }; } // namespace RC::Input diff --git a/deps/first/Input/include/Input/KeyDef.hpp b/deps/first/Input/include/Input/KeyDef.hpp index 02ec12976..219c15f79 100644 --- a/deps/first/Input/include/Input/KeyDef.hpp +++ b/deps/first/Input/include/Input/KeyDef.hpp @@ -1,13 +1,13 @@ #pragma once #include - +#include +#include namespace RC::Input { static constexpr uint32_t max_callbacks_per_event = 30; static constexpr uint8_t max_keys = 0xFF; -#ifdef _WIN32 enum Key : uint8_t { RESERVED_START_OF_ENUM = 0x0, @@ -244,11 +244,62 @@ namespace RC::Input MODIFIER_KEYS_MAX, }; + static inline bool is_modify_key_valid(ModifierKey key) + { + return (key < MODIFIER_KEYS_MAX) && (key > MOD_KEY_START_OF_ENUM); + } + + struct ModifierKeys + { + /// SAFETY: This is a bitfield, following static_assert ensures that the bitfield is not larger than 32 bits + uint32_t keys; + + // allow ops between keys + + auto operator|(const ModifierKeys& key) -> ModifierKeys&; + auto operator|=(const ModifierKeys& key) -> ModifierKeys&; + auto operator|(const ModifierKey& key) -> ModifierKeys&; + auto operator|=(const ModifierKey& key) -> ModifierKeys&; + + auto operator==(const ModifierKeys& key) const -> bool; + auto operator!=(const ModifierKeys& key) const -> bool; + + auto operator<(const ModifierKeys& key) const -> bool; + auto operator>(const ModifierKeys& key) const -> bool; + + ModifierKeys(const ModifierKey key) : keys{is_modify_key_valid(key) ? (1u << key) : 0} {}; + ModifierKeys(const ModifierKeys& other) : keys{other.keys} {}; + + ModifierKeys() : keys{0} {}; + + template + ModifierKeys(ModifierKey key, Args... args) : keys{(is_modify_key_valid(key) ? (1 << key) : 0) | ModifierKeys(args...).keys} {}; + + ModifierKeys(std::initializer_list keys); + + template + ModifierKeys(const TArray& keys) : keys{0} + { + for (auto key : keys) + { + if (is_modify_key_valid(key)) + { + this->keys |= (1 << key); + } + } + } + + bool empty() const + { + return keys == 0; + } + }; + static constexpr uint8_t max_modifier_keys = MODIFIER_KEYS_MAX; + static_assert(max_modifier_keys < 32, "Modifier keys cannot exceed 32"); -#else - static_assert(false, "The input library only works on Windows."); -#endif + auto operator&(const ModifierKeys& keys, const ModifierKey& key) -> bool; + auto operator&(const ModifierKeys& keys, const ModifierKeys& key) -> bool; auto operator++(Input::Key& key) -> Input::Key&; } // namespace RC::Input diff --git a/deps/first/Input/include/Input/Platform/GLFW3InputSource.hpp b/deps/first/Input/include/Input/Platform/GLFW3InputSource.hpp new file mode 100644 index 000000000..333673b5f --- /dev/null +++ b/deps/first/Input/include/Input/Platform/GLFW3InputSource.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +namespace RC::Input +{ + + class GLFW3InputSource : public QueueInputSource + { + public: + auto begin_frame() -> void; + auto receive_input(int key, int action, int mods) -> void; + auto end_frame() -> void; + + private: + Key m_translate_key[512]; + + public: + auto is_available() -> bool override; + const char* get_name() override + { + return "GLFW3"; + } + GLFW3InputSource(); + }; + +} // namespace RC::Input diff --git a/deps/first/Input/include/Input/Platform/QueueInputSource.hpp b/deps/first/Input/include/Input/Platform/QueueInputSource.hpp new file mode 100644 index 000000000..b184cc9e3 --- /dev/null +++ b/deps/first/Input/include/Input/Platform/QueueInputSource.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include +#include + +#include + +namespace RC::Input +{ + class QueueInputSource : public PlatformInputSource + { + private: + static constexpr int max_inputs = 256; + RingBufferSPSC m_input_queue; + + protected: + bool m_activated{false}; + + private: + /// SAFETY: Only update and return m_input_events + /// in process_event and flush_events functions + std::vector m_input_events; + + public: + ~QueueInputSource() = default; + + // QueeueInputSource is not a implemented input source + // and should not be used directly + bool is_available() override + { + return false; + }; + + bool activate() override + { + return m_activated = true; + }; + + bool deactivate() override + { + m_activated = false; + return true; + }; + + std::vector& process_event(Handler* handler) override; + + int source_priority() override + { + return 0; + } + + const char* get_name() override + { + return "Queue"; + } + + public: + auto push_input_event(const InputEvent& event) -> void; + }; + +}; // namespace RC::Input \ No newline at end of file diff --git a/deps/first/Input/include/Input/Platform/Win32AsyncInputSource.hpp b/deps/first/Input/include/Input/Platform/Win32AsyncInputSource.hpp new file mode 100644 index 000000000..0564de08a --- /dev/null +++ b/deps/first/Input/include/Input/Platform/Win32AsyncInputSource.hpp @@ -0,0 +1,86 @@ +#pragma once + +#include +#include +#include +#include + +#include + +namespace RC::Input +{ + class Win32AsyncInputSource : public PlatformInputSource + { + private: + std::vector m_active_window_classes{}; + std::unordered_map m_modifier_keys_down{}; + bool m_any_keys_are_down{}; + bool m_activated{false}; + std::array m_key_down{}; + + private: + /// SAFETY: Only update and return m_input_events + /// in the process_event function + std::vector m_input_events{}; + + public: + template + explicit Win32AsyncInputSource(WindowClasses... window_classes) + { + static_assert(std::conjunction...>::value, "WindowClasses must be of type const wchar_t*"); + + m_modifier_keys_down.emplace(ModifierKey::SHIFT, false); + m_modifier_keys_down.emplace(ModifierKey::CONTROL, false); + m_modifier_keys_down.emplace(ModifierKey::ALT, false); + + register_window_classes(window_classes...); + } + + private: + template + auto register_window_classes(WindowClass window_class) -> void + { + m_active_window_classes.emplace_back(window_class); + } + + template + auto register_window_classes(WindowClass window_class, WindowClasses... window_classes) -> void + { + m_active_window_classes.emplace_back(window_class); + register_window_classes(window_classes...); + } + + auto are_modifier_keys_down(const std::vector&) -> bool; + auto is_program_focused() -> bool; + + public: + bool is_available() override + { + return true; + }; + + bool activate() override + { + m_key_down.fill(false); + return m_activated = true; + }; + + bool deactivate() override + { + m_activated = false; + return true; + }; + + std::vector& process_event(Handler* handler) override; + ~Win32AsyncInputSource() = default; + int source_priority() override + { + return 0; + } + + const char* get_name() override + { + return "Win32Async"; + } + }; +}; // namespace RC::Input diff --git a/deps/first/Input/include/Input/PlatformInputSource.hpp b/deps/first/Input/include/Input/PlatformInputSource.hpp new file mode 100644 index 000000000..387311b9a --- /dev/null +++ b/deps/first/Input/include/Input/PlatformInputSource.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include + +#include +#include + +namespace RC::Input +{ + + class PlatformInputSource + { + public: + /// Check if the input source is available + virtual bool is_available() + { + return false; + }; + + /// Initialize the input source + virtual bool activate() + { + return false; + }; + + /// Initialize the input source + virtual bool deactivate() + { + return false; + }; + + /// Get the priority of the input source, smaller number means higher priority + virtual int source_priority() + { + return 999; + }; + + /// Process the event and return the input events in the frame + virtual std::vector& process_event(Handler* handler) = 0; + + virtual ~PlatformInputSource() = default; + + virtual const char* get_name() + { + return "Unknown"; + } + }; + +}; // namespace RC::Input diff --git a/deps/first/Input/include/Input/RingBuffer.hpp b/deps/first/Input/include/Input/RingBuffer.hpp new file mode 100644 index 000000000..923d36ec9 --- /dev/null +++ b/deps/first/Input/include/Input/RingBuffer.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +namespace RC::Input +{ + /// SAFETY: This is ONLY a single producer, single consumer lock-free queue + template + struct RingBufferSPSC + { + T m_queue[max_buffer]; + std::atomic m_head{0}; + std::atomic m_tail{0}; + + // tail belongs to the producer + auto push(const T& event) -> bool + { + auto current_tail = m_tail.load(std::memory_order_relaxed); + int next_tail = (current_tail + 1) % max_buffer; + if (next_tail == m_head.load(std::memory_order_acquire)) + { + // Queue is full + return false; + } + + m_queue[current_tail] = event; + m_tail.store(next_tail, std::memory_order_release); + return true; + } + + // head belongs to the consumer + auto pop() -> std::optional + { + auto current_head = m_head.load(std::memory_order_relaxed); + if (current_head == m_tail.load(std::memory_order_acquire)) + { + // Queue is empty + return std::nullopt; + } + + T event = m_queue[current_head]; + m_head.store((current_head + 1) % max_buffer, std::memory_order_release); + return event; + } + }; +} // namespace RC::Input diff --git a/deps/first/Input/src/Handler.cpp b/deps/first/Input/src/Handler.cpp index 8533a9aec..0165e16ff 100644 --- a/deps/first/Input/src/Handler.cpp +++ b/deps/first/Input/src/Handler.cpp @@ -1,345 +1,209 @@ #include +#include +#include #include - -#define NOMINMAX -#include - +#include namespace RC::Input { - auto is_modifier_key_required(ModifierKey modifier_key, std::vector modifier_keys) -> bool - { - for (const auto& required_modifier_key : modifier_keys) - { - if (required_modifier_key == ModifierKey::MOD_KEY_START_OF_ENUM) - { - continue; - } - - if (modifier_key == required_modifier_key) - { - return true; - } - } - - return false; - } - - auto Handler::are_modifier_keys_down(const std::vector& required_modifier_keys) -> bool - { - bool are_required_modifier_keys_down = true; - - for (const auto& [modifier_key, modifier_key_is_down] : m_modifier_keys_down) - { - for (const auto& required_modifier_key : required_modifier_keys) - { - if (modifier_key == required_modifier_key && !modifier_key_is_down) - { - are_required_modifier_keys_down = false; - } - - if (modifier_key != required_modifier_key && modifier_key_is_down && !is_modifier_key_required(modifier_key, required_modifier_keys)) - { - return false; - } - } - } - - return are_required_modifier_keys_down; - } - - auto Handler::is_program_focused() -> bool - { - HWND hwnd = GetForegroundWindow(); - if (!hwnd) return false; - - wchar_t current_window_class_name[MAX_PATH]; - if (!GetClassNameW(hwnd, current_window_class_name, MAX_PATH)) return false; - - for (const auto& active_window_class : m_active_window_classes) - { - if (wcscmp(current_window_class_name, active_window_class) == 0) - { - return true; - } - } - - return false; - } + std::unordered_map> Handler::m_input_sources_store; auto Handler::process_event() -> void { - if (!is_program_focused()) + if (m_platform_handler == nullptr) { return; } std::vector callbacks_to_call{}; - bool skip_this_frame = !get_allow_input(); - bool is_any_modifier_keys_down = false; - bool any_keys_are_down = false; + auto events = m_platform_handler->process_event(this); - if (m_any_keys_are_down) { - skip_this_frame = true; - } - - // Check if any modifier keys are down - for (auto& [modifier_key, key_is_down] : m_modifier_keys_down) - { - if (GetAsyncKeyState(modifier_key)) - { - is_any_modifier_keys_down = true; - key_is_down = true; - } - else + // Lock the event mutex to access the key_set + auto event_update_lock = std::lock_guard(m_event_mutex); + for (auto& event : events) { - key_is_down = false; - } - } - - for (auto& key_set_data : m_key_sets) - { - for (auto& [key, key_data_array] : key_set_data.key_data) - { - for (auto& key_data : key_data_array) + auto key_set_array = m_key_set.key_data[event.key]; + for (auto& key_data : key_set_array) { - if (GetAsyncKeyState(key) && !key_data.is_down) + if (key_data.required_modifier_keys == event.modifier_keys) { - any_keys_are_down = true; - bool should_propagate = true; - - if (key_data.requires_modifier_keys) - { - if (!are_modifier_keys_down(key_data.required_modifier_keys)) - { - should_propagate = false; - } - } - - if (!key_data.requires_modifier_keys && is_any_modifier_keys_down) - { - should_propagate = false; - } - - if (should_propagate) - { - key_data.is_down = true; - for (const auto& callback : key_data.callbacks) - { - callbacks_to_call.emplace_back(callback); - } - } - } - else if (!GetAsyncKeyState(key) && key_data.is_down) - { - key_data.is_down = false; + callbacks_to_call.emplace_back(key_data.callback); } } } } - if (any_keys_are_down) - { - m_any_keys_are_down = true; - } - else - { - m_any_keys_are_down = false; - } - + // No need to lock the event mutex to call the callbacks + // this avoids key registration inside the callback for (const auto& callback : callbacks_to_call) { - if (skip_this_frame) - { - return; - } callback(); } } auto Handler::register_keydown_event(Input::Key key, EventCallbackCallable callback, uint8_t custom_data, void* custom_data2) -> void { - KeySet& key_set = [&]() -> KeySet& { - for (auto& key_set : m_key_sets) - { - if (key_set.key_data.contains(key)) - { - return key_set; - } - } - - return m_key_sets.emplace_back(KeySet{}); - }(); - - KeyData& key_data = key_set.key_data[key].emplace_back(); - key_data.callbacks.emplace_back(callback); + auto event_update_lock = std::lock_guard(m_event_mutex); + KeyData& key_data = m_key_set.key_data[key].emplace_back(); + key_data.callback = callback; key_data.custom_data = custom_data; key_data.custom_data2 = custom_data2; + m_subscribed_keys[key] = true; } auto Handler::register_keydown_event( Input::Key key, const ModifierKeyArray& modifier_keys, const EventCallbackCallable& callback, uint8_t custom_data, void* custom_data2) -> void { - KeySet& key_set = [&]() -> KeySet& { - for (auto& key_set : m_key_sets) - { - if (key_set.key_data.contains(key)) - { - return key_set; - } - } - - return m_key_sets.emplace_back(KeySet{}); - }(); - - KeyData& key_data = key_set.key_data[key].emplace_back(); - key_data.callbacks.emplace_back(callback); + auto event_update_lock = std::lock_guard(m_event_mutex); + KeyData& key_data = m_key_set.key_data[key].emplace_back(); + key_data.callback = callback; key_data.custom_data = custom_data; key_data.custom_data2 = custom_data2; key_data.requires_modifier_keys = true; + key_data.required_modifier_keys = modifier_keys; + m_subscribed_keys[key] = true; + } - for (const auto& modifier_key : modifier_keys) + auto Handler::is_keydown_event_registered(Input::Key key) -> bool + { + auto event_update_lock = std::lock_guard(m_event_mutex); + auto key_data = m_key_set.key_data.find(key); + if (key_data == m_key_set.key_data.end()) { - if (modifier_key != ModifierKey::MOD_KEY_START_OF_ENUM) + return false; + } + for (const auto& key_data_container : key_data->second) + { + if (key_data_container.required_modifier_keys.empty()) { - key_data.required_modifier_keys.emplace_back(modifier_key); + return true; } } + return false; } - auto Handler::is_keydown_event_registered(Input::Key key) -> bool + auto Handler::is_keydown_event_registered(Input::Key key, const ModifierKeyArray& modifier_keys_array) -> bool { - bool is_key_registered{}; - bool is_key_registered_with_no_modifier_keys = true; - for (const auto& key_set : m_key_sets) + auto event_update_lock = std::lock_guard(m_event_mutex); + auto key_data = m_key_set.key_data.find(key); + auto modifier_keys = ModifierKeys(modifier_keys_array); + if (key_data == m_key_set.key_data.end()) { - for (const auto& [key_registered, key_data_container] : key_set.key_data) - { - if (key_registered == key) - { - is_key_registered = true; - } - else - { - continue; - } - - for (const auto& key_data : key_data_container) - { - if (key_data.requires_modifier_keys) - { - is_key_registered_with_no_modifier_keys = false; - break; - } - } - - if (!is_key_registered_with_no_modifier_keys) - { - break; - } - } - - if (!is_key_registered_with_no_modifier_keys) + return false; + } + for (const auto& key_data_container : key_data->second) + { + if (key_data_container.required_modifier_keys == modifier_keys) { - break; + return true; } } - - return is_key_registered && is_key_registered_with_no_modifier_keys; + return false; } - auto Handler::is_keydown_event_registered(Input::Key key, const ModifierKeyArray& modifier_keys) -> bool + auto Handler::has_event_on_key(Input::Key key) -> bool { - bool is_key_registered{}; - bool all_modifier_keys_match{}; - for (const auto& key_set : m_key_sets) - { - for (const auto& [key_registered, key_data_container] : key_set.key_data) - { - if (key_registered == key) - { - is_key_registered = true; - } - else - { - continue; - } + return m_subscribed_keys[key]; + } - all_modifier_keys_match = false; - for (const auto& key_data : key_data_container) - { - if (!key_data.requires_modifier_keys && !modifier_keys.empty()) - { - all_modifier_keys_match = false; - continue; - } + auto Handler::get_events_safe(std::function callback) -> void + { + auto event_update_lock = std::lock_guard(m_event_mutex); + callback(m_key_set); + } - if (!key_data.requires_modifier_keys && modifier_keys.empty()) - { - all_modifier_keys_match = true; - break; - } + auto Handler::clear_subscribed_keys() -> void + { + m_subscribed_keys.fill(false); + } - for (const auto& modifier_key : key_data.required_modifier_keys) - { - for (const auto modifier_key_to_check : modifier_keys) - { - if (modifier_key_to_check == ModifierKey::MOD_KEY_START_OF_ENUM) - { - continue; - } + auto Handler::clear_subscribed_key(Key k) -> void + { + m_subscribed_keys[k] = false; + } - if (modifier_key_to_check == modifier_key) - { - all_modifier_keys_match = true; - } - else - { - all_modifier_keys_match = false; - } - } + auto Handler::get_allow_input() -> bool + { + return m_allow_input; + } - if (all_modifier_keys_match) - { - break; - } - } + auto Handler::set_allow_input(bool new_value) -> void + { + m_allow_input = new_value; + } - if (all_modifier_keys_match) - { - break; - } + /// Set the input source to the given source + /// SAFETY: Only call this function from the main thread + auto Handler::set_input_source(std::string source) -> bool + { + auto event_update_lock = std::lock_guard(m_event_mutex); + std::shared_ptr next_input_source = nullptr; + if (source == "Default") + { + // find the highest priority input source + int highest_priority = INT_MAX; + for (auto& input_source : m_input_sources_store) + { + if (!input_source.second->is_available()) + { + continue; } - - if (all_modifier_keys_match) + auto priority = input_source.second->source_priority(); + if (priority < highest_priority) { - break; + next_input_source = input_source.second; + highest_priority = priority; } } - - if (all_modifier_keys_match) + if (highest_priority == INT_MAX) { - break; + return false; } } - - return is_key_registered && all_modifier_keys_match; - } - - auto Handler::get_events() -> std::vector& - { - return m_key_sets; + else + { + auto input_source = m_input_sources_store.find(source); + if (input_source == m_input_sources_store.end()) + { + return false; + } + next_input_source = input_source->second; + if (!next_input_source->is_available()) + { + return false; + } + } + if (next_input_source != m_platform_handler) + { + if (m_platform_handler != nullptr) + { + m_platform_handler->deactivate(); + } + next_input_source->activate(); + m_platform_handler = next_input_source; + return true; + } + return true; } - auto Handler::get_allow_input() -> bool + // register the input source to the input source store + auto Handler::register_input_source(std::shared_ptr input_source) -> void { - return m_allow_input; + std::string name = input_source->get_name(); + if (m_input_sources_store.find(name) == m_input_sources_store.end()) + { + m_input_sources_store[name] = input_source; + } } - auto Handler::set_allow_input(bool new_value) -> void + auto Handler::get_current_input_source() -> std::string { - m_allow_input = new_value; + if (m_platform_handler == nullptr) + { + return "None"; + } + return m_platform_handler->get_name(); } } // namespace RC::Input diff --git a/deps/first/Input/src/KeyDef.cpp b/deps/first/Input/src/KeyDef.cpp index 5e73dbbc1..9057adc0f 100644 --- a/deps/first/Input/src/KeyDef.cpp +++ b/deps/first/Input/src/KeyDef.cpp @@ -1,4 +1,5 @@ #include +#include namespace RC::Input { @@ -14,4 +15,71 @@ namespace RC::Input return key; } + + auto ModifierKeys::operator|(const ModifierKeys& rkeys) -> ModifierKeys& + { + keys |= rkeys.keys; + return *this; + } + + auto ModifierKeys::operator|(const ModifierKey& key) -> ModifierKeys& + { + if (is_modify_key_valid(key)) + { + keys |= (1 << key); + } + return *this; + } + + auto ModifierKeys::operator|=(const ModifierKeys& rkeys) -> ModifierKeys& + { + return *this = *this | rkeys; + } + + auto ModifierKeys::operator|=(const ModifierKey& key) -> ModifierKeys& + { + return *this = *this | key; + } + + auto ModifierKeys::operator==(const ModifierKeys& key) const -> bool + { + return keys == key.keys; + } + + auto ModifierKeys::operator<(const ModifierKeys& rkeys) const -> bool + { + return keys < rkeys.keys; + } + + auto ModifierKeys::operator>(const ModifierKeys& rkeys) const -> bool + { + return keys > rkeys.keys; + } + + auto ModifierKeys::operator!=(const ModifierKeys& key) const -> bool + { + return keys != key.keys; + } + + ModifierKeys::ModifierKeys(std::initializer_list keys) + { + for (auto key : keys) + { + if (is_modify_key_valid(key)) + { + this->keys |= (1 << key); + } + } + } + + auto operator&(const ModifierKeys& keys, const ModifierKey& key) -> bool + { + return !!(keys.keys & (1 << key)); + } + + auto operator&(const ModifierKeys& keys, const ModifierKeys& key) -> bool + { + return !!(keys.keys & key.keys); + } + } // namespace RC::Input diff --git a/deps/first/Input/src/Platform/GLFW3InputSource.cpp b/deps/first/Input/src/Platform/GLFW3InputSource.cpp new file mode 100644 index 000000000..776276513 --- /dev/null +++ b/deps/first/Input/src/Platform/GLFW3InputSource.cpp @@ -0,0 +1,349 @@ +#include + +#define GLFW_KEY_SPACE 32 + +#define GLFW_KEY_APOSTROPHE 39 /* ' */ + +#define GLFW_KEY_COMMA 44 /* , */ + +#define GLFW_KEY_MINUS 45 /* - */ + +#define GLFW_KEY_PERIOD 46 /* . */ + +#define GLFW_KEY_SLASH 47 /* / */ + +#define GLFW_KEY_0 48 + +#define GLFW_KEY_1 49 + +#define GLFW_KEY_2 50 + +#define GLFW_KEY_3 51 + +#define GLFW_KEY_4 52 + +#define GLFW_KEY_5 53 + +#define GLFW_KEY_6 54 + +#define GLFW_KEY_7 55 + +#define GLFW_KEY_8 56 + +#define GLFW_KEY_9 57 + +#define GLFW_KEY_SEMICOLON 59 /* ; */ + +#define GLFW_KEY_EQUAL 61 /* = */ + +#define GLFW_KEY_A 65 + +#define GLFW_KEY_B 66 + +#define GLFW_KEY_C 67 + +#define GLFW_KEY_D 68 + +#define GLFW_KEY_E 69 + +#define GLFW_KEY_F 70 + +#define GLFW_KEY_G 71 + +#define GLFW_KEY_H 72 + +#define GLFW_KEY_I 73 + +#define GLFW_KEY_J 74 + +#define GLFW_KEY_K 75 + +#define GLFW_KEY_L 76 + +#define GLFW_KEY_M 77 + +#define GLFW_KEY_N 78 + +#define GLFW_KEY_O 79 + +#define GLFW_KEY_P 80 + +#define GLFW_KEY_Q 81 + +#define GLFW_KEY_R 82 + +#define GLFW_KEY_S 83 + +#define GLFW_KEY_T 84 + +#define GLFW_KEY_U 85 + +#define GLFW_KEY_V 86 + +#define GLFW_KEY_W 87 + +#define GLFW_KEY_X 88 + +#define GLFW_KEY_Y 89 + +#define GLFW_KEY_Z 90 + +#define GLFW_KEY_LEFT_BRACKET 91 /* [ */ + +#define GLFW_KEY_BACKSLASH 92 /* \ */ + +#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */ + +#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */ + +#define GLFW_KEY_WORLD_1 161 /* non-US #1 */ + +#define GLFW_KEY_WORLD_2 162 /* non-US #2 */ + +#define GLFW_KEY_ESCAPE 256 + +#define GLFW_KEY_ENTER 257 + +#define GLFW_KEY_TAB 258 + +#define GLFW_KEY_BACKSPACE 259 + +#define GLFW_KEY_INSERT 260 + +#define GLFW_KEY_DELETE 261 + +#define GLFW_KEY_RIGHT 262 + +#define GLFW_KEY_LEFT 263 + +#define GLFW_KEY_DOWN 264 + +#define GLFW_KEY_UP 265 + +#define GLFW_KEY_PAGE_UP 266 + +#define GLFW_KEY_PAGE_DOWN 267 + +#define GLFW_KEY_HOME 268 + +#define GLFW_KEY_END 269 + +#define GLFW_KEY_CAPS_LOCK 280 + +#define GLFW_KEY_SCROLL_LOCK 281 + +#define GLFW_KEY_NUM_LOCK 282 + +#define GLFW_KEY_PRINT_SCREEN 283 + +#define GLFW_KEY_PAUSE 284 + +#define GLFW_KEY_F1 290 + +#define GLFW_KEY_F2 291 + +#define GLFW_KEY_F3 292 + +#define GLFW_KEY_F4 293 + +#define GLFW_KEY_F5 294 + +#define GLFW_KEY_F6 295 + +#define GLFW_KEY_F7 296 + +#define GLFW_KEY_F8 297 + +#define GLFW_KEY_F9 298 + +#define GLFW_KEY_F10 299 + +#define GLFW_KEY_F11 300 + +#define GLFW_KEY_F12 301 + +#define GLFW_KEY_F13 302 + +#define GLFW_KEY_F14 303 + +#define GLFW_KEY_F15 304 + +#define GLFW_KEY_F16 305 + +#define GLFW_KEY_F17 306 + +#define GLFW_KEY_F18 307 + +#define GLFW_KEY_F19 308 + +#define GLFW_KEY_F20 309 + +#define GLFW_KEY_F21 310 + +#define GLFW_KEY_F22 311 + +#define GLFW_KEY_F23 312 + +#define GLFW_KEY_F24 313 + +#define GLFW_KEY_F25 314 + +#define GLFW_KEY_KP_0 320 + +#define GLFW_KEY_KP_1 321 + +#define GLFW_KEY_KP_2 322 + +#define GLFW_KEY_KP_3 323 + +#define GLFW_KEY_KP_4 324 + +#define GLFW_KEY_KP_5 325 + +#define GLFW_KEY_KP_6 326 + +#define GLFW_KEY_KP_7 327 + +#define GLFW_KEY_KP_8 328 + +#define GLFW_KEY_KP_9 329 + +#define GLFW_KEY_KP_DECIMAL 330 + +#define GLFW_KEY_KP_DIVIDE 331 + +#define GLFW_KEY_KP_MULTIPLY 332 + +#define GLFW_KEY_KP_SUBTRACT 333 + +#define GLFW_KEY_KP_ADD 334 + +#define GLFW_KEY_KP_ENTER 335 + +#define GLFW_KEY_KP_EQUAL 336 + +#define GLFW_KEY_LEFT_SHIFT 340 + +#define GLFW_KEY_LEFT_CONTROL 341 + +#define GLFW_KEY_LEFT_ALT 342 + +#define GLFW_KEY_LEFT_SUPER 343 + +#define GLFW_KEY_RIGHT_SHIFT 344 + +#define GLFW_KEY_RIGHT_CONTROL 345 + +#define GLFW_KEY_RIGHT_ALT 346 + +#define GLFW_KEY_RIGHT_SUPER 347 + +#define GLFW_KEY_MENU 348 + +#define GLFW_KEY_LAST GLFW_KEY_MENU + +#define GLFW_MOD_SHIFT 0x0001 +#define GLFW_MOD_CONTROL 0x0002 +#define GLFW_MOD_ALT 0x0004 + +#define GLFW_RELEASE 0 +#define GLFW_PRESS 1 +#define GLFW_REPEAT 2 + +namespace RC::Input +{ + auto GLFW3InputSource::begin_frame() -> void + { + } + + auto GLFW3InputSource::receive_input(int key, int action, int mods) -> void + { + auto modifier_keys = ModifierKeys{}; + modifier_keys |= (mods & GLFW_MOD_CONTROL ? ModifierKey::CONTROL : ModifierKey::MOD_KEY_START_OF_ENUM); + modifier_keys |= (mods & GLFW_MOD_SHIFT ? ModifierKey::SHIFT : ModifierKey::MOD_KEY_START_OF_ENUM); + modifier_keys |= (mods & GLFW_MOD_ALT ? ModifierKey::ALT : ModifierKey::MOD_KEY_START_OF_ENUM); + if (action == GLFW_PRESS) + { + // translate key + Key input = m_translate_key[key]; + if (input != RESERVED_START_OF_ENUM) + { + push_input_event({input, modifier_keys}); + } + } + } + + auto GLFW3InputSource::end_frame() -> void + { + } + + auto GLFW3InputSource::is_available() -> bool + { + return true; + } + + GLFW3InputSource::GLFW3InputSource() + { + // init to 0 + for (int i = 0; i < 512; ++i) + { + m_translate_key[i] = static_cast(0); + } + // Alphanumeric keys + for (int key = GLFW_KEY_A; key <= GLFW_KEY_Z; ++key) + { + m_translate_key[key] = static_cast(key); + } + for (int key = GLFW_KEY_0; key <= GLFW_KEY_9; ++key) + { + m_translate_key[key] = static_cast(key + 22); + } + + // Symbol keys + m_translate_key[GLFW_KEY_SPACE] = Key::SPACE; + m_translate_key[GLFW_KEY_APOSTROPHE] = Key::OEM_SEVEN; + m_translate_key[GLFW_KEY_COMMA] = Key::OEM_COMMA; + m_translate_key[GLFW_KEY_MINUS] = Key::OEM_MINUS; + m_translate_key[GLFW_KEY_PERIOD] = Key::OEM_PERIOD; + m_translate_key[GLFW_KEY_SLASH] = Key::OEM_TWO; + m_translate_key[GLFW_KEY_SEMICOLON] = Key::OEM_ONE; + m_translate_key[GLFW_KEY_EQUAL] = Key::OEM_PLUS; + m_translate_key[GLFW_KEY_LEFT_BRACKET] = Key::OEM_FOUR; + m_translate_key[GLFW_KEY_BACKSLASH] = Key::OEM_FIVE; + m_translate_key[GLFW_KEY_RIGHT_BRACKET] = Key::OEM_SIX; + m_translate_key[GLFW_KEY_GRAVE_ACCENT] = Key::OEM_THREE; + + // Control keys + m_translate_key[GLFW_KEY_ESCAPE] = Key::ESCAPE; + m_translate_key[GLFW_KEY_ENTER] = Key::RETURN; + m_translate_key[GLFW_KEY_TAB] = Key::TAB; + m_translate_key[GLFW_KEY_BACKSPACE] = Key::BACKSPACE; + m_translate_key[GLFW_KEY_INSERT] = Key::INS; + m_translate_key[GLFW_KEY_DELETE] = Key::DEL; + m_translate_key[GLFW_KEY_RIGHT] = Key::RIGHT_ARROW; + m_translate_key[GLFW_KEY_LEFT] = Key::LEFT_ARROW; + m_translate_key[GLFW_KEY_DOWN] = Key::DOWN_ARROW; + m_translate_key[GLFW_KEY_UP] = Key::UP_ARROW; + m_translate_key[GLFW_KEY_PAGE_UP] = Key::PAGE_UP; + m_translate_key[GLFW_KEY_PAGE_DOWN] = Key::PAGE_DOWN; + m_translate_key[GLFW_KEY_HOME] = Key::HOME; + m_translate_key[GLFW_KEY_END] = Key::END; + m_translate_key[GLFW_KEY_CAPS_LOCK] = Key::CAPS_LOCK; + m_translate_key[GLFW_KEY_SCROLL_LOCK] = Key::SCROLL_LOCK; + m_translate_key[GLFW_KEY_NUM_LOCK] = Key::NUM_LOCK; + m_translate_key[GLFW_KEY_PRINT_SCREEN] = Key::PRINT_SCREEN; + m_translate_key[GLFW_KEY_PAUSE] = Key::PAUSE; + + // Function keys + for (int key = GLFW_KEY_F1; key <= GLFW_KEY_F25; ++key) + { + m_translate_key[key] = static_cast(key + 111); + } + + // Numeric keypad + for (int key = GLFW_KEY_KP_0; key <= GLFW_KEY_KP_EQUAL; ++key) + { + m_translate_key[key] = static_cast(key + 208); + } + } +} // namespace RC::Input \ No newline at end of file diff --git a/deps/first/Input/src/Platform/QueueInputSource.cpp b/deps/first/Input/src/Platform/QueueInputSource.cpp new file mode 100644 index 000000000..f7170101e --- /dev/null +++ b/deps/first/Input/src/Platform/QueueInputSource.cpp @@ -0,0 +1,46 @@ +#include +#include + +#include + +namespace RC::Input +{ + auto QueueInputSource::push_input_event(const InputEvent& event) -> void + { + if (m_activated) + { + m_input_queue.push(event); + Output::send(SYSSTR("QueueInputSource::push_input_event: {}"), (int)event.key); + } + } + + // even if not activated, we still consume the remaining events in the queue + std::vector& QueueInputSource::process_event(Handler* handler) + { + m_input_events.clear(); + + auto event = m_input_queue.pop(); + auto& key_set = handler->get_subscribed_keys(); + while (event) + { + Output::send(SYSSTR("QueueInputSource::reveive key event: {}"), (int)event->key); + if (key_set[event->key]) + { + m_input_events.emplace_back(*event); + } + event = m_input_queue.pop(); + } + + if (!m_activated) + { + m_input_events.clear(); + } + + if (!handler->get_allow_input()) + { + m_input_events.clear(); + } + + return m_input_events; + } +}; // namespace RC::Input diff --git a/deps/first/Input/src/Platform/Win32AsyncInputSource.cpp b/deps/first/Input/src/Platform/Win32AsyncInputSource.cpp new file mode 100644 index 000000000..7169ae55f --- /dev/null +++ b/deps/first/Input/src/Platform/Win32AsyncInputSource.cpp @@ -0,0 +1,102 @@ +#include +#include +#include +#include + +#define NOMINMAX +#include + +namespace RC::Input +{ + + auto Win32AsyncInputSource::is_program_focused() -> bool + { + HWND hwnd = GetForegroundWindow(); + if (!hwnd) return false; + wchar_t current_window_class_name[MAX_PATH]; + if (!GetClassNameW(hwnd, current_window_class_name, MAX_PATH)) return false; + for (const auto& active_window_class : m_active_window_classes) + { + if (wcscmp(current_window_class_name, active_window_class) == 0) + { + return true; + } + } + return false; + } + + std::vector& Win32AsyncInputSource::process_event(Handler* handler) + { + m_input_events.clear(); + + if (!is_program_focused()) + { + return m_input_events; + } + + if (!m_activated) + { + return m_input_events; + } + + bool skip_this_frame = !handler->get_allow_input(); + + if (m_any_keys_are_down) + { + skip_this_frame = true; + } + + bool any_keys_are_down = false; + + // Check if any modifier keys are down + ModifierKeys modifier_keys{}; + for (auto& [modifier_key, key_is_down] : m_modifier_keys_down) + { + if (GetAsyncKeyState(modifier_key)) + { + modifier_keys |= modifier_key; + key_is_down = true; + } + else + { + key_is_down = false; + } + } + + auto& subscribed_keys = handler->get_subscribed_keys(); + + for (int key = 0; key < max_keys; ++key) + { + if (subscribed_keys[key]) + { + auto keyed = GetAsyncKeyState(key); + if (keyed && !m_key_down[key]) + { + any_keys_are_down = true; + m_key_down[key] = true; + m_input_events.emplace_back(InputEvent{static_cast(key), modifier_keys}); + } + else if (!keyed && m_key_down[key]) + { + m_key_down[key] = false; + } + } + } + + if (any_keys_are_down) + { + m_any_keys_are_down = true; + } + else + { + m_any_keys_are_down = false; + } + + if (skip_this_frame) + { + m_input_events.clear(); + } + return m_input_events; + } + +} // namespace RC::Input diff --git a/deps/first/Input/src/PlatformInit.cpp b/deps/first/Input/src/PlatformInit.cpp new file mode 100644 index 000000000..8bc45515a --- /dev/null +++ b/deps/first/Input/src/PlatformInit.cpp @@ -0,0 +1,12 @@ +#include +#include +#include + +namespace RC::Input +{ + auto Handler::init() -> void + { + register_input_source(std::make_shared(L"ConsoleWindowClass", L"UnrealWindow")); + register_input_source(std::make_shared()); + } +} // namespace RC::Input \ No newline at end of file diff --git a/deps/first/Input/xmake.lua b/deps/first/Input/xmake.lua index 02b2c633f..7a05cfbff 100644 --- a/deps/first/Input/xmake.lua +++ b/deps/first/Input/xmake.lua @@ -9,4 +9,12 @@ target(projectName) add_includedirs("include", { public = true }) add_headerfiles("include/**.hpp") - add_files("src/**.cpp") \ No newline at end of file + add_files("src/**.cpp|Platform/**.cpp") + + add_deps("DynamicOutput") + + if is_plat("windows") then + add_files("src/Platform/Win32AsyncInputSource.cpp") + add_files("src/Platform/GLFW3InputSource.cpp") + add_files("src/Platform/QueueInputSource.cpp") + end diff --git a/deps/first/JSON/include/JSON/Array.hpp b/deps/first/JSON/include/JSON/Array.hpp index 979b31aab..e4cd241b8 100644 --- a/deps/first/JSON/include/JSON/Array.hpp +++ b/deps/first/JSON/include/JSON/Array.hpp @@ -41,7 +41,7 @@ namespace RC::JSON public: auto new_object() -> class Object&; auto new_array() -> class Array&; - auto new_string(const StringType& value) -> void; + auto new_string(const SystemStringType& value) -> void; auto new_null() -> void; auto new_bool(bool value) -> void; @@ -87,7 +87,7 @@ namespace RC::JSON } public: - auto serialize(ShouldFormat should_format = ShouldFormat::No, int32_t* indent_level = nullptr) -> StringType override; + auto serialize(ShouldFormat should_format = ShouldFormat::No, int32_t* indent_level = nullptr) -> SystemStringType override; auto get_type() const -> Type override { return Type::Array; diff --git a/deps/first/JSON/include/JSON/Bool.hpp b/deps/first/JSON/include/JSON/Bool.hpp index 31dcfa978..fc599f6cc 100644 --- a/deps/first/JSON/include/JSON/Bool.hpp +++ b/deps/first/JSON/include/JSON/Bool.hpp @@ -23,7 +23,8 @@ namespace RC::JSON } public: - auto serialize([[maybe_unused]] ShouldFormat should_format = ShouldFormat::No, [[maybe_unused]] int32_t* indent_level = nullptr) -> StringType override; + auto serialize([[maybe_unused]] ShouldFormat should_format = ShouldFormat::No, [[maybe_unused]] int32_t* indent_level = nullptr) + -> SystemStringType override; auto get_type() const -> Type override { return Type::Bool; diff --git a/deps/first/JSON/include/JSON/Common.hpp b/deps/first/JSON/include/JSON/Common.hpp index f0aaf684f..d5f2ee70f 100644 --- a/deps/first/JSON/include/JSON/Common.hpp +++ b/deps/first/JSON/include/JSON/Common.hpp @@ -29,7 +29,7 @@ namespace RC::JSON class ScopeStack; } - auto inline indent(int32_t* indent_level, File::StringType& string) -> void + auto inline indent(int32_t* indent_level, SystemStringType& string) -> void { if (!indent_level) { @@ -38,7 +38,7 @@ namespace RC::JSON for (int32_t i = 0; i < *indent_level; ++i) { - string.append(STR(" ")); + string.append(SYSSTR(" ")); } } } // namespace RC::JSON diff --git a/deps/first/JSON/include/JSON/KeyValuePair.hpp b/deps/first/JSON/include/JSON/KeyValuePair.hpp index 208901e75..8c665ab32 100644 --- a/deps/first/JSON/include/JSON/KeyValuePair.hpp +++ b/deps/first/JSON/include/JSON/KeyValuePair.hpp @@ -5,13 +5,13 @@ namespace RC::JSON template struct TypedKeyValuePair { - const StringType& key; + const SystemStringType& key; T* value{}; }; struct KeyValuePair { - StringType key{}; + SystemStringType key{}; std::unique_ptr value{}; template @@ -126,13 +126,13 @@ type_to_string(get_type()), type_to_string(JSONElementType::static_type()))}; template struct JSONTypedKeyValuePair { - const StringType& key; + const SystemStringType& key; T* value{}; }; struct JSONKeyValuePair { - StringType key{}; + SystemStringType key{}; std::unique_ptr value{}; template @@ -191,7 +191,7 @@ type_to_string(get_type()), type_to_string(JSONElementType::static_type()))}; auto get(StringViewType key) const -> ValueType& { auto value = find_value_by_key(key); - if (!value) { throw std::runtime_error{to_string(std::format(STR("No key in JSON object with name {}"), key))}; } + if (!value) { throw std::runtime_error{to_string(std::format(SYSSTR("No key in JSON object with name {}"), key))}; } return *static_cast(value); } @@ -199,7 +199,7 @@ type_to_string(get_type()), type_to_string(JSONElementType::static_type()))}; auto get(StringViewType key) -> ValueType& { auto value = find_value_by_key(key); - if (!value) { throw std::runtime_error{to_string(std::format(STR("No key in JSON object with name {}"), key))}; } + if (!value) { throw std::runtime_error{to_string(std::format(SYSSTR("No key in JSON object with name {}"), key))}; } return *static_cast(value); } }; @@ -222,16 +222,16 @@ type_to_string(get_type()), type_to_string(JSONElementType::static_type()))}; struct JSONString : JSONElementBase { private: - StringType value{}; + SystemStringType value{}; public: JSONString() = default; - JSONString(StringType value) : value(std::move(value)) { } + JSONString(SystemStringType value) : value(std::move(value)) { } public: constexpr static auto static_type() -> JSONElementType { return JSONElementType::String; } - auto get() -> StringType& { return value; } - auto get() const -> const StringType& { return value; } + auto get() -> SystemStringType& { return value; } + auto get() const -> const SystemStringType& { return value; } auto get_view() -> StringViewType { return value; } auto get_view() const -> StringViewType { return value; } auto get_type() const -> JSONElementType override { return JSONElementType::String; } diff --git a/deps/first/JSON/include/JSON/Null.hpp b/deps/first/JSON/include/JSON/Null.hpp index 17943bf1f..d23353a2e 100644 --- a/deps/first/JSON/include/JSON/Null.hpp +++ b/deps/first/JSON/include/JSON/Null.hpp @@ -13,7 +13,8 @@ namespace RC::JSON ~Null() override = default; public: - auto serialize([[maybe_unused]] ShouldFormat should_format = ShouldFormat::No, [[maybe_unused]] int32_t* indent_level = nullptr) -> StringType override; + auto serialize([[maybe_unused]] ShouldFormat should_format = ShouldFormat::No, [[maybe_unused]] int32_t* indent_level = nullptr) + -> SystemStringType override; auto get_type() const -> Type override { return Type::Null; diff --git a/deps/first/JSON/include/JSON/Number.hpp b/deps/first/JSON/include/JSON/Number.hpp index 897b60e99..59a876d15 100644 --- a/deps/first/JSON/include/JSON/Number.hpp +++ b/deps/first/JSON/include/JSON/Number.hpp @@ -167,7 +167,8 @@ namespace RC::JSON } public: - auto serialize([[maybe_unused]] ShouldFormat should_format = ShouldFormat::No, [[maybe_unused]] int32_t* indent_level = nullptr) -> StringType override; + auto serialize([[maybe_unused]] ShouldFormat should_format = ShouldFormat::No, [[maybe_unused]] int32_t* indent_level = nullptr) + -> SystemStringType override; auto get_type() const -> JSON::Type override { return JSON::Type::Number; diff --git a/deps/first/JSON/include/JSON/Object.hpp b/deps/first/JSON/include/JSON/Object.hpp index f3f5dd609..207225cc9 100644 --- a/deps/first/JSON/include/JSON/Object.hpp +++ b/deps/first/JSON/include/JSON/Object.hpp @@ -30,7 +30,7 @@ namespace RC::JSON #pragma warning(disable : 4251) private: - std::unordered_map> m_members{}; + std::unordered_map> m_members{}; IsGlobalObject m_is_global_object{IsGlobalObject::No}; #pragma warning(default : 4251) @@ -44,17 +44,17 @@ namespace RC::JSON auto operator=(const Object&) -> Object& = delete; private: - auto find_value_by_key(const StringType& key) const -> Value*; - auto find_value_by_key(const StringType& key) -> Value*; + auto find_value_by_key(const SystemStringType& key) const -> Value*; + auto find_value_by_key(const SystemStringType& key) -> Value*; public: - auto new_object(StringType name) -> Object&; - auto new_array(StringType name) -> class Array&; - auto new_string(StringType name, const StringType& value) -> void; - auto new_null(StringType name) -> void; - auto new_bool(StringType name, bool value) -> void; + auto new_object(SystemStringType name) -> Object&; + auto new_array(SystemStringType name) -> class Array&; + auto new_string(SystemStringType name, const SystemStringType& value) -> void; + auto new_null(SystemStringType name) -> void; + auto new_bool(SystemStringType name, bool value) -> void; - auto add_object(StringType name, std::unique_ptr) -> void; + auto add_object(SystemStringType name, std::unique_ptr) -> void; auto get() -> decltype(m_members)& { @@ -66,34 +66,34 @@ namespace RC::JSON }; template - auto get(const StringType& key) const -> ValueType& + auto get(const SystemStringType& key) const -> ValueType& { auto value = find_value_by_key(key); if (!value) { - throw std::runtime_error{to_string(std::format(STR("No key in JSON object with name {}"), key))}; + throw std::runtime_error{to_string(std::format(SYSSTR("No key in JSON object with name {}"), key))}; } return *static_cast(value); } template - auto get(const StringType& key) -> ValueType& + auto get(const SystemStringType& key) -> ValueType& { auto value = find_value_by_key(key); if (!value) { - throw std::runtime_error{to_string(std::format(STR("No key in JSON object with name {}"), key))}; + throw std::runtime_error{to_string(std::format(SYSSTR("No key in JSON object with name {}"), key))}; } return *static_cast(value); } template - auto new_number(StringType name, number_type value) -> void + auto new_number(SystemStringType name, number_type value) -> void { m_members.emplace(std::move(name), std::make_unique(value)); } - auto serialize(ShouldFormat should_format = ShouldFormat::No, int32_t* indent_level = nullptr) -> StringType override; + auto serialize(ShouldFormat should_format = ShouldFormat::No, int32_t* indent_level = nullptr) -> SystemStringType override; auto get_type() const -> Type override { return Type::Object; diff --git a/deps/first/JSON/include/JSON/Parser/Parser.hpp b/deps/first/JSON/include/JSON/Parser/Parser.hpp index a3324df5d..5efa7f690 100644 --- a/deps/first/JSON/include/JSON/Parser/Parser.hpp +++ b/deps/first/JSON/include/JSON/Parser/Parser.hpp @@ -10,6 +10,7 @@ namespace RC::JSON::Parser { - RC_JSON_API auto parse(StringType& input) -> std::unique_ptr; + RC_JSON_API auto parse(File::StringType& input) -> std::unique_ptr; + RC_JSON_API auto parse(UEStringType& input) -> std::unique_ptr; RC_JSON_API auto parse(const File::Handle&) -> std::unique_ptr; } // namespace RC::JSON::Parser diff --git a/deps/first/JSON/include/JSON/Parser/TokenParser.hpp b/deps/first/JSON/include/JSON/Parser/TokenParser.hpp index b28cdc9d4..35e003afa 100644 --- a/deps/first/JSON/include/JSON/Parser/TokenParser.hpp +++ b/deps/first/JSON/include/JSON/Parser/TokenParser.hpp @@ -79,7 +79,7 @@ namespace RC::JSON::Parser } } template - auto add_element_to_top(StringType key, std::unique_ptr value) -> ValueType* + auto add_element_to_top(SystemStringType key, std::unique_ptr value) -> ValueType* { auto& top = peek_top(); if (top.is()) @@ -107,7 +107,7 @@ namespace RC::JSON::Parser private: std::unique_ptr m_global_object; ScopeStack m_scope_stack{}; - StringType m_last_key{}; + SystemStringType m_last_key{}; std::unique_ptr m_last_value{}; State m_current_state{State::StartOfFile}; TokenType m_expected_token{}; @@ -115,7 +115,7 @@ namespace RC::JSON::Parser bool m_defer_element_creation{}; public: - TokenParser(const ParserBase::Tokenizer& tokenizer, File::StringType& input) : ParserBase::TokenParser(tokenizer, input) + TokenParser(const ParserBase::Tokenizer& tokenizer, SystemStringType& input) : ParserBase::TokenParser(tokenizer, input) { } virtual ~TokenParser() = default; diff --git a/deps/first/JSON/include/JSON/String.hpp b/deps/first/JSON/include/JSON/String.hpp index c3edc1fd9..f62602ddf 100644 --- a/deps/first/JSON/include/JSON/String.hpp +++ b/deps/first/JSON/include/JSON/String.hpp @@ -14,25 +14,25 @@ namespace RC::JSON RC_JSON_API constexpr static Type static_type = Type::String; private: - StringType m_data{}; + SystemStringType m_data{}; public: RC_JSON_API String() = default; - RC_JSON_API explicit String(StringViewType string); + RC_JSON_API explicit String(SystemStringViewType string); RC_JSON_API ~String() override = default; public: - RC_JSON_API auto get() -> StringType& + RC_JSON_API auto get() -> SystemStringType& { return m_data; } - RC_JSON_API auto get_view() const -> StringViewType + RC_JSON_API auto get_view() const -> SystemStringViewType { return m_data; } public: - RC_JSON_API auto serialize(ShouldFormat should_format = ShouldFormat::No, int32_t* indent_level = nullptr) -> StringType override; + RC_JSON_API auto serialize(ShouldFormat should_format = ShouldFormat::No, int32_t* indent_level = nullptr) -> SystemStringType override; RC_JSON_API auto get_type() const -> Type override { return Type::String; diff --git a/deps/first/JSON/include/JSON/Value.hpp b/deps/first/JSON/include/JSON/Value.hpp index 5914d163f..e7fa78b18 100644 --- a/deps/first/JSON/include/JSON/Value.hpp +++ b/deps/first/JSON/include/JSON/Value.hpp @@ -50,7 +50,7 @@ namespace RC::JSON virtual ~Value() = default; public: - virtual auto serialize(ShouldFormat, int32_t* indent_level) -> StringType = 0; + virtual auto serialize(ShouldFormat, int32_t* indent_level) -> SystemStringType = 0; virtual auto get_type() const -> Type = 0; public: diff --git a/deps/first/JSON/src/Array.cpp b/deps/first/JSON/src/Array.cpp index 0f02e46f9..413d103f8 100644 --- a/deps/first/JSON/src/Array.cpp +++ b/deps/first/JSON/src/Array.cpp @@ -16,7 +16,7 @@ namespace RC::JSON return static_cast(*m_members.emplace_back(std::make_unique())); } - auto Array::new_string(const StringType& value) -> void + auto Array::new_string(const SystemStringType& value) -> void { m_members.emplace_back(std::make_unique(value)); } @@ -36,22 +36,22 @@ namespace RC::JSON m_members.emplace_back(std::move(object)); } - auto Array::serialize(ShouldFormat should_format, int32_t* indent_level) -> StringType + auto Array::serialize(ShouldFormat should_format, int32_t* indent_level) -> SystemStringType { if (!indent_level) { throw std::runtime_error{"Must supply an indent_level pointer"}; }; - StringType array_as_string{}; + SystemStringType array_as_string{}; if (should_format == ShouldFormat::Yes && !m_members.empty()) { - array_as_string.append(STR("[\n")); + array_as_string.append(SYSSTR("[\n")); } else { - array_as_string.append(STR("[")); + array_as_string.append(SYSSTR("[")); } ++(*indent_level); @@ -70,11 +70,11 @@ namespace RC::JSON { if (should_format == ShouldFormat::Yes) { - array_as_string.append(STR(",\n")); + array_as_string.append(SYSSTR(",\n")); } else { - array_as_string.append(STR(",")); + array_as_string.append(SYSSTR(",")); } } @@ -85,13 +85,13 @@ namespace RC::JSON if (should_format == ShouldFormat::Yes && !m_members.empty()) { - array_as_string.append(STR("\n")); + array_as_string.append(SYSSTR("\n")); indent(indent_level, array_as_string); - array_as_string.append(STR("]")); + array_as_string.append(SYSSTR("]")); } else { - array_as_string.append(STR("]")); + array_as_string.append(SYSSTR("]")); } if (!m_members.empty()) diff --git a/deps/first/JSON/src/Bool.cpp b/deps/first/JSON/src/Bool.cpp index 79ff91871..62b894131 100644 --- a/deps/first/JSON/src/Bool.cpp +++ b/deps/first/JSON/src/Bool.cpp @@ -6,10 +6,10 @@ namespace RC::JSON { } - auto Bool::serialize(ShouldFormat should_format, int32_t* indent_level) -> StringType + auto Bool::serialize(ShouldFormat should_format, int32_t* indent_level) -> SystemStringType { (void)should_format; (void)indent_level; - return m_underlying_value ? STR("true") : STR("false"); + return m_underlying_value ? SYSSTR("true") : SYSSTR("false"); } } // namespace RC::JSON diff --git a/deps/first/JSON/src/Null.cpp b/deps/first/JSON/src/Null.cpp index 867dd612c..0cbda75f9 100644 --- a/deps/first/JSON/src/Null.cpp +++ b/deps/first/JSON/src/Null.cpp @@ -2,10 +2,10 @@ namespace RC::JSON { - auto Null::serialize(ShouldFormat should_format, int32_t* indent_level) -> StringType + auto Null::serialize(ShouldFormat should_format, int32_t* indent_level) -> SystemStringType { (void)should_format; (void)indent_level; - return STR("null"); + return SYSSTR("null"); } } // namespace RC::JSON diff --git a/deps/first/JSON/src/Number.cpp b/deps/first/JSON/src/Number.cpp index 4628a8948..eb97ade3b 100644 --- a/deps/first/JSON/src/Number.cpp +++ b/deps/first/JSON/src/Number.cpp @@ -42,7 +42,7 @@ namespace RC::JSON m_stored_type = Type::Double; } - auto Number::serialize(ShouldFormat should_format, int32_t* indent_level) -> StringType + auto Number::serialize(ShouldFormat should_format, int32_t* indent_level) -> SystemStringType { (void)should_format; (void)indent_level; diff --git a/deps/first/JSON/src/Object.cpp b/deps/first/JSON/src/Object.cpp index e4c1c265b..172ed07cd 100644 --- a/deps/first/JSON/src/Object.cpp +++ b/deps/first/JSON/src/Object.cpp @@ -6,7 +6,7 @@ namespace RC::JSON { - auto Object::find_value_by_key(const StringType& look_for_key) const -> Value* + auto Object::find_value_by_key(const SystemStringType& look_for_key) const -> Value* { if (auto it = m_members.find(look_for_key); it != m_members.end()) { @@ -17,7 +17,7 @@ namespace RC::JSON return nullptr; } } - auto Object::find_value_by_key(const StringType& look_for_key) -> Value* + auto Object::find_value_by_key(const SystemStringType& look_for_key) -> Value* { if (auto it = m_members.find(look_for_key); it != m_members.end()) { @@ -29,52 +29,52 @@ namespace RC::JSON } } - auto Object::new_object(StringType name) -> Object& + auto Object::new_object(SystemStringType name) -> Object& { return *static_cast(m_members.emplace(std::move(name), std::make_unique()).first->second.get()); } - auto Object::new_array(StringType name) -> Array& + auto Object::new_array(SystemStringType name) -> Array& { return *static_cast(m_members.emplace(std::move(name), std::make_unique()).first->second.get()); } - auto Object::new_string(StringType name, const StringType& value) -> void + auto Object::new_string(SystemStringType name, const SystemStringType& value) -> void { m_members.emplace(std::move(name), std::make_unique(value)); } - auto Object::new_null(StringType name) -> void + auto Object::new_null(SystemStringType name) -> void { m_members.emplace(std::move(name), std::make_unique()); } - auto Object::new_bool(StringType name, bool value) -> void + auto Object::new_bool(SystemStringType name, bool value) -> void { m_members.emplace(std::move(name), std::make_unique(value)); } - auto Object::add_object(StringType name, std::unique_ptr object) -> void + auto Object::add_object(SystemStringType name, std::unique_ptr object) -> void { m_members.emplace(std::move(name), std::move(object)); } - auto Object::serialize(ShouldFormat should_format, int32_t* indent_level) -> StringType + auto Object::serialize(ShouldFormat should_format, int32_t* indent_level) -> SystemStringType { if (!indent_level) { throw std::runtime_error{"Must supply an indent_level pointer"}; }; - StringType object_as_string{}; + SystemStringType object_as_string{}; if (should_format == ShouldFormat::Yes && !m_members.empty()) { - object_as_string.append(STR("{\n")); + object_as_string.append(SYSSTR("{\n")); } else { - object_as_string.append(STR("{")); + object_as_string.append(SYSSTR("{")); } ++(*indent_level); @@ -87,18 +87,18 @@ namespace RC::JSON indent(indent_level, object_as_string); } - object_as_string.append(std::format(STR("\"{}\":"), key)); + object_as_string.append(std::format(SYSSTR("\"{}\":"), key)); object_as_string.append(value->serialize(should_format, indent_level)); if (member_count + 1 < m_members.size()) { if (should_format == ShouldFormat::Yes) { - object_as_string.append(STR(",\n")); + object_as_string.append(SYSSTR(",\n")); } else { - object_as_string.append(STR(",")); + object_as_string.append(SYSSTR(",")); } } @@ -109,13 +109,13 @@ namespace RC::JSON if (should_format == ShouldFormat::Yes && !m_members.empty()) { - object_as_string.append(STR("\n")); + object_as_string.append(SYSSTR("\n")); indent(indent_level, object_as_string); - object_as_string.append(STR("}")); + object_as_string.append(SYSSTR("}")); } else { - object_as_string.append(STR("}")); + object_as_string.append(SYSSTR("}")); } if (!m_members.empty() || m_is_global_object == IsGlobalObject::Yes) diff --git a/deps/first/JSON/src/Parser/Parser.cpp b/deps/first/JSON/src/Parser/Parser.cpp index 4dbc3beff..96ba288ac 100644 --- a/deps/first/JSON/src/Parser/Parser.cpp +++ b/deps/first/JSON/src/Parser/Parser.cpp @@ -11,28 +11,28 @@ namespace RC::JSON::Parser { ParserBase::TokenContainer tc; - tc.add(ParserBase::Token::create(TokenType::CarriageReturn, STR("CarriageReturn"), STR("\r"))); - tc.add(ParserBase::Token::create(TokenType::NewLine, STR("NewLine"), STR("\n"))); - tc.add(ParserBase::Token::create(TokenType::DoubleQuote, STR("DoubleQuote"), STR("\""))); + tc.add(ParserBase::Token::create(TokenType::CarriageReturn, SYSSTR("CarriageReturn"), SYSSTR("\r"))); + tc.add(ParserBase::Token::create(TokenType::NewLine, SYSSTR("NewLine"), SYSSTR("\n"))); + tc.add(ParserBase::Token::create(TokenType::DoubleQuote, SYSSTR("DoubleQuote"), SYSSTR("\""))); tc.add(ParserBase::Token::create(TokenType::Characters, - STR("Characters"), - STR(""), + SYSSTR("Characters"), + SYSSTR(""), ParserBase::Token::HasData::Yes)); // Empty identifier will match everything that no other token identifier matches - tc.add(ParserBase::Token::create(TokenType::ClosingCurlyBrace, STR("ClosingCurlyBrace"), STR("}"))); - tc.add(ParserBase::Token::create(TokenType::OpeningCurlyBrace, STR("OpeningCurlyBrace"), STR("{"))); - tc.add(ParserBase::Token::create(TokenType::ClosingSquareBracket, STR("ClosingSquareBracket"), STR("]"))); - tc.add(ParserBase::Token::create(TokenType::OpeningSquareBracket, STR("OpeningSquareBracket"), STR("["))); - tc.add(ParserBase::Token::create(TokenType::Comma, STR("Comma"), STR(","))); - tc.add(ParserBase::Token::create(TokenType::Colon, STR("Colon"), STR(":"))); - tc.add(ParserBase::Token::create(TokenType::True, STR("True"), STR("true"))); - tc.add(ParserBase::Token::create(TokenType::False, STR("False"), STR("false"))); + tc.add(ParserBase::Token::create(TokenType::ClosingCurlyBrace, SYSSTR("ClosingCurlyBrace"), SYSSTR("}"))); + tc.add(ParserBase::Token::create(TokenType::OpeningCurlyBrace, SYSSTR("OpeningCurlyBrace"), SYSSTR("{"))); + tc.add(ParserBase::Token::create(TokenType::ClosingSquareBracket, SYSSTR("ClosingSquareBracket"), SYSSTR("]"))); + tc.add(ParserBase::Token::create(TokenType::OpeningSquareBracket, SYSSTR("OpeningSquareBracket"), SYSSTR("["))); + tc.add(ParserBase::Token::create(TokenType::Comma, SYSSTR("Comma"), SYSSTR(","))); + tc.add(ParserBase::Token::create(TokenType::Colon, SYSSTR("Colon"), SYSSTR(":"))); + tc.add(ParserBase::Token::create(TokenType::True, SYSSTR("True"), SYSSTR("true"))); + tc.add(ParserBase::Token::create(TokenType::False, SYSSTR("False"), SYSSTR("false"))); tc.set_eof_token(TokenType::EndOfFile); return tc; } - static auto parse_internal(File::StringType& input) -> std::unique_ptr + static auto parse_internal(SystemStringType& input) -> std::unique_ptr { // Tokenize -> START ParserBase::Tokenizer tokenizer; @@ -56,12 +56,19 @@ namespace RC::JSON::Parser auto parse(File::StringType& input) -> std::unique_ptr { - return Internal::parse_internal(input); + auto sys_input = to_system(input); + return Internal::parse_internal(sys_input); + } + + auto parse(UEStringType& input) -> std::unique_ptr + { + auto sys_input = to_system(input); + return Internal::parse_internal(sys_input); } auto parse(const File::Handle& file) -> std::unique_ptr { - auto input = file.read_all(); + auto input = to_system_string(file.read_file_all()); return Internal::parse_internal(input); } } // namespace RC::JSON::Parser diff --git a/deps/first/JSON/src/Parser/TokenParser.cpp b/deps/first/JSON/src/Parser/TokenParser.cpp index df0b83912..cdb495d74 100644 --- a/deps/first/JSON/src/Parser/TokenParser.cpp +++ b/deps/first/JSON/src/Parser/TokenParser.cpp @@ -32,17 +32,11 @@ namespace RC::JSON::Parser throw std::runtime_error{e}; \ } - static auto is_number(StringViewType data) -> bool + static auto is_number(SystemStringViewType data) -> bool { - return std::ranges::all_of(data.begin(), data.end(), [&](const CharType c) { - if constexpr (std::is_same_v) - { - return std::iswdigit(c) != 0; - } - else - { - return std::isdigit(c) != 0; - } + return std::ranges::all_of(data.begin(), data.end(), [&](const SystemCharType c) { + // SystemChar might be a wchar_t or char, wchar_t should be large enough to hold all possible characters. + return std::iswdigit((wchar_t)c) != 0; }); } @@ -71,10 +65,10 @@ namespace RC::JSON::Parser return m_storage.back(); } - static auto has_only_spaces(const File::StringType& data) -> bool + static auto has_only_spaces(const SystemStringType& data) -> bool { - return std::all_of(data.begin(), data.end(), [](File::CharType c) { - return std::isspace(c) || c == '\n'; + return std::all_of(data.begin(), data.end(), [](SystemCharType c) { + return std::iswspace(c) || c == SYSSTR('\n'); }); } @@ -171,7 +165,7 @@ namespace RC::JSON::Parser else if (m_current_state == State::ReadValue) { auto data_raw = get_data(token); - StringType data_no_spaces = data_raw; + SystemStringType data_no_spaces = data_raw; data_no_spaces.erase(std::remove_if(data_no_spaces.begin(), data_no_spaces.end(), [](wchar_t c) { diff --git a/deps/first/JSON/src/String.cpp b/deps/first/JSON/src/String.cpp index 5001c7c2c..6a89d1165 100644 --- a/deps/first/JSON/src/String.cpp +++ b/deps/first/JSON/src/String.cpp @@ -2,12 +2,12 @@ namespace RC::JSON { - String::String(StringViewType string) : m_data(string) + String::String(SystemStringViewType string) : m_data(string) { } - auto String::serialize([[maybe_unused]] ShouldFormat should_format, [[maybe_unused]] int32_t* indent_level) -> StringType + auto String::serialize([[maybe_unused]] ShouldFormat should_format, [[maybe_unused]] int32_t* indent_level) -> SystemStringType { - return std::format(STR("\"{}\""), m_data); + return std::format(SYSSTR("\"{}\""), m_data); } } // namespace RC::JSON diff --git a/deps/first/ParserBase/include/ParserBase/Token.hpp b/deps/first/ParserBase/include/ParserBase/Token.hpp index 35c12ccd8..39c31c25b 100644 --- a/deps/first/ParserBase/include/ParserBase/Token.hpp +++ b/deps/first/ParserBase/include/ParserBase/Token.hpp @@ -12,20 +12,20 @@ namespace RC::ParserBase class TokenRule { private: - File::StringType m_debug_name; + SystemStringType m_debug_name; public: - explicit TokenRule(File::StringViewType rule_name) : m_debug_name(rule_name) + explicit TokenRule(SystemStringViewType rule_name) : m_debug_name(rule_name) { } virtual ~TokenRule() = default; public: - RC_PB_API virtual auto exec(const class Token& token, const File::CharType* start_of_token, size_t current_cursor_location, class Tokenizer&) -> int = 0; + RC_PB_API virtual auto exec(const class Token& token, const SystemCharType* start_of_token, size_t current_cursor_location, class Tokenizer&) -> int = 0; - [[nodiscard]] RC_PB_API virtual auto to_string() const -> File::StringType + [[nodiscard]] RC_PB_API virtual auto to_string() const -> SystemStringType { - return STR("BaseTokenRule (invalid)"); + return SYSSTR("BaseTokenRule (invalid)"); } }; @@ -42,8 +42,8 @@ namespace RC::ParserBase }; private: - File::StringType m_debug_name; - File::StringType m_identifier; + SystemStringType m_debug_name; + SystemStringType m_identifier; std::vector> m_rules; int m_type; // To be cast to an enum before use. This is to avoid using a template which forces everything to be in the header file. mutable size_t m_start{}; @@ -53,7 +53,7 @@ namespace RC::ParserBase HasData m_has_data; public: - RC_PB_API Token(int type, File::StringViewType name, File::StringViewType identifier, HasData has_data = HasData::No); + RC_PB_API Token(int type, SystemStringViewType name, SystemStringViewType identifier, HasData has_data = HasData::No); public: RC_PB_API auto get_type() const -> int; @@ -63,7 +63,7 @@ namespace RC::ParserBase RC_PB_API auto get_start() const -> size_t; RC_PB_API auto set_end(size_t) -> void; RC_PB_API auto get_end() const -> size_t; - RC_PB_API auto get_identifier() const -> File::StringViewType; + RC_PB_API auto get_identifier() const -> SystemStringViewType; RC_PB_API auto get_line() const -> size_t; RC_PB_API auto get_column() const -> size_t; @@ -74,7 +74,7 @@ namespace RC::ParserBase } RC_PB_API auto get_rules() const -> const std::vector>&; - [[nodiscard]] RC_PB_API auto to_string() const -> File::StringType; + [[nodiscard]] RC_PB_API auto to_string() const -> SystemStringType; public: template @@ -92,10 +92,10 @@ namespace RC::ParserBase create_internal(token); } - RC_PB_API auto static create(int type, File::StringViewType name, File::StringViewType identifier, HasData = HasData::No) -> Token; + RC_PB_API auto static create(int type, SystemStringViewType name, SystemStringViewType identifier, HasData = HasData::No) -> Token; template - auto static create(int type, File::StringViewType name, File::StringViewType identifier, HasData has_data = HasData::No) -> Token + auto static create(int type, SystemStringViewType name, SystemStringViewType identifier, HasData has_data = HasData::No) -> Token { Token token{type, name, identifier, has_data}; create_internal(token); @@ -103,7 +103,7 @@ namespace RC::ParserBase } template - auto static create(int type, File::StringViewType name, File::StringViewType identifier, HasData has_data = HasData::No) -> Token + auto static create(int type, SystemStringViewType name, SystemStringViewType identifier, HasData has_data = HasData::No) -> Token { Token token{type, name, identifier, has_data}; create_internal(token); diff --git a/deps/first/ParserBase/include/ParserBase/TokenParser.hpp b/deps/first/ParserBase/include/ParserBase/TokenParser.hpp index 708d4a743..2bd3a306b 100644 --- a/deps/first/ParserBase/include/ParserBase/TokenParser.hpp +++ b/deps/first/ParserBase/include/ParserBase/TokenParser.hpp @@ -34,7 +34,7 @@ namespace RC::ParserBase private: const class Tokenizer& m_tokenizer; - mutable File::StringType m_data; + mutable SystemStringType m_data; protected: mutable size_t m_current_token_index_being_parsed{0}; @@ -42,7 +42,7 @@ namespace RC::ParserBase public: // Investigate whether I want to std::move the input here - RC_PB_API TokenParser(const class Tokenizer&, File::StringType& input); + RC_PB_API TokenParser(const class Tokenizer&, SystemStringType& input); RC_PB_API virtual ~TokenParser() = default; protected: @@ -61,7 +61,7 @@ namespace RC::ParserBase protected: RC_PB_API auto get_token(size_t index) const -> const class Token&; - RC_PB_API auto get_data(const class Token&) const -> const File::StringType; + RC_PB_API auto get_data(const class Token&) const -> const SystemStringType; // auto find_token_with_data(int token_type, File::StringViewType data) const -> std::optional>; diff --git a/deps/first/ParserBase/include/ParserBase/Tokenizer.hpp b/deps/first/ParserBase/include/ParserBase/Tokenizer.hpp index 1ea87a5f7..8812f1ddb 100644 --- a/deps/first/ParserBase/include/ParserBase/Tokenizer.hpp +++ b/deps/first/ParserBase/include/ParserBase/Tokenizer.hpp @@ -43,7 +43,7 @@ namespace RC::ParserBase public: RC_PB_API auto set_available_tokens(TokenContainer&&) -> void; // TODO: Maybe the constructor should take the input instead of 'tokenize' - RC_PB_API auto tokenize(const File::StringType& input) -> void; + RC_PB_API auto tokenize(const SystemStringType& input) -> void; [[nodiscard]] RC_PB_API auto get_tokens() const -> const std::vector&; [[nodiscard]] RC_PB_API auto get_last_token() const -> const Token&; }; diff --git a/deps/first/ParserBase/src/Token.cpp b/deps/first/ParserBase/src/Token.cpp index 1a11b8d12..386816ec8 100644 --- a/deps/first/ParserBase/src/Token.cpp +++ b/deps/first/ParserBase/src/Token.cpp @@ -2,7 +2,7 @@ namespace RC::ParserBase { - Token::Token(int type, File::StringViewType name, File::StringViewType identifier, Token::HasData has_data) + Token::Token(int type, SystemStringViewType name, SystemStringViewType identifier, Token::HasData has_data) : m_debug_name(name), m_identifier(identifier), m_type(type), m_has_data(has_data) { } @@ -42,7 +42,7 @@ namespace RC::ParserBase return m_end; } - auto Token::get_identifier() const -> File::StringViewType + auto Token::get_identifier() const -> SystemStringViewType { return m_identifier; } @@ -62,12 +62,12 @@ namespace RC::ParserBase return m_rules; } - auto Token::to_string() const -> File::StringType + auto Token::to_string() const -> SystemStringType { return m_debug_name; } - auto Token::create(int type, File::StringViewType name, File::StringViewType identifier, HasData has_data) -> Token + auto Token::create(int type, SystemStringViewType name, SystemStringViewType identifier, HasData has_data) -> Token { Token token{type, name, identifier, has_data}; return token; diff --git a/deps/first/ParserBase/src/TokenParser.cpp b/deps/first/ParserBase/src/TokenParser.cpp index 5e75b9d19..750ca15eb 100644 --- a/deps/first/ParserBase/src/TokenParser.cpp +++ b/deps/first/ParserBase/src/TokenParser.cpp @@ -2,9 +2,11 @@ #include #include +#include + namespace RC::ParserBase { - TokenParser::TokenParser(const Tokenizer& tokenizer, File::StringType& input) : m_tokenizer(tokenizer), m_data(input) + TokenParser::TokenParser(const Tokenizer& tokenizer, SystemStringType& input) : m_tokenizer(tokenizer), m_data(input) { } @@ -13,7 +15,7 @@ namespace RC::ParserBase return m_tokenizer.get_tokens()[index]; } - auto TokenParser::get_data(const Token& token) const -> const File::StringType + auto TokenParser::get_data(const Token& token) const -> const SystemStringType { if (!token.has_data()) { diff --git a/deps/first/ParserBase/src/Tokenizer.cpp b/deps/first/ParserBase/src/Tokenizer.cpp index 40e57bfec..68630bbf1 100644 --- a/deps/first/ParserBase/src/Tokenizer.cpp +++ b/deps/first/ParserBase/src/Tokenizer.cpp @@ -41,7 +41,7 @@ namespace RC::ParserBase m_token_container = std::move(token_container); } - auto Tokenizer::tokenize(const File::StringType& input) -> void + auto Tokenizer::tokenize(const SystemStringType& input) -> void { // printf_s("Tokenizer::tokenize()\n\n"); @@ -75,12 +75,12 @@ namespace RC::ParserBase throw std::runtime_error{"[Tokenizer::tokenize] Input was empty"}; } - File::StringType a; + SystemStringType a; - const File::CharType* input_array = input.c_str(); + const SystemCharType* input_array = input.c_str(); size_t global_cursor{}; - auto peek = [&](File::StringType& out_str, const File::CharType* character, size_t num_chars) -> void { + auto peek = [&](SystemStringType& out_str, const SystemCharType* character, size_t num_chars) -> void { if (global_cursor + num_chars <= input.size()) { for (size_t i = 0; i < num_chars; ++i) @@ -97,12 +97,12 @@ namespace RC::ParserBase bool matched_anything{false}; }; - File::StringType current_empty_token{}; - File::StringType empty_token_data{}; + SystemStringType current_empty_token{}; + SystemStringType empty_token_data{}; TokenFoundWrapper empty_token{}; size_t start_of_empty_token{}; bool start_of_empty_token_set{}; - const File::CharType* c = input_array; + const SystemCharType* c = input_array; auto deal_with_possible_empty_token = [&]() { if (empty_token.token) @@ -137,8 +137,8 @@ namespace RC::ParserBase int advance_cursor_by{-1}; bool all_rules_obeyed{true}; - File::StringViewType identifier_to_find = token.get_identifier(); - File::StringType compare_to; + SystemStringViewType identifier_to_find = token.get_identifier(); + SystemStringType compare_to; size_t identifier_size = identifier_to_find.size(); peek(compare_to, c, identifier_size); bool identifier_should_match_all = identifier_to_find.empty(); @@ -213,7 +213,7 @@ namespace RC::ParserBase // This is required because the loop above stops at end-of-file without processing it deal_with_possible_empty_token(); - m_tokens_in_input.emplace_back(Token{m_token_container.m_eof_token_type, STR("EndOfFile"), STR("--EOF-DO-NOT-PARSE--")}); + m_tokens_in_input.emplace_back(Token{m_token_container.m_eof_token_type, SYSSTR("EndOfFile"), SYSSTR("--EOF-DO-NOT-PARSE--")}); } auto Tokenizer::get_tokens() const -> const std::vector& diff --git a/deps/first/Unreal b/deps/first/Unreal index ebfddd128..63ba05af1 160000 --- a/deps/first/Unreal +++ b/deps/first/Unreal @@ -1 +1 @@ -Subproject commit ebfddd128dc9e4b1ef76108348d70e57e1639b88 +Subproject commit 63ba05af17da46f814ecee7c0707e90564322a11 diff --git a/deps/first/patternsleuth b/deps/first/patternsleuth index 33e731e99..0d5175345 160000 --- a/deps/first/patternsleuth +++ b/deps/first/patternsleuth @@ -1 +1 @@ -Subproject commit 33e731e99f2a6bb7f65a8e95e89fd1c06ce9d1d2 +Subproject commit 0d5175345a4827f98bc51df893cf2079ebf53306 diff --git a/tools/xmakescripts/rules/build_rules.lua b/tools/xmakescripts/rules/build_rules.lua index 194d2849d..991fd9881 100644 --- a/tools/xmakescripts/rules/build_rules.lua +++ b/tools/xmakescripts/rules/build_rules.lua @@ -56,10 +56,12 @@ local PLATFORM_TYPES = { ["defines"] = { "PLATFORM_WINDOWS", "PLATFORM_MICROSOFT", + "WIN32", "OVERRIDE_PLATFORM_HEADER_NAME=Windows", "UBT_COMPILED_PLATFORM=Win64", "UNICODE", - "_UNICODE" + "_UNICODE", + "DLLEXT=.dll" }, } diff --git a/xmake.lua b/xmake.lua index 5c3ee1296..681029680 100644 --- a/xmake.lua +++ b/xmake.lua @@ -47,8 +47,7 @@ on_install(function(target) end) includes("deps") includes("UE4SS") -includes("UVTD") -includes("cppmods") +-- includes("cppmods") -- TODO: Remove this before the next release. It only exists to maintain backwards compat -- warnings for older mod templates.