Compare commits
10
Commits
f08be1d72c
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90b9faf31a | ||
|
|
81cfced965 | ||
|
|
737207f3dd | ||
|
|
0d2260f983 | ||
|
|
1528f0a2b0 | ||
|
|
bcf798a5f9 | ||
|
|
31a2ac82d0 | ||
|
|
f66c505082 | ||
|
|
cf65959148 | ||
|
|
43883f3841 |
No files matched your search
@@ -1,11 +1,11 @@
|
|||||||
STEAMAPPID=232330
|
STEAMAPPID=232330
|
||||||
STEAMAPP=css
|
STEAMAPP=css
|
||||||
|
|
||||||
SRCDS_TOKEN=C02633B3395EA6BEF7D8DFBA440ABB7F
|
SRCDS_TOKEN=3C403551712E10420F08F5CA337F9B21
|
||||||
SRCDS_RCONPW="lol"
|
SRCDS_RCONPW="reebok"
|
||||||
SRCDS_PW="6"
|
SRCDS_PW="6"
|
||||||
|
|
||||||
SRCDS_STARTMAP="surf_boreas"
|
SRCDS_STARTMAP="surf_anzchamps"
|
||||||
SRCDS_HOSTNAME="megastructure surf"
|
SRCDS_HOSTNAME="megastructure surf"
|
||||||
SRCDS_MAXPLAYERS=16
|
SRCDS_MAXPLAYERS=16
|
||||||
|
|
||||||
@@ -28,6 +28,11 @@ SRCDS_WORKSHOP_AUTHKEY=""
|
|||||||
SRCDS_CFG="server.cfg"
|
SRCDS_CFG="server.cfg"
|
||||||
SRCDS_MAPCYCLE="mapcycle.txt"
|
SRCDS_MAPCYCLE="mapcycle.txt"
|
||||||
|
|
||||||
|
SRCDS_ADMINS=[U:1:1589252886],[U:1:12270329]
|
||||||
|
|
||||||
|
# ----------
|
||||||
|
# fastdl
|
||||||
|
FASTDL_URL=https://fastdl.megastructure.surf
|
||||||
|
|
||||||
# ----------
|
# ----------
|
||||||
# mariadb
|
# mariadb
|
||||||
@@ -35,3 +40,4 @@ MARIADB_ROOT_PASSWORD="surfsup"
|
|||||||
MARIADB_DATABASE="influx"
|
MARIADB_DATABASE="influx"
|
||||||
MARIADB_USER="influx"
|
MARIADB_USER="influx"
|
||||||
MARIADB_PASSWORD="righteous"
|
MARIADB_PASSWORD="righteous"
|
||||||
|
|
||||||
@@ -2,8 +2,11 @@
|
|||||||
*.sql.gz
|
*.sql.gz
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
|
|
||||||
|
.env/
|
||||||
data/
|
data/
|
||||||
|
|
||||||
|
src/mapsdl/credentials
|
||||||
|
|
||||||
surf.sublime-workspace
|
surf.sublime-workspace
|
||||||
|
|
||||||
|
|
||||||
@@ -1,17 +1,40 @@
|
|||||||
build-css:
|
# Map downloader commands
|
||||||
docker build -f css/css.dockerfile css/ -t megastructure/css
|
mapsdl-dry:
|
||||||
|
cd src/mapsdl && deno run -A mapsdl.ts --dry-run
|
||||||
|
|
||||||
up:
|
mapsdl:
|
||||||
docker compose up --remove-orphans
|
cd src/mapsdl && deno run -A mapsdl.ts
|
||||||
|
|
||||||
down:
|
mapsdl-all-dry:
|
||||||
docker compose down -v --remove-orphans
|
cd src/mapsdl && deno run -A mapsdl-all.ts --dry-run
|
||||||
|
|
||||||
|
mapsdl-all:
|
||||||
|
cd src/mapsdl && deno run -A mapsdl-all.ts --dry-run
|
||||||
|
|
||||||
|
# k8s
|
||||||
build:
|
build:
|
||||||
docker compose build
|
docker build -t megastructure-surf-cssds:local -t registry.ntwl.xyz/megastructure-surf-cssds src/cssds
|
||||||
|
docker build -t megastructure-surf-mapsdl:local -t registry.ntwl.xyz/megastructure-surf-mapsdl src/mapsdl
|
||||||
|
docker build -t megastructure-surf-fastdl:local -t registry.ntwl.xyz/megastructure-surf-fastdl src/fastdl
|
||||||
|
|
||||||
cssds-run:
|
push:
|
||||||
docker compose run -u root -it cssds bash
|
docker push registry.ntwl.xyz/megastructure-surf-cssds
|
||||||
|
docker push registry.ntwl.xyz/megastructure-surf-mapsdl
|
||||||
|
docker push registry.ntwl.xyz/megastructure-surf-fastdl
|
||||||
|
|
||||||
cssds-exec:
|
build-cssds:
|
||||||
docker compose exec -u root -it cssds bash
|
docker build -t megastructure-surf-cssds:local -t registry.ntwl.xyz/megastructure-surf-cssds src/cssds
|
||||||
|
|
||||||
|
build-mapsdl:
|
||||||
|
docker build -t megastructure-surf-mapsdl:local -t registry.ntwl.xyz/megastructure-surf-mapsdl src/mapsdl
|
||||||
|
|
||||||
|
build-fastdl:
|
||||||
|
docker build -t megastructure-surf-fastdl:local -t registry.ntwl.xyz/megastructure-surf-fastdl src/fastdl
|
||||||
|
|
||||||
|
apply:
|
||||||
|
kubectl delete pod mapsdl -n surf --ignore-not-found
|
||||||
|
kubectl apply -f k8s.yaml
|
||||||
|
|
||||||
|
env:
|
||||||
|
kubectl delete secret surf -n surf --ignore-not-found
|
||||||
|
kubectl create secret generic surf --from-env-file=.env -n surf
|
||||||
@@ -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.
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
services:
|
|
||||||
cssds:
|
|
||||||
image: registry.ntwl.xyz/megastructure-surf
|
|
||||||
|
|
||||||
build:
|
|
||||||
dockerfile: cssds.dockerfile
|
|
||||||
context: ./etc
|
|
||||||
|
|
||||||
user: "1000:1000"
|
|
||||||
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
|
|
||||||
# command: sleep 5000000
|
|
||||||
|
|
||||||
network_mode: host
|
|
||||||
|
|
||||||
ports:
|
|
||||||
- "27015:27015"
|
|
||||||
- "27015:27015/udp"
|
|
||||||
- "27020:27020"
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
- ./etc:/home/steam/etc
|
|
||||||
- ./data/cssds:/home/steam/cssds
|
|
||||||
- tf2ds:/home/steam/tf2ds
|
|
||||||
|
|
||||||
db:
|
|
||||||
image: mariadb:12
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "3306:3306"
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
- ./etc/mariadb/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
tf2ds:
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
FROM cm2network/steamcmd AS build
|
|
||||||
LABEL maintainer="ntr@megastructure.games"
|
|
||||||
|
|
||||||
EXPOSE 27015/tcp \
|
|
||||||
27015/udp \
|
|
||||||
27020/udp
|
|
||||||
|
|
||||||
USER root
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y \
|
|
||||||
wget \
|
|
||||||
ca-certificates \
|
|
||||||
zlib1g \
|
|
||||||
lib32gcc-s1 \
|
|
||||||
libncurses5 \
|
|
||||||
libbz2-1.0 \
|
|
||||||
libtinfo5 \
|
|
||||||
libcurl3-gnutls \
|
|
||||||
unzip \
|
|
||||||
rcon
|
|
||||||
|
|
||||||
ENV CSSDS="/home/steam/cssds"
|
|
||||||
ENV TF2DS="/home/steam/tf2ds"
|
|
||||||
ENV STEAMCMD="/home/steam/steamcmd"
|
|
||||||
ENV ETC="/home/steam/etc"
|
|
||||||
ENV METAMOD_VERSION=1.12
|
|
||||||
ENV SOURCEMOD_VERSION=1.12
|
|
||||||
|
|
||||||
# ensure gamedirs exist and have been chowned to steam
|
|
||||||
# before they potentially get setup as docker volumes
|
|
||||||
# which would otherwise cause them to be owned by root
|
|
||||||
RUN mkdir -p "$CSSDS" "$TF2DS" "$STEAMCMD" "$ETC"
|
|
||||||
RUN chown -R steam:steam /home/steam
|
|
||||||
|
|
||||||
FROM build AS steam
|
|
||||||
|
|
||||||
USER steam
|
|
||||||
WORKDIR /home/steam
|
|
||||||
|
|
||||||
COPY . /home/steam/etc
|
|
||||||
CMD ["bash", "./etc/run.sh"]
|
|
||||||
-375
@@ -1,375 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
set -uxe
|
|
||||||
|
|
||||||
CSTRIKE="$CSSDS/cstrike"
|
|
||||||
|
|
||||||
update_cssds() {
|
|
||||||
cd $STEAMCMD
|
|
||||||
./steamcmd.sh +runscript "$HOME/etc/update_cssds.txt"
|
|
||||||
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
echo "CSS DS is up to date"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
}
|
|
||||||
|
|
||||||
update_tf2ds() {
|
|
||||||
cd $STEAMCMD
|
|
||||||
./steamcmd.sh +runscript "$HOME/etc/update_tf2ds.txt"
|
|
||||||
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
echo "TF2 DS is up to date"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_metamod() {
|
|
||||||
# is the metamod folder missing?
|
|
||||||
if [ ! -d "$CSTRIKE/addons/metamod" ]; then
|
|
||||||
LATESTMM=$(wget -qO- https://mms.alliedmods.net/mmsdrop/"${METAMOD_VERSION}"/mmsource-latest-linux)
|
|
||||||
wget -qO- https://mms.alliedmods.net/mmsdrop/"${METAMOD_VERSION}"/"${LATESTMM}" | tar xvzf - -C "$CSTRIKE"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
echo "Installed MetaMod $METAMOD_VERSION"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
install_sourcemod() {
|
|
||||||
# Are we in a sourcemod container and is the sourcemod folder missing?
|
|
||||||
if [ ! -d "$CSTRIKE/addons/sourcemod" ]; then
|
|
||||||
LATESTSM=$(wget -qO- https://sm.alliedmods.net/smdrop/"${SOURCEMOD_VERSION}"/sourcemod-latest-linux)
|
|
||||||
wget -qO- https://sm.alliedmods.net/smdrop/"${SOURCEMOD_VERSION}"/"${LATESTSM}" | tar xvzf - -C "$CSTRIKE"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
echo "Installed SourceMod $SOURCEMOD_VERSION"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
install_surf() {
|
|
||||||
cd $CSTRIKE
|
|
||||||
|
|
||||||
# Install Shavit BHopTimer (replaces InfluxTimer)
|
|
||||||
if [ ! -d "$CSTRIKE/addons/sourcemod/configs/shavit" ]; then
|
|
||||||
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 "Installed Shavit BHopTimer v4.0.1"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install MomSurfFix
|
|
||||||
if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/momsurffix2.smx" ]; then
|
|
||||||
wget "https://github.com/GAMMACASE/MomSurfFix/releases/download/1.1.5/MomSurfFix2v1.1.5.zip"
|
|
||||||
unzip "MomSurfFix2v1.1.5.zip"
|
|
||||||
rm "MomSurfFix2v1.1.5.zip"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
echo "Installed MomSurfFix v1.1.5"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install PushFix Definitive Edition
|
|
||||||
if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/pushfix_de.smx" ]; then
|
|
||||||
wget "https://github.com/GAMMACASE/PushFixDE/releases/download/1.0.0/pushfix_de_1.0.0.zip"
|
|
||||||
unzip "pushfix_de_1.0.0.zip"
|
|
||||||
rm "pushfix_de_1.0.0.zip"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
echo "Installed PushFix Definitive Edition v1.0.0"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install EventQueue Fix
|
|
||||||
if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/eventqueuefix.smx" ]; then
|
|
||||||
wget "https://github.com/hermansimensen/eventqueue-fix/releases/download/1.3.2/eventqueuefix-1.3.2.zip"
|
|
||||||
unzip "eventqueuefix-1.3.2.zip"
|
|
||||||
rm "eventqueuefix-1.3.2.zip"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
echo "Installed EventQueue Fix v1.3.2"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install RNGFix
|
|
||||||
if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/rngfix.smx" ]; then
|
|
||||||
wget "https://github.com/jason-e/rngfix/releases/download/v1.1.3/rngfix_1.1.3.zip"
|
|
||||||
unzip "rngfix_1.1.3.zip"
|
|
||||||
rm "rngfix_1.1.3.zip"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
echo "Installed RNGFix v1.1.3"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
configure_shavit_zones() {
|
|
||||||
cd $CSTRIKE
|
|
||||||
|
|
||||||
# Check if already configured
|
|
||||||
if [ -f "$CSTRIKE/addons/sourcemod/configs/shavit-mapfixes.cfg" ]; then
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
echo "Shavit zones already configured"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
echo "Configuring Shavit to use JSON zones from surf-zones repo"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
|
|
||||||
# Download surf-zones repository
|
|
||||||
cd /tmp
|
|
||||||
wget "https://github.com/wrldspawn/surf-zones/archive/refs/heads/main.zip" -O surf-zones.zip
|
|
||||||
unzip -q surf-zones.zip
|
|
||||||
|
|
||||||
# Copy stripper directory
|
|
||||||
if [ -d "surf-zones-main/addons/stripper" ]; then
|
|
||||||
mkdir -p "$CSTRIKE/addons/stripper"
|
|
||||||
cp -r surf-zones-main/addons/stripper/* "$CSTRIKE/addons/stripper/"
|
|
||||||
echo "Copied stripper configurations"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Copy mapfixes configuration
|
|
||||||
if [ -f "surf-zones-main/addons/sourcemod/configs/shavit-mapfixes.cfg" ]; then
|
|
||||||
mkdir -p "$CSTRIKE/addons/sourcemod/configs"
|
|
||||||
cp surf-zones-main/addons/sourcemod/configs/shavit-mapfixes.cfg "$CSTRIKE/addons/sourcemod/configs/"
|
|
||||||
echo "Copied shavit-mapfixes.cfg"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Copy styles configuration (optional - removes irrelevant styles, matches KSF behavior)
|
|
||||||
if [ -f "surf-zones-main/addons/sourcemod/configs/shavit-styles.cfg" ]; then
|
|
||||||
cp surf-zones-main/addons/sourcemod/configs/shavit-styles.cfg "$CSTRIKE/addons/sourcemod/configs/"
|
|
||||||
echo "Copied shavit-styles.cfg"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
rm -rf surf-zones-main surf-zones.zip
|
|
||||||
|
|
||||||
# Create cfg directory for plugin configs if it doesn't exist
|
|
||||||
mkdir -p "$CSTRIKE/cfg/sourcemod"
|
|
||||||
|
|
||||||
# Configure zones plugin to use JSON instead of SQL
|
|
||||||
cat > "$CSTRIKE/cfg/sourcemod/plugin.shavit-zones.cfg" <<'EOF'
|
|
||||||
// Shavit Zones Plugin Configuration
|
|
||||||
// Set to 0 to use JSON zones instead of SQL database
|
|
||||||
shavit_zones_usesql "0"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Configure JSON zones URL
|
|
||||||
cat > "$CSTRIKE/cfg/sourcemod/plugin.shavit-zones-json.cfg" <<'EOF'
|
|
||||||
// Shavit JSON Zones Configuration
|
|
||||||
// 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"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
echo "Configured Shavit to use JSON zones"
|
|
||||||
echo "JSON URL: https://wrldspawn.github.io/surf-zones/z/{map}.json"
|
|
||||||
echo "Note: Use !setmaxvel in-game to set max velocity per map"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
}
|
|
||||||
|
|
||||||
configure_shavit_database() {
|
|
||||||
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 "Shavit database already configured"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
echo "Configuring Shavit database connection"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
|
|
||||||
# Set defaults if environment variables are not set
|
|
||||||
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"
|
|
||||||
|
|
||||||
# If databases.cfg doesn't exist, create it with full structure
|
|
||||||
if [ ! -f "$CSTRIKE/addons/sourcemod/configs/databases.cfg" ]; then
|
|
||||||
cat > "$CSTRIKE/addons/sourcemod/configs/databases.cfg" <<EOF
|
|
||||||
"Databases"
|
|
||||||
{
|
|
||||||
"driver_default" "mysql"
|
|
||||||
|
|
||||||
// Shavit BHopTimer Database
|
|
||||||
"shavit"
|
|
||||||
{
|
|
||||||
"driver" "mysql"
|
|
||||||
"host" "$DB_HOST"
|
|
||||||
"port" "$DB_PORT"
|
|
||||||
"database" "$DB_NAME"
|
|
||||||
"user" "$DB_USER"
|
|
||||||
"pass" "$DB_PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default SourceMod database (local SQLite)
|
|
||||||
"default"
|
|
||||||
{
|
|
||||||
"driver" "sqlite"
|
|
||||||
"database" "sourcemod-local"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Storage database (can also use MySQL if desired)
|
|
||||||
"storage-local"
|
|
||||||
{
|
|
||||||
"driver" "sqlite"
|
|
||||||
"database" "sourcemod-local"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 "Configured Shavit database connection"
|
|
||||||
echo "Host: $DB_HOST:$DB_PORT"
|
|
||||||
echo "Database: $DB_NAME"
|
|
||||||
echo "User: $DB_USER"
|
|
||||||
echo "--------------------------------------------------------------"
|
|
||||||
}
|
|
||||||
|
|
||||||
copy_64bit() {
|
|
||||||
cp -a "$TF2DS/bin/linux64/libsteam_api.so" \
|
|
||||||
"$CSSDS/bin/linux64/."
|
|
||||||
cp -a "$TF2DS/srcds_linux64" "$TF2DS/srcds_run_64" \
|
|
||||||
"$CSSDS/."
|
|
||||||
}
|
|
||||||
|
|
||||||
symlink_binaries() {
|
|
||||||
cd "$CSSDS/bin/linux64"
|
|
||||||
|
|
||||||
for file in *_srv.so; do
|
|
||||||
echo "Symlinking \"$file\" to \"${file/_srv/}"
|
|
||||||
ln -nfs "$file" "${file/_srv/}"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
steamclient_binary() {
|
|
||||||
echo "Looking for steamclient.so and symlinking it..."
|
|
||||||
local _steamclient64bit=$(find "$HOME" -type f -name 'steamclient.so' | grep "linux64" | head -n 1)
|
|
||||||
if [ ! -n $_steamclient64bit ]; then
|
|
||||||
echo "Could not locate 64-bit steamclient.so binary. Exiting..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "$HOME/.steam/sdk64/" # srcds_linux64 looks for steamclient.so in this directory
|
|
||||||
ln -nfs "$_steamclient64bit" "$HOME/.steam/sdk64/steamclient.so"
|
|
||||||
ln -nfs "$_steamclient64bit" "$CSSDS/bin/linux64/steamclient.so"
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg() {
|
|
||||||
cd
|
|
||||||
cp etc/cfg/server.cfg cssds/cstrike/cfg/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
run_cssds() {
|
|
||||||
echo "ready to run"
|
|
||||||
cd "$CSSDS"
|
|
||||||
|
|
||||||
./srcds_run_64 -game cstrike \
|
|
||||||
-port "${SRCDS_PORT}" \
|
|
||||||
+maxplayers "${SRCDS_MAXPLAYERS}" \
|
|
||||||
+map "${SRCDS_STARTMAP}"
|
|
||||||
# -ip "${SRCDS_IP}"
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
|
||||||
update_cssds
|
|
||||||
update_tf2ds
|
|
||||||
copy_64bit
|
|
||||||
symlink_binaries
|
|
||||||
steamclient_binary
|
|
||||||
|
|
||||||
install_metamod
|
|
||||||
install_sourcemod
|
|
||||||
install_surf
|
|
||||||
configure_shavit_zones
|
|
||||||
configure_shavit_database
|
|
||||||
|
|
||||||
cfg
|
|
||||||
run_cssds
|
|
||||||
}
|
|
||||||
|
|
||||||
main
|
|
||||||
|
|
||||||
|
|
||||||
# sm plugins
|
|
||||||
# "vipmodel.smx" vipmodel.smx
|
|
||||||
# "Reserved Slots" (1.7.2) by AlliedModders LLC
|
|
||||||
# "ColoredText" (2.0) by unt0uch4bl3 for KSF use ONLY
|
|
||||||
# "Basic Ban Commands" (1.7.2) by AlliedModders LLC
|
|
||||||
# "Server Hop" (0.8.1) by [GRAVE] rig0r
|
|
||||||
# "PlayerTransmit" (1.0) by unt0uch
|
|
||||||
# "strippermodels.smx" strippermodels.smx
|
|
||||||
# "Whitelist" (1.0.0) by unt0uch4bl3
|
|
||||||
# "SMAC Anti-Speedhack" (0.8.0.9) by GoD-Tony
|
|
||||||
# "Player Commands" (1.4.0-dev) by AlliedModders LLC
|
|
||||||
# "sm_super_cmds_unt0uch.smx" sm_super_cmds_unt0uch.smx
|
|
||||||
# "Basic Chat" (1.7.2) by AlliedModders LLC
|
|
||||||
# "Admin File Reader" (1.7.2) by AlliedModders LLC
|
|
||||||
# "Name Change Punisher" (1.1) by Powerlord
|
|
||||||
# "Map Nominations" (1.7.2) by AlliedModders LLC
|
|
||||||
# "Stipper" (1.0) by unt0uch4bl3
|
|
||||||
# "No Block" (1.0.0.0) by sslice
|
|
||||||
# "Basic Votes" (1.7.2) by AlliedModders LLC
|
|
||||||
# "CMD Logger" (1.0.0) by unt0uch4bl3
|
|
||||||
# "Momentum surf fix '2" (1.1.5) by GAMMA CASE
|
|
||||||
# "Fun Commands" (1.4.0-dev) by AlliedModders LLC
|
|
||||||
# "Custom Votes" (0.5.6) by chundo
|
|
||||||
# "SurfTimer" (7.8.0) by unt0uch4bl3
|
|
||||||
# "Anti-Flood" (1.7.2) by AlliedModders LLC
|
|
||||||
# "EventQueue fix" (1.3.3) by carnifex
|
|
||||||
# "antibhop.smx" antibhop.smx
|
|
||||||
# "Basic Info Triggers" (1.4.2) by AlliedModders LLC
|
|
||||||
# "MapChooser" (1.7.2) by AlliedModders LLC
|
|
||||||
# "Admin Help" (1.4.0-dev) by AlliedModders LLC
|
|
||||||
# "Basic Respawn Plugin" (0.05) by Spyder
|
|
||||||
# "Rock The Vote" (1.7.2) by AlliedModders LLC
|
|
||||||
# "UrlOpen" (1.0) by unt0uch4bl3
|
|
||||||
# "Message Admin" by evolv
|
|
||||||
# "RandomCycle" (1.7.2) by AlliedModders LLC
|
|
||||||
# "PushFix - Definitive Edition" (1.1.0) by Original idea xutaxkamay | Implementation GAMMACASE
|
|
||||||
# "No-Jump Boost Fix" (1.0.0) by rio
|
|
||||||
# "Admin Menu" (1.7.2) by AlliedModders LLC
|
|
||||||
# "Client Preferences" (1.7.2) by AlliedModders LLC
|
|
||||||
# "Map configs" (1.1.1) by Berni
|
|
||||||
# "Nextmap" (1.5.1) by AlliedModders LLC
|
|
||||||
# "draw.smx" draw.smx
|
|
||||||
# "Player Trails" (3.0.2) by Twisted|Panda
|
|
||||||
# "Fun Votes" (1.7.2) by AlliedModders LLC
|
|
||||||
# "RNGFix" (1.1.3) by rio
|
|
||||||
# "SQL Admins (Threaded)" (1.7.2) by AlliedModders LLC
|
|
||||||
# "Surftimer Announcer" (1.0) by unt0uch4bl3
|
|
||||||
# "Basic Commands" (1.7.2) by AlliedModders LLC
|
|
||||||
# "DEMO Uploader" (1.0) by unt0uch4bl3
|
|
||||||
# "Players Votes" (1.5.0) by The Resident, pZv!
|
|
||||||
# "SMAC Command Monitor" (0.8.0.9) by GoD-Tony, psychonic, Kigen
|
|
||||||
# "Dissolve" (1.0.0.2) by L. Duke
|
|
||||||
# "SourceMod Anti-Cheat" (0.8.0.9) by GoD-Tony, psychonic
|
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: surf
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# VOLUMES
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: cssds-data
|
||||||
|
namespace: surf
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 10Gi
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: fastdl-maps
|
||||||
|
namespace: surf
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# ENV (create/update with: just env)
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# CSSDS
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: cfg
|
||||||
|
namespace: surf
|
||||||
|
data:
|
||||||
|
mapcycle.txt: |
|
||||||
|
surf_anzchamps
|
||||||
|
surf_boreas
|
||||||
|
surf_deathstar
|
||||||
|
surf_ebony
|
||||||
|
surf_fornax
|
||||||
|
surf_garden
|
||||||
|
surf_in_space
|
||||||
|
surf_kepler
|
||||||
|
surf_kitsune
|
||||||
|
surf_kitsune2
|
||||||
|
surf_lt_omnific
|
||||||
|
surf_pantheon
|
||||||
|
surf_utopia_njv
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: cssds
|
||||||
|
namespace: surf
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: cssds
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: cssds
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 1000
|
||||||
|
runAsGroup: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
initContainers:
|
||||||
|
- name: fix-permissions
|
||||||
|
image: busybox
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 0
|
||||||
|
command: ['sh', '-c', 'chown -R 1000:1000 /home/steam/cssds']
|
||||||
|
volumeMounts:
|
||||||
|
- name: cssds-data
|
||||||
|
mountPath: /home/steam/cssds
|
||||||
|
containers:
|
||||||
|
- name: cssds
|
||||||
|
image: megastructure-surf-cssds:local
|
||||||
|
imagePullPolicy: Never
|
||||||
|
ports:
|
||||||
|
- containerPort: 27015
|
||||||
|
protocol: TCP
|
||||||
|
- containerPort: 27015
|
||||||
|
protocol: UDP
|
||||||
|
- containerPort: 27020
|
||||||
|
protocol: UDP
|
||||||
|
envFrom:
|
||||||
|
- secretRef:
|
||||||
|
name: surf
|
||||||
|
volumeMounts:
|
||||||
|
- name: src
|
||||||
|
mountPath: /home/steam/src
|
||||||
|
- name: cssds-data
|
||||||
|
mountPath: /home/steam/cssds
|
||||||
|
- name: fastdl-maps
|
||||||
|
mountPath: /fastdl/maps
|
||||||
|
readOnly: true
|
||||||
|
- name: cfg
|
||||||
|
mountPath: /home/steam/cfg
|
||||||
|
readOnly: true
|
||||||
|
volumes:
|
||||||
|
- name: src
|
||||||
|
hostPath:
|
||||||
|
path: /run/desktop/mnt/host/c/Users/ntr/code/surf_megastructure/src/cssds
|
||||||
|
- name: cssds-data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: cssds-data
|
||||||
|
- name: fastdl-maps
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: fastdl-maps
|
||||||
|
- name: cfg
|
||||||
|
configMap:
|
||||||
|
name: cfg
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: cssds
|
||||||
|
namespace: surf
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
selector:
|
||||||
|
app: cssds
|
||||||
|
ports:
|
||||||
|
- name: game-tcp
|
||||||
|
protocol: TCP
|
||||||
|
port: 27015
|
||||||
|
targetPort: 27015
|
||||||
|
- name: game-udp
|
||||||
|
protocol: UDP
|
||||||
|
port: 27015
|
||||||
|
targetPort: 27015
|
||||||
|
- name: tv
|
||||||
|
protocol: UDP
|
||||||
|
port: 27020
|
||||||
|
targetPort: 27020
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# FASTDL
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: fastdl
|
||||||
|
namespace: surf
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: fastdl
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: fastdl
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: fastdl
|
||||||
|
image: megastructure-surf-fastdl:local
|
||||||
|
imagePullPolicy: Never
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
volumeMounts:
|
||||||
|
- name: fastdl-maps
|
||||||
|
mountPath: /srv/maps
|
||||||
|
readOnly: true
|
||||||
|
volumes:
|
||||||
|
- name: fastdl-maps
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: fastdl-maps
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: fastdl
|
||||||
|
namespace: surf
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
selector:
|
||||||
|
app: fastdl
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 8080
|
||||||
|
targetPort: 80
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# MAP DOWNLOADER (run manually: kubectl apply, then delete when done)
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: mapsdl
|
||||||
|
namespace: surf
|
||||||
|
spec:
|
||||||
|
restartPolicy: Never
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 1000
|
||||||
|
runAsGroup: 1000
|
||||||
|
fsGroup: 1000
|
||||||
|
containers:
|
||||||
|
- name: mapsdl
|
||||||
|
image: megastructure-surf-mapsdl:local
|
||||||
|
imagePullPolicy: Never
|
||||||
|
command: ["deno", "run", "-A", "mapsdl.ts"]
|
||||||
|
env:
|
||||||
|
- name: MAPS_DIR
|
||||||
|
value: "/maps"
|
||||||
|
- name: TEMP_DIR
|
||||||
|
value: "/tmp/mapsdl"
|
||||||
|
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
value: "/app/credentials/service-account.json"
|
||||||
|
- name: MAPS_LIST_FILE
|
||||||
|
value: "/cfg/mapcycle.txt"
|
||||||
|
volumeMounts:
|
||||||
|
- name: fastdl-maps
|
||||||
|
mountPath: /maps
|
||||||
|
- name: credentials
|
||||||
|
mountPath: /app/credentials
|
||||||
|
readOnly: true
|
||||||
|
- name: cfg
|
||||||
|
mountPath: /cfg
|
||||||
|
readOnly: true
|
||||||
|
volumes:
|
||||||
|
- name: fastdl-maps
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: fastdl-maps
|
||||||
|
- name: credentials
|
||||||
|
hostPath:
|
||||||
|
path: /run/desktop/mnt/host/c/Users/ntr/code/surf_megastructure/src/mapsdl/credentials
|
||||||
|
- name: cfg
|
||||||
|
configMap:
|
||||||
|
name: cfg
|
||||||
|
|
||||||
|
---
|
||||||
@@ -6,30 +6,36 @@ 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
|
bzip2 \
|
||||||
|
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 SRC="/home/steam/src"
|
||||||
ENV METAMOD_VERSION=1.12
|
ENV METAMOD_VERSION=1.12
|
||||||
ENV SOURCEMOD_VERSION=1.12
|
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" "$SRC"
|
||||||
RUN chown -R steam:steam /home/steam
|
RUN chown -R steam:steam /home/steam
|
||||||
|
|
||||||
FROM build AS steam
|
FROM build AS steam
|
||||||
@@ -37,5 +43,5 @@ FROM build AS steam
|
|||||||
USER steam
|
USER steam
|
||||||
WORKDIR /home/steam
|
WORKDIR /home/steam
|
||||||
|
|
||||||
COPY . /home/steam/etc
|
COPY . /home/steam/src
|
||||||
CMD ["bash", "./etc/run.sh"]
|
CMD ["bash", "./src/run.sh"]
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
surf_fornax
|
||||||
|
surf_boreas
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
"MapLists"
|
||||||
|
{
|
||||||
|
"default"
|
||||||
|
{
|
||||||
|
"target" "mapcyclefile"
|
||||||
|
}
|
||||||
|
|
||||||
|
"sm_map menu"
|
||||||
|
{
|
||||||
|
"target" "mapcyclefile"
|
||||||
|
}
|
||||||
|
|
||||||
|
"sm_votemap menu"
|
||||||
|
{
|
||||||
|
"target" "mapcyclefile"
|
||||||
|
}
|
||||||
|
|
||||||
|
"randomcycle"
|
||||||
|
{
|
||||||
|
"target" "mapcyclefile"
|
||||||
|
}
|
||||||
|
|
||||||
|
"mapchooser"
|
||||||
|
{
|
||||||
|
"target" "mapcyclefile"
|
||||||
|
}
|
||||||
|
|
||||||
|
"nominations"
|
||||||
|
{
|
||||||
|
"target" "mapcyclefile"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<html>
|
||||||
|
<body style="background:#0a0a0a;color:#00ff88;font-family:monospace;padding:20px;">
|
||||||
|
<pre style="font-size:6px;line-height:1.1;">
|
||||||
|
███╗ ███╗███████╗ ██████╗ █████╗ ███████╗████████╗██████╗ ██╗ ██╗ ██████╗████████╗██╗ ██╗██████╗ ███████╗
|
||||||
|
████╗ ████║██╔════╝██╔════╝ ██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██║ ██║██╔════╝╚══██╔══╝██║ ██║██╔══██╗██╔════╝
|
||||||
|
██╔████╔██║█████╗ ██║ ███╗███████║███████╗ ██║ ██████╔╝██║ ██║██║ ██║ ██║ ██║██████╔╝█████╗
|
||||||
|
██║╚██╔╝██║██╔══╝ ██║ ██║██╔══██║╚════██║ ██║ ██╔══██╗██║ ██║██║ ██║ ██║ ██║██╔══██╗██╔══╝
|
||||||
|
██║ ╚═╝ ██║███████╗╚██████╔╝██║ ██║███████║ ██║ ██║ ██║╚██████╔╝╚██████╗ ██║ ╚██████╔╝██║ ██║███████╗
|
||||||
|
╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
|
||||||
|
███████╗██╗ ██╗██████╗ ███████╗
|
||||||
|
██╔════╝██║ ██║██╔══██╗██╔════╝
|
||||||
|
███████╗██║ ██║██████╔╝█████╗
|
||||||
|
╚════██║██║ ██║██╔══██╗██╔══╝
|
||||||
|
███████║╚██████╔╝██║ ██║██║
|
||||||
|
╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -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
|
||||||
// ================================================================
|
// ================================================================
|
||||||
Executable
+596
@@ -0,0 +1,596 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
set -ue
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
|
||||||
|
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
|
||||||
|
./steamcmd.sh +runscript "$HOME/src/update_cssds.txt"
|
||||||
|
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "CSS DS is up to date"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
# TF2 DS no longer needed - running in 32-bit mode
|
||||||
|
# update_tf2ds() function removed
|
||||||
|
|
||||||
|
install_surf() {
|
||||||
|
cd $CSTRIKE
|
||||||
|
|
||||||
|
# is the metamod folder missing?
|
||||||
|
if [ ! -d "$CSTRIKE/addons/metamod" ]; then
|
||||||
|
LATESTMM=$(wget -qO- https://mms.alliedmods.net/mmsdrop/"${METAMOD_VERSION}"/mmsource-latest-linux)
|
||||||
|
wget -qO- https://mms.alliedmods.net/mmsdrop/"${METAMOD_VERSION}"/"${LATESTMM}" | tar xvzf - -C "$CSTRIKE"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Installed MetaMod $METAMOD_VERSION"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Are we in a sourcemod container and is the sourcemod folder missing?
|
||||||
|
if [ ! -d "$CSTRIKE/addons/sourcemod" ]; then
|
||||||
|
LATESTSM=$(wget -qO- https://sm.alliedmods.net/smdrop/"${SOURCEMOD_VERSION}"/sourcemod-latest-linux)
|
||||||
|
wget -qO- https://sm.alliedmods.net/smdrop/"${SOURCEMOD_VERSION}"/"${LATESTSM}" | tar xvzf - -C "$CSTRIKE"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Installed SourceMod $SOURCEMOD_VERSION"
|
||||||
|
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/rip.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 "--------------------------------------------------------------"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Disable shavit-sounds plugin
|
||||||
|
if [ -f "$CSTRIKE/addons/sourcemod/plugins/shavit-sounds.smx" ]; then
|
||||||
|
mkdir -p "$CSTRIKE/addons/sourcemod/plugins/disabled"
|
||||||
|
mv "$CSTRIKE/addons/sourcemod/plugins/shavit-sounds.smx" \
|
||||||
|
"$CSTRIKE/addons/sourcemod/plugins/disabled/" 2>/dev/null || true
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Disabled shavit-sounds"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install MomSurfFix
|
||||||
|
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"
|
||||||
|
unzip -o "MomSurfFix2v1.1.5.zip"
|
||||||
|
cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
|
||||||
|
rm -rf "MomSurfFix2v1.1.5.zip" addons/
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Installed MomSurfFix v1.1.5"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
else
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "MomSurfFix already installed"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# PushFix Definitive Edition - appears in KSF plugin list but fails on CSS
|
||||||
|
# The DE version is CS:GO only and will fail with "g_SendTableCRC" error on CSS
|
||||||
|
# Disabled by default - if KSF uses a different version, it's not publicly available
|
||||||
|
# if [ ! -f "$CSTRIKE/addons/sourcemod/plugins/pushfix_de.smx" ]; then
|
||||||
|
# cd /tmp
|
||||||
|
# wget "https://github.com/GAMMACASE/PushFixDE/releases/download/1.0.0/pushfix_de_1.0.0.zip"
|
||||||
|
# unzip -o "pushfix_de_1.0.0.zip"
|
||||||
|
# cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
|
||||||
|
# rm -rf "pushfix_de_1.0.0.zip" addons/
|
||||||
|
# fi
|
||||||
|
|
||||||
|
# Install EventQueue Fix
|
||||||
|
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"
|
||||||
|
unzip -o "eventqueuefix-1.3.2.zip"
|
||||||
|
cp -r addons/* "$CSTRIKE/addons/" 2>/dev/null || true
|
||||||
|
rm -rf "eventqueuefix-1.3.2.zip" addons/
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Installed EventQueue Fix v1.3.2"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
else
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "EventQueue Fix already installed"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install RNGFix
|
||||||
|
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"
|
||||||
|
unzip -o "rngfix_1.1.3.zip"
|
||||||
|
cp -r rngfix_1.1.3/* "$CSTRIKE/addons/sourcemod/" 2>/dev/null || true
|
||||||
|
rm -rf "rngfix_1.1.3.zip" rngfix_1.1.3/
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Installed RNGFix v1.1.3"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
else
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "RNGFix already installed"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_shavit_zones() {
|
||||||
|
cd $CSTRIKE
|
||||||
|
|
||||||
|
# Check if already configured
|
||||||
|
if [ -f "$CSTRIKE/addons/sourcemod/configs/shavit-mapfixes.cfg" ]; then
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Shavit zones already configured"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Configuring Shavit to use JSON zones from surf-zones repo"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
|
||||||
|
# Download surf-zones repository
|
||||||
|
cd /tmp
|
||||||
|
wget "https://github.com/wrldspawn/surf-zones/archive/refs/heads/main.zip" -O surf-zones.zip
|
||||||
|
unzip -o surf-zones.zip
|
||||||
|
|
||||||
|
# Copy stripper directory
|
||||||
|
if [ -d "surf-zones-main/addons/stripper" ]; then
|
||||||
|
mkdir -p "$CSTRIKE/addons/stripper"
|
||||||
|
cp -r surf-zones-main/addons/stripper/* "$CSTRIKE/addons/stripper/"
|
||||||
|
echo "Copied stripper configurations"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy mapfixes configuration
|
||||||
|
if [ -f "surf-zones-main/addons/sourcemod/configs/shavit-mapfixes.cfg" ]; then
|
||||||
|
mkdir -p "$CSTRIKE/addons/sourcemod/configs"
|
||||||
|
cp surf-zones-main/addons/sourcemod/configs/shavit-mapfixes.cfg "$CSTRIKE/addons/sourcemod/configs/"
|
||||||
|
echo "Copied shavit-mapfixes.cfg"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy styles configuration (optional - removes irrelevant styles, matches KSF behavior)
|
||||||
|
if [ -f "surf-zones-main/addons/sourcemod/configs/shavit-styles.cfg" ]; then
|
||||||
|
cp surf-zones-main/addons/sourcemod/configs/shavit-styles.cfg "$CSTRIKE/addons/sourcemod/configs/"
|
||||||
|
echo "Copied shavit-styles.cfg"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
rm -rf surf-zones-main surf-zones.zip
|
||||||
|
|
||||||
|
# Create cfg directory for plugin configs if it doesn't exist
|
||||||
|
mkdir -p "$CSTRIKE/cfg/sourcemod"
|
||||||
|
|
||||||
|
# Configure zones plugin to use SQL database
|
||||||
|
cat > "$CSTRIKE/cfg/sourcemod/plugin.shavit-zones.cfg" <<'EOF'
|
||||||
|
// Shavit Zones Plugin Configuration
|
||||||
|
// Set to 1 to use SQL zones (default for Surf Timer fork)
|
||||||
|
shavit_zones_usesql "1"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Configure mapchooser to allow all maps from disk
|
||||||
|
cat > "$CSTRIKE/cfg/sourcemod/plugin.shavit-mapchooser.cfg" <<'EOF'
|
||||||
|
// 0 = zoned maps from database, 1 = maplist.txt, 2 = maps folder
|
||||||
|
smc_maplist_type "2"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# JSON zones temporarily disabled for testing
|
||||||
|
# cat > "$CSTRIKE/cfg/sourcemod/plugin.shavit-zones-json.cfg" <<'EOF'
|
||||||
|
# // Shavit JSON Zones Configuration
|
||||||
|
# // 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"
|
||||||
|
# EOF
|
||||||
|
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Configured Shavit to use SQL zones"
|
||||||
|
echo "Use !zones in-game to create start/end zones for maps"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_shavit_database() {
|
||||||
|
cd $CSTRIKE
|
||||||
|
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Writing Shavit database configuration (SQLite)"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
|
||||||
|
# Always recreate databases.cfg
|
||||||
|
mkdir -p "$CSTRIKE/addons/sourcemod/configs"
|
||||||
|
|
||||||
|
cat > "$CSTRIKE/addons/sourcemod/configs/databases.cfg" <<'EOF'
|
||||||
|
"Databases"
|
||||||
|
{
|
||||||
|
"driver_default" "sqlite"
|
||||||
|
|
||||||
|
// Shavit BHopTimer Database (using local SQLite)
|
||||||
|
"shavit"
|
||||||
|
{
|
||||||
|
"driver" "sqlite"
|
||||||
|
"database" "shavit-local"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default SourceMod database (local SQLite)
|
||||||
|
"default"
|
||||||
|
{
|
||||||
|
"driver" "sqlite"
|
||||||
|
"database" "sourcemod-local"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Storage database (local SQLite)
|
||||||
|
"storage-local"
|
||||||
|
{
|
||||||
|
"driver" "sqlite"
|
||||||
|
"database" "sourcemod-local"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Configured Shavit to use local SQLite database"
|
||||||
|
echo "Database: shavit-local.sq3"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
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 "--------------------------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_64bit() {
|
||||||
|
cp -a "$TF2DS/bin/linux64/libsteam_api.so" \
|
||||||
|
"$CSSDS/bin/linux64/"
|
||||||
|
cp -a "$TF2DS/srcds_linux64" "$TF2DS/srcds_run_64" \
|
||||||
|
"$CSSDS/"
|
||||||
|
}
|
||||||
|
|
||||||
|
symlink_binaries() {
|
||||||
|
cd "$CSSDS/bin/linux64"
|
||||||
|
|
||||||
|
for file in *_srv.so; do
|
||||||
|
echo "Symlinking \"$file\" to \"${file/_srv/}"
|
||||||
|
ln -nfs "$file" "${file/_srv/}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
steamclient_binary() {
|
||||||
|
echo "Looking for steamclient.so and symlinking it..."
|
||||||
|
# For 32-bit mode, look for 32-bit steamclient (linux32 or default)
|
||||||
|
local _steamclient32bit=$(find "$HOME" -type f -name 'steamclient.so' | grep -E "linux32|steamcmd/linux32" | head -n 1)
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$HOME/.steam/sdk32/" # srcds_run looks for steamclient.so in this directory
|
||||||
|
ln -nfs "$_steamclient32bit" "$HOME/.steam/sdk32/steamclient.so"
|
||||||
|
ln -nfs "$_steamclient32bit" "$CSSDS/steamclient.so"
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_admins() {
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Configuring SourceMod admins"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
|
||||||
|
local ADMINS_INI="$CSTRIKE/addons/sourcemod/configs/admins_simple.ini"
|
||||||
|
|
||||||
|
if [ -z "${SRCDS_ADMINS:-}" ]; then
|
||||||
|
echo "No admins configured (set SRCDS_ADMINS env var)"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
: > "$ADMINS_INI"
|
||||||
|
|
||||||
|
IFS=',' read -ra ADMIN_IDS <<< "$SRCDS_ADMINS"
|
||||||
|
for steamid in "${ADMIN_IDS[@]}"; do
|
||||||
|
steamid=$(echo "$steamid" | tr -d '"' | tr -d "'" | tr -d ' ')
|
||||||
|
if [ -n "$steamid" ]; then
|
||||||
|
echo "\"$steamid\" \"99:z\"" >> "$ADMINS_INI"
|
||||||
|
echo "Added admin: $steamid"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Configured ${#ADMIN_IDS[@]} admin(s)"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg() {
|
||||||
|
cd
|
||||||
|
cp src/cfg/server.cfg cssds/cstrike/cfg/
|
||||||
|
cp src/cfg/motd.txt cssds/cstrike/
|
||||||
|
cp src/cfg/maplists.cfg cssds/cstrike/addons/sourcemod/configs/maplists.cfg
|
||||||
|
cp cfg/mapcycle.txt cssds/cstrike/cfg/
|
||||||
|
cp cfg/mapcycle.txt cssds/cstrike/addons/sourcemod/configs/adminmenu_maplist.ini
|
||||||
|
sed -i "s|sv_downloadurl .*|sv_downloadurl \"${FASTDL_URL:-}/cstrike/\"|" "$CSTRIKE/cfg/server.cfg"
|
||||||
|
sed -i "s|rcon_password .*|rcon_password \"${SRCDS_RCONPW:-changeme}\"|" "$CSTRIKE/cfg/server.cfg"
|
||||||
|
}
|
||||||
|
|
||||||
|
populate_maps() {
|
||||||
|
local BZ2_DIR="/fastdl/maps"
|
||||||
|
local MAPS_DIR="$CSTRIKE/maps"
|
||||||
|
local MAPCYCLE="$CSTRIKE/cfg/mapcycle.txt"
|
||||||
|
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Populating maps from compressed archive"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
|
||||||
|
if [ ! -f "$MAPCYCLE" ]; then
|
||||||
|
echo "No mapcycle.txt found, skipping map population"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$MAPS_DIR"
|
||||||
|
|
||||||
|
local total=0 skipped=0 extracted=0 missing=0
|
||||||
|
|
||||||
|
while IFS= read -r line || [ -n "$line" ]; do
|
||||||
|
# skip empty lines and comments
|
||||||
|
line=$(echo "$line" | sed 's|//.*||' | xargs)
|
||||||
|
[ -z "$line" ] && continue
|
||||||
|
|
||||||
|
total=$((total + 1))
|
||||||
|
local bz2="$BZ2_DIR/${line}.bsp.bz2"
|
||||||
|
local bsp="$MAPS_DIR/${line}.bsp"
|
||||||
|
|
||||||
|
if [ -f "$bsp" ]; then
|
||||||
|
skipped=$((skipped + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$bz2" ]; then
|
||||||
|
missing=$((missing + 1))
|
||||||
|
echo " [!] ${line}: not in fastdl volume"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
bunzip2 -c "$bz2" > "$bsp"
|
||||||
|
extracted=$((extracted + 1))
|
||||||
|
done < "$MAPCYCLE"
|
||||||
|
|
||||||
|
echo "Maps: $total in mapcycle, $extracted extracted, $skipped already present, $missing not available"
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
run_cssds() {
|
||||||
|
cd "$CSSDS"
|
||||||
|
|
||||||
|
local startmap="${SRCDS_STARTMAP:-}"
|
||||||
|
if [ -z "$startmap" ]; then
|
||||||
|
startmap=$(grep -v '^\s*\/\/' "$CSTRIKE/cfg/mapcycle.txt" | grep -m1 '\S')
|
||||||
|
fi
|
||||||
|
|
||||||
|
./srcds_run -game cstrike \
|
||||||
|
-port "${SRCDS_PORT}" \
|
||||||
|
+sv_setsteamaccount "${SRCDS_TOKEN}" \
|
||||||
|
+maxplayers "${SRCDS_MAXPLAYERS}" \
|
||||||
|
+map "$startmap" \
|
||||||
|
-ip "${SRCDS_IP}"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
update_cssds
|
||||||
|
# TF2 DS not needed - running in 32-bit mode
|
||||||
|
steamclient_binary
|
||||||
|
|
||||||
|
install_surf
|
||||||
|
configure_shavit_zones
|
||||||
|
configure_shavit_database
|
||||||
|
configure_admins
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
populate_maps
|
||||||
|
|
||||||
|
run_cssds
|
||||||
|
}
|
||||||
|
|
||||||
|
main
|
||||||
|
|
||||||
|
|
||||||
|
# sm plugins
|
||||||
|
# "vipmodel.smx" vipmodel.smx
|
||||||
|
# "Reserved Slots" (1.7.2) by AlliedModders LLC
|
||||||
|
# "ColoredText" (2.0) by unt0uch4bl3 for KSF use ONLY
|
||||||
|
# "Basic Ban Commands" (1.7.2) by AlliedModders LLC
|
||||||
|
# "Server Hop" (0.8.1) by [GRAVE] rig0r
|
||||||
|
# "PlayerTransmit" (1.0) by unt0uch
|
||||||
|
# "strippermodels.smx" strippermodels.smx
|
||||||
|
# "Whitelist" (1.0.0) by unt0uch4bl3
|
||||||
|
# "SMAC Anti-Speedhack" (0.8.0.9) by GoD-Tony
|
||||||
|
# "Player Commands" (1.4.0-dev) by AlliedModders LLC
|
||||||
|
# "sm_super_cmds_unt0uch.smx" sm_super_cmds_unt0uch.smx
|
||||||
|
# "Basic Chat" (1.7.2) by AlliedModders LLC
|
||||||
|
# "Admin File Reader" (1.7.2) by AlliedModders LLC
|
||||||
|
# "Name Change Punisher" (1.1) by Powerlord
|
||||||
|
# "Map Nominations" (1.7.2) by AlliedModders LLC
|
||||||
|
# "Stipper" (1.0) by unt0uch4bl3
|
||||||
|
# "No Block" (1.0.0.0) by sslice
|
||||||
|
# "Basic Votes" (1.7.2) by AlliedModders LLC
|
||||||
|
# "CMD Logger" (1.0.0) by unt0uch4bl3
|
||||||
|
# "Momentum surf fix '2" (1.1.5) by GAMMA CASE
|
||||||
|
# "Fun Commands" (1.4.0-dev) by AlliedModders LLC
|
||||||
|
# "Custom Votes" (0.5.6) by chundo
|
||||||
|
# "SurfTimer" (7.8.0) by unt0uch4bl3
|
||||||
|
# "Anti-Flood" (1.7.2) by AlliedModders LLC
|
||||||
|
# "EventQueue fix" (1.3.3) by carnifex
|
||||||
|
# "antibhop.smx" antibhop.smx
|
||||||
|
# "Basic Info Triggers" (1.4.2) by AlliedModders LLC
|
||||||
|
# "MapChooser" (1.7.2) by AlliedModders LLC
|
||||||
|
# "Admin Help" (1.4.0-dev) by AlliedModders LLC
|
||||||
|
# "Basic Respawn Plugin" (0.05) by Spyder
|
||||||
|
# "Rock The Vote" (1.7.2) by AlliedModders LLC
|
||||||
|
# "UrlOpen" (1.0) by unt0uch4bl3
|
||||||
|
# "Message Admin" by evolv
|
||||||
|
# "RandomCycle" (1.7.2) by AlliedModders LLC
|
||||||
|
# "PushFix - Definitive Edition" (1.1.0) by Original idea xutaxkamay | Implementation GAMMACASE
|
||||||
|
# "No-Jump Boost Fix" (1.0.0) by rio
|
||||||
|
# "Admin Menu" (1.7.2) by AlliedModders LLC
|
||||||
|
# "Client Preferences" (1.7.2) by AlliedModders LLC
|
||||||
|
# "Map configs" (1.1.1) by Berni
|
||||||
|
# "Nextmap" (1.5.1) by AlliedModders LLC
|
||||||
|
# "draw.smx" draw.smx
|
||||||
|
# "Player Trails" (3.0.2) by Twisted|Panda
|
||||||
|
# "Fun Votes" (1.7.2) by AlliedModders LLC
|
||||||
|
# "RNGFix" (1.1.3) by rio
|
||||||
|
# "SQL Admins (Threaded)" (1.7.2) by AlliedModders LLC
|
||||||
|
# "Surftimer Announcer" (1.0) by unt0uch4bl3
|
||||||
|
# "Basic Commands" (1.7.2) by AlliedModders LLC
|
||||||
|
# "DEMO Uploader" (1.0) by unt0uch4bl3
|
||||||
|
# "Players Votes" (1.5.0) by The Resident, pZv!
|
||||||
|
# "SMAC Command Monitor" (0.8.0.9) by GoD-Tony, psychonic, Kigen
|
||||||
|
# "Dissolve" (1.0.0.2) by L. Duke
|
||||||
|
# "SourceMod Anti-Cheat" (0.8.0.9) by GoD-Tony, psychonic
|
||||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,2 @@
|
|||||||
|
FROM nginx:alpine
|
||||||
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
root /srv;
|
||||||
|
location /cstrike/maps/ {
|
||||||
|
alias /srv/maps/;
|
||||||
|
autoindex off;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,812 @@
|
|||||||
|
// ______________________
|
||||||
|
//___________.( h0lmGUI™v4.1 by h0lm ).___________
|
||||||
|
//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// Object Control Panel scheme resource file
|
||||||
|
//
|
||||||
|
// sections:
|
||||||
|
// Colors - all the colors used by the scheme
|
||||||
|
// BaseSettings - contains settings for app to use to draw controls
|
||||||
|
// Fonts - list of all the fonts used by app
|
||||||
|
// Borders - description of all the borders
|
||||||
|
//
|
||||||
|
// hit ctrl-alt-shift-R in the app to reload this file
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
Scheme
|
||||||
|
{
|
||||||
|
//////////////////////// COLORS ///////////////////////////
|
||||||
|
// color details
|
||||||
|
// this is a list of all the colors used by the scheme
|
||||||
|
Colors
|
||||||
|
{
|
||||||
|
// base colors
|
||||||
|
//"BaseText" "48 192 192 255" // used in text windows, lists
|
||||||
|
//"BrightBaseText" "155 255 255 255" // brightest text
|
||||||
|
|
||||||
|
"BaseText" "220 30 30 255"
|
||||||
|
"BrightBaseText" "255 0 0 255"
|
||||||
|
"DimBaseText" "220 30 30 255" // dim base text
|
||||||
|
"LabelDimText" "220 30 30 255" // slight modification on above, used for info text
|
||||||
|
// could be just removed and use DimBaseText?
|
||||||
|
|
||||||
|
"ControlText" "48 192 192 255" // used in all text controls
|
||||||
|
"BrightControlText" "64 224 224 255" // use for selected controls
|
||||||
|
"DisabledText1" "32 128 128 255" // disabled text
|
||||||
|
"DisabledText2" "30 30 30 255" // overlay color for disabled text (to give that inset look)
|
||||||
|
|
||||||
|
// background colors
|
||||||
|
"ControlBG" "76 88 68 255" // background color of controls
|
||||||
|
"ControlDarkBG" "90 106 80 255" // darker background color; used for background of scrollbars
|
||||||
|
"WindowBG" "62 70 55 255" // background color of text edit panes (chat, text entries, etc.)
|
||||||
|
|
||||||
|
"SelectionBG" "76 88 68 255" // background color of any selected text or menu item
|
||||||
|
|
||||||
|
// title colors
|
||||||
|
"TitleText" "255 255 255 255"
|
||||||
|
"TitleDimText" "120 132 114 255"
|
||||||
|
"TitleBG" "76 88 68 0"
|
||||||
|
"TitleDimBG" "76 88 68 0"
|
||||||
|
|
||||||
|
// border colors
|
||||||
|
"BorderBright" "136 145 128 255" // the lit side of a control
|
||||||
|
"BorderDark" "45 49 40 255" // the dark/unlit side of a control
|
||||||
|
"BorderSelection" "0 0 0 255" // the additional border color for displaying the default/selected button
|
||||||
|
|
||||||
|
"C4Panel_Armed" "0 128 255 200"
|
||||||
|
"C4Panel_Defused" "0 255 0 200"
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////// BASE SETTINGS ////////////////////////
|
||||||
|
//
|
||||||
|
// default settings for all panels
|
||||||
|
// controls use these to determine their settings
|
||||||
|
BaseSettings
|
||||||
|
{
|
||||||
|
Panel.FgColor "48 192 192 255"
|
||||||
|
Panel.BgColor "0 0 0 0" //Important! - makes the panels transparent
|
||||||
|
|
||||||
|
"FgColor" "ControlText"
|
||||||
|
"BgColor" "ControlBG"
|
||||||
|
"LabelBgColor" "ControlBG"
|
||||||
|
"SubPanelBgColor" "ControlBG"
|
||||||
|
|
||||||
|
"DisabledFgColor1" "DisabledText1"
|
||||||
|
"DisabledFgColor2" "DisabledText2" // set this to the BgColor if you don't want it to draw
|
||||||
|
|
||||||
|
"TitleBarFgColor" "TitleText"
|
||||||
|
"TitleBarDisabledFgColor" "TitleDimText"
|
||||||
|
"TitleBarBgColor" "TitleBG"
|
||||||
|
"TitleBarDisabledBgColor" "TitleDimBG"
|
||||||
|
|
||||||
|
// "TitleBarIcon" "resource/icon_steam"
|
||||||
|
// "TitleBarDisabledIcon" "resource/icon_steam_disabled"
|
||||||
|
"TitleBarIcon" "resource/icon_hlicon1"
|
||||||
|
"TitleBarDisabledIcon" "resource/icon_hlicon2"
|
||||||
|
|
||||||
|
"TitleButtonFgColor" "BorderBright"
|
||||||
|
"TitleButtonBgColor" "ControlBG"
|
||||||
|
"TitleButtonDisabledFgColor" "TitleDimText"
|
||||||
|
"TitleButtonDisabledBgColor" "TitleDimBG"
|
||||||
|
|
||||||
|
"TextCursorColor" "BaseText" // color of the blinking text cursor in text entries
|
||||||
|
"URLTextColor" "BrightBaseText" // color that URL's show up in chat window
|
||||||
|
|
||||||
|
Menu
|
||||||
|
{
|
||||||
|
"FgColor" "DimBaseText"
|
||||||
|
"BgColor" "ControlBG"
|
||||||
|
"ArmedFgColor" "BrightBaseText"
|
||||||
|
"ArmedBgColor" "SelectionBG"
|
||||||
|
"DividerColor" "BorderDark"
|
||||||
|
|
||||||
|
"TextInset" "6"
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuButton // the little arrow on the side of boxes that triggers drop down menus
|
||||||
|
{
|
||||||
|
"ButtonArrowColor" "DimBaseText" // color of arrows
|
||||||
|
"ButtonBgColor" "WindowBG" // bg color of button. same as background color of text edit panes
|
||||||
|
|
||||||
|
"ArmedArrowColor" "BrightBaseText" // color of arrow when mouse is over button
|
||||||
|
"ArmedBgColor" "DimBaseText" // bg color of button when mouse is over button
|
||||||
|
}
|
||||||
|
|
||||||
|
Slider
|
||||||
|
{
|
||||||
|
"SliderFgColor" "ControlText" // handle with which the slider is grabbed
|
||||||
|
"SliderBgColor" "ControlDarkBG" // area behind handle
|
||||||
|
"SliderTickColor" "ControlText" // slider tick's color
|
||||||
|
"SliderTickLabelColor" "ControlText" // color of labels at the ends of the slider tick
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollBarSlider
|
||||||
|
{
|
||||||
|
"BgColor" "ControlBG" // this isn't really used
|
||||||
|
|
||||||
|
"ScrollBarSliderFgColor" "ControlBG" // handle with which the slider is grabbed
|
||||||
|
"ScrollBarSliderBgColor" "ControlDarkBG" // area behind handle
|
||||||
|
|
||||||
|
"ButtonFgColor" "DimBaseText" // color of arrows
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// text edit windows
|
||||||
|
"WindowFgColor" "BaseText" // off-white
|
||||||
|
"WindowBgColor" "WindowBG"
|
||||||
|
"WindowDisabledFgColor" "DimBaseText"
|
||||||
|
"WindowDisabledBgColor" "66 80 60 255" // background of chat conversation
|
||||||
|
|
||||||
|
"SelectionFgColor" "255 255 255 255" // fg color of selected text
|
||||||
|
"SelectionBgColor" "SelectionBG"
|
||||||
|
"ListSelectionFgColor" "255 255 255 255" //
|
||||||
|
|
||||||
|
"ListBgColor" "62 70 55 255" // background of server browser control, etc
|
||||||
|
"BuddyListBgColor" "62 70 55 255" // background of buddy list pane
|
||||||
|
|
||||||
|
// App-specific stuff
|
||||||
|
"ChatBgColor" "WindowBgColor"
|
||||||
|
|
||||||
|
// status selection
|
||||||
|
"StatusSelectFgColor" "BrightBaseText"
|
||||||
|
"StatusSelectFgColor2" "BrightControlText" // this is the color of the friends status
|
||||||
|
|
||||||
|
// checkboxes
|
||||||
|
"CheckButtonBorder1" "BorderDark" // the left checkbutton border
|
||||||
|
"CheckButtonBorder2" "BorderBright" // the right checkbutton border
|
||||||
|
"CheckButtonCheck" "0 0 0 255" // color of the check itself
|
||||||
|
"CheckBgColor" "158 168 150 255"
|
||||||
|
|
||||||
|
// buttons (default fg/bg colors are used if these are not set)
|
||||||
|
// "ButtonArmedFgColor"
|
||||||
|
// "ButtonArmedBgColor"
|
||||||
|
// "ButtonDepressedFgColor" "BrightControlText"
|
||||||
|
// "ButtonDepressedBgColor"
|
||||||
|
|
||||||
|
// buddy buttons
|
||||||
|
BuddyButton
|
||||||
|
{
|
||||||
|
"FgColor1" "ControlText"
|
||||||
|
"FgColor2" "117 134 102 255"
|
||||||
|
|
||||||
|
"ArmedFgColor1" "BrightBaseText"
|
||||||
|
"ArmedFgColor2" "BrightBaseText"
|
||||||
|
"ArmedBgColor" "SelectionBG"
|
||||||
|
}
|
||||||
|
|
||||||
|
Chat
|
||||||
|
{
|
||||||
|
"TextColor" "BrightControlText"
|
||||||
|
"SelfTextColor" "BaseText"
|
||||||
|
"SeperatorTextColor" "DimBaseText"
|
||||||
|
}
|
||||||
|
|
||||||
|
"SectionTextColor" "BrightControlText" // text color for IN-GAME, ONLINE, OFFLINE sections of buddy list
|
||||||
|
"SectionDividerColor" "BorderDark" // color of line that runs under section name in buddy list
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//////////////////////// FONTS /////////////////////////////
|
||||||
|
//
|
||||||
|
// describes all the fonts
|
||||||
|
Fonts
|
||||||
|
{
|
||||||
|
// fonts are used in order that they are listed
|
||||||
|
// fonts listed later in the order will only be used if they fulfill a range not already filled
|
||||||
|
// if a font fails to load then the subsequent fonts will replace
|
||||||
|
"Default"
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"name" "Dead Kansas"
|
||||||
|
"tall" "45" //45
|
||||||
|
"weight" "600" //900
|
||||||
|
"range" "0x0000 0x017F" // Basic Latin, Latin-1 Supplement, Latin Extended-A
|
||||||
|
"antialias" "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"DefaultUnderline"
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"name" "Impact"
|
||||||
|
"tall" "32"
|
||||||
|
"weight" "900"
|
||||||
|
"underline" "1"
|
||||||
|
"range" "0x0000 0x017F" // Basic Latin, Latin-1 Supplement, Latin Extended-A
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"DefaultSmall"
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"name" "Impact"
|
||||||
|
"tall" "24"
|
||||||
|
"weight" "900"
|
||||||
|
"range" "0x0000 0x017F" // Basic Latin, Latin-1 Supplement, Latin Extended-A
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"DefaultVerySmall"
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"name" "Impact"
|
||||||
|
"tall" "18"
|
||||||
|
"weight" "900"
|
||||||
|
"range" "0x0000 0x017F" // Basic Latin, Latin-1 Supplement, Latin Extended-A
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"DefaultLarge"
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"name" "Impact"
|
||||||
|
"tall" "48"
|
||||||
|
"weight" "0"
|
||||||
|
"range" "0x0000 0x017F" // Basic Latin, Latin-1 Supplement, Latin Extended-A
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is the symbol font
|
||||||
|
"Marlett"
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"name" "Marlett"
|
||||||
|
"tall" "14"
|
||||||
|
"weight" "0"
|
||||||
|
"symbol" "1"
|
||||||
|
"range" "0x0000 0x007F" // Basic Latin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//////////////////// BORDERS //////////////////////////////
|
||||||
|
//
|
||||||
|
// describes all the border types
|
||||||
|
Borders
|
||||||
|
{
|
||||||
|
BaseBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TitleButtonBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"4"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TitleButtonDisabledBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BgColor"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BgColor"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BgColor"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BgColor"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TitleButtonDepressedBorder
|
||||||
|
{
|
||||||
|
"inset" "1 1 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollBarButtonBorder
|
||||||
|
{
|
||||||
|
"inset" "2 2 0 0"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TabBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TabActiveBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 0"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "ControlBG"
|
||||||
|
"offset" "6 2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ToolTipBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 0"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is the border used for default buttons (the button that gets pressed when you hit enter)
|
||||||
|
ButtonKeyFocusBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderSelection"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderSelection"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderSelection"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderSelection"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonDepressedBorder
|
||||||
|
{
|
||||||
|
"inset" "2 1 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBoxBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuBorder
|
||||||
|
{
|
||||||
|
"inset" "1 1 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderBright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "BorderDark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//________________________________________________
|
||||||
|
//¯¯¯¯¯¯¯¯¯¯¯'( h0lmGUI™v4.1 by h0lm )'¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
@@ -0,0 +1,755 @@
|
|||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// Tracker scheme resource file
|
||||||
|
//
|
||||||
|
// sections:
|
||||||
|
// Colors - all the colors used by the scheme
|
||||||
|
// BaseSettings - contains settings for app to use to draw controls
|
||||||
|
// Fonts - list of all the fonts used by app
|
||||||
|
// Borders - description of all the borders
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
Scheme
|
||||||
|
{
|
||||||
|
//////////////////////// COLORS ///////////////////////////
|
||||||
|
// color details
|
||||||
|
// this is a list of all the colors used by the scheme
|
||||||
|
Colors
|
||||||
|
{
|
||||||
|
// base colors
|
||||||
|
"White" "255 255 255 255"
|
||||||
|
"OffWhite" "216 216 216 255"
|
||||||
|
"DullWhite" "0 0 0 0"
|
||||||
|
"Orange" "255 110 0 255"
|
||||||
|
"TransparentBlack" "0 0 0 0"
|
||||||
|
"Black" "0 0 0 255"
|
||||||
|
|
||||||
|
"Blank" "0 0 0 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////// BASE SETTINGS ////////////////////////
|
||||||
|
//
|
||||||
|
// default settings for all panels
|
||||||
|
// controls use these to determine their settings
|
||||||
|
BaseSettings
|
||||||
|
{
|
||||||
|
// vgui_controls color specifications
|
||||||
|
Border.Bright "0 0 0 0" //"200 200 200 196" // the lit side of a control
|
||||||
|
Border.Dark "0 0 0 0" //"40 40 40 196" // the dark/unlit side of a control
|
||||||
|
Border.Selection "0 0 0 0" //"0 0 0 196" // the additional border color for displaying the default/selected button
|
||||||
|
|
||||||
|
Button.TextColor "White"
|
||||||
|
Button.BgColor "Blank"
|
||||||
|
Button.ArmedTextColor "White"
|
||||||
|
Button.ArmedBgColor "Blank" [$WIN32]
|
||||||
|
Button.ArmedBgColor "190 115 0 255" [$X360]
|
||||||
|
Button.DepressedTextColor "White"
|
||||||
|
Button.DepressedBgColor "Blank"
|
||||||
|
Button.FocusBorderColor "Black"
|
||||||
|
|
||||||
|
CheckButton.TextColor "OffWhite"
|
||||||
|
CheckButton.SelectedTextColor "White"
|
||||||
|
CheckButton.BgColor "TransparentBlack"
|
||||||
|
CheckButton.Border1 "Border.Dark" // the left checkbutton border
|
||||||
|
CheckButton.Border2 "Border.Bright" // the right checkbutton border
|
||||||
|
CheckButton.Check "White" // color of the check itself
|
||||||
|
|
||||||
|
ComboBoxButton.ArrowColor "DullWhite"
|
||||||
|
ComboBoxButton.ArmedArrowColor "White"
|
||||||
|
ComboBoxButton.BgColor "Blank"
|
||||||
|
ComboBoxButton.DisabledBgColor "Blank"
|
||||||
|
|
||||||
|
"Chat.TypingText" "white"
|
||||||
|
|
||||||
|
Frame.TitleTextInsetX 16
|
||||||
|
Frame.ClientInsetX 8
|
||||||
|
Frame.ClientInsetY 6
|
||||||
|
Frame.BgColor "160 160 160 128" [$WIN32]
|
||||||
|
Frame.BgColor "80 80 80 192" [$X360]
|
||||||
|
Frame.OutOfFocusBgColor "160 160 160 32" [$WIN32]
|
||||||
|
Frame.OutOfFocusBgColor "80 80 80 192" [$X360]
|
||||||
|
Frame.FocusTransitionEffectTime "0.3" // time it takes for a window to fade in/out on focus/out of focus
|
||||||
|
Frame.TransitionEffectTime "0.3" // time it takes for a window to fade in/out on open/close
|
||||||
|
Frame.AutoSnapRange "0"
|
||||||
|
FrameGrip.Color1 "200 200 200 196"
|
||||||
|
FrameGrip.Color2 "0 0 0 196"
|
||||||
|
FrameTitleButton.FgColor "200 200 200 196"
|
||||||
|
FrameTitleButton.BgColor "Blank"
|
||||||
|
FrameTitleButton.DisabledFgColor "255 255 255 192"
|
||||||
|
FrameTitleButton.DisabledBgColor "Blank"
|
||||||
|
FrameSystemButton.FgColor "Blank"
|
||||||
|
FrameSystemButton.BgColor "Blank"
|
||||||
|
FrameSystemButton.Icon ""
|
||||||
|
FrameSystemButton.DisabledIcon ""
|
||||||
|
FrameTitleBar.Font "UiBold" [$WIN32]
|
||||||
|
FrameTitleBar.Font "DefaultLarge" [$WIN32]
|
||||||
|
FrameTitleBar.TextColor "White"
|
||||||
|
FrameTitleBar.BgColor "Blank"
|
||||||
|
FrameTitleBar.DisabledTextColor "255 255 255 192"
|
||||||
|
FrameTitleBar.DisabledBgColor "Blank"
|
||||||
|
|
||||||
|
GraphPanel.FgColor "White"
|
||||||
|
GraphPanel.BgColor "TransparentBlack"
|
||||||
|
|
||||||
|
Label.TextDullColor "DullWhite"
|
||||||
|
Label.TextColor "OffWhite"
|
||||||
|
Label.TextBrightColor "White"
|
||||||
|
Label.SelectedTextColor "White"
|
||||||
|
Label.BgColor "TransparentBlack"
|
||||||
|
Label.DisabledFgColor1 "117 117 117 255"
|
||||||
|
Label.DisabledFgColor2 "30 30 30 255"
|
||||||
|
|
||||||
|
ListPanel.TextColor "OffWhite"
|
||||||
|
ListPanel.TextBgColor "Blank"
|
||||||
|
ListPanel.BgColor "TransparentBlack"
|
||||||
|
ListPanel.SelectedTextColor "Black"
|
||||||
|
ListPanel.SelectedBgColor "Orange"
|
||||||
|
ListPanel.SelectedOutOfFocusBgColor "255 155 0 128"
|
||||||
|
ListPanel.EmptyListInfoTextColor "OffWhite"
|
||||||
|
|
||||||
|
Menu.TextColor "White"
|
||||||
|
Menu.BgColor "160 160 160 64"
|
||||||
|
Menu.ArmedTextColor "Black"
|
||||||
|
Menu.ArmedBgColor "Orange"
|
||||||
|
Menu.TextInset "6"
|
||||||
|
|
||||||
|
Panel.FgColor "Blank"
|
||||||
|
Panel.BgColor "DullWhite"
|
||||||
|
|
||||||
|
ProgressBar.FgColor "White"
|
||||||
|
ProgressBar.BgColor "TransparentBlack"
|
||||||
|
|
||||||
|
PropertySheet.TextColor "OffWhite"
|
||||||
|
PropertySheet.SelectedTextColor "White"
|
||||||
|
PropertySheet.TransitionEffectTime "0.25" // time to change from one tab to another
|
||||||
|
|
||||||
|
RadioButton.TextColor "DullWhite"
|
||||||
|
RadioButton.SelectedTextColor "White"
|
||||||
|
|
||||||
|
RichText.TextColor "OffWhite"
|
||||||
|
RichText.BgColor "TransparentBlack"
|
||||||
|
RichText.SelectedTextColor "Black"
|
||||||
|
RichText.SelectedBgColor "Orange"
|
||||||
|
|
||||||
|
ScrollBar.Wide 11
|
||||||
|
|
||||||
|
ScrollBarButton.FgColor "White"
|
||||||
|
ScrollBarButton.BgColor "Blank"
|
||||||
|
ScrollBarButton.ArmedFgColor "White"
|
||||||
|
ScrollBarButton.ArmedBgColor "Blank"
|
||||||
|
ScrollBarButton.DepressedFgColor "White"
|
||||||
|
ScrollBarButton.DepressedBgColor "Blank"
|
||||||
|
|
||||||
|
ScrollBarSlider.FgColor "Blank" // nob color
|
||||||
|
ScrollBarSlider.BgColor "0 0 0 0" // slider background color 255 255 255 64
|
||||||
|
|
||||||
|
SectionedListPanel.HeaderTextColor "White"
|
||||||
|
SectionedListPanel.HeaderBgColor "Blank"
|
||||||
|
SectionedListPanel.DividerColor "Black"
|
||||||
|
SectionedListPanel.TextColor "DullWhite"
|
||||||
|
SectionedListPanel.BrightTextColor "White"
|
||||||
|
SectionedListPanel.BgColor "TransparentBlack"
|
||||||
|
SectionedListPanel.SelectedTextColor "Black"
|
||||||
|
SectionedListPanel.SelectedBgColor "Orange"
|
||||||
|
SectionedListPanel.OutOfFocusSelectedTextColor "Black"
|
||||||
|
SectionedListPanel.OutOfFocusSelectedBgColor "255 155 0 128"
|
||||||
|
|
||||||
|
TextEntry.TextColor "OffWhite"
|
||||||
|
TextEntry.BgColor "TransparentBlack"
|
||||||
|
TextEntry.CursorColor "OffWhite"
|
||||||
|
TextEntry.DisabledTextColor "DullWhite"
|
||||||
|
TextEntry.DisabledBgColor "Blank"
|
||||||
|
TextEntry.SelectedTextColor "Black"
|
||||||
|
TextEntry.SelectedBgColor "Orange"
|
||||||
|
TextEntry.OutOfFocusSelectedBgColor "255 155 0 128"
|
||||||
|
TextEntry.FocusEdgeColor "0 0 0 196"
|
||||||
|
|
||||||
|
ToggleButton.SelectedTextColor "White"
|
||||||
|
|
||||||
|
Tooltip.TextColor "0 0 0 196"
|
||||||
|
Tooltip.BgColor "Orange"
|
||||||
|
|
||||||
|
TreeView.BgColor "TransparentBlack"
|
||||||
|
|
||||||
|
WizardSubPanel.BgColor "Blank"
|
||||||
|
|
||||||
|
// scheme-specific colors
|
||||||
|
MainMenu.TextColor "White" [$WIN32]
|
||||||
|
MainMenu.TextColor "200 200 200 255" [$X360]
|
||||||
|
MainMenu.ArmedTextColor "200 200 200 255" [$WIN32]
|
||||||
|
MainMenu.ArmedTextColor "White" [$X360]
|
||||||
|
MainMenu.DepressedTextColor "192 186 80 255"
|
||||||
|
MainMenu.MenuItemHeight "16" [$WIN32]
|
||||||
|
MainMenu.MenuItemHeight "32" [$X360]
|
||||||
|
MainMenu.Inset "32"
|
||||||
|
MainMenu.Backdrop "0 0 0 156"
|
||||||
|
|
||||||
|
Console.TextColor "OffWhite"
|
||||||
|
Console.DevTextColor "White"
|
||||||
|
|
||||||
|
NewGame.TextColor "White"
|
||||||
|
NewGame.FillColor "0 0 0 255"
|
||||||
|
NewGame.SelectionColor "Orange" [$WIN32]
|
||||||
|
NewGame.SelectionColor "0 0 0 255" [$X360]
|
||||||
|
NewGame.DisabledColor "128 128 128 196"
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////// BITMAP FONT FILES /////////////////////////////
|
||||||
|
//
|
||||||
|
// Bitmap Fonts are ****VERY*** expensive static memory resources so they are purposely sparse
|
||||||
|
BitmapFontFiles
|
||||||
|
{
|
||||||
|
// UI buttons, custom font, (256x64)
|
||||||
|
//"Buttons" "materials/vgui/fonts/buttons_32.vbf"
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////// FONTS /////////////////////////////
|
||||||
|
//
|
||||||
|
// describes all the fonts
|
||||||
|
Fonts
|
||||||
|
{
|
||||||
|
|
||||||
|
"Default"
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"name" "Tahoma"
|
||||||
|
"tall" "12"
|
||||||
|
"weight" "0"
|
||||||
|
"range" "0x0000 0x017F"
|
||||||
|
"yres" "480 599"
|
||||||
|
}
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"name" "Tahoma"
|
||||||
|
"tall" "13"
|
||||||
|
"weight" "0"
|
||||||
|
"range" "0x0000 0x017F"
|
||||||
|
"yres" "600 767"
|
||||||
|
}
|
||||||
|
"3"
|
||||||
|
{
|
||||||
|
"name" "Tahoma"
|
||||||
|
"tall" "14"
|
||||||
|
"weight" "0"
|
||||||
|
"range" "0x0000 0x017F"
|
||||||
|
"yres" "768 1023"
|
||||||
|
"antialias" "1"
|
||||||
|
}
|
||||||
|
"4"
|
||||||
|
{
|
||||||
|
"name" "Tahoma"
|
||||||
|
"tall" "16"
|
||||||
|
"weight" "0"
|
||||||
|
"range" "0x0000 0x017F"
|
||||||
|
"yres" "1024 1280"
|
||||||
|
"antialias" "1"
|
||||||
|
}
|
||||||
|
"5"
|
||||||
|
{
|
||||||
|
"name" "Tahoma"
|
||||||
|
"tall" "20"
|
||||||
|
"weight" "0"
|
||||||
|
"range" "0x0000 0x017F"
|
||||||
|
"yres" "1200 6000"
|
||||||
|
"antialias" "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is the symbol font
|
||||||
|
"Marlett"
|
||||||
|
{
|
||||||
|
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"name" "Marlett"
|
||||||
|
"tall" "10"
|
||||||
|
"weight" "0"
|
||||||
|
"yres" "480 599"
|
||||||
|
"symbol" "1"
|
||||||
|
}
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"name" "Marlett"
|
||||||
|
"tall" "14"
|
||||||
|
"weight" "0"
|
||||||
|
"yres" "600 767"
|
||||||
|
"symbol" "1"
|
||||||
|
}
|
||||||
|
"3"
|
||||||
|
{
|
||||||
|
"name" "Marlett"
|
||||||
|
"tall" "13"
|
||||||
|
"weight" "0"
|
||||||
|
"yres" "768 1023"
|
||||||
|
"symbol" "1"
|
||||||
|
}
|
||||||
|
"4"
|
||||||
|
{
|
||||||
|
"name" "Marlett"
|
||||||
|
"tall" "17"
|
||||||
|
"weight" "0"
|
||||||
|
"yres" "1024 1199"
|
||||||
|
"symbol" "1"
|
||||||
|
}
|
||||||
|
"5"
|
||||||
|
{
|
||||||
|
"name" "Marlett"
|
||||||
|
"tall" "22"
|
||||||
|
"weight" "0"
|
||||||
|
"yres" "1200 10000"
|
||||||
|
"symbol" "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
"ChatFont"
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"name" "Tahoma"
|
||||||
|
"tall" "13"
|
||||||
|
"weight" "1000"
|
||||||
|
"yres" "480 599"
|
||||||
|
"outline" "1"
|
||||||
|
}
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"name" "Tahoma"
|
||||||
|
"tall" "13"
|
||||||
|
"weight" "1000"
|
||||||
|
"yres" "600 767"
|
||||||
|
"outline" "1"
|
||||||
|
}
|
||||||
|
"3"
|
||||||
|
{
|
||||||
|
"name" "Tahoma"
|
||||||
|
"tall" "13"
|
||||||
|
"weight" "1000"
|
||||||
|
"yres" "768 1023"
|
||||||
|
"outline" "1"
|
||||||
|
}
|
||||||
|
"4"
|
||||||
|
{
|
||||||
|
"name" "Tahoma"
|
||||||
|
"tall" "13"
|
||||||
|
"weight" "1000"
|
||||||
|
"yres" "1024 1199"
|
||||||
|
"outline" "1"
|
||||||
|
}
|
||||||
|
"5"
|
||||||
|
{
|
||||||
|
"name" "Tahoma"
|
||||||
|
"tall" "13"
|
||||||
|
"weight" "1000"
|
||||||
|
"yres" "1200 10000"
|
||||||
|
"outline" "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//////////////////// BORDERS //////////////////////////////
|
||||||
|
//
|
||||||
|
// describes all the border types
|
||||||
|
Borders
|
||||||
|
{
|
||||||
|
BaseBorder DepressedBorder
|
||||||
|
ButtonBorder RaisedBorder
|
||||||
|
ComboBoxBorder DepressedBorder
|
||||||
|
MenuBorder RaisedBorder
|
||||||
|
BrowserBorder DepressedBorder
|
||||||
|
PropertySheetBorder RaisedBorder
|
||||||
|
|
||||||
|
FrameBorder
|
||||||
|
{
|
||||||
|
// rounded corners for frames
|
||||||
|
"backgroundtype" "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
DepressedBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RaisedBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TitleButtonBorder
|
||||||
|
{
|
||||||
|
"backgroundtype" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
TitleButtonDisabledBorder
|
||||||
|
{
|
||||||
|
"backgroundtype" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
TitleButtonDepressedBorder
|
||||||
|
{
|
||||||
|
"backgroundtype" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollBarButtonBorder
|
||||||
|
{
|
||||||
|
"inset" "2 2 0 0"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollBarButtonDepressedBorder
|
||||||
|
{
|
||||||
|
"inset" "2 2 0 0"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TabBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TabActiveBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 0"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ToolTipBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 0"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is the border used for default buttons (the button that gets pressed when you hit enter)
|
||||||
|
ButtonKeyFocusBorder
|
||||||
|
{
|
||||||
|
"inset" "0 0 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Selection"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Selection"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Selection"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Selection"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonDepressedBorder
|
||||||
|
{
|
||||||
|
"inset" "2 1 1 1"
|
||||||
|
Left
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Right
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "1 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Top
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Dark"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bottom
|
||||||
|
{
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"color" "Border.Bright"
|
||||||
|
"offset" "0 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////// CUSTOM FONT FILES /////////////////////////////
|
||||||
|
//
|
||||||
|
// specifies all the custom (non-system) font files that need to be loaded to service the above described fonts
|
||||||
|
CustomFontFiles
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,64 @@
|
|||||||
|
// ______________________
|
||||||
|
//___________.( h0lmGUI™v4.1 by h0lm ).___________
|
||||||
|
//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
"Resource/UI/BuyMenu.res"
|
||||||
|
{
|
||||||
|
"buy"
|
||||||
|
{
|
||||||
|
"ControlName" "CBuyMenu"
|
||||||
|
"fieldName" "buy"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"setTitleBarVisible" "0"
|
||||||
|
}
|
||||||
|
"BuySubMenu"
|
||||||
|
{
|
||||||
|
"ControlName" "WizardSubPanel"
|
||||||
|
"fieldName" "BuySubMenu"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
"autoResize" "3"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
}
|
||||||
|
"LinePanel2"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "LinePanel2"
|
||||||
|
"xpos" "25"
|
||||||
|
"ypos" "20"
|
||||||
|
"zpos" "0"
|
||||||
|
"wide" "590"
|
||||||
|
"tall" "53"
|
||||||
|
"visible" "1"
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
"fillcolor" "0 0 0 196"
|
||||||
|
}
|
||||||
|
"LinePanel"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "LinePanel"
|
||||||
|
"xpos" "25"
|
||||||
|
"ypos" "78"
|
||||||
|
"zpos" "0"
|
||||||
|
"wide" "590"
|
||||||
|
"tall" "352"
|
||||||
|
"visible" "1"
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
"fillcolor" "0 0 0 196"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//________________________________________________
|
||||||
|
//¯¯¯¯¯¯¯¯¯¯¯'( h0lmGUI™v4.1 by h0lm )'¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
@@ -0,0 +1,284 @@
|
|||||||
|
// ______________________
|
||||||
|
//___________.( h0lmGUI™v4.1 by h0lm ).___________
|
||||||
|
//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
"Resource/UI/ClassMenu_CT.res"
|
||||||
|
{
|
||||||
|
"class_ct"
|
||||||
|
{
|
||||||
|
"ControlName" "Frame"
|
||||||
|
"fieldName" "class_ct"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
"SysMenu"
|
||||||
|
{
|
||||||
|
"ControlName" "Menu"
|
||||||
|
"fieldName" "SysMenu"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "64"
|
||||||
|
"tall" "24"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "0"
|
||||||
|
"tabPosition" "0"
|
||||||
|
}
|
||||||
|
"Backgroundz"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "Backgroundz"
|
||||||
|
"xpos" "115"
|
||||||
|
"ypos" "c-134"
|
||||||
|
"zpos" "0"
|
||||||
|
"wide" "411"
|
||||||
|
"tall" "40"
|
||||||
|
"visible" "1"
|
||||||
|
"fillcolor" "0 0 0 196"
|
||||||
|
}
|
||||||
|
|
||||||
|
"Backgroundx"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "Backgroundx"
|
||||||
|
"xpos" "115"
|
||||||
|
"ypos" "c-91"
|
||||||
|
"zpos" "0"
|
||||||
|
"wide" "411"
|
||||||
|
"tall" "227"
|
||||||
|
"visible" "1"
|
||||||
|
"fillcolor" "0 0 0 196"
|
||||||
|
}
|
||||||
|
|
||||||
|
"HeadlineZ"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "HeadlineZ"
|
||||||
|
"xpos" "127"
|
||||||
|
"ypos" "c-124"
|
||||||
|
"wide" "200"
|
||||||
|
"tall" "20"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "PICK A WARRIOR"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"font" "TeamMenuHeadLine"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
//"bgcolor_override" "200 200 200 100"
|
||||||
|
}
|
||||||
|
|
||||||
|
"LOLmlogo"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "LOLmlogo"
|
||||||
|
"xpos" "428"
|
||||||
|
"ypos" "c-124"
|
||||||
|
"wide" "200"
|
||||||
|
"tall" "20"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "COUN"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"font" "MenuLogogo"
|
||||||
|
"fgcolor_override" "255 255 255 20"
|
||||||
|
}
|
||||||
|
"joinClass"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "joinClass"
|
||||||
|
"xpos" "76"
|
||||||
|
"ypos" "22"
|
||||||
|
"wide" "450"
|
||||||
|
"tall" "48"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_Join_Class"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"font" "MenuTitle"
|
||||||
|
"fgcolor_override" "255 255 255 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
"classInfoLabel"
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
"ClassInfo"
|
||||||
|
{
|
||||||
|
"ControlName" "Panel"
|
||||||
|
"fieldName" "ClassInfo"
|
||||||
|
"xpos" "290" //"244"
|
||||||
|
"ypos" "164"
|
||||||
|
"wide" "0" //"400"
|
||||||
|
"tall" "0" //"380"
|
||||||
|
"autoResize" "2" //"3"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "0"
|
||||||
|
"tabPosition" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
"urban"
|
||||||
|
{
|
||||||
|
"ControlName" "MouseOverPanelButton"
|
||||||
|
"fieldName" "urban"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "162"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "#Cstrike_Urban"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "joinclass 5"
|
||||||
|
}
|
||||||
|
|
||||||
|
"gsg9"
|
||||||
|
{
|
||||||
|
"ControlName" "MouseOverPanelButton"
|
||||||
|
"fieldName" "gsg9"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "192"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "#Cstrike_GSG9"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "joinclass 6"
|
||||||
|
}
|
||||||
|
|
||||||
|
"sas"
|
||||||
|
{
|
||||||
|
"ControlName" "MouseOverPanelButton"
|
||||||
|
"fieldName" "sas"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "222"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "#Cstrike_SAS"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "joinclass 7"
|
||||||
|
}
|
||||||
|
|
||||||
|
"gign"
|
||||||
|
{
|
||||||
|
"ControlName" "MouseOverPanelButton"
|
||||||
|
"fieldName" "gign"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "252"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "#Cstrike_GIGN"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "joinclass 8"
|
||||||
|
}
|
||||||
|
|
||||||
|
"autoselect_ct"
|
||||||
|
{
|
||||||
|
"ControlName" "MouseOverPanelButton"
|
||||||
|
"fieldName" "autoselect_ct"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "312"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "#Cstrike_Auto_Select"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "joinclass 0"
|
||||||
|
"Default" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
"deadspec"
|
||||||
|
{
|
||||||
|
"ControlName" "MouseOverPanelButton"
|
||||||
|
"fieldName" "deadspec"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "282"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "&5 DEAD SPECTATE"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "vguicancel"
|
||||||
|
"Default" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CancelButton"
|
||||||
|
{
|
||||||
|
"ControlName" "Button"
|
||||||
|
"fieldName" "CancelButton"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "342"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "#Cstrike_Cancel"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"Command" "vguicancel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//________________________________________________
|
||||||
|
//¯¯¯¯¯¯¯¯¯¯¯'( h0lmGUI™v4.1 by h0lm )'¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
@@ -0,0 +1,283 @@
|
|||||||
|
// ______________________
|
||||||
|
//___________.( h0lmGUI™v4.1 by h0lm ).___________
|
||||||
|
//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
"Resource/UI/ClassMenu_TER.res"
|
||||||
|
{
|
||||||
|
"class_ter"
|
||||||
|
{
|
||||||
|
"ControlName" "Frame"
|
||||||
|
"fieldName" "class_ter"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
"SysMenu"
|
||||||
|
{
|
||||||
|
"ControlName" "Menu"
|
||||||
|
"fieldName" "SysMenu"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "64"
|
||||||
|
"tall" "24"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "0"
|
||||||
|
"tabPosition" "0"
|
||||||
|
}
|
||||||
|
"Backgroundz"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "Backgroundz"
|
||||||
|
"xpos" "115"
|
||||||
|
"ypos" "c-134"
|
||||||
|
"zpos" "0"
|
||||||
|
"wide" "411"
|
||||||
|
"tall" "40"
|
||||||
|
"visible" "1"
|
||||||
|
"fillcolor" "0 0 0 196"
|
||||||
|
}
|
||||||
|
|
||||||
|
"Backgroundx"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "Backgroundx"
|
||||||
|
"xpos" "115"
|
||||||
|
"ypos" "c-91"
|
||||||
|
"zpos" "0"
|
||||||
|
"wide" "411"
|
||||||
|
"tall" "227"
|
||||||
|
"visible" "1"
|
||||||
|
"fillcolor" "0 0 0 196"
|
||||||
|
}
|
||||||
|
|
||||||
|
"HeadlineZ"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "HeadlineZ"
|
||||||
|
"xpos" "127"
|
||||||
|
"ypos" "c-124"
|
||||||
|
"wide" "200"
|
||||||
|
"tall" "20"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "PICK A WARRIOR"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"font" "TeamMenuHeadLine"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
//"bgcolor_override" "200 200 200 100"
|
||||||
|
}
|
||||||
|
|
||||||
|
"LOLmlogo"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "LOLmlogo"
|
||||||
|
"xpos" "428"
|
||||||
|
"ypos" "c-124"
|
||||||
|
"wide" "200"
|
||||||
|
"tall" "20"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "COUN"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"font" "MenuLogogo"
|
||||||
|
"fgcolor_override" "255 255 255 20"
|
||||||
|
}
|
||||||
|
"joinClass"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "joinClass"
|
||||||
|
"xpos" "76"
|
||||||
|
"ypos" "22"
|
||||||
|
"wide" "450"
|
||||||
|
"tall" "48"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_Join_Class"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"font" "MenuTitle"
|
||||||
|
"fgcolor_override" "255 255 255 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
"classInfoLabel"
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
"ClassInfo"
|
||||||
|
{
|
||||||
|
"ControlName" "Panel"
|
||||||
|
"fieldName" "ClassInfo"
|
||||||
|
"xpos" "290" //"244"
|
||||||
|
"ypos" "164"
|
||||||
|
"wide" "0" //"400"
|
||||||
|
"tall" "0" //"380"
|
||||||
|
"autoResize" "2" //"3"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "0"
|
||||||
|
"tabPosition" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
"terror"
|
||||||
|
{
|
||||||
|
"ControlName" "MouseOverPanelButton"
|
||||||
|
"fieldName" "terror"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "162"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "#Cstrike_Terror"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "joinclass 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
"leet"
|
||||||
|
{
|
||||||
|
"ControlName" "MouseOverPanelButton"
|
||||||
|
"fieldName" "leet"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "192"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "#Cstrike_L337_Krew"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "joinclass 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
"arctic"
|
||||||
|
{
|
||||||
|
"ControlName" "MouseOverPanelButton"
|
||||||
|
"fieldName" "arctic"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "222"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "#Cstrike_Arctic"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "joinclass 3"
|
||||||
|
}
|
||||||
|
|
||||||
|
"guerilla"
|
||||||
|
{
|
||||||
|
"ControlName" "MouseOverPanelButton"
|
||||||
|
"fieldName" "guerilla"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "252"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "#Cstrike_Guerilla"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "joinclass 4"
|
||||||
|
}
|
||||||
|
|
||||||
|
"autoselect_t"
|
||||||
|
{
|
||||||
|
"ControlName" "MouseOverPanelButton"
|
||||||
|
"fieldName" "autoselect_t"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "312"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "#Cstrike_Auto_Select"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "joinclass 0"
|
||||||
|
"Default" "1"
|
||||||
|
}
|
||||||
|
"deadspec"
|
||||||
|
{
|
||||||
|
"ControlName" "MouseOverPanelButton"
|
||||||
|
"fieldName" "deadspec"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "282"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "&5 DEAD SPECTATE"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "vguicancel"
|
||||||
|
"Default" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CancelButton"
|
||||||
|
{
|
||||||
|
"ControlName" "Button"
|
||||||
|
"fieldName" "CancelButton"
|
||||||
|
"xpos" "132"
|
||||||
|
"ypos" "342"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "#Cstrike_Cancel"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"Command" "vguicancel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//________________________________________________
|
||||||
|
//¯¯¯¯¯¯¯¯¯¯¯'( h0lmGUI™v4.1 by h0lm )'¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
@@ -0,0 +1,935 @@
|
|||||||
|
"Resource/UI/ScoreBoard.res"
|
||||||
|
{
|
||||||
|
"scores"
|
||||||
|
{
|
||||||
|
"ControlName" "CCSClientScoreBoardDialog"
|
||||||
|
"fieldName" "scores"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"zpos" "90"
|
||||||
|
"wide" "f0"
|
||||||
|
"tall" "480"
|
||||||
|
"settitlebarvisible" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
"ScoreboardBackground"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "ScoreboardBackground"
|
||||||
|
"xpos" "c-295"
|
||||||
|
"ypos" "c-158"
|
||||||
|
"wide" "590"
|
||||||
|
"tall" "253"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"PaintBackgroundType" "0"
|
||||||
|
"fillcolor" "0 0 0 200"
|
||||||
|
}
|
||||||
|
"Spec_Label"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "Spec_Label"
|
||||||
|
"xpos" "c-288"
|
||||||
|
"ypos" "c+59"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "140"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "Broadcast"
|
||||||
|
"textAlignment" "south-west"
|
||||||
|
"font" "ScoreboardTeamName"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
}
|
||||||
|
"HeadLine"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "HeadLine"
|
||||||
|
"xpos" "c-290"
|
||||||
|
"ypos" "c-144"
|
||||||
|
"wide" "580"
|
||||||
|
"tall" "1"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"PaintBackgroundType" "0"
|
||||||
|
"fillcolor" "255 255 255 255"
|
||||||
|
}
|
||||||
|
"SpecLine"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "HeadLine"
|
||||||
|
"xpos" "c-290"
|
||||||
|
"ypos" "c+75"
|
||||||
|
"wide" "580"
|
||||||
|
"tall" "1"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"PaintBackgroundType" "0"
|
||||||
|
"fillcolor" "255 255 255 255"
|
||||||
|
}
|
||||||
|
"CTLine"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "CTLine"
|
||||||
|
"xpos" "c-290"
|
||||||
|
"ypos" "c-125"
|
||||||
|
"wide" "290"
|
||||||
|
"tall" "1"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"PaintBackgroundType" "0"
|
||||||
|
"fillcolor" "128 206 255 255"
|
||||||
|
}
|
||||||
|
"TLine"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "TLine"
|
||||||
|
"xpos" "c+0"
|
||||||
|
"ypos" "c-125"
|
||||||
|
"wide" "290"
|
||||||
|
"tall" "1"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"PaintBackgroundType" "0"
|
||||||
|
"fillcolor" "255 26 28 255"
|
||||||
|
}
|
||||||
|
"CTScoreBox"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "CTScoreBox"
|
||||||
|
"xpos" "c-60"
|
||||||
|
"ypos" "c-137"
|
||||||
|
"wide" "25"
|
||||||
|
"tall" "12"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"PaintBackgroundType" "0"
|
||||||
|
"fillcolor" "128 206 255 255"
|
||||||
|
}
|
||||||
|
"TScoreBox"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "TScoreBox"
|
||||||
|
"xpos" "c+35"
|
||||||
|
"ypos" "c-137"
|
||||||
|
"wide" "25"
|
||||||
|
"tall" "12"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"PaintBackgroundType" "0"
|
||||||
|
"fillcolor" "255 26 28 255"
|
||||||
|
}
|
||||||
|
"CTPlayerBox1"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "PlayerBox1"
|
||||||
|
"xpos" "c-290"
|
||||||
|
"ypos" "c-105"
|
||||||
|
"wide" "287"
|
||||||
|
"tall" "163"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"PaintBackgroundType" "0"
|
||||||
|
"fillcolor" "0 0 0 40"
|
||||||
|
}
|
||||||
|
"TPlayerBox1"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "PlayerBox1"
|
||||||
|
"xpos" "c+4"
|
||||||
|
"ypos" "c-105"
|
||||||
|
"wide" "287"
|
||||||
|
"tall" "163"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"PaintBackgroundType" "0"
|
||||||
|
"fillcolor" "0 0 0 40"
|
||||||
|
}
|
||||||
|
"ServerNameLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "ServerNameLabel"
|
||||||
|
"xpos" "c-288"
|
||||||
|
"ypos" "c-157"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "100"
|
||||||
|
"tall" "15"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" ""
|
||||||
|
"auto_wide_tocontents" "1"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "1"
|
||||||
|
"font" "ScoreboardHeader"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"DividerLabel1"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "DividerLabel1"
|
||||||
|
"xpos" "10"
|
||||||
|
"ypos" "0"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "5"
|
||||||
|
"tall" "15"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "-"
|
||||||
|
"auto_wide_tocontents" "1"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "1"
|
||||||
|
"font" "ScoreboardHeader"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
"pin_to_sibling" "ServerNameLabel"
|
||||||
|
"pin_corner_to_sibling" "2"
|
||||||
|
"pin_to_sibling_corner" "3"
|
||||||
|
}
|
||||||
|
"MapName"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "MapName"
|
||||||
|
"xpos" "10"
|
||||||
|
"ypos" "0"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "30"
|
||||||
|
"tall" "15"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "%mapname%"
|
||||||
|
"auto_wide_tocontents" "1"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "1"
|
||||||
|
"font" "ScoreboardHeader"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
"pin_to_sibling" "DividerLabel1"
|
||||||
|
"pin_corner_to_sibling" "2"
|
||||||
|
"pin_to_sibling_corner" "3"
|
||||||
|
}
|
||||||
|
"DividerLabel2"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "DividerLabel2"
|
||||||
|
"xpos" "1"
|
||||||
|
"ypos" "0"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "5"
|
||||||
|
"tall" "15"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "/"
|
||||||
|
"auto_wide_tocontents" "1"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "1"
|
||||||
|
"font" "ScoreboardHeader"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
"pin_to_sibling" "MapName"
|
||||||
|
"pin_corner_to_sibling" "2"
|
||||||
|
"pin_to_sibling_corner" "3"
|
||||||
|
}
|
||||||
|
|
||||||
|
"StatsStatus"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "StatsStatus"
|
||||||
|
"xpos" "1"
|
||||||
|
"ypos" "0"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "65"
|
||||||
|
"tall" "15"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "%statsstatus%"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "1"
|
||||||
|
"font" "ScoreboardHeader"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
"pin_to_sibling" "DividerLabel2"
|
||||||
|
"pin_corner_to_sibling" "2"
|
||||||
|
"pin_to_sibling_corner" "3"
|
||||||
|
}
|
||||||
|
|
||||||
|
"PositionLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "PositionLabel"
|
||||||
|
"xpos" "c+287"
|
||||||
|
"ypos" "c-157"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "1"
|
||||||
|
"tall" "15"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" ""
|
||||||
|
"auto_wide_tocontents" "1"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "1"
|
||||||
|
"font" "ScoreboardHeader"
|
||||||
|
"fgcolor_override" "0 0 0 0"
|
||||||
|
}
|
||||||
|
"WinConditionLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "WinConditionLabel"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "80"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" ""
|
||||||
|
"auto_wide_tocontents" "1"
|
||||||
|
"textAlignment" "east"
|
||||||
|
"font" "ScoreboardHeader"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
"pin_to_sibling" "PositionLabel"
|
||||||
|
"pin_corner_to_sibling" "3"
|
||||||
|
"pin_to_sibling_corner" "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
"CT_Label"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "CT_Label"
|
||||||
|
"xpos" "c-288"
|
||||||
|
"ypos" "c-138"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "140"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "Counter-Terrorists" //"%ct_teamname%"
|
||||||
|
"auto_wide_tocontents" "1"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"font" "ScoreboardTeamName"
|
||||||
|
"fgcolor_override" "128 206 255 255"
|
||||||
|
}
|
||||||
|
"CTSeperator"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "CTSeperator"
|
||||||
|
"xpos" "10"
|
||||||
|
"ypos" "0"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "5"
|
||||||
|
"tall" "15"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "-"
|
||||||
|
"auto_wide_tocontents" "1"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"font" "ScoreboardPlayersAlive"
|
||||||
|
"fgcolor_override" "128 206 255 255"
|
||||||
|
"pin_to_sibling" "CT_Label"
|
||||||
|
"pin_corner_to_sibling" "2"
|
||||||
|
"pin_to_sibling_corner" "3"
|
||||||
|
}
|
||||||
|
"CTPlayersAlive"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "CTPlayersAlive"
|
||||||
|
"xpos" "10"
|
||||||
|
"ypos" "0"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "45"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "%ct_alivecount%"
|
||||||
|
"auto_wide_tocontents" "1"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"font" "ScoreboardPlayersAlive"
|
||||||
|
"fgcolor_override" "128 206 255 255"
|
||||||
|
"pin_to_sibling" "CTSeperator"
|
||||||
|
"pin_corner_to_sibling" "2"
|
||||||
|
"pin_to_sibling_corner" "3"
|
||||||
|
}
|
||||||
|
"CTPlayersAliveSuffix"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"xpos" "4"
|
||||||
|
"ypos" "0"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "80"
|
||||||
|
"tall" "15"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_Scoreboard_PlayersAlive"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"font" "ScoreboardPlayersAliveSuffix"
|
||||||
|
"fgcolor_override" "128 206 255 255"
|
||||||
|
"pin_to_sibling" "CTPlayersAlive"
|
||||||
|
"pin_corner_to_sibling" "2"
|
||||||
|
"pin_to_sibling_corner" "3"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTTeamScore"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "CTTeamScore"
|
||||||
|
"xpos" "c-97"
|
||||||
|
"ypos" "c-138"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "100"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "%ct_totalteamscore%"
|
||||||
|
"textAlignment" "center"
|
||||||
|
"font" "ScoreboardScore"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"T_Label"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "T_Label"
|
||||||
|
"xpos" "c+256"
|
||||||
|
"ypos" "c-138"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "140"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "Terrorists" //"%t_teamname%"
|
||||||
|
"auto_wide_tocontents" "1"
|
||||||
|
"textAlignment" "east"
|
||||||
|
"font" "ScoreboardTeamName"
|
||||||
|
"fgcolor_override" "255 26 28 255"
|
||||||
|
}
|
||||||
|
"TSeperator"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "TSeperator"
|
||||||
|
"xpos" "10"
|
||||||
|
"ypos" "0"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "5"
|
||||||
|
"tall" "15"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "-"
|
||||||
|
"auto_wide_tocontents" "1"
|
||||||
|
"textAlignment" "east"
|
||||||
|
"font" "ScoreboardPlayersAlive"
|
||||||
|
"fgcolor_override" "255 26 28 255"
|
||||||
|
"pin_to_sibling" "T_Label"
|
||||||
|
"pin_corner_to_sibling" "3"
|
||||||
|
"pin_to_sibling_corner" "2"
|
||||||
|
}
|
||||||
|
"TPlayersAlive"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "TPlayersAlive"
|
||||||
|
"xpos" "10"
|
||||||
|
"ypos" "0"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "45"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "%t_alivecount%"
|
||||||
|
"auto_wide_tocontents" "1"
|
||||||
|
"textAlignment" "east"
|
||||||
|
"font" "ScoreboardPlayersAlive"
|
||||||
|
"fgcolor_override" "255 26 28 255"
|
||||||
|
"pin_to_sibling" "TSeperator"
|
||||||
|
"pin_corner_to_sibling" "3"
|
||||||
|
"pin_to_sibling_corner" "2"
|
||||||
|
}
|
||||||
|
"TPlayersAliveSuffix"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"xpos" "4"
|
||||||
|
"ypos" "0"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "80"
|
||||||
|
"tall" "15"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_Scoreboard_PlayersAlive"
|
||||||
|
"textAlignment" "east"
|
||||||
|
"font" "ScoreboardPlayersAliveSuffix"
|
||||||
|
"fgcolor_override" "255 26 28 255"
|
||||||
|
"pin_to_sibling" "TPlayersAlive"
|
||||||
|
"pin_corner_to_sibling" "3"
|
||||||
|
"pin_to_sibling_corner" "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
"TTeamScore"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "TTeamScore"
|
||||||
|
"xpos" "c-3"
|
||||||
|
"ypos" "c-138"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "100"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "%t_totalteamscore%"
|
||||||
|
"textAlignment" "center"
|
||||||
|
"font" "ScoreboardScore"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTClanLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "CTClanLabel"
|
||||||
|
"xpos" "c-275"
|
||||||
|
"ypos" "c-125"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "45"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "Clan"
|
||||||
|
"textAlignment" "center"
|
||||||
|
"font" "ScoreboardColumns"
|
||||||
|
"fgcolor_override" "128 206 255 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTPlayerLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "CTPlayerLabel"
|
||||||
|
"xpos" "c-228"
|
||||||
|
"ypos" "c-125"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "60"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_SB_PlayerName"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"font" "ScoreboardColumns"
|
||||||
|
"fgcolor_override" "128 206 255 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTPlayerScoreLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "CTPlayerScoreLabel"
|
||||||
|
"xpos" "c-93"
|
||||||
|
"ypos" "c-125"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "30"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_SB_Score"
|
||||||
|
"textAlignment" "center"
|
||||||
|
"font" "ScoreboardColumns"
|
||||||
|
"fgcolor_override" "128 206 255 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTPlayerDeathsLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "CTPlayerDeathsLabel"
|
||||||
|
"xpos" "c-68"
|
||||||
|
"ypos" "c-125"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "37"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_SB_Deaths"
|
||||||
|
"textAlignment" "center"
|
||||||
|
"font" "ScoreboardColumns"
|
||||||
|
"fgcolor_override" "128 206 255 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTPlayerLatencyLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "CTPlayerLatencyLabel"
|
||||||
|
"xpos" "c-39"
|
||||||
|
"ypos" "c-125"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "42"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_SB_Latency"
|
||||||
|
"textAlignment" "center"
|
||||||
|
"font" "ScoreboardColumns"
|
||||||
|
"fgcolor_override" "128 206 255 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"TClanLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "TClanLabel"
|
||||||
|
"xpos" "c+20"
|
||||||
|
"ypos" "c-125"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "45"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "Clan"
|
||||||
|
"textAlignment" "center"
|
||||||
|
"font" "ScoreboardColumns"
|
||||||
|
"fgcolor_override" "255 26 28 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"TPlayerLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "TPlayerLabel"
|
||||||
|
"xpos" "c+67"
|
||||||
|
"ypos" "c-125"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "60"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_SB_PlayerName"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"font" "ScoreboardColumns"
|
||||||
|
"fgcolor_override" "255 26 28 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"TPlayerScoreLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "TPlayerScoreLabel"
|
||||||
|
"xpos" "c+200"
|
||||||
|
"ypos" "c-125"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "30"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_SB_Score"
|
||||||
|
"textAlignment" "center"
|
||||||
|
"font" "ScoreboardColumns"
|
||||||
|
"fgcolor_override" "255 26 28 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"TPlayerDeathsLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "TPlayerDeathsLabel"
|
||||||
|
"xpos" "c+225"
|
||||||
|
"ypos" "c-125"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "37"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_SB_Deaths"
|
||||||
|
"textAlignment" "center"
|
||||||
|
"font" "ScoreboardColumns"
|
||||||
|
"fgcolor_override" "255 26 28 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"TPlayerLatencyLabel"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "TPlayerLatencyLabel"
|
||||||
|
"xpos" "c+252"
|
||||||
|
"ypos" "c-125"
|
||||||
|
"zpos" "4"
|
||||||
|
"wide" "42"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_SB_Latency"
|
||||||
|
"textAlignment" "center"
|
||||||
|
"font" "ScoreboardColumns"
|
||||||
|
"fgcolor_override" "255 26 28 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTPlayerArea"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "CTPlayerArea"
|
||||||
|
"xpos" "c-286"
|
||||||
|
"ypos" "c-105"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "283"
|
||||||
|
"tall" "210"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "222 222 222 190"
|
||||||
|
}
|
||||||
|
"TPlayerArea"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "TPlayerArea"
|
||||||
|
"xpos" "c+4"
|
||||||
|
"ypos" "c-105"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "283"
|
||||||
|
"tall" "210"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "0 222 222 190"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTPlayerAvatar0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "CTPlayerAvatar0"
|
||||||
|
"xpos" "c-289"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "10"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "222 0 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTPlayerClan0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "CTPlayerClan0"
|
||||||
|
"xpos" "c-274"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "45"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "0 222 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTPlayerName0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "CTPlayerName0"
|
||||||
|
"xpos" "c-228"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "135"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "0 222 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTPlayerStatus0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "CTPlayerStatus0"
|
||||||
|
"xpos" "c-104"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "10"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "222 0 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTPlayerScore0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "CTPlayerScore0"
|
||||||
|
"xpos" "c-95"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "30"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "0 222 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTPlayerDeaths0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "CTPlayerDeaths0"
|
||||||
|
"xpos" "c-70"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "37"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "222 0 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CTPlayerLatency0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "CTPlayerLatency0"
|
||||||
|
"xpos" "c-38"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "31"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "0 222 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"TPlayerAvatar0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "TPlayerAvatar0"
|
||||||
|
"xpos" "c+5"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "10"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "222 0 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"TPlayerClan0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "TPlayerClan0"
|
||||||
|
"xpos" "c+20"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "45"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "0 222 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"TPlayerName0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "TPlayerName0"
|
||||||
|
"xpos" "c+67"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "135"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "0 222 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"TPlayerStatus0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "TPlayerStatus0"
|
||||||
|
"xpos" "c+191"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "10"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "222 0 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"TPlayerScore0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "TPlayerScore0"
|
||||||
|
"xpos" "c+199"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "30"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "0 222 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"TPlayerDeaths0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "TPlayerDeaths0"
|
||||||
|
"xpos" "c+224"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "37"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "222 0 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"TPlayerLatency0"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "TPlayerLatency0"
|
||||||
|
"xpos" "c+258"
|
||||||
|
"ypos" "c-99"
|
||||||
|
"zpos" "10"
|
||||||
|
"wide" "30"
|
||||||
|
"tall" "10"
|
||||||
|
"visible" "0"
|
||||||
|
"fillcolor" "0 222 0 64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"Spectators"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "Spectators"
|
||||||
|
"labelText" "%spectators%"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"xpos" "c-288"
|
||||||
|
"ypos" "c+77"
|
||||||
|
"zpos" "90"
|
||||||
|
"wide" "485"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"font" "ScoreboardHeader"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
}
|
||||||
|
|
||||||
|
"SourceTV"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "SourceTV"
|
||||||
|
"labelText" "%sourcetv%"
|
||||||
|
"textAlignment" "east"
|
||||||
|
"xpos" "c+208"
|
||||||
|
"ypos" "c+77"
|
||||||
|
"zpos" "90"
|
||||||
|
"wide" "80"
|
||||||
|
"tall" "15"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"font" "ScoreboardHeader"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,308 @@
|
|||||||
|
// ______________________
|
||||||
|
//___________.( h0lmGUI™v4.1 by h0lm ).___________
|
||||||
|
//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
"Resource/UI/TeamMenu.res"
|
||||||
|
{
|
||||||
|
"team"
|
||||||
|
{
|
||||||
|
"ControlName" "CTeamMenu"
|
||||||
|
"fieldName" "team"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
}
|
||||||
|
"SysMenu"
|
||||||
|
{
|
||||||
|
"ControlName" "Menu"
|
||||||
|
"fieldName" "SysMenu"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "64"
|
||||||
|
"tall" "24"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "0"
|
||||||
|
"tabPosition" "0"
|
||||||
|
}
|
||||||
|
"MapInfo"
|
||||||
|
{
|
||||||
|
"ControlName" "RichText"
|
||||||
|
"fieldName" "MapInfo"
|
||||||
|
"xpos" "10000" //"244"
|
||||||
|
"ypos" "10000" //"116"
|
||||||
|
"wide" "10" //"316"
|
||||||
|
"tall" "10" //"286"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "0"
|
||||||
|
"tabPosition" "0"
|
||||||
|
}
|
||||||
|
"joinTeam"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "joinTeam"
|
||||||
|
"xpos" "76"
|
||||||
|
"ypos" "22"
|
||||||
|
"wide" "450"
|
||||||
|
"tall" "48"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "#Cstrike_Join_Team"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"font" "MenuTitle"
|
||||||
|
"fgcolor_override" "255 255 255 0"
|
||||||
|
}
|
||||||
|
"mapname"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "mapname"
|
||||||
|
"xpos" "244"
|
||||||
|
"ypos" "72"
|
||||||
|
"wide" "180"
|
||||||
|
"tall" "24"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" ""
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "1"
|
||||||
|
}
|
||||||
|
"Backgroundz"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "Backgroundz"
|
||||||
|
"xpos" "115"
|
||||||
|
"ypos" "c-134"
|
||||||
|
"zpos" "0"
|
||||||
|
"wide" "411"
|
||||||
|
"tall" "40"
|
||||||
|
"visible" "1"
|
||||||
|
"fillcolor" "0 0 0 196"
|
||||||
|
}
|
||||||
|
|
||||||
|
"Backgroundx"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "Backgroundx"
|
||||||
|
"xpos" "115"
|
||||||
|
"ypos" "c-91"
|
||||||
|
"zpos" "0"
|
||||||
|
"wide" "411"
|
||||||
|
"tall" "227"
|
||||||
|
"visible" "1"
|
||||||
|
"fillcolor" "0 0 0 196"
|
||||||
|
}
|
||||||
|
|
||||||
|
"HeadlineZ"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "HeadlineZ"
|
||||||
|
"xpos" "127"
|
||||||
|
"ypos" "c-124"
|
||||||
|
"wide" "200"
|
||||||
|
"tall" "20"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "PICK A TEAM"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"font" "TeamMenuHeadLine"
|
||||||
|
"fgcolor_override" "255 255 255 255"
|
||||||
|
//"bgcolor_override" "200 200 200 100"
|
||||||
|
}
|
||||||
|
|
||||||
|
"LOLmlogo"
|
||||||
|
{
|
||||||
|
"ControlName" "Label"
|
||||||
|
"fieldName" "LOLmlogo"
|
||||||
|
"xpos" "428"
|
||||||
|
"ypos" "c-124"
|
||||||
|
"wide" "200"
|
||||||
|
"tall" "20"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "0"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"labelText" "COUN"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"font" "MenuLogogo"
|
||||||
|
"fgcolor_override" "255 255 255 20"
|
||||||
|
}
|
||||||
|
"terbuttonbg"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "terbuttonbg"
|
||||||
|
"xpos" "145"
|
||||||
|
"ypos" "c-66"
|
||||||
|
"wide" "160"
|
||||||
|
"tall" "22"
|
||||||
|
"visible" "1"
|
||||||
|
"fillcolor" "102 0 0 128"
|
||||||
|
}
|
||||||
|
"terbutton"
|
||||||
|
{
|
||||||
|
"ControlName" "Button"
|
||||||
|
"fieldName" "terbutton"
|
||||||
|
"xpos" "145"
|
||||||
|
"ypos" "c-66"
|
||||||
|
"wide" "160"
|
||||||
|
"tall" "22"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "3"
|
||||||
|
"labelText" "&1 TERRORIST-FACTION"
|
||||||
|
"textAlignment" "center"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "jointeam 2"
|
||||||
|
"Font" "TeamMenuOption"
|
||||||
|
}
|
||||||
|
"ctbuttonbg"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "ctbuttonbg"
|
||||||
|
"xpos" "336"
|
||||||
|
"ypos" "c-66"
|
||||||
|
"wide" "175"
|
||||||
|
"tall" "22"
|
||||||
|
"visible" "1"
|
||||||
|
"fillcolor" "0 39 102 128"
|
||||||
|
}
|
||||||
|
"ctbutton"
|
||||||
|
{
|
||||||
|
"ControlName" "Button"
|
||||||
|
"fieldName" "ctbutton"
|
||||||
|
"xpos" "336"
|
||||||
|
"ypos" "c-66"
|
||||||
|
"wide" "175"
|
||||||
|
"tall" "22"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "4"
|
||||||
|
"labelText" "&2 COUNTER-TERRORISTS"
|
||||||
|
"textAlignment" "center"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "jointeam 3"
|
||||||
|
"Font" "TeamMenuOption"
|
||||||
|
}
|
||||||
|
"vipbutton"
|
||||||
|
{
|
||||||
|
"ControlName" "Button"
|
||||||
|
"fieldName" "vipbutton"
|
||||||
|
"xpos" "76"
|
||||||
|
"ypos" "180"
|
||||||
|
"wide" "148"
|
||||||
|
"tall" "20"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "5"
|
||||||
|
"labelText" "#Cstrike_VIP"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "jointeam 3"
|
||||||
|
}
|
||||||
|
|
||||||
|
"autobutton"
|
||||||
|
{
|
||||||
|
"ControlName" "Button"
|
||||||
|
"fieldName" "autobutton"
|
||||||
|
"xpos" "228"
|
||||||
|
"ypos" "c-26"
|
||||||
|
"wide" "78"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "1"
|
||||||
|
"labelText" "&5 AUTO-SIGN"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "jointeam 0"
|
||||||
|
"Default" "1"
|
||||||
|
"Font" "TeamMenuOption2"
|
||||||
|
}
|
||||||
|
"specbutton"
|
||||||
|
{
|
||||||
|
"ControlName" "Button"
|
||||||
|
"fieldName" "specbutton"
|
||||||
|
"xpos" "336"
|
||||||
|
"ypos" "c-26"
|
||||||
|
"wide" "71"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "2"
|
||||||
|
"labelText" "&6 SPECTATE"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"command" "jointeam 1"
|
||||||
|
"Font" "TeamMenuOption2"
|
||||||
|
}
|
||||||
|
"LinweBor"
|
||||||
|
{
|
||||||
|
"ControlName" "ImagePanel"
|
||||||
|
"fieldName" "LinweBor"
|
||||||
|
"xpos" "144"
|
||||||
|
"ypos" "c+13"
|
||||||
|
"zpos" "0"
|
||||||
|
"wide" "354"
|
||||||
|
"tall" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"fillcolor" "0 0 0 100"
|
||||||
|
}
|
||||||
|
"CancelButton"
|
||||||
|
{
|
||||||
|
"ControlName" "Button"
|
||||||
|
"fieldName" "CancelButton"
|
||||||
|
"xpos" "447"
|
||||||
|
"ypos" "c+107"
|
||||||
|
"wide" "64"
|
||||||
|
"tall" "18"
|
||||||
|
"autoResize" "0"
|
||||||
|
"pinCorner" "2"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"tabPosition" "0"
|
||||||
|
"labelText" "&0 CANCEL"
|
||||||
|
"textAlignment" "west"
|
||||||
|
"dulltext" "0"
|
||||||
|
"brighttext" "0"
|
||||||
|
"Command" "vguicancel"
|
||||||
|
"Font" "TeamMenuOption2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//________________________________________________
|
||||||
|
//¯¯¯¯¯¯¯¯¯¯¯'( h0lmGUI™v4.1 by h0lm )'¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
@@ -0,0 +1,346 @@
|
|||||||
|
// sample animation script
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// commands:
|
||||||
|
// Animate <panel name> <variable> <target value> <interpolator> <start time> <duration>
|
||||||
|
// variables:
|
||||||
|
// FgColor
|
||||||
|
// BgColor
|
||||||
|
// Position
|
||||||
|
// Size
|
||||||
|
// Blur (hud panels only)
|
||||||
|
// TextColor (hud panels only)
|
||||||
|
// Ammo2Color (hud panels only)
|
||||||
|
// Alpha (hud weapon selection only)
|
||||||
|
// SelectionAlpha (hud weapon selection only)
|
||||||
|
// TextScan (hud weapon selection only)
|
||||||
|
//
|
||||||
|
// interpolator:
|
||||||
|
// Linear
|
||||||
|
// Accel - starts moving slow, ends fast
|
||||||
|
// Deaccel - starts moving fast, ends slow
|
||||||
|
// Spline - simple ease in/out curve
|
||||||
|
// Pulse - < freq > over the duration, the value is pulsed (cosine) freq times ending at the dest value (assuming freq is integral)
|
||||||
|
// Flicker - < randomness factor 0.0 to 1.0 > over duration, each frame if random # is less than factor, use end value, otherwise use prev value
|
||||||
|
//
|
||||||
|
// RunEvent <event name> <start time>
|
||||||
|
// starts another even running at the specified time
|
||||||
|
//
|
||||||
|
// StopEvent <event name> <start time>
|
||||||
|
// stops another event that is current running at the specified time
|
||||||
|
//
|
||||||
|
// StopAnimation <panel name> <variable> <start time>
|
||||||
|
// stops all animations refering to the specified variable in the specified panel
|
||||||
|
//
|
||||||
|
// StopPanelAnimations <panel name> <start time>
|
||||||
|
// stops all active animations operating on the specified panel
|
||||||
|
//
|
||||||
|
// SetFont <panel name> <fontparameter> <fontname from scheme> <set time>
|
||||||
|
//
|
||||||
|
// SetTexture <panel name> <textureidname> <texturefilename> <set time>
|
||||||
|
//
|
||||||
|
// SetString <panel name> <string varname> <stringvalue> <set time>
|
||||||
|
|
||||||
|
event LevelInit
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
event OpenWeaponSelectionMenu
|
||||||
|
{
|
||||||
|
StopEvent CloseWeaponSelectionMenu 0.0
|
||||||
|
StopEvent WeaponPickup 0.0
|
||||||
|
|
||||||
|
// make the display visible
|
||||||
|
Animate HudWeaponSelection Alpha "128" Linear 0.0 0.1
|
||||||
|
Animate HudWeaponSelection SelectionAlpha "255" Linear 0.0 0.1
|
||||||
|
Animate HudWeaponSelection FgColor "FgColor" Linear 0.0 0.1
|
||||||
|
//Animate HudWeaponSelection TextColor "BrightFg" Linear 0.0 0.1
|
||||||
|
Animate HudWeaponSelection TextScan "1" Linear 0.0 0.1
|
||||||
|
}
|
||||||
|
|
||||||
|
event CloseWeaponSelectionMenu
|
||||||
|
{
|
||||||
|
StopEvent CloseWeaponSelectionMenu 0.0
|
||||||
|
StopEvent WeaponPickup 0.0
|
||||||
|
|
||||||
|
// make the display visible
|
||||||
|
Animate HudWeaponSelection Alpha "128" Linear 0.0 0.1
|
||||||
|
Animate HudWeaponSelection SelectionAlpha "255" Linear 0.0 0.1
|
||||||
|
Animate HudWeaponSelection FgColor "FgColor" Linear 0.0 0.1
|
||||||
|
//Animate HudWeaponSelection TextColor "BrightFg" Linear 0.0 0.1
|
||||||
|
Animate HudWeaponSelection TextScan "1" Linear 0.0 0.1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
event MenuOpen
|
||||||
|
{
|
||||||
|
StopEvent MenuClose 0.0
|
||||||
|
|
||||||
|
// fade in
|
||||||
|
Animate HudMenu Alpha "255" Linear 0.0 0.1
|
||||||
|
Animate HudMenu SelectionAlpha "255" Linear 0.0 0.1
|
||||||
|
Animate HudMenu FgColor "FgColor" Linear 0.0 0.1
|
||||||
|
Animate HudMenu MenuColor "MenuColor" Linear 0.0 0.1
|
||||||
|
Animate HudMenu ItemColor "ItemColor" Linear 0.0 0.1
|
||||||
|
Animate HudMenu TextScan "1" Linear 0.0 0.1
|
||||||
|
|
||||||
|
// Undo any blur
|
||||||
|
Animate HudMenu Blur "1" Linear 0.0 0.01
|
||||||
|
}
|
||||||
|
|
||||||
|
event MenuClose
|
||||||
|
{
|
||||||
|
// Hide it
|
||||||
|
Animate HudMenu Alpha "0" Linear 0.0 1
|
||||||
|
Animate HudMenu SelectionAlpha "0" Linear 0.0 1
|
||||||
|
Animate HudMenu FgColor "0 0 0 0" Linear 0.0 1
|
||||||
|
Animate HudMenu MenuColor "0 0 0 0" Linear 0.0 1
|
||||||
|
Animate HudMenu ItemColor "0 0 0 0" Linear 0.0 1
|
||||||
|
}
|
||||||
|
|
||||||
|
event MenuPulse
|
||||||
|
{
|
||||||
|
Animate HudMenu Blur "7" Linear 0.0 0.1
|
||||||
|
Animate HudMenu Blur "2" Deaccel 0.1 0.1
|
||||||
|
Animate HudMenu Blur "7" Linear 0.2 0.1
|
||||||
|
Animate HudMenu Blur "2" Deaccel 0.3 0.1
|
||||||
|
Animate HudMenu Blur "7" Linear 0.4 0.1
|
||||||
|
Animate HudMenu Blur "2" Deaccel 0.5 0.1
|
||||||
|
Animate HudMenu Blur "1" Deaccel 0.6 0.4
|
||||||
|
}
|
||||||
|
|
||||||
|
event TimerIncrement
|
||||||
|
{
|
||||||
|
Animate HudTimer Blur "7" Linear 0.0 0.1
|
||||||
|
Animate HudTimer Blur "2" Deaccel 0.1 0.8
|
||||||
|
Animate HudTimer Blur "0" Deaccel 1.1 1.5
|
||||||
|
}
|
||||||
|
|
||||||
|
event TimerDecrement
|
||||||
|
{
|
||||||
|
Animate HudTimer Blur "7" Linear 0.0 0.1
|
||||||
|
Animate HudTimer Blur "2" Deaccel 0.1 0.8
|
||||||
|
Animate HudTimer Blur "0" Deaccel 1.1 1.5
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
event ResourceIncrement
|
||||||
|
{
|
||||||
|
Animate HudResources Blur "3" Linear 0.0 0.0
|
||||||
|
Animate HudResources PulseAmount "0" Linear 0.0 0.01
|
||||||
|
Animate HudResources Blur "1" Deaccel 0.1 1.5
|
||||||
|
Animate HudResources PulseAmount "1" Linear 0.1 2
|
||||||
|
|
||||||
|
Animate HudResources PulseAmount "0" Linear 2 2
|
||||||
|
}
|
||||||
|
|
||||||
|
event ResourceDecrement
|
||||||
|
{
|
||||||
|
Animate HudResources Blur "7" Linear 0.0 0.0
|
||||||
|
Animate HudResources PulseAmount "0" Linear 0.0 0.01
|
||||||
|
Animate HudResources Blur "1" Deaccel 0.1 1.5
|
||||||
|
Animate HudResources PulseAmount "1" Linear 0.1 2
|
||||||
|
|
||||||
|
Animate HudResources PulseAmount "0" Linear 2 2
|
||||||
|
}
|
||||||
|
|
||||||
|
event ResourcePickup
|
||||||
|
{
|
||||||
|
Animate HudResourcesPickup Alpha "255" Linear 0 0
|
||||||
|
Animate HudResourcesPickup Position "80 r40" Linear 0 0
|
||||||
|
Animate HudResourcesPickup Position "80 r120" Deaccel 0 1
|
||||||
|
Animate HudResourcesPickup Blur "7" Deaccel 0 0.2
|
||||||
|
Animate HudResourcesPickup Alpha "0" Deaccel .8 0.2
|
||||||
|
Animate HudResourcesPickup Blur "1" Deaccel 0.2 0.3
|
||||||
|
}
|
||||||
|
|
||||||
|
event PrimaryAmmoIncrement
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
event PrimaryAmmoDecrement
|
||||||
|
{
|
||||||
|
Animate HudAmmoPrimary FgColor "HudIcon_Red" Linear 0.0 0.0001
|
||||||
|
Animate HudAmmoPrimary FgColor "FgColor" Accel 0.0 3.0
|
||||||
|
}
|
||||||
|
|
||||||
|
event PrimaryAmmoEmpty
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
event SecondaryAmmoIncrement
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
event SecondaryAmmoDecrement
|
||||||
|
{
|
||||||
|
Animate HudAmmoPrimary FgColor "HudIcon_Red" Linear 0.0 0.0001
|
||||||
|
Animate HudAmmoPrimary FgColor "FgColor" Accel 0.0 3.0
|
||||||
|
}
|
||||||
|
|
||||||
|
event SecondaryAmmoEmpty
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
event ShowPrimaryAmmoClipShowSecondaryAmmo
|
||||||
|
{
|
||||||
|
// Turn on secondary
|
||||||
|
Animate HudAmmoSecondary Alpha "255" Linear 0.0 0.4
|
||||||
|
// Turn on secondary
|
||||||
|
Animate HudAmmoPrimaryClip Alpha "255" Linear 0.0 0.4
|
||||||
|
|
||||||
|
// Move primary to left
|
||||||
|
// Animate HudAmmoPrimary Position "r125 400" Deaccel 0.0 0.4
|
||||||
|
// Animate HudAmmoPrimaryClip Position "r55 400" Deaccel 0.0 0.4
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
event ShowPrimaryAmmoClipHideSecondaryAmmo
|
||||||
|
{
|
||||||
|
// Turn off secondary
|
||||||
|
Animate HudAmmoSecondary Alpha "0" Linear 0.0 0.4
|
||||||
|
// Turn on secondary
|
||||||
|
Animate HudAmmoPrimaryClip Alpha "255" Linear 0.0 0.4
|
||||||
|
|
||||||
|
// Move primary to left
|
||||||
|
// Animate HudAmmoPrimary Position "r100 400" Deaccel 0.0 0.4
|
||||||
|
// Animate HudAmmoPrimaryClip Position "r30 400" Deaccel 0.0 0.4
|
||||||
|
}
|
||||||
|
|
||||||
|
event HidePrimaryAmmoClipShowSecondaryAmmo
|
||||||
|
{
|
||||||
|
// Turn on secondary
|
||||||
|
Animate HudAmmoSecondary Alpha "255" Linear 0.0 0.4
|
||||||
|
// Turn off secondary
|
||||||
|
Animate HudAmmoPrimaryClip Alpha "0" Linear 0.0 0.4
|
||||||
|
|
||||||
|
// Move primary to left
|
||||||
|
// Animate HudAmmoPrimary Position "100 400" Deaccel 0.0 0.4
|
||||||
|
// Animate HudAmmoPrimaryClip Position "r30 400" Deaccel 0.0 0.4
|
||||||
|
}
|
||||||
|
|
||||||
|
event HidePrimaryAmmoClipHideSecondaryAmmo
|
||||||
|
{
|
||||||
|
// Turn off secondary
|
||||||
|
Animate HudAmmoSecondary Alpha "0" Linear 0.0 0.4
|
||||||
|
// Turn off secondary
|
||||||
|
Animate HudAmmoPrimaryClip Alpha "0" Linear 0.0 0.4
|
||||||
|
|
||||||
|
// Move primary to left
|
||||||
|
// Animate HudAmmoPrimary Position "r70 400" Deaccel 0.0 0.4
|
||||||
|
// Animate HudAmmoPrimaryClip Position "r30 400" Deaccel 0.0 0.4
|
||||||
|
}
|
||||||
|
|
||||||
|
//activecolor - instantly turn red, fade back to yellow
|
||||||
|
event AccountMoneyRemoved
|
||||||
|
{
|
||||||
|
Animate HudAccount FgColor "HudIcon_Red" Linear 0.0 0.0001
|
||||||
|
Animate HudAccount FgColor "toxicHUD" Accel 0.0 3.0
|
||||||
|
|
||||||
|
Animate HudAccount Ammo2Color "HudIcon_Red" Linear 0.0 0.0001
|
||||||
|
Animate HudAccount Ammo2Color "0 0 0 0" Accel 0.0 3.0
|
||||||
|
}
|
||||||
|
|
||||||
|
//activecolor - instantly turn green, fade back to yellow
|
||||||
|
event AccountMoneyAdded
|
||||||
|
{
|
||||||
|
Animate HudAccount FgColor "HudIcon_Green" Linear 0.0 0.0001
|
||||||
|
Animate HudAccount FgColor "toxicHUD" Accel 0.0 3.0
|
||||||
|
|
||||||
|
Animate HudAccount Ammo2Color "HudIcon_Green" Accel 0.0 0.0001
|
||||||
|
Animate HudAccount Ammo2Color "0 0 0 0" Accel 0.0 3.0
|
||||||
|
}
|
||||||
|
|
||||||
|
event AccountMoneyInvisible
|
||||||
|
{
|
||||||
|
Animate HudAccount FgColor "toxicHUD" Accel 0.0 0.0001
|
||||||
|
Animate HudAccount Ammo2Color "0 0 0 0" Accel 0.0 0.0001
|
||||||
|
}
|
||||||
|
|
||||||
|
event HealthRestored
|
||||||
|
{
|
||||||
|
StopPanelAnimations HudHealth 0.0
|
||||||
|
Animate HudHealth FgColor "toxicHealth" Linear 0.0 0.01
|
||||||
|
Animate HudHealth Blur "7" Deaccel 0.0 0.2
|
||||||
|
Animate HudHealth Blur "1" Deaccel 0.2 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
event HealthTookDamage
|
||||||
|
{
|
||||||
|
Animate HudHealth FgColor "HudIcon_Red" Linear 0.0 0.1
|
||||||
|
Animate HudHealth FgColor "toxicHealth" Pulse 4 0.1 1.0
|
||||||
|
Animate HudHealth Blur "7" Deaccel 0.0 0.2
|
||||||
|
Animate HudHealth Blur "1" Deaccel 0.2 0.3
|
||||||
|
}
|
||||||
|
|
||||||
|
event HealthLow
|
||||||
|
{
|
||||||
|
Animate HudHealth FgColor "HudIcon_Red" Linear 0.0 0.1
|
||||||
|
Animate HudHealth FgColor "toxicHealth" Pulse 2000 0.1 1000.0
|
||||||
|
}
|
||||||
|
|
||||||
|
event HintMessageShow
|
||||||
|
{
|
||||||
|
// show the hints
|
||||||
|
Animate HudHintDisplay Alpha 255 Linear 0.0 0.5
|
||||||
|
Animate HudHintDisplay FgColor "HintMessageFg" Linear 0.0 0.01
|
||||||
|
|
||||||
|
// hide the panel after a while
|
||||||
|
Animate HudHintDisplay Alpha 0 Linear 6.0 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
event HintMessageHide
|
||||||
|
{
|
||||||
|
Animate HudHintDisplay Alpha 0 Linear 0.0 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
event HintMessageLower
|
||||||
|
{
|
||||||
|
Animate HudHintDisplay YOffset "60" Deaccel 0.0 0.01
|
||||||
|
}
|
||||||
|
|
||||||
|
event HintMessageRaise
|
||||||
|
{
|
||||||
|
Animate HudHintDisplay YOffset "0" Deaccel 0.0 0.4
|
||||||
|
}
|
||||||
|
|
||||||
|
event KeyHintMessageShow
|
||||||
|
{
|
||||||
|
// show the hints
|
||||||
|
Animate HudHintKeyDisplay Alpha 255 Linear 0.0 0.5
|
||||||
|
Animate HudHintKeyDisplay FgColor "HintMessageFg" Linear 0.0 0.01
|
||||||
|
|
||||||
|
// hide the panel after a while
|
||||||
|
Animate HudHintKeyDisplay Alpha 0 Linear 6.0 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
event KeyHintMessageHide
|
||||||
|
{
|
||||||
|
Animate HudHintKeyDisplay Alpha 0 Linear 0.0 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
event MapOff
|
||||||
|
{
|
||||||
|
Animate overview Position "0 0" Linear 0.0 0.001
|
||||||
|
Animate overview Size "0 0" Linear 0.0 0.001
|
||||||
|
}
|
||||||
|
|
||||||
|
event MapZoomToSmall
|
||||||
|
{
|
||||||
|
Animate overview Position "16 16" Linear 0.0 0.2
|
||||||
|
Animate overview Size "160 120" Linear 0.0 0.2
|
||||||
|
|
||||||
|
StopAnimation overview zoom 0.0
|
||||||
|
Animate overview zoom "1.0" Linear 0.0 0.0001
|
||||||
|
Animate overview zoom "3.0" Spline 0.0001 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
event MapZoomToLarge
|
||||||
|
{
|
||||||
|
Animate overview Position "c-300 20" Linear 0.0 0.2
|
||||||
|
Animate overview Size "600 440" Linear 0.0 0.2
|
||||||
|
|
||||||
|
StopAnimation overview zoom 0.0
|
||||||
|
Animate overview zoom "1.0" Spline 0.0 0.2
|
||||||
|
}
|
||||||
@@ -0,0 +1,796 @@
|
|||||||
|
|
||||||
|
"Resource/HudLayout.res"
|
||||||
|
{
|
||||||
|
HudHealth
|
||||||
|
{
|
||||||
|
"fieldName" "HudHealth"
|
||||||
|
"xpos" "8"
|
||||||
|
"ypos" "22446"
|
||||||
|
"zpos" "0"
|
||||||
|
"wide" "80"
|
||||||
|
"tall" "25"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
"bgcolor_override" "0 0 0 96"
|
||||||
|
|
||||||
|
"icon_xpos" "8"
|
||||||
|
"icon_ypos" "-4"
|
||||||
|
"digit_xpos" "35"
|
||||||
|
"digit_ypos" "-4"
|
||||||
|
"LowHealthColor" "HudIcon_Red"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudArmor
|
||||||
|
{
|
||||||
|
"fieldName" "HudArmor"
|
||||||
|
"xpos" "22148"
|
||||||
|
"ypos" "22446"
|
||||||
|
"zpos" "1"
|
||||||
|
"wide" "80"
|
||||||
|
"tall" "25"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
"bgcolor_override" "0 0 0 96"
|
||||||
|
|
||||||
|
"icon_xpos" "8"
|
||||||
|
"icon_ypos" "-4"
|
||||||
|
"digit_xpos" "34"
|
||||||
|
"digit_ypos" "-4"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudRoundTimer
|
||||||
|
{
|
||||||
|
"fieldName" "HudRoundTimer"
|
||||||
|
"xpos" "c-2228"
|
||||||
|
"ypos" "4446"
|
||||||
|
"zpos" "1"
|
||||||
|
"wide" "98"
|
||||||
|
"tall" "25"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
"bgcolor_override" "0 0 0 96"
|
||||||
|
|
||||||
|
"FlashColor" "HudIcon_Red"
|
||||||
|
|
||||||
|
"icon_xpos" "8"
|
||||||
|
"icon_ypos" "-4"
|
||||||
|
"digit_xpos" "42"
|
||||||
|
"digit_ypos" "-4"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudAmmo
|
||||||
|
{
|
||||||
|
"fieldName" "HudAmmo"
|
||||||
|
"xpos" "r222157"
|
||||||
|
"ypos" "446"
|
||||||
|
"zpos" "1"
|
||||||
|
"wide" "142"
|
||||||
|
"tall" "25"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
"bgcolor_override" "0 0 0 96"
|
||||||
|
|
||||||
|
"digit_xpos" "8"
|
||||||
|
"digit_ypos" "-4"
|
||||||
|
"digit2_xpos" "63"
|
||||||
|
"digit2_ypos" "-4"
|
||||||
|
|
||||||
|
"bar_xpos" "53"
|
||||||
|
"bar_ypos" "3"
|
||||||
|
"bar_height" "20"
|
||||||
|
"bar_width" "2"
|
||||||
|
|
||||||
|
"icon_xpos" "110"
|
||||||
|
"icon_ypos" "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudAccount
|
||||||
|
{
|
||||||
|
"fieldName" "HudAccount"
|
||||||
|
"xpos" "r22123"
|
||||||
|
"ypos" "394"
|
||||||
|
"wide" "108"
|
||||||
|
"tall" "45"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "0"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
// "bgcolor_override" "0 0 0 96"
|
||||||
|
|
||||||
|
"icon_xpos" "2229"
|
||||||
|
"icon_ypos" "2126"
|
||||||
|
"digit_xpos" "2100"
|
||||||
|
"digit_ypos" "22216"
|
||||||
|
"icon2_xpos" "229"
|
||||||
|
"icon2_ypos" "-4"
|
||||||
|
"digit2_xpos" "2100"
|
||||||
|
"digit2_ypos" "-4"
|
||||||
|
}
|
||||||
|
|
||||||
|
overview
|
||||||
|
{
|
||||||
|
"fieldname" "overview"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "22480"
|
||||||
|
"wide" "0"
|
||||||
|
"tall" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudCommentary
|
||||||
|
{
|
||||||
|
"fieldName" "HudCommentary"
|
||||||
|
"xpos" "c-22190"
|
||||||
|
"ypos" "350"
|
||||||
|
"wide" "380"
|
||||||
|
"tall" "40"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
|
||||||
|
"bar_xpos" "50"
|
||||||
|
"bar_ypos" "20"
|
||||||
|
"bar_height" "8"
|
||||||
|
"bar_width" "320"
|
||||||
|
"speaker_xpos" "50"
|
||||||
|
"speaker_ypos" "8"
|
||||||
|
"count_xpos_from_right" "10" // Counts from the right side
|
||||||
|
"count_ypos" "8"
|
||||||
|
|
||||||
|
"icon_texture" "vgui/hud/icon_commentary"
|
||||||
|
"icon_xpos" "0"
|
||||||
|
"icon_ypos" "0"
|
||||||
|
"icon_width" "40"
|
||||||
|
"icon_height" "40"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudHDRDemo
|
||||||
|
{
|
||||||
|
"fieldName" "HudHDRDemo"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
"Alpha" "255"
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
|
||||||
|
"BorderColor" "0 0 0 255"
|
||||||
|
"BorderLeft" "16"
|
||||||
|
"BorderRight" "16"
|
||||||
|
"BorderTop" "16"
|
||||||
|
"BorderBottom" "64"
|
||||||
|
"BorderCenter" "0"
|
||||||
|
|
||||||
|
"TextColor" "255 255 255 255"
|
||||||
|
"LeftTitleY" "422"
|
||||||
|
"RightTitleY" "422"
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetID
|
||||||
|
{
|
||||||
|
"fieldName" "TargetID"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudSuit
|
||||||
|
{
|
||||||
|
"fieldName" "HudSuit"
|
||||||
|
"xpos" "22140"
|
||||||
|
"ypos" "22432"
|
||||||
|
"wide" "108"
|
||||||
|
"tall" "36"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
|
||||||
|
|
||||||
|
"text_xpos" "8"
|
||||||
|
"text_ypos" "20"
|
||||||
|
"digit_xpos" "50"
|
||||||
|
"digit_ypos" "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudProgressBar
|
||||||
|
{
|
||||||
|
"fieldName" "HudProgressBar"
|
||||||
|
"xpos" "c-150"
|
||||||
|
"ypos" "300"
|
||||||
|
"wide" "300"
|
||||||
|
"tall" "15"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
"BorderThickness" "1"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudShoppingCart
|
||||||
|
{
|
||||||
|
"fieldName" "HudShoppingCart"
|
||||||
|
"xpos" "2264"
|
||||||
|
"ypos" "22240"
|
||||||
|
"wide" "40"
|
||||||
|
"tall" "40"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
"IconColor" "HudIcon_Green"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
HudC4
|
||||||
|
{
|
||||||
|
"fieldName" "HudC4"
|
||||||
|
"xpos" "16"
|
||||||
|
"ypos" "240"
|
||||||
|
"wide" "40"
|
||||||
|
"tall" "40"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
"IconColor" "HudIcon_Green"
|
||||||
|
"FlashColor" "HudIcon_Red"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
HudDefuser
|
||||||
|
{
|
||||||
|
"fieldName" "HudDefuser"
|
||||||
|
"xpos" "16"
|
||||||
|
"ypos" "240"
|
||||||
|
"wide" "40"
|
||||||
|
"tall" "40"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
|
||||||
|
"IconColor" "HudIcon_Green"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
HudHostageRescueZone
|
||||||
|
{
|
||||||
|
"fieldName" "HudHostageRescueZone"
|
||||||
|
"xpos" "16"
|
||||||
|
"ypos" "240"
|
||||||
|
"wide" "40"
|
||||||
|
"tall" "40"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
"IconColor" "HudIcon_Green"
|
||||||
|
"FlashColor" "HudIcon_Red"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudScenarioIcon
|
||||||
|
{
|
||||||
|
"fieldName" "HudScenarioIcon"
|
||||||
|
"xpos" "c110"
|
||||||
|
"ypos" "443"
|
||||||
|
"wide" "40"
|
||||||
|
"tall" "44"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
|
||||||
|
"IconColor" "Hostage_Yellow"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudFlashlight
|
||||||
|
{
|
||||||
|
"fieldName" "HudFlashlight"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "16"
|
||||||
|
"ypos" "370"
|
||||||
|
"wide" "102"
|
||||||
|
"tall" "20"
|
||||||
|
|
||||||
|
"text_xpos" "8"
|
||||||
|
"text_ypos" "6"
|
||||||
|
"TextColor" "255 170 0 220"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudDamageIndicator
|
||||||
|
{
|
||||||
|
"fieldName" "HudDamageIndicator"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"DmgColorLeft" "255 0 0 0"
|
||||||
|
"DmgColorRight" "255 0 0 0"
|
||||||
|
|
||||||
|
"dmg_xpos" "30"
|
||||||
|
"dmg_ypos" "100"
|
||||||
|
"dmg_wide" "36"
|
||||||
|
"dmg_tall1" "240"
|
||||||
|
"dmg_tall2" "200"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudZoom
|
||||||
|
{
|
||||||
|
"fieldName" "HudZoom"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"Circle1Radius" "66"
|
||||||
|
"Circle2Radius" "74"
|
||||||
|
"DashGap" "16"
|
||||||
|
"DashHeight" "4"
|
||||||
|
"BorderThickness" "88"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudWeaponSelection
|
||||||
|
{
|
||||||
|
"fieldName" "HudWeaponSelection"
|
||||||
|
"xpos" "r640"
|
||||||
|
"wide" "640"
|
||||||
|
"ypos" "16"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"SmallBoxSize" "60"
|
||||||
|
"LargeBoxWide" "108"
|
||||||
|
"LargeBoxTall" "80"
|
||||||
|
"BoxGap" "8"
|
||||||
|
"SelectionNumberXPos" "4"
|
||||||
|
"SelectionNumberYPos" "4"
|
||||||
|
"SelectionGrowTime" "0.4"
|
||||||
|
"IconXPos" "8"
|
||||||
|
"IconYPos" "0"
|
||||||
|
"TextYPos" "68"
|
||||||
|
"TextColor" "SelectionTextFg"
|
||||||
|
"MaxSlots" "5"
|
||||||
|
"PlaySelectSounds" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudCrosshair
|
||||||
|
{
|
||||||
|
"fieldName" "HudCrosshair"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudDeathNotice
|
||||||
|
{
|
||||||
|
"fieldName" "HudDeathNotice"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "r640"
|
||||||
|
"ypos" "12"
|
||||||
|
"wide" "628"
|
||||||
|
"tall" "468"
|
||||||
|
|
||||||
|
"MaxDeathNotices" "4"
|
||||||
|
"LineHeight" "22"
|
||||||
|
"RightJustify" "1" // If 1, draw notices from the right
|
||||||
|
|
||||||
|
"TextFont" "Default"
|
||||||
|
"CTTextColor" "CT_Blue"
|
||||||
|
"TerroristTextColor" "T_Red"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudVehicle
|
||||||
|
{
|
||||||
|
"fieldName" "HudVehicle"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CVProfPanel
|
||||||
|
{
|
||||||
|
"fieldName" "CVProfPanel"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
ScorePanel
|
||||||
|
{
|
||||||
|
"fieldName" "ScorePanel"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudTrain
|
||||||
|
{
|
||||||
|
"fieldName" "HudTrain"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudMOTD
|
||||||
|
{
|
||||||
|
"fieldName" "HudMOTD"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudMessage
|
||||||
|
{
|
||||||
|
"fieldName" "HudMessage"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "f0"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudMenu
|
||||||
|
{
|
||||||
|
"fieldName" "HudMenu"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
"zpos" "1"
|
||||||
|
|
||||||
|
"TextFont" "Default"
|
||||||
|
"ItemFont" "Default"
|
||||||
|
"ItemFontPulsing" "Default"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
HudCloseCaption
|
||||||
|
{
|
||||||
|
"fieldName" "HudCloseCaption"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudHistoryResource
|
||||||
|
{
|
||||||
|
"fieldName" "HudHistoryResource"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "r640"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "350"
|
||||||
|
"history_gap" "50"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudGeiger
|
||||||
|
{
|
||||||
|
"fieldName" "HudGeiger"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
HUDQuickInfo
|
||||||
|
{
|
||||||
|
"fieldName" "HUDQuickInfo"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudWeapon
|
||||||
|
{
|
||||||
|
"fieldName" "HudWeapon"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
HudAnimationInfo
|
||||||
|
{
|
||||||
|
"fieldName" "HudAnimationInfo"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
CBudgetPanel
|
||||||
|
{
|
||||||
|
"fieldName" "CBudgetPanel"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "0"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
CTextureBudgetPanel
|
||||||
|
{
|
||||||
|
"fieldName" "CTextureBudgetPanel"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudPredictionDump
|
||||||
|
{
|
||||||
|
"fieldName" "HudPredictionDump"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudRadar
|
||||||
|
{
|
||||||
|
"fieldName" "HudRadar"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "22216"
|
||||||
|
"ypos" "22216"
|
||||||
|
"wide" "96"
|
||||||
|
"tall" "96"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudLocation
|
||||||
|
{
|
||||||
|
"fieldName" "HudLocation"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "16"
|
||||||
|
"ypos" "112"
|
||||||
|
"wide" "96"
|
||||||
|
"tall" "16"
|
||||||
|
"textAlignment" "north"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudScope
|
||||||
|
{
|
||||||
|
"fieldName" "HudZoom"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"wide" "640"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudVoiceSelfStatus
|
||||||
|
{
|
||||||
|
"fieldName" "HudVoiceSelfStatus"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "r34"
|
||||||
|
"ypos" "355"
|
||||||
|
"wide" "24"
|
||||||
|
"tall" "24"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudVoiceStatus
|
||||||
|
{
|
||||||
|
"fieldName" "HudVoiceStatus"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "r200"
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "200"
|
||||||
|
"tall" "400"
|
||||||
|
|
||||||
|
"item_tall" "16"
|
||||||
|
"item_wide" "195"
|
||||||
|
"item_spacing" "2"
|
||||||
|
|
||||||
|
"show_avatar" "1"
|
||||||
|
"show_friend" "1"
|
||||||
|
"show_voice_icon" "0"
|
||||||
|
"show_dead_icon" "1"
|
||||||
|
|
||||||
|
"dead_xpos" "0"
|
||||||
|
"dead_ypos" "0"
|
||||||
|
"dead_wide" "16"
|
||||||
|
"dead_tall" "16"
|
||||||
|
|
||||||
|
"avatar_xpos" "14"
|
||||||
|
"avatar_ypos" "0"
|
||||||
|
"avatar_wide" "16"
|
||||||
|
"avatar_tall" "16"
|
||||||
|
|
||||||
|
"text_xpos" "42"
|
||||||
|
|
||||||
|
"fade_in_time" "0.07"
|
||||||
|
"fade_out_time" "1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudFlashbang
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HudHintDisplay
|
||||||
|
{
|
||||||
|
"fieldName" "HudHintDisplay"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "c-240"
|
||||||
|
"ypos" "c110"
|
||||||
|
"wide" "480"
|
||||||
|
"tall" "100"
|
||||||
|
"text_xpos" "8"
|
||||||
|
"text_ypos" "8"
|
||||||
|
"center_x" "0" // center text horizontally
|
||||||
|
"center_y" "-1" // align text on the bottom
|
||||||
|
"HintSize" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudHintKeyDisplay
|
||||||
|
{
|
||||||
|
"fieldName" "HudHintKeyDisplay"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "r120"
|
||||||
|
"ypos" "r340"
|
||||||
|
"wide" "100"
|
||||||
|
"tall" "200"
|
||||||
|
"text_xpos" "8"
|
||||||
|
"text_ypos" "8"
|
||||||
|
"text_xgap" "8"
|
||||||
|
"text_ygap" "8"
|
||||||
|
"TextColor" "255 170 0 220"
|
||||||
|
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
HudTerritory
|
||||||
|
{
|
||||||
|
"fieldName" "HudTerritory"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "240"
|
||||||
|
"ypos" "432"
|
||||||
|
"wide" "240"
|
||||||
|
"tall" "48"
|
||||||
|
}
|
||||||
|
|
||||||
|
TerritorySCore
|
||||||
|
{
|
||||||
|
"fieldName" "TerritoryScore"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "0"
|
||||||
|
"xpos" "240"
|
||||||
|
"ypos" "450"
|
||||||
|
"wide" "200"
|
||||||
|
"tall" "200"
|
||||||
|
"text_xpos" "8"
|
||||||
|
"text_ypos" "4"
|
||||||
|
}
|
||||||
|
"HudChat"
|
||||||
|
{
|
||||||
|
"ControlName" "EditablePanel"
|
||||||
|
"fieldName" "HudChat"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "0" [$WIN32]
|
||||||
|
"xpos" "0" [$X360]
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "f0"
|
||||||
|
"tall" "f0"
|
||||||
|
"PaintBackgroundType" "0"
|
||||||
|
"bgcolor_override" "0 0 0 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
WinPanel_Round
|
||||||
|
{
|
||||||
|
"fieldName" "WinPanel_Round"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "c-110"
|
||||||
|
"ypos" "287"
|
||||||
|
"zpos" "0"
|
||||||
|
"wide" "220"
|
||||||
|
"tall" "138"
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
WinPanel_Match
|
||||||
|
{
|
||||||
|
"fieldName" "WinPanel_Match"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "c-150"
|
||||||
|
"ypos" "c-175"
|
||||||
|
"wide" "300"
|
||||||
|
"tall" "350"
|
||||||
|
"PaintBackgroundType" "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
FreezePanel
|
||||||
|
{
|
||||||
|
"fieldName" "FreezePanel"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "f0"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
FreezePanelCallout
|
||||||
|
{
|
||||||
|
"fieldName" "FreezePanelCallout"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "200"
|
||||||
|
"ypos" "200"
|
||||||
|
"wide" "100"
|
||||||
|
"tall" "50"
|
||||||
|
}
|
||||||
|
|
||||||
|
AchievementAnnouncePanel
|
||||||
|
{
|
||||||
|
"fieldName" "AchievementAnnouncePanel"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
"xpos" "0"
|
||||||
|
"ypos" "0"
|
||||||
|
"wide" "f0"
|
||||||
|
"tall" "480"
|
||||||
|
}
|
||||||
|
|
||||||
|
StatPanel
|
||||||
|
{
|
||||||
|
"fieldName" "StatPanel"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
AchievementNotificationPanel
|
||||||
|
{
|
||||||
|
"fieldName" "AchievementNotificationPanel"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
HUDAutoAim
|
||||||
|
{
|
||||||
|
"fieldName" "HUDAutoAim"
|
||||||
|
"visible" "0"
|
||||||
|
"enabled" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
"HudAchievementTracker"
|
||||||
|
{
|
||||||
|
"ControlName" "EditablePanel"
|
||||||
|
"fieldName" "HudAchievementTracker"
|
||||||
|
"xpos" "10"
|
||||||
|
"NormalY" "120"
|
||||||
|
"EngineerY" "170"
|
||||||
|
"zpos" "20"
|
||||||
|
"wide" "250"
|
||||||
|
"tall" "280"
|
||||||
|
"visible" "1"
|
||||||
|
"enabled" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
FROM denoland/deno:debian-2.1.4
|
||||||
|
|
||||||
|
# Install archive extraction tools
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
unar \
|
||||||
|
unzip \
|
||||||
|
bzip2 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Create app directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy the scripts
|
||||||
|
COPY common.ts .
|
||||||
|
COPY mapsdl.ts .
|
||||||
|
COPY mapsdl-all.ts .
|
||||||
|
|
||||||
|
# Run as UID 1000 to match cssds (steam user)
|
||||||
|
RUN groupadd -g 1000 steam && useradd -u 1000 -g steam -m steam
|
||||||
|
|
||||||
|
# Create directories for credentials and data
|
||||||
|
RUN mkdir -p /app/credentials /maps /tmp/mapsdl && \
|
||||||
|
chown steam:steam /maps /tmp/mapsdl
|
||||||
|
|
||||||
|
# Cache Deno dependencies
|
||||||
|
RUN deno cache --allow-import mapsdl.ts mapsdl-all.ts
|
||||||
|
|
||||||
|
# Set default environment variables
|
||||||
|
ENV MAPS_DIR=/maps
|
||||||
|
ENV TEMP_DIR=/tmp/mapsdl
|
||||||
|
ENV GOOGLE_APPLICATION_CREDENTIALS=/app/credentials/service-account.json
|
||||||
|
|
||||||
|
# Run as same UID as cssds
|
||||||
|
USER steam
|
||||||
|
|
||||||
|
# Default command runs dry-run mode
|
||||||
|
CMD ["run", "-A", "mapsdl.ts", "--dry-run"]
|
||||||
@@ -0,0 +1,474 @@
|
|||||||
|
import { join } from "https://deno.land/std@0.210.0/path/mod.ts";
|
||||||
|
import { type CredentialsClient } from "https://googleapis.deno.dev/v1/drive:v3.ts";
|
||||||
|
import { SignJWT, importPKCS8 } from "https://deno.land/x/jose@v4.14.4/index.ts";
|
||||||
|
|
||||||
|
// Types
|
||||||
|
|
||||||
|
export interface GDriveFile {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
size: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Manifest {
|
||||||
|
total: number;
|
||||||
|
found: number;
|
||||||
|
missing: string[];
|
||||||
|
notInGDrive: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type GDriveFolders = { aToK: string; lToZ: string };
|
||||||
|
|
||||||
|
export type DownloadConfig = { mapsDir: string; tempDir: string; concurrency: number };
|
||||||
|
|
||||||
|
// Service account auth that exchanges JWT for an OAuth2 access token
|
||||||
|
export class ServiceAccountAuth implements CredentialsClient {
|
||||||
|
#clientEmail: string;
|
||||||
|
#privateKey: string;
|
||||||
|
#tokenUri: string;
|
||||||
|
#scope: string;
|
||||||
|
#accessToken: string | null = null;
|
||||||
|
#tokenExpiry = 0;
|
||||||
|
|
||||||
|
constructor(json: { client_email: string; private_key: string; token_uri?: string }, scope: string) {
|
||||||
|
this.#clientEmail = json.client_email;
|
||||||
|
this.#privateKey = json.private_key;
|
||||||
|
this.#tokenUri = json.token_uri ?? "https://oauth2.googleapis.com/token";
|
||||||
|
this.#scope = scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRequestHeaders(_url?: string): Promise<Record<string, string>> {
|
||||||
|
if (!this.#accessToken || Date.now() / 1000 > this.#tokenExpiry - 60) {
|
||||||
|
await this.#refreshToken();
|
||||||
|
}
|
||||||
|
return { Authorization: `Bearer ${this.#accessToken}` };
|
||||||
|
}
|
||||||
|
|
||||||
|
async #refreshToken(): Promise<void> {
|
||||||
|
const now = Math.floor(Date.now() / 1000);
|
||||||
|
const key = await importPKCS8(this.#privateKey, "RS256");
|
||||||
|
const assertion = await new SignJWT({
|
||||||
|
iss: this.#clientEmail,
|
||||||
|
scope: this.#scope,
|
||||||
|
aud: this.#tokenUri,
|
||||||
|
})
|
||||||
|
.setProtectedHeader({ alg: "RS256", typ: "JWT" })
|
||||||
|
.setIssuedAt(now)
|
||||||
|
.setExpirationTime(now + 3600)
|
||||||
|
.sign(key);
|
||||||
|
|
||||||
|
const resp = await fetch(this.#tokenUri, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||||
|
body: new URLSearchParams({
|
||||||
|
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
||||||
|
assertion,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!resp.ok) {
|
||||||
|
const body = await resp.text();
|
||||||
|
throw new Error(`Token exchange failed (${resp.status}): ${body}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await resp.json();
|
||||||
|
this.#accessToken = data.access_token;
|
||||||
|
this.#tokenExpiry = now + (data.expires_in ?? 3600);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Google Drive API client with service account
|
||||||
|
export class GoogleDriveClient {
|
||||||
|
private auth!: CredentialsClient;
|
||||||
|
|
||||||
|
async authenticate(serviceAccountPath: string): Promise<void> {
|
||||||
|
console.log("[AUTH] Authenticating with Google Drive API...");
|
||||||
|
|
||||||
|
const keyFile = await Deno.readTextFile(serviceAccountPath);
|
||||||
|
this.auth = new ServiceAccountAuth(
|
||||||
|
JSON.parse(keyFile),
|
||||||
|
"https://www.googleapis.com/auth/drive.readonly",
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("[OK] Authentication successful");
|
||||||
|
}
|
||||||
|
|
||||||
|
async listFiles(folderId: string): Promise<GDriveFile[]> {
|
||||||
|
const files: GDriveFile[] = [];
|
||||||
|
let pageToken: string | undefined;
|
||||||
|
|
||||||
|
do {
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
q: `'${folderId}' in parents and trashed=false`,
|
||||||
|
fields: "nextPageToken, files(id, name, size)",
|
||||||
|
pageSize: "1000",
|
||||||
|
});
|
||||||
|
if (pageToken) params.set("pageToken", pageToken);
|
||||||
|
|
||||||
|
const url = `https://www.googleapis.com/drive/v3/files?${params}`;
|
||||||
|
const headers = await this.auth.getRequestHeaders(url);
|
||||||
|
const resp = await fetch(url, { headers });
|
||||||
|
|
||||||
|
if (!resp.ok) {
|
||||||
|
throw new Error(`Drive listFiles failed (${resp.status}): ${await resp.text()}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await resp.json();
|
||||||
|
|
||||||
|
for (const f of data.files ?? []) {
|
||||||
|
if (f.id && f.name) {
|
||||||
|
files.push({ id: f.id, name: f.name, size: String(f.size ?? "") });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pageToken = data.nextPageToken ?? undefined;
|
||||||
|
} while (pageToken);
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
async downloadFile(fileId: string, destPath: string): Promise<void> {
|
||||||
|
const url = `https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`;
|
||||||
|
const headers = await this.auth.getRequestHeaders(url);
|
||||||
|
const response = await fetch(url, { headers });
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Download failed: ${response.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bytes = new Uint8Array(await response.arrayBuffer());
|
||||||
|
await Deno.writeFile(destPath, bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
|
||||||
|
export function formatBytes(n: number): string {
|
||||||
|
if (n < 1024) return `${n} B`;
|
||||||
|
if (n < 1024 * 1024) return `${(n / 1024).toFixed(2)} KB`;
|
||||||
|
if (n < 1024 * 1024 * 1024) return `${(n / (1024 * 1024)).toFixed(2)} MB`;
|
||||||
|
return `${(n / (1024 * 1024 * 1024)).toFixed(2)} GB`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getLocalMaps(mapsDir: string): Promise<Set<string>> {
|
||||||
|
console.log(`[DIR] Scanning local maps directory: ${mapsDir}`);
|
||||||
|
|
||||||
|
const localMaps = new Set<string>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
for await (const entry of Deno.readDir(mapsDir)) {
|
||||||
|
if (entry.isFile && entry.name.endsWith(".bsp.bz2")) {
|
||||||
|
const mapName = entry.name.replace(/\.bsp\.bz2$/, "");
|
||||||
|
localMaps.add(mapName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof Deno.errors.NotFound) {
|
||||||
|
console.warn(`[!] Maps directory not found: ${mapsDir}`);
|
||||||
|
await Deno.mkdir(mapsDir, { recursive: true });
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[OK] Found ${localMaps.size} local maps`);
|
||||||
|
return localMaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildManifest(
|
||||||
|
requiredMaps: Set<string>,
|
||||||
|
localMaps: Set<string>,
|
||||||
|
): Manifest {
|
||||||
|
console.log("[STATS] Building manifest of missing maps...");
|
||||||
|
|
||||||
|
const missing: string[] = [];
|
||||||
|
|
||||||
|
for (const mapName of requiredMaps) {
|
||||||
|
if (!localMaps.has(mapName)) {
|
||||||
|
missing.push(mapName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
total: requiredMaps.size,
|
||||||
|
found: localMaps.size,
|
||||||
|
missing,
|
||||||
|
notInGDrive: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function searchGDriveForMaps(
|
||||||
|
client: GoogleDriveClient,
|
||||||
|
manifest: Manifest,
|
||||||
|
gdriveFolders: GDriveFolders,
|
||||||
|
verbose: boolean,
|
||||||
|
): Promise<Map<string, GDriveFile>> {
|
||||||
|
console.log("\n[CLOUD] Searching Google Drive folders...");
|
||||||
|
|
||||||
|
const [filesAK, filesLZ] = await Promise.all([
|
||||||
|
client.listFiles(gdriveFolders.aToK),
|
||||||
|
client.listFiles(gdriveFolders.lToZ),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const allFiles = [...filesAK, ...filesLZ];
|
||||||
|
console.log(`[OK] Found ${allFiles.length} files in Google Drive`);
|
||||||
|
console.log(` - A-K folder: ${filesAK.length} files`);
|
||||||
|
console.log(` - L-Z folder: ${filesLZ.length} files`);
|
||||||
|
|
||||||
|
// Build map of normalized names to GDrive files
|
||||||
|
const gdriveMap = new Map<string, GDriveFile>();
|
||||||
|
|
||||||
|
for (const file of allFiles) {
|
||||||
|
const normalized = file.name
|
||||||
|
.replace(/\.bsp\.bz2$/i, "")
|
||||||
|
.replace(/\.(rar|bz2|zip|bsp)$/i, "")
|
||||||
|
.toLowerCase()
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
if (normalized.startsWith("surf_")) {
|
||||||
|
gdriveMap.set(normalized, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
console.log("\n[>>] Debug - First 5 GDrive files (normalized):");
|
||||||
|
Array.from(gdriveMap.keys()).slice(0, 5).forEach(name => {
|
||||||
|
console.log(` - "${name}"`);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("\n[>>] Debug - First 5 missing maps:");
|
||||||
|
manifest.missing.slice(0, 5).forEach(name => {
|
||||||
|
console.log(` - "${name.toLowerCase().trim()}"`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check which missing maps are available in GDrive
|
||||||
|
const availableMaps = new Map<string, GDriveFile>();
|
||||||
|
|
||||||
|
for (const mapName of manifest.missing) {
|
||||||
|
const normalized = mapName.toLowerCase().trim();
|
||||||
|
|
||||||
|
if (gdriveMap.has(normalized)) {
|
||||||
|
availableMaps.set(mapName, gdriveMap.get(normalized)!);
|
||||||
|
} else {
|
||||||
|
manifest.notInGDrive.push(mapName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum total download size
|
||||||
|
let totalBytes = 0;
|
||||||
|
for (const file of availableMaps.values()) {
|
||||||
|
const size = parseInt(file.size, 10);
|
||||||
|
if (!isNaN(size)) totalBytes += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`\n[STATS] Cross-reference results:`);
|
||||||
|
console.log(` [OK] Available to download: ${availableMaps.size} maps`);
|
||||||
|
console.log(` [X] Not in Google Drive: ${manifest.notInGDrive.length} maps`);
|
||||||
|
console.log(` Total download size: ${formatBytes(totalBytes)}`);
|
||||||
|
|
||||||
|
if (manifest.notInGDrive.length > 0) {
|
||||||
|
console.log(`\n[!] Maps not found in Google Drive (showing first 10):`);
|
||||||
|
manifest.notInGDrive.slice(0, 10).forEach(map => {
|
||||||
|
console.log(` - ${map}`);
|
||||||
|
});
|
||||||
|
if (manifest.notInGDrive.length > 10) {
|
||||||
|
console.log(` ... and ${manifest.notInGDrive.length - 10} more`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableMaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cross-device safe move (copy + delete)
|
||||||
|
export async function moveFile(src: string, dest: string): Promise<void> {
|
||||||
|
try {
|
||||||
|
await Deno.rename(src, dest);
|
||||||
|
} catch (e) {
|
||||||
|
if ((e as Error).message.includes("os error 18")) {
|
||||||
|
await Deno.copyFile(src, dest);
|
||||||
|
await Deno.remove(src);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function downloadAndExtractMaps(
|
||||||
|
client: GoogleDriveClient,
|
||||||
|
mapsToDownload: Map<string, GDriveFile>,
|
||||||
|
config: DownloadConfig,
|
||||||
|
): Promise<{ success: number; failed: number }> {
|
||||||
|
console.log(`\n[DL] Downloading ${mapsToDownload.size} maps...`);
|
||||||
|
|
||||||
|
await Deno.mkdir(config.tempDir, { recursive: true });
|
||||||
|
|
||||||
|
const stats = { success: 0, failed: 0 };
|
||||||
|
let completed = 0;
|
||||||
|
|
||||||
|
const entries = Array.from(mapsToDownload.entries());
|
||||||
|
|
||||||
|
for (let i = 0; i < entries.length; i += config.concurrency) {
|
||||||
|
const batch = entries.slice(i, i + config.concurrency);
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
batch.map(async ([mapName, gdriveFile]) => {
|
||||||
|
try {
|
||||||
|
completed++;
|
||||||
|
console.log(`[${completed}/${mapsToDownload.size}] Downloading ${mapName}...`);
|
||||||
|
|
||||||
|
const archivePath = join(config.tempDir, gdriveFile.name);
|
||||||
|
const tempBspPath = join(config.tempDir, `${mapName}.bsp`);
|
||||||
|
const bz2Path = join(config.mapsDir, `${mapName}.bsp.bz2`);
|
||||||
|
|
||||||
|
await client.downloadFile(gdriveFile.id, archivePath);
|
||||||
|
|
||||||
|
if (gdriveFile.name.endsWith(".rar")) {
|
||||||
|
await extractRAR(archivePath, mapName, config.tempDir, config.tempDir);
|
||||||
|
await Deno.remove(archivePath);
|
||||||
|
} else if (gdriveFile.name.endsWith(".bz2")) {
|
||||||
|
await decompressBZ2(archivePath, tempBspPath);
|
||||||
|
await Deno.remove(archivePath);
|
||||||
|
} else if (gdriveFile.name.endsWith(".zip")) {
|
||||||
|
await extractZIP(archivePath, mapName, config.tempDir, config.tempDir);
|
||||||
|
await Deno.remove(archivePath);
|
||||||
|
} else if (gdriveFile.name.endsWith(".bsp")) {
|
||||||
|
await moveFile(archivePath, tempBspPath);
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unknown archive format: ${gdriveFile.name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await verifyBSP(tempBspPath);
|
||||||
|
await compressBSP(tempBspPath, bz2Path);
|
||||||
|
await Deno.remove(tempBspPath);
|
||||||
|
|
||||||
|
stats.success++;
|
||||||
|
console.log(` [OK] ${mapName} downloaded and compressed`);
|
||||||
|
} catch (error) {
|
||||||
|
stats.failed++;
|
||||||
|
console.error(` [X] Failed to download ${mapName}: ${(error as Error).message}`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function extractRAR(archivePath: string, mapName: string, destDir: string, tempDir: string): Promise<void> {
|
||||||
|
const tempExtractDir = join(tempDir, `extract_${mapName}`);
|
||||||
|
await Deno.mkdir(tempExtractDir, { recursive: true });
|
||||||
|
|
||||||
|
const process = new Deno.Command("unar", {
|
||||||
|
args: ["-f", "-o", tempExtractDir, archivePath],
|
||||||
|
stdout: "piped",
|
||||||
|
stderr: "piped",
|
||||||
|
});
|
||||||
|
|
||||||
|
const { code, stderr } = await process.output();
|
||||||
|
|
||||||
|
if (code !== 0) {
|
||||||
|
const errorMsg = new TextDecoder().decode(stderr);
|
||||||
|
throw new Error(`unar failed: ${errorMsg}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bspFile = await findBSPFile(tempExtractDir, mapName);
|
||||||
|
|
||||||
|
if (!bspFile) {
|
||||||
|
throw new Error(`No BSP file found in archive for ${mapName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await moveFile(bspFile, join(destDir, `${mapName}.bsp`));
|
||||||
|
await Deno.remove(tempExtractDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function extractZIP(archivePath: string, mapName: string, destDir: string, tempDir: string): Promise<void> {
|
||||||
|
const tempExtractDir = join(tempDir, `extract_${mapName}`);
|
||||||
|
await Deno.mkdir(tempExtractDir, { recursive: true });
|
||||||
|
|
||||||
|
const process = new Deno.Command("unzip", {
|
||||||
|
args: ["-o", archivePath, "-d", tempExtractDir],
|
||||||
|
stdout: "piped",
|
||||||
|
stderr: "piped",
|
||||||
|
});
|
||||||
|
|
||||||
|
const { code, stderr } = await process.output();
|
||||||
|
|
||||||
|
if (code !== 0) {
|
||||||
|
const errorMsg = new TextDecoder().decode(stderr);
|
||||||
|
throw new Error(`unzip failed: ${errorMsg}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bspFile = await findBSPFile(tempExtractDir, mapName);
|
||||||
|
|
||||||
|
if (!bspFile) {
|
||||||
|
throw new Error(`No BSP file found in archive for ${mapName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await moveFile(bspFile, join(destDir, `${mapName}.bsp`));
|
||||||
|
await Deno.remove(tempExtractDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function decompressBZ2(archivePath: string, outputPath: string): Promise<void> {
|
||||||
|
const process = new Deno.Command("bunzip2", {
|
||||||
|
args: ["-c", archivePath],
|
||||||
|
stdout: "piped",
|
||||||
|
});
|
||||||
|
|
||||||
|
const { code, stdout } = await process.output();
|
||||||
|
|
||||||
|
if (code !== 0) {
|
||||||
|
throw new Error(`bunzip2 failed with exit code ${code}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Deno.writeFile(outputPath, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function findBSPFile(dir: string, mapName: string): Promise<string | null> {
|
||||||
|
for await (const entry of Deno.readDir(dir)) {
|
||||||
|
const fullPath = join(dir, entry.name);
|
||||||
|
|
||||||
|
if (entry.isFile && entry.name.endsWith(".bsp")) {
|
||||||
|
const baseName = entry.name.replace(/\.bsp$/i, "").toLowerCase();
|
||||||
|
if (baseName === mapName.toLowerCase()) {
|
||||||
|
return fullPath;
|
||||||
|
}
|
||||||
|
} else if (entry.isDirectory) {
|
||||||
|
const found = await findBSPFile(fullPath, mapName);
|
||||||
|
if (found) return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function verifyBSP(bspPath: string): Promise<void> {
|
||||||
|
const file = await Deno.open(bspPath, { read: true });
|
||||||
|
|
||||||
|
try {
|
||||||
|
const buffer = new Uint8Array(4);
|
||||||
|
await file.read(buffer);
|
||||||
|
|
||||||
|
const signature = new TextDecoder().decode(buffer);
|
||||||
|
|
||||||
|
if (signature !== "VBSP") {
|
||||||
|
throw new Error(`Invalid BSP signature: ${signature}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const stat = await Deno.stat(bspPath);
|
||||||
|
if (stat.size < 1024 * 1024) {
|
||||||
|
throw new Error("BSP file too small - possibly corrupted");
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function compressBSP(bspPath: string, bz2Path: string): Promise<void> {
|
||||||
|
const process = new Deno.Command("bzip2", {
|
||||||
|
args: ["-c", bspPath],
|
||||||
|
stdout: "piped",
|
||||||
|
});
|
||||||
|
const { code, stdout } = await process.output();
|
||||||
|
if (code !== 0) throw new Error(`bzip2 failed with exit code ${code}`);
|
||||||
|
await Deno.writeFile(bz2Path, stdout);
|
||||||
|
}
|
||||||
Executable
+116
@@ -0,0 +1,116 @@
|
|||||||
|
import { parse } from "https://deno.land/std@0.210.0/flags/mod.ts";
|
||||||
|
import {
|
||||||
|
GoogleDriveClient,
|
||||||
|
getLocalMaps,
|
||||||
|
buildManifest,
|
||||||
|
searchGDriveForMaps,
|
||||||
|
downloadAndExtractMaps,
|
||||||
|
} from "./common.ts";
|
||||||
|
|
||||||
|
const CONFIG = {
|
||||||
|
sqlUrl: "https://raw.githubusercontent.com/bhopppp/Shavit-Surf-Timer/master/sql/surfzones.sql",
|
||||||
|
mapsDir: Deno.env.get("MAPS_DIR") || "/home/ntr/surf_megastructure/data/cssds/cstrike/maps",
|
||||||
|
tempDir: Deno.env.get("TEMP_DIR") || "/tmp/mapsdl",
|
||||||
|
serviceAccountPath: Deno.env.get("GOOGLE_APPLICATION_CREDENTIALS") || "./credentials/service-account.json",
|
||||||
|
gdriveFolders: {
|
||||||
|
aToK: "17QJ-Wzk9eMHKZqX227HkPCg9_Vmrf9h-",
|
||||||
|
lToZ: "1f3Oe65BngrSxTPKHAt6MEwK0FTsDbUsO",
|
||||||
|
},
|
||||||
|
concurrency: 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
async function downloadSurfZonesSQL(): Promise<string> {
|
||||||
|
console.log(`[DL] Downloading SQL file from ${CONFIG.sqlUrl}...`);
|
||||||
|
const response = await fetch(CONFIG.sqlUrl);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed to download SQL: ${response.statusText}`);
|
||||||
|
}
|
||||||
|
return await response.text();
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractMapNamesFromSQL(sqlContent: string): Set<string> {
|
||||||
|
console.log("[>>] Extracting map names from SQL...");
|
||||||
|
|
||||||
|
const mapNames = new Set<string>();
|
||||||
|
const insertRegex = /INSERT INTO\s+`?(?:map)?zones`?\s+.*?VALUES\s*\((.*?)\);/gis;
|
||||||
|
|
||||||
|
for (const match of sqlContent.matchAll(insertRegex)) {
|
||||||
|
const valuesSection = match[1];
|
||||||
|
const stringRegex = /'([^']+)'/g;
|
||||||
|
|
||||||
|
for (const stringMatch of valuesSection.matchAll(stringRegex)) {
|
||||||
|
const value = stringMatch[1];
|
||||||
|
if (value.startsWith("surf_")) {
|
||||||
|
mapNames.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[OK] Found ${mapNames.size} unique surf maps in SQL`);
|
||||||
|
return mapNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const args = parse(Deno.args);
|
||||||
|
|
||||||
|
console.log("[*] Surf Map Downloader\n");
|
||||||
|
console.log("━".repeat(60));
|
||||||
|
|
||||||
|
try {
|
||||||
|
const sqlContent = await downloadSurfZonesSQL();
|
||||||
|
const requiredMaps = extractMapNamesFromSQL(sqlContent);
|
||||||
|
|
||||||
|
const localMaps = await getLocalMaps(CONFIG.mapsDir);
|
||||||
|
const manifest = buildManifest(requiredMaps, localMaps);
|
||||||
|
|
||||||
|
console.log("\n[INFO] Summary:");
|
||||||
|
console.log(` Total maps in SQL: ${manifest.total}`);
|
||||||
|
console.log(` Already downloaded: ${manifest.found}`);
|
||||||
|
console.log(` Missing: ${manifest.missing.length}`);
|
||||||
|
|
||||||
|
if (manifest.missing.length === 0) {
|
||||||
|
console.log("\n[*] All maps are already downloaded!");
|
||||||
|
Deno.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = new GoogleDriveClient();
|
||||||
|
await client.authenticate(CONFIG.serviceAccountPath);
|
||||||
|
|
||||||
|
const mapsToDownload = await searchGDriveForMaps(client, manifest, CONFIG.gdriveFolders, args.verbose === true);
|
||||||
|
|
||||||
|
if (mapsToDownload.size === 0) {
|
||||||
|
console.log("\n[!] No maps available to download from Google Drive");
|
||||||
|
Deno.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args["dry-run"]) {
|
||||||
|
console.log("\n[END] Dry run complete. Use without --dry-run to download.");
|
||||||
|
Deno.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const stats = await downloadAndExtractMaps(client, mapsToDownload, {
|
||||||
|
mapsDir: CONFIG.mapsDir,
|
||||||
|
tempDir: CONFIG.tempDir,
|
||||||
|
concurrency: CONFIG.concurrency,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("\n" + "━".repeat(60));
|
||||||
|
console.log("[OK] Download Complete!\n");
|
||||||
|
console.log(`[DL] Successfully downloaded: ${stats.success} maps`);
|
||||||
|
console.log(`[X] Failed: ${stats.failed} maps`);
|
||||||
|
console.log(`[!] Not in Google Drive: ${manifest.notInGDrive.length} maps`);
|
||||||
|
console.log("━".repeat(60));
|
||||||
|
|
||||||
|
Deno.exit(stats.failed > 0 ? 1 : 0);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`\n[X] Fatal error: ${(error as Error).message}`);
|
||||||
|
if (args.verbose) {
|
||||||
|
console.error((error as Error).stack);
|
||||||
|
}
|
||||||
|
Deno.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (import.meta.main) {
|
||||||
|
main();
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
import { parse } from "https://deno.land/std@0.210.0/flags/mod.ts";
|
||||||
|
import {
|
||||||
|
GoogleDriveClient,
|
||||||
|
getLocalMaps,
|
||||||
|
buildManifest,
|
||||||
|
searchGDriveForMaps,
|
||||||
|
downloadAndExtractMaps,
|
||||||
|
} from "./common.ts";
|
||||||
|
|
||||||
|
function loadMapList(): string[] {
|
||||||
|
const listFile = Deno.env.get("MAPS_LIST_FILE");
|
||||||
|
if (listFile) {
|
||||||
|
const text = Deno.readTextFileSync(listFile);
|
||||||
|
return text.split("\n").map(s => s.replace(/\/\/.*/, "").trim()).filter(Boolean);
|
||||||
|
}
|
||||||
|
return (Deno.env.get("MAPS_WISHLIST") || "").split("\n").map(s => s.trim()).filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
const CONFIG = {
|
||||||
|
maps: loadMapList(),
|
||||||
|
mapsDir: Deno.env.get("MAPS_DIR") || "/home/ntr/surf_megastructure/data/cssds/cstrike/maps",
|
||||||
|
tempDir: Deno.env.get("TEMP_DIR") || "/tmp/mapsdl",
|
||||||
|
serviceAccountPath: Deno.env.get("GOOGLE_APPLICATION_CREDENTIALS") || "./credentials/service-account.json",
|
||||||
|
gdriveFolders: {
|
||||||
|
aToK: "17QJ-Wzk9eMHKZqX227HkPCg9_Vmrf9h-",
|
||||||
|
lToZ: "1f3Oe65BngrSxTPKHAt6MEwK0FTsDbUsO",
|
||||||
|
},
|
||||||
|
concurrency: 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const args = parse(Deno.args);
|
||||||
|
|
||||||
|
console.log("[*] Surf Map Downloader\n");
|
||||||
|
console.log("━".repeat(60));
|
||||||
|
|
||||||
|
try {
|
||||||
|
const requiredMaps = new Set(CONFIG.maps);
|
||||||
|
console.log(`[OK] Wishlist: ${requiredMaps.size} maps`);
|
||||||
|
|
||||||
|
const localMaps = await getLocalMaps(CONFIG.mapsDir);
|
||||||
|
const manifest = buildManifest(requiredMaps, localMaps);
|
||||||
|
|
||||||
|
console.log("\n[INFO] Summary:");
|
||||||
|
console.log(` Total maps in wishlist: ${manifest.total}`);
|
||||||
|
console.log(` Already downloaded: ${manifest.found}`);
|
||||||
|
console.log(` Missing: ${manifest.missing.length}`);
|
||||||
|
|
||||||
|
if (manifest.missing.length === 0) {
|
||||||
|
console.log("\n[*] All maps are already downloaded!");
|
||||||
|
Deno.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = new GoogleDriveClient();
|
||||||
|
await client.authenticate(CONFIG.serviceAccountPath);
|
||||||
|
|
||||||
|
const mapsToDownload = await searchGDriveForMaps(client, manifest, CONFIG.gdriveFolders, args.verbose === true);
|
||||||
|
|
||||||
|
if (mapsToDownload.size === 0) {
|
||||||
|
console.log("\n[!] No maps available to download from Google Drive");
|
||||||
|
Deno.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args["dry-run"]) {
|
||||||
|
console.log("\n[END] Dry run complete. Use without --dry-run to download.");
|
||||||
|
Deno.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const stats = await downloadAndExtractMaps(client, mapsToDownload, {
|
||||||
|
mapsDir: CONFIG.mapsDir,
|
||||||
|
tempDir: CONFIG.tempDir,
|
||||||
|
concurrency: CONFIG.concurrency,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("\n" + "━".repeat(60));
|
||||||
|
console.log("[OK] Download Complete!\n");
|
||||||
|
console.log(`[DL] Successfully downloaded: ${stats.success} maps`);
|
||||||
|
console.log(`[X] Failed: ${stats.failed} maps`);
|
||||||
|
console.log(`[!] Not in Google Drive: ${manifest.notInGDrive.length} maps`);
|
||||||
|
console.log("━".repeat(60));
|
||||||
|
|
||||||
|
Deno.exit(stats.failed > 0 ? 1 : 0);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`\n[X] Fatal error: ${(error as Error).message}`);
|
||||||
|
if (args.verbose) {
|
||||||
|
console.error((error as Error).stack);
|
||||||
|
}
|
||||||
|
Deno.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (import.meta.main) {
|
||||||
|
main();
|
||||||
|
}
|
||||||
@@ -2,7 +2,13 @@
|
|||||||
"folders":
|
"folders":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"path": "."
|
"path": ".",
|
||||||
}
|
},
|
||||||
]
|
{
|
||||||
|
"path": "C:\\Users\\ntr\\code\\ntwl\\surf",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "h:ome\\ntr\\ntwl\\surf",
|
||||||
|
},
|
||||||
|
],
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user