diff --git a/CHANGELOG.md b/CHANGELOG.md index 3943ae5f..47becf92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,10 +40,12 @@ Making a new release? Simply add the new header with the version and date undern * Fixed `$path` values that point outside the project folder failing to match `syncRule`s on Windows, which broke `rojo sourcemap` with a "could not be turned into a Roblox Instance" error. ([#1290]) * Fixed `rojo serve` silently stopping syncing file changes on Windows when the served project path was a verbatim (`\\?\`) path, because tree paths and file-watcher event paths were canonicalized to different forms. ([#1290]) * Fixed `rojo sourcemap --absolute` emitting verbatim (`\\?\`) paths on Windows, which broke require types in luau-lsp. ([#1290]) +* Local place files can now be auto-connected via the `__Rojo_ProjectName` attribute on Workspace. ([#1296]) * The plugin now disables the `Check for Updates` setting if you block access to `api.github.com`. ([#1297]) [7.7.1]: https://github.com/rojo-rbx/rojo/releases/tag/v7.7.1 [#1290]: https://github.com/rojo-rbx/rojo/pull/1290 +[#1296]: https://github.com/rojo-rbx/rojo/pull/1296 [#1297]: https://github.com/rojo-rbx/rojo/pull/1297 ## [7.7.0] (July 1st, 2026) diff --git a/plugin/src/App/init.lua b/plugin/src/App/init.lua index e6e4deee..7e3614b8 100644 --- a/plugin/src/App/init.lua +++ b/plugin/src/App/init.lua @@ -255,18 +255,32 @@ function App:checkForUpdates() end end +local function getActiveProjectIdentifier(): string + local placeId = tostring(game.PlaceId) + + local attributeProjectName = workspace:GetAttribute("__Rojo_ProjectName") + assert( + typeof(attributeProjectName) == "string" or typeof(attributeProjectName) == "nil", + `Expected Workspace attribute '__Rojo_ProjectName' to be a string or nil, got {typeof(attributeProjectName)}` + ) + + local identifier = attributeProjectName or placeId + + return identifier +end + function App:getPriorSyncInfo(): { host: string?, port: string?, projectName: string?, timestamp: number? } local priorSyncInfos = Settings:get("priorEndpoints") if not priorSyncInfos then return {} end - local id = tostring(game.PlaceId) - if ignorePlaceIds[id] then + local identifier = getActiveProjectIdentifier() + if ignorePlaceIds[identifier] then return {} end - return priorSyncInfos[id] or {} + return priorSyncInfos[identifier] or {} end function App:setPriorSyncInfo(host: string, port: string, projectName: string) @@ -278,25 +292,25 @@ function App:setPriorSyncInfo(host: string, port: string, projectName: string) local now = os.time() -- Clear any stale saves to avoid disc bloat - for placeId, syncInfo in priorSyncInfos do + for identifier, syncInfo in priorSyncInfos do if now - (syncInfo.timestamp or now) > 12_960_000 then - priorSyncInfos[placeId] = nil - Log.trace("Cleared stale saved endpoint for {}", placeId) + priorSyncInfos[identifier] = nil + Log.trace("Cleared stale saved endpoint for {}", identifier) end end - local id = tostring(game.PlaceId) - if ignorePlaceIds[id] then + local identifier = getActiveProjectIdentifier() + if ignorePlaceIds[identifier] then return end - priorSyncInfos[id] = { + priorSyncInfos[identifier] = { host = if host ~= Config.defaultHost then host else nil, port = if port ~= Config.defaultPort then port else nil, projectName = projectName, timestamp = now, } - Log.trace("Saved last used endpoint for {}", game.PlaceId) + Log.trace("Saved last used endpoint for {}", identifier) Settings:set("priorEndpoints", priorSyncInfos) end @@ -307,9 +321,9 @@ function App:forgetPriorSyncInfo() priorSyncInfos = {} end - local id = tostring(game.PlaceId) - priorSyncInfos[id] = nil - Log.trace("Erased last used endpoint for {}", game.PlaceId) + local identifier = getActiveProjectIdentifier() + priorSyncInfos[identifier] = nil + Log.trace("Erased last used endpoint for {}", identifier) Settings:set("priorEndpoints", priorSyncInfos) end