Enhance script handling and temp ID resolution in ServeSession and Reconciler

- Improved error handling in ServeSession by rolling back temp IDs if encoding fails for new scripts.
- Added logic in applyPatch to remap echoed additions from the DescendantAdded handler, preventing duplicate instances.
- Updated API to resolve intermediate container temp IDs to real tree references, ensuring proper parent-child relationships for new scripts.
- Introduced new tests to verify the presence of server info flags and the resolution of temp IDs in scripts-only mode.

These changes aim to optimize script management and enhance the overall functionality of the session handling.
This commit is contained in:
Joe 2026-02-28 06:39:13 -06:00
parent 4985a3fede
commit 9820ec6534
4 changed files with 175 additions and 9 deletions

View file

@ -67,6 +67,33 @@ local function applyPatch(instanceMap, patch)
end
end
-- Detect echoed additions from DescendantAdded handler.
-- When the plugin pre-inserts instances with temp IDs and the server
-- broadcasts the same instances with real Refs, remap the InstanceMap
-- entries rather than creating duplicates via reify.
local remapProgress = true
while remapProgress do
remapProgress = false
for id, virtualInstance in pairs(patch.added) do
local parentInstance = instanceMap.fromIds[virtualInstance.Parent]
if not parentInstance then continue end
for _, child in parentInstance:GetChildren() do
if child.Name == virtualInstance.Name
and child.ClassName == virtualInstance.ClassName then
local existingId = instanceMap.fromInstances[child]
if existingId and existingId ~= id then
Log.trace("Echo remap: {} -> {} for {}", existingId, id, child:GetFullName())
instanceMap:removeId(existingId)
instanceMap:insert(id, child)
patch.added[id] = nil
remapProgress = true
break
end
end
end
end
end
for id, virtualInstance in pairs(patch.added) do
if instanceMap.fromIds[id] ~= nil then
-- This instance already exists. We might've already added it in a

View file

@ -961,7 +961,15 @@ function ServeSession:__connectScriptsOnlyWatchers()
end
local scriptTempId = string.gsub(HttpService:GenerateGUID(false), "-", ""):lower()
patch.added[scriptTempId] = encodeInstance(descendant, prevParentId)
local encoded = encodeInstance(descendant, prevParentId)
if not encoded then
Log.warn("Scripts-only: failed to encode new script {}, rolling back temp IDs", descendant:GetFullName())
for tempId in patch.added do
self.__instanceMap:removeId(tempId)
end
return
end
patch.added[scriptTempId] = encoded
self.__instanceMap:insert(scriptTempId, descendant)
Log.info(