# Online networking games for STK ## Hosting server First of all, you can compile STK with `-DSERVER_ONLY=ON` which will produce a GUI-less STK binary optimized for size and memory usage, useful for situation like in VPS. The dependencies for RHEL/CentOS 7 are installed with: ```bash yum install wget; cd /tmp; wget https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-12.noarch.rpm; rpm -Uvh epel-release*rpm yum install gcc-c++ cmake openssl-devel libcurl-devel zlib-devel enet ``` ### Hosting WAN (public internet) server You are required to have an stk online account first, go [here](https://online.supertuxkart.net/register.php) for registration. It is recommended you have a saved user in your computer to allow hosting multiple servers simultaneously with the same account, if you have a fresh STK installation, first run: If you intend to keep your server always on (24x7) you are required to implement port forward / direct connection with NAT penetration in your network, we will regularly remove any servers not following this rule. `supertuxkart --init-user --login=your_registered_name --password=your_password` After that you should see `Done saving user, leaving` in terminal if it successfully logged in. Than you can just run: `supertuxkart --server-config=your_config.xml --network-console` It will create that xml configuration file if not found in current directory, you can type `quit` in terminal, than you can edit that file for further configuration as required. ` --network-console` should not be used if you run supertuxkart server later with systemd service, see issue [#4299](https://github.com/supertuxkart/stk-code/issues/4299). The current server configuration xml looks like this: ```xml ``` At the moment STK has a list of STUN servers for NAT penetration which allows players or servers behind a firewall or router to be able to connect to each other, but in case it doesn't work, you have to manually disable the firewall or port forward the port(s) used by STK. By default STK servers use port `2759`. For example, in Ubuntu based distributions, run the following command to disable the firewall on that port: `sudo ufw allow 2759` You may also need to handle the server discovery port `2757` for connecting your WAN server in LAN / localhost. Notice: You don't need to make any firewall or router configuration changes if you connect to the recommended servers (marked with β˜†β˜…STKβ˜…β˜†). ### Hosting LAN (local internet) server Everything is basically the same as WAN one, except you don't need an stk online account, just do: `supertuxkart --server-config=your_config.xml --lan-server=your_server_name --network-console` For LAN server it is required that the server and server discovery port is connectable by clients directly, no NAT penetration will be done in LAN. LAN server can be connected too by typing your server public address (with port) in ```Enter server address``` dialog without relying on stk-addons. ------ After the first time configuration, you can just start the server with the command: `supertuxkart --server-config=your_config.xml`, regardless of whether LAN or WAN server is chosen (of course you need to have a saved user for the WAN one), by default your server logging will be saved to the STK configuration directory with a name of `your_config.log`, given that the server configuration filename is `your_config.xml`. You can find out that directory location [here (See Where is the configuration stored?)](https://supertuxkart.net/FAQ) ## Testing server There is a network AI tester in STK which can use AI on player controller for server hosting linear races game mode, which helps automating the testing for servers, to enable it use it on lan server: `supertuxkart --connect-now=x.x.x.x:y --network-ai=n --no-graphics` Remove `--no-graphics` if you want to see the AI racing. You can also run network AI tester in server-only build of STK. With the network AI tester, it's easier to for example simulate high-loaded servers or bad networks (ones with high ping and/or packet loss). Tested on a Raspberry Pi 3 Model B+, if you have 8 players connected to a server hosted on it, the usage of a single CPU core is ~60% and there are ~60MB of memory usage for game with heavy tracks like Cocoa Temple or Candela City on the server, you can use the above figures to estimate how many STK servers can be hosted on the same computer. For bad network simulation, we recommend `network traffic control` by Linux kernel, see [here](https://wiki.linuxfoundation.org/networking/netem) for details. You will have the best gaming experience by choosing a server where all players have less than 100ms ping with no packet loss. ## Server management (Since 1.1) Currently STK uses sqlite (if building with sqlite3 on) for server management with the following functions at the moment: 1. Server statistics 2. IP / online ID ban list 3. Player reports 4. IPv4 and IPv6 geolocation You need to create a database in sqlite first, run `sqlite3 stkservers.db` in the folder where (all) your server_config.xml(s) located. A table named `v(server database version)_(your_server_config_filename_without_.xml_extension)_stats` will also be created in your database if one does not exist.: ```sql CREATE TABLE IF NOT EXISTS (table name above) ( host_id INTEGER UNSIGNED NOT NULL PRIMARY KEY, -- Unique host id in STKHost of each connection session for a STKPeer ip INTEGER UNSIGNED NOT NULL, -- IP decimal of host ipv6 TEXT NOT NULL DEFAULT '', -- IPv6 (if exists) in string of host (only created if IPv6 server) port INTEGER UNSIGNED NOT NULL, -- Port of host online_id INTEGER UNSIGNED NOT NULL, -- Online if of the host (0 for offline account) username TEXT NOT NULL, -- First player name in the host (if the host has splitscreen player) player_num INTEGER UNSIGNED NOT NULL, -- Number of player(s) from the host, more than 1 if it has splitscreen player country_code TEXT NULL DEFAULT NULL, -- 2-letter country code of the host version TEXT NOT NULL, -- SuperTuxKart version of the host os TEXT NOT NULL, -- Operating system of the host connected_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- Time when connected disconnected_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- Time when disconnected (saved when disconnected) ping INTEGER UNSIGNED NOT NULL DEFAULT 0 -- Ping of the host ) WITHOUT ROWID; ``` STK will also create the following default views from the stats table: `*_full_stats` Full stats with ip in human readable format and time played of each players in minutes. `*_current_players` Current players in server with ip in human readable format and time played of each players in minutes. `*_player_stats` All players with online id and username with their time played stats in this server since creation of this database. If sqlite supports window functions (since 3.25), it will include last session player info (ip, country, ping...). A empty table named `v(server database version)_countries` will also be created in your database if not exists: ```sql CREATE TABLE IF NOT EXISTS (table name above) ( country_code TEXT NOT NULL PRIMARY KEY UNIQUE, -- Unique 2-letter country code country_flag TEXT NOT NULL, -- Unicode country flag representation of 2-letter country code country_name TEXT NOT NULL -- Readable name of this country ) WITHOUT ROWID; ``` If you want to see flags and readable names of countries in the above views, you need to initialize `v(server database version)_countries` table, check [this script](tools/generate-countries-table.py). For IPv4 and online ID ban list, player reports or IP mapping, you need to create one yourself: ```sql CREATE TABLE ip_ban ( ip_start INTEGER UNSIGNED NOT NULL UNIQUE, -- Starting of ip decimal for banning (inclusive) ip_end INTEGER UNSIGNED NOT NULL UNIQUE, -- Ending of ip decimal for banning (inclusive) starting_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- Starting time of this banning entry to be effective expired_days REAL NULL DEFAULT NULL, -- Days for this banning to be expired, use NULL for a permanent ban reason TEXT NOT NULL DEFAULT '', -- Banned reason shown in user stk menu, can be empty description TEXT NOT NULL DEFAULT '', -- Private description for server admin trigger_count INTEGER UNSIGNED NOT NULL DEFAULT 0, -- Number of banning triggered by this ban entry last_trigger TIMESTAMP NULL DEFAULT NULL -- Latest time this banning entry was triggered ); CREATE TABLE ipv6_ban ( ipv6_cidr TEXT NOT NULL UNIQUE, -- IPv6 CIDR range for banning (for example 2001::/64), use /128 for a specific ip starting_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- Starting time of this banning entry to be effective expired_days REAL NULL DEFAULT NULL, -- Days for this banning to be expired, use NULL for a permanent ban reason TEXT NOT NULL DEFAULT '', -- Banned reason shown in user stk menu, can be empty description TEXT NOT NULL DEFAULT '', -- Private description for server admin trigger_count INTEGER UNSIGNED NOT NULL DEFAULT 0, -- Number of banning triggered by this ban entry last_trigger TIMESTAMP NULL DEFAULT NULL -- Latest time this banning entry was triggered ); CREATE TABLE online_id_ban ( online_id INTEGER UNSIGNED NOT NULL UNIQUE, -- Online id from STK addons database for banning starting_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- Starting time of this banning entry to be effective expired_days REAL NULL DEFAULT NULL, -- Days for this banning to be expired, use NULL for a permanent ban reason TEXT NOT NULL DEFAULT '', -- Banned reason shown in user stk menu, can be empty description TEXT NOT NULL DEFAULT '', -- Private description for server admin trigger_count INTEGER UNSIGNED NOT NULL DEFAULT 0, -- Number of banning triggered by this ban entry last_trigger TIMESTAMP NULL DEFAULT NULL -- Latest time this banning entry was triggered ); CREATE TABLE player_reports ( server_uid TEXT NOT NULL, -- Report from which server unique id (config filename) reporter_ip INTEGER UNSIGNED NOT NULL, -- IP decimal of player who reports reporter_ipv6 TEXT NOT NULL DEFAULT '', -- IPv6 (if exists) in string of player who reports (only needed for IPv6 server) reporter_online_id INTEGER UNSIGNED NOT NULL, -- Online id of player who reports, 0 for offline player reporter_username TEXT NOT NULL, -- Player name who reports reported_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- Time of reporting info TEXT NOT NULL, -- Report info by reporter reporting_ip INTEGER UNSIGNED NOT NULL, -- IP decimal of player being reported reporting_ipv6 TEXT NOT NULL DEFAULT '', -- IPv6 (if exists) in string of player who reports (only needed for IPv6 server) reporting_online_id INTEGER UNSIGNED NOT NULL, -- Online id of player being reported, 0 for offline player reporting_username TEXT NOT NULL -- Player name being reported ); CREATE TABLE ip_mapping ( ip_start INTEGER UNSIGNED NOT NULL PRIMARY KEY UNIQUE, -- IP decimal start ip_end INTEGER UNSIGNED NOT NULL UNIQUE, -- IP decimal end latitude REAL NOT NULL, -- Latitude of this IP range longitude REAL NOT NULL, -- Longitude of this IP range country_code TEXT NOT NULL -- 2-letter country code ) WITHOUT ROWID; CREATE TABLE ipv6_mapping ( ip_start INTEGER UNSIGNED NOT NULL PRIMARY KEY UNIQUE, -- IP decimal (upper 64bit) start ip_end INTEGER UNSIGNED NOT NULL UNIQUE, -- IP decimal (upper 64bit) end latitude REAL NOT NULL, -- Latitude of this IP range longitude REAL NOT NULL, -- Longitude of this IP range country_code TEXT NOT NULL -- 2-letter country code ) ``` For initialization of `ip_mapping` table, check [this script](tools/generate-ip-mappings.py).