Allow showing full country info in views

This commit is contained in:
Benau 2019-05-11 10:16:38 +08:00
parent d47cdac279
commit 21322fdf9e
3 changed files with 67 additions and 4 deletions

View File

@ -253,6 +253,18 @@ Current players in server with ip in human readable format and time played of ea
`*_player_stats`
All players with online id and username with their time played stats in this server since creation of this database.
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 `*_full_stats` and `*_current_players` views, you need to initialize `v(server database version)_countries` table, check [this script](tools/generate-countries-table.py).
For IP, online ID ban list or player reports, you need to create one yourself:
```sql
CREATE TABLE ip_ban

View File

@ -258,6 +258,18 @@ void ServerLobby::initServerStatsTable()
if (m_server_stats_table.empty())
return;
// Extra default table _countries:
// Server owner need to initialise this table himself, check NETWORKING.md
std::string country_table_name = std::string("v") + StringUtils::toString(
ServerConfig::m_server_db_version) + "_countries";
query = StringUtils::insertValues(
"CREATE TABLE IF NOT EXISTS %s (\n"
" country_code TEXT NOT NULL PRIMARY KEY UNIQUE, -- Unique 2-letter country code\n"
" country_flag TEXT NOT NULL, -- Unicode country flag representation of 2-letter country code\n"
" country_name TEXT NOT NULL -- Readable name of this country\n"
") WITHOUT ROWID;", country_table_name.c_str());
easySQLQuery(query);
// Default views:
// _full_stats
// Full stats with ip in human readable format and time played of each
@ -269,10 +281,13 @@ void ServerLobby::initServerStatsTable()
oss << "CREATE VIEW IF NOT EXISTS " << view_name << " AS\n"
<< " SELECT host_id, ip,\n"
<< " ((ip >> 24) & 255) ||'.'|| ((ip >> 16) & 255) ||'.'|| ((ip >> 8) & 255) ||'.'|| ((ip ) & 255) AS ip_readable,\n"
<< " port, online_id, username, player_num, country_code, version,\n"
<< " port, online_id, username, player_num,\n"
<< " " << m_server_stats_table << ".country_code AS country_code, country_flag, country_name, version,\n"
<< " ROUND((STRFTIME(\"%s\", disconnected_time) - STRFTIME(\"%s\", connected_time)) / 60.0, 2) AS time_played,\n"
<< " connected_time, disconnected_time, ping\n"
<< " FROM " << m_server_stats_table << " ORDER BY connected_time DESC;";
<< " connected_time, disconnected_time, ping FROM " << m_server_stats_table << "\n"
<< " LEFT JOIN " << country_table_name << " ON "
<< country_table_name << ".country_code = " << m_server_stats_table << ".country_code\n"
<< " ORDER BY connected_time DESC;";
query = oss.str();
easySQLQuery(query);
@ -287,9 +302,12 @@ void ServerLobby::initServerStatsTable()
oss << "CREATE VIEW IF NOT EXISTS " << view_name << " AS\n"
<< " SELECT host_id, ip,\n"
<< " ((ip >> 24) & 255) ||'.'|| ((ip >> 16) & 255) ||'.'|| ((ip >> 8) & 255) ||'.'|| ((ip ) & 255) AS ip_readable,\n"
<< " port, online_id, username, player_num, country_code, version,\n"
<< " port, online_id, username, player_num,\n"
<< " " << m_server_stats_table << ".country_code AS country_code, country_flag, country_name, version,\n"
<< " ROUND((STRFTIME(\"%s\", 'now') - STRFTIME(\"%s\", connected_time)) / 60.0, 2) AS time_played,\n"
<< " connected_time, ping FROM " << m_server_stats_table << "\n"
<< " LEFT JOIN " << country_table_name << " ON "
<< country_table_name << ".country_code = " << m_server_stats_table << ".country_code\n"
<< " WHERE connected_time = disconnected_time;";
query = oss.str();
easySQLQuery(query);

View File

@ -0,0 +1,33 @@
#!/usr/bin/env python3
# usage: generate-countries-table.py > countries.csv
# in sqlite3 terminal:
#
# .mode csv
# .headers off
# .separator ";"
# .import `full path to countries.csv` `v(database_version)_countries`
#
import csv
import os
import sys
CSV_FILE = '../data/country_names.csv'
# Use another name in the country_code header if you want countries names in different language
READABLE_NAME = 'en'
# ord("🇦") - ord("A")
FLAG_OFFSET = 127397
if not os.path.exists(CSV_FILE):
print("File = {} does not exist.".format(CSV_FILE))
sys.exit(1)
with open(CSV_FILE, 'r') as csvfile:
country = csv.DictReader(csvfile, delimiter=';', quotechar='"')
# Skip header
next(country)
for row in country:
country_code = row['country_code']
codepoints = [ord(x) + FLAG_OFFSET for x in country_code]
print('%s;%s;%s' % (country_code, chr(codepoints[0]) + chr(codepoints[1]), row[READABLE_NAME]))