@skating/swiftpacket 0.1.4
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/LICENSE +21 -0
- package/README.md +123 -0
- package/package.json +31 -0
- package/src/client.luau +472 -0
- package/src/configuration.luau +74 -0
- package/src/cursor.luau +18 -0
- package/src/index.d.ts +122 -0
- package/src/init.luau +199 -0
- package/src/packet.luau +186 -0
- package/src/rate_limit.luau +38 -0
- package/src/registry.luau +40 -0
- package/src/schema.luau +1606 -0
- package/src/server.luau +691 -0
- package/src/signal.luau +145 -0
- package/src/thread_pool.luau +37 -0
- package/src/wire.luau +218 -0
package/src/cursor.luau
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!optimize 2
|
|
3
|
+
|
|
4
|
+
--[[
|
|
5
|
+
Author: @skaterstudios
|
|
6
|
+
Website: skaterstudios.com
|
|
7
|
+
GitHub: github.com/skatingii/SwiftPacket
|
|
8
|
+
Discord Server: discord.gg/skaterstudios
|
|
9
|
+
|
|
10
|
+
Licensed under the MIT License. You may use, modify, redistribute and sell
|
|
11
|
+
this system freely, as long as this notice and the LICENSE file stay with it.
|
|
12
|
+
]]
|
|
13
|
+
|
|
14
|
+
const Schema = require("./schema")
|
|
15
|
+
|
|
16
|
+
export type Cursor = Schema.Cursor
|
|
17
|
+
|
|
18
|
+
return Schema.Cursor
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
declare namespace SwiftPacket {
|
|
2
|
+
type Results<R extends unknown[]> = R extends [] ? void : R extends [infer T] ? T : LuaTuple<R>;
|
|
3
|
+
|
|
4
|
+
type OptionalKeys<T> = { [K in keyof T]-?: undefined extends T[K] ? K : never }[keyof T];
|
|
5
|
+
|
|
6
|
+
type Shape<T> = { [K in Exclude<keyof T, OptionalKeys<T>>]: T[K] } & { [K in OptionalKeys<T>]?: T[K] };
|
|
7
|
+
|
|
8
|
+
type Flatten<T> = { [K in keyof T]: T[K] };
|
|
9
|
+
|
|
10
|
+
interface Options {
|
|
11
|
+
Logging?: boolean;
|
|
12
|
+
IncomingBytesPerSecond?: number;
|
|
13
|
+
UnreliableByteLimit?: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface Connection {
|
|
17
|
+
readonly Connected: boolean;
|
|
18
|
+
Disconnect(): void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface Signal<A extends unknown[]> {
|
|
22
|
+
Connect(callback: (...args: A) => void): Connection;
|
|
23
|
+
Once(callback: (...args: A) => void): Connection;
|
|
24
|
+
Wait(): LuaTuple<A>;
|
|
25
|
+
DisconnectAll(): void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface Event<A extends unknown[]> {
|
|
29
|
+
readonly Name: string;
|
|
30
|
+
readonly OnServerEvent: Signal<[player: Player, ...args: A]>;
|
|
31
|
+
readonly OnClientEvent: Signal<A>;
|
|
32
|
+
Fire(...args: A): void;
|
|
33
|
+
FireClient(player: Player, ...args: A): void;
|
|
34
|
+
FireClients(players: ReadonlyArray<Player>, ...args: A): void;
|
|
35
|
+
FireExcept(player: Player, ...args: A): void;
|
|
36
|
+
Response<R extends unknown[]>(...types: R): Request<A, R>;
|
|
37
|
+
Unreliable(): Event<A>;
|
|
38
|
+
RateLimit(count: number, interval: number): Event<A>;
|
|
39
|
+
Validate(validator: (player: Player, ...args: A) => boolean): Event<A>;
|
|
40
|
+
Serialize(...args: A): LuaTuple<[buffer, Array<Instance> | undefined]>;
|
|
41
|
+
Deserialize(data: buffer, instances?: ReadonlyArray<Instance>): Results<A>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface Request<A extends unknown[], R extends unknown[]> {
|
|
45
|
+
readonly Name: string;
|
|
46
|
+
OnServerInvoke?: (player: Player, ...args: A) => Results<R>;
|
|
47
|
+
OnClientInvoke?: (...args: A) => Results<R>;
|
|
48
|
+
Fire(...args: A): Results<R>;
|
|
49
|
+
FireClient(player: Player, ...args: A): Results<R>;
|
|
50
|
+
SetServerInvoke(handler: (player: Player, ...args: A) => Results<R>): Request<A, R>;
|
|
51
|
+
SetClientInvoke(handler: (...args: A) => Results<R>): Request<A, R>;
|
|
52
|
+
Timeout(seconds: number, ...fallback: R): Request<A, R>;
|
|
53
|
+
RateLimit(count: number, interval: number): Request<A, R>;
|
|
54
|
+
Validate(validator: (player: Player, ...args: A) => boolean): Request<A, R>;
|
|
55
|
+
Serialize(...args: A): LuaTuple<[buffer, Array<Instance> | undefined]>;
|
|
56
|
+
Deserialize(data: buffer, instances?: ReadonlyArray<Instance>): Results<A>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface Library {
|
|
60
|
+
<A extends unknown[]>(name: string, ...types: A): Event<A>;
|
|
61
|
+
|
|
62
|
+
readonly Version: string;
|
|
63
|
+
readonly Configure: (options: Options) => void;
|
|
64
|
+
|
|
65
|
+
readonly Any: unknown;
|
|
66
|
+
readonly Nil: undefined;
|
|
67
|
+
readonly Boolean: boolean;
|
|
68
|
+
|
|
69
|
+
readonly U8: number;
|
|
70
|
+
readonly U16: number;
|
|
71
|
+
readonly U24: number;
|
|
72
|
+
readonly U32: number;
|
|
73
|
+
readonly I8: number;
|
|
74
|
+
readonly I16: number;
|
|
75
|
+
readonly I24: number;
|
|
76
|
+
readonly I32: number;
|
|
77
|
+
readonly F16: number;
|
|
78
|
+
readonly F24: number;
|
|
79
|
+
readonly F32: number;
|
|
80
|
+
readonly F64: number;
|
|
81
|
+
|
|
82
|
+
readonly String: string;
|
|
83
|
+
readonly Characters: string;
|
|
84
|
+
readonly Buffer: buffer;
|
|
85
|
+
readonly Instance: Instance | undefined;
|
|
86
|
+
|
|
87
|
+
readonly Vector2: Vector2;
|
|
88
|
+
readonly Vector2F16: Vector2;
|
|
89
|
+
readonly Vector2I16: Vector2;
|
|
90
|
+
readonly Vector3: Vector3;
|
|
91
|
+
readonly Vector3F24: Vector3;
|
|
92
|
+
readonly Vector3F16: Vector3;
|
|
93
|
+
readonly Vector3I16: Vector3;
|
|
94
|
+
readonly CFrame: CFrame;
|
|
95
|
+
readonly CFrameF24: CFrame;
|
|
96
|
+
|
|
97
|
+
readonly Color3: Color3;
|
|
98
|
+
readonly BrickColor: BrickColor;
|
|
99
|
+
readonly UDim: UDim;
|
|
100
|
+
readonly UDim2: UDim2;
|
|
101
|
+
readonly Rect: Rect;
|
|
102
|
+
readonly NumberRange: NumberRange;
|
|
103
|
+
readonly NumberSequence: NumberSequence;
|
|
104
|
+
readonly ColorSequence: ColorSequence;
|
|
105
|
+
readonly DateTime: DateTime;
|
|
106
|
+
|
|
107
|
+
readonly Array: <T>(element: T, maximumLength?: number) => Array<T>;
|
|
108
|
+
readonly Map: <K, V>(key: K, value: V, maximumCount?: number) => Map<K, V>;
|
|
109
|
+
readonly Struct: <T extends object>(shape: T) => Flatten<Shape<T>>;
|
|
110
|
+
readonly Optional: <T>(inner: T) => T | undefined;
|
|
111
|
+
readonly Static: <const T>(values: ReadonlyArray<T>) => T;
|
|
112
|
+
readonly Range: (inner: number, minimum: number, maximum: number) => number;
|
|
113
|
+
readonly Flags: <const N extends string>(names: ReadonlyArray<N>) => Record<N, boolean>;
|
|
114
|
+
readonly Charset: (characters: string) => string;
|
|
115
|
+
readonly InstanceOf: <T extends keyof Instances>(className: T) => Instances[T] | undefined;
|
|
116
|
+
readonly EnumItem: <T extends EnumItem>(enumType: { GetEnumItems(): Array<T> }) => T;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
declare const SwiftPacket: SwiftPacket.Library;
|
|
121
|
+
|
|
122
|
+
export = SwiftPacket;
|
package/src/init.luau
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
--!nonstrict
|
|
2
|
+
--!optimize 2
|
|
3
|
+
|
|
4
|
+
--[[
|
|
5
|
+
Author: @skaterstudios
|
|
6
|
+
Website: skaterstudios.com
|
|
7
|
+
GitHub: github.com/skatingii/SwiftPacket
|
|
8
|
+
Discord Server: discord.gg/skaterstudios
|
|
9
|
+
|
|
10
|
+
Licensed under the MIT License. You may use, modify, redistribute and sell
|
|
11
|
+
this system freely, as long as this notice and the LICENSE file stay with it.
|
|
12
|
+
]]
|
|
13
|
+
|
|
14
|
+
const RunService = game:GetService("RunService")
|
|
15
|
+
|
|
16
|
+
const Client = require("@self/client")
|
|
17
|
+
const Configuration = require("@self/configuration")
|
|
18
|
+
const Packet = require("@self/packet")
|
|
19
|
+
const Schema = require("@self/schema")
|
|
20
|
+
const Server = require("@self/server")
|
|
21
|
+
|
|
22
|
+
export type Options = Configuration.Options
|
|
23
|
+
|
|
24
|
+
export type Connection = {
|
|
25
|
+
Connected: boolean,
|
|
26
|
+
Disconnect: (self: Connection) -> (),
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type Signal<A...> = {
|
|
30
|
+
Connect: (self: Signal<A...>, Callback: (A...) -> ()) -> Connection,
|
|
31
|
+
Once: (self: Signal<A...>, Callback: (A...) -> ()) -> Connection,
|
|
32
|
+
Wait: (self: Signal<A...>) -> A...,
|
|
33
|
+
DisconnectAll: (self: Signal<A...>) -> (),
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type Request<A..., B...> = {
|
|
37
|
+
Name: string,
|
|
38
|
+
OnServerInvoke: ((Player: Player, A...) -> B...)?,
|
|
39
|
+
OnClientInvoke: ((A...) -> B...)?,
|
|
40
|
+
Fire: (self: Request<A..., B...>, A...) -> B...,
|
|
41
|
+
FireClient: (self: Request<A..., B...>, Player: Player, A...) -> B...,
|
|
42
|
+
SetServerInvoke: (self: Request<A..., B...>, Handler: (Player: Player, A...) -> B...) -> Request<A..., B...>,
|
|
43
|
+
SetClientInvoke: (self: Request<A..., B...>, Handler: (A...) -> B...) -> Request<A..., B...>,
|
|
44
|
+
Timeout: (self: Request<A..., B...>, Seconds: number, B...) -> Request<A..., B...>,
|
|
45
|
+
RateLimit: (self: Request<A..., B...>, Count: number, Interval: number) -> Request<A..., B...>,
|
|
46
|
+
Validate: (self: Request<A..., B...>, Validator: (Player: Player, A...) -> boolean) -> Request<A..., B...>,
|
|
47
|
+
Serialize: (self: Request<A..., B...>, A...) -> (buffer, { Instance }?),
|
|
48
|
+
Deserialize: (self: Request<A..., B...>, Data: buffer, Instances: { Instance }?) -> A...,
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type Event<A...> = {
|
|
52
|
+
Name: string,
|
|
53
|
+
OnServerEvent: Signal<(Player, A...)>,
|
|
54
|
+
OnClientEvent: Signal<A...>,
|
|
55
|
+
Fire: (self: Event<A...>, A...) -> (),
|
|
56
|
+
FireClient: (self: Event<A...>, Player: Player, A...) -> (),
|
|
57
|
+
FireClients: (self: Event<A...>, Players: { Player }, A...) -> (),
|
|
58
|
+
FireExcept: (self: Event<A...>, Player: Player, A...) -> (),
|
|
59
|
+
Response: <B...>(self: Event<A...>, B...) -> Request<A..., B...>,
|
|
60
|
+
Unreliable: (self: Event<A...>) -> Event<A...>,
|
|
61
|
+
RateLimit: (self: Event<A...>, Count: number, Interval: number) -> Event<A...>,
|
|
62
|
+
Validate: (self: Event<A...>, Validator: (Player: Player, A...) -> boolean) -> Event<A...>,
|
|
63
|
+
Serialize: (self: Event<A...>, A...) -> (buffer, { Instance }?),
|
|
64
|
+
Deserialize: (self: Event<A...>, Data: buffer, Instances: { Instance }?) -> A...,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type Fields = {
|
|
68
|
+
Version: string,
|
|
69
|
+
Configure: (Options: Options) -> (),
|
|
70
|
+
|
|
71
|
+
Any: any,
|
|
72
|
+
Nil: nil,
|
|
73
|
+
Boolean: boolean,
|
|
74
|
+
|
|
75
|
+
U8: number,
|
|
76
|
+
U16: number,
|
|
77
|
+
U24: number,
|
|
78
|
+
U32: number,
|
|
79
|
+
I8: number,
|
|
80
|
+
I16: number,
|
|
81
|
+
I24: number,
|
|
82
|
+
I32: number,
|
|
83
|
+
F16: number,
|
|
84
|
+
F24: number,
|
|
85
|
+
F32: number,
|
|
86
|
+
F64: number,
|
|
87
|
+
|
|
88
|
+
String: string,
|
|
89
|
+
Characters: string,
|
|
90
|
+
Buffer: buffer,
|
|
91
|
+
Instance: Instance?,
|
|
92
|
+
|
|
93
|
+
Vector2: Vector2,
|
|
94
|
+
Vector2F16: Vector2,
|
|
95
|
+
Vector2I16: Vector2,
|
|
96
|
+
Vector3: Vector3,
|
|
97
|
+
Vector3F24: Vector3,
|
|
98
|
+
Vector3F16: Vector3,
|
|
99
|
+
Vector3I16: Vector3,
|
|
100
|
+
CFrame: CFrame,
|
|
101
|
+
CFrameF24: CFrame,
|
|
102
|
+
|
|
103
|
+
Color3: Color3,
|
|
104
|
+
BrickColor: BrickColor,
|
|
105
|
+
UDim: UDim,
|
|
106
|
+
UDim2: UDim2,
|
|
107
|
+
Rect: Rect,
|
|
108
|
+
NumberRange: NumberRange,
|
|
109
|
+
NumberSequence: NumberSequence,
|
|
110
|
+
ColorSequence: ColorSequence,
|
|
111
|
+
DateTime: DateTime,
|
|
112
|
+
|
|
113
|
+
Array: <T>(Element: T, MaximumLength: number?) -> { T },
|
|
114
|
+
Map: <K, V>(Key: K, Value: V, MaximumCount: number?) -> { [K]: V },
|
|
115
|
+
Struct: <T>(Shape: T) -> T,
|
|
116
|
+
Optional: <T>(Inner: T) -> T?,
|
|
117
|
+
Static: <T>(Values: { T }) -> T,
|
|
118
|
+
Range: (Inner: number, Minimum: number, Maximum: number) -> number,
|
|
119
|
+
Flags: (Names: { string }) -> { [string]: boolean },
|
|
120
|
+
Charset: (Characters: string) -> string,
|
|
121
|
+
InstanceOf: (ClassName: string) -> Instance?,
|
|
122
|
+
EnumItem: (EnumType: Enum) -> EnumItem,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export type SwiftPacket = setmetatable<Fields, {
|
|
126
|
+
__call: <A...>(self: Fields, Name: string, A...) -> Event<A...>,
|
|
127
|
+
}>
|
|
128
|
+
|
|
129
|
+
if RunService:IsServer() then
|
|
130
|
+
Server.Start(script)
|
|
131
|
+
else
|
|
132
|
+
Client.Start(script)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
const Library = {
|
|
136
|
+
Version = "0.1.4",
|
|
137
|
+
Configure = Configuration.Configure,
|
|
138
|
+
|
|
139
|
+
Any = Schema.Any,
|
|
140
|
+
Nil = Schema.Nil,
|
|
141
|
+
Boolean = Schema.Boolean,
|
|
142
|
+
|
|
143
|
+
U8 = Schema.U8,
|
|
144
|
+
U16 = Schema.U16,
|
|
145
|
+
U24 = Schema.U24,
|
|
146
|
+
U32 = Schema.U32,
|
|
147
|
+
I8 = Schema.I8,
|
|
148
|
+
I16 = Schema.I16,
|
|
149
|
+
I24 = Schema.I24,
|
|
150
|
+
I32 = Schema.I32,
|
|
151
|
+
F16 = Schema.F16,
|
|
152
|
+
F24 = Schema.F24,
|
|
153
|
+
F32 = Schema.F32,
|
|
154
|
+
F64 = Schema.F64,
|
|
155
|
+
|
|
156
|
+
String = Schema.String,
|
|
157
|
+
Characters = Schema.Characters,
|
|
158
|
+
Buffer = Schema.Buffer,
|
|
159
|
+
Instance = Schema.Instance,
|
|
160
|
+
|
|
161
|
+
Vector2 = Schema.Vector2,
|
|
162
|
+
Vector2F16 = Schema.Vector2F16,
|
|
163
|
+
Vector2I16 = Schema.Vector2I16,
|
|
164
|
+
Vector3 = Schema.Vector3,
|
|
165
|
+
Vector3F24 = Schema.Vector3F24,
|
|
166
|
+
Vector3F16 = Schema.Vector3F16,
|
|
167
|
+
Vector3I16 = Schema.Vector3I16,
|
|
168
|
+
CFrame = Schema.CFrame,
|
|
169
|
+
CFrameF24 = Schema.CFrameF24,
|
|
170
|
+
|
|
171
|
+
Color3 = Schema.Color3,
|
|
172
|
+
BrickColor = Schema.BrickColor,
|
|
173
|
+
UDim = Schema.UDim,
|
|
174
|
+
UDim2 = Schema.UDim2,
|
|
175
|
+
Rect = Schema.Rect,
|
|
176
|
+
NumberRange = Schema.NumberRange,
|
|
177
|
+
NumberSequence = Schema.NumberSequence,
|
|
178
|
+
ColorSequence = Schema.ColorSequence,
|
|
179
|
+
DateTime = Schema.DateTime,
|
|
180
|
+
|
|
181
|
+
Array = Schema.Array,
|
|
182
|
+
Map = Schema.Map,
|
|
183
|
+
Struct = Schema.Struct,
|
|
184
|
+
Optional = Schema.Optional,
|
|
185
|
+
Static = Schema.Static,
|
|
186
|
+
Range = Schema.Range,
|
|
187
|
+
Flags = Schema.Flags,
|
|
188
|
+
Charset = Schema.Charset,
|
|
189
|
+
InstanceOf = Schema.InstanceOf,
|
|
190
|
+
EnumItem = Schema.EnumItem,
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const SwiftPacket: SwiftPacket = setmetatable(Library, {
|
|
194
|
+
__call = function(Target, Name: string, ...)
|
|
195
|
+
return Packet.New(Name, table.pack(...))
|
|
196
|
+
end,
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
return SwiftPacket
|
package/src/packet.luau
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!optimize 2
|
|
3
|
+
|
|
4
|
+
--[[
|
|
5
|
+
Author: @skaterstudios
|
|
6
|
+
Website: skaterstudios.com
|
|
7
|
+
GitHub: github.com/skatingii/SwiftPacket
|
|
8
|
+
Discord Server: discord.gg/skaterstudios
|
|
9
|
+
|
|
10
|
+
Licensed under the MIT License. You may use, modify, redistribute and sell
|
|
11
|
+
this system freely, as long as this notice and the LICENSE file stay with it.
|
|
12
|
+
]]
|
|
13
|
+
|
|
14
|
+
const RunService = game:GetService("RunService")
|
|
15
|
+
|
|
16
|
+
const Client = require("./client")
|
|
17
|
+
const Registry = require("./registry")
|
|
18
|
+
const Schema = require("./schema")
|
|
19
|
+
const Server = require("./server")
|
|
20
|
+
const Signal = require("./signal")
|
|
21
|
+
|
|
22
|
+
const IsServer = RunService:IsServer()
|
|
23
|
+
|
|
24
|
+
const Packet = {}
|
|
25
|
+
Packet.__index = Packet
|
|
26
|
+
|
|
27
|
+
export type Packet = setmetatable<Registry.Definition, typeof(Packet)>
|
|
28
|
+
|
|
29
|
+
const Packets: { [string]: Packet } = {}
|
|
30
|
+
const NoInstances: { any } = {}
|
|
31
|
+
|
|
32
|
+
const function RequireServer(self: Packet, Method: string)
|
|
33
|
+
if not IsServer then
|
|
34
|
+
error(`[swiftpacket] {Method} on {self.Name} can only be called on the server`, 3)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
const function RequireEvent(self: Packet, Method: string)
|
|
39
|
+
if self.Responses then
|
|
40
|
+
error(`[swiftpacket] {self.Name} expects a response, so {Method} cannot be used with it`, 3)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
function Packet.New(Name: string, Parameters: Schema.Arguments): Packet
|
|
45
|
+
if #Name > 100 or string.match(Name, "^[%a_][%w_]*$") == nil or string.sub(Name, 1, 3) == "RBX" then
|
|
46
|
+
error(`[swiftpacket] "{Name}" is not a valid packet name, use letters, digits and underscores`, 3)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
const Existing = Packets[Name]
|
|
50
|
+
|
|
51
|
+
if Existing then
|
|
52
|
+
return Existing
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
const State: Registry.Definition = {
|
|
56
|
+
Name = Name,
|
|
57
|
+
Arguments = Schema.CompileList(Parameters),
|
|
58
|
+
TimeoutSeconds = 10,
|
|
59
|
+
TimeoutValues = { n = 0 },
|
|
60
|
+
Reliable = true,
|
|
61
|
+
OnServerEvent = Signal.New(),
|
|
62
|
+
OnClientEvent = Signal.New(),
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const self: Packet = setmetatable(State, Packet)
|
|
66
|
+
Packets[Name] = self
|
|
67
|
+
|
|
68
|
+
if IsServer then
|
|
69
|
+
Server.Register(self)
|
|
70
|
+
else
|
|
71
|
+
Client.Register(self)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
return self
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
function Packet.Fire(self: Packet, ...: any): ...any
|
|
78
|
+
if IsServer then
|
|
79
|
+
RequireEvent(self, "Fire")
|
|
80
|
+
Server.Broadcast(self, nil, ...)
|
|
81
|
+
|
|
82
|
+
return
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
if self.Responses then
|
|
86
|
+
return Client.Invoke(self, ...)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
Client.Send(self, ...)
|
|
90
|
+
|
|
91
|
+
return
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
function Packet.FireClient(self: Packet, Player: Player, ...: any): ...any
|
|
95
|
+
RequireServer(self, "FireClient")
|
|
96
|
+
|
|
97
|
+
if self.Responses then
|
|
98
|
+
return Server.Invoke(Player, self, ...)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
Server.SendTo(Player, self, ...)
|
|
102
|
+
|
|
103
|
+
return
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
function Packet.FireClients(self: Packet, Recipients: { Player }, ...: any)
|
|
107
|
+
RequireServer(self, "FireClients")
|
|
108
|
+
RequireEvent(self, "FireClients")
|
|
109
|
+
Server.SendMany(Recipients, nil, self, ...)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
function Packet.FireExcept(self: Packet, Excluded: Player, ...: any)
|
|
113
|
+
RequireServer(self, "FireExcept")
|
|
114
|
+
RequireEvent(self, "FireExcept")
|
|
115
|
+
Server.Broadcast(self, Excluded, ...)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
function Packet.Response(self: Packet, ...: any): Packet
|
|
119
|
+
if not self.Reliable then
|
|
120
|
+
error(`[swiftpacket] {self.Name} is unreliable and cannot expect a response`, 2)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
self.Responses = Schema.CompileList(table.pack(...))
|
|
124
|
+
|
|
125
|
+
return self
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
function Packet.Timeout(self: Packet, Seconds: number, ...: any): Packet
|
|
129
|
+
if Seconds <= 0 then
|
|
130
|
+
error(`[swiftpacket] timeout for {self.Name} must be above zero`, 2)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
self.TimeoutSeconds = Seconds
|
|
134
|
+
self.TimeoutValues = table.pack(...)
|
|
135
|
+
|
|
136
|
+
return self
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
function Packet.Unreliable(self: Packet): Packet
|
|
140
|
+
if self.Responses then
|
|
141
|
+
error(`[swiftpacket] {self.Name} expects a response and cannot be unreliable`, 2)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
self.Reliable = false
|
|
145
|
+
|
|
146
|
+
return self
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
function Packet.RateLimit(self: Packet, Count: number, Interval: number): Packet
|
|
150
|
+
if Count < 1 or Interval <= 0 then
|
|
151
|
+
error(`[swiftpacket] rate limit for {self.Name} needs a count of at least 1 and an interval above zero`, 2)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
self.RateLimitCount = Count
|
|
155
|
+
self.RateLimitInterval = Interval
|
|
156
|
+
|
|
157
|
+
return self
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
function Packet.Validate(self: Packet, Validator: (Player, ...any) -> boolean): Packet
|
|
161
|
+
self.Validator = Validator
|
|
162
|
+
|
|
163
|
+
return self
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
function Packet.SetServerInvoke(self: Packet, Handler: (Player, ...any) -> ...any): Packet
|
|
167
|
+
self.OnServerInvoke = Handler
|
|
168
|
+
|
|
169
|
+
return self
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
function Packet.SetClientInvoke(self: Packet, Handler: (...any) -> ...any): Packet
|
|
173
|
+
self.OnClientInvoke = Handler
|
|
174
|
+
|
|
175
|
+
return self
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
function Packet.Serialize(self: Packet, ...: any): (buffer, { any }?)
|
|
179
|
+
return Schema.Serialize(self.Name, self.Arguments, ...)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
function Packet.Deserialize(self: Packet, Source: buffer, Instances: { any }?): ...any
|
|
183
|
+
return Schema.Deserialize(self.Arguments, Source, Instances or NoInstances)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
return Packet
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!optimize 2
|
|
3
|
+
|
|
4
|
+
--[[
|
|
5
|
+
Author: @skaterstudios
|
|
6
|
+
Website: skaterstudios.com
|
|
7
|
+
GitHub: github.com/skatingii/SwiftPacket
|
|
8
|
+
Discord Server: discord.gg/skaterstudios
|
|
9
|
+
|
|
10
|
+
Licensed under the MIT License. You may use, modify, redistribute and sell
|
|
11
|
+
this system freely, as long as this notice and the LICENSE file stay with it.
|
|
12
|
+
]]
|
|
13
|
+
|
|
14
|
+
const RateLimit = {}
|
|
15
|
+
|
|
16
|
+
function RateLimit.Refill(Tokens: number, Elapsed: number, Rate: number, Capacity: number): number
|
|
17
|
+
return math.min(Capacity, Tokens + math.max(Elapsed, 0) * Rate)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
function RateLimit.Window(
|
|
21
|
+
Count: number,
|
|
22
|
+
EndsAt: number,
|
|
23
|
+
Now: number,
|
|
24
|
+
Limit: number,
|
|
25
|
+
Interval: number
|
|
26
|
+
): (boolean, number, number)
|
|
27
|
+
if Now >= EndsAt then
|
|
28
|
+
return true, 1, Now + Interval
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
if Count >= Limit then
|
|
32
|
+
return false, Count, EndsAt
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
return true, Count + 1, EndsAt
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
return RateLimit
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!optimize 2
|
|
3
|
+
|
|
4
|
+
--[[
|
|
5
|
+
Author: @skaterstudios
|
|
6
|
+
Website: skaterstudios.com
|
|
7
|
+
GitHub: github.com/skatingii/SwiftPacket
|
|
8
|
+
Discord Server: discord.gg/skaterstudios
|
|
9
|
+
|
|
10
|
+
Licensed under the MIT License. You may use, modify, redistribute and sell
|
|
11
|
+
this system freely, as long as this notice and the LICENSE file stay with it.
|
|
12
|
+
]]
|
|
13
|
+
|
|
14
|
+
const Schema = require("./schema")
|
|
15
|
+
const Signal = require("./signal")
|
|
16
|
+
|
|
17
|
+
export type Definition = {
|
|
18
|
+
Name: string,
|
|
19
|
+
Id: number?,
|
|
20
|
+
Arguments: { Schema.Schema },
|
|
21
|
+
Responses: { Schema.Schema }?,
|
|
22
|
+
TimeoutSeconds: number,
|
|
23
|
+
TimeoutValues: Schema.Arguments,
|
|
24
|
+
Reliable: boolean,
|
|
25
|
+
RateLimitCount: number?,
|
|
26
|
+
RateLimitInterval: number?,
|
|
27
|
+
Validator: ((Player, ...any) -> boolean)?,
|
|
28
|
+
OnServerEvent: Signal.Signal,
|
|
29
|
+
OnClientEvent: Signal.Signal,
|
|
30
|
+
OnServerInvoke: ((Player, ...any) -> ...any)?,
|
|
31
|
+
OnClientInvoke: ((...any) -> ...any)?,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const ById: { [number]: Definition } = {}
|
|
35
|
+
|
|
36
|
+
const Registry = {
|
|
37
|
+
ById = ById,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return Registry
|