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.
Files changed (248) hide show
  1. package/README.md +122 -0
  2. package/commands/setup-game.md +108 -0
  3. package/commands/sync-check.md +53 -0
  4. package/core/roblox-core.md +93 -0
  5. package/dist/server.js +167 -0
  6. package/package.json +35 -0
  7. package/skills/roblox-analytics/SKILL.md +277 -0
  8. package/skills/roblox-analytics/references/event-batcher.luau +75 -0
  9. package/skills/roblox-animation-vfx/SKILL.md +1325 -0
  10. package/skills/roblox-architecture/SKILL.md +863 -0
  11. package/skills/roblox-architecture/references/combat-systems.md +1381 -0
  12. package/skills/roblox-code-review/SKILL.md +687 -0
  13. package/skills/roblox-data/SKILL.md +889 -0
  14. package/skills/roblox-data/references/inventory-systems.md +1729 -0
  15. package/skills/roblox-debug/SKILL.md +99 -0
  16. package/skills/roblox-gui/SKILL.md +1103 -0
  17. package/skills/roblox-gui-fusion/SKILL.md +150 -0
  18. package/skills/roblox-gui-fusion/references/inventory.luau +427 -0
  19. package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -0
  20. package/skills/roblox-gui-fusion/references/shop.luau +411 -0
  21. package/skills/roblox-luau-mastery/SKILL.md +1519 -0
  22. package/skills/roblox-monetization/SKILL.md +1084 -0
  23. package/skills/roblox-monetization/references/process-receipt.luau +131 -0
  24. package/skills/roblox-networking/SKILL.md +669 -0
  25. package/skills/roblox-networking/references/remote-validator.luau +193 -0
  26. package/skills/roblox-publish-checklist/SKILL.md +128 -0
  27. package/skills/roblox-runtime/SKILL.md +753 -0
  28. package/skills/roblox-sharp-edges/SKILL.md +295 -0
  29. package/skills/roblox-sync/SKILL.md +126 -0
  30. package/skills/roblox-testing/SKILL.md +943 -0
  31. package/skills/roblox-tooling/SKILL.md +150 -0
  32. package/vendor/LICENSES/ProfileStore-LICENSE +201 -0
  33. package/vendor/LICENSES/RbxUtil-LICENSE +7 -0
  34. package/vendor/LICENSES/promise-LICENSE +21 -0
  35. package/vendor/LICENSES/t-LICENSE +21 -0
  36. package/vendor/LICENSES/testez-LICENSE +201 -0
  37. package/vendor/README.md +84 -0
  38. package/vendor/fusion/Animation/ExternalTime.luau +84 -0
  39. package/vendor/fusion/Animation/Spring.luau +322 -0
  40. package/vendor/fusion/Animation/Stopwatch.luau +128 -0
  41. package/vendor/fusion/Animation/Tween.luau +187 -0
  42. package/vendor/fusion/Animation/getTweenDuration.luau +27 -0
  43. package/vendor/fusion/Animation/getTweenRatio.luau +47 -0
  44. package/vendor/fusion/Animation/lerpType.luau +164 -0
  45. package/vendor/fusion/Animation/packType.luau +100 -0
  46. package/vendor/fusion/Animation/springCoefficients.luau +80 -0
  47. package/vendor/fusion/Animation/unpackType.luau +103 -0
  48. package/vendor/fusion/Colour/Oklab.luau +70 -0
  49. package/vendor/fusion/Colour/sRGB.luau +55 -0
  50. package/vendor/fusion/External.luau +168 -0
  51. package/vendor/fusion/ExternalDebug.luau +70 -0
  52. package/vendor/fusion/Graph/Observer.luau +114 -0
  53. package/vendor/fusion/Graph/castToGraph.luau +29 -0
  54. package/vendor/fusion/Graph/change.luau +81 -0
  55. package/vendor/fusion/Graph/depend.luau +33 -0
  56. package/vendor/fusion/Graph/evaluate.luau +56 -0
  57. package/vendor/fusion/Instances/Attribute.luau +58 -0
  58. package/vendor/fusion/Instances/AttributeChange.luau +47 -0
  59. package/vendor/fusion/Instances/AttributeOut.luau +63 -0
  60. package/vendor/fusion/Instances/Child.luau +21 -0
  61. package/vendor/fusion/Instances/Children.luau +148 -0
  62. package/vendor/fusion/Instances/Hydrate.luau +33 -0
  63. package/vendor/fusion/Instances/New.luau +53 -0
  64. package/vendor/fusion/Instances/OnChange.luau +50 -0
  65. package/vendor/fusion/Instances/OnEvent.luau +54 -0
  66. package/vendor/fusion/Instances/Out.luau +69 -0
  67. package/vendor/fusion/Instances/applyInstanceProps.luau +149 -0
  68. package/vendor/fusion/Instances/defaultProps.luau +194 -0
  69. package/vendor/fusion/LICENSE +21 -0
  70. package/vendor/fusion/Logging/formatError.luau +49 -0
  71. package/vendor/fusion/Logging/messages.luau +52 -0
  72. package/vendor/fusion/Logging/parseError.luau +25 -0
  73. package/vendor/fusion/Memory/checkLifetime.luau +134 -0
  74. package/vendor/fusion/Memory/deriveScope.luau +24 -0
  75. package/vendor/fusion/Memory/deriveScopeImpl.luau +45 -0
  76. package/vendor/fusion/Memory/doCleanup.luau +79 -0
  77. package/vendor/fusion/Memory/innerScope.luau +34 -0
  78. package/vendor/fusion/Memory/legacyCleanup.luau +18 -0
  79. package/vendor/fusion/Memory/needsDestruction.luau +17 -0
  80. package/vendor/fusion/Memory/poisonScope.luau +34 -0
  81. package/vendor/fusion/Memory/scopePool.luau +55 -0
  82. package/vendor/fusion/Memory/scoped.luau +27 -0
  83. package/vendor/fusion/Memory/whichLivesLonger.luau +75 -0
  84. package/vendor/fusion/RobloxExternal.luau +98 -0
  85. package/vendor/fusion/State/Computed.luau +139 -0
  86. package/vendor/fusion/State/For/Disassembly.luau +211 -0
  87. package/vendor/fusion/State/For/ForTypes.luau +30 -0
  88. package/vendor/fusion/State/For/init.luau +110 -0
  89. package/vendor/fusion/State/ForKeys.luau +94 -0
  90. package/vendor/fusion/State/ForPairs.luau +97 -0
  91. package/vendor/fusion/State/ForValues.luau +94 -0
  92. package/vendor/fusion/State/Value.luau +88 -0
  93. package/vendor/fusion/State/castToState.luau +26 -0
  94. package/vendor/fusion/State/peek.luau +31 -0
  95. package/vendor/fusion/State/updateAll.luau +1 -0
  96. package/vendor/fusion/Types.luau +314 -0
  97. package/vendor/fusion/Utility/Contextual.luau +91 -0
  98. package/vendor/fusion/Utility/Safe.luau +23 -0
  99. package/vendor/fusion/Utility/isSimilar.luau +29 -0
  100. package/vendor/fusion/Utility/merge.luau +35 -0
  101. package/vendor/fusion/Utility/nameOf.luau +35 -0
  102. package/vendor/fusion/Utility/never.luau +14 -0
  103. package/vendor/fusion/Utility/nicknames.luau +11 -0
  104. package/vendor/fusion/Utility/xtypeof.luau +27 -0
  105. package/vendor/fusion/init.luau +82 -0
  106. package/vendor/profilestore/init.luau +2243 -0
  107. package/vendor/promise/init.luau +1982 -0
  108. package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -0
  109. package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -0
  110. package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -0
  111. package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -0
  112. package/vendor/rbxutil/buffer-util/Types.luau +60 -0
  113. package/vendor/rbxutil/buffer-util/index.d.ts +153 -0
  114. package/vendor/rbxutil/buffer-util/init.luau +41 -0
  115. package/vendor/rbxutil/buffer-util/package.json +16 -0
  116. package/vendor/rbxutil/buffer-util/wally.toml +9 -0
  117. package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -0
  118. package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -0
  119. package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -0
  120. package/vendor/rbxutil/comm/Client/init.luau +135 -0
  121. package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -0
  122. package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -0
  123. package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -0
  124. package/vendor/rbxutil/comm/Server/init.luau +140 -0
  125. package/vendor/rbxutil/comm/Types.luau +18 -0
  126. package/vendor/rbxutil/comm/Util.luau +27 -0
  127. package/vendor/rbxutil/comm/init.luau +35 -0
  128. package/vendor/rbxutil/comm/wally.toml +13 -0
  129. package/vendor/rbxutil/component/init.luau +759 -0
  130. package/vendor/rbxutil/component/init.test.luau +311 -0
  131. package/vendor/rbxutil/component/wally.toml +14 -0
  132. package/vendor/rbxutil/concur/init.luau +542 -0
  133. package/vendor/rbxutil/concur/init.test.luau +364 -0
  134. package/vendor/rbxutil/concur/wally.toml +8 -0
  135. package/vendor/rbxutil/enum-list/init.luau +101 -0
  136. package/vendor/rbxutil/enum-list/init.test.luau +91 -0
  137. package/vendor/rbxutil/enum-list/wally.toml +8 -0
  138. package/vendor/rbxutil/find/index.d.ts +20 -0
  139. package/vendor/rbxutil/find/init.luau +44 -0
  140. package/vendor/rbxutil/find/package.json +17 -0
  141. package/vendor/rbxutil/find/wally.toml +8 -0
  142. package/vendor/rbxutil/input/Gamepad.luau +559 -0
  143. package/vendor/rbxutil/input/Keyboard.luau +124 -0
  144. package/vendor/rbxutil/input/Mouse.luau +278 -0
  145. package/vendor/rbxutil/input/PreferredInput.luau +91 -0
  146. package/vendor/rbxutil/input/Touch.luau +120 -0
  147. package/vendor/rbxutil/input/init.luau +33 -0
  148. package/vendor/rbxutil/input/wally.toml +12 -0
  149. package/vendor/rbxutil/loader/index.d.ts +15 -0
  150. package/vendor/rbxutil/loader/init.luau +137 -0
  151. package/vendor/rbxutil/loader/wally.toml +8 -0
  152. package/vendor/rbxutil/log/index.d.ts +38 -0
  153. package/vendor/rbxutil/log/init.luau +746 -0
  154. package/vendor/rbxutil/log/wally.toml +8 -0
  155. package/vendor/rbxutil/net/init.luau +190 -0
  156. package/vendor/rbxutil/net/wally.toml +8 -0
  157. package/vendor/rbxutil/option/index.d.ts +44 -0
  158. package/vendor/rbxutil/option/init.luau +489 -0
  159. package/vendor/rbxutil/option/init.test.luau +342 -0
  160. package/vendor/rbxutil/option/wally.toml +8 -0
  161. package/vendor/rbxutil/pid/index.d.ts +53 -0
  162. package/vendor/rbxutil/pid/init.luau +195 -0
  163. package/vendor/rbxutil/pid/package.json +16 -0
  164. package/vendor/rbxutil/pid/wally.toml +9 -0
  165. package/vendor/rbxutil/quaternion/index.d.ts +117 -0
  166. package/vendor/rbxutil/quaternion/init.luau +570 -0
  167. package/vendor/rbxutil/quaternion/package.json +16 -0
  168. package/vendor/rbxutil/quaternion/wally.toml +9 -0
  169. package/vendor/rbxutil/query/index.d.ts +43 -0
  170. package/vendor/rbxutil/query/init.luau +117 -0
  171. package/vendor/rbxutil/query/package.json +18 -0
  172. package/vendor/rbxutil/query/wally.toml +9 -0
  173. package/vendor/rbxutil/sequent/index.d.ts +28 -0
  174. package/vendor/rbxutil/sequent/init.luau +340 -0
  175. package/vendor/rbxutil/sequent/package.json +16 -0
  176. package/vendor/rbxutil/sequent/wally.toml +9 -0
  177. package/vendor/rbxutil/ser/init.luau +175 -0
  178. package/vendor/rbxutil/ser/init.test.luau +50 -0
  179. package/vendor/rbxutil/ser/wally.toml +11 -0
  180. package/vendor/rbxutil/shake/index.d.ts +36 -0
  181. package/vendor/rbxutil/shake/init.luau +532 -0
  182. package/vendor/rbxutil/shake/init.test.luau +267 -0
  183. package/vendor/rbxutil/shake/package.json +16 -0
  184. package/vendor/rbxutil/shake/wally.toml +9 -0
  185. package/vendor/rbxutil/signal/index.d.ts +100 -0
  186. package/vendor/rbxutil/signal/init.luau +432 -0
  187. package/vendor/rbxutil/signal/init.test.luau +190 -0
  188. package/vendor/rbxutil/signal/package.json +17 -0
  189. package/vendor/rbxutil/signal/wally.toml +9 -0
  190. package/vendor/rbxutil/silo/TableWatcher.luau +65 -0
  191. package/vendor/rbxutil/silo/Util.luau +55 -0
  192. package/vendor/rbxutil/silo/init.luau +338 -0
  193. package/vendor/rbxutil/silo/init.test.luau +215 -0
  194. package/vendor/rbxutil/silo/wally.toml +8 -0
  195. package/vendor/rbxutil/spring/index.d.ts +40 -0
  196. package/vendor/rbxutil/spring/init.luau +97 -0
  197. package/vendor/rbxutil/spring/package.json +17 -0
  198. package/vendor/rbxutil/spring/wally.toml +8 -0
  199. package/vendor/rbxutil/stream/index.d.ts +88 -0
  200. package/vendor/rbxutil/stream/init.luau +597 -0
  201. package/vendor/rbxutil/stream/package.json +18 -0
  202. package/vendor/rbxutil/stream/wally.toml +9 -0
  203. package/vendor/rbxutil/streamable/Streamable.luau +202 -0
  204. package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -0
  205. package/vendor/rbxutil/streamable/init.luau +8 -0
  206. package/vendor/rbxutil/streamable/wally.toml +12 -0
  207. package/vendor/rbxutil/symbol/init.luau +56 -0
  208. package/vendor/rbxutil/symbol/init.test.luau +37 -0
  209. package/vendor/rbxutil/symbol/wally.toml +8 -0
  210. package/vendor/rbxutil/table-util/init.luau +938 -0
  211. package/vendor/rbxutil/table-util/init.test.luau +439 -0
  212. package/vendor/rbxutil/table-util/wally.toml +8 -0
  213. package/vendor/rbxutil/task-queue/index.d.ts +27 -0
  214. package/vendor/rbxutil/task-queue/init.luau +97 -0
  215. package/vendor/rbxutil/task-queue/wally.toml +8 -0
  216. package/vendor/rbxutil/timer/index.d.ts +81 -0
  217. package/vendor/rbxutil/timer/init.luau +249 -0
  218. package/vendor/rbxutil/timer/init.test.luau +73 -0
  219. package/vendor/rbxutil/timer/wally.toml +11 -0
  220. package/vendor/rbxutil/tree/index.d.ts +15 -0
  221. package/vendor/rbxutil/tree/init.luau +137 -0
  222. package/vendor/rbxutil/tree/wally.toml +8 -0
  223. package/vendor/rbxutil/trove/index.d.ts +46 -0
  224. package/vendor/rbxutil/trove/init.luau +787 -0
  225. package/vendor/rbxutil/trove/init.test.luau +203 -0
  226. package/vendor/rbxutil/trove/wally.toml +8 -0
  227. package/vendor/rbxutil/typed-remote/init.luau +196 -0
  228. package/vendor/rbxutil/typed-remote/wally.toml +8 -0
  229. package/vendor/rbxutil/wait-for/index.d.ts +17 -0
  230. package/vendor/rbxutil/wait-for/init.luau +257 -0
  231. package/vendor/rbxutil/wait-for/init.test.luau +182 -0
  232. package/vendor/rbxutil/wait-for/wally.toml +11 -0
  233. package/vendor/t/t.lua +1350 -0
  234. package/vendor/testez/Context.lua +26 -0
  235. package/vendor/testez/Expectation.lua +311 -0
  236. package/vendor/testez/ExpectationContext.lua +38 -0
  237. package/vendor/testez/LifecycleHooks.lua +89 -0
  238. package/vendor/testez/Reporters/TeamCityReporter.lua +102 -0
  239. package/vendor/testez/Reporters/TextReporter.lua +106 -0
  240. package/vendor/testez/Reporters/TextReporterQuiet.lua +97 -0
  241. package/vendor/testez/TestBootstrap.lua +147 -0
  242. package/vendor/testez/TestEnum.lua +28 -0
  243. package/vendor/testez/TestPlan.lua +304 -0
  244. package/vendor/testez/TestPlanner.lua +40 -0
  245. package/vendor/testez/TestResults.lua +112 -0
  246. package/vendor/testez/TestRunner.lua +188 -0
  247. package/vendor/testez/TestSession.lua +243 -0
  248. 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