Skip to content

Instantly share code, notes, and snippets.

@TheEpicFace007
Created May 21, 2020 01:57
Show Gist options
  • Save TheEpicFace007/0cd7d58e69f4d4204e1f53b3283fecaa to your computer and use it in GitHub Desktop.
Save TheEpicFace007/0cd7d58e69f4d4204e1f53b3283fecaa to your computer and use it in GitHub Desktop.
TopBar+ for exploits
-- UTILITY
-- local Signal = require(4893141590)
-- local DirectoryService = require(4926442976)
-- read the docs here: https://1foreverhd.github.io/HDAdmin/projects/topbarplus/about/
local __IS_TESTING = true
-- init
-- CREATE ICON UI
local topbarPlusGui = Instance.new("ScreenGui")
topbarPlusGui.Enabled = true
topbarPlusGui.DisplayOrder = 0
topbarPlusGui.IgnoreGuiInset = true
topbarPlusGui.Name = "Topbar+"
if __IS_TESTING then
topbarPlusGui.Parent = game.Players.LocalPlayer.PlayerGui
topbarPlusGui.ResetOnSpawn = true
else
topbarPlusGui.Parent = game.CoreGui
end
local topbarContainer = Instance.new("Frame")
topbarContainer.BackgroundTransparency = 1
topbarContainer.Name = "TopbarContainer"
topbarContainer.Position = UDim2.new(0, 0, 0, 0)
topbarContainer.Size = UDim2.new(1, 0, 0, 36)
topbarContainer.Visible = true
topbarContainer.ZIndex = 1
topbarContainer.Parent = topbarPlusGui
local iconContainer = Instance.new("Frame")
iconContainer.BackgroundTransparency = 1
iconContainer.Name = "_IconTemplate"
iconContainer.Position = UDim2.new(0, 104, 0, 4)
iconContainer.Size = UDim2.new(0, 32, 0, 32)
iconContainer.Visible = false
iconContainer.ZIndex = 1
iconContainer.Parent = topbarContainer
local iconButton = Instance.new("ImageButton")
iconButton.BackgroundTransparency = 1
iconButton.Name = "IconButton"
iconButton.Position = UDim2.new(0, 0, 0, 0)
iconButton.Size = UDim2.new(1, 0, 1, 0)
iconButton.Visible = true
iconButton.ZIndex = 2
iconButton.Image = "rbxassetid://5027411759"
iconButton.ImageTransparency = 0.5
iconButton.ImageColor3 = Color3.fromRGB(0, 0, 0)
iconButton.ScaleType = Enum.ScaleType.Stretch
iconButton.Parent = iconContainer
local iconImage = Instance.new("ImageLabel")
iconImage.BackgroundTransparency = 1
iconImage.Name = "IconImage"
iconImage.AnchorPoint = Vector2.new(0.5, 0.5)
iconImage.Position = UDim2.new(0.5, 0, 0.5, 0)
iconImage.Size = UDim2.new(0, 20, 0, 20)
iconImage.Visible = true
iconImage.ZIndex = 3
iconImage.ImageTransparency = 0
iconImage.ImageColor3 = Color3.fromRGB(255, 255, 255)
iconImage.ScaleType = Enum.ScaleType.Fit
iconImage.Parent = iconButton
local notification = Instance.new("ImageLabel")
notification.BackgroundTransparency = 1
notification.Name = "Notification"
notification.Position = UDim2.new(0.45, 0, 0, -2)
notification.Size = UDim2.new(1, 0, 0.7, 0)
notification.Visible = false
notification.ZIndex = 4
notification.Image = "http://www.roblox.com/asset/?id=4871790969"
notification.ImageTransparency = 0
notification.ImageColor3 = Color3.fromRGB(255, 255, 255)
notification.ScaleType = Enum.ScaleType.Fit
notification.Parent = iconButton
local amount = Instance.new("TextLabel")
amount.BackgroundTransparency = 1
amount.Name = "Amount"
amount.Position = UDim2.new(0.25, 0, 0.15, 0)
amount.Size = UDim2.new(0.5, 0, 0.7, 0)
amount.Visible = true
amount.ZIndex = 5
amount.Font = Enum.Font.Arial
amount.Text = "0"
amount.TextColor3 = Color3.fromRGB(31, 33, 35)
amount.TextScaled = true
amount.Parent = notification
-- signal library
-- Quenty's Signal Module, modified to include Disconnect method
local Signal = {}
Signal.__index = Signal
Signal.ClassName = "Signal"
function Signal.new()
local self = setmetatable({}, Signal)
self._bindableEvent = Instance.new("BindableEvent")
self._argData = nil
self._argCount = nil -- Prevent edge case of :Fire("A", nil) --> "A" instead of "A", nil
return self
end
function Signal:Fire(...)
self._argData = {...}
self._argCount = select("#", ...)
self._bindableEvent:Fire()
self._argData = nil
self._argCount = nil
end
function Signal:Connect(handler)
if not (type(handler) == "function") then
error(("connect(%s)"):format(typeof(handler)), 2)
end
return self._bindableEvent.Event:Connect(function()
handler(unpack(self._argData, 1, self._argCount))
end)
end
function Signal:Wait()
self._bindableEvent.Event:Wait()
assert(self._argData, "Missing arg data, likely due to :TweenSize/Position corrupting threadrefs.")
return unpack(self._argData, 1, self._argCount)
end
function Signal:Destroy()
if self._bindableEvent then
self._bindableEvent:Destroy()
self._bindableEvent = nil
end
self._argData = nil
self._argCount = nil
end
function Signal:Disconnect()
self:Destroy()
end
-- icon.lua
-- LOCAL
local tweenService = game:GetService("TweenService")
local replicatedStorage = game:GetService("ReplicatedStorage")
local iconTemplate = topbarContainer["_IconTemplate"]
local Icon = {}
Icon.__index = Icon
-- CONSTRUCTOR
function Icon.new(name, imageId, order)
local self = {}
setmetatable(self, Icon)
local container = iconTemplate:Clone()
container.Name = name
container.Visible = true
local button = container.IconButton
self.objects = {
["container"] = container,
["button"] = button,
["image"] = button.IconImage,
["notification"] = button.Notification,
["amount"] = button.Notification.Amount
}
self.theme = {
-- TOGGLE EFFECT
["toggleTweenInfo"] = TweenInfo.new(0, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
-- OBJECT PROPERTIES
["container"] = {
selected = {},
deselected = {}
},
["button"] = {
selected = {
ImageColor3 = Color3.fromRGB(245, 245, 245),
ImageTransparency = 0.1
},
deselected = {
ImageColor3 = Color3.fromRGB(0, 0, 0),
ImageTransparency = 0.5
}
},
["image"] = {
selected = {
ImageColor3 = Color3.fromRGB(57, 60, 65),
},
deselected = {
ImageColor3 = Color3.fromRGB(255, 255, 255),
}
},
["notification"] = {
selected = {},
deselected = {},
},
["amount"] = {
selected = {},
deselected = {},
},
}
self.toggleStatus = "deselected"
self:applyThemeToAllObjects()
self.name = name
self.imageId = imageId or 0
self:setImageSize(20)
self.order = order or 1
self.enabled = true
self.totalNotifications = 0
self.toggleFunction = function() end
self.hoverFunction = function() end
self.deselectWhenOtherIconSelected = true
self.fakeChatConnections = {}
self.updated = Signal.new()
self.selected = Signal.new()
self.deselected = Signal.new()
self.endNotifications = Signal.new()
--[[
local hoverInputs = {"InputBegan", "InputEnded"}
local originalTransparency = button.ImageTransparency
self:setHoverFunction(function(inputName)
local hovering = inputName == "InputBegan"
button.ImageTransparency = (hovering and originalTransparency + 0.2) or (self.theme.button.selected.ImageTransparency or originalTransparency)
end)
for _, inputName in pairs(hoverInputs) do
button[inputName]:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement then
self.hoverFunction(inputName)
end
end)
end
--]]
button.MouseButton1Click:Connect(function()
if self.toggleStatus == "selected" then
self:deselect()
else
self:select()
end
end)
if imageId then
self:setImage(imageId)
end
container.Parent = topbarContainer
return self
end
-- METHODS
function Icon:setImage(imageId)
local textureId = (tonumber(imageId) and "http://www.roblox.com/asset/?id="..imageId) or imageId
self.imageId = textureId
self.objects.image.Image = textureId
self.theme.image = self.theme.image or {}
self.theme.image.selected = self.theme.image.selected or {}
self.theme.image.selected.Image = textureId
end
function Icon:setOrder(order)
self.order = tonumber(order) or 1
self.updated:Fire()
end
function Icon:setImageSize(pixelsX, pixelsY)
pixelsX = tonumber(pixelsX) or self.imageSize
if not pixelsY then
pixelsY = pixelsX
end
self.imageSize = Vector2.new(pixelsX, pixelsY)
self.objects.image.Size = UDim2.new(0, pixelsX, 0, pixelsY)
end
function Icon:setEnabled(bool)
self.enabled = bool
self.objects.container.Visible = bool
self.updated:Fire()
end
function Icon:setBaseZIndex(baseValue)
local container = self.objects.container
local baseValue = tonumber(baseValue) or container.ZIndex
local difference = baseValue - container.ZIndex
if difference == 0 then
return "The baseValue is the same"
end
for _, object in pairs(self.objects) do
object.ZIndex = object.ZIndex + difference
end
end
function Icon:setToggleMenu(guiObject)
if not guiObject or not guiObject:IsA("GuiObject") then
guiObject = nil
end
self.toggleMenu = guiObject
end
function Icon:setToggleFunction(toggleFunction)
if type(toggleFunction) == "function" then
local oppositeToggleStatus = (toggleStatus == "selected" and "deselected") or "selected"
local oppositeGroup = self.theme[objectName][oppositeToggleStatus]
local group = self.theme[objectName][toggleStatus]
for key, value in pairs(propertiesTable) do
local oppositeKey = oppositeGroup[key]
if not oppositeKey then
oppositeGroup[key] = group[key]
end
group[key] = value
end
if toggleStatus == self.toggleStatus then
self:applyThemeToObject(objectName, toggleStatus)
end
end
for objectName, toggleDetails in pairs(themeDetails) do
parseDetails(objectName, toggleDetails)
end
end
function Icon:applyThemeToObject(objectName, toggleStatus)
local object = self.objects[objectName]
if object then
local propertiesTable = self.theme[objectName][(toggleStatus or self.toggleStatus)]
local toggleTweenInfo = self.theme.toggleTweenInfo
local invalidProperties = {"Image"}
local finalPropertiesTable = {}
for propName, propValue in pairs(propertiesTable) do
if table.find(invalidProperties, propName) then
object[propName] = propValue
else
finalPropertiesTable[propName] = propValue
end
end
tweenService:Create(object, toggleTweenInfo, finalPropertiesTable):Play()
end
end
function Icon:applyThemeToAllObjects(...)
for objectName, toggleDetails in pairs(self.theme) do
self:applyThemeToObject(objectName, ...)
end
end
function Icon:select()
self.toggleStatus = "selected"
self:applyThemeToAllObjects()
self.toggleFunction()
if self.toggleMenu then
self.toggleMenu.Visible = true
end
self.selected:Fire()
end
function Icon:deselect()
self.toggleStatus = "deselected"
self:applyThemeToAllObjects()
self.toggleFunction()
if self.toggleMenu then
self.toggleMenu.Visible = false
end
self.deselected:Fire()
end
function Icon:notify(clearNoticeEvent)
coroutine.wrap(function()
if not clearNoticeEvent then
clearNoticeEvent = self.deselected
end
self.totalNotifications = self.totalNotifications + 1
self.objects.amount.Text = (self.totalNotifications < 100 and self.totalNotifications) or "99+"
self.objects.notification.Visible = true
local notifComplete = Signal.new()
local endEvent = self.endNotifications:Connect(function()
notifComplete:Fire()
end)
local customEvent = clearNoticeEvent:Connect(function()
notifComplete:Fire()
end)
notifComplete:Wait()
endEvent:Disconnect()
customEvent:Disconnect()
notifComplete:Disconnect()
self.totalNotifications = self.totalNotifications - 1
if self.totalNotifications < 1 then
self.objects.notification.Visible = false
end
end)()
end
function Icon:clearNotifications()
self.endNotifications:Fire()
end
function Icon:clearFakeChatConnections()
for cName, connection in pairs(self.fakeChatConnections) do
connection:Disconnect()
self.fakeChatConnections[cName] = nil
end
end
function Icon:destroy()
self:clearNotifications()
self:clearFakeChatConnections()
self.objects.button:Destroy()
for signalName, signal in pairs(self) do
if type(signal) == "table" and signal.Destroy then
signal:Destroy()
end
end
end
-- icon controller
-- LOCAL
local starterGui = game:GetService("StarterGui")
local userInputService = game:GetService("UserInputService")
local players = game:GetService("Players")
local IconController = {}
local topbarIcons = {}
local errorStart = "Topbar+ | "
local fakeChatName = "_FakeChat"
local function deepCopy(original)
local copy = {}
for k, v in pairs(original) do
if type(v) == "table" then
v = deepCopy(v)
end
copy[k] = v
end
return copy
end
local function getChatMain()
return require(players.LocalPlayer.PlayerScripts:WaitForChild("ChatScript").ChatMain)
end
local function getTopbarPlusGui()
local player = game:GetService("Players").LocalPlayer
local playerGui = player.PlayerGui
local topbarPlusGui = playerGui:WaitForChild("Topbar+")
return topbarPlusGui
end
-- METHODS
function IconController:createIcon(name, imageId, order)
-- Verify data
local iconDetails = topbarIcons[name]
if iconDetails then
warn(("%sFailed to create Icon '%s': an icon already exists under that name."):format(errorStart, name))
return false
end
-- Create and record icon
local icon = Icon.new(name, imageId, order)
iconDetails = {name = name, icon = icon, order = icon.order}
topbarIcons[name] = iconDetails
icon:setOrder(icon.order)
-- Events
local function updateIcon()
local iconDetails = topbarIcons[name]
if not iconDetails then
warn(("%sFailed to update Icon '%s': icon not found."):format(errorStart, name))
return false
end
iconDetails.order = icon.order or 1
local orderedIconDetails = {}
for name, details in pairs(topbarIcons) do
if details.icon.enabled == true then
table.insert(orderedIconDetails, details)
end
end
if #orderedIconDetails > 1 then
table.sort(orderedIconDetails, function(a,b) return a.order < b.order end)
end
local startPosition = 104
local positionIncrement = 44
if not starterGui:GetCoreGuiEnabled("Chat") then
startPosition = startPosition - positionIncrement
end
for i, details in pairs(orderedIconDetails) do
local container = details.icon.objects.container
local iconX = startPosition + (i-1)*positionIncrement
container.Position = UDim2.new(0, iconX, 0, 4)
end
return true
end
updateIcon()
icon.updated:Connect(function()
updateIcon()
end)
icon.selected:Connect(function()
local allIcons = self:getAllIcons()
for _, otherIcon in pairs(allIcons) do
if otherIcon ~= icon and otherIcon.deselectWhenOtherIconSelected and otherIcon.toggleStatus == "selected" then
otherIcon:deselect()
end
end
end)
return icon
end
function IconController:createFakeChat(theme)
local ChatMain = getChatMain()
local iconName = fakeChatName
local icon = self:getIcon(iconName)
local function displayChatBar(visibility)
icon.ignoreVisibilityStateChange = true
ChatMain.CoreGuiEnabled:fire(visibility)
ChatMain:SetVisible(visibility)
icon.ignoreVisibilityStateChange = nil
end
local function setIconEnabled(visibility)
icon.ignoreVisibilityStateChange = true
ChatMain.CoreGuiEnabled:fire(visibility)
icon:setEnabled(visibility)
starterGui:SetCoreGuiEnabled("Chat", false)
icon:deselect()
icon.updated:Fire()
icon.ignoreVisibilityStateChange = nil
end
if not icon then
icon = self:createIcon(iconName, "rbxasset://textures/ui/TopBar/chatOff.png", -1)
-- Open chat via Slash key
icon.fakeChatConnections["ChatInput"] = userInputService.InputEnded:connect(function(inputObject, gameProcessedEvent)
if gameProcessedEvent then
return "Another menu has priority"
elseif inputObject.KeyCode ~= Enum.KeyCode.Slash then
return "No relavent key pressed"
elseif ChatMain.IsFocused() then
return "Chat bar already open"
end
displayChatBar(true)
ChatMain:FocusChatBar(true)
icon:select()
end)
-- Keep when other icons selected
icon.deselectWhenOtherIconSelected = false
-- Mimic chat notifications
icon.fakeChatConnections["MessagesChanged"] = ChatMain.MessagesChanged:connect(function(messageCount)
if ChatMain:GetVisibility() == true then
return "ChatWindow was open"
end
icon:notify(icon.selected)
end)
-- Mimic visibility when StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Chat, state) is called
icon.fakeChatConnections["CoreGuiEnabled"] = ChatMain.CoreGuiEnabled:connect(function(newState)
if icon.ignoreVisibilityStateChange then
return "ignoreVisibilityStateChange enabled"
end
setIconEnabled(newState)
end)
end
theme = (theme and deepCopy(theme)) or {}
theme.image = theme.image or {}
theme.image.selected = theme.image.selected or {}
theme.image.selected.Image = "rbxasset://textures/ui/TopBar/chatOn.png"
icon:setTheme(theme)
icon:setImageSize(20)
icon:setToggleFunction(function()
local isSelected = icon.toggleStatus == "selected"
displayChatBar(isSelected)
end)
setIconEnabled(starterGui:GetCoreGuiEnabled("Chat"))
return icon
end
function IconController:removeFakeChat()
local icon = IconController:getIcon(fakeChatName)
local enabled = icon.enabled
icon:clearFakeChatConnections()
IconController:removeIcon(fakeChatName)
starterGui:SetCoreGuiEnabled("Chat", enabled)
end
function IconController:setTopbarEnabled(newState)
local topbarPlusGui = getTopbarPlusGui()
local topbarContainer = topbarPlusGui.TopbarContainer
topbarContainer.Visible = newState
end
function IconController:setDisplayOrder(value)
local topbarPlusGui = getTopbarPlusGui()
local value = tonumber(value) or topbarPlusGui.DisplayOrder
topbarPlusGui.DisplayOrder = value
end
function IconController:getIcon(name)
local iconDetails = topbarIcons[name]
if not iconDetails then
--warn(("%sFailed to get Icon '%s': icon not found."):format(errorStart, name))
return false
end
return iconDetails.icon
end
function IconController:getAllIcons()
local allIcons = {}
for name, details in pairs(topbarIcons) do
table.insert(allIcons, details.icon)
end
return allIcons
end
function IconController:removeIcon(name)
local iconDetails = topbarIcons[name]
if not iconDetails then
warn(("%sFailed to remove Icon '%s': icon not found."):format(errorStart, name))
return false
end
local icon = iconDetails.icon
icon:setEnabled(false)
icon:deselect()
icon.updated:Fire()
icon:destroy()
topbarIcons[name] = nil
return true
end
-- BEHAVIOUR
coroutine.wrap(function()
-- Mimic the enabling of the topbar when StarterGui:SetCore("TopbarEnabled", state) is called
local ChatMain = getChatMain()
ChatMain.CoreGuiEnabled:connect(function(newState)
local enabled = starterGui:GetCore("TopbarEnabled")
IconController:setTopbarEnabled(enabled)
local icons = IconController:getAllIcons()
for _, icon in pairs(icons) do
icon.updated:Fire()
end
end)
IconController:setTopbarEnabled(starterGui:GetCore("TopbarEnabled"))
end)()
-- actual script
infinite_yield = Icon.new("Infinite yield",5063637342,1)
infinite_yield.toggleFunction = function() loadstring(game:HttpGet('https://raw.githubusercontent.com/EdgeIY/infiniteyield/master/source'))() end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment