local HttpService = game:GetService("HttpService") local Players = game:GetService("Players") local player = Players.LocalPlayer if not player then warn("[Globle Internal] LocalPlayer missing.") return end local playerGui = player:FindFirstChildOfClass("PlayerGui") or player:WaitForChild("PlayerGui") local BASE_URL = "http://127.0.0.1:5000" local HEARTBEAT_INTERVAL = 1.0 local CONNECT_RETRY_INTERVAL = 1.0 local requestFn = request or http_request or (http and http.request) or (syn and syn.request) if not requestFn then warn("[Globle Internal] No supported HTTP request function found in this executor.") return end local clientId = "roblox-" .. HttpService:GenerateGUID(false) local connected = false local running = false local fullscreenReady = false local destroyed = false local function createUi() local gui = Instance.new("ScreenGui") gui.Name = "GlobleBridgeGui" gui.ResetOnSpawn = false gui.IgnoreGuiInset = false gui.Parent = playerGui local frame = Instance.new("Frame") frame.Name = "Root" frame.Parent = gui frame.Size = UDim2.new(0, 270, 0, 120) frame.Position = UDim2.new(0, 12, 0, 12) frame.BackgroundColor3 = Color3.fromRGB(23, 27, 34) frame.BorderSizePixel = 0 local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 8) corner.Parent = frame local title = Instance.new("TextLabel") title.Name = "Title" title.Parent = frame title.BackgroundTransparency = 1 title.Position = UDim2.new(0, 10, 0, 8) title.Size = UDim2.new(1, -20, 0, 22) title.Font = Enum.Font.GothamBold title.TextSize = 14 title.TextColor3 = Color3.fromRGB(255, 255, 255) title.TextXAlignment = Enum.TextXAlignment.Left title.Text = "Globle Bridge" local status = Instance.new("TextLabel") status.Name = "Status" status.Parent = frame status.BackgroundTransparency = 1 status.Position = UDim2.new(0, 10, 0, 36) status.Size = UDim2.new(1, -20, 0, 34) status.Font = Enum.Font.Gotham status.TextSize = 12 status.TextWrapped = true status.TextXAlignment = Enum.TextXAlignment.Left status.TextYAlignment = Enum.TextYAlignment.Top status.TextColor3 = Color3.fromRGB(209, 214, 221) status.Text = "Waiting for external to connect" local function makeButton(name, text, x, color) local button = Instance.new("TextButton") button.Name = name button.Parent = frame button.Size = UDim2.new(0, 118, 0, 30) button.Position = UDim2.new(0, x, 0, 78) button.BackgroundColor3 = color button.BorderSizePixel = 0 button.Text = text button.Font = Enum.Font.GothamBold button.TextSize = 12 button.TextColor3 = Color3.fromRGB(255, 255, 255) local bCorner = Instance.new("UICorner") bCorner.CornerRadius = UDim.new(0, 6) bCorner.Parent = button return button end local startButton = makeButton("StartButton", "Start", 10, Color3.fromRGB(34, 146, 92)) local stopButton = makeButton("StopButton", "Stop", 142, Color3.fromRGB(166, 59, 59)) return { gui = gui, status = status, startButton = startButton, stopButton = stopButton, } end local ui = createUi() local function setStatus(text) ui.status.Text = text end local function setButtonEnabled(button, enabled) button.AutoButtonColor = enabled button.Active = enabled button.TextTransparency = enabled and 0 or 0.35 button.BackgroundTransparency = enabled and 0 or 0.2 end local function updateButtons() local canStart = connected and fullscreenReady and (not running) local canStop = connected and running setButtonEnabled(ui.startButton, canStart) setButtonEnabled(ui.stopButton, canStop) end local function parseBody(response) local body = response and response.Body if not body or body == "" then return nil end local ok, decoded = pcall(function() return HttpService:JSONDecode(body) end) if ok then return decoded end return nil end local function post(path, payload) local body = "" if payload then body = HttpService:JSONEncode(payload) end local ok, response = pcall(function() return requestFn({ Url = BASE_URL .. path, Method = "POST", Headers = { ["Content-Type"] = "application/json", }, Body = body, }) end) if not ok or not response then return false, nil end local statusCode = tonumber(response.StatusCode or response.Status or 0) or 0 if statusCode < 200 or statusCode >= 300 then return false, parseBody(response) end return true, parseBody(response) end local function connectLoop() while not destroyed do if not connected then setStatus("Waiting for external to connect") local ok, data = post("/client/hello", { client_id = clientId, }) if ok then connected = true running = false fullscreenReady = false local message = "Connected. Ready" if data and data.state and data.state.status_message then message = tostring(data.state.status_message) end if data and data.state and type(data.state.roblox_fullscreen_ready) == "boolean" then fullscreenReady = data.state.roblox_fullscreen_ready end setStatus(message) updateButtons() end end task.wait(CONNECT_RETRY_INTERVAL) end end local function heartbeatLoop() while not destroyed do if connected then local ok, data = post("/client/heartbeat", { client_id = clientId, }) if not ok then connected = false running = false fullscreenReady = false setStatus("External offline. Waiting for reconnect") updateButtons() else if data and type(data.running) == "boolean" then running = data.running end if data and type(data.roblox_fullscreen_ready) == "boolean" then fullscreenReady = data.roblox_fullscreen_ready end local statusMessage = "Connected" if data and data.status_message then statusMessage = tostring(data.status_message) end setStatus(statusMessage) updateButtons() end end task.wait(HEARTBEAT_INTERVAL) end end ui.startButton.MouseButton1Click:Connect(function() if not connected then return end local ok, data = post("/control/start", { source = "roblox", }) if ok then running = true if data and data.state and type(data.state.roblox_fullscreen_ready) == "boolean" then fullscreenReady = data.state.roblox_fullscreen_ready end local message = "Running" if data and data.message then message = tostring(data.message) end setStatus(message) else if data and data.state and type(data.state.roblox_fullscreen_ready) == "boolean" then fullscreenReady = data.state.roblox_fullscreen_ready end local message = "Start failed" if data and data.message then message = tostring(data.message) end setStatus(message) end updateButtons() end) ui.stopButton.MouseButton1Click:Connect(function() if not connected then return end local ok, data = post("/control/stop", { reason = "Stopped from Roblox script", }) if ok then running = false if data and data.state and type(data.state.roblox_fullscreen_ready) == "boolean" then fullscreenReady = data.state.roblox_fullscreen_ready end local message = "Stopped" if data and data.message then message = tostring(data.message) end setStatus(message) else if data and data.state and type(data.state.roblox_fullscreen_ready) == "boolean" then fullscreenReady = data.state.roblox_fullscreen_ready end local message = "Stop failed" if data and data.message then message = tostring(data.message) end setStatus(message) end updateButtons() end) updateButtons() setStatus("Waiting for external to connect") task.spawn(connectLoop) task.spawn(heartbeatLoop) ui.gui.Destroying:Connect(function() destroyed = true if connected then pcall(function() post("/client/disconnect", { client_id = clientId, }) end) end end) print("[Globle Internal] Bridge loaded. Waiting for external.")