@chrrxs/robloxstudio-mcp-inspector 3.1.3 → 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 +238 -44
- package/package.json +1 -1
- package/studio-plugin/MCPInspectorPlugin.rbxmx +524 -46
|
@@ -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
|
|
@@ -8298,7 +8776,7 @@ return {
|
|
|
8298
8776
|
</Properties>
|
|
8299
8777
|
</Item>
|
|
8300
8778
|
</Item>
|
|
8301
|
-
<Item class="ModuleScript" referent="
|
|
8779
|
+
<Item class="ModuleScript" referent="26">
|
|
8302
8780
|
<Properties>
|
|
8303
8781
|
<string name="Name">HttpDiagnostics</string>
|
|
8304
8782
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -8379,7 +8857,7 @@ return {
|
|
|
8379
8857
|
]]></string>
|
|
8380
8858
|
</Properties>
|
|
8381
8859
|
</Item>
|
|
8382
|
-
<Item class="ModuleScript" referent="
|
|
8860
|
+
<Item class="ModuleScript" referent="27">
|
|
8383
8861
|
<Properties>
|
|
8384
8862
|
<string name="Name">LuauExec</string>
|
|
8385
8863
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -8813,7 +9291,7 @@ return {
|
|
|
8813
9291
|
]]></string>
|
|
8814
9292
|
</Properties>
|
|
8815
9293
|
</Item>
|
|
8816
|
-
<Item class="ModuleScript" referent="
|
|
9294
|
+
<Item class="ModuleScript" referent="28">
|
|
8817
9295
|
<Properties>
|
|
8818
9296
|
<string name="Name">PeerRole</string>
|
|
8819
9297
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -8834,7 +9312,7 @@ return {
|
|
|
8834
9312
|
]]></string>
|
|
8835
9313
|
</Properties>
|
|
8836
9314
|
</Item>
|
|
8837
|
-
<Item class="ModuleScript" referent="
|
|
9315
|
+
<Item class="ModuleScript" referent="29">
|
|
8838
9316
|
<Properties>
|
|
8839
9317
|
<string name="Name">PluginSession</string>
|
|
8840
9318
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -9023,7 +9501,7 @@ return {
|
|
|
9023
9501
|
]]></string>
|
|
9024
9502
|
</Properties>
|
|
9025
9503
|
</Item>
|
|
9026
|
-
<Item class="ModuleScript" referent="
|
|
9504
|
+
<Item class="ModuleScript" referent="30">
|
|
9027
9505
|
<Properties>
|
|
9028
9506
|
<string name="Name">Recording</string>
|
|
9029
9507
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -9053,7 +9531,7 @@ return {
|
|
|
9053
9531
|
]]></string>
|
|
9054
9532
|
</Properties>
|
|
9055
9533
|
</Item>
|
|
9056
|
-
<Item class="ModuleScript" referent="
|
|
9534
|
+
<Item class="ModuleScript" referent="31">
|
|
9057
9535
|
<Properties>
|
|
9058
9536
|
<string name="Name">RenderMonitor</string>
|
|
9059
9537
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -9121,7 +9599,7 @@ return {
|
|
|
9121
9599
|
]]></string>
|
|
9122
9600
|
</Properties>
|
|
9123
9601
|
</Item>
|
|
9124
|
-
<Item class="ModuleScript" referent="
|
|
9602
|
+
<Item class="ModuleScript" referent="32">
|
|
9125
9603
|
<Properties>
|
|
9126
9604
|
<string name="Name">RuntimeLogBuffer</string>
|
|
9127
9605
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -9357,7 +9835,7 @@ return {
|
|
|
9357
9835
|
]]></string>
|
|
9358
9836
|
</Properties>
|
|
9359
9837
|
</Item>
|
|
9360
|
-
<Item class="ModuleScript" referent="
|
|
9838
|
+
<Item class="ModuleScript" referent="33">
|
|
9361
9839
|
<Properties>
|
|
9362
9840
|
<string name="Name">ScriptSearch</string>
|
|
9363
9841
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -9684,7 +10162,7 @@ return {
|
|
|
9684
10162
|
]]></string>
|
|
9685
10163
|
</Properties>
|
|
9686
10164
|
</Item>
|
|
9687
|
-
<Item class="ModuleScript" referent="
|
|
10165
|
+
<Item class="ModuleScript" referent="34">
|
|
9688
10166
|
<Properties>
|
|
9689
10167
|
<string name="Name">ServerUrlSettings</string>
|
|
9690
10168
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -9823,11 +10301,11 @@ return {
|
|
|
9823
10301
|
]]></string>
|
|
9824
10302
|
</Properties>
|
|
9825
10303
|
</Item>
|
|
9826
|
-
<Item class="ModuleScript" referent="
|
|
10304
|
+
<Item class="ModuleScript" referent="35">
|
|
9827
10305
|
<Properties>
|
|
9828
10306
|
<string name="Name">State</string>
|
|
9829
10307
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
9830
|
-
local CURRENT_VERSION = "3.1.
|
|
10308
|
+
local CURRENT_VERSION = "3.1.4"
|
|
9831
10309
|
local PLUGIN_VARIANT = "inspector"
|
|
9832
10310
|
local BASE_PORT = 58741
|
|
9833
10311
|
local function createConnection(port)
|
|
@@ -9857,7 +10335,7 @@ return {
|
|
|
9857
10335
|
]]></string>
|
|
9858
10336
|
</Properties>
|
|
9859
10337
|
</Item>
|
|
9860
|
-
<Item class="ModuleScript" referent="
|
|
10338
|
+
<Item class="ModuleScript" referent="36">
|
|
9861
10339
|
<Properties>
|
|
9862
10340
|
<string name="Name">StopPlayMonitor</string>
|
|
9863
10341
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -10090,7 +10568,7 @@ return {
|
|
|
10090
10568
|
]]></string>
|
|
10091
10569
|
</Properties>
|
|
10092
10570
|
</Item>
|
|
10093
|
-
<Item class="ModuleScript" referent="
|
|
10571
|
+
<Item class="ModuleScript" referent="37">
|
|
10094
10572
|
<Properties>
|
|
10095
10573
|
<string name="Name">StudioWebSocket</string>
|
|
10096
10574
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -11041,7 +11519,7 @@ return {
|
|
|
11041
11519
|
]]></string>
|
|
11042
11520
|
</Properties>
|
|
11043
11521
|
</Item>
|
|
11044
|
-
<Item class="ModuleScript" referent="
|
|
11522
|
+
<Item class="ModuleScript" referent="38">
|
|
11045
11523
|
<Properties>
|
|
11046
11524
|
<string name="Name">TopologyId</string>
|
|
11047
11525
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -11086,7 +11564,7 @@ return {
|
|
|
11086
11564
|
]]></string>
|
|
11087
11565
|
</Properties>
|
|
11088
11566
|
</Item>
|
|
11089
|
-
<Item class="ModuleScript" referent="
|
|
11567
|
+
<Item class="ModuleScript" referent="39">
|
|
11090
11568
|
<Properties>
|
|
11091
11569
|
<string name="Name">UI</string>
|
|
11092
11570
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -11638,7 +12116,7 @@ return {
|
|
|
11638
12116
|
]]></string>
|
|
11639
12117
|
</Properties>
|
|
11640
12118
|
</Item>
|
|
11641
|
-
<Item class="ModuleScript" referent="
|
|
12119
|
+
<Item class="ModuleScript" referent="40">
|
|
11642
12120
|
<Properties>
|
|
11643
12121
|
<string name="Name">Utils</string>
|
|
11644
12122
|
<string name="Source"><![CDATA[-- Compiled with roblox-ts v3.0.0
|
|
@@ -12479,11 +12957,11 @@ return {
|
|
|
12479
12957
|
</Properties>
|
|
12480
12958
|
</Item>
|
|
12481
12959
|
</Item>
|
|
12482
|
-
<Item class="Folder" referent="
|
|
12960
|
+
<Item class="Folder" referent="45">
|
|
12483
12961
|
<Properties>
|
|
12484
12962
|
<string name="Name">include</string>
|
|
12485
12963
|
</Properties>
|
|
12486
|
-
<Item class="ModuleScript" referent="
|
|
12964
|
+
<Item class="ModuleScript" referent="41">
|
|
12487
12965
|
<Properties>
|
|
12488
12966
|
<string name="Name">LibMP</string>
|
|
12489
12967
|
<string name="Source"><![CDATA[-- =============================================================================
|
|
@@ -168867,7 +169345,7 @@ return LibMP
|
|
|
168867
169345
|
]]></string>
|
|
168868
169346
|
</Properties>
|
|
168869
169347
|
</Item>
|
|
168870
|
-
<Item class="ModuleScript" referent="
|
|
169348
|
+
<Item class="ModuleScript" referent="42">
|
|
168871
169349
|
<Properties>
|
|
168872
169350
|
<string name="Name">Promise</string>
|
|
168873
169351
|
<string name="Source"><![CDATA[--[[
|
|
@@ -170941,7 +171419,7 @@ return Promise
|
|
|
170941
171419
|
]]></string>
|
|
170942
171420
|
</Properties>
|
|
170943
171421
|
</Item>
|
|
170944
|
-
<Item class="ModuleScript" referent="
|
|
171422
|
+
<Item class="ModuleScript" referent="43">
|
|
170945
171423
|
<Properties>
|
|
170946
171424
|
<string name="Name">RuntimeLib</string>
|
|
170947
171425
|
<string name="Source"><![CDATA[local Promise = require(script.Parent.Promise)
|
|
@@ -171208,15 +171686,15 @@ return TS
|
|
|
171208
171686
|
</Properties>
|
|
171209
171687
|
</Item>
|
|
171210
171688
|
</Item>
|
|
171211
|
-
<Item class="Folder" referent="
|
|
171689
|
+
<Item class="Folder" referent="46">
|
|
171212
171690
|
<Properties>
|
|
171213
171691
|
<string name="Name">node_modules</string>
|
|
171214
171692
|
</Properties>
|
|
171215
|
-
<Item class="Folder" referent="
|
|
171693
|
+
<Item class="Folder" referent="47">
|
|
171216
171694
|
<Properties>
|
|
171217
171695
|
<string name="Name">@rbxts</string>
|
|
171218
171696
|
</Properties>
|
|
171219
|
-
<Item class="ModuleScript" referent="
|
|
171697
|
+
<Item class="ModuleScript" referent="44">
|
|
171220
171698
|
<Properties>
|
|
171221
171699
|
<string name="Name">services</string>
|
|
171222
171700
|
<string name="Source"><![CDATA[return setmetatable({}, {
|