Gear Utility
UPDATE:
This plugin has been fixed. I have added checks to ignore Roblox tablets; otherwise, your account could be terminated for “fake login screens”.
Features:
- Gear Importer
- Gear Fixer
This plugin is designed to import most gears from the ROBLOX Catalog and fix them. Since ROBLOX removed the LoadLibrary feature, most gears are now broken. However, this plugin will automatically fix them for you.
To use this plugin, simply install it, open your place, and click on “Load Gears.” The gears will then be loaded with the necessary fixes applied. Alternatively, if you already have a gear, you can select it and click on “Fix Object.” You can also select folders, and the plugin will fix everything inside the folder.
I’ve spent a considerable amount of time coding a Python script to grab the gears and create an auto-fixer, so crediting would be greatly appreciated! <3
Visit the Gear Utility plugin on ROBLOX
[Demo video on YouTube]
(Gear Utility Demo - YouTube)
Here’s the source code:
local ChangeHistoryService = game:GetService("ChangeHistoryService")
local Selection = game:GetService("Selection")
local HttpService = game:GetService("HttpService")
local ServerStorage = game:GetService("ServerStorage")
local InsertService = game:GetService("InsertService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local JointsService = game:GetService("JointsService")
local Toolbar = plugin:CreateToolbar("Gears Utility")
local LoadGearsButton = Toolbar:CreateButton("Load Gears", "Load gears on Roblox", "rbxassetid://5711524831")
local FixObjectButton = Toolbar:CreateButton("Fix Object", "Fix object and its childrens", "rbxassetid://6172144323")
local UpdateModulePackagesButton =
Toolbar:CreateButton("Update Packages", "Update gear module packages", "rbxassetid://6022668955")
local ModuleStart = 'game:GetService("ReplicatedStorage"):WaitForChild("GearModulesFolder"):WaitForChild("'
local ModuleEnd = '")'
local LoadLibraryFunction = "local function LoadLibrary(Library)"
local TreeTab = " "
local function GetModule(Module)
return ModuleStart .. Module .. ModuleEnd
end
local LoadLibraryRequire = "require(" .. GetModule("LoadLibrary") .. ")(Library)"
local ReplaceList = {
[754568173] = GetModule("SwordModule"), --Sword Module
[172349822] = GetModule("GearModule"), --Gear Module
[191816425] = GetModule("MultiPurposeModule"), --Multi Purpose Module
[201433042] = GetModule("ScaleCharacterModule"), --Scale Character Module
[1075123174] = GetModule("GearService"), --GearService
[199238756] = GetModule("SkateboardModule"), --Skateboard Module
[836581200] = GetModule("PackageMaker"), --Package Maker
[180464321] = GetModule("HalloweenMonsterCustomesLibrary"), --Halloween Monster Costumes Library
[185791213] = GetModule("GuitarModule"), --Guitar Module
["NPCModule = require%(game%.ServerScriptService%.MainModule%)"] = "NPCModule = require(" .. GetModule(
"MultiPurposeModule"
) .. ")",
}
function IsCodeHolder(Object)
return Object:IsA("Script") or Object:IsA("LocalScript") or Object:IsA("ModuleScript")
end
function CreateTestScript()
local Success, Error = pcall(function()
local NewScript = Instance.new("Script")
NewScript.Name = "GearUtility_TestScript"
NewScript.Parent = JointsService
end)
return Success
end
function EditTestScript(Script)
return pcall(function()
Script.Source = 'print("Works!")'
end)
end
function CheckCodeHolderPermission()
local Success = CreateTestScript()
if not Success then
print("Please allow plugin access to create scripts")
repeat
task.wait(1)
until CreateTestScript() == true
end
Success = EditTestScript(JointsService:WaitForChild("GearUtility_TestScript"))
if not Success then
print("Please allow plugin access to edit scripts")
repeat
task.wait(1)
until EditTestScript(JointsService:WaitForChild("GearUtility_TestScript")) == true
end
for Index, Object in pairs(JointsService:GetChildren()) do
if Object:IsA("Script") and Object.Name == "GearUtility_TestScript" then
Object:Destroy()
end
end
end
function FixCodeHolder(CodeHolder)
CheckCodeHolderPermission()
local NeedModules = false
local CodeHodlerFixed = false
if CodeHolder.Source:find("LoadLibrary") then
NeedModules = true
if not CodeHolder.Source:find(LoadLibraryFunction, 1, true) then
local LoadLibraryCode = LoadLibraryFunction .. "\n"
LoadLibraryCode ..= " return " .. LoadLibraryRequire .. "\n"
LoadLibraryCode ..= "end"
CodeHolder.Source = LoadLibraryCode .. "\n\n" .. CodeHolder.Source
CodeHodlerFixed = true
end
end
for Key, Value in pairs(ReplaceList) do
if CodeHolder.Source:find(Key) then
NeedModules = true
CodeHolder.Source = CodeHolder.Source:gsub(Key, Value)
CodeHodlerFixed = true
end
end
if CodeHolder.Name == "BackpackMonitor" and not CodeHolder.Disabled then
CodeHolder.Disabled = true
CodeHodlerFixed = true
end
return NeedModules, CodeHodlerFixed, CodeHolder.ClassName
end
function Fix(Object)
CheckCodeHolderPermission()
local FixedCodeHolder = {
Script = 0,
LocalScript = 0,
ModuleScript = 0,
}
print("Fixing " .. Object:GetFullName())
local Time = os.time()
local TotalFixed = 0
local CreateModule = false
if IsCodeHolder(Object) then
local NeedModules, CodeHodlerFixed, CodeHolderType = FixCodeHolder(Object)
if NeedModules then
CreateModule = true
end
if CodeHodlerFixed then
FixedCodeHolder[CodeHolderType] += 1
TotalFixed += 1
end
end
for Index, Object in pairs(Object:GetDescendants()) do
if IsCodeHolder(Object) then
local NeedModules, CodeHodlerFixed, CodeHolderType = FixCodeHolder(Object)
if NeedModules then
CreateModule = true
end
if CodeHodlerFixed then
FixedCodeHolder[CodeHolderType] += 1
TotalFixed += 1
end
end
end
print(
"Fixed "
.. Object:GetFullName()
.. " and its descendants\n"
.. TreeTab
.. "-Time Taken: "
.. tostring(os.time() - Time)
.. " seconds\n"
.. TreeTab
.. "-Scripts Fixed: "
.. tostring(FixedCodeHolder.Script)
.. " Scripts\n"
.. TreeTab
.. "-LocalScripts Fixed: "
.. tostring(FixedCodeHolder.LocalScript)
.. " LocalScripts\n"
.. TreeTab
.. "-ModuleScripts Fixed: "
.. tostring(FixedCodeHolder.ModuleScript)
.. " ModuleScripts\n"
.. TreeTab
.. "-Total Fixed: "
.. tostring(TotalFixed)
.. " Scripts/LocalScripts/ModuleScripts"
)
ChangeHistoryService:SetWaypoint("Fixed " .. Object:GetFullName() .. " and its descendants")
Selection:Set({
Object,
})
return CreateModule
end
function UpdateModulePackage()
CheckCodeHolderPermission()
print("Updating Gear Module Packages")
local Time = os.time()
local GearModulesFolder = ReplicatedStorage:FindFirstChild("GearModulesFolder")
if GearModulesFolder then
GearModulesFolder:Destroy()
end
GearModulesFolder = Instance.new("Folder")
GearModulesFolder.Name = "GearModulesFolder"
GearModulesFolder.Parent = ReplicatedStorage
require(9507732691)(GearModulesFolder)
repeat
task.wait()
until GearModulesFolder:GetAttribute("Loaded") == true
Fix(GearModulesFolder)
print("Gear Module Packages Updated\n" .. TreeTab .. "-Time Taken: " .. tostring(os.time() - Time) .. " seconds")
end
LoadGearsButton.ClickableWhenViewportHidden = true
FixObjectButton.ClickableWhenViewportHidden = true
UpdateModulePackagesButton.ClickableWhenViewportHidden = true
LoadGearsButton.Click:Connect(function()
print("Initiallizing")
local GearsFolder = ServerStorage:FindFirstChild("GearsFolder")
if GearsFolder then
GearsFolder:Destroy()
end
GearsFolder = Instance.new("Folder")
GearsFolder.Name = "GearsFolder"
GearsFolder.Parent = ServerStorage
Selection:Set({
GearsFolder,
})
print("Fetching Gears List")
local Gears = HttpService:JSONDecode(
HttpService:GetAsync("https://raw.githubusercontent.com/iUnstable0/Roblox/main/Gears-Detailed.json")
)
print(
"Got Gears List\n"
.. TreeTab
.. "-Total Gears: "
.. tostring(#Gears.data)
.. "\n"
.. TreeTab
.. "-Last Updated: "
.. Gears["last-updated"]
)
local Loaded = 0
local FixedCodeHolder = {
Script = 0,
LocalScript = 0,
ModuleScript = 0,
}
local TotalFixed = 0
print("Loading " .. tostring(#Gears.data) .. " Gears in " .. GearsFolder:GetFullName())
CheckCodeHolderPermission()
local Time = os.time()
for Index, Gear in pairs(Gears.data) do
coroutine.wrap(function()
-- Safety check, https://devforum.roblox.com/t/open-source-gear-utility/1776131/34?u=iunstable0
if string.find(Gear.name, "ROBLOX Tablet") then
return
end
local Success, InsertedGear = pcall(function()
return InsertService:LoadAsset(Gear.id)
end)
if not Success then
Loaded += 1
print(
"Failed to load "
.. tostring(Loaded)
.. "/"
.. tostring(#Gears.data)
.. " Gears\n"
.. TreeTab
.. "-Gear Name: "
.. Gear.name
.. "\n"
.. TreeTab
.. "-Gear Id: "
.. tostring(Gear.id)
)
return
end
for Index, Object in pairs(InsertedGear:GetChildren()) do
if Object:IsA("Tool") then
Object:SetAttribute("GEARDATA_id", Gear.id)
Object:SetAttribute("GEARDATA_name", Gear.name)
Object.Parent = GearsFolder
end
end
InsertedGear:Destroy()
Loaded += 1
print(
"Loaded "
.. tostring(Loaded)
.. "/"
.. tostring(#Gears.data)
.. " Gears\n"
.. TreeTab
.. "-Gear Name: "
.. Gear.name
.. "\n"
.. TreeTab
.. "-Gear Id: "
.. tostring(Gear.id)
)
end)()
end
repeat
task.wait()
until Loaded >= #Gears.data
print(
"Loaded "
.. tostring(#Gears.data)
.. " Gears in "
.. GearsFolder:GetFullName()
.. "\n"
.. TreeTab
.. "-Time Taken: "
.. tostring(os.time() - Time)
.. " seconds"
)
ChangeHistoryService:SetWaypoint("Loaded " .. tostring(#Gears.data) .. " Gears in " .. GearsFolder:GetFullName())
if Fix(GearsFolder) then
UpdateModulePackage()
end
end)
FixObjectButton.Click:Connect(function()
local SelectedObject = Selection:Get()
if #SelectedObject == 0 then
error("Please an object to fix")
elseif #SelectedObject > 1 then
error("Please select only one object")
elseif SelectedObject[1].Name == "GearUtilityPlugin" then
error("You cannot fix this script")
end
if Fix(SelectedObject[1]) then
UpdateModulePackage()
end
end)
UpdateModulePackagesButton.Click:Connect(function()
UpdateModulePackage()
end)