[Open Source] Gear Utility

Gear Utility

Features:

  • Gear Importer
  • Gear Fixer

This library will import most gears on ROBLOX Catalog and fix it
Since roblox removed LoadLibrary most Gears are broken so this plugin will fix it automatically

Just install this plugin, open your place, and click on Load Gears then it will load the gears with the fixes
Or IF you already have a gear you can just select it and click ‘Fix Object’ (you can also select folders and it will fix everything inside the folder)

I spent time coding Python script to grab the gears and auto fixer so crediting would be nice <3

this is 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()
			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)

I’m not really good at coding so please tell me if there’s anything to improve or bad practices

Screen Shot 2022-05-01 at 11.25.27 AM

16 Likes

Sorry I forgot to put the plugin on sale, u should be able to install it now

1 Like

I fixed the plugin not showing in studio Plugins tab
please update it

1 Like

this is something genius but has to be improved as this isn’t a temporary fix for most of the gears 'cause of the fact that it replacec a few lines of code, I think there should be an auto-fix mechanism for non-filtering gears.

wdym non-filtering gear? or did u mean gears that still use insertservice on the client side or non FE gears

Can you include a video of the plugin?

1 Like

Sure but why do you need the video though?
I can record a video later I’m busy right now

I would like a video of the plugin so I know what it does and if its worth installing.

1 Like

It works perfectly! I will definitely use it in my game!

1 Like

thank you! :smiley: If you find any broken gears please tell me so I can fix it and update the plugin

Added new script permission check so the plugin wont start until it is granted script injection permission

Video: Gear Utility Demo - YouTube

3 Likes

he means non fe gears is that possible?

@iUnstable0 there’s at least several hundred that need to be fixed because of Filtering Enabled turned on however I wouldn’t recommend fixing the insert tool and stamp tool because of well you know

it is possible but requires a lot of work

How could a fe detecter work at all? that’s sound almost impossible

hey one little improvement you can make is where it changes connect to Connect because a lot of gears have connect instead of Connect

That wont make any differences and instead it could cause problems

how could it cause problems also connect is deprecated

1 Like

This plugin is amazing! I am working on a project that requires the use of ROBLOX’s gears and this helped a ton. I also love that you added in the name and Id of the gear as attributes in its respective tool.

Kudos to you

2 Likes

glad that it helped your project! :slight_smile: