@rbxts/tether 1.0.6 → 1.0.8
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 +8 -4
- package/out/builtin-middlewares.d.ts +2 -2
- package/out/builtin-middlewares.luau +1 -1
- package/out/message-emitter.luau +34 -20
- package/out/middleware.d.ts +13 -4
- package/out/middleware.luau +50 -3
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -69,10 +69,14 @@ import { MessageEmitter, BuiltinMiddlewares } from "@rbxts/tether";
|
|
|
69
69
|
|
|
70
70
|
export const messaging = MessageEmitter.create<MessageData>();
|
|
71
71
|
messaging.middleware
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
.
|
|
75
|
-
|
|
72
|
+
// only allows requests to the server every 5 seconds,
|
|
73
|
+
// drops any requests that occur within 5 seconds of each other
|
|
74
|
+
.useServer(Message.Test, [BuiltinMiddlewares.rateLimit(5)])
|
|
75
|
+
// automatically validates that data sent through the remote
|
|
76
|
+
// matches the data associated with the message at runtime
|
|
77
|
+
.useShared(Message.Test, [BuiltinMiddlewares.validateClient()])
|
|
78
|
+
// rate limit every server remote (global)
|
|
79
|
+
.useServerGlobal([BuiltinMiddlewares.rateLimit(1)]);
|
|
76
80
|
|
|
77
81
|
export const enum Message {
|
|
78
82
|
Test
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Modding } from "@flamework/core";
|
|
2
|
-
import { type
|
|
2
|
+
import { type SharedMiddleware, type ServerMiddleware, type ClientMiddleware } from "./middleware";
|
|
3
3
|
type Guard<T> = (value: unknown) => value is T;
|
|
4
4
|
export declare namespace BuiltinMiddlewares {
|
|
5
5
|
/**
|
|
@@ -7,7 +7,7 @@ export declare namespace BuiltinMiddlewares {
|
|
|
7
7
|
* @param interval The interval in seconds that the middleware should wait before allowing a new request.
|
|
8
8
|
* @returns A middleware that will drop any message that occurs within the given interval.
|
|
9
9
|
*/
|
|
10
|
-
function rateLimit(interval: number):
|
|
10
|
+
function rateLimit(interval: number): SharedMiddleware;
|
|
11
11
|
/**
|
|
12
12
|
* Creates a server middleware that validates the data with the given guard (or a generated guard if none was provided).
|
|
13
13
|
* If the guard fails, the middleware will drop the message.
|
|
@@ -3,7 +3,7 @@ local TS = _G[script]
|
|
|
3
3
|
local DropRequest = TS.import(script, script.Parent, "middleware").DropRequest
|
|
4
4
|
local noOp = function() end
|
|
5
5
|
local validationGuardGenerationFailed = function(context)
|
|
6
|
-
return `[
|
|
6
|
+
return `[@rbxts/tether]: Failed to generate guard for validate{context}<T> builtin middleware - skipping validation`
|
|
7
7
|
end
|
|
8
8
|
local BuiltinMiddlewares = {}
|
|
9
9
|
do
|
package/out/message-emitter.luau
CHANGED
|
@@ -89,7 +89,7 @@ do
|
|
|
89
89
|
function MessageEmitter:create(metaForEachMessage)
|
|
90
90
|
local emitter = MessageEmitter.new()
|
|
91
91
|
if metaForEachMessage == nil then
|
|
92
|
-
warn("[
|
|
92
|
+
warn("[@rbxts/tether]: Failed to generate serializer metadata for MessageEmitter")
|
|
93
93
|
return emitter:initialize()
|
|
94
94
|
end
|
|
95
95
|
for kind, meta in pairs(metaForEachMessage) do
|
|
@@ -132,12 +132,16 @@ do
|
|
|
132
132
|
if unreliable == nil then
|
|
133
133
|
unreliable = false
|
|
134
134
|
end
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
135
|
+
for _, middleware in self.middleware:getServerGlobal() do
|
|
136
|
+
local result = middleware(data)
|
|
137
|
+
if result == DropRequest then
|
|
138
|
+
return nil
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
for _, middleware in self.middleware:getServer(message) do
|
|
142
|
+
local result = middleware(data)
|
|
143
|
+
if result == DropRequest then
|
|
144
|
+
return nil
|
|
141
145
|
end
|
|
142
146
|
end
|
|
143
147
|
local send = if unreliable then self.clientEvents.sendUnreliableServerMessage else self.clientEvents.sendServerMessage
|
|
@@ -147,12 +151,16 @@ do
|
|
|
147
151
|
if unreliable == nil then
|
|
148
152
|
unreliable = false
|
|
149
153
|
end
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
for _, middleware in self.middleware:getClientGlobal() do
|
|
155
|
+
local result = middleware(player, data)
|
|
156
|
+
if result == DropRequest then
|
|
157
|
+
return nil
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
for _, middleware in self.middleware:getClient(message) do
|
|
161
|
+
local result = middleware(player, data)
|
|
162
|
+
if result == DropRequest then
|
|
163
|
+
return nil
|
|
156
164
|
end
|
|
157
165
|
end
|
|
158
166
|
local send = if unreliable then self.serverEvents.sendUnreliableClientMessage else self.serverEvents.sendClientMessage
|
|
@@ -162,13 +170,19 @@ do
|
|
|
162
170
|
if unreliable == nil then
|
|
163
171
|
unreliable = false
|
|
164
172
|
end
|
|
165
|
-
|
|
166
|
-
for
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
173
|
+
for _, middleware in self.middleware:getClientGlobal() do
|
|
174
|
+
for _1, player in Players:GetPlayers() do
|
|
175
|
+
local result = middleware(player, data)
|
|
176
|
+
if result == DropRequest then
|
|
177
|
+
return nil
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
for _, middleware in self.middleware:getClient(message) do
|
|
182
|
+
for _1, player in Players:GetPlayers() do
|
|
183
|
+
local result = middleware(player, data)
|
|
184
|
+
if result == DropRequest then
|
|
185
|
+
return nil
|
|
172
186
|
end
|
|
173
187
|
end
|
|
174
188
|
end
|
package/out/middleware.d.ts
CHANGED
|
@@ -4,17 +4,26 @@ type DropRequestSymbol = symbol & {
|
|
|
4
4
|
export declare const DropRequest: DropRequestSymbol;
|
|
5
5
|
export type ClientMiddleware<Data = unknown> = (player: Player, data: Readonly<Data> | undefined) => DropRequestSymbol | void;
|
|
6
6
|
export type ServerMiddleware<Data = unknown> = (data: Readonly<Data> | undefined) => DropRequestSymbol | void;
|
|
7
|
-
export type
|
|
7
|
+
export type SharedMiddleware = () => DropRequestSymbol | void;
|
|
8
8
|
export type Middleware<Data = unknown> = ServerMiddleware<Data> & ClientMiddleware<Data>;
|
|
9
9
|
export declare class MiddlewareProvider<MessageData> {
|
|
10
|
+
private readonly clientGlobalMiddlewares;
|
|
11
|
+
private readonly serverGlobalMiddlewares;
|
|
10
12
|
private readonly clientMiddlewares;
|
|
11
13
|
private readonly serverMiddlewares;
|
|
12
14
|
/** @hidden */
|
|
13
15
|
getClient<Kind extends keyof MessageData>(message: Kind): ClientMiddleware<MessageData[Kind]>[];
|
|
14
16
|
/** @hidden */
|
|
15
17
|
getServer<Kind extends keyof MessageData>(message: Kind): ServerMiddleware<MessageData[Kind]>[];
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
/** @hidden */
|
|
19
|
+
getClientGlobal<Data>(): ClientMiddleware<Data>[];
|
|
20
|
+
/** @hidden */
|
|
21
|
+
getServerGlobal<Data>(): ServerMiddleware<Data>[];
|
|
22
|
+
useClient<Kind extends keyof MessageData>(message: Kind, middlewares: ClientMiddleware<MessageData[Kind]> | readonly ClientMiddleware<MessageData[Kind]>[], order?: number): this;
|
|
23
|
+
useServer<Kind extends keyof MessageData>(message: Kind, middlewares: ServerMiddleware<MessageData[Kind]> | readonly ServerMiddleware<MessageData[Kind]>[], order?: number): this;
|
|
24
|
+
useShared<Kind extends keyof MessageData>(message: Kind, middlewares: SharedMiddleware | readonly SharedMiddleware[], order?: number): this;
|
|
25
|
+
useClientGlobal<Data>(middlewares: ClientMiddleware<Data> | readonly ClientMiddleware<Data>[], order?: number): this;
|
|
26
|
+
useServerGlobal<Data>(middlewares: ServerMiddleware<Data> | readonly ServerMiddleware<Data>[], order?: number): this;
|
|
27
|
+
useSharedGlobal(middlewares: SharedMiddleware | readonly SharedMiddleware[], order?: number): this;
|
|
19
28
|
}
|
|
20
29
|
export {};
|
package/out/middleware.luau
CHANGED
|
@@ -13,6 +13,8 @@ do
|
|
|
13
13
|
return self:constructor(...) or self
|
|
14
14
|
end
|
|
15
15
|
function MiddlewareProvider:constructor()
|
|
16
|
+
self.clientGlobalMiddlewares = {}
|
|
17
|
+
self.serverGlobalMiddlewares = {}
|
|
16
18
|
self.clientMiddlewares = {}
|
|
17
19
|
self.serverMiddlewares = {}
|
|
18
20
|
end
|
|
@@ -28,6 +30,12 @@ do
|
|
|
28
30
|
end
|
|
29
31
|
return self.serverMiddlewares[message]
|
|
30
32
|
end
|
|
33
|
+
function MiddlewareProvider:getClientGlobal()
|
|
34
|
+
return self.clientGlobalMiddlewares
|
|
35
|
+
end
|
|
36
|
+
function MiddlewareProvider:getServerGlobal()
|
|
37
|
+
return self.serverGlobalMiddlewares
|
|
38
|
+
end
|
|
31
39
|
function MiddlewareProvider:useClient(message, middlewares, order)
|
|
32
40
|
local messageMiddleware = self:getClient(message)
|
|
33
41
|
local _middlewares = middlewares
|
|
@@ -40,7 +48,7 @@ do
|
|
|
40
48
|
table.insert(messageMiddleware, _condition + 1, _middlewares_1)
|
|
41
49
|
else
|
|
42
50
|
for _, middleware in middlewares do
|
|
43
|
-
self:useClient(message, middleware)
|
|
51
|
+
self:useClient(message, middleware, order)
|
|
44
52
|
end
|
|
45
53
|
end
|
|
46
54
|
return self
|
|
@@ -57,16 +65,55 @@ do
|
|
|
57
65
|
table.insert(messageMiddleware, _condition + 1, _middlewares_1)
|
|
58
66
|
else
|
|
59
67
|
for _, middleware in middlewares do
|
|
60
|
-
self:useServer(message, middleware)
|
|
68
|
+
self:useServer(message, middleware, order)
|
|
61
69
|
end
|
|
62
70
|
end
|
|
63
71
|
return self
|
|
64
72
|
end
|
|
65
|
-
function MiddlewareProvider:
|
|
73
|
+
function MiddlewareProvider:useShared(message, middlewares, order)
|
|
66
74
|
self:useClient(message, middlewares, order)
|
|
67
75
|
self:useServer(message, middlewares, order)
|
|
68
76
|
return self
|
|
69
77
|
end
|
|
78
|
+
function MiddlewareProvider:useClientGlobal(middlewares, order)
|
|
79
|
+
local globalMiddleware = self:getClientGlobal()
|
|
80
|
+
local _middlewares = middlewares
|
|
81
|
+
if typeof(_middlewares) == "function" then
|
|
82
|
+
local _condition = order
|
|
83
|
+
if _condition == nil then
|
|
84
|
+
_condition = #globalMiddleware - 1
|
|
85
|
+
end
|
|
86
|
+
local _middlewares_1 = middlewares
|
|
87
|
+
table.insert(globalMiddleware, _condition + 1, _middlewares_1)
|
|
88
|
+
else
|
|
89
|
+
for _, middleware in middlewares do
|
|
90
|
+
self:useClientGlobal(middleware, order)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
return self
|
|
94
|
+
end
|
|
95
|
+
function MiddlewareProvider:useServerGlobal(middlewares, order)
|
|
96
|
+
local globalMiddleware = self:getServerGlobal()
|
|
97
|
+
local _middlewares = middlewares
|
|
98
|
+
if typeof(_middlewares) == "function" then
|
|
99
|
+
local _condition = order
|
|
100
|
+
if _condition == nil then
|
|
101
|
+
_condition = #globalMiddleware - 1
|
|
102
|
+
end
|
|
103
|
+
local _middlewares_1 = middlewares
|
|
104
|
+
table.insert(globalMiddleware, _condition + 1, _middlewares_1)
|
|
105
|
+
else
|
|
106
|
+
for _, middleware in middlewares do
|
|
107
|
+
self:useServerGlobal(middleware, order)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
return self
|
|
111
|
+
end
|
|
112
|
+
function MiddlewareProvider:useSharedGlobal(middlewares, order)
|
|
113
|
+
self:useClientGlobal(middlewares, order)
|
|
114
|
+
self:useServerGlobal(middlewares, order)
|
|
115
|
+
return self
|
|
116
|
+
end
|
|
70
117
|
end
|
|
71
118
|
return {
|
|
72
119
|
DropRequest = DropRequest,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rbxts/tether",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"main": "out/init.lua",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "rbxtsc",
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
"roblox",
|
|
12
12
|
"tether",
|
|
13
13
|
"networking",
|
|
14
|
-
"message"
|
|
14
|
+
"message",
|
|
15
|
+
"serialization",
|
|
16
|
+
"middleware"
|
|
15
17
|
],
|
|
16
18
|
"repository": {
|
|
17
19
|
"url": "git+https://github.com/R-unic/tether.git"
|