415 lines
13 KiB
Markdown
415 lines
13 KiB
Markdown
# megastructure.surf
|
|
|
|
A Docker-based Counter-Strike: Source surf server with Shavit Surf Timer and community physics fix plugins.
|
|
|
|
## Overview
|
|
|
|
This repository contains a complete CSS surf server setup using Docker containers. The setup includes:
|
|
|
|
- **CSS Dedicated Server (CSSDS)** - Running in 32-bit mode for compatibility
|
|
- **Shavit Surf Timer** - Surf-specific fork (v1.0.6) with JSON zone support and SQLite
|
|
- **MetaMod:Source** - Plugin loader framework
|
|
- **SourceMod** - Server administration and plugin platform
|
|
- **Community Physics Plugins** - Essential surf fixes and enhancements
|
|
- **JSON Zone Loading** - Automatic zone loading from surf-zones repository
|
|
|
|
## Architecture
|
|
|
|
### Docker Service
|
|
|
|
#### `cssds` (CSS Dedicated Server)
|
|
- Based on Debian Bookworm
|
|
- Runs SteamCMD to download/update CSS DS
|
|
- Installs MetaMod:Source and SourceMod
|
|
- Installs surf-specific plugins and timer system
|
|
- Runs in 32-bit mode for plugin compatibility
|
|
- Port: 27015 (configurable via `SRCDS_PORT`)
|
|
|
|
### Key Files
|
|
|
|
```
|
|
.
|
|
├── docker-compose.yaml # Service orchestration
|
|
├── etc/
|
|
│ ├── cssds.dockerfile # CSS DS container definition
|
|
│ ├── run.sh # Main setup and launch script
|
|
│ ├── update_cssds.txt # SteamCMD script for CSS DS
|
|
│ └── cfg/
|
|
│ └── server.cfg # Server configuration
|
|
└── data/ # Persistent data (volume mount)
|
|
└── cssds/ # CSS server files and database
|
|
```
|
|
|
|
## Installed Plugins & Extensions
|
|
|
|
### Timer System
|
|
|
|
**Shavit Surf Timer v1.0.6** ([GitHub](https://github.com/bhopppp/Shavit-Surf-Timer))
|
|
- Surf-specific fork with enhanced features
|
|
- Full surf timer with SQLite backend (no separate database needed)
|
|
- Replays, rankings, zone system, statistics
|
|
- **JSON zone support** from [surf-zones](https://github.com/wrldspawn/surf-zones) repository
|
|
- Zones loaded from `https://wrldspawn.github.io/surf-zones/z/{map}.json`
|
|
- Includes stripper configurations and mapfixes
|
|
- Matches KSF (Kreedz Surf Federation) server behavior
|
|
- Config location: `addons/sourcemod/configs/shavit/`
|
|
|
|
### Required Extensions
|
|
|
|
**sm-json v5.0.1** ([GitHub](https://github.com/clugg/sm-json))
|
|
- Pure SourcePawn JSON library for zone loading
|
|
- Provides `JSONArray.FromFile()` for loading JSON zones
|
|
|
|
**sm_closestpos v1.1.1** ([GitHub](https://github.com/rtldg/sm_closestpos))
|
|
- Required for ghost/replay functionality
|
|
- Enables replay bot positioning
|
|
|
|
**sm-ripext v1.3.2** ([GitHub](https://github.com/ErikMinekus/sm-ripext))
|
|
- HTTP/REST extension for Shavit
|
|
- Required for shavit-wrsh plugin
|
|
- Alternative JSON/HTTP support
|
|
|
|
**DHooks v2.2.0** ([GitHub](https://github.com/peace-maker/DHooks2))
|
|
- Included with SourceMod
|
|
- Required by most modern plugins
|
|
|
|
### Physics Fix Plugins
|
|
|
|
**MomSurfFix v1.1.5** ([GitHub](https://github.com/GAMMACASE/MomSurfFix))
|
|
- Fixes Source engine surf physics to match Momentum Mod behavior
|
|
- Essential for proper surf mechanics
|
|
|
|
**EventQueue Fix v1.3.2** ([GitHub](https://github.com/hermansimensen/eventqueue-fix))
|
|
- Fixes map entity timing issues
|
|
- Ensures triggers and outputs work correctly
|
|
|
|
**RNGFix v1.1.3** ([GitHub](https://github.com/jason-e/rngfix))
|
|
- Fixes Source engine RNG determinism issues
|
|
- Ensures consistent physics behavior
|
|
|
|
**Note:** PushFix Definitive Edition is NOT installed as it's CS:GO only and not compatible with CSS.
|
|
|
|
### Base Plugins
|
|
|
|
SourceMod includes built-in plugins for server administration:
|
|
- Admin Menu, Basic Commands, Player Commands
|
|
- Rock The Vote, Map Nominations, MapChooser
|
|
- Reserved Slots, Basic Bans
|
|
- And more (see `etc/run.sh` for full list)
|
|
|
|
## Setup & Usage
|
|
|
|
### Prerequisites
|
|
|
|
- Docker
|
|
- Docker Compose
|
|
- ~10GB disk space for server files
|
|
|
|
### Environment Variables
|
|
|
|
Configure in `docker-compose.yaml` or `.env` file:
|
|
|
|
```yaml
|
|
# Server Settings
|
|
METAMOD_VERSION: "1.12" # MetaMod:Source version
|
|
SOURCEMOD_VERSION: "1.12" # SourceMod version
|
|
SRCDS_PORT: 27015 # Server port
|
|
SRCDS_MAXPLAYERS: 32 # Max player slots
|
|
SRCDS_STARTMAP: "surf_ski_2" # Starting map
|
|
SRCDS_IP: "0.0.0.0" # Bind IP address
|
|
|
|
# Admin Configuration (comma-separated Steam IDs)
|
|
SRCDS_ADMINS: "STEAM_1:0:12345678,STEAM_1:1:87654321"
|
|
```
|
|
|
|
**Admin Steam ID Format:**
|
|
- Use `STEAM_1:Y:XXXXXX` format (recommended)
|
|
- Or `[U:1:XXXXXX]` format (modern SteamID3)
|
|
- Find your Steam ID in-game with `status` command
|
|
- Or use https://steamid.io/
|
|
|
|
### Building & Running
|
|
|
|
```bash
|
|
# Build the container
|
|
docker-compose build
|
|
|
|
# Start the server
|
|
docker-compose up -d
|
|
|
|
# View logs
|
|
docker-compose logs -f cssds
|
|
|
|
# Restart the server
|
|
docker-compose restart cssds
|
|
|
|
# Stop the server
|
|
docker-compose down
|
|
```
|
|
|
|
### Update Server Files
|
|
|
|
The server installation is persistent - game files are only downloaded on first run. To force an update:
|
|
|
|
```bash
|
|
# Update CSS game files
|
|
docker-compose run cssds bash ./etc/run.sh --update-cssds
|
|
```
|
|
|
|
Or modify the environment to skip updates by default (already configured):
|
|
- Default: Updates are **skipped** for faster restarts
|
|
- Use `--update-cssds` flag to force updates
|
|
|
|
### Database Configuration
|
|
|
|
The server uses **SQLite by default** (no separate database needed):
|
|
- Database file: `addons/sourcemod/data/sqlite/shavit-local.sq3`
|
|
- Automatically created on first run
|
|
- Stores player times, rankings, and replay data
|
|
|
|
**To switch to MariaDB later** (optional):
|
|
1. Edit `addons/sourcemod/configs/databases.cfg`
|
|
2. Change driver from `sqlite` to `mysql`
|
|
3. Configure host, database, user, password
|
|
4. Restart server
|
|
|
|
### JSON Zones Configuration
|
|
|
|
The server is **automatically configured** to use JSON zones instead of SQL-based zones:
|
|
|
|
**Automatic Setup:**
|
|
- Zones loaded from [surf-zones](https://github.com/wrldspawn/surf-zones) repository
|
|
- Includes 400+ maps with pre-configured zones
|
|
- No manual zone creation needed for supported maps
|
|
- URL: `https://wrldspawn.github.io/surf-zones/z/{map}.json`
|
|
|
|
**Configuration Files Created:**
|
|
- `cfg/sourcemod/plugin.shavit-zones.cfg` - Disables SQL zones
|
|
- `cfg/sourcemod/plugin.shavit-zones-json.cfg` - Sets JSON URL
|
|
- `addons/stripper/` - Map entity fixes
|
|
- `addons/sourcemod/configs/shavit-mapfixes.cfg` - Map settings
|
|
- `addons/sourcemod/configs/shavit-styles.cfg` - KSF-style configurations
|
|
|
|
**Benefits:**
|
|
- ✅ No manual zone editing for popular maps
|
|
- ✅ Community-maintained and updated
|
|
- ✅ Includes map fixes
|
|
- ✅ Matches KSF server standards
|
|
- ✅ Faster deployment
|
|
|
|
### Server Configuration
|
|
|
|
Edit `etc/cfg/server.cfg` for server settings:
|
|
- Hostname, RCON password (change default!)
|
|
- Surf physics (gravity, air accelerate, max velocity)
|
|
- HUD settings (minimal by default)
|
|
- Network rates
|
|
- Player settings
|
|
|
|
**Important:** Change the default RCON password:
|
|
```cfg
|
|
rcon_password "changeme" // CHANGE THIS!
|
|
```
|
|
|
|
## In-Game Commands
|
|
|
|
### Admin Commands
|
|
```
|
|
rcon_password <password> // Authenticate RCON
|
|
rcon sm_admin // Open admin menu
|
|
sm_map <mapname> // Change map
|
|
sm_kick <player> // Kick player
|
|
sm_ban <player> <time> // Ban player
|
|
```
|
|
|
|
### Player Commands
|
|
```
|
|
!wr // World records
|
|
!top // Top players
|
|
!profile // Your profile
|
|
!rank // Your rank
|
|
!recent // Recent records
|
|
!nominate // Nominate map
|
|
!rtv // Rock the vote
|
|
!stage <number> // Teleport to stage
|
|
!r / !restart // Restart timer
|
|
!pause // Pause timer
|
|
!cp / !checkpoint // Save checkpoint
|
|
!tp / !teleport // Teleport to checkpoint
|
|
!hide // Hide players
|
|
!hideweapon // Hide weapon
|
|
!hud // HUD settings
|
|
!zones // Show/edit zones
|
|
```
|
|
|
|
### Console Commands
|
|
```
|
|
sm plugins list // List loaded plugins
|
|
sm exts list // List loaded extensions
|
|
sm cmds // List all commands
|
|
status // Show players and Steam IDs
|
|
```
|
|
|
|
## Development Notes
|
|
|
|
### 32-bit Mode
|
|
|
|
The server runs in **32-bit mode** for maximum plugin compatibility:
|
|
- Most SourceMod plugins and extensions are 32-bit only
|
|
- DHooks and other critical extensions lack 64-bit versions
|
|
- 32-bit provides better compatibility with the plugin ecosystem
|
|
|
|
### Plugin Installation Pattern
|
|
|
|
All plugins follow an idempotent installation pattern in `etc/run.sh`:
|
|
|
|
```bash
|
|
if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/plugin.smx" ]; then
|
|
cd /tmp
|
|
wget "https://github.com/author/repo/releases/download/version/plugin.zip"
|
|
unzip -o "plugin.zip"
|
|
cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
|
|
rm -rf "plugin.zip" addons/
|
|
echo "Installed Plugin vX.Y.Z"
|
|
fi
|
|
```
|
|
|
|
This allows safe re-runs without reinstalling existing plugins.
|
|
|
|
### Run Script Flow
|
|
|
|
The `etc/run.sh` script executes in this order:
|
|
|
|
1. **update_cssds()** - Download/update CSS DS via SteamCMD (skipped by default)
|
|
2. **steamclient_binary()** - Locate and symlink steamclient.so (32-bit)
|
|
3. **install_surf()** - Install timer, extensions, and physics plugins
|
|
- Install MetaMod:Source if missing
|
|
- Install SourceMod if missing
|
|
- Install sm-json (JSON library)
|
|
- Install sm_closestpos (replay positioning)
|
|
- Install sm-ripext (HTTP/REST)
|
|
- Install Shavit Surf Timer with sounds/materials
|
|
- Install shavit-zones-json from original bhoptimer
|
|
- Install MomSurfFix, EventQueue Fix, RNGFix
|
|
4. **configure_shavit_zones()** - Download JSON zones, stripper configs, mapfixes
|
|
5. **configure_shavit_database()** - Create SQLite database config
|
|
6. **configure_admins()** - Create admins from SRCDS_ADMINS env var
|
|
7. **cfg()** - Copy server.cfg
|
|
8. **run_cssds()** - Launch the dedicated server
|
|
|
|
### Version Strategy
|
|
|
|
**Fixed versions are used** for:
|
|
- **Stability** - Known working versions
|
|
- **Reproducibility** - Deterministic builds
|
|
- **No API dependencies** - Avoids rate limits
|
|
- **Easy rollback** - Specific version control
|
|
|
|
## Verification
|
|
|
|
### Check Installed Plugins
|
|
|
|
```bash
|
|
docker exec -it $(docker ps -qf "name=cssds") \
|
|
ls -la /home/steam/cssds/cstrike/addons/sourcemod/plugins/*.smx
|
|
```
|
|
|
|
### Check Extensions
|
|
|
|
```bash
|
|
docker exec -it $(docker ps -qf "name=cssds") \
|
|
ls -la /home/steam/cssds/cstrike/addons/sourcemod/extensions/*.so
|
|
```
|
|
|
|
### In-Game Verification
|
|
|
|
Connect to the server and run:
|
|
```
|
|
sm plugins list
|
|
sm exts list
|
|
```
|
|
|
|
You should see:
|
|
- **Plugins:** Shavit (multiple modules), momsurffix2, eventqueuefix, rngfix
|
|
- **Extensions:** sm-json, closestpos, ripext, dhooks, sdkhooks
|
|
|
|
## Troubleshooting
|
|
|
|
### Plugins Not Loading
|
|
|
|
1. Check MetaMod: `meta list`
|
|
2. Check SourceMod: `sm version`
|
|
3. Check errors: `sm plugins list`
|
|
4. Check logs: `addons/sourcemod/logs/`
|
|
|
|
**Common Issues:**
|
|
- Missing extension dependencies (install sm-json, closestpos, ripext)
|
|
- Wrong architecture (use 32-bit plugins/extensions)
|
|
- File permissions (ensure steam user owns files)
|
|
|
|
### Zones Not Loading
|
|
|
|
**Symptoms:** Map loads but no start/end zones
|
|
|
|
**Solutions:**
|
|
|
|
1. **Check if map exists in surf-zones:**
|
|
- Visit: https://github.com/wrldspawn/surf-zones/tree/main/z
|
|
- Search for `surf_<mapname>.json`
|
|
|
|
2. **Verify JSON zones enabled:**
|
|
```
|
|
sm_cvar shavit_zones_usesql
|
|
// Should be "0"
|
|
```
|
|
|
|
3. **Check sm-json loaded:**
|
|
```
|
|
sm exts list
|
|
// Look for sm-json or json.inc in includes
|
|
```
|
|
|
|
4. **Check logs:**
|
|
- `addons/sourcemod/logs/shavit/`
|
|
- Look for HTTP/JSON errors
|
|
|
|
5. **Create zones manually:**
|
|
```
|
|
!zones // Zone editor
|
|
!edit // Admin zone editor
|
|
```
|
|
|
|
### Missing Sounds/Materials
|
|
|
|
**Symptoms:** Missing finish sounds, zone decals
|
|
|
|
**Solution:** Reinstall Shavit to get sound/material files:
|
|
```bash
|
|
rm /path/to/data/cssds/cstrike/addons/sourcemod/plugins/shavit-core.smx
|
|
docker-compose restart cssds
|
|
```
|
|
|
|
### Server Won't Start
|
|
|
|
1. Check logs: `docker-compose logs cssds`
|
|
2. Verify port 27015 available
|
|
3. Check disk space
|
|
4. Verify SteamCMD succeeded
|
|
|
|
## Credits
|
|
|
|
- **Shavit Surf Timer** - [bhopppp](https://github.com/bhopppp/Shavit-Surf-Timer)
|
|
- **sm-json** - [clugg](https://github.com/clugg/sm-json)
|
|
- **sm_closestpos** - [rtldg](https://github.com/rtldg/sm_closestpos)
|
|
- **sm-ripext** - [ErikMinekus](https://github.com/ErikMinekus/sm-ripext)
|
|
- **MomSurfFix** - [GAMMACASE](https://github.com/GAMMACASE/MomSurfFix)
|
|
- **EventQueue Fix** - [hermansimensen](https://github.com/hermansimensen/eventqueue-fix)
|
|
- **RNGFix** - [jason-e](https://github.com/jason-e/rngfix)
|
|
- **Surf Zones** - [wrldspawn](https://github.com/wrldspawn/surf-zones)
|
|
- **MetaMod:Source** - [AlliedModders](https://www.metamodsource.net/)
|
|
- **SourceMod** - [AlliedModders](https://www.sourcemod.net/)
|
|
|
|
## License
|
|
|
|
This setup configuration is provided as-is. Individual components retain their original licenses.
|