diff --git a/main.lua b/main.lua index 9fa6385..6d401b6 100644 --- a/main.lua +++ b/main.lua @@ -1,6 +1,71 @@ -local Players = game:GetService("Players") -local LocalPlayer = Players.LocalPlayer -local Event = LocalPlayer.Character:FindFirstChild("ServerEndpoint", true) or LocalPlayer:FindFirstChild("ServerEndpoint", true) +local HttpService = game:GetService("HttpService") +local LocalPlayer = game:GetService("Players").LocalPlayer +local Event = { + InvokeServer = function(_, ...) + local Remote + repeat + Remote = LocalPlayer.Character:FindFirstChild("ServerEndpoint", true) or LocalPlayer:FindFirstChild("ServerEndpoint", true) + if not Remote then + task.wait(0.1) + end + until Remote + return Remote:InvokeServer(...) + end +} + +local api +local getproperties = getproperties or function(Object) -- Fallback to custom `getproperties` + -- Fetch API + if not api then + local success + repeat + success,api = pcall(game.HttpGet, game, "http://github.com/MaximumADHD/Roblox-Client-Tracker/raw/roblox/Full-API-Dump.json") + if success and api then + -- Check if parsable via JSON + success,api = pcall(HttpService.JSONDecode, HttpService, api) + if success and api then + -- Validate structure + xpcall(function() + assert(type(api.Classes[1]) == "table") + end, function() + success = false + task.wait() + end) + else + success = false + task.wait() + end + else + task.wait() + end + until success and api + end + -- Main part + local properties = {} + for _,class in next,api.Classes do + -- Find class structure + if class.Name == Object.ClassName then + for __,member in next,class.Members do + for ___=1,1 do + -- Validate member info + if member.MemberType ~= "Property" then break end + if member.Security.Read ~= "None" then break end + if member.Security.Write ~= "None" then break end + if member.Tags then + if table.find(member.Tags, "ReadOnly") then break end + if table.find(member.Tags, "NotScriptable") then break end + end + properties[member.Name] = Object[member.Name] + end + end + end + end + return { -- Fallback + Name = Object.Name, + Parent = Object.Parent, + Archivable = Object.Archivable + } +end local ClassNames = { Part = "Normal", @@ -65,32 +130,32 @@ function F3X.Object(Object) end function F3X.Edit(Object, Properties) - spawn(function() + task.spawn(function() if Object:IsA("BasePart") then - for Property, Value in pairs(Properties) do - if Edit[Property] then - Property, Value = Edit[Property](Value) - end + for Property, Value in pairs(Properties) do + task.spawn(function() + if Edit[Property] then + Property, Value = Edit[Property](Value) + end - local Sync = SyncProperties[Property] + local Sync = SyncProperties[Property] - if Sync == "SyncSurface" then - Event:InvokeServer(Sync, {{Part = Object, Surfaces = {[Property] = Value}}}) - elseif Sync == "SetName" or Sync == "SetParent" then - Event:InvokeServer(Sync, {Object}, Value) - elseif Sync == "SyncShape" then - F3X.Object(Object):AddMesh().MeshType = tostring(Value) == "Ball" and "Sphere" or Value - elseif Sync == "SyncTexture" then - if Object.ClassName == "Decal" then - Event:InvokeServer(Sync, {{Part = Object, TextureType = "Decal", [Property] = Value}}) - elseif Object.ClassName == "Texture" then - Event:InvokeServer(Sync, {{Part = Object, TextureType = "Texture", [Property] = Value}}) - end - else - pcall(function() + if Sync == "SyncSurface" then + Event:InvokeServer(Sync, {{Part = Object, Surfaces = {[Property] = Value}}}) + elseif Sync == "SetName" or Sync == "SetParent" then + Event:InvokeServer(Sync, {Object}, Value) + elseif Sync == "SyncShape" then + F3X.Object(Object):AddMesh().MeshType = tostring(Value) == "Ball" and "Sphere" or Value + elseif Sync == "SyncTexture" then + if Object.ClassName == "Decal" then + Event:InvokeServer(Sync, {{Part = Object, TextureType = "Decal", [Property] = Value}}) + elseif Object.ClassName == "Texture" then + Event:InvokeServer(Sync, {{Part = Object, TextureType = "Texture", [Property] = Value}}) + end + else Event:InvokeServer(Sync, {{Part = Object, [Property] = Value}}) - end) - end + end + end) end else Properties.Part = Object.Parent @@ -109,6 +174,10 @@ function F3X.Edit(Object, Properties) end end end) -end +end + +F3X.getproperties = getproperties -- Miscellaneous + +task.spawn(pcall, getproperties, game) -- Preload API return F3X