roblox-opencode 1.0.0 → 1.0.2
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 +112 -122
- package/commands/setup-game.md +108 -108
- package/commands/sync-check.md +53 -53
- package/core/roblox-core.md +93 -93
- package/dist/server.js +189 -167
- package/package.json +35 -35
- package/skills/roblox-analytics/SKILL.md +277 -277
- package/skills/roblox-analytics/references/event-batcher.luau +75 -75
- package/skills/roblox-animation-vfx/SKILL.md +1325 -1325
- package/skills/roblox-architecture/SKILL.md +877 -863
- package/skills/roblox-architecture/references/combat-systems.md +1381 -1381
- package/skills/roblox-code-review/SKILL.md +686 -686
- package/skills/roblox-data/SKILL.md +889 -889
- package/skills/roblox-data/references/inventory-systems.md +1729 -1729
- package/skills/roblox-debug/SKILL.md +98 -98
- package/skills/roblox-gui/SKILL.md +1103 -1103
- package/skills/roblox-gui-fusion/SKILL.md +150 -150
- package/skills/roblox-gui-fusion/references/inventory.luau +427 -427
- package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -579
- package/skills/roblox-gui-fusion/references/shop.luau +411 -411
- package/skills/roblox-luau-mastery/SKILL.md +1618 -1519
- package/skills/roblox-monetization/SKILL.md +1084 -1084
- package/skills/roblox-monetization/references/process-receipt.luau +131 -131
- package/skills/roblox-networking/SKILL.md +669 -669
- package/skills/roblox-networking/references/remote-validator.luau +193 -193
- package/skills/roblox-publish-checklist/SKILL.md +127 -127
- package/skills/roblox-runtime/SKILL.md +753 -753
- package/skills/roblox-sharp-edges/SKILL.md +294 -294
- package/skills/roblox-sync/SKILL.md +126 -126
- package/skills/roblox-testing/SKILL.md +943 -943
- package/skills/roblox-tooling/SKILL.md +149 -149
- package/vendor/LICENSES/ProfileStore-LICENSE +201 -201
- package/vendor/LICENSES/RbxUtil-LICENSE +7 -7
- package/vendor/LICENSES/promise-LICENSE +20 -20
- package/vendor/LICENSES/t-LICENSE +21 -21
- package/vendor/LICENSES/testez-LICENSE +200 -200
- package/vendor/README.md +83 -83
- package/vendor/fusion/Animation/ExternalTime.luau +83 -83
- package/vendor/fusion/Animation/Spring.luau +321 -321
- package/vendor/fusion/Animation/Stopwatch.luau +127 -127
- package/vendor/fusion/Animation/Tween.luau +187 -187
- package/vendor/fusion/Animation/getTweenDuration.luau +27 -27
- package/vendor/fusion/Animation/getTweenRatio.luau +47 -47
- package/vendor/fusion/Animation/lerpType.luau +163 -163
- package/vendor/fusion/Animation/packType.luau +99 -99
- package/vendor/fusion/Animation/springCoefficients.luau +80 -80
- package/vendor/fusion/Animation/unpackType.luau +102 -102
- package/vendor/fusion/Colour/Oklab.luau +70 -70
- package/vendor/fusion/Colour/sRGB.luau +54 -54
- package/vendor/fusion/External.luau +167 -167
- package/vendor/fusion/ExternalDebug.luau +69 -69
- package/vendor/fusion/Graph/Observer.luau +113 -113
- package/vendor/fusion/Graph/castToGraph.luau +28 -28
- package/vendor/fusion/Graph/change.luau +80 -80
- package/vendor/fusion/Graph/depend.luau +32 -32
- package/vendor/fusion/Graph/evaluate.luau +55 -55
- package/vendor/fusion/Instances/Attribute.luau +57 -57
- package/vendor/fusion/Instances/AttributeChange.luau +46 -46
- package/vendor/fusion/Instances/AttributeOut.luau +63 -63
- package/vendor/fusion/Instances/Child.luau +21 -21
- package/vendor/fusion/Instances/Children.luau +147 -147
- package/vendor/fusion/Instances/Hydrate.luau +32 -32
- package/vendor/fusion/Instances/New.luau +52 -52
- package/vendor/fusion/Instances/OnChange.luau +49 -49
- package/vendor/fusion/Instances/OnEvent.luau +53 -53
- package/vendor/fusion/Instances/Out.luau +69 -69
- package/vendor/fusion/Instances/applyInstanceProps.luau +148 -148
- package/vendor/fusion/Instances/defaultProps.luau +194 -194
- package/vendor/fusion/LICENSE +21 -21
- package/vendor/fusion/Logging/formatError.luau +48 -48
- package/vendor/fusion/Logging/messages.luau +51 -51
- package/vendor/fusion/Logging/parseError.luau +24 -24
- package/vendor/fusion/Memory/checkLifetime.luau +133 -133
- package/vendor/fusion/Memory/deriveScope.luau +23 -23
- package/vendor/fusion/Memory/deriveScopeImpl.luau +44 -44
- package/vendor/fusion/Memory/doCleanup.luau +78 -78
- package/vendor/fusion/Memory/innerScope.luau +33 -33
- package/vendor/fusion/Memory/legacyCleanup.luau +17 -17
- package/vendor/fusion/Memory/needsDestruction.luau +16 -16
- package/vendor/fusion/Memory/poisonScope.luau +33 -33
- package/vendor/fusion/Memory/scopePool.luau +54 -54
- package/vendor/fusion/Memory/scoped.luau +26 -26
- package/vendor/fusion/Memory/whichLivesLonger.luau +74 -74
- package/vendor/fusion/RobloxExternal.luau +97 -97
- package/vendor/fusion/State/Computed.luau +138 -138
- package/vendor/fusion/State/For/Disassembly.luau +210 -210
- package/vendor/fusion/State/For/ForTypes.luau +30 -30
- package/vendor/fusion/State/For/init.luau +109 -109
- package/vendor/fusion/State/ForKeys.luau +93 -93
- package/vendor/fusion/State/ForPairs.luau +96 -96
- package/vendor/fusion/State/ForValues.luau +93 -93
- package/vendor/fusion/State/Value.luau +87 -87
- package/vendor/fusion/State/castToState.luau +25 -25
- package/vendor/fusion/State/peek.luau +30 -30
- package/vendor/fusion/Types.luau +314 -314
- package/vendor/fusion/Utility/Contextual.luau +90 -90
- package/vendor/fusion/Utility/Safe.luau +22 -22
- package/vendor/fusion/Utility/isSimilar.luau +29 -29
- package/vendor/fusion/Utility/merge.luau +35 -35
- package/vendor/fusion/Utility/nameOf.luau +34 -34
- package/vendor/fusion/Utility/never.luau +13 -13
- package/vendor/fusion/Utility/nicknames.luau +10 -10
- package/vendor/fusion/Utility/xtypeof.luau +26 -26
- package/vendor/fusion/init.luau +82 -82
- package/vendor/profilestore/init.luau +2242 -2242
- package/vendor/promise/init.luau +1982 -1982
- package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -25
- package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -228
- package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -269
- package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -223
- package/vendor/rbxutil/buffer-util/Types.luau +60 -60
- package/vendor/rbxutil/buffer-util/index.d.ts +153 -153
- package/vendor/rbxutil/buffer-util/init.luau +41 -41
- package/vendor/rbxutil/buffer-util/package.json +16 -16
- package/vendor/rbxutil/buffer-util/wally.toml +9 -9
- package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -232
- package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -156
- package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -109
- package/vendor/rbxutil/comm/Client/init.luau +135 -135
- package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -295
- package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -211
- package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -211
- package/vendor/rbxutil/comm/Server/init.luau +140 -140
- package/vendor/rbxutil/comm/Types.luau +18 -18
- package/vendor/rbxutil/comm/Util.luau +27 -27
- package/vendor/rbxutil/comm/init.luau +35 -35
- package/vendor/rbxutil/comm/wally.toml +13 -13
- package/vendor/rbxutil/component/init.luau +759 -759
- package/vendor/rbxutil/component/init.test.luau +311 -311
- package/vendor/rbxutil/component/wally.toml +14 -14
- package/vendor/rbxutil/concur/init.luau +542 -542
- package/vendor/rbxutil/concur/init.test.luau +364 -364
- package/vendor/rbxutil/concur/wally.toml +8 -8
- package/vendor/rbxutil/enum-list/init.luau +101 -101
- package/vendor/rbxutil/enum-list/init.test.luau +91 -91
- package/vendor/rbxutil/enum-list/wally.toml +8 -8
- package/vendor/rbxutil/find/index.d.ts +20 -20
- package/vendor/rbxutil/find/init.luau +44 -44
- package/vendor/rbxutil/find/package.json +17 -17
- package/vendor/rbxutil/find/wally.toml +8 -8
- package/vendor/rbxutil/input/Gamepad.luau +559 -559
- package/vendor/rbxutil/input/Keyboard.luau +124 -124
- package/vendor/rbxutil/input/Mouse.luau +278 -278
- package/vendor/rbxutil/input/PreferredInput.luau +91 -91
- package/vendor/rbxutil/input/Touch.luau +120 -120
- package/vendor/rbxutil/input/init.luau +33 -33
- package/vendor/rbxutil/input/wally.toml +12 -12
- package/vendor/rbxutil/loader/index.d.ts +15 -15
- package/vendor/rbxutil/loader/init.luau +137 -137
- package/vendor/rbxutil/loader/wally.toml +8 -8
- package/vendor/rbxutil/log/index.d.ts +38 -38
- package/vendor/rbxutil/log/init.luau +746 -746
- package/vendor/rbxutil/log/wally.toml +8 -8
- package/vendor/rbxutil/net/init.luau +190 -190
- package/vendor/rbxutil/net/wally.toml +8 -8
- package/vendor/rbxutil/option/index.d.ts +44 -44
- package/vendor/rbxutil/option/init.luau +489 -489
- package/vendor/rbxutil/option/init.test.luau +342 -342
- package/vendor/rbxutil/option/wally.toml +8 -8
- package/vendor/rbxutil/pid/index.d.ts +53 -53
- package/vendor/rbxutil/pid/init.luau +195 -195
- package/vendor/rbxutil/pid/package.json +16 -16
- package/vendor/rbxutil/pid/wally.toml +9 -9
- package/vendor/rbxutil/quaternion/index.d.ts +117 -117
- package/vendor/rbxutil/quaternion/init.luau +570 -570
- package/vendor/rbxutil/quaternion/package.json +16 -16
- package/vendor/rbxutil/quaternion/wally.toml +9 -9
- package/vendor/rbxutil/query/index.d.ts +43 -43
- package/vendor/rbxutil/query/init.luau +117 -117
- package/vendor/rbxutil/query/package.json +18 -18
- package/vendor/rbxutil/query/wally.toml +9 -9
- package/vendor/rbxutil/sequent/index.d.ts +28 -28
- package/vendor/rbxutil/sequent/init.luau +340 -340
- package/vendor/rbxutil/sequent/package.json +16 -16
- package/vendor/rbxutil/sequent/wally.toml +9 -9
- package/vendor/rbxutil/ser/init.luau +175 -175
- package/vendor/rbxutil/ser/init.test.luau +50 -50
- package/vendor/rbxutil/ser/wally.toml +11 -11
- package/vendor/rbxutil/shake/index.d.ts +36 -36
- package/vendor/rbxutil/shake/init.luau +532 -532
- package/vendor/rbxutil/shake/init.test.luau +267 -267
- package/vendor/rbxutil/shake/package.json +16 -16
- package/vendor/rbxutil/shake/wally.toml +9 -9
- package/vendor/rbxutil/signal/index.d.ts +100 -100
- package/vendor/rbxutil/signal/init.luau +432 -432
- package/vendor/rbxutil/signal/init.test.luau +190 -190
- package/vendor/rbxutil/signal/package.json +17 -17
- package/vendor/rbxutil/signal/wally.toml +9 -9
- package/vendor/rbxutil/silo/TableWatcher.luau +65 -65
- package/vendor/rbxutil/silo/Util.luau +55 -55
- package/vendor/rbxutil/silo/init.luau +338 -338
- package/vendor/rbxutil/silo/init.test.luau +215 -215
- package/vendor/rbxutil/silo/wally.toml +8 -8
- package/vendor/rbxutil/spring/index.d.ts +40 -40
- package/vendor/rbxutil/spring/init.luau +97 -97
- package/vendor/rbxutil/spring/package.json +17 -17
- package/vendor/rbxutil/spring/wally.toml +8 -8
- package/vendor/rbxutil/stream/index.d.ts +88 -88
- package/vendor/rbxutil/stream/init.luau +597 -597
- package/vendor/rbxutil/stream/package.json +18 -18
- package/vendor/rbxutil/stream/wally.toml +9 -9
- package/vendor/rbxutil/streamable/Streamable.luau +202 -202
- package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -80
- package/vendor/rbxutil/streamable/init.luau +8 -8
- package/vendor/rbxutil/streamable/wally.toml +12 -12
- package/vendor/rbxutil/symbol/init.luau +56 -56
- package/vendor/rbxutil/symbol/init.test.luau +37 -37
- package/vendor/rbxutil/symbol/wally.toml +8 -8
- package/vendor/rbxutil/table-util/init.luau +938 -938
- package/vendor/rbxutil/table-util/init.test.luau +439 -439
- package/vendor/rbxutil/task-queue/index.d.ts +27 -27
- package/vendor/rbxutil/task-queue/init.luau +97 -97
- package/vendor/rbxutil/task-queue/wally.toml +8 -8
- package/vendor/rbxutil/timer/index.d.ts +81 -81
- package/vendor/rbxutil/timer/init.luau +249 -249
- package/vendor/rbxutil/timer/init.test.luau +73 -73
- package/vendor/rbxutil/timer/wally.toml +11 -11
- package/vendor/rbxutil/tree/index.d.ts +15 -15
- package/vendor/rbxutil/tree/init.luau +137 -137
- package/vendor/rbxutil/tree/wally.toml +8 -8
- package/vendor/rbxutil/trove/index.d.ts +46 -46
- package/vendor/rbxutil/trove/init.luau +787 -787
- package/vendor/rbxutil/trove/init.test.luau +203 -203
- package/vendor/rbxutil/trove/wally.toml +8 -8
- package/vendor/rbxutil/typed-remote/init.luau +196 -196
- package/vendor/rbxutil/typed-remote/wally.toml +8 -8
- package/vendor/rbxutil/wait-for/index.d.ts +17 -17
- package/vendor/rbxutil/wait-for/init.luau +257 -257
- package/vendor/rbxutil/wait-for/init.test.luau +182 -182
- package/vendor/rbxutil/wait-for/wally.toml +11 -11
- package/vendor/t/t.lua +1350 -1350
- package/vendor/testez/Context.lua +26 -26
- package/vendor/testez/Expectation.lua +311 -311
- package/vendor/testez/ExpectationContext.lua +38 -38
- package/vendor/testez/LifecycleHooks.lua +89 -89
- package/vendor/testez/Reporters/TeamCityReporter.lua +101 -101
- package/vendor/testez/Reporters/TextReporter.lua +105 -105
- package/vendor/testez/Reporters/TextReporterQuiet.lua +96 -96
- package/vendor/testez/TestBootstrap.lua +146 -146
- package/vendor/testez/TestEnum.lua +27 -27
- package/vendor/testez/TestPlan.lua +304 -304
- package/vendor/testez/TestPlanner.lua +39 -39
- package/vendor/testez/TestResults.lua +111 -111
- package/vendor/testez/TestRunner.lua +188 -188
- package/vendor/testez/TestSession.lua +243 -243
- package/vendor/testez/init.lua +39 -39
|
@@ -1,295 +1,295 @@
|
|
|
1
|
-
-- RemoteProperty
|
|
2
|
-
-- Stephen Leitnick
|
|
3
|
-
-- December 20, 2021
|
|
4
|
-
|
|
5
|
-
local Players = game:GetService("Players")
|
|
6
|
-
|
|
7
|
-
local RemoteSignal = require(script.Parent.RemoteSignal)
|
|
8
|
-
local Types = require(script.Parent.Parent.Types)
|
|
9
|
-
local Util = require(script.Parent.Parent.Util)
|
|
10
|
-
|
|
11
|
-
local None = Util.None
|
|
12
|
-
|
|
13
|
-
--[=[
|
|
14
|
-
@class RemoteProperty
|
|
15
|
-
@server
|
|
16
|
-
Created via `ServerComm:CreateProperty()`.
|
|
17
|
-
|
|
18
|
-
Values set can be anything that can pass through a
|
|
19
|
-
[RemoteEvent](https://developer.roblox.com/en-us/articles/Remote-Functions-and-Events#parameter-limitations).
|
|
20
|
-
|
|
21
|
-
Here is a cheat-sheet for the below methods:
|
|
22
|
-
- Setting data
|
|
23
|
-
- `Set`: Set "top" value for all current and future players. Overrides any custom-set data per player.
|
|
24
|
-
- `SetTop`: Set the "top" value for all players, but does _not_ override any custom-set data per player.
|
|
25
|
-
- `SetFor`: Set custom data for the given player. Overrides the "top" value. (_Can be nil_)
|
|
26
|
-
- `SetForList`: Same as `SetFor`, but accepts a list of players.
|
|
27
|
-
- `SetFilter`: Accepts a predicate function which checks for which players to set.
|
|
28
|
-
- Clearing data
|
|
29
|
-
- `ClearFor`: Clears the custom data set for a given player. Player will start using the "top" level value instead.
|
|
30
|
-
- `ClearForList`: Same as `ClearFor`, but accepts a list of players.
|
|
31
|
-
- `ClearFilter`: Accepts a predicate function which checks for which players to clear.
|
|
32
|
-
- Getting data
|
|
33
|
-
- `Get`: Retrieves the "top" value
|
|
34
|
-
- `GetFor`: Gets the current value for the given player. If cleared, returns the top value.
|
|
35
|
-
|
|
36
|
-
:::caution Network
|
|
37
|
-
Calling any of the data setter methods (e.g. `Set()`) will
|
|
38
|
-
fire the underlying RemoteEvent to replicate data to the
|
|
39
|
-
clients. Therefore, setting data should only occur when it
|
|
40
|
-
is necessary to change the data that the clients receive.
|
|
41
|
-
:::
|
|
42
|
-
|
|
43
|
-
:::caution Tables
|
|
44
|
-
Tables _can_ be used with RemoteProperties. However, the
|
|
45
|
-
RemoteProperty object will _not_ watch for changes within
|
|
46
|
-
the table. Therefore, anytime changes are made to the table,
|
|
47
|
-
the data must be set again using one of the setter methods.
|
|
48
|
-
:::
|
|
49
|
-
]=]
|
|
50
|
-
local RemoteProperty = {}
|
|
51
|
-
RemoteProperty.__index = RemoteProperty
|
|
52
|
-
|
|
53
|
-
function RemoteProperty.new(
|
|
54
|
-
parent: Instance,
|
|
55
|
-
name: string,
|
|
56
|
-
initialValue: any,
|
|
57
|
-
inboundMiddleware: Types.ServerMiddleware?,
|
|
58
|
-
outboundMiddleware: Types.ServerMiddleware?
|
|
59
|
-
)
|
|
60
|
-
local self = setmetatable({}, RemoteProperty)
|
|
61
|
-
self._rs = RemoteSignal.new(parent, name, false, inboundMiddleware, outboundMiddleware)
|
|
62
|
-
self._value = initialValue
|
|
63
|
-
self._perPlayer = {}
|
|
64
|
-
self._playerRemoving = Players.PlayerRemoving:Connect(function(player)
|
|
65
|
-
self._perPlayer[player] = nil
|
|
66
|
-
end)
|
|
67
|
-
self._rs:Connect(function(player)
|
|
68
|
-
local playerValue = self._perPlayer[player]
|
|
69
|
-
local value = if playerValue == nil then self._value elseif playerValue == None then nil else playerValue
|
|
70
|
-
self._rs:Fire(player, value)
|
|
71
|
-
end)
|
|
72
|
-
return self
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
--[=[
|
|
76
|
-
Sets the top-level value of all clients to the same value.
|
|
77
|
-
|
|
78
|
-
:::note Override Per-Player Data
|
|
79
|
-
This will override any per-player data that was set using
|
|
80
|
-
`SetFor` or `SetFilter`. To avoid overriding this data,
|
|
81
|
-
`SetTop` can be used instead.
|
|
82
|
-
:::
|
|
83
|
-
|
|
84
|
-
```lua
|
|
85
|
-
-- Examples
|
|
86
|
-
remoteProperty:Set(10)
|
|
87
|
-
remoteProperty:Set({SomeData = 32})
|
|
88
|
-
remoteProperty:Set("HelloWorld")
|
|
89
|
-
```
|
|
90
|
-
]=]
|
|
91
|
-
function RemoteProperty:Set(value: any)
|
|
92
|
-
self._value = value
|
|
93
|
-
table.clear(self._perPlayer)
|
|
94
|
-
self._rs:FireAll(value)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
--[=[
|
|
98
|
-
Set the top-level value of the property, but does not override
|
|
99
|
-
any per-player data (e.g. set with `SetFor` or `SetFilter`).
|
|
100
|
-
Any player without custom-set data will receive this new data.
|
|
101
|
-
|
|
102
|
-
This is useful if certain players have specific values that
|
|
103
|
-
should not be changed, but all other players should receive
|
|
104
|
-
the same new value.
|
|
105
|
-
|
|
106
|
-
```lua
|
|
107
|
-
-- Using just 'Set' overrides per-player data:
|
|
108
|
-
remoteProperty:SetFor(somePlayer, "CustomData")
|
|
109
|
-
remoteProperty:Set("Data")
|
|
110
|
-
print(remoteProperty:GetFor(somePlayer)) --> "Data"
|
|
111
|
-
|
|
112
|
-
-- Using 'SetTop' does not override:
|
|
113
|
-
remoteProperty:SetFor(somePlayer, "CustomData")
|
|
114
|
-
remoteProperty:SetTop("Data")
|
|
115
|
-
print(remoteProperty:GetFor(somePlayer)) --> "CustomData"
|
|
116
|
-
```
|
|
117
|
-
]=]
|
|
118
|
-
function RemoteProperty:SetTop(value: any)
|
|
119
|
-
self._value = value
|
|
120
|
-
for _, player in ipairs(Players:GetPlayers()) do
|
|
121
|
-
if self._perPlayer[player] == nil then
|
|
122
|
-
self._rs:Fire(player, value)
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
--[=[
|
|
128
|
-
@param value any -- Value to set for the clients (and to the predicate)
|
|
129
|
-
Sets the value for specific clients that pass the `predicate`
|
|
130
|
-
function test. This can be used to finely set the values
|
|
131
|
-
based on more control logic (e.g. setting certain values
|
|
132
|
-
per team).
|
|
133
|
-
|
|
134
|
-
```lua
|
|
135
|
-
-- Set the value of "NewValue" to players with a name longer than 10 characters:
|
|
136
|
-
remoteProperty:SetFilter(function(player)
|
|
137
|
-
return #player.Name > 10
|
|
138
|
-
end, "NewValue")
|
|
139
|
-
```
|
|
140
|
-
]=]
|
|
141
|
-
function RemoteProperty:SetFilter(predicate: (Player, any) -> boolean, value: any)
|
|
142
|
-
for _, player in ipairs(Players:GetPlayers()) do
|
|
143
|
-
if predicate(player, value) then
|
|
144
|
-
self:SetFor(player, value)
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
--[=[
|
|
150
|
-
Set the value of the property for a specific player. This
|
|
151
|
-
will override the value used by `Set` (and the initial value
|
|
152
|
-
set for the property when created).
|
|
153
|
-
|
|
154
|
-
This value _can_ be `nil`. In order to reset the value for a
|
|
155
|
-
given player and let the player use the top-level value held
|
|
156
|
-
by this property, either use `Set` to set all players' data,
|
|
157
|
-
or use `ClearFor`.
|
|
158
|
-
|
|
159
|
-
```lua
|
|
160
|
-
remoteProperty:SetFor(somePlayer, "CustomData")
|
|
161
|
-
```
|
|
162
|
-
]=]
|
|
163
|
-
function RemoteProperty:SetFor(player: Player, value: any)
|
|
164
|
-
if player.Parent then
|
|
165
|
-
self._perPlayer[player] = if value == nil then None else value
|
|
166
|
-
end
|
|
167
|
-
self._rs:Fire(player, value)
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
--[=[
|
|
171
|
-
Set the value of the property for specific players. This just
|
|
172
|
-
loops through the players given and calls `SetFor`.
|
|
173
|
-
|
|
174
|
-
```lua
|
|
175
|
-
local players = {player1, player2, player3}
|
|
176
|
-
remoteProperty:SetForList(players, "CustomData")
|
|
177
|
-
```
|
|
178
|
-
]=]
|
|
179
|
-
function RemoteProperty:SetForList(players: { Player }, value: any)
|
|
180
|
-
for _, player in ipairs(players) do
|
|
181
|
-
self:SetFor(player, value)
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
--[=[
|
|
186
|
-
Clears the custom property value for the given player. When
|
|
187
|
-
this occurs, the player will reset to use the top-level
|
|
188
|
-
value held by this property (either the value set when the
|
|
189
|
-
property was created, or the last value set by `Set`).
|
|
190
|
-
|
|
191
|
-
```lua
|
|
192
|
-
remoteProperty:Set("DATA")
|
|
193
|
-
|
|
194
|
-
remoteProperty:SetFor(somePlayer, "CUSTOM_DATA")
|
|
195
|
-
print(remoteProperty:GetFor(somePlayer)) --> "CUSTOM_DATA"
|
|
196
|
-
|
|
197
|
-
-- DOES NOT CLEAR, JUST SETS CUSTOM DATA TO NIL:
|
|
198
|
-
remoteProperty:SetFor(somePlayer, nil)
|
|
199
|
-
print(remoteProperty:GetFor(somePlayer)) --> nil
|
|
200
|
-
|
|
201
|
-
-- CLEAR:
|
|
202
|
-
remoteProperty:ClearFor(somePlayer)
|
|
203
|
-
print(remoteProperty:GetFor(somePlayer)) --> "DATA"
|
|
204
|
-
```
|
|
205
|
-
]=]
|
|
206
|
-
function RemoteProperty:ClearFor(player: Player)
|
|
207
|
-
if self._perPlayer[player] == nil then
|
|
208
|
-
return
|
|
209
|
-
end
|
|
210
|
-
self._perPlayer[player] = nil
|
|
211
|
-
self._rs:Fire(player, self._value)
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
--[=[
|
|
215
|
-
Clears the custom value for the given players. This
|
|
216
|
-
just loops through the list of players and calls
|
|
217
|
-
the `ClearFor` method for each player.
|
|
218
|
-
]=]
|
|
219
|
-
function RemoteProperty:ClearForList(players: { Player })
|
|
220
|
-
for _, player in ipairs(players) do
|
|
221
|
-
self:ClearFor(player)
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
--[=[
|
|
226
|
-
The same as `SetFiler`, except clears the custom value
|
|
227
|
-
for any player that passes the predicate.
|
|
228
|
-
]=]
|
|
229
|
-
function RemoteProperty:ClearFilter(predicate: (Player) -> boolean)
|
|
230
|
-
for _, player in ipairs(Players:GetPlayers()) do
|
|
231
|
-
if predicate(player) then
|
|
232
|
-
self:ClearFor(player)
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
--[=[
|
|
238
|
-
Returns the top-level value held by the property. This will
|
|
239
|
-
either be the initial value set, or the last value set
|
|
240
|
-
with `Set()`.
|
|
241
|
-
|
|
242
|
-
```lua
|
|
243
|
-
remoteProperty:Set("Data")
|
|
244
|
-
print(remoteProperty:Get()) --> "Data"
|
|
245
|
-
```
|
|
246
|
-
]=]
|
|
247
|
-
function RemoteProperty:Get(): any
|
|
248
|
-
return self._value
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
--[=[
|
|
252
|
-
Returns the current value for the given player. This value
|
|
253
|
-
will depend on if `SetFor` or `SetFilter` has affected the
|
|
254
|
-
custom value for the player. If so, that custom value will
|
|
255
|
-
be returned. Otherwise, the top-level value will be used
|
|
256
|
-
(e.g. value from `Set`).
|
|
257
|
-
|
|
258
|
-
```lua
|
|
259
|
-
-- Set top level data:
|
|
260
|
-
remoteProperty:Set("Data")
|
|
261
|
-
print(remoteProperty:GetFor(somePlayer)) --> "Data"
|
|
262
|
-
|
|
263
|
-
-- Set custom data:
|
|
264
|
-
remoteProperty:SetFor(somePlayer, "CustomData")
|
|
265
|
-
print(remoteProperty:GetFor(somePlayer)) --> "CustomData"
|
|
266
|
-
|
|
267
|
-
-- Set top level again, overriding custom data:
|
|
268
|
-
remoteProperty:Set("NewData")
|
|
269
|
-
print(remoteProperty:GetFor(somePlayer)) --> "NewData"
|
|
270
|
-
|
|
271
|
-
-- Set custom data again, and set top level without overriding:
|
|
272
|
-
remoteProperty:SetFor(somePlayer, "CustomData")
|
|
273
|
-
remoteProperty:SetTop("Data")
|
|
274
|
-
print(remoteProperty:GetFor(somePlayer)) --> "CustomData"
|
|
275
|
-
|
|
276
|
-
-- Clear custom data to use top level data:
|
|
277
|
-
remoteProperty:ClearFor(somePlayer)
|
|
278
|
-
print(remoteProperty:GetFor(somePlayer)) --> "Data"
|
|
279
|
-
```
|
|
280
|
-
]=]
|
|
281
|
-
function RemoteProperty:GetFor(player: Player): any
|
|
282
|
-
local playerValue = self._perPlayer[player]
|
|
283
|
-
local value = if playerValue == nil then self._value elseif playerValue == None then nil else playerValue
|
|
284
|
-
return value
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
--[=[
|
|
288
|
-
Destroys the RemoteProperty object.
|
|
289
|
-
]=]
|
|
290
|
-
function RemoteProperty:Destroy()
|
|
291
|
-
self._rs:Destroy()
|
|
292
|
-
self._playerRemoving:Disconnect()
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
return RemoteProperty
|
|
1
|
+
-- RemoteProperty
|
|
2
|
+
-- Stephen Leitnick
|
|
3
|
+
-- December 20, 2021
|
|
4
|
+
|
|
5
|
+
local Players = game:GetService("Players")
|
|
6
|
+
|
|
7
|
+
local RemoteSignal = require(script.Parent.RemoteSignal)
|
|
8
|
+
local Types = require(script.Parent.Parent.Types)
|
|
9
|
+
local Util = require(script.Parent.Parent.Util)
|
|
10
|
+
|
|
11
|
+
local None = Util.None
|
|
12
|
+
|
|
13
|
+
--[=[
|
|
14
|
+
@class RemoteProperty
|
|
15
|
+
@server
|
|
16
|
+
Created via `ServerComm:CreateProperty()`.
|
|
17
|
+
|
|
18
|
+
Values set can be anything that can pass through a
|
|
19
|
+
[RemoteEvent](https://developer.roblox.com/en-us/articles/Remote-Functions-and-Events#parameter-limitations).
|
|
20
|
+
|
|
21
|
+
Here is a cheat-sheet for the below methods:
|
|
22
|
+
- Setting data
|
|
23
|
+
- `Set`: Set "top" value for all current and future players. Overrides any custom-set data per player.
|
|
24
|
+
- `SetTop`: Set the "top" value for all players, but does _not_ override any custom-set data per player.
|
|
25
|
+
- `SetFor`: Set custom data for the given player. Overrides the "top" value. (_Can be nil_)
|
|
26
|
+
- `SetForList`: Same as `SetFor`, but accepts a list of players.
|
|
27
|
+
- `SetFilter`: Accepts a predicate function which checks for which players to set.
|
|
28
|
+
- Clearing data
|
|
29
|
+
- `ClearFor`: Clears the custom data set for a given player. Player will start using the "top" level value instead.
|
|
30
|
+
- `ClearForList`: Same as `ClearFor`, but accepts a list of players.
|
|
31
|
+
- `ClearFilter`: Accepts a predicate function which checks for which players to clear.
|
|
32
|
+
- Getting data
|
|
33
|
+
- `Get`: Retrieves the "top" value
|
|
34
|
+
- `GetFor`: Gets the current value for the given player. If cleared, returns the top value.
|
|
35
|
+
|
|
36
|
+
:::caution Network
|
|
37
|
+
Calling any of the data setter methods (e.g. `Set()`) will
|
|
38
|
+
fire the underlying RemoteEvent to replicate data to the
|
|
39
|
+
clients. Therefore, setting data should only occur when it
|
|
40
|
+
is necessary to change the data that the clients receive.
|
|
41
|
+
:::
|
|
42
|
+
|
|
43
|
+
:::caution Tables
|
|
44
|
+
Tables _can_ be used with RemoteProperties. However, the
|
|
45
|
+
RemoteProperty object will _not_ watch for changes within
|
|
46
|
+
the table. Therefore, anytime changes are made to the table,
|
|
47
|
+
the data must be set again using one of the setter methods.
|
|
48
|
+
:::
|
|
49
|
+
]=]
|
|
50
|
+
local RemoteProperty = {}
|
|
51
|
+
RemoteProperty.__index = RemoteProperty
|
|
52
|
+
|
|
53
|
+
function RemoteProperty.new(
|
|
54
|
+
parent: Instance,
|
|
55
|
+
name: string,
|
|
56
|
+
initialValue: any,
|
|
57
|
+
inboundMiddleware: Types.ServerMiddleware?,
|
|
58
|
+
outboundMiddleware: Types.ServerMiddleware?
|
|
59
|
+
)
|
|
60
|
+
local self = setmetatable({}, RemoteProperty)
|
|
61
|
+
self._rs = RemoteSignal.new(parent, name, false, inboundMiddleware, outboundMiddleware)
|
|
62
|
+
self._value = initialValue
|
|
63
|
+
self._perPlayer = {}
|
|
64
|
+
self._playerRemoving = Players.PlayerRemoving:Connect(function(player)
|
|
65
|
+
self._perPlayer[player] = nil
|
|
66
|
+
end)
|
|
67
|
+
self._rs:Connect(function(player)
|
|
68
|
+
local playerValue = self._perPlayer[player]
|
|
69
|
+
local value = if playerValue == nil then self._value elseif playerValue == None then nil else playerValue
|
|
70
|
+
self._rs:Fire(player, value)
|
|
71
|
+
end)
|
|
72
|
+
return self
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
--[=[
|
|
76
|
+
Sets the top-level value of all clients to the same value.
|
|
77
|
+
|
|
78
|
+
:::note Override Per-Player Data
|
|
79
|
+
This will override any per-player data that was set using
|
|
80
|
+
`SetFor` or `SetFilter`. To avoid overriding this data,
|
|
81
|
+
`SetTop` can be used instead.
|
|
82
|
+
:::
|
|
83
|
+
|
|
84
|
+
```lua
|
|
85
|
+
-- Examples
|
|
86
|
+
remoteProperty:Set(10)
|
|
87
|
+
remoteProperty:Set({SomeData = 32})
|
|
88
|
+
remoteProperty:Set("HelloWorld")
|
|
89
|
+
```
|
|
90
|
+
]=]
|
|
91
|
+
function RemoteProperty:Set(value: any)
|
|
92
|
+
self._value = value
|
|
93
|
+
table.clear(self._perPlayer)
|
|
94
|
+
self._rs:FireAll(value)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
--[=[
|
|
98
|
+
Set the top-level value of the property, but does not override
|
|
99
|
+
any per-player data (e.g. set with `SetFor` or `SetFilter`).
|
|
100
|
+
Any player without custom-set data will receive this new data.
|
|
101
|
+
|
|
102
|
+
This is useful if certain players have specific values that
|
|
103
|
+
should not be changed, but all other players should receive
|
|
104
|
+
the same new value.
|
|
105
|
+
|
|
106
|
+
```lua
|
|
107
|
+
-- Using just 'Set' overrides per-player data:
|
|
108
|
+
remoteProperty:SetFor(somePlayer, "CustomData")
|
|
109
|
+
remoteProperty:Set("Data")
|
|
110
|
+
print(remoteProperty:GetFor(somePlayer)) --> "Data"
|
|
111
|
+
|
|
112
|
+
-- Using 'SetTop' does not override:
|
|
113
|
+
remoteProperty:SetFor(somePlayer, "CustomData")
|
|
114
|
+
remoteProperty:SetTop("Data")
|
|
115
|
+
print(remoteProperty:GetFor(somePlayer)) --> "CustomData"
|
|
116
|
+
```
|
|
117
|
+
]=]
|
|
118
|
+
function RemoteProperty:SetTop(value: any)
|
|
119
|
+
self._value = value
|
|
120
|
+
for _, player in ipairs(Players:GetPlayers()) do
|
|
121
|
+
if self._perPlayer[player] == nil then
|
|
122
|
+
self._rs:Fire(player, value)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
--[=[
|
|
128
|
+
@param value any -- Value to set for the clients (and to the predicate)
|
|
129
|
+
Sets the value for specific clients that pass the `predicate`
|
|
130
|
+
function test. This can be used to finely set the values
|
|
131
|
+
based on more control logic (e.g. setting certain values
|
|
132
|
+
per team).
|
|
133
|
+
|
|
134
|
+
```lua
|
|
135
|
+
-- Set the value of "NewValue" to players with a name longer than 10 characters:
|
|
136
|
+
remoteProperty:SetFilter(function(player)
|
|
137
|
+
return #player.Name > 10
|
|
138
|
+
end, "NewValue")
|
|
139
|
+
```
|
|
140
|
+
]=]
|
|
141
|
+
function RemoteProperty:SetFilter(predicate: (Player, any) -> boolean, value: any)
|
|
142
|
+
for _, player in ipairs(Players:GetPlayers()) do
|
|
143
|
+
if predicate(player, value) then
|
|
144
|
+
self:SetFor(player, value)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
--[=[
|
|
150
|
+
Set the value of the property for a specific player. This
|
|
151
|
+
will override the value used by `Set` (and the initial value
|
|
152
|
+
set for the property when created).
|
|
153
|
+
|
|
154
|
+
This value _can_ be `nil`. In order to reset the value for a
|
|
155
|
+
given player and let the player use the top-level value held
|
|
156
|
+
by this property, either use `Set` to set all players' data,
|
|
157
|
+
or use `ClearFor`.
|
|
158
|
+
|
|
159
|
+
```lua
|
|
160
|
+
remoteProperty:SetFor(somePlayer, "CustomData")
|
|
161
|
+
```
|
|
162
|
+
]=]
|
|
163
|
+
function RemoteProperty:SetFor(player: Player, value: any)
|
|
164
|
+
if player.Parent then
|
|
165
|
+
self._perPlayer[player] = if value == nil then None else value
|
|
166
|
+
end
|
|
167
|
+
self._rs:Fire(player, value)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
--[=[
|
|
171
|
+
Set the value of the property for specific players. This just
|
|
172
|
+
loops through the players given and calls `SetFor`.
|
|
173
|
+
|
|
174
|
+
```lua
|
|
175
|
+
local players = {player1, player2, player3}
|
|
176
|
+
remoteProperty:SetForList(players, "CustomData")
|
|
177
|
+
```
|
|
178
|
+
]=]
|
|
179
|
+
function RemoteProperty:SetForList(players: { Player }, value: any)
|
|
180
|
+
for _, player in ipairs(players) do
|
|
181
|
+
self:SetFor(player, value)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
--[=[
|
|
186
|
+
Clears the custom property value for the given player. When
|
|
187
|
+
this occurs, the player will reset to use the top-level
|
|
188
|
+
value held by this property (either the value set when the
|
|
189
|
+
property was created, or the last value set by `Set`).
|
|
190
|
+
|
|
191
|
+
```lua
|
|
192
|
+
remoteProperty:Set("DATA")
|
|
193
|
+
|
|
194
|
+
remoteProperty:SetFor(somePlayer, "CUSTOM_DATA")
|
|
195
|
+
print(remoteProperty:GetFor(somePlayer)) --> "CUSTOM_DATA"
|
|
196
|
+
|
|
197
|
+
-- DOES NOT CLEAR, JUST SETS CUSTOM DATA TO NIL:
|
|
198
|
+
remoteProperty:SetFor(somePlayer, nil)
|
|
199
|
+
print(remoteProperty:GetFor(somePlayer)) --> nil
|
|
200
|
+
|
|
201
|
+
-- CLEAR:
|
|
202
|
+
remoteProperty:ClearFor(somePlayer)
|
|
203
|
+
print(remoteProperty:GetFor(somePlayer)) --> "DATA"
|
|
204
|
+
```
|
|
205
|
+
]=]
|
|
206
|
+
function RemoteProperty:ClearFor(player: Player)
|
|
207
|
+
if self._perPlayer[player] == nil then
|
|
208
|
+
return
|
|
209
|
+
end
|
|
210
|
+
self._perPlayer[player] = nil
|
|
211
|
+
self._rs:Fire(player, self._value)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
--[=[
|
|
215
|
+
Clears the custom value for the given players. This
|
|
216
|
+
just loops through the list of players and calls
|
|
217
|
+
the `ClearFor` method for each player.
|
|
218
|
+
]=]
|
|
219
|
+
function RemoteProperty:ClearForList(players: { Player })
|
|
220
|
+
for _, player in ipairs(players) do
|
|
221
|
+
self:ClearFor(player)
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
--[=[
|
|
226
|
+
The same as `SetFiler`, except clears the custom value
|
|
227
|
+
for any player that passes the predicate.
|
|
228
|
+
]=]
|
|
229
|
+
function RemoteProperty:ClearFilter(predicate: (Player) -> boolean)
|
|
230
|
+
for _, player in ipairs(Players:GetPlayers()) do
|
|
231
|
+
if predicate(player) then
|
|
232
|
+
self:ClearFor(player)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
--[=[
|
|
238
|
+
Returns the top-level value held by the property. This will
|
|
239
|
+
either be the initial value set, or the last value set
|
|
240
|
+
with `Set()`.
|
|
241
|
+
|
|
242
|
+
```lua
|
|
243
|
+
remoteProperty:Set("Data")
|
|
244
|
+
print(remoteProperty:Get()) --> "Data"
|
|
245
|
+
```
|
|
246
|
+
]=]
|
|
247
|
+
function RemoteProperty:Get(): any
|
|
248
|
+
return self._value
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
--[=[
|
|
252
|
+
Returns the current value for the given player. This value
|
|
253
|
+
will depend on if `SetFor` or `SetFilter` has affected the
|
|
254
|
+
custom value for the player. If so, that custom value will
|
|
255
|
+
be returned. Otherwise, the top-level value will be used
|
|
256
|
+
(e.g. value from `Set`).
|
|
257
|
+
|
|
258
|
+
```lua
|
|
259
|
+
-- Set top level data:
|
|
260
|
+
remoteProperty:Set("Data")
|
|
261
|
+
print(remoteProperty:GetFor(somePlayer)) --> "Data"
|
|
262
|
+
|
|
263
|
+
-- Set custom data:
|
|
264
|
+
remoteProperty:SetFor(somePlayer, "CustomData")
|
|
265
|
+
print(remoteProperty:GetFor(somePlayer)) --> "CustomData"
|
|
266
|
+
|
|
267
|
+
-- Set top level again, overriding custom data:
|
|
268
|
+
remoteProperty:Set("NewData")
|
|
269
|
+
print(remoteProperty:GetFor(somePlayer)) --> "NewData"
|
|
270
|
+
|
|
271
|
+
-- Set custom data again, and set top level without overriding:
|
|
272
|
+
remoteProperty:SetFor(somePlayer, "CustomData")
|
|
273
|
+
remoteProperty:SetTop("Data")
|
|
274
|
+
print(remoteProperty:GetFor(somePlayer)) --> "CustomData"
|
|
275
|
+
|
|
276
|
+
-- Clear custom data to use top level data:
|
|
277
|
+
remoteProperty:ClearFor(somePlayer)
|
|
278
|
+
print(remoteProperty:GetFor(somePlayer)) --> "Data"
|
|
279
|
+
```
|
|
280
|
+
]=]
|
|
281
|
+
function RemoteProperty:GetFor(player: Player): any
|
|
282
|
+
local playerValue = self._perPlayer[player]
|
|
283
|
+
local value = if playerValue == nil then self._value elseif playerValue == None then nil else playerValue
|
|
284
|
+
return value
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
--[=[
|
|
288
|
+
Destroys the RemoteProperty object.
|
|
289
|
+
]=]
|
|
290
|
+
function RemoteProperty:Destroy()
|
|
291
|
+
self._rs:Destroy()
|
|
292
|
+
self._playerRemoving:Disconnect()
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
return RemoteProperty
|