mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-20 20:55:50 +00:00
Add sync locking for Team Create (#590)
* Add sync locking * Steal lock from users who left without releasing * Do not remove lock as unknown instance * Don't delete non Archivable instance
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
local Players = game:GetService("Players")
|
||||||
|
local ServerStorage = game:GetService("ServerStorage")
|
||||||
|
|
||||||
local Rojo = script:FindFirstAncestor("Rojo")
|
local Rojo = script:FindFirstAncestor("Rojo")
|
||||||
local Plugin = Rojo.Plugin
|
local Plugin = Rojo.Plugin
|
||||||
local Packages = Rojo.Packages
|
local Packages = Rojo.Packages
|
||||||
@@ -92,7 +95,65 @@ function App:getHostAndPort()
|
|||||||
return host, port
|
return host, port
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function App:claimSyncLock()
|
||||||
|
if #Players:GetPlayers() == 0 then
|
||||||
|
Log.trace("Skipping sync lock because this isn't in Team Create")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local lock = ServerStorage:FindFirstChild("__Rojo_SessionLock")
|
||||||
|
if not lock then
|
||||||
|
lock = Instance.new("ObjectValue")
|
||||||
|
lock.Name = "__Rojo_SessionLock"
|
||||||
|
lock.Archivable = false
|
||||||
|
lock.Value = Players.LocalPlayer
|
||||||
|
lock.Parent = ServerStorage
|
||||||
|
Log.trace("Created and claimed sync lock")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if lock.Value and lock.Value ~= Players.LocalPlayer and lock.Value.Parent then
|
||||||
|
Log.trace("Found existing sync lock owned by {}", lock.Value)
|
||||||
|
return false, lock.Value
|
||||||
|
end
|
||||||
|
|
||||||
|
lock.Value = Players.LocalPlayer
|
||||||
|
Log.trace("Claimed existing sync lock")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function App:releaseSyncLock()
|
||||||
|
local lock = ServerStorage:FindFirstChild("__Rojo_SessionLock")
|
||||||
|
if not lock then
|
||||||
|
Log.trace("No sync lock found, assumed released")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if lock.Value == Players.LocalPlayer then
|
||||||
|
lock.Value = nil
|
||||||
|
Log.trace("Released sync lock")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
Log.trace("Could not relase sync lock because it is owned by {}", lock.Value)
|
||||||
|
end
|
||||||
|
|
||||||
function App:startSession()
|
function App:startSession()
|
||||||
|
local claimedLock, priorOwner = self:claimSyncLock()
|
||||||
|
if not claimedLock then
|
||||||
|
local msg = string.format("Could not sync because user '%s' is already syncing", tostring(priorOwner))
|
||||||
|
|
||||||
|
Log.warn(msg)
|
||||||
|
self:addNotification(msg, 10)
|
||||||
|
self:setState({
|
||||||
|
appStatus = AppStatus.Error,
|
||||||
|
errorMessage = msg,
|
||||||
|
toolbarIcon = Assets.Images.PluginButtonWarning,
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local host, port = self:getHostAndPort()
|
local host, port = self:getHostAndPort()
|
||||||
|
|
||||||
local sessionOptions = {
|
local sessionOptions = {
|
||||||
@@ -155,6 +216,7 @@ function App:startSession()
|
|||||||
self:addNotification(string.format("Connected to session '%s' at %s.", details, address), 5)
|
self:addNotification(string.format("Connected to session '%s' at %s.", details, address), 5)
|
||||||
elseif status == ServeSession.Status.Disconnected then
|
elseif status == ServeSession.Status.Disconnected then
|
||||||
self.serveSession = nil
|
self.serveSession = nil
|
||||||
|
self:releaseSyncLock()
|
||||||
|
|
||||||
-- Details being present indicates that this
|
-- Details being present indicates that this
|
||||||
-- disconnection was from an error.
|
-- disconnection was from an error.
|
||||||
|
|||||||
@@ -115,6 +115,12 @@ local function diff(instanceMap, virtualInstances, rootId)
|
|||||||
local childId = instanceMap.fromInstances[childInstance]
|
local childId = instanceMap.fromInstances[childInstance]
|
||||||
|
|
||||||
if childId == nil then
|
if childId == nil then
|
||||||
|
if childInstance.Archivable == false then
|
||||||
|
-- We don't remove instances that aren't going to be saved anyway,
|
||||||
|
-- such as the Rojo session lock value.
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
-- This is an existing instance not present in the virtual DOM.
|
-- This is an existing instance not present in the virtual DOM.
|
||||||
-- We can mark it for deletion unless the user has asked us not
|
-- We can mark it for deletion unless the user has asked us not
|
||||||
-- to delete unknown stuff.
|
-- to delete unknown stuff.
|
||||||
|
|||||||
Reference in New Issue
Block a user