This commit is contained in:
Nathan Rashleigh 2026-02-09 18:15:01 +11:00
parent f08be1d72c
commit 43883f3841
6 changed files with 539 additions and 316 deletions

4
.env
View File

@ -2,7 +2,7 @@ STEAMAPPID=232330
STEAMAPP=css STEAMAPP=css
SRCDS_TOKEN=C02633B3395EA6BEF7D8DFBA440ABB7F SRCDS_TOKEN=C02633B3395EA6BEF7D8DFBA440ABB7F
SRCDS_RCONPW="lol" SRCDS_RCONPW="reebok"
SRCDS_PW="6" SRCDS_PW="6"
SRCDS_STARTMAP="surf_boreas" SRCDS_STARTMAP="surf_boreas"
@ -28,6 +28,7 @@ SRCDS_WORKSHOP_AUTHKEY=""
SRCDS_CFG="server.cfg" SRCDS_CFG="server.cfg"
SRCDS_MAPCYCLE="mapcycle.txt" SRCDS_MAPCYCLE="mapcycle.txt"
SRCDS_ADMINS="STEAM_1:1:12270329"
# ---------- # ----------
# mariadb # mariadb
@ -35,3 +36,4 @@ MARIADB_ROOT_PASSWORD="surfsup"
MARIADB_DATABASE="influx" MARIADB_DATABASE="influx"
MARIADB_USER="influx" MARIADB_USER="influx"
MARIADB_PASSWORD="righteous" MARIADB_PASSWORD="righteous"

412
README.md
View File

@ -1,36 +1,30 @@
# megastructure.surf # megastructure.surf
A Docker-based Counter-Strike: Source surf server with Shavit BHopTimer and community physics fix plugins. A Docker-based Counter-Strike: Source surf server with Shavit Surf Timer and community physics fix plugins.
## Overview ## Overview
This repository contains a complete CSS surf server setup using Docker containers. The setup includes: This repository contains a complete CSS surf server setup using Docker containers. The setup includes:
- **CSS Dedicated Server (CSSDS)** - Running on 64-bit binaries for improved performance - **CSS Dedicated Server (CSSDS)** - Running in 32-bit mode for compatibility
- **Shavit BHopTimer** - Actively maintained timer system (v4.0.1) with MySQL support - **Shavit Surf Timer** - Surf-specific fork (v1.0.6) with JSON zone support and SQLite
- **MariaDB** - Database backend for timer records and player data
- **MetaMod:Source** - Plugin loader framework - **MetaMod:Source** - Plugin loader framework
- **SourceMod** - Server administration and plugin platform - **SourceMod** - Server administration and plugin platform
- **Community Physics Plugins** - Essential surf/bhop fixes and enhancements - **Community Physics Plugins** - Essential surf fixes and enhancements
- **JSON Zone Loading** - Automatic zone loading from surf-zones repository
## Architecture ## Architecture
### Docker Services ### Docker Service
#### `cssds` (CSS Dedicated Server) #### `cssds` (CSS Dedicated Server)
- Based on Debian Bookworm - Based on Debian Bookworm
- Runs SteamCMD to download/update CSS DS and TF2 DS (for 64-bit binaries) - Runs SteamCMD to download/update CSS DS
- Installs MetaMod:Source and SourceMod - Installs MetaMod:Source and SourceMod
- Installs surf-specific plugins and timer system - Installs surf-specific plugins and timer system
- Uses 64-bit server binaries for better performance - Runs in 32-bit mode for plugin compatibility
- Port: 27015 (configurable via `SRCDS_PORT`) - Port: 27015 (configurable via `SRCDS_PORT`)
#### `mariadb` (Database)
- MariaDB 10.11 for timer data persistence
- Stores player records, map times, rankings
- Port: 3306 (internal)
- Data persisted in `./sql:/var/lib/mysql`
### Key Files ### Key Files
``` ```
@ -38,30 +32,46 @@ This repository contains a complete CSS surf server setup using Docker container
├── docker-compose.yaml # Service orchestration ├── docker-compose.yaml # Service orchestration
├── etc/ ├── etc/
│ ├── cssds.dockerfile # CSS DS container definition │ ├── cssds.dockerfile # CSS DS container definition
│ ├── mariadb.dockerfile # MariaDB container definition
│ ├── run.sh # Main setup and launch script │ ├── run.sh # Main setup and launch script
│ ├── update_cssds.txt # SteamCMD script for CSS DS │ ├── update_cssds.txt # SteamCMD script for CSS DS
│ ├── update_tf2ds.txt # SteamCMD script for TF2 DS (64-bit libs)
│ └── cfg/ │ └── cfg/
│ └── server.cfg # Server configuration │ └── server.cfg # Server configuration
└── sql/ # MariaDB data directory (volume mount) └── data/ # Persistent data (volume mount)
└── cssds/ # CSS server files and database
``` ```
## Installed Plugins ## Installed Plugins & Extensions
### Timer System ### Timer System
**Shavit BHopTimer v4.0.1** ([GitHub](https://github.com/shavitush/bhoptimer)) **Shavit Surf Timer v1.0.6** ([GitHub](https://github.com/bhopppp/Shavit-Surf-Timer))
- Actively maintained (last update: February 2026) - Surf-specific fork with enhanced features
- Full surf/bhop timer with MySQL backend - Full surf timer with SQLite backend (no separate database needed)
- Replays, rankings, zone system, statistics - Replays, rankings, zone system, statistics
- Better SQL schema design than archived alternatives - **JSON zone support** from [surf-zones](https://github.com/wrldspawn/surf-zones) repository
- Config location: `addons/sourcemod/configs/shavit/`
- **Configured to use JSON zones** from [surf-zones](https://github.com/wrldspawn/surf-zones) repository
- Zones loaded from `https://wrldspawn.github.io/surf-zones/z/{map}.json` - Zones loaded from `https://wrldspawn.github.io/surf-zones/z/{map}.json`
- Includes stripper configurations and mapfixes - Includes stripper configurations and mapfixes
- Matches KSF (Kreedz Surf Federation) server behavior - Matches KSF (Kreedz Surf Federation) server behavior
- Use `!setmaxvel` in-game to configure max velocity per map - 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 ### Physics Fix Plugins
@ -69,10 +79,6 @@ This repository contains a complete CSS surf server setup using Docker container
- Fixes Source engine surf physics to match Momentum Mod behavior - Fixes Source engine surf physics to match Momentum Mod behavior
- Essential for proper surf mechanics - Essential for proper surf mechanics
**PushFix Definitive Edition v1.0.0** ([GitHub](https://github.com/GAMMACASE/PushFixDE))
- Fixes player collision and push mechanics
- Prevents physics exploits
**EventQueue Fix v1.3.2** ([GitHub](https://github.com/hermansimensen/eventqueue-fix)) **EventQueue Fix v1.3.2** ([GitHub](https://github.com/hermansimensen/eventqueue-fix))
- Fixes map entity timing issues - Fixes map entity timing issues
- Ensures triggers and outputs work correctly - Ensures triggers and outputs work correctly
@ -81,13 +87,15 @@ This repository contains a complete CSS surf server setup using Docker container
- Fixes Source engine RNG determinism issues - Fixes Source engine RNG determinism issues
- Ensures consistent physics behavior - Ensures consistent physics behavior
**Note:** PushFix Definitive Edition is NOT installed as it's CS:GO only and not compatible with CSS.
### Base Plugins ### Base Plugins
SourceMod includes built-in plugins for server administration: SourceMod includes built-in plugins for server administration:
- Admin Menu, Basic Commands, Player Commands - Admin Menu, Basic Commands, Player Commands
- Rock The Vote, Map Nominations, MapChooser - Rock The Vote, Map Nominations, MapChooser
- Reserved Slots, Basic Bans - Reserved Slots, Basic Bans
- And more (see `etc/run.sh` comments for full list) - And more (see `etc/run.sh` for full list)
## Setup & Usage ## Setup & Usage
@ -99,173 +107,218 @@ SourceMod includes built-in plugins for server administration:
### Environment Variables ### Environment Variables
Configure in `docker-compose.yaml`: Configure in `docker-compose.yaml` or `.env` file:
```yaml ```yaml
METAMOD_VERSION: "1.11" # MetaMod:Source version # Server Settings
SOURCEMOD_VERSION: "1.11" # SourceMod version METAMOD_VERSION: "1.12" # MetaMod:Source version
SOURCEMOD_VERSION: "1.12" # SourceMod version
SRCDS_PORT: 27015 # Server port SRCDS_PORT: 27015 # Server port
SRCDS_MAXPLAYERS: 32 # Max player slots SRCDS_MAXPLAYERS: 32 # Max player slots
SRCDS_STARTMAP: "surf_ski_2" # Starting map 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 ### Building & Running
```bash ```bash
# Build the containers # Build the container
docker-compose build docker-compose build
# Start the services # Start the server
docker-compose up -d docker-compose up -d
# View logs # View logs
docker-compose logs -f cssds docker-compose logs -f cssds
# Stop the services # Restart the server
docker-compose restart cssds
# Stop the server
docker-compose down docker-compose down
``` ```
### First-Time Database Configuration ### Update Server Files
After the first build, configure Shavit to use MariaDB: The server installation is persistent - game files are only downloaded on first run. To force an update:
1. Edit `addons/sourcemod/configs/databases.cfg`: ```bash
``` # Update CSS game files
"Databases" docker-compose run cssds bash ./etc/run.sh --update-cssds
{
"shavit"
{
"driver" "mysql"
"host" "mariadb"
"database" "shavit"
"user" "root"
"pass" "your_password"
}
}
``` ```
2. Shavit will automatically create tables on first connection 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 ### JSON Zones Configuration
The server is **automatically configured** to use JSON zones instead of SQL-based zones. This provides several advantages: The server is **automatically configured** to use JSON zones instead of SQL-based zones:
**Automatic Setup:** **Automatic Setup:**
- Zones are loaded from the community-maintained [surf-zones](https://github.com/wrldspawn/surf-zones) repository - Zones loaded from [surf-zones](https://github.com/wrldspawn/surf-zones) repository
- Includes 400+ maps with pre-configured zones, stripper configs, and mapfixes - Includes 400+ maps with pre-configured zones
- No manual zone creation needed for supported maps - No manual zone creation needed for supported maps
- Automatically downloads: `https://wrldspawn.github.io/surf-zones/z/{map}.json` - URL: `https://wrldspawn.github.io/surf-zones/z/{map}.json`
**Configuration Files Created:** **Configuration Files Created:**
- `cfg/sourcemod/plugin.shavit-zones.cfg` - Disables SQL zones (`shavit_zones_usesql "0"`) - `cfg/sourcemod/plugin.shavit-zones.cfg` - Disables SQL zones
- `cfg/sourcemod/plugin.shavit-zones-json.cfg` - Sets JSON URL - `cfg/sourcemod/plugin.shavit-zones-json.cfg` - Sets JSON URL
- `addons/stripper/` - Map entity fixes and modifications - `addons/stripper/` - Map entity fixes
- `addons/sourcemod/configs/shavit-mapfixes.cfg` - Map-specific settings - `addons/sourcemod/configs/shavit-mapfixes.cfg` - Map settings
- `addons/sourcemod/configs/shavit-styles.cfg` - KSF-style configurations - `addons/sourcemod/configs/shavit-styles.cfg` - KSF-style configurations
**Benefits:** **Benefits:**
- ✅ No manual zone editing required for popular maps - ✅ No manual zone editing for popular maps
- ✅ Community-maintained and regularly updated - ✅ Community-maintained and updated
- ✅ Includes map fixes for common issues - ✅ Includes map fixes
- ✅ Matches KSF server behavior and standards - ✅ Matches KSF server standards
- ✅ Faster deployment (no SQL import needed) - ✅ Faster deployment
**Important Note:** The `sv_maxvelocity` settings in mapfixes won't auto-apply. After loading a map, use the in-game command:
```
!setmaxvel <value>
```
For most surf maps, use `!setmaxvel 3500`. Some maps may require different values (check surf-zones repo for specific maps).
### Server Configuration ### Server Configuration
Edit `etc/cfg/server.cfg` for server settings: Edit `etc/cfg/server.cfg` for server settings:
- Hostname, rcon password - Hostname, RCON password (change default!)
- Game settings (gravity, air accelerate, etc.) - Surf physics (gravity, air accelerate, max velocity)
- SourceMod configurations - 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 ## 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 ### Plugin Installation Pattern
All plugins follow an idempotent installation pattern in `etc/run.sh`: All plugins follow an idempotent installation pattern in `etc/run.sh`:
```bash ```bash
if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/plugin.smx" ]; then if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/plugin.smx" ]; then
cd /tmp
wget "https://github.com/author/repo/releases/download/version/plugin.zip" wget "https://github.com/author/repo/releases/download/version/plugin.zip"
unzip "plugin.zip" unzip -o "plugin.zip"
rm "plugin.zip" cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
rm -rf "plugin.zip" addons/
echo "Installed Plugin vX.Y.Z" echo "Installed Plugin vX.Y.Z"
fi fi
``` ```
This allows safe re-runs without reinstalling existing plugins. This allows safe re-runs without reinstalling existing plugins.
### Version Strategy
**Fixed versions are used** (not dynamic `latest` detection) for:
- **Stability** - Known working versions prevent unexpected breaks
- **Reproducibility** - Docker builds are deterministic
- **No API dependencies** - Avoids GitHub API rate limits
- **Easy rollback** - Can revert to specific versions if issues arise
### 64-bit Binary Support
The server uses 64-bit binaries for improved performance:
1. TF2 DS is downloaded for its 64-bit libraries
2. `libsteam_api.so` and `srcds_linux64` are copied from TF2 to CSS
3. `_srv.so` binaries are symlinked to regular `.so` names
4. `steamclient.so` is located and symlinked to expected paths
### Run Script Flow ### Run Script Flow
The `etc/run.sh` script executes in this order: The `etc/run.sh` script executes in this order:
1. **update_cssds()** - Download/update CSS DS via SteamCMD 1. **update_cssds()** - Download/update CSS DS via SteamCMD (skipped by default)
2. **update_tf2ds()** - Download/update TF2 DS for 64-bit binaries 2. **steamclient_binary()** - Locate and symlink steamclient.so (32-bit)
3. **copy_64bit()** - Copy 64-bit libraries from TF2 to CSS 3. **install_surf()** - Install timer, extensions, and physics plugins
4. **symlink_binaries()** - Create symlinks for server binaries - Install MetaMod:Source if missing
5. **steamclient_binary()** - Locate and symlink steamclient.so - Install SourceMod if missing
6. **install_metamod()** - Install MetaMod:Source if missing - Install sm-json (JSON library)
7. **install_sourcemod()** - Install SourceMod if missing - Install sm_closestpos (replay positioning)
8. **install_surf()** - Install timer and physics plugins - Install sm-ripext (HTTP/REST)
9. **configure_shavit_zones()** - Download and configure JSON zones, stripper configs, and mapfixes - Install Shavit Surf Timer with sounds/materials
10. **cfg()** - Copy server configuration - Install shavit-zones-json from original bhoptimer
11. **run_cssds()** - Launch the dedicated server - 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 ## Verification
### Check Installed Plugins ### Check Installed Plugins
```bash ```bash
docker exec -it surf_megastructure-cssds-1 \ docker exec -it $(docker ps -qf "name=cssds") \
ls -la /home/steam/cssds/cstrike/addons/sourcemod/plugins/*.smx ls -la /home/steam/cssds/cstrike/addons/sourcemod/plugins/*.smx
``` ```
### Check Shavit Configuration ### Check Extensions
```bash ```bash
docker exec -it surf_megastructure-cssds-1 \ docker exec -it $(docker ps -qf "name=cssds") \
ls -la /home/steam/cssds/cstrike/addons/sourcemod/configs/shavit/ ls -la /home/steam/cssds/cstrike/addons/sourcemod/extensions/*.so
```
### Check JSON Zones Configuration
```bash
# Check zone configuration files
docker exec -it surf_megastructure-cssds-1 \
cat /home/steam/cssds/cstrike/cfg/sourcemod/plugin.shavit-zones.cfg
# Check JSON URL configuration
docker exec -it surf_megastructure-cssds-1 \
cat /home/steam/cssds/cstrike/cfg/sourcemod/plugin.shavit-zones-json.cfg
# Check stripper configs installed
docker exec -it surf_megastructure-cssds-1 \
ls -la /home/steam/cssds/cstrike/addons/stripper/
# Check mapfixes
docker exec -it surf_megastructure-cssds-1 \
cat /home/steam/cssds/cstrike/addons/sourcemod/configs/shavit-mapfixes.cfg
``` ```
### In-Game Verification ### In-Game Verification
@ -273,104 +326,89 @@ docker exec -it surf_megastructure-cssds-1 \
Connect to the server and run: Connect to the server and run:
``` ```
sm plugins list sm plugins list
sm exts list
``` ```
You should see: You should see:
- Shavit BHopTimer (multiple modules) - **Plugins:** Shavit (multiple modules), momsurffix2, eventqueuefix, rngfix
- momsurffix2 - **Extensions:** sm-json, closestpos, ripext, dhooks, sdkhooks
- pushfix_de
- eventqueuefix
- rngfix
- Standard SourceMod plugins
## Troubleshooting ## Troubleshooting
### Plugins Not Loading ### Plugins Not Loading
1. Check MetaMod is loaded: `meta list` 1. Check MetaMod: `meta list`
2. Check SourceMod is loaded: `sm version` 2. Check SourceMod: `sm version`
3. Check plugin errors: `sm plugins list` and look for "Failed" or "Error" 3. Check errors: `sm plugins list`
4. Check logs: `addons/sourcemod/logs/` 4. Check logs: `addons/sourcemod/logs/`
### Database Connection Issues **Common Issues:**
- Missing extension dependencies (install sm-json, closestpos, ripext)
- Wrong architecture (use 32-bit plugins/extensions)
- File permissions (ensure steam user owns files)
1. Verify MariaDB container is running: `docker ps` ### Zones Not Loading
2. Check database credentials in `databases.cfg`
3. Check Shavit logs: `addons/sourcemod/logs/shavit/`
4. Test connection: `sm_sql_query shavit "SELECT 1"`
### Zones Not Loading / Map Has No Zones **Symptoms:** Map loads but no start/end zones
**Symptoms:** Map loads but no start/end zones, timer doesn't work
**Solutions:** **Solutions:**
1. **Check if map is in surf-zones repository:** 1. **Check if map exists in surf-zones:**
- Visit: https://github.com/wrldspawn/surf-zones/tree/main/z - Visit: https://github.com/wrldspawn/surf-zones/tree/main/z
- Search for your map name (e.g., `surf_ski_2.json`) - Search for `surf_<mapname>.json`
- Not all maps have pre-made zones
2. **Verify JSON zones are enabled:** 2. **Verify JSON zones enabled:**
``` ```
// In console
sm_cvar shavit_zones_usesql sm_cvar shavit_zones_usesql
// Should show: "shavit_zones_usesql" = "0" // Should be "0"
``` ```
3. **Check zone loading errors:** 3. **Check sm-json loaded:**
- Check `addons/sourcemod/logs/shavit/`
- Look for HTTP errors or JSON parsing failures
4. **Create zones manually (if map not in repo):**
``` ```
// In-game sm exts list
!zones // Open zone editor // Look for sm-json or json.inc in includes
!start // Create start zone
!end // Create end zone
``` ```
- Zones created in-game are saved to the database (not JSON)
5. **Network connectivity:** 4. **Check logs:**
- Verify container can reach GitHub: `docker exec -it surf_megastructure-cssds-1 curl -I https://wrldspawn.github.io/` - `addons/sourcemod/logs/shavit/`
- Check firewall/proxy settings - Look for HTTP/JSON errors
**Note:** If a map doesn't exist in the surf-zones repository, you'll need to create zones manually using the in-game zone editor (`!zones`). These will be saved to your MariaDB database. 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 ### Server Won't Start
1. Check logs: `docker-compose logs cssds` 1. Check logs: `docker-compose logs cssds`
2. Verify port 27015 is available 2. Verify port 27015 available
3. Check disk space for server files 3. Check disk space
4. Verify SteamCMD downloaded files successfully 4. Verify SteamCMD succeeded
## Future Enhancements
### Potential Additions
- **FastDL** - Fast map download server (HTTP/Web server for map downloads)
- **SourceBans** - Web-based ban management system
- **Map rotation** - Automated map cycling configuration
- **GOTV** - Source TV for spectating/recording matches
- **Workshop maps** - Steam Workshop integration for map downloads
- **Backup system** - Automated database and config backups
### Maintenance
- Update plugin versions periodically
- Monitor Shavit GitHub for new releases
- Check for MetaMod/SourceMod updates
- Review server logs for errors or exploits
## Credits ## Credits
- **Shavit BHopTimer** - [shavitush](https://github.com/shavitush/bhoptimer) - **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) - **MomSurfFix** - [GAMMACASE](https://github.com/GAMMACASE/MomSurfFix)
- **PushFix DE** - [GAMMACASE](https://github.com/GAMMACASE/PushFixDE)
- **EventQueue Fix** - [hermansimensen](https://github.com/hermansimensen/eventqueue-fix) - **EventQueue Fix** - [hermansimensen](https://github.com/hermansimensen/eventqueue-fix)
- **RNGFix** - [jason-e](https://github.com/jason-e/rngfix) - **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/) - **MetaMod:Source** - [AlliedModders](https://www.metamodsource.net/)
- **SourceMod** - [AlliedModders](https://www.sourcemod.net/) - **SourceMod** - [AlliedModders](https://www.sourcemod.net/)
## License ## License
This setup configuration is provided as-is. Individual components (Shavit, SourceMod, etc.) retain their original licenses. This setup configuration is provided as-is. Individual components retain their original licenses.

View File

@ -27,6 +27,8 @@ sv_accelerate_use_weapon_speed 0 // Weapon weight doesn't affect accelera
// Fall damage and movement // Fall damage and movement
mp_falldamage 0 // No fall damage mp_falldamage 0 // No fall damage
sv_falldamage_to_velocity_scale 0 // Disable view punch/head knock from falls
sv_turbophysics 1 // Disable some physics effects (smoother movement)
phys_pushscale 1000 // Push force multiplier phys_pushscale 1000 // Push force multiplier
// ================================================================ // ================================================================
@ -69,6 +71,11 @@ mp_idlemaxtime 0 // No idle kick (let Shavit handle this)
mp_idledealmethod 0 // Don't deal with idle players mp_idledealmethod 0 // Don't deal with idle players
sv_timeout 900 // 15 minute timeout sv_timeout 900 // 15 minute timeout
// HUD Settings (minimal HUD for clean surf experience)
sv_hudhint_sound 0 // Disable hint sounds
mp_radar_showall 0 // Hide radar
sv_showimpacts 0 // Hide bullet impacts
// ================================================================ // ================================================================
// RCON SETTINGS // RCON SETTINGS
// ================================================================ // ================================================================

View File

@ -6,21 +6,26 @@ EXPOSE 27015/tcp \
27020/udp 27020/udp
USER root USER root
RUN apt-get update RUN apt-get update && apt-get install -y \
RUN apt-get install -y \
wget \ wget \
ca-certificates \ ca-certificates \
zlib1g \ zlib1g \
lib32z1 \
lib32gcc-s1 \ lib32gcc-s1 \
libncurses5 \ libncurses5 \
libbz2-1.0 \ libbz2-1.0 \
libtinfo5 \ libtinfo5 \
libcurl3-gnutls \ libcurl3-gnutls \
unzip \ unzip \
rcon rcon \
neovim \
tmux \
less \
procps \
sqlite3 \
&& rm -rf /var/lib/apt/lists/*
ENV CSSDS="/home/steam/cssds" ENV CSSDS="/home/steam/cssds"
ENV TF2DS="/home/steam/tf2ds"
ENV STEAMCMD="/home/steam/steamcmd" ENV STEAMCMD="/home/steam/steamcmd"
ENV ETC="/home/steam/etc" ENV ETC="/home/steam/etc"
ENV METAMOD_VERSION=1.12 ENV METAMOD_VERSION=1.12
@ -29,7 +34,7 @@ ENV SOURCEMOD_VERSION=1.12
# ensure gamedirs exist and have been chowned to steam # ensure gamedirs exist and have been chowned to steam
# before they potentially get setup as docker volumes # before they potentially get setup as docker volumes
# which would otherwise cause them to be owned by root # which would otherwise cause them to be owned by root
RUN mkdir -p "$CSSDS" "$TF2DS" "$STEAMCMD" "$ETC" RUN mkdir -p "$CSSDS" "$STEAMCMD" "$ETC"
RUN chown -R steam:steam /home/steam RUN chown -R steam:steam /home/steam
FROM build AS steam FROM build AS steam

View File

@ -2,9 +2,42 @@
set -uxe set -uxe
# Parse command-line flags
# By default, skip updates (set to 1)
SKIP_CSSDS_UPDATE=1
while [[ $# -gt 0 ]]; do
case $1 in
--update-cssds)
SKIP_CSSDS_UPDATE=0
shift
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 [--update-cssds]"
exit 1
;;
esac
done
CSTRIKE="$CSSDS/cstrike" CSTRIKE="$CSSDS/cstrike"
update_cssds() { update_cssds() {
# Check if CSS DS is already populated with game files
if [ -f "$CSSDS/srcds_run" ]; then
# Game files exist, respect the skip flag
if [ $SKIP_CSSDS_UPDATE -eq 1 ]; then
echo "--------------------------------------------------------------"
echo "Skipping CSS DS update (use --update-cssds to enable)"
echo "--------------------------------------------------------------"
return
fi
else
echo "--------------------------------------------------------------"
echo "CSS DS not populated, performing initial installation"
echo "--------------------------------------------------------------"
fi
cd $STEAMCMD cd $STEAMCMD
./steamcmd.sh +runscript "$HOME/etc/update_cssds.txt" ./steamcmd.sh +runscript "$HOME/etc/update_cssds.txt"
@ -13,16 +46,12 @@ update_cssds() {
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
} }
update_tf2ds() { # TF2 DS no longer needed - running in 32-bit mode
cd $STEAMCMD # update_tf2ds() function removed
./steamcmd.sh +runscript "$HOME/etc/update_tf2ds.txt"
echo "--------------------------------------------------------------" install_surf() {
echo "TF2 DS is up to date" cd $CSTRIKE
echo "--------------------------------------------------------------"
}
install_metamod() {
# is the metamod folder missing? # is the metamod folder missing?
if [ ! -d "$CSTRIKE/addons/metamod" ]; then if [ ! -d "$CSTRIKE/addons/metamod" ]; then
LATESTMM=$(wget -qO- https://mms.alliedmods.net/mmsdrop/"${METAMOD_VERSION}"/mmsource-latest-linux) LATESTMM=$(wget -qO- https://mms.alliedmods.net/mmsdrop/"${METAMOD_VERSION}"/mmsource-latest-linux)
@ -31,9 +60,7 @@ install_metamod() {
echo "Installed MetaMod $METAMOD_VERSION" echo "Installed MetaMod $METAMOD_VERSION"
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
fi fi
}
install_sourcemod() {
# Are we in a sourcemod container and is the sourcemod folder missing? # Are we in a sourcemod container and is the sourcemod folder missing?
if [ ! -d "$CSTRIKE/addons/sourcemod" ]; then if [ ! -d "$CSTRIKE/addons/sourcemod" ]; then
LATESTSM=$(wget -qO- https://sm.alliedmods.net/smdrop/"${SOURCEMOD_VERSION}"/sourcemod-latest-linux) LATESTSM=$(wget -qO- https://sm.alliedmods.net/smdrop/"${SOURCEMOD_VERSION}"/sourcemod-latest-linux)
@ -42,59 +69,157 @@ install_sourcemod() {
echo "Installed SourceMod $SOURCEMOD_VERSION" echo "Installed SourceMod $SOURCEMOD_VERSION"
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
fi fi
} # Install sm-json (required for JSON zone loading - pure SourcePawn library)
if [ ! -f "$CSTRIKE/addons/sourcemod/scripting/include/json.inc" ]; then
install_surf() { cd /tmp
cd $CSTRIKE wget "https://github.com/clugg/sm-json/archive/refs/tags/v5.0.1.zip" -O sm-json-v5.0.1.zip
unzip -o sm-json-v5.0.1.zip
# Install Shavit BHopTimer (replaces InfluxTimer) cp -r sm-json-5.0.1/addons/* "$CSTRIKE/addons/" 2>/dev/null || true
if [ ! -d "$CSTRIKE/addons/sourcemod/configs/shavit" ]; then rm -rf sm-json-v5.0.1.zip sm-json-5.0.1/
wget "https://github.com/shavitush/bhoptimer/releases/download/v4.0.1/bhoptimer-v4.0.1.zip"
unzip "bhoptimer-v4.0.1.zip"
rm "bhoptimer-v4.0.1.zip"
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
echo "Installed Shavit BHopTimer v4.0.1" echo "Installed sm-json v5.0.1"
echo "--------------------------------------------------------------"
else
echo "--------------------------------------------------------------"
echo "sm-json already installed"
echo "--------------------------------------------------------------"
fi
# Install sm_closestpos (required for ghost/replay functionality)
if [ ! -f "$CSTRIKE/addons/sourcemod/extensions/closestpos.ext.so" ]; then
cd /tmp
wget "https://github.com/rtldg/sm_closestpos/releases/download/v1.1.1/sm_closestpos-sm1.10-ubuntu-20.04-b0a9b88.zip"
unzip -o "sm_closestpos-sm1.10-ubuntu-20.04-b0a9b88.zip"
cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
rm -rf "sm_closestpos-sm1.10-ubuntu-20.04-b0a9b88.zip" addons/
echo "--------------------------------------------------------------"
echo "Installed sm_closestpos v1.1.1"
echo "--------------------------------------------------------------"
else
echo "--------------------------------------------------------------"
echo "sm_closestpos already installed"
echo "--------------------------------------------------------------"
fi
# Install sm-ripext (required for shavit-wrsh plugin)
if [ ! -f "$CSTRIKE/addons/sourcemod/extensions/ripext.ext.so" ]; then
cd /tmp
wget "https://github.com/ErikMinekus/sm-ripext/releases/download/1.3.2/sm-ripext-1.3.2-linux.zip"
unzip -o "sm-ripext-1.3.2-linux.zip"
cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
rm -rf "sm-ripext-1.3.2-linux.zip" addons/
echo "--------------------------------------------------------------"
echo "Installed sm-ripext v1.3.2"
echo "--------------------------------------------------------------"
else
echo "--------------------------------------------------------------"
echo "sm-ripext already installed"
echo "--------------------------------------------------------------"
fi
# Install Shavit Surf Timer (surf-specific fork)
if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/shavit-core.smx" ]; then
cd /tmp
wget "https://github.com/bhopppp/Shavit-Surf-Timer/releases/download/v1.0.6/Shavit-SurfTimer-v1.0.6.zip"
unzip -o "Shavit-SurfTimer-v1.0.6.zip"
# Copy addons, sounds, and materials
cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
cp -r sound/* "$CSTRIKE/sound/" 2>/dev/null || true
cp -r materials/* "$CSTRIKE/materials/" 2>/dev/null || true
rm -rf "Shavit-SurfTimer-v1.0.6.zip" addons/ sound/ materials/
echo "--------------------------------------------------------------"
echo "Installed Shavit Surf Timer v1.0.6 (with sounds & materials)"
echo "--------------------------------------------------------------"
else
echo "--------------------------------------------------------------"
echo "Shavit Surf Timer already installed"
echo "--------------------------------------------------------------"
fi
# Temporarily disabled - testing SQL zones instead of JSON
# Install shavit-zones-json from original bhoptimer (missing in Surf Timer release)
# if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/shavit-zones-json.smx" ]; then
# cd /tmp
# wget "https://github.com/shavitush/bhoptimer/releases/download/v4.0.1/bhoptimer-v4.0.1.zip"
# unzip -o "bhoptimer-v4.0.1.zip" "addons/sourcemod/plugins/shavit-zones-json.smx"
# cp addons/sourcemod/plugins/shavit-zones-json.smx "$CSTRIKE/addons/sourcemod/plugins/"
# rm -rf "bhoptimer-v4.0.1.zip" addons/
# echo "--------------------------------------------------------------"
# echo "Installed shavit-zones-json.smx from bhoptimer v4.0.1"
# echo "--------------------------------------------------------------"
# else
# echo "--------------------------------------------------------------"
# echo "shavit-zones-json already installed"
# echo "--------------------------------------------------------------"
# fi
# Disable zones-json plugin if it exists
if [ -f "$CSTRIKE/addons/sourcemod/plugins/shavit-zones-json.smx" ]; then
mkdir -p "$CSTRIKE/addons/sourcemod/plugins/disabled"
mv "$CSTRIKE/addons/sourcemod/plugins/shavit-zones-json.smx" \
"$CSTRIKE/addons/sourcemod/plugins/disabled/" 2>/dev/null || true
echo "--------------------------------------------------------------"
echo "Disabled shavit-zones-json (using SQL zones instead)"
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
fi fi
# Install MomSurfFix # Install MomSurfFix
if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/momsurffix2.smx" ]; then if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/momsurffix2.smx" ]; then
cd /tmp
wget "https://github.com/GAMMACASE/MomSurfFix/releases/download/1.1.5/MomSurfFix2v1.1.5.zip" wget "https://github.com/GAMMACASE/MomSurfFix/releases/download/1.1.5/MomSurfFix2v1.1.5.zip"
unzip "MomSurfFix2v1.1.5.zip" unzip -o "MomSurfFix2v1.1.5.zip"
rm "MomSurfFix2v1.1.5.zip" cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
rm -rf "MomSurfFix2v1.1.5.zip" addons/
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
echo "Installed MomSurfFix v1.1.5" echo "Installed MomSurfFix v1.1.5"
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
else
echo "--------------------------------------------------------------"
echo "MomSurfFix already installed"
echo "--------------------------------------------------------------"
fi fi
# Install PushFix Definitive Edition # PushFix Definitive Edition - appears in KSF plugin list but fails on CSS
if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/pushfix_de.smx" ]; then # The DE version is CS:GO only and will fail with "g_SendTableCRC" error on CSS
wget "https://github.com/GAMMACASE/PushFixDE/releases/download/1.0.0/pushfix_de_1.0.0.zip" # Disabled by default - if KSF uses a different version, it's not publicly available
unzip "pushfix_de_1.0.0.zip" # if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/pushfix_de.smx" ]; then
rm "pushfix_de_1.0.0.zip" # cd /tmp
echo "--------------------------------------------------------------" # wget "https://github.com/GAMMACASE/PushFixDE/releases/download/1.0.0/pushfix_de_1.0.0.zip"
echo "Installed PushFix Definitive Edition v1.0.0" # unzip -o "pushfix_de_1.0.0.zip"
echo "--------------------------------------------------------------" # cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
fi # rm -rf "pushfix_de_1.0.0.zip" addons/
# fi
# Install EventQueue Fix # Install EventQueue Fix
if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/eventqueuefix.smx" ]; then if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/eventqueuefix.smx" ]; then
cd /tmp
wget "https://github.com/hermansimensen/eventqueue-fix/releases/download/1.3.2/eventqueuefix-1.3.2.zip" wget "https://github.com/hermansimensen/eventqueue-fix/releases/download/1.3.2/eventqueuefix-1.3.2.zip"
unzip "eventqueuefix-1.3.2.zip" unzip -o "eventqueuefix-1.3.2.zip"
rm "eventqueuefix-1.3.2.zip" cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
rm -rf "eventqueuefix-1.3.2.zip" addons/
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
echo "Installed EventQueue Fix v1.3.2" echo "Installed EventQueue Fix v1.3.2"
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
else
echo "--------------------------------------------------------------"
echo "EventQueue Fix already installed"
echo "--------------------------------------------------------------"
fi fi
# Install RNGFix # Install RNGFix
if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/rngfix.smx" ]; then if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/rngfix.smx" ]; then
cd /tmp
wget "https://github.com/jason-e/rngfix/releases/download/v1.1.3/rngfix_1.1.3.zip" wget "https://github.com/jason-e/rngfix/releases/download/v1.1.3/rngfix_1.1.3.zip"
unzip "rngfix_1.1.3.zip" unzip -o "rngfix_1.1.3.zip"
rm "rngfix_1.1.3.zip" cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
rm -rf "rngfix_1.1.3.zip" addons/
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
echo "Installed RNGFix v1.1.3" echo "Installed RNGFix v1.1.3"
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
else
echo "--------------------------------------------------------------"
echo "RNGFix already installed"
echo "--------------------------------------------------------------"
fi fi
} }
@ -116,7 +241,7 @@ configure_shavit_zones() {
# Download surf-zones repository # Download surf-zones repository
cd /tmp cd /tmp
wget "https://github.com/wrldspawn/surf-zones/archive/refs/heads/main.zip" -O surf-zones.zip wget "https://github.com/wrldspawn/surf-zones/archive/refs/heads/main.zip" -O surf-zones.zip
unzip -q surf-zones.zip unzip -o surf-zones.zip
# Copy stripper directory # Copy stripper directory
if [ -d "surf-zones-main/addons/stripper" ]; then if [ -d "surf-zones-main/addons/stripper" ]; then
@ -144,71 +269,46 @@ configure_shavit_zones() {
# Create cfg directory for plugin configs if it doesn't exist # Create cfg directory for plugin configs if it doesn't exist
mkdir -p "$CSTRIKE/cfg/sourcemod" mkdir -p "$CSTRIKE/cfg/sourcemod"
# Configure zones plugin to use JSON instead of SQL # Configure zones plugin to use SQL database
cat > "$CSTRIKE/cfg/sourcemod/plugin.shavit-zones.cfg" <<'EOF' cat > "$CSTRIKE/cfg/sourcemod/plugin.shavit-zones.cfg" <<'EOF'
// Shavit Zones Plugin Configuration // Shavit Zones Plugin Configuration
// Set to 0 to use JSON zones instead of SQL database // Set to 1 to use SQL zones (default for Surf Timer fork)
shavit_zones_usesql "0" shavit_zones_usesql "1"
EOF EOF
# Configure JSON zones URL # JSON zones temporarily disabled for testing
cat > "$CSTRIKE/cfg/sourcemod/plugin.shavit-zones-json.cfg" <<'EOF' # cat > "$CSTRIKE/cfg/sourcemod/plugin.shavit-zones-json.cfg" <<'EOF'
// Shavit JSON Zones Configuration # // Shavit JSON Zones Configuration
// URL template for loading zone data - {map} will be replaced with map name # // URL template for loading zone data - {map} will be replaced with map name
shavit_zones_json_url "https://wrldspawn.github.io/surf-zones/z/{map}.json" # shavit_zones_json_url "https://wrldspawn.github.io/surf-zones/z/{map}.json"
EOF # EOF
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
echo "Configured Shavit to use JSON zones" echo "Configured Shavit to use SQL zones"
echo "JSON URL: https://wrldspawn.github.io/surf-zones/z/{map}.json" echo "Use !zones in-game to create start/end zones for maps"
echo "Note: Use !setmaxvel in-game to set max velocity per map"
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
} }
configure_shavit_database() { configure_shavit_database() {
cd $CSTRIKE cd $CSTRIKE
# Check if database config already exists
if [ -f "$CSTRIKE/addons/sourcemod/configs/databases.cfg" ]; then
# Check if shavit database entry already exists
if grep -q '"shavit"' "$CSTRIKE/addons/sourcemod/configs/databases.cfg"; then
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
echo "Shavit database already configured" echo "Writing Shavit database configuration (SQLite)"
echo "--------------------------------------------------------------"
return
fi
fi
echo "--------------------------------------------------------------"
echo "Configuring Shavit database connection"
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
# Set defaults if environment variables are not set # Always recreate databases.cfg
DB_HOST="${MYSQL_HOST:-mariadb}"
DB_PORT="${MYSQL_PORT:-3306}"
DB_NAME="${MYSQL_DATABASE:-shavit}"
DB_USER="${MYSQL_USER:-root}"
DB_PASS="${MYSQL_ROOT_PASSWORD:-changeme}"
# Create or append to databases.cfg
mkdir -p "$CSTRIKE/addons/sourcemod/configs" mkdir -p "$CSTRIKE/addons/sourcemod/configs"
# If databases.cfg doesn't exist, create it with full structure cat > "$CSTRIKE/addons/sourcemod/configs/databases.cfg" <<'EOF'
if [ ! -f "$CSTRIKE/addons/sourcemod/configs/databases.cfg" ]; then
cat > "$CSTRIKE/addons/sourcemod/configs/databases.cfg" <<EOF
"Databases" "Databases"
{ {
"driver_default" "mysql" "driver_default" "sqlite"
// Shavit BHopTimer Database // Shavit BHopTimer Database (using local SQLite)
"shavit" "shavit"
{ {
"driver" "mysql" "driver" "sqlite"
"host" "$DB_HOST" "database" "shavit-local"
"port" "$DB_PORT"
"database" "$DB_NAME"
"user" "$DB_USER"
"pass" "$DB_PASS"
} }
// Default SourceMod database (local SQLite) // Default SourceMod database (local SQLite)
@ -218,7 +318,7 @@ configure_shavit_database() {
"database" "sourcemod-local" "database" "sourcemod-local"
} }
// Storage database (can also use MySQL if desired) // Storage database (local SQLite)
"storage-local" "storage-local"
{ {
"driver" "sqlite" "driver" "sqlite"
@ -226,39 +326,62 @@ configure_shavit_database() {
} }
} }
EOF EOF
else
# Append shavit config to existing databases.cfg (before closing brace)
# Remove the last closing brace, add shavit config, then add closing brace back
sed -i '$ d' "$CSTRIKE/addons/sourcemod/configs/databases.cfg"
cat >> "$CSTRIKE/addons/sourcemod/configs/databases.cfg" <<EOF
// Shavit BHopTimer Database
"shavit"
{
"driver" "mysql"
"host" "$DB_HOST"
"port" "$DB_PORT"
"database" "$DB_NAME"
"user" "$DB_USER"
"pass" "$DB_PASS"
}
}
EOF
fi
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
echo "Configured Shavit database connection" echo "Configured Shavit to use local SQLite database"
echo "Host: $DB_HOST:$DB_PORT" echo "Database: shavit-local.sq3"
echo "Database: $DB_NAME" echo "--------------------------------------------------------------"
echo "User: $DB_USER" }
import_zone_data() {
echo "--------------------------------------------------------------"
echo "Importing zone data from Surf Timer repository"
echo "--------------------------------------------------------------"
local DB_FILE="$CSTRIKE/addons/sourcemod/data/sqlite/shavit-local.sq3"
# Check if database file exists
if [ ! -f "$DB_FILE" ]; then
echo "Database file not created yet - skipping zone import"
echo "Zones will be imported on next restart after Shavit creates tables"
echo "--------------------------------------------------------------"
return
fi
# Check if Shavit migrations have run (mapzones table must exist)
local table_exists=$(sqlite3 "$DB_FILE" "SELECT name FROM sqlite_master WHERE type='table' AND name='mapzones';" 2>/dev/null)
if [ -z "$table_exists" ]; then
echo "Shavit has not created tables yet - skipping zone import"
echo "Zones will be imported on next restart after Shavit runs migrations"
echo "--------------------------------------------------------------"
return
fi
# Check if zones already imported
local zone_count=$(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM mapzones;" 2>/dev/null || echo "0")
if [ "$zone_count" -gt "0" ]; then
echo "Zone data already imported ($zone_count zones)"
echo "--------------------------------------------------------------"
return
fi
# Download and import surfzones.sql
cd /tmp
wget -q "https://raw.githubusercontent.com/bhopppp/Shavit-Surf-Timer/master/sql/surfzones.sql" -O surfzones.sql
sqlite3 "$DB_FILE" < surfzones.sql 2>/dev/null
local imported_count=$(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM mapzones;" 2>/dev/null || echo "unknown")
echo "Imported $imported_count zones from surfzones.sql"
rm -f surfzones.sql
echo "--------------------------------------------------------------" echo "--------------------------------------------------------------"
} }
copy_64bit() { copy_64bit() {
cp -a "$TF2DS/bin/linux64/libsteam_api.so" \ cp -a "$TF2DS/bin/linux64/libsteam_api.so" \
"$CSSDS/bin/linux64/." "$CSSDS/bin/linux64/"
cp -a "$TF2DS/srcds_linux64" "$TF2DS/srcds_run_64" \ cp -a "$TF2DS/srcds_linux64" "$TF2DS/srcds_run_64" \
"$CSSDS/." "$CSSDS/"
} }
symlink_binaries() { symlink_binaries() {
@ -272,15 +395,57 @@ symlink_binaries() {
steamclient_binary() { steamclient_binary() {
echo "Looking for steamclient.so and symlinking it..." echo "Looking for steamclient.so and symlinking it..."
local _steamclient64bit=$(find "$HOME" -type f -name 'steamclient.so' | grep "linux64" | head -n 1) # For 32-bit mode, look for 32-bit steamclient (linux32 or default)
if [ ! -n $_steamclient64bit ]; then local _steamclient32bit=$(find "$HOME" -type f -name 'steamclient.so' | grep -E "linux32|steamcmd/linux32" | head -n 1)
echo "Could not locate 64-bit steamclient.so binary. Exiting..." if [ ! -n "$_steamclient32bit" ]; then
# Fallback to any steamclient.so if linux32 not found
_steamclient32bit=$(find "$HOME" -type f -name 'steamclient.so' | head -n 1)
fi
if [ ! -n "$_steamclient32bit" ]; then
echo "Could not locate steamclient.so binary. Exiting..."
exit 1 exit 1
fi fi
mkdir -p "$HOME/.steam/sdk64/" # srcds_linux64 looks for steamclient.so in this directory mkdir -p "$HOME/.steam/sdk32/" # srcds_run looks for steamclient.so in this directory
ln -nfs "$_steamclient64bit" "$HOME/.steam/sdk64/steamclient.so" ln -nfs "$_steamclient32bit" "$HOME/.steam/sdk32/steamclient.so"
ln -nfs "$_steamclient64bit" "$CSSDS/bin/linux64/steamclient.so" ln -nfs "$_steamclient32bit" "$CSSDS/steamclient.so"
}
configure_admins() {
echo "--------------------------------------------------------------"
echo "Configuring SourceMod admins"
echo "--------------------------------------------------------------"
# Create admins_simple.ini with header
cat > "$CSTRIKE/addons/sourcemod/configs/admins_simple.ini" <<'EOF'
//
// SourceMod Admins Simple Configuration
// Auto-generated by run.sh from SRCDS_ADMINS environment variable
//
// Format: "STEAM_ID" "immunity:flags" // optional comment
// Flags: z = root (full access)
//
EOF
# Add admins from environment variable (comma-separated Steam IDs)
if [ -n "$SRCDS_ADMINS" ]; then
IFS=',' read -ra ADMIN_IDS <<< "$SRCDS_ADMINS"
for steamid in "${ADMIN_IDS[@]}"; do
# Trim whitespace and quotes
steamid=$(echo "$steamid" | xargs | tr -d '"' | tr -d "'")
if [ -n "$steamid" ]; then
echo "\"$steamid\" \"99:z\" // Root admin" >> "$CSTRIKE/addons/sourcemod/configs/admins_simple.ini"
echo "Added admin: $steamid"
fi
done
echo "--------------------------------------------------------------"
echo "Configured ${#ADMIN_IDS[@]} admin(s)"
echo "--------------------------------------------------------------"
else
echo "--------------------------------------------------------------"
echo "No admins configured (set SRCDS_ADMINS env var)"
echo "--------------------------------------------------------------"
fi
} }
cfg() { cfg() {
@ -293,27 +458,30 @@ run_cssds() {
echo "ready to run" echo "ready to run"
cd "$CSSDS" cd "$CSSDS"
./srcds_run_64 -game cstrike \ ./srcds_run -game cstrike \
-port "${SRCDS_PORT}" \ -port "${SRCDS_PORT}" \
+maxplayers "${SRCDS_MAXPLAYERS}" \ +maxplayers "${SRCDS_MAXPLAYERS}" \
+map "${SRCDS_STARTMAP}" +map "${SRCDS_STARTMAP}" \
# -ip "${SRCDS_IP}" -ip "${SRCDS_IP}"
} }
main() { main() {
update_cssds update_cssds
update_tf2ds # TF2 DS not needed - running in 32-bit mode
copy_64bit
symlink_binaries
steamclient_binary steamclient_binary
install_metamod
install_sourcemod
install_surf install_surf
configure_shavit_zones configure_shavit_zones
configure_shavit_database configure_shavit_database
configure_admins
cfg cfg
# Import zone data after server config is ready
# Note: Database might not exist yet on first run
# Zones will be available after server starts and creates tables
import_zone_data
run_cssds run_cssds
} }

View File

@ -2,7 +2,10 @@
"folders": "folders":
[ [
{ {
"path": "." "path": ".",
} },
] {
"path": "C:\\Users\\ntr\\code\\ntwl\\surf"
},
],
} }