Teleport hub
Key RequiredUniversal

Teleport hub

Universal ScriptVastBike_705421VastBike_705421 511 views 772 executesUpdated May 14, 2026
Unrated
00
Lua Script•668 lines (24732 chars)
-- Remove previous GUI version if it exists
if game:GetService("CoreGui"):FindFirstChild("TeleportHubGui") then
    game:GetService("CoreGui").TeleportHubGui:Destroy()
end

-- Service variables
local Players = game:GetService("Players")
local CoreGui = game:GetService("CoreGui")
local HttpService = game:GetService("HttpService")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer

-- Live script variables
local savedPositions = {}
local isMinimized = false

-- Main GUI container
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "TeleportHubGui"
screenGui.Parent = CoreGui
screenGui.ResetOnSpawn = false

-- Main frame (The Main Window container)
local mainFrame = Instance.new("Frame")
mainFrame.Size = UDim2.new(0, 330, 0, 430)
mainFrame.Position = UDim2.new(0.5, -165, 0.5, -215)
mainFrame.BackgroundColor3 = Color3.fromRGB(20, 10, 35)
mainFrame.BorderSizePixel = 0
mainFrame.Active = true
mainFrame.Parent = screenGui

local mainCorner = Instance.new("UICorner")
mainCorner.CornerRadius = UDim.new(0, 10)
mainCorner.Parent = mainFrame

-- Title bar panel (Hold to drag STRICTLY here)
local titleLabel = Instance.new("TextLabel")
titleLabel.Size = UDim2.new(1, 0, 0, 40)
titleLabel.BackgroundColor3 = Color3.fromRGB(40, 15, 75)
titleLabel.Text = "  Teleport Hub"
titleLabel.TextColor3 = Color3.fromRGB(185, 115, 255)
titleLabel.Font = Enum.Font.SourceSansBold
titleLabel.TextSize = 18
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.Active = true
titleLabel.Parent = mainFrame

local titleCorner = Instance.new("UICorner")
titleCorner.CornerRadius = UDim.new(0, 10)
titleCorner.Parent = titleLabel

-- Smooth Dragging Engine for Mobile Devices (No Shifting Bug)
local dragging, dragInput, dragStart, startPos
local function updateDrag(input)
    local delta = input.Position - dragStart
    mainFrame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
end

titleLabel.InputBegan:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
        dragging = true
        dragStart = input.Position
        startPos = mainFrame.Position
        input.Changed:Connect(function()
            if input.UserInputState == Enum.UserInputState.End then dragging = false end
        end)
    end
end)

titleLabel.InputChanged:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
        dragInput = input
    end
end)

UserInputService.InputChanged:Connect(function(input)
    if input == dragInput and dragging then updateDrag(input) end
end)

-- Minimize/Maximize Button
local toggleButton = Instance.new("TextButton")
toggleButton.Size = UDim2.new(0, 35, 0, 30)
toggleButton.Position = UDim2.new(1, -40, 0, 5)
toggleButton.BackgroundColor3 = Color3.fromRGB(60, 25, 110)
toggleButton.Text = "▼"
toggleButton.TextColor3 = Color3.fromRGB(185, 115, 255)
toggleButton.Font = Enum.Font.SourceSansBold
toggleButton.TextSize = 14
toggleButton.Parent = titleLabel

local toggleCorner = Instance.new("UICorner")
toggleCorner.CornerRadius = UDim.new(0, 5)
toggleCorner.Parent = toggleButton

-- MASTER SCROLLING FRAME
local masterScroll = Instance.new("ScrollingFrame")
masterScroll.Size = UDim2.new(1, 0, 1, -45)
masterScroll.Position = UDim2.new(0, 0, 0, 45)
masterScroll.BackgroundTransparency = 1
masterScroll.BorderSizePixel = 0
masterScroll.CanvasSize = UDim2.new(0, 0, 0, 530)
masterScroll.ScrollBarThickness = 8
masterScroll.ScrollBarImageColor3 = Color3.fromRGB(110, 35, 200)
masterScroll.ScrollingDirection = Enum.ScrollingDirection.Y
masterScroll.Parent = mainFrame

----------------------------------------------------
-- FIXED: POPUP PROMPT WINDOW (Всплывающее фиолетовое окошко)
----------------------------------------------------
local promptFrame = Instance.new("Frame")
promptFrame.Size = UDim2.new(0, 260, 0, 130)
promptFrame.Position = UDim2.new(0.5, -130, 0.5, -65)
promptFrame.BackgroundColor3 = Color3.fromRGB(35, 15, 60)
promptFrame.BorderSizePixel = 0
promptFrame.ZIndex = 50 -- Ставим поверх всех остальных элементов
promptFrame.Active = true -- Замораживает клики сквозь это окно
promptFrame.Visible = false
promptFrame.Parent = mainFrame

local promptCorner = Instance.new("UICorner")
promptCorner.CornerRadius = UDim.new(0, 8)
promptCorner.Parent = promptFrame

local promptLabel = Instance.new("TextLabel")
promptLabel.Size = UDim2.new(1, 0, 0, 30)
promptLabel.BackgroundTransparency = 1
promptLabel.Text = "Enter new name:"
promptLabel.TextColor3 = Color3.fromRGB(185, 115, 255)
promptLabel.Font = Enum.Font.SourceSansBold
promptLabel.TextSize = 15
promptLabel.ZIndex = 51
promptLabel.Parent = promptFrame

local promptInput = Instance.new("TextBox")
promptInput.Size = UDim2.new(1, -20, 0, 35)
promptInput.Position = UDim2.new(0, 10, 0, 40)
promptInput.BackgroundColor3 = Color3.fromRGB(20, 10, 35)
promptInput.Text = ""
promptInput.TextColor3 = Color3.fromRGB(185, 115, 255)
promptInput.Font = Enum.Font.SourceSans
promptInput.TextSize = 15
promptInput.ZIndex = 51
-- Полная блокировка сдвигов Roblox при фокусе на клавиатуру смартфона
promptInput.ClipsDescendants = false
promptInput.Parent = promptFrame

local promptInputCorner = Instance.new("UICorner")
promptInputCorner.CornerRadius = UDim.new(0, 4)
promptInputCorner.Parent = promptInput

local promptOk = Instance.new("TextButton")
promptOk.Size = UDim2.new(0.5, -15, 0, 30)
promptOk.Position = UDim2.new(0, 10, 0, 85)
promptOk.BackgroundColor3 = Color3.fromRGB(110, 35, 200)
promptOk.Text = "OK"
promptOk.TextColor3 = Color3.fromRGB(255, 255, 255)
promptOk.Font = Enum.Font.SourceSansBold
promptOk.TextSize = 14
promptOk.ZIndex = 51
promptOk.Parent = promptFrame

local promptOkCorner = Instance.new("UICorner")
promptOkCorner.CornerRadius = UDim.new(0, 4)
promptOkCorner.Parent = promptOk

local promptCancel = Instance.new("TextButton")
promptCancel.Size = UDim2.new(0.5, -15, 0, 30)
promptCancel.Position = UDim2.new(0.5, 5, 0, 85)
promptCancel.BackgroundColor3 = Color3.fromRGB(80, 20, 60)
promptCancel.Text = "Cancel"
promptCancel.TextColor3 = Color3.fromRGB(255, 255, 255)
promptCancel.Font = Enum.Font.SourceSansBold
promptCancel.TextSize = 14
promptCancel.ZIndex = 51
promptCancel.Parent = promptFrame

local promptCancelCorner = Instance.new("UICorner")
promptCancelCorner.CornerRadius = UDim.new(0, 4)
promptCancelCorner.Parent = promptCancel

local currentPromptCallback = nil
local function openPrompt(defaultText, callback)
    promptInput.Text = defaultText
    masterScroll.ScrollingEnabled = false -- Временно отключаем общую прокрутку (замораживаем меню)
    promptFrame.Visible = true
    promptInput:CaptureFocus()
    currentPromptCallback = callback
end

promptCancel.MouseButton1Click:Connect(function()
    promptFrame.Visible = false
    masterScroll.ScrollingEnabled = true -- Размораживаем меню
    currentPromptCallback = nil
end)

promptOk.MouseButton1Click:Connect(function()
    local text = promptInput.Text:match("^%s*(.-)%s*$")
    if text ~= "" and currentPromptCallback then
        currentPromptCallback(text)
    end
    promptFrame.Visible = false
    masterScroll.ScrollingEnabled = true -- Размораживаем меню
    currentPromptCallback = nil
end)

----------------------------------------------------
-- INTERFACE ELEMENTS
----------------------------------------------------
local nameInput = Instance.new("TextBox")
nameInput.Size = UDim2.new(1, -26, 0, 35)
nameInput.Position = UDim2.new(0, 10, 0, 15)
nameInput.BackgroundColor3 = Color3.fromRGB(35, 15, 55)
nameInput.Text = ""
nameInput.PlaceholderText = "Enter location name..."
nameInput.TextColor3 = Color3.fromRGB(185, 115, 255)
nameInput.PlaceholderColor3 = Color3.fromRGB(110, 60, 160)
nameInput.Font = Enum.Font.SourceSans
nameInput.TextSize = 16
nameInput.Parent = masterScroll

local inputCorner = Instance.new("UICorner")
inputCorner.CornerRadius = UDim.new(0, 5)
inputCorner.Parent = nameInput

local saveButton = Instance.new("TextButton")
saveButton.Size = UDim2.new(1, -26, 0, 35)
saveButton.Position = UDim2.new(0, 10, 0, 55)
saveButton.BackgroundColor3 = Color3.fromRGB(110, 35, 200)
saveButton.Text = "Save Current Position"
saveButton.TextColor3 = Color3.fromRGB(220, 180, 255)
saveButton.Font = Enum.Font.SourceSansBold
saveButton.TextSize = 16
saveButton.Parent = masterScroll

local saveCorner = Instance.new("UICorner")
saveCorner.CornerRadius = UDim.new(0, 5)
saveCorner.Parent = saveButton

local configInput = Instance.new("TextBox")
configInput.Size = UDim2.new(1, -26, 0, 35)
configInput.Position = UDim2.new(0, 10, 0, 105)
configInput.BackgroundColor3 = Color3.fromRGB(35, 15, 55)
configInput.Text = ""
configInput.PlaceholderText = "Enter config name (e.g. birds)..."
configInput.TextColor3 = Color3.fromRGB(185, 115, 255)
configInput.PlaceholderColor3 = Color3.fromRGB(110, 60, 160)
configInput.Font = Enum.Font.SourceSans
configInput.TextSize = 16
configInput.Parent = masterScroll

local configInputCorner = Instance.new("UICorner")
configInputCorner.CornerRadius = UDim.new(0, 5)
configInputCorner.Parent = configInput

local saveConfigBtn = Instance.new("TextButton")
saveConfigBtn.Size = UDim2.new(0.5, -18, 0, 35)
saveConfigBtn.Position = UDim2.new(0, 10, 0, 145)
saveConfigBtn.BackgroundColor3 = Color3.fromRGB(80, 20, 150)
saveConfigBtn.Text = "Save Config"
saveConfigBtn.TextColor3 = Color3.fromRGB(220, 180, 255)
saveConfigBtn.Font = Enum.Font.SourceSansBold
saveConfigBtn.TextSize = 15
saveConfigBtn.Parent = masterScroll

local saveConfigCorner = Instance.new("UICorner")
saveConfigCorner.CornerRadius = UDim.new(0, 5)
saveConfigCorner.Parent = saveConfigBtn

local loadConfigBtn = Instance.new("TextButton")
loadConfigBtn.Size = UDim2.new(0.5, -18, 0, 35)
loadConfigBtn.Position = UDim2.new(0.5, 2, 0, 145)
loadConfigBtn.BackgroundColor3 = Color3.fromRGB(95, 30, 175)
loadConfigBtn.Text = "Load Config"
loadConfigBtn.TextColor3 = Color3.fromRGB(220, 180, 255)
loadConfigBtn.Font = Enum.Font.SourceSansBold
loadConfigBtn.TextSize = 15
loadConfigBtn.Parent = masterScroll

local loadConfigCorner = Instance.new("UICorner")
loadConfigCorner.CornerRadius = UDim.new(0, 5)
loadConfigCorner.Parent = loadConfigBtn

local deleteConfigBtn = Instance.new("TextButton")
deleteConfigBtn.Size = UDim2.new(1, -26, 0, 30)
deleteConfigBtn.Position = UDim2.new(0, 10, 0, 185)
deleteConfigBtn.BackgroundColor3 = Color3.fromRGB(95, 30, 175)
deleteConfigBtn.Text = "Delete config"
deleteConfigBtn.TextColor3 = Color3.fromRGB(220, 180, 255)
deleteConfigBtn.Font = Enum.Font.SourceSansBold
deleteConfigBtn.TextSize = 14
deleteConfigBtn.Parent = masterScroll

local deleteConfigCorner = Instance.new("UICorner")
deleteConfigCorner.CornerRadius = UDim.new(0, 5)
deleteConfigCorner.Parent = deleteConfigBtn

----------------------------------------------------
-- CONFIG MANAGER MINI ZONE
----------------------------------------------------
local miniMenuHeader = Instance.new("TextLabel")
miniMenuHeader.Size = UDim2.new(1, -26, 0, 20)
miniMenuHeader.Position = UDim2.new(0, 10, 0, 225)
miniMenuHeader.BackgroundTransparency = 1
miniMenuHeader.Text = "Saved Config Files Manager:"
miniMenuHeader.TextColor3 = Color3.fromRGB(140, 80, 210)
miniMenuHeader.Font = Enum.Font.SourceSansBold
miniMenuHeader.TextSize = 14
miniMenuHeader.TextXAlignment = Enum.TextXAlignment.Left
miniMenuHeader.Parent = masterScroll

local miniMenuScroll = Instance.new("ScrollingFrame")
miniMenuScroll.Size = UDim2.new(1, -26, 0, 75)
miniMenuScroll.Position = UDim2.new(0, 10, 0, 245)
miniMenuScroll.BackgroundColor3 = Color3.fromRGB(15, 5, 25)
miniMenuScroll.BorderSizePixel = 0
miniMenuScroll.ScrollBarThickness = 5
miniMenuScroll.ScrollBarImageColor3 = Color3.fromRGB(95, 30, 175)
miniMenuScroll.ScrollingDirection = Enum.ScrollingDirection.Y
miniMenuScroll.Parent = masterScroll

local miniMenuCorner = Instance.new("UICorner")
miniMenuCorner.CornerRadius = UDim.new(0, 6)
miniMenuCorner.Parent = miniMenuScroll

local miniMenuLayout = Instance.new("UIListLayout")
miniMenuLayout.Parent = miniMenuScroll
miniMenuLayout.SortOrder = Enum.SortOrder.LayoutOrder
miniMenuLayout.Padding = UDim.new(0, 3)

miniMenuLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
    miniMenuScroll.CanvasSize = UDim2.new(0, 0, 0, miniMenuLayout.AbsoluteContentSize.Y + 5)
end)

----------------------------------------------------
-- LOCATIONS CONTAINER
----------------------------------------------------
local tpHeader = Instance.new("TextLabel")
tpHeader.Size = UDim2.new(1, -26, 0, 20)
tpHeader.Position = UDim2.new(0, 10, 0, 330)
tpHeader.BackgroundTransparency = 1
tpHeader.Text = "Saved Locations Points:"
tpHeader.TextColor3 = Color3.fromRGB(140, 80, 210)
tpHeader.Font = Enum.Font.SourceSansBold
tpHeader.TextSize = 14
tpHeader.TextXAlignment = Enum.TextXAlignment.Left
tpHeader.Parent = masterScroll

local pointsScroll = Instance.new("ScrollingFrame")
pointsScroll.Size = UDim2.new(1, -26, 0, 160)
pointsScroll.Position = UDim2.new(0, 10, 0, 350)
pointsScroll.BackgroundColor3 = Color3.fromRGB(15, 5, 25)
pointsScroll.BorderSizePixel = 0
pointsScroll.ScrollBarThickness = 6
pointsScroll.ScrollBarImageColor3 = Color3.fromRGB(110, 35, 200)
pointsScroll.ScrollingDirection = Enum.ScrollingDirection.Y
pointsScroll.Parent = masterScroll

local pointsCorner = Instance.new("UICorner")
pointsCorner.CornerRadius = UDim.new(0, 6)
pointsCorner.Parent = pointsScroll

local listLayout = Instance.new("UIListLayout")
listLayout.Parent = pointsScroll
listLayout.SortOrder = Enum.SortOrder.LayoutOrder
listLayout.Padding = UDim.new(0, 5)

listLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
    pointsScroll.CanvasSize = UDim2.new(0, 0, 0, listLayout.AbsoluteContentSize.Y + 10)
end)

----------------------------------------------------
-- CORE IMPLEMENTATIONS
----------------------------------------------------
local function clearListUI()
    for _, child in ipairs(pointsScroll:GetChildren()) do
        if child:IsA("Frame") then child:Destroy() end
    end
end

local function createLocationRow(name, position)
    local rowFrame = Instance.new("Frame")
    rowFrame.Size = UDim2.new(1, -8, 0, 40)
    rowFrame.BackgroundColor3 = Color3.fromRGB(35, 15, 55)
    rowFrame.Name = name
    rowFrame.Parent = pointsScroll
    
    local rowCorner = Instance.new("UICorner")
    rowCorner.CornerRadius = UDim.new(0, 5)
    rowCorner.Parent = rowFrame

    local locationLabel = Instance.new("TextLabel")
    locationLabel.Size = UDim2.new(0.4, 0, 1, 0)
    locationLabel.Position = UDim2.new(0, 10, 0, 0)
    locationLabel.BackgroundTransparency = 1
    locationLabel.Text = name
    locationLabel.TextColor3 = Color3.fromRGB(185, 115, 255)
    locationLabel.Font = Enum.Font.SourceSans
    locationLabel.TextSize = 16
    locationLabel.TextXAlignment = Enum.TextXAlignment.Left
    locationLabel.Parent = rowFrame

    local tpButton = Instance.new("TextButton")
    tpButton.Size = UDim2.new(0, 50, 0, 30)
    tpButton.Position = UDim2.new(1, -125, 0, 5)
    tpButton.BackgroundColor3 = Color3.fromRGB(90, 25, 160)
    tpButton.Text = "TP"
    tpButton.TextColor3 = Color3.fromRGB(220, 180, 255)
    tpButton.Font = Enum.Font.SourceSansBold
    tpButton.TextSize = 14
    tpButton.Parent = rowFrame

    local tpCorner = Instance.new("UICorner")
    tpCorner.CornerRadius = UDim.new(0, 4)
    tpCorner.Parent = tpButton

    local renameBtn = Instance.new("TextButton")
    renameBtn.Size = UDim2.new(0, 32, 0, 30)
    renameBtn.Position = UDim2.new(1, -70, 0, 5)
    renameBtn.BackgroundColor3 = Color3.fromRGB(60, 25, 110)
    renameBtn.Text = "✏️"
    renameBtn.TextColor3 = Color3.fromRGB(255, 255, 255)
    renameBtn.Font = Enum.Font.SourceSansBold
    renameBtn.TextSize = 14
    renameBtn.Parent = rowFrame

    local renCorner = Instance.new("UICorner")
    renCorner.CornerRadius = UDim.new(0, 4)
    renCorner.Parent = renameBtn

    local delButton = Instance.new("TextButton")
    delButton.Size = UDim2.new(0, 32, 0, 30)
    delButton.Position = UDim2.new(1, -35, 0, 5)
    delButton.BackgroundColor3 = Color3.fromRGB(130, 20, 80)
    delButton.Text = "🗑️"
    delButton.TextColor3 = Color3.fromRGB(255, 255, 255)
    delButton.Font = Enum.Font.SourceSansBold
    delButton.TextSize = 14
    delButton.Parent = rowFrame

    local delCorner = Instance.new("UICorner")
    delCorner.CornerRadius = UDim.new(0, 4)
    delCorner.Parent = delButton

    tpButton.MouseButton1Click:Connect(function()
        local character = player.Character
        if character and character:FindFirstChild("HumanoidRootPart") then
            character.HumanoidRootPart.CFrame = CFrame.new(position)
        end
    end)

    -- FIXED: Окошко гарантированно вылетает, замораживая меню!
    renameBtn.MouseButton1Click:Connect(function()
        openPrompt(name, function(newName)
            if newName ~= "" and not savedPositions[newName] then
                savedPositions[newName] = position
                savedPositions[name] = nil
                locationLabel.Text = newName
                rowFrame.Name = newName
                name = newName
            end
        end)
    end)

    delButton.MouseButton1Click:Connect(function()
        savedPositions[name] = nil
        rowFrame:Destroy()
    end)
end

-- WORKSPACE SAVED CONFIG EXPLORER
local lastScannedFiles = ""
local function scanWorkspaceConfigFiles()
    local files = listfiles("")
    local currentFilesString = table.concat(files, ",")
    if currentFilesString == lastScannedFiles then return end
    lastScannedFiles = currentFilesString

    for _, child in ipairs(miniMenuScroll:GetChildren()) do
        if child:IsA("Frame") or child:IsA("TextLabel") then child:Destroy() end
    end
    
    local found = false
    for _, path in ipairs(files) do
        if path:match("_tphub%.json$") then
            found = true
            local cleanName = path:gsub("_tphub%.json", ""):gsub("^%./", ""):gsub("^workspace/", ""):gsub("^files/", "")
            
            local fileFrame = Instance.new("Frame")
            fileFrame.Size = UDim2.new(1, -5, 0, 25)
            fileFrame.BackgroundTransparency = 1
            fileFrame.Parent = miniMenuScroll

            local fileLabel = Instance.new("TextLabel")
            fileLabel.Size = UDim2.new(1, -45, 1, 0)
            fileLabel.BackgroundTransparency = 1
            fileLabel.Text = "  📄 " .. cleanName
            fileLabel.TextColor3 = Color3.fromRGB(185, 115, 255)
            fileLabel.Font = Enum.Font.SourceSans
            fileLabel.TextSize = 14
            fileLabel.TextXAlignment = Enum.TextXAlignment.Left
            fileLabel.Parent = fileFrame

            local renameFileBtn = Instance.new("TextButton")
            renameFileBtn.Size = UDim2.new(0, 22, 0, 20)
            renameFileBtn.Position = UDim2.new(1, -25, 0, 2)
            renameFileBtn.BackgroundColor3 = Color3.fromRGB(45, 20, 70)
            renameFileBtn.Text = "✏️"
            renameFileBtn.TextColor3 = Color3.fromRGB(255, 255, 255)
            renameFileBtn.Font = Enum.Font.SourceSansBold
            renameFileBtn.TextSize = 11
            renameFileBtn.Parent = fileFrame
            
            local rfCorner = Instance.new("UICorner")
            rfCorner.CornerRadius = UDim.new(0, 3)
            rfCorner.Parent = renameFileBtn

            -- FIXED: Окошко гарантированно вылетает для файлов конфигураций!
            renameFileBtn.MouseButton1Click:Connect(function()
                openPrompt(cleanName, function(newConfigName)
                    local oldPath = cleanName .. "_tphub.json"
                    local newPath = newConfigName .. "_tphub.json"
                    if isfile(oldPath) and not isfile(newPath) then
                        local content = readfile(oldPath)
                        writefile(newPath, content)
                        delfile(oldPath)
                        lastScannedFiles = "" 
                        scanWorkspaceConfigFiles()
                    end
                end)
            end)
        end
    end
    
    if not found then
        local emptyLabel = Instance.new("TextLabel")
        emptyLabel.Size = UDim2.new(1, 0, 0, 20)
        emptyLabel.BackgroundTransparency = 1
        emptyLabel.Text = "  No saved configs found"
        emptyLabel.TextColor3 = Color3.fromRGB(110, 60, 160)
        emptyLabel.Font = Enum.Font.SourceSansItalic
        emptyLabel.TextSize = 13
        emptyLabel.TextXAlignment = Enum.TextXAlignment.Left
        emptyLabel.Parent = miniMenuScroll
    end
end

local HttpService = game:GetService("HttpService")

-- SAVE CONFIG ENGINE
saveConfigBtn.MouseButton1Click:Connect(function()
    local cfgName = configInput.Text:match("^%s*(.-)%s*$")
    if cfgName == "" then return end
    
    local exportData = {}
    for name, pos in pairs(savedPositions) do
        exportData[name] = {pos.X, pos.Y, pos.Z}
    end
    
    local success, jsonStr = pcall(function() return HttpService:JSONEncode(exportData) end)
    if success then
        writefile(cfgName .. "_tphub.json", jsonStr)
        configInput.Text = ""
        configInput.PlaceholderText = "Saved!"
        lastScannedFiles = "" 
        scanWorkspaceConfigFiles()
        task.delay(1.5, function() configInput.PlaceholderText = "Enter config name (e.g. birds)..." end)
    end
end)

-- LOAD CONFIG ENGINE
loadConfigBtn.MouseButton1Click:Connect(function()
    local cfgName = configInput.Text:match("^%s*(.-)%s*$")
    if cfgName == "" then return end
    
    local fileName = cfgName .. "_tphub.json"
    if not isfile(fileName) then return end
    
    local fileContent = readfile(fileName)
    local success, importData = pcall(function() return HttpService:JSONDecode(fileContent) end)
    
    if success and importData then
        savedPositions = {}
        clearListUI()
        for name, coords in pairs(importData) do
            local vectorPos = Vector3.new(coords, coords, coords)
            savedPositions[name] = vectorPos
            createLocationRow(name, vectorPos)
        end
        configInput.Text = ""
    end
end)

-- DELETE CONFIG ENGINE
deleteConfigBtn.MouseButton1Click:Connect(function()
    local cfgName = configInput.Text:match("^%s*(.-)%s*$")
    if cfgName == "" then return end
    
    local fileName = cfgName .. "_tphub.json"
    if isfile(fileName) then
        delfile(fileName)
        configInput.Text = ""
        lastScannedFiles = "" 
        scanWorkspaceConfigFiles()
    end
end)

-- Live Location Creator
saveButton.MouseButton1Click:Connect(function()
    local text = nameInput.Text:match("^%s*(.-)%s*$")
    
    if text == "" or savedPositions[text] then
        if savedPositions[text] then
            nameInput.Text = ""
            nameInput.PlaceholderText = "Name already taken!"
            nameInput.PlaceholderColor3 = Color3.fromRGB(185, 115, 255)
            task.delay(2, function() 
                nameInput.PlaceholderText = "Enter location name..." 
                nameInput.PlaceholderColor3 = Color3.fromRGB(110, 60, 160)
            end)
        end
        return 
    end

    local character = player.Character
    if character and character:FindFirstChild("HumanoidRootPart") then
        local currentPos = character.HumanoidRootPart.Position
        
        for savedName, savedPos in pairs(savedPositions) do
            if (currentPos - savedPos).Magnitude < 1.5 then
                nameInput.Text = ""
                nameInput.PlaceholderText = "Position already saved!"
                nameInput.PlaceholderColor3 = Color3.fromRGB(185, 115, 255)
                task.delay(2, function() 
                    nameInput.PlaceholderText = "Enter location name..." 
                    nameInput.PlaceholderColor3 = Color3.fromRGB(110, 60, 160)
                end)
                return
            end
        end

        savedPositions[text] = currentPos
        createLocationRow(text, currentPos)
        nameInput.Text = ""
    end
end)

-- Minimize/Maximize calculation
toggleButton.MouseButton1Click:Connect(function()
    isMinimized = not isMinimized
    if isMinimized then
        masterScroll.Visible = false
        mainFrame.Size = UDim2.new(0, 330, 0, 40)
        toggleButton.Text = "▲"
    else
        masterScroll.Visible = true
        mainFrame.Size = UDim2.new(0, 330, 0, 430)
        toggleButton.Text = "▼"
    end
end)

-- Run background scanners loop thread safely
scanWorkspaceConfigFiles()
task.spawn(function()
    while true do
        task.wait(2)
        pcall(scanWorkspaceConfigFiles)
    end
end)

Features & Information

The script has: creating configs create points viewing configs and much more

Community Comments (0)

No comments yet for this script.

More Scripts for Universal Scripts