Consolidate docs/ content into wiki as single source of truth

Port logging config, MHFML tags, course bitfields, security checklist,
command security classification, player commands reference, DB
troubleshooting/backup/tuning, and firewall/monitoring guides from the
v9.2.x-stable docs/ into the wiki. All schema references adapted to
current main branch field names.
houmgaor
2026-02-18 11:41:31 +01:00
parent 8c8d5b4a2d
commit d303f98c05
6 changed files with 515 additions and 7 deletions

@@ -4,6 +4,8 @@ Commands are typed in the in-game chat. The prefix is configurable in `config.js
Operators (users with the appropriate `rights` bitmask) can use disabled commands.
> **Looking for a player-friendly guide?** See [Player Commands](Player-Commands) for usage examples and troubleshooting.
## General Commands
| Command | Description | Default |
@@ -57,16 +59,93 @@ These control the Raviente large-scale raid. Some subcommands require the ZZ cli
| Input | Effect |
|-------|--------|
| `@dice` | Roll a random number 1100 |
| `@dice` | Roll a random number 1-100 |
## Security Classification
### High-Risk (disable in production)
| Command | Risk |
|---------|------|
| `rights` | Grants admin privileges and all courses |
| `kqf` | Unlocks restricted HR progression content |
| `ban` | Can permanently remove players |
| `tele` | Bypasses normal movement restrictions |
### Medium-Risk (use with caution)
| Command | Risk | Mitigation |
|---------|------|------------|
| `course` | Players toggle courses without payment | Limit which courses are available via `DefaultCourses` in [config](Erupe-Configuration#courses-subscription-types) |
### Safe
| Command | Reason |
|---------|--------|
| `help` | Read-only, shows available commands |
| `reload` | Only affects visual state, no persistent changes |
| `ravi` | Only affects raid event state |
| `timer` | User preference only |
| `playtime` | Read-only display |
| `psn` | Account linking, low risk |
| `discord` | Token generation, requires Discord bot |
## Configuration
Commands are defined in the `Commands` array in `config.json`:
Commands are defined in the `Commands` array in `config.json`. Each entry has three fields:
| Property | Type | Description |
|----------|------|-------------|
| `Name` | string | Command identifier (must match internal name) |
| `Enabled` | boolean | Whether the command is active for non-operators |
| `Prefix` | string | Chat text that triggers the command |
### Example: Minimal Safe Config
```json
"Commands": [
{ "Name": "help", "Enabled": true, "Prefix": "help" },
{ "Name": "rights", "Enabled": false, "Prefix": "rights" },
...
{ "Name": "reload", "Enabled": true, "Prefix": "reload" },
{ "Name": "ravi", "Enabled": true, "Prefix": "ravi" },
{ "Name": "timer", "Enabled": true, "Prefix": "timer" },
{ "Name": "playtime", "Enabled": true, "Prefix": "playtime" }
]
```
### Example: Community Server
```json
"Commands": [
{ "Name": "help", "Enabled": true, "Prefix": "help" },
{ "Name": "reload", "Enabled": true, "Prefix": "reload" },
{ "Name": "ravi", "Enabled": true, "Prefix": "ravi" },
{ "Name": "course", "Enabled": true, "Prefix": "course" },
{ "Name": "timer", "Enabled": true, "Prefix": "timer" },
{ "Name": "playtime", "Enabled": true, "Prefix": "playtime" },
{ "Name": "psn", "Enabled": true, "Prefix": "psn" },
{ "Name": "discord", "Enabled": true, "Prefix": "discord" },
{ "Name": "rights", "Enabled": false, "Prefix": "rights" },
{ "Name": "tele", "Enabled": false, "Prefix": "tele" },
{ "Name": "kqf", "Enabled": false, "Prefix": "kqf" },
{ "Name": "ban", "Enabled": false, "Prefix": "ban" }
]
```
### Example: Full Development Config
```json
"Commands": [
{ "Name": "help", "Enabled": true, "Prefix": "help" },
{ "Name": "reload", "Enabled": true, "Prefix": "reload" },
{ "Name": "ravi", "Enabled": true, "Prefix": "ravi" },
{ "Name": "course", "Enabled": true, "Prefix": "course" },
{ "Name": "rights", "Enabled": true, "Prefix": "rights" },
{ "Name": "tele", "Enabled": true, "Prefix": "tele" },
{ "Name": "kqf", "Enabled": true, "Prefix": "kqf" },
{ "Name": "ban", "Enabled": true, "Prefix": "ban" },
{ "Name": "timer", "Enabled": true, "Prefix": "timer" },
{ "Name": "playtime", "Enabled": true, "Prefix": "playtime" },
{ "Name": "psn", "Enabled": true, "Prefix": "psn" },
{ "Name": "discord", "Enabled": true, "Prefix": "discord" }
]
```

@@ -139,3 +139,69 @@ SELECT ravireset(0);
SELECT u.username, s.token FROM sign_sessions s
JOIN users u ON u.id = s.user_id;
```
## Backup & Restore
### Backup
```bash
# Full backup (custom format, recommended)
pg_dump -U postgres -Fc erupe > erupe_backup.dump
# Plain SQL backup
pg_dump -U postgres erupe > erupe_backup.sql
# Compressed plain SQL
pg_dump -U postgres erupe | gzip > erupe_backup.sql.gz
```
### Restore
```bash
# From custom format
dropdb -U postgres erupe
createdb -U postgres erupe
pg_restore -U postgres -d erupe erupe_backup.dump
# From plain SQL
dropdb -U postgres erupe
createdb -U postgres erupe
psql -U postgres -d erupe -f erupe_backup.sql
# From compressed SQL
gunzip -c erupe_backup.sql.gz | psql -U postgres -d erupe
```
### Maintenance
```bash
# Reclaim space and update query planner statistics
psql -U postgres -d erupe -c "VACUUM ANALYZE;"
# Check database size
psql -U postgres -d erupe -c "SELECT pg_size_pretty(pg_database_size('erupe'));"
```
## Troubleshooting
| Error | Cause | Fix |
|-------|-------|-----|
| `Connection refused` | PostgreSQL not running or wrong port | Verify service is running: `systemctl status postgresql`. Check `Port` in config. |
| `password authentication failed` | Wrong password or user | Verify `Database.Password` in `config.json`. Check user exists: `psql -U postgres -c "\du"` |
| `database "erupe" does not exist` | Database not created | Run `createdb -U postgres erupe` |
| `permission denied for table` | User lacks privileges | `GRANT ALL ON ALL TABLES IN SCHEMA public TO <user>;` |
| Server starts but data doesn't load | Schema patches missing or out of order | Re-apply patches in numerical order from `schemas/patch-schema/` |
## Performance Tuning
For servers with many concurrent players, consider tuning PostgreSQL:
```conf
# /etc/postgresql/*/main/postgresql.conf
shared_buffers = 2GB # 25% of available RAM
work_mem = 16MB # Per-operation memory
maintenance_work_mem = 512MB # For VACUUM, CREATE INDEX
```
For high connection counts, consider [PgBouncer](https://www.pgbouncer.org/) for connection pooling. Restart PostgreSQL after changing `postgresql.conf`.

@@ -8,7 +8,7 @@
| Language | Sets the language of server-side strings. Only English `en` and Japanese `jp` are available, contributions welcome | en | en/jp |
| DisableSoftCrash | Disables some crash outputs and in-game shutdown timer | false | |
| HideLoginNotice | Hides the notices that appear on login from `LoginNotices` | true | |
| LoginNotices | Array of login notices for users, you can have multiple notices | | |
| LoginNotices | Array of MHFML-formatted login notices (see below) | | |
| PatchServerManifest | See [ZeruLight/Servers](https://github.com/ZeruLight/Servers#mhf-patch-server-api) | | |
| PatchServerFile | See [ZeruLight/Servers](https://github.com/ZeruLight/Servers#mhf-patch-server-api) | | |
| ScreenshotAPIURL | See [ZeruLight/Servers](https://github.com/ZeruLight/Servers#mhf-screenshot-bbs-api) | | |
@@ -25,6 +25,28 @@
| SaveDumps.RawEnabled | Enables saving an uncompressed copy of the savedata | false | |
| SaveDumps.OutputDir | The folder that save dumps are saved to | save-backups | |
#### MHFML Tags (Login Notice Formatting)
Login notices use MHFML (Monster Hunter Frontier Markup Language) tags:
| Tag | Effect |
|-----|--------|
| `<BODY>` | Start new text block |
| `<BR>` | Line break |
| `<CENTER>`, `<LEFT>`, `<RIGHT>` | Text alignment |
| `<SIZE_2>` | Normal text size |
| `<SIZE_3>` | Large text size |
| `<C_4>` | Red text |
| `<C_5>` | Yellow text |
| `<C_7>` | White text |
**Example notice:**
```json
"LoginNotices": [
"<BODY><CENTER><SIZE_3><C_4>Welcome to Our Server!<BR><BODY><LEFT><SIZE_2><C_5>Join our Discord: discord.gg/example"
]
```
### `DebugOptions` Configuration
| Variable | Description | Default | Options |
@@ -101,6 +123,78 @@
| DisableRoad | Disables the Hunting Road | false | |
| SeasonOverride | Enables quests to use the current Season and time | false | |
### `Logging` Configuration
> **Branch availability:** File logging is available on the `v9.2.x-stable` branch. The `main` branch logs to stdout only.
When enabled, Erupe uses [lumberjack](https://github.com/natefinch/lumberjack) for automatic log rotation and compression.
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `LogToFile` | boolean | `true` | Enable file logging (logs to both console and file) |
| `LogFilePath` | string | `"logs/erupe.log"` | Path to log file (directory created automatically) |
| `LogMaxSize` | number | `100` | Maximum log file size in MB before rotation |
| `LogMaxBackups` | number | `3` | Number of old log files to keep |
| `LogMaxAge` | number | `28` | Maximum days to retain old logs |
| `LogCompress` | boolean | `true` | Compress rotated log files with gzip |
#### Log Rotation
When the current log reaches `LogMaxSize` MB:
1. Current log is renamed to `erupe.log.YYYY-MM-DD-HH-MM-SS`
2. If `LogCompress` is `true`, old log is compressed to `.gz`
3. New `erupe.log` is created
4. Logs beyond `LogMaxBackups` count or `LogMaxAge` days are deleted
#### Log Format
The format depends on `DevMode`:
- **`DevMode: true`** — human-readable console format: `2025-11-18T10:30:45.123Z INFO channelserver Player connected {"charID": 12345}`
- **`DevMode: false`** — JSON format: `{"level":"info","ts":"...","logger":"channelserver","msg":"Player connected","charID":12345}`
#### Disk Space Estimate
```
Total ≈ (LogMaxSize × LogMaxBackups) / CompressionRatio
```
Text logs compress ~10:1, JSON logs ~8:1. Default settings (100 MB × 3 backups, compressed) use roughly **30 MB** of disk.
#### Examples
**Standard production:**
```json
"Logging": {
"LogToFile": true,
"LogFilePath": "logs/erupe.log",
"LogMaxSize": 100,
"LogMaxBackups": 7,
"LogMaxAge": 30,
"LogCompress": true
}
```
**Development (no file logging):**
```json
"Logging": {
"LogToFile": false
}
```
**High-volume server:**
```json
"Logging": {
"LogToFile": true,
"LogFilePath": "/var/log/erupe/erupe.log",
"LogMaxSize": 500,
"LogMaxBackups": 14,
"LogMaxAge": 60,
"LogCompress": true
}
```
### Discord
There is limited Discord capability in Erupe. The feature allows you to relay messages from your server into a channel.
This may be either be removed or revamped in a future version.
@@ -155,7 +249,55 @@ There are several chat commands that can be turned on and off. Most are for admi
* 12288 = PC/PS3(R)
### Courses (Subscription Types)
See [Enumerations](https://github.com/ZeruLight/Erupe/wiki/Enumerations#course-types)
See [Enumerations](https://github.com/ZeruLight/Erupe/wiki/Enumerations#course-types) for the full course type list.
Courses are stored as a bitfield in `users.rights`. Players toggle available courses with the [`!course` command](Player-Commands#course).
#### Bitfield Encoding
| Course | Bit | Value |
|--------|-----|-------|
| HunterLife | 0 | 1 |
| Extra | 1 | 2 |
| Premium | 2 | 4 |
| Assist | 3 | 8 |
| N | 4 | 16 |
| Hiden | 5 | 32 |
| HunterSupport | 6 | 64 |
| NBoost | 7 | 128 |
| NetCafe | 8 | 256 |
| HLRenewing | 9 | 512 |
| EXRenewing | 10 | 1024 |
Add values together for combinations. Example: HunterLife + Extra + NetCafe = 1 + 2 + 256 = **259**.
#### Manual Database Override
```sql
-- Enable all courses for a user
UPDATE users SET rights = 2047 WHERE username = 'player';
-- Enable only HunterLife + Extra + NetCafe
UPDATE users SET rights = 259 WHERE username = 'player';
```
#### Example Configs
**Open server (all courses available):**
```json
"DefaultCourses": [1, 2, 3, 4, 5, 6, 7, 8, 9, 23, 24]
```
**Restricted server (core only):**
```json
"DefaultCourses": [1, 2, 23, 24]
```
**Free-to-play (NetCafe only):**
```json
"DefaultCourses": [9, 23, 24]
```
# Database Configuration Schemas
The following can be edited via the database for gameplay customization.
@@ -168,4 +310,21 @@ The following can be edited via the database for gameplay customization.
- Net-Cafe
- [Scenarios](https://github.com/ZeruLight/Erupe/wiki/Scenarios)
There are examples of these in `/schemas/bundled-schema/`.
There are examples of these in `/schemas/bundled-schema/`.
# Production Security Checklist
Before running a public-facing server, verify:
- [ ] `DebugOptions.CleanDB: false` — prevents wiping the database on startup
- [ ] `DebugOptions.DisableTokenCheck: false` — enables session token validation
- [ ] `DebugOptions.MaxLauncherHR: false` — prevents bypassing HR requirements
- [ ] `AutoCreateAccount: false` — require manual account creation (or use the API)
- [ ] Strong `Database.Password` set (not blank, not default)
- [ ] `Rights` command disabled in `Commands` array (or restricted to operators)
- [ ] `KeyQuest` command disabled (unless intentional)
- [ ] `Ban` command disabled for non-operators
- [ ] Firewall configured for only necessary ports (see [Server Operations](Server-Operations#firewall-configuration))
- [ ] Database not exposed publicly (bind PostgreSQL to `localhost` or internal network)
- [ ] `Logging` enabled for monitoring and incident response
- [ ] `SaveDumps.Enabled: true` for character backup recovery

@@ -72,6 +72,7 @@ docker compose up server # Start Erupe
- **[Server Operations](Server-Operations)** — quest/scenario files, save system, REST API, Discord bot, Docker
- **[Erupe Configuration](Erupe-Configuration)** — full config.json reference (general, debug, gameplay, worlds, courses)
- **[Commands](Commands)** — in-game chat commands (general, admin, Raviente)
- **[Player Commands](Player-Commands)** — player-friendly command reference with usage examples
### Development
- **[Contributing](Contributing)** — adding packet handlers, debugging, testing, CI

160
Player-Commands.md Normal file

@@ -0,0 +1,160 @@
# Player Commands Reference
This guide covers all chat commands available to players on Erupe servers.
## Using Commands
Type commands in the chat window. All commands start with `!` (your server may use a different prefix).
---
## General Commands
### !help
Display available commands.
**Usage:** `!help`
Shows a list of all enabled commands on your server.
### !reload
Reload all players in your current area.
**Usage:** `!reload`
Forces a refresh of all player data in your Land/Stage. Useful if you see visual glitches or invisible players.
### !course
Toggle subscription courses on your account.
**Usage:** `!course <course_name>`
Available courses (server-dependent):
| Course Name | Description |
|-------------|-------------|
| `hunterlife` | Hunter Life Course — various hunting QoL benefits |
| `extra` | Extra Course — additional features |
| `premium` | Premium Course — premium benefits |
| `assist` | Assist Course — helper features |
| `nboost` | N Boost — point multipliers |
| `netcafe` | NetCafe Course — boost time, bonus rewards |
| `hiden` | Hiden Course — hidden features and content |
Example:
```
!course hunterlife → Toggles Hunter Life Course on/off
```
Available courses depend on server configuration. If a course is locked, you'll see a message saying so.
### !timer
Toggle the quest timer display.
**Usage:** `!timer`
Shows or hides the quest countdown timer during hunts. Your preference is saved to your account.
### !playtime
Show your total playtime.
**Usage:** `!playtime`
Displays how long you've played on your current character.
---
## Account Linking
### !psn
Link a PlayStation Network ID to your account.
**Usage:** `!psn <your_psn_id>`
Example: `!psn MyPSNUsername`
### !discord
Generate a Discord account linking token.
**Usage:** `!discord`
1. Type `!discord` in-game
2. Copy the token shown
3. Use `/link <token>` in your server's Discord bot
---
## Raviente Siege Commands
These commands are used during the Great Slaying (Raviente) siege event.
| Command | Description |
|---------|-------------|
| `!ravi start` | Start the Great Slaying event |
| `!ravi cm` | Check current damage multiplier |
| `!ravi sr` | Send resurrection support |
| `!ravi ss` | Send sedation support |
| `!ravi rs` | Request sedation support from others |
Commands only work while participating in a Raviente siege.
---
## Special Chat
| Input | Effect |
|-------|--------|
| `@dice` | Roll a random number 1-100, visible to all players in your area |
This is not a `!` command — just type `@dice` in regular chat.
---
## Admin Commands
These commands are disabled by default and require operator permissions (`rights` bitmask). Server administrators may enable some for staff use.
| Command | Description |
|---------|-------------|
| `!tele <x> <y>` | Teleport to coordinates |
| `!rights <value>` | Set account permission level |
| `!kqf get` | View current Key Quest Flag value |
| `!kqf set <hex>` | Set KQF to specific 16-char hex value (takes effect after switching Land) |
| `!ban <character_id> [duration]` | Ban a player (optionally with duration) |
### Ban Duration Format
| Unit | Meaning |
|------|---------|
| `s` | Seconds |
| `m` | Minutes |
| `h` | Hours |
| `d` | Days |
| `mo` | Months |
| `y` | Years |
Examples: `!ban ABC123 7d` (7-day ban), `!ban ABC123` (permanent).
---
## Troubleshooting
| Problem | Solution |
|---------|----------|
| Command not recognized | Check spelling; try `!help` to see what's available |
| "Command is disabled" | The server operator has disabled this command |
| Command does nothing | Make sure you're in the correct chat channel; some commands only work in specific situations |
| Course says "locked" | That course is not available on this server — contact your server admin |
---
## For Server Operators
See [Commands](Commands) for configuration details and security classification.

@@ -170,3 +170,46 @@ docker compose up server # 2. Start Erupe
### Troubleshooting
If PostgreSQL doesn't initialize properly, check that `docker/init/setup.sh` has LF line endings (not CRLF).
## Firewall Configuration
Open the sign, entrance, and channel server ports for incoming TCP connections. Adjust the channel port range to match your `Entrance.Entries` configuration.
### Linux (ufw)
```bash
sudo ufw allow 53312/tcp # Sign server
sudo ufw allow 53310/tcp # Entrance server
sudo ufw allow 54001:54010/tcp # Channel servers
```
### Linux (iptables)
```bash
sudo iptables -A INPUT -p tcp --dport 53312 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 53310 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 54001:54010 -j ACCEPT
```
### Windows PowerShell
```powershell
New-NetFirewallRule -DisplayName "Erupe Sign" -Direction Inbound -Protocol TCP -LocalPort 53312 -Action Allow
New-NetFirewallRule -DisplayName "Erupe Entrance" -Direction Inbound -Protocol TCP -LocalPort 53310 -Action Allow
New-NetFirewallRule -DisplayName "Erupe Channels" -Direction Inbound -Protocol TCP -LocalPort 54001-54010 -Action Allow
```
## Monitoring
Quick one-liners to check server health:
```bash
# Check if all servers are listening
ss -tlnp | grep -E '(53312|53310|54001)'
# Count established connections per channel port
netstat -an | grep ESTABLISHED | grep -c 54001
# Watch connections in real time (refreshes every second)
watch -n 1 'ss -tn state established | grep -E "54[0-9]{3}" | wc -l'
```