Developer Guides ‐ Overview Project Structure - MarechJ/hll_rcon_tool GitHub Wiki

🧭 You are here : Wiki home / Developer Guides / Overview Project Structure


Menu


General presentation

The project is split up into several main components :

  • backend, split into two major components :
    • rcon package :
      Handles the implementation of the HLL RCON protocol and implements most of the core behavior/features that CRCON has.
    • rconweb package, which is a Django web (WSGI) application :
      Handles all of the web portions (URL routing, authentication, sessions, etc.) once a HTTP request has been received by nginx in the frontend.
  • frontend :
    A combination of nginx (used as a reverse proxy) and gunicorn web servers that handles all of the HTTP requests and serves all of the responses.
    The flow is incoming request -> nginx -> gunicorn -> nginx -> outgoing response.
    nginx handles serving all of the static content like HTML/css/images, and Django processes all of the API calls that return dynamic content.
  • supervisord :
    Manages starting and restarting all of the optional/non optional (if you want a fully functioning CRCON) services, all of which are implemented in the rcon package or are standalone programs like rq or cron.
  • maintenance, redis and postgres, that is shared across each image.

It is intended to be run using Docker and docker compose.
Each CRCON install can manage multiple game servers, and each game server (server 1, server 2, etc.) has its own set of images (backend_1, frontend_1, supervisor_1, etc.).

rcon package

The rcon package relies on several core classes.

rcon.connection.HLLConnection handles connecting to the game server (IP, port and RCON password), xor encoding/decoding content and sending/receiving raw bytes over TCP sockets.

rcon.commands.ServerCtl is the parent class of Rcon and handles managing a pool of HllConnection instances, validating/converting low level stuff (like stripping tabs from user generated content for HLL tab delimited lists), automatically retrying commands that fail, and sending the raw commands (such as get profanity) to the game server.

rcon.commands.ServerCtl can be used without any database or redis connection, but is of limited use and not published separately.

rcon.rcon.Rcon inherits from ServerCtl and handles parsing/structuring the raw text received from the game server into meaningful data, interacting with the database, caching command results, etc.

CRCON is not an async (ASGI) web app (async) or multi core (multiprocessing), but it does support running multiple slow (to the game server) requests simultaneously through thread pools.

The rcon package also contains the implementation of most of CRCNs features, if you're not sure how something works, identify which API endpoint is doing the action, look in the URL routing in rconweb and you can see what parts of rcon are imported.

rconweb

The rconweb package is a Django web app that actually exposes all of the URL endpoints and imports from rcon as needed when interacting with the game server versus the local CRCON backend (redis, postgres, etc.).

Some endpoints are explicitly exposed, but some (Rcon methods) are implicitly exposed (rconweb.api.views.expose_api_endpoint).

supervisord

Due to the fact that Python is notoriously single threaded, some core parts of CRCON have been broken out into services that run in their own Python interpreter, so they can take advantage of multiple cores/threads on the system.
This also enables faster network access since each individual network request (to the game server, steam API, Discord, etc.) blocks until completion.

Other portions are optional services and have been split so users have more control over what runs.

The services are managed by supervisord and run inside of their own (supervisor) container.

redis

Redis is used for two reasons in CRCON, caching and interprocess communication.

Every round trip to the game server can be significantly slow (in computing terms) and induces some amount of overhead on both CRCON and the game server.

Some commands are cached, even if they have a very low cache time (such as retrieving logs from the game server) to avoid constantly reprocessing info on very short time frames and others are on a longer cache time because they rarely (if ever) change (such as the list of available maps from the game server).

This also condenses requests that occur almost simultaneously to be reduced to a single request that makes it to the game server, the remaining requests will be resolved from the cache (unless they happened before the first request has completed and cached its results).

Many portions of CRCON run in their own separate Python interpreter instances with their own section of memory, but by caching results with redis, we can communicate back and forth between interpreter instances. This is used both explicitly with rq to run tasks (such as recording game stats to the database, or bulk VIP uploads) and implicitly when something caches function results in redis and is accessed elsewhere.

postgres

CRCON uses postgres 12 with a default configuration.