# ROSS A [ROSE Online](https://en.wikipedia.org/wiki/Rose_Online) (KTRose, pre-evo era) private server emulator, ported from its original Windows/MSVC codebase to build and run natively on Linux, packaged as a Docker Compose stack. Three C++ servers (login, character, world) talk to a MariaDB database and to each other over plain sockets, exactly like the original 2007-era server did — just with the Windows-only bits (MSVC CRT calls, `clock()` semantics, path handling) shimmed out so it builds and runs correctly under Linux/glibc/POSIX threads. ## Quick start ```sh cp .env.example .env # edit PUBLIC_HOST at minimum if clients connect from another machine docker compose up -d --build ``` That brings up: | Service | Container | Port | What it is | |---|---|---|---| | `db` | `ross-db-1` | — (internal) | MariaDB, schema auto-loaded from `database sql files/` on first start | | `loginserver` | `ross-loginserver-1` | `29000` | Account login | | `charserver` | `ross-charserver-1` | `29100` | Character select/create/delete | | `worldserver` | `ross-worldserver-1` | `29200` | The actual game world | | `webtools` | `ross-webtools-1` | `80` | Static GM toolbox (see below) + reverse-proxies `/admin/` | | `webadmin` | `ross-webadmin-1` | — (behind webtools) | Account/character/server admin panel | Point a KTRose pre-evo client at `PUBLIC_HOST:29000` and log in — `LOGIN_CREATE_ACCOUNT=1` (the default) auto-creates an account on first login with that username/password. ## Web tools — `http:///` A static, no-build-step GM toolbox, generated from the same STB/DB data the server itself reads: - **GM Commands** — every `/command` `gmcmds.cpp` understands, with syntax, access-level, and a copy button. - **Item Configurator** — browse all ~9,950 items, configure refine/count/etc., copy the exact `/item` or `/give2` command. - **Maps** — every map with spawn/NPC activity, named from `LIST_ZONE.STB` (row index = map id, same as the server's own `CWorldServer::LoadZoneData`). - **NPCs** — every placed NPC (`list_npcs`) with coordinates; click to copy a `/tele `. - **Monsters** — all 1,193 named monster types from `LIST_NPC.STB`; click to copy a `/mon `. ## Web admin — `http:///admin/` Logs in with an existing **game account** — only accounts with `accesslevel >= ADMIN_MIN_ACCESSLEVEL` (default `900`) get in. From there: - Browse/edit/delete accounts and characters, reset stats, grant GM/DEV, reset a stuck "online" flag. - **Server** tab: start/stop/restart each of the three game servers, live-tail their logs (SSE), broadcast a message to everyone online, or kick a character — all straight from the browser. The server-control features talk to the Docker API (`/var/run/docker.sock`, mounted read-only into `webadmin`), so this panel effectively has host-level privileges. It's fine behind GM-only login on a machine you control; don't put it directly on the public internet without a reverse proxy that adds another auth layer. ## Building without Docker ```sh apt-get install cmake g++ make libmariadb-dev pkg-config cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build -j"$(nproc)" ``` Produces `build/loginserver`, `build/charserver`, `build/worldserver`. Each expects a `.conf` file as its only argument (see `docker/conf/*.conf.tmpl` for the format, or `Binary/*.conf` for a filled-in example) and reads game data relative to its working directory — run it from a directory containing `3DData/` (see below) and `clanmark/`. ## Repo layout - `Src/` — the three servers' C++ source, plus `Src/Common/` (shared networking/DB/crypto code all three link against). - `database sql files/` — MariaDB schema, loaded automatically into a fresh `db` container. - `Binary/3DData/` — the subset of the original game's data files the **server** actually reads at runtime: item/skill/ quest/zone definitions (`STB/`), quest scripts (`QUESTDATA/`), monster AI scripts (`AI/`). This is *not* the client's 3D models/textures/sound — the server never touches those, so they aren't in this repo. - `webtools/`, `webadmin/` — the two web UIs described above. - `docker/` — Dockerfile support files: config templates, entrypoint script, the webtools nginx config. - `tools/rose_login_test.cpp` — a standalone protocol-level login smoke test, linking against the server's own `rosecrypt.cpp` so it exercises the real crypto/handshake instead of a reimplementation. ## Notes for anyone touching the server code This codebase was written entirely against Windows/MSVC assumptions that don't hold on Linux. The two that will bite you if you're not aware of them: - **`clock()`**: POSIX `clock()` returns *CPU time summed across every thread in the process*, not wall-clock time, and ticks at `CLOCKS_PER_SEC == 1,000,000` instead of Windows' `1,000`. `Src/Common/sockets.h` `#define`s `clock()` to a `CLOCK_MONOTONIC`-backed wall-clock millisecond counter for the whole codebase — don't remove that shim, and don't call `clock()` expecting Windows semantics anywhere it might not apply. - **DB string widths**: this server was built against MySQL 5.0, which silently truncated over-length strings instead of rejecting them. MariaDB's default strict mode does not — if you add a new DB-backed field that stores a server-generated string (timestamps, etc.), size the column generously.