@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.
@@ -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
@@ -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