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,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
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
-- RemoteSignal
|
|
2
|
+
-- Stephen Leitnick
|
|
3
|
+
-- December 20, 2021
|
|
4
|
+
|
|
5
|
+
local Players = game:GetService("Players")
|
|
6
|
+
|
|
7
|
+
local Signal = require(script.Parent.Parent.Parent.Signal)
|
|
8
|
+
local Types = require(script.Parent.Parent.Types)
|
|
9
|
+
|
|
10
|
+
--[=[
|
|
11
|
+
@class RemoteSignal
|
|
12
|
+
@server
|
|
13
|
+
Created via `ServerComm:CreateSignal()`.
|
|
14
|
+
]=]
|
|
15
|
+
local RemoteSignal = {}
|
|
16
|
+
RemoteSignal.__index = RemoteSignal
|
|
17
|
+
|
|
18
|
+
--[=[
|
|
19
|
+
@within RemoteSignal
|
|
20
|
+
@interface Connection
|
|
21
|
+
.Disconnect () -> nil
|
|
22
|
+
.Connected boolean
|
|
23
|
+
|
|
24
|
+
Represents a connection.
|
|
25
|
+
]=]
|
|
26
|
+
|
|
27
|
+
function RemoteSignal.new(
|
|
28
|
+
parent: Instance,
|
|
29
|
+
name: string,
|
|
30
|
+
unreliable: boolean?,
|
|
31
|
+
inboundMiddleware: Types.ServerMiddleware?,
|
|
32
|
+
outboundMiddleware: Types.ServerMiddleware?
|
|
33
|
+
)
|
|
34
|
+
local self = setmetatable({}, RemoteSignal)
|
|
35
|
+
self._re = if unreliable == true then Instance.new("UnreliableRemoteEvent") else Instance.new("RemoteEvent")
|
|
36
|
+
self._re.Name = name
|
|
37
|
+
self._re.Parent = parent
|
|
38
|
+
if outboundMiddleware and #outboundMiddleware > 0 then
|
|
39
|
+
self._hasOutbound = true
|
|
40
|
+
self._outbound = outboundMiddleware
|
|
41
|
+
else
|
|
42
|
+
self._hasOutbound = false
|
|
43
|
+
end
|
|
44
|
+
if inboundMiddleware and #inboundMiddleware > 0 then
|
|
45
|
+
self._directConnect = false
|
|
46
|
+
self._signal = Signal.new()
|
|
47
|
+
self._re.OnServerEvent:Connect(function(player, ...)
|
|
48
|
+
local args = table.pack(...)
|
|
49
|
+
for _, middlewareFunc in inboundMiddleware do
|
|
50
|
+
local middlewareResult = table.pack(middlewareFunc(player, args))
|
|
51
|
+
if not middlewareResult[1] then
|
|
52
|
+
return
|
|
53
|
+
end
|
|
54
|
+
args.n = #args
|
|
55
|
+
end
|
|
56
|
+
self._signal:Fire(player, table.unpack(args, 1, args.n))
|
|
57
|
+
end)
|
|
58
|
+
else
|
|
59
|
+
self._directConnect = true
|
|
60
|
+
end
|
|
61
|
+
return self
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
--[=[
|
|
65
|
+
@return boolean
|
|
66
|
+
Returns `true` if the underlying RemoteSignal is bound to an
|
|
67
|
+
UnreliableRemoteEvent object.
|
|
68
|
+
]=]
|
|
69
|
+
function RemoteSignal:IsUnreliable(): boolean
|
|
70
|
+
return self._re:IsA("UnreliableRemoteEvent")
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
--[=[
|
|
74
|
+
@param fn (player: Player, ...: any) -> nil -- The function to connect
|
|
75
|
+
@return Connection
|
|
76
|
+
Connect a function to the signal. Anytime a matching ClientRemoteSignal
|
|
77
|
+
on a client fires, the connected function will be invoked with the
|
|
78
|
+
arguments passed by the client.
|
|
79
|
+
]=]
|
|
80
|
+
function RemoteSignal:Connect(fn)
|
|
81
|
+
if self._directConnect then
|
|
82
|
+
return self._re.OnServerEvent:Connect(fn)
|
|
83
|
+
else
|
|
84
|
+
return self._signal:Connect(fn)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
function RemoteSignal:_processOutboundMiddleware(player: Player?, ...: any)
|
|
89
|
+
if not self._hasOutbound then
|
|
90
|
+
return ...
|
|
91
|
+
end
|
|
92
|
+
local args = table.pack(...)
|
|
93
|
+
for _, middlewareFunc in self._outbound do
|
|
94
|
+
local middlewareResult = table.pack(middlewareFunc(player, args))
|
|
95
|
+
if not middlewareResult[1] then
|
|
96
|
+
return table.unpack(middlewareResult, 2, middlewareResult.n)
|
|
97
|
+
end
|
|
98
|
+
args.n = #args
|
|
99
|
+
end
|
|
100
|
+
return table.unpack(args, 1, args.n)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
--[=[
|
|
104
|
+
@param player Player -- The target client
|
|
105
|
+
@param ... any -- Arguments passed to the client
|
|
106
|
+
Fires the signal at the specified client with any arguments.
|
|
107
|
+
|
|
108
|
+
:::note Outbound Middleware
|
|
109
|
+
All arguments pass through any outbound middleware (if any)
|
|
110
|
+
before being sent to the clients.
|
|
111
|
+
:::
|
|
112
|
+
]=]
|
|
113
|
+
function RemoteSignal:Fire(player: Player, ...: any)
|
|
114
|
+
self._re:FireClient(player, self:_processOutboundMiddleware(player, ...))
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
--[=[
|
|
118
|
+
@param ... any
|
|
119
|
+
Fires the signal at _all_ clients with any arguments.
|
|
120
|
+
|
|
121
|
+
:::note Outbound Middleware
|
|
122
|
+
All arguments pass through any outbound middleware (if any)
|
|
123
|
+
before being sent to the clients.
|
|
124
|
+
:::
|
|
125
|
+
]=]
|
|
126
|
+
function RemoteSignal:FireAll(...: any)
|
|
127
|
+
self._re:FireAllClients(self:_processOutboundMiddleware(nil, ...))
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
--[=[
|
|
131
|
+
@param ignorePlayer Player -- The client to ignore
|
|
132
|
+
@param ... any -- Arguments passed to the other clients
|
|
133
|
+
Fires the signal to all clients _except_ the specified
|
|
134
|
+
client.
|
|
135
|
+
|
|
136
|
+
:::note Outbound Middleware
|
|
137
|
+
All arguments pass through any outbound middleware (if any)
|
|
138
|
+
before being sent to the clients.
|
|
139
|
+
:::
|
|
140
|
+
]=]
|
|
141
|
+
function RemoteSignal:FireExcept(ignorePlayer: Player, ...: any)
|
|
142
|
+
self:FireFilter(function(plr)
|
|
143
|
+
return plr ~= ignorePlayer
|
|
144
|
+
end, ...)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
--[=[
|
|
148
|
+
@param predicate (player: Player, argsFromFire: ...) -> boolean
|
|
149
|
+
@param ... any -- Arguments to pass to the clients (and to the predicate)
|
|
150
|
+
Fires the signal at any clients that pass the `predicate`
|
|
151
|
+
function test. This can be used to fire signals with much
|
|
152
|
+
more control logic.
|
|
153
|
+
|
|
154
|
+
:::note Outbound Middleware
|
|
155
|
+
All arguments pass through any outbound middleware (if any)
|
|
156
|
+
before being sent to the clients.
|
|
157
|
+
:::
|
|
158
|
+
|
|
159
|
+
:::caution Predicate Before Middleware
|
|
160
|
+
The arguments sent to the predicate are sent _before_ getting
|
|
161
|
+
transformed by any middleware.
|
|
162
|
+
:::
|
|
163
|
+
|
|
164
|
+
```lua
|
|
165
|
+
-- Fire signal to players of the same team:
|
|
166
|
+
remoteSignal:FireFilter(function(player)
|
|
167
|
+
return player.Team.Name == "Best Team"
|
|
168
|
+
end)
|
|
169
|
+
```
|
|
170
|
+
]=]
|
|
171
|
+
function RemoteSignal:FireFilter(predicate: (Player, ...any) -> boolean, ...: any)
|
|
172
|
+
for _, player in Players:GetPlayers() do
|
|
173
|
+
if predicate(player, ...) then
|
|
174
|
+
self._re:FireClient(player, self:_processOutboundMiddleware(nil, ...))
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
--[=[
|
|
180
|
+
Fires a signal at the clients within the `players` table. This is
|
|
181
|
+
useful when signals need to fire for a specific set of players.
|
|
182
|
+
|
|
183
|
+
For more complex firing, see `FireFilter`.
|
|
184
|
+
|
|
185
|
+
:::note Outbound Middleware
|
|
186
|
+
All arguments pass through any outbound middleware (if any)
|
|
187
|
+
before being sent to the clients.
|
|
188
|
+
:::
|
|
189
|
+
|
|
190
|
+
```lua
|
|
191
|
+
local players = {somePlayer1, somePlayer2, somePlayer3}
|
|
192
|
+
remoteSignal:FireFor(players, "Hello, players!")
|
|
193
|
+
```
|
|
194
|
+
]=]
|
|
195
|
+
function RemoteSignal:FireFor(players: { Player }, ...: any)
|
|
196
|
+
for _, player in players do
|
|
197
|
+
self._re:FireClient(player, self:_processOutboundMiddleware(nil, ...))
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
--[=[
|
|
202
|
+
Destroys the RemoteSignal object.
|
|
203
|
+
]=]
|
|
204
|
+
function RemoteSignal:Destroy()
|
|
205
|
+
self._re:Destroy()
|
|
206
|
+
if self._signal then
|
|
207
|
+
self._signal:Destroy()
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
return RemoteSignal
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
-- ServerComm
|
|
2
|
+
-- Stephen Leitnick
|
|
3
|
+
-- December 20, 2021
|
|
4
|
+
|
|
5
|
+
local Comm = require(script.Parent)
|
|
6
|
+
local Types = require(script.Parent.Parent.Types)
|
|
7
|
+
local Util = require(script.Parent.Parent.Util)
|
|
8
|
+
|
|
9
|
+
--[=[
|
|
10
|
+
@class ServerComm
|
|
11
|
+
@server
|
|
12
|
+
]=]
|
|
13
|
+
local ServerComm = {}
|
|
14
|
+
ServerComm.__index = ServerComm
|
|
15
|
+
|
|
16
|
+
--[=[
|
|
17
|
+
@within ServerComm
|
|
18
|
+
@type ServerMiddlewareFn (player: Player, args: {any}) -> (shouldContinue: boolean, ...: any)
|
|
19
|
+
The middleware function takes the client player and the arguments (as a table array), and should
|
|
20
|
+
return `true|false` to indicate if the process should continue.
|
|
21
|
+
|
|
22
|
+
If returning `false`, the optional varargs after the `false` are used as the new return values
|
|
23
|
+
to whatever was calling the middleware.
|
|
24
|
+
]=]
|
|
25
|
+
--[=[
|
|
26
|
+
@within ServerComm
|
|
27
|
+
@type ServerMiddleware {ServerMiddlewareFn}
|
|
28
|
+
Array of middleware functions.
|
|
29
|
+
]=]
|
|
30
|
+
|
|
31
|
+
--[=[
|
|
32
|
+
@return ServerComm
|
|
33
|
+
Constructs a ServerComm object. The `namespace` parameter is used
|
|
34
|
+
in cases where more than one ServerComm object may be bound
|
|
35
|
+
to the same object. Otherwise, a default namespace is used.
|
|
36
|
+
|
|
37
|
+
```lua
|
|
38
|
+
local serverComm = ServerComm.new(game:GetService("ReplicatedStorage"))
|
|
39
|
+
|
|
40
|
+
-- If many might exist in the given parent, use a unique namespace:
|
|
41
|
+
local serverComm = ServerComm.new(game:GetService("ReplicatedStorage"), "MyNamespace")
|
|
42
|
+
```
|
|
43
|
+
]=]
|
|
44
|
+
function ServerComm.new(parent: Instance, namespace: string?)
|
|
45
|
+
assert(Util.IsServer, "ServerComm must be constructed from the server")
|
|
46
|
+
assert(typeof(parent) == "Instance", "Parent must be of type Instance")
|
|
47
|
+
local ns = Util.DefaultCommFolderName
|
|
48
|
+
if namespace then
|
|
49
|
+
ns = namespace
|
|
50
|
+
end
|
|
51
|
+
assert(not parent:FindFirstChild(ns), "Parent already has another ServerComm bound to namespace " .. ns)
|
|
52
|
+
local self = setmetatable({}, ServerComm)
|
|
53
|
+
self._instancesFolder = Instance.new("Folder")
|
|
54
|
+
self._instancesFolder.Name = ns
|
|
55
|
+
self._instancesFolder.Parent = parent
|
|
56
|
+
return self
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
--[=[
|
|
60
|
+
@param name string
|
|
61
|
+
@param fn (player: Player, ...: any) -> ...: any
|
|
62
|
+
@param inboundMiddleware ServerMiddleware?
|
|
63
|
+
@param outboundMiddleware ServerMiddleware?
|
|
64
|
+
@return RemoteFunction
|
|
65
|
+
Creates a RemoteFunction and binds the given function to it. Inbound
|
|
66
|
+
and outbound middleware can be applied if desired.
|
|
67
|
+
|
|
68
|
+
```lua
|
|
69
|
+
local function GetSomething(player: Player)
|
|
70
|
+
return "Something"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
serverComm:BindFunction("GetSomething", GetSomething)
|
|
74
|
+
```
|
|
75
|
+
]=]
|
|
76
|
+
function ServerComm:BindFunction(
|
|
77
|
+
name: string,
|
|
78
|
+
fn: Types.FnBind,
|
|
79
|
+
inboundMiddleware: Types.ServerMiddleware?,
|
|
80
|
+
outboundMiddleware: Types.ServerMiddleware?
|
|
81
|
+
): RemoteFunction
|
|
82
|
+
return Comm.BindFunction(self._instancesFolder, name, fn, inboundMiddleware, outboundMiddleware)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
--[=[
|
|
86
|
+
@param tbl table
|
|
87
|
+
@param name string
|
|
88
|
+
@param inboundMiddleware ServerMiddleware?
|
|
89
|
+
@param outboundMiddleware ServerMiddleware?
|
|
90
|
+
@return RemoteFunction
|
|
91
|
+
|
|
92
|
+
Binds a function to a table method. The name must match the
|
|
93
|
+
name of the method in the table. The same name will be used
|
|
94
|
+
on the client to access the given function.
|
|
95
|
+
|
|
96
|
+
```lua
|
|
97
|
+
local MyObject = {
|
|
98
|
+
_Data = 10,
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function MyObject:GetData(player: Player)
|
|
102
|
+
return self._Data
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
serverComm:WrapMethod(MyObject, "GetData")
|
|
106
|
+
```
|
|
107
|
+
]=]
|
|
108
|
+
function ServerComm:WrapMethod(
|
|
109
|
+
tbl: {},
|
|
110
|
+
name: string,
|
|
111
|
+
inboundMiddleware: Types.ServerMiddleware?,
|
|
112
|
+
outboundMiddleware: Types.ServerMiddleware?
|
|
113
|
+
): RemoteFunction
|
|
114
|
+
return Comm.WrapMethod(self._instancesFolder, tbl, name, inboundMiddleware, outboundMiddleware)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
--[=[
|
|
118
|
+
@param name string
|
|
119
|
+
@param unreliable boolean?
|
|
120
|
+
@param inboundMiddleware ServerMiddleware?
|
|
121
|
+
@param outboundMiddleware ServerMiddleware?
|
|
122
|
+
@return RemoteSignal
|
|
123
|
+
|
|
124
|
+
Creates a signal that can be used to fire data to the clients
|
|
125
|
+
or receive data from the clients.
|
|
126
|
+
|
|
127
|
+
By default, signals use RemoteEvents internally. However, if
|
|
128
|
+
the `unreliable` argument is set to `true`, then an
|
|
129
|
+
UnreliableRemoteEvent will be used instead.
|
|
130
|
+
|
|
131
|
+
```lua
|
|
132
|
+
local mySignal = serverComm:CreateSignal("MySignal")
|
|
133
|
+
|
|
134
|
+
-- Examples of firing in different ways (see docs for RemoteSignal for further info):
|
|
135
|
+
mySignal:Fire(somePlayer, "Hello world")
|
|
136
|
+
mySignal:FireAll("Hi there")
|
|
137
|
+
mySignal:FireExcept(somePlayer, "Hello everyone except " .. somePlayer.Name)
|
|
138
|
+
mySignal:FireFilter(function(player) return player.Team == someCoolTeam end, "Hello cool team")
|
|
139
|
+
|
|
140
|
+
-- Example of listening for clients to send data:
|
|
141
|
+
mySignal:Connect(function(player, message)
|
|
142
|
+
print("Got a message from " .. player.Name .. ":", message)
|
|
143
|
+
end)
|
|
144
|
+
```
|
|
145
|
+
]=]
|
|
146
|
+
function ServerComm:CreateSignal(
|
|
147
|
+
name: string,
|
|
148
|
+
unreliable: boolean?,
|
|
149
|
+
inboundMiddleware: Types.ServerMiddleware?,
|
|
150
|
+
outboundMiddleware: Types.ServerMiddleware?
|
|
151
|
+
)
|
|
152
|
+
return Comm.CreateSignal(self._instancesFolder, name, unreliable, inboundMiddleware, outboundMiddleware)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
--[=[
|
|
156
|
+
@param name string
|
|
157
|
+
@param initialValue any
|
|
158
|
+
@param inboundMiddleware ServerMiddleware?
|
|
159
|
+
@param outboundMiddleware ServerMiddleware?
|
|
160
|
+
@return RemoteProperty
|
|
161
|
+
|
|
162
|
+
Create a property object which will replicate its property value to
|
|
163
|
+
the clients. Optionally, specific clients can be targeted with
|
|
164
|
+
different property values.
|
|
165
|
+
|
|
166
|
+
```lua
|
|
167
|
+
local comm = Comm.ServerComm.new(game:GetService("ReplicatedStorage"))
|
|
168
|
+
|
|
169
|
+
local mapInfo = comm:CreateProperty("MapInfo", {
|
|
170
|
+
MapName = "TheAwesomeMap",
|
|
171
|
+
MapDuration = 60,
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
-- Change the data:
|
|
175
|
+
mapInfo:Set({
|
|
176
|
+
MapName = "AnotherMap",
|
|
177
|
+
MapDuration = 30,
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
-- Change the data for one player:
|
|
181
|
+
mapInfo:SetFor(somePlayer, {
|
|
182
|
+
MapName = "ASpecialMapForYou",
|
|
183
|
+
MapDuration = 90,
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
-- Change data based on a predicate function:
|
|
187
|
+
mapInfo:SetFilter(function(player)
|
|
188
|
+
return player.Team == game.Teams.SomeSpecialTeam
|
|
189
|
+
end, {
|
|
190
|
+
MapName = "TeamMap",
|
|
191
|
+
MapDuration = 20,
|
|
192
|
+
})
|
|
193
|
+
```
|
|
194
|
+
]=]
|
|
195
|
+
function ServerComm:CreateProperty(
|
|
196
|
+
name: string,
|
|
197
|
+
initialValue: any,
|
|
198
|
+
inboundMiddleware: Types.ServerMiddleware?,
|
|
199
|
+
outboundMiddleware: Types.ServerMiddleware?
|
|
200
|
+
)
|
|
201
|
+
return Comm.CreateProperty(self._instancesFolder, name, initialValue, inboundMiddleware, outboundMiddleware)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
--[=[
|
|
205
|
+
Destroy the ServerComm object.
|
|
206
|
+
]=]
|
|
207
|
+
function ServerComm:Destroy()
|
|
208
|
+
self._instancesFolder:Destroy()
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
return ServerComm
|