forked from rojo-rbx/rojo
Play Solo & Test Server auto connect (#840)
When enabled, the `baseurl` of the session is written to
`workspace:SetAttribute("__Rojo_ConnectionUrl")` so that the test server
can connect to that session automatically.
This works for Play Solo and Local Test Server. It is marked
experimental for now (and disabled by default) since connecting during a
playtest session is... not polished. Rojo may overwrite things and cause
headaches. Further work can be done later.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
## Unreleased Changes
|
||||
* Added popout diff visualizer for table properties like Attributes and Tags ([#834])
|
||||
* Updated Theme to use Studio colors ([#838])
|
||||
* Added experimental setting for Auto Connect in playtests ([#840])
|
||||
* Projects may now specify rules for syncing files as if they had a different file extension. ([#813])
|
||||
This is specified via a new field on project files, `syncRules`:
|
||||
|
||||
@@ -53,6 +54,7 @@
|
||||
[#813]: https://github.com/rojo-rbx/rojo/pull/813
|
||||
[#834]: https://github.com/rojo-rbx/rojo/pull/834
|
||||
[#838]: https://github.com/rojo-rbx/rojo/pull/838
|
||||
[#840]: https://github.com/rojo-rbx/rojo/pull/840
|
||||
|
||||
## [7.4.0] - January 16, 2024
|
||||
* Improved the visualization for array properties like Tags ([#829])
|
||||
|
||||
@@ -75,6 +75,12 @@ function SettingsPage:init()
|
||||
end
|
||||
|
||||
function SettingsPage:render()
|
||||
local layoutOrder = 0
|
||||
local function layoutIncrement()
|
||||
layoutOrder += 1
|
||||
return layoutOrder
|
||||
end
|
||||
|
||||
return Theme.with(function(theme)
|
||||
theme = theme.Settings
|
||||
|
||||
@@ -86,7 +92,7 @@ function SettingsPage:render()
|
||||
Navbar = e(Navbar, {
|
||||
onBack = self.props.onBack,
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 0,
|
||||
layoutOrder = layoutIncrement(),
|
||||
}),
|
||||
|
||||
ShowNotifications = e(Setting, {
|
||||
@@ -94,7 +100,7 @@ function SettingsPage:render()
|
||||
name = "Show Notifications",
|
||||
description = "Popup notifications in viewport",
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 1,
|
||||
layoutOrder = layoutIncrement(),
|
||||
}),
|
||||
|
||||
SyncReminder = e(Setting, {
|
||||
@@ -103,7 +109,7 @@ function SettingsPage:render()
|
||||
description = "Notify to sync when opening a place that has previously been synced",
|
||||
transparency = self.props.transparency,
|
||||
visible = Settings:getBinding("showNotifications"),
|
||||
layoutOrder = 2,
|
||||
layoutOrder = layoutIncrement(),
|
||||
}),
|
||||
|
||||
ConfirmationBehavior = e(Setting, {
|
||||
@@ -111,7 +117,7 @@ function SettingsPage:render()
|
||||
name = "Confirmation Behavior",
|
||||
description = "When to prompt for confirmation before syncing",
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 3,
|
||||
layoutOrder = layoutIncrement(),
|
||||
|
||||
options = confirmationBehaviors,
|
||||
}),
|
||||
@@ -121,7 +127,7 @@ function SettingsPage:render()
|
||||
name = "Confirmation Threshold",
|
||||
description = "How many modified instances to be considered a large change",
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 4,
|
||||
layoutOrder = layoutIncrement(),
|
||||
visible = Settings:getBinding("confirmationBehavior"):map(function(value)
|
||||
return value == "Large Changes"
|
||||
end),
|
||||
@@ -152,7 +158,16 @@ function SettingsPage:render()
|
||||
name = "Play Sounds",
|
||||
description = "Toggle sound effects",
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 5,
|
||||
layoutOrder = layoutIncrement(),
|
||||
}),
|
||||
|
||||
AutoConnectPlaytestServer = e(Setting, {
|
||||
id = "autoConnectPlaytestServer",
|
||||
name = "Auto Connect Playtest Server",
|
||||
description = "Automatically connect game server to Rojo when playtesting while connected in Edit",
|
||||
experimental = true,
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = layoutIncrement(),
|
||||
}),
|
||||
|
||||
OpenScriptsExternally = e(Setting, {
|
||||
@@ -162,7 +177,7 @@ function SettingsPage:render()
|
||||
locked = self.props.syncActive,
|
||||
experimental = true,
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 6,
|
||||
layoutOrder = layoutIncrement(),
|
||||
}),
|
||||
|
||||
TwoWaySync = e(Setting, {
|
||||
@@ -172,7 +187,7 @@ function SettingsPage:render()
|
||||
locked = self.props.syncActive,
|
||||
experimental = true,
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 7,
|
||||
layoutOrder = layoutIncrement(),
|
||||
}),
|
||||
|
||||
LogLevel = e(Setting, {
|
||||
@@ -180,7 +195,7 @@ function SettingsPage:render()
|
||||
name = "Log Level",
|
||||
description = "Plugin output verbosity level",
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 100,
|
||||
layoutOrder = layoutIncrement(),
|
||||
|
||||
options = invertedLevels,
|
||||
showReset = Settings:getBinding("logLevel"):map(function(value)
|
||||
@@ -196,7 +211,7 @@ function SettingsPage:render()
|
||||
name = "Typechecking",
|
||||
description = "Toggle typechecking on the API surface",
|
||||
transparency = self.props.transparency,
|
||||
layoutOrder = 101,
|
||||
layoutOrder = layoutIncrement(),
|
||||
}),
|
||||
|
||||
Layout = e("UIListLayout", {
|
||||
|
||||
@@ -158,11 +158,29 @@ function App:init()
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
if self:isAutoConnectPlaytestServerAvailable() then
|
||||
self:useRunningConnectionInfo()
|
||||
self:startSession()
|
||||
end
|
||||
self.autoConnectPlaytestServerListener = Settings:onChanged("autoConnectPlaytestServer", function(enabled)
|
||||
if enabled then
|
||||
if self:isAutoConnectPlaytestServerWriteable() and self.serveSession ~= nil then
|
||||
-- Write the existing session
|
||||
local baseUrl = self.serveSession.__apiContext.__baseUrl
|
||||
self:setRunningConnectionInfo(baseUrl)
|
||||
end
|
||||
else
|
||||
self:clearRunningConnectionInfo()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function App:willUnmount()
|
||||
self.waypointConnection:Disconnect()
|
||||
self.confirmationBindable:Destroy()
|
||||
self.autoConnectPlaytestServerListener()
|
||||
self:clearRunningConnectionInfo()
|
||||
end
|
||||
|
||||
function App:addNotification(
|
||||
@@ -278,10 +296,7 @@ function App:getHostAndPort()
|
||||
local host = self.host:getValue()
|
||||
local port = self.port:getValue()
|
||||
|
||||
local host = if #host > 0 then host else Config.defaultHost
|
||||
local port = if #port > 0 then port else Config.defaultPort
|
||||
|
||||
return host, port
|
||||
return if #host > 0 then host else Config.defaultHost, if #port > 0 then port else Config.defaultPort
|
||||
end
|
||||
|
||||
function App:isSyncLockAvailable()
|
||||
@@ -349,6 +364,49 @@ function App:releaseSyncLock()
|
||||
Log.trace("Could not relase sync lock because it is owned by {}", lock.Value)
|
||||
end
|
||||
|
||||
function App:isAutoConnectPlaytestServerAvailable()
|
||||
return RunService:IsRunMode()
|
||||
and RunService:IsServer()
|
||||
and Settings:get("autoConnectPlaytestServer")
|
||||
and workspace:GetAttribute("__Rojo_ConnectionUrl")
|
||||
end
|
||||
|
||||
function App:isAutoConnectPlaytestServerWriteable()
|
||||
return RunService:IsEdit() and Settings:get("autoConnectPlaytestServer")
|
||||
end
|
||||
|
||||
function App:setRunningConnectionInfo(baseUrl: string)
|
||||
if not self:isAutoConnectPlaytestServerWriteable() then
|
||||
return
|
||||
end
|
||||
|
||||
Log.trace("Setting connection info for play solo auto-connect")
|
||||
workspace:SetAttribute("__Rojo_ConnectionUrl", baseUrl)
|
||||
end
|
||||
|
||||
function App:clearRunningConnectionInfo()
|
||||
if not RunService:IsEdit() then
|
||||
-- Only write connection info from edit mode
|
||||
return
|
||||
end
|
||||
|
||||
Log.trace("Clearing connection info for play solo auto-connect")
|
||||
workspace:SetAttribute("__Rojo_ConnectionUrl", nil)
|
||||
end
|
||||
|
||||
function App:useRunningConnectionInfo()
|
||||
local connectionInfo = workspace:GetAttribute("__Rojo_ConnectionUrl")
|
||||
if not connectionInfo then
|
||||
return
|
||||
end
|
||||
|
||||
Log.trace("Using connection info for play solo auto-connect")
|
||||
local host, port = string.match(connectionInfo, "^(.+):(.-)$")
|
||||
|
||||
self.setHost(host)
|
||||
self.setPort(port)
|
||||
end
|
||||
|
||||
function App:startSession()
|
||||
local claimedLock, priorOwner = self:claimSyncLock()
|
||||
if not claimedLock then
|
||||
@@ -441,6 +499,7 @@ function App:startSession()
|
||||
self:addNotification("Connecting to session...")
|
||||
elseif status == ServeSession.Status.Connected then
|
||||
self.knownProjects[details] = true
|
||||
self:setRunningConnectionInfo(baseUrl)
|
||||
|
||||
local address = ("%s:%s"):format(host, port)
|
||||
self:setState({
|
||||
@@ -453,6 +512,7 @@ function App:startSession()
|
||||
elseif status == ServeSession.Status.Disconnected then
|
||||
self.serveSession = nil
|
||||
self:releaseSyncLock()
|
||||
self:clearRunningConnectionInfo()
|
||||
self:setState({
|
||||
patchData = {
|
||||
patch = PatchSet.newEmpty(),
|
||||
@@ -488,6 +548,12 @@ function App:startSession()
|
||||
return "Accept"
|
||||
end
|
||||
|
||||
-- Play solo auto-connect does not require confirmation
|
||||
if self:isAutoConnectPlaytestServerAvailable() then
|
||||
Log.trace("Accepting patch without confirmation because play solo auto-connect is enabled")
|
||||
return "Accept"
|
||||
end
|
||||
|
||||
local confirmationBehavior = Settings:get("confirmationBehavior")
|
||||
if confirmationBehavior == "Initial" then
|
||||
-- Only confirm if we haven't synced this project yet this session
|
||||
@@ -603,7 +669,7 @@ function App:render()
|
||||
value = self.props.plugin,
|
||||
}, {
|
||||
e(Theme.StudioProvider, nil, {
|
||||
e(Tooltip.Provider, nil, {
|
||||
tooltip = e(Tooltip.Provider, nil, {
|
||||
gui = e(StudioPluginGui, {
|
||||
id = pluginName,
|
||||
title = pluginName,
|
||||
|
||||
@@ -14,6 +14,7 @@ local defaultSettings = {
|
||||
twoWaySync = false,
|
||||
showNotifications = true,
|
||||
syncReminder = true,
|
||||
autoConnectPlaytestServer = false,
|
||||
confirmationBehavior = "Initial",
|
||||
largeChangesConfirmationThreshold = 5,
|
||||
playSounds = true,
|
||||
|
||||
Reference in New Issue
Block a user