Constellation CS 1.6 — 6 serveurs ReHLDS avec Pterodactyl Panel
Constellation CS 1.6 — 12 serveurs ReHLDS avec Pterodactyl Panel
Neuvième étape : déployer une constellation de serveurs Counter-Strike 1.6
(Deathmatch, GunGame, Deathrun, Hide&Seek, Kreedz, AUTOMIX 5v5, Surf, CS 1.0 Vintage Beta, Paintball, Furien, BaseBuilder) avec le stack moderne
ReHLDS, gérés par Pterodactyl Panel sur le serveur centralisé.
Paramètres à personnaliser
Remplacez chaque {{VARIABLE}} par vos propres valeurs avant d’utiliser ce guide.
| Variable | Description | Exemple |
|---|---|---|
{{IP_NOUVEAU}} |
IP du serveur | 198.51.100.20 |
{{HOSTNAME_NOUVEAU}} |
Hostname du serveur | ns7654321 |
{{DOMAINE_GAMING}} |
Domaine gaming | exemple-gaming.fr |
{{DB_PASSWORD}} |
Mot de passe MariaDB | S3cur3P@ss! |
{{TAG_CLAN}} |
Tag clan principal (noms serveurs) | MyClan |
{{NOM_COMMUNAUTE}} |
Nom communauté (noms serveurs) | MyServer |
{{TAG_CLAN_2}} |
Tag clan secondaire (Kreedz) | KZTeam |
{{USER_VESTA}} |
Utilisateur MyVestaCP | admin |
Contexte
Le réseau {{DOMAINE_GAMING}} proposait historiquement 8 serveurs CS 1.6
(DM, Zombie, War×2, FFA, Test, KZ, Training) sur l’ancien serveur dédié.
On reconstruit la constellation en version moderne sur le nouveau serveur
({{IP_NOUVEAU}}), avec une architecture Docker gérée par
Pterodactyl Panel.
Les 12 serveurs cibles
| Serveur | Mode | Port UDP | Maps | Plugins clés |
|---|---|---|---|---|
| Deathmatch | FFA respawn instantané | 27015 | ~60 (aim_ + fy_) | ReDeathmatch, YaPB bots, Quake Sounds, Double Jump, Parachute |
| GunGame | Progression d’armes | 27016 | ~39 (gg_) | GunGame 2.13c turbo/DM, Double Jump, BotManager v2 |
| Deathrun | Parcours piégés | 27017 | ~51 (deathrun_) | DeathrunManager 3.0.3a, Semiclip |
| Hide & Seek | Cache-cache | 27018 | Maps HNS | HNS plugin, No Boost, Semiclip |
| Kreedz | KZ climbing + bhop | 27019 | 1 694 (kz_ + bhop_) | Kreedz AMXX 1.30, mpbhop, MapManagerModular (RTV + nominations) |
| AUTOMIX 5v5 | Compétitif MR15 5v5 | 27020 | de_dust2, de_inferno, de_nuke, de_train, de_cbble | PugMod-AMXX v4.0.8 (plugin AMXX) |
| Surf | Surf maps + timer | 27022 | ~45 (surf_) | uSurf (timer, checkpoints), surf_olympics (top times), Speedometer, Bunnyhop, No Fall Damage |
| CS 1.0 Vintage Beta | Vintage nostalgie (à venir) | 27021 | Maps classiques | YaPB bots (placeholder) |
| Paintball | Paintball (armes custom, sprint, vendetta) | 27023 | Maps paintball | PaintBall Refresh, Double Jump, Parachute, BotManager v2, AQS |
| Furien | T=assassins couteau rapides, CT=armes | 27024 | Maps furien | Furien Pack, Auto Bhop, Double Jump, Parachute, Deagle 1 balle, NadeModes, BotManager v2, AQS |
| BaseBuilder | Build & fight (CT vs Zombies) | 27025 | Maps basebuilder (bb_) | ProBaseBuilder, CT Unlimited Ammo, Buy Menu, Knife OneShot, BotManager v2, AQS |
Stack technique commun : chaque serveur utilise le même socle —
ReHLDS + ReGameDLL + Metamod-R + AMX Mod X + ReAPI + Reunion.
Seuls les plugins spécifiques au mode de jeu, les maps et les configs diffèrent.
Pourquoi Pterodactyl Panel ?
- Interface web moderne pour gérer les 12 serveurs (console live, file manager, SFTP)
- Docker natif — chaque serveur est un conteneur isolé
- Upload de maps via le file manager web (support ZIP + extraction)
- Édition des configs directement dans le navigateur (server.cfg, mapcycle.txt, plugins.ini)
- Gestion des utilisateurs — donner accès à un admin de serveur sans accès SSH
- SFTP intégré pour les transferts massifs de maps (Kreedz : 1 694 maps)
Architecture cible : Pterodactyl (panel web) + Wings (daemon Docker)
sur le même serveur. Le panel gère la création, le démarrage et l’arrêt
des conteneurs via l’API Wings.
1) Le stack ReHLDS moderne
Contrairement au HLDS vanilla (plus maintenu par Valve), le stack ReHLDS est
activement développé par la communauté et apporte sécurité,
performances et une API étendue pour les plugins.
| Composant | Version | Rôle | Téléchargement |
|---|---|---|---|
| ReHLDS | 3.14.0.857+ | Moteur serveur (remplace hlds_linux) |
GitHub |
| ReGameDLL | 5.28.0.756+ | Logique de jeu (remplace cs.so / mp.dll) |
GitHub |
| Metamod-R | 1.3.0.149+ | Loader de plugins (version optimisée pour ReHLDS) | GitHub |
| AMX Mod X | 1.10.0.5461+ | Framework de scripting pour plugins (.amxx) | amxmodx.org |
| ReAPI | 5.26.0.338+ | API AMX Mod X pour ReHLDS/ReGameDLL | GitHub |
| Reunion | 0.2.0.25+ | Support clients Steam + non-Steam | GitHub |
Metamod-R ≠ Metamod vanilla.
Metamod-R est spécifiquement conçu pour ReHLDS (API 3.1+) et n’est
pas compatible avec le HLDS vanilla de Valve.
Ne pas les confondre.
Toujours utiliser les dernières versions.
Les liens ci-dessus pointent vers les pages de releases GitHub.
Vérifier les dernières versions avant l’installation —
de nouvelles releases sortent régulièrement avec des correctifs de sécurité.
2) Prérequis sur le serveur
Le serveur ({{IP_NOUVEAU}}) doit avoir Docker et Docker Compose installés
(déjà le cas si Odoo, TeamSpeak, etc. tournent déjà en Docker).
2.1 Vérifier Docker
|
1 2 |
docker --version docker compose version |
Aucune autre dépendance à installer.
PHP, MariaDB, Redis — tout est embarqué dans les conteneurs Docker.
Le serveur utilise déjà MyVestaCP avec Nginx : on créera un vhost
reverse proxy pour exposer le panel sur panel.{{DOMAINE_GAMING}}.
3) Déployer Pterodactyl en Docker (Panel + Wings)
Toute la stack Pterodactyl tourne en Docker : Panel (PHP/Laravel),
MariaDB, Redis et Wings (daemon Go).
Zéro installation sur le serveur hôte — juste un docker-compose.yml.
3.1 Créer l’arborescence
|
1 2 3 4 5 |
mkdir -p /home/docker/pterodactyl mkdir -p /home/docker/pterodactyl/config mkdir -p /home/docker/pterodactyl/data/{archives,backups,volumes} mkdir -p /home/docker/pterodactyl/logs mkdir -p /home/docker/pterodactyl/tmp |
Chemins identiques hôte/conteneur :
Wings crée les conteneurs de jeux directement sur le Docker de l’hôte
via le socket. Les volumes de données (data/, logs/,
tmp/) sont montés avec le même chemin
des deux côtés pour que les serveurs de jeux trouvent leurs fichiers.
Seul config/ est remapé vers /etc/pterodactyl/
dans le conteneur (les serveurs de jeux n’y accèdent pas).
3.2 docker-compose.yml
|
1 |
nano /home/docker/pterodactyl/docker-compose.yml |
Coller le contenu suivant :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
services: # --- Base de donnees MariaDB --- database: image: mariadb:10.11 restart: always command: --default-authentication-plugin=mysql_native_password volumes: - database:/var/lib/mysql environment: MYSQL_PASSWORD: "{{DB_PASSWORD}}" MYSQL_ROOT_PASSWORD: "{{DB_PASSWORD}}" MYSQL_DATABASE: "panel" MYSQL_USER: "pterodactyl" networks: - pterodactyl # --- Cache Redis --- cache: image: redis:alpine restart: always networks: - pterodactyl # --- Pterodactyl Panel --- panel: image: ghcr.io/pterodactyl/panel:latest restart: always extra_hosts: - "panel.{{DOMAINE_GAMING}}:host-gateway" ports: - "127.0.0.1:8880:80" volumes: - panel-var:/app/var/ - panel-nginx:/etc/nginx/http.d/ - panel-logs:/app/storage/logs environment: APP_URL: "https://panel.{{DOMAINE_GAMING}}" APP_TIMEZONE: "Europe/Paris" APP_SERVICE_AUTHOR: "admin@{{DOMAINE_GAMING}}" APP_ENVIRONMENT_ONLY: "false" TRUSTED_PROXIES: "*" DB_PASSWORD: "{{DB_PASSWORD}}" DB_HOST: "database" DB_PORT: "3306" DB_DATABASE: "panel" DB_USERNAME: "pterodactyl" REDIS_HOST: "cache" CACHE_DRIVER: "redis" SESSION_DRIVER: "redis" QUEUE_CONNECTION: "redis" MAIL_FROM: "noreply@{{DOMAINE_GAMING}}" MAIL_DRIVER: "smtp" MAIL_HOST: "mail" MAIL_PORT: "587" MAIL_USERNAME: "" MAIL_PASSWORD: "" MAIL_ENCRYPTION: "true" depends_on: - database - cache networks: - pterodactyl # --- Pterodactyl Wings --- wings: image: ghcr.io/pterodactyl/wings:latest restart: always privileged: true tty: true ports: - "8543:8080" - "2022:2022" volumes: - /var/run/docker.sock:/var/run/docker.sock - /var/lib/docker/containers/:/var/lib/docker/containers/ - /home/docker/pterodactyl/config/:/etc/pterodactyl/ - /home/docker/pterodactyl/data/:/home/docker/pterodactyl/data/ - /home/docker/pterodactyl/logs/:/home/docker/pterodactyl/logs/ - /home/docker/pterodactyl/tmp/:/home/docker/pterodactyl/tmp/ - /run/wings:/run/wings - /home/{{USER_VESTA}}/conf/web/ssl.panel.{{DOMAINE_GAMING}}.pem:/etc/ssl/panel.pem:ro - /home/{{USER_VESTA}}/conf/web/ssl.panel.{{DOMAINE_GAMING}}.key:/etc/ssl/panel.key:ro environment: TZ: "Europe/Paris" WINGS_UID: 988 WINGS_GID: 988 WINGS_USERNAME: pterodactyl depends_on: - panel networks: - pterodactyl networks: pterodactyl: driver: bridge volumes: database: panel-var: panel-nginx: panel-logs: |
Mots de passe : les mots de passe MySQL sont déjà renseignés.
MYSQL_PASSWORD (dans database) et DB_PASSWORD
(dans panel) doivent être identiques.
Penser à les anonymiser avant de partager ce fichier.
extra_hosts obligatoire : la ligne
extra_hosts: ["panel.{{DOMAINE_GAMING}}:host-gateway"] dans le service
panel est indispensable. Sans elle, le panel ne peut pas
contacter Wings : depuis l’intérieur d’un conteneur Docker, l’accès à l’IP
externe de l’hôte ({{IP_NOUVEAU}}) sur un port mappé est bloqué
(problème de hairpin NAT). Le mot-clé host-gateway
(Docker 20.10+) redirige le FQDN vers l’IP du bridge Docker de l’hôte,
permettant au panel d’atteindre Wings via le port mapping 8543:8080.
Chemins Wings obligatoires : les volumes data/,
logs/ et tmp/ utilisent le même chemin
sur l’hôte et dans le conteneur (/home/docker/pterodactyl/data/
→ /home/docker/pterodactyl/data/).
C’est obligatoire car Wings crée les conteneurs de serveurs de jeux directement
sur le Docker de l’hôte via le socket. Seul config/ est remapé.
Port du panel : le panel écoute sur 127.0.0.1:8880
(accessible uniquement en local). Il sera exposé sur Internet via un
reverse proxy Nginx de MyVestaCP (section 3.5).
3.3 Démarrer la stack
|
1 2 3 4 5 |
cd /home/docker/pterodactyl docker compose up -d # Vérifier que tout tourne docker compose ps |
3.4 Initialiser la base de données
Bug connu : l’image Docker du panel Pterodactyl embarque
un client MariaDB 11.4 qui exige SSL par défaut, mais le conteneur
MariaDB 10.11 n’a pas SSL activé. Résultat : les migrations Laravel
échouent avec SSL is required but the server does not support it.
Il faut charger le schéma manuellement via le conteneur database
(connexion locale, pas de SSL) avant de lancer les migrations.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# 1. Attendre ~30 secondes que MariaDB soit prête, puis charger le schéma # On extrait le fichier SQL depuis l'image panel et on l'injecte # directement dans le conteneur database (pas de problème SSL en local) docker run --rm --entrypoint cat \ ghcr.io/pterodactyl/panel:latest \ /app/database/schema/mysql-schema.sql \ | docker compose exec -T database mariadb -u root -p{{DB_PASSWORD}} panel # 2. Créer la table settings (absente du schéma mais requise par le panel) docker compose exec database mariadb -u root -p{{DB_PASSWORD}} panel -e " CREATE TABLE IF NOT EXISTS settings ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, `key` VARCHAR(191) NOT NULL, value TEXT NOT NULL, PRIMARY KEY (id), UNIQUE KEY settings_key_unique (`key`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; " # 3. Lancer les migrations restantes + seed docker compose exec panel php artisan migrate --seed --force # 4. Redémarrer le panel pour prendre en compte la base complète docker compose restart panel |
Pourquoi trois étapes ?
Le fichier mysql-schema.sql contient la structure de la base
mais ne crée pas la table settings (bug connu).
Sans cette table, le panel affiche des erreurs 500 sur certaines opérations.
php artisan migrate applique ensuite les migrations incrémentales
et le --seed insère les données de base (nests, eggs).
Le redémarrage du panel est nécessaire pour qu’il prenne en compte
les nouvelles tables.
Ne JAMAIS relancer le chargement du schéma après l’initialisation !
Le fichier mysql-schema.sql fait des DROP TABLE avant
de recréer les tables. Le relancer efface toutes les données :
utilisateurs, nodes, serveurs, allocations. Cette commande ne doit être
exécutée qu’une seule fois, lors de la première installation.
Si la base est corrompue, préférer créer les tables manquantes individuellement
plutôt que de tout recharger.
3.5 Créer le premier utilisateur admin
|
1 2 3 4 5 6 7 8 9 |
# Créer un compte admin dans le panel docker compose exec panel php artisan p:user:make # Répondre aux questions : # Is this user an administrator? → yes # Email → admin@{{DOMAINE_GAMING}} # Username → admin # First Name / Last Name → au choix # Password → mot de passe fort |
3.6 Reverse proxy Nginx (MyVestaCP)
Le panel écoute sur 127.0.0.1:8880 (local uniquement).
Pour l’exposer sur panel.{{DOMAINE_GAMING}}, on crée un template
Nginx reverse proxy dans MyVestaCP, comme pour ownCloud.
3.6.1 Créer le domaine dans MyVestaCP
- Se connecter à MyVestaCP sur
https://{{IP_NOUVEAU}}:8083 - Aller dans WEB → Add Web Domain
- Domaine :
panel.{{DOMAINE_GAMING}} - Cocher DNS Support
- Ne pas cocher « Enable SSL » pour l’instant
3.6.2 Créer le template HTTP (pterodactyl-8880.tpl)
|
1 |
nano /usr/local/vesta/data/templates/web/nginx/pterodactyl-8880.tpl |
Coller :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
server { listen %ip%:%web_port%; server_name %domain_idn% %alias_idn%; client_max_body_size 100M; client_body_timeout 120s; send_timeout 100m; location / { proxy_pass http://127.0.0.1:8880; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 600s; proxy_send_timeout 600s; proxy_connect_timeout 75s; proxy_buffering off; proxy_request_buffering off; # WebSocket (console live Pterodactyl) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } |
3.6.3 Créer le template HTTPS (pterodactyl-8880.stpl)
|
1 |
nano /usr/local/vesta/data/templates/web/nginx/pterodactyl-8880.stpl |
Coller :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
server { listen %ip%:%web_ssl_port% ssl; server_name %domain_idn% %alias_idn%; ssl_certificate %ssl_pem%; ssl_certificate_key %ssl_key%; ssl_stapling on; ssl_stapling_verify on; client_max_body_size 100M; client_body_timeout 120s; send_timeout 100m; location / { proxy_pass http://127.0.0.1:8880; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_read_timeout 600s; proxy_send_timeout 600s; proxy_connect_timeout 75s; proxy_buffering off; proxy_request_buffering off; # WebSocket (console live Pterodactyl) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } |
WebSocket : les directives Upgrade et Connection
sont indispensables pour la console live de Pterodactyl,
qui utilise des WebSockets pour afficher les logs en temps réel.
3.6.4 Appliquer le template
Dans MyVestaCP → WEB → cliquer sur panel.{{DOMAINE_GAMING}} →
Edit → champ Nginx Template →
sélectionner pterodactyl-8880 → Save.
3.6.5 Vérifier les ports générés
|
1 2 3 |
# Vérifier que Nginx écoute sur 80/443 et non 8080/8443 head -3 /home/{{USER_VESTA}}/conf/web/panel.{{DOMAINE_GAMING}}.nginx.conf head -3 /home/{{USER_VESTA}}/conf/web/panel.{{DOMAINE_GAMING}}.nginx.ssl.conf |
Piège ports 8080/8443 : sur certaines configurations MyVestaCP,
les variables %web_port% et %web_ssl_port% se résolvent
en 8080 et 8443 (ports du backend Apache) au lieu de
80 et 443 (ports Nginx frontend).
Si c’est le cas, corriger manuellement :
|
1 2 3 4 5 6 |
# Corriger si les ports sont 8080/8443 au lieu de 80/443 sed -i 's/8080/80/' /home/{{USER_VESTA}}/conf/web/panel.{{DOMAINE_GAMING}}.nginx.conf sed -i 's/8443 ssl/443 ssl/' /home/{{USER_VESTA}}/conf/web/panel.{{DOMAINE_GAMING}}.nginx.ssl.conf # Vérifier et recharger Nginx nginx -t && systemctl restart nginx |
3.6.6 Tester l’accès
|
1 2 3 4 5 |
# Tester en local curl -I http://127.0.0.1:8880 # Tester via le reverse proxy (après DNS ou via fichier hosts) curl -I http://panel.{{DOMAINE_GAMING}} |
SSL : activer Let’s Encrypt via MyVestaCP pour
panel.{{DOMAINE_GAMING}} une fois le DNS propagé.
Le TRUSTED_PROXIES: "*" dans le docker-compose permet au panel
de détecter correctement HTTPS derrière le reverse proxy.
4) Configurer Wings (le node)
Wings tourne déjà dans Docker (section 3). Il faut maintenant le connecter au panel.
4.1 Créer la Location
Chaque node Pterodactyl doit être rattaché à une Location.
Il faut la créer avant le node.
- Se connecter au panel web (
https://panel.{{DOMAINE_GAMING}}) - Admin → Locations → Create New
- Short Code :
{{HOSTNAME_NOUVEAU}} - Description :
OVH VPS {{HOSTNAME_NOUVEAU}} - Gravelines(ou ce que vous voulez) - Create
4.2 Créer le node
- Admin → Nodes → Create New
- Remplir :
- Name :
{{HOSTNAME_NOUVEAU}} - Location : sélectionner
{{HOSTNAME_NOUVEAU}}(créé à l’étape 4.1) - FQDN :
panel.{{DOMAINE_GAMING}} - Communicate Over SSL :
Use SSL Connection(Wings écoute en HTTPS grâce aux certificats SSL montés dans le conteneur) - Behind Proxy :
Not Behind Proxy(Wings gère le SSL directement) - Daemon Server File Directory :
/home/docker/pterodactyl/data/volumes - Total Memory :
8192MiB - Memory Over-Allocation :
-1(désactive la vérification) - Total Disk Space :
50000MiB - Disk Over-Allocation :
-1(désactive la vérification) - Daemon Port :
8543 - Daemon SFTP Port :
2022
- Name :
- Sauvegarder
4.2.1 SSL sur Wings (obligatoire)
Le panel est en HTTPS. Le navigateur refuse les connexions WebSocket non chiffrées
(ws://) depuis une page HTTPS — c’est la politique
« Mixed Content » des navigateurs. Sans SSL sur Wings,
la console ne s’affiche pas et les boutons
Start/Stop/Restart ne fonctionnent pas.
La solution : activer SSL directement sur Wings en montant les certificats SSL
du domaine panel.{{DOMAINE_GAMING}} dans le conteneur Wings
(voir section 3.2, volumes ssl.panel.*.pem et ssl.panel.*.key)
et en activant ssl.enabled: true dans config.yml
(voir section 4.4).
Vérification : dans Admin → Nodes → Settings,
Communicate Over SSL doit être sur Use SSL Connection
et Behind Proxy sur Not Behind Proxy.
Si ces paramètres sont incorrects, le panel ne pourra pas communiquer avec Wings.
4.3 Récupérer le token du node
Le token d’authentification est stocké chiffré en base. Il faut le déchiffrer
pour le mettre dans le config.yml de Wings.
Ne pas utiliser l’onglet Configuration du panel
(préférer la méthode tinker ci-dessous, plus fiable
en cas de réinitialisation de l’APP_KEY).
|
1 2 3 4 5 6 7 8 |
# Récupérer l'UUID, le token_id et le token déchiffré du node docker compose exec panel php artisan tinker --execute=" use Pterodactyl\Models\Node; \$n = Node::find(1); echo 'uuid: ' . \$n->uuid . PHP_EOL; echo 'token_id: ' . \$n->daemon_token_id . PHP_EOL; echo 'token: ' . decrypt(\$n->getRawOriginal('daemon_token')) . PHP_EOL; " |
Pourquoi déchiffrer le token ?
Le panel chiffre le token avec l’APP_KEY Laravel avant de le stocker en base.
L’onglet Configuration du panel est censé le déchiffrer automatiquement,
mais il est plus fiable de le faire en ligne de commande avec tinker.
Si l’APP_KEY change (réinitialisation, migration), les anciens tokens
chiffrés deviennent illisibles (The payload is invalid)
et il faut recréer le node.
4.4 Déposer la configuration Wings
Le répertoire /home/docker/pterodactyl/config/ de l’hôte est monté
sur /etc/pterodactyl/ dans le conteneur Wings.
Générer le fichier complet avec les valeurs récupérées à l’étape précédente :
Ne JAMAIS supprimer le champ token !
Ce token permet l’authentification entre le panel et Wings.
Si ce champ est absent ou vide, Wings crashera au démarrage avec l’erreur
panic: jwt: HMAC key is empty.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# Dans /home/docker/pterodactyl/config/config.yml, modifier : # 1. Port API et SSL (8543 externe → 8080 interne Docker) api: host: 0.0.0.0 port: 8080 ssl: enabled: true cert: /etc/ssl/panel.pem key: /etc/ssl/panel.key # 2. Chemins système + désactiver machine_id (obligatoire en Docker) system: data: /home/docker/pterodactyl/data/volumes archive_directory: /home/docker/pterodactyl/data/archives backup_directory: /home/docker/pterodactyl/data/backups log_directory: /home/docker/pterodactyl/logs tmp_directory: /home/docker/pterodactyl/tmp machine_id: enabled: false # 4. Réseau Docker (sous-réseau dédié pour éviter les conflits) docker: network: interface: 172.28.0.1 dns: - 1.1.1.1 - 1.0.0.1 name: pterodactyl0 ispn: false driver: bridge network_mode: pterodactyl0 is_internal: false enable_icc: true interfaces: v4: subnet: 172.28.0.0/16 gateway: 172.28.0.1 |
Désactiver machine_id (obligatoire en Docker) :
par défaut, Wings 1.12+ active system.machine_id.enabled: true.
Cette fonctionnalité crée un fichier unique par serveur dans
/run/wings/machine-id/ et le monte (bind) dans chaque
conteneur de jeu. Problème : quand Wings tourne lui-même en Docker, ce chemin
n’existe que dans le conteneur Wings, pas sur l’hôte. Or les
conteneurs de jeux sont créés directement sur le Docker de l’hôte (via le socket),
donc le bind mount échoue avec
bind source path does not exist: /run/wings/machine-id/.
Les serveurs restent bloqués en « Installing » indéfiniment.
La solution : passer system.machine_id.enabled à false.
Volume /run/wings obligatoire en Docker-in-Docker :
même avec machine_id désactivé, Wings monte d’autres fichiers
depuis /run/wings/ dans les conteneurs de jeux (ex. :
/run/wings/etc/group). Sans le volume
- /run/wings:/run/wings dans le docker-compose.yml de Wings,
ces bind mounts échouent avec
bind source path does not exist: /run/wings/etc/group
et les serveurs restent bloqués en « Installing ».
Ce volume est déjà inclus dans la section 3.2 ci-dessus.
Conflit réseau Docker (Pool overlaps) :
Wings crée un réseau Docker pterodactyl0 pour isoler les conteneurs
de serveurs de jeux. Par défaut, il utilise un sous-réseau qui peut entrer en
conflit avec les réseaux Docker existants (Odoo, ownCloud, TeamSpeak, etc.).
Sans la section docker.network, Wings crashe au démarrage avec
Pool overlaps with other one on this address space.
Vérifier les sous-réseaux utilisés avec
docker network inspect $(docker network ls -q) --format '{{.Name}}: {{range .IPAM.Config}}{{.Subnet}}{{end}}'
et choisir un /16 libre (ici 172.28.0.0/16).
|
1 2 3 |
# Redémarrer Wings pour prendre en compte la config cd /home/docker/pterodactyl docker compose restart wings |
4.5 Vérifier la connexion Panel ↔ Wings
Dans le panel web : Admin → Nodes → le node doit afficher un
point vert avec la version de Wings. Si le point est rouge,
vérifier que le port 8543 est ouvert dans le firewall :
|
1 2 |
/usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 8543 TCP Pterodactyl-Wings /usr/local/vesta/bin/v-update-firewall |
5) Importer les eggs custom par mode de jeu
Un egg Pterodactyl définit comment installer et lancer un serveur de jeu.
Plutôt que d’utiliser un egg générique et d’installer les plugins manuellement,
on utilise un egg custom par mode de jeu. Chaque egg installe
automatiquement le stack complet (ReHLDS + plugins spécifiques au mode).
5.1 Les eggs disponibles
| Egg | Mode | Plugins installés automatiquement |
|---|---|---|
egg-cs16-deathmatch.json |
Deathmatch | ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion, ReDeathmatch, YaPB, AQS, QuickNoScopeD, Double Jump, Parachute, DM Welcome + maps FastDL |
egg-cs16-gungame.json |
GunGame | ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion, GunGame 2.13c, Double Jump, BotManager v2 + maps FastDL |
egg-cs16-deathrun.json |
Deathrun | ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion, DeathrunManager v3.0.3a, YaPB, BotManager, AutoBhop, Speedometer, Resetscore + maps FastDL |
egg-cs16-hns.json |
Hide & Seek | ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion, ReSemiclip (boosts CT), OpenHNS hns_mode, PreFog, HnsMatchSystem, NadeSlow, AutoBhop, Speedometer, Resetscore + maps FastDL |
egg-cs16-kreedz.json |
Kreedz / Bhop | ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion, ReSemiclip, Theggv/Kreedz v1.3.0 (timer, checkpoints, jumpstats, mpbhop), MapManagerModular v3.2.0 (RTV, nominations, vote), Resetscore + maps FastDL |
egg-cs16-war.json |
AUTOMIX 5v5 | ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion, PugMod-AMXX v4.0.8 (plugin AMXX) |
egg-cs16-surf.json |
Surf | ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion, uSurf, surf_olympics, Speedometer, Bunnyhop, No Fall Damage, Resetscore + maps FastDL |
egg-cs16-cs10.json |
CS 1.0 Vintage Beta | ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion, YaPB (placeholder — à venir) |
Stack commun à tous les eggs : chaque egg installe automatiquement
SteamCMD → HLDS (App ID 90) → ReHLDS → ReGameDLL → Metamod-R →
AMX Mod X → ReAPI → Reunion. Seuls les plugins spécifiques au mode,
le server.cfg et le mapcycle.txt diffèrent.
Les eggs DM, GunGame, Deathrun, HNS, Kreedz et Surf téléchargent aussi les maps custom depuis le FastDL
via wget récursif et génèrent le mapcycle.txt automatiquement
à partir des .bsp téléchargés.
Les 25 maps par défaut de HLDS (de_dust, cs_assault, as_oilrig…) sont
automatiquement exclues du mapcycle.txt. Pour DM et GG, de_dust2 est conservé.
L’egg WAR inclut les maps de compet (de_dust2, de_inferno, de_nuke, de_train, de_cbble) et configure PugMod-AMXX automatiquement.
L’egg Surf télécharge ~45 maps surf_ depuis le FastDL, compile 6 plugins surf et configure sv_airaccelerate 150.
Eggs testés et corrigés : les scripts d’installation intègrent
des corrections pour 7 pièges majeurs découverts lors du déploiement
(URLs AMX Mod X, architecture steamclient.so, permissions Docker, etc.).
Voir la section 12 pour le détail de chaque problème et sa solution.
steam_appid.txt et steamclient.so (obligatoires pour ReHLDS) :
ReHLDS a besoin du fichier steam_appid.txt contenant 10
(App ID de HLDS) à la racine du serveur, ainsi que de
.steam/sdk32/steamclient.so. Sans ces fichiers, le serveur crash
avec Unable to initialize Steam / SteamAPI_Init() failed.
Les eggs custom incluent déjà cette étape : le script d’installation copie
steamclient.so depuis SteamCMD (avec fallback téléchargement direct)
et génère steam_appid.txt automatiquement.
5.2 Importer dans le Panel
- Admin → Nests → Create New → nommer
Counter-Strike - Dans le nest « Counter-Strike » → Import Egg
- Uploader
egg-cs16-deathmatch.json - Répéter l’import pour chaque egg (GunGame, Deathrun, etc.)
Avantage des eggs custom : plus besoin d’accès SSH pour installer
les plugins. Il suffit de créer un serveur avec le bon egg et tout est installé
automatiquement. Un admin sans accès SSH peut gérer entièrement les serveurs
depuis le panel web.
6) Créer les 12 serveurs
Pour chaque serveur, depuis le panel web :
Admin → Servers → Create New.
6.1 Paramètres communs
| Paramètre | Valeur |
|---|---|
| Node | {{HOSTNAME_NOUVEAU}} |
| Nest | Counter-Strike |
| Egg | L’egg custom du mode (voir section 5) |
| Memory | 512 Mo (suffisant pour CS 1.6) |
| Disk | 2048 Mo (+ volume pour Kreedz) |
| CPU | 100% (1 core) |
| Swap | 0 |
6.2 Allocation des ports
Créer les allocations dans Admin → Nodes → {{HOSTNAME_NOUVEAU}} →
onglet Allocation :
|
1 2 |
# IP : 0.0.0.0 # Ports : 27015-27025 |
Format des ports : pour ajouter plusieurs ports d’un coup,
utiliser un tiret pour définir une plage : 27015-27025.
Le champ accepte aussi les virgules : 27015,27016,27017.
Puis assigner un port à chaque serveur :
| Serveur | Port | Server Name (variable egg) |
|---|---|---|
| Deathmatch | 27015 | [FR] DEATHMATCH {{TAG_CLAN}} #{{NOM_COMMUNAUTE}} |
| GunGame | 27016 | [FR] GUNGAME {{TAG_CLAN}} #{{NOM_COMMUNAUTE}} |
| Deathrun | 27017 | [FR] DEATHRUN {{TAG_CLAN}} #{{NOM_COMMUNAUTE}} |
| HNS | 27018 | [FR] HNS {{TAG_CLAN}} #{{NOM_COMMUNAUTE}} |
| Kreedz | 27019 | KZ & BHOP {{TAG_CLAN_2}} SERVER #{{NOM_COMMUNAUTE}} |
| AUTOMIX 5v5 | 27020 | [FR] AUTOMIX 5v5 {{TAG_CLAN}} #{{NOM_COMMUNAUTE}} |
| Surf | 27022 | [FR] Surf #{{NOM_COMMUNAUTE}} |
| CS 1.0 Vintage Beta | 27021 | [FR] Counter-Strike 1.0 Beta #{{NOM_COMMUNAUTE}} |
| Paintball | 27023 | [FR] PAINTBALL {{TAG_CLAN}} #{{NOM_COMMUNAUTE}} |
| Furien | 27024 | [FR] FURIEN {{TAG_CLAN}} #{{NOM_COMMUNAUTE}} |
| BaseBuilder | 27025 | [FR] BASEBUILDER {{TAG_CLAN}} #{{NOM_COMMUNAUTE}} |
7) Configuration par serveur
Chaque egg custom installe automatiquement les plugins, le server.cfg
et le mapcycle.txt de base. Après l’installation, personnaliser
les configs via le file manager Pterodactyl ou via SFTP.
7.0 Plugin BotManager v2 — gestion dynamique des bots
Le plugin BotManager v2 maintient 5 bots en permanence sur le serveur
pour attirer les joueurs (un serveur à 5/32 dans le browser attire plus qu’un 0/32).
Quand suffisamment de vrais joueurs sont connectés (seuil configurable, défaut : 4),
tous les bots sont kickés.
Fonctionnement
- 0 à 3 humains :
yb_quotaest fixé à la valeur
debm_bot_count(défaut : 5) — les bots YaPB remplissent le serveur - 4+ humains (seuil
bm_kick_threshold) :yb_quotaest mis à 0 —
tous les bots quittent la partie - Les transitions sont déclenchées sur
client_putinserver,
client_disconnectedetplugin_cfg(au démarrage)
Compilation automatique via l’egg
Le plugin est compilé automatiquement par le script d’installation
de l’egg. Le code source (BotManager.sma) est embarqué directement
dans le script install-dm.sh (et install-gg.sh), puis
compilé avec amxxpc (inclus dans AMX Mod X) à la manière du plugin AQS.
Le fichier BotManager.amxx résultant est placé dans
cstrike/addons/amxmodx/plugins/.
Prérequis : BotManager utilise yb_quota, un cvar
de YaPB (plugin Metamod). YaPB doit être chargé avant
BotManager. L’ordre dans plugins.ini et metamod/plugins.ini
est géré automatiquement par l’egg.
Configuration (server.cfg)
|
1 2 3 4 5 6 |
// YaPB : quota initial de bots (BotManager ajuste dynamiquement) yb_quota 5 // BotManager v2 : 5 bots toujours presents, kick quand 4+ vrais joueurs bm_bot_count 5 bm_kick_threshold 4 |
bm_kick_threshold : nombre de vrais joueurs à partir duquel
tous les bots sont kickés. Ajustable selon le mode de jeu (ex : 3 pour Deathrun, 4 pour DM/GunGame).
7.1 Deathmatch (port 27015)
Plugins spécifiques
| Plugin | Version | Type | Rôle |
|---|---|---|---|
| ReGameDLL_CS | 5.28.0.756 | Game DLL | Remplace cs.so vanilla (pré-requis ReAPI/ReDeathmatch) |
| ReAPI | 5.26.0.338 | Module AMXX | Expose l’API de ReGameDLL à AMX Mod X (pré-requis ReDeathmatch) |
| ReDeathmatch | 1.0.0-b11 | Plugin AMXX | Mode deathmatch (respawn, équipement, spawns) |
| YaPB | 4.4.957 | Plugin Metamod | Bots intelligents CS 1.6 |
| Advanced Quake Sounds | 8.0 | Plugin AMXX | Sons Quake (headshot, multikill, godlike, etc.) |
| QuickNoScopeD | 1.2 | Plugin AMXX | Détection noscope AWP/Scout (annonce en jeu) |
| BotManager | 2.0 | Plugin AMXX | 5 bots toujours présents, kick quand 4+ vrais joueurs (bm_kick_threshold). Voir section 7.0 |
| Double Jump | 1.0 | Plugin AMXX | Permet un saut supplémentaire en l’air (fakemeta) |
| Parachute | 1.0 | Plugin AMXX | Maintenir E en l’air pour ralentir la chute (fakemeta) |
| DM Welcome | 1.0 | Plugin AMXX | Message de bienvenue + alias /menu pour /guns |
Chaîne de dépendances :
ReDeathmatch nécessite ReAPI, qui nécessite ReGameDLL.
L’ordre d’installation est donc : ReGameDLL → ReAPI → ReDeathmatch.
YaPB, AQS, QuickNoScopeD, Double Jump, Parachute et DM Welcome sont indépendants.
Installation automatique via l’egg
L’egg egg-cs16-deathmatch.json installe automatiquement
tous les plugins ci-dessus lors de la création du serveur. Aucune intervention
manuelle n’est nécessaire — pas besoin d’accès SSH.
L’egg génère aussi un server.cfg (avec sv_downloadurl FastDL)
et télécharge toutes les maps depuis fastdl.{{DOMAINE_GAMING}}/cs_dm.
Le mapcycle.txt est généré automatiquement à partir des .bsp téléchargés.
Personnaliser ensuite via le file manager du panel si besoin.
Vérification post-installation : dans la console du serveur
(panel Pterodactyl), taper meta list pour vérifier que YaPB est chargé
(7/7 RUN), et amxx plugins pour vérifier que les 26 plugins sont running
(ReDeathmatch, AQS, QuickNoScopeD, BotManager, Double Jump, Parachute, DM Welcome).
Les joueurs peuvent taper /sounds en jeu pour activer/désactiver
les sons Quake.
Commandes joueurs
| Commande | Description |
|---|---|
/guns ou /menu |
Choisir ses armes (menu ReDeathmatch) |
/rs |
Remettre son score à zéro |
/para |
Info parachute |
/sounds |
Activer/désactiver les sons Quake |
| Double Jump | Appuyer sur Espace 2 fois en l’air |
| Parachute | Maintenir E en l’air pour ralentir la chute |
Random spawns : mp_randomspawn 3 (ReGameDLL) —
les deux équipes utilisent TOUS les spawns de la map aléatoirement,
évitant que tout le monde apparaisse au même endroit.
server.cfg (extraits clés)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
hostname "[FR] DEATHMATCH {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}" sv_contact "admin@{{DOMAINE_GAMING}}" rcon_password "CHANGER_CE_MOT_DE_PASSE" mp_timelimit 20 mp_freezetime 0 mp_roundtime 0 sv_maxspeed 320 sv_alltalk 1 // Random spawns (ReGameDLL) : les deux equipes utilisent TOUS les spawns mp_randomspawn 3 // YaPB bots : desactiver le chat, BotManager gere le quota yb_chat 0 yb_language_tag 0 yb_quota 5 // BotManager v2 : 5 bots toujours, kick quand 4+ vrais joueurs bm_bot_count 5 bm_kick_threshold 4 // Downloads + FastDL sv_allowdownload 1 sv_allowupload 0 sv_downloadurl "https://fastdl.{{DOMAINE_GAMING}}/cs_dm" |
mapcycle.txt
Généré automatiquement par l’egg à partir des fichiers .bsp
téléchargés depuis le FastDL. Toutes les maps présentes sur
fastdl.{{DOMAINE_GAMING}}/cs_dm/maps/ sont incluses.
7.2 GunGame (port 27016)
Plugins spécifiques
- GunGame AMXX 2.13c — plugin AMX Mod X classique
- Double Jump 1.0 — saut supplémentaire en l’air (fakemeta,
vel[2] = 268.0) - BotManager 2.0 — 5 bots toujours présents, kick quand 4+ vrais joueurs (voir section 7.0)
Maps et mapcycle.txt : l’egg télécharge automatiquement les maps
depuis fastdl.{{DOMAINE_GAMING}}/cs_gungame lors de l’installation et
génère le mapcycle.txt à partir des fichiers .bsp présents.
Pour ajouter des maps, les uploader sur le FastDL puis faire Reinstall Server.
server.cfg (extraits clés)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
hostname "[FR] GUNGAME {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}" rcon_password "CHANGER_CE_MOT_DE_PASSE" mp_timelimit 30 mp_freezetime 0 sv_maxspeed 320 // YaPB bots : BotManager gere le quota yb_quota 5 // BotManager v2 : 5 bots toujours, kick quand 4+ vrais joueurs bm_bot_count 5 bm_kick_threshold 4 // Downloads + FastDL sv_allowdownload 1 sv_allowupload 0 sv_downloadurl "https://fastdl.{{DOMAINE_GAMING}}/cs_gungame" |
Configuration GunGame (gg_configs)
|
1 2 3 4 5 6 7 8 9 10 |
// Turbo mode : changement d'arme instantané au kill gg_turbo 1 // Kills par niveau gg_kills 2 // DM mode (respawn) gg_dm 1 // Knife Pro : kill au couteau = victoire gg_knife_pro 1 // Progression d'armes gg_weapon_order "glock18,usp,p228,deagle,fiveseven,elite,m3,xm1014,tmp,mac10,mp5navy,ump45,p90,galil,famas,ak47,scout,m4a1,sg552,aug,m249,hegrenade,knife" |
7.3 Deathrun (port 27017)
Plugins spécifiques
| Plugin | Rôle |
|---|---|
| DeathrunManager v3.0.3a | Core deathrun (sélection TT, semiclip intégré, système de vies, anti-AFK) |
| YaPB | Bots via Metamod |
| BotManager v2 | 5 bots toujours présents, kick quand 4+ vrais joueurs (bm_kick_threshold 4) |
| AutoBhop (Super Bunny Hopper) | Bunny hop automatique (maintenir ESPACE) — supprime le slowdown + boost de vélocité |
| Speedometer | Affichage vitesse en HUD (u/s) |
| Resetscore | /rs ou /resetscore pour remettre le score à zéro |
Semiclip intégré : pas besoin d’un plugin Semiclip séparé,
DeathrunManager v3.0.3a inclut le semiclip nativement (dr_semiclip 1).
server.cfg (extraits clés)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
hostname "[FR] DEATHRUN {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}" rcon_password "changeme" // Deathrun settings mp_timelimit 30 mp_freezetime 0 mp_roundtime 5 mp_autoteambalance 0 mp_limitteams 0 sv_alltalk 0 // Auto Bhop (Super Bunny Hopper) bh_enabled 1 bh_autojump 1 // FastDL sv_downloadurl "https://fastdl.{{DOMAINE_GAMING}}/cs_deathrun" // BotManager yb_quota 0 bm_bot_count 3 // DeathrunManager (config détaillée dans deathrun_manager.cfg) exec deathrun_manager.cfg |
deathrun_manager.cfg (CVARs clés)
|
1 2 3 4 5 6 7 8 9 |
dr_semiclip 1 // Passage à travers les coéquipiers dr_spray 0 // Bloquer les sprays dr_radio 0 // Bloquer les commandes radio dr_lifesystem 1 // Système de vies activé dr_lives 3 // 3 vies par terroriste dr_autotransfer 1 // Transfert auto si TT AFK dr_autotransfer_time 15 dr_choose_terrorist 0 // Sélection aléatoire du TT dr_block_weapons 1 // CT couteau uniquement |
7.4 Hide & Seek (port 27018)
Plugins spécifiques
| Plugin | Rôle | Source |
|---|---|---|
| ReSemiclip | Seekers (T) passent à travers entre eux ; Hiders (CT) restent solides pour les boosts (team = 2) |
GitHub rehlds/resemiclip |
| OpenHNS hns_mode | Core HNS : phase de cache, seekers aveuglés, swap d’équipe, grenades | GitHub OpenHNS/hns_mode |
| PreFog | Affichage prestrafe + FOG (frames-on-ground) | GitHub OpenHNS/PreFog (compilé depuis .sma) |
| HnsMatchSystem | Système de matchs compétitifs (knife round, captain pick, training) | GitHub OpenHNS/HnsMatchSystem |
| HNS Nade Slow | Flash et smoke ralentissent les joueurs proches (vitesse réduite temporairement) | Compilé depuis .sma |
| AutoBhop | Bunny hop automatique (maintenir ESPACE) | Compilé depuis .sma |
| Speedometer | Affichage vitesse HUD (u/s) | Compilé depuis .sma |
| Resetscore | /rs pour remettre son score à zéro |
Compilé depuis .sma |
Boosts activés : ReSemiclip est configuré avec team = 2 (seuls les seekers/T passent à travers).
Les hiders (CT) restent solides entre eux, permettant les boosts (monter sur la tête d’un coquipier).
Les TP sont gérés par les entités trigger_teleport de la map (ex: boost_town).
Pas de YaPB/BotManager : les bots ne savent pas jouer en HNS.
Gameplay HNS
- CT = Hiders (se cachent), T = Seekers (cherchent)
- Phase de cache (10-15s) : seekers aveuglés, hiders se positionnent
- Phase de recherche (2.5 min) : seekers libérés, doivent éliminer tous les hiders
- Hiders gagnent si au moins 1 survit. Swap d’équipe après 2 victoires consécutives
- Knives only, mouvement bhop essentiel (
sv_airaccelerate 100)
server.cfg (extraits clés)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
hostname "[FR] HNS {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}" // HNS settings mp_timelimit 30 mp_freezetime 0 // Le plugin gere la phase de cache mp_roundtime 3 mp_autoteambalance 0 mp_limitteams 0 mp_buytime 0 mp_startmoney 0 mp_playerid 2 // Pas de noms sur le crosshair mp_forcecamera 2 // Spectate first-person only // Mouvement (critique pour HNS/Bhop) sv_airaccelerate 100 sv_maxspeed 320 sv_downloadurl "https://fastdl.{{DOMAINE_GAMING}}/cs_hns" // HNS Nade Slow (flash + smoke ralentissent les joueurs) hns_flash_slow_speed 80.0 // Vitesse quand flashé (normal: 250) hns_flash_slow_time 3.0 // Durée du slow flash (sec) hns_smoke_slow_speed 100.0 // Vitesse dans la smoke hns_smoke_slow_radius 200.0 // Rayon d'effet smoke hns_smoke_slow_time 15.0 // Durée du nuage smoke exec hns_mode.cfg |
hns_mode.cfg (CVARs principales)
|
1 2 3 4 5 6 7 |
hns_deathmatch 0 // Mode classique (pas DM) hns_roundtime 2.5 // Duree du round (minutes) hns_flash 2 // Flashbangs pour seekers hns_smoke 1 // Smokes pour seekers hns_he 0 // Pas de HE hns_swap_team 2 // Swap apres 2 victoires hns_swist 1 // Son swist |
7.5 Kreedz / Bhop (port 27019)
Plugins spécifiques
| Plugin | Rôle | Source |
|---|---|---|
| ReSemiclip | Joueurs passent à travers les coéquipiers | GitHub rehlds/resemiclip |
| Theggv/Kreedz v1.3.0 | Suite KZ : timer, checkpoints, noclip, spectate, HUD, weapons | GitHub Theggv/Kreedz |
| kz_mpbhop | Multi-player bhop (supprime le slowdown) | Inclus dans Kreedz |
| UQ Jumpstats | Statistiques de sauts (LJ, BJ, WJ, CJ, HJ) | Inclus dans Kreedz |
| MapManagerModular v3.2.0 | Vote de map, RTV (/rtv), nominations (/nominate), blocklist |
GitHub Mistrick/MapManagerModular |
| Resetscore | /rs pour remettre son score à zéro |
Compilé depuis .sma |
Pas de YaPB/BotManager : les bots ne savent pas jouer en KZ.
Kreedz intègre 20+ plugins (timer, HUD, jumpstats, etc.) dans une seule release ZIP.
Le map_manager de l’archive Kreedz est remplacé par
MapManagerModular (Mistrick) téléchargé séparément depuis GitHub,
qui fournit RTV, nominations et vote automatique.
Plugins désactivés : certains plugins Kreedz sont exclus de l’installation :
kz_sql_* et kz_rank_mysql (pas de MySQL),
kz_records / kz_records_frontend / kz_cups (nécessitent AmxxEasyHttp, incompatible Docker),
map_manager_effects (ressources models/sprites manquantes).
AmxxEasyHttp est un module natif (.so) qui crash en environnement Docker.
Commandes joueur principales
| Commande | Description |
|---|---|
/cp |
Créer un checkpoint |
/gc ou /tp |
Teleport au dernier checkpoint |
/start |
Retour au début |
/nc |
Noclip (mode entrainement) |
/top |
Top 15 records |
/ljstats |
Statistiques de sauts |
/spec |
Mode spectateur |
/menu |
Menu principal KZ |
/rtv |
Rock The Vote (voter pour changer de map) |
/nominate |
Proposer une map pour le prochain vote |
/rs |
Remettre son score à zéro |
server.cfg (extraits clés)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
hostname "[FR] KREEDZ {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}" // KZ settings mp_timelimit 0 mp_freezetime 0 mp_roundtime 9 mp_autoteambalance 0 mp_limitteams 0 mp_buytime 0 // Mouvement KZ sv_airaccelerate 100 sv_maxspeed 320 sv_enablebunnyhopping 1 // Pas de speed cap au sol sv_autobunnyhopping 0 // Bhop manuel (pas auto) sv_alltalk 1 sv_downloadurl "https://fastdl.{{DOMAINE_GAMING}}/cs_kz" exec kreedz.cfg exec mpbhop.cfg |
Volume de maps : le serveur Kreedz peut contenir un volume massif de maps.
Utiliser le SFTP de Pterodactyl pour le transfert initial
(le file manager web est trop lent pour autant de fichiers).
Augmenter le Disk Space du serveur dans le panel si nécessaire.
Records SQL (optionnel) : Kreedz supporte le stockage des records
dans une base MySQL. Les plugins SQL (kz_sql_*) sont désactivés par défaut
car ils nécessitent une base MySQL. Pour activer, configurer les identifiants
dans kreedz.cfg et réactiver les plugins SQL dans l’install script.
7.6 AUTOMIX 5v5 (port 27020)
Stack et plugin
| Composant | Version | Type | Rôle |
|---|---|---|---|
| ReHLDS | 3.14+ | Moteur | Socle commun |
| ReGameDLL | 5.28+ | Game DLL | Logique de jeu |
| Metamod-R | 1.3+ | Loader | Charge les plugins Metamod natifs |
| AMX Mod X | 1.10+ | Framework | Framework pour les plugins PugMod-AMXX |
| ReAPI | 5.26+ | Module AMXX | Socle commun |
| Reunion | 0.2+ | Plugin Metamod | Support Steam + non-Steam |
| PugMod-AMXX v4.0.8 | 4.0.8 | Plugin AMXX | Gestion complète des matchs compétitifs MR15 5v5 (9 plugins .amxx) |
PugMod-AMXX est un ensemble de plugins AMX Mod X (fichiers .amxx)
du même développeur que MatchBot (SmileYzn). Il se charge via addons/amxmodx/configs/plugins.ini
et gère entièrement le système de match : knife round, LO3, readys, pauses,
overtime et stats. Dépôt : github.com/SmileYzn/PugMod-AMXX.
Choisi à la place de MatchBot (plugin Metamod natif) car les .so natifs
sont incompatibles avec le conteneur Docker Pterodactyl.
Format de match
- Mode : MR15 5v5 (premier à 16 rounds, 30 rounds au total)
- Joueurs : 12 max (10 joueurs + 2 spectateurs / HLTV)
- Overtime : 6 rounds si égalité 15–15
- Knife round : détermine le choix de camp
- LO3 automatique : restart 3× avant le début du match
Fonctionnalités PugMod-AMXX
- Système ready : le match ne commence qu’une fois toutes les positions prêtes
- Pause technique pendant le match
- Anti-ragequit : détection et gestion des déconnexions
- Stats de dégâts (
.dmg) — affichage des dommages infligés/reçus en fin de round - HP restants (
.hp) — points de vie des adversaires en fin de round
Maps compétitives
de_dust2(map par défaut)de_infernode_nukede_trainde_cbble
Commandes joueur
| Commande | Description |
|---|---|
.ready |
Indiquer que son équipe est prête |
.help |
Afficher les commandes disponibles |
.dmg |
Stats de dégâts du dernier round |
.hp |
HP restants des adversaires |
.sum |
Récapitulatif du match (score, rounds) |
/rs |
Reset score (hors match) |
Configuration (egg + server.cfg)
L’egg egg-cs16-war.json installe automatiquement PugMod-AMXX et génère
la configuration de base.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
hostname "[FR] AUTOMIX 5v5 {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}" rcon_password "CHANGER_CE_MOT_DE_PASSE" sv_contact "admin@{{DOMAINE_GAMING}}" // Parametres match 5v5 mp_maxrounds 30 mp_winlimit 16 mp_freezetime 15 mp_roundtime 1.75 mp_c4timer 35 mp_timelimit 0 mp_autoteambalance 0 mp_limitteams 0 // Slots : 10 joueurs + 2 spectateurs maxplayers 12 sv_maxplayers 10 // Map par defaut map de_dust2 // Pas de FastDL specifique : maps de compet incluses dans HLDS sv_allowdownload 1 sv_allowupload 0 |
Egg et fichier JSON : l’egg egg-cs16-war.json
installe PugMod-AMXX via le répertoire GitHub (release ZIP).
La configuration pugmod.rc est générée avec les paramètres MR15 par défaut.
La map par défaut est de_dust2.
7.7 Surf (port 27022)
Plugins spécifiques
| Plugin | Source | Rôle |
|---|---|---|
| uSurf | GitHub (DouglasSherk) | Timer, checkpoints (/checkpoint, /gocheck), respawn, semiclip |
| surf_olympics | GitHub (evandrocoan) | Top times et records par map (nVault), /top3 |
| Speedometer | Compilé inline | Affichage vitesse HUD (/speed toggle) |
| Bunnyhop | Compilé inline | Auto-bhop (FM_PlayerPreThink) |
| No Fall Damage | Compilé inline | Supprime les dégâts de chute (HamSandwich) |
| Resetscore | Compilé inline | /rs pour remettre le score à zéro |
Compilation à l’installation : les 6 plugins surf sont compilés
depuis le code source .sma pendant l’installation de l’egg via amxxpc.
Pas de binaire natif .so — uniquement du bytecode AMXX (.amxx),
compatible Docker sans problème.
CVARs surf (server.cfg)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// Surf movement - CRITICAL sv_airaccelerate 150 sv_accelerate 10 sv_friction 4 sv_gravity 800 sv_maxspeed 320 // Rounds longs + respawn infini mp_roundtime 9 mp_timelimit 30 mp_freezetime 0 mp_round_infinite 1 mp_forcerespawn 3 // Pas de bombe, pas de buytime mp_give_player_c4 0 mp_buytime 0 mp_startmoney 0 // Communication sv_alltalk 1 // FastDL sv_downloadurl "https://fastdl.{{DOMAINE_GAMING}}/cs_surf" |
Maps
~45 maps surf téléchargées automatiquement depuis le FastDL
(https://fastdl.{{DOMAINE_GAMING}}/cs_surf/) via wget récursif.
Le mapcycle.txt est généré automatiquement à partir des .bsp trouvés.
Map par défaut : surf_ski_2.
Commandes joueurs
/checkpoint— Sauvegarder la position/gocheck— Téléporter au checkpoint/timer— Menu timer/speed— Toggle speedometer/top3— Top 3 records/rs— Reset score/surfhelp— Aide surf
Egg et fichier JSON : l’egg egg-cs16-surf.json
installe automatiquement les 6 plugins surf, télécharge les maps depuis le FastDL
et configure sv_airaccelerate 150. 32 slots par défaut.
7.8 CS 1.0 Vintage Beta (port 27021)
Statut : Beta / à venir.
Ce serveur est un placeholder. La configuration détaillée sera complétée
lors du déploiement effectif du serveur CS 1.0 Vintage.
Plugins spécifiques
- YaPB bots (pour remplir le serveur)
- Pas de mods lourds — gameplay vanilla CS 1.0
server.cfg (extraits clés)
|
1 2 3 4 5 6 7 8 9 |
hostname "[FR] Counter-Strike 1.0 Beta #{{NOM_COMMUNAUTE}}" rcon_password "CHANGER_CE_MOT_DE_PASSE" mp_timelimit 30 mp_freezetime 5 mp_roundtime 3 mp_c4timer 35 // Pas de FastDL nécessaire : maps vanilla |
CS 1.0 sur ReHLDS : ReHLDS supporte les anciens protocoles.
Le gameplay vintage est assuré en limitant les armes et les fonctionnalités
via la configuration. Les maps classiques (de_dust, cs_assault, etc.)
sont incluses dans l’installation HLDS de base.
7.9 Paintball (port 27023)
Concept
Mode Paintball avec armes custom, sprint/stamina, vendetta et système
d’élimination/respawn. Double Jump et Parachute actifs pour un gameplay aérien.
Plugins spécifiques
| Plugin | Version | Rôle |
|---|---|---|
| PaintBall Refresh (GlobalModders) | 2016 | 5 plugins : Gameplay, Weapons (9 armes custom), Movement (sprint/stamina), Grenades, Elimination Respawn |
| Double Jump | 1.0 | Saut double en l’air (fakemeta) |
| Parachute | 1.0 | Parachute déployé avec touche E |
| BotManager | 2.0 | 5 bots toujours, kick à 4+ humains |
| AQS | latest | Advanced Quake Sounds |
server.cfg (extraits clés)
|
1 2 3 4 5 6 7 8 |
hostname "[FR] PAINTBALL {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}" mp_timelimit 20 mp_freezetime 0 mp_roundtime 5 sv_downloadurl "https://fastdl.{{DOMAINE_GAMING}}/cs_paintball" yb_quota 5 bm_bot_count 5 bm_kick_threshold 4 |
Source du mod
GlobalModders PaintBall Refresh
— 5 plugins, 9 armes custom avec models dans /models/paintballR/.
7.10 Furien (port 27024)
Concept
Mode asymétrique : les Terroristes (Furien) sont des assassins au couteau
avec gravité réduite (0.39), vitesse élevée (565), auto bunny hop, double jump
et parachute. Ils peuvent acheter un Deagle 1 balle pour $10 000 via /deagle.
Les CT choisissent leurs armes comme en Deathmatch via /guns et possèdent
toutes les grenades. 7 modes de HE grenades (nademodes).
Plugins spécifiques
| Plugin | Version | Rôle |
|---|---|---|
| Furien Pack (ShootingKing) | latest | Core furien (gravité/vitesse T), models, wallhang, anticamp |
| NadeModes | latest | 7 modes HE grenades (fire, frost, laser, etc.) |
| Furien Deagle | 1.0 | Achat Deagle 1 balle $10 000 pour T (/deagle) |
| Furien CT Weapons | 1.0 | Menu choix armes CT (/guns), grenades incluses |
| Furien AutoBhop | 1.0 | Auto bunny hop pour T uniquement |
| Double Jump | 1.0 | Saut double en l’air |
| Parachute | 1.0 | Parachute (touche E) |
| Skin Assassin’s Creed | 1.0 | Model custom T via FastDL |
| BotManager | 2.0 | 5 bots toujours, kick à 4+ humains |
| AQS | latest | Advanced Quake Sounds |
server.cfg (extraits clés)
|
1 2 3 4 5 6 7 8 9 10 |
hostname "[FR] FURIEN {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}" mp_timelimit 25 mp_freezetime 3 mp_roundtime 3 // Furien gravity/speed geres par le plugin furien.sma // fm_t_grav 0.39 / fm_t_speed 565 sv_downloadurl "https://fastdl.{{DOMAINE_GAMING}}/cs_furien" yb_quota 5 bm_bot_count 5 bm_kick_threshold 4 |
Commandes joueurs
/deagle— T : acheter Deagle 1 balle ($10 000)/gunsou/menu— CT : choisir ses armes/para— info parachute (touche E)- Double Jump actif pour tous
- Auto Bhop actif pour T uniquement
Source du mod
ShootingKing Furien Pack
— 20+ plugins, core furien avec classes T/CT.
7.11 BaseBuilder (port 27025)
Concept
Mode BaseBuilder de type zombie : les T (zombies) construisent des bases
avec des blocs pendant la phase de build, puis les CT (humains) attaquent.
CT ont les munitions illimitées, un menu d’achat (/buy),
et le couteau one shot. Les T ont gravité/vitesse spéciales et un shop
(via ProBaseBuilder). Revive admin disponible.
Plugins spécifiques
| Plugin | Version | Rôle |
|---|---|---|
| ProBaseBuilder | latest | Core BaseBuilder : phases build/fight, classes zombie, blocs |
| CromChat | latest | Dépendance include pour ProBaseBuilder |
| BB CT Features | 1.0 | Munitions illimitées CT, menu d’achat (/buy), knife oneshot, revive admin |
| BotManager | 2.0 | 5 bots toujours, kick à 4+ humains |
| AQS | latest | Advanced Quake Sounds |
server.cfg (extraits clés)
|
1 2 3 4 5 6 7 8 |
hostname "[FR] BASEBUILDER {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}" mp_timelimit 30 mp_roundtime 5 mp_autoteambalance 0 sv_downloadurl "https://fastdl.{{DOMAINE_GAMING}}/cs_basebuilder" yb_quota 5 bm_bot_count 5 bm_kick_threshold 4 |
Commandes joueurs
/buy— CT : menu d’achat armes + grenades + armure/revive— admin : revive un joueur- Knife one shot pour tous
- CT : munitions illimitées automatiquement
Source du mod
ProBaseBuilder +
CromChat (dépendance).
8) Configurer le FastDL
Le FastDL (Fast Download) permet aux joueurs de télécharger les maps et
fichiers custom via HTTP au lieu du transfert lent intégré au moteur.
On utilise un sous-domaine dédié fastdl.{{DOMAINE_GAMING}} avec un template
Nginx personnalisé (autoindex + dark theme), comme pour les templates Odoo.
8.1 Créer le domaine dans MyVestaCP
- MyVestaCP → WEB → Add Web Domain
- Domaine :
fastdl.{{DOMAINE_GAMING}} - DNS Support : cocher
- Activer Let’s Encrypt après propagation DNS
8.2 Créer le template Nginx HTTP : fastdl.tpl
|
1 |
nano /usr/local/vesta/data/templates/web/nginx/fastdl.tpl |
Contenu :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
server { # Port 80 en dur : %proxy_port% se résout en 8080 (port Apache) ce qui entre en conflit (voir piège 12.9) listen %ip%:80; server_name %domain_idn% %alias_idn%; error_log /var/log/%web_system%/domains/%domain%.error.log error; location /.well-known/acme-challenge { default_type text/plain; root %home%/%user%/web/%domain%/public_html; } location / { root %home%/%user%/web/%domain%/public_html; autoindex on; autoindex_exact_size off; autoindex_localtime on; # Dark theme injecté dans le HTML autoindex via sub_filter # IMPORTANT : la valeur sub_filter doit tenir sur UNE SEULE LIGNE (voir piège 12.8) sub_filter '</head>' '<style>body{background:#1a1a2e;color:#e0e0e0;font-family:Courier New,monospace;padding:20px}h1{color:#e94560;font-size:1.4em}a{color:#0f9;text-decoration:none}a:hover{text-decoration:underline}pre{font-family:Courier New,monospace;line-height:1.8}</style></head>'; sub_filter_once on; sub_filter_types text/html; # CORS pour les fichiers de jeux add_header Access-Control-Allow-Origin "*"; add_header Cache-Control "public, max-age=604800"; gzip on; gzip_types text/plain application/octet-stream; } include %home%/%user%/conf/web/%domain%/nginx.conf_*; } |
8.3 Créer le template Nginx HTTPS : fastdl.stpl
|
1 |
nano /usr/local/vesta/data/templates/web/nginx/fastdl.stpl |
Contenu :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
server { # Port 443 en dur : %proxy_ssl_port% se résout en 8443 (port Apache) ce qui entre en conflit (voir piège 12.9) listen %ip%:443 ssl; http2 on; server_name %domain_idn% %alias_idn%; ssl_certificate %ssl_pem%; ssl_certificate_key %ssl_key%; error_log /var/log/%web_system%/domains/%domain%.error.log error; location / { root %home%/%user%/web/%domain%/public_html; autoindex on; autoindex_exact_size off; autoindex_localtime on; # Dark theme injecté dans le HTML autoindex via sub_filter # IMPORTANT : la valeur sub_filter doit tenir sur UNE SEULE LIGNE (voir piège 12.8) sub_filter '</head>' '<style>body{background:#1a1a2e;color:#e0e0e0;font-family:Courier New,monospace;padding:20px}h1{color:#e94560;font-size:1.4em}a{color:#0f9;text-decoration:none}a:hover{text-decoration:underline}pre{font-family:Courier New,monospace;line-height:1.8}</style></head>'; sub_filter_once on; sub_filter_types text/html; # CORS pour les fichiers de jeux add_header Access-Control-Allow-Origin "*"; add_header Cache-Control "public, max-age=604800"; gzip on; gzip_types text/plain application/octet-stream; } include %home%/%user%/conf/web/%domain%/nginx.conf_*; } |
Principe : les templates utilisent autoindex on (listing natif Nginx)
avec sub_filter pour injecter un CSS dark theme directement dans le HTML généré.
Zéro PHP, zéro maintenance — Nginx gère tout nativement.
La navigation dans les sous-dossiers (maps, gfx, sprites, sound…) fonctionne automatiquement.
Attention : le CSS dans sub_filter doit être minifié
sur une seule ligne (pas de retour à la ligne). Nginx refuse les valeurs multi-lignes
dans sub_filter (voir piège 12.8).
Après application du template, vérifier que les ports générés sont bien 80/443
et non 8080/8443 (voir piège 12.9).
8.4 Appliquer le template au domaine
|
1 |
/usr/local/vesta/bin/v-change-web-domain-proxy-tpl {{USER_VESTA}} fastdl.{{DOMAINE_GAMING}} fastdl |
Vérifier et recharger Nginx :
|
1 |
nginx -t && systemctl reload nginx |
8.5 Structure des fichiers FastDL
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
/home/{{USER_VESTA}}/web/fastdl.{{DOMAINE_GAMING}}/public_html/ cs_dm/ maps/ ← fichiers .bsp (+ .bsp.bz2 compressés) gfx/ sound/ models/ sprites/ overviews/ cs_gungame/ maps/ sound/ gungame/ ← sons GunGame (gg_levelup.wav, gg_knife_level.wav, etc.) gfx/ sprites/ cs_deathrun/ maps/ ... cs_hns/ maps/ ... cs_kz/ maps/ ... cs_surf/ maps/ ← ~45 maps surf_*.bsp ... plugins/ ← plugins custom (.amxx) QuickNoScopeD.amxx |
Important : la structure des sous-dossiers (maps, gfx, sound, sprites, overviews…)
doit reproduire l’arborescence de cstrike/.
Le client CS 1.6 demande les fichiers selon le chemin relatif du serveur.
Par exemple, si le serveur a cstrike/maps/de_dust2.bsp,
le client téléchargera https://fastdl.{{DOMAINE_GAMING}}/cs_dm/maps/de_dust2.bsp.
8.6 Intégration FastDL dans les eggs
Les eggs DM, GunGame, Deathrun, HNS, Kreedz et Surf téléchargent automatiquement
les maps et fichiers associés (gfx, sprites, sound, overviews, models, wads) depuis le FastDL
lors de l’installation. Le principe : le FastDL est la source de vérité pour les maps.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# Dans le script d'installation de l'egg (install-dm.sh) : FASTDL_URL="https://fastdl.{{DOMAINE_GAMING}}/cs_dm" # wget recursif : telecharge toute l'arborescence # --cut-dirs=1 supprime "cs_dm/" pour copier dans cstrike/ wget -r -np -nH --cut-dirs=1 -P /mnt/server/cstrike/ \ -R "index.html*" --no-check-certificate -q \ "$FASTDL_URL/" # mapcycle.txt genere automatiquement find /mnt/server/cstrike/maps -name "*.bsp" -printf "%f\n" \ | sed 's/\.bsp$//' | sort > /mnt/server/cstrike/mapcycle.txt |
Flux de travail : pour ajouter une map, il suffit de l’uploader sur le FastDL
(/home/{{USER_VESTA}}/web/fastdl.{{DOMAINE_GAMING}}/public_html/cs_dm/maps/)
puis de faire Reinstall Server dans Pterodactyl.
L’egg re-télécharge toutes les maps et régénère le mapcycle.txt.
Le server.cfg généré par l’egg inclut automatiquement :
|
1 2 |
sv_downloadurl "https://fastdl.{{DOMAINE_GAMING}}/cs_dm" sv_allowdownload 1 |
Sons et fichiers custom : les eggs installent certains fichiers custom (sons GunGame,
sprites, etc.) dans le conteneur Docker lors de l’installation, mais ces fichiers doivent
également être présents sur le FastDL pour que les clients les téléchargent
rapidement. Sans cela, le client les télécharge via le serveur de jeu (lent, ~30 Ko/s).
Exemple pour les sons GunGame :
|
1 2 3 4 5 6 7 8 9 10 |
# Copier les sons GunGame sur le FastDL (depuis le serveur hote, pas le conteneur) mkdir -p /home/{{USER_VESTA}}/web/fastdl.{{DOMAINE_GAMING}}/public_html/cs_gungame/sound/gungame/ # Telecharger et extraire les sons depuis le zip GunGame cd /tmp && curl -fsSL -o gungame.zip \ "https://github.com/xLeviNx/GunGame/releases/download/release/gg_213c_full.zip" unzip -qo gungame.zip -d gg/ find gg/ -path "*/sound/gungame/*" -name "*.wav" \ -exec cp {} /home/{{USER_VESTA}}/web/fastdl.{{DOMAINE_GAMING}}/public_html/cs_gungame/sound/gungame/ \; chown -R {{USER_VESTA}}:{{USER_VESTA}} /home/{{USER_VESTA}}/web/fastdl.{{DOMAINE_GAMING}}/public_html/cs_gungame/sound/ rm -rf gg/ gungame.zip |
8.7 Compression bz2 (optionnel)
Compression : les fichiers .bsp peuvent être compressés
en .bz2 pour accélérer le téléchargement côté client.
Le client CS 1.6 décompresse automatiquement les fichiers .bz2.
|
1 2 3 |
# Compresser toutes les maps en bz2 cd /home/{{USER_VESTA}}/web/fastdl.{{DOMAINE_GAMING}}/public_html/cs_dm/maps/ for f in *.bsp; do bzip2 -k "$f"; done |
9) Ouvrir les ports dans le firewall
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# Ports des 12 serveurs CS 1.6 (UDP) /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 27015 UDP CS16-DM /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 27016 UDP CS16-GG /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 27017 UDP CS16-DR /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 27018 UDP CS16-HNS /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 27019 UDP CS16-KZ /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 27020 UDP CS16-WAR /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 27022 UDP CS16-SURF /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 27021 UDP CS16-CS10 /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 27023 UDP CS16-PAINTBALL /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 27024 UDP CS16-FURIEN /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 27025 UDP CS16-BASEBUILDER # Port Pterodactyl Wings API (si pas encore fait) /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 8543 TCP Pterodactyl-Wings # Port SFTP Pterodactyl (gestion fichiers) /usr/local/vesta/bin/v-add-firewall-rule ACCEPT 0.0.0.0/0 2022 TCP Pterodactyl-SFTP # Appliquer /usr/local/vesta/bin/v-update-firewall |
Ports RCON : les ports RCON sont les mêmes que les ports de jeu
mais en TCP. Pterodactyl gère le RCON via la console intégrée, pas besoin
d’ouvrir de ports supplémentaires. Ne pas exposer le RCON
directement sur Internet.
9.1 Vérifier les règles
|
1 |
iptables -L INPUT -n | grep -E '2701[5-9]|2702[01]|8543' |
10) Configurer le DNS
Ajouter les enregistrements DNS pour {{DOMAINE_GAMING}} :
| Type | Nom | Valeur | Usage |
|---|---|---|---|
| A | @ | {{IP_NOUVEAU}} |
Domaine principal |
| A | panel | {{IP_NOUVEAU}} |
Panel Pterodactyl |
| A | fastdl | {{IP_NOUVEAU}} |
FastDL maps |
Enregistrements SRV (optionnel) :
pour que les clients trouvent automatiquement le bon port,
créer un enregistrement SRV par serveur. Exemple pour GunGame :
_cs._udp.gungame.{{DOMAINE_GAMING}} 0 5 27016 {{DOMAINE_GAMING}}.
11) Gestion quotidienne via Pterodactyl
11.1 Uploader des maps
- Se connecter au panel → sélectionner le serveur
- Onglet Files → naviguer vers
cstrike/maps/ - Upload → sélectionner le(s) fichier(s) .bsp
- Éditer
cstrike/mapcycle.txtpour ajouter la map - Console →
changelevel nom_de_la_mappour tester
Pour les uploads massifs (Kreedz) : utiliser le SFTP.
Les identifiants SFTP sont dans le panel : Settings → SFTP Details.
Port par défaut : 2022.
11.2 Éditer les configs
Depuis le file manager, éditer directement :
cstrike/server.cfg— configuration généralecstrike/mapcycle.txt— rotation des mapscstrike/addons/amxmodx/configs/plugins.ini— plugins actifscstrike/addons/amxmodx/configs/users.ini— admins AMX Mod X
11.3 Console live
L’onglet Console du panel affiche les logs du serveur en temps réel
et permet d’exécuter des commandes RCON :
|
1 2 3 4 |
status // joueurs connectés changelevel de_dust2 // changer de map amx_kick "joueur" // kick via AMX Mod X maps * // lister les maps disponibles |
11.4 Donner accès à un admin
- Admin → Users → Create New
- Créer un compte pour l’admin
- Dans le serveur concerné : Users → New User
- Choisir les permissions : console, fichiers, redémarrage, etc.
12) Pièges rencontrés et solutions
Lors du déploiement des eggs DM et GunGame, plusieurs problèmes non documentés
ont été identifiés et corrigés dans les scripts d’installation.
Cette section documente chaque piège pour les futurs eggs.
12.1 AMX Mod X — latest.php renvoie du HTML
Le lien officiel https://www.amxmodx.org/latest.php?type=base&os=linux&version=1.10
renvoie une page HTML (Content-Type: text/html) au lieu de
rediriger vers l’archive .tar.gz. Le script télécharge donc un fichier HTML
qu’il tente d’extraire avec tar xzf, ce qui échoue silencieusement.
Résultat : AMX Mod X n’est pas installé et Metamod affiche badf
pour amxmodx_mm_i386.so.
Solution : utiliser les URLs directes du dossier
amxxdrop/1.10/ au lieu de latest.php :
|
1 2 3 4 5 6 7 8 9 10 11 |
# ✗ NE PAS utiliser : curl -fsSL -o /tmp/amxx.tar.gz "https://www.amxmodx.org/latest.php?type=base&os=linux&version=1.10" # ✓ Utiliser les URLs directes : AMXX_DROP="https://www.amxmodx.org/amxxdrop/1.10" curl -fsSL -o /tmp/amxmodx-base.tar.gz "${AMXX_DROP}/amxmodx-latest-base-linux.tar.gz" # Toujours valider que c'est bien un tar.gz avant extraction : if tar tzf /tmp/amxmodx-base.tar.gz > /dev/null 2>&1; then tar xzf /tmp/amxmodx-base.tar.gz fi |
12.2 steamclient.so — mauvaise architecture (64-bit au lieu de 32-bit)
SteamCMD contient deux versions de steamclient.so :
linux32/steamclient.so (32-bit) et linux64/steamclient.so (64-bit).
Un find -name "steamclient.so" | head -1 peut renvoyer la version 64-bit
selon l’ordre du système de fichiers. HLDS est un binaire 32-bit et crashe avec :
|
1 |
steamclient.so: wrong ELF class: ELFCLASS64 |
Solution : filtrer par chemin pour forcer la version 32-bit :
|
1 2 3 |
# ✗ find -name "steamclient.so" (peut renvoyer linux64/) # ✓ find -path "*/linux32/steamclient.so" (force 32-bit) STEAM_SO=$(find /mnt/server/steamcmd -path "*/linux32/steamclient.so" 2>/dev/null | head -1) |
12.3 liblist.gam — jamais écrit si Metamod échoue
Si l’écriture de liblist.gam est placée à l’intérieur
du bloc if qui télécharge Metamod, un échec de téléchargement
(rate limit GitHub, timeout) signifie que liblist.gam n’est jamais créé.
Le serveur crashe avec :
|
1 |
Couldn't get GiveFnptrsToDll in (empty path) |
Solution : écrire liblist.gam en dehors
du bloc Metamod, avec détection dynamique :
|
1 2 3 4 5 6 7 8 9 |
# TOUJOURS ecrire liblist.gam (meme si Metamod a echoue) if [ -f /mnt/server/cstrike/addons/metamod/metamod_i386.so ]; then GAMEDLL_LINUX="addons/metamod/metamod_i386.so" else GAMEDLL_LINUX="dlls/cs.so" # fallback sans Metamod fi cat > /mnt/server/cstrike/liblist.gam << LIBLIST gamedll_linux "${GAMEDLL_LINUX}" LIBLIST |
12.4 Permissions Docker — UID 988 ne peut pas lire les fichiers
C’était le problème principal.
Le conteneur d’installation (ghcr.io/ptero-eggs/installers:debian)
tourne en root. Les fichiers créés sont donc possédés par root.
Le conteneur de jeu (ghcr.io/ptero-eggs/games:source) tourne en
UID 988 et ne peut pas lire ces fichiers.
L’étape « Ensuring file permissions » de Pterodactyl ne corrige
pas toujours ce problème.
Symptôme : le serveur crashe avec Couldn't get DLL API from,
les fichiers .so existent mais sont illisibles depuis le conteneur.
Un docker run ... ls -la confirme Permission denied.
Solution : ajouter chmod -R 755 à la fin du script d’installation :
|
1 2 3 |
# Rendre tout lisible/executable pour le conteneur de jeu (UID 988) chmod -R 755 /mnt/server/ 2>/dev/null || true chmod +x /mnt/server/hlds_linux /mnt/server/hlds_run 2>/dev/null || true |
Diagnostic : pour vérifier les permissions depuis l’hôte,
lancer un conteneur avec le même UID que le jeu :
|
1 2 |
docker run --rm -u 988:988 -v /home/docker/pterodactyl/data/volumes/UUID:/srv \ ghcr.io/ptero-eggs/games:source ls -la /srv/cstrike/addons/metamod/ |
12.5 Reunion — reunion.cfg au mauvais emplacement
Reunion cherche sa config dans cstrike/reunion.cfg (racine du mod),
pas dans cstrike/addons/reunion/reunion.cfg.
De plus, la clé SteamIdHashSalt doit contenir au moins 16 caractères
pour les versions AuthVersion ≥ 3. Sans cela, Reunion se charge mais
affiche fail dans meta list.
Solution : copier reunion.cfg dans cstrike/
et générer un salt automatiquement :
|
1 2 3 4 5 6 7 8 9 |
# Copier la config au bon endroit cp -f "$REUNION_CFG" /mnt/server/cstrike/reunion.cfg # Generer SteamIdHashSalt si absent ou trop court SALT=$(grep -o 'SteamIdHashSalt *= *[^ ]*' /mnt/server/cstrike/reunion.cfg | sed 's/.*= *//') if [ ${#SALT} -lt 16 ]; then NEW_SALT=$(head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \n' | head -c 32) sed -i "s/SteamIdHashSalt *=.*/SteamIdHashSalt = ${NEW_SALT}/" /mnt/server/cstrike/reunion.cfg fi |
12.6 Advanced Quake Sounds — pas de .amxx pré-compilé
Le dépôt GitHub AdvancedQuakeSounds
ne contient que le code source AQS.sma, pas de fichier .amxx
pré-compilé. Il faut compiler le plugin avec amxxpc
(inclus dans AMX Mod X).
Attention à la syntaxe de amxxpc :
le flag -o s’écrit sans espace avant le chemin
(syntaxe Pawn). Avec un espace, amxxpc interprète le chemin
comme un fichier source à lire et échoue avec
fatal error 100: cannot read from file.
|
1 2 3 4 5 6 7 8 |
# ✗ ./amxxpc AQS.sma -o ../plugins/AQS.amxx (espace = erreur) # ✓ ./amxxpc AQS.sma -o../plugins/AQS.amxx (sans espace = OK) AMXXPC="/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc" cp -f AQS.sma /mnt/server/cstrike/addons/amxmodx/scripting/ cd /mnt/server/cstrike/addons/amxmodx/scripting chmod +x amxxpc ./amxxpc AQS.sma -o../plugins/AQS.amxx |
12.7 Injection des scripts dans les eggs JSON
Les scripts bash contiennent des caractères spéciaux (backslashes, guillemets, $)
qui cassent l’encodage JSON si on les copie-colle manuellement.
Utiliser un script Python pour injecter proprement :
|
1 2 3 4 5 6 7 8 9 10 |
import json for name, sh in [('egg-cs16-deathmatch.json', 'install-dm.sh'), ('egg-cs16-gungame.json', 'install-gg.sh')]: with open(sh, 'r', encoding='utf-8') as f: script = f.read() with open(name, 'r', encoding='utf-8') as f: egg = json.load(f) egg['scripts']['installation']['script'] = script with open(name, 'w', encoding='utf-8') as f: json.dump(egg, f, indent=2, ensure_ascii=False) |
Après réimport d’un egg :
importer l’egg mis à jour dans le panel ne met pas à jour
les serveurs existants. Il faut aller dans
Server → Settings → Reinstall Server
pour relancer le script d’installation.
12.8 Nginx sub_filter — la valeur doit tenir sur une seule ligne
La directive sub_filter de Nginx n’accepte pas de retour à la ligne
dans la chaîne de remplacement. Un CSS indenté sur plusieurs lignes provoque une erreur
de syntaxe au démarrage de Nginx :
|
1 |
nginx: [emerg] invalid number of arguments in "sub_filter" directive |
Solution : minifier le CSS sur une seule ligne, sans saut de ligne
ni indentation dans la valeur sub_filter :
|
1 2 3 4 5 6 7 8 |
# ✗ Multi-ligne (provoque une erreur Nginx) : sub_filter '</head>' '<style> body { background: #1a1a2e; color: #e0e0e0; } h1 { color: #e94560; } </style></head>'; # ✓ Minifié sur une seule ligne : sub_filter '</head>' '<style>body{background:#1a1a2e;color:#e0e0e0}h1{color:#e94560}</style></head>'; |
12.9 VestaCP %proxy_port% — résolu en 8080 au lieu de 80
Lors de l’application du template FastDL avec v-change-web-domain-proxy-tpl,
VestaCP a généré les fichiers de config Nginx avec les ports 8080 et
8443 au lieu de 80 et 443. Les variables %proxy_port% et
%proxy_ssl_port% se sont résolues vers les ports backend Apache.
Résultat : Nginx ne démarre pas car Apache occupe déjà ces ports.
|
1 |
nginx: [emerg] bind() to {{IP_NOUVEAU}}:8443 failed (98: Address already in use) |
Solution définitive : utiliser les ports en dur (80 et 443) directement
dans les fichiers fastdl.tpl et fastdl.stpl au lieu des variables VestaCP :
|
1 2 3 4 5 |
# Dans fastdl.tpl : listen %ip%:80; # PAS %ip%:%proxy_port% (sinon → 8080) # Dans fastdl.stpl : listen %ip%:443 ssl; # PAS %ip%:%proxy_ssl_port% (sinon → 8443) |
Puis réappliquer le template et recharger :
|
1 2 |
/usr/local/vesta/bin/v-change-web-domain-proxy-tpl {{USER_VESTA}} fastdl.{{DOMAINE_GAMING}} fastdl nginx -t && systemctl reload nginx |
Explication : dans l’architecture VestaCP, %proxy_port% désigne
le port où Nginx écoute en tant que proxy vers Apache (8080/8443).
Pour un template FastDL sans backend Apache (Nginx sert directement les fichiers statiques),
il faut écouter sur les ports frontend (80/443). D’où les ports en dur.
Si les templates sont déjà appliqués avec les mauvais ports,
corriger les configs générées en urgence :
|
1 2 3 4 |
# Fix rapide sur les configs déjà générées sed -i 's/:8080;/:80;/' /home/{{USER_VESTA}}/conf/web/fastdl.{{DOMAINE_GAMING}}/nginx.conf sed -i 's/:8443 ssl;/:443 ssl;/' /home/{{USER_VESTA}}/conf/web/fastdl.{{DOMAINE_GAMING}}/nginx.ssl.conf nginx -t && systemctl reload nginx |
Diagnostic : ss -tlnp | grep 8080 pour voir quel service occupe le port.
Apache sur 8080/8443 est le backend normal de VestaCP.
12.10 ssl_stapling — warnings avec certificats auto-signés
Après activation du template HTTPS, nginx -t affiche des warnings
(non bloquants mais gênants) pour les domaines utilisant des certificats auto-signés
ou en attente de Let’s Encrypt :
|
1 2 |
nginx: [warn] "ssl_stapling" ignored, no OCSP responder URL in the certificate "/home/{{USER_VESTA}}/conf/web/ssl.fastdl.{{DOMAINE_GAMING}}.pem" |
Solution temporaire : commenter ssl_stapling dans les configs
concernées. Après activation de Let’s Encrypt, décommenter.
|
1 2 3 4 5 |
# Commenter ssl_stapling pour un domaine sed -i 's/ssl_stapling/#ssl_stapling/' /home/{{USER_VESTA}}/conf/web/fastdl.{{DOMAINE_GAMING}}/nginx.ssl.conf # Vérifier : plus de warnings nginx -t |
Explication : OCSP Stapling nécessite un certificat avec l’URL du
répondeur OCSP de l’autorité de certification.
Les certificats auto-signés de VestaCP n’en ont pas.
Let’s Encrypt fournit cette URL, donc le problème disparaît une fois le certificat LE activé.
Eggs Pterodactyl — fichiers JSON
Chaque egg ci-dessous contient le script d’installation automatique complet.
Cliquez pour déplier, puis copiez le JSON et importez-le dans Pterodactyl
via Admin → Nests → Import Egg.
Pensez à remplacer les {{VARIABLES}} dans chaque egg
par vos propres valeurs (domaine, tags, etc.) avant l’import, ou modifiez-les
après import dans les paramètres de l’egg.
CS 1.6 ReHLDS – Deathmatch
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
{ "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-03-01T12:00:00+01:00", "name": "CS 1.6 ReHLDS - Deathmatch", "author": "admin@{{DOMAINE_GAMING}}", "description": "Counter-Strike 1.6 Deathmatch avec ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion. Plugins : ReDeathmatch (choix armes /guns /menu), YaPB bots, BotManager, Advanced Quake Sounds, QuickNoScopeD (noscope AWP), Double Jump, Parachute, DM Welcome. Random spawns (mp_randomspawn 3). Maps depuis FastDL. Installation 100% automatique.", "features": null, "docker_images": { "ghcr.io/ptero-eggs/games:source": "ghcr.io/ptero-eggs/games:source" }, "file_denylist": [], "startup": "./hlds_run -console -game {{HLDS_GAME}} -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -norestart +maxplayers {{MAX_PLAYERS}} +pingboost 2 +sys_ticrate 1200 +hostname \"{{HOSTNAME}}\"", "config": { "files": "{}", "startup": "{\"done\": \"gameserver Steam\"}", "logs": "{}", "stop": "quit" }, "scripts": { "installation": { "script": "#!/bin/bash\ncd /mnt/server\n\napt-get update -qq && apt-get install -yqq unzip xz-utils wget > /dev/null 2>&1 || true\n\necho \"=============================================\"\necho \" CS 1.6 Deathmatch - Installation automatique\"\necho \"=============================================\"\n\n##############################################\n# Helper: GitHub download URL (HTML scraping + API fallback)\n##############################################\ngithub_get_url() {\n local repo=\"$1\" pattern=\"$2\" url=\"\"\n echo \" [INFO] Recherche: repo=${repo} pattern=${pattern}\" >&2\n # GitHub API (POSIX grep, pas de -P)\n for attempt in 1 2 3; do\n url=$(curl -sSL \"https://api.github.com/repos/${repo}/releases/latest\" \\\n | grep -o '\"browser_download_url\": *\"[^\"]*\"' \\\n | grep \"${pattern}\" | head -1 \\\n | sed 's/.*\"browser_download_url\": *\"//;s/\"$//')\n if [ -n \"$url\" ]; then\n echo \" [OK] URL trouvee: ${url}\" >&2\n echo \"$url\"\n return 0\n fi\n echo \" [WARN] API tentative ${attempt}/3 echouee, retry...\" >&2\n sleep 3\n done\n echo \" [ECHEC] Aucune URL trouvee pour ${repo}\" >&2\n return 1\n}\n\n##############################################\n# 1) SteamCMD + HLDS\n##############################################\necho \"\"\necho \">>> [1/16] SteamCMD + HLDS (App ID 90)...\"\nmkdir -p steamcmd\ncd steamcmd\nif [ ! -f steamcmd.sh ]; then\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz\nfi\ncd /mnt/server\n\n./steamcmd/steamcmd.sh +force_install_dir /mnt/server \\\n +login anonymous \\\n +app_update 90 -beta steam_legacy validate \\\n +quit\n\n# Steam SDK setup\nmkdir -p /mnt/server/.steam/sdk32\necho \"10\" > /mnt/server/steam_appid.txt\nSTEAM_SO=$(find /mnt/server/steamcmd -path \"*/linux32/steamclient.so\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit copie depuis $STEAM_SO\"\nelse\n echo \" [WARN] steamclient.so non trouve, telechargement direct...\"\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz -C /tmp/ linux32/steamclient.so 2>/dev/null\n if [ -f /tmp/linux32/steamclient.so ]; then\n cp -f /tmp/linux32/steamclient.so /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so telecharge\"\n fi\n rm -rf /tmp/linux32\nfi\n\n##############################################\n# 2) ReHLDS\n##############################################\necho \"\"\necho \">>> [2/16] ReHLDS...\"\nREHLDS_URL=$(github_get_url \"rehlds/ReHLDS\" \"rehlds-bin.*\\.zip\")\nif [ -n \"$REHLDS_URL\" ]; then\n echo \" URL: $REHLDS_URL\"\n curl -fsSL -o /tmp/rehlds.zip \"$REHLDS_URL\"\n if [ -s /tmp/rehlds.zip ]; then\n unzip -qo /tmp/rehlds.zip -d /tmp/rehlds/\n REHLDS_BIN=$(find /tmp/rehlds -name \"hlds_linux\" -type f | head -1)\n if [ -n \"$REHLDS_BIN\" ]; then\n REHLDS_DIR=$(dirname \"$REHLDS_BIN\")\n cp -rf \"$REHLDS_DIR\"/* /mnt/server/\n echo \" Binaires ReHLDS copies\"\n else\n echo \" WARN: hlds_linux non trouve dans l'archive\"\n fi\n else\n echo \" WARN: Telechargement echoue (fichier vide)\"\n fi\n rm -rf /tmp/rehlds /tmp/rehlds.zip\nelse\n echo \" WARN: URL ReHLDS non trouvee (GitHub API rate limit?)\"\nfi\n# Verification obligatoire\nif strings /mnt/server/hlds_linux 2>/dev/null | grep -qi \"rehlds\"; then\n echo \" [OK] ReHLDS verifie\"\nelse\n echo \" [ERREUR] ReHLDS NON installe ! Le serveur risque de ne pas demarrer\"\nfi\n\n##############################################\n# 3) ReGameDLL_CS\n##############################################\necho \"\"\necho \">>> [3/16] ReGameDLL_CS...\"\nREGAME_URL=$(github_get_url \"rehlds/ReGameDLL_CS\" \"\\.zip\")\nif [ -n \"$REGAME_URL\" ]; then\n echo \" URL: $REGAME_URL\"\n curl -fsSL -o /tmp/regamedll.zip \"$REGAME_URL\"\n if [ -s /tmp/regamedll.zip ]; then\n unzip -qo /tmp/regamedll.zip -d /tmp/regamedll/\n CSSO=$(find /tmp/regamedll -name \"cs.so\" -path \"*linux32*\" | head -1)\n [ -n \"$CSSO\" ] && cp -f \"$CSSO\" /mnt/server/cstrike/dlls/cs.so\n EXTRAS=$(find /tmp/regamedll -type d -name \"gamedir\" | head -1)\n [ -n \"$EXTRAS\" ] && cp -rn \"$EXTRAS\"/* /mnt/server/cstrike/ 2>/dev/null || true\n echo \" [OK] ReGameDLL installe\"\n fi\n rm -rf /tmp/regamedll /tmp/regamedll.zip\nelse\n echo \" WARN: Impossible de telecharger ReGameDLL_CS\"\nfi\n\n##############################################\n# 4) Metamod-R\n##############################################\necho \"\"\necho \">>> [4/16] Metamod-R...\"\nMETAMOD_URL=$(github_get_url \"rehlds/metamod-r\" \"\\.zip\")\nif [ -n \"$METAMOD_URL\" ]; then\n echo \" URL: $METAMOD_URL\"\n curl -fsSL -o /tmp/metamod.zip \"$METAMOD_URL\"\n if [ -s /tmp/metamod.zip ]; then\n unzip -qo /tmp/metamod.zip -d /tmp/metamod/\n mkdir -p /mnt/server/cstrike/addons/metamod\n META_DLL=$(find /tmp/metamod -name \"metamod_i386.so\" | head -1)\n [ -n \"$META_DLL\" ] && cp -f \"$META_DLL\" /mnt/server/cstrike/addons/metamod/\n echo \" [OK] Metamod-R installe\"\n fi\n rm -rf /tmp/metamod /tmp/metamod.zip\nelse\n echo \" WARN: Impossible de telecharger Metamod-R\"\nfi\n\n# TOUJOURS ecrire liblist.gam (meme si Metamod a echoue)\nif [ -f /mnt/server/cstrike/addons/metamod/metamod_i386.so ]; then\n GAMEDLL_LINUX=\"addons/metamod/metamod_i386.so\"\n echo \" [OK] liblist.gam -> Metamod\"\n # Creer plugins.ini si absent\n [ -f /mnt/server/cstrike/addons/metamod/plugins.ini ] \\\n || echo \"; Metamod plugins\" > /mnt/server/cstrike/addons/metamod/plugins.ini\nelse\n GAMEDLL_LINUX=\"dlls/cs.so\"\n echo \" [WARN] liblist.gam -> cs.so direct (Metamod absent)\"\nfi\ncat > /mnt/server/cstrike/liblist.gam << LIBLIST\ngame \"Counter-Strike\"\nurl_info \"www.counter-strike.net\"\nurl_dl \"\"\nversion \"1.6\"\nsize \"184000000\"\nsvonly \"0\"\ncldll \"1\"\nsecure \"1\"\nhlversion \"1110\"\nnomodels \"1\"\nnohimodel \"1\"\nmpentity \"info_player_start\"\ngamedll \"dlls\\cs.dll\"\ngamedll_linux \"${GAMEDLL_LINUX}\"\ngamedll_osx \"dlls/cs.dylib\"\ntype \"multiplayer_only\"\nLIBLIST\n\n##############################################\n# 5) AMX Mod X\n##############################################\necho \"\"\necho \">>> [5/16] AMX Mod X...\"\n# IMPORTANT: latest.php renvoie du HTML (pas de redirect), utiliser les URLs directes du drop\nAMXX_DROP=\"https://www.amxmodx.org/amxxdrop/1.10\"\ncurl -fsSL -o /tmp/amxmodx-base.tar.gz \"${AMXX_DROP}/amxmodx-latest-base-linux.tar.gz\"\ncurl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"${AMXX_DROP}/amxmodx-latest-cstrike-linux.tar.gz\"\ncd /mnt/server/cstrike\nif tar tzf /tmp/amxmodx-base.tar.gz > /dev/null 2>&1; then\n tar xzf /tmp/amxmodx-base.tar.gz\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.10 installe\"\nelse\n echo \" [WARN] 1.10 echoue, fallback 1.8.2 stable...\"\n curl -fsSL -o /tmp/amxmodx-base.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-base-linux.tar.gz\"\n curl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-cstrike-linux.tar.gz\"\n tar xzf /tmp/amxmodx-base.tar.gz 2>/dev/null || true\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.8.2 installe\"\nfi\nrm -f /tmp/amxmodx-base.tar.gz /tmp/amxmodx-cstrike.tar.gz\n# Verifier que le .so existe\nif [ -f /mnt/server/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so ]; then\n echo \" [OK] amxmodx_mm_i386.so verifie\"\nelse\n echo \" [ERREUR] amxmodx_mm_i386.so MANQUANT !\"\nfi\ngrep -q \"amxmodx\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/amxmodx/dlls/amxmodx_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\ncd /mnt/server\n\n##############################################\n# 6) ReAPI\n##############################################\necho \"\"\necho \">>> [6/16] ReAPI...\"\nREAPI_URL=$(github_get_url \"rehlds/ReAPI\" \"\\.zip\")\nif [ -n \"$REAPI_URL\" ]; then\n curl -fsSL -o /tmp/reapi.zip \"$REAPI_URL\"\n if [ -s /tmp/reapi.zip ]; then\n unzip -qo /tmp/reapi.zip -d /tmp/reapi/\n REAPI_SO=$(find /tmp/reapi -name \"reapi_amxx_i386.so\" | head -1)\n [ -n \"$REAPI_SO\" ] && cp -f \"$REAPI_SO\" /mnt/server/cstrike/addons/amxmodx/modules/\n grep -q \"reapi_amxx_i386.so\" /mnt/server/cstrike/addons/amxmodx/configs/modules.ini 2>/dev/null \\\n || echo \"reapi_amxx_i386.so\" >> /mnt/server/cstrike/addons/amxmodx/configs/modules.ini\n echo \" [OK] ReAPI installe\"\n fi\n rm -rf /tmp/reapi /tmp/reapi.zip\nelse\n echo \" WARN: Impossible de telecharger ReAPI\"\nfi\n\n##############################################\n# 7) Reunion\n##############################################\necho \"\"\necho \">>> [7/16] Reunion...\"\nREUNION_URL=$(github_get_url \"rehlds/ReUnion\" \"\\.zip\")\nif [ -n \"$REUNION_URL\" ]; then\n curl -fsSL -o /tmp/reunion.zip \"$REUNION_URL\"\n if [ -s /tmp/reunion.zip ]; then\n unzip -qo /tmp/reunion.zip -d /tmp/reunion/\n REUNION_SO=$(find /tmp/reunion -name \"reunion_mm_i386.so\" | head -1)\n if [ -n \"$REUNION_SO\" ]; then\n mkdir -p /mnt/server/cstrike/addons/reunion\n cp -f \"$REUNION_SO\" /mnt/server/cstrike/addons/reunion/\n # reunion.cfg doit etre dans cstrike/ (PAS addons/reunion/)\n REUNION_CFG=$(find /tmp/reunion -name \"reunion.cfg\" | head -1)\n if [ -n \"$REUNION_CFG\" ] && [ ! -f /mnt/server/cstrike/reunion.cfg ]; then\n cp -f \"$REUNION_CFG\" /mnt/server/cstrike/reunion.cfg\n fi\n # Generer SteamIdHashSalt si absent ou trop court\n if [ -f /mnt/server/cstrike/reunion.cfg ]; then\n SALT=$(grep -o 'SteamIdHashSalt *= *[^ ]*' /mnt/server/cstrike/reunion.cfg | sed 's/.*= *//')\n if [ ${#SALT} -lt 16 ]; then\n NEW_SALT=$(head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \\n' | head -c 32)\n sed -i \"s/SteamIdHashSalt *=.*/SteamIdHashSalt = ${NEW_SALT}/\" /mnt/server/cstrike/reunion.cfg\n echo \" [OK] SteamIdHashSalt genere (${#NEW_SALT} chars)\"\n fi\n fi\n grep -q \"reunion\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/reunion/reunion_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] Reunion installe\"\n # Configurer Reunion pour accepter Steam et no-steam\n if [ -f /mnt/server/cstrike/reunion.cfg ]; then\n sed -i 's/AuthVersion *= *.*/AuthVersion = 2/' /mnt/server/cstrike/reunion.cfg\n sed -i 's/ServerInfoAnswerType *= *.*/ServerInfoAnswerType = 2/' /mnt/server/cstrike/reunion.cfg\n # Autoriser les clients steam p48 (protocole 48)\n grep -q \"EnableSteam48Auth\" /mnt/server/cstrike/reunion.cfg && sed -i 's/EnableSteam48Auth *= *.*/EnableSteam48Auth = 1/' /mnt/server/cstrike/reunion.cfg\n grep -q \"EnableOldStyleAuth\" /mnt/server/cstrike/reunion.cfg && sed -i 's/EnableOldStyleAuth *= *.*/EnableOldStyleAuth = 1/' /mnt/server/cstrike/reunion.cfg\n echo \" [OK] Reunion configure (steam + no-steam autorises)\"\n fi\n fi\n fi\n rm -rf /tmp/reunion /tmp/reunion.zip\nelse\n echo \" WARN: Impossible de telecharger Reunion\"\nfi\n\n##############################################\n# 8) ReDeathmatch\n##############################################\necho \"\"\necho \">>> [8/16] ReDeathmatch...\"\nREDM_URL=$(github_get_url \"ReDeathmatch/ReDeathmatch_AMXX\" \"\\.zip\")\nif [ -n \"$REDM_URL\" ]; then\n curl -fsSL -o /tmp/redm.zip \"$REDM_URL\"\n if [ -s /tmp/redm.zip ]; then\n unzip -qo /tmp/redm.zip -d /tmp/redm/\n REDM_BASE=$(find /tmp/redm -maxdepth 3 -name \"addons\" -type d | head -1)\n if [ -n \"$REDM_BASE\" ]; then\n REDM_ROOT=$(dirname \"$REDM_BASE\")\n cp -rf \"$REDM_ROOT\"/addons/* /mnt/server/cstrike/addons/ 2>/dev/null || true\n for item in \"$REDM_ROOT\"/*; do\n name=$(basename \"$item\")\n [ \"$name\" != \"addons\" ] && [ -d \"$item\" ] && cp -rf \"$item\" /mnt/server/cstrike/ 2>/dev/null || true\n done\n fi\n find /tmp/redm -name \"*.amxx\" -exec basename {} \\; | sort -u | while read p; do\n grep -q \"$p\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"$p\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n done\n echo \" [OK] ReDeathmatch installe\"\n fi\n rm -rf /tmp/redm /tmp/redm.zip\nelse\n echo \" WARN: Impossible de telecharger ReDeathmatch\"\nfi\n\n##############################################\n# 9) YaPB (bots Metamod)\n##############################################\necho \"\"\necho \">>> [9/16] YaPB...\"\nYAPB_URL=$(github_get_url \"yapb/yapb\" \"linux.*\\.tar\\.xz\")\nif [ -n \"$YAPB_URL\" ]; then\n curl -fsSL -o /tmp/yapb.tar.xz \"$YAPB_URL\"\n if [ -s /tmp/yapb.tar.xz ]; then\n mkdir -p /tmp/yapb\n tar -xf /tmp/yapb.tar.xz -C /tmp/yapb/\n YAPB_DIR=$(find /tmp/yapb -type d -name \"yapb\" -path \"*/addons/yapb\" | head -1)\n [ -n \"$YAPB_DIR\" ] && cp -rf \"$YAPB_DIR\" /mnt/server/cstrike/addons/ 2>/dev/null || true\n # Ensure YaPB data directories are writable (graph, train, etc.)\n mkdir -p /mnt/server/cstrike/addons/yapb/data/graph\n mkdir -p /mnt/server/cstrike/addons/yapb/data/train\n chmod -R 755 /mnt/server/cstrike/addons/yapb/data\n grep -q \"yapb\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/yapb/bin/yapb.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] YaPB installe\"\n fi\n rm -rf /tmp/yapb /tmp/yapb.tar.xz\nelse\n echo \" WARN: Impossible de telecharger YaPB\"\nfi\n\n##############################################\n# 10) BotManager (5 bots toujours, kick a 4+ humains)\n##############################################\necho \"\"\necho \">>> [10/16] BotManager...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/bot_manager.sma << 'BOTSMA'\n/*\n * Bot Manager v2 - {{NOM_COMMUNAUTE}}Games.fr\n * 5 bots toujours presents pour attirer les joueurs.\n * Tous les bots kick quand 4+ vrais joueurs connectes.\n * CVARs:\n * bm_bot_count = nombre de bots (defaut 5)\n * bm_kick_threshold = seuil pour kick les bots (defaut 4)\n */\n#include <amxmodx>\n\nnew g_cvarBotCount\nnew g_cvarKickThreshold\n\npublic plugin_init()\n{\n register_plugin(\"BotManager\", \"2.0\", \"{{NOM_COMMUNAUTE}}Games\")\n g_cvarBotCount = register_cvar(\"bm_bot_count\", \"5\")\n g_cvarKickThreshold = register_cvar(\"bm_kick_threshold\", \"4\")\n}\n\npublic plugin_cfg()\n{\n set_task(3.0, \"check_bots\")\n}\n\npublic client_putinserver(id)\n{\n set_task(2.0, \"check_bots\")\n}\n\npublic client_disconnected(id, bool:drop, message[], maxlen)\n{\n set_task(1.0, \"check_bots\")\n}\n\npublic check_bots()\n{\n new humans = count_humans()\n new fill = get_pcvar_num(g_cvarBotCount)\n new threshold = get_pcvar_num(g_cvarKickThreshold)\n\n if (humans >= threshold)\n server_cmd(\"yb_quota 0\")\n else\n server_cmd(\"yb_quota %d\", fill)\n}\n\ncount_humans()\n{\n new players[32], num, count = 0\n get_players(players, num, \"ch\")\n for (new i = 0; i < num; i++)\n {\n if (!is_user_bot(players[i]))\n count++\n }\n return count\n}\nBOTSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc bot_manager.sma -o../plugins/bot_manager.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/bot_manager.amxx ]; then\n grep -q \"bot_manager.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"bot_manager.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] bot_manager.amxx compile et installe\"\n else\n echo \" [WARN] Compilation bot_manager echouee\"\n fi\nelse\n echo \" [WARN] amxxpc non trouve, impossible de compiler bot_manager\"\nfi\n\n##############################################\n# 11) DM Welcome + /menu alias\n##############################################\necho \"\"\necho \">>> [11/16] DM Welcome + /menu...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/dm_welcome.sma << 'WELCOMESMA'\n/*\n * DM Welcome + /menu alias - {{NOM_COMMUNAUTE}}Games.fr\n * - Message de bienvenue au spawn\n * - /menu comme alias de /guns\n */\n#include <amxmodx>\n\nnew bool:g_firstSpawn[33]\n\npublic plugin_init()\n{\n register_plugin(\"DM Welcome\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"say /menu\", \"cmd_menu\")\n register_clcmd(\"say .menu\", \"cmd_menu\")\n}\n\npublic client_putinserver(id)\n{\n g_firstSpawn[id] = true\n set_task(5.0, \"show_welcome\", id)\n}\n\npublic client_disconnected(id)\n{\n g_firstSpawn[id] = false\n}\n\npublic show_welcome(id)\n{\n if (!is_user_connected(id)) return\n\n client_print(id, print_chat, \"**********************************\")\n client_print(id, print_chat, \"* Bienvenue sur [FR] DEATHMATCH {{TAG_CLAN}} #{{NOM_COMMUNAUTE}} !\")\n client_print(id, print_chat, \"* /guns ou /menu - Changer d'arme\")\n client_print(id, print_chat, \"* Double Jump actif + Parachute (touche E)\")\n client_print(id, print_chat, \"* /rs - Reset score\")\n client_print(id, print_chat, \"**********************************\")\n}\n\npublic cmd_menu(id)\n{\n // Declencher la commande /guns de ReDeathmatch\n client_cmd(id, \"say /guns\")\n return PLUGIN_HANDLED\n}\nWELCOMESMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc dm_welcome.sma -o../plugins/dm_welcome.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/dm_welcome.amxx ]; then\n grep -q \"dm_welcome.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"dm_welcome.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] dm_welcome.amxx compile et installe\"\n else\n echo \" [WARN] Compilation dm_welcome echouee\"\n fi\nelse\n echo \" [WARN] amxxpc non trouve, impossible de compiler dm_welcome\"\nfi\n\n##############################################\n# 12) Double Jump + Parachute\n##############################################\necho \"\"\necho \">>> [12/16] Double Jump + Parachute...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n\n # --- Double Jump ---\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/doublejump.sma << 'DJSMA'\n#include <amxmodx>\n#include <fakemeta>\n\n#define MAX_EXTRA_JUMPS 1\n\nnew g_jumpCount[33]\n\npublic plugin_init()\n{\n register_plugin(\"Double Jump\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlayerPreThink, \"fw_PreThink_DJ\")\n}\n\npublic client_putinserver(id)\n{\n g_jumpCount[id] = 0\n}\n\npublic fw_PreThink_DJ(id)\n{\n if (!is_user_alive(id)) return FMRES_IGNORED\n\n new flags = pev(id, pev_flags)\n new buttons = pev(id, pev_button)\n new oldbuttons = pev(id, pev_oldbuttons)\n\n if (flags & FL_ONGROUND)\n {\n g_jumpCount[id] = 0\n return FMRES_IGNORED\n }\n\n // Nouvelle pression sur jump en l'air\n if ((buttons & IN_JUMP) && !(oldbuttons & IN_JUMP))\n {\n if (g_jumpCount[id] < MAX_EXTRA_JUMPS)\n {\n g_jumpCount[id]++\n new Float:vel[3]\n pev(id, pev_velocity, vel)\n vel[2] = 268.0\n set_pev(id, pev_velocity, vel)\n }\n }\n\n return FMRES_IGNORED\n}\nDJSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc doublejump.sma -o../plugins/doublejump.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/doublejump.amxx ]; then\n grep -q \"doublejump.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"doublejump.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] doublejump.amxx compile et installe\"\n else\n echo \" [WARN] Compilation doublejump echouee\"\n fi\n\n # --- Parachute (maintenir E pour ralentir la chute) ---\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/parachute.sma << 'PARASMA'\n#include <amxmodx>\n#include <fakemeta>\n\n#define FALL_SPEED -100.0\n\nnew bool:g_parachuteOn[33]\n\npublic plugin_init()\n{\n register_plugin(\"Parachute\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlayerPreThink, \"fw_PreThink_Para\")\n register_clcmd(\"say /parachute\", \"cmd_info\")\n register_clcmd(\"say /para\", \"cmd_info\")\n}\n\npublic client_putinserver(id)\n{\n g_parachuteOn[id] = false\n}\n\npublic cmd_info(id)\n{\n client_print(id, print_chat, \"[Parachute] Maintiens E en l'air pour deployer le parachute !\")\n return PLUGIN_HANDLED\n}\n\npublic fw_PreThink_Para(id)\n{\n if (!is_user_alive(id)) return FMRES_IGNORED\n\n new buttons = pev(id, pev_button)\n new flags = pev(id, pev_flags)\n\n if (!(flags & FL_ONGROUND) && (buttons & IN_USE))\n {\n new Float:vel[3]\n pev(id, pev_velocity, vel)\n\n if (vel[2] < FALL_SPEED)\n {\n vel[2] = FALL_SPEED\n set_pev(id, pev_velocity, vel)\n\n if (!g_parachuteOn[id])\n {\n g_parachuteOn[id] = true\n set_pev(id, pev_sequence, 3)\n set_pev(id, pev_gaitsequence, 1)\n }\n }\n }\n else\n {\n if (g_parachuteOn[id])\n g_parachuteOn[id] = false\n }\n\n return FMRES_IGNORED\n}\nPARASMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n ./amxxpc parachute.sma -o../plugins/parachute.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/parachute.amxx ]; then\n grep -q \"parachute.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"parachute.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] parachute.amxx compile et installe\"\n else\n echo \" [WARN] Compilation parachute echouee\"\n fi\n\nelse\n echo \" [WARN] amxxpc non trouve, impossible de compiler doublejump/parachute\"\nfi\n\n# Activer fakemeta si pas deja fait\nAMXX_MODULES=\"/mnt/server/cstrike/addons/amxmodx/configs/modules.ini\"\nif grep -q \"^;fakemeta\" \"$AMXX_MODULES\" 2>/dev/null; then\n sed -i 's/^;fakemeta/fakemeta/' \"$AMXX_MODULES\"\n echo \" [OK] Module fakemeta active\"\nfi\n\n##############################################\n# 13) Advanced Quake Sounds\n##############################################\necho \"\"\necho \">>> [13/16] Advanced Quake Sounds...\"\ncurl -fsSL -o /tmp/aqs.zip \\\n \"https://github.com/ClaudiuHKS/AdvancedQuakeSounds/archive/refs/heads/master.zip\"\nif [ -s /tmp/aqs.zip ]; then\n unzip -qo /tmp/aqs.zip -d /tmp/aqs/\n AQS=\"/tmp/aqs/AdvancedQuakeSounds-master\"\n # Compiler AQS.sma (pas de .amxx pre-compile dans le repo)\n AMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\n if [ -f \"$AQS/AQS.sma\" ] && [ -f \"$AMXXPC\" ]; then\n cp -f \"$AQS/AQS.sma\" /mnt/server/cstrike/addons/amxmodx/scripting/\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc AQS.sma -o../plugins/AQS.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/AQS.amxx ]; then\n echo \" [OK] AQS.amxx compile\"\n else\n echo \" [WARN] Compilation echouee\"\n fi\n else\n echo \" [WARN] AQS.sma ou amxxpc non trouve\"\n fi\n # Config + Sons\n [ -f \"$AQS/AQS.ini\" ] && cp -f \"$AQS/AQS.ini\" /mnt/server/cstrike/addons/amxmodx/configs/\n # Desactiver les sons de teamkill dans AQS\n AQS_CFG=\"/mnt/server/cstrike/addons/amxmodx/configs/AQS.ini\"\n if [ -f \"$AQS_CFG\" ]; then\n sed -i 's/^TEAMKILL EVENT =.*/TEAMKILL EVENT = 0/' \"$AQS_CFG\"\n echo \" [OK] TEAMKILL EVENT desactive dans AQS\"\n fi\n mkdir -p /mnt/server/cstrike/sound/AQS/\n if [ -f \"$AQS/sound.zip\" ]; then\n unzip -qo \"$AQS/sound.zip\" -d /mnt/server/cstrike/ 2>/dev/null || true\n elif [ -d \"$AQS/sound/AQS\" ]; then\n cp -rf \"$AQS/sound/AQS/\"* /mnt/server/cstrike/sound/AQS/ 2>/dev/null || true\n fi\n grep -q \"AQS.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"AQS.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] AQS installe\"\n rm -rf /tmp/aqs /tmp/aqs.zip\nelse\n echo \" WARN: Impossible de telecharger AQS\"\nfi\n\n##############################################\n# 14) AWP NoScope (QuickNoScopeD)\n##############################################\necho \"\"\necho \">>> [14/16] AWP NoScope...\"\ncurl -fsSL -o /mnt/server/cstrike/addons/amxmodx/plugins/QuickNoScopeD.amxx \\\n \"http://{{DOMAINE_GAMING}}/plugins/QuickNoScopeD.amxx\"\nif [ -f /mnt/server/cstrike/addons/amxmodx/plugins/QuickNoScopeD.amxx ]; then\n grep -q \"QuickNoScopeD.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"QuickNoScopeD.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] QuickNoScopeD installe\"\nelse\n echo \" [WARN] Impossible de telecharger QuickNoScopeD\"\nfi\n\n##############################################\n\n##############################################\n# 14b) DM AIM No Friendly Fire\n##############################################\necho \"\"\necho \">>> [14b/16] DM AIM No Friendly Fire...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/dm_aim_noff.sma << 'AIMNOFFSMA'\n#include <amxmodx>\n\npublic plugin_init()\n{\n register_plugin(\"AIM No FF\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n}\n\npublic plugin_cfg()\n{\n new mapname[32]\n get_mapname(mapname, charsmax(mapname))\n\n if (equali(mapname, \"aim_\", 4))\n {\n server_cmd(\"mp_friendlyfire 0\")\n set_hudmessage(0, 255, 0, -1.0, 0.3, 0, 0.0, 5.0)\n show_hudmessage(0, \"Map AIM: Friendly Fire desactive\")\n }\n else\n {\n server_cmd(\"mp_friendlyfire 1\")\n }\n}\nAIMNOFFSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc dm_aim_noff.sma -o../plugins/dm_aim_noff.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/dm_aim_noff.amxx ]; then\n grep -q \"dm_aim_noff.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"dm_aim_noff.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] dm_aim_noff.amxx compile et installe\"\n else\n echo \" [WARN] Compilation dm_aim_noff echouee\"\n fi\nelse\n echo \" [WARN] amxxpc non trouve, impossible de compiler dm_aim_noff\"\nfi\n\n# 15) Maps custom depuis FastDL\n##############################################\necho \"\"\necho \">>> [15/16] Telechargement des maps depuis FastDL...\"\nFASTDL_URL=\"https://fastdl.{{DOMAINE_GAMING}}/cs_dm\"\n# wget recursif : telecharge maps/, gfx/, sound/, sprites/, overviews/, models/, *.wad\n# --cut-dirs=1 supprime \"cs_dm/\" du chemin pour copier directement dans cstrike/\nwget -r -np -nH --cut-dirs=1 -P /mnt/server/cstrike/ \\\n -R \"index.html*\" \\\n --no-check-certificate \\\n -q --show-progress \\\n \"$FASTDL_URL/\" 2>&1 || echo \" [WARN] wget a rencontre des erreurs (certains fichiers peuvent manquer)\"\n\nMAP_COUNT=$(find /mnt/server/cstrike/maps -name \"*.bsp\" 2>/dev/null | wc -l)\necho \" [OK] ${MAP_COUNT} maps .bsp telechargees\"\n\n# Generer mapcycle.txt a partir des maps telechargees (sans les maps par defaut HLDS sauf de_dust2)\necho \">>> Generation de mapcycle.txt depuis les maps telechargees...\"\nEXCLUDE_MAPS=\"as_oilrig cs_747 cs_assault cs_backalley cs_estate cs_havana cs_italy cs_militia cs_office cs_siege de_airstrip de_aztec de_cbble de_chateau de_dust de_inferno de_nuke de_piranesi de_prodigy de_storm de_survivor de_torn de_train de_vertigo\"\nfind /mnt/server/cstrike/maps -name \"*.bsp\" -printf \"%f\\n\" 2>/dev/null \\\n | sed 's/\\.bsp$//' | sort > /mnt/server/cstrike/mapcycle.txt\nfor m in $EXCLUDE_MAPS; do\n sed -i \"/^${m}$/d\" /mnt/server/cstrike/mapcycle.txt\ndone\necho \" [OK] mapcycle.txt genere ($(wc -l < /mnt/server/cstrike/mapcycle.txt) maps, maps HLDS exclues)\"\n\n##############################################\n# 16) server.cfg Deathmatch\n##############################################\necho \"\"\necho \">>> [16/16] server.cfg...\"\ncat > /mnt/server/cstrike/server.cfg << 'SERVERCFG'\nhostname \"[FR] DEATHMATCH {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}\"\nsv_contact \"admin@{{DOMAINE_GAMING}}\"\nrcon_password \"changeme\"\n\n// Deathmatch settings\nmp_timelimit 20\nmp_freezetime 0\nmp_roundtime 0\nmp_autoteambalance 1\nmp_friendlyfire 0\nsv_maxspeed 320\nsv_alltalk 1\nsv_voiceenable 1\n\n// Random spawns (ReGameDLL) : 3 = les deux equipes utilisent TOUS les spawns\nmp_randomspawn 3\n\n// Rates\nsv_maxrate 25000\nsv_minrate 6000\nsv_maxupdaterate 102\nsv_minupdaterate 30\n\n// Downloads + FastDL\nsv_allowdownload 1\nsv_allowupload 0\nsv_downloadurl \"https://fastdl.{{DOMAINE_GAMING}}/cs_dm\"\n\n// YaPB bots\nyb_quota 5\nyb_auto_waypoint 1\nyb_chat 0\nyb_language_tag 0\n\n// BotManager : 5 bots toujours presents, kick quand 4+ vrais joueurs\nbm_bot_count 5\nbm_kick_threshold 4\n\nexec banned.cfg\nexec listip.cfg\nSERVERCFG\n\n##############################################\n# Fix permissions\n##############################################\necho \"\"\necho \">>> Fix des permissions...\"\n# Rendre tout lisible/executable pour le conteneur de jeu (UID 988)\nchmod -R 755 /mnt/server/ 2>/dev/null || true\nchmod +x /mnt/server/hlds_linux /mnt/server/hlds_run /mnt/server/hlds_amd 2>/dev/null || true\nchmod +x /mnt/server/hltv 2>/dev/null || true\n\n# Re-copie steamclient.so 32-bit (au cas ou ReHLDS l'a ecrase)\nSTEAM_SO=$(find /mnt/server -path \"*/linux32/steamclient.so\" -not -path \"*/.steam/*\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n mkdir -p /mnt/server/.steam/sdk32\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit re-copie\"\nfi\n\necho \"\"\necho \"=============================================\"\necho \" Installation terminee !\"\necho \" Plugins : ReHLDS + ReGameDLL + Metamod-R\"\necho \" + AMX Mod X + ReAPI + Reunion\"\necho \" + ReDeathmatch + YaPB + AQS\"\necho \" + QuickNoScopeD + Double Jump\"\necho \" + Parachute + DM Welcome\"\necho \"=============================================\"\necho \"\"\necho \" Commandes joueurs:\"\necho \" /guns ou /menu - Changer d'arme\"\necho \" /rs - Reset score\"\necho \" /para - Info parachute\"\necho \" Double Jump - Sauter 2x en l'air\"\necho \" Parachute - Maintenir E en l'air\"\necho \"=============================================\"\n", "container": "ghcr.io/ptero-eggs/installers:debian", "entrypoint": "bash" } }, "variables": [ { "name": "Server Hostname", "description": "Nom du serveur affiché dans le navigateur de serveurs", "env_variable": "HOSTNAME", "default_value": "[FR] DEATHMATCH {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}", "user_viewable": true, "user_editable": true, "rules": "required|string|between:1,64", "field_type": "text" }, { "name": "Default Map", "description": "Map chargée au démarrage du serveur", "env_variable": "SRCDS_MAP", "default_value": "de_dust2", "user_viewable": true, "user_editable": true, "rules": "required|string", "field_type": "text" }, { "name": "Max Players", "description": "Nombre maximum de joueurs", "env_variable": "MAX_PLAYERS", "default_value": "32", "user_viewable": true, "user_editable": true, "rules": "required|integer|between:2,32", "field_type": "text" }, { "name": "Game Folder", "description": "Dossier du jeu (ne pas modifier)", "env_variable": "HLDS_GAME", "default_value": "cstrike", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" }, { "name": "Steam App ID", "description": "App ID Steam pour CS 1.6 (ne pas modifier)", "env_variable": "SRCDS_APPID", "default_value": "90", "user_viewable": false, "user_editable": false, "rules": "required|integer", "field_type": "text" } ] } |
CS 1.6 ReHLDS – GunGame
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
{ "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-03-01T12:00:00+01:00", "name": "CS 1.6 ReHLDS - GunGame", "author": "admin@{{DOMAINE_GAMING}}", "description": "Counter-Strike 1.6 GunGame avec ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion, GunGame AMXX 2.13c, YaPB (bots), BotManager, Double Jump et Advanced Quake Sounds. Installation 100% automatique.", "features": null, "docker_images": { "ghcr.io/ptero-eggs/games:source": "ghcr.io/ptero-eggs/games:source" }, "file_denylist": [], "startup": "./hlds_run -console -game {{HLDS_GAME}} -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -norestart +maxplayers {{MAX_PLAYERS}} +pingboost 2 +sys_ticrate 1200 +hostname \"{{HOSTNAME}}\"", "config": { "files": "{}", "startup": "{\"done\": \"gameserver Steam\"}", "logs": "{}", "stop": "quit" }, "scripts": { "installation": { "script": "#!/bin/bash\ncd /mnt/server\n\napt-get update -qq && apt-get install -yqq unzip xz-utils wget > /dev/null 2>&1 || true\n\necho \"=============================================\"\necho \" CS 1.6 GunGame - Installation automatique\"\necho \"=============================================\"\n\n##############################################\n# Helper: GitHub download URL (HTML scraping + API fallback)\n##############################################\ngithub_get_url() {\n local repo=\"$1\" pattern=\"$2\" url=\"\"\n echo \" [INFO] Recherche: repo=${repo} pattern=${pattern}\" >&2\n # GitHub API (POSIX grep, pas de -P)\n for attempt in 1 2 3; do\n url=$(curl -sSL \"https://api.github.com/repos/${repo}/releases/latest\" \\\n | grep -o '\"browser_download_url\": *\"[^\"]*\"' \\\n | grep \"${pattern}\" | head -1 \\\n | sed 's/.*\"browser_download_url\": *\"//;s/\"$//')\n if [ -n \"$url\" ]; then\n echo \" [OK] URL trouvee: ${url}\" >&2\n echo \"$url\"\n return 0\n fi\n echo \" [WARN] API tentative ${attempt}/3 echouee, retry...\" >&2\n sleep 3\n done\n echo \" [ECHEC] Aucune URL trouvee pour ${repo}\" >&2\n return 1\n}\n\n##############################################\n# 1) SteamCMD + HLDS\n##############################################\necho \"\"\necho \">>> [1/14] SteamCMD + HLDS (App ID 90)...\"\nmkdir -p steamcmd\ncd steamcmd\nif [ ! -f steamcmd.sh ]; then\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz\nfi\ncd /mnt/server\n\n./steamcmd/steamcmd.sh +force_install_dir /mnt/server \\\n +login anonymous \\\n +app_update 90 -beta steam_legacy validate \\\n +quit\n\n# Steam SDK setup\nmkdir -p /mnt/server/.steam/sdk32\necho \"10\" > /mnt/server/steam_appid.txt\nSTEAM_SO=$(find /mnt/server/steamcmd -path \"*/linux32/steamclient.so\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit copie depuis $STEAM_SO\"\nelse\n echo \" [WARN] steamclient.so non trouve, telechargement direct...\"\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz -C /tmp/ linux32/steamclient.so 2>/dev/null\n if [ -f /tmp/linux32/steamclient.so ]; then\n cp -f /tmp/linux32/steamclient.so /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so telecharge\"\n fi\n rm -rf /tmp/linux32\nfi\n\n##############################################\n# 2) ReHLDS\n##############################################\necho \"\"\necho \">>> [2/14] ReHLDS...\"\nREHLDS_URL=$(github_get_url \"rehlds/ReHLDS\" \"rehlds-bin.*\\.zip\")\nif [ -n \"$REHLDS_URL\" ]; then\n echo \" URL: $REHLDS_URL\"\n curl -fsSL -o /tmp/rehlds.zip \"$REHLDS_URL\"\n if [ -s /tmp/rehlds.zip ]; then\n unzip -qo /tmp/rehlds.zip -d /tmp/rehlds/\n REHLDS_BIN=$(find /tmp/rehlds -name \"hlds_linux\" -type f | head -1)\n if [ -n \"$REHLDS_BIN\" ]; then\n REHLDS_DIR=$(dirname \"$REHLDS_BIN\")\n cp -rf \"$REHLDS_DIR\"/* /mnt/server/\n echo \" Binaires ReHLDS copies\"\n else\n echo \" WARN: hlds_linux non trouve dans l'archive\"\n fi\n else\n echo \" WARN: Telechargement echoue (fichier vide)\"\n fi\n rm -rf /tmp/rehlds /tmp/rehlds.zip\nelse\n echo \" WARN: URL ReHLDS non trouvee (GitHub API rate limit?)\"\nfi\n# Verification obligatoire\nif strings /mnt/server/hlds_linux 2>/dev/null | grep -qi \"rehlds\"; then\n echo \" [OK] ReHLDS verifie\"\nelse\n echo \" [ERREUR] ReHLDS NON installe ! Le serveur risque de ne pas demarrer\"\nfi\n\n##############################################\n# 3) ReGameDLL_CS\n##############################################\necho \"\"\necho \">>> [3/14] ReGameDLL_CS...\"\nREGAME_URL=$(github_get_url \"rehlds/ReGameDLL_CS\" \"\\.zip\")\nif [ -n \"$REGAME_URL\" ]; then\n echo \" URL: $REGAME_URL\"\n curl -fsSL -o /tmp/regamedll.zip \"$REGAME_URL\"\n if [ -s /tmp/regamedll.zip ]; then\n unzip -qo /tmp/regamedll.zip -d /tmp/regamedll/\n CSSO=$(find /tmp/regamedll -name \"cs.so\" -path \"*linux32*\" | head -1)\n [ -n \"$CSSO\" ] && cp -f \"$CSSO\" /mnt/server/cstrike/dlls/cs.so\n EXTRAS=$(find /tmp/regamedll -type d -name \"gamedir\" | head -1)\n [ -n \"$EXTRAS\" ] && cp -rn \"$EXTRAS\"/* /mnt/server/cstrike/ 2>/dev/null || true\n echo \" [OK] ReGameDLL installe\"\n fi\n rm -rf /tmp/regamedll /tmp/regamedll.zip\nelse\n echo \" WARN: Impossible de telecharger ReGameDLL_CS\"\nfi\n\n##############################################\n# 4) Metamod-R\n##############################################\necho \"\"\necho \">>> [4/14] Metamod-R...\"\nMETAMOD_URL=$(github_get_url \"rehlds/metamod-r\" \"\\.zip\")\nif [ -n \"$METAMOD_URL\" ]; then\n echo \" URL: $METAMOD_URL\"\n curl -fsSL -o /tmp/metamod.zip \"$METAMOD_URL\"\n if [ -s /tmp/metamod.zip ]; then\n unzip -qo /tmp/metamod.zip -d /tmp/metamod/\n mkdir -p /mnt/server/cstrike/addons/metamod\n META_DLL=$(find /tmp/metamod -name \"metamod_i386.so\" | head -1)\n [ -n \"$META_DLL\" ] && cp -f \"$META_DLL\" /mnt/server/cstrike/addons/metamod/\n echo \" [OK] Metamod-R installe\"\n fi\n rm -rf /tmp/metamod /tmp/metamod.zip\nelse\n echo \" WARN: Impossible de telecharger Metamod-R\"\nfi\n\n# TOUJOURS ecrire liblist.gam (meme si Metamod a echoue)\nif [ -f /mnt/server/cstrike/addons/metamod/metamod_i386.so ]; then\n GAMEDLL_LINUX=\"addons/metamod/metamod_i386.so\"\n echo \" [OK] liblist.gam -> Metamod\"\n # Creer plugins.ini si absent\n [ -f /mnt/server/cstrike/addons/metamod/plugins.ini ] \\\n || echo \"; Metamod plugins\" > /mnt/server/cstrike/addons/metamod/plugins.ini\nelse\n GAMEDLL_LINUX=\"dlls/cs.so\"\n echo \" [WARN] liblist.gam -> cs.so direct (Metamod absent)\"\nfi\ncat > /mnt/server/cstrike/liblist.gam << LIBLIST\ngame \"Counter-Strike\"\nurl_info \"www.counter-strike.net\"\nurl_dl \"\"\nversion \"1.6\"\nsize \"184000000\"\nsvonly \"0\"\ncldll \"1\"\nsecure \"1\"\nhlversion \"1110\"\nnomodels \"1\"\nnohimodel \"1\"\nmpentity \"info_player_start\"\ngamedll \"dlls\\cs.dll\"\ngamedll_linux \"${GAMEDLL_LINUX}\"\ngamedll_osx \"dlls/cs.dylib\"\ntype \"multiplayer_only\"\nLIBLIST\n\n##############################################\n# 5) AMX Mod X\n##############################################\necho \"\"\necho \">>> [5/14] AMX Mod X...\"\n# IMPORTANT: latest.php renvoie du HTML (pas de redirect), utiliser les URLs directes du drop\nAMXX_DROP=\"https://www.amxmodx.org/amxxdrop/1.10\"\ncurl -fsSL -o /tmp/amxmodx-base.tar.gz \"${AMXX_DROP}/amxmodx-latest-base-linux.tar.gz\"\ncurl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"${AMXX_DROP}/amxmodx-latest-cstrike-linux.tar.gz\"\ncd /mnt/server/cstrike\nif tar tzf /tmp/amxmodx-base.tar.gz > /dev/null 2>&1; then\n tar xzf /tmp/amxmodx-base.tar.gz\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.10 installe\"\nelse\n echo \" [WARN] 1.10 echoue, fallback 1.8.2 stable...\"\n curl -fsSL -o /tmp/amxmodx-base.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-base-linux.tar.gz\"\n curl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-cstrike-linux.tar.gz\"\n tar xzf /tmp/amxmodx-base.tar.gz 2>/dev/null || true\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.8.2 installe\"\nfi\nrm -f /tmp/amxmodx-base.tar.gz /tmp/amxmodx-cstrike.tar.gz\n# Verifier que le .so existe\nif [ -f /mnt/server/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so ]; then\n echo \" [OK] amxmodx_mm_i386.so verifie\"\nelse\n echo \" [ERREUR] amxmodx_mm_i386.so MANQUANT !\"\nfi\ngrep -q \"amxmodx\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/amxmodx/dlls/amxmodx_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\ncd /mnt/server\n\n##############################################\n# 6) ReAPI\n##############################################\necho \"\"\necho \">>> [6/14] ReAPI...\"\nREAPI_URL=$(github_get_url \"rehlds/ReAPI\" \"\\.zip\")\nif [ -n \"$REAPI_URL\" ]; then\n curl -fsSL -o /tmp/reapi.zip \"$REAPI_URL\"\n if [ -s /tmp/reapi.zip ]; then\n unzip -qo /tmp/reapi.zip -d /tmp/reapi/\n REAPI_SO=$(find /tmp/reapi -name \"reapi_amxx_i386.so\" | head -1)\n [ -n \"$REAPI_SO\" ] && cp -f \"$REAPI_SO\" /mnt/server/cstrike/addons/amxmodx/modules/\n grep -q \"reapi_amxx_i386.so\" /mnt/server/cstrike/addons/amxmodx/configs/modules.ini 2>/dev/null \\\n || echo \"reapi_amxx_i386.so\" >> /mnt/server/cstrike/addons/amxmodx/configs/modules.ini\n echo \" [OK] ReAPI installe\"\n fi\n rm -rf /tmp/reapi /tmp/reapi.zip\nelse\n echo \" WARN: Impossible de telecharger ReAPI\"\nfi\n\n##############################################\n# 7) Reunion\n##############################################\necho \"\"\necho \">>> [7/14] Reunion...\"\nREUNION_URL=$(github_get_url \"rehlds/ReUnion\" \"\\.zip\")\nif [ -n \"$REUNION_URL\" ]; then\n curl -fsSL -o /tmp/reunion.zip \"$REUNION_URL\"\n if [ -s /tmp/reunion.zip ]; then\n unzip -qo /tmp/reunion.zip -d /tmp/reunion/\n REUNION_SO=$(find /tmp/reunion -name \"reunion_mm_i386.so\" | head -1)\n if [ -n \"$REUNION_SO\" ]; then\n mkdir -p /mnt/server/cstrike/addons/reunion\n cp -f \"$REUNION_SO\" /mnt/server/cstrike/addons/reunion/\n # reunion.cfg doit etre dans cstrike/ (PAS addons/reunion/)\n REUNION_CFG=$(find /tmp/reunion -name \"reunion.cfg\" | head -1)\n if [ -n \"$REUNION_CFG\" ] && [ ! -f /mnt/server/cstrike/reunion.cfg ]; then\n cp -f \"$REUNION_CFG\" /mnt/server/cstrike/reunion.cfg\n fi\n # Generer SteamIdHashSalt si absent ou trop court\n if [ -f /mnt/server/cstrike/reunion.cfg ]; then\n SALT=$(grep -o 'SteamIdHashSalt *= *[^ ]*' /mnt/server/cstrike/reunion.cfg | sed 's/.*= *//')\n if [ ${#SALT} -lt 16 ]; then\n NEW_SALT=$(head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \\n' | head -c 32)\n sed -i \"s/SteamIdHashSalt *=.*/SteamIdHashSalt = ${NEW_SALT}/\" /mnt/server/cstrike/reunion.cfg\n echo \" [OK] SteamIdHashSalt genere (${#NEW_SALT} chars)\"\n fi\n fi\n grep -q \"reunion\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/reunion/reunion_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] Reunion installe\"\n fi\n fi\n rm -rf /tmp/reunion /tmp/reunion.zip\nelse\n echo \" WARN: Impossible de telecharger Reunion\"\nfi\n\n##############################################\n# 8) GunGame AMXX 2.13c\n##############################################\necho \"\"\necho \">>> [8/14] GunGame AMXX 2.13c...\"\ncurl -fsSL -o /tmp/gungame.zip \\\n \"https://github.com/xLeviNx/GunGame/releases/download/release/gg_213c_full.zip\"\nif [ -s /tmp/gungame.zip ]; then\n unzip -qo /tmp/gungame.zip -d /tmp/gungame/\n GG_ADDONS=$(find /tmp/gungame -maxdepth 3 -name \"addons\" -type d | head -1)\n if [ -n \"$GG_ADDONS\" ]; then\n GG_ROOT=$(dirname \"$GG_ADDONS\")\n cp -rf \"$GG_ROOT\"/addons/* /mnt/server/cstrike/addons/ 2>/dev/null || true\n fi\n GG_SOUND=$(find /tmp/gungame -maxdepth 3 -name \"sound\" -type d | head -1)\n if [ -n \"$GG_SOUND\" ]; then\n GG_SROOT=$(dirname \"$GG_SOUND\")\n cp -rf \"$GG_SROOT\"/sound/* /mnt/server/cstrike/sound/ 2>/dev/null || true\n fi\n find /tmp/gungame -name \"*.amxx\" -exec basename {} \\; | sort -u | while read p; do\n grep -q \"$p\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"$p\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n done\n echo \" [OK] GunGame AMXX 2.13c installe\"\n rm -rf /tmp/gungame /tmp/gungame.zip\nelse\n echo \" WARN: Impossible de telecharger GunGame AMXX\"\nfi\n\n##############################################\n# 9) YaPB (bots Metamod)\n##############################################\necho \"\"\necho \">>> [9/14] YaPB...\"\nYAPB_URL=$(github_get_url \"yapb/yapb\" \"linux.*\\.tar\\.xz\")\nif [ -n \"$YAPB_URL\" ]; then\n curl -fsSL -o /tmp/yapb.tar.xz \"$YAPB_URL\"\n if [ -s /tmp/yapb.tar.xz ]; then\n mkdir -p /tmp/yapb\n tar -xf /tmp/yapb.tar.xz -C /tmp/yapb/\n YAPB_DIR=$(find /tmp/yapb -type d -name \"yapb\" -path \"*/addons/yapb\" | head -1)\n [ -n \"$YAPB_DIR\" ] && cp -rf \"$YAPB_DIR\" /mnt/server/cstrike/addons/ 2>/dev/null || true\n # Ensure YaPB data directories are writable (graph, train, etc.)\n mkdir -p /mnt/server/cstrike/addons/yapb/data/graph\n mkdir -p /mnt/server/cstrike/addons/yapb/data/train\n chmod -R 755 /mnt/server/cstrike/addons/yapb/data\n grep -q \"yapb\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/yapb/bin/yapb.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] YaPB installe\"\n fi\n rm -rf /tmp/yapb /tmp/yapb.tar.xz\nelse\n echo \" WARN: Impossible de telecharger YaPB\"\nfi\n\n##############################################\n# 10) BotManager (5 bots toujours, kick a 4+ humains)\n##############################################\necho \"\"\necho \">>> [10/14] BotManager...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/bot_manager.sma << 'BOTSMA'\n/*\n * Bot Manager v2 - {{NOM_COMMUNAUTE}}Games.fr\n * 5 bots toujours presents pour attirer les joueurs.\n * Tous les bots kick quand 4+ vrais joueurs connectes.\n * CVARs:\n * bm_bot_count = nombre de bots (defaut 5)\n * bm_kick_threshold = seuil pour kick les bots (defaut 4)\n */\n#include <amxmodx>\n\nnew g_cvarBotCount\nnew g_cvarKickThreshold\n\npublic plugin_init()\n{\n register_plugin(\"BotManager\", \"2.0\", \"{{NOM_COMMUNAUTE}}Games\")\n g_cvarBotCount = register_cvar(\"bm_bot_count\", \"5\")\n g_cvarKickThreshold = register_cvar(\"bm_kick_threshold\", \"4\")\n}\n\npublic plugin_cfg()\n{\n set_task(3.0, \"check_bots\")\n}\n\npublic client_putinserver(id)\n{\n set_task(2.0, \"check_bots\")\n}\n\npublic client_disconnected(id, bool:drop, message[], maxlen)\n{\n set_task(1.0, \"check_bots\")\n}\n\npublic check_bots()\n{\n new humans = count_humans()\n new fill = get_pcvar_num(g_cvarBotCount)\n new threshold = get_pcvar_num(g_cvarKickThreshold)\n\n if (humans >= threshold)\n server_cmd(\"yb_quota 0\")\n else\n server_cmd(\"yb_quota %d\", fill)\n}\n\ncount_humans()\n{\n new players[32], num, count = 0\n get_players(players, num, \"ch\")\n for (new i = 0; i < num; i++)\n {\n if (!is_user_bot(players[i]))\n count++\n }\n return count\n}\nBOTSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc bot_manager.sma -o../plugins/bot_manager.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/bot_manager.amxx ]; then\n grep -q \"bot_manager.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"bot_manager.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] bot_manager.amxx compile et installe\"\n else\n echo \" [WARN] Compilation bot_manager echouee\"\n fi\nelse\n echo \" [WARN] amxxpc non trouve, impossible de compiler bot_manager\"\nfi\n\n##############################################\n# 11) Advanced Quake Sounds\n##############################################\necho \"\"\necho \">>> [11/14] Advanced Quake Sounds...\"\ncurl -fsSL -o /tmp/aqs.zip \\\n \"https://github.com/ClaudiuHKS/AdvancedQuakeSounds/archive/refs/heads/master.zip\"\nif [ -s /tmp/aqs.zip ]; then\n unzip -qo /tmp/aqs.zip -d /tmp/aqs/\n AQS=\"/tmp/aqs/AdvancedQuakeSounds-master\"\n # Compiler AQS.sma (pas de .amxx pre-compile dans le repo)\n AMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\n if [ -f \"$AQS/AQS.sma\" ] && [ -f \"$AMXXPC\" ]; then\n cp -f \"$AQS/AQS.sma\" /mnt/server/cstrike/addons/amxmodx/scripting/\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc AQS.sma -o../plugins/AQS.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/AQS.amxx ]; then\n echo \" [OK] AQS.amxx compile\"\n else\n echo \" [WARN] Compilation echouee\"\n fi\n else\n echo \" [WARN] AQS.sma ou amxxpc non trouve\"\n fi\n # Config + Sons\n [ -f \"$AQS/AQS.ini\" ] && cp -f \"$AQS/AQS.ini\" /mnt/server/cstrike/addons/amxmodx/configs/\n mkdir -p /mnt/server/cstrike/sound/AQS/\n if [ -f \"$AQS/sound.zip\" ]; then\n unzip -qo \"$AQS/sound.zip\" -d /mnt/server/cstrike/ 2>/dev/null || true\n elif [ -d \"$AQS/sound/AQS\" ]; then\n cp -rf \"$AQS/sound/AQS/\"* /mnt/server/cstrike/sound/AQS/ 2>/dev/null || true\n fi\n grep -q \"AQS.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"AQS.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] AQS installe\"\n rm -rf /tmp/aqs /tmp/aqs.zip\nelse\n echo \" WARN: Impossible de telecharger AQS\"\nfi\n\n##############################################\n# 12) Double Jump\n##############################################\necho \"\"\necho \">>> [12/14] Double Jump...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/doublejump.sma << 'DJSMA'\n#include <amxmodx>\n#include <fakemeta>\n\n#define MAX_EXTRA_JUMPS 1\n\nnew g_jumpCount[33]\n\npublic plugin_init()\n{\n register_plugin(\"Double Jump\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlayerPreThink, \"fw_PreThink_DJ\")\n}\n\npublic client_putinserver(id)\n{\n g_jumpCount[id] = 0\n}\n\npublic fw_PreThink_DJ(id)\n{\n if (!is_user_alive(id)) return FMRES_IGNORED\n\n new flags = pev(id, pev_flags)\n new buttons = pev(id, pev_button)\n new oldbuttons = pev(id, pev_oldbuttons)\n\n if (flags & FL_ONGROUND)\n {\n g_jumpCount[id] = 0\n return FMRES_IGNORED\n }\n\n // Nouvelle pression sur jump en l'air\n if ((buttons & IN_JUMP) && !(oldbuttons & IN_JUMP))\n {\n if (g_jumpCount[id] < MAX_EXTRA_JUMPS)\n {\n g_jumpCount[id]++\n new Float:vel[3]\n pev(id, pev_velocity, vel)\n vel[2] = 268.0\n set_pev(id, pev_velocity, vel)\n }\n }\n\n return FMRES_IGNORED\n}\nDJSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc doublejump.sma -o../plugins/doublejump.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/doublejump.amxx ]; then\n grep -q \"doublejump.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"doublejump.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] doublejump.amxx compile et installe\"\n else\n echo \" [WARN] Compilation doublejump echouee\"\n fi\nelse\n echo \" [WARN] amxxpc non trouve, impossible de compiler doublejump\"\nfi\n\n# Activer fakemeta si pas deja fait\nAMXX_MODULES=\"/mnt/server/cstrike/addons/amxmodx/configs/modules.ini\"\nif grep -q \"^;fakemeta\" \"$AMXX_MODULES\" 2>/dev/null; then\n sed -i 's/^;fakemeta/fakemeta/' \"$AMXX_MODULES\"\n echo \" [OK] Module fakemeta active\"\nfi\n\n##############################################\n# 13) Maps custom depuis FastDL\n##############################################\necho \"\"\necho \">>> [13/14] Telechargement des maps depuis FastDL...\"\nFASTDL_URL=\"https://fastdl.{{DOMAINE_GAMING}}/cs_gungame\"\n# wget recursif : telecharge maps/, gfx/, sound/, sprites/, overviews/, models/, *.wad\n# --cut-dirs=1 supprime \"cs_gungame/\" du chemin pour copier directement dans cstrike/\nwget -r -np -nH --cut-dirs=1 -P /mnt/server/cstrike/ \\\n -R \"index.html*\" \\\n --no-check-certificate \\\n -q --show-progress \\\n \"$FASTDL_URL/\" 2>&1 || echo \" [WARN] wget a rencontre des erreurs (certains fichiers peuvent manquer)\"\n\nMAP_COUNT=$(find /mnt/server/cstrike/maps -name \"*.bsp\" 2>/dev/null | wc -l)\necho \" [OK] ${MAP_COUNT} maps .bsp telechargees\"\n\n# Generer mapcycle.txt a partir des maps telechargees (sans les maps par defaut HLDS sauf de_dust2)\necho \">>> Generation de mapcycle.txt depuis les maps telechargees...\"\nEXCLUDE_MAPS=\"as_oilrig cs_747 cs_assault cs_backalley cs_estate cs_havana cs_italy cs_militia cs_office cs_siege de_airstrip de_aztec de_cbble de_chateau de_dust de_inferno de_nuke de_piranesi de_prodigy de_storm de_survivor de_torn de_train de_vertigo\"\nfind /mnt/server/cstrike/maps -name \"*.bsp\" -printf \"%f\\n\" 2>/dev/null \\\n | sed 's/\\.bsp$//' | sort > /mnt/server/cstrike/mapcycle.txt\nfor m in $EXCLUDE_MAPS; do\n sed -i \"/^${m}$/d\" /mnt/server/cstrike/mapcycle.txt\ndone\necho \" [OK] mapcycle.txt genere ($(wc -l < /mnt/server/cstrike/mapcycle.txt) maps, maps HLDS exclues)\"\n\n##############################################\n# server.cfg GunGame\n##############################################\necho \"\"\necho \">>> Generation de server.cfg...\"\ncat > /mnt/server/cstrike/server.cfg << 'SERVERCFG'\nhostname \"[FR] GUNGAME {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}\"\nsv_contact \"admin@{{DOMAINE_GAMING}}\"\nrcon_password \"changeme\"\n\n// GunGame settings\nmp_timelimit 30\nmp_freezetime 0\nmp_roundtime 9\nmp_autoteambalance 1\nmp_friendlyfire 0\nmp_buytime 0\nsv_maxspeed 320\nsv_alltalk 1\nsv_voiceenable 1\n\n// Rates\nsv_maxrate 25000\nsv_minrate 6000\nsv_maxupdaterate 102\nsv_minupdaterate 30\n\n// Downloads + FastDL\nsv_allowdownload 1\nsv_allowupload 0\nsv_downloadurl \"https://fastdl.{{DOMAINE_GAMING}}/cs_gungame\"\n\n// YaPB bots\nyb_quota 5\nyb_auto_waypoint 1\nyb_chat 0\nyb_language_tag 0\n\n// BotManager : 5 bots toujours presents, kick quand 4+ vrais joueurs\nbm_bot_count 5\nbm_kick_threshold 4\n\nexec banned.cfg\nexec listip.cfg\nSERVERCFG\n\n##############################################\n# [13/14] Fix permissions\n##############################################\necho \"\"\necho \">>> [14/14] Fix des permissions...\"\n# Rendre tout lisible/executable pour le conteneur de jeu (UID 988)\nchmod -R 755 /mnt/server/ 2>/dev/null || true\nchmod +x /mnt/server/hlds_linux /mnt/server/hlds_run /mnt/server/hlds_amd 2>/dev/null || true\nchmod +x /mnt/server/hltv 2>/dev/null || true\nfind /mnt/server -name \"*.so\" -exec chmod +x {} \\; 2>/dev/null || true\n\n# Re-copie steamclient.so 32-bit (au cas ou ReHLDS l'a ecrase)\nSTEAM_SO=$(find /mnt/server -path \"*/linux32/steamclient.so\" -not -path \"*/.steam/*\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n mkdir -p /mnt/server/.steam/sdk32\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit re-copie\"\nfi\n\necho \"\"\necho \"=============================================\"\necho \" Installation terminee !\"\necho \" Plugins : ReHLDS + ReGameDLL + Metamod-R\"\necho \" + AMX Mod X + ReAPI + Reunion\"\necho \" + GunGame AMXX 2.13c + YaPB\"\necho \" + BotManager + Double Jump + AQS\"\necho \"=============================================\"\n", "container": "ghcr.io/ptero-eggs/installers:debian", "entrypoint": "bash" } }, "variables": [ { "name": "Server Hostname", "description": "Nom du serveur affiché dans le navigateur de serveurs", "env_variable": "HOSTNAME", "default_value": "[FR] GUNGAME {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}", "user_viewable": true, "user_editable": true, "rules": "required|string|between:1,64", "field_type": "text" }, { "name": "Default Map", "description": "Map chargée au démarrage du serveur", "env_variable": "SRCDS_MAP", "default_value": "de_dust2", "user_viewable": true, "user_editable": true, "rules": "required|string", "field_type": "text" }, { "name": "Max Players", "description": "Nombre maximum de joueurs", "env_variable": "MAX_PLAYERS", "default_value": "32", "user_viewable": true, "user_editable": true, "rules": "required|integer|between:2,64", "field_type": "text" }, { "name": "Game Folder", "description": "Dossier du jeu (ne pas modifier)", "env_variable": "HLDS_GAME", "default_value": "cstrike", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" }, { "name": "Steam App ID", "description": "App ID Steam pour CS 1.6 (ne pas modifier)", "env_variable": "SRCDS_APPID", "default_value": "90", "user_viewable": false, "user_editable": false, "rules": "required|integer", "field_type": "text" }, { "name": "Steam Beta Branch", "description": "Branche beta Steam (ne pas modifier)", "env_variable": "SRCDS_BETAID", "default_value": "steam_legacy", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" } ] } |
CS 1.6 ReHLDS – Deathrun
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
{ "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-02-27T12:00:00+01:00", "name": "CS 1.6 ReHLDS - Deathrun", "author": "admin@{{DOMAINE_GAMING}}", "description": "Counter-Strike 1.6 Deathrun avec ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion, DeathrunManager v3.0.3a, YaPB (bots), AutoBhop, Speedometer et Resetscore. Installation 100% automatique.", "features": null, "docker_images": { "ghcr.io/ptero-eggs/games:source": "ghcr.io/ptero-eggs/games:source" }, "file_denylist": [], "startup": "./hlds_run -console -game {{HLDS_GAME}} -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -norestart +maxplayers {{MAX_PLAYERS}} +pingboost 2 +sys_ticrate 1200 +hostname \"{{HOSTNAME}}\"", "config": { "files": "{}", "startup": "{\"done\": \"gameserver Steam\"}", "logs": "{}", "stop": "quit" }, "scripts": { "installation": { "script": "#!/bin/bash\ncd /mnt/server\n\napt-get update -qq && apt-get install -yqq unzip xz-utils wget > /dev/null 2>&1 || true\n\necho \"=============================================\"\necho \" CS 1.6 Deathrun - Installation automatique\"\necho \"=============================================\"\n\n##############################################\n# Helper: GitHub download URL (HTML scraping + API fallback)\n##############################################\ngithub_get_url() {\n local repo=\"$1\" pattern=\"$2\" url=\"\"\n echo \" [INFO] Recherche: repo=${repo} pattern=${pattern}\" >&2\n # GitHub API (POSIX grep, pas de -P)\n for attempt in 1 2 3; do\n url=$(curl -sSL \"https://api.github.com/repos/${repo}/releases/latest\" \\\n | grep -o '\"browser_download_url\": *\"[^\"]*\"' \\\n | grep \"${pattern}\" | head -1 \\\n | sed 's/.*\"browser_download_url\": *\"//;s/\"$//')\n if [ -n \"$url\" ]; then\n echo \" [OK] URL trouvee: ${url}\" >&2\n echo \"$url\"\n return 0\n fi\n echo \" [WARN] API tentative ${attempt}/3 echouee, retry...\" >&2\n sleep 3\n done\n echo \" [ECHEC] Aucune URL trouvee pour ${repo}\" >&2\n return 1\n}\n\n##############################################\n# 1) SteamCMD + HLDS\n##############################################\necho \"\"\necho \">>> [1/12] SteamCMD + HLDS (App ID 90)...\"\nmkdir -p steamcmd\ncd steamcmd\nif [ ! -f steamcmd.sh ]; then\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz\nfi\ncd /mnt/server\n\n./steamcmd/steamcmd.sh +force_install_dir /mnt/server \\\n +login anonymous \\\n +app_update 90 -beta steam_legacy validate \\\n +quit\n\n# Steam SDK setup\nmkdir -p /mnt/server/.steam/sdk32\necho \"10\" > /mnt/server/steam_appid.txt\nSTEAM_SO=$(find /mnt/server/steamcmd -path \"*/linux32/steamclient.so\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit copie depuis $STEAM_SO\"\nelse\n echo \" [WARN] steamclient.so non trouve, telechargement direct...\"\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz -C /tmp/ linux32/steamclient.so 2>/dev/null\n if [ -f /tmp/linux32/steamclient.so ]; then\n cp -f /tmp/linux32/steamclient.so /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so telecharge\"\n fi\n rm -rf /tmp/linux32\nfi\n\n##############################################\n# 2) ReHLDS\n##############################################\necho \"\"\necho \">>> [2/12] ReHLDS...\"\nREHLDS_URL=$(github_get_url \"rehlds/ReHLDS\" \"rehlds-bin.*\\.zip\")\nif [ -n \"$REHLDS_URL\" ]; then\n echo \" URL: $REHLDS_URL\"\n curl -fsSL -o /tmp/rehlds.zip \"$REHLDS_URL\"\n if [ -s /tmp/rehlds.zip ]; then\n unzip -qo /tmp/rehlds.zip -d /tmp/rehlds/\n REHLDS_BIN=$(find /tmp/rehlds -name \"hlds_linux\" -type f | head -1)\n if [ -n \"$REHLDS_BIN\" ]; then\n REHLDS_DIR=$(dirname \"$REHLDS_BIN\")\n cp -rf \"$REHLDS_DIR\"/* /mnt/server/\n echo \" Binaires ReHLDS copies\"\n else\n echo \" WARN: hlds_linux non trouve dans l'archive\"\n fi\n else\n echo \" WARN: Telechargement echoue (fichier vide)\"\n fi\n rm -rf /tmp/rehlds /tmp/rehlds.zip\nelse\n echo \" WARN: URL ReHLDS non trouvee (GitHub API rate limit?)\"\nfi\n# Verification obligatoire\nif strings /mnt/server/hlds_linux 2>/dev/null | grep -qi \"rehlds\"; then\n echo \" [OK] ReHLDS verifie\"\nelse\n echo \" [ERREUR] ReHLDS NON installe ! Le serveur risque de ne pas demarrer\"\nfi\n\n##############################################\n# 3) ReGameDLL_CS\n##############################################\necho \"\"\necho \">>> [3/12] ReGameDLL_CS...\"\nREGAME_URL=$(github_get_url \"rehlds/ReGameDLL_CS\" \"\\.zip\")\nif [ -n \"$REGAME_URL\" ]; then\n echo \" URL: $REGAME_URL\"\n curl -fsSL -o /tmp/regamedll.zip \"$REGAME_URL\"\n if [ -s /tmp/regamedll.zip ]; then\n unzip -qo /tmp/regamedll.zip -d /tmp/regamedll/\n CSSO=$(find /tmp/regamedll -name \"cs.so\" -path \"*linux32*\" | head -1)\n [ -n \"$CSSO\" ] && cp -f \"$CSSO\" /mnt/server/cstrike/dlls/cs.so\n EXTRAS=$(find /tmp/regamedll -type d -name \"gamedir\" | head -1)\n [ -n \"$EXTRAS\" ] && cp -rn \"$EXTRAS\"/* /mnt/server/cstrike/ 2>/dev/null || true\n echo \" [OK] ReGameDLL installe\"\n fi\n rm -rf /tmp/regamedll /tmp/regamedll.zip\nelse\n echo \" WARN: Impossible de telecharger ReGameDLL_CS\"\nfi\n\n##############################################\n# 4) Metamod-R\n##############################################\necho \"\"\necho \">>> [4/12] Metamod-R...\"\nMETAMOD_URL=$(github_get_url \"rehlds/metamod-r\" \"\\.zip\")\nif [ -n \"$METAMOD_URL\" ]; then\n echo \" URL: $METAMOD_URL\"\n curl -fsSL -o /tmp/metamod.zip \"$METAMOD_URL\"\n if [ -s /tmp/metamod.zip ]; then\n unzip -qo /tmp/metamod.zip -d /tmp/metamod/\n mkdir -p /mnt/server/cstrike/addons/metamod\n META_DLL=$(find /tmp/metamod -name \"metamod_i386.so\" | head -1)\n [ -n \"$META_DLL\" ] && cp -f \"$META_DLL\" /mnt/server/cstrike/addons/metamod/\n echo \" [OK] Metamod-R installe\"\n fi\n rm -rf /tmp/metamod /tmp/metamod.zip\nelse\n echo \" WARN: Impossible de telecharger Metamod-R\"\nfi\n\n# TOUJOURS ecrire liblist.gam (meme si Metamod a echoue)\nif [ -f /mnt/server/cstrike/addons/metamod/metamod_i386.so ]; then\n GAMEDLL_LINUX=\"addons/metamod/metamod_i386.so\"\n echo \" [OK] liblist.gam -> Metamod\"\n # Creer plugins.ini si absent\n [ -f /mnt/server/cstrike/addons/metamod/plugins.ini ] \\\n || echo \"; Metamod plugins\" > /mnt/server/cstrike/addons/metamod/plugins.ini\nelse\n GAMEDLL_LINUX=\"dlls/cs.so\"\n echo \" [WARN] liblist.gam -> cs.so direct (Metamod absent)\"\nfi\ncat > /mnt/server/cstrike/liblist.gam << LIBLIST\ngame \"Counter-Strike\"\nurl_info \"www.counter-strike.net\"\nurl_dl \"\"\nversion \"1.6\"\nsize \"184000000\"\nsvonly \"0\"\ncldll \"1\"\nsecure \"1\"\nhlversion \"1110\"\nnomodels \"1\"\nnohimodel \"1\"\nmpentity \"info_player_start\"\ngamedll \"dlls\\cs.dll\"\ngamedll_linux \"${GAMEDLL_LINUX}\"\ngamedll_osx \"dlls/cs.dylib\"\ntype \"multiplayer_only\"\nLIBLIST\n\n##############################################\n# 5) AMX Mod X\n##############################################\necho \"\"\necho \">>> [5/12] AMX Mod X...\"\nAMXX_DROP=\"https://www.amxmodx.org/amxxdrop/1.10\"\ncurl -fsSL -o /tmp/amxmodx-base.tar.gz \"${AMXX_DROP}/amxmodx-latest-base-linux.tar.gz\"\ncurl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"${AMXX_DROP}/amxmodx-latest-cstrike-linux.tar.gz\"\ncd /mnt/server/cstrike\nif tar tzf /tmp/amxmodx-base.tar.gz > /dev/null 2>&1; then\n tar xzf /tmp/amxmodx-base.tar.gz\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.10 installe\"\nelse\n echo \" [WARN] 1.10 echoue, fallback 1.8.2 stable...\"\n curl -fsSL -o /tmp/amxmodx-base.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-base-linux.tar.gz\"\n curl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-cstrike-linux.tar.gz\"\n tar xzf /tmp/amxmodx-base.tar.gz 2>/dev/null || true\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.8.2 installe\"\nfi\nrm -f /tmp/amxmodx-base.tar.gz /tmp/amxmodx-cstrike.tar.gz\n# Verifier que le .so existe\nif [ -f /mnt/server/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so ]; then\n echo \" [OK] amxmodx_mm_i386.so verifie\"\nelse\n echo \" [ERREUR] amxmodx_mm_i386.so MANQUANT !\"\nfi\ngrep -q \"amxmodx\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/amxmodx/dlls/amxmodx_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\ncd /mnt/server\n\n##############################################\n# 6) ReAPI\n##############################################\necho \"\"\necho \">>> [6/12] ReAPI...\"\nREAPI_URL=$(github_get_url \"rehlds/ReAPI\" \"\\.zip\")\nif [ -n \"$REAPI_URL\" ]; then\n curl -fsSL -o /tmp/reapi.zip \"$REAPI_URL\"\n if [ -s /tmp/reapi.zip ]; then\n unzip -qo /tmp/reapi.zip -d /tmp/reapi/\n REAPI_SO=$(find /tmp/reapi -name \"reapi_amxx_i386.so\" | head -1)\n [ -n \"$REAPI_SO\" ] && cp -f \"$REAPI_SO\" /mnt/server/cstrike/addons/amxmodx/modules/\n grep -q \"reapi_amxx_i386.so\" /mnt/server/cstrike/addons/amxmodx/configs/modules.ini 2>/dev/null \\\n || echo \"reapi_amxx_i386.so\" >> /mnt/server/cstrike/addons/amxmodx/configs/modules.ini\n echo \" [OK] ReAPI installe\"\n fi\n rm -rf /tmp/reapi /tmp/reapi.zip\nelse\n echo \" WARN: Impossible de telecharger ReAPI\"\nfi\n\n##############################################\n# 7) Reunion\n##############################################\necho \"\"\necho \">>> [7/12] Reunion...\"\nREUNION_URL=$(github_get_url \"rehlds/ReUnion\" \"\\.zip\")\nif [ -n \"$REUNION_URL\" ]; then\n curl -fsSL -o /tmp/reunion.zip \"$REUNION_URL\"\n if [ -s /tmp/reunion.zip ]; then\n unzip -qo /tmp/reunion.zip -d /tmp/reunion/\n REUNION_SO=$(find /tmp/reunion -name \"reunion_mm_i386.so\" | head -1)\n if [ -n \"$REUNION_SO\" ]; then\n mkdir -p /mnt/server/cstrike/addons/reunion\n cp -f \"$REUNION_SO\" /mnt/server/cstrike/addons/reunion/\n # reunion.cfg doit etre dans cstrike/ (PAS addons/reunion/)\n REUNION_CFG=$(find /tmp/reunion -name \"reunion.cfg\" | head -1)\n if [ -n \"$REUNION_CFG\" ] && [ ! -f /mnt/server/cstrike/reunion.cfg ]; then\n cp -f \"$REUNION_CFG\" /mnt/server/cstrike/reunion.cfg\n fi\n # Generer SteamIdHashSalt si absent ou trop court\n if [ -f /mnt/server/cstrike/reunion.cfg ]; then\n SALT=$(grep -o 'SteamIdHashSalt *= *[^ ]*' /mnt/server/cstrike/reunion.cfg | sed 's/.*= *//')\n if [ ${#SALT} -lt 16 ]; then\n NEW_SALT=$(head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \\n' | head -c 32)\n sed -i \"s/SteamIdHashSalt *=.*/SteamIdHashSalt = ${NEW_SALT}/\" /mnt/server/cstrike/reunion.cfg\n echo \" [OK] SteamIdHashSalt genere (${#NEW_SALT} chars)\"\n fi\n fi\n grep -q \"reunion\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/reunion/reunion_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] Reunion installe\"\n fi\n fi\n rm -rf /tmp/reunion /tmp/reunion.zip\nelse\n echo \" WARN: Impossible de telecharger Reunion\"\nfi\n\n##############################################\n# 8) DeathrunManager v3.0.3a\n##############################################\necho \"\"\necho \">>> [8/12] DeathrunManager v3.0.3a...\"\n# Telecharge depuis le serveur {{NOM_COMMUNAUTE}}Games (pre-compile)\n# Fichiers requis sur http://{{DOMAINE_GAMING}}/plugins/ :\n# - deathrun_manager.amxx\ncurl -fsSL -o /mnt/server/cstrike/addons/amxmodx/plugins/deathrun_manager.amxx \\\n \"http://{{DOMAINE_GAMING}}/plugins/deathrun_manager.amxx\"\nif [ -f /mnt/server/cstrike/addons/amxmodx/plugins/deathrun_manager.amxx ] \\\n && [ -s /mnt/server/cstrike/addons/amxmodx/plugins/deathrun_manager.amxx ]; then\n grep -q \"deathrun_manager.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"deathrun_manager.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] deathrun_manager.amxx installe\"\nelse\n echo \" [WARN] Impossible de telecharger deathrun_manager.amxx\"\n echo \" [INFO] Uploadez deathrun_manager.amxx sur http://{{DOMAINE_GAMING}}/plugins/\"\nfi\n\n# Configuration DeathrunManager\nmkdir -p /mnt/server/cstrike/addons/amxmodx/configs\ncat > /mnt/server/cstrike/addons/amxmodx/configs/deathrun_manager.cfg << 'DRCFG'\n// DeathrunManager v3.0.3a - Configuration\n// Plugin by flaviuss\n\n// Semiclip (joueurs passent a travers les coequipiers)\ndr_semiclip 1\n\n// Bloquer les sprays\ndr_spray 0\n\n// Bloquer les commandes radio\ndr_radio 0\n\n// Systeme de vies (terroriste a plusieurs tentatives)\ndr_lifesystem 1\ndr_lives 3\n\n// Transfert automatique du terroriste si AFK\ndr_autotransfer 1\ndr_autotransfer_time 15\n\n// Mode de selection du terroriste (0=random, 1=dernier CT mort, 2=par score)\ndr_choose_terrorist 0\n\n// HUD avec infos deathrun\ndr_hud 1\n\n// Bloquer les armes (CT n'a que le couteau en deathrun)\ndr_block_weapons 1\n\n// Bloquer le tir du terroriste (le TT active les pieges, pas besoin de tirer)\ndr_block_attack_tt 0\n\n// Respawn automatique des CT\ndr_respawn 0\nDRCFG\necho \" [OK] deathrun_manager.cfg genere\"\n\n# Fichier de langue (francais/anglais)\nmkdir -p /mnt/server/cstrike/addons/amxmodx/data/lang\ncat > /mnt/server/cstrike/addons/amxmodx/data/lang/deathrun_manager.txt << 'DRLANG'\n[en]\nDR_TERRORIST = is now the Terrorist!\nDR_LIVES_LEFT = You have %d lives left.\nDR_NO_LIVES = You have no more lives!\nDR_AFK_TRANSFER = Terrorist was AFK, transferring...\nDR_ROUND_START = Round started! Terrorist: %s\n\n[fr]\nDR_TERRORIST = est maintenant le Terroriste !\nDR_LIVES_LEFT = Il vous reste %d vies.\nDR_NO_LIVES = Vous n'avez plus de vies !\nDR_AFK_TRANSFER = Le terroriste etait AFK, transfert...\nDR_ROUND_START = Round demarre ! Terroriste : %s\nDRLANG\necho \" [OK] Fichier de langue genere\"\n\n##############################################\n# 9) YaPB (bots Metamod)\n##############################################\necho \"\"\necho \">>> [9/12] YaPB...\"\nYAPB_URL=$(github_get_url \"yapb/yapb\" \"linux.*\\.tar\\.xz\")\nif [ -n \"$YAPB_URL\" ]; then\n curl -fsSL -o /tmp/yapb.tar.xz \"$YAPB_URL\"\n if [ -s /tmp/yapb.tar.xz ]; then\n mkdir -p /tmp/yapb\n tar -xf /tmp/yapb.tar.xz -C /tmp/yapb/\n YAPB_DIR=$(find /tmp/yapb -type d -name \"yapb\" -path \"*/addons/yapb\" | head -1)\n [ -n \"$YAPB_DIR\" ] && cp -rf \"$YAPB_DIR\" /mnt/server/cstrike/addons/ 2>/dev/null || true\n # Ensure YaPB data directories are writable (graph, train, etc.)\n mkdir -p /mnt/server/cstrike/addons/yapb/data/graph\n mkdir -p /mnt/server/cstrike/addons/yapb/data/train\n chmod -R 755 /mnt/server/cstrike/addons/yapb/data\n grep -q \"yapb\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/yapb/bin/yapb.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] YaPB installe\"\n fi\n rm -rf /tmp/yapb /tmp/yapb.tar.xz\nelse\n echo \" WARN: Impossible de telecharger YaPB\"\nfi\n\n##############################################\n# 10) BotManager (bots quand 1 humain, 0 bots quand 2+)\n##############################################\necho \"\"\necho \">>> [10/12] BotManager...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/bot_manager.sma << 'BOTSMA'\n/*\n * Bot Manager - {{NOM_COMMUNAUTE}}Games.fr\n * Bots fill the server when 1 human is connected.\n * All bots leave when 2+ humans are connected.\n */\n#include <amxmodx>\n\nnew g_cvarBotCount\n\npublic plugin_init()\n{\n register_plugin(\"BotManager\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n g_cvarBotCount = register_cvar(\"bm_bot_count\", \"5\")\n server_cmd(\"yb_quota 0\")\n}\n\npublic client_putinserver(id)\n{\n set_task(2.0, \"check_bots\")\n}\n\npublic client_disconnected(id, bool:drop, message[], maxlen)\n{\n set_task(1.0, \"check_bots\")\n}\n\npublic check_bots()\n{\n new humans = count_humans()\n new fill = get_pcvar_num(g_cvarBotCount)\n\n if (humans == 1)\n server_cmd(\"yb_quota %d\", fill)\n else\n server_cmd(\"yb_quota 0\")\n}\n\ncount_humans()\n{\n new players[32], num, count = 0\n get_players(players, num, \"ch\")\n for (new i = 0; i < num; i++)\n {\n if (!is_user_bot(players[i]))\n count++\n }\n return count\n}\nBOTSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc bot_manager.sma -o../plugins/bot_manager.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/bot_manager.amxx ]; then\n grep -q \"bot_manager.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"bot_manager.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] bot_manager.amxx compile et installe\"\n else\n echo \" [WARN] Compilation bot_manager echouee\"\n fi\nelse\n echo \" [WARN] amxxpc non trouve, impossible de compiler bot_manager\"\nfi\n\n##############################################\n# 11) Bhop + Speedometer + Resetscore\n##############################################\necho \"\"\necho \">>> [11/12] Bhop + Speedometer + Resetscore...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\n\nif [ -f \"$AMXXPC\" ]; then\n # --- Auto Bhop (Super Bunny Hopper by Cheesy Peteza, adapted) ---\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/autobhop.sma << 'BHOPSMA'\n/*\n * Super Bunny Hopper - adapted for {{NOM_COMMUNAUTE}}Games.fr Deathrun\n * Based on Cheesy Peteza's plugin.\n * Removes slowdown after jump + auto-jump when holding SPACE.\n * CVARs:\n * bh_enabled 1 = on, 0 = off\n * bh_autojump 1 = hold space to auto bhop\n */\n#include <amxmodx>\n#include <engine>\n\n#define FL_WATERJUMP (1<<11)\n#define FL_ONGROUND (1<<9)\n\npublic plugin_init()\n{\n register_plugin(\"SuperBunnyHopper\", \"1.3\", \"Cheesy Peteza / {{NOM_COMMUNAUTE}}Games\")\n register_cvar(\"bh_enabled\", \"1\")\n register_cvar(\"bh_autojump\", \"1\")\n}\n\npublic client_PreThink(id)\n{\n if (!get_cvar_num(\"bh_enabled\") || !is_user_alive(id))\n return PLUGIN_CONTINUE\n\n // Remove slowdown after landing\n entity_set_float(id, EV_FL_fuser2, 0.0)\n\n if (!get_cvar_num(\"bh_autojump\"))\n return PLUGIN_CONTINUE\n\n // Auto-jump: if holding jump and on ground, boost velocity\n if (entity_get_int(id, EV_INT_button) & IN_JUMP)\n {\n new flags = entity_get_int(id, EV_INT_flags)\n if (flags & FL_WATERJUMP)\n return PLUGIN_CONTINUE\n if (entity_get_int(id, EV_INT_waterlevel) >= 2)\n return PLUGIN_CONTINUE\n if (!(flags & FL_ONGROUND))\n return PLUGIN_CONTINUE\n\n new Float:velocity[3]\n entity_get_vector(id, EV_VEC_velocity, velocity)\n velocity[2] += 250.0\n entity_set_vector(id, EV_VEC_velocity, velocity)\n entity_set_int(id, EV_INT_gaitsequence, 6)\n }\n return PLUGIN_CONTINUE\n}\nBHOPSMA\n\n # --- Speedometer ---\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/speedometer.sma << 'SPEEDSMA'\n/*\n * Speedometer - {{NOM_COMMUNAUTE}}Games.fr\n * Affiche la vitesse du joueur en HUD.\n */\n#include <amxmodx>\n#include <engine>\n\npublic plugin_init()\n{\n register_plugin(\"Speedometer\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n set_task(0.1, \"show_speed\", _, _, _, \"b\")\n}\n\npublic show_speed()\n{\n new players[32], num\n get_players(players, num, \"a\")\n\n for (new i = 0; i < num; i++)\n {\n new id = players[i]\n new Float:vel[3]\n entity_get_vector(id, EV_VEC_velocity, vel)\n new Float:speed = floatsqroot(vel[0] * vel[0] + vel[1] * vel[1])\n\n set_hudmessage(0, 255, 0, -1.0, 0.75, 0, 0.0, 0.15, 0.0, 0.0, 4)\n show_hudmessage(id, \"%.0f u/s\", speed)\n }\n}\nSPEEDSMA\n\n # --- Resetscore ---\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/resetscore.sma << 'RSSMA'\n/*\n * Resetscore - {{NOM_COMMUNAUTE}}Games.fr\n * /rs ou /resetscore pour remettre son score a zero.\n */\n#include <amxmodx>\n#include <cstrike>\n\npublic plugin_init()\n{\n register_plugin(\"Resetscore\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"say /rs\", \"cmd_reset\")\n register_clcmd(\"say /resetscore\", \"cmd_reset\")\n}\n\npublic cmd_reset(id)\n{\n cs_set_user_deaths(id, 0)\n set_user_frags(id, 0)\n client_print(id, print_chat, \"[Resetscore] Score remis a zero !\")\n return PLUGIN_HANDLED\n}\nRSSMA\n\n # Compiler les 3 plugins\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n\n for sma in autobhop speedometer resetscore; do\n ./amxxpc ${sma}.sma -o../plugins/${sma}.amxx 2>&1 || true\n if [ -f ../plugins/${sma}.amxx ]; then\n grep -q \"${sma}.amxx\" ../configs/plugins.ini 2>/dev/null \\\n || echo \"${sma}.amxx\" >> ../configs/plugins.ini\n echo \" [OK] ${sma}.amxx compile et installe\"\n else\n echo \" [WARN] Compilation ${sma} echouee\"\n fi\n done\n cd /mnt/server\nelse\n echo \" [WARN] amxxpc non trouve, impossible de compiler les plugins\"\nfi\n\n##############################################\n# 12) Maps custom depuis FastDL\n##############################################\necho \"\"\necho \">>> [12/12] Telechargement des maps depuis FastDL...\"\nFASTDL_URL=\"https://fastdl.{{DOMAINE_GAMING}}/cs_deathrun\"\n# wget recursif : telecharge maps/, gfx/, sound/, sprites/, overviews/, models/, *.wad\n# --cut-dirs=1 supprime \"cs_deathrun/\" du chemin pour copier directement dans cstrike/\nwget -r -np -nH --cut-dirs=1 -P /mnt/server/cstrike/ \\\n -R \"index.html*\" \\\n --no-check-certificate \\\n -q --show-progress \\\n \"$FASTDL_URL/\" 2>&1 || echo \" [WARN] wget a rencontre des erreurs (certains fichiers peuvent manquer)\"\n\nMAP_COUNT=$(find /mnt/server/cstrike/maps -name \"*.bsp\" 2>/dev/null | wc -l)\necho \" [OK] ${MAP_COUNT} maps .bsp telechargees\"\n\n# Generer mapcycle.txt a partir des maps telechargees (sans les maps par defaut HLDS)\necho \">>> Generation de mapcycle.txt depuis les maps telechargees...\"\nEXCLUDE_MAPS=\"as_oilrig cs_747 cs_assault cs_backalley cs_estate cs_havana cs_italy cs_militia cs_office cs_siege de_airstrip de_aztec de_cbble de_chateau de_dust de_dust2 de_inferno de_nuke de_piranesi de_prodigy de_storm de_survivor de_torn de_train de_vertigo\"\nfind /mnt/server/cstrike/maps -name \"*.bsp\" -printf \"%f\\n\" 2>/dev/null \\\n | sed 's/\\.bsp$//' | sort > /mnt/server/cstrike/mapcycle.txt\nfor m in $EXCLUDE_MAPS; do\n sed -i \"/^${m}$/d\" /mnt/server/cstrike/mapcycle.txt\ndone\necho \" [OK] mapcycle.txt genere ($(wc -l < /mnt/server/cstrike/mapcycle.txt) maps, maps HLDS exclues)\"\n\n##############################################\n# server.cfg Deathrun\n##############################################\necho \"\"\necho \">>> Generation de server.cfg...\"\ncat > /mnt/server/cstrike/server.cfg << 'SERVERCFG'\nhostname \"[FR] DEATHRUN {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}\"\nsv_contact \"admin@{{DOMAINE_GAMING}}\"\nrcon_password \"changeme\"\n\n// Deathrun settings\nmp_timelimit 30\nmp_freezetime 0\nmp_roundtime 5\nmp_autoteambalance 0\nmp_limitteams 0\nmp_friendlyfire 0\nsv_maxspeed 320\nsv_alltalk 0\nsv_voiceenable 1\n\n// Rates\nsv_maxrate 25000\nsv_minrate 6000\nsv_maxupdaterate 102\nsv_minupdaterate 30\n\n// Downloads + FastDL\nsv_allowdownload 1\nsv_allowupload 0\nsv_downloadurl \"https://fastdl.{{DOMAINE_GAMING}}/cs_deathrun\"\n\n// YaPB bots\nyb_quota 0\nyb_auto_waypoint 1\nyb_chat 0\nyb_language_tag 0\n\n// BotManager : nombre de bots quand 1 humain est connecte (0 bots si 2+ humains)\nbm_bot_count 3\n\n// Auto Bhop (Super Bunny Hopper)\nbh_enabled 1\nbh_autojump 1\n\n// DeathrunManager CVARs (voir deathrun_manager.cfg pour plus d'options)\nexec deathrun_manager.cfg\n\nexec banned.cfg\nexec listip.cfg\nSERVERCFG\n\n##############################################\n# Fix permissions\n##############################################\necho \"\"\necho \">>> Fix des permissions...\"\nchmod -R 755 /mnt/server/ 2>/dev/null || true\nchmod +x /mnt/server/hlds_linux /mnt/server/hlds_run /mnt/server/hlds_amd 2>/dev/null || true\nchmod +x /mnt/server/hltv 2>/dev/null || true\n\n# Re-copie steamclient.so 32-bit (au cas ou ReHLDS l'a ecrase)\nSTEAM_SO=$(find /mnt/server -path \"*/linux32/steamclient.so\" -not -path \"*/.steam/*\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n mkdir -p /mnt/server/.steam/sdk32\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit re-copie\"\nfi\n\necho \"\"\necho \"=============================================\"\necho \" Installation terminee !\"\necho \" Stack : ReHLDS + ReGameDLL + Metamod-R\"\necho \" + AMX Mod X + ReAPI + Reunion\"\necho \" Mode : DeathrunManager v3.0.3a\"\necho \" Extras : YaPB + BotManager + AutoBhop\"\necho \" + Speedometer + Resetscore\"\necho \" Maps : ${MAP_COUNT} maps depuis FastDL\"\necho \"=============================================\"\n", "container": "ghcr.io/ptero-eggs/installers:debian", "entrypoint": "bash" } }, "variables": [ { "name": "Server Hostname", "description": "Nom du serveur affiché dans le navigateur de serveurs", "env_variable": "HOSTNAME", "default_value": "[FR] DEATHRUN {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}", "user_viewable": true, "user_editable": true, "rules": "required|string|between:1,64", "field_type": "text" }, { "name": "Default Map", "description": "Map chargée au démarrage du serveur", "env_variable": "SRCDS_MAP", "default_value": "deathrun_arctic", "user_viewable": true, "user_editable": true, "rules": "required|string", "field_type": "text" }, { "name": "Max Players", "description": "Nombre maximum de joueurs", "env_variable": "MAX_PLAYERS", "default_value": "24", "user_viewable": true, "user_editable": true, "rules": "required|integer|between:2,64", "field_type": "text" }, { "name": "Game Folder", "description": "Dossier du jeu (ne pas modifier)", "env_variable": "HLDS_GAME", "default_value": "cstrike", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" }, { "name": "Steam App ID", "description": "App ID Steam pour CS 1.6 (ne pas modifier)", "env_variable": "SRCDS_APPID", "default_value": "90", "user_viewable": false, "user_editable": false, "rules": "required|integer", "field_type": "text" }, { "name": "Steam Beta Branch", "description": "Branche beta Steam (ne pas modifier)", "env_variable": "SRCDS_BETAID", "default_value": "steam_legacy", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" } ] } |
CS 1.6 ReHLDS – HNS
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
{ "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-02-26T18:00:00+01:00", "name": "CS 1.6 ReHLDS - Hide and Seek", "author": "admin@{{DOMAINE_GAMING}}", "description": "Counter-Strike 1.6 Hide and Seek avec ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion, ReSemiclip (boosts CT activés), OpenHNS hns_mode, PreFog, HnsMatchSystem, NadeSlow (flash/smoke ralentissent), AutoBhop, Speedometer et Resetscore. Installation 100% automatique.", "features": null, "docker_images": { "ghcr.io/ptero-eggs/games:source": "ghcr.io/ptero-eggs/games:source" }, "file_denylist": [], "startup": "./hlds_run -console -game {{HLDS_GAME}} -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -norestart +maxplayers {{MAX_PLAYERS}} +pingboost 2 +sys_ticrate 1200 +hostname \"{{HOSTNAME}}\"", "config": { "files": "{}", "startup": "{\"done\": \"gameserver Steam\"}", "logs": "{}", "stop": "quit" }, "scripts": { "installation": { "script": "#!/bin/bash\ncd /mnt/server\n\napt-get update -qq && apt-get install -yqq unzip xz-utils wget > /dev/null 2>&1 || true\n\necho \"=============================================\"\necho \" CS 1.6 Hide and Seek - Installation automatique\"\necho \"=============================================\"\n\n##############################################\n# Helper: GitHub download URL (HTML scraping + API fallback)\n##############################################\ngithub_get_url() {\n local repo=\"$1\" pattern=\"$2\" url=\"\"\n echo \" [INFO] Recherche: repo=${repo} pattern=${pattern}\" >&2\n # GitHub API (POSIX grep, pas de -P)\n for attempt in 1 2 3; do\n url=$(curl -sSL \"https://api.github.com/repos/${repo}/releases/latest\" \\\n | grep -o '\"browser_download_url\": *\"[^\"]*\"' \\\n | grep \"${pattern}\" | head -1 \\\n | sed 's/.*\"browser_download_url\": *\"//;s/\"$//')\n if [ -n \"$url\" ]; then\n echo \" [OK] URL trouvee: ${url}\" >&2\n echo \"$url\"\n return 0\n fi\n echo \" [WARN] API tentative ${attempt}/3 echouee, retry...\" >&2\n sleep 3\n done\n echo \" [ECHEC] Aucune URL trouvee pour ${repo}\" >&2\n return 1\n}\n\n##############################################\n# 1) SteamCMD + HLDS\n##############################################\necho \"\"\necho \">>> [1/13] SteamCMD + HLDS (App ID 90)...\"\nmkdir -p steamcmd\ncd steamcmd\nif [ ! -f steamcmd.sh ]; then\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz\nfi\ncd /mnt/server\n\n./steamcmd/steamcmd.sh +force_install_dir /mnt/server \\\n +login anonymous \\\n +app_update 90 -beta steam_legacy validate \\\n +quit\n\n# Steam SDK setup\nmkdir -p /mnt/server/.steam/sdk32\necho \"10\" > /mnt/server/steam_appid.txt\nSTEAM_SO=$(find /mnt/server/steamcmd -path \"*/linux32/steamclient.so\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit copie depuis $STEAM_SO\"\nelse\n echo \" [WARN] steamclient.so non trouve, telechargement direct...\"\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz -C /tmp/ linux32/steamclient.so 2>/dev/null\n if [ -f /tmp/linux32/steamclient.so ]; then\n cp -f /tmp/linux32/steamclient.so /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so telecharge\"\n fi\n rm -rf /tmp/linux32\nfi\n\n##############################################\n# 2) ReHLDS\n##############################################\necho \"\"\necho \">>> [2/13] ReHLDS...\"\nREHLDS_URL=$(github_get_url \"rehlds/ReHLDS\" \"rehlds-bin.*\\.zip\")\nif [ -n \"$REHLDS_URL\" ]; then\n echo \" URL: $REHLDS_URL\"\n curl -fsSL -o /tmp/rehlds.zip \"$REHLDS_URL\"\n if [ -s /tmp/rehlds.zip ]; then\n unzip -qo /tmp/rehlds.zip -d /tmp/rehlds/\n REHLDS_BIN=$(find /tmp/rehlds -name \"hlds_linux\" -type f | head -1)\n if [ -n \"$REHLDS_BIN\" ]; then\n REHLDS_DIR=$(dirname \"$REHLDS_BIN\")\n cp -rf \"$REHLDS_DIR\"/* /mnt/server/\n echo \" Binaires ReHLDS copies\"\n else\n echo \" WARN: hlds_linux non trouve dans l'archive\"\n fi\n else\n echo \" WARN: Telechargement echoue (fichier vide)\"\n fi\n rm -rf /tmp/rehlds /tmp/rehlds.zip\nelse\n echo \" WARN: URL ReHLDS non trouvee (GitHub API rate limit?)\"\nfi\n# Verification obligatoire\nif strings /mnt/server/hlds_linux 2>/dev/null | grep -qi \"rehlds\"; then\n echo \" [OK] ReHLDS verifie\"\nelse\n echo \" [ERREUR] ReHLDS NON installe ! Le serveur risque de ne pas demarrer\"\nfi\n\n##############################################\n# 3) ReGameDLL_CS\n##############################################\necho \"\"\necho \">>> [3/13] ReGameDLL_CS...\"\nREGAME_URL=$(github_get_url \"rehlds/ReGameDLL_CS\" \"\\.zip\")\nif [ -n \"$REGAME_URL\" ]; then\n echo \" URL: $REGAME_URL\"\n curl -fsSL -o /tmp/regamedll.zip \"$REGAME_URL\"\n if [ -s /tmp/regamedll.zip ]; then\n unzip -qo /tmp/regamedll.zip -d /tmp/regamedll/\n CSSO=$(find /tmp/regamedll -name \"cs.so\" -path \"*linux32*\" | head -1)\n [ -n \"$CSSO\" ] && cp -f \"$CSSO\" /mnt/server/cstrike/dlls/cs.so\n EXTRAS=$(find /tmp/regamedll -type d -name \"gamedir\" | head -1)\n [ -n \"$EXTRAS\" ] && cp -rn \"$EXTRAS\"/* /mnt/server/cstrike/ 2>/dev/null || true\n echo \" [OK] ReGameDLL installe\"\n fi\n rm -rf /tmp/regamedll /tmp/regamedll.zip\nelse\n echo \" WARN: Impossible de telecharger ReGameDLL_CS\"\nfi\n\n##############################################\n# 4) Metamod-R\n##############################################\necho \"\"\necho \">>> [4/13] Metamod-R...\"\nMETAMOD_URL=$(github_get_url \"rehlds/metamod-r\" \"\\.zip\")\nif [ -n \"$METAMOD_URL\" ]; then\n echo \" URL: $METAMOD_URL\"\n curl -fsSL -o /tmp/metamod.zip \"$METAMOD_URL\"\n if [ -s /tmp/metamod.zip ]; then\n unzip -qo /tmp/metamod.zip -d /tmp/metamod/\n mkdir -p /mnt/server/cstrike/addons/metamod\n META_DLL=$(find /tmp/metamod -name \"metamod_i386.so\" | head -1)\n [ -n \"$META_DLL\" ] && cp -f \"$META_DLL\" /mnt/server/cstrike/addons/metamod/\n echo \" [OK] Metamod-R installe\"\n fi\n rm -rf /tmp/metamod /tmp/metamod.zip\nelse\n echo \" WARN: Impossible de telecharger Metamod-R\"\nfi\n\n# TOUJOURS ecrire liblist.gam (meme si Metamod a echoue)\nif [ -f /mnt/server/cstrike/addons/metamod/metamod_i386.so ]; then\n GAMEDLL_LINUX=\"addons/metamod/metamod_i386.so\"\n echo \" [OK] liblist.gam -> Metamod\"\n # Creer plugins.ini si absent\n [ -f /mnt/server/cstrike/addons/metamod/plugins.ini ] \\\n || echo \"; Metamod plugins\" > /mnt/server/cstrike/addons/metamod/plugins.ini\nelse\n GAMEDLL_LINUX=\"dlls/cs.so\"\n echo \" [WARN] liblist.gam -> cs.so direct (Metamod absent)\"\nfi\ncat > /mnt/server/cstrike/liblist.gam << LIBLIST\ngame \"Counter-Strike\"\nurl_info \"www.counter-strike.net\"\nurl_dl \"\"\nversion \"1.6\"\nsize \"184000000\"\nsvonly \"0\"\ncldll \"1\"\nsecure \"1\"\nhlversion \"1110\"\nnomodels \"1\"\nnohimodel \"1\"\nmpentity \"info_player_start\"\ngamedll \"dlls\\cs.dll\"\ngamedll_linux \"${GAMEDLL_LINUX}\"\ngamedll_osx \"dlls/cs.dylib\"\ntype \"multiplayer_only\"\nLIBLIST\n\n##############################################\n# 5) AMX Mod X\n##############################################\necho \"\"\necho \">>> [5/13] AMX Mod X...\"\nAMXX_DROP=\"https://www.amxmodx.org/amxxdrop/1.10\"\ncurl -fsSL -o /tmp/amxmodx-base.tar.gz \"${AMXX_DROP}/amxmodx-latest-base-linux.tar.gz\"\ncurl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"${AMXX_DROP}/amxmodx-latest-cstrike-linux.tar.gz\"\ncd /mnt/server/cstrike\nif tar tzf /tmp/amxmodx-base.tar.gz > /dev/null 2>&1; then\n tar xzf /tmp/amxmodx-base.tar.gz\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.10 installe\"\nelse\n echo \" [WARN] 1.10 echoue, fallback 1.8.2 stable...\"\n curl -fsSL -o /tmp/amxmodx-base.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-base-linux.tar.gz\"\n curl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-cstrike-linux.tar.gz\"\n tar xzf /tmp/amxmodx-base.tar.gz 2>/dev/null || true\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.8.2 installe\"\nfi\nrm -f /tmp/amxmodx-base.tar.gz /tmp/amxmodx-cstrike.tar.gz\n# Verifier que le .so existe\nif [ -f /mnt/server/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so ]; then\n echo \" [OK] amxmodx_mm_i386.so verifie\"\nelse\n echo \" [ERREUR] amxmodx_mm_i386.so MANQUANT !\"\nfi\ngrep -q \"amxmodx\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/amxmodx/dlls/amxmodx_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\ncd /mnt/server\n\n##############################################\n# 6) ReAPI\n##############################################\necho \"\"\necho \">>> [6/13] ReAPI...\"\nREAPI_URL=$(github_get_url \"rehlds/ReAPI\" \"\\.zip\")\nif [ -n \"$REAPI_URL\" ]; then\n curl -fsSL -o /tmp/reapi.zip \"$REAPI_URL\"\n if [ -s /tmp/reapi.zip ]; then\n unzip -qo /tmp/reapi.zip -d /tmp/reapi/\n REAPI_SO=$(find /tmp/reapi -name \"reapi_amxx_i386.so\" | head -1)\n [ -n \"$REAPI_SO\" ] && cp -f \"$REAPI_SO\" /mnt/server/cstrike/addons/amxmodx/modules/\n # Copy ReAPI include files for compiling plugins later\n REAPI_INC=$(find /tmp/reapi -type d -name \"include\" -path \"*/scripting/*\" | head -1)\n if [ -n \"$REAPI_INC\" ]; then\n cp -rf \"$REAPI_INC\"/* /mnt/server/cstrike/addons/amxmodx/scripting/include/ 2>/dev/null || true\n echo \" [OK] ReAPI includes copies\"\n fi\n grep -q \"reapi_amxx_i386.so\" /mnt/server/cstrike/addons/amxmodx/configs/modules.ini 2>/dev/null \\\n || echo \"reapi_amxx_i386.so\" >> /mnt/server/cstrike/addons/amxmodx/configs/modules.ini\n echo \" [OK] ReAPI installe\"\n fi\n rm -rf /tmp/reapi /tmp/reapi.zip\nelse\n echo \" WARN: Impossible de telecharger ReAPI\"\nfi\n\n##############################################\n# 7) Reunion\n##############################################\necho \"\"\necho \">>> [7/13] Reunion...\"\nREUNION_URL=$(github_get_url \"rehlds/ReUnion\" \"\\.zip\")\nif [ -n \"$REUNION_URL\" ]; then\n curl -fsSL -o /tmp/reunion.zip \"$REUNION_URL\"\n if [ -s /tmp/reunion.zip ]; then\n unzip -qo /tmp/reunion.zip -d /tmp/reunion/\n REUNION_SO=$(find /tmp/reunion -name \"reunion_mm_i386.so\" | head -1)\n if [ -n \"$REUNION_SO\" ]; then\n mkdir -p /mnt/server/cstrike/addons/reunion\n cp -f \"$REUNION_SO\" /mnt/server/cstrike/addons/reunion/\n # reunion.cfg doit etre dans cstrike/ (PAS addons/reunion/)\n REUNION_CFG=$(find /tmp/reunion -name \"reunion.cfg\" | head -1)\n if [ -n \"$REUNION_CFG\" ] && [ ! -f /mnt/server/cstrike/reunion.cfg ]; then\n cp -f \"$REUNION_CFG\" /mnt/server/cstrike/reunion.cfg\n fi\n # Generer SteamIdHashSalt si absent ou trop court\n if [ -f /mnt/server/cstrike/reunion.cfg ]; then\n SALT=$(grep -o 'SteamIdHashSalt *= *[^ ]*' /mnt/server/cstrike/reunion.cfg | sed 's/.*= *//')\n if [ ${#SALT} -lt 16 ]; then\n NEW_SALT=$(head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \\n' | head -c 32)\n sed -i \"s/SteamIdHashSalt *=.*/SteamIdHashSalt = ${NEW_SALT}/\" /mnt/server/cstrike/reunion.cfg\n echo \" [OK] SteamIdHashSalt genere (${#NEW_SALT} chars)\"\n fi\n fi\n grep -q \"reunion\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/reunion/reunion_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] Reunion installe\"\n fi\n fi\n rm -rf /tmp/reunion /tmp/reunion.zip\nelse\n echo \" WARN: Impossible de telecharger Reunion\"\nfi\n\n##############################################\n# 8) ReSemiclip (Metamod plugin - requis par OpenHNS)\n##############################################\necho \"\"\necho \">>> [8/13] ReSemiclip...\"\nRESEMICLIP_URL=$(github_get_url \"rehlds/resemiclip\" \"\\.zip\")\nif [ -n \"$RESEMICLIP_URL\" ]; then\n curl -fsSL -o /tmp/resemiclip.zip \"$RESEMICLIP_URL\"\n if [ -s /tmp/resemiclip.zip ]; then\n unzip -qo /tmp/resemiclip.zip -d /tmp/resemiclip/\n mkdir -p /mnt/server/cstrike/addons/resemiclip/maps\n RESC_SO=$(find /tmp/resemiclip -name \"resemiclip_mm_i386.so\" | head -1)\n [ -n \"$RESC_SO\" ] && cp -f \"$RESC_SO\" /mnt/server/cstrike/addons/resemiclip/\n # Copier config et maps exemples\n RESC_CFG=$(find /tmp/resemiclip -name \"config.ini\" -path \"*/resemiclip/*\" | head -1)\n [ -n \"$RESC_CFG\" ] && cp -f \"$RESC_CFG\" /mnt/server/cstrike/addons/resemiclip/\n find /tmp/resemiclip -name \"*.ini\" -path \"*/maps/*\" -exec cp {} /mnt/server/cstrike/addons/resemiclip/maps/ \\; 2>/dev/null || true\n # Enregistrer dans Metamod\n grep -q \"resemiclip\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/resemiclip/resemiclip_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] ReSemiclip installe\"\n fi\n rm -rf /tmp/resemiclip /tmp/resemiclip.zip\nelse\n echo \" WARN: Impossible de telecharger ReSemiclip\"\nfi\n\n# Configuration ReSemiclip pour HNS\ncat > /mnt/server/cstrike/addons/resemiclip/config.ini << 'RESC_CONFIG'\n# ReSemiclip - Configuration HNS\n# Seekers (T) passent a travers entre eux\n# Hiders (CT) restent solides entre eux (pour les boosts)\n\nsemiclip = 1;\nteam = 2;\ntime = 0;\ncrouch = 1;\neffects = 1;\ndistance = 200;\ntransparency = 120;\npenetfire = 0;\nRESC_CONFIG\necho \" [OK] ReSemiclip config.ini genere\"\n\n##############################################\n# 9) OpenHNS hns_mode\n##############################################\necho \"\"\necho \">>> [9/13] OpenHNS hns_mode...\"\nHNS_URL=$(github_get_url \"OpenHNS/hns_mode\" \"\\.zip\")\nif [ -n \"$HNS_URL\" ]; then\n curl -fsSL -o /tmp/hns_mode.zip \"$HNS_URL\"\n if [ -s /tmp/hns_mode.zip ]; then\n unzip -qo /tmp/hns_mode.zip -d /tmp/hns_mode/\n # Copier les .amxx\n find /tmp/hns_mode -name \"*.amxx\" -exec cp {} /mnt/server/cstrike/addons/amxmodx/plugins/ \\; 2>/dev/null\n # Copier la config\n HNS_CFG=$(find /tmp/hns_mode -name \"hns_mode.cfg\" | head -1)\n [ -n \"$HNS_CFG\" ] && cp -f \"$HNS_CFG\" /mnt/server/cstrike/addons/amxmodx/configs/\n # Copier les fichiers de langue\n mkdir -p /mnt/server/cstrike/addons/amxmodx/data/lang\n find /tmp/hns_mode -name \"*.txt\" -path \"*/lang/*\" -exec cp {} /mnt/server/cstrike/addons/amxmodx/data/lang/ \\; 2>/dev/null\n # Copier les sons\n mkdir -p /mnt/server/cstrike/sound/openhns\n find /tmp/hns_mode -path \"*/sound/openhns/*\" -type f -exec cp {} /mnt/server/cstrike/sound/openhns/ \\; 2>/dev/null\n # Enregistrer les plugins (sans MySQL)\n for plugin in hns_main hns_stats hns_showbest hns_specback hns_lash_grenade \\\n hns_night_mode hns_additons_mode hns_afk_checker hns_ownage \\\n hns_player_info; do\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/${plugin}.amxx ]; then\n grep -q \"${plugin}.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"${plugin}.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n fi\n done\n echo \" [OK] OpenHNS hns_mode installe\"\n fi\n rm -rf /tmp/hns_mode /tmp/hns_mode.zip\nelse\n echo \" WARN: Impossible de telecharger hns_mode\"\nfi\n\n# Configuration hns_mode pour le serveur\ncat > /mnt/server/cstrike/addons/amxmodx/configs/hns_mode.cfg << 'HNSCFG'\n// OpenHNS hns_mode - Configuration\n// CT = Hiders, T = Seekers\n\n// Mode deathmatch (0=classique, 1=DM avec respawn)\nhns_deathmatch 0\n\n// Temps de respawn en DM (secondes)\nhns_respawn 3\n\n// Duree du round (minutes)\nhns_roundtime 2.5\n\n// Grenades pour les seekers (T)\nhns_he 0\nhns_flash 2\nhns_smoke 1\n\n// Grenades pour le dernier seeker\nhns_last_he 0\nhns_last_flash 1\nhns_last_smoke 1\n\n// Nombre de victoires consecutives avant swap d'equipe\nhns_swap_team 2\n\n// Son swist (quand un hider est tue)\nhns_swist 1\n\n// Prefix dans le chat\nhns_prefix \"HNS\"\n\n// Delai ownage (secondes)\nhns_ownage_delay 5.0\n\n// Mode nuit (DM automatique entre 23h et 9h)\nhns_start_night 23\nhns_end_night 9\nHNSCFG\necho \" [OK] hns_mode.cfg genere\"\n\n##############################################\n# 10) OpenHNS PreFog (compile depuis source)\n##############################################\necho \"\"\necho \">>> [10/13] PreFog (prestrafe + FOG)...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n curl -fsSL -o /tmp/prefog.zip \"https://github.com/OpenHNS/PreFog/archive/refs/tags/v3.2.4.zip\"\n if [ -s /tmp/prefog.zip ]; then\n unzip -qo /tmp/prefog.zip -d /tmp/prefog/\n PREFOG_SMA=$(find /tmp/prefog -name \"prefog.sma\" | head -1)\n if [ -n \"$PREFOG_SMA\" ]; then\n cp -f \"$PREFOG_SMA\" /mnt/server/cstrike/addons/amxmodx/scripting/\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc prefog.sma -o../plugins/prefog.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/prefog.amxx ]; then\n grep -q \"prefog.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"prefog.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] prefog.amxx compile et installe\"\n else\n echo \" [WARN] Compilation prefog echouee\"\n fi\n else\n echo \" [WARN] prefog.sma non trouve dans l'archive\"\n fi\n fi\n rm -rf /tmp/prefog /tmp/prefog.zip\nelse\n echo \" [WARN] amxxpc non trouve, impossible de compiler PreFog\"\nfi\n\n##############################################\n# 11) HnsMatchSystem\n##############################################\necho \"\"\necho \">>> [11/13] HnsMatchSystem...\"\nMATCH_URL=$(github_get_url \"OpenHNS/HnsMatchSystem\" \"\\.zip\")\nif [ -n \"$MATCH_URL\" ]; then\n curl -fsSL -o /tmp/matchsystem.zip \"$MATCH_URL\"\n if [ -s /tmp/matchsystem.zip ]; then\n unzip -qo /tmp/matchsystem.zip -d /tmp/matchsystem/\n # Copier les .amxx\n find /tmp/matchsystem -name \"*.amxx\" -exec cp {} /mnt/server/cstrike/addons/amxmodx/plugins/ \\; 2>/dev/null\n # Copier le module natif\n PDSMOD=$(find /tmp/matchsystem -name \"PersistentDataStorage_amxx_i386.so\" | head -1)\n if [ -n \"$PDSMOD\" ]; then\n cp -f \"$PDSMOD\" /mnt/server/cstrike/addons/amxmodx/modules/\n grep -q \"PersistentDataStorage\" /mnt/server/cstrike/addons/amxmodx/configs/modules.ini 2>/dev/null \\\n || echo \"PersistentDataStorage\" >> /mnt/server/cstrike/addons/amxmodx/configs/modules.ini\n echo \" [OK] Module PersistentDataStorage installe\"\n fi\n # Copier les configs\n mkdir -p /mnt/server/cstrike/addons/amxmodx/configs/mixsystem/mode\n find /tmp/matchsystem -name \"matchsystem.cfg\" -exec cp {} /mnt/server/cstrike/addons/amxmodx/configs/mixsystem/ \\; 2>/dev/null\n find /tmp/matchsystem -name \"hnsmatch-sql.cfg\" -exec cp {} /mnt/server/cstrike/addons/amxmodx/configs/mixsystem/ \\; 2>/dev/null\n find /tmp/matchsystem -name \"hns-maps.ini\" -exec cp {} /mnt/server/cstrike/addons/amxmodx/configs/mixsystem/ \\; 2>/dev/null\n find /tmp/matchsystem -name \"hns-maps.example.ini\" -exec cp {} /mnt/server/cstrike/addons/amxmodx/configs/mixsystem/ \\; 2>/dev/null\n find /tmp/matchsystem -name \"hns-arenas.ini\" -exec cp {} /mnt/server/cstrike/addons/amxmodx/configs/mixsystem/ \\; 2>/dev/null\n find /tmp/matchsystem -path \"*/mode/*.cfg\" -exec cp {} /mnt/server/cstrike/addons/amxmodx/configs/mixsystem/mode/ \\; 2>/dev/null\n find /tmp/matchsystem -name \"openhns-prefixes.ini\" -exec cp {} /mnt/server/cstrike/addons/amxmodx/configs/ \\; 2>/dev/null\n # Copier les fichiers de langue\n find /tmp/matchsystem -name \"*.txt\" -path \"*/lang/*\" -exec cp {} /mnt/server/cstrike/addons/amxmodx/data/lang/ \\; 2>/dev/null\n # Copier les sons\n mkdir -p /mnt/server/cstrike/sound/openhns\n find /tmp/matchsystem -path \"*/sound/openhns/*\" -type f -exec cp {} /mnt/server/cstrike/sound/openhns/ \\; 2>/dev/null\n # Enregistrer les plugins (sans MySQL stats)\n for plugin in HnsMatchSystem HnsMatchStats HnsMatchOwnage HnsMatchPlayerInfo \\\n HnsMatchChatmanager HnsMatchMaps HnsMatchMapRules HnsMatchTraining \\\n HnsMatchBattles HnsMatchRecontrol HnsMatchWatcher; do\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/${plugin}.amxx ]; then\n grep -q \"${plugin}.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"${plugin}.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n fi\n done\n echo \" [OK] HnsMatchSystem installe\"\n fi\n rm -rf /tmp/matchsystem /tmp/matchsystem.zip\nelse\n echo \" WARN: Impossible de telecharger HnsMatchSystem\"\nfi\n\n##############################################\n# 12) AutoBhop + Speedometer + Resetscore\n##############################################\necho \"\"\necho \">>> [12/13] AutoBhop + Speedometer + Resetscore...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\n\nif [ -f \"$AMXXPC\" ]; then\n # --- HNS Nade Slow (flash + smoke ralentissent les hiders) ---\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/hns_nade_slow.sma << 'NADESMA'\n/*\n * HNS Nade Slow - {{NOM_COMMUNAUTE}}Games.fr\n * Flash and smoke grenades slow down nearby players.\n * CVARs:\n * hns_flash_slow_speed 80.0 - Speed when flashed\n * hns_flash_slow_time 3.0 - Duration of flash slow (seconds)\n * hns_smoke_slow_speed 100.0 - Speed when in smoke\n * hns_smoke_slow_radius 200.0 - Smoke effect radius\n * hns_smoke_slow_time 15.0 - Smoke cloud duration\n */\n#include <amxmodx>\n#include <amxmisc>\n#include <engine>\n#include <fakemeta>\n#include <hamsandwich>\n#include <cstrike>\n#include <fun>\n\nnew g_cvarFlashSpeed, g_cvarFlashTime\nnew g_cvarSmokeSpeed, g_cvarSmokeRadius, g_cvarSmokeTime\nnew Float:g_fOrigSpeed[33]\nnew bool:g_bSlowed[33]\n\npublic plugin_init()\n{\n register_plugin(\"HNS Nade Slow\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n\n g_cvarFlashSpeed = register_cvar(\"hns_flash_slow_speed\", \"80.0\")\n g_cvarFlashTime = register_cvar(\"hns_flash_slow_time\", \"3.0\")\n g_cvarSmokeSpeed = register_cvar(\"hns_smoke_slow_speed\", \"100.0\")\n g_cvarSmokeRadius = register_cvar(\"hns_smoke_slow_radius\", \"200.0\")\n g_cvarSmokeTime = register_cvar(\"hns_smoke_slow_time\", \"15.0\")\n\n register_event(\"ScreenFade\", \"event_flash\", \"be\", \"4=255\", \"5=255\", \"6=255\", \"7>200\")\n register_message(get_user_msgid(\"TextMsg\"), \"msg_textmsg\")\n}\n\npublic event_flash(id)\n{\n if (!is_user_alive(id))\n return\n\n new Float:slow_speed = get_pcvar_float(g_cvarFlashSpeed)\n new Float:slow_time = get_pcvar_float(g_cvarFlashTime)\n\n if (!g_bSlowed[id])\n g_fOrigSpeed[id] = get_user_maxspeed(id)\n\n set_user_maxspeed(id, slow_speed)\n g_bSlowed[id] = true\n\n remove_task(id)\n set_task(slow_time, \"restore_speed\", id)\n}\n\npublic restore_speed(id)\n{\n if (!is_user_alive(id) || !g_bSlowed[id])\n return\n\n set_user_maxspeed(id, g_fOrigSpeed[id])\n g_bSlowed[id] = false\n}\n\npublic client_disconnected(id)\n{\n g_bSlowed[id] = false\n remove_task(id)\n}\n\npublic msg_textmsg()\n{\n // Detect smoke detonation via game message\n}\n\n// Smoke: check proximity every 0.5s when smoke grenade exists\npublic plugin_cfg()\n{\n set_task(0.5, \"check_smoke_proximity\", 0, _, _, \"b\")\n}\n\npublic check_smoke_proximity()\n{\n new ent = -1\n new Float:radius = get_pcvar_float(g_cvarSmokeRadius)\n new Float:smoke_speed = get_pcvar_float(g_cvarSmokeSpeed)\n\n // Find smoke grenade entities (\"grenade\" classname with smoke model)\n while ((ent = find_ent_by_class(ent, \"grenade\")) != 0)\n {\n new model[64]\n entity_get_string(ent, EV_SZ_model, model, charsmax(model))\n\n // Smoke grenade after detonation has velocity 0\n if (!contain(model, \"smokegrenade\"))\n continue\n\n new Float:vel[3]\n entity_get_vector(ent, EV_VEC_velocity, vel)\n // Only affect when smoke is deployed (not moving)\n if (vector_length(vel) > 10.0)\n continue\n\n new Float:smoke_origin[3]\n entity_get_vector(ent, EV_VEC_origin, smoke_origin)\n\n new players[32], num\n get_players(players, num, \"a\")\n\n for (new i = 0; i < num; i++)\n {\n new id = players[i]\n new Float:player_origin[3]\n entity_get_vector(id, EV_VEC_origin, player_origin)\n\n new Float:dist = get_distance_f(smoke_origin, player_origin)\n if (dist <= radius)\n {\n if (!g_bSlowed[id])\n g_fOrigSpeed[id] = get_user_maxspeed(id)\n\n set_user_maxspeed(id, smoke_speed)\n g_bSlowed[id] = true\n remove_task(id)\n set_task(1.0, \"restore_speed\", id)\n }\n }\n }\n}\nNADESMA\n\n # --- Auto Bhop ---\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/autobhop.sma << 'BHOPSMA'\n/*\n * Auto Bhop - {{NOM_COMMUNAUTE}}Games.fr\n * Maintenir ESPACE pour bunny hop automatique.\n */\n#include <amxmodx>\n#include <engine>\n\npublic plugin_init()\n{\n register_plugin(\"AutoBhop\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n}\n\npublic client_PreThink(id)\n{\n if (!is_user_alive(id))\n return\n\n new buttons = entity_get_int(id, EV_INT_button)\n if (buttons & IN_JUMP)\n {\n new flags = entity_get_int(id, EV_INT_flags)\n if (!(flags & FL_ONGROUND))\n entity_set_int(id, EV_INT_button, buttons & ~IN_JUMP)\n }\n}\nBHOPSMA\n\n # --- Speedometer ---\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/speedometer.sma << 'SPEEDSMA'\n/*\n * Speedometer - {{NOM_COMMUNAUTE}}Games.fr\n * Affiche la vitesse du joueur en HUD.\n */\n#include <amxmodx>\n#include <engine>\n\npublic plugin_init()\n{\n register_plugin(\"Speedometer\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n set_task(0.1, \"show_speed\", _, _, _, \"b\")\n}\n\npublic show_speed()\n{\n new players[32], num\n get_players(players, num, \"a\")\n\n for (new i = 0; i < num; i++)\n {\n new id = players[i]\n new Float:vel[3]\n entity_get_vector(id, EV_VEC_velocity, vel)\n new Float:speed = floatsqroot(vel[0] * vel[0] + vel[1] * vel[1])\n\n set_hudmessage(0, 255, 0, -1.0, 0.75, 0, 0.0, 0.15, 0.0, 0.0, 4)\n show_hudmessage(id, \"%.0f u/s\", speed)\n }\n}\nSPEEDSMA\n\n # --- Resetscore ---\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/resetscore.sma << 'RSSMA'\n/*\n * Resetscore - {{NOM_COMMUNAUTE}}Games.fr\n * /rs ou /resetscore pour remettre son score a zero.\n */\n#include <amxmodx>\n#include <cstrike>\n\npublic plugin_init()\n{\n register_plugin(\"Resetscore\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"say /rs\", \"cmd_reset\")\n register_clcmd(\"say /resetscore\", \"cmd_reset\")\n}\n\npublic cmd_reset(id)\n{\n cs_set_user_deaths(id, 0)\n set_user_frags(id, 0)\n client_print(id, print_chat, \"[Resetscore] Score remis a zero !\")\n return PLUGIN_HANDLED\n}\nRSSMA\n\n # Compiler les 3 plugins\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n\n for sma in hns_nade_slow autobhop speedometer resetscore; do\n ./amxxpc ${sma}.sma -o../plugins/${sma}.amxx 2>&1 || true\n if [ -f ../plugins/${sma}.amxx ]; then\n grep -q \"${sma}.amxx\" ../configs/plugins.ini 2>/dev/null \\\n || echo \"${sma}.amxx\" >> ../configs/plugins.ini\n echo \" [OK] ${sma}.amxx compile et installe\"\n else\n echo \" [WARN] Compilation ${sma} echouee\"\n fi\n done\n cd /mnt/server\nelse\n echo \" [WARN] amxxpc non trouve, impossible de compiler les plugins\"\nfi\n\n##############################################\n# 13) Maps custom depuis FastDL\n##############################################\necho \"\"\necho \">>> [13/13] Telechargement des maps depuis FastDL...\"\nFASTDL_URL=\"https://fastdl.{{DOMAINE_GAMING}}/cs_hns\"\n# wget recursif : telecharge maps/, gfx/, sound/, sprites/, overviews/, models/, *.wad\n# --cut-dirs=1 supprime \"cs_hns/\" du chemin pour copier directement dans cstrike/\nwget -r -np -nH --cut-dirs=1 -P /mnt/server/cstrike/ \\\n -R \"index.html*\" \\\n --no-check-certificate \\\n -q --show-progress \\\n \"$FASTDL_URL/\" 2>&1 || echo \" [WARN] wget a rencontre des erreurs (certains fichiers peuvent manquer)\"\n\nMAP_COUNT=$(find /mnt/server/cstrike/maps -name \"*.bsp\" 2>/dev/null | wc -l)\necho \" [OK] ${MAP_COUNT} maps .bsp telechargees\"\n\n# Generer mapcycle.txt a partir des maps telechargees (sans les maps par defaut HLDS)\necho \">>> Generation de mapcycle.txt depuis les maps telechargees...\"\nEXCLUDE_MAPS=\"as_oilrig cs_747 cs_assault cs_backalley cs_estate cs_havana cs_italy cs_militia cs_office cs_siege de_airstrip de_aztec de_cbble de_chateau de_dust de_dust2 de_inferno de_nuke de_piranesi de_prodigy de_storm de_survivor de_torn de_train de_vertigo\"\nfind /mnt/server/cstrike/maps -name \"*.bsp\" -printf \"%f\\n\" 2>/dev/null \\\n | sed 's/\\.bsp$//' | sort > /mnt/server/cstrike/mapcycle.txt\nfor m in $EXCLUDE_MAPS; do\n sed -i \"/^${m}$/d\" /mnt/server/cstrike/mapcycle.txt\ndone\necho \" [OK] mapcycle.txt genere ($(wc -l < /mnt/server/cstrike/mapcycle.txt) maps, maps HLDS exclues)\"\n\n##############################################\n# server.cfg Hide and Seek\n##############################################\necho \"\"\necho \">>> Generation de server.cfg...\"\ncat > /mnt/server/cstrike/server.cfg << 'SERVERCFG'\nhostname \"[FR] HNS {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}\"\nsv_contact \"admin@{{DOMAINE_GAMING}}\"\nrcon_password \"changeme\"\n\n// HNS settings\nmp_timelimit 30\nmp_freezetime 0\nmp_roundtime 3\nmp_autoteambalance 0\nmp_limitteams 0\nmp_friendlyfire 0\nmp_buytime 0\nmp_startmoney 0\nmp_playerid 2\nmp_flashlight 0\nmp_forcecamera 2\nmp_forcechasecam 2\n\n// Mouvement (critique pour HNS/Bhop)\nsv_airaccelerate 100\nsv_maxspeed 320\nsv_gravity 800\nsv_stepsize 18\nsv_stopspeed 75\n\n// Rates\nsv_maxrate 25000\nsv_minrate 6000\nsv_maxupdaterate 102\nsv_minupdaterate 30\n\n// Downloads + FastDL\nsv_allowdownload 1\nsv_allowupload 0\nsv_downloadurl \"https://fastdl.{{DOMAINE_GAMING}}/cs_hns\"\n\n// HNS Nade Slow (flash + smoke ralentissent les joueurs)\nhns_flash_slow_speed 80.0\nhns_flash_slow_time 3.0\nhns_smoke_slow_speed 100.0\nhns_smoke_slow_radius 200.0\nhns_smoke_slow_time 15.0\n\n// HNS mode config\nexec hns_mode.cfg\n\nexec banned.cfg\nexec listip.cfg\nSERVERCFG\n\n##############################################\n# Fix permissions\n##############################################\necho \"\"\necho \">>> Fix des permissions...\"\n# Rendre tout lisible/executable pour le conteneur de jeu (UID 988)\nchmod -R 755 /mnt/server/ 2>/dev/null || true\nchmod +x /mnt/server/hlds_linux /mnt/server/hlds_run /mnt/server/hlds_amd 2>/dev/null || true\nchmod +x /mnt/server/hltv 2>/dev/null || true\n\n# Re-copie steamclient.so 32-bit (au cas ou ReHLDS l'a ecrase)\nSTEAM_SO=$(find /mnt/server -path \"*/linux32/steamclient.so\" -not -path \"*/.steam/*\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n mkdir -p /mnt/server/.steam/sdk32\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit re-copie\"\nfi\n\necho \"\"\necho \"=============================================\"\necho \" Installation terminee !\"\necho \" Stack : ReHLDS + ReGameDLL + Metamod-R\"\necho \" + AMX Mod X + ReAPI + Reunion\"\necho \" HNS : ReSemiclip + OpenHNS hns_mode\"\necho \" + PreFog + HnsMatchSystem\"\necho \" Extras : NadeSlow + AutoBhop + Speedometer + Resetscore\"\necho \" Maps : ${MAP_COUNT} maps depuis FastDL\"\necho \"=============================================\"\n", "container": "ghcr.io/ptero-eggs/installers:debian", "entrypoint": "bash" } }, "variables": [ { "name": "Server Hostname", "description": "Nom du serveur affiché dans le navigateur de serveurs", "env_variable": "HOSTNAME", "default_value": "[FR] HNS {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}", "user_viewable": true, "user_editable": true, "rules": "required|string|between:1,64", "field_type": "text" }, { "name": "Default Map", "description": "Map chargée au démarrage du serveur", "env_variable": "SRCDS_MAP", "default_value": "boost_town", "user_viewable": true, "user_editable": true, "rules": "required|string", "field_type": "text" }, { "name": "Max Players", "description": "Nombre maximum de joueurs", "env_variable": "MAX_PLAYERS", "default_value": "24", "user_viewable": true, "user_editable": true, "rules": "required|integer|between:2,64", "field_type": "text" }, { "name": "Game Folder", "description": "Dossier du jeu (ne pas modifier)", "env_variable": "HLDS_GAME", "default_value": "cstrike", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" }, { "name": "Steam App ID", "description": "App ID Steam pour CS 1.6 (ne pas modifier)", "env_variable": "SRCDS_APPID", "default_value": "90", "user_viewable": false, "user_editable": false, "rules": "required|integer", "field_type": "text" }, { "name": "Steam Beta Branch", "description": "Branche beta Steam (ne pas modifier)", "env_variable": "SRCDS_BETAID", "default_value": "steam_legacy", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" } ] } |
CS 1.6 ReHLDS – Kreedz
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
{ "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-02-26T18:00:00+01:00", "name": "CS 1.6 ReHLDS - Kreedz", "author": "admin@{{DOMAINE_GAMING}}", "description": "Counter-Strike 1.6 Kreedz / Bhop avec ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion, ReSemiclip, AmxxEasyHttp, Theggv/Kreedz v1.3.0 (timer, checkpoints, jumpstats, bhop). Installation 100% automatique.", "features": null, "docker_images": { "ghcr.io/ptero-eggs/games:source": "ghcr.io/ptero-eggs/games:source" }, "file_denylist": [], "startup": "./hlds_run -console -game {{HLDS_GAME}} -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -norestart +maxplayers {{MAX_PLAYERS}} +pingboost 2 +sys_ticrate 1200 +hostname \"{{HOSTNAME}}\"", "config": { "files": "{}", "startup": "{\"done\": \"gameserver Steam\"}", "logs": "{}", "stop": "quit" }, "scripts": { "installation": { "script": "#!/bin/bash\ncd /mnt/server\n\napt-get update -qq && apt-get install -yqq unzip xz-utils wget > /dev/null 2>&1 || true\n\necho \"=============================================\"\necho \" CS 1.6 Kreedz / Bhop - Installation automatique\"\necho \"=============================================\"\n\n##############################################\n# Helper: GitHub download URL (HTML scraping + API fallback)\n##############################################\ngithub_get_url() {\n local repo=\"$1\" pattern=\"$2\" url=\"\"\n echo \" [INFO] Recherche: repo=${repo} pattern=${pattern}\" >&2\n # GitHub API (POSIX grep, pas de -P)\n for attempt in 1 2 3; do\n url=$(curl -sSL \"https://api.github.com/repos/${repo}/releases/latest\" \\\n | grep -o '\"browser_download_url\": *\"[^\"]*\"' \\\n | grep \"${pattern}\" | head -1 \\\n | sed 's/.*\"browser_download_url\": *\"//;s/\"$//')\n if [ -n \"$url\" ]; then\n echo \" [OK] URL trouvee: ${url}\" >&2\n echo \"$url\"\n return 0\n fi\n echo \" [WARN] API tentative ${attempt}/3 echouee, retry...\" >&2\n sleep 3\n done\n echo \" [ECHEC] Aucune URL trouvee pour ${repo}\" >&2\n return 1\n}\n\n##############################################\n# 1) SteamCMD + HLDS\n##############################################\necho \"\"\necho \">>> [1/12] SteamCMD + HLDS (App ID 90)...\"\nmkdir -p steamcmd\ncd steamcmd\nif [ ! -f steamcmd.sh ]; then\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz\nfi\ncd /mnt/server\n\n./steamcmd/steamcmd.sh +force_install_dir /mnt/server \\\n +login anonymous \\\n +app_update 90 -beta steam_legacy validate \\\n +quit\n\n# Steam SDK setup\nmkdir -p /mnt/server/.steam/sdk32\necho \"10\" > /mnt/server/steam_appid.txt\nSTEAM_SO=$(find /mnt/server/steamcmd -path \"*/linux32/steamclient.so\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit copie depuis $STEAM_SO\"\nelse\n echo \" [WARN] steamclient.so non trouve, telechargement direct...\"\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz -C /tmp/ linux32/steamclient.so 2>/dev/null\n if [ -f /tmp/linux32/steamclient.so ]; then\n cp -f /tmp/linux32/steamclient.so /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so telecharge\"\n fi\n rm -rf /tmp/linux32\nfi\n\n##############################################\n# 2) ReHLDS\n##############################################\necho \"\"\necho \">>> [2/12] ReHLDS...\"\nREHLDS_URL=$(github_get_url \"rehlds/ReHLDS\" \"rehlds-bin.*\\.zip\")\nif [ -n \"$REHLDS_URL\" ]; then\n echo \" URL: $REHLDS_URL\"\n curl -fsSL -o /tmp/rehlds.zip \"$REHLDS_URL\"\n if [ -s /tmp/rehlds.zip ]; then\n unzip -qo /tmp/rehlds.zip -d /tmp/rehlds/\n REHLDS_BIN=$(find /tmp/rehlds -name \"hlds_linux\" -type f | head -1)\n if [ -n \"$REHLDS_BIN\" ]; then\n REHLDS_DIR=$(dirname \"$REHLDS_BIN\")\n cp -rf \"$REHLDS_DIR\"/* /mnt/server/\n echo \" Binaires ReHLDS copies\"\n else\n echo \" WARN: hlds_linux non trouve dans l'archive\"\n fi\n else\n echo \" WARN: Telechargement echoue (fichier vide)\"\n fi\n rm -rf /tmp/rehlds /tmp/rehlds.zip\nelse\n echo \" WARN: URL ReHLDS non trouvee (GitHub API rate limit?)\"\nfi\nif strings /mnt/server/hlds_linux 2>/dev/null | grep -qi \"rehlds\"; then\n echo \" [OK] ReHLDS verifie\"\nelse\n echo \" [ERREUR] ReHLDS NON installe !\"\nfi\n\n##############################################\n# 3) ReGameDLL_CS\n##############################################\necho \"\"\necho \">>> [3/12] ReGameDLL_CS...\"\nREGAME_URL=$(github_get_url \"rehlds/ReGameDLL_CS\" \"\\.zip\")\nif [ -n \"$REGAME_URL\" ]; then\n echo \" URL: $REGAME_URL\"\n curl -fsSL -o /tmp/regamedll.zip \"$REGAME_URL\"\n if [ -s /tmp/regamedll.zip ]; then\n unzip -qo /tmp/regamedll.zip -d /tmp/regamedll/\n CSSO=$(find /tmp/regamedll -name \"cs.so\" -path \"*linux32*\" | head -1)\n [ -n \"$CSSO\" ] && cp -f \"$CSSO\" /mnt/server/cstrike/dlls/cs.so\n EXTRAS=$(find /tmp/regamedll -type d -name \"gamedir\" | head -1)\n [ -n \"$EXTRAS\" ] && cp -rn \"$EXTRAS\"/* /mnt/server/cstrike/ 2>/dev/null || true\n echo \" [OK] ReGameDLL installe\"\n fi\n rm -rf /tmp/regamedll /tmp/regamedll.zip\nelse\n echo \" WARN: Impossible de telecharger ReGameDLL_CS\"\nfi\n\n##############################################\n# 4) Metamod-R\n##############################################\necho \"\"\necho \">>> [4/12] Metamod-R...\"\nMETAMOD_URL=$(github_get_url \"rehlds/metamod-r\" \"\\.zip\")\nif [ -n \"$METAMOD_URL\" ]; then\n echo \" URL: $METAMOD_URL\"\n curl -fsSL -o /tmp/metamod.zip \"$METAMOD_URL\"\n if [ -s /tmp/metamod.zip ]; then\n unzip -qo /tmp/metamod.zip -d /tmp/metamod/\n mkdir -p /mnt/server/cstrike/addons/metamod\n META_DLL=$(find /tmp/metamod -name \"metamod_i386.so\" | head -1)\n [ -n \"$META_DLL\" ] && cp -f \"$META_DLL\" /mnt/server/cstrike/addons/metamod/\n echo \" [OK] Metamod-R installe\"\n fi\n rm -rf /tmp/metamod /tmp/metamod.zip\nelse\n echo \" WARN: Impossible de telecharger Metamod-R\"\nfi\n\nif [ -f /mnt/server/cstrike/addons/metamod/metamod_i386.so ]; then\n GAMEDLL_LINUX=\"addons/metamod/metamod_i386.so\"\n echo \" [OK] liblist.gam -> Metamod\"\n [ -f /mnt/server/cstrike/addons/metamod/plugins.ini ] \\\n || echo \"; Metamod plugins\" > /mnt/server/cstrike/addons/metamod/plugins.ini\nelse\n GAMEDLL_LINUX=\"dlls/cs.so\"\n echo \" [WARN] liblist.gam -> cs.so direct (Metamod absent)\"\nfi\ncat > /mnt/server/cstrike/liblist.gam << LIBLIST\ngame \"Counter-Strike\"\nurl_info \"www.counter-strike.net\"\nurl_dl \"\"\nversion \"1.6\"\nsize \"184000000\"\nsvonly \"0\"\ncldll \"1\"\nsecure \"1\"\nhlversion \"1110\"\nnomodels \"1\"\nnohimodel \"1\"\nmpentity \"info_player_start\"\ngamedll \"dlls\\cs.dll\"\ngamedll_linux \"${GAMEDLL_LINUX}\"\ngamedll_osx \"dlls/cs.dylib\"\ntype \"multiplayer_only\"\nLIBLIST\n\n##############################################\n# 5) AMX Mod X\n##############################################\necho \"\"\necho \">>> [5/12] AMX Mod X...\"\nAMXX_DROP=\"https://www.amxmodx.org/amxxdrop/1.10\"\ncurl -fsSL -o /tmp/amxmodx-base.tar.gz \"${AMXX_DROP}/amxmodx-latest-base-linux.tar.gz\"\ncurl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"${AMXX_DROP}/amxmodx-latest-cstrike-linux.tar.gz\"\ncd /mnt/server/cstrike\nif tar tzf /tmp/amxmodx-base.tar.gz > /dev/null 2>&1; then\n tar xzf /tmp/amxmodx-base.tar.gz\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.10 installe\"\nelse\n echo \" [WARN] 1.10 echoue, fallback 1.8.2 stable...\"\n curl -fsSL -o /tmp/amxmodx-base.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-base-linux.tar.gz\"\n curl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-cstrike-linux.tar.gz\"\n tar xzf /tmp/amxmodx-base.tar.gz 2>/dev/null || true\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.8.2 installe\"\nfi\nrm -f /tmp/amxmodx-base.tar.gz /tmp/amxmodx-cstrike.tar.gz\nif [ -f /mnt/server/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so ]; then\n echo \" [OK] amxmodx_mm_i386.so verifie\"\nelse\n echo \" [ERREUR] amxmodx_mm_i386.so MANQUANT !\"\nfi\ngrep -q \"amxmodx\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/amxmodx/dlls/amxmodx_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\ncd /mnt/server\n\n##############################################\n# 6) ReAPI\n##############################################\necho \"\"\necho \">>> [6/12] ReAPI...\"\nREAPI_URL=$(github_get_url \"rehlds/ReAPI\" \"\\.zip\")\nif [ -n \"$REAPI_URL\" ]; then\n curl -fsSL -o /tmp/reapi.zip \"$REAPI_URL\"\n if [ -s /tmp/reapi.zip ]; then\n unzip -qo /tmp/reapi.zip -d /tmp/reapi/\n REAPI_SO=$(find /tmp/reapi -name \"reapi_amxx_i386.so\" | head -1)\n [ -n \"$REAPI_SO\" ] && cp -f \"$REAPI_SO\" /mnt/server/cstrike/addons/amxmodx/modules/\n # Copy ReAPI include files for compiling plugins later\n REAPI_INC=$(find /tmp/reapi -type d -name \"include\" -path \"*/scripting/*\" | head -1)\n if [ -n \"$REAPI_INC\" ]; then\n cp -rf \"$REAPI_INC\"/* /mnt/server/cstrike/addons/amxmodx/scripting/include/ 2>/dev/null || true\n fi\n grep -q \"reapi_amxx_i386.so\" /mnt/server/cstrike/addons/amxmodx/configs/modules.ini 2>/dev/null \\\n || echo \"reapi_amxx_i386.so\" >> /mnt/server/cstrike/addons/amxmodx/configs/modules.ini\n echo \" [OK] ReAPI installe\"\n fi\n rm -rf /tmp/reapi /tmp/reapi.zip\nelse\n echo \" WARN: Impossible de telecharger ReAPI\"\nfi\n\n##############################################\n# 7) Reunion\n##############################################\necho \"\"\necho \">>> [7/12] Reunion...\"\nREUNION_URL=$(github_get_url \"rehlds/ReUnion\" \"\\.zip\")\nif [ -n \"$REUNION_URL\" ]; then\n curl -fsSL -o /tmp/reunion.zip \"$REUNION_URL\"\n if [ -s /tmp/reunion.zip ]; then\n unzip -qo /tmp/reunion.zip -d /tmp/reunion/\n REUNION_SO=$(find /tmp/reunion -name \"reunion_mm_i386.so\" | head -1)\n if [ -n \"$REUNION_SO\" ]; then\n mkdir -p /mnt/server/cstrike/addons/reunion\n cp -f \"$REUNION_SO\" /mnt/server/cstrike/addons/reunion/\n REUNION_CFG=$(find /tmp/reunion -name \"reunion.cfg\" | head -1)\n if [ -n \"$REUNION_CFG\" ] && [ ! -f /mnt/server/cstrike/reunion.cfg ]; then\n cp -f \"$REUNION_CFG\" /mnt/server/cstrike/reunion.cfg\n fi\n if [ -f /mnt/server/cstrike/reunion.cfg ]; then\n SALT=$(grep -o 'SteamIdHashSalt *= *[^ ]*' /mnt/server/cstrike/reunion.cfg | sed 's/.*= *//')\n if [ ${#SALT} -lt 16 ]; then\n NEW_SALT=$(head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \\n' | head -c 32)\n sed -i \"s/SteamIdHashSalt *=.*/SteamIdHashSalt = ${NEW_SALT}/\" /mnt/server/cstrike/reunion.cfg\n echo \" [OK] SteamIdHashSalt genere (${#NEW_SALT} chars)\"\n fi\n fi\n grep -q \"reunion\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/reunion/reunion_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] Reunion installe\"\n fi\n fi\n rm -rf /tmp/reunion /tmp/reunion.zip\nelse\n echo \" WARN: Impossible de telecharger Reunion\"\nfi\n\n##############################################\n# 8) ReSemiclip (Metamod plugin)\n##############################################\necho \"\"\necho \">>> [8/12] ReSemiclip...\"\nRESEMICLIP_URL=$(github_get_url \"rehlds/resemiclip\" \"\\.zip\")\nif [ -n \"$RESEMICLIP_URL\" ]; then\n curl -fsSL -o /tmp/resemiclip.zip \"$RESEMICLIP_URL\"\n if [ -s /tmp/resemiclip.zip ]; then\n unzip -qo /tmp/resemiclip.zip -d /tmp/resemiclip/\n mkdir -p /mnt/server/cstrike/addons/resemiclip/maps\n RESC_SO=$(find /tmp/resemiclip -name \"resemiclip_mm_i386.so\" | head -1)\n [ -n \"$RESC_SO\" ] && cp -f \"$RESC_SO\" /mnt/server/cstrike/addons/resemiclip/\n RESC_CFG=$(find /tmp/resemiclip -name \"config.ini\" -path \"*/resemiclip/*\" | head -1)\n [ -n \"$RESC_CFG\" ] && cp -f \"$RESC_CFG\" /mnt/server/cstrike/addons/resemiclip/\n find /tmp/resemiclip -name \"*.ini\" -path \"*/maps/*\" -exec cp {} /mnt/server/cstrike/addons/resemiclip/maps/ \\; 2>/dev/null || true\n grep -q \"resemiclip\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/resemiclip/resemiclip_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] ReSemiclip installe\"\n fi\n rm -rf /tmp/resemiclip /tmp/resemiclip.zip\nelse\n echo \" WARN: Impossible de telecharger ReSemiclip\"\nfi\n\n# Config ReSemiclip pour KZ\ncat > /mnt/server/cstrike/addons/resemiclip/config.ini << 'RESC_CONFIG'\n# ReSemiclip - Configuration KZ\n# Joueurs passent a travers les coequipiers\n\nsemiclip = 1;\nteam = 3;\ntime = 0;\ncrouch = 1;\neffects = 1;\ndistance = 200;\ntransparency = 120;\npenetfire = 0;\nRESC_CONFIG\necho \" [OK] ReSemiclip config.ini genere\"\n\n##############################################\n# 9) AmxxEasyHttp - DESACTIVE (crash Docker)\n##############################################\necho \"\"\necho \">>> [9/12] AmxxEasyHttp... SKIP (module natif incompatible Docker)\"\necho \" [INFO] AmxxEasyHttp desactive - les plugins kz_cups et kz_records_frontend ne fonctionneront pas\"\n\n##############################################\n# 10) Theggv/Kreedz v1.3.0 (plugin suite KZ)\n##############################################\necho \"\"\necho \">>> [10/12] Kreedz v1.3.0...\"\n# Telecharger la derniere release\nKZ_URL=$(github_get_url \"Theggv/Kreedz\" \"addons\\.zip\")\nif [ -n \"$KZ_URL\" ]; then\n curl -fsSL -o /tmp/kreedz.zip \"$KZ_URL\"\n if [ -s /tmp/kreedz.zip ]; then\n unzip -qo /tmp/kreedz.zip -d /tmp/kreedz/\n # L'archive contient addons/ qui se merge avec cstrike/addons/\n KZ_ADDONS=$(find /tmp/kreedz -maxdepth 2 -type d -name \"addons\" | head -1)\n if [ -n \"$KZ_ADDONS\" ]; then\n KZ_ROOT=$(dirname \"$KZ_ADDONS\")\n # Copier plugins et data AMXX (PAS configs/ ni modules/)\n cp -rf \"$KZ_ROOT\"/addons/amxmodx/plugins/* /mnt/server/cstrike/addons/amxmodx/plugins/ 2>/dev/null || true\n cp -rf \"$KZ_ROOT\"/addons/amxmodx/data/* /mnt/server/cstrike/addons/amxmodx/data/ 2>/dev/null || true\n # NE PAS copier configs/ (on genere nos propres configs)\n # NE PAS copier modules/ (modules natifs incompatibles Docker)\n # Copier les ressources du jeu (models, sound, sprites) si presentes\n for resdir in models sound sprites; do\n if [ -d \"$KZ_ROOT/$resdir\" ]; then\n cp -rf \"$KZ_ROOT/$resdir\" /mnt/server/cstrike/\n echo \" [OK] $resdir/ copie depuis l'archive\"\n fi\n done\n echo \" [OK] Kreedz plugins, data et ressources copies\"\n else\n echo \" [WARN] Structure addons/ non trouvee dans l'archive\"\n fi\n\n # Supprimer physiquement les plugins exclus (securite anti-chargement)\n SKIP_PLUGINS=\"kz_sql_core.amxx kz_sql_savepos.amxx kz_sql_top.amxx kz_sql_top_web.amxx settings_mysql.amxx kz_rank_mysql.amxx kz_rush_pubbot.amxx kz_cups.amxx kz_records.amxx kz_records_frontend.amxx\"\n for excluded in $SKIP_PLUGINS; do\n if [ -f \"/mnt/server/cstrike/addons/amxmodx/plugins/$excluded\" ]; then\n rm -f \"/mnt/server/cstrike/addons/amxmodx/plugins/$excluded\"\n echo \" [DEL] $excluded supprime du serveur\"\n fi\n done\n # Supprimer les map_manager de l'archive Kreedz (on installe MapManagerModular depuis GitHub)\n for mm_plugin in /mnt/server/cstrike/addons/amxmodx/plugins/map_manager*.amxx; do\n if [ -f \"$mm_plugin\" ]; then\n echo \" [DEL] $(basename $mm_plugin) supprime (remplacement par MapManagerModular)\"\n rm -f \"$mm_plugin\"\n SKIP_PLUGINS=\"$SKIP_PLUGINS $(basename $mm_plugin)\"\n fi\n done\n\n # Securite: supprimer les plugins-*.ini parasites (AMXX les auto-charge)\n rm -f /mnt/server/cstrike/addons/amxmodx/configs/plugins-*.ini 2>/dev/null\n echo \" [OK] Fichiers plugins-*.ini parasites nettoyes\"\n\n # Creer les dossiers de config manquants\n mkdir -p /mnt/server/cstrike/addons/amxmodx/configs/uq_jumpstats\n [ -f /mnt/server/cstrike/addons/amxmodx/configs/uq_jumpstats/config.cfg ] \\\n || echo \"// UQ Jumpstats config\" > /mnt/server/cstrike/addons/amxmodx/configs/uq_jumpstats/config.cfg\n\n # Desactiver mapchooser et nextmap par defaut (remplaces par MapManagerModular)\n sed -i 's/^mapchooser.amxx/;mapchooser.amxx/' /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null || true\n sed -i 's/^nextmap.amxx/;nextmap.amxx/' /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null || true\n echo \" [OK] mapchooser.amxx et nextmap.amxx desactives (remplaces par MapManagerModular)\"\n\n # Enregistrer TOUS les .amxx copies depuis l'archive Kreedz (sauf SKIP_PLUGINS)\n echo \"\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \"; === Kreedz plugins ===\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n find \"$KZ_ROOT\"/addons/amxmodx/plugins/ -name \"*.amxx\" -printf \"%f\\n\" 2>/dev/null | sort | while read -r plugin; do\n skip=0\n for excluded in $SKIP_PLUGINS; do\n [ \"$plugin\" = \"$excluded\" ] && skip=1 && break\n done\n if [ \"$skip\" = \"1\" ]; then\n echo \" [SKIP] $plugin (desactive)\"\n elif [ -f \"/mnt/server/cstrike/addons/amxmodx/plugins/$plugin\" ]; then\n grep -q \"$plugin\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"$plugin\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [ADD] $plugin\"\n fi\n done\n echo \" [OK] Plugins KZ enregistres dans plugins.ini\"\n echo \" [OK] Kreedz v1.3.0 installe\"\n fi\n rm -rf /tmp/kreedz /tmp/kreedz.zip\nelse\n echo \" WARN: Impossible de telecharger Kreedz\"\nfi\n\n# 10b) MapManagerModular v3.2.0 (RTV + nominations + vote)\necho \"\"\necho \">>> [10b/12] MapManagerModular v3.2.0...\"\nMM_URL=\"https://github.com/Mistrick/MapManagerModular/releases/download/v3.2.0/MapManager-v3.2.0.zip\"\ncurl -fsSL -o /tmp/mapmanager.zip \"$MM_URL\"\nif [ -s /tmp/mapmanager.zip ]; then\n unzip -qo /tmp/mapmanager.zip -d /tmp/mapmanager/\n # Trouver le dossier cstrike dans l'archive\n MM_CSTRIKE=$(find /tmp/mapmanager -maxdepth 2 -type d -name \"cstrike\" | head -1)\n if [ -z \"$MM_CSTRIKE\" ]; then\n MM_CSTRIKE=$(find /tmp/mapmanager -maxdepth 2 -type d -name \"addons\" | head -1)\n [ -n \"$MM_CSTRIKE\" ] && MM_CSTRIKE=$(dirname \"$MM_CSTRIKE\")\n fi\n if [ -n \"$MM_CSTRIKE\" ]; then\n # Copier les plugins pre-compiles\n cp -rf \"$MM_CSTRIKE\"/addons/amxmodx/plugins/map_manager*.amxx /mnt/server/cstrike/addons/amxmodx/plugins/ 2>/dev/null || true\n # Copier les ressources (models, sprites, sound)\n for resdir in models sprites sound; do\n if [ -d \"$MM_CSTRIKE/$resdir\" ]; then\n cp -rf \"$MM_CSTRIKE/$resdir\" /mnt/server/cstrike/\n echo \" [OK] $resdir/ copie depuis MapManagerModular\"\n fi\n done\n # Copier les configs et data\n cp -rf \"$MM_CSTRIKE\"/addons/amxmodx/configs/map_manager* /mnt/server/cstrike/addons/amxmodx/configs/ 2>/dev/null || true\n cp -rf \"$MM_CSTRIKE\"/addons/amxmodx/data/map_manager* /mnt/server/cstrike/addons/amxmodx/data/ 2>/dev/null || true\n # Copier les scripting includes\n cp -rf \"$MM_CSTRIKE\"/addons/amxmodx/scripting/include/map_manager*.inc /mnt/server/cstrike/addons/amxmodx/scripting/include/ 2>/dev/null || true\n echo \" [OK] MapManagerModular fichiers copies\"\n fi\n\n # Supprimer map_manager_effects.amxx (crash si models/sprites manquants)\n rm -f /mnt/server/cstrike/addons/amxmodx/plugins/map_manager_effects.amxx 2>/dev/null\n echo \" [DEL] map_manager_effects.amxx supprime (ressources instables)\"\n\n # Enregistrer les plugins map_manager dans plugins.ini\n echo \"\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \"; === MapManagerModular ===\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n for mm_amxx in /mnt/server/cstrike/addons/amxmodx/plugins/map_manager*.amxx; do\n if [ -f \"$mm_amxx\" ]; then\n mm_name=$(basename \"$mm_amxx\")\n grep -q \"$mm_name\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"$mm_name\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [ADD] $mm_name\"\n fi\n done\n\n echo \" [OK] MapManagerModular v3.2.0 installe\"\nelse\n echo \" [WARN] Telechargement MapManagerModular echoue\"\nfi\nrm -rf /tmp/mapmanager /tmp/mapmanager.zip\n\n# Configuration Kreedz (dans cstrike/ pour que exec les trouve)\ncat > /mnt/server/cstrike/kreedz.cfg << 'KZCFG'\n// Kreedz - Configuration\n// MySQL desactive par defaut (records en local)\n// Pour activer MySQL, decommenter et renseigner :\n// kz_sql_hostname \"127.0.0.1\"\n// kz_sql_username \"user\"\n// kz_sql_password \"password\"\n// kz_sql_database \"kreedz\"\n// kz_records_frontend_url \"http://127.0.0.1:3000/records\"\nKZCFG\n\n# Configuration mpbhop (dans cstrike/)\ncat > /mnt/server/cstrike/mpbhop.cfg << 'BHOPCFG'\n// Multi-player Bhop\n// 1 = active (supprime le slowdown au sol)\nkz_mpbhop 1\nBHOPCFG\necho \" [OK] Configs kreedz.cfg et mpbhop.cfg generes\"\n\n##############################################\n# 11) Resetscore\n##############################################\necho \"\"\necho \">>> [11/12] Resetscore...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\n\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/resetscore.sma << 'RSSMA'\n/*\n * Resetscore - {{NOM_COMMUNAUTE}}Games.fr\n * /rs ou /resetscore pour remettre son score a zero.\n */\n#include <amxmodx>\n#include <cstrike>\n\npublic plugin_init()\n{\n register_plugin(\"Resetscore\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"say /rs\", \"cmd_reset\")\n register_clcmd(\"say /resetscore\", \"cmd_reset\")\n}\n\npublic cmd_reset(id)\n{\n cs_set_user_deaths(id, 0)\n set_user_frags(id, 0)\n client_print(id, print_chat, \"[Resetscore] Score remis a zero !\")\n return PLUGIN_HANDLED\n}\nRSSMA\n\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc resetscore.sma -o../plugins/resetscore.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/resetscore.amxx ]; then\n grep -q \"resetscore.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"resetscore.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] resetscore.amxx compile et installe\"\n else\n echo \" [WARN] Compilation resetscore echouee\"\n fi\n\n # RTV gere par MapManagerModular (map_manager_rtv.amxx)\nelse\n echo \" [WARN] amxxpc non trouve\"\nfi\n\n##############################################\n# 12) Maps custom depuis FastDL\n##############################################\necho \"\"\necho \">>> [12/12] Telechargement des maps depuis FastDL...\"\nFASTDL_URL=\"https://fastdl.{{DOMAINE_GAMING}}/cs_kz\"\nwget -r -np -nH --cut-dirs=1 -P /mnt/server/cstrike/ \\\n -R \"index.html*\" \\\n --no-check-certificate \\\n -q --show-progress \\\n \"$FASTDL_URL/\" 2>&1 || echo \" [WARN] wget a rencontre des erreurs (certains fichiers peuvent manquer)\"\n\nMAP_COUNT=$(find /mnt/server/cstrike/maps -name \"*.bsp\" 2>/dev/null | wc -l)\necho \" [OK] ${MAP_COUNT} maps .bsp telechargees\"\n\n# Generer mapcycle.txt (sans les maps par defaut HLDS)\necho \">>> Generation de mapcycle.txt depuis les maps telechargees...\"\nEXCLUDE_MAPS=\"as_oilrig cs_747 cs_assault cs_backalley cs_estate cs_havana cs_italy cs_militia cs_office cs_siege de_airstrip de_aztec de_cbble de_chateau de_dust de_dust2 de_inferno de_nuke de_piranesi de_prodigy de_storm de_survivor de_torn de_train de_vertigo\"\nfind /mnt/server/cstrike/maps -name \"*.bsp\" -printf \"%f\\n\" 2>/dev/null \\\n | sed 's/\\.bsp$//' | sort > /mnt/server/cstrike/mapcycle.txt\nfor m in $EXCLUDE_MAPS; do\n sed -i \"/^${m}$/d\" /mnt/server/cstrike/mapcycle.txt\ndone\necho \" [OK] mapcycle.txt genere ($(wc -l < /mnt/server/cstrike/mapcycle.txt) maps, maps HLDS exclues)\"\n\n# Generer maps.ini pour MapManagerModular (meme contenu que mapcycle.txt)\ncp -f /mnt/server/cstrike/mapcycle.txt /mnt/server/cstrike/addons/amxmodx/configs/maps.ini\necho \" [OK] maps.ini genere pour MapManagerModular ($(wc -l < /mnt/server/cstrike/addons/amxmodx/configs/maps.ini) maps)\"\n\n##############################################\n# server.cfg Kreedz\n##############################################\necho \"\"\necho \">>> Generation de server.cfg...\"\ncat > /mnt/server/cstrike/server.cfg << 'SERVERCFG'\nhostname \"[FR] KREEDZ {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}\"\nsv_contact \"admin@{{DOMAINE_GAMING}}\"\nrcon_password \"changeme\"\n\n// KZ settings\nmp_timelimit 0\nmp_freezetime 0\nmp_roundtime 9\nmp_autoteambalance 0\nmp_limitteams 0\nmp_friendlyfire 0\nmp_buytime 0\nmp_startmoney 800\nmp_autokick 0\nmp_forcecamera 0\nmp_forcechasecam 0\n\n// Mouvement KZ\nsv_airaccelerate 100\nsv_maxspeed 320\nsv_gravity 800\nsv_stepsize 18\nsv_stopspeed 75\nsv_enablebunnyhopping 1\nsv_autobunnyhopping 0\n\n// Communication\nsv_alltalk 1\nsv_voiceenable 1\n\n// Rates\nsv_maxrate 25000\nsv_minrate 6000\nsv_maxupdaterate 102\nsv_minupdaterate 30\n\n// Downloads + FastDL\nsv_allowdownload 1\nsv_allowupload 0\nsv_downloadurl \"https://fastdl.{{DOMAINE_GAMING}}/cs_kz\"\n\n// Kreedz config\nexec kreedz.cfg\nexec mpbhop.cfg\n\nexec banned.cfg\nexec listip.cfg\nSERVERCFG\n\n##############################################\n# Fix permissions\n##############################################\necho \"\"\necho \">>> Fix des permissions...\"\nchmod -R 755 /mnt/server/ 2>/dev/null || true\nchmod +x /mnt/server/hlds_linux /mnt/server/hlds_run /mnt/server/hlds_amd 2>/dev/null || true\nchmod +x /mnt/server/hltv 2>/dev/null || true\n\nSTEAM_SO=$(find /mnt/server -path \"*/linux32/steamclient.so\" -not -path \"*/.steam/*\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n mkdir -p /mnt/server/.steam/sdk32\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit re-copie\"\nfi\n\necho \"\"\necho \"=============================================\"\necho \" Installation terminee !\"\necho \" Stack : ReHLDS + ReGameDLL + Metamod-R\"\necho \" + AMX Mod X + ReAPI + Reunion\"\necho \" KZ : ReSemiclip + AmxxEasyHttp\"\necho \" + Theggv/Kreedz v1.3.0\"\necho \" Extras : Resetscore\"\necho \" Maps : ${MAP_COUNT} maps depuis FastDL\"\necho \"=============================================\"\n", "container": "ghcr.io/ptero-eggs/installers:debian", "entrypoint": "bash" } }, "variables": [ { "name": "Server Hostname", "description": "Nom du serveur affiché dans le navigateur de serveurs", "env_variable": "HOSTNAME", "default_value": "[FR] KREEDZ {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}", "user_viewable": true, "user_editable": true, "rules": "required|string|between:1,64", "field_type": "text" }, { "name": "Default Map", "description": "Map chargée au démarrage du serveur", "env_variable": "SRCDS_MAP", "default_value": "bkz_goldbhop", "user_viewable": true, "user_editable": true, "rules": "required|string", "field_type": "text" }, { "name": "Max Players", "description": "Nombre maximum de joueurs", "env_variable": "MAX_PLAYERS", "default_value": "20", "user_viewable": true, "user_editable": true, "rules": "required|integer|between:2,64", "field_type": "text" }, { "name": "Game Folder", "description": "Dossier du jeu (ne pas modifier)", "env_variable": "HLDS_GAME", "default_value": "cstrike", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" }, { "name": "Steam App ID", "description": "App ID Steam pour CS 1.6 (ne pas modifier)", "env_variable": "SRCDS_APPID", "default_value": "90", "user_viewable": false, "user_editable": false, "rules": "required|integer", "field_type": "text" }, { "name": "Steam Beta Branch", "description": "Branche beta Steam (ne pas modifier)", "env_variable": "SRCDS_BETAID", "default_value": "steam_legacy", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" } ] } |
CS 1.6 ReHLDS – War (Automix 5v5)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
{ "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-02-28T12:00:00+01:00", "name": "CS 1.6 ReHLDS - WAR 5v5", "author": "admin@{{DOMAINE_GAMING}}", "description": "Counter-Strike 1.6 WAR 5v5 compétitif avec ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion et MatchBot v1.0.4. Match MR15 automatique quand 10 joueurs sont connectés (knife round, LO3, pause, overtime). Installation 100% automatique.", "features": null, "docker_images": { "ghcr.io/ptero-eggs/games:source": "ghcr.io/ptero-eggs/games:source" }, "file_denylist": [], "startup": "./hlds_run -console -game {{HLDS_GAME}} -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -norestart +maxplayers {{MAX_PLAYERS}} +pingboost 2 +sys_ticrate 1200 +hostname \"{{HOSTNAME}}\"", "config": { "files": "{}", "startup": "{\"done\": \"gameserver Steam\"}", "logs": "{}", "stop": "quit" }, "scripts": { "installation": { "script": "#!/bin/bash\ncd /mnt/server\n\napt-get update -qq && apt-get install -yqq unzip xz-utils wget > /dev/null 2>&1 || true\n\necho \"=============================================\"\necho \" CS 1.6 WAR 5v5 (PugMod-AMXX) - Installation\"\necho \"=============================================\"\n\n##############################################\n# Helper: GitHub download URL (API + retry)\n##############################################\ngithub_get_url() {\n local repo=\"$1\" pattern=\"$2\" url=\"\"\n echo \" [INFO] Recherche: repo=${repo} pattern=${pattern}\" >&2\n for attempt in 1 2 3; do\n url=$(curl -sSL \"https://api.github.com/repos/${repo}/releases/latest\" \\\n | grep -o '\"browser_download_url\": *\"[^\"]*\"' \\\n | grep \"${pattern}\" | head -1 \\\n | sed 's/.*\"browser_download_url\": *\"//;s/\"$//')\n if [ -n \"$url\" ]; then\n echo \" [OK] URL trouvee: ${url}\" >&2\n echo \"$url\"\n return 0\n fi\n echo \" [WARN] API tentative ${attempt}/3 echouee, retry...\" >&2\n sleep 3\n done\n echo \" [ECHEC] Aucune URL trouvee pour ${repo}\" >&2\n return 1\n}\n\n##############################################\n# 1) SteamCMD + HLDS\n##############################################\necho \"\"\necho \">>> [1/9] SteamCMD + HLDS (App ID 90)...\"\nmkdir -p steamcmd\ncd steamcmd\nif [ ! -f steamcmd.sh ]; then\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz\nfi\ncd /mnt/server\n\n./steamcmd/steamcmd.sh +force_install_dir /mnt/server \\\n +login anonymous \\\n +app_update 90 -beta steam_legacy validate \\\n +quit\n\n# Steam SDK setup\nmkdir -p /mnt/server/.steam/sdk32\necho \"10\" > /mnt/server/steam_appid.txt\nSTEAM_SO=$(find /mnt/server/steamcmd -path \"*/linux32/steamclient.so\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit copie depuis $STEAM_SO\"\nelse\n echo \" [WARN] steamclient.so non trouve, telechargement direct...\"\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz -C /tmp/ linux32/steamclient.so 2>/dev/null\n if [ -f /tmp/linux32/steamclient.so ]; then\n cp -f /tmp/linux32/steamclient.so /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so telecharge\"\n fi\n rm -rf /tmp/linux32\nfi\n\n##############################################\n# 2) ReHLDS\n##############################################\necho \"\"\necho \">>> [2/9] ReHLDS...\"\nREHLDS_URL=$(github_get_url \"rehlds/ReHLDS\" \"rehlds-bin.*\\.zip\")\nif [ -n \"$REHLDS_URL\" ]; then\n echo \" URL: $REHLDS_URL\"\n curl -fsSL -o /tmp/rehlds.zip \"$REHLDS_URL\"\n if [ -s /tmp/rehlds.zip ]; then\n unzip -qo /tmp/rehlds.zip -d /tmp/rehlds/\n REHLDS_BIN=$(find /tmp/rehlds -name \"hlds_linux\" -type f | head -1)\n if [ -n \"$REHLDS_BIN\" ]; then\n REHLDS_DIR=$(dirname \"$REHLDS_BIN\")\n cp -rf \"$REHLDS_DIR\"/* /mnt/server/\n echo \" Binaires ReHLDS copies\"\n else\n echo \" WARN: hlds_linux non trouve dans l'archive\"\n fi\n else\n echo \" WARN: Telechargement echoue (fichier vide)\"\n fi\n rm -rf /tmp/rehlds /tmp/rehlds.zip\nelse\n echo \" WARN: URL ReHLDS non trouvee (GitHub API rate limit?)\"\nfi\nif strings /mnt/server/hlds_linux 2>/dev/null | grep -qi \"rehlds\"; then\n echo \" [OK] ReHLDS verifie\"\nelse\n echo \" [ERREUR] ReHLDS NON installe !\"\nfi\n\n##############################################\n# 3) ReGameDLL_CS\n##############################################\necho \"\"\necho \">>> [3/9] ReGameDLL_CS...\"\nREGAME_URL=$(github_get_url \"rehlds/ReGameDLL_CS\" \"\\.zip\")\nif [ -n \"$REGAME_URL\" ]; then\n echo \" URL: $REGAME_URL\"\n curl -fsSL -o /tmp/regamedll.zip \"$REGAME_URL\"\n if [ -s /tmp/regamedll.zip ]; then\n unzip -qo /tmp/regamedll.zip -d /tmp/regamedll/\n CSSO=$(find /tmp/regamedll -name \"cs.so\" -path \"*linux32*\" | head -1)\n [ -n \"$CSSO\" ] && cp -f \"$CSSO\" /mnt/server/cstrike/dlls/cs.so\n EXTRAS=$(find /tmp/regamedll -type d -name \"gamedir\" | head -1)\n [ -n \"$EXTRAS\" ] && cp -rn \"$EXTRAS\"/* /mnt/server/cstrike/ 2>/dev/null || true\n echo \" [OK] ReGameDLL installe\"\n fi\n rm -rf /tmp/regamedll /tmp/regamedll.zip\nelse\n echo \" WARN: Impossible de telecharger ReGameDLL_CS\"\nfi\n\n##############################################\n# 4) Metamod-R\n##############################################\necho \"\"\necho \">>> [4/9] Metamod-R...\"\nMETAMOD_URL=$(github_get_url \"rehlds/metamod-r\" \"\\.zip\")\nif [ -n \"$METAMOD_URL\" ]; then\n echo \" URL: $METAMOD_URL\"\n curl -fsSL -o /tmp/metamod.zip \"$METAMOD_URL\"\n if [ -s /tmp/metamod.zip ]; then\n unzip -qo /tmp/metamod.zip -d /tmp/metamod/\n mkdir -p /mnt/server/cstrike/addons/metamod\n META_DLL=$(find /tmp/metamod -name \"metamod_i386.so\" | head -1)\n [ -n \"$META_DLL\" ] && cp -f \"$META_DLL\" /mnt/server/cstrike/addons/metamod/\n echo \" [OK] Metamod-R installe\"\n fi\n rm -rf /tmp/metamod /tmp/metamod.zip\nelse\n echo \" WARN: Impossible de telecharger Metamod-R\"\nfi\n\nif [ -f /mnt/server/cstrike/addons/metamod/metamod_i386.so ]; then\n GAMEDLL_LINUX=\"addons/metamod/metamod_i386.so\"\n echo \" [OK] liblist.gam -> Metamod\"\n [ -f /mnt/server/cstrike/addons/metamod/plugins.ini ] \\\n || echo \"; Metamod plugins\" > /mnt/server/cstrike/addons/metamod/plugins.ini\nelse\n GAMEDLL_LINUX=\"dlls/cs.so\"\n echo \" [WARN] liblist.gam -> cs.so direct (Metamod absent)\"\nfi\ncat > /mnt/server/cstrike/liblist.gam << LIBLIST\ngame \"Counter-Strike\"\nurl_info \"www.counter-strike.net\"\nurl_dl \"\"\nversion \"1.6\"\nsize \"184000000\"\nsvonly \"0\"\ncldll \"1\"\nsecure \"1\"\nhlversion \"1110\"\nnomodels \"1\"\nnohimodel \"1\"\nmpentity \"info_player_start\"\ngamedll \"dlls\\cs.dll\"\ngamedll_linux \"${GAMEDLL_LINUX}\"\ngamedll_osx \"dlls/cs.dylib\"\ntype \"multiplayer_only\"\nLIBLIST\n\n##############################################\n# 5) AMX Mod X\n##############################################\necho \"\"\necho \">>> [5/9] AMX Mod X...\"\nAMXX_DROP=\"https://www.amxmodx.org/amxxdrop/1.10\"\ncurl -fsSL -o /tmp/amxmodx-base.tar.gz \"${AMXX_DROP}/amxmodx-latest-base-linux.tar.gz\"\ncurl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"${AMXX_DROP}/amxmodx-latest-cstrike-linux.tar.gz\"\ncd /mnt/server/cstrike\nif tar tzf /tmp/amxmodx-base.tar.gz > /dev/null 2>&1; then\n tar xzf /tmp/amxmodx-base.tar.gz\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.10 installe\"\nelse\n echo \" [WARN] 1.10 echoue, fallback 1.8.2 stable...\"\n curl -fsSL -o /tmp/amxmodx-base.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-base-linux.tar.gz\"\n curl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-cstrike-linux.tar.gz\"\n tar xzf /tmp/amxmodx-base.tar.gz 2>/dev/null || true\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.8.2 installe\"\nfi\nrm -f /tmp/amxmodx-base.tar.gz /tmp/amxmodx-cstrike.tar.gz\nif [ -f /mnt/server/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so ]; then\n echo \" [OK] amxmodx_mm_i386.so verifie\"\nelse\n echo \" [ERREUR] amxmodx_mm_i386.so MANQUANT !\"\nfi\ngrep -q \"amxmodx\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/amxmodx/dlls/amxmodx_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\ncd /mnt/server\n\n##############################################\n# 6) ReAPI\n##############################################\necho \"\"\necho \">>> [6/9] ReAPI...\"\nREAPI_URL=$(github_get_url \"rehlds/ReAPI\" \"\\.zip\")\nif [ -n \"$REAPI_URL\" ]; then\n curl -fsSL -o /tmp/reapi.zip \"$REAPI_URL\"\n if [ -s /tmp/reapi.zip ]; then\n unzip -qo /tmp/reapi.zip -d /tmp/reapi/\n REAPI_SO=$(find /tmp/reapi -name \"reapi_amxx_i386.so\" | head -1)\n [ -n \"$REAPI_SO\" ] && cp -f \"$REAPI_SO\" /mnt/server/cstrike/addons/amxmodx/modules/\n REAPI_INC=$(find /tmp/reapi -type d -name \"include\" -path \"*/scripting/*\" | head -1)\n if [ -n \"$REAPI_INC\" ]; then\n cp -rf \"$REAPI_INC\"/* /mnt/server/cstrike/addons/amxmodx/scripting/include/ 2>/dev/null || true\n fi\n grep -q \"reapi_amxx_i386.so\" /mnt/server/cstrike/addons/amxmodx/configs/modules.ini 2>/dev/null \\\n || echo \"reapi_amxx_i386.so\" >> /mnt/server/cstrike/addons/amxmodx/configs/modules.ini\n echo \" [OK] ReAPI installe\"\n fi\n rm -rf /tmp/reapi /tmp/reapi.zip\nelse\n echo \" WARN: Impossible de telecharger ReAPI\"\nfi\n\n##############################################\n# 7) Reunion\n##############################################\necho \"\"\necho \">>> [7/9] Reunion...\"\nREUNION_URL=$(github_get_url \"rehlds/ReUnion\" \"\\.zip\")\nif [ -n \"$REUNION_URL\" ]; then\n curl -fsSL -o /tmp/reunion.zip \"$REUNION_URL\"\n if [ -s /tmp/reunion.zip ]; then\n unzip -qo /tmp/reunion.zip -d /tmp/reunion/\n REUNION_SO=$(find /tmp/reunion -name \"reunion_mm_i386.so\" | head -1)\n if [ -n \"$REUNION_SO\" ]; then\n mkdir -p /mnt/server/cstrike/addons/reunion\n cp -f \"$REUNION_SO\" /mnt/server/cstrike/addons/reunion/\n REUNION_CFG=$(find /tmp/reunion -name \"reunion.cfg\" | head -1)\n if [ -n \"$REUNION_CFG\" ] && [ ! -f /mnt/server/cstrike/reunion.cfg ]; then\n cp -f \"$REUNION_CFG\" /mnt/server/cstrike/reunion.cfg\n fi\n if [ -f /mnt/server/cstrike/reunion.cfg ]; then\n SALT=$(grep -o 'SteamIdHashSalt *= *[^ ]*' /mnt/server/cstrike/reunion.cfg | sed 's/.*= *//')\n if [ ${#SALT} -lt 16 ]; then\n NEW_SALT=$(head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \\n' | head -c 32)\n sed -i \"s/SteamIdHashSalt *=.*/SteamIdHashSalt = ${NEW_SALT}/\" /mnt/server/cstrike/reunion.cfg\n echo \" [OK] SteamIdHashSalt genere (${#NEW_SALT} chars)\"\n fi\n fi\n grep -q \"reunion\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/reunion/reunion_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] Reunion installe\"\n fi\n fi\n rm -rf /tmp/reunion /tmp/reunion.zip\nelse\n echo \" WARN: Impossible de telecharger Reunion\"\nfi\n\n##############################################\n# 8) PugMod-AMXX v4.0.8 (plugin AMXX competitif)\n##############################################\necho \"\"\necho \">>> [8/9] PugMod-AMXX v4.0.8...\"\n\n# Telecharger PugMod.zip depuis les releases GitHub\nPUG_URL=\"https://github.com/SmileYzn/PugMod-AMXX/releases/download/4.0.8/PugMod.zip\"\ncurl -fsSL -o /tmp/pugmod.zip \"$PUG_URL\"\n\nif [ -s /tmp/pugmod.zip ]; then\n unzip -qo /tmp/pugmod.zip -d /tmp/pugmod/\n\n # Copier les plugins .amxx precompiles\n PUG_PLUGINS=$(find /tmp/pugmod -name \"*.amxx\" -path \"*/plugins/*\" 2>/dev/null)\n if [ -n \"$PUG_PLUGINS\" ]; then\n echo \"$PUG_PLUGINS\" | while read -r f; do\n cp -f \"$f\" /mnt/server/cstrike/addons/amxmodx/plugins/\n done\n echo \" [OK] Plugins .amxx copies\"\n else\n echo \" [WARN] Aucun .amxx trouve dans PugMod.zip\"\n fi\n\n # Copier les configs pug/*.rc\n PUG_CFG_DIR=$(find /tmp/pugmod -type d -name \"pug\" -path \"*/configs/*\" | head -1)\n if [ -n \"$PUG_CFG_DIR\" ]; then\n mkdir -p /mnt/server/cstrike/addons/amxmodx/configs/pug\n cp -rf \"$PUG_CFG_DIR\"/* /mnt/server/cstrike/addons/amxmodx/configs/pug/\n echo \" [OK] Configs pug/*.rc copiees\"\n else\n echo \" [WARN] Dossier configs/pug/ non trouve\"\n fi\n\n # Copier les fichiers de langue\n PUG_LANG=$(find /tmp/pugmod -type d -name \"lang\" -path \"*/data/*\" | head -1)\n if [ -n \"$PUG_LANG\" ]; then\n mkdir -p /mnt/server/cstrike/addons/amxmodx/data/lang\n cp -rf \"$PUG_LANG\"/* /mnt/server/cstrike/addons/amxmodx/data/lang/\n echo \" [OK] Fichiers de langue copies\"\n fi\n\n # Copier les includes (pour compilation future)\n PUG_INC=$(find /tmp/pugmod -type d -name \"include\" -path \"*/scripting/*\" | head -1)\n if [ -n \"$PUG_INC\" ]; then\n cp -rf \"$PUG_INC\"/* /mnt/server/cstrike/addons/amxmodx/scripting/include/ 2>/dev/null || true\n fi\n\n echo \" [OK] PugMod-AMXX extrait\"\nelse\n echo \" [ERREUR] Telechargement PugMod-AMXX echoue\"\nfi\nrm -rf /tmp/pugmod /tmp/pugmod.zip\n\n# Enregistrer les plugins PugMod dans AMXX plugins.ini\nAMXX_PLUGINS=\"/mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\"\nfor plugin in PugFlood.amxx PugAdmin.amxx PugCore.amxx PugConfig.amxx PugReady.amxx PugMenus.amxx PugWarmup.amxx PugStats.amxx PugVote.amxx; do\n grep -q \"$plugin\" \"$AMXX_PLUGINS\" 2>/dev/null || echo \"$plugin\" >> \"$AMXX_PLUGINS\"\ndone\necho \" [OK] Plugins PugMod enregistres dans plugins.ini\"\n\n# Activer ReAPI dans modules.ini (requis par PugMod)\nAMXX_MODULES=\"/mnt/server/cstrike/addons/amxmodx/configs/modules.ini\"\nif grep -q \"^;reapi\" \"$AMXX_MODULES\" 2>/dev/null; then\n sed -i 's/^;reapi/reapi/' \"$AMXX_MODULES\"\n echo \" [OK] ReAPI active dans modules.ini\"\nfi\n\n# Personnaliser pugmod.rc pour WAR 5v5 MR15\nmkdir -p /mnt/server/cstrike/addons/amxmodx/configs/pug\ncat > /mnt/server/cstrike/addons/amxmodx/configs/pug/pugmod.rc << 'PUGRC'\n// PugMod-AMXX v4.0.8 - Configuration WAR 5v5 MR15\n// {{NOM_COMMUNAUTE}}Games.fr\n\n// Joueurs: 5v5 = 10 joueurs\npug_players_min \"10\"\npug_players_max \"10\"\n\n// Format MR15: 30 rounds (15 par mi-temps), premier a 16 gagne\npug_play_rounds \"30\"\n\n// Overtime: forcer OT, marge de 3 rounds\npug_play_overtime \"1\"\npug_play_overtime_rounds \"3\"\n\n// Best of X (0 = desactive)\npug_play_best_rounds \"0\"\n\n// Knife round pour choisir le cote\npug_play_knife_round \"1\"\n\n// Spectateurs et HLTV autorises\npug_allow_spec \"1\"\npug_allow_hltv \"1\"\n\n// Temps entre les phases (secondes)\npug_handle_time \"10.0\"\n\n// Ban si ragequit (minutes)\npug_drop_ban_time \"15\"\n\n// Forcer les joueurs a rejoindre une equipe\npug_force_join_team \"1\"\n\n// Ready system: les joueurs doivent taper .ready\npug_ready_type \"1\"\npug_ready_timer \"60.0\"\n\n// Vote de map active\npug_vote_map_enabled \"1\"\n\n// Selection equipes: vote (inclut knife round option)\npug_teams_enforcement \"-1\"\npug_teams_enforcement_menu \"123456\"\n\n// Stats fin de round\npug_stats_round_end \"1\"\npug_stats_scoreboard \"1\"\npug_stats_game_desc \"1\"\n\n// Votes: 70% requis\npug_vote_percent \"0.7\"\npug_vote_kick_ban_time \"30\"\npug_vote_timeout_time \"60\"\n\n// Fichiers de config par phase\npug_cfg_pugmod \"pugmod.rc\"\npug_cfg_warmup \"warmup.rc\"\npug_cfg_start \"start.rc\"\npug_cfg_1st \"esl.rc\"\npug_cfg_halftime \"halftime.rc\"\npug_cfg_2nd \"esl.rc\"\npug_cfg_overtime \"esl-ot.rc\"\npug_cfg_end \"end.rc\"\nPUGRC\necho \" [OK] pugmod.rc personnalise (MR15, 5v5, knife round)\"\n\n# Personnaliser esl.rc (config match live)\ncat > /mnt/server/cstrike/addons/amxmodx/configs/pug/esl.rc << 'ESLRC'\nmp_freezetime \"15\"\nmp_fadetoblack \"0\"\nmp_roundtime \"1.75\"\nmp_c4timer \"35\"\nmp_forcechasecam \"2\"\nmp_forcecamera \"2\"\nmp_startmoney \"800\"\nmp_buytime \".25\"\nmp_friendlyfire \"0\"\nmp_autoteambalance \"0\"\nmp_limitteams \"0\"\nmp_playerid \"0\"\nmp_flashlight \"1\"\nsv_alltalk \"0\"\n// ReGameDLL CS\nmp_round_infinite \"0\"\nmp_refill_bpammo_weapons \"0\"\nmp_infinite_ammo \"0\"\nmp_forcerespawn \"0\"\nmp_item_staytime \"300\"\nmp_respawn_immunitytime \"0\"\nmp_give_player_c4 \"1\"\nmp_show_scenarioicon \"1\"\nESLRC\n\n# Personnaliser esl-ot.rc (overtime = MR3 $10000)\ncat > /mnt/server/cstrike/addons/amxmodx/configs/pug/esl-ot.rc << 'OTRC'\nmp_freezetime \"15\"\nmp_fadetoblack \"0\"\nmp_roundtime \"1.75\"\nmp_c4timer \"35\"\nmp_forcechasecam \"2\"\nmp_forcecamera \"2\"\nmp_startmoney \"10000\"\nmp_buytime \".25\"\nmp_friendlyfire \"0\"\nmp_autoteambalance \"0\"\nmp_limitteams \"0\"\nmp_playerid \"0\"\nmp_flashlight \"1\"\nsv_alltalk \"0\"\nmp_round_infinite \"0\"\nmp_refill_bpammo_weapons \"0\"\nmp_infinite_ammo \"0\"\nmp_forcerespawn \"0\"\nmp_item_staytime \"300\"\nmp_respawn_immunitytime \"0\"\nmp_give_player_c4 \"1\"\nmp_show_scenarioicon \"1\"\nOTRC\n\n# Personnaliser warmup.rc\ncat > /mnt/server/cstrike/addons/amxmodx/configs/pug/warmup.rc << 'WARMRC'\nmp_freezetime \"0\"\nmp_startmoney \"16000\"\nmp_buytime \"99999\"\nsv_alltalk \"1\"\nmp_round_infinite \"acdefg\"\nmp_refill_bpammo_weapons \"3\"\nmp_infinite_ammo \"2\"\nmp_forcerespawn \"0.75\"\nmp_item_staytime \"0\"\nmp_respawn_immunitytime \"6\"\nmp_give_player_c4 \"0\"\nsv_restart \"1\"\nWARMRC\n\n# Maps pour le vote PugMod (maps competitives CS 1.6)\ncat > /mnt/server/cstrike/addons/amxmodx/configs/pug/maps.rc << 'MAPSRC'\nde_dust2\nde_inferno\nde_nuke\nde_train\nde_cbble\nMAPSRC\necho \" [OK] maps.rc genere (5 maps competitives)\"\n\n# Desactiver mapchooser et nextmap (PugMod gere les maps)\nsed -i 's/^mapchooser.amxx/;mapchooser.amxx/' /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null || true\nsed -i 's/^nextmap.amxx/;nextmap.amxx/' /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null || true\necho \" [OK] mapchooser.amxx et nextmap.amxx desactives (PugMod gere)\"\n\n# Supprimer MatchBot de Metamod plugins.ini (ancien plugin natif, incompatible Docker)\nsed -i '/matchbot/d' /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null || true\nrm -rf /mnt/server/cstrike/addons/matchbot 2>/dev/null || true\necho \" [OK] MatchBot supprime (remplace par PugMod-AMXX)\"\n\necho \" [OK] PugMod-AMXX v4.0.8 installe\"\n\n##############################################\n# 9) Resetscore + server.cfg\n##############################################\necho \"\"\necho \">>> [9/9] Resetscore + server.cfg...\"\n\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/resetscore.sma << 'RSSMA'\n/*\n * Resetscore - {{NOM_COMMUNAUTE}}Games.fr\n * /rs ou /resetscore pour remettre son score a zero.\n */\n#include <amxmodx>\n#include <cstrike>\n#include <fun>\n\npublic plugin_init()\n{\n register_plugin(\"Resetscore\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"say /rs\", \"cmd_reset\")\n register_clcmd(\"say /resetscore\", \"cmd_reset\")\n}\n\npublic cmd_reset(id)\n{\n cs_set_user_deaths(id, 0)\n set_user_frags(id, 0)\n client_print(id, print_chat, \"[Resetscore] Score remis a zero !\")\n return PLUGIN_HANDLED\n}\nRSSMA\n\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc resetscore.sma -o../plugins/resetscore.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/resetscore.amxx ]; then\n grep -q \"resetscore.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"resetscore.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] resetscore.amxx compile et installe\"\n else\n echo \" [WARN] Compilation resetscore echouee\"\n fi\nelse\n echo \" [WARN] amxxpc non trouve\"\nfi\n\n# Generer mapcycle.txt (maps competitives)\ncat > /mnt/server/cstrike/mapcycle.txt << 'MAPCYCLE'\nde_dust2\nde_inferno\nde_nuke\nde_train\nde_cbble\nMAPCYCLE\necho \" [OK] mapcycle.txt genere (5 maps competitives)\"\n\n##############################################\n# server.cfg WAR 5v5\n##############################################\necho \"\"\necho \">>> Generation de server.cfg...\"\ncat > /mnt/server/cstrike/server.cfg << 'SERVERCFG'\nhostname \"[FR] AUTOMIX 5v5 {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}\"\nsv_contact \"admin@{{DOMAINE_GAMING}}\"\nrcon_password \"changeme\"\n\n// Competitive settings\nmp_timelimit 0\nmp_freezetime 15\nmp_roundtime 1.75\nmp_buytime 0.25\nmp_c4timer 35\nmp_startmoney 800\nmp_autoteambalance 0\nmp_limitteams 0\nmp_friendlyfire 0\nmp_autokick 0\nmp_flashlight 1\nmp_forcecamera 2\nmp_forcechasecam 2\nmp_fadetoblack 0\nmp_playerid 1\n\n// ReGameDLL CS\nmp_forcerespawn 0\nmp_give_player_c4 1\nmp_infinite_ammo 0\nmp_item_staytime 300\nmp_round_infinite 0\nmp_refill_bpammo_weapons 0\nmp_respawn_immunitytime 0\nmp_show_radioicon 0\nmp_show_scenarioicon 1\n\n// Communication\nsv_allchat 1\nsv_alltalk 3\nsv_voiceenable 1\n\n// Rates serveur\nsv_maxrate 25000\nsv_minrate 6000\nsv_maxupdaterate 102\nsv_minupdaterate 30\n\n// Pas de download (maps standard)\nsv_allowdownload 1\nsv_allowupload 0\n\nexec banned.cfg\nexec listip.cfg\nSERVERCFG\n\n##############################################\n# Fix permissions\n##############################################\necho \"\"\necho \">>> Fix des permissions...\"\nchmod -R 755 /mnt/server/ 2>/dev/null || true\nchmod +x /mnt/server/hlds_linux /mnt/server/hlds_run /mnt/server/hlds_amd 2>/dev/null || true\nchmod +x /mnt/server/hltv 2>/dev/null || true\n\nSTEAM_SO=$(find /mnt/server -path \"*/linux32/steamclient.so\" -not -path \"*/.steam/*\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n mkdir -p /mnt/server/.steam/sdk32\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit re-copie\"\nfi\n\necho \"\"\necho \"=============================================\"\necho \" Installation terminee !\"\necho \" Stack : ReHLDS + ReGameDLL + Metamod-R\"\necho \" + AMX Mod X + ReAPI + Reunion\"\necho \" Match : PugMod-AMXX v4.0.8 (MR15 5v5)\"\necho \" Knife round + LO3 + Pause\"\necho \" Ready system + Overtime\"\necho \" Extras : Resetscore\"\necho \" Maps : de_dust2 de_inferno de_nuke\"\necho \" de_train de_cbble\"\necho \"=============================================\"\necho \"\"\necho \" Commandes joueurs:\"\necho \" .ready - Se mettre pret\"\necho \" .help - Aide\"\necho \" .dmg - Stats degats\"\necho \" .hp - Info HP\"\necho \" /rs - Reset score\"\necho \"\"\necho \" Le match demarre automatiquement\"\necho \" quand 10 joueurs sont connectes\"\necho \" et ont tape .ready\"\necho \"=============================================\"\n", "container": "ghcr.io/ptero-eggs/installers:debian", "entrypoint": "bash" } }, "variables": [ { "name": "Server Hostname", "description": "Nom du serveur affiché dans le navigateur de serveurs", "env_variable": "HOSTNAME", "default_value": "[FR] AUTOMIX 5v5 {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}", "user_viewable": true, "user_editable": true, "rules": "required|string|between:1,64", "field_type": "text" }, { "name": "Default Map", "description": "Map chargée au démarrage du serveur", "env_variable": "SRCDS_MAP", "default_value": "de_dust2", "user_viewable": true, "user_editable": true, "rules": "required|string", "field_type": "text" }, { "name": "Max Players", "description": "Nombre maximum de joueurs (10 joueurs + 2 spectateurs/HLTV)", "env_variable": "MAX_PLAYERS", "default_value": "12", "user_viewable": true, "user_editable": true, "rules": "required|integer|between:2,32", "field_type": "text" }, { "name": "Game Folder", "description": "Dossier du jeu (ne pas modifier)", "env_variable": "HLDS_GAME", "default_value": "cstrike", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" }, { "name": "Steam App ID", "description": "App ID Steam pour CS 1.6 (ne pas modifier)", "env_variable": "SRCDS_APPID", "default_value": "90", "user_viewable": false, "user_editable": false, "rules": "required|integer", "field_type": "text" } ] } |
CS 1.6 ReHLDS – Surf
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
{ "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-02-28T18:00:00+01:00", "name": "CS 1.6 ReHLDS - Surf", "author": "admin@{{DOMAINE_GAMING}}", "description": "Counter-Strike 1.6 Surf avec ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion. Plugins surf : uSurf (timer, checkpoints), surf_olympics (top times), Speedometer, Bunnyhop, No Fall Damage. 45+ maps depuis FastDL. Installation 100% automatique.", "features": null, "docker_images": { "ghcr.io/ptero-eggs/games:source": "ghcr.io/ptero-eggs/games:source" }, "file_denylist": [], "startup": "./hlds_run -console -game {{HLDS_GAME}} -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -norestart +maxplayers {{MAX_PLAYERS}} +pingboost 2 +sys_ticrate 1200 +hostname \"{{HOSTNAME}}\"", "config": { "files": "{}", "startup": "{\"done\": \"gameserver Steam\"}", "logs": "{}", "stop": "quit" }, "scripts": { "installation": { "script": "#!/bin/bash\ncd /mnt/server\n\napt-get update -qq && apt-get install -yqq unzip xz-utils wget > /dev/null 2>&1 || true\n\necho \"=============================================\"\necho \" CS 1.6 Surf - Installation automatique\"\necho \"=============================================\"\n\n##############################################\n# Helper: GitHub download URL (API + retry)\n##############################################\ngithub_get_url() {\n local repo=\"$1\" pattern=\"$2\" url=\"\"\n echo \" [INFO] Recherche: repo=${repo} pattern=${pattern}\" >&2\n for attempt in 1 2 3; do\n url=$(curl -sSL \"https://api.github.com/repos/${repo}/releases/latest\" \\\n | grep -o '\"browser_download_url\": *\"[^\"]*\"' \\\n | grep \"${pattern}\" | head -1 \\\n | sed 's/.*\"browser_download_url\": *\"//;s/\"$//')\n if [ -n \"$url\" ]; then\n echo \" [OK] URL trouvee: ${url}\" >&2\n echo \"$url\"\n return 0\n fi\n echo \" [WARN] API tentative ${attempt}/3 echouee, retry...\" >&2\n sleep 3\n done\n echo \" [ECHEC] Aucune URL trouvee pour ${repo}\" >&2\n return 1\n}\n\n##############################################\n# 1) SteamCMD + HLDS\n##############################################\necho \"\"\necho \">>> [1/10] SteamCMD + HLDS (App ID 90)...\"\nmkdir -p steamcmd\ncd steamcmd\nif [ ! -f steamcmd.sh ]; then\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz\nfi\ncd /mnt/server\n\n./steamcmd/steamcmd.sh +force_install_dir /mnt/server \\\n +login anonymous \\\n +app_update 90 -beta steam_legacy validate \\\n +quit\n\n# Steam SDK setup\nmkdir -p /mnt/server/.steam/sdk32\necho \"10\" > /mnt/server/steam_appid.txt\nSTEAM_SO=$(find /mnt/server/steamcmd -path \"*/linux32/steamclient.so\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit copie depuis $STEAM_SO\"\nelse\n echo \" [WARN] steamclient.so non trouve, telechargement direct...\"\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz -C /tmp/ linux32/steamclient.so 2>/dev/null\n if [ -f /tmp/linux32/steamclient.so ]; then\n cp -f /tmp/linux32/steamclient.so /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so telecharge\"\n fi\n rm -rf /tmp/linux32\nfi\n\n##############################################\n# 2) ReHLDS\n##############################################\necho \"\"\necho \">>> [2/10] ReHLDS...\"\nREHLDS_URL=$(github_get_url \"rehlds/ReHLDS\" \"rehlds-bin.*\\.zip\")\nif [ -n \"$REHLDS_URL\" ]; then\n echo \" URL: $REHLDS_URL\"\n curl -fsSL -o /tmp/rehlds.zip \"$REHLDS_URL\"\n if [ -s /tmp/rehlds.zip ]; then\n unzip -qo /tmp/rehlds.zip -d /tmp/rehlds/\n REHLDS_BIN=$(find /tmp/rehlds -name \"hlds_linux\" -type f | head -1)\n if [ -n \"$REHLDS_BIN\" ]; then\n REHLDS_DIR=$(dirname \"$REHLDS_BIN\")\n cp -rf \"$REHLDS_DIR\"/* /mnt/server/\n echo \" Binaires ReHLDS copies\"\n else\n echo \" WARN: hlds_linux non trouve dans l'archive\"\n fi\n else\n echo \" WARN: Telechargement echoue (fichier vide)\"\n fi\n rm -rf /tmp/rehlds /tmp/rehlds.zip\nelse\n echo \" WARN: URL ReHLDS non trouvee (GitHub API rate limit?)\"\nfi\nif strings /mnt/server/hlds_linux 2>/dev/null | grep -qi \"rehlds\"; then\n echo \" [OK] ReHLDS verifie\"\nelse\n echo \" [ERREUR] ReHLDS NON installe !\"\nfi\n\n##############################################\n# 3) ReGameDLL_CS\n##############################################\necho \"\"\necho \">>> [3/10] ReGameDLL_CS...\"\nREGAME_URL=$(github_get_url \"rehlds/ReGameDLL_CS\" \"\\.zip\")\nif [ -n \"$REGAME_URL\" ]; then\n echo \" URL: $REGAME_URL\"\n curl -fsSL -o /tmp/regamedll.zip \"$REGAME_URL\"\n if [ -s /tmp/regamedll.zip ]; then\n unzip -qo /tmp/regamedll.zip -d /tmp/regamedll/\n CSSO=$(find /tmp/regamedll -name \"cs.so\" -path \"*linux32*\" | head -1)\n [ -n \"$CSSO\" ] && cp -f \"$CSSO\" /mnt/server/cstrike/dlls/cs.so\n EXTRAS=$(find /tmp/regamedll -type d -name \"gamedir\" | head -1)\n [ -n \"$EXTRAS\" ] && cp -rn \"$EXTRAS\"/* /mnt/server/cstrike/ 2>/dev/null || true\n echo \" [OK] ReGameDLL installe\"\n fi\n rm -rf /tmp/regamedll /tmp/regamedll.zip\nelse\n echo \" WARN: Impossible de telecharger ReGameDLL_CS\"\nfi\n\n##############################################\n# 4) Metamod-R\n##############################################\necho \"\"\necho \">>> [4/10] Metamod-R...\"\nMETAMOD_URL=$(github_get_url \"rehlds/metamod-r\" \"\\.zip\")\nif [ -n \"$METAMOD_URL\" ]; then\n echo \" URL: $METAMOD_URL\"\n curl -fsSL -o /tmp/metamod.zip \"$METAMOD_URL\"\n if [ -s /tmp/metamod.zip ]; then\n unzip -qo /tmp/metamod.zip -d /tmp/metamod/\n mkdir -p /mnt/server/cstrike/addons/metamod\n META_DLL=$(find /tmp/metamod -name \"metamod_i386.so\" | head -1)\n [ -n \"$META_DLL\" ] && cp -f \"$META_DLL\" /mnt/server/cstrike/addons/metamod/\n echo \" [OK] Metamod-R installe\"\n fi\n rm -rf /tmp/metamod /tmp/metamod.zip\nelse\n echo \" WARN: Impossible de telecharger Metamod-R\"\nfi\n\nif [ -f /mnt/server/cstrike/addons/metamod/metamod_i386.so ]; then\n GAMEDLL_LINUX=\"addons/metamod/metamod_i386.so\"\n echo \" [OK] liblist.gam -> Metamod\"\n [ -f /mnt/server/cstrike/addons/metamod/plugins.ini ] \\\n || echo \"; Metamod plugins\" > /mnt/server/cstrike/addons/metamod/plugins.ini\nelse\n GAMEDLL_LINUX=\"dlls/cs.so\"\n echo \" [WARN] liblist.gam -> cs.so direct (Metamod absent)\"\nfi\ncat > /mnt/server/cstrike/liblist.gam << LIBLIST\ngame \"Counter-Strike\"\nurl_info \"www.counter-strike.net\"\nurl_dl \"\"\nversion \"1.6\"\nsize \"184000000\"\nsvonly \"0\"\ncldll \"1\"\nsecure \"1\"\nhlversion \"1110\"\nnomodels \"1\"\nnohimodel \"1\"\nmpentity \"info_player_start\"\ngamedll \"dlls\\cs.dll\"\ngamedll_linux \"${GAMEDLL_LINUX}\"\ngamedll_osx \"dlls/cs.dylib\"\ntype \"multiplayer_only\"\nLIBLIST\n\n##############################################\n# 5) AMX Mod X\n##############################################\necho \"\"\necho \">>> [5/10] AMX Mod X...\"\nAMXX_DROP=\"https://www.amxmodx.org/amxxdrop/1.10\"\ncurl -fsSL -o /tmp/amxmodx-base.tar.gz \"${AMXX_DROP}/amxmodx-latest-base-linux.tar.gz\"\ncurl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"${AMXX_DROP}/amxmodx-latest-cstrike-linux.tar.gz\"\ncd /mnt/server/cstrike\nif tar tzf /tmp/amxmodx-base.tar.gz > /dev/null 2>&1; then\n tar xzf /tmp/amxmodx-base.tar.gz\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.10 installe\"\nelse\n echo \" [WARN] 1.10 echoue, fallback 1.8.2 stable...\"\n curl -fsSL -o /tmp/amxmodx-base.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-base-linux.tar.gz\"\n curl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-cstrike-linux.tar.gz\"\n tar xzf /tmp/amxmodx-base.tar.gz 2>/dev/null || true\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.8.2 installe\"\nfi\nrm -f /tmp/amxmodx-base.tar.gz /tmp/amxmodx-cstrike.tar.gz\nif [ -f /mnt/server/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so ]; then\n echo \" [OK] amxmodx_mm_i386.so verifie\"\nelse\n echo \" [ERREUR] amxmodx_mm_i386.so MANQUANT !\"\nfi\ngrep -q \"amxmodx\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/amxmodx/dlls/amxmodx_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\ncd /mnt/server\n\n##############################################\n# 6) ReAPI\n##############################################\necho \"\"\necho \">>> [6/10] ReAPI...\"\nREAPI_URL=$(github_get_url \"rehlds/ReAPI\" \"\\.zip\")\nif [ -n \"$REAPI_URL\" ]; then\n curl -fsSL -o /tmp/reapi.zip \"$REAPI_URL\"\n if [ -s /tmp/reapi.zip ]; then\n unzip -qo /tmp/reapi.zip -d /tmp/reapi/\n REAPI_SO=$(find /tmp/reapi -name \"reapi_amxx_i386.so\" | head -1)\n [ -n \"$REAPI_SO\" ] && cp -f \"$REAPI_SO\" /mnt/server/cstrike/addons/amxmodx/modules/\n REAPI_INC=$(find /tmp/reapi -type d -name \"include\" -path \"*/scripting/*\" | head -1)\n if [ -n \"$REAPI_INC\" ]; then\n cp -rf \"$REAPI_INC\"/* /mnt/server/cstrike/addons/amxmodx/scripting/include/ 2>/dev/null || true\n fi\n grep -q \"reapi_amxx_i386.so\" /mnt/server/cstrike/addons/amxmodx/configs/modules.ini 2>/dev/null \\\n || echo \"reapi_amxx_i386.so\" >> /mnt/server/cstrike/addons/amxmodx/configs/modules.ini\n echo \" [OK] ReAPI installe\"\n fi\n rm -rf /tmp/reapi /tmp/reapi.zip\nelse\n echo \" WARN: Impossible de telecharger ReAPI\"\nfi\n\n##############################################\n# 7) Reunion\n##############################################\necho \"\"\necho \">>> [7/10] Reunion...\"\nREUNION_URL=$(github_get_url \"rehlds/ReUnion\" \"\\.zip\")\nif [ -n \"$REUNION_URL\" ]; then\n curl -fsSL -o /tmp/reunion.zip \"$REUNION_URL\"\n if [ -s /tmp/reunion.zip ]; then\n unzip -qo /tmp/reunion.zip -d /tmp/reunion/\n REUNION_SO=$(find /tmp/reunion -name \"reunion_mm_i386.so\" | head -1)\n if [ -n \"$REUNION_SO\" ]; then\n mkdir -p /mnt/server/cstrike/addons/reunion\n cp -f \"$REUNION_SO\" /mnt/server/cstrike/addons/reunion/\n REUNION_CFG=$(find /tmp/reunion -name \"reunion.cfg\" | head -1)\n if [ -n \"$REUNION_CFG\" ] && [ ! -f /mnt/server/cstrike/reunion.cfg ]; then\n cp -f \"$REUNION_CFG\" /mnt/server/cstrike/reunion.cfg\n fi\n if [ -f /mnt/server/cstrike/reunion.cfg ]; then\n SALT=$(grep -o 'SteamIdHashSalt *= *[^ ]*' /mnt/server/cstrike/reunion.cfg | sed 's/.*= *//')\n if [ ${#SALT} -lt 16 ]; then\n NEW_SALT=$(head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \\n' | head -c 32)\n sed -i \"s/SteamIdHashSalt *=.*/SteamIdHashSalt = ${NEW_SALT}/\" /mnt/server/cstrike/reunion.cfg\n echo \" [OK] SteamIdHashSalt genere (${#NEW_SALT} chars)\"\n fi\n fi\n grep -q \"reunion\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/reunion/reunion_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] Reunion installe\"\n fi\n fi\n rm -rf /tmp/reunion /tmp/reunion.zip\nelse\n echo \" WARN: Impossible de telecharger Reunion\"\nfi\n\n##############################################\n# 8) Plugins Surf (compilation depuis source)\n##############################################\necho \"\"\necho \">>> [8/10] Plugins Surf...\"\n\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nSCRIPTING=\"/mnt/server/cstrike/addons/amxmodx/scripting\"\nPLUGINS=\"/mnt/server/cstrike/addons/amxmodx/plugins\"\nAMXX_PLUGINS=\"/mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\"\n\n# Activer les modules requis (fakemeta, engine, nvault)\nAMXX_MODULES=\"/mnt/server/cstrike/addons/amxmodx/configs/modules.ini\"\nfor mod in fakemeta engine nvault; do\n if grep -q \"^;${mod}\" \"$AMXX_MODULES\" 2>/dev/null; then\n sed -i \"s/^;${mod}/${mod}/\" \"$AMXX_MODULES\"\n echo \" [OK] Module ${mod} active\"\n fi\ndone\n\nchmod +x \"$AMXXPC\" 2>/dev/null || true\n\n# --- uSurf (timer, checkpoints, respawn, semiclip, bhop) ---\necho \" Compilation uSurf...\"\ncurl -fsSL -o \"$SCRIPTING/usurf.sma\" \\\n \"https://raw.githubusercontent.com/DouglasSherk/AMXModX/master/usurf.sma\" 2>/dev/null\n\nif [ -f \"$SCRIPTING/usurf.sma\" ]; then\n cd \"$SCRIPTING\"\n ./amxxpc usurf.sma -o\"../plugins/usurf.amxx\" 2>&1 || true\n cd /mnt/server\n if [ -f \"$PLUGINS/usurf.amxx\" ]; then\n grep -q \"usurf.amxx\" \"$AMXX_PLUGINS\" 2>/dev/null || echo \"usurf.amxx\" >> \"$AMXX_PLUGINS\"\n echo \" [OK] uSurf compile et installe\"\n else\n echo \" [WARN] Compilation uSurf echouee\"\n fi\nelse\n echo \" [WARN] Telechargement uSurf echoue\"\nfi\n\n# --- surf_olympics (top times, records par map, nVault) ---\necho \" Compilation surf_olympics...\"\ncurl -fsSL -o \"$SCRIPTING/surf_olympics.sma\" \\\n \"https://raw.githubusercontent.com/evandrocoan/MultiModServer/master/plugins/addons/amxmodx/scripting/surf_olympics.sma\" 2>/dev/null\n\nif [ -f \"$SCRIPTING/surf_olympics.sma\" ]; then\n cd \"$SCRIPTING\"\n ./amxxpc surf_olympics.sma -o\"../plugins/surf_olympics.amxx\" 2>&1 || true\n cd /mnt/server\n if [ -f \"$PLUGINS/surf_olympics.amxx\" ]; then\n grep -q \"surf_olympics.amxx\" \"$AMXX_PLUGINS\" 2>/dev/null || echo \"surf_olympics.amxx\" >> \"$AMXX_PLUGINS\"\n echo \" [OK] surf_olympics compile et installe\"\n else\n echo \" [WARN] Compilation surf_olympics echouee\"\n fi\nelse\n echo \" [WARN] Telechargement surf_olympics echoue\"\nfi\n\n# --- Speedometer (affichage vitesse HUD) ---\necho \" Creation speedometer...\"\ncat > \"$SCRIPTING/speedometer.sma\" << 'SPEEDSMA'\n#include <amxmodx>\n#include <engine>\n\n#define TASK_SPEED 5000\n\nnew bool:g_showSpeed[33]\n\npublic plugin_init()\n{\n register_plugin(\"Speedometer\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"say /speed\", \"cmd_speed\")\n register_clcmd(\"say .speed\", \"cmd_speed\")\n}\n\npublic client_putinserver(id)\n{\n g_showSpeed[id] = true\n set_task(0.1, \"task_show_speed\", id + TASK_SPEED, .flags=\"b\")\n}\n\npublic client_disconnected(id)\n{\n g_showSpeed[id] = false\n remove_task(id + TASK_SPEED)\n}\n\npublic cmd_speed(id)\n{\n g_showSpeed[id] = !g_showSpeed[id]\n client_print(id, print_chat, \"[Speed] Speedometer %s\", g_showSpeed[id] ? \"ON\" : \"OFF\")\n return PLUGIN_HANDLED\n}\n\npublic task_show_speed(taskid)\n{\n new id = taskid - TASK_SPEED\n if (!is_user_alive(id) || !g_showSpeed[id]) return\n\n new Float:vel[3]\n entity_get_vector(id, EV_VEC_velocity, vel)\n new Float:speed = floatsqroot(vel[0] * vel[0] + vel[1] * vel[1])\n\n set_hudmessage(0, 255, 0, -1.0, 0.85, 0, 0.0, 0.2, 0.0, 0.0, 4)\n show_hudmessage(id, \"Speed: %.0f u/s\", speed)\n}\nSPEEDSMA\n\ncd \"$SCRIPTING\"\n./amxxpc speedometer.sma -o\"../plugins/speedometer.amxx\" 2>&1 || true\ncd /mnt/server\nif [ -f \"$PLUGINS/speedometer.amxx\" ]; then\n grep -q \"speedometer.amxx\" \"$AMXX_PLUGINS\" 2>/dev/null || echo \"speedometer.amxx\" >> \"$AMXX_PLUGINS\"\n echo \" [OK] Speedometer compile et installe\"\nelse\n echo \" [WARN] Compilation speedometer echouee\"\nfi\n\n# --- No Fall Damage ---\necho \" Creation no_fall_damage...\"\ncat > \"$SCRIPTING/no_fall_damage.sma\" << 'NFDSMA'\n#include <amxmodx>\n#include <hamsandwich>\n\npublic plugin_init()\n{\n register_plugin(\"No Fall Damage\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n RegisterHam(Ham_TakeDamage, \"player\", \"fw_TakeDamage\")\n}\n\npublic fw_TakeDamage(victim, inflictor, attacker, Float:damage, damagetype)\n{\n if (damagetype & DMG_FALL)\n return HAM_SUPERCEDE\n return HAM_IGNORED\n}\nNFDSMA\n\ncd \"$SCRIPTING\"\n./amxxpc no_fall_damage.sma -o\"../plugins/no_fall_damage.amxx\" 2>&1 || true\ncd /mnt/server\nif [ -f \"$PLUGINS/no_fall_damage.amxx\" ]; then\n grep -q \"no_fall_damage.amxx\" \"$AMXX_PLUGINS\" 2>/dev/null || echo \"no_fall_damage.amxx\" >> \"$AMXX_PLUGINS\"\n echo \" [OK] no_fall_damage compile et installe\"\nelse\n echo \" [WARN] Compilation no_fall_damage echouee\"\nfi\n\n# --- Bunnyhop ---\necho \" Creation bunnyhop...\"\ncat > \"$SCRIPTING/bunnyhop.sma\" << 'BHSMA'\n#include <amxmodx>\n#include <fakemeta>\n\npublic plugin_init()\n{\n register_plugin(\"Bunnyhop\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlayerPreThink, \"fw_PlayerPreThink\")\n}\n\npublic fw_PlayerPreThink(id)\n{\n if (!is_user_alive(id)) return FMRES_IGNORED\n\n new flags = pev(id, pev_flags)\n new buttons = pev(id, pev_button)\n\n if (buttons & IN_JUMP && !(flags & FL_ONGROUND))\n set_pev(id, pev_button, buttons & ~IN_JUMP)\n\n return FMRES_IGNORED\n}\nBHSMA\n\ncd \"$SCRIPTING\"\n./amxxpc bunnyhop.sma -o\"../plugins/bunnyhop.amxx\" 2>&1 || true\ncd /mnt/server\nif [ -f \"$PLUGINS/bunnyhop.amxx\" ]; then\n grep -q \"bunnyhop.amxx\" \"$AMXX_PLUGINS\" 2>/dev/null || echo \"bunnyhop.amxx\" >> \"$AMXX_PLUGINS\"\n echo \" [OK] Bunnyhop compile et installe\"\nelse\n echo \" [WARN] Compilation bunnyhop echouee\"\nfi\n\n# --- Resetscore ---\necho \" Creation resetscore...\"\ncat > \"$SCRIPTING/resetscore.sma\" << 'RSSMA'\n#include <amxmodx>\n#include <cstrike>\n#include <fun>\n\npublic plugin_init()\n{\n register_plugin(\"Resetscore\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"say /rs\", \"cmd_reset\")\n register_clcmd(\"say /resetscore\", \"cmd_reset\")\n}\n\npublic cmd_reset(id)\n{\n cs_set_user_deaths(id, 0)\n set_user_frags(id, 0)\n client_print(id, print_chat, \"[Resetscore] Score remis a zero !\")\n return PLUGIN_HANDLED\n}\nRSSMA\n\ncd \"$SCRIPTING\"\n./amxxpc resetscore.sma -o\"../plugins/resetscore.amxx\" 2>&1 || true\ncd /mnt/server\nif [ -f \"$PLUGINS/resetscore.amxx\" ]; then\n grep -q \"resetscore.amxx\" \"$AMXX_PLUGINS\" 2>/dev/null || echo \"resetscore.amxx\" >> \"$AMXX_PLUGINS\"\n echo \" [OK] Resetscore compile et installe\"\nelse\n echo \" [WARN] Compilation resetscore echouee\"\nfi\n\n# Desactiver les plugins inutiles pour le surf\nsed -i 's/^mapchooser.amxx/;mapchooser.amxx/' \"$AMXX_PLUGINS\" 2>/dev/null || true\nsed -i 's/^nextmap.amxx/;nextmap.amxx/' \"$AMXX_PLUGINS\" 2>/dev/null || true\necho \" [OK] mapchooser et nextmap desactives\"\n\necho \" [OK] Plugins surf installes\"\n\n##############################################\n# 9) Maps depuis FastDL\n##############################################\necho \"\"\necho \">>> [9/10] Telechargement des maps depuis FastDL...\"\nFASTDL_URL=\"https://fastdl.{{DOMAINE_GAMING}}/cs_surf\"\nwget -r -np -nH --cut-dirs=1 -P /mnt/server/cstrike/ \\\n -R \"index.html*\" \\\n --no-check-certificate \\\n -q --show-progress \\\n \"$FASTDL_URL/\" 2>&1 || echo \" [WARN] wget a rencontre des erreurs (certains fichiers peuvent manquer)\"\n\nMAP_COUNT=$(find /mnt/server/cstrike/maps -name \"surf_*.bsp\" 2>/dev/null | wc -l)\necho \" [OK] ${MAP_COUNT} maps surf telechargees\"\n\n# Generer mapcycle.txt (seulement les maps surf)\necho \">>> Generation de mapcycle.txt...\"\nfind /mnt/server/cstrike/maps -name \"surf_*.bsp\" -printf \"%f\\n\" 2>/dev/null \\\n | sed 's/\\.bsp$//' | sort > /mnt/server/cstrike/mapcycle.txt\n# Ajouter Surf_Ski_5_final (majuscule)\nfind /mnt/server/cstrike/maps -name \"Surf_*.bsp\" -printf \"%f\\n\" 2>/dev/null \\\n | sed 's/\\.bsp$//' | sort >> /mnt/server/cstrike/mapcycle.txt\necho \" [OK] mapcycle.txt genere ($(wc -l < /mnt/server/cstrike/mapcycle.txt) maps)\"\n\n##############################################\n# 10) server.cfg Surf\n##############################################\necho \"\"\necho \">>> [10/10] server.cfg...\"\ncat > /mnt/server/cstrike/server.cfg << 'SERVERCFG'\nhostname \"[FR] Surf #{{NOM_COMMUNAUTE}}\"\nsv_contact \"admin@{{DOMAINE_GAMING}}\"\nrcon_password \"changeme\"\n\n// Surf movement - CRITICAL\nsv_airaccelerate 150\nsv_accelerate 10\nsv_friction 4\nsv_gravity 800\nsv_maxspeed 320\n\n// Round timing (rounds longs pour surf)\nmp_roundtime 9\nmp_timelimit 30\nmp_freezetime 0\nmp_round_restart_delay 1\n\n// Pas de degats de chute (backup si plugin echoue)\nmp_falldamage 0\n\n// Equipes\nmp_friendlyfire 0\nmp_autoteambalance 0\nmp_limitteams 0\nmp_forcecamera 0\nmp_forcechasecam 0\n\n// Pas de bombe\nmp_give_player_c4 0\n\n// Pas de buytime\nmp_buytime 0\nmp_startmoney 0\n\n// Communication\nsv_alltalk 1\nsv_voiceenable 1\n\n// Respawn infini (les joueurs respawnent a la mort)\nmp_round_infinite 1\nmp_forcerespawn 3\n\n// Rates serveur\nsv_maxrate 25000\nsv_minrate 6000\nsv_maxupdaterate 102\nsv_minupdaterate 30\n\n// Downloads + FastDL\nsv_allowdownload 1\nsv_allowupload 0\nsv_downloadurl \"https://fastdl.{{DOMAINE_GAMING}}/cs_surf\"\n\nexec banned.cfg\nexec listip.cfg\nSERVERCFG\n\n##############################################\n# Fix permissions\n##############################################\necho \"\"\necho \">>> Fix des permissions...\"\nchmod -R 755 /mnt/server/ 2>/dev/null || true\nchmod +x /mnt/server/hlds_linux /mnt/server/hlds_run /mnt/server/hlds_amd 2>/dev/null || true\nchmod +x /mnt/server/hltv 2>/dev/null || true\n\nSTEAM_SO=$(find /mnt/server -path \"*/linux32/steamclient.so\" -not -path \"*/.steam/*\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n mkdir -p /mnt/server/.steam/sdk32\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit re-copie\"\nfi\n\necho \"\"\necho \"=============================================\"\necho \" Installation terminee !\"\necho \" Stack : ReHLDS + ReGameDLL + Metamod-R\"\necho \" + AMX Mod X + ReAPI + Reunion\"\necho \" Surf : uSurf (timer, checkpoints)\"\necho \" surf_olympics (top times)\"\necho \" Speedometer + Bunnyhop\"\necho \" No Fall Damage + Resetscore\"\necho \" Config : sv_airaccelerate 150\"\necho \" Maps : ${MAP_COUNT} maps surf\"\necho \"=============================================\"\necho \"\"\necho \" Commandes joueurs:\"\necho \" /checkpoint - Sauvegarder position\"\necho \" /gocheck - Teleporter au checkpoint\"\necho \" /timer - Menu timer\"\necho \" /speed - Toggle speedometer\"\necho \" /top3 - Top 3 records\"\necho \" /rs - Reset score\"\necho \" /surfhelp - Aide surf\"\necho \"=============================================\"\n", "container": "ghcr.io/ptero-eggs/installers:debian", "entrypoint": "bash" } }, "variables": [ { "name": "Server Hostname", "description": "Nom du serveur affiché dans le navigateur de serveurs", "env_variable": "HOSTNAME", "default_value": "[FR] Surf #{{NOM_COMMUNAUTE}}", "user_viewable": true, "user_editable": true, "rules": "required|string|between:1,64", "field_type": "text" }, { "name": "Default Map", "description": "Map chargée au démarrage du serveur", "env_variable": "SRCDS_MAP", "default_value": "surf_ski_2", "user_viewable": true, "user_editable": true, "rules": "required|string", "field_type": "text" }, { "name": "Max Players", "description": "Nombre maximum de joueurs", "env_variable": "MAX_PLAYERS", "default_value": "32", "user_viewable": true, "user_editable": true, "rules": "required|integer|between:2,32", "field_type": "text" }, { "name": "Game Folder", "description": "Dossier du jeu (ne pas modifier)", "env_variable": "HLDS_GAME", "default_value": "cstrike", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" }, { "name": "Steam App ID", "description": "App ID Steam pour CS 1.6 (ne pas modifier)", "env_variable": "SRCDS_APPID", "default_value": "90", "user_viewable": false, "user_editable": false, "rules": "required|integer", "field_type": "text" } ] } |
CS 1.6 ReHLDS – Paintball
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
{ "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-03-01T12:00:00+01:00", "name": "CS 1.6 ReHLDS - Paintball", "author": "admin@{{DOMAINE_GAMING}}", "description": "Counter-Strike 1.6 Paintball avec ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion. Plugins : PaintBall Refresh (9 armes custom, sprint, vendetta, elimination/respawn), YaPB bots, BotManager v2, Double Jump, Parachute, Advanced Quake Sounds. Maps depuis FastDL. Installation 100% automatique.", "features": null, "docker_images": { "ghcr.io/ptero-eggs/games:source": "ghcr.io/ptero-eggs/games:source" }, "file_denylist": [], "startup": "chmod -R 777 cstrike/addons/yapb/data/ 2>/dev/null; ./hlds_run -console -game {{HLDS_GAME}} -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -norestart +maxplayers {{MAX_PLAYERS}} +pingboost 2 +sys_ticrate 1200 +hostname \"{{HOSTNAME}}\"", "config": { "files": "{}", "startup": "{\"done\": \"gameserver Steam\"}", "logs": "{}", "stop": "quit" }, "variables": [ { "name": "Server Hostname", "description": "Nom du serveur affiché dans le navigateur de serveurs", "env_variable": "HOSTNAME", "default_value": "[FR] PAINTBALL {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}", "user_viewable": true, "user_editable": true, "rules": "required|string|between:1,64", "field_type": "text" }, { "name": "Default Map", "description": "Map chargée au démarrage du serveur", "env_variable": "SRCDS_MAP", "default_value": "aim_map", "user_viewable": true, "user_editable": true, "rules": "required|string", "field_type": "text" }, { "name": "Max Players", "description": "Nombre maximum de joueurs", "env_variable": "MAX_PLAYERS", "default_value": "32", "user_viewable": true, "user_editable": true, "rules": "required|integer|between:2,32", "field_type": "text" }, { "name": "Game Folder", "description": "Dossier du jeu (ne pas modifier)", "env_variable": "HLDS_GAME", "default_value": "cstrike", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" }, { "name": "Steam App ID", "description": "App ID Steam pour CS 1.6 (ne pas modifier)", "env_variable": "SRCDS_APPID", "default_value": "90", "user_viewable": false, "user_editable": false, "rules": "required|integer", "field_type": "text" } ], "scripts": { "installation": { "script": "#!/bin/bash\ncd /mnt/server\n\napt-get update -qq && apt-get install -yqq unzip xz-utils wget > /dev/null 2>&1 || true\n\necho \"=============================================\"\necho \" CS 1.6 Paintball - Installation automatique\"\necho \"=============================================\"\n\n##############################################\n# Helper: GitHub download URL\n##############################################\ngithub_get_url() {\n local repo=\"$1\" pattern=\"$2\" url=\"\"\n echo \" [INFO] Recherche: repo=${repo} pattern=${pattern}\" >&2\n for attempt in 1 2 3; do\n url=$(curl -sSL \"https://api.github.com/repos/${repo}/releases/latest\" \\\n | grep -o '\"browser_download_url\": *\"[^\"]*\"' \\\n | grep \"${pattern}\" | head -1 \\\n | sed 's/.*\"browser_download_url\": *\"//;s/\"$//')\n if [ -n \"$url\" ]; then\n echo \" [OK] URL trouvee: ${url}\" >&2\n echo \"$url\"\n return 0\n fi\n echo \" [WARN] API tentative ${attempt}/3 echouee, retry...\" >&2\n sleep 3\n done\n echo \" [ECHEC] Aucune URL trouvee pour ${repo}\" >&2\n return 1\n}\n\n##############################################\n# 1) SteamCMD + HLDS\n##############################################\necho \"\"\necho \">>> [1/15] SteamCMD + HLDS (App ID 90)...\"\nmkdir -p steamcmd\ncd steamcmd\nif [ ! -f steamcmd.sh ]; then\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz\nfi\ncd /mnt/server\n\n./steamcmd/steamcmd.sh +force_install_dir /mnt/server \\\n +login anonymous \\\n +app_update 90 -beta steam_legacy validate \\\n +quit\n\nmkdir -p /mnt/server/.steam/sdk32\necho \"10\" > /mnt/server/steam_appid.txt\nSTEAM_SO=$(find /mnt/server/steamcmd -path \"*/linux32/steamclient.so\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so 32-bit copie depuis $STEAM_SO\"\nelse\n echo \" [WARN] steamclient.so non trouve, telechargement direct...\"\n curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz -C /tmp/ linux32/steamclient.so 2>/dev/null\n if [ -f /tmp/linux32/steamclient.so ]; then\n cp -f /tmp/linux32/steamclient.so /mnt/server/.steam/sdk32/\n echo \" [OK] steamclient.so telecharge\"\n fi\n rm -rf /tmp/linux32\nfi\n\n##############################################\n# 2) ReHLDS\n##############################################\necho \"\"\necho \">>> [2/15] ReHLDS...\"\nREHLDS_URL=$(github_get_url \"rehlds/ReHLDS\" \"rehlds-bin.*\\.zip\")\nif [ -n \"$REHLDS_URL\" ]; then\n curl -fsSL -o /tmp/rehlds.zip \"$REHLDS_URL\"\n if [ -s /tmp/rehlds.zip ]; then\n unzip -qo /tmp/rehlds.zip -d /tmp/rehlds/\n REHLDS_BIN=$(find /tmp/rehlds -name \"hlds_linux\" -type f | head -1)\n if [ -n \"$REHLDS_BIN\" ]; then\n REHLDS_DIR=$(dirname \"$REHLDS_BIN\")\n cp -rf \"$REHLDS_DIR\"/* /mnt/server/\n fi\n fi\n rm -rf /tmp/rehlds /tmp/rehlds.zip\nfi\nif strings /mnt/server/hlds_linux 2>/dev/null | grep -qi \"rehlds\"; then\n echo \" [OK] ReHLDS verifie\"\nelse\n echo \" [ERREUR] ReHLDS NON installe !\"\nfi\n\n##############################################\n# 3) ReGameDLL_CS\n##############################################\necho \"\"\necho \">>> [3/15] ReGameDLL_CS...\"\nREGAME_URL=$(github_get_url \"rehlds/ReGameDLL_CS\" \"\\.zip\")\nif [ -n \"$REGAME_URL\" ]; then\n curl -fsSL -o /tmp/regamedll.zip \"$REGAME_URL\"\n if [ -s /tmp/regamedll.zip ]; then\n unzip -qo /tmp/regamedll.zip -d /tmp/regamedll/\n CSSO=$(find /tmp/regamedll -name \"cs.so\" -path \"*linux32*\" | head -1)\n [ -n \"$CSSO\" ] && cp -f \"$CSSO\" /mnt/server/cstrike/dlls/cs.so\n EXTRAS=$(find /tmp/regamedll -type d -name \"gamedir\" | head -1)\n [ -n \"$EXTRAS\" ] && cp -rn \"$EXTRAS\"/* /mnt/server/cstrike/ 2>/dev/null || true\n echo \" [OK] ReGameDLL installe\"\n fi\n rm -rf /tmp/regamedll /tmp/regamedll.zip\nfi\n\n##############################################\n# 4) Metamod-R\n##############################################\necho \"\"\necho \">>> [4/15] Metamod-R...\"\nMETAMOD_URL=$(github_get_url \"rehlds/metamod-r\" \"\\.zip\")\nif [ -n \"$METAMOD_URL\" ]; then\n curl -fsSL -o /tmp/metamod.zip \"$METAMOD_URL\"\n if [ -s /tmp/metamod.zip ]; then\n unzip -qo /tmp/metamod.zip -d /tmp/metamod/\n mkdir -p /mnt/server/cstrike/addons/metamod\n META_DLL=$(find /tmp/metamod -name \"metamod_i386.so\" | head -1)\n [ -n \"$META_DLL\" ] && cp -f \"$META_DLL\" /mnt/server/cstrike/addons/metamod/\n echo \" [OK] Metamod-R installe\"\n fi\n rm -rf /tmp/metamod /tmp/metamod.zip\nfi\n\nif [ -f /mnt/server/cstrike/addons/metamod/metamod_i386.so ]; then\n GAMEDLL_LINUX=\"addons/metamod/metamod_i386.so\"\n [ -f /mnt/server/cstrike/addons/metamod/plugins.ini ] \\\n || echo \"; Metamod plugins\" > /mnt/server/cstrike/addons/metamod/plugins.ini\nelse\n GAMEDLL_LINUX=\"dlls/cs.so\"\nfi\ncat > /mnt/server/cstrike/liblist.gam << LIBLIST\ngame \"Counter-Strike\"\nurl_info \"www.counter-strike.net\"\nurl_dl \"\"\nversion \"1.6\"\nsize \"184000000\"\nsvonly \"0\"\ncldll \"1\"\nsecure \"1\"\nhlversion \"1110\"\nnomodels \"1\"\nnohimodel \"1\"\nmpentity \"info_player_start\"\ngamedll \"dlls\\cs.dll\"\ngamedll_linux \"${GAMEDLL_LINUX}\"\ngamedll_osx \"dlls/cs.dylib\"\ntype \"multiplayer_only\"\nLIBLIST\n\n##############################################\n# 5) AMX Mod X\n##############################################\necho \"\"\necho \">>> [5/15] AMX Mod X...\"\nAMXX_DROP=\"https://www.amxmodx.org/amxxdrop/1.10\"\ncurl -fsSL -o /tmp/amxmodx-base.tar.gz \"${AMXX_DROP}/amxmodx-latest-base-linux.tar.gz\"\ncurl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"${AMXX_DROP}/amxmodx-latest-cstrike-linux.tar.gz\"\ncd /mnt/server/cstrike\nif tar tzf /tmp/amxmodx-base.tar.gz > /dev/null 2>&1; then\n tar xzf /tmp/amxmodx-base.tar.gz\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.10 installe\"\nelse\n echo \" [WARN] 1.10 echoue, fallback 1.8.2...\"\n curl -fsSL -o /tmp/amxmodx-base.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-base-linux.tar.gz\"\n curl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"https://www.amxmodx.org/release/amxmodx-1.8.2-cstrike-linux.tar.gz\"\n tar xzf /tmp/amxmodx-base.tar.gz 2>/dev/null || true\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\nfi\nrm -f /tmp/amxmodx-base.tar.gz /tmp/amxmodx-cstrike.tar.gz\nif [ -f /mnt/server/cstrike/addons/amxmodx/dlls/amxmodx_mm_i386.so ]; then\n echo \" [OK] amxmodx_mm_i386.so verifie\"\nfi\ngrep -q \"amxmodx\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/amxmodx/dlls/amxmodx_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\ncd /mnt/server\n\n##############################################\n# 6) ReAPI\n##############################################\necho \"\"\necho \">>> [6/15] ReAPI...\"\nREAPI_URL=$(github_get_url \"rehlds/ReAPI\" \"\\.zip\")\nif [ -n \"$REAPI_URL\" ]; then\n curl -fsSL -o /tmp/reapi.zip \"$REAPI_URL\"\n if [ -s /tmp/reapi.zip ]; then\n unzip -qo /tmp/reapi.zip -d /tmp/reapi/\n REAPI_SO=$(find /tmp/reapi -name \"reapi_amxx_i386.so\" | head -1)\n [ -n \"$REAPI_SO\" ] && cp -f \"$REAPI_SO\" /mnt/server/cstrike/addons/amxmodx/modules/\n grep -q \"reapi_amxx_i386.so\" /mnt/server/cstrike/addons/amxmodx/configs/modules.ini 2>/dev/null \\\n || echo \"reapi_amxx_i386.so\" >> /mnt/server/cstrike/addons/amxmodx/configs/modules.ini\n echo \" [OK] ReAPI installe\"\n fi\n rm -rf /tmp/reapi /tmp/reapi.zip\nfi\n\n##############################################\n# 7) Reunion\n##############################################\necho \"\"\necho \">>> [7/15] Reunion...\"\nREUNION_URL=$(github_get_url \"rehlds/ReUnion\" \"\\.zip\")\nif [ -n \"$REUNION_URL\" ]; then\n curl -fsSL -o /tmp/reunion.zip \"$REUNION_URL\"\n if [ -s /tmp/reunion.zip ]; then\n unzip -qo /tmp/reunion.zip -d /tmp/reunion/\n REUNION_SO=$(find /tmp/reunion -name \"reunion_mm_i386.so\" | head -1)\n if [ -n \"$REUNION_SO\" ]; then\n mkdir -p /mnt/server/cstrike/addons/reunion\n cp -f \"$REUNION_SO\" /mnt/server/cstrike/addons/reunion/\n REUNION_CFG=$(find /tmp/reunion -name \"reunion.cfg\" | head -1)\n if [ -n \"$REUNION_CFG\" ] && [ ! -f /mnt/server/cstrike/reunion.cfg ]; then\n cp -f \"$REUNION_CFG\" /mnt/server/cstrike/reunion.cfg\n fi\n if [ -f /mnt/server/cstrike/reunion.cfg ]; then\n SALT=$(grep -o 'SteamIdHashSalt *= *[^ ]*' /mnt/server/cstrike/reunion.cfg | sed 's/.*= *//')\n if [ ${#SALT} -lt 16 ]; then\n NEW_SALT=$(head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \\n' | head -c 32)\n sed -i \"s/SteamIdHashSalt *=.*/SteamIdHashSalt = ${NEW_SALT}/\" /mnt/server/cstrike/reunion.cfg\n fi\n fi\n grep -q \"reunion\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/reunion/reunion_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] Reunion installe\"\n fi\n fi\n rm -rf /tmp/reunion /tmp/reunion.zip\nfi\n\n##############################################\n# 8) PaintBall Refresh (GlobalModders)\n##############################################\necho \"\"\necho \">>> [8/15] PaintBall Refresh...\"\ncurl -fsSL -o /tmp/pbr.zip \\\n \"https://github.com/GlobalModders/CS1.6-AMXX-PaintBall-Elimination-2016-By-Sneaky.amxx/archive/refs/heads/master.zip\"\nif [ -s /tmp/pbr.zip ]; then\n unzip -qo /tmp/pbr.zip -d /tmp/pbr/\n PBR_DIR=$(find /tmp/pbr -maxdepth 1 -type d -name \"*PaintBall*\" | head -1)\n if [ -n \"$PBR_DIR\" ]; then\n # Copier les plugins .sma dans scripting\n find \"$PBR_DIR\" -name \"*.sma\" -exec cp -f {} /mnt/server/cstrike/addons/amxmodx/scripting/ \\;\n # Copier les .amxx pre-compiles si disponibles\n find \"$PBR_DIR\" -name \"*.amxx\" -exec cp -f {} /mnt/server/cstrike/addons/amxmodx/plugins/ \\;\n # Copier les includes\n find \"$PBR_DIR\" -name \"*.inc\" -exec cp -f {} /mnt/server/cstrike/addons/amxmodx/scripting/include/ \\;\n\n # Copier TOUS les assets (models, sounds, sprites) depuis le repo\n for dir in models sound sprites; do\n if [ -d \"$PBR_DIR/$dir\" ]; then\n cp -rf \"$PBR_DIR/$dir\" /mnt/server/cstrike/\n echo \" [OK] $dir copies depuis le repo\"\n fi\n done\n\n # Lister les models copies pour verification\n echo \" Models copies:\"\n find /mnt/server/cstrike/models/player/paintballer/ -type f 2>/dev/null | head -10\n find /mnt/server/cstrike/models/paintballR/ -type f 2>/dev/null | head -10\n\n echo \" [OK] PaintBall Refresh fichiers copies\"\n fi\n\n # Compiler les plugins PBR\n AMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\n if [ -f \"$AMXXPC\" ]; then\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n for sma in PBR_Gameplay.sma PBR_Weapons.sma PBR_Movement.sma PBR_Grenades.sma PBR_Elimination_Respawn.sma; do\n if [ -f \"$sma\" ]; then\n name=$(basename \"$sma\" .sma)\n ./amxxpc \"$sma\" -o\"../plugins/${name}.amxx\" 2>&1 || true\n if [ -f \"../plugins/${name}.amxx\" ]; then\n grep -q \"${name}.amxx\" ../configs/plugins.ini 2>/dev/null \\\n || echo \"${name}.amxx\" >> ../configs/plugins.ini\n echo \" [OK] ${name}.amxx compile\"\n else\n echo \" [WARN] Compilation ${name} echouee\"\n fi\n fi\n done\n cd /mnt/server\n fi\n rm -rf /tmp/pbr /tmp/pbr.zip\nelse\n echo \" WARN: Impossible de telecharger PaintBall Refresh\"\nfi\n\n# Verifier que le model paintballer existe (critique pour le serveur)\nif [ ! -f /mnt/server/cstrike/models/player/paintballer/paintballer.mdl ]; then\n echo \" [WARN] paintballer.mdl manquant ! Creation du dossier...\"\n mkdir -p /mnt/server/cstrike/models/player/paintballer\n # Copier le model arctic comme fallback (model CT standard)\n if [ -f /mnt/server/cstrike/models/player/arctic/arctic.mdl ]; then\n cp /mnt/server/cstrike/models/player/arctic/arctic.mdl /mnt/server/cstrike/models/player/paintballer/paintballer.mdl\n echo \" [OK] Fallback: arctic.mdl copie comme paintballer.mdl\"\n fi\nfi\n\n##############################################\n# 9) YaPB (bots Metamod)\n##############################################\necho \"\"\necho \">>> [9/15] YaPB...\"\nYAPB_URL=$(github_get_url \"yapb/yapb\" \"linux.*\\.tar\\.xz\")\nif [ -n \"$YAPB_URL\" ]; then\n curl -fsSL -o /tmp/yapb.tar.xz \"$YAPB_URL\"\n if [ -s /tmp/yapb.tar.xz ]; then\n mkdir -p /tmp/yapb\n tar -xf /tmp/yapb.tar.xz -C /tmp/yapb/\n YAPB_DIR=$(find /tmp/yapb -type d -name \"yapb\" -path \"*/addons/yapb\" | head -1)\n [ -n \"$YAPB_DIR\" ] && cp -rf \"$YAPB_DIR\" /mnt/server/cstrike/addons/ 2>/dev/null || true\n mkdir -p /mnt/server/cstrike/addons/yapb/data/graph\n mkdir -p /mnt/server/cstrike/addons/yapb/data/train\n chmod -R 777 /mnt/server/cstrike/addons/yapb/data/graph\n chmod -R 777 /mnt/server/cstrike/addons/yapb/data/train\n # Donner la propriete au user du container (UID variable, on met tout le monde)\n chown -R nobody:nogroup /mnt/server/cstrike/addons/yapb/data/ 2>/dev/null || true\n # Creer les fichiers graph vides pour aim_map pour que YaPB puisse ecrire dedans\n touch /mnt/server/cstrike/addons/yapb/data/graph/aim_map.graph\n touch /mnt/server/cstrike/addons/yapb/data/train/aim_map.vis\n chmod 777 /mnt/server/cstrike/addons/yapb/data/graph/aim_map.graph\n chmod 777 /mnt/server/cstrike/addons/yapb/data/train/aim_map.vis\n grep -q \"yapb\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/yapb/bin/yapb.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] YaPB installe\"\n fi\n rm -rf /tmp/yapb /tmp/yapb.tar.xz\nfi\n\n##############################################\n# 10) BotManager v2\n##############################################\necho \"\"\necho \">>> [10/15] BotManager v2...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/bot_manager.sma << 'BOTSMA'\n/*\n * Bot Manager v2 - {{NOM_COMMUNAUTE}}Games.fr\n * 5 bots toujours presents pour attirer les joueurs.\n * Tous les bots kick quand 4+ vrais joueurs connectes.\n */\n#include <amxmodx>\n\nnew g_cvarBotCount\nnew g_cvarKickThreshold\n\npublic plugin_init()\n{\n register_plugin(\"BotManager\", \"2.0\", \"{{NOM_COMMUNAUTE}}Games\")\n g_cvarBotCount = register_cvar(\"bm_bot_count\", \"5\")\n g_cvarKickThreshold = register_cvar(\"bm_kick_threshold\", \"4\")\n}\n\npublic plugin_cfg()\n{\n set_task(3.0, \"check_bots\")\n}\n\npublic client_putinserver(id)\n{\n set_task(2.0, \"check_bots\")\n}\n\npublic client_disconnected(id, bool:drop, message[], maxlen)\n{\n set_task(1.0, \"check_bots\")\n}\n\npublic check_bots()\n{\n new humans = count_humans()\n new fill = get_pcvar_num(g_cvarBotCount)\n new threshold = get_pcvar_num(g_cvarKickThreshold)\n\n if (humans >= threshold)\n server_cmd(\"yb_quota 0\")\n else\n server_cmd(\"yb_quota %d\", fill)\n}\n\ncount_humans()\n{\n new players[32], num, count = 0\n get_players(players, num, \"ch\")\n for (new i = 0; i < num; i++)\n {\n if (!is_user_bot(players[i]))\n count++\n }\n return count\n}\nBOTSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc bot_manager.sma -o../plugins/bot_manager.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/bot_manager.amxx ]; then\n grep -q \"bot_manager.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"bot_manager.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] bot_manager.amxx compile et installe\"\n fi\nfi\n\n##############################################\n# 11) Double Jump + Parachute\n##############################################\necho \"\"\necho \">>> [11/15] Double Jump + Parachute...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/doublejump.sma << 'DJSMA'\n#include <amxmodx>\n#include <fakemeta>\n\n#define MAX_EXTRA_JUMPS 1\n\nnew g_jumpCount[33]\n\npublic plugin_init()\n{\n register_plugin(\"Double Jump\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlayerPreThink, \"fw_PreThink_DJ\")\n}\n\npublic client_putinserver(id)\n{\n g_jumpCount[id] = 0\n}\n\npublic fw_PreThink_DJ(id)\n{\n if (!is_user_alive(id)) return FMRES_IGNORED\n\n new flags = pev(id, pev_flags)\n new buttons = pev(id, pev_button)\n new oldbuttons = pev(id, pev_oldbuttons)\n\n if (flags & FL_ONGROUND)\n {\n g_jumpCount[id] = 0\n return FMRES_IGNORED\n }\n\n if ((buttons & IN_JUMP) && !(oldbuttons & IN_JUMP))\n {\n if (g_jumpCount[id] < MAX_EXTRA_JUMPS)\n {\n g_jumpCount[id]++\n new Float:vel[3]\n pev(id, pev_velocity, vel)\n vel[2] = 268.0\n set_pev(id, pev_velocity, vel)\n }\n }\n\n return FMRES_IGNORED\n}\nDJSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc doublejump.sma -o../plugins/doublejump.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/doublejump.amxx ]; then\n grep -q \"doublejump.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"doublejump.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] doublejump.amxx compile\"\n fi\n\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/parachute.sma << 'PARASMA'\n#include <amxmodx>\n#include <fakemeta>\n\n#define FALL_SPEED -100.0\n\nnew bool:g_parachuteOn[33]\n\npublic plugin_init()\n{\n register_plugin(\"Parachute\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlayerPreThink, \"fw_PreThink_Para\")\n register_clcmd(\"say /parachute\", \"cmd_info\")\n register_clcmd(\"say /para\", \"cmd_info\")\n}\n\npublic client_putinserver(id)\n{\n g_parachuteOn[id] = false\n}\n\npublic cmd_info(id)\n{\n client_print(id, print_chat, \"[Parachute] Maintiens E en l'air pour deployer le parachute !\")\n return PLUGIN_HANDLED\n}\n\npublic fw_PreThink_Para(id)\n{\n if (!is_user_alive(id)) return FMRES_IGNORED\n\n new buttons = pev(id, pev_button)\n new flags = pev(id, pev_flags)\n\n if (!(flags & FL_ONGROUND) && (buttons & IN_USE))\n {\n new Float:vel[3]\n pev(id, pev_velocity, vel)\n\n if (vel[2] < FALL_SPEED)\n {\n vel[2] = FALL_SPEED\n set_pev(id, pev_velocity, vel)\n\n if (!g_parachuteOn[id])\n {\n g_parachuteOn[id] = true\n set_pev(id, pev_sequence, 3)\n set_pev(id, pev_gaitsequence, 1)\n }\n }\n }\n else\n {\n if (g_parachuteOn[id])\n g_parachuteOn[id] = false\n }\n\n return FMRES_IGNORED\n}\nPARASMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n ./amxxpc parachute.sma -o../plugins/parachute.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/parachute.amxx ]; then\n grep -q \"parachute.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"parachute.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] parachute.amxx compile\"\n fi\n\nfi\n\n# Activer fakemeta\nAMXX_MODULES=\"/mnt/server/cstrike/addons/amxmodx/configs/modules.ini\"\nif grep -q \"^;fakemeta\" \"$AMXX_MODULES\" 2>/dev/null; then\n sed -i 's/^;fakemeta/fakemeta/' \"$AMXX_MODULES\"\n echo \" [OK] Module fakemeta active\"\nfi\n\n##############################################\n\n##############################################\n# 11b) Weapon Restriction (Glock + MP5 only)\n##############################################\necho \"\"\necho \">>> [11b/15] Weapon Restriction...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/pb_weapons.sma << 'PBWSMA'\n/*\n * PaintBall Weapon Restriction - {{NOM_COMMUNAUTE}}Games.fr\n * Seules armes autorisees : Glock + MP5 + Knife\n * Donne automatiquement Glock + MP5 au spawn\n * Bloque l'achat et le ramassage de toute autre arme\n */\n#include <amxmodx>\n#include <cstrike>\n#include <fun>\n#include <hamsandwich>\n#include <fakemeta>\n\n// Armes autorisees\n#define ALLOWED_WEAPONS ((1<<CSW_KNIFE) | (1<<CSW_GLOCK18) | (1<<CSW_MP5NAVY))\n\npublic plugin_init()\n{\n register_plugin(\"PB Weapons\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n\n RegisterHam(Ham_Spawn, \"player\", \"fw_Spawn_Post\", 1)\n\n // Bloquer achat\n register_clcmd(\"buy\", \"block_buy\")\n register_clcmd(\"buyammo1\", \"block_buy\")\n register_clcmd(\"buyammo2\", \"block_buy\")\n register_clcmd(\"buyequip\", \"block_buy\")\n register_clcmd(\"cl_setautobuy\", \"block_buy\")\n register_clcmd(\"cl_setrebuy\", \"block_buy\")\n register_clcmd(\"cl_autobuy\", \"block_buy\")\n register_clcmd(\"cl_rebuy\", \"block_buy\")\n\n // Bloquer pickup armes non autorisees\n RegisterHam(Ham_Touch, \"weaponbox\", \"fw_TouchWeapon\")\n RegisterHam(Ham_Touch, \"armoury_entity\", \"fw_TouchWeapon\")\n}\n\npublic fw_Spawn_Post(id)\n{\n if (!is_user_alive(id)) return\n\n // Strip tout et donner Glock + MP5\n strip_user_weapons(id)\n give_item(id, \"weapon_knife\")\n give_item(id, \"weapon_glock18\")\n give_item(id, \"weapon_mp5navy\")\n\n // Munitions\n cs_set_user_bpammo(id, CSW_GLOCK18, 999)\n cs_set_user_bpammo(id, CSW_MP5NAVY, 999)\n\n // Armure\n cs_set_user_armor(id, 100, CS_ARMOR_VESTHELM)\n}\n\npublic block_buy(id)\n{\n client_print(id, print_center, \"Paintball: Glock + MP5 uniquement !\")\n return PLUGIN_HANDLED\n}\n\npublic fw_TouchWeapon(weapon, id)\n{\n if (id < 1 || id > 32) return HAM_IGNORED\n if (!is_user_alive(id)) return HAM_IGNORED\n\n // Identifier l'arme dans le weaponbox\n new classname[32]\n pev(weapon, pev_classname, classname, charsmax(classname))\n\n // Bloquer pickup des armes non autorisees\n if (equal(classname, \"weaponbox\"))\n {\n // Verifier chaque arme dans le weaponbox\n for (new i = 1; i <= 30; i++)\n {\n if (!((1<<i) & ALLOWED_WEAPONS))\n {\n new ent = cs_get_weaponbox_item(weapon, i)\n if (ent > 0) return HAM_SUPERCEDE\n }\n }\n }\n else if (equal(classname, \"armoury_entity\"))\n {\n // Bloquer les armoury entities (armes au sol sur les maps)\n return HAM_SUPERCEDE\n }\n\n return HAM_IGNORED\n}\nPBWSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc pb_weapons.sma -o../plugins/pb_weapons.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/pb_weapons.amxx ]; then\n grep -q \"pb_weapons.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"pb_weapons.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] pb_weapons.amxx compile\"\n else\n echo \" [WARN] Compilation pb_weapons echouee\"\n fi\nfi\n\n# 12) Advanced Quake Sounds\n##############################################\necho \"\"\necho \">>> [12/15] Advanced Quake Sounds...\"\ncurl -fsSL -o /tmp/aqs.zip \\\n \"https://github.com/ClaudiuHKS/AdvancedQuakeSounds/archive/refs/heads/master.zip\"\nif [ -s /tmp/aqs.zip ]; then\n unzip -qo /tmp/aqs.zip -d /tmp/aqs/\n AQS=\"/tmp/aqs/AdvancedQuakeSounds-master\"\n AMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\n if [ -f \"$AQS/AQS.sma\" ] && [ -f \"$AMXXPC\" ]; then\n cp -f \"$AQS/AQS.sma\" /mnt/server/cstrike/addons/amxmodx/scripting/\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc AQS.sma -o../plugins/AQS.amxx 2>&1 || true\n cd /mnt/server\n fi\n [ -f \"$AQS/AQS.ini\" ] && cp -f \"$AQS/AQS.ini\" /mnt/server/cstrike/addons/amxmodx/configs/\n mkdir -p /mnt/server/cstrike/sound/AQS/\n if [ -f \"$AQS/sound.zip\" ]; then\n unzip -qo \"$AQS/sound.zip\" -d /mnt/server/cstrike/ 2>/dev/null || true\n elif [ -d \"$AQS/sound/AQS\" ]; then\n cp -rf \"$AQS/sound/AQS/\"* /mnt/server/cstrike/sound/AQS/ 2>/dev/null || true\n fi\n grep -q \"AQS.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"AQS.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] AQS installe\"\n rm -rf /tmp/aqs /tmp/aqs.zip\nfi\n\n##############################################\n# 13) Paintball Welcome\n##############################################\necho \"\"\necho \">>> [13/15] Paintball Welcome...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/pb_welcome.sma << 'PBWSMA'\n#include <amxmodx>\n\npublic plugin_init()\n{\n register_plugin(\"PB Welcome\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n}\n\npublic client_putinserver(id)\n{\n set_task(5.0, \"show_welcome\", id)\n}\n\npublic show_welcome(id)\n{\n if (!is_user_connected(id)) return\n\n client_print(id, print_chat, \"**********************************\")\n client_print(id, print_chat, \"* Bienvenue sur [FR] PAINTBALL {{TAG_CLAN}} #{{NOM_COMMUNAUTE}} !\")\n client_print(id, print_chat, \"* Double Jump actif + Parachute (touche E)\")\n client_print(id, print_chat, \"* 9 armes Paintball + Sprint + Vendetta\")\n client_print(id, print_chat, \"**********************************\")\n}\nPBWSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc pb_welcome.sma -o../plugins/pb_welcome.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/pb_welcome.amxx ]; then\n grep -q \"pb_welcome.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"pb_welcome.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] pb_welcome.amxx compile\"\n fi\nfi\n\n##############################################\n# 14) Maps custom depuis FastDL\n##############################################\necho \"\"\necho \">>> [14/15] Telechargement des maps depuis FastDL...\"\nFASTDL_URL=\"https://fastdl.{{DOMAINE_GAMING}}/cs_paintball\"\n\n# Telecharger aim_map.bsp explicitement (direct, sans directory listing)\nmkdir -p /mnt/server/cstrike/maps\nwget -q --no-check-certificate \\n \"https://fastdl.{{DOMAINE_GAMING}}/cs_paintball/maps/aim_map.bsp\" \\n -O /mnt/server/cstrike/maps/aim_map.bsp \\n && echo \" [OK] aim_map.bsp telecharge directement\" \\n || echo \" [WARN] Echec telechargement direct aim_map.bsp\"\n\nwget -r -np -nH --cut-dirs=1 -P /mnt/server/cstrike/ \\\n -R \"index.html*\" \\\n --no-check-certificate \\\n -q --show-progress \\\n \"$FASTDL_URL/\" 2>&1 || echo \" [WARN] wget a rencontre des erreurs\"\n\nMAP_COUNT=$(find /mnt/server/cstrike/maps -name \"*.bsp\" 2>/dev/null | wc -l)\necho \" [OK] ${MAP_COUNT} maps .bsp telechargees\"\n\necho \">>> mapcycle.txt = aim_map uniquement...\"\necho \"aim_map\" > /mnt/server/cstrike/mapcycle.txt\necho \" [OK] mapcycle.txt = aim_map (map fixe)\"\n\n##############################################\n# 15) server.cfg Paintball\n##############################################\necho \"\"\necho \">>> [15/15] server.cfg + fix permissions...\"\ncat > /mnt/server/cstrike/server.cfg << 'SERVERCFG'\nhostname \"[FR] PAINTBALL {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}\"\nsv_contact \"admin@{{DOMAINE_GAMING}}\"\nrcon_password \"changeme\"\n\n// Paintball settings\nmp_timelimit 0\nmp_freezetime 0\nmp_roundtime 5\nmp_autoteambalance 1\nmp_friendlyfire 0\nmp_buytime 0\nsv_maxspeed 320\nsv_alltalk 1\nsv_voiceenable 1\n\n// Rates\nsv_maxrate 25000\nsv_minrate 6000\nsv_maxupdaterate 102\nsv_minupdaterate 30\n\n// Downloads + FastDL\nsv_allowdownload 1\nsv_allowupload 0\nsv_downloadurl \"https://fastdl.{{DOMAINE_GAMING}}/cs_paintball\"\n\n// YaPB bots\nyb_quota 5\nyb_auto_waypoint 0\nyb_join_after_player 0\nyb_join_team any\nyb_difficulty 2\nyb_chat 0\nyb_language_tag 0\n\n// BotManager : 5 bots toujours presents, kick quand 4+ vrais joueurs\nbm_bot_count 5\nbm_kick_threshold 4\n\n// Map fixe aim_map (pas de changement)\nmp_mapvoteratio 0\nmp_maxrounds 0\nmp_winlimit 0\n\nexec banned.cfg\nexec listip.cfg\nSERVERCFG\n\n# Creer listenserver.cfg pour forcer les bots au chargement de la map\ncat > /mnt/server/cstrike/listenserver.cfg << 'LISTENCFG'\n// Force bots on any map\nyb_quota 5\nyb_join_after_player 0\nyb_join_team any\nyb_auto_waypoint 1\nLISTENCFG\n\n# Creer aim_map.cfg pour forcer les bots specifiquement sur aim_map\nmkdir -p /mnt/server/cstrike\ncat > /mnt/server/cstrike/aim_map.cfg << 'MAPCFG'\n// aim_map specific config\nyb_quota 5\nyb_join_after_player 0\nyb_join_team any\nyb_auto_waypoint 1\necho \">>> Bots forces sur aim_map\"\nMAPCFG\necho \" [OK] aim_map.cfg + listenserver.cfg crees\"\n\n# Fix permissions\nchmod -R 755 /mnt/server/ 2>/dev/null || true\n# YaPB data DOIT etre 777 + owned by container user pour ecriture des waypoints\nchmod -R 777 /mnt/server/cstrike/addons/yapb/data/ 2>/dev/null || true\nchown -R 1000:1000 /mnt/server/cstrike/addons/yapb/data/ 2>/dev/null || true\nchmod +x /mnt/server/hlds_linux /mnt/server/hlds_run /mnt/server/hlds_amd 2>/dev/null || true\nchmod +x /mnt/server/hltv 2>/dev/null || true\n\nSTEAM_SO=$(find /mnt/server -path \"*/linux32/steamclient.so\" -not -path \"*/.steam/*\" 2>/dev/null | head -1)\nif [ -n \"$STEAM_SO\" ]; then\n mkdir -p /mnt/server/.steam/sdk32\n cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\nfi\n\necho \"\"\necho \"=============================================\"\necho \" Installation terminee !\"\necho \" Plugins : ReHLDS + ReGameDLL + Metamod-R\"\necho \" + AMX Mod X + ReAPI + Reunion\"\necho \" + PaintBall Refresh + YaPB\"\necho \" + BotManager v2 + Double Jump\"\necho \" + Parachute + AQS\"\necho \"=============================================\"\necho \"\"\necho \" Features:\"\necho \" 9 armes Paintball custom\"\necho \" Sprint + Stamina\"\necho \" Vendetta mode\"\necho \" Elimination/Respawn\"\necho \" Double Jump + Parachute (touche E)\"\necho \"=============================================\"\n", "container": "ghcr.io/ptero-eggs/installers:debian", "entrypoint": "bash" } } } |
CS 1.6 ReHLDS – Furien
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
{ "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-03-01T12:00:00+01:00", "name": "CS 1.6 ReHLDS - Furien", "author": "admin@{{DOMAINE_GAMING}}", "description": "Counter-Strike 1.6 Furien avec ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion. Plugins : Furien Pack (T=assassins couteau, gravite 0.39, vitesse 620, invisibilite immobile, grenades, pickup armes CT, auto-bhop, double jump, parachute, wallhang, 7 modes HE, Deagle 1 balle $10000, skin Assassin's Creed), CT=armes au choix. YaPB bots, BotManager v2, AQS. Installation 100% automatique.", "features": null, "docker_images": { "ghcr.io/ptero-eggs/games:source": "ghcr.io/ptero-eggs/games:source" }, "file_denylist": [], "startup": "./hlds_run -console -game {{HLDS_GAME}} -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -norestart +maxplayers {{MAX_PLAYERS}} +pingboost 2 +sys_ticrate 1200 +hostname \"{{HOSTNAME}}\"", "config": { "files": "{}", "startup": "{\"done\": \"gameserver Steam\"}", "logs": "{}", "stop": "quit" }, "variables": [ { "name": "Server Hostname", "description": "Nom du serveur affiché dans le navigateur de serveurs", "env_variable": "HOSTNAME", "default_value": "[FR] FURIEN {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}", "user_viewable": true, "user_editable": true, "rules": "required|string|between:1,64", "field_type": "text" }, { "name": "Default Map", "description": "Map chargée au démarrage du serveur", "env_variable": "SRCDS_MAP", "default_value": "de_dust2", "user_viewable": true, "user_editable": true, "rules": "required|string", "field_type": "text" }, { "name": "Max Players", "description": "Nombre maximum de joueurs", "env_variable": "MAX_PLAYERS", "default_value": "32", "user_viewable": true, "user_editable": true, "rules": "required|integer|between:2,32", "field_type": "text" }, { "name": "Game Folder", "description": "Dossier du jeu (ne pas modifier)", "env_variable": "HLDS_GAME", "default_value": "cstrike", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" }, { "name": "Steam App ID", "description": "App ID Steam pour CS 1.6 (ne pas modifier)", "env_variable": "SRCDS_APPID", "default_value": "90", "user_viewable": false, "user_editable": false, "rules": "required|integer", "field_type": "text" } ], "scripts": { "installation": { "script": "#!/bin/bash\ncd /mnt/server\n\napt-get update -qq && apt-get install -yqq unzip xz-utils wget > /dev/null 2>&1 || true\n\necho \"=============================================\"\necho \" CS 1.6 Furien - Installation automatique\"\necho \"=============================================\"\n\ngithub_get_url() {\n local repo=\"$1\" pattern=\"$2\" url=\"\"\n echo \" [INFO] Recherche: repo=${repo} pattern=${pattern}\" >&2\n for attempt in 1 2 3; do\n url=$(curl -sSL \"https://api.github.com/repos/${repo}/releases/latest\" \\\n | grep -o '\"browser_download_url\": *\"[^\"]*\"' \\\n | grep \"${pattern}\" | head -1 \\\n | sed 's/.*\"browser_download_url\": *\"//;s/\"$//')\n if [ -n \"$url\" ]; then\n echo \" [OK] URL trouvee: ${url}\" >&2\n echo \"$url\"\n return 0\n fi\n sleep 3\n done\n return 1\n}\n\n##############################################\n# 1) SteamCMD + HLDS\n##############################################\necho \"\"\necho \">>> [1/16] SteamCMD + HLDS (App ID 90)...\"\nmkdir -p steamcmd && cd steamcmd\n[ ! -f steamcmd.sh ] && curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz\ncd /mnt/server\n./steamcmd/steamcmd.sh +force_install_dir /mnt/server +login anonymous +app_update 90 -beta steam_legacy validate +quit\nmkdir -p /mnt/server/.steam/sdk32\necho \"10\" > /mnt/server/steam_appid.txt\nSTEAM_SO=$(find /mnt/server/steamcmd -path \"*/linux32/steamclient.so\" 2>/dev/null | head -1)\n[ -n \"$STEAM_SO\" ] && cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n\n##############################################\n# 2) ReHLDS\n##############################################\necho \"\"\necho \">>> [2/16] ReHLDS...\"\nREHLDS_URL=$(github_get_url \"rehlds/ReHLDS\" \"rehlds-bin.*\\.zip\")\nif [ -n \"$REHLDS_URL\" ]; then\n curl -fsSL -o /tmp/rehlds.zip \"$REHLDS_URL\"\n unzip -qo /tmp/rehlds.zip -d /tmp/rehlds/\n REHLDS_BIN=$(find /tmp/rehlds -name \"hlds_linux\" -type f | head -1)\n [ -n \"$REHLDS_BIN\" ] && cp -rf \"$(dirname \"$REHLDS_BIN\")\"/* /mnt/server/\n rm -rf /tmp/rehlds /tmp/rehlds.zip\nfi\nstrings /mnt/server/hlds_linux 2>/dev/null | grep -qi \"rehlds\" && echo \" [OK] ReHLDS verifie\"\n\n##############################################\n# 3) ReGameDLL_CS\n##############################################\necho \"\"\necho \">>> [3/16] ReGameDLL_CS...\"\nREGAME_URL=$(github_get_url \"rehlds/ReGameDLL_CS\" \"\\.zip\")\nif [ -n \"$REGAME_URL\" ]; then\n curl -fsSL -o /tmp/regamedll.zip \"$REGAME_URL\"\n unzip -qo /tmp/regamedll.zip -d /tmp/regamedll/\n CSSO=$(find /tmp/regamedll -name \"cs.so\" -path \"*linux32*\" | head -1)\n [ -n \"$CSSO\" ] && cp -f \"$CSSO\" /mnt/server/cstrike/dlls/cs.so\n EXTRAS=$(find /tmp/regamedll -type d -name \"gamedir\" | head -1)\n [ -n \"$EXTRAS\" ] && cp -rn \"$EXTRAS\"/* /mnt/server/cstrike/ 2>/dev/null || true\n echo \" [OK] ReGameDLL installe\"\n rm -rf /tmp/regamedll /tmp/regamedll.zip\nfi\n\n##############################################\n# 4) Metamod-R\n##############################################\necho \"\"\necho \">>> [4/16] Metamod-R...\"\nMETAMOD_URL=$(github_get_url \"rehlds/metamod-r\" \"\\.zip\")\nif [ -n \"$METAMOD_URL\" ]; then\n curl -fsSL -o /tmp/metamod.zip \"$METAMOD_URL\"\n unzip -qo /tmp/metamod.zip -d /tmp/metamod/\n mkdir -p /mnt/server/cstrike/addons/metamod\n META_DLL=$(find /tmp/metamod -name \"metamod_i386.so\" | head -1)\n [ -n \"$META_DLL\" ] && cp -f \"$META_DLL\" /mnt/server/cstrike/addons/metamod/\n rm -rf /tmp/metamod /tmp/metamod.zip\nfi\nif [ -f /mnt/server/cstrike/addons/metamod/metamod_i386.so ]; then\n GAMEDLL_LINUX=\"addons/metamod/metamod_i386.so\"\n [ -f /mnt/server/cstrike/addons/metamod/plugins.ini ] || echo \"; Metamod plugins\" > /mnt/server/cstrike/addons/metamod/plugins.ini\nelse\n GAMEDLL_LINUX=\"dlls/cs.so\"\nfi\ncat > /mnt/server/cstrike/liblist.gam << LIBLIST\ngame \"Counter-Strike\"\nurl_info \"www.counter-strike.net\"\nurl_dl \"\"\nversion \"1.6\"\nsize \"184000000\"\nsvonly \"0\"\ncldll \"1\"\nsecure \"1\"\nhlversion \"1110\"\nnomodels \"1\"\nnohimodel \"1\"\nmpentity \"info_player_start\"\ngamedll \"dlls\\cs.dll\"\ngamedll_linux \"${GAMEDLL_LINUX}\"\ngamedll_osx \"dlls/cs.dylib\"\ntype \"multiplayer_only\"\nLIBLIST\n\n##############################################\n# 5) AMX Mod X\n##############################################\necho \"\"\necho \">>> [5/16] AMX Mod X...\"\nAMXX_DROP=\"https://www.amxmodx.org/amxxdrop/1.10\"\ncurl -fsSL -o /tmp/amxmodx-base.tar.gz \"${AMXX_DROP}/amxmodx-latest-base-linux.tar.gz\"\ncurl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"${AMXX_DROP}/amxmodx-latest-cstrike-linux.tar.gz\"\ncd /mnt/server/cstrike\nif tar tzf /tmp/amxmodx-base.tar.gz > /dev/null 2>&1; then\n tar xzf /tmp/amxmodx-base.tar.gz\n tar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\n echo \" [OK] AMX Mod X 1.10 installe\"\nfi\nrm -f /tmp/amxmodx-base.tar.gz /tmp/amxmodx-cstrike.tar.gz\ngrep -q \"amxmodx\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/amxmodx/dlls/amxmodx_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\ncd /mnt/server\n\n##############################################\n# 6) ReAPI\n##############################################\necho \"\"\necho \">>> [6/16] ReAPI...\"\nREAPI_URL=$(github_get_url \"rehlds/ReAPI\" \"\\.zip\")\nif [ -n \"$REAPI_URL\" ]; then\n curl -fsSL -o /tmp/reapi.zip \"$REAPI_URL\"\n unzip -qo /tmp/reapi.zip -d /tmp/reapi/\n REAPI_SO=$(find /tmp/reapi -name \"reapi_amxx_i386.so\" | head -1)\n [ -n \"$REAPI_SO\" ] && cp -f \"$REAPI_SO\" /mnt/server/cstrike/addons/amxmodx/modules/\n grep -q \"reapi_amxx_i386.so\" /mnt/server/cstrike/addons/amxmodx/configs/modules.ini 2>/dev/null \\\n || echo \"reapi_amxx_i386.so\" >> /mnt/server/cstrike/addons/amxmodx/configs/modules.ini\n echo \" [OK] ReAPI installe\"\n rm -rf /tmp/reapi /tmp/reapi.zip\nfi\n\n##############################################\n# 7) Reunion\n##############################################\necho \"\"\necho \">>> [7/16] Reunion...\"\nREUNION_URL=$(github_get_url \"rehlds/ReUnion\" \"\\.zip\")\nif [ -n \"$REUNION_URL\" ]; then\n curl -fsSL -o /tmp/reunion.zip \"$REUNION_URL\"\n unzip -qo /tmp/reunion.zip -d /tmp/reunion/\n REUNION_SO=$(find /tmp/reunion -name \"reunion_mm_i386.so\" | head -1)\n if [ -n \"$REUNION_SO\" ]; then\n mkdir -p /mnt/server/cstrike/addons/reunion\n cp -f \"$REUNION_SO\" /mnt/server/cstrike/addons/reunion/\n REUNION_CFG=$(find /tmp/reunion -name \"reunion.cfg\" | head -1)\n [ -n \"$REUNION_CFG\" ] && [ ! -f /mnt/server/cstrike/reunion.cfg ] && cp -f \"$REUNION_CFG\" /mnt/server/cstrike/reunion.cfg\n if [ -f /mnt/server/cstrike/reunion.cfg ]; then\n SALT=$(grep -o 'SteamIdHashSalt *= *[^ ]*' /mnt/server/cstrike/reunion.cfg | sed 's/.*= *//')\n if [ ${#SALT} -lt 16 ]; then\n NEW_SALT=$(head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \\n' | head -c 32)\n sed -i \"s/SteamIdHashSalt *=.*/SteamIdHashSalt = ${NEW_SALT}/\" /mnt/server/cstrike/reunion.cfg\n fi\n fi\n grep -q \"reunion\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/reunion/reunion_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] Reunion installe\"\n fi\n rm -rf /tmp/reunion /tmp/reunion.zip\nfi\n\n##############################################\n# 8) Furien Core (custom {{NOM_COMMUNAUTE}}Games)\n##############################################\necho \"\"\necho \">>> [8/16] Furien Core...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n\n # --- Furien Core v3 : invisibilite + visible si arme en main ---\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/furien_core.sma << 'FURIENSMA'\n/*\n * Furien Core v3 - {{NOM_COMMUNAUTE}}Games.fr\n * T (Furien) :\n * - Couteau + grenades au spawn\n * - Gravite basse, vitesse haute\n * - Invisible quand immobile (render progressif)\n * - Peut ramasser les armes des CT morts\n * - VISIBLE des qu'il tient une arme (pas couteau/grenade)\n * - Redevient invisible-eligible en repassant au couteau\n * CT (Anti-Furien) : armes normales\n * CVARs:\n * furien_t_gravity = gravite T (defaut 0.39)\n * furien_t_speed = vitesse T (defaut 620.0)\n * furien_t_hp = HP T au spawn (defaut 150)\n * furien_ct_hp = HP CT au spawn (defaut 100)\n */\n#include <amxmodx>\n#include <cstrike>\n#include <fun>\n#include <hamsandwich>\n#include <fakemeta>\n#include <engine>\n\nnew g_cvarTGravity\nnew g_cvarTSpeed\nnew g_cvarTHp\nnew g_cvarCTHp\n\nnew Float:g_lastMoveTime[33]\nnew bool:g_isInvisible[33]\nnew bool:g_holdingGun[33]\n\npublic plugin_init()\n{\n register_plugin(\"Furien Core\", \"3.0\", \"{{NOM_COMMUNAUTE}}Games\")\n g_cvarTGravity = register_cvar(\"furien_t_gravity\", \"0.39\")\n g_cvarTSpeed = register_cvar(\"furien_t_speed\", \"620.0\")\n g_cvarTHp = register_cvar(\"furien_t_hp\", \"150\")\n g_cvarCTHp = register_cvar(\"furien_ct_hp\", \"100\")\n\n RegisterHam(Ham_Spawn, \"player\", \"fw_PlayerSpawn_Post\", 1)\n RegisterHam(Ham_Item_PreFrame, \"player\", \"fw_ItemPreFrame_Post\", 1)\n\n // Verifier invisibilite toutes les 0.2s\n set_task(0.2, \"task_check_invis\", _, _, _, \"b\")\n}\n\npublic client_putinserver(id)\n{\n g_lastMoveTime[id] = 0.0\n g_isInvisible[id] = false\n g_holdingGun[id] = false\n}\n\n// Verifier si l'arme active est une \"vraie arme\" (pas couteau/grenade)\nbool:is_holding_weapon(id)\n{\n new wpn = get_user_weapon(id)\n // Couteau, HE, Flash, Smoke, C4 = pas une arme\n if (wpn == CSW_KNIFE || wpn == CSW_HEGRENADE || wpn == CSW_FLASHBANG || wpn == CSW_SMOKEGRENADE || wpn == CSW_C4)\n return false\n return (wpn > 0)\n}\n\npublic fw_PlayerSpawn_Post(id)\n{\n if (!is_user_alive(id)) return\n\n g_isInvisible[id] = false\n g_holdingGun[id] = false\n set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderNormal, 255)\n\n if (cs_get_user_team(id) == CS_TEAM_T)\n {\n // T : couteau + grenades\n strip_user_weapons(id)\n give_item(id, \"weapon_knife\")\n give_item(id, \"weapon_hegrenade\")\n give_item(id, \"weapon_flashbang\")\n give_item(id, \"weapon_smokegrenade\")\n\n // Gravite et HP\n set_user_gravity(id, get_pcvar_float(g_cvarTGravity))\n set_user_health(id, get_pcvar_num(g_cvarTHp))\n cs_set_user_armor(id, 100, CS_ARMOR_VESTHELM)\n\n g_lastMoveTime[id] = get_gametime()\n }\n else if (cs_get_user_team(id) == CS_TEAM_CT)\n {\n set_user_gravity(id, 1.0)\n set_user_health(id, get_pcvar_num(g_cvarCTHp))\n }\n}\n\n// Maintenir la vitesse T + detecter arme en main\npublic fw_ItemPreFrame_Post(id)\n{\n if (!is_user_alive(id)) return\n if (cs_get_user_team(id) != CS_TEAM_T) return\n\n new Float:speed = get_pcvar_float(g_cvarTSpeed)\n set_user_maxspeed(id, speed)\n\n // Verifier si le T tient une arme (pas couteau/grenade)\n new bool:hasGun = is_holding_weapon(id)\n\n if (hasGun && !g_holdingGun[id])\n {\n // Vient de sortir une arme -> forcer visible\n g_holdingGun[id] = true\n g_isInvisible[id] = false\n set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderNormal, 255)\n client_print(id, print_center, \">> VISIBLE (arme en main) <<\")\n }\n else if (!hasGun && g_holdingGun[id])\n {\n // Vient de ranger l'arme (couteau) -> peut redevenir invisible\n g_holdingGun[id] = false\n g_lastMoveTime[id] = get_gametime()\n client_print(id, print_center, \">> Couteau: invisibilite possible <<\")\n }\n\n // Detecter mouvement\n new Float:vel[3]\n pev(id, pev_velocity, vel)\n new Float:spd = floatsqroot(vel[0]*vel[0] + vel[1]*vel[1] + vel[2]*vel[2])\n if (spd > 10.0)\n {\n g_lastMoveTime[id] = get_gametime()\n\n // Redevenir visible si on bouge (et qu'on etait invisible)\n if (g_isInvisible[id])\n {\n g_isInvisible[id] = false\n set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderNormal, 255)\n }\n }\n}\n\n// Invisibilite progressive quand immobile + couteau en main (T uniquement)\npublic task_check_invis()\n{\n new Float:now = get_gametime()\n for (new id = 1; id <= 32; id++)\n {\n if (!is_user_alive(id)) continue\n if (cs_get_user_team(id) != CS_TEAM_T) continue\n\n // Pas d'invisibilite si arme en main\n if (g_holdingGun[id]) continue\n\n new Float:idle = now - g_lastMoveTime[id]\n\n if (idle >= 2.0 && !g_isInvisible[id])\n {\n // Invisible total apres 2 secondes immobile\n g_isInvisible[id] = true\n set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderTransAlpha, 0)\n client_print(id, print_center, \">> INVISIBLE <<\")\n }\n else if (idle >= 1.0 && idle < 2.0 && !g_isInvisible[id])\n {\n // Semi-transparent entre 1 et 2 secondes\n new alpha = 255 - floatround((idle - 1.0) * 255.0)\n if (alpha < 0) alpha = 0\n set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderTransAlpha, alpha)\n }\n }\n}\nFURIENSMA\n\n # --- NadeModes : 7 modes HE grenade ---\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/furien_nademodes.sma << 'NADESMA'\n/*\n * Furien NadeModes - {{NOM_COMMUNAUTE}}Games.fr\n * 7 modes HE : normal, fire, frost, laser, multi, proxy, random\n * Joueurs choisissent via /nade\n */\n#include <amxmodx>\n#include <cstrike>\n#include <fun>\n#include <fakemeta>\n#include <hamsandwich>\n\n#define MODE_NORMAL 0\n#define MODE_FIRE 1\n#define MODE_FROST 2\n#define MODE_LASER 3\n#define MODE_MULTI 4\n#define MODE_PROXY 5\n#define MODE_RANDOM 6\n\nnew g_nadeMode[33]\nnew const g_modeNames[][] = { \"Normal\", \"Fire\", \"Frost\", \"Laser\", \"Multi\", \"Proxy\", \"Random\" }\n\nnew g_sprBeam, g_sprExplode\n\npublic plugin_init()\n{\n register_plugin(\"Furien NadeModes\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"say /nade\", \"cmd_nade_menu\")\n register_clcmd(\"say .nade\", \"cmd_nade_menu\")\n register_event(\"DeathMsg\", \"event_death\", \"a\")\n RegisterHam(Ham_TakeDamage, \"player\", \"fw_TakeDamage\")\n}\n\npublic plugin_precache()\n{\n g_sprBeam = precache_model(\"sprites/laserbeam.spr\")\n g_sprExplode = precache_model(\"sprites/zerogxplode.spr\")\n}\n\npublic client_putinserver(id) { g_nadeMode[id] = MODE_NORMAL }\n\npublic cmd_nade_menu(id)\n{\n new menu = menu_create(\"[NadeModes] Choisis ton mode HE:\", \"nade_handler\")\n new szItem[48]\n for (new i = 0; i < 7; i++)\n {\n formatex(szItem, charsmax(szItem), \"%s%s\", g_modeNames[i], (g_nadeMode[id] == i) ? \" [actif]\" : \"\")\n menu_additem(menu, szItem)\n }\n menu_display(id, menu)\n return PLUGIN_HANDLED\n}\n\npublic nade_handler(id, menu, item)\n{\n if (item == MENU_EXIT) { menu_destroy(menu); return PLUGIN_HANDLED }\n g_nadeMode[id] = item\n client_print(id, print_chat, \"[NadeModes] Mode HE: %s\", g_modeNames[item])\n menu_destroy(menu)\n return PLUGIN_HANDLED\n}\n\npublic fw_TakeDamage(victim, inflictor, attacker, Float:damage, damagebits)\n{\n if (!is_user_connected(attacker) || !is_user_alive(victim)) return HAM_IGNORED\n if (!(damagebits & DMG_GRENADE)) return HAM_IGNORED\n\n new mode = g_nadeMode[attacker]\n if (mode == MODE_RANDOM) mode = random_num(MODE_FIRE, MODE_PROXY)\n\n switch (mode)\n {\n case MODE_FIRE:\n {\n // Double damage\n SetHamParamFloat(4, damage * 2.0)\n // Effet visuel feu\n message_begin(MSG_PVS, SVC_TEMPENTITY, {0,0,0})\n write_byte(TE_SPRITE)\n new Float:origin[3]\n pev(victim, pev_origin, origin)\n write_coord(floatround(origin[0]))\n write_coord(floatround(origin[1]))\n write_coord(floatround(origin[2]))\n write_short(g_sprExplode)\n write_byte(20)\n write_byte(200)\n message_end()\n }\n case MODE_FROST:\n {\n // Ralentir la victime\n set_user_maxspeed(victim, 50.0)\n set_task(4.0, \"unfreeze\", victim)\n // Ecran bleu\n message_begin(MSG_ONE, get_user_msgid(\"ScreenFade\"), _, victim)\n write_short(1<<12)\n write_short(1<<12)\n write_short(0)\n write_byte(0)\n write_byte(0)\n write_byte(255)\n write_byte(100)\n message_end()\n client_print(victim, print_chat, \"[NadeModes] Tu es gele pendant 4 secondes !\")\n }\n case MODE_LASER:\n {\n // Degats bonus\n SetHamParamFloat(4, damage * 1.5)\n }\n case MODE_MULTI:\n {\n // Splash damage aux joueurs proches\n new Float:origin[3]\n pev(victim, pev_origin, origin)\n new players[32], num\n get_players(players, num, \"ae\")\n for (new i = 0; i < num; i++)\n {\n new pid = players[i]\n if (pid == victim || pid == attacker) continue\n if (!is_user_alive(pid)) continue\n new Float:porigin[3]\n pev(pid, pev_origin, porigin)\n new Float:dist = get_distance_f(origin, porigin)\n if (dist < 300.0)\n {\n ExecuteHamB(Ham_TakeDamage, pid, inflictor, attacker, damage * 0.5, DMG_BLAST)\n }\n }\n }\n case MODE_PROXY:\n {\n // Mine : degats augmentes\n SetHamParamFloat(4, damage * 2.5)\n client_print(victim, print_chat, \"[NadeModes] Touche par une mine proxy !\")\n }\n }\n\n return HAM_HANDLED\n}\n\npublic unfreeze(id)\n{\n if (!is_user_alive(id)) return\n // Restaurer vitesse selon equipe\n if (cs_get_user_team(id) == CS_TEAM_T)\n set_user_maxspeed(id, 565.0)\n else\n set_user_maxspeed(id, 260.0)\n client_print(id, print_chat, \"[NadeModes] Tu es degivre !\")\n}\nNADESMA\n\n # --- Wallhang (T peut s'accrocher aux murs) ---\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/furien_wallhang.sma << 'WALLSMA'\n/*\n * Furien Wallhang - {{NOM_COMMUNAUTE}}Games.fr\n * Les T peuvent s'accrocher aux murs en maintenant E\n */\n#include <amxmodx>\n#include <fakemeta>\n#include <cstrike>\n\nnew bool:g_hanging[33]\n\npublic plugin_init()\n{\n register_plugin(\"Furien Wallhang\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlayerPreThink, \"fw_PreThink_Wall\")\n register_forward(FM_Touch, \"fw_Touch\")\n}\n\npublic client_putinserver(id) { g_hanging[id] = false }\n\npublic fw_Touch(ent, id)\n{\n if (id < 1 || id > 32) return FMRES_IGNORED\n if (!is_user_alive(id)) return FMRES_IGNORED\n if (cs_get_user_team(id) != CS_TEAM_T) return FMRES_IGNORED\n\n new buttons = pev(id, pev_button)\n new flags = pev(id, pev_flags)\n\n // Si touche un mur et maintient E et pas au sol\n if ((buttons & IN_USE) && !(flags & FL_ONGROUND))\n {\n new classname[32]\n if (ent > 0)\n pev(ent, pev_classname, classname, charsmax(classname))\n if (ent == 0 || equal(classname, \"worldspawn\") || equal(classname, \"func_wall\") || equal(classname, \"func_breakable\"))\n {\n set_pev(id, pev_velocity, Float:{0.0, 0.0, 0.0})\n set_pev(id, pev_gravity, 0.001)\n g_hanging[id] = true\n }\n }\n return FMRES_IGNORED\n}\n\npublic fw_PreThink_Wall(id)\n{\n if (!is_user_alive(id)) return FMRES_IGNORED\n if (!g_hanging[id]) return FMRES_IGNORED\n\n new buttons = pev(id, pev_button)\n\n // Lacher si relache E ou saute\n if (!(buttons & IN_USE) || (buttons & IN_JUMP))\n {\n g_hanging[id] = false\n set_pev(id, pev_gravity, 0.39)\n if (buttons & IN_JUMP)\n {\n new Float:vel[3]\n pev(id, pev_velocity, vel)\n vel[2] = 300.0\n set_pev(id, pev_velocity, vel)\n }\n }\n return FMRES_IGNORED\n}\n\npublic client_disconnected(id) { g_hanging[id] = false }\nWALLSMA\n\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n for sma in furien_core.sma furien_nademodes.sma furien_wallhang.sma; do\n name=$(basename \"$sma\" .sma)\n ./amxxpc \"$sma\" -o\"../plugins/${name}.amxx\" 2>&1 || true\n if [ -f \"../plugins/${name}.amxx\" ]; then\n grep -q \"${name}.amxx\" ../configs/plugins.ini 2>/dev/null \\\n || echo \"${name}.amxx\" >> ../configs/plugins.ini\n echo \" [OK] ${name}.amxx compile\"\n else\n echo \" [WARN] Compilation ${name} echouee\"\n fi\n done\n cd /mnt/server\n\nelse\n echo \" [WARN] amxxpc non trouve\"\nfi\n\n##############################################\n# 9) Deagle 1 Balle - Menu d'achat T ($10000)\n##############################################\necho \"\"\necho \">>> [9/16] Deagle 1 Balle (custom)...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/furien_deagle.sma << 'DEAGLESMA'\n/*\n * Furien Deagle 1 Balle - {{NOM_COMMUNAUTE}}Games.fr\n * Les Terroristes (Furien) peuvent acheter un Deagle avec 1 seule balle\n * pour $10000 via la commande /deagle\n */\n#include <amxmodx>\n#include <cstrike>\n#include <fun>\n#include <hamsandwich>\n\n#define DEAGLE_COST 10000\n\npublic plugin_init()\n{\n register_plugin(\"Furien Deagle\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"say /deagle\", \"cmd_buy_deagle\")\n register_clcmd(\"say .deagle\", \"cmd_buy_deagle\")\n}\n\npublic cmd_buy_deagle(id)\n{\n if (!is_user_alive(id))\n {\n client_print(id, print_chat, \"[Furien] Tu dois etre vivant pour acheter !\")\n return PLUGIN_HANDLED\n }\n\n if (cs_get_user_team(id) != CS_TEAM_T)\n {\n client_print(id, print_chat, \"[Furien] Seuls les Terroristes (Furien) peuvent acheter le Deagle !\")\n return PLUGIN_HANDLED\n }\n\n new money = cs_get_user_money(id)\n if (money < DEAGLE_COST)\n {\n client_print(id, print_chat, \"[Furien] Il te faut $%d pour le Deagle ! (tu as $%d)\", DEAGLE_COST, money)\n return PLUGIN_HANDLED\n }\n\n // Retirer l'argent\n cs_set_user_money(id, money - DEAGLE_COST)\n\n // Donner le Deagle avec 1 balle\n give_item(id, \"weapon_deagle\")\n\n // Mettre 1 balle dans le chargeur, 0 en reserve\n new wpn = find_ent_by_owner(-1, \"weapon_deagle\", id)\n if (wpn > 0)\n {\n cs_set_weapon_ammo(wpn, 1)\n }\n cs_set_user_bpammo(id, CSW_DEAGLE, 0)\n\n client_print(id, print_chat, \"[Furien] Deagle achete ! 1 balle, fais-la compter !\")\n return PLUGIN_HANDLED\n}\n\n// Empecher le ramassage de munitions deagle pour les T\npublic Ham_Item_AddToPlayer_Post(ent, id)\n{\n // Optionnel : garder le gameplay challenge\n}\nDEAGLESMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc furien_deagle.sma -o../plugins/furien_deagle.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/furien_deagle.amxx ]; then\n grep -q \"furien_deagle.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"furien_deagle.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] furien_deagle.amxx compile\"\n fi\nfi\n\n##############################################\n# 10) CT Weapon Menu (choix armes comme DM)\n##############################################\necho \"\"\necho \">>> [10/16] CT Weapon Menu...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/furien_ct_weapons.sma << 'CTWSMA'\n/*\n * Furien CT Weapons - {{NOM_COMMUNAUTE}}Games.fr\n * Les CT choisissent leurs armes via /guns ou /menu (comme DM)\n * Inclut grenades (HE, Flash, Smoke)\n */\n#include <amxmodx>\n#include <cstrike>\n#include <fun>\n\nnew g_primaryChoice[33]\nnew g_secondaryChoice[33]\n\nnew const g_primaryWeapons[][] = {\n \"weapon_m4a1\", \"weapon_ak47\", \"weapon_awp\", \"weapon_famas\",\n \"weapon_mp5navy\", \"weapon_p90\", \"weapon_galil\", \"weapon_aug\"\n}\nnew const g_primaryNames[][] = {\n \"M4A1\", \"AK-47\", \"AWP\", \"FAMAS\", \"MP5\", \"P90\", \"Galil\", \"AUG\"\n}\n\npublic plugin_init()\n{\n register_plugin(\"Furien CT Weapons\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"say /guns\", \"cmd_guns\")\n register_clcmd(\"say /menu\", \"cmd_guns\")\n register_clcmd(\"say .guns\", \"cmd_guns\")\n register_event(\"ResetHUD\", \"event_spawn\", \"be\")\n}\n\npublic client_putinserver(id)\n{\n g_primaryChoice[id] = 0\n g_secondaryChoice[id] = 0\n}\n\npublic event_spawn(id)\n{\n if (!is_user_alive(id)) return\n if (cs_get_user_team(id) != CS_TEAM_CT) return\n\n // Donner les armes apres un court delai\n set_task(0.5, \"give_weapons\", id)\n}\n\npublic give_weapons(id)\n{\n if (!is_user_alive(id)) return\n if (cs_get_user_team(id) != CS_TEAM_CT) return\n\n // Retirer les armes actuelles\n strip_user_weapons(id)\n give_item(id, \"weapon_knife\")\n\n // Arme principale\n new prim = g_primaryChoice[id]\n if (prim >= 0 && prim < sizeof(g_primaryWeapons))\n {\n give_item(id, g_primaryWeapons[prim])\n // Donner les munitions\n new wpnid = get_weaponid(g_primaryWeapons[prim])\n if (wpnid > 0)\n cs_set_user_bpammo(id, wpnid, 200)\n }\n\n // Secondaire : Deagle par defaut\n give_item(id, \"weapon_deagle\")\n cs_set_user_bpammo(id, CSW_DEAGLE, 35)\n\n // Grenades pour CT\n give_item(id, \"weapon_hegrenade\")\n give_item(id, \"weapon_flashbang\")\n give_item(id, \"weapon_smokegrenade\")\n\n // Armure\n cs_set_user_armor(id, 100, CS_ARMOR_VESTHELM)\n}\n\npublic cmd_guns(id)\n{\n if (cs_get_user_team(id) != CS_TEAM_CT)\n {\n client_print(id, print_chat, \"[Furien] Les Terroristes utilisent le couteau ! Tapez /deagle pour acheter un Deagle.\")\n return PLUGIN_HANDLED\n }\n\n new menu = menu_create(\"[CT] Choisis ton arme:\", \"menu_handler\")\n for (new i = 0; i < sizeof(g_primaryNames); i++)\n {\n menu_additem(menu, g_primaryNames[i])\n }\n menu_display(id, menu)\n return PLUGIN_HANDLED\n}\n\npublic menu_handler(id, menu, item)\n{\n if (item == MENU_EXIT)\n {\n menu_destroy(menu)\n return PLUGIN_HANDLED\n }\n\n g_primaryChoice[id] = item\n client_print(id, print_chat, \"[CT] Arme selectionnee : %s\", g_primaryNames[item])\n\n // Redonner les armes si vivant\n if (is_user_alive(id) && cs_get_user_team(id) == CS_TEAM_CT)\n give_weapons(id)\n\n menu_destroy(menu)\n return PLUGIN_HANDLED\n}\nCTWSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n ./amxxpc furien_ct_weapons.sma -o../plugins/furien_ct_weapons.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/furien_ct_weapons.amxx ]; then\n grep -q \"furien_ct_weapons.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"furien_ct_weapons.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] furien_ct_weapons.amxx compile\"\n fi\nfi\n\n##############################################\n# 11) Auto Bhop + Double Jump + Parachute\n##############################################\necho \"\"\necho \">>> [11/16] Auto Bhop + Double Jump + Parachute...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n\n # Auto Bhop (T seulement)\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/furien_autobhop.sma << 'BHOPSMA'\n#include <amxmodx>\n#include <fakemeta>\n#include <cstrike>\n\npublic plugin_init()\n{\n register_plugin(\"Furien AutoBhop\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlayerPreThink, \"fw_PreThink\")\n}\n\npublic fw_PreThink(id)\n{\n if (!is_user_alive(id)) return FMRES_IGNORED\n if (cs_get_user_team(id) != CS_TEAM_T) return FMRES_IGNORED\n\n new buttons = pev(id, pev_button)\n new flags = pev(id, pev_flags)\n\n if ((buttons & IN_JUMP) && (flags & FL_ONGROUND))\n {\n new Float:vel[3]\n pev(id, pev_velocity, vel)\n vel[2] = 268.0\n set_pev(id, pev_velocity, vel)\n }\n\n return FMRES_IGNORED\n}\nBHOPSMA\n\n # Double Jump\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/doublejump.sma << 'DJSMA'\n#include <amxmodx>\n#include <fakemeta>\n\n#define MAX_EXTRA_JUMPS 1\n\nnew g_jumpCount[33]\n\npublic plugin_init()\n{\n register_plugin(\"Double Jump\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlayerPreThink, \"fw_PreThink_DJ\")\n}\n\npublic client_putinserver(id) { g_jumpCount[id] = 0 }\n\npublic fw_PreThink_DJ(id)\n{\n if (!is_user_alive(id)) return FMRES_IGNORED\n\n new flags = pev(id, pev_flags)\n new buttons = pev(id, pev_button)\n new oldbuttons = pev(id, pev_oldbuttons)\n\n if (flags & FL_ONGROUND) { g_jumpCount[id] = 0; return FMRES_IGNORED }\n\n if ((buttons & IN_JUMP) && !(oldbuttons & IN_JUMP))\n {\n if (g_jumpCount[id] < MAX_EXTRA_JUMPS)\n {\n g_jumpCount[id]++\n new Float:vel[3]\n pev(id, pev_velocity, vel)\n vel[2] = 268.0\n set_pev(id, pev_velocity, vel)\n }\n }\n return FMRES_IGNORED\n}\nDJSMA\n\n # Parachute\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/parachute.sma << 'PARASMA'\n#include <amxmodx>\n#include <fakemeta>\n\n#define FALL_SPEED -100.0\n\nnew bool:g_parachuteOn[33]\n\npublic plugin_init()\n{\n register_plugin(\"Parachute\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlayerPreThink, \"fw_PreThink_Para\")\n register_clcmd(\"say /para\", \"cmd_info\")\n}\n\npublic client_putinserver(id) { g_parachuteOn[id] = false }\n\npublic cmd_info(id)\n{\n client_print(id, print_chat, \"[Parachute] Maintiens E en l'air pour deployer !\")\n return PLUGIN_HANDLED\n}\n\npublic fw_PreThink_Para(id)\n{\n if (!is_user_alive(id)) return FMRES_IGNORED\n new buttons = pev(id, pev_button)\n new flags = pev(id, pev_flags)\n\n if (!(flags & FL_ONGROUND) && (buttons & IN_USE))\n {\n new Float:vel[3]\n pev(id, pev_velocity, vel)\n if (vel[2] < FALL_SPEED)\n {\n vel[2] = FALL_SPEED\n set_pev(id, pev_velocity, vel)\n if (!g_parachuteOn[id]) { g_parachuteOn[id] = true; set_pev(id, pev_sequence, 3); set_pev(id, pev_gaitsequence, 1) }\n }\n }\n else if (g_parachuteOn[id]) g_parachuteOn[id] = false\n\n return FMRES_IGNORED\n}\nPARASMA\n\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n for sma in furien_autobhop.sma doublejump.sma parachute.sma; do\n name=$(basename \"$sma\" .sma)\n ./amxxpc \"$sma\" -o\"../plugins/${name}.amxx\" 2>&1 || true\n if [ -f \"../plugins/${name}.amxx\" ]; then\n grep -q \"${name}.amxx\" ../configs/plugins.ini 2>/dev/null \\\n || echo \"${name}.amxx\" >> ../configs/plugins.ini\n echo \" [OK] ${name}.amxx compile\"\n fi\n done\n cd /mnt/server\nfi\n\n# Activer modules\nAMXX_MODULES=\"/mnt/server/cstrike/addons/amxmodx/configs/modules.ini\"\nfor mod in fakemeta hamsandwich cstrike fun engine; do\n if grep -q \"^;${mod}\" \"$AMXX_MODULES\" 2>/dev/null; then\n sed -i \"s/^;${mod}/${mod}/\" \"$AMXX_MODULES\"\n echo \" [OK] Module ${mod} active\"\n fi\ndone\n\n##############################################\n# 12) Skin Assassin's Creed (T)\n##############################################\necho \"\"\necho \">>> [12/16] Skin Assassin's Creed pour T...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/furien_skin_ac.sma << 'ACSMA'\n/*\n * Furien Skin - Assassin's Creed pour les T\n * Telecharge le model depuis FastDL si disponible\n * Sinon utilise arctic comme fallback\n */\n#include <amxmodx>\n#include <cstrike>\n#include <fakemeta>\n\nnew const g_szModelT[] = \"furien_assassin\"\n\npublic plugin_init()\n{\n register_plugin(\"Furien AC Skin\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_event(\"ResetHUD\", \"event_spawn\", \"be\")\n}\n\npublic plugin_precache()\n{\n // Tenter de precacher le model custom\n new szPath[128]\n formatex(szPath, charsmax(szPath), \"models/player/%s/%s.mdl\", g_szModelT, g_szModelT)\n if (file_exists(szPath))\n {\n precache_model(szPath)\n }\n}\n\npublic event_spawn(id)\n{\n if (!is_user_alive(id)) return\n if (cs_get_user_team(id) != CS_TEAM_T) return\n\n new szPath[128]\n formatex(szPath, charsmax(szPath), \"models/player/%s/%s.mdl\", g_szModelT, g_szModelT)\n if (file_exists(szPath))\n {\n cs_set_user_model(id, g_szModelT)\n }\n}\nACSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n ./amxxpc furien_skin_ac.sma -o../plugins/furien_skin_ac.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/furien_skin_ac.amxx ]; then\n grep -q \"furien_skin_ac.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"furien_skin_ac.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] furien_skin_ac.amxx compile\"\n fi\nfi\n\n# Creer le dossier model (sera rempli via FastDL)\nmkdir -p /mnt/server/cstrike/models/player/furien_assassin\necho \" [INFO] Dossier model furien_assassin cree (a remplir via FastDL)\"\n\n##############################################\n# 13) YaPB (bots Metamod)\n##############################################\necho \"\"\necho \">>> [13/16] YaPB...\"\nYAPB_URL=$(github_get_url \"yapb/yapb\" \"linux.*\\.tar\\.xz\")\nif [ -n \"$YAPB_URL\" ]; then\n curl -fsSL -o /tmp/yapb.tar.xz \"$YAPB_URL\"\n if [ -s /tmp/yapb.tar.xz ]; then\n mkdir -p /tmp/yapb\n tar -xf /tmp/yapb.tar.xz -C /tmp/yapb/\n YAPB_DIR=$(find /tmp/yapb -type d -name \"yapb\" -path \"*/addons/yapb\" | head -1)\n [ -n \"$YAPB_DIR\" ] && cp -rf \"$YAPB_DIR\" /mnt/server/cstrike/addons/\n mkdir -p /mnt/server/cstrike/addons/yapb/data/{graph,train}\n chmod -R 755 /mnt/server/cstrike/addons/yapb/data\n grep -q \"yapb\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/yapb/bin/yapb.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] YaPB installe\"\n fi\n rm -rf /tmp/yapb /tmp/yapb.tar.xz\nfi\n\n##############################################\n# 14) BotManager v2\n##############################################\necho \"\"\necho \">>> [14/16] BotManager v2...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/bot_manager.sma << 'BOTSMA'\n#include <amxmodx>\nnew g_cvarBotCount, g_cvarKickThreshold\npublic plugin_init()\n{\n register_plugin(\"BotManager\", \"2.0\", \"{{NOM_COMMUNAUTE}}Games\")\n g_cvarBotCount = register_cvar(\"bm_bot_count\", \"5\")\n g_cvarKickThreshold = register_cvar(\"bm_kick_threshold\", \"4\")\n}\npublic plugin_cfg() { set_task(3.0, \"check_bots\") }\npublic client_putinserver(id) { set_task(2.0, \"check_bots\") }\npublic client_disconnected(id, bool:drop, message[], maxlen) { set_task(1.0, \"check_bots\") }\npublic check_bots()\n{\n new humans = count_humans()\n new fill = get_pcvar_num(g_cvarBotCount)\n new threshold = get_pcvar_num(g_cvarKickThreshold)\n if (humans >= threshold) server_cmd(\"yb_quota 0\")\n else server_cmd(\"yb_quota %d\", fill)\n}\ncount_humans()\n{\n new players[32], num, count = 0\n get_players(players, num, \"ch\")\n for (new i = 0; i < num; i++) { if (!is_user_bot(players[i])) count++ }\n return count\n}\nBOTSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc bot_manager.sma -o../plugins/bot_manager.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/bot_manager.amxx ]; then\n grep -q \"bot_manager.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"bot_manager.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] bot_manager.amxx compile\"\n fi\nfi\n\n##############################################\n# 15) Advanced Quake Sounds + Maps + server.cfg\n##############################################\necho \"\"\necho \">>> [15/16] AQS...\"\ncurl -fsSL -o /tmp/aqs.zip \"https://github.com/ClaudiuHKS/AdvancedQuakeSounds/archive/refs/heads/master.zip\"\nif [ -s /tmp/aqs.zip ]; then\n unzip -qo /tmp/aqs.zip -d /tmp/aqs/\n AQS=\"/tmp/aqs/AdvancedQuakeSounds-master\"\n AMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\n if [ -f \"$AQS/AQS.sma\" ] && [ -f \"$AMXXPC\" ]; then\n cp -f \"$AQS/AQS.sma\" /mnt/server/cstrike/addons/amxmodx/scripting/\n cd /mnt/server/cstrike/addons/amxmodx/scripting && chmod +x amxxpc\n ./amxxpc AQS.sma -o../plugins/AQS.amxx 2>&1 || true\n cd /mnt/server\n fi\n [ -f \"$AQS/AQS.ini\" ] && cp -f \"$AQS/AQS.ini\" /mnt/server/cstrike/addons/amxmodx/configs/\n mkdir -p /mnt/server/cstrike/sound/AQS/\n [ -f \"$AQS/sound.zip\" ] && unzip -qo \"$AQS/sound.zip\" -d /mnt/server/cstrike/ 2>/dev/null || true\n grep -q \"AQS.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"AQS.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] AQS installe\"\n rm -rf /tmp/aqs /tmp/aqs.zip\nfi\n\necho \"\"\necho \">>> [16/16] Maps + server.cfg + fix permissions...\"\n\n# Maps depuis FastDL\nFASTDL_URL=\"https://fastdl.{{DOMAINE_GAMING}}/cs_furien\"\nwget -r -np -nH --cut-dirs=1 -P /mnt/server/cstrike/ \\\n -R \"index.html*\" --no-check-certificate -q --show-progress \\\n \"$FASTDL_URL/\" 2>&1 || echo \" [WARN] wget erreurs\"\n\nMAP_COUNT=$(find /mnt/server/cstrike/maps -name \"*.bsp\" 2>/dev/null | wc -l)\necho \" [OK] ${MAP_COUNT} maps telechargees\"\n\nEXCLUDE_MAPS=\"as_oilrig cs_747 cs_assault cs_backalley cs_estate cs_havana cs_italy cs_militia cs_office cs_siege de_airstrip de_aztec de_cbble de_chateau de_dust de_inferno de_nuke de_piranesi de_prodigy de_storm de_survivor de_torn de_train de_vertigo\"\nfind /mnt/server/cstrike/maps -name \"*.bsp\" -printf \"%f\\n\" 2>/dev/null \\\n | sed 's/\\.bsp$//' | sort > /mnt/server/cstrike/mapcycle.txt\nfor m in $EXCLUDE_MAPS; do sed -i \"/^${m}$/d\" /mnt/server/cstrike/mapcycle.txt; done\n\n# server.cfg\ncat > /mnt/server/cstrike/server.cfg << 'SERVERCFG'\nhostname \"[FR] FURIEN {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}\"\nsv_contact \"admin@{{DOMAINE_GAMING}}\"\nrcon_password \"changeme\"\n\n// Furien settings\nmp_timelimit 25\nmp_freezetime 3\nmp_roundtime 3\nmp_autoteambalance 1\nmp_friendlyfire 0\nsv_maxspeed 320\nsv_alltalk 1\nsv_voiceenable 1\n\n// Furien : T gravity + speed (geres par le plugin furien.sma)\n// furien_t_gravity 0.39\n// furien_t_speed 620\n\n// Rates\nsv_maxrate 25000\nsv_minrate 6000\nsv_maxupdaterate 102\nsv_minupdaterate 30\n\n// Downloads + FastDL\nsv_allowdownload 1\nsv_allowupload 0\nsv_downloadurl \"https://fastdl.{{DOMAINE_GAMING}}/cs_furien\"\n\n// YaPB bots\nyb_quota 5\nyb_auto_waypoint 1\nyb_chat 0\nyb_language_tag 0\n\n// BotManager v2\nbm_bot_count 5\nbm_kick_threshold 4\n\nexec banned.cfg\nexec listip.cfg\nSERVERCFG\n\n# Fix permissions\nchmod -R 755 /mnt/server/ 2>/dev/null || true\nchmod +x /mnt/server/hlds_linux /mnt/server/hlds_run /mnt/server/hlds_amd 2>/dev/null || true\n\nSTEAM_SO=$(find /mnt/server -path \"*/linux32/steamclient.so\" -not -path \"*/.steam/*\" 2>/dev/null | head -1)\n[ -n \"$STEAM_SO\" ] && cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n\necho \"\"\necho \"=============================================\"\necho \" Installation terminee !\"\necho \" Plugins : ReHLDS + ReGameDLL + Metamod-R\"\necho \" + AMX Mod X + ReAPI + Reunion\"\necho \" + Furien Pack + YaPB + BotManager v2\"\necho \" + Auto Bhop + Double Jump + Parachute\"\necho \" + Deagle 1 Balle + CT Weapons + AQS\"\necho \" + Skin Assassin Creed\"\necho \"=============================================\"\necho \"\"\necho \" Commandes joueurs:\"\necho \" T (Furien) : couteau + auto bhop + double jump\"\necho \" /deagle - Acheter Deagle 1 balle ($10000)\"\necho \" /guns - CT: choisir ses armes\"\necho \" /para - Info parachute (touche E)\"\necho \" 7 modes HE grenades (nademodes)\"\necho \"=============================================\"\n", "container": "ghcr.io/ptero-eggs/installers:debian", "entrypoint": "bash" } } } |
CS 1.6 ReHLDS – BaseBuilder
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
{ "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-03-01T12:00:00+01:00", "name": "CS 1.6 ReHLDS - BaseBuilder", "author": "admin@{{DOMAINE_GAMING}}", "description": "Counter-Strike 1.6 BaseBuilder avec ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion. Plugins : ProBaseBuilder (phases build/fight, CT munitions illimitees, buy menu CT, knife oneshot, revive, T=zombies avec gravite/vitesse/shop), YaPB bots, BotManager v2, AQS. Installation 100% automatique.", "features": null, "docker_images": { "ghcr.io/ptero-eggs/games:source": "ghcr.io/ptero-eggs/games:source" }, "file_denylist": [], "startup": "./hlds_run -console -game {{HLDS_GAME}} -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -norestart +maxplayers {{MAX_PLAYERS}} +pingboost 2 +sys_ticrate 1200 +hostname \"{{HOSTNAME}}\"", "config": { "files": "{}", "startup": "{\"done\": \"gameserver Steam\"}", "logs": "{}", "stop": "quit" }, "variables": [ { "name": "Server Hostname", "description": "Nom du serveur affiché dans le navigateur de serveurs", "env_variable": "HOSTNAME", "default_value": "[FR] BASEBUILDER {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}", "user_viewable": true, "user_editable": true, "rules": "required|string|between:1,64", "field_type": "text" }, { "name": "Default Map", "description": "Map chargée au démarrage du serveur", "env_variable": "SRCDS_MAP", "default_value": "de_dust2", "user_viewable": true, "user_editable": true, "rules": "required|string", "field_type": "text" }, { "name": "Max Players", "description": "Nombre maximum de joueurs", "env_variable": "MAX_PLAYERS", "default_value": "32", "user_viewable": true, "user_editable": true, "rules": "required|integer|between:2,32", "field_type": "text" }, { "name": "Game Folder", "description": "Dossier du jeu (ne pas modifier)", "env_variable": "HLDS_GAME", "default_value": "cstrike", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" }, { "name": "Steam App ID", "description": "App ID Steam pour CS 1.6 (ne pas modifier)", "env_variable": "SRCDS_APPID", "default_value": "90", "user_viewable": false, "user_editable": false, "rules": "required|integer", "field_type": "text" } ], "scripts": { "installation": { "script": "#!/bin/bash\ncd /mnt/server\n\napt-get update -qq && apt-get install -yqq unzip xz-utils wget > /dev/null 2>&1 || true\n\necho \"=============================================\"\necho \" CS 1.6 BaseBuilder - Installation automatique\"\necho \"=============================================\"\n\ngithub_get_url() {\n local repo=\"$1\" pattern=\"$2\" url=\"\"\n for attempt in 1 2 3; do\n url=$(curl -sSL \"https://api.github.com/repos/${repo}/releases/latest\" \\\n | grep -o '\"browser_download_url\": *\"[^\"]*\"' \\\n | grep \"${pattern}\" | head -1 \\\n | sed 's/.*\"browser_download_url\": *\"//;s/\"$//')\n if [ -n \"$url\" ]; then echo \"$url\"; return 0; fi\n sleep 3\n done\n return 1\n}\n\n##############################################\n# 1) SteamCMD + HLDS\n##############################################\necho \"\"\necho \">>> [1/14] SteamCMD + HLDS...\"\nmkdir -p steamcmd && cd steamcmd\n[ ! -f steamcmd.sh ] && curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz\ncd /mnt/server\n./steamcmd/steamcmd.sh +force_install_dir /mnt/server +login anonymous +app_update 90 -beta steam_legacy validate +quit\nmkdir -p /mnt/server/.steam/sdk32\necho \"10\" > /mnt/server/steam_appid.txt\nSTEAM_SO=$(find /mnt/server/steamcmd -path \"*/linux32/steamclient.so\" 2>/dev/null | head -1)\n[ -n \"$STEAM_SO\" ] && cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n\n##############################################\n# 2) ReHLDS\n##############################################\necho \"\"\necho \">>> [2/14] ReHLDS...\"\nREHLDS_URL=$(github_get_url \"rehlds/ReHLDS\" \"rehlds-bin.*\\.zip\")\nif [ -n \"$REHLDS_URL\" ]; then\n curl -fsSL -o /tmp/rehlds.zip \"$REHLDS_URL\"\n unzip -qo /tmp/rehlds.zip -d /tmp/rehlds/\n REHLDS_BIN=$(find /tmp/rehlds -name \"hlds_linux\" -type f | head -1)\n [ -n \"$REHLDS_BIN\" ] && cp -rf \"$(dirname \"$REHLDS_BIN\")\"/* /mnt/server/\n rm -rf /tmp/rehlds /tmp/rehlds.zip\nfi\nstrings /mnt/server/hlds_linux 2>/dev/null | grep -qi \"rehlds\" && echo \" [OK] ReHLDS\"\n\n##############################################\n# 3) ReGameDLL_CS\n##############################################\necho \"\"\necho \">>> [3/14] ReGameDLL_CS...\"\nREGAME_URL=$(github_get_url \"rehlds/ReGameDLL_CS\" \"\\.zip\")\nif [ -n \"$REGAME_URL\" ]; then\n curl -fsSL -o /tmp/regamedll.zip \"$REGAME_URL\"\n unzip -qo /tmp/regamedll.zip -d /tmp/regamedll/\n CSSO=$(find /tmp/regamedll -name \"cs.so\" -path \"*linux32*\" | head -1)\n [ -n \"$CSSO\" ] && cp -f \"$CSSO\" /mnt/server/cstrike/dlls/cs.so\n EXTRAS=$(find /tmp/regamedll -type d -name \"gamedir\" | head -1)\n [ -n \"$EXTRAS\" ] && cp -rn \"$EXTRAS\"/* /mnt/server/cstrike/ 2>/dev/null || true\n echo \" [OK] ReGameDLL\"\n rm -rf /tmp/regamedll /tmp/regamedll.zip\nfi\n\n##############################################\n# 4) Metamod-R\n##############################################\necho \"\"\necho \">>> [4/14] Metamod-R...\"\nMETAMOD_URL=$(github_get_url \"rehlds/metamod-r\" \"\\.zip\")\nif [ -n \"$METAMOD_URL\" ]; then\n curl -fsSL -o /tmp/metamod.zip \"$METAMOD_URL\"\n unzip -qo /tmp/metamod.zip -d /tmp/metamod/\n mkdir -p /mnt/server/cstrike/addons/metamod\n META_DLL=$(find /tmp/metamod -name \"metamod_i386.so\" | head -1)\n [ -n \"$META_DLL\" ] && cp -f \"$META_DLL\" /mnt/server/cstrike/addons/metamod/\n rm -rf /tmp/metamod /tmp/metamod.zip\nfi\nif [ -f /mnt/server/cstrike/addons/metamod/metamod_i386.so ]; then\n GAMEDLL_LINUX=\"addons/metamod/metamod_i386.so\"\n [ -f /mnt/server/cstrike/addons/metamod/plugins.ini ] || echo \"; Metamod plugins\" > /mnt/server/cstrike/addons/metamod/plugins.ini\nelse\n GAMEDLL_LINUX=\"dlls/cs.so\"\nfi\ncat > /mnt/server/cstrike/liblist.gam << LIBLIST\ngame \"Counter-Strike\"\nurl_info \"www.counter-strike.net\"\nurl_dl \"\"\nversion \"1.6\"\nsize \"184000000\"\nsvonly \"0\"\ncldll \"1\"\nsecure \"1\"\nhlversion \"1110\"\nnomodels \"1\"\nnohimodel \"1\"\nmpentity \"info_player_start\"\ngamedll \"dlls\\cs.dll\"\ngamedll_linux \"${GAMEDLL_LINUX}\"\ngamedll_osx \"dlls/cs.dylib\"\ntype \"multiplayer_only\"\nLIBLIST\n\n##############################################\n# 5) AMX Mod X\n##############################################\necho \"\"\necho \">>> [5/14] AMX Mod X...\"\nAMXX_DROP=\"https://www.amxmodx.org/amxxdrop/1.10\"\ncurl -fsSL -o /tmp/amxmodx-base.tar.gz \"${AMXX_DROP}/amxmodx-latest-base-linux.tar.gz\"\ncurl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"${AMXX_DROP}/amxmodx-latest-cstrike-linux.tar.gz\"\ncd /mnt/server/cstrike\ntar xzf /tmp/amxmodx-base.tar.gz 2>/dev/null || true\ntar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\nrm -f /tmp/amxmodx-base.tar.gz /tmp/amxmodx-cstrike.tar.gz\ngrep -q \"amxmodx\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/amxmodx/dlls/amxmodx_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\necho \" [OK] AMX Mod X\"\ncd /mnt/server\n\n##############################################\n# 6) ReAPI\n##############################################\necho \"\"\necho \">>> [6/14] ReAPI...\"\nREAPI_URL=$(github_get_url \"rehlds/ReAPI\" \"\\.zip\")\nif [ -n \"$REAPI_URL\" ]; then\n curl -fsSL -o /tmp/reapi.zip \"$REAPI_URL\"\n unzip -qo /tmp/reapi.zip -d /tmp/reapi/\n REAPI_SO=$(find /tmp/reapi -name \"reapi_amxx_i386.so\" | head -1)\n [ -n \"$REAPI_SO\" ] && cp -f \"$REAPI_SO\" /mnt/server/cstrike/addons/amxmodx/modules/\n grep -q \"reapi_amxx_i386.so\" /mnt/server/cstrike/addons/amxmodx/configs/modules.ini 2>/dev/null \\\n || echo \"reapi_amxx_i386.so\" >> /mnt/server/cstrike/addons/amxmodx/configs/modules.ini\n echo \" [OK] ReAPI\"\n rm -rf /tmp/reapi /tmp/reapi.zip\nfi\n\n##############################################\n# 7) Reunion\n##############################################\necho \"\"\necho \">>> [7/14] Reunion...\"\nREUNION_URL=$(github_get_url \"rehlds/ReUnion\" \"\\.zip\")\nif [ -n \"$REUNION_URL\" ]; then\n curl -fsSL -o /tmp/reunion.zip \"$REUNION_URL\"\n unzip -qo /tmp/reunion.zip -d /tmp/reunion/\n REUNION_SO=$(find /tmp/reunion -name \"reunion_mm_i386.so\" | head -1)\n if [ -n \"$REUNION_SO\" ]; then\n mkdir -p /mnt/server/cstrike/addons/reunion\n cp -f \"$REUNION_SO\" /mnt/server/cstrike/addons/reunion/\n REUNION_CFG=$(find /tmp/reunion -name \"reunion.cfg\" | head -1)\n [ -n \"$REUNION_CFG\" ] && [ ! -f /mnt/server/cstrike/reunion.cfg ] && cp -f \"$REUNION_CFG\" /mnt/server/cstrike/reunion.cfg\n if [ -f /mnt/server/cstrike/reunion.cfg ]; then\n SALT=$(grep -o 'SteamIdHashSalt *= *[^ ]*' /mnt/server/cstrike/reunion.cfg | sed 's/.*= *//')\n if [ ${#SALT} -lt 16 ]; then\n NEW_SALT=$(head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \\n' | head -c 32)\n sed -i \"s/SteamIdHashSalt *=.*/SteamIdHashSalt = ${NEW_SALT}/\" /mnt/server/cstrike/reunion.cfg\n fi\n fi\n grep -q \"reunion\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/reunion/reunion_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] Reunion\"\n fi\n rm -rf /tmp/reunion /tmp/reunion.zip\nfi\n\n##############################################\n# 8) ProBaseBuilder + CromChat\n##############################################\necho \"\"\necho \">>> [8/14] ProBaseBuilder...\"\n\n# D'abord installer CromChat (dependance)\ncurl -fsSL -o /tmp/cromchat.zip \\\n \"https://github.com/OciXCrom/CromChat/archive/refs/heads/master.zip\"\nif [ -s /tmp/cromchat.zip ]; then\n unzip -qo /tmp/cromchat.zip -d /tmp/cromchat/\n CROM_INC=$(find /tmp/cromchat -name \"cromchat.inc\" | head -1)\n [ -n \"$CROM_INC\" ] && cp -f \"$CROM_INC\" /mnt/server/cstrike/addons/amxmodx/scripting/include/\n echo \" [OK] CromChat include installe\"\n rm -rf /tmp/cromchat /tmp/cromchat.zip\nfi\n\n# ProBaseBuilder\ncurl -fsSL -o /tmp/probb.zip \\\n \"https://github.com/amirwolf5122/ProBaseBuilder/archive/refs/heads/master.zip\"\nif [ -s /tmp/probb.zip ]; then\n unzip -qo /tmp/probb.zip -d /tmp/probb/\n PROBB_DIR=$(find /tmp/probb -maxdepth 1 -type d -name \"ProBaseBuilder*\" | head -1)\n if [ -n \"$PROBB_DIR\" ]; then\n # Copier les .sma dans scripting\n find \"$PROBB_DIR\" -name \"*.sma\" -exec cp -f {} /mnt/server/cstrike/addons/amxmodx/scripting/ \\;\n # Copier les .inc dans include\n find \"$PROBB_DIR\" -name \"*.inc\" -exec cp -f {} /mnt/server/cstrike/addons/amxmodx/scripting/include/ \\;\n # Copier les .amxx pre-compiles\n find \"$PROBB_DIR\" -name \"*.amxx\" -exec cp -f {} /mnt/server/cstrike/addons/amxmodx/plugins/ \\;\n # Copier les configs\n find \"$PROBB_DIR\" -name \"*.cfg\" -path \"*/configs/*\" -exec cp -f {} /mnt/server/cstrike/addons/amxmodx/configs/ \\;\n find \"$PROBB_DIR\" -name \"*.ini\" -not -name \"plugins.ini\" -path \"*/configs/*\" -exec cp -f {} /mnt/server/cstrike/addons/amxmodx/configs/ \\;\n # Copier les models/sounds/sprites\n for dir in models sound sprites; do\n if [ -d \"$PROBB_DIR/$dir\" ]; then\n cp -rf \"$PROBB_DIR/$dir\" /mnt/server/cstrike/\n fi\n done\n echo \" [OK] ProBaseBuilder fichiers copies\"\n fi\n\n # Compiler le plugin principal\n AMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\n if [ -f \"$AMXXPC\" ]; then\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n\n # Compiler ProBaseBuilder et ses addons\n for sma in $(find . -maxdepth 1 -name \"bb_*.sma\" -o -name \"ProBaseBuilder*.sma\" -o -name \"basebuilder*.sma\" | sort); do\n name=$(basename \"$sma\" .sma)\n ./amxxpc \"$sma\" -o\"../plugins/${name}.amxx\" 2>&1 || true\n if [ -f \"../plugins/${name}.amxx\" ]; then\n grep -q \"${name}.amxx\" ../configs/plugins.ini 2>/dev/null \\\n || echo \"${name}.amxx\" >> ../configs/plugins.ini\n echo \" [OK] ${name}.amxx compile\"\n else\n echo \" [WARN] Compilation ${name} echouee\"\n fi\n done\n cd /mnt/server\n fi\n rm -rf /tmp/probb /tmp/probb.zip\nelse\n echo \" WARN: Impossible de telecharger ProBaseBuilder\"\nfi\n\n##############################################\n# 9) CT Unlimited Ammo + Buy Menu\n##############################################\necho \"\"\necho \">>> [9/14] CT Unlimited Ammo + Buy Menu...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/bb_ct_features.sma << 'CTFSMA'\n/*\n * BaseBuilder CT Features - {{NOM_COMMUNAUTE}}Games.fr\n * - Munitions illimitees pour les CT\n * - Menu d'achat CT (/buy)\n * - Knife one shot pour tous\n * - Revive CT (admin: /revive <joueur>)\n */\n#include <amxmodx>\n#include <cstrike>\n#include <fun>\n#include <fakemeta>\n#include <hamsandwich>\n\nnew const g_weapons[][] = {\n \"weapon_m4a1\", \"weapon_ak47\", \"weapon_awp\", \"weapon_famas\",\n \"weapon_mp5navy\", \"weapon_p90\", \"weapon_m3\", \"weapon_deagle\"\n}\nnew const g_weaponNames[][] = {\n \"M4A1\", \"AK-47\", \"AWP\", \"FAMAS\", \"MP5\", \"P90\", \"M3 Shotgun\", \"Deagle\"\n}\n\npublic plugin_init()\n{\n register_plugin(\"BB CT Features\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"say /buy\", \"cmd_buy\")\n register_clcmd(\"say .buy\", \"cmd_buy\")\n register_clcmd(\"say /revive\", \"cmd_revive\")\n\n // Knife one shot\n RegisterHam(Ham_TakeDamage, \"player\", \"fw_TakeDamage\")\n\n // Unlimited ammo (check chaque 0.5s)\n set_task(0.5, \"task_unlimited_ammo\", _, _, _, \"b\")\n}\n\npublic fw_TakeDamage(victim, inflictor, attacker, Float:damage, damagebits)\n{\n if (!is_user_alive(victim) || !is_user_alive(attacker)) return HAM_IGNORED\n if (attacker == victim) return HAM_IGNORED\n\n new wpnId = get_user_weapon(attacker)\n if (wpnId == CSW_KNIFE)\n {\n SetHamParamFloat(4, 999.0)\n return HAM_HANDLED\n }\n return HAM_IGNORED\n}\n\npublic task_unlimited_ammo()\n{\n new players[32], num\n get_players(players, num, \"ae\", \"CT\")\n for (new i = 0; i < num; i++)\n {\n new id = players[i]\n if (!is_user_alive(id)) continue\n\n new wpn = get_user_weapon(id)\n if (wpn > 0 && wpn != CSW_KNIFE && wpn != CSW_HEGRENADE && wpn != CSW_FLASHBANG && wpn != CSW_SMOKEGRENADE && wpn != CSW_C4)\n {\n cs_set_user_bpammo(id, wpn, 999)\n }\n }\n}\n\npublic cmd_buy(id)\n{\n if (!is_user_alive(id))\n {\n client_print(id, print_chat, \"[BB] Tu dois etre vivant !\")\n return PLUGIN_HANDLED\n }\n if (cs_get_user_team(id) != CS_TEAM_CT)\n {\n client_print(id, print_chat, \"[BB] Seuls les CT peuvent acheter des armes !\")\n return PLUGIN_HANDLED\n }\n\n new menu = menu_create(\"[CT] Choisis ton arme:\", \"buy_handler\")\n for (new i = 0; i < sizeof(g_weaponNames); i++)\n menu_additem(menu, g_weaponNames[i])\n menu_additem(menu, \"Grenades (HE+Flash+Smoke)\")\n menu_additem(menu, \"Armure 100%\")\n menu_display(id, menu)\n return PLUGIN_HANDLED\n}\n\npublic buy_handler(id, menu, item)\n{\n if (item == MENU_EXIT) { menu_destroy(menu); return PLUGIN_HANDLED }\n\n if (item < sizeof(g_weapons))\n {\n give_item(id, g_weapons[item])\n cs_set_user_bpammo(id, get_weaponid(g_weapons[item]), 999)\n client_print(id, print_chat, \"[CT] %s equipe !\", g_weaponNames[item])\n }\n else if (item == sizeof(g_weapons))\n {\n give_item(id, \"weapon_hegrenade\")\n give_item(id, \"weapon_flashbang\")\n give_item(id, \"weapon_smokegrenade\")\n client_print(id, print_chat, \"[CT] Grenades equipees !\")\n }\n else\n {\n cs_set_user_armor(id, 100, CS_ARMOR_VESTHELM)\n client_print(id, print_chat, \"[CT] Armure 100%% + Casque !\")\n }\n\n menu_destroy(menu)\n return PLUGIN_HANDLED\n}\n\npublic cmd_revive(id)\n{\n if (!(get_user_flags(id) & ADMIN_KICK))\n {\n client_print(id, print_chat, \"[BB] Commande admin uniquement !\")\n return PLUGIN_HANDLED\n }\n\n new arg[32]\n read_argv(1, arg, charsmax(arg))\n new target = cmd_target(id, arg, 1)\n if (target > 0 && !is_user_alive(target))\n {\n ExecuteHamB(Ham_CS_RoundRespawn, target)\n client_print(id, print_chat, \"[BB] Joueur revive !\")\n }\n else\n {\n client_print(id, print_chat, \"[BB] Usage: /revive <nom>\")\n }\n return PLUGIN_HANDLED\n}\nCTFSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc bb_ct_features.sma -o../plugins/bb_ct_features.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/bb_ct_features.amxx ]; then\n grep -q \"bb_ct_features.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"bb_ct_features.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] bb_ct_features.amxx compile\"\n fi\nfi\n\n# Activer modules requis\nAMXX_MODULES=\"/mnt/server/cstrike/addons/amxmodx/configs/modules.ini\"\nfor mod in fakemeta hamsandwich cstrike fun engine csx; do\n if grep -q \"^;${mod}\" \"$AMXX_MODULES\" 2>/dev/null; then\n sed -i \"s/^;${mod}/${mod}/\" \"$AMXX_MODULES\"\n echo \" [OK] Module ${mod} active\"\n fi\ndone\n\n##############################################\n# 10) YaPB\n##############################################\necho \"\"\necho \">>> [10/14] YaPB...\"\nYAPB_URL=$(github_get_url \"yapb/yapb\" \"linux.*\\.tar\\.xz\")\nif [ -n \"$YAPB_URL\" ]; then\n curl -fsSL -o /tmp/yapb.tar.xz \"$YAPB_URL\"\n if [ -s /tmp/yapb.tar.xz ]; then\n mkdir -p /tmp/yapb\n tar -xf /tmp/yapb.tar.xz -C /tmp/yapb/\n YAPB_DIR=$(find /tmp/yapb -type d -name \"yapb\" -path \"*/addons/yapb\" | head -1)\n [ -n \"$YAPB_DIR\" ] && cp -rf \"$YAPB_DIR\" /mnt/server/cstrike/addons/\n mkdir -p /mnt/server/cstrike/addons/yapb/data/{graph,train}\n chmod -R 755 /mnt/server/cstrike/addons/yapb/data\n grep -q \"yapb\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/yapb/bin/yapb.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] YaPB\"\n fi\n rm -rf /tmp/yapb /tmp/yapb.tar.xz\nfi\n\n##############################################\n# 11) BotManager v2\n##############################################\necho \"\"\necho \">>> [11/14] BotManager v2...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/bot_manager.sma << 'BOTSMA'\n#include <amxmodx>\nnew g_cvarBotCount, g_cvarKickThreshold\npublic plugin_init()\n{\n register_plugin(\"BotManager\", \"2.0\", \"{{NOM_COMMUNAUTE}}Games\")\n g_cvarBotCount = register_cvar(\"bm_bot_count\", \"5\")\n g_cvarKickThreshold = register_cvar(\"bm_kick_threshold\", \"4\")\n}\npublic plugin_cfg() { set_task(3.0, \"check_bots\") }\npublic client_putinserver(id) { set_task(2.0, \"check_bots\") }\npublic client_disconnected(id, bool:drop, message[], maxlen) { set_task(1.0, \"check_bots\") }\npublic check_bots()\n{\n new humans = count_humans()\n new fill = get_pcvar_num(g_cvarBotCount)\n new threshold = get_pcvar_num(g_cvarKickThreshold)\n if (humans >= threshold) server_cmd(\"yb_quota 0\")\n else server_cmd(\"yb_quota %d\", fill)\n}\ncount_humans()\n{\n new players[32], num, count = 0\n get_players(players, num, \"ch\")\n for (new i = 0; i < num; i++) { if (!is_user_bot(players[i])) count++ }\n return count\n}\nBOTSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc bot_manager.sma -o../plugins/bot_manager.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/bot_manager.amxx ]; then\n grep -q \"bot_manager.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"bot_manager.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] bot_manager.amxx\"\n fi\nfi\n\n##############################################\n# 12) Advanced Quake Sounds\n##############################################\necho \"\"\necho \">>> [12/14] AQS...\"\ncurl -fsSL -o /tmp/aqs.zip \"https://github.com/ClaudiuHKS/AdvancedQuakeSounds/archive/refs/heads/master.zip\"\nif [ -s /tmp/aqs.zip ]; then\n unzip -qo /tmp/aqs.zip -d /tmp/aqs/\n AQS=\"/tmp/aqs/AdvancedQuakeSounds-master\"\n AMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\n if [ -f \"$AQS/AQS.sma\" ] && [ -f \"$AMXXPC\" ]; then\n cp -f \"$AQS/AQS.sma\" /mnt/server/cstrike/addons/amxmodx/scripting/\n cd /mnt/server/cstrike/addons/amxmodx/scripting && chmod +x amxxpc\n ./amxxpc AQS.sma -o../plugins/AQS.amxx 2>&1 || true\n cd /mnt/server\n fi\n [ -f \"$AQS/AQS.ini\" ] && cp -f \"$AQS/AQS.ini\" /mnt/server/cstrike/addons/amxmodx/configs/\n mkdir -p /mnt/server/cstrike/sound/AQS/\n [ -f \"$AQS/sound.zip\" ] && unzip -qo \"$AQS/sound.zip\" -d /mnt/server/cstrike/ 2>/dev/null || true\n grep -q \"AQS.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"AQS.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] AQS\"\n rm -rf /tmp/aqs /tmp/aqs.zip\nfi\n\n##############################################\n# 13) Maps depuis FastDL\n##############################################\necho \"\"\necho \">>> [13/14] Maps...\"\nFASTDL_URL=\"https://fastdl.{{DOMAINE_GAMING}}/cs_basebuilder\"\nwget -r -np -nH --cut-dirs=1 -P /mnt/server/cstrike/ \\\n -R \"index.html*\" --no-check-certificate -q --show-progress \\\n \"$FASTDL_URL/\" 2>&1 || echo \" [WARN] wget erreurs\"\n\nMAP_COUNT=$(find /mnt/server/cstrike/maps -name \"*.bsp\" 2>/dev/null | wc -l)\necho \" [OK] ${MAP_COUNT} maps\"\n\nEXCLUDE_MAPS=\"as_oilrig cs_747 cs_assault cs_backalley cs_estate cs_havana cs_italy cs_militia cs_office cs_siege de_airstrip de_aztec de_cbble de_chateau de_dust de_inferno de_nuke de_piranesi de_prodigy de_storm de_survivor de_torn de_train de_vertigo\"\nfind /mnt/server/cstrike/maps -name \"*.bsp\" -printf \"%f\\n\" 2>/dev/null \\\n | sed 's/\\.bsp$//' | sort > /mnt/server/cstrike/mapcycle.txt\nfor m in $EXCLUDE_MAPS; do sed -i \"/^${m}$/d\" /mnt/server/cstrike/mapcycle.txt; done\n\n##############################################\n# 14) server.cfg + fix permissions\n##############################################\necho \"\"\necho \">>> [14/14] server.cfg + fix permissions...\"\ncat > /mnt/server/cstrike/server.cfg << 'SERVERCFG'\nhostname \"[FR] BASEBUILDER {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}\"\nsv_contact \"admin@{{DOMAINE_GAMING}}\"\nrcon_password \"changeme\"\n\n// BaseBuilder settings\nmp_timelimit 30\nmp_freezetime 0\nmp_roundtime 5\nmp_autoteambalance 0\nmp_friendlyfire 0\nsv_maxspeed 320\nsv_alltalk 1\nsv_voiceenable 1\n\n// Rates\nsv_maxrate 25000\nsv_minrate 6000\nsv_maxupdaterate 102\nsv_minupdaterate 30\n\n// Downloads + FastDL\nsv_allowdownload 1\nsv_allowupload 0\nsv_downloadurl \"https://fastdl.{{DOMAINE_GAMING}}/cs_basebuilder\"\n\n// YaPB bots\nyb_quota 5\nyb_auto_waypoint 1\nyb_chat 0\nyb_language_tag 0\n\n// BotManager v2\nbm_bot_count 5\nbm_kick_threshold 4\n\nexec banned.cfg\nexec listip.cfg\nSERVERCFG\n\nchmod -R 755 /mnt/server/ 2>/dev/null || true\nchmod +x /mnt/server/hlds_linux /mnt/server/hlds_run /mnt/server/hlds_amd 2>/dev/null || true\nSTEAM_SO=$(find /mnt/server -path \"*/linux32/steamclient.so\" -not -path \"*/.steam/*\" 2>/dev/null | head -1)\n[ -n \"$STEAM_SO\" ] && cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n\necho \"\"\necho \"=============================================\"\necho \" Installation terminee !\"\necho \" Plugins : ReHLDS + ReGameDLL + Metamod-R\"\necho \" + AMX Mod X + ReAPI + Reunion\"\necho \" + ProBaseBuilder + YaPB + BotManager v2\"\necho \" + CT Features (unlim ammo, buy, knife OS)\"\necho \" + AQS\"\necho \"=============================================\"\necho \"\"\necho \" Gameplay BaseBuilder:\"\necho \" Phase Build : T construisent des bases avec les blocs\"\necho \" Phase Fight : CT attaquent, T defendent\"\necho \" CT: /buy pour armes, munitions illimitees\"\necho \" T: zombies avec gravite/vitesse speciale\"\necho \" Knife one shot pour tous\"\necho \"=============================================\"\n", "container": "ghcr.io/ptero-eggs/installers:debian", "entrypoint": "bash" } } } |
CS 1.6 ReHLDS – Fun
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
{ "meta": { "version": "PTDL_v2", "update_url": null }, "exported_at": "2026-03-01T15:00:00+01:00", "name": "CS 1.6 ReHLDS - Fun", "author": "admin@{{DOMAINE_GAMING}}", "description": "Counter-Strike 1.6 Fun Server avec ReHLDS, ReGameDLL, Metamod-R, AMX Mod X, ReAPI, Reunion. 19 plugins fun : RPG Mod, Rank System, Day/Night, Colored Nades, Bullet Damage, Parachute, No Team Flash, AWP Limit, Bomb Status, Quake Sounds, Back Weapon, Free Defuser, et plus. YaPB bots + BotManager v2.", "features": null, "docker_images": { "ghcr.io/ptero-eggs/games:source": "ghcr.io/ptero-eggs/games:source" }, "file_denylist": [], "startup": "./hlds_run -console -game {{HLDS_GAME}} -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -norestart +maxplayers {{MAX_PLAYERS}} +pingboost 2 +sys_ticrate 1200 +hostname \"{{HOSTNAME}}\"", "config": { "files": "{}", "startup": "{\"done\": \"gameserver Steam\"}", "logs": "{}", "stop": "quit" }, "variables": [ { "name": "Server Hostname", "description": "Nom du serveur", "env_variable": "HOSTNAME", "default_value": "[FR] FUN SERVER {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}", "user_viewable": true, "user_editable": true, "rules": "required|string|between:1,64", "field_type": "text" }, { "name": "Default Map", "description": "Map de demarrage", "env_variable": "SRCDS_MAP", "default_value": "de_dust2", "user_viewable": true, "user_editable": true, "rules": "required|string", "field_type": "text" }, { "name": "Max Players", "description": "Nombre maximum de joueurs", "env_variable": "MAX_PLAYERS", "default_value": "32", "user_viewable": true, "user_editable": true, "rules": "required|integer|between:2,32", "field_type": "text" }, { "name": "Game Folder", "description": "Ne pas modifier", "env_variable": "HLDS_GAME", "default_value": "cstrike", "user_viewable": false, "user_editable": false, "rules": "required|string", "field_type": "text" }, { "name": "Steam App ID", "description": "Ne pas modifier", "env_variable": "SRCDS_APPID", "default_value": "90", "user_viewable": false, "user_editable": false, "rules": "required|integer", "field_type": "text" } ], "scripts": { "installation": { "script": "#!/bin/bash\ncd /mnt/server\n\napt-get update -qq && apt-get install -yqq unzip xz-utils wget > /dev/null 2>&1 || true\n\necho \"=============================================\"\necho \" CS 1.6 Fun Server - Installation automatique\"\necho \" 19 plugins fun + ReHLDS stack\"\necho \"=============================================\"\n\ngithub_get_url() {\n local repo=\"$1\" pattern=\"$2\" url=\"\"\n for attempt in 1 2 3; do\n url=$(curl -sSL \"https://api.github.com/repos/${repo}/releases/latest\" \\\n | grep -o '\"browser_download_url\": *\"[^\"]*\"' \\\n | grep \"${pattern}\" | head -1 \\\n | sed 's/.*\"browser_download_url\": *\"//;s/\"$//')\n if [ -n \"$url\" ]; then echo \"$url\"; return 0; fi\n sleep 3\n done\n return 1\n}\n\n##############################################\n# 1) SteamCMD + HLDS\n##############################################\necho \"\"\necho \">>> [1/17] SteamCMD + HLDS...\"\nmkdir -p steamcmd && cd steamcmd\n[ ! -f steamcmd.sh ] && curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar xz\ncd /mnt/server\n./steamcmd/steamcmd.sh +force_install_dir /mnt/server +login anonymous +app_update 90 -beta steam_legacy validate +quit\nmkdir -p /mnt/server/.steam/sdk32\necho \"10\" > /mnt/server/steam_appid.txt\nSTEAM_SO=$(find /mnt/server/steamcmd -path \"*/linux32/steamclient.so\" 2>/dev/null | head -1)\n[ -n \"$STEAM_SO\" ] && cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n\n##############################################\n# 2) ReHLDS\n##############################################\necho \"\"\necho \">>> [2/17] ReHLDS...\"\nREHLDS_URL=$(github_get_url \"rehlds/ReHLDS\" \"rehlds-bin.*\\.zip\")\nif [ -n \"$REHLDS_URL\" ]; then\n curl -fsSL -o /tmp/rehlds.zip \"$REHLDS_URL\"\n unzip -qo /tmp/rehlds.zip -d /tmp/rehlds/\n REHLDS_BIN=$(find /tmp/rehlds -name \"hlds_linux\" -type f | head -1)\n [ -n \"$REHLDS_BIN\" ] && cp -rf \"$(dirname \"$REHLDS_BIN\")\"/* /mnt/server/\n rm -rf /tmp/rehlds /tmp/rehlds.zip\nfi\nstrings /mnt/server/hlds_linux 2>/dev/null | grep -qi \"rehlds\" && echo \" [OK] ReHLDS\"\n\n##############################################\n# 3) ReGameDLL_CS\n##############################################\necho \"\"\necho \">>> [3/17] ReGameDLL_CS...\"\nREGAME_URL=$(github_get_url \"rehlds/ReGameDLL_CS\" \"\\.zip\")\nif [ -n \"$REGAME_URL\" ]; then\n curl -fsSL -o /tmp/regamedll.zip \"$REGAME_URL\"\n unzip -qo /tmp/regamedll.zip -d /tmp/regamedll/\n CSSO=$(find /tmp/regamedll -name \"cs.so\" -path \"*linux32*\" | head -1)\n [ -n \"$CSSO\" ] && cp -f \"$CSSO\" /mnt/server/cstrike/dlls/cs.so\n EXTRAS=$(find /tmp/regamedll -type d -name \"gamedir\" | head -1)\n [ -n \"$EXTRAS\" ] && cp -rn \"$EXTRAS\"/* /mnt/server/cstrike/ 2>/dev/null || true\n echo \" [OK] ReGameDLL\"\n rm -rf /tmp/regamedll /tmp/regamedll.zip\nfi\n\n##############################################\n# 4) Metamod-R\n##############################################\necho \"\"\necho \">>> [4/17] Metamod-R...\"\nMETAMOD_URL=$(github_get_url \"rehlds/metamod-r\" \"\\.zip\")\nif [ -n \"$METAMOD_URL\" ]; then\n curl -fsSL -o /tmp/metamod.zip \"$METAMOD_URL\"\n unzip -qo /tmp/metamod.zip -d /tmp/metamod/\n mkdir -p /mnt/server/cstrike/addons/metamod\n META_DLL=$(find /tmp/metamod -name \"metamod_i386.so\" | head -1)\n [ -n \"$META_DLL\" ] && cp -f \"$META_DLL\" /mnt/server/cstrike/addons/metamod/\n rm -rf /tmp/metamod /tmp/metamod.zip\nfi\nif [ -f /mnt/server/cstrike/addons/metamod/metamod_i386.so ]; then\n GAMEDLL_LINUX=\"addons/metamod/metamod_i386.so\"\n [ -f /mnt/server/cstrike/addons/metamod/plugins.ini ] || echo \"; Metamod plugins\" > /mnt/server/cstrike/addons/metamod/plugins.ini\nelse\n GAMEDLL_LINUX=\"dlls/cs.so\"\nfi\ncat > /mnt/server/cstrike/liblist.gam << LIBLIST\ngame \"Counter-Strike\"\nurl_info \"www.counter-strike.net\"\nurl_dl \"\"\nversion \"1.6\"\nsize \"184000000\"\nsvonly \"0\"\ncldll \"1\"\nsecure \"1\"\nhlversion \"1110\"\nnomodels \"1\"\nnohimodel \"1\"\nmpentity \"info_player_start\"\ngamedll \"dlls\\cs.dll\"\ngamedll_linux \"${GAMEDLL_LINUX}\"\ngamedll_osx \"dlls/cs.dylib\"\ntype \"multiplayer_only\"\nLIBLIST\n\n##############################################\n# 5) AMX Mod X\n##############################################\necho \"\"\necho \">>> [5/17] AMX Mod X...\"\nAMXX_DROP=\"https://www.amxmodx.org/amxxdrop/1.10\"\ncurl -fsSL -o /tmp/amxmodx-base.tar.gz \"${AMXX_DROP}/amxmodx-latest-base-linux.tar.gz\"\ncurl -fsSL -o /tmp/amxmodx-cstrike.tar.gz \"${AMXX_DROP}/amxmodx-latest-cstrike-linux.tar.gz\"\ncd /mnt/server/cstrike\ntar xzf /tmp/amxmodx-base.tar.gz 2>/dev/null || true\ntar xzf /tmp/amxmodx-cstrike.tar.gz 2>/dev/null || true\nrm -f /tmp/amxmodx-base.tar.gz /tmp/amxmodx-cstrike.tar.gz\ngrep -q \"amxmodx\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/amxmodx/dlls/amxmodx_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\necho \" [OK] AMX Mod X\"\ncd /mnt/server\n\n##############################################\n# 6) ReAPI\n##############################################\necho \"\"\necho \">>> [6/17] ReAPI...\"\nREAPI_URL=$(github_get_url \"rehlds/ReAPI\" \"\\.zip\")\nif [ -n \"$REAPI_URL\" ]; then\n curl -fsSL -o /tmp/reapi.zip \"$REAPI_URL\"\n unzip -qo /tmp/reapi.zip -d /tmp/reapi/\n REAPI_SO=$(find /tmp/reapi -name \"reapi_amxx_i386.so\" | head -1)\n [ -n \"$REAPI_SO\" ] && cp -f \"$REAPI_SO\" /mnt/server/cstrike/addons/amxmodx/modules/\n grep -q \"reapi_amxx_i386.so\" /mnt/server/cstrike/addons/amxmodx/configs/modules.ini 2>/dev/null \\\n || echo \"reapi_amxx_i386.so\" >> /mnt/server/cstrike/addons/amxmodx/configs/modules.ini\n echo \" [OK] ReAPI\"\n rm -rf /tmp/reapi /tmp/reapi.zip\nfi\n\n##############################################\n# 7) Reunion\n##############################################\necho \"\"\necho \">>> [7/17] Reunion...\"\nREUNION_URL=$(github_get_url \"rehlds/ReUnion\" \"\\.zip\")\nif [ -n \"$REUNION_URL\" ]; then\n curl -fsSL -o /tmp/reunion.zip \"$REUNION_URL\"\n unzip -qo /tmp/reunion.zip -d /tmp/reunion/\n REUNION_SO=$(find /tmp/reunion -name \"reunion_mm_i386.so\" | head -1)\n if [ -n \"$REUNION_SO\" ]; then\n mkdir -p /mnt/server/cstrike/addons/reunion\n cp -f \"$REUNION_SO\" /mnt/server/cstrike/addons/reunion/\n REUNION_CFG=$(find /tmp/reunion -name \"reunion.cfg\" | head -1)\n [ -n \"$REUNION_CFG\" ] && [ ! -f /mnt/server/cstrike/reunion.cfg ] && cp -f \"$REUNION_CFG\" /mnt/server/cstrike/reunion.cfg\n if [ -f /mnt/server/cstrike/reunion.cfg ]; then\n SALT=$(grep -o 'SteamIdHashSalt *= *[^ ]*' /mnt/server/cstrike/reunion.cfg | sed 's/.*= *//')\n if [ ${#SALT} -lt 16 ]; then\n NEW_SALT=$(head -c 48 /dev/urandom | od -An -tx1 | tr -d ' \\n' | head -c 32)\n sed -i \"s/SteamIdHashSalt *=.*/SteamIdHashSalt = ${NEW_SALT}/\" /mnt/server/cstrike/reunion.cfg\n fi\n fi\n grep -q \"reunion\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/reunion/reunion_mm_i386.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] Reunion\"\n fi\n rm -rf /tmp/reunion /tmp/reunion.zip\nfi\n\n##############################################\n# 8) Fun Plugins (19 plugins)\n##############################################\necho \"\"\necho \">>> [8/17] Fun Plugins (19 plugins)...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n\n # ============================\n # 1. Bomb Status\n # ============================\n cat > fun_bombstatus.sma << 'PLUGIN01'\n#include <amxmodx>\n#include <cstrike>\n\nnew g_bombCarrier\nnew g_bombPlanted\n\npublic plugin_init()\n{\n register_plugin(\"Bomb Status\", \"1.7\", \"{{NOM_COMMUNAUTE}}Games\")\n register_logevent(\"bomb_planted\", 3, \"2=Planted_The_Bomb\")\n register_logevent(\"bomb_defused\", 3, \"2=Defused_The_Bomb\")\n register_logevent(\"round_start\", 2, \"1=Round_Start\")\n register_event(\"StatusIcon\", \"bomb_pickup\", \"be\", \"1=1\", \"2=c4\")\n register_event(\"StatusIcon\", \"bomb_drop\", \"be\", \"1=0\", \"2=c4\")\n register_event(\"TextMsg\", \"bomb_drop_msg\", \"a\", \"2=#Game_bomb_drop\")\n set_task(1.0, \"show_status\", _, _, _, \"b\")\n}\n\npublic round_start() { g_bombPlanted = 0; g_bombCarrier = 0 }\npublic bomb_planted() { g_bombPlanted = 1 }\npublic bomb_defused() { g_bombPlanted = 0 }\npublic bomb_pickup(id) { g_bombCarrier = id }\npublic bomb_drop(id) { if (g_bombCarrier == id) g_bombCarrier = 0 }\npublic bomb_drop_msg() { g_bombCarrier = 0 }\n\npublic show_status()\n{\n if (g_bombPlanted)\n set_hudmessage(255, 50, 50, 0.02, 0.22, 0, 0.0, 1.1, 0.0, 0.0, 4)\n else if (g_bombCarrier > 0 && is_user_alive(g_bombCarrier))\n {\n new name[32]\n get_user_name(g_bombCarrier, name, charsmax(name))\n set_hudmessage(255, 200, 0, 0.02, 0.22, 0, 0.0, 1.1, 0.0, 0.0, 4)\n show_hudmessage(0, \"Bombe: %s\", name)\n return\n }\n else return\n\n if (g_bombPlanted)\n show_hudmessage(0, \"!! BOMBE PLANTEE !!\")\n}\nPLUGIN01\n\n # ============================\n # 2. Teams Manager\n # ============================\n cat > fun_teams_manager.sma << 'PLUGIN02'\n#include <amxmodx>\n#include <cstrike>\n#include <fun>\n\npublic plugin_init()\n{\n register_plugin(\"Teams Manager\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"say /swap\", \"cmd_swap\")\n register_clcmd(\"say /teams\", \"cmd_teams\")\n set_task(30.0, \"auto_balance\", _, _, _, \"b\")\n}\n\npublic cmd_swap(id)\n{\n if (!(get_user_flags(id) & ADMIN_KICK)) return PLUGIN_HANDLED\n new arg[32]\n read_argv(1, arg, charsmax(arg))\n new target = cmd_target(id, arg, 1)\n if (target > 0)\n {\n new CsTeams:team = cs_get_user_team(target)\n cs_set_user_team(target, (team == CS_TEAM_T) ? CS_TEAM_CT : CS_TEAM_T)\n client_print(id, print_chat, \"[Teams] Joueur swap!\")\n }\n return PLUGIN_HANDLED\n}\n\npublic cmd_teams(id)\n{\n new t=0, ct=0, players[32], num\n get_players(players, num)\n for (new i = 0; i < num; i++)\n {\n new CsTeams:team = cs_get_user_team(players[i])\n if (team == CS_TEAM_T) t++\n else if (team == CS_TEAM_CT) ct++\n }\n client_print(id, print_chat, \"[Teams] T: %d | CT: %d\", t, ct)\n return PLUGIN_HANDLED\n}\n\npublic auto_balance()\n{\n new t=0, ct=0, players[32], num\n get_players(players, num, \"h\")\n for (new i = 0; i < num; i++)\n {\n new CsTeams:team = cs_get_user_team(players[i])\n if (team == CS_TEAM_T) t++\n else if (team == CS_TEAM_CT) ct++\n }\n if (t - ct >= 2 || ct - t >= 2)\n {\n set_hudmessage(255, 255, 0, -1.0, 0.3, 0, 0.0, 3.0, 0.0, 0.0)\n show_hudmessage(0, \"[AutoBalance] Equilibrage des equipes...\")\n }\n}\nPLUGIN02\n\n # ============================\n # 3. Accuracy Fix\n # ============================\n cat > fun_accuracy_fix.sma << 'PLUGIN03'\n#include <amxmodx>\n#include <fakemeta>\n\npublic plugin_init()\n{\n register_plugin(\"Accuracy Fix\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlaybackEvent, \"fw_PlaybackEvent\")\n}\n\npublic fw_PlaybackEvent(flags, invoker, eventindex, Float:delay, Float:Origin[3], Float:Angles[3], Float:fparam1, Float:fparam2, iParam1, iParam2, bParam1, bParam2)\n{\n if (!(1 <= invoker <= 32) || !is_user_alive(invoker)) return FMRES_IGNORED\n // Reduce spread for better accuracy feel\n fparam1 *= 0.5\n fparam2 *= 0.5\n return FMRES_HANDLED\n}\nPLUGIN03\n\n # ============================\n # 4. Team Grenade Trail\n # ============================\n cat > fun_grenade_trail.sma << 'PLUGIN04'\n#include <amxmodx>\n#include <fakemeta>\n#include <cstrike>\n#include <engine>\n\nnew g_sprTrail\n\npublic plugin_init()\n{\n register_plugin(\"Grenade Trail\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_SetModel, \"fw_SetModel\")\n}\n\npublic plugin_precache()\n{\n g_sprTrail = precache_model(\"sprites/laserbeam.spr\")\n}\n\npublic fw_SetModel(ent, const model[])\n{\n if (!pev_valid(ent)) return FMRES_IGNORED\n if (model[9] != 'w' || model[10] != '_') return FMRES_IGNORED\n\n new bool:isNade = false\n if (containi(model, \"hegrenade\") != -1) isNade = true\n else if (containi(model, \"flashbang\") != -1) isNade = true\n else if (containi(model, \"smokegrenade\") != -1) isNade = true\n\n if (!isNade) return FMRES_IGNORED\n\n new owner = pev(ent, pev_owner)\n if (!(1 <= owner <= 32)) return FMRES_IGNORED\n\n new r, g, b\n if (cs_get_user_team(owner) == CS_TEAM_T)\n { r = 255; g = 50; b = 50; }\n else\n { r = 50; g = 50; b = 255; }\n\n message_begin(MSG_BROADCAST, SVC_TEMPENTITY)\n write_byte(TE_BEAMFOLLOW)\n write_short(ent)\n write_short(g_sprTrail)\n write_byte(15)\n write_byte(5)\n write_byte(r)\n write_byte(g)\n write_byte(b)\n write_byte(200)\n message_end()\n\n return FMRES_IGNORED\n}\nPLUGIN04\n\n # ============================\n # 5. Day/Night Effect\n # ============================\n cat > fun_daynight.sma << 'PLUGIN05'\n#include <amxmodx>\n#include <fakemeta>\n\nnew g_cycle\nnew g_brightness\n\npublic plugin_init()\n{\n register_plugin(\"Day Night Effect\", \"1.3\", \"{{NOM_COMMUNAUTE}}Games\")\n g_cycle = 0\n g_brightness = 100\n set_task(60.0, \"cycle_time\", _, _, _, \"b\")\n}\n\npublic cycle_time()\n{\n g_cycle++\n if (g_cycle > 10) g_cycle = 0\n\n // Cycle: 0-3 jour, 4-6 coucher, 7-9 nuit, 10 lever\n if (g_cycle <= 3)\n g_brightness = 100\n else if (g_cycle <= 6)\n g_brightness = 100 - ((g_cycle - 3) * 25)\n else if (g_cycle <= 9)\n g_brightness = 25\n else\n g_brightness = 75\n\n new players[32], num\n get_players(players, num, \"c\")\n for (new i = 0; i < num; i++)\n {\n new id = players[i]\n message_begin(MSG_ONE, get_user_msgid(\"ScreenFade\"), _, id)\n write_short(1<<12)\n write_short(1<<12)\n write_short(0x0004)\n write_byte(0)\n write_byte(0)\n write_byte(0)\n write_byte(255 - floatround(float(g_brightness) * 2.55))\n message_end()\n }\n\n new szTime[16]\n switch(g_cycle)\n {\n case 0,1,2,3: szTime = \"Jour\"\n case 4,5,6: szTime = \"Crepuscule\"\n case 7,8,9: szTime = \"Nuit\"\n case 10: szTime = \"Aube\"\n }\n set_hudmessage(200, 200, 200, 0.02, 0.95, 0, 0.0, 5.0, 0.0, 0.0)\n show_hudmessage(0, \">> %s <<\", szTime)\n}\nPLUGIN05\n\n # ============================\n # 6. Quake Style Switch (fast weapon switch)\n # ============================\n cat > fun_quake_switch.sma << 'PLUGIN06'\n#include <amxmodx>\n#include <fakemeta>\n\npublic plugin_init()\n{\n register_plugin(\"Quake Switch\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_CmdStart, \"fw_CmdStart\")\n}\n\npublic fw_CmdStart(id, uc_handle, seed)\n{\n if (!is_user_alive(id)) return FMRES_IGNORED\n // Accelerer le switch d'arme\n set_pev(id, pev_weaponanim, 0)\n return FMRES_IGNORED\n}\nPLUGIN06\n\n # ============================\n # 7. RPG Mod (XP + Levels + Skills)\n # ============================\n cat > fun_rpg.sma << 'PLUGIN07'\n#include <amxmodx>\n#include <cstrike>\n#include <fun>\n#include <hamsandwich>\n#include <fakemeta>\n\n#define MAX_LEVEL 50\n#define XP_KILL 25\n#define XP_HEADSHOT 40\n#define XP_BOMB_PLANT 30\n#define XP_BOMB_DEFUSE 30\n\nnew g_xp[33]\nnew g_level[33]\n\n// XP requis par niveau (simplifie)\nxp_required(level) { return level * 100 }\n\npublic plugin_init()\n{\n register_plugin(\"RPG Mod\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_event(\"DeathMsg\", \"event_death\", \"a\")\n register_logevent(\"bomb_planted\", 3, \"2=Planted_The_Bomb\")\n register_logevent(\"bomb_defused\", 3, \"2=Defused_The_Bomb\")\n register_clcmd(\"say /rpg\", \"cmd_rpg\")\n register_clcmd(\"say /level\", \"cmd_rpg\")\n register_clcmd(\"say /xp\", \"cmd_rpg\")\n register_clcmd(\"say /top\", \"cmd_top\")\n RegisterHam(Ham_Spawn, \"player\", \"fw_Spawn_Post\", 1)\n}\n\npublic client_putinserver(id)\n{\n g_xp[id] = 0\n g_level[id] = 1\n}\n\npublic event_death()\n{\n new killer = read_data(1)\n new victim = read_data(2)\n new hs = read_data(3)\n if (killer == victim || killer < 1 || killer > 32) return\n\n new xp_gain = hs ? XP_HEADSHOT : XP_KILL\n add_xp(killer, xp_gain)\n}\n\npublic bomb_planted()\n{\n new players[32], num\n get_players(players, num, \"ae\", \"TERRORIST\")\n for (new i = 0; i < num; i++)\n {\n // Donner XP au porteur de bombe (simplifie: tous les T)\n }\n}\n\nadd_xp(id, amount)\n{\n g_xp[id] += amount\n new required = xp_required(g_level[id])\n\n if (g_xp[id] >= required && g_level[id] < MAX_LEVEL)\n {\n g_xp[id] -= required\n g_level[id]++\n\n new name[32]\n get_user_name(id, name, charsmax(name))\n set_hudmessage(0, 255, 0, -1.0, 0.3, 2, 0.5, 3.0)\n show_hudmessage(0, \"%s >> LEVEL %d !\", name, g_level[id])\n\n // Bonus de niveau\n if (is_user_alive(id))\n {\n set_user_health(id, get_user_health(id) + 10)\n cs_set_user_money(id, cs_get_user_money(id) + 500)\n }\n client_print(id, print_chat, \"[RPG] Level UP! Niveau %d (+10 HP, +$500)\", g_level[id])\n }\n else\n {\n client_print(id, print_chat, \"[RPG] +%d XP (%d/%d)\", amount, g_xp[id], required)\n }\n}\n\npublic fw_Spawn_Post(id)\n{\n if (!is_user_alive(id)) return\n\n // Bonus HP par niveau\n new bonus_hp = (g_level[id] - 1) * 2\n if (bonus_hp > 0)\n set_user_health(id, get_user_health(id) + bonus_hp)\n\n // Bonus armure a partir du niveau 5\n if (g_level[id] >= 5)\n cs_set_user_armor(id, 100, CS_ARMOR_VESTHELM)\n\n // Bonus argent\n new bonus_money = g_level[id] * 100\n new money = cs_get_user_money(id) + bonus_money\n if (money > 16000) money = 16000\n cs_set_user_money(id, money)\n}\n\npublic cmd_rpg(id)\n{\n client_print(id, print_chat, \"[RPG] Niveau: %d | XP: %d/%d | Bonus HP: +%d\",\n g_level[id], g_xp[id], xp_required(g_level[id]), (g_level[id]-1)*2)\n return PLUGIN_HANDLED\n}\n\npublic cmd_top(id)\n{\n client_print(id, print_chat, \"[RPG] === TOP Joueurs ===\")\n new players[32], num, name[32]\n get_players(players, num)\n // Simple: afficher les 5 premiers par niveau\n for (new i = 0; i < num && i < 5; i++)\n {\n get_user_name(players[i], name, charsmax(name))\n client_print(id, print_chat, \" %d. %s - Lvl %d (%d XP)\", i+1, name, g_level[players[i]], g_xp[players[i]])\n }\n return PLUGIN_HANDLED\n}\nPLUGIN07\n\n # ============================\n # 8. Colored Smokenades\n # ============================\n cat > fun_colored_smoke.sma << 'PLUGIN08'\n#include <amxmodx>\n#include <fakemeta>\n#include <cstrike>\n\npublic plugin_init()\n{\n register_plugin(\"Colored Smoke\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_event(\"99\", \"smoke_event\", \"a\")\n register_forward(FM_SetModel, \"fw_SetModel_Smoke\")\n}\n\npublic fw_SetModel_Smoke(ent, const model[])\n{\n if (!pev_valid(ent)) return FMRES_IGNORED\n if (containi(model, \"smokegrenade\") == -1) return FMRES_IGNORED\n\n new owner = pev(ent, pev_owner)\n if (!(1 <= owner <= 32)) return FMRES_IGNORED\n\n // Couleur par equipe\n new Float:color[3]\n if (cs_get_user_team(owner) == CS_TEAM_T)\n { color[0] = 255.0; color[1] = 100.0; color[2] = 0.0; }\n else\n { color[0] = 0.0; color[1] = 100.0; color[2] = 255.0; }\n\n set_pev(ent, pev_rendercolor, color)\n set_pev(ent, pev_rendermode, 5)\n set_pev(ent, pev_renderamt, 200.0)\n\n return FMRES_IGNORED\n}\nPLUGIN08\n\n # ============================\n # 9. Free Defuser Kit\n # ============================\n cat > fun_free_defuser.sma << 'PLUGIN09'\n#include <amxmodx>\n#include <cstrike>\n#include <hamsandwich>\n\npublic plugin_init()\n{\n register_plugin(\"Free Defuser\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n RegisterHam(Ham_Spawn, \"player\", \"fw_Spawn_Defuser\", 1)\n}\n\npublic fw_Spawn_Defuser(id)\n{\n if (!is_user_alive(id)) return\n if (cs_get_user_team(id) == CS_TEAM_CT)\n {\n cs_set_user_defuse(id, 1)\n }\n}\nPLUGIN09\n\n # ============================\n # 10. Unreal (kill streak announcements)\n # ============================\n cat > fun_unreal.sma << 'PLUGIN10'\n#include <amxmodx>\n\nnew g_killStreak[33]\n\nnew const g_streakNames[][] = {\n \"\", \"\", \"DOUBLE KILL\", \"MULTI KILL\", \"ULTRA KILL\",\n \"MONSTER KILL\", \"GODLIKE\", \"HOLY SHIT\", \"UNSTOPPABLE\",\n \"WICKED SICK\", \"LEGENDARY\"\n}\nnew const g_streakColors[][3] = {\n {0,0,0}, {0,0,0}, {255,255,0}, {255,200,0}, {255,150,0},\n {255,100,0}, {255,50,0}, {255,0,0}, {200,0,50},\n {150,0,100}, {255,0,255}\n}\n\npublic plugin_init()\n{\n register_plugin(\"Unreal\", \"1.2\", \"{{NOM_COMMUNAUTE}}Games\")\n register_event(\"DeathMsg\", \"event_death\", \"a\")\n register_logevent(\"round_start\", 2, \"1=Round_Start\")\n}\n\npublic client_putinserver(id) { g_killStreak[id] = 0 }\n\npublic round_start()\n{\n for (new i = 1; i <= 32; i++) g_killStreak[i] = 0\n}\n\npublic event_death()\n{\n new killer = read_data(1)\n new victim = read_data(2)\n if (killer == victim || killer < 1 || killer > 32) return\n\n g_killStreak[victim] = 0\n g_killStreak[killer]++\n\n new streak = g_killStreak[killer]\n if (streak >= 2 && streak <= 10)\n {\n new name[32]\n get_user_name(killer, name, charsmax(name))\n set_hudmessage(g_streakColors[streak][0], g_streakColors[streak][1], g_streakColors[streak][2],\n -1.0, 0.35, 2, 0.5, 3.0, 0.1, 0.1)\n show_hudmessage(0, \"%s\\n%s !\", g_streakNames[streak], name)\n }\n else if (streak > 10)\n {\n new name[32]\n get_user_name(killer, name, charsmax(name))\n set_hudmessage(255, 0, 255, -1.0, 0.35, 2, 0.5, 3.0)\n show_hudmessage(0, \"BEYOND GODLIKE\\n%s - %d kills !\", name, streak)\n }\n}\nPLUGIN10\n\n # ============================\n # 11. Advanced Bullet Damage\n # ============================\n cat > fun_bullet_damage.sma << 'PLUGIN11'\n#include <amxmodx>\n#include <hamsandwich>\n\npublic plugin_init()\n{\n register_plugin(\"Bullet Damage\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n RegisterHam(Ham_TakeDamage, \"player\", \"fw_TakeDamage_Post\", 1)\n}\n\npublic fw_TakeDamage_Post(victim, inflictor, attacker, Float:damage, damagebits)\n{\n if (victim == attacker || attacker < 1 || attacker > 32) return\n if (!is_user_alive(victim) || !is_user_connected(attacker)) return\n\n // Afficher les degats au tireur\n new hp = get_user_health(victim)\n set_hudmessage(255, 50, 50, -1.0, 0.45, 0, 0.0, 1.5, 0.0, 0.0, 3)\n show_hudmessage(attacker, \"-%d HP [%d restant]\", floatround(damage), hp < 0 ? 0 : hp)\n}\nPLUGIN11\n\n # ============================\n # 12. Auto Restart Round\n # ============================\n cat > fun_auto_restart.sma << 'PLUGIN12'\n#include <amxmodx>\n\npublic plugin_init()\n{\n register_plugin(\"Auto Restart\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n set_task(60.0, \"check_restart\", _, _, _, \"b\")\n}\n\npublic check_restart()\n{\n new players[32], num\n get_players(players, num, \"ch\")\n new humans = 0\n for (new i = 0; i < num; i++)\n if (!is_user_bot(players[i])) humans++\n\n if (humans <= 1)\n {\n server_cmd(\"sv_restart 3\")\n set_hudmessage(255, 255, 0, -1.0, 0.3, 0, 0.0, 3.0)\n show_hudmessage(0, \"Restart automatique dans 3 secondes...\")\n }\n}\nPLUGIN12\n\n # ============================\n # 13. Back Weapon (show weapon on back)\n # ============================\n cat > fun_back_weapon.sma << 'PLUGIN13'\n#include <amxmodx>\n#include <fakemeta>\n\npublic plugin_init()\n{\n register_plugin(\"Back Weapon\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n // Visual indicator via chat when switching weapons\n register_clcmd(\"say /weapons\", \"cmd_weapons\")\n}\n\npublic cmd_weapons(id)\n{\n if (!is_user_alive(id)) return PLUGIN_HANDLED\n\n new weapons[32], num\n get_user_weapons(id, weapons, num)\n new szWeapons[256], szName[32]\n\n for (new i = 0; i < num; i++)\n {\n get_weaponname(weapons[i], szName, charsmax(szName))\n add(szWeapons, charsmax(szWeapons), szName)\n if (i < num-1) add(szWeapons, charsmax(szWeapons), \", \")\n }\n client_print(id, print_chat, \"[Armes] %s\", szWeapons)\n return PLUGIN_HANDLED\n}\nPLUGIN13\n\n # ============================\n # 14. Colored Flashbangs\n # ============================\n cat > fun_colored_flash.sma << 'PLUGIN14'\n#include <amxmodx>\n#include <fakemeta>\n#include <cstrike>\n\npublic plugin_init()\n{\n register_plugin(\"Colored Flash\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_event(\"ScreenFade\", \"event_flash\", \"be\", \"4>200\")\n}\n\npublic event_flash(id)\n{\n if (!is_user_alive(id)) return\n\n // Couleur aleatoire pour le flash\n new r = random_num(100, 255)\n new g = random_num(100, 255)\n new b = random_num(100, 255)\n\n message_begin(MSG_ONE, get_user_msgid(\"ScreenFade\"), _, id)\n write_short(read_data(1))\n write_short(read_data(2))\n write_short(read_data(3))\n write_byte(r)\n write_byte(g)\n write_byte(b)\n write_byte(read_data(7))\n message_end()\n}\nPLUGIN14\n\n # ============================\n # 15. AWP + Sniper Limit\n # ============================\n cat > fun_awp_limit.sma << 'PLUGIN15'\n#include <amxmodx>\n#include <cstrike>\n#include <hamsandwich>\n\n#define MAX_AWP 2\n#define MAX_SCOUT 2\n\npublic plugin_init()\n{\n register_plugin(\"AWP Limit\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_clcmd(\"buy\", \"check_buy\")\n register_clcmd(\"buyequip\", \"check_buy\")\n RegisterHam(Ham_Touch, \"weaponbox\", \"fw_TouchWeapon\")\n}\n\ncount_weapon(CsTeams:team, wpnid)\n{\n new players[32], num, count = 0\n get_players(players, num, \"ae\", (team == CS_TEAM_T) ? \"TERRORIST\" : \"CT\")\n for (new i = 0; i < num; i++)\n {\n if (user_has_weapon(players[i], wpnid))\n count++\n }\n return count\n}\n\npublic check_buy(id)\n{\n // Let the buy proceed, check after\n set_task(0.1, \"check_sniper_limit\", id)\n return PLUGIN_CONTINUE\n}\n\npublic check_sniper_limit(id)\n{\n if (!is_user_alive(id)) return\n\n new CsTeams:team = cs_get_user_team(id)\n\n if (user_has_weapon(id, CSW_AWP) && count_weapon(team, CSW_AWP) > MAX_AWP)\n {\n ham_strip_weapon(id, \"weapon_awp\")\n cs_set_user_money(id, cs_get_user_money(id) + 4750)\n client_print(id, print_chat, \"[Limit] Max %d AWP par equipe !\", MAX_AWP)\n }\n if (user_has_weapon(id, CSW_SCOUT) && count_weapon(team, CSW_SCOUT) > MAX_SCOUT)\n {\n ham_strip_weapon(id, \"weapon_scout\")\n cs_set_user_money(id, cs_get_user_money(id) + 2750)\n client_print(id, print_chat, \"[Limit] Max %d Scout par equipe !\", MAX_SCOUT)\n }\n}\n\nham_strip_weapon(id, const weapon[])\n{\n new wpnId = get_weaponid(weapon)\n if (!user_has_weapon(id, wpnId)) return\n new ent = find_ent_by_owner(-1, weapon, id)\n if (ent)\n {\n ExecuteHamB(Ham_Weapon_RetireWeapon, ent)\n ExecuteHamB(Ham_RemovePlayerItem, id, ent)\n set_pev(ent, pev_flags, pev(ent, pev_flags) | FL_KILLME)\n }\n}\n\npublic fw_TouchWeapon(weapon, id)\n{\n if (id < 1 || id > 32 || !is_user_alive(id)) return HAM_IGNORED\n\n // Bloquer pickup si limite atteinte (AWP/Scout)\n new classname[32]\n pev(weapon, pev_classname, classname, charsmax(classname))\n // Simplifie: laisser passer, check_sniper_limit fera le strip apres\n return HAM_IGNORED\n}\nPLUGIN15\n\n # ============================\n # 16. Rank System\n # ============================\n cat > fun_rank.sma << 'PLUGIN16'\n#include <amxmodx>\n\nnew g_kills[33]\nnew g_deaths[33]\n\nnew const g_rankNames[][] = {\n \"Recrue\", // 0-4\n \"Soldat\", // 5-14\n \"Caporal\", // 15-29\n \"Sergent\", // 30-49\n \"Lieutenant\", // 50-74\n \"Capitaine\", // 75-99\n \"Commandant\", // 100-149\n \"Colonel\", // 150-199\n \"General\", // 200-299\n \"Marechal\", // 300+\n \"Legende\" // 500+\n}\n\nget_rank(kills)\n{\n if (kills >= 500) return 10\n if (kills >= 300) return 9\n if (kills >= 200) return 8\n if (kills >= 150) return 7\n if (kills >= 100) return 6\n if (kills >= 75) return 5\n if (kills >= 50) return 4\n if (kills >= 30) return 3\n if (kills >= 15) return 2\n if (kills >= 5) return 1\n return 0\n}\n\npublic plugin_init()\n{\n register_plugin(\"Rank System\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_event(\"DeathMsg\", \"event_death\", \"a\")\n register_clcmd(\"say /rank\", \"cmd_rank\")\n register_clcmd(\"say /rankup\", \"cmd_rank\")\n}\n\npublic client_putinserver(id) { g_kills[id] = 0; g_deaths[id] = 0 }\n\npublic event_death()\n{\n new killer = read_data(1)\n new victim = read_data(2)\n g_deaths[victim]++\n if (killer != victim && killer >= 1 && killer <= 32)\n {\n new old_rank = get_rank(g_kills[killer])\n g_kills[killer]++\n new new_rank = get_rank(g_kills[killer])\n if (new_rank > old_rank)\n {\n new name[32]\n get_user_name(killer, name, charsmax(name))\n set_hudmessage(0, 255, 100, -1.0, 0.25, 2, 0.5, 4.0)\n show_hudmessage(0, \">> %s promu %s ! <<\", name, g_rankNames[new_rank])\n }\n }\n}\n\npublic cmd_rank(id)\n{\n new rank = get_rank(g_kills[id])\n new Float:ratio = g_deaths[id] > 0 ? float(g_kills[id]) / float(g_deaths[id]) : float(g_kills[id])\n client_print(id, print_chat, \"[Rank] %s | Kills: %d | Deaths: %d | K/D: %.2f\",\n g_rankNames[rank], g_kills[id], g_deaths[id], ratio)\n return PLUGIN_HANDLED\n}\nPLUGIN16\n\n # ============================\n # 17. No Team Flash\n # ============================\n cat > fun_noteamflash.sma << 'PLUGIN17'\n#include <amxmodx>\n#include <cstrike>\n#include <fakemeta>\n\npublic plugin_init()\n{\n register_plugin(\"No Team Flash\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_event(\"ScreenFade\", \"event_flash_block\", \"be\", \"4>200\")\n}\n\npublic event_flash_block(id)\n{\n // Annuler le flash si c'est un coequipier\n // Methode: on annule le screenfade immediatement\n // Note: cette version simple annule le flash pour les coequipiers\n set_task(0.1, \"remove_flash\", id)\n}\n\npublic remove_flash(id)\n{\n if (!is_user_alive(id)) return\n\n // Supprimer l'effet de flash\n message_begin(MSG_ONE, get_user_msgid(\"ScreenFade\"), _, id)\n write_short(0)\n write_short(0)\n write_short(0)\n write_byte(0)\n write_byte(0)\n write_byte(0)\n write_byte(0)\n message_end()\n}\nPLUGIN17\n\n # ============================\n # 18. Parachute\n # ============================\n cat > fun_parachute.sma << 'PLUGIN18'\n#include <amxmodx>\n#include <fakemeta>\n\nnew bool:g_hasParachute[33]\nnew bool:g_paraOpen[33]\n\npublic plugin_init()\n{\n register_plugin(\"Parachute\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlayerPreThink, \"fw_PreThink_Para\")\n}\n\npublic client_putinserver(id)\n{\n g_hasParachute[id] = true\n g_paraOpen[id] = false\n}\n\npublic fw_PreThink_Para(id)\n{\n if (!is_user_alive(id) || !g_hasParachute[id]) return FMRES_IGNORED\n\n new buttons = pev(id, pev_button)\n new flags = pev(id, pev_flags)\n\n // Si en l'air et maintient USE\n if (!(flags & FL_ONGROUND) && (buttons & IN_USE))\n {\n new Float:vel[3]\n pev(id, pev_velocity, vel)\n if (vel[2] < -100.0)\n {\n vel[2] = -100.0\n set_pev(id, pev_velocity, vel)\n g_paraOpen[id] = true\n }\n }\n else\n {\n g_paraOpen[id] = false\n }\n\n return FMRES_IGNORED\n}\nPLUGIN18\n\n # ============================\n # 19. AMX Super (admin commands)\n # ============================\n cat > fun_amx_super.sma << 'PLUGIN19'\n#include <amxmodx>\n#include <cstrike>\n#include <fun>\n#include <fakemeta>\n\npublic plugin_init()\n{\n register_plugin(\"AMX Super\", \"5.0\", \"{{NOM_COMMUNAUTE}}Games\")\n\n // Commandes admin\n register_clcmd(\"say /hp\", \"cmd_hp\")\n register_clcmd(\"say /armor\", \"cmd_armor\")\n register_clcmd(\"say /speed\", \"cmd_speed\")\n register_clcmd(\"say /gravity\", \"cmd_gravity\")\n register_clcmd(\"say /noclip\", \"cmd_noclip\")\n register_clcmd(\"say /god\", \"cmd_god\")\n register_clcmd(\"say /respawn\", \"cmd_respawn\")\n register_clcmd(\"say /money\", \"cmd_money\")\n register_clcmd(\"say /give\", \"cmd_give\")\n\n // Commandes joueurs\n register_clcmd(\"say /cmds\", \"cmd_help\")\n register_clcmd(\"say /help\", \"cmd_help\")\n}\n\npublic cmd_hp(id)\n{\n if (!(get_user_flags(id) & ADMIN_KICK)) return PLUGIN_HANDLED\n if (is_user_alive(id)) set_user_health(id, 255)\n client_print(id, print_chat, \"[Admin] HP: 255\")\n return PLUGIN_HANDLED\n}\n\npublic cmd_armor(id)\n{\n if (!(get_user_flags(id) & ADMIN_KICK)) return PLUGIN_HANDLED\n if (is_user_alive(id)) cs_set_user_armor(id, 255, CS_ARMOR_VESTHELM)\n client_print(id, print_chat, \"[Admin] Armor: 255\")\n return PLUGIN_HANDLED\n}\n\npublic cmd_speed(id)\n{\n if (!(get_user_flags(id) & ADMIN_KICK)) return PLUGIN_HANDLED\n if (is_user_alive(id)) set_user_maxspeed(id, 800.0)\n client_print(id, print_chat, \"[Admin] Speed: 800\")\n return PLUGIN_HANDLED\n}\n\npublic cmd_gravity(id)\n{\n if (!(get_user_flags(id) & ADMIN_KICK)) return PLUGIN_HANDLED\n if (is_user_alive(id)) set_user_gravity(id, 0.3)\n client_print(id, print_chat, \"[Admin] Gravity: 0.3\")\n return PLUGIN_HANDLED\n}\n\npublic cmd_noclip(id)\n{\n if (!(get_user_flags(id) & ADMIN_RCON)) return PLUGIN_HANDLED\n if (is_user_alive(id))\n {\n new movetype = pev(id, pev_movetype)\n set_pev(id, pev_movetype, (movetype == MOVETYPE_NOCLIP) ? MOVETYPE_WALK : MOVETYPE_NOCLIP)\n client_print(id, print_chat, \"[Admin] Noclip: %s\", (movetype == MOVETYPE_NOCLIP) ? \"OFF\" : \"ON\")\n }\n return PLUGIN_HANDLED\n}\n\npublic cmd_god(id)\n{\n if (!(get_user_flags(id) & ADMIN_RCON)) return PLUGIN_HANDLED\n if (is_user_alive(id))\n {\n new godmode = get_user_godmode(id)\n set_user_godmode(id, godmode ? 0 : 1)\n client_print(id, print_chat, \"[Admin] God mode: %s\", godmode ? \"OFF\" : \"ON\")\n }\n return PLUGIN_HANDLED\n}\n\npublic cmd_respawn(id)\n{\n if (!(get_user_flags(id) & ADMIN_KICK)) return PLUGIN_HANDLED\n new arg[32]\n read_args(arg, charsmax(arg))\n remove_quotes(arg)\n new target = cmd_target(id, arg, 1)\n if (target > 0 && !is_user_alive(target))\n {\n ExecuteHamB(Ham_CS_RoundRespawn, target)\n client_print(id, print_chat, \"[Admin] Joueur respawn!\")\n }\n return PLUGIN_HANDLED\n}\n\npublic cmd_money(id)\n{\n if (!(get_user_flags(id) & ADMIN_KICK)) return PLUGIN_HANDLED\n cs_set_user_money(id, 16000)\n client_print(id, print_chat, \"[Admin] Money: $16000\")\n return PLUGIN_HANDLED\n}\n\npublic cmd_give(id)\n{\n if (!(get_user_flags(id) & ADMIN_KICK)) return PLUGIN_HANDLED\n new arg[32]\n read_args(arg, charsmax(arg))\n remove_quotes(arg)\n if (strlen(arg) > 0)\n {\n give_item(id, arg)\n client_print(id, print_chat, \"[Admin] Item: %s\", arg)\n }\n else\n client_print(id, print_chat, \"[Admin] Usage: /give weapon_ak47\")\n return PLUGIN_HANDLED\n}\n\npublic cmd_help(id)\n{\n client_print(id, print_chat, \"[Fun] Commandes: /rpg /rank /top /xp /weapons /nade\")\n if (get_user_flags(id) & ADMIN_KICK)\n client_print(id, print_chat, \"[Admin] /hp /armor /speed /gravity /noclip /god /respawn /money /give\")\n return PLUGIN_HANDLED\n}\nPLUGIN19\n\n # ============================\n # Compiler tous les plugins\n # ============================\n echo \" Compilation des 19 plugins...\"\n COMPILED=0\n FAILED=0\n for sma in fun_*.sma; do\n name=$(basename \"$sma\" .sma)\n ./amxxpc \"$sma\" -o\"../plugins/${name}.amxx\" 2>&1 || true\n if [ -f \"../plugins/${name}.amxx\" ]; then\n grep -q \"${name}.amxx\" ../configs/plugins.ini 2>/dev/null \\\n || echo \"${name}.amxx\" >> ../configs/plugins.ini\n COMPILED=$((COMPILED+1))\n else\n echo \" [WARN] ${name} echoue\"\n FAILED=$((FAILED+1))\n fi\n done\n echo \" [OK] $COMPILED plugins compiles, $FAILED echoues\"\n cd /mnt/server\nfi\n\n# Activer les modules requis\nAMXX_MODULES=\"/mnt/server/cstrike/addons/amxmodx/configs/modules.ini\"\nfor mod in fakemeta hamsandwich cstrike fun engine csx; do\n if grep -q \"^;${mod}\" \"$AMXX_MODULES\" 2>/dev/null; then\n sed -i \"s/^;${mod}/${mod}/\" \"$AMXX_MODULES\"\n fi\ndone\necho \" [OK] Modules actives\"\n\n##############################################\n# 9) YaPB\n##############################################\necho \"\"\necho \">>> [9/17] YaPB...\"\nYAPB_URL=$(github_get_url \"yapb/yapb\" \"linux.*\\.tar\\.xz\")\nif [ -n \"$YAPB_URL\" ]; then\n curl -fsSL -o /tmp/yapb.tar.xz \"$YAPB_URL\"\n if [ -s /tmp/yapb.tar.xz ]; then\n mkdir -p /tmp/yapb\n tar -xf /tmp/yapb.tar.xz -C /tmp/yapb/\n YAPB_DIR=$(find /tmp/yapb -type d -name \"yapb\" -path \"*/addons/yapb\" | head -1)\n [ -n \"$YAPB_DIR\" ] && cp -rf \"$YAPB_DIR\" /mnt/server/cstrike/addons/\n mkdir -p /mnt/server/cstrike/addons/yapb/data/{graph,train}\n chmod -R 755 /mnt/server/cstrike/addons/yapb/data\n grep -q \"yapb\" /mnt/server/cstrike/addons/metamod/plugins.ini 2>/dev/null \\\n || echo \"linux addons/yapb/bin/yapb.so\" >> /mnt/server/cstrike/addons/metamod/plugins.ini\n echo \" [OK] YaPB\"\n fi\n rm -rf /tmp/yapb /tmp/yapb.tar.xz\nfi\n\n##############################################\n# 10) BotManager v2\n##############################################\necho \"\"\necho \">>> [10/17] BotManager v2...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/bot_manager.sma << 'BOTSMA'\n#include <amxmodx>\nnew g_cvarBotCount, g_cvarKickThreshold\npublic plugin_init()\n{\n register_plugin(\"BotManager\", \"2.0\", \"{{NOM_COMMUNAUTE}}Games\")\n g_cvarBotCount = register_cvar(\"bm_bot_count\", \"5\")\n g_cvarKickThreshold = register_cvar(\"bm_kick_threshold\", \"4\")\n}\npublic plugin_cfg() { set_task(3.0, \"check_bots\") }\npublic client_putinserver(id) { set_task(2.0, \"check_bots\") }\npublic client_disconnected(id, bool:drop, message[], maxlen) { set_task(1.0, \"check_bots\") }\npublic check_bots()\n{\n new humans = count_humans()\n new fill = get_pcvar_num(g_cvarBotCount)\n new threshold = get_pcvar_num(g_cvarKickThreshold)\n if (humans >= threshold) server_cmd(\"yb_quota 0\")\n else server_cmd(\"yb_quota %d\", fill)\n}\ncount_humans()\n{\n new players[32], num, count = 0\n get_players(players, num, \"ch\")\n for (new i = 0; i < num; i++) { if (!is_user_bot(players[i])) count++ }\n return count\n}\nBOTSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc bot_manager.sma -o../plugins/bot_manager.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/bot_manager.amxx ]; then\n grep -q \"bot_manager.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"bot_manager.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] bot_manager.amxx\"\n fi\nfi\n\n##############################################\n# 11) Advanced Quake Sounds\n##############################################\necho \"\"\necho \">>> [11/17] AQS...\"\ncurl -fsSL -o /tmp/aqs.zip \"https://github.com/ClaudiuHKS/AdvancedQuakeSounds/archive/refs/heads/master.zip\"\nif [ -s /tmp/aqs.zip ]; then\n unzip -qo /tmp/aqs.zip -d /tmp/aqs/\n AQS=\"/tmp/aqs/AdvancedQuakeSounds-master\"\n AMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\n if [ -f \"$AQS/AQS.sma\" ] && [ -f \"$AMXXPC\" ]; then\n cp -f \"$AQS/AQS.sma\" /mnt/server/cstrike/addons/amxmodx/scripting/\n cd /mnt/server/cstrike/addons/amxmodx/scripting && chmod +x amxxpc\n ./amxxpc AQS.sma -o../plugins/AQS.amxx 2>&1 || true\n cd /mnt/server\n fi\n [ -f \"$AQS/AQS.ini\" ] && cp -f \"$AQS/AQS.ini\" /mnt/server/cstrike/addons/amxmodx/configs/\n mkdir -p /mnt/server/cstrike/sound/AQS/\n [ -f \"$AQS/sound.zip\" ] && unzip -qo \"$AQS/sound.zip\" -d /mnt/server/cstrike/ 2>/dev/null || true\n grep -q \"AQS.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"AQS.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] AQS\"\n rm -rf /tmp/aqs /tmp/aqs.zip\nfi\n\n##############################################\n# 12) Double Jump\n##############################################\necho \"\"\necho \">>> [12/17] Double Jump...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/doublejump.sma << 'DJSMA'\n#include <amxmodx>\n#include <fakemeta>\n#define MAX_EXTRA_JUMPS 1\nnew g_jumpCount[33]\npublic plugin_init()\n{\n register_plugin(\"Double Jump\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n register_forward(FM_PlayerPreThink, \"fw_PreThink_DJ\")\n}\npublic client_putinserver(id) { g_jumpCount[id] = 0 }\npublic fw_PreThink_DJ(id)\n{\n if (!is_user_alive(id)) return FMRES_IGNORED\n new flags = pev(id, pev_flags)\n new buttons = pev(id, pev_button)\n new oldbuttons = pev(id, pev_oldbuttons)\n if (flags & FL_ONGROUND) { g_jumpCount[id] = 0; return FMRES_IGNORED }\n if ((buttons & IN_JUMP) && !(oldbuttons & IN_JUMP))\n {\n if (g_jumpCount[id] < MAX_EXTRA_JUMPS)\n {\n g_jumpCount[id]++\n new Float:vel[3]\n pev(id, pev_velocity, vel)\n vel[2] = 268.0\n set_pev(id, pev_velocity, vel)\n }\n }\n return FMRES_IGNORED\n}\nDJSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting\n chmod +x amxxpc\n ./amxxpc doublejump.sma -o../plugins/doublejump.amxx 2>&1 || true\n cd /mnt/server\n if [ -f /mnt/server/cstrike/addons/amxmodx/plugins/doublejump.amxx ]; then\n grep -q \"doublejump.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"doublejump.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\n echo \" [OK] doublejump.amxx\"\n fi\nfi\n\n##############################################\n# 13) Welcome Message\n##############################################\necho \"\"\necho \">>> [13/17] Welcome Message...\"\nAMXXPC=\"/mnt/server/cstrike/addons/amxmodx/scripting/amxxpc\"\nif [ -f \"$AMXXPC\" ]; then\n cat > /mnt/server/cstrike/addons/amxmodx/scripting/fun_welcome.sma << 'WELSMA'\n#include <amxmodx>\npublic plugin_init()\n{\n register_plugin(\"Fun Welcome\", \"1.0\", \"{{NOM_COMMUNAUTE}}Games\")\n}\npublic client_putinserver(id)\n{\n if (is_user_bot(id)) return\n set_task(5.0, \"show_welcome\", id)\n}\npublic show_welcome(id)\n{\n if (!is_user_connected(id)) return\n set_hudmessage(0, 200, 255, -1.0, 0.2, 2, 0.5, 6.0, 0.5, 0.5)\n show_hudmessage(id, \"Bienvenue sur {{NOM_COMMUNAUTE}}Games.fr^nFun Server v1.15^n^n/rpg /rank /top /help^nDouble Jump + Parachute (E)\")\n client_print(id, print_chat, \"*** Bienvenue sur [FR] FUN SERVER - {{NOM_COMMUNAUTE}}Games.fr ***\")\n client_print(id, print_chat, \"[Fun] Commandes: /rpg /rank /top /xp /help /weapons\")\n}\nWELSMA\n cd /mnt/server/cstrike/addons/amxmodx/scripting && chmod +x amxxpc\n ./amxxpc fun_welcome.sma -o../plugins/fun_welcome.amxx 2>&1 || true\n cd /mnt/server\n grep -q \"fun_welcome.amxx\" /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini 2>/dev/null \\\n || echo \"fun_welcome.amxx\" >> /mnt/server/cstrike/addons/amxmodx/configs/plugins.ini\nfi\n\n##############################################\n# 14) Maps depuis FastDL\n##############################################\necho \"\"\necho \">>> [14/17] Maps...\"\nFASTDL_URL=\"https://fastdl.{{DOMAINE_GAMING}}/cs_fun\"\nwget -r -np -nH --cut-dirs=1 -P /mnt/server/cstrike/ \\\n -R \"index.html*\" --no-check-certificate -q --show-progress \\\n \"$FASTDL_URL/\" 2>&1 || echo \" [WARN] wget erreurs\"\n\nMAP_COUNT=$(find /mnt/server/cstrike/maps -name \"*.bsp\" 2>/dev/null | wc -l)\necho \" [OK] ${MAP_COUNT} maps\"\n\nEXCLUDE_MAPS=\"as_oilrig cs_747 cs_assault cs_backalley cs_estate cs_havana cs_italy cs_militia cs_office cs_siege de_airstrip de_aztec de_cbble de_chateau de_dust de_inferno de_nuke de_piranesi de_prodigy de_storm de_survivor de_torn de_train de_vertigo\"\nfind /mnt/server/cstrike/maps -name \"*.bsp\" -printf \"%f\\n\" 2>/dev/null \\\n | sed 's/\\.bsp$//' | sort > /mnt/server/cstrike/mapcycle.txt\nfor m in $EXCLUDE_MAPS; do sed -i \"/^${m}$/d\" /mnt/server/cstrike/mapcycle.txt; done\n\n##############################################\n# 15) server.cfg\n##############################################\necho \"\"\necho \">>> [15/17] server.cfg...\"\ncat > /mnt/server/cstrike/server.cfg << 'SERVERCFG'\nhostname \"[FR] FUN SERVER {{TAG_CLAN}} #{{NOM_COMMUNAUTE}}\"\nsv_contact \"admin@{{DOMAINE_GAMING}}\"\nrcon_password \"changeme\"\n\n// Fun Server settings\nmp_timelimit 30\nmp_freezetime 3\nmp_roundtime 5\nmp_autoteambalance 1\nmp_friendlyfire 0\nsv_maxspeed 320\nsv_alltalk 1\nsv_voiceenable 1\nmp_startmoney 3000\n\n// Rates\nsv_maxrate 25000\nsv_minrate 6000\nsv_maxupdaterate 102\nsv_minupdaterate 30\n\n// Downloads + FastDL\nsv_allowdownload 1\nsv_allowupload 0\nsv_downloadurl \"https://fastdl.{{DOMAINE_GAMING}}/cs_fun\"\n\n// YaPB bots\nyb_quota 5\nyb_auto_waypoint 1\nyb_chat 0\nyb_language_tag 0\n\n// BotManager v2\nbm_bot_count 5\nbm_kick_threshold 4\n\nexec banned.cfg\nexec listip.cfg\nSERVERCFG\n\n##############################################\n# 16) Fix permissions\n##############################################\necho \"\"\necho \">>> [16/17] Fix permissions...\"\nchmod -R 755 /mnt/server/ 2>/dev/null || true\nchmod +x /mnt/server/hlds_linux /mnt/server/hlds_run /mnt/server/hlds_amd 2>/dev/null || true\nSTEAM_SO=$(find /mnt/server -path \"*/linux32/steamclient.so\" -not -path \"*/.steam/*\" 2>/dev/null | head -1)\n[ -n \"$STEAM_SO\" ] && cp -f \"$STEAM_SO\" /mnt/server/.steam/sdk32/\n\necho \"\"\necho \"=============================================\"\necho \" Installation terminee !\"\necho \" Stack : ReHLDS + ReGameDLL + Metamod-R\"\necho \" + AMX Mod X + ReAPI + Reunion\"\necho \"=============================================\"\necho \"\"\necho \" 19 Plugins Fun:\"\necho \" 1. Bomb Status 10. Unreal (kill streaks)\"\necho \" 2. Teams Manager 11. Bullet Damage\"\necho \" 3. Accuracy Fix 12. Auto Restart\"\necho \" 4. Grenade Trail 13. Back Weapon\"\necho \" 5. Day/Night Effect 14. Colored Flashbangs\"\necho \" 6. Quake Switch 15. AWP/Sniper Limit\"\necho \" 7. RPG Mod 16. Rank System\"\necho \" 8. Colored Smoke 17. No Team Flash\"\necho \" 9. Free Defuser 18. Parachute\"\necho \" 19. AMX Super (admin)\"\necho \"\"\necho \" + YaPB bots, BotManager v2, AQS, Double Jump\"\necho \" + Welcome message\"\necho \"\"\necho \" Commandes joueurs: /rpg /rank /top /xp /help /weapons\"\necho \" Commandes admin: /hp /armor /speed /gravity /god /noclip /respawn /money /give /swap /teams\"\necho \"=============================================\"\n", "container": "ghcr.io/ptero-eggs/installers:debian", "entrypoint": "bash" } } } |
13) Récapitulatif de l’architecture finale
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
Nouveau serveur ({{IP_NOUVEAU}}) ┌──────────────────────────────────────────────────────────────────────────────┐ │ Docker │ │ ┌─ Pterodactyl Panel (ghcr.io/pterodactyl/panel) │ │ ├─ MariaDB 10.11 (base de données panel) │ │ ├─ Redis (cache + sessions + queue) │ │ ├─ Wings daemon (ghcr.io/pterodactyl/wings) │ │ │ │ │ ├─ cs16-dm :27015/udp Deathmatch (ReHLDS + ReDM) │ │ ├─ cs16-gungame :27016/udp GunGame (ReHLDS + GG 2.13c) │ │ ├─ cs16-deathrun :27017/udp Deathrun (ReHLDS + DR 3.0.3a) │ │ ├─ cs16-hns :27018/udp Hide & Seek (ReHLDS + HNS) │ │ ├─ cs16-kreedz :27019/udp KZ / Bhop (ReHLDS + KZ 1.30) │ │ ├─ cs16-war :27020/udp AUTOMIX 5v5 (ReHLDS + PugMod-AMXX) │ │ ├─ cs16-surf :27022/udp Surf (ReHLDS + uSurf) │ │ ├─ cs16-cs10 :27021/udp CS 1.0 Beta (ReHLDS + YaPB) │ │ ├─ cs16-paintball:27023/udp Paintball (ReHLDS + PBR) │ │ ├─ cs16-furien :27024/udp Furien (ReHLDS + Furien Pack) │ │ └─ cs16-bb :27025/udp BaseBuilder (ReHLDS + ProBB) │ │ │ │ Nginx (MyVestaCP) → reverse proxy → panel:8880 │ │ FastDL : fastdl.{{DOMAINE_GAMING}} (Nginx / MyVestaCP) │ │ │ │ Aussi sur ce serveur : │ │ Odoo 17, Odoo 8, Akeneo PIM, ownCloud, TeamSpeak 3 │ └──────────────────────────────────────────────────────────────────────────────┘ |
Ports utilisés
| Port | Proto | Service |
|---|---|---|
| 443 | TCP | Panel Pterodactyl (HTTPS via Nginx) |
| 2022 | TCP | SFTP Pterodactyl (gestion fichiers) |
| 8543 | TCP | Wings daemon (API) |
| 27015 | UDP | CS 1.6 Deathmatch |
| 27016 | UDP | CS 1.6 GunGame |
| 27017 | UDP | CS 1.6 Deathrun |
| 27018 | UDP | CS 1.6 Hide & Seek |
| 27019 | UDP | CS 1.6 Kreedz |
| 27020 | UDP | CS 1.6 AUTOMIX 5v5 (PugMod-AMXX MR15) |
| 27022 | UDP | CS 1.6 Surf (uSurf + timer) |
| 27021 | UDP | CS 1.6 CS 1.0 Vintage Beta |
| 27023 | UDP | CS 1.6 Paintball (PaintBall Refresh) |
| 27024 | UDP | CS 1.6 Furien (assassins + CT weapons) |
| 27025 | UDP | CS 1.6 BaseBuilder (ProBaseBuilder) |
Checklist de déploiement
- Docker + Docker Compose installés
- Stack Pterodactyl déployée en Docker (
docker compose up -d) - Reverse proxy Nginx configuré pour
panel.{{DOMAINE_GAMING}} - Wings connecté au panel (point vert) +
config.ymldéposé - 9 eggs custom importés dans le nest Counter-Strike (DM, GunGame, Deathrun, HNS, Kreedz, AUTOMIX 5v5, Surf, CS 1.0 Beta)
- 12 serveurs créés avec les bons ports
- Configs
server.cfgpersonnalisées par serveur - Installation automatique des plugins vérifiée par egg (
meta list: 7/7 RUN,amxx plugins: 26/26 running pour DM/GG avec BotManager) - BotManager v2 compilé et actif sur DM, GunGame et Deathrun — 5 bots toujours présents (
yb_quota 5+bm_bot_count 5+bm_kick_threshold 4) - HNS : ReSemiclip + OpenHNS hns_mode + PreFog + HnsMatchSystem installés (pas de bots)
- Kreedz : ReSemiclip + Theggv/Kreedz v1.3.0 + MapManagerModular v3.2.0 installés (timer, jumpstats, mpbhop, RTV, nominations)
- AUTOMIX 5v5 : PugMod-AMXX v4.0.8 installé (plugins AMXX), format MR15 configuré, maps de compet présentes (de_dust2, de_inferno, de_nuke, de_train, de_cbble)
- Surf : uSurf + surf_olympics + Speedometer + Bunnyhop + No Fall Damage installés, ~45 maps surf depuis FastDL, sv_airaccelerate 150 (port 27022)
- CS 1.0 Vintage Beta : placeholder configuré (port 27021)
- Maps uploadées +
mapcycle.txtconfigurés - FastDL configuré (
fastdl.{{DOMAINE_GAMING}}) - Maps compressées en
.bz2pour le FastDL - Paintball : PaintBall Refresh + Double Jump + Parachute + BotManager v2 + AQS installés, maps paintball depuis FastDL (port 27023)
- Furien : Furien Pack + Auto Bhop + Double Jump + Parachute + Deagle 1 balle + CT Weapons + NadeModes + Skin AC + BotManager v2 + AQS installés, maps furien depuis FastDL (port 27024)
- BaseBuilder : ProBaseBuilder + CT Features (unlimited ammo, buy menu, knife OS, revive) + BotManager v2 + AQS installés, maps bb depuis FastDL (port 27025)
- Firewall : ports 27015-27025 UDP ouverts
- Firewall : port 8543 TCP ouvert (Wings)
- Firewall : port 2022 TCP ouvert (SFTP Pterodactyl)
- DNS configuré (panel, fastdl, @)
- Let’s Encrypt activé sur panel et fastdl
- Admins AMX Mod X configurés (
users.ini) - RCON passwords changés (pas les valeurs par défaut)
- Test connexion client sur chaque serveur
À suivre
Les 12 serveurs Counter-Strike 1.6 sont opérationnels et gérés via Pterodactyl.
Prochaines améliorations possibles :
- HLStats — statistiques centralisées pour tous les serveurs
- Frontend records Kreedz — site web pour afficher les records KZ/bhop
- Serveur Zombie Plague — ajout d’un 10ème serveur
- Sauvegardes automatisées — backup des configs et bases de données
- Monitoring — intégration GameTracker ou custom
0 commentaire