@el4cteo/rbx-studio-mcp 0.6.1 → 0.6.7
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/README.md +28 -2
- package/dist/bridge/console.js +182 -0
- package/dist/bridge/console.js.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/cloudassets.js +233 -0
- package/dist/lib/cloudassets.js.map +1 -0
- package/dist/lib/credentials.js +180 -0
- package/dist/lib/credentials.js.map +1 -0
- package/dist/lib/livedata.js +325 -0
- package/dist/lib/livedata.js.map +1 -0
- package/dist/lib/liveluau.js +83 -0
- package/dist/lib/liveluau.js.map +1 -0
- package/dist/lib/liveops.js +358 -0
- package/dist/lib/liveops.js.map +1 -0
- package/dist/lib/opencloud.js +235 -0
- package/dist/lib/opencloud.js.map +1 -0
- package/dist/tools/anim.js +159 -0
- package/dist/tools/anim.js.map +1 -0
- package/dist/tools/audio.js +96 -0
- package/dist/tools/audio.js.map +1 -0
- package/dist/tools/character.js +95 -5
- package/dist/tools/character.js.map +1 -1
- package/dist/tools/data.js +292 -0
- package/dist/tools/data.js.map +1 -0
- package/dist/tools/device.js +77 -7
- package/dist/tools/device.js.map +1 -1
- package/dist/tools/discover.js +80 -4
- package/dist/tools/discover.js.map +1 -1
- package/dist/tools/exec.js +96 -2
- package/dist/tools/exec.js.map +1 -1
- package/dist/tools/input.js +35 -9
- package/dist/tools/input.js.map +1 -1
- package/dist/tools/perf.js +74 -7
- package/dist/tools/perf.js.map +1 -1
- package/dist/tools/scripts.js +162 -6
- package/dist/tools/scripts.js.map +1 -1
- package/dist/tools/spatial.js +135 -0
- package/dist/tools/spatial.js.map +1 -0
- package/dist/tools/universe.js +177 -0
- package/dist/tools/universe.js.map +1 -0
- package/dist/tools/upload.js +294 -0
- package/dist/tools/upload.js.map +1 -0
- package/dist/tools/world.js +675 -51
- package/dist/tools/world.js.map +1 -1
- package/package.json +2 -2
- package/plugin/src/Commands.luau +31 -7
- package/plugin/src/Config.luau +65 -65
- package/plugin/src/Console.luau +1909 -1843
- package/plugin/src/Emulation.luau +172 -0
- package/plugin/src/Phrase.luau +816 -618
- package/plugin/src/Png.luau +8 -4
- package/plugin/src/Prompt.luau +965 -961
- package/plugin/src/Secret.luau +86 -0
- package/plugin/src/Serialize.luau +440 -8
- package/plugin/src/Undo.luau +94 -6
- package/plugin/src/handlers/Anim.luau +897 -0
- package/plugin/src/handlers/Assets.luau +286 -2
- package/plugin/src/handlers/Audio.luau +411 -0
- package/plugin/src/handlers/Capture.luau +155 -20
- package/plugin/src/handlers/Character.luau +823 -361
- package/plugin/src/handlers/Data.luau +539 -0
- package/plugin/src/handlers/Device.luau +394 -139
- package/plugin/src/handlers/Discover.luau +685 -363
- package/plugin/src/handlers/Geometry.luau +722 -450
- package/plugin/src/handlers/Instances.luau +84 -4
- package/plugin/src/handlers/Perf.luau +227 -0
- package/plugin/src/handlers/Scripts.luau +673 -539
- package/plugin/src/handlers/Session.luau +3 -0
- package/plugin/src/handlers/Spatial.luau +334 -0
- package/plugin/src/handlers/Viewport.luau +268 -0
- package/plugin/src/handlers/World.luau +89 -15
- package/plugin/src/init.server.luau +9 -1
- package/scripts/build-plugin.mjs +20 -0
- package/scripts/check-plugin.mjs +171 -124
|
@@ -8,6 +8,12 @@
|
|
|
8
8
|
shape. Emulation persists until it is switched off, which is exactly the kind
|
|
9
9
|
of state that goes wrong quietly.
|
|
10
10
|
|
|
11
|
+
The network conditions Studio is shaping traffic with live here too. They are
|
|
12
|
+
the same kind of state for the same reason: set once, invisible on screen,
|
|
13
|
+
and they stay until something turns them off. A place that "feels laggy" with
|
|
14
|
+
a forgotten 400ms delay on it is exactly the bug this file exists to stop
|
|
15
|
+
people chasing.
|
|
16
|
+
|
|
11
17
|
`StudioDeviceSimulatorService` is undocumented on its return shapes, so what
|
|
12
18
|
is here was read off a live session. Two things are worth knowing:
|
|
13
19
|
|
|
@@ -21,8 +27,172 @@
|
|
|
21
27
|
|
|
22
28
|
local StudioDeviceSimulatorService = game:GetService("StudioDeviceSimulatorService")
|
|
23
29
|
|
|
30
|
+
--[[
|
|
31
|
+
`NetworkSettings` is not a `game` service; it hangs off `settings()`.
|
|
32
|
+
|
|
33
|
+
`game:GetService("NetworkSettings")` throws outright, which is worth writing
|
|
34
|
+
down because every other service in this codebase is reached that way. The
|
|
35
|
+
traffic-shaping properties on it -- delay, jitter, loss, in each direction --
|
|
36
|
+
are PluginSecurity, so they are readable and writable here and nowhere near a
|
|
37
|
+
running game.
|
|
38
|
+
|
|
39
|
+
Guarded: it is reached through a `pcall` at every use rather than captured
|
|
40
|
+
once, because a Studio old enough to lack the properties should cost the
|
|
41
|
+
network feature, not the whole `device` tool.
|
|
42
|
+
]]
|
|
43
|
+
local function networkSettings(): any?
|
|
44
|
+
local ok, service = pcall(function()
|
|
45
|
+
return (settings() :: any):GetService("NetworkSettings")
|
|
46
|
+
end)
|
|
47
|
+
if ok and service ~= nil then
|
|
48
|
+
return service
|
|
49
|
+
end
|
|
50
|
+
return nil
|
|
51
|
+
end
|
|
52
|
+
|
|
24
53
|
local Emulation = {}
|
|
25
54
|
|
|
55
|
+
Emulation.networkSettings = networkSettings
|
|
56
|
+
|
|
57
|
+
--[[
|
|
58
|
+
The six traffic-shaping properties, in the order a person reads them.
|
|
59
|
+
|
|
60
|
+
Inbound is what the client receives and is what a laggy connection feels
|
|
61
|
+
like; outbound is what it sends, which is what makes a player's own actions
|
|
62
|
+
arrive late to everyone else. Both are shaped separately by Studio, so both
|
|
63
|
+
are carried separately here.
|
|
64
|
+
]]
|
|
65
|
+
--[[
|
|
66
|
+
The memory ceiling this session set, if any.
|
|
67
|
+
|
|
68
|
+
Session-local by necessity: see the note in `Emulation.network`. A cap set by
|
|
69
|
+
Studio's own toolbar before the plugin loaded is invisible to this, which is
|
|
70
|
+
the honest failure -- reporting a cap that is not there was the alternative,
|
|
71
|
+
and it was worse.
|
|
72
|
+
]]
|
|
73
|
+
local memoryCap: number? = nil
|
|
74
|
+
|
|
75
|
+
local NETWORK_FIELDS = {
|
|
76
|
+
{ key = "inLatency", property = "InboundNetworkMinDelayMs", scale = 1 },
|
|
77
|
+
{ key = "inJitter", property = "InboundNetworkJitterMs", scale = 1 },
|
|
78
|
+
{ key = "inLoss", property = "InboundNetworkLossPercent", scale = 100 },
|
|
79
|
+
{ key = "outLatency", property = "OutboundNetworkMinDelayMs", scale = 1 },
|
|
80
|
+
{ key = "outJitter", property = "OutboundNetworkJitterMs", scale = 1 },
|
|
81
|
+
{ key = "outLoss", property = "OutboundNetworkLossPercent", scale = 100 },
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
--[[
|
|
85
|
+
What the engine will actually accept, measured rather than assumed.
|
|
86
|
+
|
|
87
|
+
None of this is documented and all three of them bite. Writes outside these
|
|
88
|
+
ranges SUCCEED and are silently clamped, so a preset asking for 2% loss was
|
|
89
|
+
reporting 0.5 back and the only way to notice was to read the value again --
|
|
90
|
+
which is how this was found.
|
|
91
|
+
|
|
92
|
+
* Loss is a FRACTION, despite `LossPercent` in the name: it tops out at 0.5,
|
|
93
|
+
and 0.5 is half the packets, not half a percent. Everything above this
|
|
94
|
+
layer speaks in percent because that is what a person means by "2% loss",
|
|
95
|
+
so the conversion happens at the edges -- `scale` above on the way out, and
|
|
96
|
+
`LOSS_LIMIT` on the way in.
|
|
97
|
+
* Delay and jitter both stop at 1000ms. A second of latency is already past
|
|
98
|
+
anything a real connection does, so this costs nothing but honesty.
|
|
99
|
+
]]
|
|
100
|
+
local LOSS_LIMIT = 0.5
|
|
101
|
+
local DELAY_LIMIT = 1000
|
|
102
|
+
|
|
103
|
+
Emulation.LOSS_LIMIT_PERCENT = LOSS_LIMIT * 100
|
|
104
|
+
Emulation.DELAY_LIMIT = DELAY_LIMIT
|
|
105
|
+
|
|
106
|
+
--[[
|
|
107
|
+
What Studio is currently doing to network traffic.
|
|
108
|
+
|
|
109
|
+
`shaping` is the field callers should branch on: every value being zero is
|
|
110
|
+
the normal, un-emulated state, and reporting six zeroes without saying so
|
|
111
|
+
makes "is anything on" a question the caller has to work out for itself.
|
|
112
|
+
]]
|
|
113
|
+
function Emulation.network(): { [string]: any }
|
|
114
|
+
local service = networkSettings()
|
|
115
|
+
if service == nil then
|
|
116
|
+
return { available = false, shaping = false }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
local state: { [string]: any } = { available = true }
|
|
120
|
+
local shaping = false
|
|
121
|
+
for _, field in NETWORK_FIELDS do
|
|
122
|
+
local ok, value = pcall(function()
|
|
123
|
+
return (service :: any)[field.property]
|
|
124
|
+
end)
|
|
125
|
+
local number = if ok then tonumber(value) or 0 else 0
|
|
126
|
+
--[[
|
|
127
|
+
Scaled into the caller's units, then rounded to two places. These are
|
|
128
|
+
32-bit floats: 2% loss is stored as 0.02 and reads back as
|
|
129
|
+
0.019999999552965164, and reporting that instead of 2 makes a
|
|
130
|
+
perfectly applied setting look like a failed one.
|
|
131
|
+
]]
|
|
132
|
+
number *= field.scale
|
|
133
|
+
state[field.key] = math.round(number * 100) / 100
|
|
134
|
+
if number > 0 then
|
|
135
|
+
shaping = true
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
--[[
|
|
140
|
+
Reported, but deliberately not counted as shaping.
|
|
141
|
+
|
|
142
|
+
`EmulatedTotalMemoryInMB` does not read back 0 when nothing is emulated:
|
|
143
|
+
it answers with the machine's real memory -- measured, 16159 on the
|
|
144
|
+
session this was written against. Treating "greater than zero" as a cap
|
|
145
|
+
therefore declared every untouched Studio to be emulating a low-memory
|
|
146
|
+
device, and `studio_status` told the agent traffic was being degraded on
|
|
147
|
+
a session where nothing had ever been set.
|
|
148
|
+
|
|
149
|
+
There is no read that distinguishes a cap from the true figure, so the
|
|
150
|
+
cap is remembered instead, by the one thing that sets it.
|
|
151
|
+
]]
|
|
152
|
+
local okMemory, memory = pcall(function()
|
|
153
|
+
return (service :: any).EmulatedTotalMemoryInMB
|
|
154
|
+
end)
|
|
155
|
+
if okMemory then
|
|
156
|
+
state.memoryMB = math.floor(tonumber(memory) or 0)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
if memoryCap ~= nil and memoryCap > 0 then
|
|
160
|
+
state.memoryCapMB = memoryCap
|
|
161
|
+
shaping = true
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
state.shaping = shaping
|
|
165
|
+
return state
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
--[[
|
|
169
|
+
Records the memory ceiling this session asked for.
|
|
170
|
+
|
|
171
|
+
Held here rather than in the handler because `network` writes it and
|
|
172
|
+
`Emulation.network` reports it, and a value those two disagree about is worse
|
|
173
|
+
than no value at all. nil or 0 means no cap.
|
|
174
|
+
]]
|
|
175
|
+
function Emulation.setMemoryCap(megabytes: number?)
|
|
176
|
+
memoryCap = if megabytes ~= nil and megabytes > 0 then megabytes else nil
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
--[[
|
|
180
|
+
The short form for `studio_status`, or nil when traffic is untouched.
|
|
181
|
+
|
|
182
|
+
Separate from the device summary rather than folded into it: a session can be
|
|
183
|
+
shaping traffic without emulating a device, and the device summary returns
|
|
184
|
+
nil in exactly that case.
|
|
185
|
+
]]
|
|
186
|
+
function Emulation.networkSummary(): { [string]: any }?
|
|
187
|
+
local state = Emulation.network()
|
|
188
|
+
if state.shaping ~= true then
|
|
189
|
+
return nil
|
|
190
|
+
end
|
|
191
|
+
state.note = 'Studio is degrading network traffic on purpose. `device op="network" '
|
|
192
|
+
.. 'preset="clear"` restores it.'
|
|
193
|
+
return state
|
|
194
|
+
end
|
|
195
|
+
|
|
26
196
|
--[[
|
|
27
197
|
The resolution as it actually appears, rather than as the panel is specified.
|
|
28
198
|
|
|
@@ -128,6 +298,8 @@ function Emulation.state(): { [string]: any }
|
|
|
128
298
|
state.scalingMode = tostring(scaling)
|
|
129
299
|
end
|
|
130
300
|
|
|
301
|
+
state.network = Emulation.network()
|
|
302
|
+
|
|
131
303
|
return state
|
|
132
304
|
end
|
|
133
305
|
|