--[[ GirlMaker Hub — loader Authorization, game routing and delivery of GirlMaker-owned payloads. Contains no secrets, no game routing table and no anti-detection logic. Any Lua delivered to a client can be copied: obfuscation adds friction, not absolute protection. ]] local LOADER_VERSION = "1.0.0" local PROTOCOL_VERSION = 1 -- Injected from the server environment when this file is served. local API_BASE = "https://cdn.girlmaker.su" local SITE_URL = "girlmaker.su" -- Turn this on only in a local preview copy. It never calls the key API, -- changes the saved license or executes a payload. local UI_PREVIEW_MODE = false local BRAND = "GirlMaker" local COLOR_BG = Color3.fromRGB(14, 11, 17) local COLOR_SURFACE = Color3.fromRGB(29, 24, 32) local COLOR_LINE = Color3.fromRGB(52, 43, 57) local COLOR_ACCENT = Color3.fromRGB(203, 183, 255) local COLOR_TEXT = Color3.fromRGB(247, 242, 247) local COLOR_MUTED = Color3.fromRGB(201, 191, 202) local COLOR_SUBTLE = Color3.fromRGB(160, 149, 162) local COLOR_SUCCESS = Color3.fromRGB(141, 216, 186) local COLOR_WARNING = Color3.fromRGB(239, 196, 126) local COLOR_DANGER = Color3.fromRGB(239, 132, 154) -- =========================================================================== -- Capability adapter -- =========================================================================== local function getRequestFunction() if syn and syn.request then return syn.request end if http_request then return http_request end if request then return request end return nil end local function hasClipboard() return type(setclipboard) == "function" end local function canOpenUrl() return false -- executors rarely expose a browser opener; kept as a hook end local function hasFileSystem() return type(writefile) == "function" and type(readfile) == "function" and type(isfile) == "function" end local function hasTeleportQueue() return type(queue_on_teleport) == "function" end -- =========================================================================== -- Filesystem helpers (optional capability) -- =========================================================================== local FS_DIR = "girlmaker" local INSTALL_FILE = FS_DIR .. "/install_id.txt" local LICENSE_FILE = FS_DIR .. "/license.txt" local function fsWrite(name, content) if not hasFileSystem() then return false end local ok = pcall(function() if makefolder then pcall(makefolder, FS_DIR) end writefile(name, content) end) return ok end local function fsRead(name) if not hasFileSystem() then return nil end local ok, content = pcall(function() if isfile(name) then return readfile(name) end return nil end) if ok then return content end return nil end -- =========================================================================== -- HTTP with bounded retries (exponential backoff + jitter) -- =========================================================================== local function rawRequest(method, url, headers, body) local requestFn = getRequestFunction() if not requestFn then return nil, "This executor does not expose an HTTP request API." end local ok, response = pcall(requestFn, { Method = method, Url = url, Headers = headers or {}, Body = body, }) if not ok or type(response) ~= "table" then return nil, "Request failed." end -- Executors disagree on response field names; normalize once here. response.StatusCode = response.StatusCode or response.status_code or response.status or 0 response.Body = response.Body or response.body or "" return response end local function sleep(seconds) if task and task.wait then task.wait(seconds) end end local function withRetries(fn, maxAttempts, baseDelaySeconds) maxAttempts = maxAttempts or 3 baseDelaySeconds = baseDelaySeconds or 0.8 local lastError for attempt = 1, maxAttempts do local ok, result = fn() if ok then return true, result end lastError = result if attempt < maxAttempts then local jitter = math.random() * 0.4 sleep(baseDelaySeconds * (2 ^ (attempt - 1)) + jitter) end end return false, lastError end local HttpService = game:GetService("HttpService") local function apiJson(method, path, payload) local ok, response = withRetries(function() local res, err = rawRequest(method, API_BASE .. path, { ["Content-Type"] = "application/json", ["Accept"] = "application/json", }, payload and HttpService:JSONEncode(payload) or nil) if not res then return false, err end if res.StatusCode >= 500 then return false, "server error " .. tostring(res.StatusCode) end if res.StatusCode >= 400 then -- Client errors are final: surface the API's own message -- (e.g. "Too many requests" for RATE_LIMITED). local message = "HTTP " .. tostring(res.StatusCode) pcall(function() local errBody = HttpService:JSONDecode(res.Body) if errBody and errBody.error and errBody.error.message then message = tostring(errBody.error.message) end end) return false, message end return true, res end, 2) if not ok then return nil, response end local decoded local parseOk = pcall(function() decoded = HttpService:JSONDecode(response.Body) end) if not parseOk or type(decoded) ~= "table" then return nil, "Malformed server response." end return decoded, nil end local function httpGet(url) local ok, response = withRetries(function() local res, err = rawRequest("GET", url, { ["Accept"] = "*/*" }, nil) if not res then return false, err end if res.StatusCode ~= 200 then return false, "HTTP " .. tostring(res.StatusCode) end return true, res end) if not ok then return nil, response end return response.Body end -- =========================================================================== -- Identity -- =========================================================================== local function getInstallId() local saved = fsRead(INSTALL_FILE) if saved and #saved >= 8 then return saved:gsub("%s", "") end local id pcall(function() id = HttpService:GenerateGUID(false) .. "-" .. tostring(math.floor(tick() * 1000)) end) if not id or #id < 8 then id = "install-" .. tostring(math.random(1e9, 9e9)) .. "-" .. tostring(math.floor(tick() * 1000)) end fsWrite(INSTALL_FILE, id) return id end local sessionLicenseToken = nil local function saveLicenseToken(token) sessionLicenseToken = token fsWrite(LICENSE_FILE, token) end local function loadLicenseToken() local token = fsRead(LICENSE_FILE) if token and #token >= 16 then return token:gsub("%s", "") end -- Executors without a filesystem: keep the license for this session only. if sessionLicenseToken and #sessionLicenseToken >= 16 then return sessionLicenseToken end return nil end local function clearLicenseToken() sessionLicenseToken = nil if hasFileSystem() then pcall(function() if delfile and isfile(LICENSE_FILE) then delfile(LICENSE_FILE) else writefile(LICENSE_FILE, "") end end) end end -- =========================================================================== -- Bootstrap -- =========================================================================== local function waitForGame() if not game:IsLoaded() then game.Loaded:Wait() end end local function callBootstrap(installId) local payload = { protocolVersion = PROTOCOL_VERSION, loaderVersion = LOADER_VERSION, universeId = tostring(game.GameId), placeId = tostring(game.PlaceId), installId = installId, licenseToken = loadLicenseToken(), capabilities = { httpRequest = getRequestFunction() ~= nil, fileSystem = hasFileSystem(), clipboard = hasClipboard(), openBrowser = canOpenUrl(), queueOnTeleport = hasTeleportQueue(), }, } local data, err = apiJson("POST", "/api/v1/bootstrap", payload) if not data then return nil, err end if type(data.status) ~= "string" then return nil, "Server response is missing a status field." end return data, nil end local function createUnlockFlow(installId) local data, err = apiJson("POST", "/api/v1/unlock/flows", { protocolVersion = PROTOCOL_VERSION, installId = installId, placeId = tostring(game.PlaceId), universeId = tostring(game.GameId), }) if not data then return nil, err end if type(data.browserUrl) ~= "string" or type(data.pollToken) ~= "string" then return nil, "Flow response is missing required fields." end return data, nil end local function apiJsonPoll(flowId, pollToken) local ok, response = withRetries(function() local res, err2 = rawRequest( "GET", API_BASE .. "/api/v1/unlock/flows/" .. flowId .. "/status", { ["x-poll-token"] = pollToken, ["Accept"] = "application/json" }, nil ) if not res then return false, err2 end if res.StatusCode ~= 200 and res.StatusCode ~= 403 and res.StatusCode ~= 410 then return false, "HTTP " .. tostring(res.StatusCode) end return true, res end, 1) if not ok then return nil, response end local decoded pcall(function() decoded = HttpService:JSONDecode(response.Body) end) if type(decoded) ~= "table" then return nil, "Malformed status response." end return decoded, nil end local function pollFlowStatus(flowId, pollToken) return apiJsonPoll(flowId, pollToken) end local function redeemKey(installId, key) local data, err = apiJson("POST", "/api/v1/keys/redeem", { installId = installId, key = key, }) if not data then return nil, err end if type(data.licenseToken) ~= "string" then local message = "Redeem failed." if data.error and data.error.message then message = data.error.message end return nil, message end return data, nil end -- =========================================================================== -- Key UI (standalone; loads nothing else before authorization) -- =========================================================================== local function makeLabel(parent, text, size, position, color, alignment, fontSize) local label = Instance.new("TextLabel") label.Size = size label.Position = position label.BackgroundTransparency = 1 label.Text = text label.TextColor3 = color label.Font = Enum.Font.Gotham label.TextSize = fontSize or 14 label.TextXAlignment = alignment or Enum.TextXAlignment.Left label.TextYAlignment = Enum.TextYAlignment.Center label.TextWrapped = true label.Parent = parent return label end local function makeButton(parent, text, size, position, accent) local button = Instance.new("TextButton") button.Size = size button.Position = position button.Text = text button.Font = Enum.Font.GothamBold button.TextSize = 13 button.BorderSizePixel = 0 button.AutoButtonColor = false if accent then button.BackgroundColor3 = COLOR_ACCENT button.TextColor3 = COLOR_BG else button.BackgroundColor3 = COLOR_SURFACE button.TextColor3 = COLOR_TEXT end local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 10) corner.Parent = button button.Parent = parent return button end local function showKeyUi(opts) -- opts: { browserUrl, flowId, pollToken, installId, onRedeemed } local player = game:GetService("Players").LocalPlayer -- Remove a previous instance before showing a new one. do local containers = { player and player:FindFirstChildOfClass("PlayerGui"), game:GetService("CoreGui") } for _, container in ipairs(containers) do if container then local old = container:FindFirstChild("GirlMakerKey") if old then old:Destroy() end end end end local camera = workspace.CurrentCamera local viewport = camera and camera.ViewportSize local guiWidth = math.min(380, (viewport and viewport.X or 380) - 16) local gui = Instance.new("ScreenGui") gui.Name = "GirlMakerKey" gui.ResetOnSpawn = false local frame = Instance.new("Frame") frame.Size = UDim2.fromOffset(guiWidth, 330) frame.Position = UDim2.new(0.5, -math.floor(guiWidth / 2), 0.5, -165) frame.BackgroundColor3 = COLOR_BG frame.BorderSizePixel = 0 frame.Active = true frame.Draggable = true frame.Parent = gui local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 14) corner.Parent = frame local stroke = Instance.new("UIStroke") stroke.Color = COLOR_ACCENT stroke.Transparency = 0.55 stroke.Parent = frame makeLabel(frame, BRAND, UDim2.new(1, -28, 0, 26), UDim2.fromOffset(16, 14), COLOR_TEXT, nil, 18).Font = Enum.Font.GothamBold local statusLabel = makeLabel(frame, opts.status or "Tap Get Key to start", UDim2.new(1, -28, 0, 18), UDim2.fromOffset(16, 44), COLOR_ACCENT, nil, 13) makeLabel(frame, "Get a key, then paste it below.", UDim2.new(1, -28, 0, 16), UDim2.fromOffset(16, 70), COLOR_MUTED, nil, 12) local linkBox = Instance.new("TextBox") linkBox.Size = UDim2.new(1, -32, 0, 34) linkBox.Position = UDim2.fromOffset(16, 92) linkBox.BackgroundColor3 = Color3.fromRGB(10, 13, 19) linkBox.BorderSizePixel = 0 linkBox.Text = opts.browserUrl linkBox.TextColor3 = COLOR_MUTED linkBox.PlaceholderText = "Hold here to copy the link" linkBox.TextEditable = false linkBox.Font = Enum.Font.GothamMedium linkBox.TextSize = 12 linkBox.TextTruncate = Enum.TextTruncate.AtEnd linkBox.Parent = frame linkBox.Visible = false local linkCorner = Instance.new("UICorner") linkCorner.CornerRadius = UDim.new(0, 8) linkCorner.Parent = linkBox local copyButton = makeButton(frame, "Get Key", UDim2.new(1, -32, 0, 36), UDim2.fromOffset(16, 92), true) copyButton.MouseButton1Click:Connect(function() if hasClipboard() then setclipboard(opts.browserUrl) copyButton.Text = "Copied! Open your browser" statusLabel.Text = "Paste the copied link in your browser" task.delay(2, function() if copyButton.Parent then copyButton.Text = "Get Key" end end) else copyButton.Visible = false linkBox.Visible = true linkBox.TextEditable = true linkBox:CaptureFocus() linkBox.SelectionStart = 1 linkBox.CursorPosition = #linkBox.Text + 1 statusLabel.Text = "Hold the link above and copy it" end end) local keyBox = Instance.new("TextBox") keyBox.Size = UDim2.new(1, -32, 0, 34) keyBox.Position = UDim2.fromOffset(16, 140) keyBox.BackgroundColor3 = Color3.fromRGB(10, 13, 19) keyBox.BorderSizePixel = 0 keyBox.Text = "" keyBox.PlaceholderText = "Paste your key here" keyBox.TextColor3 = COLOR_TEXT keyBox.Font = Enum.Font.GothamMedium keyBox.TextSize = 13 keyBox.Parent = frame local keyCorner = Instance.new("UICorner") keyCorner.CornerRadius = UDim.new(0, 8) keyCorner.Parent = keyBox local redeemButton = makeButton(frame, "Use Key", UDim2.new(1, -32, 0, 34), UDim2.fromOffset(16, 184), true) local checkButton = makeButton(frame, "I finished", UDim2.new(1, -32, 0, 28), UDim2.fromOffset(16, 226), false) local closeButton = makeButton(frame, "Close", UDim2.fromOffset(70, 24), UDim2.new(1, -86, 1, -32), false) local closed = false closeButton.MouseButton1Click:Connect(function() closed = true gui:Destroy() end) local function tryRedeem(key) if not key or #key < 6 then statusLabel.Text = "Paste your key first" return end statusLabel.Text = "Checking your key…" local data, err = redeemKey(opts.installId, key) if not data then statusLabel.Text = "That key did not work. Copy it again." warn("[" .. BRAND .. "] Key redeem failed: " .. tostring(err)) return end saveLicenseToken(data.licenseToken) statusLabel.Text = "Done! Starting your script…" closed = true gui:Destroy() opts.onRedeemed(data) end redeemButton.MouseButton1Click:Connect(function() tryRedeem(keyBox.Text) end) keyBox.FocusLost:Connect(function(enterPressed) if enterPressed then tryRedeem(keyBox.Text) end end) checkButton.MouseButton1Click:Connect(function() statusLabel.Text = "Checking…" local status = pollFlowStatus(opts.flowId, opts.pollToken) if status and status.phase == "completed" and status.key then keyBox.Text = status.key tryRedeem(status.key) elseif status and status.phase == "completed" then statusLabel.Text = "Done! Paste the key from the website." elseif status and status.error then statusLabel.Text = "Something went wrong. Try again." else statusLabel.Text = "Not ready yet. Finish the key page first." end end) gui.Parent = (player and player:FindFirstChildOfClass("PlayerGui")) or game:GetService("CoreGui") -- Background poller: auto-fills the key once issued (loader channel reveal). task.spawn(function() while not closed do sleep(5) if closed then break end local ok, status = pcall(pollFlowStatus, opts.flowId, opts.pollToken) if ok and status and status.phase == "completed" and status.key then if not closed then keyBox.Text = status.key tryRedeem(status.key) end break end if ok and status and status.phase == "expired" then statusLabel.Text = "This key page expired. Run GirlMaker again." break end end end) return gui end -- Compact one-screen UI. The older form above remains only as a fallback for -- executors that fail to create one of the newer visual primitives. local function showMinimalKeyUi(opts) local Players = game:GetService("Players") local MarketplaceService = game:GetService("MarketplaceService") local player = Players.LocalPlayer local playerGui = player and player:FindFirstChildOfClass("PlayerGui") local coreGui = game:GetService("CoreGui") local hiddenUi = nil if type(gethui) == "function" then local ok, value = pcall(gethui) if ok then hiddenUi = value end end for _, container in ipairs({ playerGui, coreGui, hiddenUi }) do if container then for _, name in ipairs({ "GirlMakerKey", "GirlMakerMinimal", "GirlMakerBoot" }) do local old = container:FindFirstChild(name) if old then old:Destroy() end end end end local viewport = workspace.CurrentCamera and workspace.CurrentCamera.ViewportSize local width = math.max(306, math.min(430, (viewport and viewport.X or 430) - 20)) local height = 278 local gui = Instance.new("ScreenGui") gui.Name = "GirlMakerMinimal" gui.ResetOnSpawn = false gui.DisplayOrder = 999 gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling local frame = Instance.new("Frame") frame.AnchorPoint = Vector2.new(0.5, 0.5) frame.Size = UDim2.fromOffset(width, height) frame.Position = UDim2.fromScale(0.5, 0.5) frame.BackgroundColor3 = COLOR_BG frame.BorderSizePixel = 0 frame.Active = true frame.Draggable = true frame.ClipsDescendants = true frame.Parent = gui local frameCorner = Instance.new("UICorner") frameCorner.CornerRadius = UDim.new(0, 16) frameCorner.Parent = frame local frameStroke = Instance.new("UIStroke") frameStroke.Color = COLOR_LINE frameStroke.Transparency = 0.15 frameStroke.Parent = frame local accentLine = Instance.new("Frame") accentLine.Size = UDim2.new(1, 0, 0, 2) accentLine.BackgroundColor3 = COLOR_ACCENT accentLine.BorderSizePixel = 0 accentLine.Parent = frame local mark = Instance.new("Frame") mark.Size = UDim2.fromOffset(34, 34) mark.Position = UDim2.fromOffset(14, 11) mark.BackgroundColor3 = COLOR_ACCENT mark.BorderSizePixel = 0 mark.Parent = frame local markCorner = Instance.new("UICorner") markCorner.CornerRadius = UDim.new(0, 10) markCorner.Parent = mark makeLabel(mark, "G", UDim2.fromScale(1, 1), UDim2.fromScale(0, 0), COLOR_BG, Enum.TextXAlignment.Center, 16).Font = Enum.Font.GothamBold local spark = Instance.new("Frame") spark.Size = UDim2.fromOffset(6, 6) spark.Position = UDim2.new(1, -3, 0, -2) spark.Rotation = 45 spark.BackgroundColor3 = COLOR_TEXT spark.BorderSizePixel = 0 spark.ZIndex = 4 spark.Parent = mark makeLabel(frame, BRAND, UDim2.new(1, -112, 0, 21), UDim2.fromOffset(58, 8), COLOR_TEXT, nil, 17).Font = Enum.Font.GothamBold local siteLabel = makeLabel(frame, SITE_URL, UDim2.new(1, -112, 0, 17), UDim2.fromOffset(58, 28), COLOR_MUTED, nil, 12) siteLabel.Font = Enum.Font.GothamMedium local closeButton = Instance.new("TextButton") closeButton.Size = UDim2.fromOffset(32, 32) closeButton.Position = UDim2.new(1, -43, 0, 11) closeButton.BackgroundTransparency = 1 closeButton.BorderSizePixel = 0 closeButton.Text = "×" closeButton.TextColor3 = COLOR_MUTED closeButton.Font = Enum.Font.GothamBold closeButton.TextSize = 18 closeButton.Parent = frame makeLabel(frame, "Get your key", UDim2.new(1, -32, 0, 28), UDim2.fromOffset(16, 62), COLOR_TEXT, nil, 22).Font = Enum.Font.GothamBold local subtitle = makeLabel( frame, "One key unlocks every GirlMaker script.", UDim2.new(1, -32, 0, 30), UDim2.fromOffset(16, 92), COLOR_MUTED, nil, 13 ) subtitle.Font = Enum.Font.GothamMedium task.spawn(function() local ok, info = pcall(MarketplaceService.GetProductInfo, MarketplaceService, game.PlaceId) if gui.Parent and ok and info and info.Name then subtitle.Text = tostring(info.Name) .. " found. One key unlocks every GirlMaker script." end end) local function makeInput(placeholder, y) local box = Instance.new("TextBox") box.Size = UDim2.new(1, -152, 0, 42) box.Position = UDim2.fromOffset(16, y) box.BackgroundColor3 = COLOR_SURFACE box.BorderSizePixel = 0 box.Text = "" box.PlaceholderText = placeholder box.PlaceholderColor3 = COLOR_SUBTLE box.TextColor3 = COLOR_TEXT box.Font = Enum.Font.GothamMedium box.TextSize = 13 box.TextXAlignment = Enum.TextXAlignment.Left box.ClearTextOnFocus = false box.ClipsDescendants = true box.Parent = frame local boxCorner = Instance.new("UICorner") boxCorner.CornerRadius = UDim.new(0, 10) boxCorner.Parent = box local boxPadding = Instance.new("UIPadding") boxPadding.PaddingLeft = UDim.new(0, 11) boxPadding.PaddingRight = UDim.new(0, 11) boxPadding.Parent = box return box end local linkBox = makeInput("Hold here to copy the link", 136) linkBox.Size = UDim2.new(1, -32, 0, 42) linkBox.Text = opts.browserUrl linkBox.TextColor3 = COLOR_MUTED linkBox.TextEditable = false linkBox.TextTruncate = Enum.TextTruncate.AtEnd linkBox.Visible = false local copyButton = makeButton(frame, "Get Key", UDim2.new(1, -32, 0, 42), UDim2.fromOffset(16, 136), true) copyButton.TextSize = 15 local keyBox = makeInput("Paste your key here", 188) local redeemButton = makeButton(frame, "Use Key", UDim2.fromOffset(112, 42), UDim2.new(1, -128, 0, 188), true) redeemButton.TextSize = 14 local statusDot = Instance.new("Frame") statusDot.Size = UDim2.fromOffset(7, 7) statusDot.Position = UDim2.fromOffset(17, 253) statusDot.BackgroundColor3 = COLOR_WARNING statusDot.BorderSizePixel = 0 statusDot.Parent = frame local dotCorner = Instance.new("UICorner") dotCorner.CornerRadius = UDim.new(1, 0) dotCorner.Parent = statusDot local statusLabel = makeLabel(frame, opts.status or "Tap Get Key to start", UDim2.new(1, -126, 0, 28), UDim2.fromOffset(31, 242), COLOR_MUTED, nil, 12) statusLabel.Font = Enum.Font.GothamMedium local checkButton = Instance.new("TextButton") checkButton.Size = UDim2.fromOffset(88, 28) checkButton.Position = UDim2.new(1, -101, 0, 242) checkButton.BackgroundTransparency = 1 checkButton.BorderSizePixel = 0 checkButton.Text = "I finished" checkButton.TextColor3 = COLOR_ACCENT checkButton.Font = Enum.Font.GothamBold checkButton.TextSize = 12 checkButton.Parent = frame local closed = false local redeeming = false local function setStatus(text, color) if not gui.Parent then return end statusLabel.Text = text statusDot.BackgroundColor3 = color or COLOR_WARNING end closeButton.MouseButton1Click:Connect(function() closed = true gui:Destroy() end) copyButton.MouseButton1Click:Connect(function() local copied = false if hasClipboard() then copied = pcall(setclipboard, opts.browserUrl) end if copied then copyButton.Text = "Copied! Open your browser" setStatus("Paste the copied link in your browser", COLOR_ACCENT) task.delay(2, function() if copyButton.Parent then copyButton.Text = "Get Key" end end) else copyButton.Visible = false linkBox.Visible = true linkBox.TextEditable = true linkBox:CaptureFocus() linkBox.SelectionStart = 1 linkBox.CursorPosition = #linkBox.Text + 1 setStatus("Hold the link above and copy it", COLOR_WARNING) end end) local function tryRedeem(key) if redeeming or closed then return end if opts.preview then keyBox.Text = "GM-PREVIEW-ONLY" redeemButton.Text = "Looks good" redeemButton.BackgroundColor3 = COLOR_SUCCESS setStatus("Preview finished. Nothing was changed.", COLOR_SUCCESS) return end if not key or #key < 6 then setStatus("Paste your key first", COLOR_WARNING) return end redeeming = true redeemButton.Active = false redeemButton.Text = "Checking…" setStatus("Checking your key…", COLOR_ACCENT) local data, err = redeemKey(opts.installId, key) if not data then redeeming = false redeemButton.Active = true redeemButton.Text = "Use Key" setStatus("That key did not work. Copy it again.", COLOR_DANGER) warn("[" .. BRAND .. "] Key redeem failed: " .. tostring(err)) return end saveLicenseToken(data.licenseToken) redeemButton.Text = "Unlocked" redeemButton.BackgroundColor3 = COLOR_SUCCESS setStatus("Done! Starting your script…", COLOR_SUCCESS) sleep(0.45) closed = true gui:Destroy() opts.onRedeemed(data) end redeemButton.MouseButton1Click:Connect(function() tryRedeem(keyBox.Text) end) keyBox.FocusLost:Connect(function(enterPressed) if enterPressed then tryRedeem(keyBox.Text) end end) checkButton.MouseButton1Click:Connect(function() if opts.preview then setStatus("Waiting for you to finish…", COLOR_WARNING) return end checkButton.Text = "Checking…" local status, statusErr = pollFlowStatus(opts.flowId, opts.pollToken) checkButton.Text = "I finished" if status and status.phase == "completed" and status.key then keyBox.Text = status.key tryRedeem(status.key) elseif status and status.phase == "completed" then setStatus("Done! Paste the key from the website.", COLOR_SUCCESS) elseif status and status.error then setStatus("Something went wrong. Try again.", COLOR_DANGER) else setStatus("Not ready yet. Finish the key page first.", COLOR_WARNING) if statusErr then warn("[" .. BRAND .. "] Status check failed: " .. tostring(statusErr)) end end end) gui.Parent = hiddenUi or playerGui or coreGui if not opts.preview then task.spawn(function() while not closed do sleep(5) if closed then break end local ok, status = pcall(pollFlowStatus, opts.flowId, opts.pollToken) if ok and status and status.phase == "completed" and status.key then if not closed then keyBox.Text = status.key tryRedeem(status.key) end break elseif ok and status and status.phase == "expired" then setStatus("This key page expired. Run GirlMaker again.", COLOR_DANGER) break end end end) end return gui end local function showBrandToast(message) local player = game:GetService("Players").LocalPlayer local playerGui = player and player:FindFirstChildOfClass("PlayerGui") local parent = playerGui or game:GetService("CoreGui") if type(gethui) == "function" then local ok, hiddenUi = pcall(gethui) if ok and hiddenUi then parent = hiddenUi end end local old = parent:FindFirstChild("GirlMakerBoot") if old then old:Destroy() end local gui = Instance.new("ScreenGui") gui.Name = "GirlMakerBoot" gui.ResetOnSpawn = false gui.DisplayOrder = 998 gui.Parent = parent local frame = Instance.new("Frame") frame.AnchorPoint = Vector2.new(1, 1) frame.Size = UDim2.fromOffset(280, 64) frame.Position = UDim2.new(1, -16, 1, -16) frame.BackgroundColor3 = COLOR_BG frame.BorderSizePixel = 0 frame.Parent = gui local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 14) corner.Parent = frame local stroke = Instance.new("UIStroke") stroke.Color = COLOR_LINE stroke.Transparency = 0.15 stroke.Parent = frame local mark = Instance.new("Frame") mark.Size = UDim2.fromOffset(34, 34) mark.Position = UDim2.fromOffset(14, 15) mark.BackgroundColor3 = COLOR_ACCENT mark.BorderSizePixel = 0 mark.Parent = frame local markCorner = Instance.new("UICorner") markCorner.CornerRadius = UDim.new(0, 9) markCorner.Parent = mark makeLabel(mark, "G", UDim2.fromScale(1, 1), UDim2.fromScale(0, 0), COLOR_BG, Enum.TextXAlignment.Center, 14).Font = Enum.Font.GothamBold makeLabel(frame, BRAND, UDim2.new(1, -68, 0, 21), UDim2.fromOffset(60, 10), COLOR_TEXT, nil, 15).Font = Enum.Font.GothamBold local detail = makeLabel(frame, message or "Checking game…", UDim2.new(1, -68, 0, 21), UDim2.fromOffset(60, 31), COLOR_MUTED, nil, 12) detail.Font = Enum.Font.GothamMedium local controller = {} function controller:set(text, color) if gui.Parent then detail.Text = text detail.TextColor3 = color or COLOR_MUTED end end function controller:destroy(delaySeconds) task.delay(delaySeconds or 0, function() if gui.Parent then gui:Destroy() end end) end return controller end local function openKeyUi(options) local ok, err = pcall(showMinimalKeyUi, options) if not ok then warn("[" .. BRAND .. "] Compact UI unavailable, using fallback: " .. tostring(err)) showKeyUi(options) end end -- =========================================================================== -- Payload delivery -- =========================================================================== local function fetchAndRunPayload(bootstrapData) local payload = bootstrapData.payload if type(payload) ~= "table" or type(payload.url) ~= "string" then return false, "Ready response is missing the payload ticket URL." end local body = httpGet(payload.url) if not body then return false, "Could not download the script payload." end local chunk, loadErr = loadstring(body) if not chunk then return false, "Payload could not be compiled: " .. tostring(loadErr) end local ok, runErr = pcall(chunk) if not ok then return false, "Payload error: " .. tostring(runErr) end return true end local function queueTeleportRequeue(bootstrapData) if bootstrapData.requeueOnTeleport ~= true then return end if not hasTeleportQueue() then return end pcall(queue_on_teleport, ('loadstring(game:HttpGet("%s/loader.lua"))()'):format(API_BASE)) end -- =========================================================================== -- Main -- =========================================================================== local function main() waitForGame() local boot = showBrandToast("Checking game…") if getRequestFunction() == nil then boot:set("This executor cannot run GirlMaker", COLOR_DANGER) boot:destroy(4) warn("[" .. BRAND .. "] This executor does not expose an HTTP request API. GirlMaker cannot run here.") return end local installId = getInstallId() if not hasFileSystem() then warn("[" .. BRAND .. "] No filesystem access: the license is kept in memory for this session only.") end local data, err = callBootstrap(installId) if not data then boot:set("Can't connect. Try again.", COLOR_DANGER) boot:destroy(4) warn("[" .. BRAND .. "] Bootstrap failed: " .. tostring(err)) return end if data.status == "ready" then boot:set("Starting script…", COLOR_ACCENT) local ok, payloadErr = fetchAndRunPayload(data) if not ok then boot:set("Script did not start. Try again.", COLOR_DANGER) boot:destroy(4) warn("[" .. BRAND .. "] " .. tostring(payloadErr)) else boot:set("Ready!", COLOR_SUCCESS) boot:destroy(1.25) queueTeleportRequeue(data) end return end if data.status == "key_required" then boot:destroy() local flow, flowErr = createUnlockFlow(installId) if not flow then warn("[" .. BRAND .. "] Could not start the unlock flow: " .. tostring(flowErr)) return end openKeyUi({ browserUrl = flow.browserUrl, flowId = flow.flowId, pollToken = flow.pollToken, installId = installId, status = "Tap Get Key to start", onRedeemed = function() local again, againErr = callBootstrap(installId) if not again then warn("[" .. BRAND .. "] Bootstrap failed after redeem: " .. tostring(againErr)) return end if again.status == "ready" then local ok, payloadErr = fetchAndRunPayload(again) if not ok then warn("[" .. BRAND .. "] " .. tostring(payloadErr)) else queueTeleportRequeue(again) end else warn("[" .. BRAND .. "] Unexpected status after redeem: " .. tostring(again.status)) end end, }) return end if data.status == "unsupported_game" then boot:set("This game is not supported yet", COLOR_WARNING) boot:destroy(4) print("[" .. BRAND .. "] This experience is not supported yet. Check the site for the list of games.") return elseif data.status == "maintenance" then boot:set("GirlMaker is updating. Try later.", COLOR_WARNING) boot:destroy(4) print("[" .. BRAND .. "] GirlMaker is under maintenance. Try again later.") return elseif data.status == "loader_outdated" then boot:set("Get the new loader at " .. SITE_URL, COLOR_DANGER) boot:destroy(4) warn("[" .. BRAND .. "] This loader is outdated. Please use the latest loader command from the site.") return elseif data.status == "executor_unsupported" then boot:set("This executor is not supported", COLOR_DANGER) boot:destroy(4) warn("[" .. BRAND .. "] This executor does not meet the requirements for this script.") return elseif data.status == "license_revoked" then boot:destroy() warn("[" .. BRAND .. "] This license was revoked. Starting a new unlock…") clearLicenseToken() local flow, flowErr = createUnlockFlow(installId) if not flow then warn("[" .. BRAND .. "] Could not start the unlock flow: " .. tostring(flowErr)) return end openKeyUi({ browserUrl = flow.browserUrl, flowId = flow.flowId, pollToken = flow.pollToken, installId = installId, status = "Get a new key to continue", onRedeemed = function() local again, againErr = callBootstrap(installId) if not again then warn("[" .. BRAND .. "] Bootstrap failed after redeem: " .. tostring(againErr)) return end if again.status == "ready" then local ok, payloadErr = fetchAndRunPayload(again) if not ok then warn("[" .. BRAND .. "] " .. tostring(payloadErr)) else queueTeleportRequeue(again) end else warn("[" .. BRAND .. "] Unexpected status after redeem: " .. tostring(again.status)) end end, }) return else boot:set("Try again in a moment", COLOR_DANGER) boot:destroy(4) warn("[" .. BRAND .. "] Unexpected bootstrap status: " .. tostring(data.status)) end end local function previewUi() waitForGame() openKeyUi({ browserUrl = "https://go.girlmaker.su/preview/example", flowId = "preview", pollToken = "preview", installId = "preview", status = "Tap Get Key to start", preview = true, onRedeemed = function() end, }) end if UI_PREVIEW_MODE then previewUi() else main() end