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` `*_player_stats`
All players with online id and username with their time played stats in this server since creation of this database. 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: For IP, online ID ban list or player reports, you need to create one yourself:
```sql ```sql
CREATE TABLE ip_ban CREATE TABLE ip_ban

View File

@ -258,6 +258,18 @@ void ServerLobby::initServerStatsTable()
if (m_server_stats_table.empty()) if (m_server_stats_table.empty())
return; 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: // Default views:
// _full_stats // _full_stats
// Full stats with ip in human readable format and time played of each // 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" oss << "CREATE VIEW IF NOT EXISTS " << view_name << " AS\n"
<< " SELECT host_id, ip,\n" << " SELECT host_id, ip,\n"
<< " ((ip >> 24) & 255) ||'.'|| ((ip >> 16) & 255) ||'.'|| ((ip >> 8) & 255) ||'.'|| ((ip ) & 255) AS ip_readable,\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" << " ROUND((STRFTIME(\"%s\", disconnected_time) - STRFTIME(\"%s\", connected_time)) / 60.0, 2) AS time_played,\n"
<< " connected_time, disconnected_time, ping\n" << " connected_time, disconnected_time, ping FROM " << m_server_stats_table << "\n"
<< " FROM " << m_server_stats_table << " ORDER BY connected_time DESC;"; << " 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(); query = oss.str();
easySQLQuery(query); easySQLQuery(query);
@ -287,9 +302,12 @@ void ServerLobby::initServerStatsTable()
oss << "CREATE VIEW IF NOT EXISTS " << view_name << " AS\n" oss << "CREATE VIEW IF NOT EXISTS " << view_name << " AS\n"
<< " SELECT host_id, ip,\n" << " SELECT host_id, ip,\n"
<< " ((ip >> 24) & 255) ||'.'|| ((ip >> 16) & 255) ||'.'|| ((ip >> 8) & 255) ||'.'|| ((ip ) & 255) AS ip_readable,\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" << " ROUND((STRFTIME(\"%s\", 'now') - STRFTIME(\"%s\", connected_time)) / 60.0, 2) AS time_played,\n"
<< " connected_time, ping FROM " << m_server_stats_table << "\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;"; << " WHERE connected_time = disconnected_time;";
query = oss.str(); query = oss.str();
easySQLQuery(query); 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]))