@chrrxs/robloxstudio-mcp-inspector 3.1.2 → 3.1.4
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/dist/index.js +366 -57
- package/package.json +1 -1
- package/studio-plugin/MCPInspectorPlugin.rbxmx +548 -58
|
@@ -278,6 +278,326 @@ return {
|
|
|
278
278
|
</Properties>
|
|
279
279
|
</Item>
|
|
280
280
|
<Item class="ModuleScript" referent="3">
|
|
281
|
+
<Properties>
|
|
282
|
+
<string name="Name">CaptureTransfer</string>
|
|
283
|
+
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
284
|
+
-- Private ClientBroker transport. Only metadata and <=1 MiB data chunks cross
|
|
285
|
+
-- InvokeClient; callers still receive the original capture-studio response.
|
|
286
|
+
local HttpService = game:GetService("HttpService")
|
|
287
|
+
local READ_ENDPOINT = "/__mcp/capture-studio/read"
|
|
288
|
+
local RELEASE_ENDPOINT = "/__mcp/capture-studio/release"
|
|
289
|
+
local CHUNK_BYTES = 1024 * 1024
|
|
290
|
+
local MAX_TRANSFER_BYTES = 64 * 1024 * 1024
|
|
291
|
+
local MAX_TRANSFERS = 2
|
|
292
|
+
local TRANSFER_TTL_SECONDS = 60
|
|
293
|
+
local transfers = {}
|
|
294
|
+
local function integer(value, min, max)
|
|
295
|
+
local _value = value
|
|
296
|
+
local _condition = type(_value) == "number"
|
|
297
|
+
if _condition then
|
|
298
|
+
_condition = value >= min and value <= max and value == math.floor(value)
|
|
299
|
+
end
|
|
300
|
+
return _condition
|
|
301
|
+
end
|
|
302
|
+
local function validId(value)
|
|
303
|
+
local _value = value
|
|
304
|
+
local _condition = type(_value) == "string"
|
|
305
|
+
if _condition then
|
|
306
|
+
_condition = #value > 0 and #value <= 64
|
|
307
|
+
end
|
|
308
|
+
return _condition
|
|
309
|
+
end
|
|
310
|
+
local function metadata(value)
|
|
311
|
+
local _value = value
|
|
312
|
+
if not (type(_value) == "table") then
|
|
313
|
+
return nil
|
|
314
|
+
end
|
|
315
|
+
local fields = value
|
|
316
|
+
if fields.success ~= true or (fields.encoding ~= "png" and fields.encoding ~= "rgba8") or fields.source ~= "StudioCaptureService" or not integer(fields.width, 1, 65536) or not integer(fields.height, 1, 65536) or not integer(fields.nativeWidth, 1, 65536) or not integer(fields.nativeHeight, 1, 65536) then
|
|
317
|
+
return nil
|
|
318
|
+
end
|
|
319
|
+
return {
|
|
320
|
+
success = true,
|
|
321
|
+
encoding = fields.encoding,
|
|
322
|
+
source = fields.source,
|
|
323
|
+
width = fields.width,
|
|
324
|
+
height = fields.height,
|
|
325
|
+
nativeWidth = fields.nativeWidth,
|
|
326
|
+
nativeHeight = fields.nativeHeight,
|
|
327
|
+
}
|
|
328
|
+
end
|
|
329
|
+
local function fail(message)
|
|
330
|
+
return {
|
|
331
|
+
success = false,
|
|
332
|
+
error = `Capture transfer: {message}`,
|
|
333
|
+
}
|
|
334
|
+
end
|
|
335
|
+
local function discard(id)
|
|
336
|
+
local _id = id
|
|
337
|
+
local transfer = transfers[_id]
|
|
338
|
+
if transfer == nil then
|
|
339
|
+
return nil
|
|
340
|
+
end
|
|
341
|
+
local _id_1 = id
|
|
342
|
+
transfers[_id_1] = nil
|
|
343
|
+
if transfer.expiryThread ~= nil then
|
|
344
|
+
task.cancel(transfer.expiryThread)
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
local function prune()
|
|
348
|
+
local now = os.clock()
|
|
349
|
+
for id, transfer in transfers do
|
|
350
|
+
if now >= transfer.expiresAt then
|
|
351
|
+
discard(id)
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
local function release(data)
|
|
356
|
+
if not validId(data.transferId) then
|
|
357
|
+
return fail("invalid transfer ID")
|
|
358
|
+
end
|
|
359
|
+
discard(data.transferId)
|
|
360
|
+
-- Idempotent release also negotiates chunk support before capture starts.
|
|
361
|
+
return {
|
|
362
|
+
success = true,
|
|
363
|
+
chunkBytes = CHUNK_BYTES,
|
|
364
|
+
}
|
|
365
|
+
end
|
|
366
|
+
local validSize
|
|
367
|
+
local function begin(data, capture)
|
|
368
|
+
prune()
|
|
369
|
+
local id = data.transferId
|
|
370
|
+
-- An older server cannot consume chunk descriptors. Let it use legacy
|
|
371
|
+
-- capture rather than returning an unsafe inline image or a hard error.
|
|
372
|
+
if id == nil then
|
|
373
|
+
return {
|
|
374
|
+
unavailable = "Client capture requires bounded transfer support",
|
|
375
|
+
}
|
|
376
|
+
end
|
|
377
|
+
if not validId(id) then
|
|
378
|
+
return fail("invalid transfer ID")
|
|
379
|
+
end
|
|
380
|
+
if transfers[id] ~= nil then
|
|
381
|
+
return fail("duplicate transfer ID")
|
|
382
|
+
end
|
|
383
|
+
-- Reserve before capture yields: concurrent captures cannot over-admit or
|
|
384
|
+
-- evict each other's data. Retained strings are capped at 2 * 64 MiB.
|
|
385
|
+
-- ▼ ReadonlyMap.size ▼
|
|
386
|
+
local _size = 0
|
|
387
|
+
for _ in transfers do
|
|
388
|
+
_size += 1
|
|
389
|
+
end
|
|
390
|
+
-- ▲ ReadonlyMap.size ▲
|
|
391
|
+
if _size >= MAX_TRANSFERS then
|
|
392
|
+
return fail("two captures are already in flight; release or await them first")
|
|
393
|
+
end
|
|
394
|
+
local transfer = {
|
|
395
|
+
offset = 0,
|
|
396
|
+
expiresAt = os.clock() + TRANSFER_TTL_SECONDS,
|
|
397
|
+
}
|
|
398
|
+
transfers[id] = transfer
|
|
399
|
+
-- Capture only the ID, not the large payload, in the expiry closure.
|
|
400
|
+
transfer.expiryThread = task.delay(TRANSFER_TTL_SECONDS, function()
|
|
401
|
+
local current = transfers[id]
|
|
402
|
+
if current ~= nil and os.clock() >= current.expiresAt then
|
|
403
|
+
current.expiryThread = nil
|
|
404
|
+
discard(id)
|
|
405
|
+
end
|
|
406
|
+
end)
|
|
407
|
+
local ok, result = pcall(capture)
|
|
408
|
+
if not ok then
|
|
409
|
+
if transfers[id] == transfer then
|
|
410
|
+
discard(id)
|
|
411
|
+
end
|
|
412
|
+
return fail(`capture failed: {tostring(result)}`)
|
|
413
|
+
end
|
|
414
|
+
if transfers[id] ~= transfer or os.clock() >= transfer.expiresAt then
|
|
415
|
+
if transfers[id] == transfer then
|
|
416
|
+
discard(id)
|
|
417
|
+
end
|
|
418
|
+
return fail("capture expired before it completed")
|
|
419
|
+
end
|
|
420
|
+
local info = metadata(result)
|
|
421
|
+
if info == nil then
|
|
422
|
+
discard(id)
|
|
423
|
+
-- Unavailability must reach core unchanged to preserve legacy fallback.
|
|
424
|
+
if type(result) == "table" then
|
|
425
|
+
local fields = result
|
|
426
|
+
local _unavailable = fields.unavailable
|
|
427
|
+
if type(_unavailable) == "string" then
|
|
428
|
+
return {
|
|
429
|
+
unavailable = string.sub(fields.unavailable, 1, 4096),
|
|
430
|
+
}
|
|
431
|
+
end
|
|
432
|
+
local _error = fields.error
|
|
433
|
+
if type(_error) == "string" then
|
|
434
|
+
return fail(string.sub(fields.error, 1, 4096))
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
return fail("invalid capture response")
|
|
438
|
+
end
|
|
439
|
+
local fields = result
|
|
440
|
+
local pixels = fields.data
|
|
441
|
+
if not (type(pixels) == "string") or not validSize(#pixels, info) then
|
|
442
|
+
discard(id)
|
|
443
|
+
return fail("invalid or oversized capture data")
|
|
444
|
+
end
|
|
445
|
+
transfer.data = pixels
|
|
446
|
+
return {
|
|
447
|
+
transferId = id,
|
|
448
|
+
totalBytes = #pixels,
|
|
449
|
+
chunkBytes = CHUNK_BYTES,
|
|
450
|
+
metadata = info,
|
|
451
|
+
}
|
|
452
|
+
end
|
|
453
|
+
function validSize(size, info)
|
|
454
|
+
if not integer(size, 4, MAX_TRANSFER_BYTES) or size % 4 ~= 0 then
|
|
455
|
+
return false
|
|
456
|
+
end
|
|
457
|
+
return info.encoding ~= "rgba8" or size == math.ceil(info.width * info.height * 4 / 3) * 4
|
|
458
|
+
end
|
|
459
|
+
local function read(data)
|
|
460
|
+
prune()
|
|
461
|
+
local id = data.transferId
|
|
462
|
+
if not validId(id) then
|
|
463
|
+
return fail("invalid transfer ID")
|
|
464
|
+
end
|
|
465
|
+
local transfer = transfers[id]
|
|
466
|
+
if transfer == nil then
|
|
467
|
+
return fail("unknown or expired transfer")
|
|
468
|
+
end
|
|
469
|
+
local pixels = transfer.data
|
|
470
|
+
local offset = data.offset
|
|
471
|
+
local length = data.length
|
|
472
|
+
if pixels == nil or not integer(offset, 0, #pixels - 1) or not integer(length, 1, CHUNK_BYTES) or offset ~= transfer.offset or length ~= math.min(CHUNK_BYTES, #pixels - offset) then
|
|
473
|
+
discard(id)
|
|
474
|
+
return fail("invalid chunk offset or length")
|
|
475
|
+
end
|
|
476
|
+
local _arg0 = offset + 1
|
|
477
|
+
local _arg1 = offset + length
|
|
478
|
+
local chunk = string.sub(pixels, _arg0, _arg1)
|
|
479
|
+
transfer.offset += length
|
|
480
|
+
-- Last read releases immediately, even if the receiver disappears before
|
|
481
|
+
-- its explicit release. Explicit release is idempotent for error paths.
|
|
482
|
+
if transfer.offset == #pixels then
|
|
483
|
+
discard(id)
|
|
484
|
+
end
|
|
485
|
+
return {
|
|
486
|
+
transferId = id,
|
|
487
|
+
offset = offset,
|
|
488
|
+
data = chunk,
|
|
489
|
+
}
|
|
490
|
+
end
|
|
491
|
+
local function receive(invoke, data)
|
|
492
|
+
local id = HttpService:GenerateGUID(false)
|
|
493
|
+
local ok, result = pcall(function()
|
|
494
|
+
-- Older clients return inline data and may disconnect on a large capture.
|
|
495
|
+
-- Probe a harmless release of our fresh ID before requesting any pixels.
|
|
496
|
+
local probe = invoke(RELEASE_ENDPOINT, {
|
|
497
|
+
transferId = id,
|
|
498
|
+
})
|
|
499
|
+
if not (type(probe) == "table") then
|
|
500
|
+
return {
|
|
501
|
+
unavailable = "Client capture lacks bounded transfer support",
|
|
502
|
+
}
|
|
503
|
+
end
|
|
504
|
+
local capability = probe
|
|
505
|
+
if capability.success ~= true or capability.chunkBytes ~= CHUNK_BYTES then
|
|
506
|
+
return {
|
|
507
|
+
unavailable = "Client capture lacks bounded transfer support",
|
|
508
|
+
}
|
|
509
|
+
end
|
|
510
|
+
local response = invoke("/api/capture-studio", {
|
|
511
|
+
encoding = data.encoding,
|
|
512
|
+
transferId = id,
|
|
513
|
+
})
|
|
514
|
+
if not (type(response) == "table") then
|
|
515
|
+
error("invalid transfer response")
|
|
516
|
+
end
|
|
517
|
+
local fields = response
|
|
518
|
+
local _unavailable = fields.unavailable
|
|
519
|
+
if type(_unavailable) == "string" then
|
|
520
|
+
return {
|
|
521
|
+
unavailable = string.sub(fields.unavailable, 1, 4096),
|
|
522
|
+
}
|
|
523
|
+
end
|
|
524
|
+
local _error = fields.error
|
|
525
|
+
if type(_error) == "string" then
|
|
526
|
+
error(string.sub(fields.error, 1, 4096))
|
|
527
|
+
end
|
|
528
|
+
local info = metadata(fields.metadata)
|
|
529
|
+
if info == nil or fields.transferId ~= id or fields.chunkBytes ~= CHUNK_BYTES or not validSize(fields.totalBytes, info) then
|
|
530
|
+
error("invalid transfer metadata or size")
|
|
531
|
+
end
|
|
532
|
+
local size = fields.totalBytes
|
|
533
|
+
local chunks = {}
|
|
534
|
+
local offset = 0
|
|
535
|
+
while offset < size do
|
|
536
|
+
local length = math.min(CHUNK_BYTES, size - offset)
|
|
537
|
+
local response = invoke(READ_ENDPOINT, {
|
|
538
|
+
transferId = id,
|
|
539
|
+
offset = offset,
|
|
540
|
+
length = length,
|
|
541
|
+
})
|
|
542
|
+
if not (type(response) == "table") then
|
|
543
|
+
error("invalid chunk response")
|
|
544
|
+
end
|
|
545
|
+
local chunk = response
|
|
546
|
+
local _error_1 = chunk.error
|
|
547
|
+
if type(_error_1) == "string" then
|
|
548
|
+
error(string.sub(chunk.error, 1, 4096))
|
|
549
|
+
end
|
|
550
|
+
local _condition = chunk.transferId ~= id or chunk.offset ~= offset
|
|
551
|
+
if not _condition then
|
|
552
|
+
local _data = chunk.data
|
|
553
|
+
_condition = not (type(_data) == "string")
|
|
554
|
+
if not _condition then
|
|
555
|
+
_condition = #chunk.data ~= length
|
|
556
|
+
end
|
|
557
|
+
end
|
|
558
|
+
if _condition then
|
|
559
|
+
error("chunk ID, offset or length mismatch")
|
|
560
|
+
end
|
|
561
|
+
local _data = chunk.data
|
|
562
|
+
table.insert(chunks, _data)
|
|
563
|
+
offset += length
|
|
564
|
+
end
|
|
565
|
+
return {
|
|
566
|
+
success = true,
|
|
567
|
+
encoding = info.encoding,
|
|
568
|
+
source = info.source,
|
|
569
|
+
width = info.width,
|
|
570
|
+
height = info.height,
|
|
571
|
+
nativeWidth = info.nativeWidth,
|
|
572
|
+
nativeHeight = info.nativeHeight,
|
|
573
|
+
data = table.concat(chunks, ""),
|
|
574
|
+
}
|
|
575
|
+
end)
|
|
576
|
+
-- The final read already frees successful transfers. Cleanup is best-effort:
|
|
577
|
+
-- it must not mask an unavailable signal from an older client or a completed
|
|
578
|
+
-- image. Failed partial transfers also have the bounded expiry above.
|
|
579
|
+
pcall(function()
|
|
580
|
+
return invoke(RELEASE_ENDPOINT, {
|
|
581
|
+
transferId = id,
|
|
582
|
+
})
|
|
583
|
+
end)
|
|
584
|
+
if not ok then
|
|
585
|
+
return fail(tostring(result))
|
|
586
|
+
end
|
|
587
|
+
return result
|
|
588
|
+
end
|
|
589
|
+
return {
|
|
590
|
+
READ_ENDPOINT = READ_ENDPOINT,
|
|
591
|
+
RELEASE_ENDPOINT = RELEASE_ENDPOINT,
|
|
592
|
+
begin = begin,
|
|
593
|
+
read = read,
|
|
594
|
+
release = release,
|
|
595
|
+
receive = receive,
|
|
596
|
+
}
|
|
597
|
+
]]></string>
|
|
598
|
+
</Properties>
|
|
599
|
+
</Item>
|
|
600
|
+
<Item class="ModuleScript" referent="4">
|
|
281
601
|
<Properties>
|
|
282
602
|
<string name="Name">ClientBroker</string>
|
|
283
603
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -291,6 +611,7 @@ local RuntimeLogBuffer = TS.import(script, script.Parent, "RuntimeLogBuffer")
|
|
|
291
611
|
local MemoryHandlers = TS.import(script, script.Parent, "handlers", "MemoryHandlers")
|
|
292
612
|
local SceneAnalysisHandlers = TS.import(script, script.Parent, "handlers", "SceneAnalysisHandlers")
|
|
293
613
|
local CaptureHandlers = TS.import(script, script.Parent, "handlers", "CaptureHandlers")
|
|
614
|
+
local CaptureTransfer = TS.import(script, script.Parent, "CaptureTransfer")
|
|
294
615
|
local InputHandlers = TS.import(script, script.Parent, "handlers", "InputHandlers")
|
|
295
616
|
local MetadataHandlers = TS.import(script, script.Parent, "handlers", "MetadataHandlers")
|
|
296
617
|
local EvalRuntimeHandlers = TS.import(script, script.Parent, "handlers", "EvalRuntimeHandlers")
|
|
@@ -327,6 +648,7 @@ local CLIENT_BROKER_ALLOWED_ENDPOINTS = {
|
|
|
327
648
|
["/api/multiplayer-test-state"] = true,
|
|
328
649
|
["/api/multiplayer-test-leave-client"] = true,
|
|
329
650
|
["/api/capture-begin"] = true,
|
|
651
|
+
["/api/capture-studio"] = true,
|
|
330
652
|
["/api/simulate-mouse-input"] = true,
|
|
331
653
|
["/api/simulate-keyboard-input"] = true,
|
|
332
654
|
["/api/focus-viewport"] = true,
|
|
@@ -528,6 +850,17 @@ local function setupClientBroker(attempt)
|
|
|
528
850
|
if payload and payload.endpoint == "/api/capture-begin" then
|
|
529
851
|
return CaptureHandlers.captureBegin()
|
|
530
852
|
end
|
|
853
|
+
if payload and payload.endpoint == "/api/capture-studio" then
|
|
854
|
+
return CaptureTransfer.begin(payload.data or {}, function()
|
|
855
|
+
return CaptureHandlers.captureStudio(payload.data or {})
|
|
856
|
+
end)
|
|
857
|
+
end
|
|
858
|
+
if payload and payload.endpoint == CaptureTransfer.READ_ENDPOINT then
|
|
859
|
+
return CaptureTransfer.read(payload.data or {})
|
|
860
|
+
end
|
|
861
|
+
if payload and payload.endpoint == CaptureTransfer.RELEASE_ENDPOINT then
|
|
862
|
+
return CaptureTransfer.release(payload.data or {})
|
|
863
|
+
end
|
|
531
864
|
if payload and payload.endpoint == "/api/simulate-mouse-input" then
|
|
532
865
|
return InputHandlers.simulateMouseInput(payload.data or {})
|
|
533
866
|
end
|
|
@@ -840,6 +1173,14 @@ local function dispatchClientRequest(peerId, target, endpoint, data)
|
|
|
840
1173
|
error = `Client-proxy does not forward {endpoint}. Allowed: {table.concat(allowed, ", ")}.`,
|
|
841
1174
|
}
|
|
842
1175
|
end
|
|
1176
|
+
if endpoint == "/api/capture-studio" then
|
|
1177
|
+
return CaptureTransfer.receive(function(captureEndpoint, captureData)
|
|
1178
|
+
return entry.remote:InvokeClient(entry.player, {
|
|
1179
|
+
endpoint = captureEndpoint,
|
|
1180
|
+
data = captureData,
|
|
1181
|
+
})
|
|
1182
|
+
end, data or {})
|
|
1183
|
+
end
|
|
843
1184
|
local envelope = {
|
|
844
1185
|
endpoint = endpoint,
|
|
845
1186
|
data = data,
|
|
@@ -920,7 +1261,7 @@ return {
|
|
|
920
1261
|
]]></string>
|
|
921
1262
|
</Properties>
|
|
922
1263
|
</Item>
|
|
923
|
-
<Item class="ModuleScript" referent="
|
|
1264
|
+
<Item class="ModuleScript" referent="5">
|
|
924
1265
|
<Properties>
|
|
925
1266
|
<string name="Name">Communication</string>
|
|
926
1267
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -988,6 +1329,7 @@ local routeMap = {
|
|
|
988
1329
|
["/api/insert-asset"] = AssetHandlers.insertAsset,
|
|
989
1330
|
["/api/preview-asset"] = AssetHandlers.previewAsset,
|
|
990
1331
|
["/api/capture-screenshot"] = CaptureHandlers.captureScreenshot,
|
|
1332
|
+
["/api/capture-studio"] = CaptureHandlers.captureStudio,
|
|
991
1333
|
["/api/capture-begin"] = CaptureHandlers.captureBegin,
|
|
992
1334
|
["/api/capture-read"] = CaptureHandlers.captureRead,
|
|
993
1335
|
["/api/simulate-mouse-input"] = InputHandlers.simulateMouseInput,
|
|
@@ -1276,7 +1618,7 @@ return {
|
|
|
1276
1618
|
]]></string>
|
|
1277
1619
|
</Properties>
|
|
1278
1620
|
</Item>
|
|
1279
|
-
<Item class="ModuleScript" referent="
|
|
1621
|
+
<Item class="ModuleScript" referent="6">
|
|
1280
1622
|
<Properties>
|
|
1281
1623
|
<string name="Name">CooperativeJobRunner</string>
|
|
1282
1624
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -1351,7 +1693,7 @@ return {
|
|
|
1351
1693
|
]]></string>
|
|
1352
1694
|
</Properties>
|
|
1353
1695
|
</Item>
|
|
1354
|
-
<Item class="ModuleScript" referent="
|
|
1696
|
+
<Item class="ModuleScript" referent="7">
|
|
1355
1697
|
<Properties>
|
|
1356
1698
|
<string name="Name">EvalBridges</string>
|
|
1357
1699
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -1472,9 +1814,9 @@ local function computeBridgeStamp()
|
|
|
1472
1814
|
for i = 1, #combined do
|
|
1473
1815
|
h = (h * 33 + (string.byte(combined, i))) % 2147483647
|
|
1474
1816
|
end
|
|
1475
|
-
-- "3.1.
|
|
1817
|
+
-- "3.1.4" is replaced with the package version at package time
|
|
1476
1818
|
-- (scripts/build-plugin.mjs injectVersion), so a release bump also restamps.
|
|
1477
|
-
return `{tostring(h)}-3.1.
|
|
1819
|
+
return `{tostring(h)}-3.1.4`
|
|
1478
1820
|
end
|
|
1479
1821
|
local BRIDGE_STAMP = computeBridgeStamp()
|
|
1480
1822
|
local function setSource(scriptInst, source)
|
|
@@ -1627,11 +1969,11 @@ return {
|
|
|
1627
1969
|
]]></string>
|
|
1628
1970
|
</Properties>
|
|
1629
1971
|
</Item>
|
|
1630
|
-
<Item class="Folder" referent="
|
|
1972
|
+
<Item class="Folder" referent="8">
|
|
1631
1973
|
<Properties>
|
|
1632
1974
|
<string name="Name">handlers</string>
|
|
1633
1975
|
</Properties>
|
|
1634
|
-
<Item class="ModuleScript" referent="
|
|
1976
|
+
<Item class="ModuleScript" referent="9">
|
|
1635
1977
|
<Properties>
|
|
1636
1978
|
<string name="Name">AssetHandlers</string>
|
|
1637
1979
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -2072,7 +2414,7 @@ return {
|
|
|
2072
2414
|
]]></string>
|
|
2073
2415
|
</Properties>
|
|
2074
2416
|
</Item>
|
|
2075
|
-
<Item class="ModuleScript" referent="
|
|
2417
|
+
<Item class="ModuleScript" referent="10">
|
|
2076
2418
|
<Properties>
|
|
2077
2419
|
<string name="Name">BreakpointHandlers</string>
|
|
2078
2420
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -2579,7 +2921,7 @@ return {
|
|
|
2579
2921
|
]]></string>
|
|
2580
2922
|
</Properties>
|
|
2581
2923
|
</Item>
|
|
2582
|
-
<Item class="ModuleScript" referent="
|
|
2924
|
+
<Item class="ModuleScript" referent="11">
|
|
2583
2925
|
<Properties>
|
|
2584
2926
|
<string name="Name">CaptureHandlers</string>
|
|
2585
2927
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -2587,11 +2929,27 @@ local TS = require(script.Parent.Parent.Parent.include.RuntimeLib)
|
|
|
2587
2929
|
local RenderMonitor = TS.import(script, script.Parent.Parent, "RenderMonitor")
|
|
2588
2930
|
local CaptureService = game:GetService("CaptureService")
|
|
2589
2931
|
local AssetService = game:GetService("AssetService")
|
|
2932
|
+
local Workspace = game:GetService("Workspace")
|
|
2590
2933
|
local MAX_TILE_SIZE = 1024
|
|
2591
2934
|
local MAX_RAW_PIXEL_BYTES = 36 * 1024 * 1024
|
|
2592
2935
|
local MAX_CREATED_IMAGE_DIM = 2048
|
|
2593
2936
|
local BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
|
2594
2937
|
local PAD_BYTE = (string.byte("="))
|
|
2938
|
+
-- StudioCaptureService (Studio-only, PluginSecurity) is the fast path: it hands
|
|
2939
|
+
-- back the framebuffer directly, so it needs neither CaptureService's
|
|
2940
|
+
-- asynchronous callback nor an EditableImage round-trip — and it captures at
|
|
2941
|
+
-- ViewportSize, which is exactly the coordinate space simulate_mouse_input
|
|
2942
|
+
-- expects. It is gated behind Studio FFlags and is missing from @rbxts/types,
|
|
2943
|
+
-- hence the local structural declarations below.
|
|
2944
|
+
-- Unchecked cast, single reason: these enums exist in Studio but are missing
|
|
2945
|
+
-- from @rbxts/types, so the global Enum table has to be read dynamically.
|
|
2946
|
+
local ENUM_TABLE = Enum
|
|
2947
|
+
local STUDIO_CAPTURE_FORMATS = ENUM_TABLE.StudioCaptureScreenshotFormat
|
|
2948
|
+
-- Measured on a 1980x1032 viewport: RGBA8 completes in ~0.16s and PNG in ~1s.
|
|
2949
|
+
-- A capture that is still Pending well past that never completes (it happens
|
|
2950
|
+
-- while a playtest owns the renderer), so we stop waiting and let the caller
|
|
2951
|
+
-- fall back instead of stalling the tool call.
|
|
2952
|
+
local STUDIO_CAPTURE_TIMEOUT = 3
|
|
2595
2953
|
local B64 = {}
|
|
2596
2954
|
for i = 0, 63 do
|
|
2597
2955
|
B64[i + 1] = (string.byte(BASE64_CHARS, i + 1))
|
|
@@ -2789,6 +3147,124 @@ local function readContentToBase64(contentId)
|
|
|
2789
3147
|
nativeHeight = nativeH,
|
|
2790
3148
|
}
|
|
2791
3149
|
end
|
|
3150
|
+
local cachedStudioService
|
|
3151
|
+
local function getStudioCaptureService()
|
|
3152
|
+
if cachedStudioService ~= nil then
|
|
3153
|
+
return cachedStudioService
|
|
3154
|
+
end
|
|
3155
|
+
-- Unchecked cast, single reason: StudioCaptureService is absent from
|
|
3156
|
+
-- @rbxts/types, so GetService cannot be called through the typed overload.
|
|
3157
|
+
local dynamicGame = game
|
|
3158
|
+
local ok, service = pcall(function()
|
|
3159
|
+
return dynamicGame:GetService("StudioCaptureService")
|
|
3160
|
+
end)
|
|
3161
|
+
if not ok or service == nil then
|
|
3162
|
+
return nil
|
|
3163
|
+
end
|
|
3164
|
+
cachedStudioService = service
|
|
3165
|
+
return cachedStudioService
|
|
3166
|
+
end
|
|
3167
|
+
-- Captures through StudioCaptureService. Returns undefined when the service
|
|
3168
|
+
-- cannot capture right now (missing FFlag, permission not granted, or this
|
|
3169
|
+
-- DataModel is not the active one) so the caller can fall back to the
|
|
3170
|
+
-- CaptureService + EditableImage path.
|
|
3171
|
+
local function doStudioCapture(wantPng)
|
|
3172
|
+
if STUDIO_CAPTURE_FORMATS == nil then
|
|
3173
|
+
return nil
|
|
3174
|
+
end
|
|
3175
|
+
local service = getStudioCaptureService()
|
|
3176
|
+
if service == nil then
|
|
3177
|
+
return nil
|
|
3178
|
+
end
|
|
3179
|
+
local canOk, can = pcall(function()
|
|
3180
|
+
return service:CanCaptureScreenshot()
|
|
3181
|
+
end)
|
|
3182
|
+
if not canOk or can ~= true then
|
|
3183
|
+
return nil
|
|
3184
|
+
end
|
|
3185
|
+
local camera = Workspace.CurrentCamera
|
|
3186
|
+
if camera == nil then
|
|
3187
|
+
return nil
|
|
3188
|
+
end
|
|
3189
|
+
local viewport = camera.ViewportSize
|
|
3190
|
+
local nativeW = math.max(1, math.floor(viewport.X))
|
|
3191
|
+
local nativeH = math.max(1, math.floor(viewport.Y))
|
|
3192
|
+
local w = nativeW
|
|
3193
|
+
local h = nativeH
|
|
3194
|
+
-- Raw RGBA rides back base64-encoded, so an oversized viewport is
|
|
3195
|
+
-- downscaled by the engine during the capture itself — no second pass.
|
|
3196
|
+
if not wantPng and nativeW * nativeH * 4 > MAX_RAW_PIXEL_BYTES then
|
|
3197
|
+
local scale = math.sqrt(MAX_RAW_PIXEL_BYTES / (nativeW * nativeH * 4))
|
|
3198
|
+
w = math.max(1, math.floor(nativeW * scale))
|
|
3199
|
+
h = math.max(1, math.floor(nativeH * scale))
|
|
3200
|
+
end
|
|
3201
|
+
-- CaptureSize is a framebuffer crop, not the logical viewport size. At
|
|
3202
|
+
-- fractional display scaling it cuts off the right/bottom of the frame.
|
|
3203
|
+
local options = {
|
|
3204
|
+
OutputSize = Vector2.new(w, h),
|
|
3205
|
+
ResampleMode = Enum.ResamplerMode.Default,
|
|
3206
|
+
Format = if wantPng then STUDIO_CAPTURE_FORMATS.PNG else STUDIO_CAPTURE_FORMATS.RGBA8,
|
|
3207
|
+
}
|
|
3208
|
+
local captureOk, captureResult = pcall(function()
|
|
3209
|
+
return service:CaptureScreenshot(options)
|
|
3210
|
+
end)
|
|
3211
|
+
if not captureOk then
|
|
3212
|
+
return {
|
|
3213
|
+
error = `StudioCaptureService:CaptureScreenshot failed: {tostring(captureResult)}`,
|
|
3214
|
+
}
|
|
3215
|
+
end
|
|
3216
|
+
if captureResult == nil then
|
|
3217
|
+
return nil
|
|
3218
|
+
end
|
|
3219
|
+
local capture = captureResult
|
|
3220
|
+
local startTime = tick()
|
|
3221
|
+
while capture.BufferStatus.Name == "Pending" or capture.BufferStatus.Name == "NotStarted" do
|
|
3222
|
+
if tick() - startTime > STUDIO_CAPTURE_TIMEOUT then
|
|
3223
|
+
return nil
|
|
3224
|
+
end
|
|
3225
|
+
task.wait(0.02)
|
|
3226
|
+
end
|
|
3227
|
+
if capture.BufferStatus.Name ~= "Ready" then
|
|
3228
|
+
local errorsOk, errors = pcall(function()
|
|
3229
|
+
return capture:GetErrors()
|
|
3230
|
+
end)
|
|
3231
|
+
local detail = if errorsOk then game:GetService("HttpService"):JSONEncode(errors) else "unavailable"
|
|
3232
|
+
return {
|
|
3233
|
+
error = `StudioCaptureService capture failed (status {capture.BufferStatus.Name}): {detail}`,
|
|
3234
|
+
}
|
|
3235
|
+
end
|
|
3236
|
+
local bufferOk, captureBuffer = pcall(function()
|
|
3237
|
+
return capture:GetBuffer()
|
|
3238
|
+
end)
|
|
3239
|
+
if not bufferOk then
|
|
3240
|
+
return {
|
|
3241
|
+
error = `StudioCaptureService:GetBuffer failed: {tostring(captureBuffer)}`,
|
|
3242
|
+
}
|
|
3243
|
+
end
|
|
3244
|
+
local resolution = capture.Resolution
|
|
3245
|
+
return {
|
|
3246
|
+
success = true,
|
|
3247
|
+
encoding = if wantPng then "png" else "rgba8",
|
|
3248
|
+
source = "StudioCaptureService",
|
|
3249
|
+
width = math.max(1, math.floor(resolution.X)),
|
|
3250
|
+
height = math.max(1, math.floor(resolution.Y)),
|
|
3251
|
+
nativeWidth = nativeW,
|
|
3252
|
+
nativeHeight = nativeH,
|
|
3253
|
+
data = encodeBase64(captureBuffer),
|
|
3254
|
+
}
|
|
3255
|
+
end
|
|
3256
|
+
-- Studio-only capture endpoint. Reports `unavailable` (instead of an error) so
|
|
3257
|
+
-- the server can fall back to the legacy CaptureService path.
|
|
3258
|
+
local function captureStudio(requestData)
|
|
3259
|
+
local wantPng = requestData.encoding == "png"
|
|
3260
|
+
local result = doStudioCapture(wantPng)
|
|
3261
|
+
if result == nil then
|
|
3262
|
+
return {
|
|
3263
|
+
unavailable = "StudioCaptureService cannot capture this DataModel right now",
|
|
3264
|
+
}
|
|
3265
|
+
end
|
|
3266
|
+
return result
|
|
3267
|
+
end
|
|
2792
3268
|
-- Edit-mode single shot: capture and read back in the same (edit) context.
|
|
2793
3269
|
local function captureScreenshotData()
|
|
2794
3270
|
local cap = doCaptureScreenshot()
|
|
@@ -2817,13 +3293,14 @@ end
|
|
|
2817
3293
|
return {
|
|
2818
3294
|
captureScreenshotData = captureScreenshotData,
|
|
2819
3295
|
captureScreenshot = captureScreenshot,
|
|
3296
|
+
captureStudio = captureStudio,
|
|
2820
3297
|
captureBegin = captureBegin,
|
|
2821
3298
|
captureRead = captureRead,
|
|
2822
3299
|
}
|
|
2823
3300
|
]]></string>
|
|
2824
3301
|
</Properties>
|
|
2825
3302
|
</Item>
|
|
2826
|
-
<Item class="ModuleScript" referent="
|
|
3303
|
+
<Item class="ModuleScript" referent="12">
|
|
2827
3304
|
<Properties>
|
|
2828
3305
|
<string name="Name">EvalRuntimeHandlers</string>
|
|
2829
3306
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -2977,7 +3454,7 @@ return {
|
|
|
2977
3454
|
]]></string>
|
|
2978
3455
|
</Properties>
|
|
2979
3456
|
</Item>
|
|
2980
|
-
<Item class="ModuleScript" referent="
|
|
3457
|
+
<Item class="ModuleScript" referent="13">
|
|
2981
3458
|
<Properties>
|
|
2982
3459
|
<string name="Name">GenerateModelHandlers</string>
|
|
2983
3460
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -3182,7 +3659,7 @@ return {
|
|
|
3182
3659
|
]]></string>
|
|
3183
3660
|
</Properties>
|
|
3184
3661
|
</Item>
|
|
3185
|
-
<Item class="ModuleScript" referent="
|
|
3662
|
+
<Item class="ModuleScript" referent="14">
|
|
3186
3663
|
<Properties>
|
|
3187
3664
|
<string name="Name">InputHandlers</string>
|
|
3188
3665
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -3382,7 +3859,7 @@ return {
|
|
|
3382
3859
|
]]></string>
|
|
3383
3860
|
</Properties>
|
|
3384
3861
|
</Item>
|
|
3385
|
-
<Item class="ModuleScript" referent="
|
|
3862
|
+
<Item class="ModuleScript" referent="15">
|
|
3386
3863
|
<Properties>
|
|
3387
3864
|
<string name="Name">LogHandlers</string>
|
|
3388
3865
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -3404,7 +3881,7 @@ return {
|
|
|
3404
3881
|
]]></string>
|
|
3405
3882
|
</Properties>
|
|
3406
3883
|
</Item>
|
|
3407
|
-
<Item class="ModuleScript" referent="
|
|
3884
|
+
<Item class="ModuleScript" referent="16">
|
|
3408
3885
|
<Properties>
|
|
3409
3886
|
<string name="Name">MemoryHandlers</string>
|
|
3410
3887
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -3472,7 +3949,7 @@ return {
|
|
|
3472
3949
|
]]></string>
|
|
3473
3950
|
</Properties>
|
|
3474
3951
|
</Item>
|
|
3475
|
-
<Item class="ModuleScript" referent="
|
|
3952
|
+
<Item class="ModuleScript" referent="17">
|
|
3476
3953
|
<Properties>
|
|
3477
3954
|
<string name="Name">MetadataHandlers</string>
|
|
3478
3955
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -3829,7 +4306,7 @@ return {
|
|
|
3829
4306
|
]]></string>
|
|
3830
4307
|
</Properties>
|
|
3831
4308
|
</Item>
|
|
3832
|
-
<Item class="ModuleScript" referent="
|
|
4309
|
+
<Item class="ModuleScript" referent="18">
|
|
3833
4310
|
<Properties>
|
|
3834
4311
|
<string name="Name">MicroProfilerHandlers</string>
|
|
3835
4312
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -5582,7 +6059,7 @@ return {
|
|
|
5582
6059
|
]]></string>
|
|
5583
6060
|
</Properties>
|
|
5584
6061
|
</Item>
|
|
5585
|
-
<Item class="ModuleScript" referent="
|
|
6062
|
+
<Item class="ModuleScript" referent="19">
|
|
5586
6063
|
<Properties>
|
|
5587
6064
|
<string name="Name">PropertyHandlers</string>
|
|
5588
6065
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -5667,6 +6144,7 @@ local function setProperties(requestData)
|
|
|
5667
6144
|
-- execute_luau edits as well, even when every assignment in this call failed.
|
|
5668
6145
|
finishRecording(recordingId, true)
|
|
5669
6146
|
return {
|
|
6147
|
+
success = failureCount == 0,
|
|
5670
6148
|
instancePath = instancePath,
|
|
5671
6149
|
summary = {
|
|
5672
6150
|
total = successCount + failureCount,
|
|
@@ -5682,7 +6160,7 @@ return {
|
|
|
5682
6160
|
]]></string>
|
|
5683
6161
|
</Properties>
|
|
5684
6162
|
</Item>
|
|
5685
|
-
<Item class="ModuleScript" referent="
|
|
6163
|
+
<Item class="ModuleScript" referent="20">
|
|
5686
6164
|
<Properties>
|
|
5687
6165
|
<string name="Name">QueryHandlers</string>
|
|
5688
6166
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -6337,7 +6815,7 @@ return {
|
|
|
6337
6815
|
]]></string>
|
|
6338
6816
|
</Properties>
|
|
6339
6817
|
</Item>
|
|
6340
|
-
<Item class="ModuleScript" referent="
|
|
6818
|
+
<Item class="ModuleScript" referent="21">
|
|
6341
6819
|
<Properties>
|
|
6342
6820
|
<string name="Name">SceneAnalysisHandlers</string>
|
|
6343
6821
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -6586,7 +7064,7 @@ return {
|
|
|
6586
7064
|
]]></string>
|
|
6587
7065
|
</Properties>
|
|
6588
7066
|
</Item>
|
|
6589
|
-
<Item class="ModuleScript" referent="
|
|
7067
|
+
<Item class="ModuleScript" referent="22">
|
|
6590
7068
|
<Properties>
|
|
6591
7069
|
<string name="Name">ScriptHandlers</string>
|
|
6592
7070
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -7258,7 +7736,7 @@ return {
|
|
|
7258
7736
|
]]></string>
|
|
7259
7737
|
</Properties>
|
|
7260
7738
|
</Item>
|
|
7261
|
-
<Item class="ModuleScript" referent="
|
|
7739
|
+
<Item class="ModuleScript" referent="23">
|
|
7262
7740
|
<Properties>
|
|
7263
7741
|
<string name="Name">ScriptProfilerHandlers</string>
|
|
7264
7742
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -7721,7 +8199,7 @@ return {
|
|
|
7721
8199
|
]]></string>
|
|
7722
8200
|
</Properties>
|
|
7723
8201
|
</Item>
|
|
7724
|
-
<Item class="ModuleScript" referent="
|
|
8202
|
+
<Item class="ModuleScript" referent="24">
|
|
7725
8203
|
<Properties>
|
|
7726
8204
|
<string name="Name">SerializationHandlers</string>
|
|
7727
8205
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -7907,7 +8385,7 @@ return {
|
|
|
7907
8385
|
]]></string>
|
|
7908
8386
|
</Properties>
|
|
7909
8387
|
</Item>
|
|
7910
|
-
<Item class="ModuleScript" referent="
|
|
8388
|
+
<Item class="ModuleScript" referent="25">
|
|
7911
8389
|
<Properties>
|
|
7912
8390
|
<string name="Name">TestHandlers</string>
|
|
7913
8391
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -7985,6 +8463,16 @@ local function startPlaytest(requestData)
|
|
|
7985
8463
|
error = "start_playtest is single-player only. Use multiplayer_test_start for multi-client StudioTestService sessions.",
|
|
7986
8464
|
}
|
|
7987
8465
|
end
|
|
8466
|
+
-- Peer teardown and ExecutePlayModeAsync completion can precede native edit
|
|
8467
|
+
-- readiness. Do not acknowledge a new start that the engine cannot execute.
|
|
8468
|
+
if not StudioTestService.EditModeActive then
|
|
8469
|
+
return {
|
|
8470
|
+
success = false,
|
|
8471
|
+
error = "Studio is not ready to start a playtest.",
|
|
8472
|
+
message = "Wait for Studio to finish its current playtest transition before starting another.",
|
|
8473
|
+
editModeReady = false,
|
|
8474
|
+
}
|
|
8475
|
+
end
|
|
7988
8476
|
-- Self-heal: if testRunning is stuck true but Studio reports no active
|
|
7989
8477
|
-- playtest, the previous start_playtest's task.spawn was orphaned
|
|
7990
8478
|
-- (plugin reload mid-test, Studio entered some inconsistent state, etc).
|
|
@@ -8064,22 +8552,24 @@ local function stopPlaytest(_requestData)
|
|
|
8064
8552
|
}
|
|
8065
8553
|
end
|
|
8066
8554
|
StopPlayMonitor.clearPending(stopRequest.requestId)
|
|
8067
|
-
--
|
|
8068
|
-
--
|
|
8069
|
-
--
|
|
8070
|
-
--
|
|
8071
|
-
-- teardown and get "A test is already running". 10s covers play-DM
|
|
8072
|
-
-- teardown on heavier places; if it still hasn't cleared we return
|
|
8073
|
-
-- anyway so users aren't stuck — but note that in the response so the
|
|
8074
|
-
-- caller knows a subsequent start may need a moment.
|
|
8555
|
+
-- EndTest consumption, task completion, and native edit readiness are distinct
|
|
8556
|
+
-- milestones. In particular, testRunning can clear before Studio accepts another
|
|
8557
|
+
-- ExecutePlayModeAsync call (and is never set for manually started playtests).
|
|
8558
|
+
-- Only report completion after both tracked execution and native teardown settle.
|
|
8075
8559
|
local deadline = tick() + 10
|
|
8076
|
-
while testRunning and tick() < deadline do
|
|
8560
|
+
while (testRunning or not StudioTestService.EditModeActive) and tick() < deadline do
|
|
8077
8561
|
task.wait(0.1)
|
|
8078
8562
|
end
|
|
8079
|
-
|
|
8563
|
+
local editModeReady = StudioTestService.EditModeActive
|
|
8564
|
+
if testRunning or not editModeReady then
|
|
8080
8565
|
return {
|
|
8081
|
-
success =
|
|
8082
|
-
|
|
8566
|
+
success = false,
|
|
8567
|
+
error = "Playtest teardown did not complete.",
|
|
8568
|
+
message = "Stop signal was accepted, but Studio teardown did not settle before timeout.",
|
|
8569
|
+
stopSignalAccepted = true,
|
|
8570
|
+
editModeReady = editModeReady,
|
|
8571
|
+
playtestTaskPending = testRunning,
|
|
8572
|
+
timedOut = true,
|
|
8083
8573
|
}
|
|
8084
8574
|
end
|
|
8085
8575
|
return {
|
|
@@ -8286,7 +8776,7 @@ return {
|
|
|
8286
8776
|
</Properties>
|
|
8287
8777
|
</Item>
|
|
8288
8778
|
</Item>
|
|
8289
|
-
<Item class="ModuleScript" referent="
|
|
8779
|
+
<Item class="ModuleScript" referent="26">
|
|
8290
8780
|
<Properties>
|
|
8291
8781
|
<string name="Name">HttpDiagnostics</string>
|
|
8292
8782
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -8367,7 +8857,7 @@ return {
|
|
|
8367
8857
|
]]></string>
|
|
8368
8858
|
</Properties>
|
|
8369
8859
|
</Item>
|
|
8370
|
-
<Item class="ModuleScript" referent="
|
|
8860
|
+
<Item class="ModuleScript" referent="27">
|
|
8371
8861
|
<Properties>
|
|
8372
8862
|
<string name="Name">LuauExec</string>
|
|
8373
8863
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -8801,7 +9291,7 @@ return {
|
|
|
8801
9291
|
]]></string>
|
|
8802
9292
|
</Properties>
|
|
8803
9293
|
</Item>
|
|
8804
|
-
<Item class="ModuleScript" referent="
|
|
9294
|
+
<Item class="ModuleScript" referent="28">
|
|
8805
9295
|
<Properties>
|
|
8806
9296
|
<string name="Name">PeerRole</string>
|
|
8807
9297
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -8822,7 +9312,7 @@ return {
|
|
|
8822
9312
|
]]></string>
|
|
8823
9313
|
</Properties>
|
|
8824
9314
|
</Item>
|
|
8825
|
-
<Item class="ModuleScript" referent="
|
|
9315
|
+
<Item class="ModuleScript" referent="29">
|
|
8826
9316
|
<Properties>
|
|
8827
9317
|
<string name="Name">PluginSession</string>
|
|
8828
9318
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -9011,7 +9501,7 @@ return {
|
|
|
9011
9501
|
]]></string>
|
|
9012
9502
|
</Properties>
|
|
9013
9503
|
</Item>
|
|
9014
|
-
<Item class="ModuleScript" referent="
|
|
9504
|
+
<Item class="ModuleScript" referent="30">
|
|
9015
9505
|
<Properties>
|
|
9016
9506
|
<string name="Name">Recording</string>
|
|
9017
9507
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -9041,7 +9531,7 @@ return {
|
|
|
9041
9531
|
]]></string>
|
|
9042
9532
|
</Properties>
|
|
9043
9533
|
</Item>
|
|
9044
|
-
<Item class="ModuleScript" referent="
|
|
9534
|
+
<Item class="ModuleScript" referent="31">
|
|
9045
9535
|
<Properties>
|
|
9046
9536
|
<string name="Name">RenderMonitor</string>
|
|
9047
9537
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -9109,7 +9599,7 @@ return {
|
|
|
9109
9599
|
]]></string>
|
|
9110
9600
|
</Properties>
|
|
9111
9601
|
</Item>
|
|
9112
|
-
<Item class="ModuleScript" referent="
|
|
9602
|
+
<Item class="ModuleScript" referent="32">
|
|
9113
9603
|
<Properties>
|
|
9114
9604
|
<string name="Name">RuntimeLogBuffer</string>
|
|
9115
9605
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -9345,7 +9835,7 @@ return {
|
|
|
9345
9835
|
]]></string>
|
|
9346
9836
|
</Properties>
|
|
9347
9837
|
</Item>
|
|
9348
|
-
<Item class="ModuleScript" referent="
|
|
9838
|
+
<Item class="ModuleScript" referent="33">
|
|
9349
9839
|
<Properties>
|
|
9350
9840
|
<string name="Name">ScriptSearch</string>
|
|
9351
9841
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -9672,7 +10162,7 @@ return {
|
|
|
9672
10162
|
]]></string>
|
|
9673
10163
|
</Properties>
|
|
9674
10164
|
</Item>
|
|
9675
|
-
<Item class="ModuleScript" referent="
|
|
10165
|
+
<Item class="ModuleScript" referent="34">
|
|
9676
10166
|
<Properties>
|
|
9677
10167
|
<string name="Name">ServerUrlSettings</string>
|
|
9678
10168
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -9811,11 +10301,11 @@ return {
|
|
|
9811
10301
|
]]></string>
|
|
9812
10302
|
</Properties>
|
|
9813
10303
|
</Item>
|
|
9814
|
-
<Item class="ModuleScript" referent="
|
|
10304
|
+
<Item class="ModuleScript" referent="35">
|
|
9815
10305
|
<Properties>
|
|
9816
10306
|
<string name="Name">State</string>
|
|
9817
10307
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
9818
|
-
local CURRENT_VERSION = "3.1.
|
|
10308
|
+
local CURRENT_VERSION = "3.1.4"
|
|
9819
10309
|
local PLUGIN_VARIANT = "inspector"
|
|
9820
10310
|
local BASE_PORT = 58741
|
|
9821
10311
|
local function createConnection(port)
|
|
@@ -9845,7 +10335,7 @@ return {
|
|
|
9845
10335
|
]]></string>
|
|
9846
10336
|
</Properties>
|
|
9847
10337
|
</Item>
|
|
9848
|
-
<Item class="ModuleScript" referent="
|
|
10338
|
+
<Item class="ModuleScript" referent="36">
|
|
9849
10339
|
<Properties>
|
|
9850
10340
|
<string name="Name">StopPlayMonitor</string>
|
|
9851
10341
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -10078,7 +10568,7 @@ return {
|
|
|
10078
10568
|
]]></string>
|
|
10079
10569
|
</Properties>
|
|
10080
10570
|
</Item>
|
|
10081
|
-
<Item class="ModuleScript" referent="
|
|
10571
|
+
<Item class="ModuleScript" referent="37">
|
|
10082
10572
|
<Properties>
|
|
10083
10573
|
<string name="Name">StudioWebSocket</string>
|
|
10084
10574
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -11029,7 +11519,7 @@ return {
|
|
|
11029
11519
|
]]></string>
|
|
11030
11520
|
</Properties>
|
|
11031
11521
|
</Item>
|
|
11032
|
-
<Item class="ModuleScript" referent="
|
|
11522
|
+
<Item class="ModuleScript" referent="38">
|
|
11033
11523
|
<Properties>
|
|
11034
11524
|
<string name="Name">TopologyId</string>
|
|
11035
11525
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -11074,7 +11564,7 @@ return {
|
|
|
11074
11564
|
]]></string>
|
|
11075
11565
|
</Properties>
|
|
11076
11566
|
</Item>
|
|
11077
|
-
<Item class="ModuleScript" referent="
|
|
11567
|
+
<Item class="ModuleScript" referent="39">
|
|
11078
11568
|
<Properties>
|
|
11079
11569
|
<string name="Name">UI</string>
|
|
11080
11570
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -11626,7 +12116,7 @@ return {
|
|
|
11626
12116
|
]]></string>
|
|
11627
12117
|
</Properties>
|
|
11628
12118
|
</Item>
|
|
11629
|
-
<Item class="ModuleScript" referent="
|
|
12119
|
+
<Item class="ModuleScript" referent="40">
|
|
11630
12120
|
<Properties>
|
|
11631
12121
|
<string name="Name">Utils</string>
|
|
11632
12122
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -12467,11 +12957,11 @@ return {
|
|
|
12467
12957
|
</Properties>
|
|
12468
12958
|
</Item>
|
|
12469
12959
|
</Item>
|
|
12470
|
-
<Item class="Folder" referent="
|
|
12960
|
+
<Item class="Folder" referent="45">
|
|
12471
12961
|
<Properties>
|
|
12472
12962
|
<string name="Name">include</string>
|
|
12473
12963
|
</Properties>
|
|
12474
|
-
<Item class="ModuleScript" referent="
|
|
12964
|
+
<Item class="ModuleScript" referent="41">
|
|
12475
12965
|
<Properties>
|
|
12476
12966
|
<string name="Name">LibMP</string>
|
|
12477
12967
|
<string name="Source"><![CDATA[-- =============================================================================
|
|
@@ -168855,7 +169345,7 @@ return LibMP
|
|
|
168855
169345
|
]]></string>
|
|
168856
169346
|
</Properties>
|
|
168857
169347
|
</Item>
|
|
168858
|
-
<Item class="ModuleScript" referent="
|
|
169348
|
+
<Item class="ModuleScript" referent="42">
|
|
168859
169349
|
<Properties>
|
|
168860
169350
|
<string name="Name">Promise</string>
|
|
168861
169351
|
<string name="Source"><![CDATA[--[[
|
|
@@ -170929,7 +171419,7 @@ return Promise
|
|
|
170929
171419
|
]]></string>
|
|
170930
171420
|
</Properties>
|
|
170931
171421
|
</Item>
|
|
170932
|
-
<Item class="ModuleScript" referent="
|
|
171422
|
+
<Item class="ModuleScript" referent="43">
|
|
170933
171423
|
<Properties>
|
|
170934
171424
|
<string name="Name">RuntimeLib</string>
|
|
170935
171425
|
<string name="Source"><![CDATA[local Promise = require(script.Parent.Promise)
|
|
@@ -171196,15 +171686,15 @@ return TS
|
|
|
171196
171686
|
</Properties>
|
|
171197
171687
|
</Item>
|
|
171198
171688
|
</Item>
|
|
171199
|
-
<Item class="Folder" referent="
|
|
171689
|
+
<Item class="Folder" referent="46">
|
|
171200
171690
|
<Properties>
|
|
171201
171691
|
<string name="Name">node_modules</string>
|
|
171202
171692
|
</Properties>
|
|
171203
|
-
<Item class="Folder" referent="
|
|
171693
|
+
<Item class="Folder" referent="47">
|
|
171204
171694
|
<Properties>
|
|
171205
171695
|
<string name="Name">@rbxts</string>
|
|
171206
171696
|
</Properties>
|
|
171207
|
-
<Item class="ModuleScript" referent="
|
|
171697
|
+
<Item class="ModuleScript" referent="44">
|
|
171208
171698
|
<Properties>
|
|
171209
171699
|
<string name="Name">services</string>
|
|
171210
171700
|
<string name="Source"><![CDATA[return setmetatable({}, {
|