-- Edit-mode only. Restores the latest completed installation without overwriting later edits. assert(not game:GetService("RunService"):IsRunning(), "Stop Play/Test before rollback.") local editor = game:GetService("ScriptEditorService") local backups = assert(game.ServerStorage:FindFirstChild("DexNativeTagBackups"), "No native-tag backup exists.") local chosen for _, backup in ipairs(backups:GetChildren()) do if backup:GetAttribute("Complete") and not backup:GetAttribute("Restored") and (not chosen or backup:GetAttribute("CreatedAt") > chosen:GetAttribute("CreatedAt")) then chosen = backup end end assert(chosen, "No completed, unrestored native-tag backup exists.") local changes = {} for _, entry in ipairs(chosen:GetChildren()) do local object = game for segment in entry:GetAttribute("Path"):gmatch("[^/]+") do object = assert(object:FindFirstChild(segment), "Missing target; nothing restored.") end assert(object.ClassName == entry:GetAttribute("Class"), "Target class changed; nothing restored.") assert(editor:GetEditorSource(object) == entry.After.Value, "Source changed after installation: " .. object:GetFullName() .. ". Nothing restored.") if object:IsA("BaseScript") then assert(object.Disabled == entry:GetAttribute("AfterDisabled"), "Enabled state changed; nothing restored.") end table.insert(changes, {entry = entry, object = object}) end local touched = {} local ok, problem = pcall(function() for _, change in ipairs(changes) do table.insert(touched, change) editor:UpdateSourceAsync(change.object, function(current) assert(current == change.entry.After.Value, "Concurrent edit during rollback") return change.entry.Before.Value end) if change.object:IsA("BaseScript") then change.object.Disabled = change.entry:GetAttribute("Disabled") == true end end end) if not ok then for _, change in ipairs(touched) do pcall(function() editor:UpdateSourceAsync(change.object, function(current) assert(current == change.entry.Before.Value or current == change.entry.After.Value, "Concurrent edit; preserve it") return change.entry.After.Value end) if change.object:IsA("BaseScript") then change.object.Disabled = change.entry:GetAttribute("AfterDisabled") end end) end error("Rollback stopped: " .. tostring(problem) .. ". Backup preserved: " .. chosen:GetFullName()) end for _, change in ipairs(changes) do if not change.entry:GetAttribute("Existed") then change.object:Destroy() end end chosen:SetAttribute("Restored", true) game:GetService("ChangeHistoryService"):SetWaypoint("Restore previous Dex Hood tag bridge") print("DEX_NATIVE_TAGS_ROLLED_BACK. Website native-tag records and native game scripts were not changed. Restart test servers; publish only after reviewing.")