mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 05:51:39 +00:00
Implement one-shot mode for explicit confirmation in ServeSession
- Introduced one-shot mode to block automatic outgoing writes and require explicit user confirmation for all changes. - Updated confirmation logic in App:startSession to ensure no auto-acceptance occurs during one-shot mode. - Enhanced logging to provide clarity on actions taken during one-shot mode, improving user awareness and control over sync operations.
This commit is contained in:
parent
d002c4e821
commit
78aab0eca4
2 changed files with 80 additions and 68 deletions
|
|
@ -709,28 +709,19 @@ function App:startSession()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
serveSession:setConfirmCallback(function(instanceMap, patch, serverInfo)
|
serveSession:setConfirmCallback(function(instanceMap, patch, serverInfo)
|
||||||
-- Helper to schedule one-shot disconnect after auto-accept
|
local isOneShotMode = Settings:get("oneShotSync")
|
||||||
local function scheduleOneShotDisconnect()
|
|
||||||
if Settings:get("oneShotSync") then
|
|
||||||
task.delay(0.5, function()
|
|
||||||
if self.serveSession then
|
|
||||||
Log.info("One-shot sync: disconnecting after sync")
|
|
||||||
self:endSession()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
-- ONE-SHOT MODE: Never auto-accept, always require explicit confirmation
|
||||||
|
-- This ensures nothing can "sneak through" without user review
|
||||||
|
if not isOneShotMode then
|
||||||
if PatchSet.isEmpty(patch) then
|
if PatchSet.isEmpty(patch) then
|
||||||
Log.trace("Accepting patch without confirmation because it is empty")
|
Log.trace("Accepting patch without confirmation because it is empty")
|
||||||
scheduleOneShotDisconnect()
|
|
||||||
return "Accept"
|
return "Accept"
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Play solo auto-connect does not require confirmation
|
-- Play solo auto-connect does not require confirmation
|
||||||
if self:isAutoConnectPlaytestServerAvailable() then
|
if self:isAutoConnectPlaytestServerAvailable() then
|
||||||
Log.trace("Accepting patch without confirmation because play solo auto-connect is enabled")
|
Log.trace("Accepting patch without confirmation because play solo auto-connect is enabled")
|
||||||
scheduleOneShotDisconnect()
|
|
||||||
return "Accept"
|
return "Accept"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -742,7 +733,6 @@ function App:startSession()
|
||||||
Log.trace(
|
Log.trace(
|
||||||
"Accepting patch without confirmation because project has already been connected and behavior is set to Initial"
|
"Accepting patch without confirmation because project has already been connected and behavior is set to Initial"
|
||||||
)
|
)
|
||||||
scheduleOneShotDisconnect()
|
|
||||||
return "Accept"
|
return "Accept"
|
||||||
end
|
end
|
||||||
elseif confirmationBehavior == "Large Changes" then
|
elseif confirmationBehavior == "Large Changes" then
|
||||||
|
|
@ -751,7 +741,6 @@ function App:startSession()
|
||||||
Log.trace(
|
Log.trace(
|
||||||
"Accepting patch without confirmation because patch is small and behavior is set to Large Changes"
|
"Accepting patch without confirmation because patch is small and behavior is set to Large Changes"
|
||||||
)
|
)
|
||||||
scheduleOneShotDisconnect()
|
|
||||||
return "Accept"
|
return "Accept"
|
||||||
end
|
end
|
||||||
elseif confirmationBehavior == "Unlisted PlaceId" then
|
elseif confirmationBehavior == "Unlisted PlaceId" then
|
||||||
|
|
@ -762,13 +751,11 @@ function App:startSession()
|
||||||
Log.trace(
|
Log.trace(
|
||||||
"Accepting patch without confirmation because placeId is listed and behavior is set to Unlisted PlaceId"
|
"Accepting patch without confirmation because placeId is listed and behavior is set to Unlisted PlaceId"
|
||||||
)
|
)
|
||||||
scheduleOneShotDisconnect()
|
|
||||||
return "Accept"
|
return "Accept"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif confirmationBehavior == "Never" then
|
elseif confirmationBehavior == "Never" then
|
||||||
Log.trace("Accepting patch without confirmation because behavior is set to Never")
|
Log.trace("Accepting patch without confirmation because behavior is set to Never")
|
||||||
scheduleOneShotDisconnect()
|
|
||||||
return "Accept"
|
return "Accept"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -787,10 +774,12 @@ function App:startSession()
|
||||||
and datamodelUpdates.changedClassName == nil
|
and datamodelUpdates.changedClassName == nil
|
||||||
then
|
then
|
||||||
Log.trace("Accepting patch without confirmation because it only contains a datamodel name change")
|
Log.trace("Accepting patch without confirmation because it only contains a datamodel name change")
|
||||||
scheduleOneShotDisconnect()
|
|
||||||
return "Accept"
|
return "Accept"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
Log.info("One-shot mode: skipping all auto-accept paths, requiring explicit confirmation")
|
||||||
|
end
|
||||||
|
|
||||||
self:setState({
|
self:setState({
|
||||||
connectingText = "Computing diff view...",
|
connectingText = "Computing diff view...",
|
||||||
|
|
@ -845,6 +834,13 @@ function App:startSession()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
serveSession:setPatchUpdateCallback(function(instanceMap, patch)
|
serveSession:setPatchUpdateCallback(function(instanceMap, patch)
|
||||||
|
-- ONE-SHOT MODE: Ignore all further changes during confirmation
|
||||||
|
-- They will be picked up on the next connection attempt
|
||||||
|
if Settings:get("oneShotSync") then
|
||||||
|
Log.info("One-shot mode: ignoring incoming changes during confirmation")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- If all changes have been reverted, auto-accept the empty patch
|
-- If all changes have been reverted, auto-accept the empty patch
|
||||||
if PatchSet.isEmpty(patch) then
|
if PatchSet.isEmpty(patch) then
|
||||||
Log.trace("Patch became empty after merging, auto-accepting")
|
Log.trace("Patch became empty after merging, auto-accepting")
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,15 @@ function ServeSession.new(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onChangesFlushed(patch)
|
local function onChangesFlushed(patch)
|
||||||
|
-- ONE-SHOT MODE: Block ALL automatic outgoing writes from the ChangeBatcher.
|
||||||
|
-- The only writes allowed in One-shot mode are explicit "pull" selections
|
||||||
|
-- from the confirmation dialog (handled directly in __confirmAndApplyInitialPatch).
|
||||||
|
-- This ensures nothing can be pushed to the server without explicit user action.
|
||||||
|
if Settings:get("oneShotSync") then
|
||||||
|
Log.info("One-shot mode: blocking automatic outgoing write from ChangeBatcher")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
self.__apiContext:write(patch)
|
self.__apiContext:write(patch)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -211,7 +220,14 @@ function ServeSession:__onWebSocketMessage(messagesPacket)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- If we're already waiting for confirmation, merge into the patch being confirmed
|
-- If we're already waiting for confirmation, merge into the patch being confirmed
|
||||||
|
-- UNLESS we're in One-shot mode, where we ignore all further changes
|
||||||
if self.__confirmingPatch ~= nil then
|
if self.__confirmingPatch ~= nil then
|
||||||
|
if Settings:get("oneShotSync") then
|
||||||
|
Log.info("One-shot mode: ignoring incoming changes while confirming (will be picked up on next connection)")
|
||||||
|
self.__apiContext:setMessageCursor(messagesPacket.messageCursor)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
Log.trace("Already confirming, merging into current patch")
|
Log.trace("Already confirming, merging into current patch")
|
||||||
PatchSet.merge(self.__confirmingPatch, combinedPatch, self.__instanceMap)
|
PatchSet.merge(self.__confirmingPatch, combinedPatch, self.__instanceMap)
|
||||||
-- Notify the UI to update the displayed patch
|
-- Notify the UI to update the displayed patch
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue