From c3561718eacf4c2822ec35b5e182ab7f3693bb08 Mon Sep 17 00:00:00 2001 From: FlashHit <56718716+FlashHit@users.noreply.github.com> Date: Tue, 10 Aug 2021 18:17:10 +0200 Subject: [PATCH 1/8] Update __init__.lua --- ext/Shared/__init__.lua | 332 +++++++++++++++++++++------------------- 1 file changed, 177 insertions(+), 155 deletions(-) diff --git a/ext/Shared/__init__.lua b/ext/Shared/__init__.lua index 4083ff8..3131b44 100644 --- a/ext/Shared/__init__.lua +++ b/ext/Shared/__init__.lua @@ -4,43 +4,68 @@ GameObjectOriginType = { CustomChild = 3 } + -- This is a global table that stores the save file data as a Lua table. Will be populated on-demand by -- the server via NetEvents on the client-side -- Stores LevelData DataContainer guids. -local m_PrimaryLevelGuids = nil - -local m_IndexCount = 0 local m_OriginalLevelIndeces = {} local m_LastLoadedMap = nil local m_ObjectVariations = {} local m_PendingVariations = {} -local m_PrimaryLevelGuids = { } -local m_CustomLevelData = { } +local m_PrimaryLevelGuids = {} +local m_CustomLevelData = {} +local m_WorldPartReference = nil +local m_World = nil -local function PatchOriginalObject(p_Object, p_World) +local function PatchOriginalObject(p_Object) if p_Object.originalRef == nil then print("Object without original reference found, dynamic object?") return end + local s_Reference = nil + if p_Object.originalRef.partitionGuid == nil or p_Object.originalRef.partitionGuid == "nil" then -- perform a search without partitionguid - s_Reference = ResourceManager:SearchForInstanceByGuid(Guid(p_Object.originalRef.instanceGuid)) - if s_Reference == nil then - print("Unable to find original reference: " .. p_Object.originalRef.instanceGuid) - return - end + s_Reference = ResourceManager:SearchForInstanceByGuid(Guid(p_Object.originalRef.instanceGuid)) + + if s_Reference == nil then + print("Unable to find original reference: " .. p_Object.originalRef.instanceGuid) + return + end else - s_Reference = ResourceManager:FindInstanceByGuid(Guid(p_Object.originalRef.partitionGuid), Guid(p_Object.originalRef.instanceGuid)) - if s_Reference == nil then - print("Unable to find original reference: " .. p_Object.originalRef.instanceGuid .. " in partition " .. p_Object.originalRef.partitionGuid) - return - end + s_Reference = ResourceManager:FindInstanceByGuid(Guid(p_Object.originalRef.partitionGuid), Guid(p_Object.originalRef.instanceGuid)) + + if s_Reference == nil then + print("Unable to find original reference: " .. p_Object.originalRef.instanceGuid .. " in partition " .. p_Object.originalRef.partitionGuid) + + ResourceManager:RegisterInstanceLoadHandlerOnce(Guid(p_Object.originalRef.partitionGuid), Guid(p_Object.originalRef.instanceGuid), function(p_Instance) + s_Reference = _G[p_Instance.typeInfo.name](p_Instance) + s_Reference:MakeWritable() + + if p_Object.isDeleted then + s_Reference.excluded = true + end + + if p_Object.localTransform then + s_Reference.blueprintTransform = LinearTransform(p_Object.localTransform) -- LinearTransform(p_Object.localTransform) + else + s_Reference.blueprintTransform = LinearTransform(p_Object.transform) -- LinearTransform(p_Object.transform) + end + + print("Fixed original reference: " .. tostring(s_Reference.instanceGuid) .. " in partition " .. tostring(s_Reference.partitionGuid)) + end) + + return + end end + s_Reference = _G[s_Reference.typeInfo.name](s_Reference) s_Reference:MakeWritable() + if p_Object.isDeleted then s_Reference.excluded = true end + if p_Object.localTransform then s_Reference.blueprintTransform = LinearTransform(p_Object.localTransform) -- LinearTransform(p_Object.localTransform) else @@ -48,8 +73,9 @@ local function PatchOriginalObject(p_Object, p_World) end end -local function AddCustomObject(p_Object, p_World, p_RegistryContainer) +local function AddCustomObject(p_Object) local s_Blueprint = ResourceManager:FindInstanceByGuid(Guid(p_Object.blueprintCtrRef.partitionGuid), Guid(p_Object.blueprintCtrRef.instanceGuid)) + if s_Blueprint == nil then print('Cannot find blueprint with guid ' .. tostring(p_Object.blueprintCtrRef.instanceGuid)) return @@ -58,12 +84,15 @@ local function AddCustomObject(p_Object, p_World, p_RegistryContainer) -- Filter BangerEntityData. if s_Blueprint:Is('ObjectBlueprint') then local s_ObjectBlueprint = ObjectBlueprint(s_Blueprint) + if s_ObjectBlueprint.object and s_ObjectBlueprint.object:Is('BangerEntityData') then + print("Cannot add custom object that is a BangerEntityData") return end end - local s_Reference + local s_Reference = nil + if s_Blueprint:Is('EffectBlueprint') then s_Reference = EffectReferenceObjectData() s_Reference.autoStart = true @@ -71,120 +100,176 @@ local function AddCustomObject(p_Object, p_World, p_RegistryContainer) s_Reference = ReferenceObjectData() end - p_RegistryContainer.referenceObjectRegistry:add(s_Reference) if p_Object.localTransform then s_Reference.blueprintTransform = LinearTransform(p_Object.localTransform) else s_Reference.blueprintTransform = LinearTransform(p_Object.transform) end - --print("AddCustomObject: " .. p_Object.transform) + s_Reference.blueprint = Blueprint(s_Blueprint) - -- s_Reference.blueprint:MakeWritable() if m_ObjectVariations[p_Object.variation] == nil then m_PendingVariations[p_Object.variation] = s_Reference else s_Reference.objectVariation = m_ObjectVariations[p_Object.variation] end - s_Reference.indexInBlueprint = #p_World.objects + m_IndexCount + 1 + s_Reference.isEventConnectionTarget = Realm.Realm_None s_Reference.isPropertyConnectionTarget = Realm.Realm_None s_Reference.excluded = false - p_World.objects:add(s_Reference) + m_World.objects:add(s_Reference) end -local function CreateWorldPart(p_PrimaryLevel, p_RegistryContainer) - local s_World = WorldPartData() - p_RegistryContainer.blueprintRegistry:add(s_World) +local function CreateWorldPart() + m_World = WorldPartData(Guid("ADC31E4A-AF50-94EC-9628-E21026DF9B7D")) + + m_WorldPartReference = WorldPartReferenceObjectData(Guid("9F1DA12C-4DE6-528D-F0FB-4D391BC4510F")) + + m_WorldPartReference.isEventConnectionTarget = Realm.Realm_None + m_WorldPartReference.isPropertyConnectionTarget = Realm.Realm_None + m_WorldPartReference.excluded = false +end + +local function GetCustomLevel(p_LevelName, p_GameModeName) + local s_LevelName = p_LevelName:gsub(".*/", "") + + local s_Path = '__shared/Levels/' .. s_LevelName .. '/' .. s_LevelName .. '_' .. p_GameModeName + + local s_Ok, s_PresetJson = pcall(require, s_Path) + s_PresetJson = s_Ok and s_PresetJson or nil + + if not s_PresetJson then + print('Couldn\'t find custom level data for Level: ' .. p_LevelName .. ' - GameMode: ' .. p_GameModeName) + return nil + end + + local s_Preset = json.decode(s_PresetJson) + + if not s_Preset then + error('Couldn\'t decode json preset') + return nil + end + + print("preset found: " .. s_Path:gsub(".*/", "")) + + return s_Preset +end + +local function GetIndexCount(p_PrimaryLevel) + local s_IndexCount = 0 --find index for _, l_Object in pairs(p_PrimaryLevel.objects) do if l_Object:Is('WorldPartReferenceObjectData') then local l_RefObjectData = WorldPartReferenceObjectData(l_Object) + if l_RefObjectData.blueprint:Is('WorldPartData') then local s_WorldPart = WorldPartData(l_RefObjectData.blueprint) + if #s_WorldPart.objects ~= 0 then local s_ROD = s_WorldPart.objects[#s_WorldPart.objects] -- last one in array + if s_ROD and s_ROD:Is('ReferenceObjectData') then s_ROD = ReferenceObjectData(s_ROD) - if s_ROD.indexInBlueprint > m_IndexCount then - m_IndexCount = s_ROD.indexInBlueprint + + if s_ROD.indexInBlueprint > s_IndexCount then + s_IndexCount = s_ROD.indexInBlueprint end end end end end end - -- m_IndexCount = 30000 - print('Index count is: '..tostring(m_IndexCount)) + + return s_IndexCount +end + +-- nº 1 in calling order +Events:Subscribe('Level:LoadResources', function() + print("-----Loading resources") + m_ObjectVariations = {} + m_PendingVariations = {} + + m_CustomLevelData = GetCustomLevel(SharedUtils:GetLevelName(), SharedUtils:GetCurrentGameMode()) + CreateWorldPart() for _, l_Object in pairs(m_CustomLevelData.data) do - if l_Object.origin == GameObjectOriginType.Custom then - if not m_CustomLevelData.vanillaOnly then - AddCustomObject(l_Object, s_World, p_RegistryContainer) + ResourceManager:RegisterInstanceLoadHandlerOnce(Guid(l_Object.blueprintCtrRef.partitionGuid), Guid(l_Object.blueprintCtrRef.instanceGuid), function(p_Instance) + if l_Object.origin == GameObjectOriginType.Custom then + if not m_CustomLevelData.vanillaOnly then + AddCustomObject(l_Object) + end + elseif l_Object.origin == GameObjectOriginType.Vanilla then + PatchOriginalObject(l_Object) end - elseif l_Object.origin == GameObjectOriginType.Vanilla then - PatchOriginalObject(l_Object, s_World) - end - -- TODO handle CustomChild + end) end - m_LastLoadedMap = SharedUtils:GetLevelName() +end) - local s_WorldPartReference = WorldPartReferenceObjectData() - s_WorldPartReference.blueprint = s_World +-- nº 3 in calling order +Events:Subscribe('Level:LoadingInfo', function(p_ScreenInfo) + print("-----Loading Info - " .. p_ScreenInfo) - s_WorldPartReference.isEventConnectionTarget = Realm.Realm_None - s_WorldPartReference.isPropertyConnectionTarget = Realm.Realm_None - s_WorldPartReference.excluded = false + if p_ScreenInfo ~= "Registering entity resources" then + return + end - return s_WorldPartReference -end + print("Patching level") -local function GetCustomLevel(p_LevelName, p_GameModeName) - print(p_LevelName) - print(p_GameModeName) - local s_LevelName = p_LevelName:split('/')[3] - print(s_LevelName) + local s_PrimaryLevel = ResourceManager:FindInstanceByGuid(m_PrimaryLevelGuids.partitionGuid, m_PrimaryLevelGuids.instanceGuid) - local s_Path = '__shared/Levels/' .. s_LevelName .. '/' .. s_LevelName .. '_' .. p_GameModeName + if s_PrimaryLevel == nil then + print("Can\'t add registry, primarylevel is nil") + return + end - print(s_Path) + s_PrimaryLevel = LevelData(s_PrimaryLevel) - local s_Ok, s_PresetJson = pcall(require, s_Path) - s_PresetJson = s_Ok and s_PresetJson or nil + local s_IndexCount = GetIndexCount(s_PrimaryLevel) + print("Index count is: " .. s_IndexCount) - if not s_PresetJson then - print('Couldnt find custom level data for Level: ' .. p_LevelName .. ' - GameMode: ' .. p_GameModeName) - return nil - end + local s_RegistryContainer = s_PrimaryLevel.registryContainer - local s_Preset = json.decode(s_PresetJson) + if s_RegistryContainer == nil then + print('No RegistryContainer found, this shouldn\'t happen') + end - if not s_Preset then - error('Couldnt decode json preset') - return nil - end + s_RegistryContainer = RegistryContainer(s_RegistryContainer) + s_RegistryContainer:MakeWritable() - print("preset found: " .. s_Path:split('/')[4]) + s_RegistryContainer.blueprintRegistry:add(m_World) + m_WorldPartReference.blueprint = m_World + m_WorldPartReference.indexInBlueprint = #s_PrimaryLevel.objects + 1 + s_RegistryContainer.referenceObjectRegistry:add(m_WorldPartReference) - return s_Preset -end + for l_Index, l_Reference in pairs(WorldPartData(m_WorldPartReference.blueprint).objects) do + l_Reference = _G[l_Reference.typeInfo.name](l_Reference) + s_RegistryContainer.referenceObjectRegistry:add(l_Reference) + l_Reference.indexInBlueprint = l_Index + s_IndexCount + end --- nº 1 in calling order -Events:Subscribe('Level:LoadResources', function() - print("-----Loading resources") - m_ObjectVariations = {} - m_PendingVariations = {} + s_PrimaryLevel.objects:add(m_WorldPartReference) + + -- Save original indeces in case LevelData has to be reset to default state later. + m_OriginalLevelIndeces = { + objects = #s_PrimaryLevel.objects, + ROFs = #s_RegistryContainer.referenceObjectRegistry, + blueprints = #s_RegistryContainer.blueprintRegistry, + entity = #s_RegistryContainer.entityRegistry + } + + m_WorldPartReference = nil + m_World = nil - m_CustomLevelData = GetCustomLevel(SharedUtils:GetLevelName(), SharedUtils:GetCurrentGameMode()) + print("Patched level") end) -- nº 2 in calling order Events:Subscribe('Partition:Loaded', function(p_Partition) - if not m_CustomLevelData then - return - end + if not m_CustomLevelData then + return + end if p_Partition == nil then return @@ -196,107 +281,44 @@ Events:Subscribe('Partition:Loaded', function(p_Partition) print('Instance is null?') return end - -- if l_Instance:Is("Blueprint") then - --print("-------"..Blueprint(l_Instance).name) - -- end - if s_PrimaryInstance.typeInfo.name == "LevelData" then - local s_Instance = LevelData(s_PrimaryInstance) - if (s_Instance.name == SharedUtils:GetLevelName()) then + + if s_PrimaryInstance:Is("LevelData") then + local s_PrimaryLevel = LevelData(s_PrimaryInstance) + + if s_PrimaryLevel.name == SharedUtils:GetLevelName() then print("----Registering PrimaryLevel guids") - s_Instance:MakeWritable() + s_PrimaryLevel:MakeWritable() m_PrimaryLevelGuids = { - instanceGuid = s_Instance.instanceGuid, - partitionGuid = s_Instance.partitionGuid + instanceGuid = s_PrimaryLevel.instanceGuid, + partitionGuid = s_PrimaryLevel.partitionGuid } + + if m_LastLoadedMap == SharedUtils:GetLevelName() then + print('Same map loading, skipping') + return + end + + m_LastLoadedMap = SharedUtils:GetLevelName() end elseif s_PrimaryInstance:Is('ObjectVariation') then -- Store all variations in a map. local s_Variation = ObjectVariation(s_PrimaryInstance) m_ObjectVariations[s_Variation.nameHash] = s_Variation - if m_PendingVariations[s_Variation.nameHash] ~= nil then - for _, l_Object in pairs(m_PendingVariations[s_Variation.nameHash]) do - l_Object.objectVariation = s_Variation - end + if m_PendingVariations[s_Variation.nameHash] ~= nil then + m_PendingVariations[s_Variation.nameHash].objectVariation = s_Variation m_PendingVariations[s_Variation.nameHash] = nil end end end) --- nº 3 in calling order -Events:Subscribe('Level:LoadingInfo', function(p_Info) - if not m_CustomLevelData then - return - end - - if p_Info == "Registering entity resources" then - print("-----Loading Info - Registering entity resources") - - if not m_CustomLevelData then - print("No custom level specified.") - return - end - - if m_PrimaryLevelGuids == nil then - print("m_PrimaryLevelGuids is nil, something went wrong") - return - end - - local s_PrimaryLevel = ResourceManager:FindInstanceByGuid(m_PrimaryLevelGuids.partitionGuid, m_PrimaryLevelGuids.instanceGuid) - - if s_PrimaryLevel == nil then - print("Couldn\'t find PrimaryLevel DataContainer, aborting") - return - end - - s_PrimaryLevel = LevelData(s_PrimaryLevel) - - if m_LastLoadedMap == SharedUtils:GetLevelName() then - print('Same map loading, skipping') - return - end - - print("Patching level") - local s_RegistryContainer = s_PrimaryLevel.registryContainer - if s_RegistryContainer == nil then - print('No registryContainer found, this shouldn\'t happen') - end - s_RegistryContainer = RegistryContainer(s_RegistryContainer) - s_RegistryContainer:MakeWritable() - - local s_WorldPartReference = CreateWorldPart(s_PrimaryLevel, s_RegistryContainer) - - s_WorldPartReference.indexInBlueprint = #s_PrimaryLevel.objects - - s_PrimaryLevel.objects:add(s_WorldPartReference) - - -- Save original indeces in case LevelData has to be reset to default state later. - m_OriginalLevelIndeces = { - objects = #s_PrimaryLevel.objects, - ROFs = #s_RegistryContainer.referenceObjectRegistry, - blueprints = #s_RegistryContainer.blueprintRegistry, - entity = #s_RegistryContainer.entityRegistry - } - s_RegistryContainer.referenceObjectRegistry:add(s_WorldPartReference) - print('Level patched') - end -end) - -- Remove all DataContainer references and reset vars Events:Subscribe('Level:Destroy', function() m_ObjectVariations = {} m_PendingVariations = {} - m_IndexCount = 0 -- TODO: remove all custom objects from level registry and leveldata if next round is -- the same map but a different save, once that is implemented. If it's a different map -- there is no need to clear anything, as the leveldata will be unloaded and a new one loaded end) - -function string:split(sep) - local sep, fields = sep or ":", {} - local pattern = string.format("([^%s]+)", sep) - self:gsub(pattern, function(c) fields[#fields+1] = c end) - return fields -end \ No newline at end of file From ef145a94c3c4cbac5ed8a08cb60df91028e3725a Mon Sep 17 00:00:00 2001 From: FlashHit <56718716+FlashHit@users.noreply.github.com> Date: Tue, 10 Aug 2021 20:07:33 +0200 Subject: [PATCH 2/8] refactor --- ext/Shared/__init__.lua | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/ext/Shared/__init__.lua b/ext/Shared/__init__.lua index 3131b44..1b3c37f 100644 --- a/ext/Shared/__init__.lua +++ b/ext/Shared/__init__.lua @@ -14,7 +14,6 @@ local m_ObjectVariations = {} local m_PendingVariations = {} local m_PrimaryLevelGuids = {} local m_CustomLevelData = {} -local m_WorldPartReference = nil local m_World = nil local function PatchOriginalObject(p_Object) @@ -121,16 +120,6 @@ local function AddCustomObject(p_Object) m_World.objects:add(s_Reference) end -local function CreateWorldPart() - m_World = WorldPartData(Guid("ADC31E4A-AF50-94EC-9628-E21026DF9B7D")) - - m_WorldPartReference = WorldPartReferenceObjectData(Guid("9F1DA12C-4DE6-528D-F0FB-4D391BC4510F")) - - m_WorldPartReference.isEventConnectionTarget = Realm.Realm_None - m_WorldPartReference.isPropertyConnectionTarget = Realm.Realm_None - m_WorldPartReference.excluded = false -end - local function GetCustomLevel(p_LevelName, p_GameModeName) local s_LevelName = p_LevelName:gsub(".*/", "") @@ -164,7 +153,7 @@ local function GetIndexCount(p_PrimaryLevel) if l_Object:Is('WorldPartReferenceObjectData') then local l_RefObjectData = WorldPartReferenceObjectData(l_Object) - if l_RefObjectData.blueprint:Is('WorldPartData') then + if l_RefObjectData.blueprint ~= nil and l_RefObjectData.blueprint:Is('WorldPartData') then local s_WorldPart = WorldPartData(l_RefObjectData.blueprint) if #s_WorldPart.objects ~= 0 then @@ -192,7 +181,7 @@ Events:Subscribe('Level:LoadResources', function() m_PendingVariations = {} m_CustomLevelData = GetCustomLevel(SharedUtils:GetLevelName(), SharedUtils:GetCurrentGameMode()) - CreateWorldPart() + m_World = WorldPartData(Guid("ADC31E4A-AF50-94EC-9628-E21026DF9B7D")) for _, l_Object in pairs(m_CustomLevelData.data) do ResourceManager:RegisterInstanceLoadHandlerOnce(Guid(l_Object.blueprintCtrRef.partitionGuid), Guid(l_Object.blueprintCtrRef.instanceGuid), function(p_Instance) @@ -238,18 +227,18 @@ Events:Subscribe('Level:LoadingInfo', function(p_ScreenInfo) s_RegistryContainer = RegistryContainer(s_RegistryContainer) s_RegistryContainer:MakeWritable() - s_RegistryContainer.blueprintRegistry:add(m_World) - m_WorldPartReference.blueprint = m_World - m_WorldPartReference.indexInBlueprint = #s_PrimaryLevel.objects + 1 - s_RegistryContainer.referenceObjectRegistry:add(m_WorldPartReference) + local s_WorldPartReference = WorldPartReferenceObjectData(s_PrimaryLevel.objects[#s_PrimaryLevel.objects]) + s_WorldPartReference.blueprint = m_World - for l_Index, l_Reference in pairs(WorldPartData(m_WorldPartReference.blueprint).objects) do + for l_Index, l_Reference in pairs(WorldPartData(s_WorldPartReference.blueprint).objects) do l_Reference = _G[l_Reference.typeInfo.name](l_Reference) s_RegistryContainer.referenceObjectRegistry:add(l_Reference) l_Reference.indexInBlueprint = l_Index + s_IndexCount end - s_PrimaryLevel.objects:add(m_WorldPartReference) + s_RegistryContainer.blueprintRegistry:add(m_World) + s_RegistryContainer.referenceObjectRegistry:add(s_WorldPartReference) + -- Save original indeces in case LevelData has to be reset to default state later. m_OriginalLevelIndeces = { @@ -259,7 +248,6 @@ Events:Subscribe('Level:LoadingInfo', function(p_ScreenInfo) entity = #s_RegistryContainer.entityRegistry } - m_WorldPartReference = nil m_World = nil print("Patched level") @@ -299,6 +287,15 @@ Events:Subscribe('Partition:Loaded', function(p_Partition) return end + local s_WorldPartReference = WorldPartReferenceObjectData(Guid("9F1DA12C-4DE6-528D-F0FB-4D391BC4510F")) + + s_WorldPartReference.indexInBlueprint = #s_PrimaryLevel.objects + 1 + s_WorldPartReference.isEventConnectionTarget = Realm.Realm_None + s_WorldPartReference.isPropertyConnectionTarget = Realm.Realm_None + s_WorldPartReference.excluded = false + + s_PrimaryLevel.objects:add(s_WorldPartReference) + m_LastLoadedMap = SharedUtils:GetLevelName() end elseif s_PrimaryInstance:Is('ObjectVariation') then From 2fde1391b3b2efdfd501ebe1ea873086fd3e0b68 Mon Sep 17 00:00:00 2001 From: FlashHit <56718716+FlashHit@users.noreply.github.com> Date: Wed, 11 Aug 2021 22:27:38 +0200 Subject: [PATCH 3/8] fix: add nil checks - fix custom object disappeared after level reload --- ext/Shared/__init__.lua | 42 ++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/ext/Shared/__init__.lua b/ext/Shared/__init__.lua index 1b3c37f..46b3f84 100644 --- a/ext/Shared/__init__.lua +++ b/ext/Shared/__init__.lua @@ -9,7 +9,7 @@ GameObjectOriginType = { -- the server via NetEvents on the client-side -- Stores LevelData DataContainer guids. local m_OriginalLevelIndeces = {} -local m_LastLoadedMap = nil +local m_LastLoadedLevelName = nil local m_ObjectVariations = {} local m_PendingVariations = {} local m_PrimaryLevelGuids = {} @@ -177,10 +177,27 @@ end -- nº 1 in calling order Events:Subscribe('Level:LoadResources', function() print("-----Loading resources") + + if m_LastLoadedLevelName == SharedUtils:GetLevelName() then + print('Same level loading, skipping') + return + end + m_ObjectVariations = {} m_PendingVariations = {} m_CustomLevelData = GetCustomLevel(SharedUtils:GetLevelName(), SharedUtils:GetCurrentGameMode()) + + if m_CustomLevelData == nil then + return + end + + if m_CustomLevelData.data == nil then + print("Custom Level preset is in a wrong format, abort.") + m_CustomLevelData = nil + return + end + m_World = WorldPartData(Guid("ADC31E4A-AF50-94EC-9628-E21026DF9B7D")) for _, l_Object in pairs(m_CustomLevelData.data) do @@ -204,7 +221,21 @@ Events:Subscribe('Level:LoadingInfo', function(p_ScreenInfo) return end + if m_CustomLevelData == nil then + return + end + + if m_PrimaryLevelGuids.instanceGuid == nil then + print("No PrimaryLevelGuids available.") + return + end + + if m_LastLoadedLevelName == SharedUtils:GetLevelName() then + return + end + print("Patching level") + m_LastLoadedLevelName = SharedUtils:GetLevelName() local s_PrimaryLevel = ResourceManager:FindInstanceByGuid(m_PrimaryLevelGuids.partitionGuid, m_PrimaryLevelGuids.instanceGuid) @@ -232,8 +263,8 @@ Events:Subscribe('Level:LoadingInfo', function(p_ScreenInfo) for l_Index, l_Reference in pairs(WorldPartData(s_WorldPartReference.blueprint).objects) do l_Reference = _G[l_Reference.typeInfo.name](l_Reference) - s_RegistryContainer.referenceObjectRegistry:add(l_Reference) l_Reference.indexInBlueprint = l_Index + s_IndexCount + s_RegistryContainer.referenceObjectRegistry:add(l_Reference) end s_RegistryContainer.blueprintRegistry:add(m_World) @@ -282,11 +313,6 @@ Events:Subscribe('Partition:Loaded', function(p_Partition) partitionGuid = s_PrimaryLevel.partitionGuid } - if m_LastLoadedMap == SharedUtils:GetLevelName() then - print('Same map loading, skipping') - return - end - local s_WorldPartReference = WorldPartReferenceObjectData(Guid("9F1DA12C-4DE6-528D-F0FB-4D391BC4510F")) s_WorldPartReference.indexInBlueprint = #s_PrimaryLevel.objects + 1 @@ -295,8 +321,6 @@ Events:Subscribe('Partition:Loaded', function(p_Partition) s_WorldPartReference.excluded = false s_PrimaryLevel.objects:add(s_WorldPartReference) - - m_LastLoadedMap = SharedUtils:GetLevelName() end elseif s_PrimaryInstance:Is('ObjectVariation') then -- Store all variations in a map. From 25fbdacae38d58073ed6676a7d9843ac3d5926df Mon Sep 17 00:00:00 2001 From: FlashHit <56718716+FlashHit@users.noreply.github.com> Date: Wed, 11 Aug 2021 23:40:18 +0200 Subject: [PATCH 4/8] fix pendingVariations --- ext/Shared/__init__.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ext/Shared/__init__.lua b/ext/Shared/__init__.lua index 46b3f84..688ce9a 100644 --- a/ext/Shared/__init__.lua +++ b/ext/Shared/__init__.lua @@ -108,7 +108,11 @@ local function AddCustomObject(p_Object) s_Reference.blueprint = Blueprint(s_Blueprint) if m_ObjectVariations[p_Object.variation] == nil then - m_PendingVariations[p_Object.variation] = s_Reference + if m_PendingVariations[p_Object.variation] == nil then + m_PendingVariations[p_Object.variation] = {} + end + + table.insert(m_PendingVariations[p_Object.variation], s_Reference) else s_Reference.objectVariation = m_ObjectVariations[p_Object.variation] end @@ -328,7 +332,10 @@ Events:Subscribe('Partition:Loaded', function(p_Partition) m_ObjectVariations[s_Variation.nameHash] = s_Variation if m_PendingVariations[s_Variation.nameHash] ~= nil then - m_PendingVariations[s_Variation.nameHash].objectVariation = s_Variation + for _, l_Object in pairs(m_PendingVariations[s_Variation.nameHash]) do + l_Object.objectVariation = s_Variation + end + m_PendingVariations[s_Variation.nameHash] = nil end end From 166993266e73b0d25be3a1bc197a5153ad97bd24 Mon Sep 17 00:00:00 2001 From: FlashHit <56718716+FlashHit@users.noreply.github.com> Date: Thu, 12 Aug 2021 00:43:56 +0200 Subject: [PATCH 5/8] fix: add variation 0 check --- ext/Shared/__init__.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/Shared/__init__.lua b/ext/Shared/__init__.lua index 688ce9a..8f18ffa 100644 --- a/ext/Shared/__init__.lua +++ b/ext/Shared/__init__.lua @@ -107,7 +107,7 @@ local function AddCustomObject(p_Object) s_Reference.blueprint = Blueprint(s_Blueprint) - if m_ObjectVariations[p_Object.variation] == nil then + if m_ObjectVariations[p_Object.variation] == nil and p_Object.variation ~= 0 then if m_PendingVariations[p_Object.variation] == nil then m_PendingVariations[p_Object.variation] = {} end From e548b07e5ce3338e4d39094746c8cb68170baf7c Mon Sep 17 00:00:00 2001 From: FlashHit <56718716+FlashHit@users.noreply.github.com> Date: Thu, 12 Aug 2021 17:25:46 +0200 Subject: [PATCH 6/8] fix some bugs --- ext/Shared/__init__.lua | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/ext/Shared/__init__.lua b/ext/Shared/__init__.lua index 8f18ffa..fcd83ea 100644 --- a/ext/Shared/__init__.lua +++ b/ext/Shared/__init__.lua @@ -225,21 +225,22 @@ Events:Subscribe('Level:LoadingInfo', function(p_ScreenInfo) return end - if m_CustomLevelData == nil then + if m_LastLoadedLevelName == SharedUtils:GetLevelName() then return end - if m_PrimaryLevelGuids.instanceGuid == nil then - print("No PrimaryLevelGuids available.") + m_LastLoadedLevelName = SharedUtils:GetLevelName() + + if m_CustomLevelData == nil then return end - if m_LastLoadedLevelName == SharedUtils:GetLevelName() then + if m_PrimaryLevelGuids.instanceGuid == nil then + print("No PrimaryLevelGuids available.") return end print("Patching level") - m_LastLoadedLevelName = SharedUtils:GetLevelName() local s_PrimaryLevel = ResourceManager:FindInstanceByGuid(m_PrimaryLevelGuids.partitionGuid, m_PrimaryLevelGuids.instanceGuid) @@ -262,7 +263,28 @@ Events:Subscribe('Level:LoadingInfo', function(p_ScreenInfo) s_RegistryContainer = RegistryContainer(s_RegistryContainer) s_RegistryContainer:MakeWritable() - local s_WorldPartReference = WorldPartReferenceObjectData(s_PrimaryLevel.objects[#s_PrimaryLevel.objects]) + local s_WorldPartReference = nil + + for l_Index = #s_PrimaryLevel.objects, 1, -1 do + if s_PrimaryLevel.objects[l_Index].instanceGuid ~= nil and + s_PrimaryLevel.objects[l_Index].instanceGuid == Guid("9F1DA12C-4DE6-528D-F0FB-4D391BC4510F") then + s_WorldPartReference = WorldPartReferenceObjectData(s_PrimaryLevel.objects[l_Index]) + break + end + end + + if s_WorldPartReference == nil then + print("WorldPartReferenceObjectData not found. Adding it again.") + s_WorldPartReference = WorldPartReferenceObjectData(Guid("9F1DA12C-4DE6-528D-F0FB-4D391BC4510F")) + + s_WorldPartReference.indexInBlueprint = #s_PrimaryLevel.objects + 1 + s_WorldPartReference.isEventConnectionTarget = Realm.Realm_None + s_WorldPartReference.isPropertyConnectionTarget = Realm.Realm_None + s_WorldPartReference.excluded = false + + s_PrimaryLevel.objects:add(s_WorldPartReference) + end + s_WorldPartReference.blueprint = m_World for l_Index, l_Reference in pairs(WorldPartData(s_WorldPartReference.blueprint).objects) do From ac4d1b8f6a11281533a6237dc57eeed3af70d1ab Mon Sep 17 00:00:00 2001 From: FlashHit <56718716+FlashHit@users.noreply.github.com> Date: Sun, 22 Aug 2021 14:11:37 +0200 Subject: [PATCH 7/8] fix crash: remove BangerEntityData filter --- ext/Shared/__init__.lua | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ext/Shared/__init__.lua b/ext/Shared/__init__.lua index fcd83ea..ba35f5a 100644 --- a/ext/Shared/__init__.lua +++ b/ext/Shared/__init__.lua @@ -80,16 +80,6 @@ local function AddCustomObject(p_Object) return end - -- Filter BangerEntityData. - if s_Blueprint:Is('ObjectBlueprint') then - local s_ObjectBlueprint = ObjectBlueprint(s_Blueprint) - - if s_ObjectBlueprint.object and s_ObjectBlueprint.object:Is('BangerEntityData') then - print("Cannot add custom object that is a BangerEntityData") - return - end - end - local s_Reference = nil if s_Blueprint:Is('EffectBlueprint') then From 8f735dbb12ee12a0e01ef9e1c2e7cec2a193dd75 Mon Sep 17 00:00:00 2001 From: FlashHit <56718716+FlashHit@users.noreply.github.com> Date: Sun, 22 Aug 2021 16:34:56 +0200 Subject: [PATCH 8/8] refactor: improve AddCustomObject and PatchOriginalObject --- ext/Shared/__init__.lua | 76 ++++++++--------------------------------- 1 file changed, 15 insertions(+), 61 deletions(-) diff --git a/ext/Shared/__init__.lua b/ext/Shared/__init__.lua index e28af86..e285088 100644 --- a/ext/Shared/__init__.lua +++ b/ext/Shared/__init__.lua @@ -17,49 +17,8 @@ local m_PrimaryLevelGuids = {} local m_CustomLevelData = {} local m_World = nil -local function PatchOriginalObject(p_Object) - if p_Object.originalRef == nil then - print("Object without original reference found, dynamic object?") - return - end - - local s_Reference = nil - - if p_Object.originalRef.partitionGuid == nil or p_Object.originalRef.partitionGuid == "nil" then -- perform a search without partitionguid - s_Reference = ResourceManager:SearchForInstanceByGuid(Guid(p_Object.originalRef.instanceGuid)) - - if s_Reference == nil then - print("Unable to find original reference: " .. p_Object.originalRef.instanceGuid) - return - end - else - s_Reference = ResourceManager:FindInstanceByGuid(Guid(p_Object.originalRef.partitionGuid), Guid(p_Object.originalRef.instanceGuid)) - - if s_Reference == nil then - print("Unable to find original reference: " .. p_Object.originalRef.instanceGuid .. " in partition " .. p_Object.originalRef.partitionGuid) - - ResourceManager:RegisterInstanceLoadHandlerOnce(Guid(p_Object.originalRef.partitionGuid), Guid(p_Object.originalRef.instanceGuid), function(p_Instance) - s_Reference = _G[p_Instance.typeInfo.name](p_Instance) - s_Reference:MakeWritable() - - if p_Object.isDeleted then - s_Reference.excluded = true - end - - if p_Object.localTransform then - s_Reference.blueprintTransform = LinearTransform(p_Object.localTransform) -- LinearTransform(p_Object.localTransform) - else - s_Reference.blueprintTransform = LinearTransform(p_Object.transform) -- LinearTransform(p_Object.transform) - end - - print("Fixed original reference: " .. tostring(s_Reference.instanceGuid) .. " in partition " .. tostring(s_Reference.partitionGuid)) - end) - - return - end - end - - s_Reference = _G[s_Reference.typeInfo.name](s_Reference) +local function PatchOriginalObject(p_Object, p_Instance) + local s_Reference = _G[p_Instance.typeInfo.name](p_Instance) s_Reference:MakeWritable() if p_Object.isDeleted then @@ -73,17 +32,10 @@ local function PatchOriginalObject(p_Object) end end -local function AddCustomObject(p_Object) - local s_Blueprint = ResourceManager:FindInstanceByGuid(Guid(p_Object.blueprintCtrRef.partitionGuid), Guid(p_Object.blueprintCtrRef.instanceGuid)) - - if s_Blueprint == nil then - print('Cannot find blueprint with guid ' .. tostring(p_Object.blueprintCtrRef.instanceGuid)) - return - end - +local function AddCustomObject(p_Object, p_Instance) local s_Reference = nil - if s_Blueprint:Is('EffectBlueprint') then + if p_Instance:Is('EffectBlueprint') then s_Reference = EffectReferenceObjectData() s_Reference.autoStart = true else @@ -96,7 +48,7 @@ local function AddCustomObject(p_Object) s_Reference.blueprintTransform = LinearTransform(p_Object.transform) end - s_Reference.blueprint = Blueprint(s_Blueprint) + s_Reference.blueprint = Blueprint(p_Instance) if m_ObjectVariations[p_Object.variation] == nil and p_Object.variation ~= 0 then if m_PendingVariations[p_Object.variation] == nil then @@ -196,15 +148,17 @@ Events:Subscribe('Level:LoadResources', function() m_World = WorldPartData(Guid("ADC31E4A-AF50-94EC-9628-E21026DF9B7D")) for _, l_Object in pairs(m_CustomLevelData.data) do - ResourceManager:RegisterInstanceLoadHandlerOnce(Guid(l_Object.blueprintCtrRef.partitionGuid), Guid(l_Object.blueprintCtrRef.instanceGuid), function(p_Instance) - if l_Object.origin == GameObjectOriginType.Custom then - if not m_CustomLevelData.vanillaOnly then - AddCustomObject(l_Object) - end - elseif l_Object.origin == GameObjectOriginType.Vanilla then - PatchOriginalObject(l_Object) + if l_Object.origin == GameObjectOriginType.Custom then + if not m_CustomLevelData.vanillaOnly then + ResourceManager:RegisterInstanceLoadHandlerOnce(Guid(l_Object.blueprintCtrRef.partitionGuid), Guid(l_Object.blueprintCtrRef.instanceGuid), function(p_Instance) + AddCustomObject(l_Object, p_Instance) + end) end - end) + elseif l_Object.origin == GameObjectOriginType.Vanilla then + ResourceManager:RegisterInstanceLoadHandlerOnce(Guid(l_Object.originalRef.partitionGuid), Guid(l_Object.originalRef.instanceGuid), function(p_Instance) + PatchOriginalObject(l_Object, p_Instance) + end) + end end end)