SourceBans++ Documentation

repository·main·Indexed 18 days ago

https://github.com/sbpp/sourcebans-pp

Documentation for SourceBans++, a global administration, banning, and communication management system for the Source engine. Includes guides on setting up a local development environment using Docker and the sbpp.sh wrapper, managing the development stack, seeding databases with synthetic data, and running quality gates like PHPStan, PHPUnit, and Playwright E2E tests. Also covers the documentation site's architecture built with Astro and Starlight.

Tokens
39.1K
Snippets
87
Records
195
Agent score
64%

What's inside SourceBans++

  1. Project structure and file locations for SourceBans++ docs

    main

    The documentation repository is organized as follows:

    PathPurpose
    astro.config.mjsSite configuration, sidebar tree, social links, and custom CSS. It also manages the @astrojs/sitemap integration.
    src/content.config.tsAstro content-collection schema using Starlight's docsLoader and docsSchema for front-matter validation.
    src/content/docs/The main directory for page content. Use .md for plain pages and .mdx for pages requiring Starlight components (e.g., Tabs, LinkCard, Card).
    src/data/sponsors.jsonThe single source of truth for funding platforms, sponsor tiers, and the sponsor roll.
    src/styles/sbpp.cssCustom CSS that mirrors the SourceBans++ panel's design tokens (brand orange, zinc neutrals, etc.).
    src/components/Custom Astro components, including Sponsors.astro, Footer.astro, SocialIcons.astro, and ThemeProvider.astro.
    public/robots.txtCrawl directives and a pointer to the sitemap at https://sbpp.github.io/sitemap-index.xml.
    scripts/capture.mjsPlaywright-driven script used for capturing screenshots of the UI.
  2. Explore the SourceBans++ top-level directory layout

    main

    The repository is organized into the following main directories and files:

    • web/: Contains the PHP web panel, JSON API, and tests.
    • game/addons/: Contains SourceMod plugin sources (.sp), configurations, and translations.
    • docker/: Contains the local development stack (Dockerfile, database initialization, and PHP configuration).
    • docker-compose.yml: Orchestrates the web panel, MariaDB database, Adminer, and Mailpit.
    • sbpp.sh: A wrapper script for managing the development stack and running quality gates.
    • .github/workflows/: CI/CD configurations for PHPStan, testing, TypeScript checking, API contract validation, and releases.
    • docs/: The Starlight-based documentation site (covering installation, upgrades, and configuration).
    .
    ├── web/                  PHP web panel (panel + JSON API + tests)
    ├── game/addons/          SourceMod plugin sources (.sp / configs / translations)
    ├── docker/               Local dev stack (Dockerfile, db-init, php config)
    ├── docker-compose.yml    web + db (MariaDB) + adminer + mailpit
    ├── sbpp.sh               Wrapper for the dev stack and quality gates
    ├── .github/workflows/    CI gates (phpstan, test, ts-check, api-contract, release)
    ├── README.md             Landing page — short, links to docs / AGENTS / ARCHITECTURE
    ├── ARCHITECTURE.md       This file — codebase overview
    ├── AGENTS.md             Conventions for AI agents / contributors
    ├── CHANGELOG.md         Release notes
    ├── docs/                 Starlight docs site (install / upgrade / configure)
    ├── LICENSE.txt           Elastic License 2.0 (web panel)
    ├── LICENSE-plugins.txt   GPLv3 (SourceMod plugins)
    ├── CLA.md                Contributor License Agreement (web/** PRs)
    └── THIRD-PARTY-NOTICES.txt
  3. Understand the SourceBans++ Web Panel Stack

    main

    The SourceBans++ web panel is a PHP-based application with the following core technology stack:

    • PHP 8.5: Requires pdo, pdo_mysql, intl, mbstring, openssl, and sodium extensions.
    • Database: MariaDB 10.11 is used in development; MySQL 5.6+ is supported in production.
    • Templating: Smarty 5 for server-side rendering.
    • Authentication: lcobucci/jwt for auth cookies.
    • Email: symfony/mailer for outbound mail.
    • Markdown: league/commonmark via Sbpp\Markup\IntroRenderer for admin-authored content.
    • Server Queries: xpaw/php-source-query-class for live server interaction.
    • Geolocation: maxmind-db/reader using web/data/GeoLite2-Country.mmdb.
    • Client-side: Vanilla JavaScript (no frameworks or bundlers). Files use // @ts-check for type-checking with tsc --checkJs.
  4. Understand the SourceBans++ licensing

    main

    SourceBans++ uses different licenses for different components:

    • Web panel (web/ directory): Elastic License 2.0. This allows for hobby use, community use, personal networks, Docker images, Pterodactyl eggs, or distribution packaging. However, providing the panel as a hosted or managed service to third parties requires a separate commercial license.
    • SourceMod plugins (game/addons/sourcemod/ directory): GPLv3.
    • Vendored third-party code: Subject to their own specific license terms (see THIRD-PARTY-NOTICES.txt).
  5. Understand the Export Subsystem Architecture

    main

    The SourceBans++ export subsystem is a one-shot, stateless process designed to generate data bundles (ZIP files) containing entity exports (admins, bans, comms, logs, etc.) and associated demo files. It operates in two primary modes:

    1. ZIP Mode: A streaming mode that writes directly to php://output. It is uncapped because it uses Zip64, allowing for arbitrarily large bundles. It uses real-time flushing to allow browser download progress bars to move.
    2. S3 Mode: A staging mode that builds the ZIP to a temporary file in SB_CACHE/exports/<uuid>.zip before uploading it via a single PUT request to an operator-supplied presigned URL. This mode is subject to a size cap (approximately 5 GiB) due to the structural limits of single-PUT S3/R2/MinIO uploads.

    The process follows a strict lifecycle: Pre-flight pass (ManifestBuilder) $\rightarrow$ Orchestration (BundleWriter) $\rightarrow$ Emission (EntityExporter) $\rightarrow$ Upload (if S3 mode).

  6. Understand the SourceBans++ Database Schema

    main

    The database schema is defined in web/install/includes/sql/struc.sql. It uses {prefix} and {charset} placeholders (rendered to sb and utf8mb4 in development).

    Key tables include:

    • sb_admins: Web admins, bcrypt passwords, and lockout state.
    • sb_groups: Web admin permission bitmasks.
    • sb_srvgroups: SourceMod admin groups (char flags).
    • sb_bans: Ban records.
    • sb_comms: Mutes, gags, and blocks.
    • sb_settings: Flat key/value configuration used by the Config class.
    • sb_log: Audit logs.
    • sb_notes: Per-Steam-ID admin notes.
  7. Understand the Full Data Export bundle structure

    main

    Every export is a Zip64 archive. The manifest.json is the first central-directory entry, allowing consumers to read metadata without downloading the entire bundle.

    Archive Layout:

    sbpp-export-<uuid>.zip
    ├── manifest.json
    ├── entities/
    │   ├── admins.jsonl
    │   ├── admins_servers_groups.jsonl
    │   ├── banlog.jsonl
    │   ├── bans.jsonl
    │   ├── comms.jsonl
    │   ├── comments.jsonl
    │   ├── demos.jsonl
    │   ├── groups.jsonl
    │   ├── log.jsonl
    │   ├── mods.jsonl
    │   ├── notes.jsonl
    │   ├── overrides.jsonl
    │   ├── protests.jsonl
    │   ├── server_groups.jsonl
    │   ├── servers.jsonl
    │   ├── servers_groups.jsonl
    │   ├── settings.jsonl
    │   ├── srvgroups.jsonl
    │   ├── srvgroups_overrides.jsonl
    │   └── submissions.jsonl
    └── demos/
        ├── <filename>.dem
        └── ...

    Manifest Fields (manifest.json):

    • format_version: integer (currently 1).
    • bundle_id: UUIDv4 string.
    • created_at: integer unix seconds (UTC).
    • panel_version: string matching the panel's data-version footer.
    • row_counts: dict of <entity>: <int>.
    • demo_total_bytes: integer.
    • estimated_bundle_bytes: integer.
    • cap_bytes: integer (S3 PUT cap: 5 GiB minus 64 MiB safety margin).
    • exceeds_cap: bool (true if estimated_bundle_bytes > cap_bytes).
    • pii_policy: dict declaring scope (e.g., includes_admin_emails, includes_ip_addresses, password_hashes: "never").
  8. Choose between ZIP download and S3 presigned PUT

    main

    The export tool provides two delivery modes depending on your needs:

    FeatureZIP downloadS3 presigned PUT
    Best Use CaseAd-hoc backups, debugging, small datasets.Scheduled backups, multi-GiB bundles, cloud analytics.
    MechanismBrowser streams directly from Apache via php://output.Panel stages to cache/exports/, then HTTPS-PUTs to your URL.
    Size LimitUncapped (uses Zip64).Hard cap of 5 GiB minus 64 MiB safety margin.
    NetworkRequires stable connection; aborting restarts the download.Server-to-server; more resilient for large files.
    DestinationsLocal machine.AWS S3, Cloudflare R2, MinIO, Wasabi, Backblaze B2.

    Note: If the estimated bundle size exceeds the 5 GiB S3 cap, the S3 button will be disabled, and you must use the ZIP download option.

  9. Manage SourceBans++ persistent volumes

    main

    The production Docker stack uses several named volumes. It is critical to back up dbdata and demos to prevent data loss.

    VolumePath inside containerDescription
    dbdata/var/lib/mysqlRequired. Contains all ban, admin, and log data.
    demos/var/www/html/web/demosRequired. Contains uploaded ban-evidence demos.
    cache/var/www/html/web/cacheOptional. Smarty compile cache and PHP sessions.
    smarty/var/www/html/web/templates_cOptional. Smarty template cache.

    Backup Commands:

    Database Backup:

    docker compose -f docker-compose.prod.yml exec db \
        mariadb-dump -uroot -p"$DB_ROOT_PASS" --single-transaction sourcebans \
        > backup-$(date +%F).sql

    Demos Backup:

    docker run --rm -v <stack>_demos:/data -v "$PWD:/backup" alpine \
        tar -czf /backup/demos-$(date +%F).tar.gz -C /data .

    Note: Replace <stack> with your compose project name (usually the directory basename).

  10. How SourceBans++ is structured

    main

    SourceBans++ consists of two main components that coordinate through a single shared database (MySQL or MariaDB). There is no direct API communication between the components; they synchronize by reading and writing to the same SQL tables.

    Components

    • Web panel (PHP): The administrative interface where admins log in to manage bans, groups, and servers. It is installed on a web server capable of running PHP and reaching the database.
    • SourceMod plugins (.smx): Installed on each individual game server. These plugins enforce bans (disconnecting players) and mutes (comm blocks) in-game, and write admin actions back to the database.
    • Database (MySQL/MariaDB): The central source of truth shared by both the web panel and all game server plugins.

    Key Architectural Implications

    • Distributed Hosting: The web panel and game servers can reside on different physical hosts as long as both have network access to the central database.
    • Scalability: Adding a new game server only requires adding a new row to the database, rather than configuring a network handshake with the panel.
    • Synchronization: Because they share a database, the only way for the two halves to desync is during a database outage.
  11. Use Column-Typed PHP Enums for Type Safety

    main

    SourceBans++ uses PHP backed enums to wrap database columns that contain a fixed set of values. This provides type safety in PHP while maintaining primitive values in the database.

    Important: When performing SQL binds, you must pass the enum's primitive value using $enum->value. Passing the enum case itself will cause a type error in the database layer.

    EnumOn-disk columnBacking TypeCases
    LogType:prefix_log.typestringMessage='m', Warning='w', Error='e'
    BanType:prefix_bans.typeintSteam=0, Ip=1
    BanRemoval:prefix_bans.RemoveTypestringDeleted='D', Unbanned='U', Expired='E'
    WebPermission:prefix_admins.extraflagsintBitmask based on web/configs/permissions/web.json

    Files are located in web/includes/ (e.g., LogType.php, BanType.php).

  12. Understand the Project Announcements strip

    main

    The SourceBans++ home dashboard includes a "Latest announcement" strip visible only to logged-in administrators. This strip displays low-frequency, high-importance information such as security advisories (CVEs), breaking upgrade notes, or new software requirements.

    How it works

    • Source: Content is fetched from a public JSON feed at https://sbpp.github.io/announcements.json.
    • Frequency: The panel fetches the feed once per day per installation in the background.
    • Performance: The fetch uses a shutdown hook to ensure it never delays a request or fails a request if the upstream is unreachable. It caches the response on disk.
    • Privacy: The fetch is a plain HTTP GET request with no cookies or tracking. The only metadata sent is the User-Agent header, which includes your panel's version: User-Agent: SourceBans++/<version> (announcements).