From 7c4ee737f1db2e4c833c610dcbb637eefc516874 Mon Sep 17 00:00:00 2001 From: Lewin Kelly Date: Sun, 28 Jan 2024 17:10:52 +0000 Subject: [PATCH] Compile Red library from corescripts/Libraries, update types to make Red FULLY TYPE SAFE! --- Libraries/Red/Net/Event.luau | 411 +++++++++ Libraries/Red/Net/Serdes.luau | 76 ++ Libraries/Red/Net/init.luau | 198 +++++ Libraries/Red/RedEvent.luau | 45 + Libraries/Red/Util/Bin.luau | 27 + Libraries/Red/Util/Clock.luau | 67 ++ Libraries/Red/Util/Collection.luau | 41 + Libraries/Red/Util/Promise.luau | 206 +++++ Libraries/Red/Util/Ratelimit.luau | 40 + Libraries/Red/Util/Signal.luau | 74 ++ Libraries/Red/Util/Spawn.luau | 23 + Libraries/Red/init.luau | 33 + Libraries/Red/typeof.luau | 181 ++++ compile.sh | 1 + defs.d.lua | 484 ++++++---- luau/10000002.luau | 1334 ---------------------------- 16 files changed, 1726 insertions(+), 1515 deletions(-) create mode 100644 Libraries/Red/Net/Event.luau create mode 100644 Libraries/Red/Net/Serdes.luau create mode 100644 Libraries/Red/Net/init.luau create mode 100644 Libraries/Red/RedEvent.luau create mode 100644 Libraries/Red/Util/Bin.luau create mode 100644 Libraries/Red/Util/Clock.luau create mode 100644 Libraries/Red/Util/Collection.luau create mode 100644 Libraries/Red/Util/Promise.luau create mode 100644 Libraries/Red/Util/Ratelimit.luau create mode 100644 Libraries/Red/Util/Signal.luau create mode 100644 Libraries/Red/Util/Spawn.luau create mode 100644 Libraries/Red/init.luau create mode 100644 Libraries/Red/typeof.luau delete mode 100644 luau/10000002.luau diff --git a/Libraries/Red/Net/Event.luau b/Libraries/Red/Net/Event.luau new file mode 100644 index 0000000..c23d23d --- /dev/null +++ b/Libraries/Red/Net/Event.luau @@ -0,0 +1,411 @@ +return function(IsServer: boolean) + local RunService = game:GetService "RunService" + + local RedEvent = require "../RedEvent"(IsServer) + local Remote = RedEvent.Remote + + local Serdes = require "./Serdes"(IsServer) + + local Spawn = require "../Util/Spawn" + local Promise = require "../Util/Promise" + local Clock = require "../Util/Clock" + + local Event = {} + local nil_symbol = { __nil = true } + + Event.Callbacks = {} :: { [string]: ((...any) -> ...any)? } + Event.Outgoing = {} :: any + + if not IsServer then + Event.ActiveCalls = {} + end + + function Event.Listen() + -- debug.setmemorycategory "Red.Listen" + if not IsServer then + Remote.OnClientEvent:connect( + function(SingleFire, MultipleFire, IncomingCall) + -- debug.profilebegin "Red.Listen.Incoming" + + -- replace nil symbols with nil + if SingleFire.__nil then + SingleFire = nil + end + if MultipleFire.__nil then + MultipleFire = nil + end + if IncomingCall.__nil then + IncomingCall = nil + end + + if SingleFire then + -- debug.profilebegin "Red.Listen.Incoming.SingleFire" + + for EventId, Call in pairs(SingleFire) do + local Callback = Event.Callbacks[EventId] + + local c = 0 + repeat -- bruh + RunService.Stepped:wait() + Callback = Event.Callbacks[EventId] + c += 1 + until Callback or c > 500 -- random + + if Callback then + if type(Call) == "table" then + Spawn(Callback, unpack(Call)) + else + Spawn(Callback, Call) + end + else + print "[Red]: Callback not found!" + end + end + + -- debug.profileend() + end + + if MultipleFire then + -- debug.profilebegin "Red.Listen.Incoming.Fire" + + for EventId, Calls in pairs(MultipleFire) do + local Callback = Event.Callbacks[EventId] + + if Callback then + for _, Call in ipairs(Calls) do + if type(Call) == "table" then + Spawn(Callback, unpack(Call)) + else + Spawn(Callback, Call) + end + end + end + end + + -- debug.profileend() + end + + if IncomingCall then + -- debug.profilebegin "Red.Listen.Incoming.Call" + + for _, Call in pairs(IncomingCall) do + local CallId = table.remove(Call, 1) + local Success = table.remove(Call, 1) + + if Event.ActiveCalls[CallId] then + if Success then + Event.ActiveCalls[CallId].Resolve( + unpack(Call) + ) + else + Event.ActiveCalls[CallId].Reject( + unpack(Call) + ) + end + + Event.ActiveCalls[CallId] = nil + end + end + + -- debug.profileend() + end + + -- debug.profileend() + end + ) + + Clock.new(1 / 60, function() + -- debug.profilebegin "Red.Listen.Outgoing" + + if not next(Event.Outgoing) then + return + end + + local SingleFire = {} + local SendSingleFire = false + + if Event.Outgoing[1] then + for EventId, Calls in pairs(Event.Outgoing[1]) do + if #Calls == 1 then + SingleFire[EventId] = Calls[1] + Event.Outgoing[1][EventId] = nil + + SendSingleFire = true + end + end + end + + -- nils cannot be sent properly across remoteevents in 2013, + -- so we have to use a symbol to represent nil + local sf = nil_symbol + if SendSingleFire then + sf = SingleFire + end + + local eo1, eo2 = Event.Outgoing[1], Event.Outgoing[2] + if eo1 == nil then + eo1 = nil_symbol + end + if eo2 == nil then + eo2 = nil_symbol + end + + Remote:FireServer(sf, eo1, eo2) + + -- table.clear(Event.Outgoing) + for i, _ in pairs(Event.Outgoing) do + Event.Outgoing[i] = nil + end + + -- debug.profileend() + end) + else + Remote.OnServerEvent:connect( + function(Player, SingleFire, MultipleFire, IncomingCall) + -- debug.profilebegin "Red.Listen.Incoming" + + -- replace nil symbols with nil + if SingleFire.__nil then + SingleFire = nil + end + if MultipleFire.__nil then + MultipleFire = nil + end + if IncomingCall.__nil then + IncomingCall = nil + end + + if SingleFire then + -- debug.profilebegin "Red.Listen.Incoming.SingleFire" + + for EventId, Call in pairs(SingleFire) do + local Callback = Event.Callbacks[EventId] + + if Callback then + if type(Call) == "table" then + Spawn(Callback, Player, unpack(Call)) + else + Spawn(Callback, Player, Call) + end + end + end + + -- debug.profileend() + end + + if MultipleFire then + -- debug.profilebegin "Red.Listen.Incoming.MultipleFire" + + for EventId, Calls in pairs(MultipleFire) do + local Callback = Event.Callbacks[EventId] + + if Callback then + for _, Call in ipairs(Calls) do + if type(Call) == "table" then + Spawn(Callback, Player, unpack(Call)) + else + Spawn(Callback, Player, Call) + end + end + end + end + + -- debug.profileend() + end + + if IncomingCall then + -- debug.profilebegin "Red.Listen.Incoming.Call" + + for EventId, Calls in pairs(IncomingCall) do + if Event.Callbacks[EventId] then + for _, Call in ipairs(Calls) do + Spawn(function() + local CallId = table.remove(Call, 1) + local Result = { + CallId, + pcall( + Event.Callbacks[EventId], + Player, + unpack(Call) + ), + } + + if Event.Outgoing[Player] == nil then + Event.Outgoing[Player] = {} + end + + if Event.Outgoing[Player][2] == nil then + Event.Outgoing[Player][2] = {} + end + + table.insert( + Event.Outgoing[Player][2], + Result + ) + end) + end + else + if Event.Outgoing[Player] == nil then + Event.Outgoing[Player] = {} + end + + if Event.Outgoing[Player][2] == nil then + Event.Outgoing[Player][2] = {} + end + + for _, Call in ipairs(Calls) do + table.insert(Event.Outgoing[Player][2], { + Call[1], + false, + "[Red]: Event not found", + }) + end + end + end + + -- debug.profileend() + end + + -- debug.profileend() + end + ) + + RunService.Heartbeat:connect(function() + -- debug.profilebegin "Red.Listen.Outgoing" + + for Player, Packets in pairs(Event.Outgoing) do + local SingleCall = {} + local SendSingleCall = false + + if Packets[1] then + for EventId, Calls in pairs(Packets[1]) do + if #Calls == 1 then + SingleCall[EventId] = Calls[1] + Packets[1][EventId] = nil + + SendSingleCall = true + end + end + end + + -- nils cannot be sent properly across remoteevents in 2013, + -- so we have to use a symbol to represent nil + local sc = nil_symbol + if SendSingleCall then + sc = SingleCall + end + + local p1, p2 = Packets[1], Packets[2] + + if p1 == nil then + p1 = nil_symbol + end + if p2 == nil then + p2 = nil_symbol + end + + Remote:FireClient(Player, sc, p1, p2) + end + + -- table.clear(Event.Outgoing) + for i, _ in pairs(Event.Outgoing) do + Event.Outgoing[i] = nil + end + + -- debug.profileend() + end) + end + end + + function Event.AddQueue(Queue: { any }, Call: { any }) + local Length = #Call + + if Length == 1 then + local Type = type(Call[1]) + + if Type ~= "table" then + table.insert(Queue, Call[1]) + else + table.insert(Queue, Call) + end + else + table.insert(Queue, Call) + end + end + + function Event.FireClient(Player: Player, EventName: string, ...) + assert(IsServer, "Event.FireClient can only be called from the server") + + local EventId = Serdes.IdentifierAsync(EventName) + + if Event.Outgoing[Player] == nil then + Event.Outgoing[Player] = {} + end + + if Event.Outgoing[Player][1] == nil then + Event.Outgoing[Player][1] = {} + end + + if Event.Outgoing[Player][1][EventId] == nil then + Event.Outgoing[Player][1][EventId] = {} + end + + Event.AddQueue(Event.Outgoing[Player][1][EventId], { ... }) + end + + function Event.FireServer(EventName: string, ...) + assert( + not IsServer, + "Event.FireServer can only be called on the client" + ) + + local Args = { ... } + + return Serdes.Identifier(EventName):Then(function(EventId) + if Event.Outgoing[1] == nil then + Event.Outgoing[1] = {} + end + + if Event.Outgoing[1][EventId] == nil then + Event.Outgoing[1][EventId] = {} + end + + Event.AddQueue(Event.Outgoing[1][EventId], Args) + end) + end + + function Event.Call(EventName: string, ...) + assert(not IsServer, "Event.Call can only be called on the client") + + local Args = { ... } + + return Promise.new(function(Resolve, Reject) + local CallId = Serdes.OneTime() + local EventId = Serdes.IdentifierAsync(EventName) + + if Event.Outgoing[2] == nil then + Event.Outgoing[2] = {} + end + + if Event.Outgoing[2][EventId] == nil then + Event.Outgoing[2][EventId] = {} + end + + table.insert(Args, 1, CallId) + table.insert(Event.Outgoing[2][EventId], Args) + + Event.ActiveCalls[CallId] = { + Resolve = Resolve, + Reject = Reject, + } + end) + end + + function Event.SetCallback(EventName: string, Callback: ((...any) -> any)?) + return Serdes.Identifier(EventName):Then(function(EventId) + Event.Callbacks[EventId] = Callback + end) + end + + return Event +end diff --git a/Libraries/Red/Net/Serdes.luau b/Libraries/Red/Net/Serdes.luau new file mode 100644 index 0000000..1cdcb48 --- /dev/null +++ b/Libraries/Red/Net/Serdes.luau @@ -0,0 +1,76 @@ +return function(IsServer: boolean) + local RedEvent = require "../RedEvent"(IsServer) + local Event = RedEvent.Remote + + local Promise = require "../Util/Promise" + local Serdes = {} + + Serdes.NextId = 1 -- StringValues think null bytes are empty strings + Serdes.NextOT = 1 + + function Serdes.RegisterIdentifier(Name: string) + assert(IsServer, "RegisterIdentifier can only be called on the server") + + local Id = string.char(Serdes.NextId) + Serdes.NextId += 1 + + local e = Event:FindFirstChild(Name) + if e then + e.Value = Id + else + e = Instance.new "StringValue" + e.Name = Name + e.Value = Id + e.Parent = Event + end + + return Id + end + + function Serdes.Identifier(Name: string) + if not IsServer then + return Promise.new(function(Resolve) + local e = Event:WaitForChild(Name) + if e.Value ~= nil then + Resolve(e.Value) + else + local Thread = Delay(5, function() + print( + "[Red.Serdes]: Retrieving identifier exceeded 5 seconds. Make sure '" + .. Name + .. "' is registered on the server." + ) + end) + + e.Changed:Once(function() + coroutine.yield(Thread :: thread) + + Resolve(e.Value) + end) + end + end) + else + local e = Event:FindFirstChild(Name) + if e and e.Value then + return Promise.Resolve(e.Value) + end + return Promise.Resolve(Serdes.RegisterIdentifier(Name)) + end + end + + function Serdes.IdentifierAsync(Name: string) + return Serdes.Identifier(Name):Await() + end + + function Serdes.OneTime() + Serdes.NextOT += 1 + + if Serdes.NextOT == 0xFFFF + 1 then + Serdes.NextOT = 0 + end + + return string.char(Serdes.NextOT) + end + + return Serdes +end diff --git a/Libraries/Red/Net/init.luau b/Libraries/Red/Net/init.luau new file mode 100644 index 0000000..d6dd261 --- /dev/null +++ b/Libraries/Red/Net/init.luau @@ -0,0 +1,198 @@ +return function(IsServer: boolean) + local Players = game:GetService "Players" + + local RedEvent = require "../RedEvent"(IsServer) + local Remote = RedEvent.Remote + local ClientFolder = RedEvent.ClientFolder + + local Serdes = require "./Serdes"(IsServer) + local Event = require "./Event"(IsServer) + + local Server = {} + Server.__index = Server + + function Server.Server(Name: string) + local self = setmetatable({}, Server) + + self.Name = Name + self.FolderInstance = nil :: Folder? + + return self + end + + Server.new = Server.Server + + function Server.Fire(self: Server, Player: Player, EventName: string, ...) + Event.FireClient(Player, self.Name .. "_" .. EventName, ...) + end + + function Server.FireAll(self: Server, EventName: string, ...) + for _, Player in ipairs(Players:GetPlayers()) do + self:Fire(Player, EventName, ...) + end + end + + function Server.FireAllExcept( + self: Server, + Player: Player, + EventName: string, + ... + ) + for _, OtherPlayer in ipairs(Players:GetPlayers()) do + if OtherPlayer ~= Player then + self:Fire(OtherPlayer, EventName, ...) + end + end + end + + function Server.FireList( + self: Server, + PlayerList: { Player }, + EventName: string, + ... + ) + for _, Player in ipairs(PlayerList) do + self:Fire(Player, EventName, ...) + end + end + + function Server.FireWithFilter( + self: Server, + Filter: (Player) -> boolean, + EventName: string, + ... + ) + for _, Player in ipairs(Players:GetPlayers()) do + if Filter(Player) then + self:Fire(Player, EventName, ...) + end + end + end + + function Server.On( + self: Server, + EventName: string, + Callback: ((Player, ...any) -> ...any)? + ) + Event.SetCallback(self.Name .. "_" .. EventName, Callback) + end + + function Server.Folder(self: Server, Player: Player?) + if Player then + ClientFolder = ( + Player:FindFirstChild "PlayerGui" :: any + ).Red :: ScreenGui + + if ClientFolder:FindFirstChild(self.Name) then + return ClientFolder:FindFirstChild(self.Name) :: Model + else + local Folder = Instance.new "Model" + Folder.Name = self.Name + Folder.Parent = ClientFolder + + return Folder :: Model + end + else + if not self.FolderInstance then + local Folder = Instance.new "Model" + Folder.Name = self.Name + Folder.Parent = Remote + + self.FolderInstance = Folder + end + + return self.FolderInstance :: Model + end + end + + export type Server = typeof(Server.Server "") + + local Client = {} + Client.__index = Client + + function Client.Client(Name: string) + local self = setmetatable({}, Client) + + self.Name = Name + self.FolderInstance = nil :: Folder? + self.LocalFolderInstance = nil :: Folder? + + return self + end + + Client.new = Client.Client + + function Client.Fire(self: Client, EventName: string, ...) + return Event.FireServer(self.Name .. "_" .. EventName, ...) + end + + function Client.Call(self: Client, EventName: string, ...) + return Event.Call(self.Name .. "_" .. EventName, ...) + end + + function Client.On( + self: Client, + EventName: string, + Callback: ((...any) -> ())? + ) + return Event.SetCallback(self.Name .. "_" .. EventName, Callback) + end + + function Client.Folder(self: Client) + if not self.FolderInstance then + self.FolderInstance = Remote:WaitForChild(self.Name) :: Model + end + + return self.FolderInstance :: Model + end + + function Client.LocalFolder(self: Client) + if not self.LocalFolderInstance then + self.LocalFolderInstance = + ClientFolder:WaitForChild(self.Name) :: Model + end + + return self.LocalFolderInstance :: Model + end + + export type Client = typeof(Client.Client "") + + local Net = {} + + Net.ServerNamespaceList = {} + Net.ClientNamespaceList = {} + + function Net.Server(Name: string, Definitions: { string }?): Server + assert(IsServer, "Net.Server can only be used on the server") + + if not Net.ServerNamespaceList[Name] then + Net.ServerNamespaceList[Name] = Server.Server(Name) + end + + if Definitions then + for _, Term in ipairs(Definitions) do + Serdes.Identifier((Name :: string) .. "_" .. Term) + end + end + + return Net.ServerNamespaceList[Name] + end + + function Net.Client(Name: string): Client + assert(not IsServer, "Net.Client can only be used on the client") + + if Net.ClientNamespaceList[Name] == nil then + Net.ClientNamespaceList[Name] = Client.Client(Name) + end + + return Net.ClientNamespaceList[Name] + end + + function Net.Identifier(Name: string) + return Serdes.Identifier(Name) + end + + Event.Listen() + + return Net +end diff --git a/Libraries/Red/RedEvent.luau b/Libraries/Red/RedEvent.luau new file mode 100644 index 0000000..197fc24 --- /dev/null +++ b/Libraries/Red/RedEvent.luau @@ -0,0 +1,45 @@ +return function(IsServer: boolean) + local ReplicatedStorage = game:GetService "ReplicatedStorage" + local Players = game:GetService "Players" + + local RedEvent = {} + + local Remote, ClientFolder + + if IsServer then + Remote = ReplicatedStorage:FindFirstChild "RedEvent" :: RemoteEvent + + if not Remote then -- prevent vile promise bugs + Remote = Instance.new "RemoteEvent" + Remote.Name = "RedEvent" + Remote.Parent = ReplicatedStorage + end + + local function PlayerAdded(Player: Player) + ClientFolder = Instance.new "ScreenGui" + + -- ClientFolder.Enabled = false + -- ClientFolder.ResetOnSpawn = false + ClientFolder.Name = "Red" + ClientFolder.Parent = Player:FindFirstChild "PlayerGui" + end + + Players.PlayerAdded:connect(PlayerAdded) + + for _, Player in ipairs(Players:GetPlayers()) do + PlayerAdded(Player) + end + else + Remote = ReplicatedStorage:WaitForChild "RedEvent" :: RemoteEvent + + ClientFolder = ( + Players.LocalPlayer:FindFirstChild "PlayerGui" :: PlayerGui + ):WaitForChild "Red" :: ScreenGui + ClientFolder.Parent = nil + end + + RedEvent.Remote = Remote + RedEvent.ClientFolder = ClientFolder + + return RedEvent +end diff --git a/Libraries/Red/Util/Bin.luau b/Libraries/Red/Util/Bin.luau new file mode 100644 index 0000000..d950fe1 --- /dev/null +++ b/Libraries/Red/Util/Bin.luau @@ -0,0 +1,27 @@ +local Spawn = require "./Spawn" +local typeof = require "../../../Modules/Polyfill/typeof" + +type BinItem = Instance | RBXScriptConnection | () -> ...any + +return function() + local Bin: { BinItem } = {} + + return function(Item: BinItem) + table.insert(Bin, Item) + end, function() + for _, Item in ipairs(Bin) do + if typeof(Item) == "Instance" then + Item:Destroy() + elseif typeof(Item) == "RBXScriptConnection" then + Item:disconnect() + elseif typeof(Item) == "function" then + Spawn(Item) + end + end + + -- table.clear(Bin) + for i, _ in ipairs(Bin) do + Bin[i] = nil + end + end +end diff --git a/Libraries/Red/Util/Clock.luau b/Libraries/Red/Util/Clock.luau new file mode 100644 index 0000000..c01c1dc --- /dev/null +++ b/Libraries/Red/Util/Clock.luau @@ -0,0 +1,67 @@ +-- local ReplicatedStorage = game:GetService "ReplicatedStorage" +local RunService = game:GetService "RunService" + +local function MakeHeartbeatFunction(Clock: Clock) + return function(Delta) + Clock:Advance(Delta) + end +end + +local Clock = {} +Clock.__index = Clock + +function Clock.Clock(Interval: number, Callback: () -> ()) + local self = setmetatable({}, Clock) + + self.Interval = Interval + self.Callback = Callback + self.Delta = 0 + + self.Connection = RunService.Heartbeat:connect(MakeHeartbeatFunction(self)) + + return self +end + +Clock.new = Clock.Clock + +function Clock.Pause(self: Clock) + if self.Connection then + self.Connection:Disconnect() + end +end + +function Clock.Resume(self: Clock) + if self.Connection.Connected then + return + end + + self.Connection = RunService.Heartbeat:connect(MakeHeartbeatFunction(self)) +end + +function Clock.Advance(self: Clock, Delta: number) + self.Delta += Delta + + if self.Delta >= self.Interval * 10 then + local Skipped = math.floor(self.Delta / self.Interval) + self.Delta -= Skipped * self.Interval + + -- if ReplicatedStorage:GetAttribute "RedDebug" then + -- warn( + -- "[Red.Clock]: Clock is falling behind! Skipped " + -- .. Skipped + -- .. " intervals." + -- ) + -- end + + return + end + + if self.Delta >= self.Interval then + self.Delta -= self.Interval + self.Callback() + end +end + +export type Clock = typeof(Clock.Clock(...)) + +return Clock diff --git a/Libraries/Red/Util/Collection.luau b/Libraries/Red/Util/Collection.luau new file mode 100644 index 0000000..f1b6ac9 --- /dev/null +++ b/Libraries/Red/Util/Collection.luau @@ -0,0 +1,41 @@ +local CollectionService = game:GetService "CollectionService" + +local Spawn = require "./Spawn" + +return function( + Tag: string, + Start: (Instance) -> T..., + Stop: (T...) -> () +): () -> () + local InstanceMap = {} + + for _, Instance in ipairs(CollectionService:GetTagged(Tag)) do + Spawn(function() + InstanceMap[Instance] = { Start(Instance) } + end) + end + + local AddConnection = CollectionService:GetInstanceAddedSignal(Tag) + :connect(function(Instance) + InstanceMap[Instance] = { Start(Instance) } + end) + + local RemoveConnection = CollectionService:GetInstanceRemovedSignal(Tag) + :connect(function(Instance) + local Value = InstanceMap[Instance] + + if Value then + InstanceMap[Instance] = nil + Stop(unpack(Value)) + end + end) + + return function() + AddConnection:Disconnect() + RemoveConnection:Disconnect() + + for Instance, Value in pairs(InstanceMap) do + Spawn(Stop, unpack(Value)) + end + end +end diff --git a/Libraries/Red/Util/Promise.luau b/Libraries/Red/Util/Promise.luau new file mode 100644 index 0000000..69804b0 --- /dev/null +++ b/Libraries/Red/Util/Promise.luau @@ -0,0 +1,206 @@ +local RunService = game:GetService "RunService" + +local Spawn = require "./Spawn" + +local Promise = {} +Promise.__index = Promise + +function Promise.Promise(Callback: ( + Resolve: (...any) -> (), + Reject: (...any) -> () +) -> ()) + local self = setmetatable({}, Promise) + + self.Status = "Pending" + self.OnResolve = {} :: { (...any) -> () } + self.OnReject = {} :: { (...any) -> () } + + self.Value = {} :: { any } + + self.Thread = nil :: thread? + self.Thread = coroutine.create(function() + local ok, err = ypcall(Callback, function(...) + self:_Resolve(...) + end, function(...) + self:_Reject(...) + end) + + if not ok then + self:_Reject(err) + end + end) + + coroutine.resume(self.Thread :: thread) + + return self +end + +Promise.new = Promise.Promise :: ( + Callback: (Resolve: (...any) -> (), Reject: (...any) -> ()) -> () +) -> Promise + +function Promise.Resolve(...: any): Promise + local self = setmetatable({}, Promise) + + self.Status = "Resolved" + self.OnResolve = {} :: { (...any) -> () } + self.OnReject = {} :: { (...any) -> () } + self.Value = { ... } :: { any } + self.Thread = nil :: thread? + + return self +end + +function Promise.Reject(...: any): Promise + local self = setmetatable({}, Promise) + + self.Status = "Rejected" + self.OnResolve = {} :: { (...any) -> () } + self.OnReject = {} :: { (...any) -> () } + self.Value = { ... } :: { any } + self.Thread = nil :: thread? + + return self +end + +function Promise._Resolve(self: Promise, ...: any) + assert( + self.Status == "Pending", + "Cannot resolve a promise that is not pending." + ) + + self.Status = "Resolved" + self.Value = { ... } + + for _, Callback in ipairs(self.OnResolve) do + Spawn(Callback, ...) + end + + -- task.defer(task.cancel, self.Thread :: thread) + coroutine.resume(coroutine.create(function() + coroutine.yield(self.Thread :: thread) + end)) +end + +function Promise._Reject(self: Promise, ...: any) + assert( + self.Status == "Pending", + "Cannot reject a promise that is not pending." + ) + + self.Status = "Rejected" + self.Value = { ... } + + for _, Callback in ipairs(self.OnReject) do + Spawn(Callback, ...) + end + + -- task.defer(task.cancel, self.Thread :: thread) + coroutine.resume(coroutine.create(function() + coroutine.yield(self.Thread :: thread) + end)) +end + +function Promise.Then( + self: Promise, + OnResolve: ((...any) -> ...any)?, + OnReject: ((...any) -> ...any)? +): Promise + return Promise.Promise(function(Resolve, Reject) + local function PromiseResolutionProcedure( + Value: Promise | any, + ...: any + ) + if type(Value) == "table" and getmetatable(Value) == Promise then + if Value.Status == "Pending" then + table.insert(Value.OnResolve, Resolve) + table.insert(Value.OnReject, Reject) + elseif Value.Status == "Resolved" then + Resolve(Value.Value) + elseif Value.Status == "Rejected" then + Reject(Value.Value) + end + else + Resolve(Value, ...) + end + end + + if self.Status == "Pending" then + if OnResolve then + table.insert(self.OnResolve, function(...) + PromiseResolutionProcedure(OnResolve(...)) + end) + else + table.insert(self.OnResolve, PromiseResolutionProcedure) + end + + if OnReject then + table.insert(self.OnReject, function(...) + PromiseResolutionProcedure(OnReject(...)) + end) + else + table.insert(self.OnReject, Reject) + end + elseif self.Status == "Resolved" then + if OnResolve then + PromiseResolutionProcedure(OnResolve(unpack(self.Value))) + else + Resolve(unpack(self.Value)) + end + elseif self.Status == "Rejected" then + if OnReject then + PromiseResolutionProcedure(OnReject(unpack(self.Value))) + else + Reject(unpack(self.Value)) + end + end + end) +end + +function Promise.Catch(self: Promise, OnReject: (...any) -> ()) + return self:Then(nil, OnReject) +end + +function Promise.Finally(self: Promise, Finally: () -> ()) + return self:Then(function(...) + Finally() + return ... + end, function(Error) + Finally() + error(Error) + end) +end + +function Promise.Await(self: Promise): ...any + if self.Status == "Resolved" then + return unpack(self.Value) + elseif self.Status == "Rejected" then + return error(unpack(self.Value)) + end + + local c = 0 + repeat -- bruh + RunService.Stepped:wait() + c += 1 + until self.Status ~= "Pending" or c > 500 -- random + + local Current = coroutine.running() + + local function Resume() + coroutine.resume(Current) + end + + table.insert(self.OnResolve, Resume) + table.insert(self.OnReject, Resume) + + coroutine.yield() + + if self.Status == "Resolved" then + return unpack(self.Value) + end + return error(unpack(self.Value)) +end + +export type Promise = typeof(Promise.Promise(...)) + +return Promise diff --git a/Libraries/Red/Util/Ratelimit.luau b/Libraries/Red/Util/Ratelimit.luau new file mode 100644 index 0000000..7435f2c --- /dev/null +++ b/Libraries/Red/Util/Ratelimit.luau @@ -0,0 +1,40 @@ +return function(Limit: number, Interval: number) + assert(Limit > 0, "Limit must be greater than 0") + + local CountMap = {} :: { [T]: number } + local CountKeyless = 0 + + return function(Key: T?) + if Key then + local Count = CountMap[Key] + + if Count == nil then + Count = 0 + + Delay(Interval, function() + CountMap[Key] = nil + end) + end + + if Count >= Limit then + return false + end + + CountMap[Key] = Count + 1 + else + if CountKeyless == 0 then + Delay(Interval, function() + CountKeyless = 0 + end) + end + + if CountKeyless >= Limit then + return false + end + + CountKeyless += 1 + end + + return true + end +end diff --git a/Libraries/Red/Util/Signal.luau b/Libraries/Red/Util/Signal.luau new file mode 100644 index 0000000..6da6de1 --- /dev/null +++ b/Libraries/Red/Util/Signal.luau @@ -0,0 +1,74 @@ +local Promise = require "./Promise" +local Spawn = require "./Spawn" + +type SignalNode = { + Next: SignalNode?, + Callback: (T...) -> (), +} + +export type Signal = { + Root: SignalNode?, + + Connect: (self: Signal, Callback: (T...) -> ()) -> () -> (), + Wait: (self: Signal) -> Promise.Promise, + Fire: (self: Signal, T...) -> (), + DisconnectAll: (self: Signal) -> (), +} + +local Signal = {} +Signal.__index = Signal + +function Signal.new(): Signal + return setmetatable({ + Root = nil, + }, Signal) :: any +end + +function Signal.Connect(self: Signal, Callback: (T...) -> ()): () -> () + local Node = { + Next = self.Root, + Callback = Callback, + } + + self.Root = Node + + return function() + if self.Root == Node then + self.Root = Node.Next + else + local Current = self.Root + while Current do + if Current.Next == Node then + Current.Next = Node.Next + break + end + Current = Current.Next + end + end + end +end + +function Signal.Wait(self: Signal): Promise.Promise + return Promise.new(function(Resolve) + local Disconnect + + Disconnect = self:Connect(function(...) + Disconnect() + Resolve(... :: any) + end) + end) +end + +function Signal.Fire(self: Signal, ...: T...) + local Current = self.Root + while Current do + Spawn(Current.Callback, ...) + Current = Current.Next + end +end + +function Signal.DisconnectAll(self: Signal) + self.Root = nil +end + +return Signal diff --git a/Libraries/Red/Util/Spawn.luau b/Libraries/Red/Util/Spawn.luau new file mode 100644 index 0000000..1dc1317 --- /dev/null +++ b/Libraries/Red/Util/Spawn.luau @@ -0,0 +1,23 @@ +local FreeThread: thread? = nil + +local function FunctionPasser(fn, ...) + local AquiredThread = FreeThread + FreeThread = nil + fn(...) + FreeThread = AquiredThread +end + +local function Yielder() + while true do + FunctionPasser(coroutine.yield()) + end +end + +return function(fn: (T...) -> (), ...: T...) + if not FreeThread then + FreeThread = coroutine.create(Yielder) + coroutine.resume(FreeThread :: any) + end + + coroutine.resume(FreeThread :: thread, fn, ...) +end diff --git a/Libraries/Red/init.luau b/Libraries/Red/init.luau new file mode 100644 index 0000000..92143c7 --- /dev/null +++ b/Libraries/Red/init.luau @@ -0,0 +1,33 @@ +local function Red(_, Script: LuaSourceContainer) + local _SERVER + + if Script:IsA "LocalScript" then + _SERVER = false + elseif Script:IsA "Script" then + _SERVER = true + else + error("Argument must be the script itself", 2) + end + + local Net = require "./Net"(_SERVER) + + return { + Server = Net.Server, + Client = Net.Client, + + Collection = require "./Util/Collection", + Ratelimit = require "./Util/Ratelimit", + Promise = require "./Util/Promise", + Signal = require "./Util/Signal", + Clock = require "./Util/Clock", + Spawn = require "./Util/Spawn", + Bin = require "./Util/Bin", + } +end + +return { + Help = function() + return "See https://redblox.dev/ for more information." + end, + Load = Red, +} diff --git a/Libraries/Red/typeof.luau b/Libraries/Red/typeof.luau new file mode 100644 index 0000000..170ab2c --- /dev/null +++ b/Libraries/Red/typeof.luau @@ -0,0 +1,181 @@ +-- A basic polyfill for the typeof function + +return function(value) + local basicType = type(value) + + if + basicType == "nil" + or basicType == "boolean" + or basicType == "number" + or basicType == "string" + or basicType == "function" + or basicType == "thread" + or basicType == "table" + then + return basicType + end + + -- Will short-circuit + --[[ + { + name of type to check, + { list of required properties }, + } + ]] + local tests = { + { + "Instance", + { "ClassName" }, + }, + { + "EnumItem", + { "EnumType", "Name", "Value" }, + }, + { + "Enum", + { "GetEnumItems" }, + }, + { + "Enums", + { "MembershipType" }, -- lmao + }, + { + "RBXScriptSignal", + { + "connect", + -- "connected", + -- "connectFirst", + -- "connectLast", + "wait", + }, + }, + { + "RBXScriptConnection", + { + "connected", + "disconnect", + }, + }, + { + "TweenInfo", + { + "EasingDirection", + -- "Time", + -- "DelayTime", + "RepeatCount", + "EasingStyle", + -- "Reverses", + }, + }, + { + "CFrame", + { + "p", + "x", + "y", + "z", + "lookVector", + }, + }, + { + "Vector3", + { + "Lerp", + -- "Cross", + -- "Dot", + "unit", + "magnitude", + "x", + "y", + "z", + }, + }, + { + "Vector3int16", + { "z", "x", "y" }, + }, + { + "Vector2", + { "unit", "magnitude", "x", "y" }, + }, + { + "Vector2int16", + { "x", "y" }, + }, + { + "Region3", + { "CFrame", "Size" }, + }, + { + "Region3int16", + { "Min", "Max" }, + }, + { + "Ray", + { + "Origin", + "Direction", + "Unit", + "ClosestPoint", + "Distance", + }, + }, + { + "UDim", + { "Scale", "Offset" }, + }, + { + "Axes", + { "Z", "X", "Y" }, + }, + { + "UDim2", + { "X", "Y" }, + }, + { + "BrickColor", + { + "Number", + "Name", + "Color", + "r", + "g", + "b", + }, + }, + { + "Color3", + { "r", "g", "b" }, + }, + { + "Faces", + { + "Right", + "Top", + "Back", + -- "Left", + -- "Bottom", + -- "Front", + }, + }, + } + + for _, v in ipairs(tests) do + local t, test = v[1], v[2] + + local ok, result = pcall(function() + for _, prop in ipairs(test) do + if value[prop] == nil then + return false + end + -- Cannot throw if the property does not exist, + -- as userdatas may allow nil indexing + end + return true + end) + + if ok and result then + return t + end + end +end diff --git a/compile.sh b/compile.sh index dd505b5..908b4a5 100644 --- a/compile.sh +++ b/compile.sh @@ -5,6 +5,7 @@ done echo "Processing libraries..." darklua process -c dense.json5 ./corescripts/Libraries/Fusion/init.luau ./corescripts/processed/10000001.lua +darklua process -c bundle.json5 ./corescripts/Libraries/Red/init.luau ./corescripts/processed/10000002.lua echo "Processing other corescripts..." for file in ./corescripts/luau/[a-z]*.luau; do diff --git a/defs.d.lua b/defs.d.lua index 541823c..70cc72b 100644 --- a/defs.d.lua +++ b/defs.d.lua @@ -5,8 +5,6 @@ type ProtectedString = string type BinaryString = string type QDir = string type QFont = string -type FloatCurveKey = any -type RotationCurveKey = any declare class Enum function GetEnumItems(self): { any } @@ -188,11 +186,6 @@ declare class EnumAssetFetchStatus_INTERNAL extends Enum Loading: EnumAssetFetchStatus TimedOut: EnumAssetFetchStatus end -declare class EnumAudioSubType extends EnumItem end -declare class EnumAudioSubType_INTERNAL extends Enum - Music: EnumAudioSubType - SoundEffect: EnumAudioSubType -end declare class EnumAudioWindowSize extends EnumItem end declare class EnumAudioWindowSize_INTERNAL extends Enum Small: EnumAudioWindowSize @@ -2526,15 +2519,6 @@ declare class EnumVerticalScrollBarPosition_INTERNAL extends Enum Left: EnumVerticalScrollBarPosition Right: EnumVerticalScrollBarPosition end -declare class EnumVibrationMotor extends EnumItem end -declare class EnumVibrationMotor_INTERNAL extends Enum - Large: EnumVibrationMotor - Small: EnumVibrationMotor - LeftTrigger: EnumVibrationMotor - RightTrigger: EnumVibrationMotor - LeftHand: EnumVibrationMotor - RightHand: EnumVibrationMotor -end declare class EnumViewMode extends EnumItem end declare class EnumViewMode_INTERNAL extends Enum None: EnumViewMode @@ -2542,12 +2526,6 @@ declare class EnumViewMode_INTERNAL extends Enum Transparent: EnumViewMode Decal: EnumViewMode end -declare class EnumVirtualCursorMode extends EnumItem end -declare class EnumVirtualCursorMode_INTERNAL extends Enum - Default: EnumVirtualCursorMode - Disabled: EnumVirtualCursorMode - Enabled: EnumVirtualCursorMode -end declare class EnumVirtualInputMode extends EnumItem end declare class EnumVirtualInputMode_INTERNAL extends Enum Recording: EnumVirtualInputMode @@ -2661,7 +2639,6 @@ type ENUM_LIST = { ApplyStrokeMode: EnumApplyStrokeMode_INTERNAL, AspectType: EnumAspectType_INTERNAL, AssetFetchStatus: EnumAssetFetchStatus_INTERNAL, - AudioSubType: EnumAudioSubType_INTERNAL, AudioWindowSize: EnumAudioWindowSize_INTERNAL, AutoIndentRule: EnumAutoIndentRule_INTERNAL, AutomaticSize: EnumAutomaticSize_INTERNAL, @@ -2957,9 +2934,7 @@ type ENUM_LIST = { VelocityConstraintMode: EnumVelocityConstraintMode_INTERNAL, VerticalAlignment: EnumVerticalAlignment_INTERNAL, VerticalScrollBarPosition: EnumVerticalScrollBarPosition_INTERNAL, - VibrationMotor: EnumVibrationMotor_INTERNAL, ViewMode: EnumViewMode_INTERNAL, - VirtualCursorMode: EnumVirtualCursorMode_INTERNAL, VirtualInputMode: EnumVirtualInputMode_INTERNAL, VolumetricAudio: EnumVolumetricAudio_INTERNAL, WaterDirection: EnumWaterDirection_INTERNAL, @@ -3060,14 +3035,6 @@ declare class Faces Top: boolean end -declare class FloatCurveKey - Interpolation: EnumKeyInterpolationMode - LeftTangent: number - RightTangent: number - Time: number - Value: number -end - declare class Font Bold: boolean Family: string @@ -3258,14 +3225,6 @@ declare class CFrame function __sub(self, other: Vector3): CFrame end -declare class RotationCurveKey - Interpolation: EnumKeyInterpolationMode - LeftTangent: number - RightTangent: number - Time: number - Value: CFrame -end - declare class Region3 CFrame: CFrame Size: Vector3 @@ -3664,7 +3623,6 @@ end declare class AudioSearchParams extends Instance Album: string Artist: string - AudioSubType: EnumAudioSubType MaxDuration: number MinDuration: number SearchKeyword: string @@ -3811,7 +3769,6 @@ declare class StarterGui extends BasePlayerGui RtlTextSupport: EnumRtlTextSupport ScreenOrientation: EnumScreenOrientation ShowDevelopmentGui: boolean - VirtualCursorMode: EnumVirtualCursorMode function GetCore(self, parameterName: string): any function GetCoreGuiEnabled(self, coreGuiType: EnumCoreGuiType): boolean function RegisterGetCore(self, parameterName: string, getFunction: ((...any) -> ...any)): nil @@ -3820,39 +3777,6 @@ declare class StarterGui extends BasePlayerGui function SetCoreGuiEnabled(self, coreGuiType: EnumCoreGuiType, enabled: boolean): nil end -declare class BaseWrap extends Instance - CageMeshId: Content - CageOrigin: CFrame - CageOriginWorld: CFrame - HSRAssetId: Content - ImportOrigin: CFrame - ImportOriginWorld: CFrame - function GetFaces(self, cageType: EnumCageType): { any } - function GetVertices(self, cageType: EnumCageType): { any } - function IsHSRReady(self): boolean - function ModifyVertices(self, cageType: EnumCageType, vertices: { any }): nil -end - -declare class WrapLayer extends BaseWrap - AutoSkin: EnumWrapLayerAutoSkin - BindOffset: CFrame - Color: Color3 - DebugMode: EnumWrapLayerDebugMode - Enabled: boolean - Order: number - Puffiness: number - ReferenceMeshId: Content - ReferenceOrigin: CFrame - ReferenceOriginWorld: CFrame - ShrinkFactor: number -end - -declare class WrapTarget extends BaseWrap - Color: Color3 - DebugMode: EnumWrapTargetDebugMode - Stiffness: number -end - declare class BindableEvent extends Instance Event: RBXScriptSignal<...any> function Fire(self, ...: any): () @@ -4750,15 +4674,6 @@ declare class DynamicImage extends Instance function WritePixels(self, position: Vector2, size: Vector2, pixels: { any }): nil end -declare class EulerRotationCurve extends Instance - RotationOrder: EnumRotationOrder - function GetAnglesAtTime(self, time: number): { any } - function GetRotationAtTime(self, time: number): CFrame - function X(self): FloatCurve - function Y(self): FloatCurve - function Z(self): FloatCurve -end - declare class EventIngestService extends Instance function SendEventDeferred(self, target: string, eventContext: string, eventName: string, additionalArgs: { [any]: any }): nil function SendEventImmediately(self, target: string, eventContext: string, eventName: string, additionalArgs: { [any]: any }): nil @@ -4876,17 +4791,6 @@ end declare class FlagStandService extends Instance end -declare class FloatCurve extends Instance - Length: number - function GetKeyAtIndex(self, index: number): FloatCurveKey - function GetKeyIndicesAtTime(self, time: number): { any } - function GetKeys(self): { any } - function GetValueAtTime(self, time: number): number? - function InsertKey(self, key: FloatCurveKey): { any } - function RemoveKeyAtIndex(self, startingIndex: number, count: number?): number - function SetKeys(self, keys: { any }): number -end - declare class ForceField extends Instance Visible: boolean end @@ -5507,13 +5411,6 @@ end declare class GuidRegistryService extends Instance end -declare class HapticService extends Instance - function GetMotor(self, inputType: EnumUserInputType, vibrationMotor: EnumVibrationMotor): any - function IsMotorSupported(self, inputType: EnumUserInputType, vibrationMotor: EnumVibrationMotor): boolean - function IsVibrationSupported(self, inputType: EnumUserInputType): boolean - function SetMotor(self, inputType: EnumUserInputType, vibrationMotor: EnumVibrationMotor, vibrationValues: any): nil -end - declare class HeightmapImporterService extends Instance ColormapHasUnknownPixels: RBXScriptSignal<> ProgressUpdate: RBXScriptSignal @@ -7083,53 +6980,14 @@ end declare class ReplicatedStorage extends Instance end -declare class RobloxServerStorage extends Instance -end - -declare class RomarkService extends Instance - function EndRemoteRomarkTest(self): nil -end - -declare class RotationCurve extends Instance - Length: number - function GetKeyAtIndex(self, index: number): RotationCurveKey - function GetKeyIndicesAtTime(self, time: number): { any } - function GetKeys(self): { any } - function GetValueAtTime(self, time: number): CFrame? - function InsertKey(self, key: RotationCurveKey): { any } - function RemoveKeyAtIndex(self, startingIndex: number, count: number?): number - function SetKeys(self, keys: { any }): number -end - -declare class RtMessagingService extends Instance -end declare class RunService extends Instance - ClientGitHash: string Heartbeat: RBXScriptSignal - PostSimulation: RBXScriptSignal - PreAnimation: RBXScriptSignal - PreRender: RBXScriptSignal - PreSimulation: RBXScriptSignal RenderStepped: RBXScriptSignal Stepped: RBXScriptSignal - function BindToRenderStep(self, name: string, priority: number, func: ((delta: number) -> ())): () - function GetCoreScriptVersion(self): string - function GetRobloxClientChannel(self): string - function GetRobloxVersion(self): string - function IsClient(self): boolean - function IsEdit(self): boolean - function IsRunMode(self): boolean - function IsRunning(self): boolean - function IsServer(self): boolean - function IsStudio(self): boolean function Pause(self): nil function Run(self): nil - function Set3dRenderingEnabled(self, enable: boolean): nil - function SetRobloxGuiFocused(self, focus: boolean): nil function Stop(self): nil - function UnbindFromRenderStep(self, name: string): nil - function setThrottleFramerateEnabled(self, enable: boolean): nil end declare class RuntimeScriptService extends Instance @@ -7344,7 +7202,6 @@ declare class ServiceProvider extends Instance GuiService: GuiService GuidRegistryService: GuidRegistryService HSRDataContentProvider: HSRDataContentProvider - HapticService: HapticService HeightmapImporterService: HeightmapImporterService HttpRbxApiService: HttpRbxApiService HttpService: HttpService @@ -7396,9 +7253,6 @@ declare class ServiceProvider extends Instance RemoteDebuggerServer: RemoteDebuggerServer RenderSettings: RenderSettings ReplicatedStorage: ReplicatedStorage - RobloxServerStorage: RobloxServerStorage - RomarkService: RomarkService - RtMessagingService: RtMessagingService RunService: RunService RuntimeScriptService: RuntimeScriptService SafetyService: SafetyService @@ -7521,7 +7375,6 @@ declare class ServiceProvider extends Instance function GetService(self, service: "GuiService"): GuiService function GetService(self, service: "GuidRegistryService"): GuidRegistryService function GetService(self, service: "HSRDataContentProvider"): HSRDataContentProvider - function GetService(self, service: "HapticService"): HapticService function GetService(self, service: "HeightmapImporterService"): HeightmapImporterService function GetService(self, service: "Hopper"): Hopper function GetService(self, service: "HttpRbxApiService"): HttpRbxApiService @@ -7576,9 +7429,6 @@ declare class ServiceProvider extends Instance function GetService(self, service: "RemoteDebuggerServer"): RemoteDebuggerServer function GetService(self, service: "RenderSettings"): RenderSettings function GetService(self, service: "ReplicatedStorage"): ReplicatedStorage - function GetService(self, service: "RobloxServerStorage"): RobloxServerStorage - function GetService(self, service: "RomarkService"): RomarkService - function GetService(self, service: "RtMessagingService"): RtMessagingService function GetService(self, service: "RunService"): RunService function GetService(self, service: "RuntimeScriptService"): RuntimeScriptService function GetService(self, service: "SafetyService"): SafetyService @@ -7774,15 +7624,12 @@ declare class SnippetService extends Instance end declare class SocialService extends Instance - GameInvitePromptClosed: RBXScriptSignal - PromptInviteRequested: RBXScriptSignal - SelfViewHidden: RBXScriptSignal<> - SelfViewVisible: RBXScriptSignal - function CanSendGameInviteAsync(self, player: Player, recipientId: number?): boolean - function HideSelfView(self): nil - function InvokeGameInvitePromptClosed(self, player: Instance, recipientIds: { any }): nil - function PromptGameInvite(self, player: Player, experienceInviteOptions: Instance?): nil - function ShowSelfView(self, selfViewPosition: EnumSelfViewPosition?): nil + function SetGroupRankUrl(self, groupRankUrl: string): nil + function SetGroupRoleUrl(self, groupRoleUrl: string): nil + function SetFriendUrl(self, friendUrl: string): nil + function SetBestFriendUrl(self, bestFriendUrl: string): nil + function SetStuffUrl(self, stuffUrl: string): nil + function SetPackageContentsUrl(self, stuffUrl: string): nil end declare class Sound extends Instance @@ -7821,11 +7668,6 @@ declare class Sound extends Instance function Stop(self): nil end -declare class SoundEffect extends Instance - Enabled: boolean - Priority: number -end - declare class SoundService extends Instance AmbientReverb: EnumReverbType DeviceListChanged: RBXScriptSignal @@ -8487,13 +8329,6 @@ declare class Vector3Value extends ValueBase Value: Vector3 end -declare class Vector3Curve extends Instance - function GetValueAtTime(self, time: number): { any } - function X(self): FloatCurve - function Y(self): FloatCurve - function Z(self): FloatCurve -end - declare class VersionControlService extends Instance ScriptCollabEnabled: boolean end @@ -8546,7 +8381,7 @@ declare class Wire extends Instance end declare Instance: { - new: ((className: "Accoutrement", parent: Instance?) -> Accoutrement) & ((className: "Hat", parent: Instance?) -> Hat) & ((className: "AdvancedDragger", parent: Instance?) -> AdvancedDragger) & ((className: "Animation", parent: Instance?) -> Animation) & ((className: "CurveAnimation", parent: Instance?) -> CurveAnimation) & ((className: "KeyframeSequence", parent: Instance?) -> KeyframeSequence) & ((className: "AnimationController", parent: Instance?) -> AnimationController) & ((className: "AnimationRigData", parent: Instance?) -> AnimationRigData) & ((className: "Animator", parent: Instance?) -> Animator) & ((className: "AudioDeviceInput", parent: Instance?) -> AudioDeviceInput) & ((className: "AudioDeviceOutput", parent: Instance?) -> AudioDeviceOutput) & ((className: "AudioDistortion", parent: Instance?) -> AudioDistortion) & ((className: "AudioEcho", parent: Instance?) -> AudioEcho) & ((className: "AudioEmitter", parent: Instance?) -> AudioEmitter) & ((className: "AudioEqualizer", parent: Instance?) -> AudioEqualizer) & ((className: "AudioFader", parent: Instance?) -> AudioFader) & ((className: "AudioFlanger", parent: Instance?) -> AudioFlanger) & ((className: "AudioListener", parent: Instance?) -> AudioListener) & ((className: "AudioPitchShifter", parent: Instance?) -> AudioPitchShifter) & ((className: "AudioPlayer", parent: Instance?) -> AudioPlayer) & ((className: "AudioReverb", parent: Instance?) -> AudioReverb) & ((className: "AudioSearchParams", parent: Instance?) -> AudioSearchParams) & ((className: "Backpack", parent: Instance?) -> Backpack) & ((className: "WrapLayer", parent: Instance?) -> WrapLayer) & ((className: "WrapTarget", parent: Instance?) -> WrapTarget) & ((className: "BindableEvent", parent: Instance?) -> BindableEvent) & ((className: "BindableFunction", parent: Instance?) -> BindableFunction) & ((className: "BodyAngularVelocity", parent: Instance?) -> BodyAngularVelocity) & ((className: "BodyForce", parent: Instance?) -> BodyForce) & ((className: "BodyGyro", parent: Instance?) -> BodyGyro) & ((className: "BodyPosition", parent: Instance?) -> BodyPosition) & ((className: "BodyThrust", parent: Instance?) -> BodyThrust) & ((className: "BodyVelocity", parent: Instance?) -> BodyVelocity) & ((className: "RocketPropulsion", parent: Instance?) -> RocketPropulsion) & ((className: "BubbleChatMessageProperties", parent: Instance?) -> BubbleChatMessageProperties) & ((className: "Camera", parent: Instance?) -> Camera) & ((className: "BodyColors", parent: Instance?) -> BodyColors) & ((className: "CharacterMesh", parent: Instance?) -> CharacterMesh) & ((className: "Pants", parent: Instance?) -> Pants) & ((className: "Shirt", parent: Instance?) -> Shirt) & ((className: "ShirtGraphic", parent: Instance?) -> ShirtGraphic) & ((className: "Skin", parent: Instance?) -> Skin) & ((className: "ClickDetector", parent: Instance?) -> ClickDetector) & ((className: "DragDetector", parent: Instance?) -> DragDetector) & ((className: "Configuration", parent: Instance?) -> Configuration) & ((className: "AngularVelocity", parent: Instance?) -> AngularVelocity) & ((className: "AnimationConstraint", parent: Instance?) -> AnimationConstraint) & ((className: "BallSocketConstraint", parent: Instance?) -> BallSocketConstraint) & ((className: "HingeConstraint", parent: Instance?) -> HingeConstraint) & ((className: "LineForce", parent: Instance?) -> LineForce) & ((className: "LinearVelocity", parent: Instance?) -> LinearVelocity) & ((className: "PlaneConstraint", parent: Instance?) -> PlaneConstraint) & ((className: "Plane", parent: Instance?) -> Plane) & ((className: "RigidConstraint", parent: Instance?) -> RigidConstraint) & ((className: "RodConstraint", parent: Instance?) -> RodConstraint) & ((className: "RopeConstraint", parent: Instance?) -> RopeConstraint) & ((className: "CylindricalConstraint", parent: Instance?) -> CylindricalConstraint) & ((className: "PrismaticConstraint", parent: Instance?) -> PrismaticConstraint) & ((className: "SpringConstraint", parent: Instance?) -> SpringConstraint) & ((className: "Torque", parent: Instance?) -> Torque) & ((className: "TorsionSpringConstraint", parent: Instance?) -> TorsionSpringConstraint) & ((className: "UniversalConstraint", parent: Instance?) -> UniversalConstraint) & ((className: "HumanoidController", parent: Instance?) -> HumanoidController) & ((className: "SkateboardController", parent: Instance?) -> SkateboardController) & ((className: "VehicleController", parent: Instance?) -> VehicleController) & ((className: "AirController", parent: Instance?) -> AirController) & ((className: "ClimbController", parent: Instance?) -> ClimbController) & ((className: "GroundController", parent: Instance?) -> GroundController) & ((className: "SwimController", parent: Instance?) -> SwimController) & ((className: "ControllerManager", parent: Instance?) -> ControllerManager) & ((className: "CustomEvent", parent: Instance?) -> CustomEvent) & ((className: "CustomEventReceiver", parent: Instance?) -> CustomEventReceiver) & ((className: "CylinderMesh", parent: Instance?) -> CylinderMesh) & ((className: "DynamicMesh", parent: Instance?) -> DynamicMesh) & ((className: "FileMesh", parent: Instance?) -> FileMesh) & ((className: "SpecialMesh", parent: Instance?) -> SpecialMesh) & ((className: "DataStoreIncrementOptions", parent: Instance?) -> DataStoreIncrementOptions) & ((className: "DataStoreOptions", parent: Instance?) -> DataStoreOptions) & ((className: "DataStoreSetOptions", parent: Instance?) -> DataStoreSetOptions) & ((className: "DebuggerWatch", parent: Instance?) -> DebuggerWatch) & ((className: "Dialog", parent: Instance?) -> Dialog) & ((className: "DialogChoice", parent: Instance?) -> DialogChoice) & ((className: "Dragger", parent: Instance?) -> Dragger) & ((className: "EulerRotationCurve", parent: Instance?) -> EulerRotationCurve) & ((className: "ExperienceInviteOptions", parent: Instance?) -> ExperienceInviteOptions) & ((className: "Explosion", parent: Instance?) -> Explosion) & ((className: "Decal", parent: Instance?) -> Decal) & ((className: "Texture", parent: Instance?) -> Texture) & ((className: "Hole", parent: Instance?) -> Hole) & ((className: "MotorFeature", parent: Instance?) -> MotorFeature) & ((className: "Fire", parent: Instance?) -> Fire) & ((className: "FloatCurve", parent: Instance?) -> FloatCurve) & ((className: "CSGDictionaryService", parent: Instance?) -> CSGDictionaryService) & ((className: "NonReplicatedCSGDictionaryService", parent: Instance?) -> NonReplicatedCSGDictionaryService) & ((className: "ForceField", parent: Instance?) -> ForceField) & ((className: "FunctionalTest", parent: Instance?) -> FunctionalTest) & ((className: "GetTextBoundsParams", parent: Instance?) -> GetTextBoundsParams) & ((className: "Frame", parent: Instance?) -> Frame) & ((className: "ImageButton", parent: Instance?) -> ImageButton) & ((className: "TextButton", parent: Instance?) -> TextButton) & ((className: "ImageLabel", parent: Instance?) -> ImageLabel) & ((className: "TextLabel", parent: Instance?) -> TextLabel) & ((className: "TextBox", parent: Instance?) -> TextBox) & ((className: "VideoFrame", parent: Instance?) -> VideoFrame) & ((className: "ViewportFrame", parent: Instance?) -> ViewportFrame) & ((className: "BillboardGui", parent: Instance?) -> BillboardGui) & ((className: "ScreenGui", parent: Instance?) -> ScreenGui) & ((className: "GuiMain", parent: Instance?) -> GuiMain) & ((className: "AdGui", parent: Instance?) -> AdGui) & ((className: "SurfaceGui", parent: Instance?) -> SurfaceGui) & ((className: "FloorWire", parent: Instance?) -> FloorWire) & ((className: "SelectionBox", parent: Instance?) -> SelectionBox) & ((className: "BoxHandleAdornment", parent: Instance?) -> BoxHandleAdornment) & ((className: "ConeHandleAdornment", parent: Instance?) -> ConeHandleAdornment) & ((className: "CylinderHandleAdornment", parent: Instance?) -> CylinderHandleAdornment) & ((className: "ImageHandleAdornment", parent: Instance?) -> ImageHandleAdornment) & ((className: "LineHandleAdornment", parent: Instance?) -> LineHandleAdornment) & ((className: "SphereHandleAdornment", parent: Instance?) -> SphereHandleAdornment) & ((className: "WireframeHandleAdornment", parent: Instance?) -> WireframeHandleAdornment) & ((className: "ParabolaAdornment", parent: Instance?) -> ParabolaAdornment) & ((className: "SelectionSphere", parent: Instance?) -> SelectionSphere) & ((className: "ArcHandles", parent: Instance?) -> ArcHandles) & ((className: "Handles", parent: Instance?) -> Handles) & ((className: "SurfaceSelection", parent: Instance?) -> SurfaceSelection) & ((className: "SelectionPartLasso", parent: Instance?) -> SelectionPartLasso) & ((className: "SelectionPointLasso", parent: Instance?) -> SelectionPointLasso) & ((className: "HeightmapImporterService", parent: Instance?) -> HeightmapImporterService) & ((className: "HiddenSurfaceRemovalAsset", parent: Instance?) -> HiddenSurfaceRemovalAsset) & ((className: "Humanoid", parent: Instance?) -> Humanoid) & ((className: "RotateP", parent: Instance?) -> RotateP) & ((className: "RotateV", parent: Instance?) -> RotateV) & ((className: "Glue", parent: Instance?) -> Glue) & ((className: "ManualGlue", parent: Instance?) -> ManualGlue) & ((className: "ManualWeld", parent: Instance?) -> ManualWeld) & ((className: "Motor", parent: Instance?) -> Motor) & ((className: "Motor6D", parent: Instance?) -> Motor6D) & ((className: "Rotate", parent: Instance?) -> Rotate) & ((className: "Snap", parent: Instance?) -> Snap) & ((className: "VelocityMotor", parent: Instance?) -> VelocityMotor) & ((className: "Weld", parent: Instance?) -> Weld) & ((className: "Keyframe", parent: Instance?) -> Keyframe) & ((className: "KeyframeMarker", parent: Instance?) -> KeyframeMarker) & ((className: "PointLight", parent: Instance?) -> PointLight) & ((className: "SpotLight", parent: Instance?) -> SpotLight) & ((className: "SurfaceLight", parent: Instance?) -> SurfaceLight) & ((className: "Script", parent: Instance?) -> Script) & ((className: "LocalScript", parent: Instance?) -> LocalScript) & ((className: "ModuleScript", parent: Instance?) -> ModuleScript) & ((className: "MarkerCurve", parent: Instance?) -> MarkerCurve) & ((className: "MemoryStoreService", parent: Instance?) -> MemoryStoreService) & ((className: "Message", parent: Instance?) -> Message) & ((className: "Hint", parent: Instance?) -> Hint) & ((className: "CornerWedgePart", parent: Instance?) -> CornerWedgePart) & ((className: "Part", parent: Instance?) -> Part) & ((className: "FlagStand", parent: Instance?) -> FlagStand) & ((className: "Seat", parent: Instance?) -> Seat) & ((className: "SkateboardPlatform", parent: Instance?) -> SkateboardPlatform) & ((className: "SpawnLocation", parent: Instance?) -> SpawnLocation) & ((className: "WedgePart", parent: Instance?) -> WedgePart) & ((className: "PartOperation", parent: Instance?) -> PartOperation) & ((className: "IntersectOperation", parent: Instance?) -> IntersectOperation) & ((className: "NegateOperation", parent: Instance?) -> NegateOperation) & ((className: "UnionOperation", parent: Instance?) -> UnionOperation) & ((className: "TrussPart", parent: Instance?) -> TrussPart) & ((className: "VehicleSeat", parent: Instance?) -> VehicleSeat) & ((className: "Model", parent: Instance?) -> Model) & ((className: "HopperBin", parent: Instance?) -> HopperBin) & ((className: "Tool", parent: Instance?) -> Tool) & ((className: "Flag", parent: Instance?) -> Flag) & ((className: "WorldModel", parent: Instance?) -> WorldModel) & ((className: "PartOperationAsset", parent: Instance?) -> PartOperationAsset) & ((className: "PathfindingLink", parent: Instance?) -> PathfindingLink) & ((className: "PathfindingModifier", parent: Instance?) -> PathfindingModifier) & ((className: "Player", parent: Instance?) -> Player) & ((className: "PluginAction", parent: Instance?) -> PluginAction) & ((className: "PluginCapabilities", parent: Instance?) -> PluginCapabilities) & ((className: "NumberPose", parent: Instance?) -> NumberPose) & ((className: "Pose", parent: Instance?) -> Pose) & ((className: "ReflectionMetadata", parent: Instance?) -> ReflectionMetadata) & ((className: "ReflectionMetadataCallbacks", parent: Instance?) -> ReflectionMetadataCallbacks) & ((className: "ReflectionMetadataClasses", parent: Instance?) -> ReflectionMetadataClasses) & ((className: "ReflectionMetadataEnums", parent: Instance?) -> ReflectionMetadataEnums) & ((className: "ReflectionMetadataEvents", parent: Instance?) -> ReflectionMetadataEvents) & ((className: "ReflectionMetadataFunctions", parent: Instance?) -> ReflectionMetadataFunctions) & ((className: "ReflectionMetadataClass", parent: Instance?) -> ReflectionMetadataClass) & ((className: "ReflectionMetadataEnum", parent: Instance?) -> ReflectionMetadataEnum) & ((className: "ReflectionMetadataEnumItem", parent: Instance?) -> ReflectionMetadataEnumItem) & ((className: "ReflectionMetadataMember", parent: Instance?) -> ReflectionMetadataMember) & ((className: "ReflectionMetadataProperties", parent: Instance?) -> ReflectionMetadataProperties) & ((className: "ReflectionMetadataYieldFunctions", parent: Instance?) -> ReflectionMetadataYieldFunctions) & ((className: "RemoteEvent", parent: Instance?) -> RemoteEvent) & ((className: "RemoteFunction", parent: Instance?) -> RemoteFunction) & ((className: "RenderingTest", parent: Instance?) -> RenderingTest) & ((className: "RotationCurve", parent: Instance?) -> RotationCurve) & ((className: "BuoyancySensor", parent: Instance?) -> BuoyancySensor) & ((className: "ControllerPartSensor", parent: Instance?) -> ControllerPartSensor) & ((className: "Sky", parent: Instance?) -> Sky) & ((className: "Smoke", parent: Instance?) -> Smoke) & ((className: "Sound", parent: Instance?) -> Sound) & ((className: "Sparkles", parent: Instance?) -> Sparkles) & ((className: "StandalonePluginScripts", parent: Instance?) -> StandalonePluginScripts) & ((className: "StarterGear", parent: Instance?) -> StarterGear) & ((className: "StudioCallout", parent: Instance?) -> StudioCallout) & ((className: "StudioObjectBase", parent: Instance?) -> StudioObjectBase) & ((className: "StudioWidget", parent: Instance?) -> StudioWidget) & ((className: "StyleDerive", parent: Instance?) -> StyleDerive) & ((className: "StyleLink", parent: Instance?) -> StyleLink) & ((className: "SurfaceAppearance", parent: Instance?) -> SurfaceAppearance) & ((className: "Team", parent: Instance?) -> Team) & ((className: "TeleportOptions", parent: Instance?) -> TeleportOptions) & ((className: "TerrainDetail", parent: Instance?) -> TerrainDetail) & ((className: "TerrainRegion", parent: Instance?) -> TerrainRegion) & ((className: "TestService", parent: Instance?) -> TestService) & ((className: "TextChannel", parent: Instance?) -> TextChannel) & ((className: "TextChatCommand", parent: Instance?) -> TextChatCommand) & ((className: "TextChatMessageProperties", parent: Instance?) -> TextChatMessageProperties) & ((className: "TrackerStreamAnimation", parent: Instance?) -> TrackerStreamAnimation) & ((className: "BinaryStringValue", parent: Instance?) -> BinaryStringValue) & ((className: "BoolValue", parent: Instance?) -> BoolValue) & ((className: "BrickColorValue", parent: Instance?) -> BrickColorValue) & ((className: "CFrameValue", parent: Instance?) -> CFrameValue) & ((className: "Color3Value", parent: Instance?) -> Color3Value) & ((className: "DoubleConstrainedValue", parent: Instance?) -> DoubleConstrainedValue) & ((className: "IntConstrainedValue", parent: Instance?) -> IntConstrainedValue) & ((className: "IntValue", parent: Instance?) -> IntValue) & ((className: "NumberValue", parent: Instance?) -> NumberValue) & ((className: "ObjectValue", parent: Instance?) -> ObjectValue) & ((className: "RayValue", parent: Instance?) -> RayValue) & ((className: "StringValue", parent: Instance?) -> StringValue) & ((className: "Vector3Value", parent: Instance?) -> Vector3Value) & ((className: "Vector3Curve", parent: Instance?) -> Vector3Curve) & ((className: "Wire", parent: Instance?) -> Wire) & ((className: string, parent: Instance?) -> Instance), + new: ((className: "Accoutrement", parent: Instance?) -> Accoutrement) & ((className: "Hat", parent: Instance?) -> Hat) & ((className: "AdvancedDragger", parent: Instance?) -> AdvancedDragger) & ((className: "Animation", parent: Instance?) -> Animation) & ((className: "CurveAnimation", parent: Instance?) -> CurveAnimation) & ((className: "KeyframeSequence", parent: Instance?) -> KeyframeSequence) & ((className: "AnimationController", parent: Instance?) -> AnimationController) & ((className: "AnimationRigData", parent: Instance?) -> AnimationRigData) & ((className: "Animator", parent: Instance?) -> Animator) & ((className: "AudioDeviceInput", parent: Instance?) -> AudioDeviceInput) & ((className: "AudioDeviceOutput", parent: Instance?) -> AudioDeviceOutput) & ((className: "AudioDistortion", parent: Instance?) -> AudioDistortion) & ((className: "AudioEcho", parent: Instance?) -> AudioEcho) & ((className: "AudioEmitter", parent: Instance?) -> AudioEmitter) & ((className: "AudioEqualizer", parent: Instance?) -> AudioEqualizer) & ((className: "AudioFader", parent: Instance?) -> AudioFader) & ((className: "AudioFlanger", parent: Instance?) -> AudioFlanger) & ((className: "AudioListener", parent: Instance?) -> AudioListener) & ((className: "AudioPitchShifter", parent: Instance?) -> AudioPitchShifter) & ((className: "AudioPlayer", parent: Instance?) -> AudioPlayer) & ((className: "AudioReverb", parent: Instance?) -> AudioReverb) & ((className: "AudioSearchParams", parent: Instance?) -> AudioSearchParams) & ((className: "Backpack", parent: Instance?) -> Backpack) & ((className: "BindableEvent", parent: Instance?) -> BindableEvent) & ((className: "BindableFunction", parent: Instance?) -> BindableFunction) & ((className: "BodyAngularVelocity", parent: Instance?) -> BodyAngularVelocity) & ((className: "BodyForce", parent: Instance?) -> BodyForce) & ((className: "BodyGyro", parent: Instance?) -> BodyGyro) & ((className: "BodyPosition", parent: Instance?) -> BodyPosition) & ((className: "BodyThrust", parent: Instance?) -> BodyThrust) & ((className: "BodyVelocity", parent: Instance?) -> BodyVelocity) & ((className: "RocketPropulsion", parent: Instance?) -> RocketPropulsion) & ((className: "BubbleChatMessageProperties", parent: Instance?) -> BubbleChatMessageProperties) & ((className: "Camera", parent: Instance?) -> Camera) & ((className: "BodyColors", parent: Instance?) -> BodyColors) & ((className: "CharacterMesh", parent: Instance?) -> CharacterMesh) & ((className: "Pants", parent: Instance?) -> Pants) & ((className: "Shirt", parent: Instance?) -> Shirt) & ((className: "ShirtGraphic", parent: Instance?) -> ShirtGraphic) & ((className: "Skin", parent: Instance?) -> Skin) & ((className: "ClickDetector", parent: Instance?) -> ClickDetector) & ((className: "DragDetector", parent: Instance?) -> DragDetector) & ((className: "Configuration", parent: Instance?) -> Configuration) & ((className: "AngularVelocity", parent: Instance?) -> AngularVelocity) & ((className: "AnimationConstraint", parent: Instance?) -> AnimationConstraint) & ((className: "BallSocketConstraint", parent: Instance?) -> BallSocketConstraint) & ((className: "HingeConstraint", parent: Instance?) -> HingeConstraint) & ((className: "LineForce", parent: Instance?) -> LineForce) & ((className: "LinearVelocity", parent: Instance?) -> LinearVelocity) & ((className: "PlaneConstraint", parent: Instance?) -> PlaneConstraint) & ((className: "Plane", parent: Instance?) -> Plane) & ((className: "RigidConstraint", parent: Instance?) -> RigidConstraint) & ((className: "RodConstraint", parent: Instance?) -> RodConstraint) & ((className: "RopeConstraint", parent: Instance?) -> RopeConstraint) & ((className: "CylindricalConstraint", parent: Instance?) -> CylindricalConstraint) & ((className: "PrismaticConstraint", parent: Instance?) -> PrismaticConstraint) & ((className: "SpringConstraint", parent: Instance?) -> SpringConstraint) & ((className: "Torque", parent: Instance?) -> Torque) & ((className: "TorsionSpringConstraint", parent: Instance?) -> TorsionSpringConstraint) & ((className: "UniversalConstraint", parent: Instance?) -> UniversalConstraint) & ((className: "HumanoidController", parent: Instance?) -> HumanoidController) & ((className: "SkateboardController", parent: Instance?) -> SkateboardController) & ((className: "VehicleController", parent: Instance?) -> VehicleController) & ((className: "AirController", parent: Instance?) -> AirController) & ((className: "ClimbController", parent: Instance?) -> ClimbController) & ((className: "GroundController", parent: Instance?) -> GroundController) & ((className: "SwimController", parent: Instance?) -> SwimController) & ((className: "ControllerManager", parent: Instance?) -> ControllerManager) & ((className: "CustomEvent", parent: Instance?) -> CustomEvent) & ((className: "CustomEventReceiver", parent: Instance?) -> CustomEventReceiver) & ((className: "CylinderMesh", parent: Instance?) -> CylinderMesh) & ((className: "DynamicMesh", parent: Instance?) -> DynamicMesh) & ((className: "FileMesh", parent: Instance?) -> FileMesh) & ((className: "SpecialMesh", parent: Instance?) -> SpecialMesh) & ((className: "DataStoreIncrementOptions", parent: Instance?) -> DataStoreIncrementOptions) & ((className: "DataStoreOptions", parent: Instance?) -> DataStoreOptions) & ((className: "DataStoreSetOptions", parent: Instance?) -> DataStoreSetOptions) & ((className: "DebuggerWatch", parent: Instance?) -> DebuggerWatch) & ((className: "Dialog", parent: Instance?) -> Dialog) & ((className: "DialogChoice", parent: Instance?) -> DialogChoice) & ((className: "Dragger", parent: Instance?) -> Dragger) & ((className: "ExperienceInviteOptions", parent: Instance?) -> ExperienceInviteOptions) & ((className: "Explosion", parent: Instance?) -> Explosion) & ((className: "Decal", parent: Instance?) -> Decal) & ((className: "Texture", parent: Instance?) -> Texture) & ((className: "Hole", parent: Instance?) -> Hole) & ((className: "MotorFeature", parent: Instance?) -> MotorFeature) & ((className: "Fire", parent: Instance?) -> Fire) & ((className: "CSGDictionaryService", parent: Instance?) -> CSGDictionaryService) & ((className: "NonReplicatedCSGDictionaryService", parent: Instance?) -> NonReplicatedCSGDictionaryService) & ((className: "ForceField", parent: Instance?) -> ForceField) & ((className: "FunctionalTest", parent: Instance?) -> FunctionalTest) & ((className: "GetTextBoundsParams", parent: Instance?) -> GetTextBoundsParams) & ((className: "Frame", parent: Instance?) -> Frame) & ((className: "ImageButton", parent: Instance?) -> ImageButton) & ((className: "TextButton", parent: Instance?) -> TextButton) & ((className: "ImageLabel", parent: Instance?) -> ImageLabel) & ((className: "TextLabel", parent: Instance?) -> TextLabel) & ((className: "TextBox", parent: Instance?) -> TextBox) & ((className: "VideoFrame", parent: Instance?) -> VideoFrame) & ((className: "ViewportFrame", parent: Instance?) -> ViewportFrame) & ((className: "BillboardGui", parent: Instance?) -> BillboardGui) & ((className: "ScreenGui", parent: Instance?) -> ScreenGui) & ((className: "GuiMain", parent: Instance?) -> GuiMain) & ((className: "AdGui", parent: Instance?) -> AdGui) & ((className: "SurfaceGui", parent: Instance?) -> SurfaceGui) & ((className: "FloorWire", parent: Instance?) -> FloorWire) & ((className: "SelectionBox", parent: Instance?) -> SelectionBox) & ((className: "BoxHandleAdornment", parent: Instance?) -> BoxHandleAdornment) & ((className: "ConeHandleAdornment", parent: Instance?) -> ConeHandleAdornment) & ((className: "CylinderHandleAdornment", parent: Instance?) -> CylinderHandleAdornment) & ((className: "ImageHandleAdornment", parent: Instance?) -> ImageHandleAdornment) & ((className: "LineHandleAdornment", parent: Instance?) -> LineHandleAdornment) & ((className: "SphereHandleAdornment", parent: Instance?) -> SphereHandleAdornment) & ((className: "WireframeHandleAdornment", parent: Instance?) -> WireframeHandleAdornment) & ((className: "ParabolaAdornment", parent: Instance?) -> ParabolaAdornment) & ((className: "SelectionSphere", parent: Instance?) -> SelectionSphere) & ((className: "ArcHandles", parent: Instance?) -> ArcHandles) & ((className: "Handles", parent: Instance?) -> Handles) & ((className: "SurfaceSelection", parent: Instance?) -> SurfaceSelection) & ((className: "SelectionPartLasso", parent: Instance?) -> SelectionPartLasso) & ((className: "SelectionPointLasso", parent: Instance?) -> SelectionPointLasso) & ((className: "HeightmapImporterService", parent: Instance?) -> HeightmapImporterService) & ((className: "HiddenSurfaceRemovalAsset", parent: Instance?) -> HiddenSurfaceRemovalAsset) & ((className: "Humanoid", parent: Instance?) -> Humanoid) & ((className: "RotateP", parent: Instance?) -> RotateP) & ((className: "RotateV", parent: Instance?) -> RotateV) & ((className: "Glue", parent: Instance?) -> Glue) & ((className: "ManualGlue", parent: Instance?) -> ManualGlue) & ((className: "ManualWeld", parent: Instance?) -> ManualWeld) & ((className: "Motor", parent: Instance?) -> Motor) & ((className: "Motor6D", parent: Instance?) -> Motor6D) & ((className: "Rotate", parent: Instance?) -> Rotate) & ((className: "Snap", parent: Instance?) -> Snap) & ((className: "VelocityMotor", parent: Instance?) -> VelocityMotor) & ((className: "Weld", parent: Instance?) -> Weld) & ((className: "Keyframe", parent: Instance?) -> Keyframe) & ((className: "KeyframeMarker", parent: Instance?) -> KeyframeMarker) & ((className: "PointLight", parent: Instance?) -> PointLight) & ((className: "SpotLight", parent: Instance?) -> SpotLight) & ((className: "SurfaceLight", parent: Instance?) -> SurfaceLight) & ((className: "Script", parent: Instance?) -> Script) & ((className: "LocalScript", parent: Instance?) -> LocalScript) & ((className: "ModuleScript", parent: Instance?) -> ModuleScript) & ((className: "MarkerCurve", parent: Instance?) -> MarkerCurve) & ((className: "MemoryStoreService", parent: Instance?) -> MemoryStoreService) & ((className: "Message", parent: Instance?) -> Message) & ((className: "Hint", parent: Instance?) -> Hint) & ((className: "CornerWedgePart", parent: Instance?) -> CornerWedgePart) & ((className: "Part", parent: Instance?) -> Part) & ((className: "FlagStand", parent: Instance?) -> FlagStand) & ((className: "Seat", parent: Instance?) -> Seat) & ((className: "SkateboardPlatform", parent: Instance?) -> SkateboardPlatform) & ((className: "SpawnLocation", parent: Instance?) -> SpawnLocation) & ((className: "WedgePart", parent: Instance?) -> WedgePart) & ((className: "PartOperation", parent: Instance?) -> PartOperation) & ((className: "IntersectOperation", parent: Instance?) -> IntersectOperation) & ((className: "NegateOperation", parent: Instance?) -> NegateOperation) & ((className: "UnionOperation", parent: Instance?) -> UnionOperation) & ((className: "TrussPart", parent: Instance?) -> TrussPart) & ((className: "VehicleSeat", parent: Instance?) -> VehicleSeat) & ((className: "Model", parent: Instance?) -> Model) & ((className: "HopperBin", parent: Instance?) -> HopperBin) & ((className: "Tool", parent: Instance?) -> Tool) & ((className: "Flag", parent: Instance?) -> Flag) & ((className: "WorldModel", parent: Instance?) -> WorldModel) & ((className: "PartOperationAsset", parent: Instance?) -> PartOperationAsset) & ((className: "PathfindingLink", parent: Instance?) -> PathfindingLink) & ((className: "PathfindingModifier", parent: Instance?) -> PathfindingModifier) & ((className: "Player", parent: Instance?) -> Player) & ((className: "PluginAction", parent: Instance?) -> PluginAction) & ((className: "PluginCapabilities", parent: Instance?) -> PluginCapabilities) & ((className: "NumberPose", parent: Instance?) -> NumberPose) & ((className: "Pose", parent: Instance?) -> Pose) & ((className: "ReflectionMetadata", parent: Instance?) -> ReflectionMetadata) & ((className: "ReflectionMetadataCallbacks", parent: Instance?) -> ReflectionMetadataCallbacks) & ((className: "ReflectionMetadataClasses", parent: Instance?) -> ReflectionMetadataClasses) & ((className: "ReflectionMetadataEnums", parent: Instance?) -> ReflectionMetadataEnums) & ((className: "ReflectionMetadataEvents", parent: Instance?) -> ReflectionMetadataEvents) & ((className: "ReflectionMetadataFunctions", parent: Instance?) -> ReflectionMetadataFunctions) & ((className: "ReflectionMetadataClass", parent: Instance?) -> ReflectionMetadataClass) & ((className: "ReflectionMetadataEnum", parent: Instance?) -> ReflectionMetadataEnum) & ((className: "ReflectionMetadataEnumItem", parent: Instance?) -> ReflectionMetadataEnumItem) & ((className: "ReflectionMetadataMember", parent: Instance?) -> ReflectionMetadataMember) & ((className: "ReflectionMetadataProperties", parent: Instance?) -> ReflectionMetadataProperties) & ((className: "ReflectionMetadataYieldFunctions", parent: Instance?) -> ReflectionMetadataYieldFunctions) & ((className: "RemoteEvent", parent: Instance?) -> RemoteEvent) & ((className: "RemoteFunction", parent: Instance?) -> RemoteFunction) & ((className: "RenderingTest", parent: Instance?) -> RenderingTest) & ((className: "BuoyancySensor", parent: Instance?) -> BuoyancySensor) & ((className: "ControllerPartSensor", parent: Instance?) -> ControllerPartSensor) & ((className: "Sky", parent: Instance?) -> Sky) & ((className: "Smoke", parent: Instance?) -> Smoke) & ((className: "Sound", parent: Instance?) -> Sound) & ((className: "Sparkles", parent: Instance?) -> Sparkles) & ((className: "StandalonePluginScripts", parent: Instance?) -> StandalonePluginScripts) & ((className: "StarterGear", parent: Instance?) -> StarterGear) & ((className: "StudioCallout", parent: Instance?) -> StudioCallout) & ((className: "StudioObjectBase", parent: Instance?) -> StudioObjectBase) & ((className: "StudioWidget", parent: Instance?) -> StudioWidget) & ((className: "StyleDerive", parent: Instance?) -> StyleDerive) & ((className: "StyleLink", parent: Instance?) -> StyleLink) & ((className: "SurfaceAppearance", parent: Instance?) -> SurfaceAppearance) & ((className: "Team", parent: Instance?) -> Team) & ((className: "TeleportOptions", parent: Instance?) -> TeleportOptions) & ((className: "TerrainDetail", parent: Instance?) -> TerrainDetail) & ((className: "TerrainRegion", parent: Instance?) -> TerrainRegion) & ((className: "TestService", parent: Instance?) -> TestService) & ((className: "TextChannel", parent: Instance?) -> TextChannel) & ((className: "TextChatCommand", parent: Instance?) -> TextChatCommand) & ((className: "TextChatMessageProperties", parent: Instance?) -> TextChatMessageProperties) & ((className: "TrackerStreamAnimation", parent: Instance?) -> TrackerStreamAnimation) & ((className: "BinaryStringValue", parent: Instance?) -> BinaryStringValue) & ((className: "BoolValue", parent: Instance?) -> BoolValue) & ((className: "BrickColorValue", parent: Instance?) -> BrickColorValue) & ((className: "CFrameValue", parent: Instance?) -> CFrameValue) & ((className: "Color3Value", parent: Instance?) -> Color3Value) & ((className: "DoubleConstrainedValue", parent: Instance?) -> DoubleConstrainedValue) & ((className: "IntConstrainedValue", parent: Instance?) -> IntConstrainedValue) & ((className: "IntValue", parent: Instance?) -> IntValue) & ((className: "NumberValue", parent: Instance?) -> NumberValue) & ((className: "ObjectValue", parent: Instance?) -> ObjectValue) & ((className: "RayValue", parent: Instance?) -> RayValue) & ((className: "StringValue", parent: Instance?) -> StringValue) & ((className: "Vector3Value", parent: Instance?) -> Vector3Value) & ((className: "Wire", parent: Instance?) -> Wire) & ((className: string, parent: Instance?) -> Instance), Lock: (instance: Instance, player: Player) -> nil, Unlock: (instance: Instance) -> nil, @@ -8713,14 +8548,6 @@ declare Font: { fromId: ((id: number, weight: EnumFontWeight?, style: EnumFontStyle?) -> Font), } -declare FloatCurveKey: { - new: ((time: number, value: number, Interpolation: EnumKeyInterpolationMode) -> FloatCurveKey), -} - -declare RotationCurveKey: { - new: ((time: number, value: CFrame, Interpolation: EnumKeyInterpolationMode) -> RotationCurveKey), -} - declare class GlobalSettings extends GenericSettings Lua: LuaSettings @@ -8782,7 +8609,302 @@ declare TeleportService: TeleportService declare plugin: Plugin declare script: LuaSourceContainer declare function loadfile(file: string): any -declare function LoadLibrary(libraryName: string): { any } + +-- fusion + +-- pubtypes + +--[[ + Stores common public-facing type information for Fusion APIs. +]] + +type Set = { [T]: any } + +--[[ + General use types +]] + +-- A unique symbolic value. +type Symbol = { + type: "Symbol", + name: string, +} + +-- Types that can be expressed as vectors of numbers, and so can be animated. +type Animatable = + number + | CFrame + | Color3 + | ColorSequenceKeypoint + | DateTime + | NumberRange + | NumberSequenceKeypoint + | PhysicalProperties + | Ray + | Rect + | Region3 + | Region3int16 + | UDim + | UDim2 + | Vector2 + | Vector2int16 + | Vector3 + | Vector3int16 + +-- A task which can be accepted for cleanup. +type Task = + Instance + | RBXScriptConnection + | () -> () | { destroy: (any) -> () } | { Destroy: (any) -> () } | { Task } + +-- Script-readable version information. +type Version = { + major: number, + minor: number, + isRelease: boolean, +} + +-- An object which stores a value scoped in time. +type Contextual = { + type: "Contextual", + now: (Contextual) -> T, + is: (Contextual, T) -> ContextualIsMethods, +} + +type ContextualIsMethods = { + during: (ContextualIsMethods, (A...) -> T, A...) -> T, +} + +--[[ + Generic reactive graph types +]] + +-- A graph object which can have dependents. +type Dependency = { + dependentSet: Set, +} + +-- A graph object which can have dependencies. +type Dependent = { + update: (Dependent) -> boolean, + dependencySet: Set, +} + +-- An object which stores a piece of reactive state. +type StateObject = Dependency & { + type: "State", + kind: string, + _typeIdentifier: T, +} + +-- Either a constant value of type T, or a state object containing type T. +type CanBeState = StateObject | T + +-- Function signature for use callbacks. +type Use = (target: CanBeState) -> T + +--[[ + Specific reactive graph types +]] + +-- A state object whose value can be set at any time by the user. +type Value = StateObject & { + kind: "State", + set: (Value, newValue: any, force: boolean?) -> (), +} + +-- A state object whose value is derived from other objects using a callback. +type Computed = StateObject & Dependent & { + kind: "Computed", +} + +-- A state object whose value is derived from other objects using a callback. +type ForPairs = StateObject<{ [KO]: VO }> & Dependent & { + kind: "ForPairs", +} +-- A state object whose value is derived from other objects using a callback. +type ForKeys = StateObject<{ [KO]: V }> & Dependent & { + kind: "ForKeys", +} +-- A state object whose value is derived from other objects using a callback. +type ForValues = StateObject<{ [K]: VO }> & Dependent & { + kind: "ForKeys", +} + +-- A state object which follows another state object using tweens. +type Tween = StateObject & Dependent & { + kind: "Tween", +} + +-- A state object which follows another state object using spring simulation. +type Spring = StateObject & Dependent & { + kind: "Spring", + setPosition: (Spring, newPosition: Animatable) -> (), + setVelocity: (Spring, newVelocity: Animatable) -> (), + addVelocity: (Spring, deltaVelocity: Animatable) -> (), +} + +-- An object which can listen for updates on another state object. +type Observer = Dependent & { + kind: "Observer", + onChange: (Observer, callback: () -> ()) -> (() -> ()), +} + +--[[ + Instance related types +]] + +-- Denotes children instances in an instance or component's property table. +type SpecialKey = { + type: "SpecialKey", + kind: string, + stage: "self" | "descendants" | "ancestor" | "observer", + apply: ( + SpecialKey, + value: any, + applyTo: Instance, + cleanupTasks: { Task } + ) -> (), +} + +-- A collection of instances that may be parented to another instance. +type Children = Instance | StateObject | { [any]: Children } + +-- A table that defines an instance's properties, handlers and children. +type PropertyTable = { [string | SpecialKey]: any } + +-- init + +export type Fusion = { + version: Version, + + New: ( + className: string + ) -> ((propertyTable: PropertyTable) -> Instance), + Hydrate: ( + target: Instance + ) -> ((propertyTable: PropertyTable) -> Instance), + Ref: SpecialKey, + Cleanup: SpecialKey, + Children: SpecialKey, + Out: (propertyName: string) -> SpecialKey, + OnEvent: (eventName: string) -> SpecialKey, + OnChange: (propertyName: string) -> SpecialKey, + + Value: (initialValue: T) -> Value, + Computed: (callback: (Use) -> T, destructor: (T) -> ()?) -> Computed, + ForPairs: ( + inputTable: CanBeState<{ [KI]: VI }>, + processor: (Use, KI, VI) -> (KO, VO, M?), + destructor: (KO, VO, M?) -> ()? + ) -> ForPairs, + ForKeys: ( + inputTable: CanBeState<{ [KI]: any }>, + processor: (Use, KI) -> (KO, M?), + destructor: (KO, M?) -> ()? + ) -> ForKeys, + ForValues: ( + inputTable: CanBeState<{ [any]: VI }>, + processor: (Use, VI) -> (VO, M?), + destructor: (VO, M?) -> ()? + ) -> ForValues, + Observer: (watchedState: StateObject) -> Observer, + + Tween: (goalState: StateObject, tweenInfo: TweenInfo?) -> Tween, + Spring: ( + goalState: StateObject, + speed: CanBeState?, + damping: CanBeState? + ) -> Spring, + + Contextual: (defaultValue: T) -> Contextual, + cleanup: (...any) -> (), + doNothing: (...any) -> (), + peek: Use, +} + +export type Server = { + new: (Name: string) -> Server, + Server: (Name: string) -> Server, + Fire: (self: Server, Player: Player, EventName: string, ...any) -> (), + FireAll: (self: Server, EventName: string, ...any) -> (), + FireAllExcept: (self: Server, Player: Player, EventName: string, ...any) -> (), + FireList: (self: Server, Players: {Player}, EventName: string, ...any) -> (), + FireWithFilter: (self: Server, Filter: (Player) -> boolean, EventName: string, ...any) -> (), + On: (self: Server, EventName: string, Callback: ((Player, ...any) -> ...any?)) -> (), + Folder: (self: Server, Player: Player?) -> Model, +} + +export type Client = { + new: (self: Client, Name: string) -> Client, + Client: (self: Client, Name: string) -> Client, + Fire: (self: Client, EventName: string, ...any) -> Promise, + Call: (self: Client, EventName: string, ...any) -> Promise, + On: (self: Client, EventName: string, Callback: ((...any) -> ())?) -> Promise, + Folder: (self: Client) -> Model, + LocalFolder: (self: Client) -> Model, +} + +export type Promise = { + new: (Callback: (Resolve: (...any) -> (), Reject: (...any) -> ()) -> ()) -> Promise, + Promise: (Callback: (Resolve: (...any) -> (), Reject: (...any) -> ()) -> ()) -> Promise, + Reject: (a: any, b: any, c: any, d: any, e: any) -> Promise, + _Resolve: (self: Promise, ...any) -> (), + _Reject: (self: Promise, ...any) -> (), + Then: (self: Promise, OnResolve: ((...any) -> ...any)?, OnReject: ((...any) -> ...any)?) -> Promise, + Catch: (self: Promise, OnReject: ((...any) -> ())) -> ...any, + Finally: (self: Promise, Finally: (() -> ())) -> ...any, + Await: (self: Promise) -> ...any, +} + +type SignalNode = { + Next: SignalNode?, + Callback: (T...) -> (), +} + +export type Signal = { + Root: SignalNode?, + + Connect: (self: Signal, Callback: (T...) -> ()) -> () -> (), + Wait: (self: Signal) -> (Callback: (Resolve: (...any) -> (), Reject: (...any) -> ()) -> ()) -> Promise, + Fire: (self: Signal, T...) -> (), + DisconnectAll: (self: Signal) -> (), +} + +export type Clock = { + new: (Interval: number, Callback: () -> ()) -> Clock, + Clock: (Interval: number, Callback: () -> ()) -> Clock, + Pause: (self: Clock) -> (), + Resume: (self: Clock) -> (), + Advance: (self: Clock, Delta: number) -> (), +} + +type RedCore = { + Server: (Name: string, Definitions: {string}?) -> Server, + Client: (Name: string) -> Client, + + Collection: (Tag: string, Start: (Instance) -> (T...), Stop: (T...) -> ()) -> () -> (), + Ratelimit: (Limit: number, Interval: number) -> (Key: T?) -> boolean, + Promise: Promise, + Signal: { + new: () -> Signal, + Connect: (self: Signal, Callback: (T...) -> ()) -> () -> (), + Wait: (self: Signal) -> Promise, + Fire: (self: Signal, T...) -> (), + DisconnectAll: (self: Signal) -> (), + }, + Clock: Clock, + Spawn: (fn: (T...) -> (), T...) -> (), -- variadics SUCK + Bin: () -> ((Item: (() -> ...any) | Instance | RBXScriptConnection) -> (), () -> ()) +} + +export type Red = { + Help: () -> string, + Load: (self: Red, Script: LuaSourceContainer) -> RedCore, +} + +declare LoadLibrary: ((libraryName: "RbxFusion") -> Fusion) & ((libraryName: "RbxRed") -> Red) + declare function settings(): GlobalSettings declare function UserSettings(): UserSettings declare function PluginManager(): PluginManager diff --git a/luau/10000002.luau b/luau/10000002.luau deleted file mode 100644 index 1f6c3e0..0000000 --- a/luau/10000002.luau +++ /dev/null @@ -1,1334 +0,0 @@ -local function Red(Script) - local _SERVER, _CLIENT - - if Script:IsA "LocalScript" then - _CLIENT = true - elseif Script:IsA "Script" then - _SERVER = true - else - error("Argument must be the script itself", 2) - end - - local success, result = ypcall(function() - local __DARKLUA_BUNDLE_MODULES = {} - - do - local ReplicatedStorage = game:GetService "ReplicatedStorage" - local Players = game:GetService "Players" - local RedEvent = {} - local Remote, ClientFolder - - if _SERVER then - Remote = Instance.new "RemoteEvent" - Remote.Name = "RedEvent" - Remote.Parent = ReplicatedStorage - - local function PlayerAdded(Player) - ClientFolder = Instance.new "ScreenGui" - ClientFolder.Name = "Red" - ClientFolder.Parent = Player:FindFirstChild "PlayerGui" - end - - Players.PlayerAdded:connect(PlayerAdded) - - for _, Player in ipairs(Players:GetPlayers()) do - PlayerAdded(Player) - end - else - Remote = ReplicatedStorage:WaitForChild "RedEvent" - ClientFolder = (Players.LocalPlayer:FindFirstChild "PlayerGui"):WaitForChild "Red" - ClientFolder.Parent = nil - end - - RedEvent.Remote = Remote - RedEvent.ClientFolder = ClientFolder - __DARKLUA_BUNDLE_MODULES.a = RedEvent - end - do - local FreeThread = nil - - local function FunctionPasser(fn, ...) - local AquiredThread = FreeThread - - FreeThread = nil - - fn(...) - - FreeThread = AquiredThread - end - local function Yielder() - while true do - FunctionPasser(coroutine.yield()) - end - end - - __DARKLUA_BUNDLE_MODULES.b = function(fn, ...) - if not FreeThread then - FreeThread = coroutine.create(Yielder) - - coroutine.resume(FreeThread) - end - - coroutine.resume(FreeThread, fn, ...) - end - end - do - local RunService = game:GetService "RunService" - local Spawn = __DARKLUA_BUNDLE_MODULES.b - local Promise = {} - - Promise.__index = Promise - - function Promise.Promise(Callback) - local self = setmetatable({}, Promise) - - self.Status = "Pending" - self.OnResolve = {} - self.OnReject = {} - self.Value = {} - self.Thread = nil - self.Thread = coroutine.create(function() - local ok, err = ypcall(Callback, function(...) - self:_Resolve(...) - end, function(...) - self:_Reject(...) - end) - - if not ok then - self:_Reject(err) - end - end) - - coroutine.resume(self.Thread) - - return self - end - - Promise.new = Promise.Promise - - function Promise.Resolve(...) - local self = setmetatable({}, Promise) - - self.Status = "Resolved" - self.OnResolve = {} - self.OnReject = {} - self.Value = { ... } - self.Thread = nil - - return self - end - function Promise.Reject(...) - local self = setmetatable({}, Promise) - - self.Status = "Rejected" - self.OnResolve = {} - self.OnReject = {} - self.Value = { ... } - self.Thread = nil - - return self - end - function Promise._Resolve(self, ...) - assert( - self.Status == "Pending", - "Cannot resolve a promise that is not pending." - ) - - self.Status = "Resolved" - self.Value = { ... } - - for _, Callback in ipairs(self.OnResolve) do - Spawn(Callback, ...) - end - - coroutine.resume(coroutine.create(function() - coroutine.yield(self.Thread) - end)) - end - function Promise._Reject(self, ...) - assert( - self.Status == "Pending", - "Cannot reject a promise that is not pending." - ) - - self.Status = "Rejected" - self.Value = { ... } - - for _, Callback in ipairs(self.OnReject) do - Spawn(Callback, ...) - end - - coroutine.resume(coroutine.create(function() - coroutine.yield(self.Thread) - end)) - end - function Promise.Then(self, OnResolve, OnReject) - return Promise.Promise(function(Resolve, Reject) - local function PromiseResolutionProcedure(Value, ...) - if - type(Value) == "table" - and getmetatable(Value) == Promise - then - if Value.Status == "Pending" then - table.insert(Value.OnResolve, Resolve) - table.insert(Value.OnReject, Reject) - elseif Value.Status == "Resolved" then - Resolve(Value.Value) - elseif Value.Status == "Rejected" then - Reject(Value.Value) - end - else - Resolve(Value, ...) - end - end - - if self.Status == "Pending" then - if OnResolve then - table.insert(self.OnResolve, function(...) - PromiseResolutionProcedure(OnResolve(...)) - end) - else - table.insert( - self.OnResolve, - PromiseResolutionProcedure - ) - end - if OnReject then - table.insert(self.OnReject, function(...) - PromiseResolutionProcedure(OnReject(...)) - end) - else - table.insert(self.OnReject, Reject) - end - elseif self.Status == "Resolved" then - if OnResolve then - PromiseResolutionProcedure( - OnResolve(unpack(self.Value)) - ) - else - Resolve(unpack(self.Value)) - end - elseif self.Status == "Rejected" then - if OnReject then - PromiseResolutionProcedure( - OnReject(unpack(self.Value)) - ) - else - Reject(unpack(self.Value)) - end - end - end) - end - function Promise.Catch(self, OnReject) - return self:Then(nil, OnReject) - end - function Promise.Finally(self, Finally) - return self:Then(function(...) - Finally() - - return ... - end, function(Error) - Finally() - error(Error) - end) - end - function Promise.Await(self) - if self.Status == "Resolved" then - return unpack(self.Value) - elseif self.Status == "Rejected" then - return error(unpack(self.Value)) - end - - local c = 0 - - repeat - RunService.Stepped:wait() - - c = c + 1 - until self.Status ~= "Pending" or c > 500 - - local Current = coroutine.running() - - local function Resume() - coroutine.resume(Current) - end - - table.insert(self.OnResolve, Resume) - table.insert(self.OnReject, Resume) - coroutine.yield() - - if self.Status == "Resolved" then - return unpack(self.Value) - end - - return error(unpack(self.Value)) - end - - __DARKLUA_BUNDLE_MODULES.c = Promise - end - do - local RedEvent = __DARKLUA_BUNDLE_MODULES.a - local Event = RedEvent.Remote - local Promise = __DARKLUA_BUNDLE_MODULES.c - local Serdes = {} - - Serdes.NextId = 1 - Serdes.NextOT = 1 - - function Serdes.RegisterIdentifier(Name) - assert( - _SERVER, - "RegisterIdentifier can only be called on the server" - ) - - local Id = string.char(Serdes.NextId) - - Serdes.NextId = Serdes.NextId + 1 - - local e = Event:FindFirstChild(Name) - - if e then - e.Value = Id - else - e = Instance.new "StringValue" - e.Name = Name - e.Value = Id - e.Parent = Event - end - - return Id - end - function Serdes.Identifier(Name) - local e - - if _CLIENT then - return Promise.new(function(Resolve) - e = Event:WaitForChild(Name) - - if e.Value ~= nil then - Resolve(e.Value) - else - local Thread = Delay(5, function() - print( - [[[Red.Serdes]: Retrieving identifier exceeded 5 seconds. Make sure ']] - .. Name - .. "' is registered on the server." - ) - end) - - e.Changed:Once(function() - coroutine.yield(Thread) - Resolve(e.Value) - end) - end - end) - else - e = Event:FindFirstChild(Name) - - if e and e.Value then - return Promise.Resolve(e.Value) - end - - return Promise.Resolve(Serdes.RegisterIdentifier(Name)) - end - end - function Serdes.IdentifierAsync(Name) - return Serdes.Identifier(Name):Await() - end - function Serdes.OneTime() - Serdes.NextOT = Serdes.NextOT + 1 - - if Serdes.NextOT == 0xffff + 1 then - Serdes.NextOT = 0 - end - - return string.char(Serdes.NextOT) - end - - __DARKLUA_BUNDLE_MODULES.d = Serdes - end - do - local RunService = game:GetService "RunService" - - local function MakeHeartbeatFunction(Clock) - return function(Delta) - Clock:Advance(Delta) - end - end - - local Clock = {} - - Clock.__index = Clock - - function Clock.Clock(Interval, Callback) - local self = setmetatable({}, Clock) - - self.Interval = Interval - self.Callback = Callback - self.Delta = 0 - self.Connection = - RunService.Heartbeat:connect(MakeHeartbeatFunction(self)) - - return self - end - - Clock.new = Clock.Clock - - function Clock.Pause(self) - if self.Connection then - self.Connection:Disconnect() - end - end - function Clock.Resume(self) - if self.Connection.Connected then - return - end - - self.Connection = - RunService.Heartbeat:connect(MakeHeartbeatFunction(self)) - end - function Clock.Advance(self, Delta) - self.Delta = self.Delta + Delta - - if self.Delta >= self.Interval * 10 then - local Skipped = math.floor(self.Delta / self.Interval) - - self.Delta = self.Delta - Skipped * self.Interval - - return - end - if self.Delta >= self.Interval then - self.Delta = self.Delta - self.Interval - - self.Callback() - end - end - - __DARKLUA_BUNDLE_MODULES.e = Clock - end - do - __DARKLUA_BUNDLE_MODULES.f = __DARKLUA_BUNDLE_MODULES.e - end - do - local RunService = game:GetService "RunService" - local RedEvent = __DARKLUA_BUNDLE_MODULES.a - local Remote = RedEvent.Remote - local Serdes = __DARKLUA_BUNDLE_MODULES.d - local Spawn = __DARKLUA_BUNDLE_MODULES.b - local Promise = __DARKLUA_BUNDLE_MODULES.c - local Clock = __DARKLUA_BUNDLE_MODULES.f - local Event = {} - local nil_symbol = { __nil = true } - - Event.Callbacks = {} - Event.Outgoing = {} - - if _CLIENT then - Event.ActiveCalls = {} - end - - function Event.Listen() - if _CLIENT then - Remote.OnClientEvent:connect( - function(SingleFire, MultipleFire, IncomingCall) - if SingleFire.__nil then - SingleFire = nil - end - if MultipleFire.__nil then - MultipleFire = nil - end - if IncomingCall.__nil then - IncomingCall = nil - end - if SingleFire then - for EventId, Call in pairs(SingleFire) do - local Callback = Event.Callbacks[EventId] - local c = 0 - - repeat - RunService.Stepped:wait() - - Callback = Event.Callbacks[EventId] - c = c + 1 - until Callback or c > 500 - - if Callback then - if type(Call) == "table" then - Spawn(Callback, unpack(Call)) - else - Spawn(Callback, Call) - end - else - print "[Red]: Callback not found!" - end - end - end - if MultipleFire then - for EventId, Calls in pairs(MultipleFire) do - local Callback = Event.Callbacks[EventId] - - if Callback then - for _, Call in ipairs(Calls) do - if type(Call) == "table" then - Spawn(Callback, unpack(Call)) - else - Spawn(Callback, Call) - end - end - end - end - end - if IncomingCall then - for _, Call in pairs(IncomingCall) do - local CallId = table.remove(Call, 1) - local Success = table.remove(Call, 1) - - if Event.ActiveCalls[CallId] then - if Success then - Event.ActiveCalls[CallId].Resolve( - unpack(Call) - ) - else - Event.ActiveCalls[CallId].Reject( - unpack(Call) - ) - end - - Event.ActiveCalls[CallId] = nil - end - end - end - end - ) - Clock.new(1 / 60, function() - if not next(Event.Outgoing) then - return - end - - local SingleFire = {} - local SendSingleFire = false - - if Event.Outgoing[1] then - for EventId, Calls in pairs(Event.Outgoing[1]) do - if #Calls == 1 then - SingleFire[EventId] = Calls[1] - Event.Outgoing[1][EventId] = nil - SendSingleFire = true - end - end - end - - local sf = nil_symbol - - if SendSingleFire then - sf = SingleFire - end - - local eo1, eo2 = Event.Outgoing[1], Event.Outgoing[2] - - if eo1 == nil then - eo1 = nil_symbol - end - if eo2 == nil then - eo2 = nil_symbol - end - - Remote:FireServer(sf, eo1, eo2) - - for i, _ in pairs(Event.Outgoing) do - Event.Outgoing[i] = nil - end - end) - else - Remote.OnServerEvent:connect( - function(Player, SingleFire, MultipleFire, IncomingCall) - if SingleFire.__nil then - SingleFire = nil - end - if MultipleFire.__nil then - MultipleFire = nil - end - if IncomingCall.__nil then - IncomingCall = nil - end - if SingleFire then - for EventId, Call in pairs(SingleFire) do - local Callback = Event.Callbacks[EventId] - - if Callback then - if type(Call) == "table" then - Spawn( - Callback, - Player, - unpack(Call) - ) - else - Spawn(Callback, Player, Call) - end - end - end - end - if MultipleFire then - for EventId, Calls in pairs(MultipleFire) do - local Callback = Event.Callbacks[EventId] - - if Callback then - for _, Call in ipairs(Calls) do - if type(Call) == "table" then - Spawn( - Callback, - Player, - unpack(Call) - ) - else - Spawn(Callback, Player, Call) - end - end - end - end - end - if IncomingCall then - for EventId, Calls in pairs(IncomingCall) do - if Event.Callbacks[EventId] then - for _, Call in ipairs(Calls) do - Spawn(function() - local CallId = - table.remove(Call, 1) - local Result = { - CallId, - pcall( - Event.Callbacks[EventId], - Player, - unpack(Call) - ), - } - - if - Event.Outgoing[Player] - == nil - then - Event.Outgoing[Player] = {} - end - if - Event.Outgoing[Player][2] - == nil - then - Event.Outgoing[Player][2] = - {} - end - - table.insert( - Event.Outgoing[Player][2], - Result - ) - end) - end - else - if Event.Outgoing[Player] == nil then - Event.Outgoing[Player] = {} - end - if Event.Outgoing[Player][2] == nil then - Event.Outgoing[Player][2] = {} - end - - for _, Call in ipairs(Calls) do - table.insert( - Event.Outgoing[Player][2], - { - Call[1], - false, - "[Red]: Event not found", - } - ) - end - end - end - end - end - ) - RunService.Heartbeat:connect(function() - for Player, Packets in pairs(Event.Outgoing) do - local SingleCall = {} - local SendSingleCall = false - - if Packets[1] then - for EventId, Calls in pairs(Packets[1]) do - if #Calls == 1 then - SingleCall[EventId] = Calls[1] - Packets[1][EventId] = nil - SendSingleCall = true - end - end - end - - local sc = nil_symbol - - if SendSingleCall then - sc = SingleCall - end - - local p1, p2 = Packets[1], Packets[2] - - if p1 == nil then - p1 = nil_symbol - end - if p2 == nil then - p2 = nil_symbol - end - - Remote:FireClient(Player, sc, p1, p2) - end - for i, _ in pairs(Event.Outgoing) do - Event.Outgoing[i] = nil - end - end) - end - end - function Event.AddQueue(Queue, Call) - local Length = #Call - - if Length == 1 then - local Type = type(Call[1]) - - if Type ~= "table" then - table.insert(Queue, Call[1]) - else - table.insert(Queue, Call) - end - else - table.insert(Queue, Call) - end - end - function Event.FireClient(Player, EventName, ...) - assert( - not _CLIENT, - "Event.FireClient can only be called from the server" - ) - - local EventId = Serdes.IdentifierAsync(EventName) - - if Event.Outgoing[Player] == nil then - Event.Outgoing[Player] = {} - end - if Event.Outgoing[Player][1] == nil then - Event.Outgoing[Player][1] = {} - end - if Event.Outgoing[Player][1][EventId] == nil then - Event.Outgoing[Player][1][EventId] = {} - end - - Event.AddQueue(Event.Outgoing[Player][1][EventId], { ... }) - end - function Event.FireServer(EventName, ...) - assert( - _CLIENT, - "Event.FireServer can only be called on the client" - ) - - local Args = { ... } - - return Serdes.Identifier(EventName):Then(function(EventId) - if Event.Outgoing[1] == nil then - Event.Outgoing[1] = {} - end - if Event.Outgoing[1][EventId] == nil then - Event.Outgoing[1][EventId] = {} - end - - Event.AddQueue(Event.Outgoing[1][EventId], Args) - end) - end - function Event.Call(EventName, ...) - assert(_CLIENT, "Event.Call can only be called on the client") - - local Args = { ... } - - return Promise.new(function(Resolve, Reject) - local CallId = Serdes.OneTime() - local EventId = Serdes.IdentifierAsync(EventName) - - if Event.Outgoing[2] == nil then - Event.Outgoing[2] = {} - end - if Event.Outgoing[2][EventId] == nil then - Event.Outgoing[2][EventId] = {} - end - - table.insert(Args, 1, CallId) - table.insert(Event.Outgoing[2][EventId], Args) - - Event.ActiveCalls[CallId] = { - Resolve = Resolve, - Reject = Reject, - } - end) - end - function Event.SetCallback(EventName, Callback) - return Serdes.Identifier(EventName):Then(function(EventId) - Event.Callbacks[EventId] = Callback - end) - end - - __DARKLUA_BUNDLE_MODULES.g = Event - end - do - local Players = game:GetService "Players" - local RedEvent = __DARKLUA_BUNDLE_MODULES.a - local Remote = RedEvent.Remote - local ClientFolder = RedEvent.ClientFolder - local Serdes = __DARKLUA_BUNDLE_MODULES.d - local Event = __DARKLUA_BUNDLE_MODULES.g - local Server = {} - - Server.__index = Server - - function Server.Server(Name) - local self = setmetatable({}, Server) - - self.Name = Name - self.FolderInstance = nil - - return self - end - - Server.new = Server.Server - - function Server.Fire(self, Player, EventName, ...) - Event.FireClient(Player, self.Name .. "_" .. EventName, ...) - end - function Server.FireAll(self, EventName, ...) - for _, Player in ipairs(Players:GetPlayers()) do - self:Fire(Player, EventName, ...) - end - end - function Server.FireAllExcept(self, Player, EventName, ...) - for _, OtherPlayer in ipairs(Players:GetPlayers()) do - if OtherPlayer ~= Player then - self:Fire(OtherPlayer, EventName, ...) - end - end - end - function Server.FireList(self, PlayerList, EventName, ...) - for _, Player in ipairs(PlayerList) do - self:Fire(Player, EventName, ...) - end - end - function Server.FireWithFilter(self, Filter, EventName, ...) - for _, Player in ipairs(Players:GetPlayers()) do - if Filter(Player) then - self:Fire(Player, EventName, ...) - end - end - end - function Server.On(self, EventName, Callback) - Event.SetCallback(self.Name .. "_" .. EventName, Callback) - end - function Server.Folder(self, Player) - if Player then - ClientFolder = (Player:FindFirstChild "PlayerGui").Red - - if ClientFolder:FindFirstChild(self.Name) then - return ClientFolder:FindFirstChild(self.Name) - else - local Folder = Instance.new "Model" - - Folder.Name = self.Name - Folder.Parent = ClientFolder - - return Folder - end - else - if not self.FolderInstance then - local Folder = Instance.new "Model" - - Folder.Name = self.Name - Folder.Parent = Remote - self.FolderInstance = Folder - end - - return self.FolderInstance - end - end - - local Client = {} - - Client.__index = Client - - function Client.Client(Name) - local self = setmetatable({}, Client) - - self.Name = Name - self.FolderInstance = nil - self.LocalFolderInstance = nil - - return self - end - - Client.new = Client.Client - - function Client.Fire(self, EventName, ...) - return Event.FireServer(self.Name .. "_" .. EventName, ...) - end - function Client.Call(self, EventName, ...) - return Event.Call(self.Name .. "_" .. EventName, ...) - end - function Client.On(self, EventName, Callback) - return Event.SetCallback( - self.Name .. "_" .. EventName, - Callback - ) - end - function Client.Folder(self) - if not self.FolderInstance then - self.FolderInstance = Remote:WaitForChild(self.Name) - end - - return self.FolderInstance - end - function Client.LocalFolder(self) - if not self.LocalFolderInstance then - self.LocalFolderInstance = - ClientFolder:WaitForChild(self.Name) - end - - return self.LocalFolderInstance - end - - local Net = {} - - Net.ServerNamespaceList = {} - Net.ClientNamespaceList = {} - - function Net.Server(Name, Definitions) - assert(_SERVER, "Net.Server can only be used on the server") - - if not Net.ServerNamespaceList[Name] then - Net.ServerNamespaceList[Name] = Server.Server(Name) - end - if Definitions then - for _, Term in ipairs(Definitions) do - Serdes.Identifier(Name .. "_" .. Term) - end - end - - return Net.ServerNamespaceList[Name] - end - function Net.Client(Name) - assert(_CLIENT, "Net.Client can only be used on the client") - - if Net.ClientNamespaceList[Name] == nil then - Net.ClientNamespaceList[Name] = Client.Client(Name) - end - - return Net.ClientNamespaceList[Name] - end - function Net.Identifier(Name) - return Serdes.Identifier(Name) - end - - Event.Listen() - - __DARKLUA_BUNDLE_MODULES.h = Net - end - do - local CollectionService = game:GetService "CollectionService" - local Spawn = __DARKLUA_BUNDLE_MODULES.b - - __DARKLUA_BUNDLE_MODULES.i = function(Tag, Start, Stop) - local InstanceMap = {} - - for _, Instance in ipairs(CollectionService:GetTagged(Tag)) do - Spawn(function() - InstanceMap[Instance] = { - Start(Instance), - } - end) - end - - local AddConnection = CollectionService - :GetInstanceAddedSignal(Tag) - :connect(function(Instance) - InstanceMap[Instance] = { - Start(Instance), - } - end) - local RemoveConnection = CollectionService - :GetInstanceRemovedSignal(Tag) - :connect(function(Instance) - local Value = InstanceMap[Instance] - - if Value then - InstanceMap[Instance] = nil - - Stop(unpack(Value)) - end - end) - - return function() - AddConnection:Disconnect() - RemoveConnection:Disconnect() - - for Instance, Value in pairs(InstanceMap) do - Spawn(Stop, unpack(Value)) - end - end - end - end - do - __DARKLUA_BUNDLE_MODULES.j = function(Limit, Interval) - assert(Limit > 0, "Limit must be greater than 0") - - local CountMap = {} - local CountKeyless = 0 - - return function(Key) - if Key then - local Count = CountMap[Key] - - if Count == nil then - Count = 0 - - Delay(Interval, function() - CountMap[Key] = nil - end) - end - if Count >= Limit then - return false - end - - CountMap[Key] = Count + 1 - else - if CountKeyless == 0 then - Delay(Interval, function() - CountKeyless = 0 - end) - end - if CountKeyless >= Limit then - return false - end - - CountKeyless = CountKeyless + 1 - end - - return true - end - end - end - do - local Promise = __DARKLUA_BUNDLE_MODULES.c - local Spawn = __DARKLUA_BUNDLE_MODULES.b - local Signal = {} - - Signal.__index = Signal - - function Signal.new() - return setmetatable({ Root = nil }, Signal) - end - function Signal.Connect(self, Callback) - local Node = { - Next = self.Root, - Callback = Callback, - } - - self.Root = Node - - return function() - if self.Root == Node then - self.Root = Node.Next - else - local Current = self.Root - - while Current do - if Current.Next == Node then - Current.Next = Node.Next - - break - end - - Current = Current.Next - end - end - end - end - function Signal.Wait(self) - return Promise.new(function(Resolve) - local Disconnect - - Disconnect = self:Connect(function(...) - Disconnect() - Resolve(...) - end) - end) - end - function Signal.Fire(self, ...) - local Current = self.Root - - while Current do - Spawn(Current.Callback, ...) - - Current = Current.Next - end - end - function Signal.DisconnectAll(self) - self.Root = nil - end - - __DARKLUA_BUNDLE_MODULES.k = Signal - end - do - __DARKLUA_BUNDLE_MODULES.l = function(value) - local basicType = type(value) - - if - basicType == "nil" - or basicType == "boolean" - or basicType == "number" - or basicType == "string" - or basicType == "function" - or basicType == "thread" - or basicType == "table" - then - return basicType - end - - local tests = { - { - "Instance", - { - "ClassName", - }, - }, - { - "EnumItem", - { - "EnumType", - "Name", - "Value", - }, - }, - { - "Enum", - { - "GetEnumItems", - }, - }, - { - "Enums", - { - "MembershipType", - }, - }, - { - "RBXScriptSignal", - { - "connect", - "wait", - }, - }, - { - "RBXScriptConnection", - { - "connected", - "disconnect", - }, - }, - { - "TweenInfo", - { - "EasingDirection", - "RepeatCount", - "EasingStyle", - }, - }, - { - "CFrame", - { - "p", - "x", - "y", - "z", - "lookVector", - }, - }, - { - "Vector3", - { - "Lerp", - "unit", - "magnitude", - "x", - "y", - "z", - }, - }, - { - "Vector3int16", - { - "z", - "x", - "y", - }, - }, - { - "Vector2", - { - "unit", - "magnitude", - "x", - "y", - }, - }, - { - "Vector2int16", - { - "x", - "y", - }, - }, - { - "Region3", - { - "CFrame", - "Size", - }, - }, - { - "Region3int16", - { - "Min", - "Max", - }, - }, - { - "Ray", - { - "Origin", - "Direction", - "Unit", - "ClosestPoint", - "Distance", - }, - }, - { - "UDim", - { - "Scale", - "Offset", - }, - }, - { - "Axes", - { - "Z", - "X", - "Y", - }, - }, - { - "UDim2", - { - "X", - "Y", - }, - }, - { - "BrickColor", - { - "Number", - "Name", - "Color", - "r", - "g", - "b", - }, - }, - { - "Color3", - { - "r", - "g", - "b", - }, - }, - { - "Faces", - { - "Right", - "Top", - "Back", - }, - }, - } - - for _, v in ipairs(tests) do - local t, test = v[1], v[2] - local ok, result = pcall(function() - for _, prop in ipairs(test) do - if value[prop] == nil then - return false - end - end - - return true - end) - - if ok and result then - return t - end - end - end - end - do - local Spawn = __DARKLUA_BUNDLE_MODULES.b - local typeof = __DARKLUA_BUNDLE_MODULES.l - - __DARKLUA_BUNDLE_MODULES.m = function() - local Bin = {} - - return function(Item) - table.insert(Bin, Item) - end, function() - for _, Item in ipairs(Bin) do - if typeof(Item) == "Instance" then - Item:Destroy() - elseif typeof(Item) == "RBXScriptConnection" then - Item:disconnect() - elseif typeof(Item) == "function" then - Spawn(Item) - end - end - for i, _ in ipairs(Bin) do - Bin[i] = nil - end - end - end - end - - local Net = __DARKLUA_BUNDLE_MODULES.h - - return { - Server = Net.Server, - Client = Net.Client, - Collection = __DARKLUA_BUNDLE_MODULES.i, - Ratelimit = __DARKLUA_BUNDLE_MODULES.j, - Promise = __DARKLUA_BUNDLE_MODULES.c, - Signal = __DARKLUA_BUNDLE_MODULES.k, - Clock = __DARKLUA_BUNDLE_MODULES.e, - Spawn = __DARKLUA_BUNDLE_MODULES.b, - Bin = __DARKLUA_BUNDLE_MODULES.m, - } - end) - - if not success then - error(result) - end - - return result -end - -return { - Help = function() - return "See https://redblox.dev/ for more information." - end, - Load = Red, -}