@flamework-experimental/networking 2.0.0-alpha.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 +66 -0
- package/flamework.build +7 -0
- package/out/event/createEvent.d.ts +59 -0
- package/out/event/createEvent.luau +114 -0
- package/out/event/createRemoteInstance.d.ts +1 -0
- package/out/event/createRemoteInstance.luau +58 -0
- package/out/events/createClientMethod.d.ts +5 -0
- package/out/events/createClientMethod.luau +30 -0
- package/out/events/createGenericHandler.d.ts +5 -0
- package/out/events/createGenericHandler.luau +102 -0
- package/out/events/createNetworkingEvent.d.ts +2 -0
- package/out/events/createNetworkingEvent.luau +60 -0
- package/out/events/createServerMethod.d.ts +13 -0
- package/out/events/createServerMethod.luau +63 -0
- package/out/events/types.d.ts +220 -0
- package/out/function/createFunctionReceiver.d.ts +52 -0
- package/out/function/createFunctionReceiver.luau +118 -0
- package/out/function/createFunctionSender.d.ts +45 -0
- package/out/function/createFunctionSender.luau +135 -0
- package/out/function/errors.d.ts +10 -0
- package/out/function/errors.luau +25 -0
- package/out/functions/createClientMethod.d.ts +15 -0
- package/out/functions/createClientMethod.luau +52 -0
- package/out/functions/createGenericHandler.d.ts +7 -0
- package/out/functions/createGenericHandler.luau +140 -0
- package/out/functions/createNetworkingFunction.d.ts +2 -0
- package/out/functions/createNetworkingFunction.luau +68 -0
- package/out/functions/createServerMethod.d.ts +15 -0
- package/out/functions/createServerMethod.luau +52 -0
- package/out/functions/types.d.ts +289 -0
- package/out/handlers.d.ts +36 -0
- package/out/index.d.ts +55 -0
- package/out/init.luau +78 -0
- package/out/middleware/createGuardMiddleware.d.ts +6 -0
- package/out/middleware/createGuardMiddleware.luau +44 -0
- package/out/middleware/createMiddlewareProcessor.d.ts +3 -0
- package/out/middleware/createMiddlewareProcessor.luau +24 -0
- package/out/middleware/skip.d.ts +8 -0
- package/out/middleware/skip.luau +22 -0
- package/out/middleware/types.d.ts +15 -0
- package/out/types.d.ts +78 -0
- package/out/util/createSignalContainer.d.ts +5 -0
- package/out/util/createSignalContainer.luau +30 -0
- package/out/util/getNamespaceConfig.d.ts +10 -0
- package/out/util/getNamespaceConfig.luau +15 -0
- package/out/util/timeoutPromise.d.ts +1 -0
- package/out/util/timeoutPromise.luau +10 -0
- package/package.json +32 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local NetworkingFunctionError = TS.import(script, script.Parent.Parent, "function", "errors").NetworkingFunctionError
|
|
4
|
+
local SkipBadRequest = TS.import(script, script.Parent.Parent, "middleware", "skip").SkipBadRequest
|
|
5
|
+
local createFunctionReceiver = TS.import(script, script.Parent.Parent, "function", "createFunctionReceiver").createFunctionReceiver
|
|
6
|
+
local createFunctionSender = TS.import(script, script.Parent.Parent, "function", "createFunctionSender").createFunctionSender
|
|
7
|
+
local createGuardMiddleware = TS.import(script, script.Parent.Parent, "middleware", "createGuardMiddleware").createGuardMiddleware
|
|
8
|
+
local Players = TS.import(script, TS.getModule(script, "@rbxts", "services")).Players
|
|
9
|
+
local getNamespaceConfig = TS.import(script, script.Parent.Parent, "util", "getNamespaceConfig").getNamespaceConfig
|
|
10
|
+
local function createGenericHandler(globalName, namespaceName, receiverPrefix, senderPrefix, metadata, config, signals, createMethod)
|
|
11
|
+
local handler = {}
|
|
12
|
+
local _set = {}
|
|
13
|
+
for _, _v in metadata.incomingIds do
|
|
14
|
+
_set[_v] = true
|
|
15
|
+
end
|
|
16
|
+
local receiverNameSet = _set
|
|
17
|
+
local _set_1 = {}
|
|
18
|
+
for _, _v in metadata.outgoingIds do
|
|
19
|
+
_set_1[_v] = true
|
|
20
|
+
end
|
|
21
|
+
local senderNameSet = _set_1
|
|
22
|
+
local _set_2 = {}
|
|
23
|
+
local _array = {}
|
|
24
|
+
local _length = #_array
|
|
25
|
+
local _array_1 = metadata.incomingIds
|
|
26
|
+
local _Length = #_array_1
|
|
27
|
+
table.move(_array_1, 1, _Length, _length + 1, _array)
|
|
28
|
+
_length += _Length
|
|
29
|
+
local _array_2 = metadata.outgoingIds
|
|
30
|
+
table.move(_array_2, 1, #_array_2, _length + 1, _array)
|
|
31
|
+
for _, _v in _array do
|
|
32
|
+
_set_2[_v] = true
|
|
33
|
+
end
|
|
34
|
+
for name in _set_2 do
|
|
35
|
+
local configMiddleware = config.middleware[name]
|
|
36
|
+
local incomingMiddleware = if configMiddleware ~= nil then table.clone(configMiddleware) else {}
|
|
37
|
+
local isReceiver = receiverNameSet[name] ~= nil
|
|
38
|
+
local isSender = senderNameSet[name] ~= nil
|
|
39
|
+
local effectiveName = if namespaceName ~= nil then `{namespaceName}/{name}` else name
|
|
40
|
+
local networkInfo = {
|
|
41
|
+
eventType = "Function",
|
|
42
|
+
name = effectiveName,
|
|
43
|
+
globalName = globalName,
|
|
44
|
+
}
|
|
45
|
+
if not config.disableIncomingGuards and isReceiver then
|
|
46
|
+
local guards = metadata.incoming[name]
|
|
47
|
+
assert(guards)
|
|
48
|
+
local _arg0 = createGuardMiddleware(name, guards[1], guards[2], networkInfo, config.warnOnInvalidGuards, signals, SkipBadRequest)
|
|
49
|
+
table.insert(incomingMiddleware, 1, _arg0)
|
|
50
|
+
end
|
|
51
|
+
-- A malformed serialized payload is reported like a failed guard, with no argument index.
|
|
52
|
+
local onMalformed = function(player, message)
|
|
53
|
+
if config.warnOnInvalidGuards then
|
|
54
|
+
local sender = if player ~= nil then `'{player}'` else "Server"
|
|
55
|
+
warn(`{sender} sent a malformed payload for function '{name}': {message}`)
|
|
56
|
+
end
|
|
57
|
+
signals:fire("onBadRequest", player or Players.LocalPlayer, {
|
|
58
|
+
networkInfo = networkInfo,
|
|
59
|
+
argIndex = -1,
|
|
60
|
+
argValue = message,
|
|
61
|
+
})
|
|
62
|
+
end
|
|
63
|
+
local _result
|
|
64
|
+
if isReceiver then
|
|
65
|
+
local _object = {
|
|
66
|
+
namespace = globalName,
|
|
67
|
+
debugName = name,
|
|
68
|
+
id = if isSender then `{receiverPrefix}{effectiveName}` else effectiveName,
|
|
69
|
+
networkInfo = networkInfo,
|
|
70
|
+
incomingMiddleware = incomingMiddleware,
|
|
71
|
+
}
|
|
72
|
+
local _left = "argsDecoder"
|
|
73
|
+
local _result_1 = metadata.incomingSerializers
|
|
74
|
+
if _result_1 ~= nil then
|
|
75
|
+
_result_1 = _result_1[name]
|
|
76
|
+
end
|
|
77
|
+
_object[_left] = _result_1
|
|
78
|
+
local _left_1 = "resultDecoder"
|
|
79
|
+
local _result_2 = metadata.incomingResults
|
|
80
|
+
if _result_2 ~= nil then
|
|
81
|
+
_result_2 = _result_2[name]
|
|
82
|
+
end
|
|
83
|
+
_object[_left_1] = _result_2
|
|
84
|
+
_object.onMalformed = onMalformed
|
|
85
|
+
_result = createFunctionReceiver(_object)
|
|
86
|
+
else
|
|
87
|
+
_result = nil
|
|
88
|
+
end
|
|
89
|
+
local receiver = _result
|
|
90
|
+
local _result_1
|
|
91
|
+
if isSender then
|
|
92
|
+
local _object = {
|
|
93
|
+
namespace = globalName,
|
|
94
|
+
debugName = name,
|
|
95
|
+
id = if isReceiver then `{senderPrefix}{effectiveName}` else effectiveName,
|
|
96
|
+
networkInfo = networkInfo,
|
|
97
|
+
}
|
|
98
|
+
local _left = "resultDecoder"
|
|
99
|
+
local _result_2 = metadata.outgoingResults
|
|
100
|
+
if _result_2 ~= nil then
|
|
101
|
+
_result_2 = _result_2[name]
|
|
102
|
+
end
|
|
103
|
+
_object[_left] = _result_2
|
|
104
|
+
_object.onMalformed = function(player, message)
|
|
105
|
+
if config.warnOnInvalidGuards then
|
|
106
|
+
warn(`Received a malformed response for function '{name}': {message}`)
|
|
107
|
+
end
|
|
108
|
+
signals:fire("onBadResponse", player or Players.LocalPlayer, {
|
|
109
|
+
networkInfo = networkInfo,
|
|
110
|
+
value = message,
|
|
111
|
+
})
|
|
112
|
+
end
|
|
113
|
+
_object.responseMiddleware = if config.disableIncomingGuards then nil else function(player, value, resolve, reject)
|
|
114
|
+
local returnGuard = metadata.outgoing[name]
|
|
115
|
+
if returnGuard and not returnGuard(value) then
|
|
116
|
+
reject(NetworkingFunctionError.InvalidResult)
|
|
117
|
+
signals:fire("onBadResponse", player or Players.LocalPlayer, {
|
|
118
|
+
networkInfo = networkInfo,
|
|
119
|
+
value = value,
|
|
120
|
+
})
|
|
121
|
+
else
|
|
122
|
+
resolve(value)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
_result_1 = createFunctionSender(_object)
|
|
126
|
+
else
|
|
127
|
+
_result_1 = nil
|
|
128
|
+
end
|
|
129
|
+
local sender = _result_1
|
|
130
|
+
handler[name] = createMethod(config, receiver, sender)
|
|
131
|
+
end
|
|
132
|
+
for _, namespaceId in metadata.namespaceIds do
|
|
133
|
+
local namespace = metadata.namespaces[namespaceId]
|
|
134
|
+
handler[namespaceId] = createGenericHandler(globalName, if namespaceName ~= nil then `{namespaceName}/{namespaceId}` else namespaceId, receiverPrefix, senderPrefix, namespace, getNamespaceConfig(config, namespaceId), signals, createMethod)
|
|
135
|
+
end
|
|
136
|
+
return handler
|
|
137
|
+
end
|
|
138
|
+
return {
|
|
139
|
+
createGenericHandler = createGenericHandler,
|
|
140
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local RunService = TS.import(script, TS.getModule(script, "@rbxts", "services")).RunService
|
|
4
|
+
local createSignalContainer = TS.import(script, script.Parent.Parent, "util", "createSignalContainer").createSignalContainer
|
|
5
|
+
local createGenericHandler = TS.import(script, script.Parent, "createGenericHandler").createGenericHandler
|
|
6
|
+
local createServerMethod = TS.import(script, script.Parent, "createServerMethod").createServerMethod
|
|
7
|
+
local createClientMethod = TS.import(script, script.Parent, "createClientMethod").createClientMethod
|
|
8
|
+
local SERVER_PREFIX = "$"
|
|
9
|
+
local CLIENT_PREFIX = "@"
|
|
10
|
+
local function getDefaultConfiguration(config)
|
|
11
|
+
local _object = {}
|
|
12
|
+
local _left = "middleware"
|
|
13
|
+
local _condition = config.middleware
|
|
14
|
+
if _condition == nil then
|
|
15
|
+
_condition = {}
|
|
16
|
+
end
|
|
17
|
+
_object[_left] = _condition
|
|
18
|
+
local _left_1 = "defaultTimeout"
|
|
19
|
+
local _condition_1 = config.defaultTimeout
|
|
20
|
+
if _condition_1 == nil then
|
|
21
|
+
_condition_1 = (if RunService:IsClient() then 30 else 10)
|
|
22
|
+
end
|
|
23
|
+
_object[_left_1] = _condition_1
|
|
24
|
+
local _left_2 = "warnOnInvalidGuards"
|
|
25
|
+
local _condition_2 = config.warnOnInvalidGuards
|
|
26
|
+
if _condition_2 == nil then
|
|
27
|
+
_condition_2 = RunService:IsStudio()
|
|
28
|
+
end
|
|
29
|
+
_object[_left_2] = _condition_2
|
|
30
|
+
local _left_3 = "disableIncomingGuards"
|
|
31
|
+
local _condition_3 = config.disableIncomingGuards
|
|
32
|
+
if _condition_3 == nil then
|
|
33
|
+
_condition_3 = false
|
|
34
|
+
end
|
|
35
|
+
_object[_left_3] = _condition_3
|
|
36
|
+
return _object
|
|
37
|
+
end
|
|
38
|
+
local function createNetworkingFunction(globalName)
|
|
39
|
+
local signals = createSignalContainer()
|
|
40
|
+
local server
|
|
41
|
+
local client
|
|
42
|
+
return {
|
|
43
|
+
createServer = function(self, config, meta)
|
|
44
|
+
if RunService:IsRunning() and not RunService:IsServer() then
|
|
45
|
+
return nil
|
|
46
|
+
end
|
|
47
|
+
if server == nil then
|
|
48
|
+
server = createGenericHandler(globalName, nil, SERVER_PREFIX, CLIENT_PREFIX, meta, getDefaultConfiguration(config), signals, createServerMethod)
|
|
49
|
+
end
|
|
50
|
+
return server
|
|
51
|
+
end,
|
|
52
|
+
createClient = function(self, config, meta)
|
|
53
|
+
if RunService:IsRunning() and not RunService:IsClient() then
|
|
54
|
+
return nil
|
|
55
|
+
end
|
|
56
|
+
if client == nil then
|
|
57
|
+
client = createGenericHandler(globalName, nil, CLIENT_PREFIX, SERVER_PREFIX, meta, getDefaultConfiguration(config), signals, createClientMethod)
|
|
58
|
+
end
|
|
59
|
+
return client
|
|
60
|
+
end,
|
|
61
|
+
registerHandler = function(self, key, callback)
|
|
62
|
+
return signals:connect(key, callback)
|
|
63
|
+
end,
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
return {
|
|
67
|
+
createNetworkingFunction = createNetworkingFunction,
|
|
68
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FunctionReceiverInterface } from "../function/createFunctionReceiver";
|
|
2
|
+
import { FunctionSenderInterface } from "../function/createFunctionSender";
|
|
3
|
+
import { FunctionCreateConfiguration } from "./types";
|
|
4
|
+
export declare function createServerMethod(config: FunctionCreateConfiguration<unknown>, receiver?: FunctionReceiverInterface, sender?: FunctionSenderInterface): {
|
|
5
|
+
readonly _flamework_send?: unknown[] | undefined;
|
|
6
|
+
_invoke: (player: Player, payload?: buffer, blobs?: Array<defined>) => Promise<unknown>;
|
|
7
|
+
_invokeWithTimeout: (player: Player, timeout: number, payload?: buffer, blobs?: Array<defined>) => Promise<unknown>;
|
|
8
|
+
invoke: (player: Player, ...args: unknown[]) => Promise<unknown>;
|
|
9
|
+
invokeWithTimeout: (player: Player, timeout: number, ...args: unknown[]) => Promise<unknown>;
|
|
10
|
+
readonly _flamework_receive?: unknown[] | undefined;
|
|
11
|
+
readonly _flamework_fn?: unknown;
|
|
12
|
+
_setCallback: (callback: (player: Player, ...args: never[]) => unknown) => void;
|
|
13
|
+
setCallback: (callback: (player: Player, ...args: unknown[]) => unknown | Promise<unknown>) => void;
|
|
14
|
+
predict: (player: Player, ...args: unknown[]) => Promise<unknown>;
|
|
15
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local NetworkingFunctionError = TS.import(script, script.Parent.Parent, "function", "errors").NetworkingFunctionError
|
|
4
|
+
local timeoutPromise = TS.import(script, script.Parent.Parent, "util", "timeoutPromise").timeoutPromise
|
|
5
|
+
local function createServerMethod(config, receiver, sender)
|
|
6
|
+
local method = {
|
|
7
|
+
invoke = function(self, player, ...)
|
|
8
|
+
local args = { ... }
|
|
9
|
+
return self:invokeWithTimeout(player, config.defaultTimeout, unpack(args))
|
|
10
|
+
end,
|
|
11
|
+
invokeWithTimeout = function(self, player, timeout, ...)
|
|
12
|
+
local args = { ... }
|
|
13
|
+
local _sender = sender
|
|
14
|
+
assert(_sender, "This is not a sender remote.")
|
|
15
|
+
return TS.Promise.race({ timeoutPromise(timeout, NetworkingFunctionError.Timeout), sender:invokeClient(player, unpack(args)) })
|
|
16
|
+
end,
|
|
17
|
+
_invoke = function(self, player, ...)
|
|
18
|
+
local packed = { ... }
|
|
19
|
+
return self:invokeWithTimeout(player, config.defaultTimeout, unpack(packed))
|
|
20
|
+
end,
|
|
21
|
+
_invokeWithTimeout = function(self, player, timeout, ...)
|
|
22
|
+
local packed = { ... }
|
|
23
|
+
return self:invokeWithTimeout(player, timeout, unpack(packed))
|
|
24
|
+
end,
|
|
25
|
+
setCallback = function(self, callback)
|
|
26
|
+
local _receiver = receiver
|
|
27
|
+
assert(_receiver, "This is not a receiver remote.")
|
|
28
|
+
receiver:setServerCallback(callback)
|
|
29
|
+
end,
|
|
30
|
+
_setCallback = function(self, callback)
|
|
31
|
+
local _receiver = receiver
|
|
32
|
+
assert(_receiver, "This is not a receiver remote.")
|
|
33
|
+
receiver:setServerCallback(callback, true)
|
|
34
|
+
end,
|
|
35
|
+
predict = function(self, player, ...)
|
|
36
|
+
local args = { ... }
|
|
37
|
+
local _receiver = receiver
|
|
38
|
+
assert(_receiver, "This is not a receiver remote.")
|
|
39
|
+
return receiver:invoke(player, unpack(args))
|
|
40
|
+
end,
|
|
41
|
+
}
|
|
42
|
+
setmetatable(method, {
|
|
43
|
+
__call = function(method, player, ...)
|
|
44
|
+
local args = { ... }
|
|
45
|
+
return method:invoke(player, unpack(args))
|
|
46
|
+
end,
|
|
47
|
+
})
|
|
48
|
+
return method
|
|
49
|
+
end
|
|
50
|
+
return {
|
|
51
|
+
createServerMethod = createServerMethod,
|
|
52
|
+
}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { NetworkingFunctionError } from "../function/errors";
|
|
2
|
+
import {
|
|
3
|
+
FunctionParameters,
|
|
4
|
+
FunctionReturn,
|
|
5
|
+
IntrinsicTupleGuards,
|
|
6
|
+
IntrinsicNetworkDecoder,
|
|
7
|
+
IntrinsicNetworkResultDecoder,
|
|
8
|
+
IntrinsicObfuscate,
|
|
9
|
+
NetworkingObfuscationMarker,
|
|
10
|
+
NetworkRaw,
|
|
11
|
+
ObfuscateNames,
|
|
12
|
+
} from "../types";
|
|
13
|
+
import { FunctionNetworkingEvents } from "../handlers";
|
|
14
|
+
import { FunctionMiddleware } from "../middleware/types";
|
|
15
|
+
import { Modding } from "@flamework-experimental/core";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A sender declared `Networking.Raw`: its arguments and the result travel as they are. Without the
|
|
19
|
+
* hidden marker below, no call site packs them and the peer runs no decoder.
|
|
20
|
+
*/
|
|
21
|
+
export interface RawServerSender<I extends unknown[], O> {
|
|
22
|
+
(player: Player, ...args: I): Promise<O>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Sends this request to the specified player.
|
|
26
|
+
* @param player The player that will receive this event
|
|
27
|
+
*/
|
|
28
|
+
invoke(player: Player, ...args: I): Promise<O>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Sends this request to the specified player, specifying a timeout.
|
|
32
|
+
* @param player The player that will receive this event
|
|
33
|
+
* @param timeout The maximum time to wait before timing out
|
|
34
|
+
*/
|
|
35
|
+
invokeWithTimeout(player: Player, timeout: number, ...args: I): Promise<O>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ServerSender<I extends unknown[], O> extends RawServerSender<I, O> {
|
|
39
|
+
/** @hidden Marks a sender for the transformer, which packs its arguments at each call site. */
|
|
40
|
+
readonly _flamework_send?: I;
|
|
41
|
+
|
|
42
|
+
/** @hidden Sends an argument list the transformer already packed; nothing when the list carries nothing. */
|
|
43
|
+
_invoke(player: Player, payload?: buffer, blobs?: Array<defined>): Promise<O>;
|
|
44
|
+
|
|
45
|
+
/** @hidden Sends an argument list the transformer already packed; nothing when the list carries nothing. */
|
|
46
|
+
_invokeWithTimeout(player: Player, timeout: number, payload?: buffer, blobs?: Array<defined>): Promise<O>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface RawServerReceiver<I extends unknown[], O> {
|
|
50
|
+
/**
|
|
51
|
+
* Connect to a networking event.
|
|
52
|
+
* @param event The event to connect to
|
|
53
|
+
* @param callback The callback that will be invoked
|
|
54
|
+
* @param guards A list of guards that will only be used on this connection
|
|
55
|
+
*/
|
|
56
|
+
setCallback(callback: (player: Player, ...args: I) => O | Promise<O>): void;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Invokes a server function using player as the sender.
|
|
60
|
+
*/
|
|
61
|
+
predict(player: Player, ...args: I): Promise<O>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface ServerReceiver<I extends unknown[], O, F = unknown> extends RawServerReceiver<I, O> {
|
|
65
|
+
/** @hidden Marks a receiver for the transformer, which packs the callback's result at the call site. */
|
|
66
|
+
readonly _flamework_receive?: I;
|
|
67
|
+
|
|
68
|
+
/** @hidden The declared function type; its return type is what the transformer packs. */
|
|
69
|
+
readonly _flamework_fn?: F;
|
|
70
|
+
|
|
71
|
+
/** @hidden Registers a callback whose successful results are already packed as `[payload, blobs?]`. */
|
|
72
|
+
_setCallback(callback: (player: Player, ...args: never[]) => unknown): void;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface RawClientSender<I extends unknown[], O> {
|
|
76
|
+
(...args: I): Promise<O>;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Sends this request to the server.
|
|
80
|
+
*/
|
|
81
|
+
invoke(...args: I): Promise<O>;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Sends this request to the server, specifying a timeout.
|
|
85
|
+
* @param timeout The maximum time to wait before timing out
|
|
86
|
+
*/
|
|
87
|
+
invokeWithTimeout(timeout: number, ...args: I): Promise<O>;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface ClientSender<I extends unknown[], O> extends RawClientSender<I, O> {
|
|
91
|
+
/** @hidden Marks a sender for the transformer, which packs its arguments at each call site. */
|
|
92
|
+
readonly _flamework_send?: I;
|
|
93
|
+
|
|
94
|
+
/** @hidden Sends an argument list the transformer already packed; nothing when the list carries nothing. */
|
|
95
|
+
_invoke(payload?: buffer, blobs?: Array<defined>): Promise<O>;
|
|
96
|
+
|
|
97
|
+
/** @hidden Sends an argument list the transformer already packed; nothing when the list carries nothing. */
|
|
98
|
+
_invokeWithTimeout(timeout: number, payload?: buffer, blobs?: Array<defined>): Promise<O>;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface RawClientReceiver<I extends unknown[], O> {
|
|
102
|
+
/**
|
|
103
|
+
* Connect to a networking function.
|
|
104
|
+
* @param event The function to connect to
|
|
105
|
+
* @param callback The callback that will be invoked
|
|
106
|
+
*/
|
|
107
|
+
setCallback(callback: (...args: I) => O | Promise<O>): void;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Invokes a client function.
|
|
111
|
+
*/
|
|
112
|
+
predict(...args: I): Promise<O>;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface ClientReceiver<I extends unknown[], O, F = unknown> extends RawClientReceiver<I, O> {
|
|
116
|
+
/** @hidden Marks a receiver for the transformer, which packs the callback's result at the call site. */
|
|
117
|
+
readonly _flamework_receive?: I;
|
|
118
|
+
|
|
119
|
+
/** @hidden The declared function type; its return type is what the transformer packs. */
|
|
120
|
+
readonly _flamework_fn?: F;
|
|
121
|
+
|
|
122
|
+
/** @hidden Registers a callback whose successful results are already packed as `[payload, blobs?]`. */
|
|
123
|
+
_setCallback(callback: (...args: never[]) => unknown): void;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export type ServerHandler<E, R> = NetworkingObfuscationMarker & {
|
|
127
|
+
[k in keyof Functions<E>]: E[k] extends NetworkRaw<unknown>
|
|
128
|
+
? RawServerSender<FunctionParameters<E[k]>, FunctionReturn<E[k]>>
|
|
129
|
+
: ServerSender<FunctionParameters<E[k]>, FunctionReturn<E[k]>>;
|
|
130
|
+
} & {
|
|
131
|
+
[k in keyof Functions<R>]: R[k] extends NetworkRaw<unknown>
|
|
132
|
+
? RawServerReceiver<FunctionParameters<R[k]>, FunctionReturn<R[k]>>
|
|
133
|
+
: ServerReceiver<FunctionParameters<R[k]>, FunctionReturn<R[k]>, R[k]>;
|
|
134
|
+
} & {
|
|
135
|
+
[k in keyof FunctionNamespaces<E>]: ServerHandler<E[k], k extends keyof R ? R[k] : {}>;
|
|
136
|
+
} & {
|
|
137
|
+
[k in keyof FunctionNamespaces<R>]: ServerHandler<k extends keyof E ? E[k] : {}, R[k]>;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export type ClientHandler<E, R> = NetworkingObfuscationMarker & {
|
|
141
|
+
[k in keyof Functions<E>]: E[k] extends NetworkRaw<unknown>
|
|
142
|
+
? RawClientSender<FunctionParameters<E[k]>, FunctionReturn<E[k]>>
|
|
143
|
+
: ClientSender<FunctionParameters<E[k]>, FunctionReturn<E[k]>>;
|
|
144
|
+
} & {
|
|
145
|
+
[k in keyof Functions<R>]: R[k] extends NetworkRaw<unknown>
|
|
146
|
+
? RawClientReceiver<FunctionParameters<R[k]>, FunctionReturn<R[k]>>
|
|
147
|
+
: ClientReceiver<FunctionParameters<R[k]>, FunctionReturn<R[k]>, R[k]>;
|
|
148
|
+
} & {
|
|
149
|
+
[k in keyof FunctionNamespaces<E>]: ClientHandler<E[k], k extends keyof R ? R[k] : {}>;
|
|
150
|
+
} & {
|
|
151
|
+
[k in keyof FunctionNamespaces<R>]: ClientHandler<k extends keyof E ? E[k] : {}, R[k]>;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export interface FunctionCreateConfiguration<T> {
|
|
155
|
+
/**
|
|
156
|
+
* Disables input validation, allowing any value to pass.
|
|
157
|
+
* Defaults to `false`
|
|
158
|
+
*/
|
|
159
|
+
disableIncomingGuards: boolean;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Emit a warning whenever a guard fails.
|
|
163
|
+
* Defaults to `RunService.IsStudio()`
|
|
164
|
+
*/
|
|
165
|
+
warnOnInvalidGuards: boolean;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* The default timeout for outgoing requests.
|
|
169
|
+
* Defaults to `10`
|
|
170
|
+
*/
|
|
171
|
+
defaultTimeout: number;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* The middleware for each event.
|
|
175
|
+
*/
|
|
176
|
+
middleware: FunctionMiddlewareList<T>;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface GlobalFunction<S, C> {
|
|
180
|
+
/**
|
|
181
|
+
* This is the server implementation of the network and does not exist on the client.
|
|
182
|
+
*
|
|
183
|
+
* @metadata macro {@link config intrinsic-const} {@link config intrinsic-middleware}
|
|
184
|
+
*/
|
|
185
|
+
createServer(config: Partial<FunctionCreateConfiguration<S>>, meta?: NamespaceMetadata<S, C>): ServerHandler<C, S>;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* This is the client implementation of the network and does not exist on the server.
|
|
189
|
+
*
|
|
190
|
+
* @metadata macro {@link config intrinsic-const} {@link config intrinsic-middleware}
|
|
191
|
+
*/
|
|
192
|
+
createClient(config: Partial<FunctionCreateConfiguration<C>>, meta?: NamespaceMetadata<C, S>): ClientHandler<S, C>;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Registers a networking event handler.
|
|
196
|
+
* @param key The name of the event
|
|
197
|
+
* @param callback The handler you wish to attach
|
|
198
|
+
*/
|
|
199
|
+
registerHandler<K extends keyof FunctionNetworkingEvents>(
|
|
200
|
+
key: K,
|
|
201
|
+
callback: FunctionNetworkingEvents[K],
|
|
202
|
+
): RBXScriptConnection;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface FunctionConfiguration {
|
|
206
|
+
/**
|
|
207
|
+
* Disables input validation and return validation on the server, allowing any value to pass.
|
|
208
|
+
* Defaults to `false`
|
|
209
|
+
*/
|
|
210
|
+
disableServerGuards: boolean;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Disables input validation and return validation on the client, allowing any value to pass.
|
|
214
|
+
* Defaults to `false`
|
|
215
|
+
*/
|
|
216
|
+
disableClientGuards: boolean;
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* The default timeout for requests from the server to the client.
|
|
220
|
+
* Defaults to `10`
|
|
221
|
+
*/
|
|
222
|
+
defaultServerTimeout: number;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* The default timeout for requests from the client to the server.
|
|
226
|
+
* Defaults to `30`
|
|
227
|
+
*/
|
|
228
|
+
defaultClientTimeout: number;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Emit a warning whenever a guard fails.
|
|
232
|
+
* Defaults to `RunService.IsStudio()`
|
|
233
|
+
*/
|
|
234
|
+
warnOnInvalidGuards: boolean;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export interface RequestInfo {
|
|
238
|
+
nextId: number;
|
|
239
|
+
requests: Map<number, (value: unknown, rejection?: NetworkingFunctionError) => void>;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export type FunctionNamespaces<T> = ExcludeMembers<T, Callback>;
|
|
243
|
+
export type Functions<T> = ExtractMembers<T, Callback>;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* We must generate the return type of events separately as Flamework no longer includes all type guards on both server and client.
|
|
247
|
+
*/
|
|
248
|
+
export type NamespaceMetadata<R, S> = Modding.Emit<{
|
|
249
|
+
incomingIds: ObfuscateNames<keyof Functions<R>>;
|
|
250
|
+
incoming: IntrinsicObfuscate<{ [k in keyof Functions<R>]: IntrinsicTupleGuards<Parameters<R[k]>> }>;
|
|
251
|
+
|
|
252
|
+
outgoingIds: ObfuscateNames<keyof Functions<S>>;
|
|
253
|
+
outgoing: IntrinsicObfuscate<{ [k in keyof Functions<S>]: Modding.Target.Guard<ReturnType<S[k]>> }>;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Decoders, present only with `networking.serialization` on and absent for raw functions: the
|
|
257
|
+
* argument lists of requests this realm receives, the results its callbacks return (so `predict`
|
|
258
|
+
* can unpack them) and the responses to requests it sends. Requests and results are packed inline
|
|
259
|
+
* where they are produced.
|
|
260
|
+
*/
|
|
261
|
+
incomingSerializers: IntrinsicObfuscate<{
|
|
262
|
+
[k in keyof Functions<R>]: R[k] extends NetworkRaw<unknown>
|
|
263
|
+
? undefined
|
|
264
|
+
: IntrinsicNetworkDecoder<Parameters<R[k]>>;
|
|
265
|
+
}>;
|
|
266
|
+
incomingResults: IntrinsicObfuscate<{
|
|
267
|
+
[k in keyof Functions<R>]: R[k] extends NetworkRaw<unknown> ? undefined : IntrinsicNetworkResultDecoder<R[k]>;
|
|
268
|
+
}>;
|
|
269
|
+
outgoingResults: IntrinsicObfuscate<{
|
|
270
|
+
[k in keyof Functions<S>]: S[k] extends NetworkRaw<unknown> ? undefined : IntrinsicNetworkResultDecoder<S[k]>;
|
|
271
|
+
}>;
|
|
272
|
+
|
|
273
|
+
namespaceIds: ObfuscateNames<keyof FunctionNamespaces<R> | keyof FunctionNamespaces<S>>;
|
|
274
|
+
namespaces: IntrinsicObfuscate<
|
|
275
|
+
{
|
|
276
|
+
[k in keyof FunctionNamespaces<R>]: NamespaceMetadata<R[k], k extends keyof S ? S[k] : {}>;
|
|
277
|
+
} & {
|
|
278
|
+
[k in keyof FunctionNamespaces<S>]: NamespaceMetadata<k extends keyof R ? R[k] : {}, S[k]>;
|
|
279
|
+
}
|
|
280
|
+
>;
|
|
281
|
+
}>;
|
|
282
|
+
|
|
283
|
+
export type FunctionMiddlewareList<T> = {
|
|
284
|
+
readonly [k in keyof Functions<T>]?: T[k] extends (...args: infer I) => infer O
|
|
285
|
+
? [...FunctionMiddleware<I, O>[]]
|
|
286
|
+
: never;
|
|
287
|
+
} & {
|
|
288
|
+
readonly [k in keyof FunctionNamespaces<T>]?: FunctionMiddlewareList<T[k]>;
|
|
289
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import Signal from "@rbxts/signal";
|
|
2
|
+
import { NetworkInfo } from "./types";
|
|
3
|
+
|
|
4
|
+
interface BaseEvent {
|
|
5
|
+
/**
|
|
6
|
+
* The event or function that was fired.
|
|
7
|
+
*/
|
|
8
|
+
networkInfo: NetworkInfo;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface BadRequestData extends BaseEvent {
|
|
12
|
+
/**
|
|
13
|
+
* The index of the argument that was incorrect, or -1 when a serialized payload could not be decoded.
|
|
14
|
+
*/
|
|
15
|
+
argIndex: number;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The value of the argument that was incorrect, or the decoding error for a malformed payload.
|
|
19
|
+
*/
|
|
20
|
+
argValue: unknown;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface BadResponseData extends BaseEvent {
|
|
24
|
+
/**
|
|
25
|
+
* The index of the argument that was incorrect.
|
|
26
|
+
*/
|
|
27
|
+
value: unknown;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface EventNetworkingEvents {
|
|
31
|
+
onBadRequest: (player: Player, data: BadRequestData) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface FunctionNetworkingEvents extends EventNetworkingEvents {
|
|
35
|
+
onBadResponse: (player: Player, data: BadResponseData) => void;
|
|
36
|
+
}
|
package/out/index.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { GlobalEvent } from "./events/types";
|
|
2
|
+
import { GlobalFunction } from "./functions/types";
|
|
3
|
+
import { Skip as NetworkingSkip } from "./middleware/skip";
|
|
4
|
+
import { NetworkingFunctionError } from "./function/errors";
|
|
5
|
+
import { EventMiddleware as _EventMiddleware, FunctionMiddleware as _FunctionMiddleware } from "./middleware/types";
|
|
6
|
+
import { NetworkRaw, NetworkUnreliable } from "./types";
|
|
7
|
+
import type { Modding } from "@flamework-experimental/core";
|
|
8
|
+
export declare namespace Networking {
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new event based off the supplied types.
|
|
11
|
+
* @param serverMiddleware Middleware for server events
|
|
12
|
+
* @param clientMiddleware Middleware for client events
|
|
13
|
+
* @metadata macro
|
|
14
|
+
*/
|
|
15
|
+
function createEvent<S, C>(name?: Modding.Caller.Uuid): GlobalEvent<S, C>;
|
|
16
|
+
/**
|
|
17
|
+
* Creates a new function event based off the supplied types.
|
|
18
|
+
* @param serverMiddleware Middleware for server events
|
|
19
|
+
* @param clientMiddleware Middleware for client events
|
|
20
|
+
* @metadata macro
|
|
21
|
+
*/
|
|
22
|
+
function createFunction<S, C>(name?: Modding.Caller.Uuid): GlobalFunction<S, C>;
|
|
23
|
+
/**
|
|
24
|
+
* Stops networking function middleware.
|
|
25
|
+
*/
|
|
26
|
+
const Skip: NetworkingSkip;
|
|
27
|
+
/**
|
|
28
|
+
* Specifies that this event is unreliable.
|
|
29
|
+
*
|
|
30
|
+
* This will only work on remote events.
|
|
31
|
+
*/
|
|
32
|
+
type Unreliable<T> = NetworkUnreliable<T>;
|
|
33
|
+
/**
|
|
34
|
+
* Sends this event's arguments as they are, bypassing `networking.serialization` for this event
|
|
35
|
+
* alone. The generated guards still run on what arrives.
|
|
36
|
+
*/
|
|
37
|
+
type RawReliable<T> = NetworkRaw<T>;
|
|
38
|
+
/**
|
|
39
|
+
* An unreliable event whose arguments bypass serialization; see {@link RawReliable}.
|
|
40
|
+
*/
|
|
41
|
+
type RawUnreliable<T> = NetworkUnreliable<NetworkRaw<T>>;
|
|
42
|
+
/**
|
|
43
|
+
* A function whose requests and results bypass serialization; see {@link RawReliable}.
|
|
44
|
+
*/
|
|
45
|
+
type Raw<T> = NetworkRaw<T>;
|
|
46
|
+
/**
|
|
47
|
+
* A function that generates an event middleware.
|
|
48
|
+
*/
|
|
49
|
+
type EventMiddleware<I extends readonly unknown[] = unknown[]> = _EventMiddleware<I>;
|
|
50
|
+
/**
|
|
51
|
+
* A function that generates an event middleware.
|
|
52
|
+
*/
|
|
53
|
+
type FunctionMiddleware<I extends readonly unknown[] = unknown[], O = void> = _FunctionMiddleware<I, O>;
|
|
54
|
+
}
|
|
55
|
+
export { NetworkingFunctionError };
|