FPSLibrary

 avatar
CITY512
lua
15 days ago
36 kB
3
Indexable
Never
local cloneref = cloneref or function(o) return o end
-- Services
local CoreGui = cloneref(game:GetService("CoreGui"))
local StarterGui = cloneref(game:GetService("StarterGui"))
local RunService = cloneref(game:GetService("RunService"))
local HttpService = cloneref(game:GetService("HttpService"))
local TweenService = cloneref(game:GetService("TweenService"))
local Players = cloneref(game:GetService("Players"))
-- Variables
repeat task.wait() until Players.LocalPlayer
local LocalPlayer = Players.LocalPlayer
local mouse = LocalPlayer:GetMouse()
local connections = {}
local a = 0
local Notifications = {}
local FPSLibrary = {
    Flags = {};
}
-- Configuration File
local FPSLibraryFolder = "FPSLibrary"
local ConfigurationFolderName = FPSLibraryFolder.."/Configurations"
local KeyFolderName = FPSLibraryFolder.."/Keys"
local LocalConfigurationFolderName = nil
-- Library Interface
local FPSLibraryAssets = game:GetObjects("rbxassetid://134829575873543")[1]
if typeof(FPSLibraryAssets) == "string" then
    warn("FPSLibrary: Failed To Get Library Package: "..FPSLibraryAssets)
    return
end
local Interface = FPSLibraryAssets:WaitForChild("Interface"):Clone()
Interface.Parent = CoreGui
-- Tweens
local Reposition = TweenInfo.new(0.75,Enum.EasingStyle.Sine,Enum.EasingDirection.Out,0,false,0)
local TweenIn32 = TweenInfo.new(0.32,Enum.EasingStyle.Sine,Enum.EasingDirection.In,0,false,0)
local TweenIn75 = TweenInfo.new(0.75,Enum.EasingStyle.Sine,Enum.EasingDirection.In,0,false,0)
local TweenOut32 = TweenInfo.new(0.32,Enum.EasingStyle.Sine,Enum.EasingDirection.Out,0,false,0)
local TweenOut75 = TweenInfo.new(0.75,Enum.EasingStyle.Sine,Enum.EasingDirection.Out,0,false,0)
-- Functions
function RippleEffects(button)
    local ripplecontainer = button:WaitForChild("RippleContainerFrame")
	local function tweenInRipple(rippleeffect)
		spawn(function()
			local Info = TweenInfo.new(0.9,Enum.EasingStyle.Linear,Enum.EasingDirection.InOut,0,false,0)
			local Goals = {Size = UDim2.new(0, 200, 0, 200)}
			local Tween = TweenService:Create(rippleeffect, Info, Goals)
			Tween:Play()
		end)
	end

	local function fadeOutRipple(rippleeffect)
		spawn(function()
			local Info = TweenInfo.new(0.6,Enum.EasingStyle.Linear,Enum.EasingDirection.InOut,0,false,0)
			local goal = {ImageTransparency = 1}
			local Tween = TweenService:Create(rippleeffect, Info, goal)
			Tween:Play()
			task.wait(1)
			rippleeffect:Destroy()
		end)
	end
	button.MouseButton1Down:Connect(function()
		a += 1
		local b = a
		local done = false
		local rippleeffect = Instance.new("ImageLabel", ripplecontainer)
		rippleeffect.Name = "RippleEffect"
		rippleeffect.Position = UDim2.new(0,mouse.X - button.AbsolutePosition.X,0,mouse.Y - button.AbsolutePosition.Y)
		rippleeffect.ZIndex = ripplecontainer.ZIndex + 1
		rippleeffect.AnchorPoint = Vector2.new(0.5, 0.5)
		rippleeffect.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
		rippleeffect.BackgroundTransparency = 1
		rippleeffect.Image = "rbxassetid://266543268"
		rippleeffect.ImageColor3 = Color3.fromRGB(0, 0, 0)
		rippleeffect.ImageTransparency = 0.8
		tweenInRipple(rippleeffect)
		connections[b] = button.MouseButton1Up:Connect(function()
			if not done then
				done = true
				fadeOutRipple(rippleeffect)
			end
		end)
		task.wait(4)
		connections[b]:Disconnect()
		done = true
		fadeOutRipple(rippleeffect)
	end)
end
function FPSLibraryErrorMessage(err,errormessage)
    FPSLibrary:Notify({
        Type = "id0x1";
        Message = errormessage;
        Duration = 3;
        Actions = {
            ViewConsole = {
                Name = "View Console";
                Callback = function()
                    keypress(0x78)
                    keyrelease(0x78)
                end
            };
        }
    })
    warn("FPSLibrary: "..err)
end
function GenerateRandomString()
    local str = ""
    for _ = 1,20,1 do
        local char
        local chartype = math.random(1,3)
        if chartype == 1 then
            char = string.char(math.random(48,57))
        elseif chartype == 2 then
            char = string.char(math.random(65,90))
        elseif chartype == 3 then
            char = string.char(math.random(97,122))
        end
        str = str..char
    end
    return str
end
function UpdateNotificationLayout()
    for i, v in ipairs(Notifications) do
		local tween = TweenService:Create(v,Reposition,{Position = UDim2.new(1,-220,1,(i*-75)-20)})
		tween:Play()
	end
end
-- Module Functions
function FPSLibrary:Notify(settings)
    task.spawn(function()
        local Spawn = tick()
        settings.Title = settings.Type == "id0x1" and "Error" or settings.Type == "id0x2" and "Info" or settings.Type == "id0x3" and "Success" or settings.Title or "Info";
        settings.Message = settings.Message or "Notification Request"
        settings.Button1 = settings.Button1 ~= "" and settings.Button1 or nil
        settings.Button2 = settings.Button2 ~= "" and settings.Button2 or nil
        settings.Icon = settings.Type == "id0x1" and "rbxassetid://102649569795605" or settings.Type == "id0x2" and "rbxassetid://76316461447556" or settings.Type == "id0x3" and "rbxassetid://111469034555385" or settings.Icon or "rbxassetid://0"
        settings.Duration = settings.Duration or 5
        local NotificationExample = FPSLibraryAssets:WaitForChild("NotificationExample"):Clone()
        NotificationExample.Parent = Interface
        local Container = NotificationExample:WaitForChild("Container")
        local Title = Container:WaitForChild("Title")
        local Message = Container:WaitForChild("Message")
        local ImageIcon = Container:WaitForChild("NotificationImage")
        local ActionButtonsContainer = Container:WaitForChild("ActionButtons"):WaitForChild("Container")
        local DurationTimer = Container:WaitForChild("SliderFrame"):WaitForChild("Slider"):WaitForChild("Frame")
        Title.Text = settings.Title
        Message.Text = settings.Message
        ImageIcon.Image = settings.Icon
        local closing = false
        a += 1
        local b = a
        connections[b] = RunService.RenderStepped:Connect(function()
            DurationTimer.Size = UDim2.new(1 - (tick() - Spawn) / settings.Duration,0,1,0)
        end)
        local function CloseNotification()
            task.spawn(function()
                if not closing then
                    closing = true
                    table.remove(Notifications,table.find(Notifications,NotificationExample))
                    UpdateNotificationLayout()
                    TweenService:Create(NotificationExample,TweenIn75,{Position = UDim2.new(1,0,1,NotificationExample.Position.Y.Offset)}):Play()
                    task.wait(0.75)
                    NotificationExample:Destroy()
                    if connections[b] then
                        connections[b]:Disconnect()
                    end
                end
            end)
        end
        if settings.Actions then
            for _, actionsettings in settings.Actions do
                local Button = FPSLibraryAssets:WaitForChild("Button"):Clone()
                Button.Parent = ActionButtonsContainer
                local ButtonNameLabel = Button:WaitForChild("NameTextLabel")
                ButtonNameLabel.Text = actionsettings.Name
                RippleEffects(Button)
                Button.MouseButton1Click:Connect(function()
                    if not closing then
                        if actionsettings.CloseOnClick then
                            CloseNotification()
                        end
                        if actionsettings.Callback then
                            local suc, err = pcall(actionsettings.Callback)
                            if not suc then
                                FPSLibraryErrorMessage(err,"Callback Error!")
                            end
                        end
                    end
                end)
            end
        end
        if settings.Type then
            local sound = Instance.new("Sound", workspace)
            sound.SoundId = settings.Type == "id0x1" and "rbxassetid://2865228021" or settings.Type == "id0x2" and "rbxassetid://3398620867" or settings.Type == "id0x3" and "rbxassetid://3450794184"
            sound.PlayOnRemove = true
            sound:Destroy()
        end
        TweenService:Create(NotificationExample,TweenOut75,{Position = UDim2.new(1,-220,1,95)}):Play()
        table.insert(Notifications,1,NotificationExample)
        UpdateNotificationLayout()
        task.delay(settings.Duration,CloseNotification)
    end)
end
function FPSLibrary:SaveConfiguration(filename)
    if not filename or not LocalConfigurationFolderName then return end
end
function FPSLibrary:LoadConfiguration(filename)
    if not filename or not LocalConfigurationFolderName then return end
end
function FPSLibrary:ListConfigurationFiles()
    if LocalConfigurationFolderName and isfolder(ConfigurationFolderName) and isfolder(ConfigurationFolderName.."/"..LocalConfigurationFolderName) then
        return listfiles(ConfigurationFolderName.."/"..LocalConfigurationFolderName)
    end
    return {}
end
function FPSLibrary:BootWindow(windowsettings)
    local Window = {}
    if windowsettings.KeySystem and windowsettings.KeySystem.Enabled then
        local keyverified = false
        local KeySystemGUI = FPSLibraryAssets:WaitForChild("KeySystem"):Clone()
        KeySystemGUI.Parent = Interface
        local TextBox = KeySystemGUI:WaitForChild("TextBox")
        local CheckKeyButton = FPSLibraryAssets:WaitForChild("Button"):Clone()
        local CheckKeyName = CheckKeyButton:WaitForChild("NameTextLabel")
        CheckKeyButton.Parent = KeySystemGUI
        CheckKeyButton.AnchorPoint = Vector2.new(0.5, 0.5)
        CheckKeyButton.Position = UDim2.new(0.5, 0, 0.5, 27)
        CheckKeyButton.Size = UDim2.new(0, 75, 0, 20)
        CheckKeyName.Text = "Authenticate"
        if windowsettings.KeySystem.GrabKeyFromSite and windowsettings.KeySystem.WebsiteURL then
            local GetKeyButton = FPSLibraryAssets:WaitForChild("Button"):Clone()
            local GetKeyName = GetKeyButton:WaitForChild("NameTextLabel")
            local GetKeyButtonOutline = GetKeyButton:WaitForChild("OutlineFrame")
            GetKeyButton.Parent = KeySystemGUI
            GetKeyButton.BackgroundColor3 = Color3.fromRGB(149, 119, 54)
            GetKeyButton.AnchorPoint = Vector2.new(0.5, 0.5)
            GetKeyButton.Position = UDim2.new(0.5, 0, 0.5, 51)
            GetKeyButton.Size = UDim2.new(0, 75, 0, 20)
            GetKeyButton.BackgroundColor3 = Color3.fromRGB(149, 119, 54)
            GetKeyButtonOutline.BackgroundColor3 = Color3.fromRGB(83, 66, 30)
            GetKeyName.Text = "Get Key"
            RippleEffects(GetKeyButton)
            GetKeyButton.MouseButton1Click:Connect(function()
                if setclipboard then
                    setclipboard(windowsettings.KeySystem.WebsiteURL)
                    FPSLibrary:Notify({
                        Type = "id0x3";
                        Message = "Link copied to clipboard!";
                        Duration = 3;
                    })
                else
                    FPSLibrary:Notify({
                        Type = "id0x2";
                        Message = 'URL: "'..windowsettings.KeySystem.WebsiteURL..'"';
                        Duration = 60;
                        Actions = {
                            Close = {
                                Name = "Close";
                                CloseOnClick = true;
                                Callback = function()
                                end
                            }
                        }
                    })
                end
            end)
        end
        local function VerifyKey(key)
            if windowsettings.KeySystem.GrabKeyFromSite then
                FPSLibrary:Notify({
                    Type = "id0x2";
                    Message = "Checking Key...";
                    Duration = 3;
                })
            end
            local suc, result = pcall(function()
                return windowsettings.KeySystem.GrabKeyFromSite and (windowsettings.KeySystem.JSONDecode and HttpService:JSONDecode(game:HttpGet(windowsettings.KeySystem.KeyRAWURL)) or {game:HttpGet(windowsettings.KeySystem.KeyRAWURL)}) or windowsettings.KeySystem.Keys
            end)
            if suc then
                for _, v in result do
                    if v == key then
                        return true
                    end
                end
            else
                FPSLibraryErrorMessage(result,"An unexpected error has occured while verifying key.")
            end
            return false
        end
        RippleEffects(CheckKeyButton)
        CheckKeyButton.MouseButton1Click:Connect(function()
            local verified = VerifyKey(TextBox.Text)
            if verified then
                keyverified = true
            end
            if not keyverified then
                FPSLibrary:Notify({
                    Type = "id0x1";
                    Message = "Invalid Key!";
                    Duration = 3;
                })
            else
                FPSLibrary:Notify({
                    Type = "id0x3";
                    Message = "Correct Key!";
                    Duration = 3;
                })
                if windowsettings.KeySystem.RememberKey then
                    local contents = {
                        Key = TextBox.Text;
                        Spawn = tick()
                    }
                    if windowsettings.KeySystem.FileName then
                        writefile(KeyFolderName.."/"..windowsettings.KeySystem.FileName,HttpService:JSONEncode(contents))
                    end
                end
            end
        end)
        if windowsettings.KeySystem.RememberKey and windowsettings.KeySystem.FileName and isfile(KeyFolderName.."/"..windowsettings.KeySystem.FileName) then
            local suc, err = pcall(function()
                local contents = HttpService:JSONDecode(readfile(KeyFolderName.."/"..windowsettings.KeySystem.FileName))
                if contents.Key then
                    if contents.Spawn + windowsettings.KeySystem.KeyTimeLimit > tick() then
                        local verified = VerifyKey(contents.Key)
                        if verified then
                            keyverified = true
                            FPSLibrary:Notify({
                                Type = "id0x3";
                                Message = "Correct Key!";
                                Duration = 3;
                            })
                        else
                            FPSLibrary:Notify({
                                Type = "id0x1";
                                Message = "Key not authenticated. Try again.";
                                Duration = 3;
                            })
                        end
                    else
                        FPSLibrary:Notify({
                            Type = "id0x2";
                            Message = "Time limit has been reached. Please re-enter key again.";
                            Duration = 3;
                        })
                    end
                end
            end)
            if not suc then
                FPSLibraryErrorMessage(err,"An unexpected error has occured while verifying key.")
            end
        end
        repeat task.wait() until keyverified
        KeySystemGUI:Destroy()
    end
    task.spawn(function()
        local BootAnimation = FPSLibraryAssets:WaitForChild("LibraryBootAnimation"):Clone()
        BootAnimation.Parent = Interface
        local Line1 = BootAnimation:WaitForChild("Line1")
        local Line2 = BootAnimation:WaitForChild("Line2")
        local TitleName = BootAnimation:WaitForChild("TitleName")
        TitleName.Text = windowsettings.LoadingTitle
        TweenService:Create(Line1,TweenOut75,{Position = UDim2.new(0.5,TitleName.TextBounds.X/2 + 8,0,0)}):Play()
        TweenService:Create(Line2,TweenOut75,{Position = UDim2.new(0.5,-TitleName.TextBounds.X/2 - 8,0,0)}):Play()
        TweenService:Create(TitleName,TweenOut75,{Size = UDim2.new(0,TitleName.TextBounds.X + 8,1,0)}):Play()
        task.wait(1.25)
        TweenService:Create(Line1,TweenIn75,{Position = UDim2.new(0.5,0,0,0)}):Play()
        TweenService:Create(Line2,TweenIn75,{Position = UDim2.new(0.5,0,0,0)}):Play()
        TweenService:Create(TitleName,TweenIn75,{Size = UDim2.new(0,0,1,0)}):Play()
        task.wait(0.75)
        BootAnimation:Destroy()
    end)
    local suc, err = pcall(function()
        if windowsettings.ConfigurationSaving and windowsettings.ConfigurationSaving.Enabled and windowsettings.ConfigurationSaving.FolderName then
            local FolderName = windowsettings.ConfigurationSaving.FolderName
            if windowsettings.ConfigurationSaving.PlaceId then
                FolderName = windowsettings.ConfigurationSaving.FolderName.." "..tostring(game.PlaceId)
            end
            if not isfolder(ConfigurationFolderName.."/"..FolderName) then
                makefolder(ConfigurationFolderName.."/"..FolderName)
            end
            LocalConfigurationFolderName = FolderName
        end
    end)
    if not suc then
        FPSLibraryErrorMessage(err,"An unexpected error has occured while loading Configurations.")
    end
    function Window:CreateTab(tabsettings)
        -- Tab Setttings
        tabsettings.Title = tabsettings.Title ~= nil and tabsettings.Title or "Title"
        tabsettings.Subtitle = tabsettings.Subtitle ~= nil and tabsettings.Subtitle or "Subtitle"
        tabsettings.TitleRichText = tabsettings.TitleRichText ~= nil and tabsettings.TitleRichText or false
        tabsettings.SubtitleRichText = tabsettings.SubtitleRichText ~= nil and tabsettings.SubtitleRichText or false
        tabsettings.SizeY = tabsettings.SizeY ~= nil and tabsettings.SizeY or 300
        tabsettings.MaxSizeY = tabsettings.MaxSizeY ~= nil and tabsettings.MaxSizeY or 300
        tabsettings.Opened = tabsettings.Opened ~= nil and tabsettings.Opened or false
        tabsettings.Position = tabsettings.Position ~= nil and tabsettings.Position or UDim2.new(0,20,0,20)
        tabsettings.Flag = tabsettings.Flag ~= "" and tabsettings.Flag or nil
        assert(typeof(tabsettings.Title) == "string" or typeof(tabsettings.Title) == "number","invalid argument to 'Title', (string expected, got "..typeof(tabsettings.Title))
        assert(typeof(tabsettings.Subtitle) == "string" or typeof(tabsettings.Subtitle) == "number","invalid argument to 'Subtitle', (string expected, got "..typeof(tabsettings.Subtitle))
        assert(typeof(tabsettings.TitleRichText) == "boolean","invalid argument to 'TitleRichText', (boolean expected, got "..typeof(tabsettings.TitleRichText))
        assert(typeof(tabsettings.SubtitleRichText) == "boolean","invalid argument to 'SubtitleRichText', (boolean expected, got "..typeof(tabsettings.SubtitleRichText))
        assert(typeof(tabsettings.SizeY) == "number","invalid argument to 'SizeY', (number expected, got "..typeof(tabsettings.SizeY))
        assert(typeof(tabsettings.MaxSizeY) == "number","invalid argument to 'MaxSizeY', (number expected, got "..typeof(tabsettings.MaxSizeY))
        assert(typeof(tabsettings.Opened) == "boolean","invalid argument to 'Opened', (boolean expected, got "..typeof(tabsettings.Opened))
        assert(typeof(tabsettings.Position) == "UDim2","invalid argument to 'Position', (UDim2 expected, got "..typeof(tabsettings.Position))
        assert(tabsettings.Flag == nil or typeof(tabsettings.Flag) == "string","invalid argument to 'Flag', (string expected, got "..typeof(tabsettings.Flag))
        if tabsettings.Flag then
            local count = 1
            repeat
                local prev = tabsettings.Flag
                local new = prev.." ("..count..")"
                FPSLibrary.Flags[prev] = FPSLibrary.Flags[new]
                count += 1
            until not FPSLibrary.Flags[new]
        end
        -- Module
        local TabModule = {ClassName = "Tab"}
        local mt = {}
        -- Variables
        local layoutorder = 0
        -- Tab
        local Tab = FPSLibraryAssets:WaitForChild("Tab"):Clone()
        Tab.Parent = Interface
        Tab.Visible = tabsettings.Visible
        local Title = Tab:WaitForChild("Title")
        local Subtitle = Tab:WaitForChild("Subtitle")
        local MinimizeButton = Tab:WaitForChild("ArrowImageButton")
        local ElementsFrame = Tab:WaitForChild("Elements")
        local ElementsContainer = ElementsFrame:WaitForChild("Container")
        Title.Text = tabsettings.Title
        Subtitle.Text = tabsettings.Subtitle
        ElementsFrame.Size = tabsettings.Opened and UDim2.new(1,0,0,tabsettings.SizeY + 5) or UDim2.new(1,0,0,0)
        MinimizeButton.Rotation = tabsettings.Opened and 0 or 180
        Tab.Position = tabsettings.Position
        -- Metatable Functions
        local function UpdateTabFlags()
            for i, v in tabsettings do
                FPSLibrary.Flags[tabsettings.Flag][i] = v
            end
        end
        function mt.__newindex(self, idx, value)
            if idx == "Title" then
                if typeof(value) ~= "string" and typeof(value) ~= "number" then
                    return error("Unable to assign property "..idx..". string expected, got "..typeof(value))
                end
                tabsettings.Title = tostring(value)
                Title.Text = tabsettings.Title
            elseif idx == "Subtitle" then
                if typeof(value) ~= "string" and typeof(value) ~= "number" then
                    return error("Unable to assign property "..idx..". string expected, got "..typeof(value))
                end
                tabsettings.Subtitle = tostring(value)
                Subtitle.Text = tabsettings.Subtitle
            elseif idx == "TitleRichText" then
                if typeof(value) ~= "boolean" then
                    return error("Unable to assign property "..idx..". boolean expected, got "..typeof(value))
                end
                tabsettings.TitleRichText = value
                Title.RichText = tabsettings.TitleRichText
            elseif idx == "SubtitleRichText" then
                if typeof(value) ~= "boolean" then
                    return error("Unable to assign property "..idx..". boolean expected, got "..typeof(value))
                end
                tabsettings.SubtitleRichText = value
                Subtitle.RichText = tabsettings.SubtitleRichText
            elseif idx == "SizeY" then
                if typeof(value) ~= "number" then
                    return error("Unable to assign property "..idx..". number expected, got "..typeof(value))
                end
                tabsettings.SizeY = value >= 100 and value or 100
                tabsettings.SizeY = value <= tabsettings.MaxSizeY and value or tabsettings.MaxSizeY
                if tabsettings.Opened then
                    TweenService:Create(ElementsFrame,TweenOut75,{Size = UDim2.new(1,0,0,tabsettings.SizeY + 5)}):Play()
                end
            elseif idx == "MaxSizeY" then
                if typeof(value) ~= "number" then
                    return error("Unable to assign property "..idx..". number expected, got "..typeof(value))
                end
                tabsettings.MaxSizeY = value >= 100 and value or 100
                if tabsettings.SizeY > tabsettings.MaxSizeY then
                    TabModule.SizeY = tabsettings.MaxSizeY
                end
            elseif idx == "Position" then
                if typeof(value) ~= "UDim2" then
                    return error("Unable to assign property "..idx..". UDim2 expected, got "..typeof(value))
                end
                tabsettings.Position = value
                TweenService:Create(Tab,TweenInfo.new(0.5,Enum.EasingStyle.Sine,Enum.EasingDirection.Out),{Position = tabsettings.Position}):Play()
            elseif idx == "Opened" then
                if typeof(value) ~= "boolean" then
                    return error("Unable to assign property "..idx..". boolean expected, got "..typeof(value))
                end
                tabsettings.Opened = value
                if tabsettings.Opened then
                    TweenService:Create(ElementsFrame,TweenOut75,{Size = UDim2.new(1,0,0,tabsettings.SizeY + 5)}):Play()
                    TweenService:Create(MinimizeButton,TweenOut32,{Rotation = 0}):Play()
                else
                    TweenService:Create(ElementsFrame,TweenOut75,{Size = UDim2.new(1,0,0,0)}):Play()
                    TweenService:Create(MinimizeButton,TweenOut32,{Rotation = 180}):Play()
                end
            elseif idx == "Visible" then
                if typeof(value) ~= "boolean" then 
                    return error("Unable to assign property "..idx..". boolean expected, got "..typeof(value))
                end
                tabsettings.Visible = value
                Tab.Visible = value
            elseif idx == "ClassName" or idx == "Flag" then
                return error("Unable to assign property "..idx..". Property is read only")
            else
                return error(idx.." is not a valid member of Tab")
            end
            if windowsettings.ConfigurationSaving and windowsettings.ConfigurationSaving.Enabled and tabsettings.Flag then
                UpdateTabFlags()
            end
        end
        function mt.__index(self, idx)
            if idx == "Title" then
                return tabsettings.Title
            elseif idx == "Subtitle" then
                return tabsettings.Subtitle
            elseif idx == "TitleRichText" then
                return tabsettings.TitleRichText
            elseif idx == "SubtitleRichText" then
                return tabsettings.SubtitleRichText
            elseif idx == "SizeY" then
                return tabsettings.SizeY
            elseif idx == "MaxSizeY" then
                return tabsettings.MaxSizeY
            elseif idx == "Position" then
                return tabsettings.Position
            elseif idx == "Opened" then
                return tabsettings.Opened
            elseif idx == "Visible" then
                return tabsettings.Visible
            elseif idx == "ClassName" then
                return "Tab"
            elseif idx == "Flag" then
                return tabsettings.Flag
            else
                return error(idx.." is not a valid member of Tab")
            end
        end
        -- Tab Main
        MinimizeButton.MouseButton1Click:Connect(function()
            if TabModule.Opened then
                TabModule.Opened = false
            else
                TabModule.Opened = true
            end
        end)
        function TabModule:CreateButton(buttonsettings)
            -- Tab Settings
            buttonsettings.Name = buttonsettings.Name or "Button"
            buttonsettings.RichText = buttonsettings.RichText or false
            buttonsettings.Callback = buttonsettings.Callback or function() print("Button Clicked!") end
            buttonsettings.Active = buttonsettings.Active ~= nil and buttonsettings.Active
            buttonsettings.Visible = buttonsettings.Visible ~= nil and buttonsettings.Visible
            buttonsettings.Tip = buttonsettings.Tip ~= "" and buttonsettings.Tip or nil
            buttonsettings.ButtonColor = buttonsettings.ButtonColor or Color3.fromRGB(97,97,97)
            assert(typeof(buttonsettings.Name) == "string" or typeof(buttonsettings.Name) == "number","invalid argument to 'Title', (string expected, got "..typeof(buttonsettings.Name))
            assert(typeof(buttonsettings.RichText) == "boolean","invalid argument to 'RichText', (string expected, got "..typeof(buttonsettings.RichText))
            assert(typeof(buttonsettings.Callback) == "function","invalid argument to 'Callback', (function expected, got "..typeof(buttonsettings.Callback))
            assert(typeof(buttonsettings.Active) == "boolean","invalid argument to 'Active', (boolean expected, got "..typeof(buttonsettings.Active))
            assert(typeof(buttonsettings.Visible) == "boolean","invalid argument to 'Visible', (boolean expected, got "..typeof(buttonsettings.Visible))
            assert(typeof(buttonsettings.Tip) == "string" or typeof(buttonsettings.Tip) == "number","invalid argument to 'Tip', (string expected, got "..typeof(buttonsettings.Tip))
            assert(typeof(buttonsettings.ButtonColor) == "Color3","invalid argument to 'ButtonColor', (Color3 expected, got "..typeof(buttonsettings.ButtonColor))
            -- Variables
            local mouseenterID = 0
            local tip
            -- Button
            local Button = FPSLibraryAssets:WaitForChild("Button"):Clone()
            Button.Parent = buttonsettings.SectionParent and buttonsettings.SectionParent.SectionContainer or ElementsContainer
            Button.Visible = buttonsettings.Visible
            Button.BackgroundColor3 = buttonsettings.ButtonColor
            local ButtonOutline = Button:WaitForChild("OutlineFrame")
            local h, s, v = Color3.new(buttonsettings.ButtonColor):ToHSV()
            ButtonOutline.BackgroundColor3 = Color3.fromHSV(h,s,v - 66 > 0 and v - 66 or 0)
            local ButtonNameLabel = Button:WaitForChild("NameTextLabel")
            ButtonNameLabel.Text = buttonsettings.Name
            local ButtonModule = {ClassName = "Button"}
            local mt = {}
            -- Metatable Functions
            function mt.__index(self,idx)
                if idx == "Name" then
                    return buttonsettings.Name
                elseif idx == "Callback" then
                    return buttonsettings.Callback
                elseif idx == "RichText" then
                    return buttonsettings.RichText
                elseif idx == "Active" then
                    return buttonsettings.Active
                elseif idx == "Visible" then
                    return buttonsettings.Visible
                elseif idx == "SectionParent" then
                    return buttonsettings.SectionParent
                elseif idx == "ButtonColor" then
                    return buttonsettings.ButtonColor
                elseif idx == "ClassName" then
                    return "Button"
                else
                    return error(idx.." is not a valid member of Button")
                end
            end
            function mt.__newindex(self,idx,value)
                if idx == "Name" then
                    if typeof(value) ~= "string" then 
                        return error("Unable to assign property "..idx..". string expected, got "..typeof(value))
                    end
                    buttonsettings.Name = tostring(value)
                    ButtonNameLabel.Text = buttonsettings.Name
                elseif idx == "Callback" then
                    if typeof(value) ~= "function" then 
                        return error("Unable to assign property "..idx..". function expected, got "..typeof(value))
                    end
                    buttonsettings.Callback = value
                elseif idx == "RichText" then
                    if typeof(value) ~= "boolean" then
                        return error("Unable to assign property "..idx..". boolean expected, got "..typeof(value))
                    end
                    tabsettings.RichText = value
                    Button.RichText = tabsettings.RichText
                elseif idx == "SectionParent" then
                    return error("Unable to assign property "..idx..". Property is read only")
                elseif idx == "Active" then
                    if typeof(value) ~= "boolean" then 
                        return error("Unable to assign property "..idx..". boolean expected, got "..typeof(value))
                    end
                    buttonsettings.Active = value
                elseif idx == "ButtonColor" then
                    if typeof(value) ~= "Color3" then 
                        return error("Unable to assign property "..idx..". Color3 expected, got "..typeof(value))
                    end
                    buttonsettings.ButtonColor = value
                    Button.BackgroundColor3 = buttonsettings.ButtonColor
                    ButtonOutline.BackgroundColor3 = Color3.fromRGB(buttonsettings.ButtonColor.R - 66 >= 0 and buttonsettings.ButtonColor.R - 66 or 0,buttonsettings.ButtonColor.G - 66 >= 0 and buttonsettings.ButtonColor.G - 66 or 0,buttonsettings.ButtonColor.B - 66 >= 0 and buttonsettings.ButtonColor.B - 66 or 0)
                elseif idx == "ClassName" then
                    return error("Unable to assign property "..idx..". Property is read only")
                else
                    return error(idx.." is not a valid member of Button")
                end
            end
            -- Button Main
            RippleEffects(Button)
            Button.MouseButton1Click:Connect(function()
                if buttonsettings.Callback and buttonsettings.Active then
                    local suc, err = pcall(buttonsettings.Callback)
                    if not suc then
                        FPSLibraryErrorMessage(err,"Callback Error!")
                    end
                end
            end)
            Button.MouseEnter:Connect(function()
                if buttonsettings.Tip then
                    a += 1
                    mouseenterID = a
                    tip = FPSLibraryAssets:WaitForChild("Tip"):Clone()
                    tip.Parent = Interface
                    connections[mouseenterID] = RunService.Heartbeat:Connect(function()
                        tip.Text = buttonsettings.Tip
                        tip.Size = UDim2.new(0,tip.TextBounds.X + 4,0,tip.TextBounds.Y + 2)
                        tip.Position = UDim2.new(0,mouse.X,0,mouse.Y)
                    end)
                end
            end)
            Button.MouseLeave:Connect(function()
                if tip then
                    tip:Destroy()
                end
                if connections[mouseenterID] then
                    connections[mouseenterID]:Disconnect()
                end
            end)
            layoutorder += 1
            Button.LayoutOrder = layoutorder
            -- Set Metatable
            setmetatable(ButtonModule,mt)
            return ButtonModule
        end
        function TabModule:CreateToggle(togglesettings)

        end
        -- Set Metatable
        setmetatable(TabModule,mt)
        -- Set Flags
        if windowsettings.ConfigurationSaving and windowsettings.ConfigurationSaving.Enabled and tabsettings.Flag then
            FPSLibrary.Flags[tabsettings.Flag] = tabsettings
        end
        return TabModule
    end
    function Window:OrganizeTabs()

    end
    return Window
end
Interface.Name = GenerateRandomString()
if not isfolder(FPSLibraryFolder) then
    makefolder(FPSLibraryFolder)
end
if not isfolder(KeyFolderName) then
    makefolder(KeyFolderName)
end
if not isfolder(ConfigurationFolderName) then
    makefolder(ConfigurationFolderName)
end
return FPSLibrary
Leave a Comment