diff --git a/CHANGELOG.md b/CHANGELOG.md
index 01deecf..d235e7d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,22 @@
This project uses [semantic versioning](https://semver.org/spec/v2.0.0.html).
-## [version](https://github.com/ffrostflame/BridgeNet2/releases/tag/v0.5.6): 9/25/2023
+## [version 1.0.0](https://github.com/ffrostflame/BridgeNet2/releases/tag/v0.5.6): 10/20/2023
+
+### Added
+
+- Added an easy way to type payloads using generics. This will be elaborated on in documentation later
+
+### Fixes
+
+- Fixed sending singular nil values with nothing else in the frame
+- Fixed a bug w/ the loading queue. Finally got around to that (https://github.com/ffrostflame/BridgeNet2/issues/35)
+- Type improvements
+
+### Improvements
+
+- Added unique IDs to the invoke functionality. Should fix a multitude of bugs.
+- Re-did rate limiting. I'm confident that it's stable.
## [version 0.5.6](https://github.com/ffrostflame/BridgeNet2/releases/tag/v0.5.6): 9/25/2023
diff --git a/LICENSE b/LICENSE
index 7c5c0aa..735f6b0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2022 ffrostfall
+Copyright 2023 ffrostfall
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
diff --git a/README.md b/README.md
index 689f25a..be6d130 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
-# BridgeNet2 v0.5.5
+# BridgeNet2 v1.0.0
## Blazing fast & opinionated networking library designed to reduce bandwidth.
@@ -15,4 +15,3 @@ Developers cannot fire a bridge with multiple parameters. This means you have to
This library favors performance, and therefore we made choices that resulted in an opinionated library. BridgeNet2 never manipulates your data under the hood, but it does encourage developing in favor of performance.
[Further Documentation](https://ffrostflame.github.io/BridgeNet2/)
-
diff --git a/sourcemap.json b/sourcemap.json
index adce4d3..a068cb9 100644
--- a/sourcemap.json
+++ b/sourcemap.json
@@ -1 +1 @@
-{"name":"bridgenet2-test","className":"DataModel","filePaths":["testing.project.json"],"children":[{"name":"ReplicatedStorage","className":"ReplicatedStorage","children":[{"name":"Packages","className":"Folder","children":[{"name":"RemotePacketSizeCounter","className":"ModuleScript","filePaths":["Packages\\RemotePacketSizeCounter.lua"]},{"name":"TableKit","className":"ModuleScript","filePaths":["Packages\\TableKit.lua"]},{"name":"_Index","className":"Folder","children":[{"name":"ffrostflame_tablekit@0.2.4","className":"Folder","children":[{"name":"tablekit","className":"ModuleScript","filePaths":["Packages\\_Index\\ffrostflame_tablekit@0.2.4\\tablekit\\src\\init.luau","Packages\\_Index\\ffrostflame_tablekit@0.2.4\\tablekit\\default.project.json"]}]},{"name":"ffrostflame_wally-instance-manager@0.1.0","className":"Folder","children":[{"name":"wally-instance-manager","className":"ModuleScript","filePaths":["Packages\\_Index\\ffrostflame_wally-instance-manager@0.1.0\\wally-instance-manager\\src\\init.luau","Packages\\_Index\\ffrostflame_wally-instance-manager@0.1.0\\wally-instance-manager\\default.project.json"]}]},{"name":"pysephwasntavailable_remotepacketsizecounter@2.1.0","className":"Folder","children":[{"name":"remotepacketsizecounter","className":"ModuleScript","filePaths":["Packages\\_Index\\pysephwasntavailable_remotepacketsizecounter@2.1.0\\remotepacketsizecounter\\src\\init.luau","Packages\\_Index\\pysephwasntavailable_remotepacketsizecounter@2.1.0\\remotepacketsizecounter\\default.project.json"]}]}]},{"name":"wallyInstanceManager","className":"ModuleScript","filePaths":["Packages\\wallyInstanceManager.lua"]},{"name":"bridgenet2","className":"ModuleScript","filePaths":["src\\init.luau"],"children":[{"name":"Client","className":"ModuleScript","filePaths":["src\\Client\\init.luau"],"children":[{"name":"ClientBridge","className":"ModuleScript","filePaths":["src\\Client\\ClientBridge.luau"]},{"name":"ClientConnection","className":"ModuleScript","filePaths":["src\\Client\\ClientConnection.luau"]},{"name":"ClientIdentifiers","className":"ModuleScript","filePaths":["src\\Client\\ClientIdentifiers.luau"]},{"name":"ClientProcess","className":"ModuleScript","filePaths":["src\\Client\\ClientProcess.luau"]}]},{"name":"Constants","className":"ModuleScript","filePaths":["src\\Constants.luau"]},{"name":"PublicTypes","className":"ModuleScript","filePaths":["src\\PublicTypes.luau"]},{"name":"Server","className":"ModuleScript","filePaths":["src\\Server\\init.luau"],"children":[{"name":"HandleInvalidPlayer","className":"ModuleScript","filePaths":["src\\Server\\HandleInvalidPlayer.luau"]},{"name":"PlayerContainers","className":"ModuleScript","filePaths":["src\\Server\\PlayerContainers\\init.luau"],"children":[{"name":"All","className":"ModuleScript","filePaths":["src\\Server\\PlayerContainers\\All.luau"]},{"name":"Except","className":"ModuleScript","filePaths":["src\\Server\\PlayerContainers\\Except.luau"]},{"name":"Players","className":"ModuleScript","filePaths":["src\\Server\\PlayerContainers\\Players.luau"]},{"name":"Single","className":"ModuleScript","filePaths":["src\\Server\\PlayerContainers\\Single.luau"]}]},{"name":"ServerBridge","className":"ModuleScript","filePaths":["src\\Server\\ServerBridge.luau"]},{"name":"ServerConnection","className":"ModuleScript","filePaths":["src\\Server\\ServerConnection.luau"]},{"name":"ServerIdentifiers","className":"ModuleScript","filePaths":["src\\Server\\ServerIdentifiers.luau"]},{"name":"ServerProcess","className":"ModuleScript","filePaths":["src\\Server\\ServerProcess.luau"]}]},{"name":"Studio","className":"Folder","children":[{"name":"MockBridge","className":"ModuleScript","filePaths":["src\\Studio\\MockBridge.luau"]},{"name":"MockConnection","className":"ModuleScript","filePaths":["src\\Studio\\MockConnection.luau"]},{"name":"MockIdentifiers","className":"ModuleScript","filePaths":["src\\Studio\\MockIdentifiers.luau"]}]},{"name":"Types","className":"ModuleScript","filePaths":["src\\Types.luau"]},{"name":"Utilities","className":"Folder","children":[{"name":"NetworkUtils","className":"ModuleScript","filePaths":["src\\Utilities\\NetworkUtils.luau"]},{"name":"Output","className":"ModuleScript","filePaths":["src\\Utilities\\Output.luau"]},{"name":"RecycledSpawn","className":"ModuleScript","filePaths":["src\\Utilities\\RecycledSpawn.luau"]},{"name":"isEditMode","className":"ModuleScript","filePaths":["src\\Utilities\\isEditMode.luau"]},{"name":"tostringData","className":"ModuleScript","filePaths":["src\\Utilities\\tostringData.luau"]}]},{"name":"version","className":"ModuleScript","filePaths":["src\\version.luau"]}]}]},{"name":"benches","className":"Folder","children":[{"name":"Hex.bench","className":"ModuleScript","filePaths":["benchmarks\\Hex.bench.luau"]}]},{"name":"framework","className":"ModuleScript","filePaths":["testing/framework\\init.luau"],"children":[{"name":"bootstrapper","className":"ModuleScript","filePaths":["testing/framework\\bootstrapper.luau"]},{"name":"expect","className":"ModuleScript","filePaths":["testing/framework\\expect.luau"]}]}]},{"name":"ServerScriptService","className":"ServerScriptService","children":[{"name":"featureTests","className":"Script","filePaths":["testing/tests/server\\featureTests\\init.server.luau"]}]},{"name":"StarterPlayer","className":"StarterPlayer","children":[{"name":"StarterPlayerScripts","className":"StarterPlayerScripts","children":[{"name":"featureTests","className":"LocalScript","filePaths":["testing/tests/client\\featureTests\\init.client.luau"]}]}]}]}
\ No newline at end of file
+{"name":"bridgenet2-test","className":"DataModel","filePaths":["testing.project.json"],"children":[{"name":"ReplicatedStorage","className":"ReplicatedStorage","children":[{"name":"Packages","className":"Folder","children":[{"name":"RemotePacketSizeCounter","className":"ModuleScript","filePaths":["Packages\\RemotePacketSizeCounter.lua"]},{"name":"TableKit","className":"ModuleScript","filePaths":["Packages\\TableKit.lua"]},{"name":"_Index","className":"Folder","children":[{"name":"ffrostflame_tablekit@0.2.4","className":"Folder","children":[{"name":"tablekit","className":"ModuleScript","filePaths":["Packages\\_Index\\ffrostflame_tablekit@0.2.4\\tablekit\\src\\init.luau","Packages\\_Index\\ffrostflame_tablekit@0.2.4\\tablekit\\default.project.json"]}]},{"name":"ffrostflame_wally-instance-manager@0.1.0","className":"Folder","children":[{"name":"wally-instance-manager","className":"ModuleScript","filePaths":["Packages\\_Index\\ffrostflame_wally-instance-manager@0.1.0\\wally-instance-manager\\src\\init.luau","Packages\\_Index\\ffrostflame_wally-instance-manager@0.1.0\\wally-instance-manager\\default.project.json"]}]},{"name":"pysephwasntavailable_remotepacketsizecounter@2.1.0","className":"Folder","children":[{"name":"remotepacketsizecounter","className":"ModuleScript","filePaths":["Packages\\_Index\\pysephwasntavailable_remotepacketsizecounter@2.1.0\\remotepacketsizecounter\\src\\init.luau","Packages\\_Index\\pysephwasntavailable_remotepacketsizecounter@2.1.0\\remotepacketsizecounter\\default.project.json"]}]}]},{"name":"wallyInstanceManager","className":"ModuleScript","filePaths":["Packages\\wallyInstanceManager.lua"]},{"name":"bridgenet2","className":"ModuleScript","filePaths":["src\\init.luau"],"children":[{"name":"Client","className":"ModuleScript","filePaths":["src\\Client\\init.luau"],"children":[{"name":"ClientBridge","className":"ModuleScript","filePaths":["src\\Client\\ClientBridge.luau"]},{"name":"ClientConnection","className":"ModuleScript","filePaths":["src\\Client\\ClientConnection.luau"]},{"name":"ClientIdentifiers","className":"ModuleScript","filePaths":["src\\Client\\ClientIdentifiers.luau"]},{"name":"ClientProcess","className":"ModuleScript","filePaths":["src\\Client\\ClientProcess.luau"]}]},{"name":"Constants","className":"ModuleScript","filePaths":["src\\Constants.luau"]},{"name":"ExportedTypes","className":"ModuleScript","filePaths":["src\\ExportedTypes.luau"]},{"name":"PublicTypes","className":"ModuleScript","filePaths":["src\\PublicTypes.luau"]},{"name":"Server","className":"ModuleScript","filePaths":["src\\Server\\init.luau"],"children":[{"name":"HandleInvalidPlayer","className":"ModuleScript","filePaths":["src\\Server\\HandleInvalidPlayer.luau"]},{"name":"PlayerContainers","className":"ModuleScript","filePaths":["src\\Server\\PlayerContainers\\init.luau"],"children":[{"name":"All","className":"ModuleScript","filePaths":["src\\Server\\PlayerContainers\\All.luau"]},{"name":"Except","className":"ModuleScript","filePaths":["src\\Server\\PlayerContainers\\Except.luau"]},{"name":"Players","className":"ModuleScript","filePaths":["src\\Server\\PlayerContainers\\Players.luau"]},{"name":"Single","className":"ModuleScript","filePaths":["src\\Server\\PlayerContainers\\Single.luau"]}]},{"name":"ServerBridge","className":"ModuleScript","filePaths":["src\\Server\\ServerBridge.luau"]},{"name":"ServerConnection","className":"ModuleScript","filePaths":["src\\Server\\ServerConnection.luau"]},{"name":"ServerIdentifiers","className":"ModuleScript","filePaths":["src\\Server\\ServerIdentifiers.luau"]},{"name":"ServerProcess","className":"ModuleScript","filePaths":["src\\Server\\ServerProcess.luau"]}]},{"name":"Studio","className":"Folder","children":[{"name":"MockBridge","className":"ModuleScript","filePaths":["src\\Studio\\MockBridge.luau"]},{"name":"MockConnection","className":"ModuleScript","filePaths":["src\\Studio\\MockConnection.luau"]},{"name":"MockIdentifiers","className":"ModuleScript","filePaths":["src\\Studio\\MockIdentifiers.luau"]}]},{"name":"Types","className":"ModuleScript","filePaths":["src\\Types.luau"]},{"name":"Utilities","className":"Folder","children":[{"name":"NetworkUtils","className":"ModuleScript","filePaths":["src\\Utilities\\NetworkUtils.luau"]},{"name":"Output","className":"ModuleScript","filePaths":["src\\Utilities\\Output.luau"]},{"name":"RecycledSpawn","className":"ModuleScript","filePaths":["src\\Utilities\\RecycledSpawn.luau"]},{"name":"isEditMode","className":"ModuleScript","filePaths":["src\\Utilities\\isEditMode.luau"]},{"name":"tostringData","className":"ModuleScript","filePaths":["src\\Utilities\\tostringData.luau"]}]},{"name":"version","className":"ModuleScript","filePaths":["src\\version.luau"]}]}]},{"name":"benches","className":"Folder","children":[{"name":"Hex.bench","className":"ModuleScript","filePaths":["benchmarks\\Hex.bench.luau"]}]},{"name":"framework","className":"ModuleScript","filePaths":["testing/framework\\init.luau"],"children":[{"name":"bootstrapper","className":"ModuleScript","filePaths":["testing/framework\\bootstrapper.luau"]},{"name":"expect","className":"ModuleScript","filePaths":["testing/framework\\expect.luau"]}]}]},{"name":"ServerScriptService","className":"ServerScriptService","children":[{"name":"featureTests","className":"Script","filePaths":["testing/tests/server\\featureTests\\init.server.luau"]}]},{"name":"StarterPlayer","className":"StarterPlayer","children":[{"name":"StarterPlayerScripts","className":"StarterPlayerScripts","children":[{"name":"featureTests","className":"LocalScript","filePaths":["testing/tests/client\\featureTests\\init.client.luau"]}]}]}]}
\ No newline at end of file
diff --git a/src/Client/ClientBridge.luau b/src/Client/ClientBridge.luau
index e221f69..7e4d96f 100644
--- a/src/Client/ClientBridge.luau
+++ b/src/Client/ClientBridge.luau
@@ -260,7 +260,7 @@ function clientBridgePrototype:InvokeServerAsync(content: any)
end
if (reply :: {})[1] == ClientIdentifiers.ref("REQUEST", 3, false) and (reply :: {})[2] == id then
connection()
- task.spawn(thread, (reply :: {})[2])
+ task.spawn(thread, (reply :: {})[3])
end
end)
return coroutine.yield()
diff --git a/src/ExportedTypes.luau b/src/ExportedTypes.luau
new file mode 100644
index 0000000..b6d9d39
--- /dev/null
+++ b/src/ExportedTypes.luau
@@ -0,0 +1,6 @@
+local PublicTypes = require(script.Parent.PublicTypes)
+
+export type ServerBridge = PublicTypes.ServerBridge
+export type ClientBridge = PublicTypes.ClientBridge
+
+return nil
diff --git a/src/PublicTypes.luau b/src/PublicTypes.luau
index 88947e2..2773c7a 100644
--- a/src/PublicTypes.luau
+++ b/src/PublicTypes.luau
@@ -1,31 +1,31 @@
--!strict
local Types = require(script.Parent.Types)
-type ServerBridge = {
+export type ServerBridge = {
Fire: (
- self: ServerBridge,
+ self: ServerBridge,
target: Player | (Types.AllPlayerContainer | Types.SetPlayerContainer),
- content: Types.Content
+ content: send
) -> (),
Connect: (
- self: ServerBridge,
+ self: ServerBridge,
callback: (player: Player, content: Types.Content?) -> (),
name: string?
) -> Connection,
- Once: (self: ServerBridge, callback: (player: Player, content: Types.Content?) -> ()) -> (),
- Wait: (self: ServerBridge, callback: (player: Player, content: Types.Content?) -> ()) -> (Player, Types.Content?),
+ Once: (self: ServerBridge, callback: (player: Player, content: Types.Content?) -> ()) -> (),
+ Wait: (self: ServerBridge) -> (Player, Types.Content?),
OnServerInvoke: ((player: Player, content: Types.Content) -> ...any)?,
RateLimitActive: boolean,
Logging: boolean,
}
-type ClientBridge = {
- Fire: (self: ClientBridge, content: any?) -> (),
- Connect: (self: ClientBridge, callback: (content: Types.Content?) -> (), name: string?) -> Connection,
- Once: (self: ClientBridge, callback: (content: Types.Content?) -> ()) -> (),
- Wait: (self: ClientBridge, callback: (content: Types.Content?) -> ()) -> Types.Content?,
+export type ClientBridge = {
+ Fire: (self: ClientBridge, content: send) -> (),
+ Connect: (self: ClientBridge, callback: (content: receive) -> (), name: string?) -> Connection,
+ Once: (self: ClientBridge, callback: (content: receive) -> ()) -> (),
+ Wait: (self: ClientBridge, callback: (content: receive) -> ()) -> receive,
- InvokeServerAsync: (self: ClientBridge, content: any?) -> ...Types.Content?,
+ InvokeServerAsync: (self: ClientBridge, content: send) -> receive,
Logging: boolean,
}
@@ -34,13 +34,13 @@ type Connection = {
Disconnect: () -> (),
}
-export type Bridge = ServerBridge & ClientBridge
+export type Bridge = ServerBridge & ClientBridge
export type BridgeNet2 = {
ReferenceBridge: (name: string) -> Bridge,
- ClientBridge: (name: string) -> ClientBridge,
- ServerBridge: (name: string) -> ServerBridge,
+ ClientBridge: (name: string) -> ClientBridge,
+ ServerBridge: (name: string) -> ServerBridge,
ReferenceIdentifier: (name: string, maxWaitTime: number?) -> Types.Identifier,
diff --git a/src/Server/ServerBridge.luau b/src/Server/ServerBridge.luau
index e5c79d8..aefac6c 100644
--- a/src/Server/ServerBridge.luau
+++ b/src/Server/ServerBridge.luau
@@ -78,20 +78,24 @@ function serverBridgePrototype:Connect(callback: (player: Player, content: Types
end
if self.RateLimitActive then
+ -- get the current second
+ local thisSecond = math.round(os.clock() - os.clock() % 1)
+
if self._rateMap[player] ~= nil then
- local currentCount: number = self._rateMap[player]
- self._rateMap[player] = currentCount + 1
- else
- self._rateMap[player] = 1
- end
+ local lastSecond = self._rateMap[player][1] or 0
- task.delay(1, function()
- local currentCount: number = self._rateMap[player]
+ if lastSecond ~= thisSecond then
+ self._rateMap[player][2] = 0
- self._rateMap[player] = math.min(0, currentCount - 1)
- end)
+ self._rateMap[player][1] = thisSecond
+ else
+ self._rateMap[player][2] += 1
+ end
+ else
+ self._rateMap[player] = { thisSecond, 1 }
+ end
- if self._rateMap[player] >= self._maxRate then
+ if self._rateMap[player][2] >= self._maxRate then
if not self._overflowFunction(player) then
return
end
@@ -316,7 +320,7 @@ return function(name: string)
-- Rate limiting
RateLimitActive = false,
_maxRate = 500,
- _rateMap = {} :: { [Player]: number },
+ _rateMap = {} :: { [Player]: { number } },
_overflowFunction = function()
return false
end,
diff --git a/src/init.luau b/src/init.luau
index df9b153..6b2f811 100644
--- a/src/init.luau
+++ b/src/init.luau
@@ -109,13 +109,14 @@ local BridgeNet2 = {
Players = Server.playerContainers().Players,
ReferenceBridge = if isServer then Server.makeBridge else Client.makeBridge,
-
ServerBridge = if isServer then Server.makeBridge else nil,
-
ClientBridge = if not isServer then Client.makeBridge else nil,
+ Types = script.ExportedTypes,
+
HandleInvalidPlayer = function(handler: (player: Player) -> ())
Output.fatalAssert(isServer, "Cannot call from client")
+
Server.invalidPlayerhandler(handler)
end,
diff --git a/src/version.luau b/src/version.luau
index 9599d96..bccc689 100644
--- a/src/version.luau
+++ b/src/version.luau
@@ -1 +1 @@
-return "0.5.7"
+return "1.0.0"
diff --git a/wally.lock b/wally.lock
index a479c0b..cba7977 100644
--- a/wally.lock
+++ b/wally.lock
@@ -4,7 +4,7 @@ registry = "test"
[[package]]
name = "ffrostflame/bridgenet2"
-version = "0.5.5"
+version = "0.5.6"
dependencies = [["RemotePacketSizeCounter", "pysephwasntavailable/remotepacketsizecounter@2.1.0"], ["TableKit", "ffrostflame/tablekit@0.2.4"], ["wallyInstanceManager", "ffrostflame/wally-instance-manager@0.1.0"]]
[[package]]
diff --git a/wally.toml b/wally.toml
index 72feb29..e7d6d20 100644
--- a/wally.toml
+++ b/wally.toml
@@ -1,6 +1,6 @@
[package]
name = "ffrostflame/bridgenet2"
-version = "0.5.6"
+version = "1.0.0"
registry = "https://github.com/UpliftGames/wally-index"
realm = "shared"
description = "The successor to BridgeNet, BridgeNet2 is a blazing-fast networking library designed for scale and performance."