ALL OF THIS CODE WAS A TEST TO SEE IF AI CAN REMAKE/RECREATE THE REQUIRED FUNCTIONALITY OF oxSB/VoidSB PLEASE KEEP THAT IN MIND.
This repro does not and will never include the actual Roblox place used in this experiment, We are preparing for repro publication - VTIL LLC
This adds a self-contained Node.js server that recreates the custom web APIs oxSB calls, now with SQLite persistence and an authenticated Vue + Bootstrap IRC frontend.
These are the project-specific HTTP APIs used in the Luau codebase:
POST /RBX_API/SERVERLIST/main.phpGET /RBX_API/SERVERLIST/main.phpGET /RBX_API/OTHER/GetAccountAge.php?UserId=...POST /RBX_API/UPLOADASSET/main.php?id=...POST /IRC/PHP.phpGET /IRC/Emojis.jsonGET /MOD/handle.phpGET /raw/TPHYh0jHGET /raw/dA63NTv9POST /SB_API/ModuleHax/Php/PushLog.phpGET /ROBLOXApi/getPlayers.php?groupId=...
These are the Roblox service shims exposed in src/roblox-services.js:
PlayersDataStoreServiceMarketplaceServiceGroupServiceBadgeServiceInsertServiceTeleportServiceHttpServiceRunService
npm startDefault URL:
http://127.0.0.1:3002
The server now loads configuration from /.env before reading process.env.
Use /.env.example as the production template.
Important variables:
HOSTPORTOXSB_SERVERLIST_API_KEYOXSB_IRC_API_KEYOXSB_PUSHLOG_ACCESS_KEYOXSB_UPLOAD_KEYOXSB_SESSION_TTL_MSOXSB_SECURE_COOKIESOXSB_RBXM_TO_RBXMX_CMDOXSB_ENABLE_CLOUDFLAREDOXSB_CLOUDFLARED_BINOXSB_CLOUDFLARED_TUNNEL_TOKENOXSB_CLOUDFLARED_CONFIGOXSB_CLOUDFLARED_TUNNELOXSB_CLOUDFLARED_URLNODE_ENV
OXSB_RBXM_TO_RBXMX_CMD is optional. If set, the asset workbench will try to convert uploaded .rbxm files into editable .rbxmx text using the external command. The command should accept {input} and {output} placeholders.
Example:
OXSB_RBXM_TO_RBXMX_CMD=C:\path\to\converter.exe "{input}" "{output}"
cloudflared is also optional. If enabled, the server will launch a managed tunnel sidecar when Node starts.
Quick tunnel example:
OXSB_ENABLE_CLOUDFLARED=1
OXSB_CLOUDFLARED_BIN=cloudflared
OXSB_CLOUDFLARED_URL=http://127.0.0.1:3002
Named tunnel example:
OXSB_ENABLE_CLOUDFLARED=1
OXSB_CLOUDFLARED_BIN=cloudflared
OXSB_CLOUDFLARED_TUNNEL_TOKEN=your-token-here
Local config example:
OXSB_ENABLE_CLOUDFLARED=1
OXSB_CLOUDFLARED_BIN=cloudflared
OXSB_CLOUDFLARED_CONFIG=C:\Users\you\.cloudflared\config.yml
OXSB_CLOUDFLARED_TUNNEL=oxsb-panel
When enabled, the server logs the public tunnel URL on startup and also exposes its current tunnel state in /debug/state.
The source of truth is SQLite at data/oxsb.sqlite.
modsConfigis stored in normalized database tables for roles, mod entries, place settings, and logging flags.emojisis stored in theemojistable.groupPlayersis stored in thegroup_playerstable.accountAgesis stored in theaccount_agestable.- IRC users, sessions, messages, uploads, push logs, and server list data are also stored in SQLite.
Fresh databases are initialized from built-in bootstrap defaults and then managed entirely through SQLite.
The Roblox side is now being split around a bootstrap/module layout so the old monolith is easier to maintain:
SBBootstrap.luauwires the server bootstrap together.SBConfig.luauowns place IDs, API URLs, and key constants.SBServices.luauowns Roblox service acquisition and wrapper helpers.SBState.luauowns the core mutable runtime tables shared across systems.SBManagers.luauwires moderator/tag/require/text-chat managers together.SBPlayerLifecycle.luauowns join/leave handling and player GUI/data bootstrap.SBCommandDispatcher.luaucentralizes alias matching and registry lookup for command tables.SBServerUtilities.luauowns shared server helpers like output dispatch, player targeting, chat relays, and script save/disable helpers.SBTextChatServerBootstrap.luauowns TextChat remotes and channel/bootstrap logic.SBServerMaintenance.luauowns the recurring ban/require/config refresh loop.SBClientBootstrap.luauandSBClientConfig.luaudo the same for the cloned client runtime.
init.legacy.luau is now a thin loader. The remaining legacy behavior lives in SBLegacyServer.luau, which is being broken apart subsystem-by-subsystem into smaller modules instead of staying as one entry script blob.
The web IRC at http://127.0.0.1:3002/irc now requires login.
Create a user with:
npm run create-irc-user -- <username> <password> [displayName] [robloxUserId] [role] [icon]Example:
npm run create-irc-user -- admin StrongPass123 superdude123456 761996 adminNotes:
- Web IRC users are stored in SQLite.
- The logged-in user’s
displayName,robloxUserId, andiconare used for IRC messages. - External IRC commands now rely on the real logged-in
robloxUserIdinstead of trusting anonymous web sessions.
You can update the local recreated moderator/group-role data with:
npm run grant-role -- <role> <userId> <userName>Examples:
npm run grant-role -- moderator 761996 superdude123456
npm run grant-role -- scripter 123456 ExampleUser
npm run grant-role -- advanced-scripter 654321 ExampleUser
npm run grant-role -- builder 111111 ExampleUserSupported roles:
moderatorscripteradvanced-scripterbuilderclear
This utility writes directly to SQLite, so the updated role data is available immediately.
POST /RBX_API/SERVERLIST/main.php
{
"ApiKey": "2A38B0BB-49AA-4B21-A600-2B3CDC1E8BCE",
"PlaceId": 18153,
"JobId": "job-123",
"Queries": {
"KeepAlive": true,
"AddPlayer": {
"UserId": 1,
"UserName": "Builderman",
"JoinTime": 12345
},
"UpdateFPS": "60.00",
"ServerType": "PUBLIC",
"ServerTeleportId": null
}
}POST /IRC/PHP.php
Supports raw JSON or base64-encoded JSON, matching the old Luau usage.
{
"ApiKey": "7D650BD8-C8B0-4437-8002-BE74B38318B8",
"SessionId": "session-1",
"ChannelId": "Place1",
"Messages": [
{
"Speaker": "Builderman",
"UserId": 1,
"Message": "hello",
"Icon": null
}
],
"RequestEmojis": 1
}POST /SB_API/ModuleHax/Php/PushLog.php
{
"AccessKey": "Dff19Pt",
"Action": "PushLog",
"Data": {
"PlaceId": "HAK-TEST",
"JobId": "HAK_LOGS",
"Player": "VOID_SB - Builderman",
"Source": "print('hello')",
"Type": "SCRIPT_RAN | Server"
}
}- This recreates the custom HTTP APIs oxSB relies on. It does not recreate the Roblox engine itself.
- The Roblox services are mockable Node-side shims, intended for testing and progressive porting.
- If you want, the next step can be wiring the Luau constants to point at this local server instead of the dead remote URLs.