diff --git a/Core/FileFormats/RagnarokRSW.lua b/Core/FileFormats/RagnarokRSW.lua index 65a9816c..a12fa4be 100644 --- a/Core/FileFormats/RagnarokRSW.lua +++ b/Core/FileFormats/RagnarokRSW.lua @@ -266,7 +266,7 @@ function RagnarokRSW:DecodeSceneObjects() if objectTypeID == RagnarokRSW.SCENE_OBJECT_TYPE_ANIMATED_PROP then self:DecodeAnimatedProps() elseif objectTypeID == RagnarokRSW.SCENE_OBJECT_TYPE_DYNAMIC_LIGHT_SOURCE then - self:DecodeDynamicLightSources() + self:DecodeDynamicLightSource() elseif objectTypeID == RagnarokRSW.SCENE_OBJECT_TYPE_SPATIAL_AUDIO_SOURCE then self:DecodeSpatialAudioSource() elseif objectTypeID == RagnarokRSW.SCENE_OBJECT_TYPE_PARTICLE_EFFECT_EMITTER then @@ -344,9 +344,14 @@ function RagnarokRSW:DecodeAnimatedProps() tinsert(self.animatedProps, objectInfo) end -function RagnarokRSW:DecodeDynamicLightSources() +function RagnarokRSW:DecodeDynamicLightSource() local objectInfo = self.reader:GetTypedArray("rsw_dynamic_light_t") + -- Garbage data exists in gl_step: See https://github.com/RagnarokResearchLab/RagLite/issues/343 + if not objectInfo.position.y then + objectInfo.position.y = -1 * 5 * 29.8 -- Denormalized Y of nearby light sources (workaround) + end + local lightSource = { name = ffi_string(objectInfo.name), normalizedWorldPosition = { diff --git a/Tests/FileFormats/RagnarokRSW.spec.lua b/Tests/FileFormats/RagnarokRSW.spec.lua index 9bd18086..3ef88aa2 100644 --- a/Tests/FileFormats/RagnarokRSW.spec.lua +++ b/Tests/FileFormats/RagnarokRSW.spec.lua @@ -1,3 +1,4 @@ +local BinaryReader = require("Core.FileFormats.BinaryReader") local QuadTreeRange = require("Core.FileFormats.RSW.QuadTreeRange") local RagnarokRSW = require("Core.FileFormats.RagnarokRSW") @@ -904,4 +905,19 @@ describe("RagnarokRSW", function() assertEquals(rsw.sceneGraph:GetBinaryStorageSize(), 65520) -- This will have to do (for now) end) end) + + describe("DecodeDynamicLightSource", function() + it("should be able to handle NaN values without crashing", function() + local name = string.rep("\000", 80) + local position = string.rep("\000", 4) .. string.rep("\255", 4) .. string.rep("\000", 4) + local color = string.rep("\000", 12) + local intensity = string.rep("\000", 4) + local garbageBytes = name .. position .. color .. intensity + + local rsw = RagnarokRSW() + rsw.reader = BinaryReader(garbageBytes) + rsw:DecodeDynamicLightSource() + assertEquals(rsw.dynamicLightSources[1].normalizedWorldPosition.y, 29.8) + end) + end) end)