robloxstudio-mcp 2.2.1 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -313,14 +313,11 @@ local function activatePlugin(connIndex)
|
|
|
313
313
|
return nil
|
|
314
314
|
end
|
|
315
315
|
local ui = UI.getElements()
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
ui.urlInput.Text = conn.serverUrl
|
|
322
|
-
end
|
|
323
|
-
elseif idx == State.getActiveTabIndex() then
|
|
316
|
+
conn.isActive = true
|
|
317
|
+
conn.consecutiveFailures = 0
|
|
318
|
+
conn.currentRetryDelay = 0.5
|
|
319
|
+
ui.screenGui.Enabled = true
|
|
320
|
+
if idx == State.getActiveTabIndex() then
|
|
324
321
|
conn.serverUrl = ui.urlInput.Text
|
|
325
322
|
local portStr = string.match(conn.serverUrl, ":(%d+)$")
|
|
326
323
|
if portStr ~= 0 and portStr == portStr and portStr ~= "" and portStr then
|
|
@@ -330,28 +327,9 @@ local function activatePlugin(connIndex)
|
|
|
330
327
|
end
|
|
331
328
|
conn.port = _condition_1
|
|
332
329
|
end
|
|
333
|
-
end
|
|
334
|
-
conn.isActive = true
|
|
335
|
-
conn.consecutiveFailures = 0
|
|
336
|
-
conn.currentRetryDelay = 0.5
|
|
337
|
-
ui.screenGui.Enabled = true
|
|
338
|
-
if idx == State.getActiveTabIndex() then
|
|
339
330
|
UI.updateUIState()
|
|
340
331
|
end
|
|
341
332
|
UI.updateTabDot(idx)
|
|
342
|
-
pcall(function()
|
|
343
|
-
HttpService:RequestAsync({
|
|
344
|
-
Url = `{conn.serverUrl}/ready`,
|
|
345
|
-
Method = "POST",
|
|
346
|
-
Headers = {
|
|
347
|
-
["Content-Type"] = "application/json",
|
|
348
|
-
},
|
|
349
|
-
Body = HttpService:JSONEncode({
|
|
350
|
-
pluginReady = true,
|
|
351
|
-
timestamp = tick(),
|
|
352
|
-
}),
|
|
353
|
-
})
|
|
354
|
-
end)
|
|
355
333
|
if not conn.heartbeatConnection then
|
|
356
334
|
conn.heartbeatConnection = RunService.Heartbeat:Connect(function()
|
|
357
335
|
local now = tick()
|
|
@@ -362,6 +340,29 @@ local function activatePlugin(connIndex)
|
|
|
362
340
|
end
|
|
363
341
|
end)
|
|
364
342
|
end
|
|
343
|
+
task.spawn(function()
|
|
344
|
+
local discoveredPort = discoverPort()
|
|
345
|
+
if discoveredPort ~= nil then
|
|
346
|
+
conn.port = discoveredPort
|
|
347
|
+
conn.serverUrl = `http://localhost:{discoveredPort}`
|
|
348
|
+
if idx == State.getActiveTabIndex() then
|
|
349
|
+
ui.urlInput.Text = conn.serverUrl
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
pcall(function()
|
|
353
|
+
HttpService:RequestAsync({
|
|
354
|
+
Url = `{conn.serverUrl}/ready`,
|
|
355
|
+
Method = "POST",
|
|
356
|
+
Headers = {
|
|
357
|
+
["Content-Type"] = "application/json",
|
|
358
|
+
},
|
|
359
|
+
Body = HttpService:JSONEncode({
|
|
360
|
+
pluginReady = true,
|
|
361
|
+
timestamp = tick(),
|
|
362
|
+
}),
|
|
363
|
+
})
|
|
364
|
+
end)
|
|
365
|
+
end)
|
|
365
366
|
end
|
|
366
367
|
local function deactivatePlugin(connIndex)
|
|
367
368
|
local _condition = connIndex
|
|
@@ -3031,6 +3032,7 @@ local stopListenerScript
|
|
|
3031
3032
|
local function buildStopListenerSource(port)
|
|
3032
3033
|
return `local HttpService = game:GetService("HttpService")\
|
|
3033
3034
|
local StudioTestService = game:GetService("StudioTestService")\
|
|
3035
|
+
warn("[MCP] Stop listener started, polling port {port}")\
|
|
3034
3036
|
while true do\
|
|
3035
3037
|
local ok, res = pcall(function()\
|
|
3036
3038
|
return HttpService:RequestAsync(\{\
|
|
@@ -3038,12 +3040,20 @@ while true do\
|
|
|
3038
3040
|
Method = "GET",\
|
|
3039
3041
|
\})\
|
|
3040
3042
|
end)\
|
|
3041
|
-
if ok
|
|
3043
|
+
if not ok then\
|
|
3044
|
+
warn("[MCP] HTTP request failed: " .. tostring(res))\
|
|
3045
|
+
elseif not res.Success then\
|
|
3046
|
+
warn("[MCP] HTTP " .. tostring(res.StatusCode) .. ": " .. tostring(res.Body))\
|
|
3047
|
+
else\
|
|
3042
3048
|
local dok, data = pcall(function()\
|
|
3043
3049
|
return HttpService:JSONDecode(res.Body)\
|
|
3044
3050
|
end)\
|
|
3045
3051
|
if dok and data.shouldStop then\
|
|
3046
|
-
|
|
3052
|
+
warn("[MCP] Stop signal received, calling EndTest")\
|
|
3053
|
+
local eok, eerr = pcall(function() StudioTestService:EndTest("stopped_by_mcp") end)\
|
|
3054
|
+
if not eok then\
|
|
3055
|
+
warn("[MCP] EndTest failed: " .. tostring(eerr))\
|
|
3056
|
+
end\
|
|
3047
3057
|
return\
|
|
3048
3058
|
end\
|
|
3049
3059
|
end\
|
|
@@ -3163,7 +3173,7 @@ return {
|
|
|
3163
3173
|
<Properties>
|
|
3164
3174
|
<string name="Name">State</string>
|
|
3165
3175
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
3166
|
-
local CURRENT_VERSION = "2.2.
|
|
3176
|
+
local CURRENT_VERSION = "2.2.2"
|
|
3167
3177
|
local MAX_CONNECTIONS = 5
|
|
3168
3178
|
local BASE_PORT = 58741
|
|
3169
3179
|
local activeTabIndex = 0
|
|
@@ -264,36 +264,19 @@ function activatePlugin(connIndex?: number) {
|
|
|
264
264
|
|
|
265
265
|
const ui = UI.getElements();
|
|
266
266
|
|
|
267
|
-
const discoveredPort = discoverPort();
|
|
268
|
-
if (discoveredPort !== undefined) {
|
|
269
|
-
conn.port = discoveredPort;
|
|
270
|
-
conn.serverUrl = `http://localhost:${discoveredPort}`;
|
|
271
|
-
if (idx === State.getActiveTabIndex()) {
|
|
272
|
-
ui.urlInput.Text = conn.serverUrl;
|
|
273
|
-
}
|
|
274
|
-
} else if (idx === State.getActiveTabIndex()) {
|
|
275
|
-
conn.serverUrl = ui.urlInput.Text;
|
|
276
|
-
const [portStr] = conn.serverUrl.match(":(%d+)$");
|
|
277
|
-
if (portStr) conn.port = tonumber(portStr) ?? conn.port;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
267
|
conn.isActive = true;
|
|
281
268
|
conn.consecutiveFailures = 0;
|
|
282
269
|
conn.currentRetryDelay = 0.5;
|
|
283
270
|
ui.screenGui.Enabled = true;
|
|
284
271
|
|
|
285
|
-
if (idx === State.getActiveTabIndex())
|
|
272
|
+
if (idx === State.getActiveTabIndex()) {
|
|
273
|
+
conn.serverUrl = ui.urlInput.Text;
|
|
274
|
+
const [portStr] = conn.serverUrl.match(":(%d+)$");
|
|
275
|
+
if (portStr) conn.port = tonumber(portStr) ?? conn.port;
|
|
276
|
+
UI.updateUIState();
|
|
277
|
+
}
|
|
286
278
|
UI.updateTabDot(idx);
|
|
287
279
|
|
|
288
|
-
pcall(() => {
|
|
289
|
-
HttpService.RequestAsync({
|
|
290
|
-
Url: `${conn.serverUrl}/ready`,
|
|
291
|
-
Method: "POST",
|
|
292
|
-
Headers: { "Content-Type": "application/json" },
|
|
293
|
-
Body: HttpService.JSONEncode({ pluginReady: true, timestamp: tick() }),
|
|
294
|
-
});
|
|
295
|
-
});
|
|
296
|
-
|
|
297
280
|
if (!conn.heartbeatConnection) {
|
|
298
281
|
conn.heartbeatConnection = RunService.Heartbeat.Connect(() => {
|
|
299
282
|
const now = tick();
|
|
@@ -304,6 +287,26 @@ function activatePlugin(connIndex?: number) {
|
|
|
304
287
|
}
|
|
305
288
|
});
|
|
306
289
|
}
|
|
290
|
+
|
|
291
|
+
task.spawn(() => {
|
|
292
|
+
const discoveredPort = discoverPort();
|
|
293
|
+
if (discoveredPort !== undefined) {
|
|
294
|
+
conn.port = discoveredPort;
|
|
295
|
+
conn.serverUrl = `http://localhost:${discoveredPort}`;
|
|
296
|
+
if (idx === State.getActiveTabIndex()) {
|
|
297
|
+
ui.urlInput.Text = conn.serverUrl;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
pcall(() => {
|
|
302
|
+
HttpService.RequestAsync({
|
|
303
|
+
Url: `${conn.serverUrl}/ready`,
|
|
304
|
+
Method: "POST",
|
|
305
|
+
Headers: { "Content-Type": "application/json" },
|
|
306
|
+
Body: HttpService.JSONEncode({ pluginReady: true, timestamp: tick() }),
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
});
|
|
307
310
|
}
|
|
308
311
|
|
|
309
312
|
function deactivatePlugin(connIndex?: number) {
|
|
@@ -21,6 +21,7 @@ let stopListenerScript: Script | undefined;
|
|
|
21
21
|
function buildStopListenerSource(port: number): string {
|
|
22
22
|
return `local HttpService = game:GetService("HttpService")
|
|
23
23
|
local StudioTestService = game:GetService("StudioTestService")
|
|
24
|
+
warn("[MCP] Stop listener started, polling port ${port}")
|
|
24
25
|
while true do
|
|
25
26
|
local ok, res = pcall(function()
|
|
26
27
|
return HttpService:RequestAsync({
|
|
@@ -28,12 +29,20 @@ while true do
|
|
|
28
29
|
Method = "GET",
|
|
29
30
|
})
|
|
30
31
|
end)
|
|
31
|
-
if ok
|
|
32
|
+
if not ok then
|
|
33
|
+
warn("[MCP] HTTP request failed: " .. tostring(res))
|
|
34
|
+
elseif not res.Success then
|
|
35
|
+
warn("[MCP] HTTP " .. tostring(res.StatusCode) .. ": " .. tostring(res.Body))
|
|
36
|
+
else
|
|
32
37
|
local dok, data = pcall(function()
|
|
33
38
|
return HttpService:JSONDecode(res.Body)
|
|
34
39
|
end)
|
|
35
40
|
if dok and data.shouldStop then
|
|
36
|
-
|
|
41
|
+
warn("[MCP] Stop signal received, calling EndTest")
|
|
42
|
+
local eok, eerr = pcall(function() StudioTestService:EndTest("stopped_by_mcp") end)
|
|
43
|
+
if not eok then
|
|
44
|
+
warn("[MCP] EndTest failed: " .. tostring(eerr))
|
|
45
|
+
end
|
|
37
46
|
return
|
|
38
47
|
end
|
|
39
48
|
end
|