From c4cc6c9925922e3c7b6185fe5126e452111bf72c Mon Sep 17 00:00:00 2001 From: James Date: Sun, 24 Sep 2023 22:38:38 -0500 Subject: [PATCH] final v4 commit --- docs/.vitepress/config.mts | 10 + docs/Tutorials/packages.md | 6 +- docs/api/controllers/network/client.md | 30 +- docs/api/controllers/network/server.md | 46 +- .../controllers/signal/signalcontroller.md | 18 +- .../api/engine/dependencies/enginedebugger.md | 26 +- docs/api/engine/dependencies/engineloader.md | 8 +- docs/api/engine/framework/canaryengine.md | 26 +- .../engine/framework/canaryengineclient.md | 6 +- .../engine/framework/canaryengineserver.md | 4 +- docs/api/libraries/base64.md | 8 +- docs/api/libraries/benchmark.md | 2 +- docs/api/libraries/benchmarkobject.md | 12 +- docs/api/libraries/data/easyprofile.md | 4 +- docs/api/libraries/data/profileobject.md | 26 +- docs/api/libraries/data/profilestoreobject.md | 46 +- docs/api/libraries/mdify.md | 4 +- docs/api/libraries/sprite.md | 8 +- docs/api/libraries/statistics.md | 12 +- docs/api/libraries/topbariconobject.md | 44 +- docs/api/libraries/topbarspacerobject.md | 10 +- docs/api/libraries/uishelf.md | 12 +- docs/featured.md | 12 +- docs/static/images/trello.svg | 20 - .../Vendor/NetworkController/init.luau | 316 ++----------- .../Vendor/SignalController/init.luau | 76 +-- .../{Controllers.luau => init.luau} | 6 - src/lua/framework/Vendor/Debugger.luau | 87 ---- .../Vendor/Libraries/EasyProfile/init.luau | 434 ++++-------------- .../Vendor/Libraries/EngineLoader/init.luau | 27 -- src/lua/framework/Vendor/Runtime.luau | 78 +--- src/lua/framework/Vendor/Types.luau | 139 +----- src/lua/framework/init.luau | 214 ++------- 33 files changed, 381 insertions(+), 1396 deletions(-) delete mode 100644 docs/static/images/trello.svg rename src/lua/framework/Vendor/Controllers/{Controllers.luau => init.luau} (81%) diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 8e77375e..507d0bdc 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -109,6 +109,7 @@ export default defineConfig({ items: [ { text: 'Framework', + collapsed: true, items: [ { text: 'CanaryEngine', link: '/api/engine/framework/canaryengine' }, { text: 'CanaryEngineServer', link: '/api/engine/framework/canaryengineserver' }, @@ -119,6 +120,7 @@ export default defineConfig({ { text: 'Dependencies', + collapsed: true, items: [ { text: 'EngineDebugger', link: '/api/engine/dependencies/enginedebugger' }, { text: 'EngineLoader', link: '/api/engine/dependencies/engineloader' }, @@ -128,6 +130,7 @@ export default defineConfig({ { text: 'Runtime', + collapsed: true, items: [ { text: 'EngineRuntime', link: '/api/engine/runtime/engineruntime' }, { text: 'EngineRuntimeContext', link: '/api/engine/runtime/engineruntimecontext' }, @@ -144,6 +147,7 @@ export default defineConfig({ items: [ { text: 'Signal', + collapsed: true, items: [ { text: 'SignalController', link: '/api/controllers/signal/signalcontroller' } ] @@ -151,6 +155,7 @@ export default defineConfig({ { text: 'Network', + collapsed: true, items: [ { text: 'NetworkControllerServer', link: '/api/controllers/network/server' }, { text: 'NetworkControllerClient', link: '/api/controllers/network/client' } @@ -166,6 +171,7 @@ export default defineConfig({ items: [ { text: 'EasyProfile', + collapsed: true, items: [ { text: 'EasyProfile', link: '/api/libraries/data/easyprofile' }, { text: 'ProfileStoreObject', link: '/api/libraries/data/profilestoreobject' }, @@ -175,6 +181,7 @@ export default defineConfig({ { text: 'UIShelf', + collapsed: true, items: [ { text: 'UIShelf', link: '/api/libraries/uishelf' }, { text: 'TopBarIconObject', link: '/api/libraries/topbariconobject' }, @@ -184,6 +191,7 @@ export default defineConfig({ { text: 'Benchmark', + collapsed: true, items: [ { text: 'Benchmark', link: '/api/libraries/benchmark' }, { text: 'BenchmarkObject', link: '/api/libraries/benchmarkobject' } @@ -199,6 +207,8 @@ export default defineConfig({ ] }, + outline: [2, 3], + search: { provider: 'local' }, diff --git a/docs/Tutorials/packages.md b/docs/Tutorials/packages.md index 2d72703b..6f6d5c06 100644 --- a/docs/Tutorials/packages.md +++ b/docs/Tutorials/packages.md @@ -1,17 +1,17 @@ # Package System -One of Canary's greatest strengths is the built in package system, which allows for many more oppurtunities. Coming in later updates, we will be adding a type generator for package intellisense support! +One of Canary's greatest strengths is the built in package system, which allows for many more oppurtunities. It allows for intellisense support along with easy organization for your package needs. ### Inserting Packages -To insert a new package, simply use the 'Create New Instance' function of the plugin, then from there you can insert a new package, for either the client, to be replicated, or the server. From there, you can reference the module in your script and start using it! Here's an example of how you would grab a package from the server. +To insert a new package, simply use the 'Create New Instance' function of the plugin, then from there you can insert a new package, for either the client, to be replicated, or the server. From there, you can reference the module in your script and start using it! ### Inserting Scripts Inserting new scripts is also a very straightforward process and very similar to packages. First, create a new instance, then select either client script or server script from the dropdown menu. In order to reference a server-sided package, you must create a server script. Here's an example of how you would get your package from the script we just created: ```lua -local Packages = CanaryEngineServer.Packages.Server +local Packages = EngineServer.Packages local MyPackage = require(Packages.MyPackage) MyPackage.MyFunction() diff --git a/docs/api/controllers/network/client.md b/docs/api/controllers/network/client.md index 3bab7694..82a1af9a 100644 --- a/docs/api/controllers/network/client.md +++ b/docs/api/controllers/network/client.md @@ -1,6 +1,6 @@ # NetworkControllerClient -A client-sided network controller. +A client-sided network controller, based on [this](/api/engine/types#networkcontrollerclient) type. ## Properties @@ -24,12 +24,12 @@ NetworkController:Fire("Hello, world!") ``` ::: -#### Parameters +**Parameters** * **data:** `Array | any`\ The data that should be sent to the server -#### Returns +**Returns** * **void** @@ -39,36 +39,26 @@ The data that should be sent to the server Invokes the server, equivalent to [RemoteFunction:InvokeServer](https://create.roblox.com/docs/reference/engine/classes/RemoteFunction#InvokeServer). Returns a promise. -#### Parameters +**Parameters** * **data:** `Array | any`\ The data to invoke the server with -#### Returns +**Returns** * **[Future](https://util.redblox.dev/future.html#methods)** --- -### Connect +### Listen -Connects a function to the event that is fired when the server fires the network controller. +Listens for the network controller to be fired by the server, then runs the provided function. -#### Parameters +**Parameters** * **func:** `(data: Array) -> ()`\ The function to call when data is recieved -#### Returns +**Returns** -* **void** - ---- - -### Wait - -Yields the current thread until the server fires the network controller. Returns a promise. - -#### Returns - -* **[Future](https://util.redblox.dev/future.html#methods)** \ No newline at end of file +* **void** \ No newline at end of file diff --git a/docs/api/controllers/network/server.md b/docs/api/controllers/network/server.md index a4967b31..c891a460 100644 --- a/docs/api/controllers/network/server.md +++ b/docs/api/controllers/network/server.md @@ -1,6 +1,6 @@ # NetworkControllerServer -A server-sided network controller. +A server-sided network controller, based on [this](/api/engine/types#networkcontrollerserver) type. ## Properties @@ -24,7 +24,7 @@ NetworkController:Fire({Player1, Player2, Player3}, {1, 2, 3}) ``` ::: -#### Parameters +**Parameters** * **recipients:** `{ Player } | Player`\ The players who should recieve the data and/or call @@ -32,7 +32,7 @@ The players who should recieve the data and/or call * **data:** `(Array | any)?`\ The data that should be sent to the client -#### Returns +**Returns** * **void** @@ -42,12 +42,12 @@ The data that should be sent to the client Fires an event which sends data to every client connected to the server, equivalent [RemoteEvent:FireAllClients](https://create.roblox.com/docs/reference/engine/classes/RemoteEvent#FireAllClients). -#### Parameters +**Parameters** * **data:** `(Array | any)?`\ The data that should be sent to each player -#### Returns +**Returns** * **void** @@ -57,7 +57,7 @@ The data that should be sent to each player Fires an event which sends data to every client connected to the server, except for players defined in the `except` parameter. -#### Parameters +**Parameters** * **except:** `Array | Player`\ The players which the call should not be sent to @@ -65,7 +65,7 @@ The players which the call should not be sent to * **data:** `(Array | any)?`\ The data that should be sent to each player except `except` -#### Returns +**Returns** * **void** @@ -75,7 +75,7 @@ The data that should be sent to each player except `except` Fires an event which sends data to every client that is within `maximumRange` studs from `comparePoint`. -#### Parameters +**Parameters** * **comparePoint:** `Vector3`\ The point to compare from, can be a standalone `Vector3` @@ -86,32 +86,22 @@ The maximum range of which the player's characters have to be within to recieve * **data:** `(Array | any)?`\ The data that should be sent to each player within `maximumRange` -#### Returns +**Returns** * **void** --- -### Wait +### Listen -Yields the current thread until the client fires the network controller. Returns a promise. +Listens for the network controller to be fired by the client, then runs the provided function. -#### Returns - -* **[Future](https://util.redblox.dev/future.html#methods)** - ---- - -### Connect - -Connects a function to the event that is fired when the client fires the network controller. - -#### Parameters +**Parameters** * **func:** `(sender: Player, data: Array?) -> ()`\ The function to call when data is recieved -#### Returns +**Returns** * **void** @@ -119,14 +109,14 @@ The function to call when data is recieved ### OnInvoke -Recieves an invoke from the server, and runs the callback function which returns some data. Equivalent to [RemoteFunction.OnServerInvoke](https://create.roblox.com/docs/reference/engine/classes/RemoteFunction#OnServerInvoke). +Recieves an invoke from the client, and runs the callback function which returns some data. Equivalent to [RemoteFunction.OnServerInvoke](https://create.roblox.com/docs/reference/engine/classes/RemoteFunction#OnServerInvoke). -#### Parameters +**Parameters** * **callback:** `(sender: Player, data: Array?) -> (Array | any)`\ The callback function to run on invoke, must return at least 1 value. -#### Returns +**Returns** * **void** @@ -136,7 +126,7 @@ The callback function to run on invoke, must return at least 1 value. Sets a rate limit that is applied when invoking or firing a network controller from the client. -#### Parameters +**Parameters** * **maxInvokesPerSecond:** `number`\ The maximum amount of invokes allowed per second, set to -1 to disable the rate limit @@ -144,6 +134,6 @@ The maximum amount of invokes allowed per second, set to -1 to disable the rate * **invokeOverflowCallback:** `((sender: Player) -> ())?`\ The callback function to run when the player has exceeded the current rate limit -#### Returns +**Returns** * **void** \ No newline at end of file diff --git a/docs/api/controllers/signal/signalcontroller.md b/docs/api/controllers/signal/signalcontroller.md index 25219676..126d0ed4 100644 --- a/docs/api/controllers/signal/signalcontroller.md +++ b/docs/api/controllers/signal/signalcontroller.md @@ -1,6 +1,6 @@ # SignalController -A lua-based signal implementation. +A lua-based signal implementation, based on [this](/api/engine/types#signalcontroller) type. ## Properties @@ -24,12 +24,12 @@ SignalController:Fire("Hello, world!") ``` ::: -#### Parameters +**Parameters** * **data:** `(Array | any)?`\ The data that should be sent the other script -#### Returns +**Returns** * **void** @@ -39,12 +39,12 @@ The data that should be sent the other script Connects a function to the event that is fired when another script fires the controller. -#### Parameters +**Parameters** * **func:** `(data: Array?) -> ()`\ The function to call when data is recieved -#### Returns +**Returns** * **[ControllerConnection](/api/engine/types#controllerconnection)** @@ -54,12 +54,12 @@ The function to call when data is recieved Connects a function to the event that is fired when another script fires the controller. When using `:Once`, the function is only run the first time and then the connection is disconnected automatically. -#### Parameters +**Parameters** * **func:** `(data: Array?) -> ()`\ The function to call when data is recieved -#### Returns +**Returns** * **[ControllerConnection](/api/engine/types#controllerconnection)** @@ -69,7 +69,7 @@ The function to call when data is recieved Yields the current thread until another script fires the signal controller. -#### Returns +**Returns** * **[Array](/api/engine/types#array)\** @@ -79,6 +79,6 @@ Yields the current thread until another script fires the signal controller. Disconnects all listeners from the current signal controller. -#### Returns +**Returns** * **void** \ No newline at end of file diff --git a/docs/api/engine/dependencies/enginedebugger.md b/docs/api/engine/dependencies/enginedebugger.md index ae1d9a15..9dc2d1b2 100644 --- a/docs/api/engine/dependencies/enginedebugger.md +++ b/docs/api/engine/dependencies/enginedebugger.md @@ -36,7 +36,7 @@ A list of cached debug calls for the current environment. The main debug handler, adds a prefix to logs sent out and respects logging settings. -#### Parameters +**Parameters** * **debugHandler:** `(...T) -> ()`\ The function to run on debug, for example `Debugger.Debug(print, "Hello, world!")` @@ -50,7 +50,7 @@ The prefix to put in front of the debug * **respectDebugger:** `boolean?`\ Whether or not to respect the debugger, should always be true for correct use -#### Returns +**Returns** * **void** @@ -60,12 +60,12 @@ Whether or not to respect the debugger, should always be true for correct use Clears the output and cached stack traces, with the option of also clearing cached debug calls. -#### Parameters +**Parameters** * **clearDebugCallCache:** `boolean?`\ Decides whether or not the debug call cache should be cleared too -#### Returns +**Returns** * **void** @@ -75,7 +75,7 @@ Decides whether or not the debug call cache should be cleared too Checks if a value is nil / false and runs the provided handler. This always respects the debugger. -#### Parameters +**Parameters** * **assertionHandler:** `(...any) -> ()`\ The handler to run if the assertion is not truthy @@ -89,7 +89,7 @@ The message to pass to the handler * **arguments:** `Tuple`\ Any values to format from `message`, functions identically to `string.format` -#### Returns +**Returns** * **T** @@ -99,7 +99,7 @@ Any values to format from `message`, functions identically to `string.format` Gets the call stack of any script within CanaryEngine. -#### Parameters +**Parameters** * **instance:** `LuaSourceContainer`\ The script to start the hierarchy at @@ -107,7 +107,7 @@ The script to start the hierarchy at * **stackName:** `string?`\ The name of the stack, defaults to the stack number -#### Returns +**Returns** * **[CallStack](#callstack)** @@ -117,7 +117,7 @@ The name of the stack, defaults to the stack number Errors if the param does not have the same type as what is expected. -#### Parameters +**Parameters** * **paramNumber:** `number`\ The number of which param errored, 1 would be the first param @@ -134,7 +134,7 @@ The param which caused the error * **debugHandler:** `(...any) -> ()`\ No description -#### Returns +**Returns** * **void** @@ -144,7 +144,7 @@ No description Logs an event in a script, which is then stored in a cache for that script. This allows you to make sure code is running while not cluttering the output in the live game. -#### Parameters +**Parameters** * **instance:** `LuaSourceContainer`\ The instance to cache the debug logs at @@ -155,7 +155,7 @@ The name to print and log it as * **printLog:** `boolean?`\ Whether or not to pring the log using [EngineDebugger.Debug](#debug), defaults to true -#### Returns +**Returns** * **void** @@ -165,6 +165,6 @@ Whether or not to pring the log using [EngineDebugger.Debug](#debug), defaults t Generates a UUID with safe characters. -#### Returns +**Returns** * **string** \ No newline at end of file diff --git a/docs/api/engine/dependencies/engineloader.md b/docs/api/engine/dependencies/engineloader.md index bbe9dce0..5e24041f 100644 --- a/docs/api/engine/dependencies/engineloader.md +++ b/docs/api/engine/dependencies/engineloader.md @@ -16,7 +16,7 @@ A boolean that is true if the client is loaded. Starts up the loader, this should be run as soon as the player joins in a client script inside `EngineReplicatedFirst/Scripts`. -#### Parameters +**Parameters** * **objectsToLoad:** `{ any }`\ The objects to load, can be a list of asset id strings or instances @@ -33,7 +33,7 @@ The amount of time to wait after the load, this is before the messages in loadin * **loadingText:** `{ loadingAssetsText: string, loadedAssetsText: string }?`\ The text that should be shown when loading assets and after loading assets -#### Returns +**Returns** * **void** @@ -43,11 +43,11 @@ The text that should be shown when loading assets and after loading assets Allows you to customize the interface, giving you the ability to change the relevant properties. `Container` is the main frame. -#### Parameters +**Parameters** * **interfaceProperties:** `{ [string]: { [string]: any } }`\ The objects to load, can be a list of asset id strings or instances -#### Returns +**Returns** * **void** \ No newline at end of file diff --git a/docs/api/engine/framework/canaryengine.md b/docs/api/engine/framework/canaryengine.md index 723802fa..49bf9cf0 100644 --- a/docs/api/engine/framework/canaryengine.md +++ b/docs/api/engine/framework/canaryengine.md @@ -18,23 +18,31 @@ The internal engine debugger, has useful functions to abide by debug settings. * [**EngineDebugger**](/api/engine/dependencies/enginedebugger) +--- + +### Future + +A reference to the Future module, which is a optimized version of a Promise. + +* [**Future**](https://util.redblox.dev/future.html) + ## Functions ### GetEngineServer Gets the server-sided interface of CanaryEngine. -#### Returns +**Returns** * [**CanaryEngineServer?**](/api/engine/framework/canaryengineserver) --- -### GetEngineClient +### GetEngineClient Gets the client-sided interface of CanaryEngine. -#### Returns +**Returns** * [**CanaryEngineClient?**](/api/engine/framework/canaryengineclient) @@ -44,7 +52,7 @@ Gets the client-sided interface of CanaryEngine. Gets the global-sided interface of CanaryEngine. Recommended that use this only in replicated packages, this is a bad practice anywhere else. -#### Returns +**Returns** * [**CanaryEngineRepliated?**](/api/engine/framework/canaryenginereplicated) @@ -54,14 +62,14 @@ Gets the global-sided interface of CanaryEngine. Recommended that use this only Creates a new signal that is then given a reference in the signals table. Create a new anonymous signal by leaving the name blank. -#### Parameters +**Parameters** * **signalName:** `string?`\ The name of the signal -#### Returns +**Returns** -* [**SignalController\**](/api/engine/types#signalcontroller) +* [**SignalController**](/api/controllers/signal/signalcontroller) --- @@ -69,6 +77,6 @@ The name of the signal Creates a new anonymous signal, this does not have a reference outside of the variable it was created in. This is essentially an alias for an empty [`CreateSignal`](#createsignal) -#### Returns +**Returns** -* [**SignalController\**](/api/engine/types#signalcontroller) \ No newline at end of file +* [**SignalController**](/api/controllers/signal/signalcontroller) \ No newline at end of file diff --git a/docs/api/engine/framework/canaryengineclient.md b/docs/api/engine/framework/canaryengineclient.md index d842c8ee..fb8cb2d2 100644 --- a/docs/api/engine/framework/canaryengineclient.md +++ b/docs/api/engine/framework/canaryengineclient.md @@ -32,12 +32,12 @@ A simple reference to the [Player.Backpack](https://create.roblox.com/docs/refer Creates a new network controller on the client, with the name of `controllerName` -#### Parameters +**Parameters** * **controllerName:** `string`\ The name of the controller -#### Returns +**Returns** * **[ClientNetworkController](/api/controllers/network/client)** @@ -47,6 +47,6 @@ The name of the controller Gets the players current character model; if it doesn't exist the thread will yield until it does. -#### Returns +**Returns** * **[Character](/api/engine/types#character)** \ No newline at end of file diff --git a/docs/api/engine/framework/canaryengineserver.md b/docs/api/engine/framework/canaryengineserver.md index d35e944f..ac527e42 100644 --- a/docs/api/engine/framework/canaryengineserver.md +++ b/docs/api/engine/framework/canaryengineserver.md @@ -16,11 +16,11 @@ Access to the [EasyProfile](/api/libraries/data/easyprofile) library. Creates a new network controller on the server, with the name of `controllerName` -#### Parameters +**Parameters** * **controllerName:** `string`\ The name of the controller -#### Returns +**Returns** * **[ServerNetworkController](/api/controllers/network/server)** \ No newline at end of file diff --git a/docs/api/libraries/base64.md b/docs/api/libraries/base64.md index 6bd229ed..b98e2a79 100644 --- a/docs/api/libraries/base64.md +++ b/docs/api/libraries/base64.md @@ -8,12 +8,12 @@ Allows you to decode and encode data into Base64. Encodes data into Base64. -#### Parameters +**Parameters** * **Data:** `string`\ The data to encode -#### Returns +**Returns** * **string** @@ -23,11 +23,11 @@ The data to encode Decodes data out of Base64. -#### Parameters +**Parameters** * **Data:** `string`\ The data to decode -#### Returns +**Returns** * **string** \ No newline at end of file diff --git a/docs/api/libraries/benchmark.md b/docs/api/libraries/benchmark.md index f93c57c9..c947b015 100644 --- a/docs/api/libraries/benchmark.md +++ b/docs/api/libraries/benchmark.md @@ -14,6 +14,6 @@ The data that is returned after a [BenchmarkObject:SetFunction](/api/libraries/b Creates a new Benchmark object to be used. -#### Returns +**Returns** * **[BenchmarkObject](/api/libraries/benchmarkobject)** \ No newline at end of file diff --git a/docs/api/libraries/benchmarkobject.md b/docs/api/libraries/benchmarkobject.md index 377e4da6..6e4e1607 100644 --- a/docs/api/libraries/benchmarkobject.md +++ b/docs/api/libraries/benchmarkobject.md @@ -32,7 +32,7 @@ A boolean to decide if the benchmark should be GC'ed. Starts the benchmark object. -#### Returns +**Returns** * **void** @@ -42,7 +42,7 @@ Starts the benchmark object. Stops the benchmark from running and destroys it, returns the amount of time it took to complete the code above it. -#### Returns +**Returns** * **number** @@ -52,7 +52,7 @@ Stops the benchmark from running and destroys it, returns the amount of time it Gets the current elapsed time of the benchmark, this will error if the benchmark is inactive. -#### Returns +**Returns** * **number?** @@ -67,7 +67,7 @@ Sets the function to be ran `timesToRun` amount of times. ::: -#### Parameters +**Parameters** * **timesToRun:** `number`\ The amount of times to run `func`. @@ -75,7 +75,7 @@ The amount of times to run `func`. * **func:** `(timesRan: number) -> ()`\ The function to run for each `timesToRun` index, has a `timesRan` argument which is how many times the benchmark has run so far. -#### Returns +**Returns** * **[BenchmarkData](/api/libraries/benchmark#benchmarkdata)** @@ -85,7 +85,7 @@ The function to run for each `timesToRun` index, has a `timesRan` argument which Destroys the `BenchmarkObject`, this is done automatically after `SetFunction` is finished or `Stop` is called. -#### Returns +**Returns** * **void** diff --git a/docs/api/libraries/data/easyprofile.md b/docs/api/libraries/data/easyprofile.md index 5728f6f3..98a88d62 100644 --- a/docs/api/libraries/data/easyprofile.md +++ b/docs/api/libraries/data/easyprofile.md @@ -34,7 +34,7 @@ A table of the currently loaded profiles in game, each key is based on a profile Gets an existing profile store or creates one if it does not exist yet. -#### Parameters +**Parameters** * **name:** `string?`\ The name of the profile store to get, defaults to "Global" @@ -45,6 +45,6 @@ The default data of profie when loaded, only applies if this is their first time * **playerKeyPattern:** `string?`\ The pattern for the key to use if used to store player data, use '%d' as a placeholder for the player's UserId. -#### Returns +**Returns** * **[ProfileStoreObject?](/api/libraries/data/profilestoreobject)** \ No newline at end of file diff --git a/docs/api/libraries/data/profileobject.md b/docs/api/libraries/data/profileobject.md index faef78cb..1c7cb767 100644 --- a/docs/api/libraries/data/profileobject.md +++ b/docs/api/libraries/data/profileobject.md @@ -8,7 +8,7 @@ What is returned from loading a profile, this is used player-per-player or by a Gets the data for the profile that was loaded in. -#### Returns +**Returns** * **[Dictionary](/api/engine/types#dictionary)?** @@ -18,7 +18,7 @@ Gets the data for the profile that was loaded in. Gets the meta tags for the profile that was loaded in. -#### Returns +**Returns** * **[Dictionary](/api/engine/types#dictionary)?** @@ -34,7 +34,7 @@ Creates leaderstats for Roblox's leaderboard based on provided values from the p |`number`| |`string`| -#### Parameters +**Parameters** * **player:** `Player`\ The player to parent the leaderstats to, required because the owner of the profile can be the player **or** a set string @@ -45,7 +45,7 @@ Specific stats to add, leaving this nil will account for all data on the profile * **isAttributes:** `boolean?`\ No description -#### Returns +**Returns** * **[Folder?](https://create.roblox.com/docs/reference/engine/classes/Folder)** @@ -55,7 +55,7 @@ No description Gets all of the global keys that were recieved when the target was offline. -#### Returns +**Returns** * **[Array](/api/engine/types#array)\<[GlobalKey](/api/libraries/data/easyprofile#globalkey)\>?** @@ -65,12 +65,12 @@ Gets all of the global keys that were recieved when the target was offline. Adds `UserId`'s to the target profile. -#### Parameters +**Parameters** * **userIds:** `number | { number }`\ The `userId`s to add. -#### Returns +**Returns** * **void** @@ -80,7 +80,7 @@ The `userId`s to add. Gets all the associated `userId`'s of the target profile. -#### Returns +**Returns** * **[Array](/api/engine/types#array)\?** @@ -90,12 +90,12 @@ Gets all the associated `userId`'s of the target profile. Removes all the associated `userId`'s off of the target profile, leave `userIds` blank to clear all user IDs. -#### Parameters +**Parameters** * **userIds:** `number | { number }`\ The `userId`'s to clear off the target profile -#### Returns +**Returns** * **void** @@ -105,7 +105,7 @@ The `userId`'s to clear off the target profile Gets all metadata that is related to the target profile. -#### Returns +**Returns** * **[ProfileMetaData?](/api/libraries/data/easyprofile#profilemetadata)** @@ -115,7 +115,7 @@ Gets all metadata that is related to the target profile. Gets the amount of data (in percent) currently being used by the profile. -#### Returns +**Returns** * **number?** @@ -125,7 +125,7 @@ Gets the amount of data (in percent) currently being used by the profile. Fires when a global key has been recieved by the server. -#### Parameters +**Parameters** * **recievedKey:** `GlobalKey`\ The global key that was recieved \ No newline at end of file diff --git a/docs/api/libraries/data/profilestoreobject.md b/docs/api/libraries/data/profilestoreobject.md index b97d3ee4..02221d11 100644 --- a/docs/api/libraries/data/profilestoreobject.md +++ b/docs/api/libraries/data/profilestoreobject.md @@ -4,33 +4,33 @@ Handles anything related to the profile store itself. ## Methods -### DeleteProfileAsync +### DeleteProfileAsync Completely wipes the data of the key userId, good for complying with `GDPR` practices. -#### Parameters +**Parameters** * **target:** `number | string`\ The user id / key to erase the data of -#### Returns +**Returns** -* **[Future](https://util.redblox.dev/future.html#methods)** +* **void** --- -### GetProfileAsync +### GetProfileAsync Fetches the data off the key `userId`, this will only read data and does not load it. -#### Parameters +**Parameters** * **target:** `number | string`\ The user id / key to get of the data of -#### Returns +**Returns** -* **[Future](https://util.redblox.dev/future.html#methods)<[Dictionary](/api/engine/types#dictionary)>** +* **[Dictionary](/api/engine/types#dictionary)** --- @@ -38,7 +38,7 @@ The user id / key to get of the data of Loads the data off the key `userId`. All edits to this data will be saved and be able to be used next session. -#### Parameters +**Parameters** * **owner:** `Player | string`\ The owner of profile to load the data of @@ -47,19 +47,19 @@ The owner of profile to load the data of Whether or not to reconcile the data of the profile, defaults to true * **profileClaimedHandler:** `((placeId: number, gameJobId: string) -> (ProfileLoadType))? | ProfileLoadType?`\ -The function to run when the profile is already claimed +The function to run when the profile is already claimed **or** the type of way to load the profile -#### Returns +**Returns** * **[Future](https://util.redblox.dev/future.html#methods)<[ProfileObject?](/api/libraries/data/profileobject)>** --- -### RemoveGlobalKeyAsync +### RemoveGlobalKeyAsync Removes the global key that sent by using [ProfileStoreObject:SetGlobalKeyAsync](#setglobalkeyasync) with the key ID of `keyId`. This only applies if it has not been recieved yet, which means the function should be ran around within the first minute of being sent. -#### Parameters +**Parameters** * **target:** `number | string`\ The target to remove the global key of @@ -67,17 +67,17 @@ The target to remove the global key of * **keyId:** `number`\ The `keyId` of the key to remove -#### Returns +**Returns** -* **[Future](https://util.redblox.dev/future.html#methods)** +* **void** --- -### SetGlobalKeyAsync +### SetGlobalKeyAsync Sets a global key for target profile, regardless of whether they share the same `JobId` as the sender or they are offline. -#### Parameters +**Parameters** * **target:** `number | string`\ The target to set the global key of @@ -88,9 +88,9 @@ The key to send to the target * **value:** `any`\ The value of `key` -#### Returns +**Returns** -* **[Future](https://util.redblox.dev/future.html#methods)** +* **void** --- @@ -108,7 +108,7 @@ Players.PlayerRemoving:Connect(function(player) end) ``` -#### Parameters +**Parameters** * **owner:** `Player | string`\ The owner of the profile to unclaim the session lock of @@ -119,7 +119,7 @@ Values to save that are not already saved to the profile data, for example attri * **hopReadyCallback:** `(() -> ())?`\ The function to run when a server hop is ready, leaving this blank will disable this feature -#### Returns +**Returns** * **void** @@ -129,7 +129,7 @@ The function to run when a server hop is ready, leaving this blank will disable Fires when a session lock has been claimed. -#### Parameters +**Parameters** * **player:** `Player | string`\ The player/key whose session lock was claimed @@ -140,7 +140,7 @@ The player/key whose session lock was claimed Fires when a session lock has been unclaimed. -#### Parameters +**Parameters** * **player:** `Player | string`\ The player/key whose session lock was unclaimed \ No newline at end of file diff --git a/docs/api/libraries/mdify.md b/docs/api/libraries/mdify.md index 6791be09..b45f6495 100644 --- a/docs/api/libraries/mdify.md +++ b/docs/api/libraries/mdify.md @@ -8,7 +8,7 @@ Converts markdown text into native Roblox RichText. Converts the provided markdown text to Roblox RichText. -#### Parameters +**Parameters** * **text:** `string`\ The markdown text to convert to RichText @@ -16,6 +16,6 @@ The markdown text to convert to RichText * **emojiColor:** `("d" | "md" | "m" | "ml" | "l")?`\ The skin color of any emojis, such as face or hands. -#### Returns +**Returns** * **string** \ No newline at end of file diff --git a/docs/api/libraries/sprite.md b/docs/api/libraries/sprite.md index 154766b7..952e3c25 100644 --- a/docs/api/libraries/sprite.md +++ b/docs/api/libraries/sprite.md @@ -8,7 +8,7 @@ Handles the animation of spritesheets on image labels. Animates the given sprite to play like a GIF. -#### Parameters +**Parameters** * **image:** `ImageLabel`\ The image label that the sprite should be animated on @@ -25,7 +25,7 @@ The amount of frames per second that the sprite should be played at. Defaults to * **imageId:** `string?`\ The image id that the image label should be set to, defaults to the initial image of the image -#### Returns +**Returns** * **void** @@ -35,11 +35,11 @@ The image id that the image label should be set to, defaults to the initial imag Stops the currently playing animation, if any. -#### Parameters +**Parameters** * **image:** `ImageLabel`\ The image label that should stop being animated -#### Returns +**Returns** * **void** \ No newline at end of file diff --git a/docs/api/libraries/statistics.md b/docs/api/libraries/statistics.md index 4d5174ab..f0f8b9ce 100644 --- a/docs/api/libraries/statistics.md +++ b/docs/api/libraries/statistics.md @@ -15,12 +15,12 @@ print(Statistics.GetMedian(CollectedData)) -- Output: 8 ``` -#### Parameters +**Parameters** * **numberList:** `Array`\ The dataset to perform the action on -#### Returns +**Returns** * **number** @@ -37,12 +37,12 @@ print(Statistics.GetMean(CoinsForPlayers)) -- Get the average amount of coins ea -- Output: 1381.125 ``` -#### Parameters +**Parameters** * **numberList:** `Array`\ The dataset to perform the action on -#### Returns +**Returns** * **number** @@ -52,11 +52,11 @@ The dataset to perform the action on Gets the number that occurs most in the provided dataset, nil if none or each number occurs the same amount of times. More info can be found [here](https://en.wikipedia.org/wiki/Mode_(statistics)) -#### Parameters +**Parameters** * **numberList:** `Array`\ The dataset to perform the action on -#### Returns +**Returns** * **number?** \ No newline at end of file diff --git a/docs/api/libraries/topbariconobject.md b/docs/api/libraries/topbariconobject.md index 757a7869..df38f612 100644 --- a/docs/api/libraries/topbariconobject.md +++ b/docs/api/libraries/topbariconobject.md @@ -64,7 +64,7 @@ The amount of notices the icon actually has. Adds notices to the parent topbar icon. -#### Parameters +**Parameters** * **notices:** `number?`\ The amount of notices to add, leaving this nil will add a single notice @@ -72,7 +72,7 @@ The amount of notices to add, leaving this nil will add a single notice * **noticeCap:** `number?`\ When to display a + sign after a set amount of notices, defaults to 99 -#### Returns +**Returns** * **void** @@ -82,12 +82,12 @@ When to display a + sign after a set amount of notices, defaults to 99 Removes notices that are active in the icon. -#### Parameters +**Parameters** * **notices:** `number?`\ The amount of notices to remove, leave nil to remove all notices -#### Returns +**Returns** * **void** @@ -97,12 +97,12 @@ The amount of notices to remove, leave nil to remove all notices Binds multiple key codes to activate the icons `Activated` event. -#### Parameters +**Parameters** * **keyCodes:** `{ Enum.KeyCode }?`\ The key codes to listen to, if it is nil it will unbind all binded key codes -#### Returns +**Returns** * **void** @@ -112,12 +112,12 @@ The key codes to listen to, if it is nil it will unbind all binded key codes Sets the image size of the icon, default is filled. -#### Parameters +**Parameters** * **imageSize:** `Vector2`\ The size to set the image to -#### Returns +**Returns** * **void** @@ -127,12 +127,12 @@ The size to set the image to Sets the status of the icon visibility. -#### Parameters +**Parameters** * **enabled:** `boolean`\ Whether or not to enable the icon -#### Returns +**Returns** * **void** @@ -142,12 +142,12 @@ Whether or not to enable the icon Binds a GuiObject to the icon. This will toggle the visibility to the opposite when the icon is clicked. -#### Parameters +**Parameters** * **guiObject:** `GuiObject`\ The [GuiObject](https://create.roblox.com/docs/reference/engine/classes/GuiObject) to bind to activation, set to nil to unbind -#### Returns +**Returns** * **void** @@ -157,12 +157,12 @@ The [GuiObject](https://create.roblox.com/docs/reference/engine/classes/GuiObjec Adds a tooltip to the icon when hovering. -#### Parameters +**Parameters** * **text:** `string?`\ The text to put in the tooltip, leave this nil to remove the tooltip -#### Returns +**Returns** * **void** @@ -172,12 +172,12 @@ The text to put in the tooltip, leave this nil to remove the tooltip Sets the tooltips visibility forcibly. -#### Parameters +**Parameters** * **enabled:** `boolean`\ Whether or not the tooltip should show -#### Returns +**Returns** * **void** @@ -187,7 +187,7 @@ Whether or not the tooltip should show Sets the image rect size and offset. Useful if you are using a spritesheet image. -#### Parameters +**Parameters** * **rectSize:** `Rect`\ The [ImageLabel.ImageRectSize](https://create.roblox.com/docs/reference/engine/classes/ImageLabel#ImageRectSize) @@ -195,7 +195,7 @@ The [ImageLabel.ImageRectSize](https://create.roblox.com/docs/reference/engine/c * **rectOffset:** `Rect`\ The [ImageLabel.ImageRectOffset](https://create.roblox.com/docs/reference/engine/classes/ImageLabel#ImageRectOffset) -#### Returns +**Returns** * **void** @@ -205,7 +205,7 @@ The [ImageLabel.ImageRectOffset](https://create.roblox.com/docs/reference/engine Destroys the icon itself, removing it from the topbar. -#### Returns +**Returns** * **void** @@ -215,7 +215,7 @@ Destroys the icon itself, removing it from the topbar. Fires when the icon is activated, by any supported input type. Also passes in the user input type enum. -#### Parameters +**Parameters** * **inputType:** `Enum.UserInputType`\ The user input type that activated the icon @@ -226,7 +226,7 @@ The user input type that activated the icon Fires whenever a notice is added to the icon. -#### Parameters +**Parameters** * **noticeCount:** `number`\ The amount of notices added to the icon @@ -237,7 +237,7 @@ The amount of notices added to the icon Fires whenever the state of the icon changes. For example: Hovering -> Default. -#### Parameters +**Parameters** * **newState:** `string`\ The latest state at the time of the event being fired \ No newline at end of file diff --git a/docs/api/libraries/topbarspacerobject.md b/docs/api/libraries/topbarspacerobject.md index 039e6333..818410e3 100644 --- a/docs/api/libraries/topbarspacerobject.md +++ b/docs/api/libraries/topbarspacerobject.md @@ -32,12 +32,12 @@ The area of the spacer. `1` is left and `2` is right. Sets whether or not the spacer should be enabled. -#### Parameters +**Parameters** * **enabled:** `boolean`\ Whether or not the spacer should be enabled -#### Returns +**Returns** * **void** @@ -47,12 +47,12 @@ Whether or not the spacer should be enabled Sets the size of the spacer on the `X` scale. -#### Parameters +**Parameters** * **size:** `number`\ The size to set the spacer to -#### Returns +**Returns** * **void** @@ -62,6 +62,6 @@ The size to set the spacer to Destroys the spacer itself, removing it from the topbar. -#### Returns +**Returns** * **void** \ No newline at end of file diff --git a/docs/api/libraries/uishelf.md b/docs/api/libraries/uishelf.md index e348aab5..db73ab34 100644 --- a/docs/api/libraries/uishelf.md +++ b/docs/api/libraries/uishelf.md @@ -40,12 +40,12 @@ Whether or not voice chat is enabled in your game, this must be toggled accordin Creates a new topbar icon, with declared properties. -#### Parameters +**Parameters** * **properties:** `Array`\ The properties to set on the icon -#### Returns +**Returns** * **[TopBarIconObject](/api/libraries/topbariconobject)** @@ -55,7 +55,7 @@ The properties to set on the icon Creates a new topbar spacer, acts a spacer to other icons. -#### Parameters +**Parameters** * **properties:** `Array`\ The properties to set on the spacer @@ -63,7 +63,7 @@ The properties to set on the spacer * **bypass:** `boolean?`\ Allows you to bypass the order restrictions, should only be used internally -#### Returns +**Returns** * **[TopBarSpacerObject](/api/libraries/topbarspacerobject)** @@ -73,11 +73,11 @@ Allows you to bypass the order restrictions, should only be used internally Sets whether or not the top bar is enabled, only applies to UIShelf icons. -#### Parameters +**Parameters** * **enabled** `boolean`\ Whether or not to enable the topbar -#### Returns +**Returns** * **void** \ No newline at end of file diff --git a/docs/featured.md b/docs/featured.md index 8c312f90..f333f920 100644 --- a/docs/featured.md +++ b/docs/featured.md @@ -1,15 +1,21 @@ --- title: Featured -description: Features trailers for games that use CanaryEngine, as example projects +description: Features trailers for experiences that use CanaryEngine, as example projects keywords: [roblox, game, trailer, featured, framework] --- # Featured -Here are a few games that use CanaryEngine as their game framework! +A list of experiences which use CanaryEngine as their framework, and their trailers. ## [Gorytown 2](https://www.roblox.com/games/13722842264/Gorytown-2) **Trailer:** - \ No newline at end of file + + +## [Fractured Franchise RP](https://www.roblox.com/games/7377364733/FNAF-Movie-RP-Fractured-Franchise-Beta) + +**Trailer:** + + \ No newline at end of file diff --git a/docs/static/images/trello.svg b/docs/static/images/trello.svg deleted file mode 100644 index 1a48a51c..00000000 --- a/docs/static/images/trello.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - trello-mark-white - Created with Sketch. - - - - - - - - - \ No newline at end of file diff --git a/src/lua/framework/Vendor/Controllers/Vendor/NetworkController/init.luau b/src/lua/framework/Vendor/Controllers/Vendor/NetworkController/init.luau index d354f2f6..a238e32d 100644 --- a/src/lua/framework/Vendor/Controllers/Vendor/NetworkController/init.luau +++ b/src/lua/framework/Vendor/Controllers/Vendor/NetworkController/init.luau @@ -1,276 +1,82 @@ --- // NetworkController ---[=[ - The parent of all classes. +-- // Package - @ignore - @class NetworkController -]=] local NetworkController = { } - ---[=[ - The NetworkControllerServer class. - - @client - @class NetworkControllerClient -]=] local NetworkControllerClient = { } - ---[=[ - The name of the the network controller. - - @readonly - - @prop Name string - @within NetworkControllerClient -]=] - ---[=[ - A list of connections. - - @private - - @prop _Connections {ControllerConnection} - @within NetworkControllerClient -]=] - ---[=[ - The bridge for use in BridgeNet. - - @readonly - @private - - @prop _Bridge ClientBridge - @within NetworkControllerClient -]=] - ---[=[ - The NetworkControllerServer class. - - @server - @class NetworkControllerServer -]=] local NetworkControllerServer = { } ---[=[ - The name of the the network controller. - - @readonly - - @prop Name string - @within NetworkControllerServer -]=] - ---[=[ - A list of connections. - - @private - - @prop _Connections {ControllerConnection} - @within NetworkControllerServer -]=] +local Vendor = script.Parent.Vendor ---[=[ - The bridge for use in BridgeNet. +-- // Variables - @readonly - @private +local EngineVendor = Vendor.Parent.Parent.Parent.Parent - @prop _Bridge ServerBridge - @within NetworkControllerServer -]=] +local PlayerService = game:GetService("Players") +local RunService = game:GetService("RunService") local Indexes = { {__index = NetworkControllerClient}, {__index = NetworkControllerServer}, } --- // Variables - -local Vendor = script.Parent.Vendor -local PlayerService = game:GetService("Players") - +local Future = require(EngineVendor.Libraries.RedbloxUtils.Future) local BridgeNet = require(Vendor.BridgeNet2.BridgeNet2) -local SanitizeData = require(Vendor.Parent.Parent.SanitizeData) +local Sanitize = require(Vendor.Parent.Parent.Sanitize) -- // Functions -- // Constructors ---[=[ - Creates a new client network controller. - - @param name string -- The name of the new controller - @return NetworkControllerClient -]=] -function NetworkController.NewClientController(name: string, timeout: number) - local self = setmetatable({ }, Indexes[1]) - - self._Bridge = BridgeNet.ClientBridge(name, timeout) - self._Connections = { } - self.Name = name - - return self -end - ---[=[ - Creates a new server network controller. +function NetworkController.CreateController(name: string) + local self = setmetatable({ }, RunService:IsClient() and Indexes[1] or Indexes[2]) - @param name string -- The name of the new controller - @return NetworkControllerServer -]=] -function NetworkController.NewServerController(name: string) - local self = setmetatable({ }, Indexes[2]) - - self._Bridge = BridgeNet.ServerBridge(name) - self._Connections = { } self.Name = name + self._Bridge = BridgeNet.ReferenceBridge(name) return self end ---[=[ - Fires an event which sends data to the server, equivalent to [RemoteEvent:FireServer] - - :::tip - - If you're firing a single piece of data, there is no need to wrap it in a table! +-- Network Controller Client - ```lua - NetworkController:Fire("Hello, world!") - ``` - - ::: - - @param data ({any} | any)? -- The data that should be sent to the server -]=] function NetworkControllerClient:Fire(data: ({any} | any)?) - self._Bridge:Fire(SanitizeData.SanitizeData(data)) + self._Bridge:Fire(Sanitize(data)) end ---[=[ - Connects a function to the event that is fired when the server fires the network controller. When using `:Once`, the function is only run the first time and then the connection is disconnected automatically. - - @param func (data: {any}) -> () -- The function to call when data is recieved from the server - @return ControllerConnection -]=] -function NetworkControllerClient:Once(func: (data: {any}?) -> ()) +function NetworkControllerClient:Listen(func: (data: {any}?) -> ()) local Connection = self._Bridge:Connect(func) - table.insert(self._Connections, Connection) return Connection end ---[=[ - Connects a function to the event that is fired when the server fires the network controller. - - @param func (data: {any}) -> () -- The function to call when data is recieved from the server - @return ControllerConnection -]=] -function NetworkControllerClient:Connect(func: (data: {any}?) -> ()) - local Connection = self._Bridge:Connect(func) - - table.insert(self._Connections, Connection) - return Connection +function NetworkControllerClient:InvokeAsync(data: ({any} | any)?) + return Future.new(function() + return Sanitize(self._Bridge:InvokeServerAsync(Sanitize(data))) + end) end ---[=[ - Yields the current thread until the server fires the network controller. +-- Network Controller Server - @yields - @return {any} -]=] -function NetworkControllerClient:Wait(): {any}? - return self._Bridge:Wait() -end - ---[=[ - Invokes the server, equivalent to [RemoteFunction:InvokeServer]. - - @yields - - @param data ({any} | any)? -- The data to invoke the server with - @return {any} -]=] -function NetworkControllerClient:InvokeAsync(data: ({any} | any)?) - return SanitizeData.SanitizeData(self._Bridge:InvokeServerAsync(SanitizeData.SanitizeData(data))) -end - ---[=[ - Disconnects all listeners from the current network controller. -]=] -function NetworkControllerClient:DisconnectAll() - for _, connection in self._Connections do - connection:Disconnect() - end -end - ---[=[ - Destroys the current network controller. -]=] -function NetworkControllerClient:Destroy() - self._Bridge:Destroy() - table.clear(self) - setmetatable(self, nil) -end - --- // Network Controller Server - ---[=[ - Fires an event which sends data to the client, equivalent to [RemoteEvent:FireClient]. - - :::tip - - If you need to fire the event to multiple players instead of one, you can use a table of players. - - ```lua - NetworkController:Fire({Player1, Player2, Player3}, {1, 2, 3}) - ``` - - ::: - - @param recipients Player | {Player} -- The players who should recieve the data and/or call - @param data ({any} | any)? -- The data that should be sent to the client -]=] function NetworkControllerServer:Fire(recipients: Player | {Player}, data: ({any} | any)?) if type(recipients) ~= "table" then - self._Bridge:Fire(recipients, SanitizeData.SanitizeData(data)) + self._Bridge:Fire(recipients, Sanitize(data)) return end - self._Bridge:Fire(BridgeNet.Players(recipients), SanitizeData.SanitizeData(data)) + self._Bridge:Fire(BridgeNet.Players(recipients), Sanitize(data)) end ---[=[ - Fires an event which sends data to every client connected to the server, equivalent to [RemoteEvent:FireAllClients]. - - @param data ({any} | any)? -- The data that should be sent to each player -]=] function NetworkControllerServer:FireAll(data: ({any} | any)?) - self._Bridge:Fire(BridgeNet.AllPlayers(), SanitizeData.SanitizeData(data)) + self._Bridge:Fire(BridgeNet.AllPlayers(), Sanitize(data)) end ---[=[ - Fires an event which sends data to every client connected to the server, except for players in the `except` parameter. - - @param except Player | {Player} -- The players which the call should not be sent to - @param data ({any} | any)? -- The data that should be sent to each player except `except` -]=] function NetworkControllerServer:FireExcept(except: Player | {Player}, data: ({any} | any)?) if type(except) ~= "table" then - self._Bridge:Fire(BridgeNet.PlayersExcept({except}), SanitizeData.SanitizeData(data)) + self._Bridge:Fire(BridgeNet.PlayersExcept({except}), Sanitize(data)) return end - self._Bridge:Fire(BridgeNet.PlayersExcept(except), SanitizeData.SanitizeData(data)) + self._Bridge:Fire(BridgeNet.PlayersExcept(except), Sanitize(data)) end ---[=[ - Fires an event which sends data to every client that is within `maximumRange` studs from `comparePoint`. - - @param comparePoint Vector3 -- The point to compare from, can be a standalone Vector3 or a part's Vector3 - @param maximumRange number -- The maximum range of which the player's characters have to be within to recieve the event - @param data ({any} | any)? -- The data that should be sent to each player within `maximumRange` -]=] function NetworkControllerServer:FireInRange(comparePoint: Vector3, maximumRange: number, data: ({any} | any)?) local PlayersToFireTo = { } @@ -283,21 +89,11 @@ function NetworkControllerServer:FireInRange(comparePoint: Vector3, maximumRange self:Fire(PlayersToFireTo, data) end ---[=[ - Recieves an invoke from the server, and runs the callback function which returns some data. Equivalent to [RemoteFunction.OnServerInvoke]. - - @param callback (sender: Player, data: {any}) -> (({any} | any)?) -- The callback function to run on invoke, must return at least 1 value. -]=] -function NetworkControllerServer:OnInvoke(callback: (sender: Player, data: {any}) -> (({any} | any))) - self._Bridge.OnServerInvoke = callback +function NetworkControllerServer:Listen(func: (sender: Player, data: {any}?) -> ()) + local Connection = self._Bridge:Connect(func) + return Connection end ---[=[ - Sets a rate limit that is applied when invoking or firing a network controller from the client. - - @param maxInvokesPerSecond number -- The maximum amount of invokes allowed per second, set to `-1` to disable the rate limit - @param invokeOverflowCallback ((sender: Player) -> ())? -- The callback function to run when the player has exceeded the current rate limit -]=] function NetworkControllerServer:SetRateLimit(maxInvokesPerSecond: number, invokeOverflowCallback: ((sender: Player) -> ())?) if maxInvokesPerSecond <= -1 then self._Bridge:DisableRateLimit() @@ -311,62 +107,8 @@ function NetworkControllerServer:SetRateLimit(maxInvokesPerSecond: number, invok self._Bridge:RateLimit(maxInvokesPerSecond, invokeOverflowCallback) end ---[=[ - Connects a function to the event that is fired when the client fires the network controller. When using `:Once`, the function is only run the first time and then the connection is disconnected automatically. - - @param func (sender: Player, data: {any}) -> () -- The function to call when data is recieved from the client - @return ControllerConnection -]=] -function NetworkControllerServer:Once(func: (sender: Player, data: {any}?) -> ()) - local Connection = self._Bridge:Once(func) - - table.insert(self._Connections, Connection) - return Connection -end - ---[=[ - Connects a function to the event that is fired when the server fires the network controller. - - @param func (sender: Player, data: {any}) -> () -- The function to call when data is recieved from the server - @return ControllerConnection -]=] -function NetworkControllerServer:Connect(func: (sender: Player, data: {any}?) -> ()) - local Connection = self._Bridge:Connect(func) - - table.insert(self._Connections, Connection) - return Connection -end - ---[=[ - Yields the current thread until the client fires the network controller. - - @yields - @return (Player, {any}) -]=] -function NetworkControllerServer:Wait(): (Player, {any}) - return self._Bridge:Wait() -end - ---[=[ - Disconnects all listeners from the current network controller. -]=] -function NetworkControllerServer:DisconnectAll() - for _, connection in self._Connections do - if not connection.Connected then - continue - end - - connection:Disconnect() - end -end - ---[=[ - Destroys the current network controller. -]=] -function NetworkControllerServer:Destroy() - self._Bridge:Destroy() - table.clear(self) - setmetatable(self, nil) +function NetworkControllerServer:OnInvoke(callback: (sender: Player, data: {any}?) -> (({any} | any))) + self._Bridge.OnServerInvoke = callback end -- // Actions diff --git a/src/lua/framework/Vendor/Controllers/Vendor/SignalController/init.luau b/src/lua/framework/Vendor/Controllers/Vendor/SignalController/init.luau index 5a6bb119..d8966f04 100644 --- a/src/lua/framework/Vendor/Controllers/Vendor/SignalController/init.luau +++ b/src/lua/framework/Vendor/Controllers/Vendor/SignalController/init.luau @@ -1,40 +1,8 @@ -- // Package ---[=[ - The parent of all classes. - - @ignore - @class SignalController -]=] local SignalController = { } - ---[=[ - The SignalControllerObject class. - - @client - @class SignalControllerObject -]=] local SignalControllerObject = { } ---[=[ - The name of the the signal controller. - - @readonly - - @prop Name string - @within SignalControllerObject -]=] - ---[=[ - The signal for use in Signal. - - @readonly - @private - - @prop _Signal SignalController - @within SignalControllerObject -]=] - SignalController.__index = SignalControllerObject -- // Variables @@ -47,13 +15,7 @@ local Sanitize = require(script.Parent.Parent.Sanitize) -- // Functions ---[=[ - Creates a new signal controller. - - @param name string -- The name of the new controller - @return SignalControllerObject -]=] -function SignalController.NewController(name: string) +function SignalController.CreateController(name: string) local self = setmetatable({ }, SignalControllerObject) self._Signal = Signal() @@ -62,41 +24,14 @@ function SignalController.NewController(name: string) return self end ---[=[ - Fires an event which sends data to another script that is connected to it, equivalent to [BindableEvent:Fire] - - :::tip - - If you're firing a single piece of data, there is no need to wrap it in a table! - - ```lua - SignalController:Fire("Hello, world!") - ``` - - ::: - - @param data ({any} | any)? -- The data that should be sent the other script -]=] function SignalControllerObject:Fire(data: ({any} | any)?) self._Signal:Fire(Sanitize(data)) end ---[=[ - Connects a function to the event that is fired when another script fires the controller. - - @param func (data: {any}) -> () -- The function to call when data is recieved - @return ControllerConnection -]=] function SignalControllerObject:Connect(func: (data: {any}?) -> ()) return self._Signal:Connect(func) end ---[=[ - Connects a function to the event that is fired when another script fires the controller. When using `:Once`, the function is only run the first time and then the connection is disconnected automatically. - - @param func (data: {any}) -> () -- The function to call when data is recieved - @return ControllerConnection -]=] function SignalControllerObject:Once(func: (data: {any}?) -> ()) local Disconnect @@ -108,19 +43,10 @@ function SignalControllerObject:Once(func: (data: {any}?) -> ()) return Disconnect end ---[=[ - Yields the current thread until another script fires the signal controller. - - @yields - @return {any} -]=] function SignalControllerObject:Wait(): {any}? return self._Signal:Wait() end ---[=[ - Disconnects all listeners from the current signal controller. -]=] function SignalControllerObject:DisconnectAll() self._Signal:DisconnectAll() end diff --git a/src/lua/framework/Vendor/Controllers/Controllers.luau b/src/lua/framework/Vendor/Controllers/init.luau similarity index 81% rename from src/lua/framework/Vendor/Controllers/Controllers.luau rename to src/lua/framework/Vendor/Controllers/init.luau index 93c9f18f..440ede35 100644 --- a/src/lua/framework/Vendor/Controllers/Controllers.luau +++ b/src/lua/framework/Vendor/Controllers/init.luau @@ -1,9 +1,3 @@ ---[=[ - The parent of all classes. - - @ignore - @class Controllers -]=] local Controllers = { } local Vendor = script.Parent.Vendor diff --git a/src/lua/framework/Vendor/Debugger.luau b/src/lua/framework/Vendor/Debugger.luau index bf334312..ff24ec23 100644 --- a/src/lua/framework/Vendor/Debugger.luau +++ b/src/lua/framework/Vendor/Debugger.luau @@ -1,42 +1,8 @@ -- // Package ---[=[ - The parent of all classes. - - @class EngineDebugger -]=] local EngineDebugger = { } ---[=[ - A list of cached stack traces for the current environment. - - @prop CachedStackTraces {[string]: CallStack} - @within EngineDebugger -]=] - ---[=[ - A list of cached debug calls for the current environment. - - @prop CachedDebugCalls {string | {string}} - @within EngineDebugger -]=] - ---[=[ - The callstack type. - - @private - - @type CallStack {Name: string, Source: string, DefinedLine: number} - @within EngineDebugger -]=] type CallStack = {Name: string, Source: string, DefinedLine: number} - ---[=[ - This type contains every roblox user data and generic type. - - @type ExpectedType "Axes" | "BrickColor" | "CatalogSearchParams" | "CFrame" | "Color3" | "ColorSequence" | "ColorSequenceKeypoint" | "Content" | "DateTime" | "DockWidgetPluginGuiInfo" | "Enum" | "EnumItem" | "Enums" | "Faces" | "FloatCurveKey" | "Font" | "Instance" | "NumberRange" | "NumberSequence" | "NumberSequenceKeyPoint" | "OverlapParams" | "PathWaypoint" | "PhysicalProperties" | "Random" | "Ray" | "RayastParams" | "RaycastResult" | "RBXScriptConnection" | "RBXScriptSignal" | "Rect" | "Region3" | "Region3int16" | "SharedTable" | "TweenInfo" | "UDim" | "UDim2" | "Vector2" | "Vector2int16" | "Vector3" | "Vector3int16" | "nil" | "boolean" | "number" | "string" | "function" | "userdata" | "thread" | "table" - @within EngineDebugger -]=] export type ExpectedType = "Axes" | "BrickColor" | "CatalogSearchParams" | "CFrame" | "Color3" | "ColorSequence" | "ColorSequenceKeypoint" | "Content" | "DateTime" | "DockWidgetPluginGuiInfo" | "Enum" | "EnumItem" | "Enums" | "Faces" | "FloatCurveKey" | "Font" | "Instance" | "NumberRange" | "NumberSequence" | "NumberSequenceKeyPoint" | "OverlapParams" | "PathWaypoint" | "PhysicalProperties" | "Random" | "Ray" | "RayastParams" | "RaycastResult" | "RBXScriptConnection" @@ -105,14 +71,6 @@ local function GetAncestorsUntilParentFolder(instance: Instance): {string | {Ins } end ---[=[ - The main debug handler, adds a prefix to logs sent out and respects logging settings. - - @param debugHandler (...T) -> () | (message: T, level: number) -> () -- The function to run on debug, for example `Debugger.Debug(print, "Hello, world!")` - @param arguments {string} | string -- The contents to be passed to the function - @param prefix string? -- The prefix to put in front of the debug - @param respectDebugger boolean? -- Whether or not to respect the debugger, should always be true for correct use -]=] function EngineDebugger.Debug(debugHandler: (...any) -> (), arguments: {any} | any, prefix: string?, respectDebugger: boolean?) prefix = prefix or Prefix @@ -140,11 +98,6 @@ function EngineDebugger.Debug(debugHandler: (...any) -> (), arguments: {any} | a end end ---[=[ - Clears the output and cached stack traces, with the option of also clearing cached debug calls. - - @param clearDebugCallCache boolean? -- Decides whether or not the debug call cache should be cleared too -]=] function EngineDebugger.ClearOutput(clearDebugCallCache: boolean?) if clearDebugCallCache then table.clear(EngineDebugger.CachedDebugCalls) @@ -154,16 +107,6 @@ function EngineDebugger.ClearOutput(clearDebugCallCache: boolean?) LogService:ClearOutput() end ---[=[ - Checks if a value is nil / false and runs the provided handler. This always respects the debugger. - - @param assertionHandler (...any) -> () -- The handler to run if the assertion is not truthy - @param assertion T -- The value to assert, this is checked - @param message string -- The message to pass to the handler - @param ... string -- Any values to format from message, functions identically to `string.format` - - @return T -]=] function EngineDebugger.Assert(assertionHandler: (...any) -> (), assertion: T, message: string, ...: string): T if not assertion then EngineDebugger.Debug(assertionHandler, string.format(message, ...)) @@ -171,14 +114,6 @@ function EngineDebugger.Assert(assertionHandler: (...any) -> (), assertion: T return assertion end ---[=[ - Gets the call stack of any script. - - @param instance LuaSourceContainer -- The script to start at - @param stackName string? -- The name of the stack, defaults to the stack number - - @return CallStack -]=] function EngineDebugger.GetCallStack(instance: LuaSourceContainer, stackName: string?): CallStack if not instance:IsA("LuaSourceContainer") then EngineDebugger.DebugInvalidData(1, "GetCallStack", "LuaSourceContainer", instance) @@ -201,16 +136,6 @@ function EngineDebugger.GetCallStack(instance: LuaSourceContainer, stackName: st return StackTable end ---[=[ - Errors if the param does not have the same type as what is expected. - - @deprecated v4.0.0 -- Use `Guard` instead - - @param paramNumber number -- The number of which param errored, 1 would be the first param - @param funcName string -- The name of the function - @param expectedType ExpectedType -- The type that was expected of `param` - @param param T -- The param which caused the error -]=] function EngineDebugger.DebugInvalidData(paramNumber: number, funcName: string, expectedType: ExpectedType, param: unknown, debugHander: (...any) -> ()) local ParamType = typeof(param) @@ -224,13 +149,6 @@ function EngineDebugger.DebugInvalidData(paramNumber: number, funcName: string, end end ---[=[ - Logs an event in a script, which is then stored in a cache for that script. This allows you to make sure code is running while not cluttering the output in the live game. - - @param instance LuaSourceContainer -- The instance to cache the debug logs at - @param eventName string -- The name to print and log it as - @param printLog boolean? -- Whether or not to pring the log using [EngineDebugger.Debug], defaults to true -]=] function EngineDebugger.LogEvent(instance: LuaSourceContainer, eventName: string, printLog: boolean?) if printLog == nil then printLog = true @@ -247,11 +165,6 @@ function EngineDebugger.LogEvent(instance: LuaSourceContainer, eventName: string end end ---[=[ - Generates a UUID with safe characters. - - @return string -]=] function EngineDebugger.GenerateUUID() return string.gsub( HttpService:GenerateGUID(false), diff --git a/src/lua/framework/Vendor/Libraries/EasyProfile/init.luau b/src/lua/framework/Vendor/Libraries/EasyProfile/init.luau index 90255987..9fb99189 100644 --- a/src/lua/framework/Vendor/Libraries/EasyProfile/init.luau +++ b/src/lua/framework/Vendor/Libraries/EasyProfile/init.luau @@ -1,35 +1,17 @@ ---[=[ - The metadata for a user's profile. +-- // Package - @field ProfileCreated number - @field ProfileLoadCount number - @field ProfileActiveSession {placeId: number, jobId: string} - - @interface ProfileMetaData - @within EasyProfile -]=] -type ProfileMetaData = {ProfileCreated: number; ProfileLoadCount: number; ProfileActiveSession: {placeId: number; jobId: string;}} -type ProfileLoadType = "Repeat" | "Cancel" | "ForceLoad" | "Steal" +local EasyProfile = { } +local Vendor = script.Parent.Vendor ---[=[ - The type for the global key. +-- // Variables - @type GlobalKey {Key: string, Value: any, KeyId: number} - @within EasyProfile -]=] export type GlobalKey = {Key: string, Value: any, KeyId: number} --- // Variables - ---[=[ - The parent of all classes. +type ProfileMetaData = {ProfileCreated: number; ProfileLoadCount: number; ProfileActiveSession: {placeId: number; jobId: string;}} +type ProfileLoadType = "Repeat" | "Cancel" | "ForceLoad" | "Steal" - @server - @class EasyProfile -]=] -local EasyProfile = { } -local Vendor = script.Parent.Vendor local EngineVendor = script.Parent.Parent.Parent +local EngineLibraries = EngineVendor.Libraries local RunService = game:GetService("RunService") local HttpService = game:GetService("HttpService") @@ -37,7 +19,8 @@ local HttpService = game:GetService("HttpService") local ProfileService = require(Vendor.ProfileService) local Types = require(EngineVendor.Types) local Debugger = require(EngineVendor.Debugger) -local Signal = require(EngineVendor.Controllers.Vendor.SignalController.SignalController) +local Signal = require(EngineVendor.Controllers.Init).SignalController +local Future = require(EngineLibraries.RedbloxUtils.Future) local ValidLeaderboardTypes = { "boolean", @@ -62,68 +45,9 @@ local ValidAttributeTypes = { "Rect", } ---[=[ - The object that holds the `ProfileStoreObject`. - - @server - @class ProfileStoreObject -]=] local ProfileStoreObject = { } - ---[=[ - Fires when a session lock has been claimed. - - @within ProfileStoreObject - @tag Event - @prop SessionLockClaimed SignalController -]=] - ---[=[ - Fires when a session lock has been unclaimed. - - @within ProfileStoreObject - @tag Event - @prop SessionLockUnclaimed SignalController -]=] - ---[=[ - The profile name pattern. - - @within ProfileStoreObject - @private - @prop _Pattern string -]=] - ---[=[ - The child object of `ProfileObject`. - - @server - @class ProfileObject -]=] local ProfileObject = { } ---[=[ - Fires when a global key has been recieved by the server. - - @within ProfileObject - @tag Event - @prop GlobalKeyAdded SignalController -]=] - ---[=[ - The loaded profile. - - @within ProfileObject - @private - @prop Profile any -]=] - ---[=[ - A table of the currently loaded profiles in game, each key is based on a profile store. - - @within EasyProfile - @prop LoadedData {[string]: {[Player | string]: ProfileObject}} -]=] EasyProfile.LoadedData = { } type EasyProfile = { @@ -135,6 +59,7 @@ export type ProfileObject = { GlobalKeyAdded: Types.SignalController, CreateProfileLeaderstats: (self: ProfileObject, player: Player, statsToAdd: {string}?) -> (), + CanSaveData: (self: ProfileObject) -> (boolean), GetProfileData: (self: ProfileObject) -> ({[string]: any}), GetGlobalKeys: (self: ProfileObject) -> ({GlobalKey}?), AddUserIds: (self: ProfileObject, userIds: {number} | number) -> (), @@ -150,7 +75,7 @@ export type ProfileStoreObject = { DeleteProfileAsync: (self: ProfileStoreObject, owner: number | string) -> (), GetProfileAsync: (self: ProfileStoreObject, owner: number | string) -> ({[string]: any}?), - LoadProfileAsync: (self: ProfileStoreObject, owner: Player | string, reconcileData: boolean?, profileClaimedHandler: (((placeId: number, gameJobId: string) -> (ProfileLoadType)) | ProfileLoadType)?) -> (ProfileObject), + LoadProfileAsync: (self: ProfileStoreObject, owner: Player | string, reconcileData: boolean?, profileClaimedHandler: (((placeId: number, gameJobId: string) -> (ProfileLoadType)) | ProfileLoadType)?) -> (Future.Future), UnclaimSessionLock: (self: ProfileStoreObject, owner: Player | string, valuesToSave: {[string]: any}, hopReadyCallback: (() -> ())?) -> (), SetGlobalKeyAsync: (self: ProfileStoreObject, target: number | string, key: string, value: any) -> (), RemoveGlobalKeyAsync: (self: ProfileStoreObject, target: number | string, keyId: number) -> (), @@ -162,15 +87,6 @@ if not RunService:IsServer() then error("Cannot run on any environments except the server.") end ---[=[ - Gets an existing profile store of creates one if it does not exist yet. - - @param name string? -- The name of the profile store to get, defaults to "Global" - @param defaultProfileData dictionary -- The default data of profie when loaded, only applies if this is their first time joining - @param playerKeyPattern string -- The pattern for the key to use if used to store player data, use '%d' as a placeholder for the player's `UserId`. - - @return ProfileStoreObject? -]=] function EasyProfile.CreateProfileStore(name: string?, defaultProfileData: {[string]: any}, playerKeyPattern: string?): ProfileStoreObject? if not defaultProfileData then Debugger.Debug(warn, "Default profile data is required") @@ -192,12 +108,8 @@ function EasyProfile.CreateProfileStore(name: string?, defaultProfileData: {[str return ProfileStoreObjectMetatable end ---[=[ - Completely wipes the data of the key `userId`, good for complying with GDPR practices. - - @param target number | string -- The user id / key to erase the data of - @yields -]=] +-- ProfileStoreObject + function ProfileStoreObject:DeleteProfileAsync(target: number | string) local CurrentLoadedProfileStore = self._ProfileStore if not CurrentLoadedProfileStore then @@ -219,12 +131,6 @@ function ProfileStoreObject:DeleteProfileAsync(target: number | string) CurrentLoadedProfileStore:WipeProfileAsync(str) end ---[=[ - Fetches the data off the key `userId`, this will only read data and does not load it. - - @param target number | string -- The user id / key to get of the data of - @yields -]=] function ProfileStoreObject:GetProfileAsync(target: number | string): {[string]: any}? local CurrentLoadedProfileStore = self._ProfileStore if not CurrentLoadedProfileStore then @@ -253,120 +159,91 @@ function ProfileStoreObject:GetProfileAsync(target: number | string): {[string]: return RequestedData end ---[=[ - Loads the data off the key `userId`. All edits to this data will be saved and be able to be used next session. - - @yields +function ProfileStoreObject:LoadProfileAsync(owner: Player | string, reconcileData: boolean?, profileClaimedHandler: (((placeId: number, gameJobId: string) -> (ProfileLoadType)) | ProfileLoadType)?): Future.Future + return Future.Try(function(profileStore, owner, reconcileData, profileClaimedHandler) + if not profileStore then + error("No profile store loaded, make sure API requests are enabled") + end - @param owner Player | string-- The owner of profile to load the data of - @param reconcileData boolean? -- Whether or not to reconcile the data of the profile, defaults to true - @param profileClaimedHandler ((placeId: number, gameJobId: string) -> (ProfileLoadType)) | ProfileLoadType? -- The function to run when the profile is already claimed + local ProfileObjectMetatable = setmetatable({ }, {__index = ProfileObject}) - @return ProfileObject? -]=] -function ProfileStoreObject:LoadProfileAsync(owner: Player | string, reconcileData: boolean?, profileClaimedHandler: (((placeId: number, gameJobId: string) -> (ProfileLoadType)) | ProfileLoadType)?): ProfileObject? - local ProfileObjectMetatable = setmetatable({ }, {__index = ProfileObject}) - local CurrentLoadedProfileStore = self._ProfileStore - - if not CurrentLoadedProfileStore then - Debugger.Debug(warn, "No profile store loaded, make sure API requests are enabled") - return nil - end - - if not owner then - Debugger.Debug(warn, "Cannot unclaim session lock for a owner that is non-existent") - return nil - end - - local str: string - - if typeof(owner) == "string" then - str = owner - elseif typeof(owner) == "Instance" and owner:IsA("Player") then - str = string.format(self._Pattern, owner.UserId) - else - Debugger.DebugInvalidData(1, "LoadProfileAsync", "Instance or string", owner, warn) - return nil - end - - local LoadedProfile = CurrentLoadedProfileStore:LoadProfileAsync(str, profileClaimedHandler) :: any - local Success = true - - ProfileObjectMetatable.GlobalKeyAdded = Signal.NewController("GlobalKeyAdded") :: Types.SignalController - - if not LoadedProfile then - if typeof(owner) == "Instance" and owner:IsA("Player") then - owner:Kick(`Data for profile {owner} could not be loaded, other JobId is trying to load this data already`) + if not owner then + Debugger.Debug(warn, "Cannot unclaim session lock for a owner that is non-existent") + return nil end - warn(`Data for profile {owner} could not be loaded, other JobId is trying to load this data already`) - Success = false - return nil - end - - if reconcileData then - LoadedProfile:Reconcile() - end - - if typeof(owner) == "Instance" and owner:IsA("Player") then - LoadedProfile:AddUserId(owner.UserId) - end - - LoadedProfile:ListenToRelease(function() - EasyProfile.LoadedData[self._Name][owner] = nil - self.SessionLockUnclaimed:Fire({owner}) - - setmetatable(ProfileObjectMetatable, nil) - table.clear(ProfileObjectMetatable) - + + local str: string + + if typeof(owner) == "string" then + str = owner + elseif typeof(owner) == "Instance" and owner:IsA("Player") then + str = string.format(self._Pattern, owner.UserId) + else + Debugger.DebugInvalidData(1, "LoadProfileAsync", "Instance or string", owner, warn) + return nil + end + + local LoadedProfile = profileStore:LoadProfileAsync(str, profileClaimedHandler) :: any + + ProfileObjectMetatable.GlobalKeyAdded = Signal.NewController("GlobalKeyAdded") :: Types.SignalController + + if not LoadedProfile then + if typeof(owner) == "Instance" and owner:IsA("Player") then + owner:Kick(`Data for profile {owner} could not be loaded, other JobId is trying to load this data already`) + end + warn(`Data for profile {owner} could not be loaded, other JobId is trying to load this data already`) + return nil + end + + if reconcileData then + LoadedProfile:Reconcile() + end + if typeof(owner) == "Instance" and owner:IsA("Player") then - owner:Kick(`Data for user {owner.UserId} active on another server, please try again`) + LoadedProfile:AddUserId(owner.UserId) end - end) - - for _, globalKey in LoadedProfile.GlobalUpdates:GetActiveUpdates() do - LoadedProfile.GlobalUpdates:LockActiveUpdate(globalKey[1]) - end - - LoadedProfile.GlobalUpdates:ListenToNewActiveUpdate(function(keyId: number, data: any) - LoadedProfile.GlobalUpdates:LockActiveUpdate(keyId) - end) - - LoadedProfile.GlobalUpdates:ListenToNewLockedUpdate(function(keyId: number, data: any) - ProfileObjectMetatable.GlobalKeyAdded:Fire({{Key = data.Key; Value = data.Value; KeyId = keyId;}}) - LoadedProfile.GlobalUpdates:ClearLockedUpdate(keyId) - end) - - self.SessionLockClaimed:Fire({owner}) + + LoadedProfile:ListenToRelease(function() + EasyProfile.LoadedData[self._Name][owner] = nil + self.SessionLockUnclaimed:Fire({owner}) + + setmetatable(ProfileObjectMetatable, nil) + table.clear(ProfileObjectMetatable) + + if typeof(owner) == "Instance" and owner:IsA("Player") then + owner:Kick(`Data for user {owner.UserId} active on another server, please try again`) + end + end) + + for _, globalKey in LoadedProfile.GlobalUpdates:GetActiveUpdates() do + LoadedProfile.GlobalUpdates:LockActiveUpdate(globalKey[1]) + end + + LoadedProfile.GlobalUpdates:ListenToNewActiveUpdate(function(keyId: number, data: any) + LoadedProfile.GlobalUpdates:LockActiveUpdate(keyId) + end) + + LoadedProfile.GlobalUpdates:ListenToNewLockedUpdate(function(keyId: number, data: any) + ProfileObjectMetatable.GlobalKeyAdded:Fire({{Key = data.Key; Value = data.Value; KeyId = keyId;}}) + LoadedProfile.GlobalUpdates:ClearLockedUpdate(keyId) + end) + + self.SessionLockClaimed:Fire({owner}) - EasyProfile.LoadedData[self._Name][owner] = ProfileObjectMetatable - ProfileObjectMetatable.Profile = LoadedProfile + ProfileObjectMetatable.Profile = LoadedProfile + EasyProfile.LoadedData[self._Name][owner] = ProfileObjectMetatable - if Success then - return ProfileObjectMetatable - else - return nil - end + return table.freeze(ProfileObjectMetatable) + end, self._ProfileStore, owner, reconcileData, profileClaimedHandler) end ---[=[ - Unclaims the session lock that the profile holds, throwing a warning if they are not session locked. This is usually because you did not load the profile data correctly. - - `valuesToSave` Example usage: - - ```lua - Players.PlayerRemoving:Connect(function(player) - MyDataStore:UnclaimSessionLock(player, { - Coins = player:GetAttribute("Coins") -- Make sure coins is a member of your profile data, or it will skip over it. - }) - end) - ``` - - @param owner Player | string -- The owner of the profile to unclaim the session lock of - @param valuesToSave dictionary? -- Values to save that are not already saved to the profile data, for example attributes that need to be saved on player removing - @param hopReadyCallback? -- The function to run when a server hop is ready, leaving this blank will disable this feature -]=] function ProfileStoreObject:UnclaimSessionLock(owner: Player | string, valuesToSave: {[string]: any}?, hopReadyCallback: (() -> ())?) local CurrentLoadedProfileStore = self._ProfileStore + if not CurrentLoadedProfileStore then + warn("No profile store loaded, make sure API requests are enabled") + return + end + local Profile = EasyProfile.LoadedData[self._Name][owner].Profile if not Profile then @@ -402,15 +279,6 @@ function ProfileStoreObject:UnclaimSessionLock(owner: Player | string, valuesToS end end ---[=[ - Sets a global key for target profile, regardless of whether they share the same `JobId` as the sender or they are offline. - - @param target number | string -- The target to set the global key of - @param key string -- The key to send to the target - @param value any -- The value of `key` - - @yields -]=] function ProfileStoreObject:SetGlobalKeyAsync(target: number | string, key: string, value: any) local CurrentLoadedProfileStore = self._ProfileStore if not CurrentLoadedProfileStore then @@ -437,14 +305,6 @@ function ProfileStoreObject:SetGlobalKeyAsync(target: number | string, key: stri end) end ---[=[ - Removes the global key that sent by using `ProfileStoreObject:SetGlobalKeyAsync` with the key ID of `keyId`. This only applies if it has not been recieved yet. - - @param target number | string -- The target to remove the global key of - @param keyId number -- The `keyId` of the key to remove - - @yields -]=] function ProfileStoreObject:RemoveGlobalKeyAsync(target: number | string, keyId: number) local CurrentLoadedProfileStore = self._ProfileStore if not CurrentLoadedProfileStore then @@ -468,60 +328,23 @@ function ProfileStoreObject:RemoveGlobalKeyAsync(target: number | string, keyId: end) end ---[=[ - Gets the data for the profile that was loaded in. - - @return {[string]: any}? -]=] -function ProfileObject:GetProfileData(): {[string]: any}? - local Profile = self.Profile - - if not Profile then - warn("No profile loaded") - return nil - end +-- ProfileObjects - return Profile.Data +function ProfileObject:GetProfileData(): {[string]: any}? + return self.Profile.Data end ---[=[ - Gets the meta tags for the profile that was loaded in. - - @return {[string]: any}? -]=] function ProfileObject:GetProfileTags(): {[string]: any}? - local Profile = self.Profile - - if not Profile then - warn("No profile loaded") - return nil - end - - return Profile.MetaData.MetaTags + return self.Profile.MetaData.MetaTags end ---[=[ - Creates leaderstats for Roblox's leaderboard based on provided values from the profile. If a value isn't supported, it won't be added to the leaderboard. Here is a list of natively supported types: - - |Type| - |-| - |`boolean`| - |`number`| - |`string`| - - @param player Player -- The player to parent the leaderstats to, required because the owner of the profile can be the player **or** a set string - @param statsToAdd {string}? -- Specific stats to add, leaving this nil will account for all data on the profile +function ProfileObject:CanSaveData(): boolean + return self.Profile:IsActive() +end - @return Folder? -]=] function ProfileObject:CreateProfileLeaderstats(player: Player, statsToAdd: {string}?, isAttributes: boolean?): Folder? local Profile = self.Profile - if not Profile then - warn("No profile loaded") - return nil - end - if not isAttributes then local LeaderstatsFolder = Instance.new("Folder") @@ -555,19 +378,8 @@ function ProfileObject:CreateProfileLeaderstats(player: Player, statsToAdd: {str end end ---[=[ - Gets all of the global keys that were recieved when the target was offline. - - @return {GlobalKey}? -]=] function ProfileObject:GetGlobalKeys(): {GlobalKey}? local Profile = self.Profile - - if not Profile then - warn("No profile loaded") - return nil - end - local GlobalKeys = { } for _, globalKey in Profile.GlobalUpdates:GetLockedUpdates() do @@ -578,19 +390,9 @@ function ProfileObject:GetGlobalKeys(): {GlobalKey}? return table.freeze(GlobalKeys) end ---[=[ - Adds `UserId`'s to the target profile. - - @param userIds number | {number} -- The `UserId`s to add. -]=] function ProfileObject:AddUserIds(userIds: number | {number}) local Profile = self.Profile - if not Profile then - warn("No profile loaded") - return - end - if type(userIds) == "number" then Profile:AddUserId(userIds) return @@ -601,35 +403,13 @@ function ProfileObject:AddUserIds(userIds: number | {number}) end end ---[=[ - Gets all the associated `UserId`'s of the target profile. - - @return {number}? -]=] function ProfileObject:GetUserIds(): {number}? - local Profile = self.Profile - - if not Profile then - warn("No profile loaded") - return nil - end - - return Profile.UserIds + return self.Profile.UserIds end ---[=[ - Removes all the associated `UserId`'s off of the target profile, leave `userIds` blank to clear all user IDs. - - @param userIds {number}? -- The `userId`'s to clear off the target profile -]=] function ProfileObject:RemoveUserIds(userIds: {number}?) local Profile = self.Profile - if not Profile then - warn("No profile loaded") - return - end - if not userIds then userIds = Profile.UserIds end @@ -639,19 +419,9 @@ function ProfileObject:RemoveUserIds(userIds: {number}?) end end ---[=[ - Gets all metadata that is related to the target profile. - - @return ProfileMetaData? -]=] function ProfileObject:GetMetaData(): ProfileMetaData? local Profile = self.Profile - if not Profile then - warn("No profile loaded") - return nil - end - return table.freeze({ ProfileCreated = Profile.MetaData.ProfileCreateTime; ProfileLoadCount = Profile.MetaData.SessionLoadCount; @@ -659,20 +429,8 @@ function ProfileObject:GetMetaData(): ProfileMetaData? }) end ---[=[ - Gets the amount of data (in percent) currently being used by the profile. - - @return number? -]=] function ProfileObject:GetDataUsage(): number? - local Profile = self.Profile - - if not Profile then - warn("No profile loaded") - return nil - end - - local EncodedUsage = HttpService:JSONEncode(Profile.Data) + local EncodedUsage = HttpService:JSONEncode(self.Profile.Data) local UsageLength = string.len(EncodedUsage) return (UsageLength / 4194304) * 100 diff --git a/src/lua/framework/Vendor/Libraries/EngineLoader/init.luau b/src/lua/framework/Vendor/Libraries/EngineLoader/init.luau index 2c7eb66f..72213c5e 100644 --- a/src/lua/framework/Vendor/Libraries/EngineLoader/init.luau +++ b/src/lua/framework/Vendor/Libraries/EngineLoader/init.luau @@ -1,19 +1,6 @@ -- // Package ---[=[ - The parent of all classes. - - @class EngineLoader -]=] local EngineLoader = { } - ---[=[ - A boolean that is true if the client is loaded. - - @prop IsClientLoaded boolean - @within EngineLoader -]=] - local Vendor = script.Vendor -- // Variables @@ -47,15 +34,6 @@ EngineLoader.IsClientLoaded = false -- // Functions ---[=[ - Starts up the loader, this should be run as soon as the player joins in `EngineReplicatedFirst/Scripts`. - - @param objectsToLoad {any} -- The objects to load, can be a list of asset id strings or instances - @param loadingMessages {[string]: Color3}? -- The messages to display after the loading is finished, the key is the message and the value is the color of the message - @param coreGuiEnabled boolean? -- Decides whether the CoreGui is enabled during loading - @param afterLoadWait number? -- The amount of time to wait after the load, this is before the messages in `loadingMessages` are shown and the loading stats are shown - @param loadingText {loadingAssetsText: string, loadedAssetsText: string}? -- The text that should be shown when loading assets and after loading assets -]=] function EngineLoader.StartLoad(objectsToLoad: {any}, loadingMessages: {[string]: Color3}?, coreGuiEnabled: boolean?, afterLoadWait: number?, loadingText: {loadingAssetsText: string, loadedAssetsText: string}?) if not script.Parent.Parent:GetAttribute("CanaryEngineLoaderEnabled") then return @@ -155,11 +133,6 @@ function EngineLoader.StartLoad(objectsToLoad: {any}, loadingMessages: {[string] end) end ---[=[ - Allows you to customize the interface, giving you the ability to change the relevant properties. `Container` is the main frame. - - @param interfaceProperties {[string]: {[string]: any}} -]=] function EngineLoader.CustomizeInterface(interfaceProperties: { Container: { BackgroundColor3: Color3?, diff --git a/src/lua/framework/Vendor/Runtime.luau b/src/lua/framework/Vendor/Runtime.luau index 3b9310db..18d5e25b 100644 --- a/src/lua/framework/Vendor/Runtime.luau +++ b/src/lua/framework/Vendor/Runtime.luau @@ -1,34 +1,12 @@ -- // Package ---[=[ - The parent of all classes. - - @class EngineRuntime -]=] local EngineRuntime = { } local RunService = game:GetService("RunService") local Framework = game:GetService("ReplicatedStorage").Framework ---[=[ - Shows different runtime contexts. - - @prop Context {[string]: boolean} - @within EngineRuntime -]=] - ---[=[ - Shows different runtime settings. - - @prop Settings {[string]: boolean | string | number} - @within EngineRuntime -]=] +-- Engine Context ---[=[ - The parent of all classes. - - @class EngineRuntimeContext -]=] local EngineRuntimeContext = { Studio = RunService:IsStudio(), Server = RunService:IsServer(), @@ -36,65 +14,15 @@ local EngineRuntimeContext = { StudioPlay = RunService:IsStudio() and RunService:IsRunning() } ---[=[ - Whether the current client is connected to studio. - - @prop Studio boolean - @within EngineRuntimeContext -]=] - ---[=[ - Whether the current environment is the server. - - @prop Server boolean - @within EngineRuntimeContext -]=] +-- Engine Settings ---[=[ - Whether the current environment is the client. - - @prop Client boolean - @within EngineRuntimeContext -]=] - ---[=[ - Whether the current client is playtesting in studio. - - @prop StudioPlay boolean - @within EngineRuntimeContext -]=] - ---[=[ - The parent of all classes. - - @class EngineRuntimeSettings -]=] local EngineRuntimeSettings = { StudioDebugEnabled = Framework:GetAttribute("StudioDebugger"), LiveGameDebugEnabled = Framework:GetAttribute("LiveGameDebugger"), Version = Framework:GetAttribute("Version"), } ---[=[ - Whether or not if `StudioDebugger` is enabled - - @prop StudioDebugEnabled boolean - @within EngineRuntimeSettings -]=] - ---[=[ - Whether or not if `LiveGameDebugger` is enabled - - @prop LiveGameDebugEnabled boolean - @within EngineRuntimeSettings -]=] - ---[=[ - The current version of CanaryEngine. - - @prop Version string - @within EngineRuntimeSettings -]=] +-- Table Assignment EngineRuntime.Context = EngineRuntimeContext EngineRuntime.Settings = EngineRuntimeSettings diff --git a/src/lua/framework/Vendor/Types.luau b/src/lua/framework/Vendor/Types.luau index 93f6dd77..ed8f128b 100644 --- a/src/lua/framework/Vendor/Types.luau +++ b/src/lua/framework/Vendor/Types.luau @@ -1,135 +1,56 @@ -- // Packages ---[=[ - The parent of all classes. - - @class EngineTypes -]=] local EngineTypes = { } +local Future = require(script.Parent.Libraries.RedbloxUtils.Future) ---[=[ - A controller connection, simply a function which allows you to disconnect from an event. - - @type ControllerConnection - @within EngineTypes - @private -]=] -type ControllerConnection = () -> () +-- Tables ---[=[ - A signal controller, similar to an [RBXScriptSignal] +export type Dictionary = {[T]: U} +export type Array = {[number]: T} - @field Connect (self: SignalController, func: (data: {T}) -> ()) -> (ControllerConnection) - @field Wait (self: SignalController) -> ({T}) - @field Once (self: SignalController, func: (data: {T}) -> ()) -> (ControllerConnection) - - @field Fire (self: SignalController, data: ({T} | T)?) -> () +-- Basic Controllers - @field DisconnectAll (self: SignalController) -> () - @field Name string +type ControllerConnection = () -> () - @interface SignalController - @within EngineTypes -]=] export type SignalController = { DisconnectAll: (self: SignalController) -> (), - Fire: (self: PublicSignalController, data: ({T} | T)?) -> (), + Fire: (self: PublicSignalController, data: (Array | T)?) -> (), } & PublicSignalController export type PublicSignalController = { - Connect: (self: PublicSignalController, func: (data: {T}) -> ()) -> (ControllerConnection), - Wait: (self: PublicSignalController) -> ({T}), - Once: (self: PublicSignalController, func: (data: {T}) -> ()) -> (ControllerConnection), + Connect: (self: PublicSignalController, func: (data: Array) -> ()) -> (ControllerConnection), + Wait: (self: PublicSignalController) -> (Array), + Once: (self: PublicSignalController, func: (data: Array) -> ()) -> (ControllerConnection), Name: string, } ---[=[ - A ClientNetworkController is basically a mixed version of a [RemoteEvent] and [RemoteFunction]. It has better features and is more performant. - - @field Connect (self: ClientNetworkController, func: (data: {T}) -> ()) -> (ControllerConnection) - @field Once (self: ClientNetworkController, func: (data: {T}) -> ()) -> (ControllerConnection) - @field Wait (self: ClientNetworkController) -> ({T}) - - @field Fire (self: ClientNetworkController, data: ({T} | T)?) -> () - @field InvokeAsync (self: ClientNetworkController, data: ({T} | T)?) -> ({U}) - - @field Destroy (self: ClientNetworkController) -> () - @field DisconnectAll (self: ClientNetworkController) -> () - @field Name string +-- Network Controllers - @interface ClientNetworkController - @within EngineTypes -]=] export type ClientNetworkController = { - Connect: (self: ClientNetworkController, func: (data: {T}) -> ()) -> (ControllerConnection), - Wait: (self: ClientNetworkController) -> ({T}), - Once: (self: ClientNetworkController, func: (data: {T}) -> ()) -> (ControllerConnection), + Listen: (self: ClientNetworkController, func: (data: Array?) -> ()) -> (), - Fire: (self: ClientNetworkController, data: ({T} | T)?) -> (), - InvokeAsync: (self: ClientNetworkController, data: ({T} | T)) -> ({U}), + Fire: (self: ClientNetworkController, data: (Array | T)?) -> (), + InvokeAsync: (self: ClientNetworkController, data: (Array | T)?) -> (Future.Future<{U}>), - Destroy: (self: ClientNetworkController) -> (), - DisconnectAll: (self: ClientNetworkController) -> (), Name: string, } ---[=[ - A ServerNetworkController is basically a mixed version of a [RemoteEvent] and [RemoteFunction]. It has better features and is more performant, though this is the server-sided API. - - @field Connect (self: ServerNetworkController, func: (sender: Player, data: {T}) -> ()) -> (ControllerConnection) - @field Once (self: ServerNetworkController, func: (sender: Player, data: {T}) -> ()) -> (ControllerConnection) - @field Wait (self: ServerNetworkController) -> (Player, {T}) - - @field Fire (self: ServerNetworkController, recipient: Player | {Player}, data: ({T} | T)?) -> () - @field FireAll (self: ServerNetworkController, data: ({T} | T)?) -> () - @field FireExcept (self: ServerNetworkController, except: Player | {Player}, data: ({T} | T)?) -> () - @field FireInRange (self: ServerNetworkController, comparePoint: Vector3, maximumRange: number, data: ({T} | T)?) -> () - @field OnInvoke (self: ServerNetworkController, callback: (sender: Player, data: {T}) -> ()) -> () - - @field SetRateLimit (self: ServerNetworkController, maxInvokesPerSecond: number, invokeOverflowCallback: (sender: Player) -> ()) -> () - @field Destroy (self: ClientNetworkController) -> () - @field DisconnectAll (self: ServerNetworkController) -> () - @field Name string - - @interface ServerNetworkController - @within EngineTypes -]=] export type ServerNetworkController = { - Connect: (self: ServerNetworkController, func: (sender: Player, data: {T}) -> ()) -> (ControllerConnection), - Wait: (self: ServerNetworkController) -> (Player, {T}), - Once: (self: ServerNetworkController, func: (sender: Player, data: {T}) -> ()) -> (ControllerConnection), - - Fire: (self: ServerNetworkController, recipient: Player | {Player}, data: ({T} | T)?) -> (), - FireAll: (self: ServerNetworkController, data: ({T} | T)?) -> (), - FireExcept: (self: ServerNetworkController, except: Player | {Player}, data: ({T} | T)?) -> (), - FireInRange: (self: ServerNetworkController, comparePoint: Vector3, maximumRange: number, data: ({T} | T)?) -> (), - OnInvoke: (self: ServerNetworkController, callback: (sender: Player, data: {T}) -> ({U} | U)) -> (), + Listen: (self: ServerNetworkController, func: (sender: Player, data: ({T} | unknown)?) -> ()) -> (), + OnInvoke: (self: ServerNetworkController, callback: (sender: Player, data: ({T} | unknown)?) -> ({U} | U)) -> (), + + Fire: (self: ServerNetworkController, recipient: Player | {Player}, data: (Array | T)?) -> (), + FireAll: (self: ServerNetworkController, data: (Array | T)?) -> (), + FireExcept: (self: ServerNetworkController, except: Player | {Player}, data: (Array | T)?) -> (), + FireInRange: (self: ServerNetworkController, comparePoint: Vector3, maximumRange: number, data: (Array | T)?) -> (), SetRateLimit: (self: ServerNetworkController, maxInvokesPerSecond: number, invokeOverflowCallback: (sender: Player) -> ()) -> (), - Destroy: (self: ClientNetworkController) -> (), - DisconnectAll: (self: ServerNetworkController) -> (), Name: string, } ---[=[ - A basic type of an R6 character rig. Should be combined with model using the `&` syntax. +-- Misc. Types - @field Body_Colors BodyColors - @field HumanoidRootPart Part - @field Humanoid Humanoid - @field Torso Part - @field Head Part - @field Animate LocalScript - @field Left_Arm Part - @field Left_Leg Part - @field Right_Arm Part - @field Right_Leg Part - - - @interface Character - @within EngineTypes -]=] export type Character = { ["Body Colors"]: BodyColors, HumanoidRootPart: Part, @@ -183,20 +104,4 @@ export type Character = { } } & Model ---[=[ - A simple dictionary type. - - @type Dictionary - @within EngineTypes -]=] -export type Dictionary = {[T]: U} - ---[=[ - A simple array type. - - @type Array - @within EngineTypes -]=] -export type Array = {[number]: T} - return EngineTypes \ No newline at end of file diff --git a/src/lua/framework/init.luau b/src/lua/framework/init.luau index dd47a512..be6b7609 100644 --- a/src/lua/framework/init.luau +++ b/src/lua/framework/init.luau @@ -1,95 +1,24 @@ -- // Packages ---[=[ - The parent of all classes. - - @class CanaryEngine -]=] local CanaryEngine = { } ---[=[ - The runtime property contains settings that are set during runtime, and the current context of the server/client. - - @prop Runtime {RuntimeSettings: EngineRuntimeSettings, RuntimeContext: EngineRuntimeContext, RuntimeObjects: {NetworkControllers: {[string]: (ServerNetworkController | ServerNetworkController)}, SignalControllers: {[string]: SignalController}}} - - @readonly - @within CanaryEngine -]=] - ---[=[ - The internal engine debugger, has useful functions to abide by debug settings. - - @prop Debugger EngineDebugger - - @readonly - @within CanaryEngine -]=] - ---[=[ - CanaryEngine's server-sided interface. - - @server - @class CanaryEngineServer -]=] local CanaryEngineServer = { } - ---[=[ - CanaryEngine's client-sided interface. - - @client - @class CanaryEngineClient -]=] local CanaryEngineClient = { } - ---[=[ - A simple reference to the [Players.LocalPlayer]. - - @prop Player Player - @readonly - - @within CanaryEngineClient -]=] - ---[=[ - A simple reference to the [Player.PlayerGui], useful for automatic typing and API simplicity. - - @prop PlayerGui StarterGui - @readonly - - @within CanaryEngineClient -]=] - ---[=[ - A simple reference to the player's [Backpack], useful for automatic typing and API simplicity. - - @prop PlayerBackpack StarterPack - @readonly - - @within CanaryEngineClient -]=] - ---[=[ - CanaryEngine's global-sided interface. - - @class CanaryEngineReplicated -]=] local CanaryEngineReplicated = { } -- // Variables local PlayerService = game:GetService("Players") -local EngineVendor = script.Parent.Vendor --- // Types +local EngineVendor = script.Parent.Vendor +local EngineLibraries = EngineVendor.Libraries local Types = require(EngineVendor.Types) -- The types used for all libraries inside of the framework - ----- - -local Controllers = require(EngineVendor.Controllers.Controllers) +local Controllers = require(EngineVendor.Controllers.Init) local Network = Controllers.NetworkController -- Networking logic local Signal = Controllers.SignalController -- Signal logic +local Future = require(EngineLibraries.RedbloxUtils.Future) -- Promise logic local Debugger = require(EngineVendor.Debugger) -- Easy debug logic local Runtime = require(EngineVendor.Runtime) -- Runtime settings + debugger @@ -106,32 +35,34 @@ CanaryEngine.Runtime = table.freeze({ }) CanaryEngine.Debugger = Debugger +CanaryEngine.Future = Future + +local RuntimeObjects = CanaryEngine.Runtime.RuntimeObjects -- // Functions ---[=[ - Gets the server-sided interface of CanaryEngine +local function CreateNetworkController(controllerName: string): Types.ClientNetworkController | Types.ServerNetworkController + if not RuntimeObjects.NetworkControllers[controllerName] then + local NewNetworkController = Network.CreateController(controllerName) + + RuntimeObjects.NetworkControllers[controllerName] = NewNetworkController + end - @server - @return CanaryEngineServer? -]=] + return RuntimeObjects.NetworkControllers[controllerName] +end + +-- Engine Contexts + function CanaryEngine.GetEngineServer() if RuntimeContext.Server then CanaryEngineServer.Data = require(EngineVendor.Libraries.EasyProfile.EasyProfile) return CanaryEngineServer else - Debugger.Debug(error, "Failed to fetch 'EngineServer', context must be server") + Debugger.Debug(error, "Failed to fetch 'EngineServer', context must be server.", nil, false) return end end ---[=[ - Gets the client-sided interface of CanaryEngine - - @yields - @client - @return CanaryEngineClient? -]=] function CanaryEngine.GetEngineClient() if RuntimeContext.Client then local Player = PlayerService.LocalPlayer @@ -142,114 +73,45 @@ function CanaryEngine.GetEngineClient() return CanaryEngineClient else - Debugger.Debug(error, "Failed to fetch 'EngineClient', Context must be client.") + Debugger.Debug(error, "Failed to fetch 'EngineClient', context must be client.", nil, false) return end end ---[=[ - Gets the global-sided interface of CanaryEngine. Recommended that use this only in replicated packages, this is a bad practice anywhere else. - - @return CanaryEngineReplicated? -]=] +-- Exclusive API for replicated will come soon function CanaryEngine.GetEngineReplicated() return CanaryEngineReplicated end ---[=[ - Creates a new network controller on the client, with the name of `controllerName` +-- Signal Creation - :::tip - - You can set the data type of a network controller after it being made like the following: - - ```lua - local NetworkController: CanaryEngine.ClientNetworkController = EngineClient.CreateNetworkController("MyNewNetworkController") -- assuming you are sending over and recieving a boolean - ``` - ::: - - @yields - - @param controllerName string -- The name of the controller - @param controllerTimeout number? -- Sets the maximum timeout when waiting for network controllers on the server, defaults to 3 seconds - - @return ClientNetworkController -]=] -function CanaryEngineClient.CreateNetworkController(controllerName: string): Types.ClientNetworkController - if not CanaryEngine.Runtime.RuntimeObjects.NetworkControllers[controllerName] then - local NewNetworkController = Network.NewClientController(controllerName) - - CanaryEngine.Runtime.RuntimeObjects.NetworkControllers[controllerName] = NewNetworkController - end - - return CanaryEngine.Runtime.RuntimeObjects.NetworkControllers[controllerName] -end - ---[=[ - Gets the players current character model; if it doesn't exist the thread will yield until it does. - - @yields - @return Types.Character -]=] -function CanaryEngineClient.GetPlayerCharacter(): Types.Character - return PlayerService.LocalPlayer.Character or PlayerService.LocalPlayer.CharacterAdded:Wait() -end - ---[=[ - Creates a new network controller on the server, with the name of `controllerName` - - :::tip - - You can set the data type of a network controller after it being made like the following: - - ```lua - local NetworkController: CanaryEngine.ServerNetworkController = EngineServer.CreateNetworkController("MyNewNetworkController") -- assuming you are sending over and recieving a number - ``` - - ::: - - @param controllerName string -- The name of the controller - @return ServerNetworkController -]=] -function CanaryEngineServer.CreateNetworkController(controllerName: string): Types.ServerNetworkController - if not CanaryEngine.Runtime.RuntimeObjects.NetworkControllers[controllerName] then - local NewNetworkController = Network.NewServerController(controllerName) - - CanaryEngine.Runtime.RuntimeObjects.NetworkControllers[controllerName] = NewNetworkController - end - - return CanaryEngine.Runtime.RuntimeObjects.NetworkControllers[controllerName] -end - ---[=[ - Creates a new signal that is then given a reference in the signals table. Create a new anonymous signal by leaving the name blank. - - @param signalName string -- The name of the signal - @return SignalController -]=] function CanaryEngine.CreateSignal(signalName: string?): Types.SignalController if not signalName then - return Signal.NewController("Anonymous") + return Signal.CreateController("Anonymous") end - if not CanaryEngine.Runtime.RuntimeObjects.SignalControllers[signalName] then - local NewSignal = Signal.NewController(signalName) + if not RuntimeObjects.SignalControllers[signalName] then + local NewSignal = Signal.CreateController(signalName) - CanaryEngine.Runtime.RuntimeObjects.SignalControllers[signalName] = NewSignal + RuntimeObjects.SignalControllers[signalName] = NewSignal end - return CanaryEngine.Runtime.RuntimeObjects.SignalControllers[signalName] + return RuntimeObjects.SignalControllers[signalName] end ---[=[ - Creates a new anonymous signal, this does not have a reference outside of the variable it was created in. This is also technically an alias for CanaryEngine.CreateSignal(nil). - - @return SignalController -]=] function CanaryEngine.CreateAnonymousSignal(): Types.SignalController - return Signal.NewController("Anonymous") + return CanaryEngine.CreateSignal() +end + +-- Context Specific Functions + +function CanaryEngineClient.GetPlayerCharacter(): Types.Character + return PlayerService.LocalPlayer.Character or PlayerService.LocalPlayer.CharacterAdded:Wait() end +CanaryEngineClient.CreateNetworkController = CreateNetworkController :: (controllerName: string) -> (Types.ClientNetworkController) +CanaryEngineServer.CreateNetworkController = CreateNetworkController :: (controllerName: string) -> (Types.ServerNetworkController) + -- // Actions -return CanaryEngine \ No newline at end of file +return table.freeze(CanaryEngine) \ No newline at end of file