- JavaScript 88.9%
- CSS 5.2%
- Python 4.9%
- HTML 0.8%
- Dockerfile 0.2%
- Item editor: dye pickers (stored by colour name, as the game's dyes write them; armor only) and a transmog picker limited to looks that fit the item. - Giving an item a look also unlocks it, since the game strips locked looks at login. - New Looks & Dyes tab: gear appearance overview, unlocked looks, unlock one or all (live via the game's checkToUnlockSkin), and removal. - Bridge v5: unlockSkins op and unlockedSkins in the player summary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| gamedata | ||
| mod | ||
| public | ||
| src | ||
| test | ||
| tools | ||
| .dockerignore | ||
| .gitignore | ||
| docker-compose.webadmin.yml | ||
| Dockerfile | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
OrbusVR: Reborn Web Admin
A web admin panel for the OrbusVR: Reborn community server
(ghcr.io/orbusvr-community/reborn-server).
- Players: search every character, see who's online, where they are, their levels, Dram and play time.
- Currencies: see and award or take Dram, honor points, dungeon/raid/event tokens and shards.
- Inventory: browse a character's bags, give any item from the catalog (searchable, with stack counts), remove items, and edit any item: level and plus level, rarity, perfect, attack (weapons) or armor (armor) and the secondary stats, affixes, durability, transmog, dyes, expiry, stack count, plus a raw JSON view of everything stored on it.
- Teleport: move a player to any zone the server can load (picking a zone fills in its default spot), to one of ~200 known spots taken from the game's own map data (graveyards, teleporter and portal arrivals, public event spots, bounty spots, monster areas), to coordinates, or to another player.
- Character: rename, surname, class levels and XP, honor, GM flag.
- Pets & Mounts: see a player's pets and mounts, give any of the game's 51 pets or 37 mounts, edit a pet's happiness and bonus, or take one away.
- Looks & Dyes: see every weapon and armor piece's transmog and dyes, change them, and manage the transmog looks a player has unlocked (unlock one, unlock all ~1000, or take them away).
- Titles: give titles (the game's own, or any you make up), take them away, and choose which one is shown.
- Monsters: spawn any of the game's ~220 monsters and bosses next to a player or at a spot in a running zone, at a fixed level (up to the level cap) or scaled to nearby players, and remove them again.
- Public events: start any public event (Collect Crystals, Defend the Fort, Critter Capture, ...) in a running zone right away, complete or fail running ones, and spawn trickster goblins, optionally with a server-wide announcement.
- Moderation: kick, ban/unban (with history and reasons), restore deleted characters, in-game messages, broadcasts.
- Accounts: label accounts and logins, link a device's login to another account (so it opens the same characters), move characters between accounts, remove logins, delete accounts, and recover lost identity files.
- Audit log: every change made through the panel, with who made it.
How it works
The game keeps an online player's state in memory and writes it back to the database regularly, so editing the database while someone is playing doesn't stick. The panel handles both cases:
| Player is | How changes are applied |
|---|---|
| Online | Live, through AdminBridge.js, a small mod inside each zone process: items, Dram, tokens, teleports and messages take effect immediately. |
| Offline | Written straight to the database; the game loads them at next login. |
Changes the game can only take from the database (class levels, honor, names, gear item levels) need the player offline. If they're online, the panel asks before kicking them, waits for their zone to save, then applies the change.
The panel reaches the server over the compose network: RethinkDB (data), redis (the bridge), the game's
REPL socket on game:5500 (kick and broadcast) and the API (server info). Nothing is added to the game
server except the bridge mod.
Install
You need a working reborn-server folder (see its README). From that folder:
-
Add the bridge mod so live changes work. The image carries the matching
mod/AdminBridge.js; copy it intomods/components/:docker run --rm git.zigz.uk/zigzutils/orbusvr-reborn-webadmin:latest cat /app/mod/AdminBridge.js > mods/components/AdminBridge.jsCheck that the file starts with
/*and mentions AdminBridge (head -3 mods/components/AdminBridge.js). Re-run this after updating the panel so the mod stays in step with it. -
Add the panel to compose. Copy
docker-compose.webadmin.ymlnext todocker-compose.yml, and set a password in a.envfile in the same folder:echo "ADMIN_PASSWORD=$(openssl rand -base64 18)" >> .env cat .env -
Start it, restarting the game so it loads the mod:
docker compose -f docker-compose.yml -f docker-compose.webadmin.yml up -d docker compose restart game -
Open
http://localhost:8090on the server machine and sign in with the password. The dashboard says "Live bridge: N zone processes answering" once a player is online and the mod is loaded.
To avoid typing both -f flags every time, add COMPOSE_FILE=docker-compose.yml:docker-compose.webadmin.yml
to .env.
Reaching it from another machine
The port is bound to 127.0.0.1 on purpose: the panel can change anything on your server. To use it
remotely, either tunnel (ssh -L 8090:localhost:8090 you@server), or put it behind a reverse proxy with
HTTPS and set SECURE_COOKIES=1 (plus TRUST_PROXY=1 so login rate limiting sees real client addresses).
Configuration
| Variable | Default | What it does |
|---|---|---|
ADMIN_PASSWORD |
(required) | Password for the panel, at least 8 characters. |
SESSION_SECRET |
generated | Signs login cookies. Generated once and kept in /data if not set. |
SESSION_HOURS |
12 |
How long a sign-in lasts. |
ORBUS_DB_HOST / ORBUS_DB_PORT / ORBUS_DB_NAME |
rethinkdb / 28015 / orbus |
The game database. |
ORBUS_REDIS_HOST / ORBUS_REDIS_PORT |
redis / 6379 |
The game's redis, used to talk to the bridge. |
ORBUS_REPL_URL |
tcp://game:5500 |
The game's REPL socket (kick, broadcast). |
ORBUS_API_URL |
http://api:3000 |
The game API (server info). |
ORBUS_CONTENT_DIR |
/content |
Mount of the server's content/ folder: item catalog, zones, bounty spots. |
ORBUS_CONFIG |
/config/orbus.config.json |
Mount of the server config, read for maxCharacters. |
DATA_DIR |
/data |
Audit log, learned teleport spots, session secret. Keep it on a volume. |
CURRENCIES_FILE |
A JSON file replacing the currency list (see below). | |
SECURE_COOKIES |
off | Set to 1 when serving over HTTPS. |
TRUST_PROXY |
off | Set to 1 behind a reverse proxy. |
Currencies
The built-in list is Dram (currency), honor points (pvpHonorPoints) and the token items players trade
in: Crypt/Hard/Expert tokens, Trickster and Goblin tokens, Grinding and Barber tokens, the five shard
types and all raid token sets. To change it, mount a JSON file and point CURRENCIES_FILE at it:
[
{"key": "dram", "name": "Dram", "kind": "field", "field": "currency", "group": "Main"},
{"key": "crypt", "name": "Crypt Token", "kind": "item", "itemId": 508, "group": "Tokens"}
]
field currencies are numbers on the character record. item currencies are counted in the bags; awarding
gives the item and taking removes it.
Accounts and logins
Every identity file (one game install or device) is a login. Logins belong to an account, and every character belongs to exactly one account. So:
- To let someone use the same characters from their PC and their Quest, open the account, and move the other device's login onto it (or use "Bring in the logins of another account").
- To give a character to someone else, move the character to their account.
- Removing a login cuts that identity file off; if it connects again it gets a new, empty account.
- Deleting an account removes all its logins and kicks anyone online. Its characters are marked deleted (restorable from the character page) unless you choose to erase them permanently.
Labels on accounts and logins are only visible in the panel and are kept in the panel's /data volume.
Monsters
The Monsters page spawns any monster or boss from the game's own catalog (names as shown in game) next to an online player or at a known spot in a zone that has players in it. Pick a fixed level, or let it scale to the players nearby like most overworld monsters; up to 20 at a time, optionally elite. Everything spawned from the panel is listed with its actual level and can be removed again; each zone allows 100 at once.
Monster scripts are written for monsters placed by the map's spawners, so a few would normally crash their zone when spawned anywhere else. The bridge protects against that: it gives each spawned monster a stand-in spawner, and if one of its scripts still fails, it removes that monster instead of letting the zone crash.
Looks and dyes
Dyes go on armor (head, shoulders, chest, gloves), as in game. An item stores its dyes by colour name, which is what the game's own dye items write, and the editor offers the game's 31 major and 23 accent dyes.
Transmog: an item's look is another item of the same slot (for weapons, the same class's weapon). Players
can only use looks they have unlocked, which normally happens when they pick up that gear; the game takes any
other look off at login. So when you give an item a look in the editor, the panel unlocks that look for the
player too. The Looks & Dyes tab lists their unlocked looks, which are what the transmog station offers them.
Unlocking uses the game's own checkToUnlockSkin and works while the player is online; taking a look away needs
them offline. Like other item edits, changing an item's look or dyes needs the player offline.
Titles
Titles are stored as their text, so besides the ones the game hands out (Elite, Dragon Ace, Knight of
Patreayl, ...) you can give any title up to 40 characters. Giving a title uses the game's own unlockTitle, so
it works while the player is online. Taking one away or changing which title is shown is a database change,
so for an online player the panel asks before kicking them. Players can switch between their titles in game
as usual. Honor titles (Recruit to Grand Champion) follow PvP rank and aren't managed here.
Level cap
Class levels and gear levels are limited to the game's level cap, which the panel reads from the running game (30 on the stock server; it shows on the dashboard). Higher levels aren't reachable by playing, and the game's formulas make monsters scaled to such players, and gear at such levels, wildly strong.
Public events
The Events page lists the public events of every zone that is running. A zone only runs while someone is in it, so events appear once players are online, and you can start them in the zones those players are in. "Start" skips the usual countdown and starts the event at once; the game handles spawning, scoring and rewards as normal. "Complete" and "Fail" end a running event the same way the game does.
Notes and limits
-
Teleport coordinates aren't checked by the server. Use a known spot or another player's position, or coordinates you know are on the ground. Graveyards are learned from zones while players are in them and remembered, so the list of spots grows as the server is used.
-
Item editing writes the same fields, in the same shape, as the game's own loot code. Weapons and armor are different:
Item Main stat Secondary stats Affixes Weapon attackstrength,intellectweapon affixes ( lightning_forged,bleed,iceheart, ...)Armor (head, shoulder, chest, glove) armorvitality,defensearmor affixes ( pluscrit,plusxp, ...)The tooltip shows
Level <itemLevel> +<itemPlusLevel>. Stats are stored on the item, not worked out from its level, so after changing a level use "Fill attack/armor & durability for level". It uses the game's own numbers, generated from its loot code: weapon attack from a per-level table (level 30 = 4529), armor = 10 × level + 10 (head, glove), + 30 (shoulder), + 90 (chest), durability = 10 × level + 20. Secondary stats are random rolls in the game, so set those yourself. The editor flags, and offers to remove, a stat that doesn't belong on the item (e.g.armoron a weapon). The required level to use an item fully is its item level; the catalog's minimum level comes from the game client and can't be changed per item. The game clears "temporarily tradable" when it saves. -
Live XP isn't offered: the game's XP function scales by monster level, so levels and XP are edited directly (with a kick if the player is online).
-
Storage chests are shown read-only. Zones cache them, so editing them from outside isn't safe.
-
Characters that never entered the world have no inventory yet; give them items after their first login.
-
The panel mirrors the server's built-in
/admin/*tools (ban, unban, rename, surname, restore, resetposition, rebind) by making the same database changes, because those tools only answer requests from the server itself.
Map data
gamedata/spots.json holds positions and the monster catalog extracted from the server's own zone files with
tools/extract-spots.py. Re-run it after a server update that changes maps (instructions are in the script).
Updating
docker compose -f docker-compose.yml -f docker-compose.webadmin.yml pull webadmin
docker compose -f docker-compose.yml -f docker-compose.webadmin.yml up -d webadmin
The bridge mod rarely changes. You only need to re-copy AdminBridge.js (step 1 of Install) and restart the
game when the dashboard says the mod is outdated; it compares the version every running zone reports with
the one the panel expects.
Development
npm install
npm test
ADMIN_PASSWORD=changeme123 DATA_DIR=./data ORBUS_CONTENT_DIR=../reborn-server/content \
ORBUS_DB_HOST=localhost ORBUS_REDIS_HOST=localhost ORBUS_REPL_URL=tcp://localhost:5500 npm start
The front end is plain HTML/CSS/JS in public/, with no build step. Build the image with
docker build -t orbusvr-reborn-webadmin ..