roblox-opencode 1.0.0
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 +122 -0
- package/commands/setup-game.md +108 -0
- package/commands/sync-check.md +53 -0
- package/core/roblox-core.md +93 -0
- package/dist/server.js +167 -0
- package/package.json +35 -0
- package/skills/roblox-analytics/SKILL.md +277 -0
- package/skills/roblox-analytics/references/event-batcher.luau +75 -0
- package/skills/roblox-animation-vfx/SKILL.md +1325 -0
- package/skills/roblox-architecture/SKILL.md +863 -0
- package/skills/roblox-architecture/references/combat-systems.md +1381 -0
- package/skills/roblox-code-review/SKILL.md +687 -0
- package/skills/roblox-data/SKILL.md +889 -0
- package/skills/roblox-data/references/inventory-systems.md +1729 -0
- package/skills/roblox-debug/SKILL.md +99 -0
- package/skills/roblox-gui/SKILL.md +1103 -0
- package/skills/roblox-gui-fusion/SKILL.md +150 -0
- package/skills/roblox-gui-fusion/references/inventory.luau +427 -0
- package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -0
- package/skills/roblox-gui-fusion/references/shop.luau +411 -0
- package/skills/roblox-luau-mastery/SKILL.md +1519 -0
- package/skills/roblox-monetization/SKILL.md +1084 -0
- package/skills/roblox-monetization/references/process-receipt.luau +131 -0
- package/skills/roblox-networking/SKILL.md +669 -0
- package/skills/roblox-networking/references/remote-validator.luau +193 -0
- package/skills/roblox-publish-checklist/SKILL.md +128 -0
- package/skills/roblox-runtime/SKILL.md +753 -0
- package/skills/roblox-sharp-edges/SKILL.md +295 -0
- package/skills/roblox-sync/SKILL.md +126 -0
- package/skills/roblox-testing/SKILL.md +943 -0
- package/skills/roblox-tooling/SKILL.md +150 -0
- package/vendor/LICENSES/ProfileStore-LICENSE +201 -0
- package/vendor/LICENSES/RbxUtil-LICENSE +7 -0
- package/vendor/LICENSES/promise-LICENSE +21 -0
- package/vendor/LICENSES/t-LICENSE +21 -0
- package/vendor/LICENSES/testez-LICENSE +201 -0
- package/vendor/README.md +84 -0
- package/vendor/fusion/Animation/ExternalTime.luau +84 -0
- package/vendor/fusion/Animation/Spring.luau +322 -0
- package/vendor/fusion/Animation/Stopwatch.luau +128 -0
- package/vendor/fusion/Animation/Tween.luau +187 -0
- package/vendor/fusion/Animation/getTweenDuration.luau +27 -0
- package/vendor/fusion/Animation/getTweenRatio.luau +47 -0
- package/vendor/fusion/Animation/lerpType.luau +164 -0
- package/vendor/fusion/Animation/packType.luau +100 -0
- package/vendor/fusion/Animation/springCoefficients.luau +80 -0
- package/vendor/fusion/Animation/unpackType.luau +103 -0
- package/vendor/fusion/Colour/Oklab.luau +70 -0
- package/vendor/fusion/Colour/sRGB.luau +55 -0
- package/vendor/fusion/External.luau +168 -0
- package/vendor/fusion/ExternalDebug.luau +70 -0
- package/vendor/fusion/Graph/Observer.luau +114 -0
- package/vendor/fusion/Graph/castToGraph.luau +29 -0
- package/vendor/fusion/Graph/change.luau +81 -0
- package/vendor/fusion/Graph/depend.luau +33 -0
- package/vendor/fusion/Graph/evaluate.luau +56 -0
- package/vendor/fusion/Instances/Attribute.luau +58 -0
- package/vendor/fusion/Instances/AttributeChange.luau +47 -0
- package/vendor/fusion/Instances/AttributeOut.luau +63 -0
- package/vendor/fusion/Instances/Child.luau +21 -0
- package/vendor/fusion/Instances/Children.luau +148 -0
- package/vendor/fusion/Instances/Hydrate.luau +33 -0
- package/vendor/fusion/Instances/New.luau +53 -0
- package/vendor/fusion/Instances/OnChange.luau +50 -0
- package/vendor/fusion/Instances/OnEvent.luau +54 -0
- package/vendor/fusion/Instances/Out.luau +69 -0
- package/vendor/fusion/Instances/applyInstanceProps.luau +149 -0
- package/vendor/fusion/Instances/defaultProps.luau +194 -0
- package/vendor/fusion/LICENSE +21 -0
- package/vendor/fusion/Logging/formatError.luau +49 -0
- package/vendor/fusion/Logging/messages.luau +52 -0
- package/vendor/fusion/Logging/parseError.luau +25 -0
- package/vendor/fusion/Memory/checkLifetime.luau +134 -0
- package/vendor/fusion/Memory/deriveScope.luau +24 -0
- package/vendor/fusion/Memory/deriveScopeImpl.luau +45 -0
- package/vendor/fusion/Memory/doCleanup.luau +79 -0
- package/vendor/fusion/Memory/innerScope.luau +34 -0
- package/vendor/fusion/Memory/legacyCleanup.luau +18 -0
- package/vendor/fusion/Memory/needsDestruction.luau +17 -0
- package/vendor/fusion/Memory/poisonScope.luau +34 -0
- package/vendor/fusion/Memory/scopePool.luau +55 -0
- package/vendor/fusion/Memory/scoped.luau +27 -0
- package/vendor/fusion/Memory/whichLivesLonger.luau +75 -0
- package/vendor/fusion/RobloxExternal.luau +98 -0
- package/vendor/fusion/State/Computed.luau +139 -0
- package/vendor/fusion/State/For/Disassembly.luau +211 -0
- package/vendor/fusion/State/For/ForTypes.luau +30 -0
- package/vendor/fusion/State/For/init.luau +110 -0
- package/vendor/fusion/State/ForKeys.luau +94 -0
- package/vendor/fusion/State/ForPairs.luau +97 -0
- package/vendor/fusion/State/ForValues.luau +94 -0
- package/vendor/fusion/State/Value.luau +88 -0
- package/vendor/fusion/State/castToState.luau +26 -0
- package/vendor/fusion/State/peek.luau +31 -0
- package/vendor/fusion/State/updateAll.luau +1 -0
- package/vendor/fusion/Types.luau +314 -0
- package/vendor/fusion/Utility/Contextual.luau +91 -0
- package/vendor/fusion/Utility/Safe.luau +23 -0
- package/vendor/fusion/Utility/isSimilar.luau +29 -0
- package/vendor/fusion/Utility/merge.luau +35 -0
- package/vendor/fusion/Utility/nameOf.luau +35 -0
- package/vendor/fusion/Utility/never.luau +14 -0
- package/vendor/fusion/Utility/nicknames.luau +11 -0
- package/vendor/fusion/Utility/xtypeof.luau +27 -0
- package/vendor/fusion/init.luau +82 -0
- package/vendor/profilestore/init.luau +2243 -0
- package/vendor/promise/init.luau +1982 -0
- package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -0
- package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -0
- package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -0
- package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -0
- package/vendor/rbxutil/buffer-util/Types.luau +60 -0
- package/vendor/rbxutil/buffer-util/index.d.ts +153 -0
- package/vendor/rbxutil/buffer-util/init.luau +41 -0
- package/vendor/rbxutil/buffer-util/package.json +16 -0
- package/vendor/rbxutil/buffer-util/wally.toml +9 -0
- package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -0
- package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -0
- package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -0
- package/vendor/rbxutil/comm/Client/init.luau +135 -0
- package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -0
- package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -0
- package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -0
- package/vendor/rbxutil/comm/Server/init.luau +140 -0
- package/vendor/rbxutil/comm/Types.luau +18 -0
- package/vendor/rbxutil/comm/Util.luau +27 -0
- package/vendor/rbxutil/comm/init.luau +35 -0
- package/vendor/rbxutil/comm/wally.toml +13 -0
- package/vendor/rbxutil/component/init.luau +759 -0
- package/vendor/rbxutil/component/init.test.luau +311 -0
- package/vendor/rbxutil/component/wally.toml +14 -0
- package/vendor/rbxutil/concur/init.luau +542 -0
- package/vendor/rbxutil/concur/init.test.luau +364 -0
- package/vendor/rbxutil/concur/wally.toml +8 -0
- package/vendor/rbxutil/enum-list/init.luau +101 -0
- package/vendor/rbxutil/enum-list/init.test.luau +91 -0
- package/vendor/rbxutil/enum-list/wally.toml +8 -0
- package/vendor/rbxutil/find/index.d.ts +20 -0
- package/vendor/rbxutil/find/init.luau +44 -0
- package/vendor/rbxutil/find/package.json +17 -0
- package/vendor/rbxutil/find/wally.toml +8 -0
- package/vendor/rbxutil/input/Gamepad.luau +559 -0
- package/vendor/rbxutil/input/Keyboard.luau +124 -0
- package/vendor/rbxutil/input/Mouse.luau +278 -0
- package/vendor/rbxutil/input/PreferredInput.luau +91 -0
- package/vendor/rbxutil/input/Touch.luau +120 -0
- package/vendor/rbxutil/input/init.luau +33 -0
- package/vendor/rbxutil/input/wally.toml +12 -0
- package/vendor/rbxutil/loader/index.d.ts +15 -0
- package/vendor/rbxutil/loader/init.luau +137 -0
- package/vendor/rbxutil/loader/wally.toml +8 -0
- package/vendor/rbxutil/log/index.d.ts +38 -0
- package/vendor/rbxutil/log/init.luau +746 -0
- package/vendor/rbxutil/log/wally.toml +8 -0
- package/vendor/rbxutil/net/init.luau +190 -0
- package/vendor/rbxutil/net/wally.toml +8 -0
- package/vendor/rbxutil/option/index.d.ts +44 -0
- package/vendor/rbxutil/option/init.luau +489 -0
- package/vendor/rbxutil/option/init.test.luau +342 -0
- package/vendor/rbxutil/option/wally.toml +8 -0
- package/vendor/rbxutil/pid/index.d.ts +53 -0
- package/vendor/rbxutil/pid/init.luau +195 -0
- package/vendor/rbxutil/pid/package.json +16 -0
- package/vendor/rbxutil/pid/wally.toml +9 -0
- package/vendor/rbxutil/quaternion/index.d.ts +117 -0
- package/vendor/rbxutil/quaternion/init.luau +570 -0
- package/vendor/rbxutil/quaternion/package.json +16 -0
- package/vendor/rbxutil/quaternion/wally.toml +9 -0
- package/vendor/rbxutil/query/index.d.ts +43 -0
- package/vendor/rbxutil/query/init.luau +117 -0
- package/vendor/rbxutil/query/package.json +18 -0
- package/vendor/rbxutil/query/wally.toml +9 -0
- package/vendor/rbxutil/sequent/index.d.ts +28 -0
- package/vendor/rbxutil/sequent/init.luau +340 -0
- package/vendor/rbxutil/sequent/package.json +16 -0
- package/vendor/rbxutil/sequent/wally.toml +9 -0
- package/vendor/rbxutil/ser/init.luau +175 -0
- package/vendor/rbxutil/ser/init.test.luau +50 -0
- package/vendor/rbxutil/ser/wally.toml +11 -0
- package/vendor/rbxutil/shake/index.d.ts +36 -0
- package/vendor/rbxutil/shake/init.luau +532 -0
- package/vendor/rbxutil/shake/init.test.luau +267 -0
- package/vendor/rbxutil/shake/package.json +16 -0
- package/vendor/rbxutil/shake/wally.toml +9 -0
- package/vendor/rbxutil/signal/index.d.ts +100 -0
- package/vendor/rbxutil/signal/init.luau +432 -0
- package/vendor/rbxutil/signal/init.test.luau +190 -0
- package/vendor/rbxutil/signal/package.json +17 -0
- package/vendor/rbxutil/signal/wally.toml +9 -0
- package/vendor/rbxutil/silo/TableWatcher.luau +65 -0
- package/vendor/rbxutil/silo/Util.luau +55 -0
- package/vendor/rbxutil/silo/init.luau +338 -0
- package/vendor/rbxutil/silo/init.test.luau +215 -0
- package/vendor/rbxutil/silo/wally.toml +8 -0
- package/vendor/rbxutil/spring/index.d.ts +40 -0
- package/vendor/rbxutil/spring/init.luau +97 -0
- package/vendor/rbxutil/spring/package.json +17 -0
- package/vendor/rbxutil/spring/wally.toml +8 -0
- package/vendor/rbxutil/stream/index.d.ts +88 -0
- package/vendor/rbxutil/stream/init.luau +597 -0
- package/vendor/rbxutil/stream/package.json +18 -0
- package/vendor/rbxutil/stream/wally.toml +9 -0
- package/vendor/rbxutil/streamable/Streamable.luau +202 -0
- package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -0
- package/vendor/rbxutil/streamable/init.luau +8 -0
- package/vendor/rbxutil/streamable/wally.toml +12 -0
- package/vendor/rbxutil/symbol/init.luau +56 -0
- package/vendor/rbxutil/symbol/init.test.luau +37 -0
- package/vendor/rbxutil/symbol/wally.toml +8 -0
- package/vendor/rbxutil/table-util/init.luau +938 -0
- package/vendor/rbxutil/table-util/init.test.luau +439 -0
- package/vendor/rbxutil/table-util/wally.toml +8 -0
- package/vendor/rbxutil/task-queue/index.d.ts +27 -0
- package/vendor/rbxutil/task-queue/init.luau +97 -0
- package/vendor/rbxutil/task-queue/wally.toml +8 -0
- package/vendor/rbxutil/timer/index.d.ts +81 -0
- package/vendor/rbxutil/timer/init.luau +249 -0
- package/vendor/rbxutil/timer/init.test.luau +73 -0
- package/vendor/rbxutil/timer/wally.toml +11 -0
- package/vendor/rbxutil/tree/index.d.ts +15 -0
- package/vendor/rbxutil/tree/init.luau +137 -0
- package/vendor/rbxutil/tree/wally.toml +8 -0
- package/vendor/rbxutil/trove/index.d.ts +46 -0
- package/vendor/rbxutil/trove/init.luau +787 -0
- package/vendor/rbxutil/trove/init.test.luau +203 -0
- package/vendor/rbxutil/trove/wally.toml +8 -0
- package/vendor/rbxutil/typed-remote/init.luau +196 -0
- package/vendor/rbxutil/typed-remote/wally.toml +8 -0
- package/vendor/rbxutil/wait-for/index.d.ts +17 -0
- package/vendor/rbxutil/wait-for/init.luau +257 -0
- package/vendor/rbxutil/wait-for/init.test.luau +182 -0
- package/vendor/rbxutil/wait-for/wally.toml +11 -0
- package/vendor/t/t.lua +1350 -0
- package/vendor/testez/Context.lua +26 -0
- package/vendor/testez/Expectation.lua +311 -0
- package/vendor/testez/ExpectationContext.lua +38 -0
- package/vendor/testez/LifecycleHooks.lua +89 -0
- package/vendor/testez/Reporters/TeamCityReporter.lua +102 -0
- package/vendor/testez/Reporters/TextReporter.lua +106 -0
- package/vendor/testez/Reporters/TextReporterQuiet.lua +97 -0
- package/vendor/testez/TestBootstrap.lua +147 -0
- package/vendor/testez/TestEnum.lua +28 -0
- package/vendor/testez/TestPlan.lua +304 -0
- package/vendor/testez/TestPlanner.lua +40 -0
- package/vendor/testez/TestResults.lua +112 -0
- package/vendor/testez/TestRunner.lua +188 -0
- package/vendor/testez/TestSession.lua +243 -0
- package/vendor/testez/init.lua +40 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
local ServerScriptService = game:GetService("ServerScriptService")
|
|
2
|
+
|
|
3
|
+
local Test = require(ServerScriptService.TestRunner.Test)
|
|
4
|
+
|
|
5
|
+
-- local BufferReader = require(script.Parent.BufferReader)
|
|
6
|
+
-- local BufferWriter = require(script.Parent.BufferWriter)
|
|
7
|
+
|
|
8
|
+
return function(ctx: Test.TestContext)
|
|
9
|
+
ctx:Describe("Some test", function()
|
|
10
|
+
ctx:Test("1 + 1 == 2", function()
|
|
11
|
+
ctx:Expect(1 + 1):ToBe(2)
|
|
12
|
+
end)
|
|
13
|
+
ctx:Test("1 + 1 != 3", function()
|
|
14
|
+
ctx:Expect(1 + 1):Not():ToBe(3)
|
|
15
|
+
end)
|
|
16
|
+
ctx:Describe("Nested group", function()
|
|
17
|
+
ctx:Test("true == true", function()
|
|
18
|
+
ctx:Expect(true):ToBe(true)
|
|
19
|
+
ctx:Expect(function()
|
|
20
|
+
return 32
|
|
21
|
+
end):ToBe(32)
|
|
22
|
+
end)
|
|
23
|
+
end)
|
|
24
|
+
end)
|
|
25
|
+
end
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
--!native
|
|
2
|
+
|
|
3
|
+
local BufferWriter = require(script.Parent.BufferWriter)
|
|
4
|
+
local DataTypeBuffer = require(script.Parent.DataTypeBuffer)
|
|
5
|
+
local Types = require(script.Parent.Types)
|
|
6
|
+
|
|
7
|
+
--[=[
|
|
8
|
+
@class BufferReader
|
|
9
|
+
|
|
10
|
+
A BufferReader is an abstraction wrapper for `buffer` objects
|
|
11
|
+
that provides a convenient way of reading out data from buffers.
|
|
12
|
+
]=]
|
|
13
|
+
local BufferReader = {}
|
|
14
|
+
BufferReader.__index = BufferReader
|
|
15
|
+
|
|
16
|
+
function BufferReader.new(buf: string | buffer | Types.BufferWriter): Types.BufferReader
|
|
17
|
+
if typeof(buf) == "string" then
|
|
18
|
+
return BufferReader.fromString(buf)
|
|
19
|
+
elseif typeof(buf) == "buffer" then
|
|
20
|
+
return BufferReader.fromBuffer(buf)
|
|
21
|
+
elseif typeof(buf) == "table" and getmetatable(buf :: any) == BufferWriter then
|
|
22
|
+
return BufferReader.fromBuffer(buf:GetBuffer())
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
error(`expected string or buffer; got {typeof(buf)}`)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
function BufferReader.fromBuffer(buf: buffer)
|
|
29
|
+
local self = setmetatable({
|
|
30
|
+
_buffer = buf,
|
|
31
|
+
_size = buffer.len(buf),
|
|
32
|
+
_cursor = 0,
|
|
33
|
+
}, BufferReader)
|
|
34
|
+
|
|
35
|
+
return self
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
function BufferReader.fromString(str: string)
|
|
39
|
+
return BufferReader.fromBuffer(buffer.fromstring(str))
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
function BufferReader:_assertSize(desiredSize: number)
|
|
43
|
+
if desiredSize > self._size then
|
|
44
|
+
error(`cursor out of bounds`, 3)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
--[=[
|
|
49
|
+
Read a signed 8-bit integer from the buffer.
|
|
50
|
+
]=]
|
|
51
|
+
function BufferReader:ReadInt8(): number
|
|
52
|
+
self:_assertSize(self._cursor + 1)
|
|
53
|
+
local n = buffer.readi8(self._buffer, self._cursor)
|
|
54
|
+
self._cursor += 1
|
|
55
|
+
return n
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
--[=[
|
|
59
|
+
Read an unsigned 8-bit integer from the buffer.
|
|
60
|
+
]=]
|
|
61
|
+
function BufferReader:ReadUInt8(): number
|
|
62
|
+
self:_assertSize(self._cursor + 1)
|
|
63
|
+
local n = buffer.readu8(self._buffer, self._cursor)
|
|
64
|
+
self._cursor += 1
|
|
65
|
+
return n
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
--[=[
|
|
69
|
+
Read a signed 16-bit integer from the buffer.
|
|
70
|
+
]=]
|
|
71
|
+
function BufferReader:ReadInt16(): number
|
|
72
|
+
self:_assertSize(self._cursor + 2)
|
|
73
|
+
local n = buffer.readi16(self._buffer, self._cursor)
|
|
74
|
+
self._cursor += 2
|
|
75
|
+
return n
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
--[=[
|
|
79
|
+
Read an unsigned 16-bit integer from the buffer.
|
|
80
|
+
]=]
|
|
81
|
+
function BufferReader:ReadUInt16(): number
|
|
82
|
+
self:_assertSize(self._cursor + 2)
|
|
83
|
+
local n = buffer.readu16(self._buffer, self._cursor)
|
|
84
|
+
self._cursor += 2
|
|
85
|
+
return n
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
--[=[
|
|
89
|
+
Read a signed 32-bit integer from the buffer.
|
|
90
|
+
]=]
|
|
91
|
+
function BufferReader:ReadInt32(): number
|
|
92
|
+
self:_assertSize(self._cursor + 4)
|
|
93
|
+
local n = buffer.readi32(self._buffer, self._cursor)
|
|
94
|
+
self._cursor += 4
|
|
95
|
+
return n
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
--[=[
|
|
99
|
+
Read an unsigned 32-bit integer from the buffer.
|
|
100
|
+
]=]
|
|
101
|
+
function BufferReader:ReadUInt32(): number
|
|
102
|
+
self:_assertSize(self._cursor + 4)
|
|
103
|
+
local n = buffer.readu32(self._buffer, self._cursor)
|
|
104
|
+
self._cursor += 4
|
|
105
|
+
return n
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
--[=[
|
|
109
|
+
Read a 32-bit single-precision float from the buffer.
|
|
110
|
+
]=]
|
|
111
|
+
function BufferReader:ReadFloat32(): number
|
|
112
|
+
self:_assertSize(self._cursor + 4)
|
|
113
|
+
local n = buffer.readf32(self._buffer, self._cursor)
|
|
114
|
+
self._cursor += 4
|
|
115
|
+
return n
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
--[=[
|
|
119
|
+
Read a 64-bit double-precision float from the buffer.
|
|
120
|
+
]=]
|
|
121
|
+
function BufferReader:ReadFloat64(): number
|
|
122
|
+
self:_assertSize(self._cursor + 8)
|
|
123
|
+
local n = buffer.readf64(self._buffer, self._cursor)
|
|
124
|
+
self._cursor += 8
|
|
125
|
+
return n
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
--[=[
|
|
129
|
+
Read a boolean from the buffer.
|
|
130
|
+
]=]
|
|
131
|
+
function BufferReader:ReadBool(): boolean
|
|
132
|
+
local n = self:ReadUInt8()
|
|
133
|
+
return n == 1
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
--[=[
|
|
137
|
+
Read a string from the buffer.
|
|
138
|
+
|
|
139
|
+
:::info
|
|
140
|
+
This assumes the string was written using the `BufferWriter:WriteString()`
|
|
141
|
+
method, which stores an extra integer to mark the size of the string.
|
|
142
|
+
:::
|
|
143
|
+
]=]
|
|
144
|
+
function BufferReader:ReadString(): string
|
|
145
|
+
local strLen = self:ReadUInt32()
|
|
146
|
+
self:_assertSize(self._cursor + strLen)
|
|
147
|
+
local s = buffer.readstring(self._buffer, self._cursor, strLen)
|
|
148
|
+
self._cursor += strLen
|
|
149
|
+
return s
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
--[=[
|
|
153
|
+
Read a string from the buffer.
|
|
154
|
+
|
|
155
|
+
:::info
|
|
156
|
+
This assumes the string was written using the `BufferWriter:WriteStringRaw()`.
|
|
157
|
+
:::
|
|
158
|
+
]=]
|
|
159
|
+
function BufferReader:ReadStringRaw(length: number): string
|
|
160
|
+
length = math.max(0, math.floor(length))
|
|
161
|
+
self:_assertSize(self._cursor + length)
|
|
162
|
+
local s = buffer.readstring(self._buffer, self._cursor, length)
|
|
163
|
+
self._cursor += length
|
|
164
|
+
return s
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
--[=[
|
|
168
|
+
Read a DataType from the buffer.
|
|
169
|
+
|
|
170
|
+
```lua
|
|
171
|
+
local cframe = reader:ReadDataType(CFrame)
|
|
172
|
+
```
|
|
173
|
+
]=]
|
|
174
|
+
function BufferReader:ReadDataType<T>(dataType: T): T
|
|
175
|
+
local name = DataTypeBuffer.DataTypesToString[dataType]
|
|
176
|
+
if not name then
|
|
177
|
+
error("unsupported data type", 2)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
local readWrite = DataTypeBuffer.ReadWrite[name]
|
|
181
|
+
return readWrite.read(self)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
--[=[
|
|
185
|
+
Sets the position of the cursor.
|
|
186
|
+
]=]
|
|
187
|
+
function BufferReader:SetCursor(position: number)
|
|
188
|
+
position = math.floor(position)
|
|
189
|
+
if position < 0 or position > self._size then
|
|
190
|
+
error(`cursor position {position} out of range [0, {self._size}]`, 3)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
self._cursor = position
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
--[=[
|
|
197
|
+
Returns the position of the cursor.
|
|
198
|
+
]=]
|
|
199
|
+
function BufferReader:GetCursor(): number
|
|
200
|
+
return self._cursor
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
--[=[
|
|
204
|
+
Resets the position of the cursor.
|
|
205
|
+
]=]
|
|
206
|
+
function BufferReader:ResetCursor()
|
|
207
|
+
self._cursor = 0
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
--[=[
|
|
211
|
+
Returns the size of the buffer.
|
|
212
|
+
]=]
|
|
213
|
+
function BufferReader:GetSize(): number
|
|
214
|
+
return self._size
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
--[=[
|
|
218
|
+
Returns the `buffer` object.
|
|
219
|
+
]=]
|
|
220
|
+
function BufferReader:GetBuffer(): buffer
|
|
221
|
+
return self._buffer
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
function BufferReader:__tostring()
|
|
225
|
+
return "BufferReader"
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
return BufferReader
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
--!native
|
|
2
|
+
|
|
3
|
+
local MAX_SIZE = 1073741824
|
|
4
|
+
|
|
5
|
+
local DataTypeBuffer = require(script.Parent.DataTypeBuffer)
|
|
6
|
+
local Types = require(script.Parent.Types)
|
|
7
|
+
|
|
8
|
+
--[=[
|
|
9
|
+
@class BufferWriter
|
|
10
|
+
|
|
11
|
+
A BufferWriter is an abstraction wrapper for `buffer` objects
|
|
12
|
+
that provides a convenient way of writing data to buffers.
|
|
13
|
+
|
|
14
|
+
The internal buffer is automatically resized to fit the data
|
|
15
|
+
that is being written.
|
|
16
|
+
]=]
|
|
17
|
+
local BufferWriter = {}
|
|
18
|
+
BufferWriter.__index = BufferWriter
|
|
19
|
+
|
|
20
|
+
function BufferWriter.new(initialSize: number?): Types.BufferWriter
|
|
21
|
+
local size = if typeof(initialSize) == "number" then math.clamp(initialSize, 0, MAX_SIZE) else 0
|
|
22
|
+
|
|
23
|
+
local self = setmetatable({
|
|
24
|
+
_buffer = buffer.create(size),
|
|
25
|
+
_cursor = 0,
|
|
26
|
+
_size = 0,
|
|
27
|
+
}, BufferWriter)
|
|
28
|
+
|
|
29
|
+
return self
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
function BufferWriter:_resizeUpTo(desiredSize: number)
|
|
33
|
+
if desiredSize > MAX_SIZE then
|
|
34
|
+
error(`cannot resize buffer to {desiredSize} bytes (max size: {MAX_SIZE} bytes)`, 3)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
self._size = math.max(self._size, desiredSize)
|
|
38
|
+
|
|
39
|
+
if desiredSize <= buffer.len(self._buffer) then
|
|
40
|
+
return
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
local newSize = desiredSize
|
|
44
|
+
|
|
45
|
+
local powerOfTwo = math.log(desiredSize, 2)
|
|
46
|
+
if math.floor(powerOfTwo) ~= powerOfTwo then
|
|
47
|
+
newSize = 2 ^ (math.floor(powerOfTwo) + 1)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
local oldBuffer = self._buffer
|
|
51
|
+
local newBuffer = buffer.create(newSize)
|
|
52
|
+
|
|
53
|
+
buffer.copy(newBuffer, 0, oldBuffer, 0)
|
|
54
|
+
|
|
55
|
+
self._buffer = newBuffer
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
--[=[
|
|
59
|
+
Write a signed 8-bit integer to the buffer.
|
|
60
|
+
]=]
|
|
61
|
+
function BufferWriter:WriteInt8(int8: number)
|
|
62
|
+
self:_resizeUpTo(self._cursor + 1)
|
|
63
|
+
buffer.writei8(self._buffer, self._cursor, int8)
|
|
64
|
+
self._cursor += 1
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
--[=[
|
|
68
|
+
Write an unsigned 8-bit integer to the buffer.
|
|
69
|
+
]=]
|
|
70
|
+
function BufferWriter:WriteUInt8(uint8: number)
|
|
71
|
+
self:_resizeUpTo(self._cursor + 1)
|
|
72
|
+
buffer.writeu8(self._buffer, self._cursor, uint8)
|
|
73
|
+
self._cursor += 1
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
--[=[
|
|
77
|
+
Write a signed 16-bit integer to the buffer.
|
|
78
|
+
]=]
|
|
79
|
+
function BufferWriter:WriteInt16(int16: number)
|
|
80
|
+
self:_resizeUpTo(self._cursor + 2)
|
|
81
|
+
buffer.writei16(self._buffer, self._cursor, int16)
|
|
82
|
+
self._cursor += 2
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
--[=[
|
|
86
|
+
Write an unsigned 16-bit integer to the buffer.
|
|
87
|
+
]=]
|
|
88
|
+
function BufferWriter:WriteUInt16(uint16: number)
|
|
89
|
+
self:_resizeUpTo(self._cursor + 2)
|
|
90
|
+
buffer.writeu16(self._buffer, self._cursor, uint16)
|
|
91
|
+
self._cursor += 2
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
--[=[
|
|
95
|
+
Write a signed 32-bit integer to the buffer.
|
|
96
|
+
]=]
|
|
97
|
+
function BufferWriter:WriteInt32(int32: number)
|
|
98
|
+
self:_resizeUpTo(self._cursor + 4)
|
|
99
|
+
buffer.writei32(self._buffer, self._cursor, int32)
|
|
100
|
+
self._cursor += 4
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
--[=[
|
|
104
|
+
Write an unsigned 32-bit integer to the buffer.
|
|
105
|
+
]=]
|
|
106
|
+
function BufferWriter:WriteUInt32(uint32: number)
|
|
107
|
+
self:_resizeUpTo(self._cursor + 4)
|
|
108
|
+
buffer.writeu32(self._buffer, self._cursor, uint32)
|
|
109
|
+
self._cursor += 4
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
--[=[
|
|
113
|
+
Write a 32-bit single-precision float to the buffer.
|
|
114
|
+
]=]
|
|
115
|
+
function BufferWriter:WriteFloat32(f32: number)
|
|
116
|
+
self:_resizeUpTo(self._cursor + 4)
|
|
117
|
+
buffer.writef32(self._buffer, self._cursor, f32)
|
|
118
|
+
self._cursor += 4
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
--[=[
|
|
122
|
+
Write a 64-bit double-precision float to the buffer.
|
|
123
|
+
]=]
|
|
124
|
+
function BufferWriter:WriteFloat64(f64: number)
|
|
125
|
+
self:_resizeUpTo(self._cursor + 8)
|
|
126
|
+
buffer.writef64(self._buffer, self._cursor, f64)
|
|
127
|
+
self._cursor += 8
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
--[=[
|
|
131
|
+
Write a boolean to the buffer.
|
|
132
|
+
]=]
|
|
133
|
+
function BufferWriter:WriteBool(bool: boolean)
|
|
134
|
+
self:WriteUInt8(if bool then 1 else 0)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
--[=[
|
|
138
|
+
Write a string to the buffer. An optional `length` argument can
|
|
139
|
+
be provided to limit the number of bytes read from the string.
|
|
140
|
+
|
|
141
|
+
:::info
|
|
142
|
+
An extra 32-bit integer is stored before the string to mark the
|
|
143
|
+
length of the string. If the length of the string is always
|
|
144
|
+
known, it is more memory-efficient to use `WriteStringRaw`.
|
|
145
|
+
:::
|
|
146
|
+
]=]
|
|
147
|
+
function BufferWriter:WriteString(str: string, length: number?)
|
|
148
|
+
local len = if length then math.min(#str, length) else #str
|
|
149
|
+
local size = len + 4
|
|
150
|
+
self:_resizeUpTo(self._cursor + size)
|
|
151
|
+
buffer.writeu32(self._buffer, self._cursor, len)
|
|
152
|
+
buffer.writestring(self._buffer, self._cursor + 4, str, length)
|
|
153
|
+
self._cursor += size
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
--[=[
|
|
157
|
+
Write a string to the buffer. An optional `length` argument can
|
|
158
|
+
be provided to limit the number of bytes read from the string.
|
|
159
|
+
|
|
160
|
+
:::info
|
|
161
|
+
The length of the string must be known to the reader in order to
|
|
162
|
+
read this string from the buffer, as the length of the string is
|
|
163
|
+
not stored in the buffer. For strings of dynamic/unknown length,
|
|
164
|
+
use `WriteString` instead.
|
|
165
|
+
:::
|
|
166
|
+
]=]
|
|
167
|
+
function BufferWriter:WriteStringRaw(str: string, length: number?)
|
|
168
|
+
local len = if length then math.min(#str, length) else #str
|
|
169
|
+
self:_resizeUpTo(self._cursor + len)
|
|
170
|
+
buffer.writestring(self._buffer, self._cursor, str, length)
|
|
171
|
+
self._cursor += len
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
--[=[
|
|
175
|
+
Write a DataType to the buffer.
|
|
176
|
+
|
|
177
|
+
```lua
|
|
178
|
+
writer:WriteDataType(CFrame.new(0, 10, 5))
|
|
179
|
+
```
|
|
180
|
+
]=]
|
|
181
|
+
function BufferWriter:WriteDataType(value: any)
|
|
182
|
+
local t = typeof(value)
|
|
183
|
+
local readWrite = DataTypeBuffer.ReadWrite[t]
|
|
184
|
+
if not readWrite then
|
|
185
|
+
error(`unsupported data type "{t}"`, 2)
|
|
186
|
+
end
|
|
187
|
+
readWrite.write(self, value)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
--[=[
|
|
191
|
+
Shrinks the capacity of the buffer to the current data size.
|
|
192
|
+
]=]
|
|
193
|
+
function BufferWriter:Shrink()
|
|
194
|
+
if self._size == buffer.len(self._buffer) then
|
|
195
|
+
return
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
local oldBuffer = self._buffer
|
|
199
|
+
local newBuffer = buffer.create(self._size)
|
|
200
|
+
|
|
201
|
+
buffer.copy(newBuffer, 0, oldBuffer, 0, self._size)
|
|
202
|
+
|
|
203
|
+
self._buffer = newBuffer
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
--[=[
|
|
207
|
+
Returns the current data size of the buffer. This is _not_ necessarily
|
|
208
|
+
equal to the capacity of the buffer.
|
|
209
|
+
]=]
|
|
210
|
+
function BufferWriter:GetSize(): number
|
|
211
|
+
return self._size
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
--[=[
|
|
215
|
+
Returns the current capacity of the buffer. This is the length of the
|
|
216
|
+
internal buffer, which is usually not the same as the length of the stored
|
|
217
|
+
data.
|
|
218
|
+
|
|
219
|
+
The buffer capacity automatically grows as data is added.
|
|
220
|
+
]=]
|
|
221
|
+
function BufferWriter:GetCapacity(): number
|
|
222
|
+
return buffer.len(self._buffer)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
--[=[
|
|
226
|
+
Sets the position of the cursor.
|
|
227
|
+
]=]
|
|
228
|
+
function BufferWriter:SetCursor(position: number)
|
|
229
|
+
position = math.floor(position)
|
|
230
|
+
if position < 0 or position > self._size then
|
|
231
|
+
error(`cursor position {position} out of range [0, {self._size}]`, 3)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
self._cursor = position
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
--[=[
|
|
238
|
+
Gets the position of the cursor.
|
|
239
|
+
]=]
|
|
240
|
+
function BufferWriter:GetCursor(): number
|
|
241
|
+
return self._cursor
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
--[=[
|
|
245
|
+
Resets the position of the cursor.
|
|
246
|
+
]=]
|
|
247
|
+
function BufferWriter:ResetCursor()
|
|
248
|
+
self._cursor = 0
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
--[=[
|
|
252
|
+
Returns the `buffer` object.
|
|
253
|
+
]=]
|
|
254
|
+
function BufferWriter:GetBuffer(): buffer
|
|
255
|
+
return self._buffer
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
--[=[
|
|
259
|
+
Returns the string version of the internal buffer.
|
|
260
|
+
]=]
|
|
261
|
+
function BufferWriter:ToString(): string
|
|
262
|
+
return buffer.tostring(self._buffer)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
function BufferWriter:__tostring()
|
|
266
|
+
return "BufferWriter"
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
return BufferWriter
|