From ca502c6e369db63ee8f99f3f074afa1ef0448fef Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 22 Nov 2025 16:01:36 +0000 Subject: [PATCH] Add documentation generator tool and README for game server docs Co-authored-by: iaretechnician <2749183+iaretechnician@users.noreply.github.com> --- modules/billing/docs/GENERATION_README.md | 199 ++++++ tools/generate_game_docs.py | 769 ++++++++++++++++++++++ 2 files changed, 968 insertions(+) create mode 100644 modules/billing/docs/GENERATION_README.md create mode 100755 tools/generate_game_docs.py diff --git a/modules/billing/docs/GENERATION_README.md b/modules/billing/docs/GENERATION_README.md new file mode 100644 index 00000000..b6075c30 --- /dev/null +++ b/modules/billing/docs/GENERATION_README.md @@ -0,0 +1,199 @@ +# Game Server Documentation Generation + +## Overview + +This directory contains comprehensive game server hosting documentation for 143+ games. The documentation follows a consistent template structure based on the Minecraft server guide. + +## Generated Documentation + +In November 2024, we generated comprehensive documentation for 98 game servers that were previously in the "todo" category. Each game now has: + +- **Quick Navigation Menu** - Easy access to all sections +- **Quick Info** - Default ports, protocols, RAM requirements, engine info +- **Network Ports** - Detailed port tables with firewall configuration examples +- **Installation & Setup** - System requirements and installation steps +- **Server Configuration** - Configuration files and essential settings +- **Startup Parameters** - Command-line parameters and service setup +- **Troubleshooting** - Common issues and solutions +- **Performance Optimization** - Tuning and monitoring tips +- **Security Best Practices** - Firewall, passwords, updates, DDoS protection +- **Additional Resources** - External references and community links + +## Documentation Structure + +Each game documentation folder contains: + +``` +gamename/ +├── index.php - Main documentation content +├── metadata.json - Category, name, description, order +└── icon.png/jpg - Game icon (optional) +``` + +### metadata.json Format + +```json +{ + "name": "Game Name", + "description": "Brief description for the game", + "category": "game", + "order": 1 +} +``` + +## Categories + +Documentation is organized into categories: + +- **game** - Game server documentation (143+ servers) +- **mods** - Mod/plugin documentation +- **panel** - Panel-specific documentation +- **troubleshooting** - General troubleshooting guides +- **other** - Other documentation + +## Generation Tool + +The documentation was generated using the `generate_game_docs.py` script located in `/tools/`. + +### Data Sources + +The generator uses multiple data sources: + +1. **XML Configurations** (`/modules/config_games/server_configs/*.xml`) + - Port configurations + - Configuration file paths + - Custom fields and parameters + +2. **YAML Knowledgepack** (`/modules/billing/docs/gameserver_knowledgepack_v2.yaml`) + - Network port details + - System requirements + - Startup commands + - Troubleshooting tips + - External references + +3. **Template Structure** (Based on Minecraft documentation) + - Consistent formatting + - Comprehensive coverage + - User-friendly navigation + +### Running the Generator + +```bash +cd /home/runner/work/GSP/GSP +python3 tools/generate_game_docs.py +``` + +The script will: +1. Load XML configurations and YAML knowledgepack +2. Find all folders with `category: "todo"` in metadata.json +3. Generate comprehensive PHP documentation for each game +4. Update metadata.json to change category to "game" + +## Games Documented + +The following games now have comprehensive hosting documentation: + +### Action/FPS Games +- Aliens vs Predator, Call of Duty series (COD, COD2, COD4, MW2, MW3, WAW, Black Ops) +- Counter-Strike variants (CS 1.6, CS:CZ, CS:S, CS:GO, CS:Promod, CS 2D) +- Battlefield 2, Battlefield Bad Company 2 +- Half-Life variants (HLDM, HL2DM, HLTV) +- Insurgency, Medal of Honor series (MOHAA, MOHBR, MOHSP, MOHSPDEMO) +- Quake 3, Quake 4, Sniper Elite V2 + +### Source Engine Games +- Dystopia, Hidden: Source, Natural Selection 2, Nuclear Dawn +- Pirates Vikings and Knights II, Zombie Panic Source, Synergy +- Brain Bread 2, Day of Defeat: Source + +### Open World/Survival +- Atlas, Hurtworld, Life is Feudal, Miscreated +- Reign of Kings, The Forest, Space Engineers +- Wurm Unlimited, PixArk + +### Racing/Simulation +- Assetto Corsa, Euro Truck Simulator 2 +- Trackmania Nations, Trackmania Forever +- Wreckfest + +### Multiplayer Mods +- FiveM (GTA V), Multi Theft Auto (GTA SA/VC) +- IV:MP (GTA IV), JC:MP (Just Cause 2) +- Mafia II Online, Epoch Mod + +### Strategy/Building +- Avorion, Colony Survival, Eco +- FreeCol, OpenTTD, Empyrion Galactic Survival + +### Arena/Combat +- Jedi Knight 2, Jedi Knight: Jedi Academy +- Mount & Blade: Warband, Mordhau +- Soldat, Smashball, Blood Frontier +- Citadel: Forged with Fire, Red Orchestra 2, Rising Storm 2 +- Arma Reforger, Homefront + +### Voice/Communication +- TeamSpeak 2, TeamSpeak 3, Mumble, Ventrilo +- SinusBot, Shoutcast, Shoutcast Bot + +### Classic/Retro +- Unreal Tournament 99, UT2004, UT3 +- Serious Sam HD TFE, Serious Sam HD TSE +- Roadkill, Wolfenstein: Return to Castle Wolfenstein +- Enemy Territory, Warsow, Nexuiz, Xonotic +- IL-2 Sturmovik, Halo: Combat Evolved + +### Other +- Feed the Beast (Minecraft modpack) +- Spigot MC (Minecraft server software) +- Rigs of Rods, Flight Gear Multiplayer Server +- Virtual Box, Smokinguns, DMC, Gearbox, ESMod +- SpunkyBot, AoC, SMS + +## Viewing Documentation + +Access the documentation through the billing website: + +``` +/modules/billing/docs.php +``` + +Or view a specific game: + +``` +/modules/billing/docs.php?action=view&doc=gamename +``` + +## Maintenance + +To update or regenerate documentation: + +1. Update data sources (XML configs, YAML knowledgepack) +2. Modify the generator script if needed +3. Run the generator script +4. Commit changes to the repository + +## Template Customization + +To customize the documentation template, edit the `build_php_content()` method in `generate_game_docs.py`. + +The template includes: +- Inline CSS styling matching the site theme +- Responsive design for mobile/desktop +- Color-coded information boxes +- Syntax-highlighted code blocks +- Professional formatting + +## Contributing + +When adding new game documentation: + +1. Create a folder with the game's slug name +2. Add metadata.json with game information +3. Add icon.png or icon.jpg (optional) +4. Either manually create index.php or add to "todo" category and run generator +5. Update this README if adding new categories + +## License + +Documentation follows the same license as the GSP project. See main repository LICENSE file. diff --git a/tools/generate_game_docs.py b/tools/generate_game_docs.py new file mode 100755 index 00000000..342100b3 --- /dev/null +++ b/tools/generate_game_docs.py @@ -0,0 +1,769 @@ +#!/usr/bin/env python3 +""" +Comprehensive Game Server Documentation Generator for GSP +Generates PHP documentation files for all games in the "todo" category +Based on the Minecraft template structure +""" + +import os +import sys +import json +import yaml +import re +from pathlib import Path +from datetime import datetime +import xml.etree.ElementTree as ET + +class GameDocGenerator: + def __init__(self, docs_dir, config_dir, knowledgepack_path): + self.docs_dir = Path(docs_dir) + self.config_dir = Path(config_dir) + self.knowledgepack_path = Path(knowledgepack_path) + self.knowledgepack_data = None + self.xml_configs = {} + + def load_knowledgepack(self): + """Load the YAML knowledgepack with game information""" + try: + with open(self.knowledgepack_path, 'r', encoding='utf-8') as f: + data = yaml.safe_load(f) + self.knowledgepack_data = data.get('games', []) + print(f"Loaded knowledgepack with {len(self.knowledgepack_data)} games") + return True + except Exception as e: + print(f"Error loading knowledgepack: {e}") + return False + + def load_xml_configs(self): + """Load all XML configuration files""" + xml_files = list(self.config_dir.glob("*.xml")) + for xml_file in xml_files: + try: + tree = ET.parse(xml_file) + root = tree.getroot() + game_key = root.find('game_key') + if game_key is not None and game_key.text: + self.xml_configs[game_key.text] = { + 'file': xml_file.name, + 'tree': root + } + except Exception as e: + print(f"Error parsing {xml_file}: {e}") + print(f"Loaded {len(self.xml_configs)} XML configurations") + + def get_game_info_from_knowledgepack(self, game_name): + """Find game info in knowledgepack by name""" + if not self.knowledgepack_data: + return None + + # Try exact match first + for game in self.knowledgepack_data: + if game.get('name', '').lower() == game_name.lower(): + return game + + # Try partial match + for game in self.knowledgepack_data: + if game_name.lower() in game.get('name', '').lower(): + return game + + return None + + def get_xml_config(self, folder_name): + """Find matching XML config for a folder""" + # Try exact match + for key, config in self.xml_configs.items(): + if key.lower() == folder_name.lower() or key.lower().replace('_', '') == folder_name.lower(): + return config['tree'] + + # Try partial match + for key, config in self.xml_configs.items(): + if folder_name.lower() in key.lower() or key.lower() in folder_name.lower(): + return config['tree'] + + return None + + def extract_ports_from_xml(self, xml_root): + """Extract port information from XML config""" + ports = [] + + # Look for replace_texts with port keys + replace_texts = xml_root.find('replace_texts') + if replace_texts is not None: + for text in replace_texts.findall('text'): + key = text.get('key', '') + if 'port' in key.lower(): + filepath = text.find('filepath') + if filepath is not None: + ports.append({ + 'key': key, + 'file': filepath.text + }) + + # Look for custom_fields with port information + custom_fields = xml_root.find('custom_fields') + if custom_fields is not None: + for field in custom_fields.findall('field'): + key = field.get('key', '') + if 'port' in key.lower(): + default_value = field.find('default_value') + desc = field.find('desc') + ports.append({ + 'key': key, + 'default': default_value.text if default_value is not None else None, + 'description': desc.text if desc is not None else None + }) + + return ports + + def extract_config_files_from_xml(self, xml_root): + """Extract configuration file paths from XML""" + config_files = [] + + config_files_elem = xml_root.find('configuration_files') + if config_files_elem is not None: + for file_elem in config_files_elem.findall('file'): + desc = file_elem.get('description', 'Configuration file') + path = file_elem.text if file_elem.text else '' + config_files.append({ + 'description': desc, + 'path': path + }) + + return config_files + + def generate_php_doc(self, folder_name, metadata): + """Generate comprehensive PHP documentation for a game""" + game_name = metadata.get('name', folder_name.replace('_', ' ').title()) + + # Get additional data + kb_info = self.get_game_info_from_knowledgepack(game_name) + xml_config = self.get_xml_config(folder_name) + + # Extract ports and configs + ports_info = [] + config_files = [] + if xml_config is not None: + ports_info = self.extract_ports_from_xml(xml_config) + config_files = self.extract_config_files_from_xml(xml_config) + + # Build the PHP document + php_content = self.build_php_content(game_name, folder_name, kb_info, xml_config, ports_info, config_files) + + return php_content + + def build_php_content(self, game_name, folder_name, kb_info, xml_config, ports_info, config_files): + """Build the complete PHP documentation content""" + + # Extract data from various sources + default_port = "Check server configuration" + protocol = "TCP/UDP" + min_ram = "1GB" + engine = "Various" + startup_cmd = "" + + if kb_info: + network = kb_info.get('network', {}) + default_ports = network.get('default_ports', []) + if default_ports: + port_info = default_ports[0] + port_str = port_info.get('port', '') + if '/' in port_str: + default_port = port_str.split('/')[0] + protocol = port_str.split('/')[1].upper() + else: + default_port = port_str + + requirements = kb_info.get('requirements', {}) + min_ram = requirements.get('ram', '1GB') + engine = kb_info.get('engine', 'Various') + + startup = kb_info.get('typical_startup', {}) + startup_cmd = startup.get('linux', '') or startup.get('windows', '') + + php_doc = ''' +
+

📚 Quick Navigation

+
+ Quick Info + 🔌 Ports + Installation + Configuration + ⚙️ Startup Parameters + 🔧 Troubleshooting + Performance + Security +
+
+ +

''' + game_name + ''' Server Hosting Guide

+ +

Overview

+

''' + game_name + ''' is a multiplayer game server that can be hosted on a VPS or dedicated server. This comprehensive guide covers everything you need to know about hosting a ''' + game_name + ''' server for your community.

+ +

Quick Info

+
+ +
+ +

🔌 Network Ports

+
+

Required Ports

+''' + + # Add port information + if kb_info and kb_info.get('network', {}).get('default_ports'): + php_doc += ''' + + + + + + + + +''' + for port_info in kb_info['network']['default_ports']: + port_str = port_info.get('port', '') + purpose = port_info.get('purpose', 'Game server') + port_num = port_str.split('/')[0] if '/' in port_str else port_str + proto = port_str.split('/')[1].upper() if '/' in port_str else 'TCP/UDP' + + php_doc += f''' + + + + +''' + + # Add additional ports if available + additional_ports = kb_info['network'].get('additional_ports', []) + for port_info in additional_ports: + port_str = port_info.get('port', '') + purpose = port_info.get('purpose', 'Additional functionality') + port_num = port_str.split('/')[0] if '/' in port_str else port_str + proto = port_str.split('/')[1].upper() if '/' in port_str else 'TCP/UDP' + + php_doc += f''' + + + + +''' + + php_doc += ''' +
PortProtocolPurpose
{port_num}{proto}{purpose}
{port_num}{proto}{purpose} (Optional)
+''' + else: + php_doc += '''

The ''' + game_name + ''' server typically uses a configurable port. Check your server configuration files for the specific port settings.

+''' + + php_doc += ''' +

Firewall Configuration

+

Allow server ports through your firewall:

+
# UFW (Ubuntu/Debian)
+sudo ufw allow [PORT]/tcp
+sudo ufw allow [PORT]/udp
+sudo ufw reload
+
+# FirewallD (CentOS/RHEL)
+sudo firewall-cmd --permanent --add-port=[PORT]/tcp
+sudo firewall-cmd --permanent --add-port=[PORT]/udp
+sudo firewall-cmd --reload
+
+# Windows Firewall
+netsh advfirewall firewall add rule name="''' + game_name + ''' Server" dir=in action=allow protocol=TCP localport=[PORT]
+netsh advfirewall firewall add rule name="''' + game_name + ''' Server" dir=in action=allow protocol=UDP localport=[PORT]
+
+ +

⚠️ Port Security Notes

+ +
+ +

Installation & Setup

+ +

System Requirements

+ +''' + + # Add dependencies if available + if kb_info and kb_info.get('requirements', {}).get('dependencies'): + dependencies = kb_info['requirements']['dependencies'] + php_doc += ''' +

Required Dependencies

+ +''' + + php_doc += ''' +

Installation Steps

+ +

Linux (Ubuntu/Debian)

+
# Update system packages
+sudo apt update && sudo apt upgrade -y
+
+# Create server directory
+mkdir -p ~/gameserver
+cd ~/gameserver
+
+# Download server files (method varies by game)
+# Check official documentation for download links
+
+''' + + if startup_cmd: + php_doc += f''' +

Starting the Server

+
{startup_cmd}
+
+''' + + php_doc += ''' +

Windows Server

+

Download the server files from the official game website or through Steam (if applicable). Extract to a dedicated folder and run the server executable.

+ +

Using SteamCMD (if applicable)

+

Many game servers can be installed via SteamCMD:

+
# Install SteamCMD (Ubuntu/Debian)
+sudo apt install lib32gcc-s1 steamcmd
+
+# Run SteamCMD
+steamcmd
+
+# Login and download (use your Steam credentials or anonymous)
+login anonymous
+force_install_dir /path/to/server
+app_update [APP_ID] validate
+quit
+
+ +

Server Configuration

+ +

After installation, configure your server through the configuration files typically located in the server directory.

+ +

Essential Settings

+ +''' + + # Add config files section if available + if config_files: + php_doc += ''' +

Configuration Files

+

Important configuration files for this server:

+ +''' + + php_doc += ''' +

Server Commands

+

Common administrative commands (access via console or RCON):

+
# Kick player
+kick [player_name]
+
+# Ban player
+ban [player_name]
+
+# Change map/level (syntax varies by game)
+changelevel [map_name]
+
+# Set admin password (if supported)
+setadminpassword [password]
+
+ +

⚙️ Startup Parameters

+ +

Basic Startup

+''' + + if startup_cmd: + php_doc += f'''
{startup_cmd}
+
+''' + else: + php_doc += '''
# Generic startup command structure
+./server_executable [parameters]
+
+''' + + php_doc += ''' +

Common Parameters

+ + +

Creating a Start Script

+ +

Linux (start.sh):

+
#!/bin/bash
+cd /path/to/server
+./server_executable [parameters] 2>&1 | tee server.log
+
+
chmod +x start.sh
+./start.sh
+
+ +

Windows (start.bat):

+
@echo off
+cd /d "%~dp0"
+server_executable.exe [parameters]
+pause
+
+ +

Running as a Service

+ +

Linux (systemd):

+
# Create service file: /etc/systemd/system/gameserver.service
+[Unit]
+Description=''' + game_name + ''' Server
+After=network.target
+
+[Service]
+Type=simple
+User=gameserver
+WorkingDirectory=/home/gameserver/server
+ExecStart=/home/gameserver/server/start.sh
+Restart=on-failure
+RestartSec=10
+
+[Install]
+WantedBy=multi-user.target
+
+ +
# Enable and start service
+sudo systemctl daemon-reload
+sudo systemctl enable gameserver
+sudo systemctl start gameserver
+sudo systemctl status gameserver
+
+ +

🔧 Troubleshooting

+ +

Server Won't Start

+''' + + # Add troubleshooting from knowledgepack if available + if kb_info and kb_info.get('troubleshooting', {}).get('common_issues'): + issues = kb_info['troubleshooting']['common_issues'] + for issue_item in issues: + issue = issue_item.get('issue', '') + fix = issue_item.get('fix', '') + php_doc += f''' +

{issue}

+

{fix}

+''' + else: + php_doc += ''' +

Check Server Logs

+
# View recent log entries
+tail -f server.log
+
+# Or check system logs
+journalctl -u gameserver -f
+
+ +

Port Already in Use

+
# Find what's using the port
+sudo lsof -i :[PORT]
+sudo netstat -tulpn | grep [PORT]
+
+# Kill the process or change server port
+
+ +

Missing Dependencies

+

Ensure all required dependencies are installed. Check the error messages for missing libraries or packages.

+''' + + php_doc += ''' +

Connection Issues

+ +

Can't Connect to Server

+
    +
  1. Verify server is running: ps aux | grep server
  2. +
  3. Check port is listening: netstat -an | grep [PORT]
  4. +
  5. Verify firewall rules (see Ports section above)
  6. +
  7. Check server IP: Use external IP, not localhost
  8. +
  9. Router/NAT: Ensure port forwarding is configured
  10. +
+ +

High Latency/Lag

+ + +

Performance Issues

+ +

Server Lag

+
    +
  1. Monitor resources: Use htop or top
  2. +
  3. Check disk I/O: Use iotop
  4. +
  5. Review server logs for errors or warnings
  6. +
  7. Reduce player count or increase server resources
  8. +
  9. Optimize configuration based on server capacity
  10. +
+ +

Memory Leaks

+
# Monitor memory usage
+free -h
+top -p $(pgrep -f server)
+
+# Restart server regularly via cron if needed
+0 4 * * * /home/gameserver/restart.sh
+
+ +

Performance Optimization

+ +

Server Tuning

+ + +

Operating System Optimization

+
# Increase file descriptor limits
+echo "* soft nofile 65536" >> /etc/security/limits.conf
+echo "* hard nofile 65536" >> /etc/security/limits.conf
+
+# Network tuning
+sysctl -w net.core.rmem_max=16777216
+sysctl -w net.core.wmem_max=16777216
+sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
+sysctl -w net.ipv4.tcp_wmem="4096 87380 16777216"
+
+ +

Monitoring

+

Set up monitoring to track server health:

+ + +

Backup Strategy

+
#!/bin/bash
+# backup.sh - Run via cron
+DATE=$(date +%Y%m%d_%H%M%S)
+BACKUP_DIR="/backups/gameserver"
+SERVER_DIR="/home/gameserver/server"
+
+# Create backup
+tar -czf $BACKUP_DIR/backup_$DATE.tar.gz -C $SERVER_DIR .
+
+# Keep only last 7 days
+find $BACKUP_DIR -name "backup_*.tar.gz" -mtime +7 -delete
+
+ +

Security Best Practices

+ +

Firewall Configuration

+
# Minimal firewall - only allow necessary ports
+sudo ufw default deny incoming
+sudo ufw default allow outgoing
+sudo ufw allow [SERVER_PORT]/tcp
+sudo ufw allow [SERVER_PORT]/udp
+sudo ufw allow 22/tcp  # SSH
+sudo ufw enable
+
+ +

Strong Passwords

+ + +

Regular Updates

+ + +

Access Control

+ + +

DDoS Protection

+ + +

Additional Resources

+ +''' + + # Add references from knowledgepack if available + if kb_info and kb_info.get('references'): + php_doc += ''' +

External References

+ +''' + + php_doc += ''' +
+

Important Notes

+ +
+ +

+ Last updated: ''' + datetime.now().strftime("%B %Y") + ''' | For ''' + game_name + ''' server hosting +

+''' + + return php_doc + + def process_todo_folders(self): + """Process all folders with category 'todo' """ + processed = 0 + errors = [] + + # Find all todo folders + for folder in self.docs_dir.iterdir(): + if not folder.is_dir(): + continue + + metadata_file = folder / 'metadata.json' + index_file = folder / 'index.php' + + if not metadata_file.exists(): + continue + + try: + # Read metadata + with open(metadata_file, 'r', encoding='utf-8') as f: + content = f.read() + # Remove BOM if present + content = content.lstrip('\ufeff') + metadata = json.loads(content) + + # Check if it's a todo category + if metadata.get('category', '').lower() != 'todo': + continue + + print(f"Processing: {folder.name}") + + # Generate new documentation + php_content = self.generate_php_doc(folder.name, metadata) + + # Write the new index.php + with open(index_file, 'w', encoding='utf-8') as f: + f.write(php_content) + + # Update metadata category from 'todo' to 'game' + metadata['category'] = 'game' + with open(metadata_file, 'w', encoding='utf-8') as f: + json.dump(metadata, f, indent=4, ensure_ascii=False) + + processed += 1 + print(f" ✓ Generated documentation for {folder.name}") + + except Exception as e: + error_msg = f"Error processing {folder.name}: {e}" + print(f" ✗ {error_msg}") + errors.append(error_msg) + + return processed, errors + +def main(): + docs_dir = "/home/runner/work/GSP/GSP/modules/billing/docs" + config_dir = "/home/runner/work/GSP/GSP/modules/config_games/server_configs" + knowledgepack = "/home/runner/work/GSP/GSP/modules/billing/docs/gameserver_knowledgepack_v2.yaml" + + generator = GameDocGenerator(docs_dir, config_dir, knowledgepack) + + print("Loading data sources...") + generator.load_knowledgepack() + generator.load_xml_configs() + + print("\nProcessing TODO folders...") + processed, errors = generator.process_todo_folders() + + print(f"\n{'='*60}") + print(f"Documentation generation complete!") + print(f" Total processed: {processed}") + print(f" Errors: {len(errors)}") + + if errors: + print("\nErrors encountered:") + for error in errors[:10]: # Show first 10 errors + print(f" - {error}") + + return 0 if not errors else 1 + +if __name__ == "__main__": + sys.exit(main())