- Global Functions
- client
- menu
- notifications
- http
- file
- browser
- GLDBrowser Usertype
- download
- input
- VK — Virtual Keys
- GP — Gamepad Keys
- html & xml Parsers
- utils
- gldconsole
- game
- GameLibrary
- communication
- SteamApi
- dll
- zip
- save
- settings
- base64
- GameInfo Usertype
- JsonWrapper Usertype
- HtmlWrapper Usertype (Legacy)
- Lua Callbacks Reference
- Full Examples
Project-GLD provides a comprehensive Lua scripting API built on top of Sol2, enabling full control over the game launcher's functionality. The API exposes browser control, file operations, HTTP requests, UI manipulation, and more.
- CEF Browser Integration - Create and control Chromium browsers
- HTTP Client - Make web requests with custom headers
- File System Operations - Read, write, and manipulate files
- UI Customization - Create menus with various control types
- Download Management - Handle file downloads with resume support
- Steam Integration - Query Steam API for game data
- DLL Injection - Inject mods and tools into games
- Save Management - Backup, restore, and sync game saves
- Input Simulation - Send keyboard and mouse events
- sol::this_state arguments are automatically hidden from Lua
- Optional parameters are indicated with
= default_value - sol::nil indicates deprecated/unavailable functions
- All Lua standard libraries are available (base, string, math, table, debug, package, os, coroutine, io, utf8, bit32)
All standard Lua libraries are available:
base- Core Lua functionsstring- String manipulationmath- Mathematical functionstable- Table operationsdebug- Debug utilitiespackage- Module systemos- Operating system functionscoroutine- Coroutine supportio- Input/outpututf8- UTF-8 utilitiesbit32- Bitwise operations
These functions are available globally without any table prefix.
print(...)Prints values to the debug console. Only useful during development when a console is attached.
exec(execpath, delay, commandline, isinnosetup, innoproc)Executes a file (e.g., an .exe).
| Parameter | Type | Default | Description |
|---|---|---|---|
execpath |
string | required | Full path to the executable |
delay |
int | 0 |
Milliseconds to wait before launching |
commandline |
string | "" |
Command-line arguments |
isinnosetup |
bool | false |
Set to true for InnoSetup installers |
innoproc |
string | "" |
Process name for InnoSetup hook |
system(command, delay)Runs a system command (CMD).
local output = system_output("whoami")Runs a system command and returns the stdout as a string.
sleep(500) -- wait 500msPauses execution for ms milliseconds.
beep(1000, 300)Plays a beep sound.
| Parameter | Type | Default | Description |
|---|---|---|---|
frequency |
int | 1000 |
Frequency in Hz |
duration |
int | 500 |
Duration in ms |
local encrypted = xor_encrypt("hello")Encrypts a plain string using XOR and returns a hex string.
local plain = xor_decrypt("2f3a...")Decrypts an XOR-encrypted hex string back to plain text.
General GLD client functions.
client.add_callback("on_gamesearch", function()
-- called every time the user searches a game
end)Registers a Lua function to be called when the named event fires. See Lua Callbacks Reference for all available event names.
client.load_script("myscript")Loads a script by name.
client.unload_script("myscript")Unloads a script by name.
client.create_script("myscript", lua_code_string)Creates a new script with the given name and Lua source code string.
local VERSION = "1.0.0"
client.auto_script_update("https://example.com/myscript.lua", VERSION)Automatically updates the script from a URL if the version differs. scriptversion must match a local VERSION = "" variable defined in the script.
client.log("Debug", "Something happened")Logs a message shown in the GLD UI.
client.quit()Exits Project-GLD.
local v = client.GetVersion() -- e.g. "2.15"Returns the GLD version as a string.
local v = client.GetVersionFloat() -- e.g. 2.15Returns the GLD version as a float.
local v = client.GetVersionDouble()Returns the GLD version as a double.
Clears the texture cache used by the search/game-search tab.
Clears the texture cache used by the game library tab.
local path = client.GetScriptsPath()Returns the full path to the scripts directory.
local path = client.GetDefaultSavePath()Returns the default save/download path.
local h = client.GetScreenHeight()Returns the screen height in pixels.
local w = client.GetScreenWidth()Returns the screen width in pixels.
Used to build custom UI elements and read/write their values.
Note: Buttons use the
on_button_(button_name)client callback. You must callclient.add_callback("on_button_mybutton", fn)after adding the button withmenu.add_button.
menu.add_check_box("Enable Feature")Adds a checkbox. Read with menu.get_bool(name).
menu.add_button("Do Action")
client.add_callback("on_button_Do Action", function()
-- fired when clicked
end)Adds a clickable button.
menu.add_text("Hello World")Adds a static text label.
menu.add_input_text("Username")Adds a text input field. Read with menu.get_text(name).
menu.add_input_int("Count", 0, 100)Adds an integer input. Read with menu.get_int(name).
menu.add_input_float("Speed", 0.0, 10.0)Adds a float input. Read with menu.get_float(name).
menu.add_combo_box("Region", {"US", "EU", "ASIA"})Adds a dropdown combo box. Read index with menu.get_int(name).
menu.add_slider_int("Volume")Adds an integer slider. Read with menu.get_int(name).
menu.add_slider_float("Opacity")Adds a float slider. Read with menu.get_float(name).
menu.add_color_picker("Text Color")Adds a color picker. Read with menu.get_color(name).
menu.add_keybind("Toggle Key", VK.F5)Adds a keybind selector. Read with menu.get_keybind(name).
Forces the next element to appear on the same line as the previous (inline layout).
| Function | Returns | Notes |
|---|---|---|
menu.get_bool(name) |
bool |
For checkboxes |
menu.get_text(name) |
string |
For input text |
menu.get_int(name) |
int |
For int inputs, sliders, combos |
menu.get_float(name) |
float |
For float inputs/sliders |
menu.get_color(name) |
Color |
For color pickers |
menu.get_keybind(name) |
int |
VK code of the bound key |
| Function | Notes |
|---|---|
menu.set_bool(name, value) |
Set checkbox state |
menu.set_text(name, value) |
Set text field |
menu.set_int(name, value) |
Set integer field |
menu.set_float(name, value) |
Set float field |
menu.set_color(name, value) |
Set color |
menu.set_keybind(name, value) |
Set keybind (VK code) |
menu.set_visible(false) -- hides the GLD menumenu.set_dpi(1.5)Sets the DPI scale of the menu.
if menu.is_main_window_active() then ... endReturns true if the GLD main window is focused.
Push toast notifications to the GLD UI.
notifications.push("Info", "Download started")notifications.push_success("Done", "Download complete!")notifications.push_error("Error", "Something went wrong")notifications.push_warning("Warning", "Low disk space")HTTP request functions.
All functions accept an optional
headerstable ({ ["Key"] = "Value" }). The body parameters accept plain strings (JSON, form data, etc.).
local res = http.get("https://example.com/api", {["Authorization"] = "Bearer token"})Performs an HTTP GET and returns the response body as a string.
local res = http.post("https://example.com/api", '{"key":"value"}', {["Content-Type"] = "application/json"})All follow the same pattern as get/post above.
local res = http.request("POST", "https://example.com", body, headers)Generic request method for any HTTP verb.
http.CloudFlareSolver("https://cf-protected-site.com")
client.add_callback("on_cfdone", function(cookie, resolved_url)
-- use cookie + specific User-Agent below
end)Opens a Cloudflare challenge solver. When done, fires the on_cfdone callback with (cookie, url).
Required User-Agent after solving:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 ProjectGLD/2.15
local resolved = http.byetresolver("https://byethost.example.com/file")Resolves Byet/iFastNet hosted download links.
File system operations.
file.write("C:/myfile.txt", "Hello World")Writes (overwrites) data to a file.
file.append("C:/log.txt", "new line\n")Appends data to a file.
local contents = file.read("C:/myfile.txt")Returns the full contents of a file as a string.
file.delete("C:/myfile.txt")Deletes a file.
if file.exists("C:/myfile.txt") then ... endReturns true if the file exists.
Same as the global exec() but scoped under file.
local folders = file.listfolders("C:/Games")
for _, f in ipairs(folders) do print(f) endReturns a list of subdirectory names in the given path.
Returns a list of .exe files in the given path.
Returns a list of .exe files in the given path and all subdirectories.
Returns a list of archive files (.zip, .rar, .7z, .tar, etc.) in the path.
local user = file.getusername()Returns the current Windows username.
file.create_directory("C:/MyFolder/SubFolder")Creates a directory (and any needed parents).
file.copy_file("C:/src.txt", "C:/dst.txt")file.move_file("C:/old.txt", "C:/new.txt")local name = file.get_filename("C:/Games/game.exe") -- "game.exe"local ext = file.get_extension("C:/file.zip") -- ".zip"local parent = file.get_parent_path("C:/Games/game.exe") -- "C:/Games"local entries = file.list_directory("C:/Games")Returns a table of all entries (files and folders) in the directory.
Manage embedded Chromium (CEF) browser windows inside GLD.
Browser names are unique. Only one browser per name can exist at a time. Keep this in mind when building download resolvers, as the download manager may launch multiple downloads simultaneously.
local b = browser.CreateBrowser("myBrowser", "https://example.com")Creates a new browser with the given name and navigates to url. Returns a GLDBrowser object.
local b = browser.GetBrowserByName("myBrowser")Returns an existing GLDBrowser by name, or nil.
local b = browser.GetBrowserByID(1)Returns a GLDBrowser by its integer ID.
browser.set_visible(true, "myBrowser")Shows or hides a browser window to the user.
if browser.IsBrowserVisible("myBrowser") then ... endReturns true if the browser is visible.
browser.EnableCaptchaDetection("myBrowser")Enables captcha detection for this browser (default is on).
browser.DisableCaptchaDetection("myBrowser")Disables captcha detection. Useful if you're getting stuck on Cloudflare "Just a moment" pages.
if browser.IsCaptchaDetectionOn("myBrowser") then ... endAn instance returned by browser.CreateBrowser() or browser.GetBrowserByName().
| Property | Type | Description |
|---|---|---|
burl |
string | Current URL of the browser |
name |
string | Browser name |
is_rendering |
bool | Whether the browser is actively rendering |
| Method | Returns | Description |
|---|---|---|
HasBrowser() |
bool | Browser instance exists |
CanGoBack() |
bool | History allows back navigation |
CanGoForward() |
bool | History allows forward navigation |
IsLoading() |
bool | Page is currently loading |
GetID() |
int | Browser integer ID |
HasBrowserAndFocusedFrame() |
bool | Browser + focused frame exist |
HasBrowserAndMainFrame() |
bool | Browser + main frame exist |
HasBrowserAndHost() |
bool | Browser + host exist |
| Method | Description |
|---|---|
ChangeBrowserURL(url) |
Navigate to a new URL |
ReloadBrowserPage() |
Reload current page |
ReloadIgnoreCache() |
Hard reload (bypass cache) |
GoBackBrowser() |
Go back in history |
GoForwardBrowser() |
Go forward in history |
CancelLoading() |
Stop loading the current page |
CloseBrowser() |
Close and destroy the browser |
BrowserUrl() |
Returns the current URL string |
| Method | Description |
|---|---|
GetPageTitle() |
Returns the page title string |
GetBrowserSource(callback) |
Calls callback(source) with the page HTML source |
ExecuteJavaScriptOnMainFrame(code) |
Runs JS in the main frame |
ExecuteJavaScriptOnFocusedFrame(code) |
Runs JS in the focused frame |
| Method | Description |
|---|---|
Copy() |
Copy selection |
Cut() |
Cut selection |
Paste() |
Paste |
PasteAsPlainText() |
Paste without formatting |
Undo() |
Undo |
Redo() |
Redo |
SelectAll() |
Select all |
| Method | Description |
|---|---|
ZoomIn() |
Zoom in |
ZoomOut() |
Zoom out |
ZoomReset() |
Reset zoom |
MuteAudio(mute) |
Mute/unmute audio |
Print() |
Print the page |
Resize() |
Resize the browser view |
ViewSource() |
Open page source |
SavePageAs() |
Save page dialog |
| Method | Description |
|---|---|
Find(text, forward, matchCase, findNext) |
Find text on page |
StopFinding(clearSelection) |
Stop find and optionally clear selection |
| Method | Description |
|---|---|
AddDownload(url) |
Add a URL to the GLD download manager |
DownloadImage(imageUrl) |
Download an image via browser |
| Method | Description |
|---|---|
ShowDevTools() |
Open DevTools panel |
CloseDevTools() |
Close DevTools |
InspectElementAt(x, y) |
Inspect element at pixel coordinates |
| Method | Description |
|---|---|
OpenBrowserPopup(url, title) |
Open a popup browser window |
ClearLocalStorage() |
Clear all localStorage for this browser |
SetCustomLocalStorageValueForURL(url, key, value) |
Set a localStorage key for a specific URL |
RemoveCustomLocalStorageValueForURL(url, key) |
Remove a localStorage key for a specific URL |
Manage file downloads.
Download.DownloadFile("https://example.com/file.zip")Adds a URL to the GLD download queue.
local name = Download.GetFileNameFromUrl("https://example.com/file.zip") -- "file.zip"Download.DirectDownload("https://example.com/file.zip", "C:/Downloads/file.zip")Downloads directly to a specified path.
local localpath = Download.DownloadImage("https://example.com/img.jpg")Downloads an image and returns the local file path.
Download.ChangeDownloadPath("D:/Downloads")local path = Download.GetDownloadPath()Download.ChangeMaxActiveDownloads(3)local max = Download.GetMaxActiveDownloads()Controls the number of simultaneous connections per download.
local magnet = Download.TorrentContentToMagnet(torrent_file_contents_string)Converts torrent file content (as a string) to a magnet link.
local magnet = Download.TorrentToMagnet("C:/file.torrent")Converts a .torrent file path to a magnet link.
Download.SetHistoryUrl(resolved_url, original_url)Associates a resolved download URL with the original URL so that GLD can resume interrupted downloads correctly.
Important: If a download is cancelled and restarted via the browser, you must call
SetHistoryUrlagain so GLD can resume it after an app restart.ogurlis the unresolved original URL.
Keyboard, mouse, and virtual gamepad input simulation and detection.
if input.is_key_down(VK.F5) then ... endReturns true while the key is held down.
if input.is_key_pressed(VK.SPACE) then ... endReturns true on the frame the key is first pressed.
Returns the raw GetKeyState short value.
Returns true if the key is in a toggled-on state (e.g., Caps Lock).
input.key_press(VK.RETURN)
input.key_press(VK.KEY_A, 100, 50) -- wait 100ms before, hold 50ms before releaseSimulates a full key press (down + up).
| Parameter | Default | Description |
|---|---|---|
delay |
0 |
Milliseconds before pressing |
delay2 |
50 |
Milliseconds between down and up |
Sends a keydown event.
Sends a keyup event.
local pos = input.get_mouse_pos()
print(pos.x, pos.y)Returns a table with x and y fields.
input.set_mouse_pos(960, 540)Moves the mouse cursor to the given screen coordinates.
input.mouse_click(0) -- left click
input.mouse_click(1) -- right click
input.mouse_click(2) -- middle clickSimulates a mouse button click.
Sends mouse button down/up events separately.
input.mouse_wheel(120) -- scroll up
input.mouse_wheel(-120) -- scroll downRequires ViGEm Bus Driver: https://vigembusdriver.com/download/
input.InitializeVirtualGamePad()Initializes a virtual Xbox controller. Call once when the script loads.
sleep(100)
input.SendVirtualGamePadKeyPress(GP.A)
sleep(100)
input.SendVirtualGamePadKeyPress(GP.B, 200) -- hold for 200msSimulates pressing an Xbox controller button. gp_code is from the GP table.
Important: You must call
sleep()before each virtual gamepad call.
sleep(100)
input.SendVirtualGamePadTriggerPress(false, 255) -- left trigger, full press
input.SendVirtualGamePadTriggerPress(true, 128) -- right trigger, half pressvalue is 0–255.
sleep(100)
input.SendVirtualGamePadThumbMove(false, 32767, 0) -- left stick, full rightMoves an analog stick. Values are typically -32768 to 32767.
Releases the virtual gamepad. Usually not needed.
The VK table contains Windows Virtual Key constants. Use these with input.* functions.
| Key | Description |
|---|---|
VK.LBUTTON |
Left mouse button |
VK.RBUTTON |
Right mouse button |
VK.MBUTTON |
Middle mouse button |
VK.XBUTTON1 |
X1 mouse button |
VK.XBUTTON2 |
X2 mouse button |
VK.CANCEL |
Control-break |
| Key | Description |
|---|---|
VK.BACK |
Backspace |
VK.TAB |
Tab |
VK.RETURN |
Enter |
VK.SHIFT |
Shift |
VK.CONTROL |
Ctrl |
VK.MENU |
Alt |
VK.ESCAPE |
Escape |
VK.SPACE |
Spacebar |
VK.CAPITAL |
Caps Lock |
VK.PAUSE |
Pause |
| Key | Description |
|---|---|
VK.LEFT |
Left Arrow |
VK.RIGHT |
Right Arrow |
VK.UP |
Up Arrow |
VK.DOWN |
Down Arrow |
VK.HOME |
Home |
VK.END |
End |
VK.PRIOR |
Page Up |
VK.NEXT |
Page Down |
VK.INSERT |
Insert |
VK.DELETE |
Delete |
VK.KEY_0 through VK.KEY_9
VK.KEY_A through VK.KEY_Z
VK.F1 through VK.F24
VK.NUMPAD0 through VK.NUMPAD9, VK.MULTIPLY, VK.ADD, VK.SUBTRACT, VK.DECIMAL, VK.DIVIDE, VK.SEPARATOR
| Key | Description |
|---|---|
VK.LSHIFT |
Left Shift |
VK.RSHIFT |
Right Shift |
VK.LCONTROL |
Left Ctrl |
VK.RCONTROL |
Right Ctrl |
VK.LMENU |
Left Alt |
VK.RMENU |
Right Alt |
VK.LWIN |
Left Windows key |
VK.RWIN |
Right Windows key |
| Key | Description |
|---|---|
VK.VOLUME_MUTE |
Mute |
VK.VOLUME_DOWN |
Volume Down |
VK.VOLUME_UP |
Volume Up |
VK.MEDIA_NEXT_TRACK |
Next Track |
VK.MEDIA_PREV_TRACK |
Previous Track |
VK.MEDIA_STOP |
Stop |
VK.MEDIA_PLAY_PAUSE |
Play/Pause |
VK.BROWSER_BACK, VK.BROWSER_FORWARD, VK.BROWSER_REFRESH, VK.BROWSER_STOP, VK.BROWSER_SEARCH, VK.BROWSER_FAVORITES, VK.BROWSER_HOME
| Key | Character |
|---|---|
VK.OEM_1 |
;: |
VK.OEM_PLUS |
=+ |
VK.OEM_COMMA |
,< |
VK.OEM_MINUS |
-_ |
VK.OEM_PERIOD |
.> |
VK.OEM_2 |
/? |
VK.OEM_3 |
`~ |
VK.OEM_4 |
[{ |
VK.OEM_5 |
| |
VK.OEM_6 |
]} |
VK.OEM_7 |
'" |
VK.OEM_102 |
<> or | (102-key keyboard) |
VK.NUMLOCK, VK.SCROLL
VK.APPS, VK.SLEEP, VK.SNAPSHOT (Print Screen), VK.HELP, VK.SELECT, VK.PRINT, VK.EXECUTE
Xbox controller button constants for use with input.SendVirtualGamePadKeyPress().
| Key | Description |
|---|---|
GP.A |
A button |
GP.B |
B button |
GP.X |
X button |
GP.Y |
Y button |
GP.DPAD_UP |
D-Pad Up |
GP.DPAD_DOWN |
D-Pad Down |
GP.DPAD_LEFT |
D-Pad Left |
GP.DPAD_RIGHT |
D-Pad Right |
GP.START |
Start button |
GP.BACK |
Back button |
GP.GUIDE |
Guide/Home button |
GP.LEFT_THUMB |
Left thumbstick click |
GP.RIGHT_THUMB |
Right thumbstick click |
GP.LEFT_SHOULDER |
Left bumper (LB) |
GP.RIGHT_SHOULDER |
Right bumper (RB) |
local doc = html.parse("<html><body><h1>Hello</h1></body></html>")
local root = doc:root()
local body = doc:body()
local nodes = doc:css("h1")
for i = 1, #nodes do
print(nodes[i]:text())
endParses an HTML string and returns an HtmlDocument.
| Method | Returns | Description |
|---|---|---|
doc:css(selector) |
table of HtmlNode |
Query with CSS selector |
doc:root() |
HtmlNode |
Root <html> node |
doc:body() |
HtmlNode |
<body> node |
| Method | Returns | Description |
|---|---|---|
node:tag() |
string | Tag name (e.g., "h1") |
node:text() |
string | Inner text content |
node:attr(name) |
string or nil | Attribute value |
node:parent() |
HtmlNode |
Parent node |
node:children() |
table of HtmlNode |
Child nodes |
local doc = xml.parse("<root><item id='1'>Value</item></root>")
local root = doc:root()
local items = doc:xpath("//item")Parses XML and returns an XmlDocument.
| Method | Returns | Description |
|---|---|---|
doc:xpath(expr) |
table of XmlNode |
Query with XPath |
doc:root() |
XmlNode |
Root element |
| Method | Returns | Description |
|---|---|---|
node:name() |
string | Element tag name |
node:text() |
string | Text content |
node:attr(name) |
string or nil | Attribute value |
local result = HtmlWrapper.findAttribute(htmlString, tagName, termKey, termValue, desiredKey)Kept for backwards compatibility. Use html.parse() instead.
Utility and debugging functions.
Attaches a Windows console window for debug output.
Detaches the console window.
utils.ConsolePrint(true, "Value: %d", 42)Prints to the attached console. Set logToFile to true to also write to log file. Must call AttachConsole() first.
Returns the current time as a human-readable string.
Returns a timestamp string.
Returns the current Unix timestamp as an integer.
utils.Log("Something happened: %s", "info")Writes to Project-GLD.log in the same folder as the GLD executable. Prefer gldconsole.print() for interactive logging.
In-app debug console. Preferred logging method.
gldconsole.print("Script started")Prints a message to the GLD built-in console.
Opens/shows the GLD console window.
Closes/hides the GLD console window.
Access information about the currently viewed game in the search/game page.
local name = game.getgamename()Returns the name of the game currently selected/displayed in the search tab.
Manage the GLD game library.
GameLibrary.launch(3)Launches the game with the given library ID. Returns true on success.
Closes/stops the running game.
GameLibrary.addGame("C:/Games/mygame.exe", "C:/img.jpg", "My Game", "", false)Adds a game to the library.
| Parameter | Type | Description |
|---|---|---|
exePath |
string | Path to the executable |
imagePath |
string | Path to the cover image |
gamename |
string | Display name |
commandline |
string | Launch arguments |
disableigdbid |
bool | Disable IGDB ID lookup |
GameLibrary.changeGameinfo(3, "", "", "New Name", "")Updates info for a library game. Pass empty strings to leave fields unchanged.
GameLibrary.removeGame(3)local id = GameLibrary.GetGameIdFromName("My Game")local name = GameLibrary.GetGameNameFromId(3)local path = GameLibrary.GetGamePath(3)Returns the executable path for the game.
local list = GameLibrary.GetGameList()
for _, g in ipairs(list) do
print(g.name, g.id)
endReturns a table of all library games. Each entry has the same fields as GameInfo.
Used by search/download scripts to pass results back to GLD's UI.
communication.receiveSearchResults({
{
title = "Game Title",
magneturl = "magnet:?xt=...",
filesize = "10 GB",
uploadDate = "2024-01-01",
uriOnline = "https://...",
image = "https://img.jpg"
}
})Sends a list of search result items to display in the GLD search results panel.
Forces the search results UI to refresh/redraw.
Interact with Steam data.
local appid = SteamApi.GetAppID("Half-Life 2")Searches for a game and returns its Steam App ID string.
local reqs = SteamApi.GetSystemRequirements("220")Returns the system requirements as a string for the given App ID.
local data = SteamApi.GetGameData("220")Returns full game metadata (JSON string) for the given App ID.
Launches the Steam application.
if SteamApi.IsSteamRunning() then ... endReturns true if Steam is currently running.
DLL injection utilities.
dll.inject("GameProcess.exe", "C:/myhook.dll", 300)Injects a 64-bit DLL into the given process. Returns true on success.
| Parameter | Description |
|---|---|
processexename |
e.g., "GoW.exe" |
dllpath |
Full path to the DLL |
delay |
Milliseconds to wait before injecting |
Same as inject but for 32-bit (x86) processes/DLLs.
dll.innohook("setup.exe")
client.add_callback("on_setupcompleted", function(from, to)
print("Extracted from:", from, "to:", to)
end)Hooks an InnoSetup installer process. Fires the on_setupcompleted callback when done.
Archive extraction.
zip.extract("C:/archive.zip", "C:/extracted", false, "")
zip.extract("C:/archive.rar", "C:/extracted", true, "mypassword")
client.add_callback("on_extractioncompleted", function(origin, dest)
print("Extracted:", origin, "->", dest)
end)Extracts an archive. Supports zip, rar, 7z, tar, and more.
| Parameter | Type | Description |
|---|---|---|
source |
string | Path to the archive |
destination |
string | Extraction destination folder |
deleteaftercomplete |
bool | Delete archive after extraction |
pass |
string | Password (empty string if none) |
Fires the
on_extractioncompletedcallback with(origin_file, destination_path)when done.
Save game backup and cloud sync.
| Function | Description |
|---|---|
save.Backup(name) |
Backup saves for a game by name |
save.Restore(name) |
Restore saves for a game by name |
save.BackupAll() |
Backup all tracked games |
save.RestoreAll() |
Restore all tracked games |
| Function | Description |
|---|---|
save.Upload(name) |
Upload saves to cloud |
save.Download(name) |
Download saves from cloud |
save.UploadAll() |
Upload all to cloud |
save.DownloadAll() |
Download all from cloud |
| Function | Description |
|---|---|
save.RefreshBackup() |
Refresh backup list |
save.RefreshRestore() |
Refresh restore list |
save.RefreshCloud() |
Refresh cloud list |
save.RefreshAll() |
Refresh all lists |
| Function | Returns | Description |
|---|---|---|
save.GetBackupGamesList() |
table | List of games with backups |
save.GetRestoreGamesList() |
string | List of restorable games |
save.GetCloudGamesList() |
table of strings | List of cloud-synced games |
Persist GLD settings.
Saves the current GLD settings to disk.
Loads GLD settings from disk.
Base64 encoding and decoding.
local encoded = base64.encode("Hello World")local decoded = base64.decode("SGVsbG8gV29ybGQ=")Encodes using a shifted variant (for obfuscation).
Decodes a shifted base64 string.
Represents a game entry. Passed to on_gamelaunch callback.
| Field | Type | Description |
|---|---|---|
id |
string | Game ID |
name |
string | Game name |
initoptions |
string | Launch options/init config |
imagePath |
string | Path or URL to cover image |
exePath |
string | Path to executable |
Example:
client.add_callback("on_gamelaunch", function(gameinfo)
print("Launching:", gameinfo.name)
print("Exe:", gameinfo.exePath)
end)local data = JsonWrapper.parse('{"key": "value"}')
print(data.key) -- "value"Parses a JSON string and returns a Lua table (sol::object).
Deprecated. Use
html.parse()instead.
local result = HtmlWrapper.findAttribute(html, "a", "class", "download-link", "href")Finds an attribute in an HTML element. Uses the Gumbo HTML parser (old).
Register callbacks with:
client.add_callback("event_name", function(...)
-- handler
end)| Event | Arguments | Description |
|---|---|---|
on_launch |
— | GLD is launched. May fire before the script fully loads — not recommended for most use cases |
on_present |
— | Main loop tick. Fires every frame |
on_quit |
— | GLD is exiting. Use sparingly |
on_gamesearch |
— | User searched for a game |
on_gameselected |
— | User selected a game in search |
on_scriptselected |
— | A script is selected in the search/game tab |
on_gamelaunch |
GameInfo |
A game was launched. Receives the GameInfo object |
on_downloadclick |
item_json, url, scriptname |
User clicked "Download" on a game page. All args are strings |
on_downloadcompleted |
path, url |
A download finished. Args are strings |
on_beforedownload |
url |
Called before a download starts. Return (resolved_url, name, headers) to modify the download, or nil to keep original |
on_extractioncompleted |
origin, destination |
A zip.extract() completed. Both args are strings |
on_setupcompleted |
from, to |
dll.innohook() completed. Both are strings |
on_cfdone |
cookie, url |
Cloudflare solver completed. Both are strings |
on_browserloaded |
browserID |
A browser finished loading a page (equivalent to OnLoadEnd) |
on_browserconsolemessage |
browserID, message |
A browser emitted a console message |
on_browserbeforeresourceload |
browserID, url, method, referrer, resourceType |
Browser is about to load a resource |
on_browserbeforedownload |
browserID, url, suggestedName, size |
Browser is about to download a file. Return (originalUrl) to set the base URL for resolvers |
on_captchadetected |
browserID |
Captcha was detected in a browser |
on_captchasolved |
browserID |
Captcha was solved in a browser |
on_button_(name) |
— | A menu button named name was clicked |
client.add_callback("on_beforedownload", function(url)
-- Resolve the URL however you need
local resolved = resolve_my_url(url)
local headers = {"Referer: https://example.com"}
-- Return: resolved_url, display_name, headers_table
-- Return nil to keep original
return resolved, "filename.zip", headers
-- Cancel a download:
-- return "cancel"
end)local VERSION = "1.0.0"
client.auto_script_update("https://example.com/myscript.lua", VERSION)
client.add_callback("on_gamesearch", function()
local gamename = game.getgamename()
gldconsole.print("Searching for: " .. gamename)
local response = http.get("https://myapi.com/search?q=" .. gamename, {})
local data = JsonWrapper.parse(response)
local results = {}
for _, item in ipairs(data.results) do
table.insert(results, {
title = item.title,
magneturl = item.magnet,
filesize = item.size,
uploadDate = item.date,
uriOnline = item.page,
image = item.image
})
end
communication.receiveSearchResults(results)
end)client.add_callback("on_beforedownload", function(url)
if not url:find("myhost.com") then return nil end
local b = browser.CreateBrowser("resolver_" .. os.time(), url)
browser.set_visible(false, b.name)
-- Wait for the page to load
sleep(3000)
local resolved = nil
b:GetBrowserSource(function(src)
local doc = html.parse(src)
local links = doc:css("a.download-btn")
if links[1] then
resolved = links[1]:attr("href")
end
end)
sleep(500)
b:CloseBrowser()
if resolved then
return resolved, nil, {"Referer: " .. url}
end
return nil
end)menu.add_check_box("Auto-Download")
menu.add_keybind("Toggle Key", VK.F8)
menu.add_button("Run Now")
client.add_callback("on_button_Run Now", function()
if menu.get_bool("Auto-Download") then
notifications.push("Script", "Auto-download is enabled!")
end
end)
client.add_callback("on_present", function()
local key = menu.get_keybind("Toggle Key")
if input.is_key_pressed(key) then
local current = menu.get_bool("Auto-Download")
menu.set_bool("Auto-Download", not current)
notifications.push_success("Toggled", "Auto-Download: " .. tostring(not current))
end
end)input.InitializeVirtualGamePad()
local function press_sequence()
sleep(200)
input.SendVirtualGamePadKeyPress(GP.A, 100)
sleep(300)
input.SendVirtualGamePadKeyPress(GP.B, 100)
sleep(300)
input.SendVirtualGamePadThumbMove(false, 32767, 0, 500) -- push left stick right
sleep(600)
end
client.add_callback("on_present", function()
if input.is_key_pressed(VK.F9) then
press_sequence()
end
end)client.add_callback("on_downloadcompleted", function(path, url)
if path:find("%.zip$") then
gldconsole.print("Download done, extracting: " .. path)
zip.extract(path, "C:/Games/MyGame", true, "")
end
end)
client.add_callback("on_extractioncompleted", function(origin, dest)
gldconsole.print("Extraction complete: " .. dest)
GameLibrary.addGame(dest .. "/game.exe", "", "My Game", "", false)
notifications.push_success("Done", "Game installed!")
end)local cf_cookie = nil
local cf_url = nil
client.add_callback("on_cfdone", function(cookie, url)
cf_cookie = cookie
cf_url = url
gldconsole.print("CF solved for: " .. url)
end)
local function get_with_cf(url)
if cf_cookie == nil then
http.CloudFlareSolver(url)
-- Wait for on_cfdone then retry
return nil
end
return http.get(url, {
["Cookie"] = cf_cookie,
["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 ProjectGLD/2.15"
})
endEnd of Project-GLD Lua API Documentation