288 lines
12 KiB
Diff
288 lines
12 KiB
Diff
|
diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp
|
||
|
index 3516ffe03..aa3fd698b 100644
|
||
|
--- a/src/network/protocols/server_lobby.cpp
|
||
|
+++ b/src/network/protocols/server_lobby.cpp
|
||
|
@@ -249,6 +249,7 @@ ServerLobby::ServerLobby() : LobbyProtocol()
|
||
|
m_game_mode.store(ServerConfig::m_server_mode);
|
||
|
m_default_vote = new PeerVote();
|
||
|
m_player_reports_table_exists = false;
|
||
|
+ m_grand_prix_rowid = -1;
|
||
|
initDatabase();
|
||
|
} // ServerLobby
|
||
|
|
||
|
@@ -389,6 +390,51 @@ void ServerLobby::initServerStatsTable()
|
||
|
") WITHOUT ROWID;", country_table_name.c_str());
|
||
|
easySQLQuery(query);
|
||
|
|
||
|
+ // Extra default table _grandprixresults:
|
||
|
+ std::string grandprixresults_table_name = std::string("v") +
|
||
|
+ StringUtils::toString(ServerConfig::m_server_db_version) + "_" +
|
||
|
+ ServerConfig::m_server_uid + "_grandprixresults";
|
||
|
+ query = StringUtils::insertValues(
|
||
|
+ "CREATE TABLE IF NOT EXISTS %s (\n"
|
||
|
+ " num_races INTEGER NOT NULL, -- Number of races completed\n"
|
||
|
+ " total_races INTEGER NOT NULL -- Total number of races\n"
|
||
|
+ ");", grandprixresults_table_name.c_str());
|
||
|
+ if(easySQLQuery(query)) {
|
||
|
+ m_server_grandprixresults_table = grandprixresults_table_name;
|
||
|
+ }
|
||
|
+
|
||
|
+ // Extra default table _raceresults:
|
||
|
+ std::string raceresults_table_name = std::string("v") +
|
||
|
+ StringUtils::toString(ServerConfig::m_server_db_version) + "_" +
|
||
|
+ ServerConfig::m_server_uid + "_raceresults";
|
||
|
+ query = StringUtils::insertValues(
|
||
|
+ "CREATE TABLE IF NOT EXISTS %s (\n"
|
||
|
+ " race_finished TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- Time when race was completed\n"
|
||
|
+ " grandprix_rowid INTEGER, -- ROWID of the grand prix this race is part of (optional)\n"
|
||
|
+ " track_name TEXT NOT NULL, -- Number of laps completed\n"
|
||
|
+ " num_laps INTEGER NOT NULL, -- Number of laps completed\n"
|
||
|
+ " total_laps INTEGER NOT NULL, -- Total number of laps\n"
|
||
|
+ " fastest_lap_time FLOAT NOT NULL, -- Fastest lap so far\n"
|
||
|
+ " fastest_lap_player TEXT NOT NULL -- Fastest lap so far\n"
|
||
|
+ ");", raceresults_table_name.c_str());
|
||
|
+ if(easySQLQuery(query)) {
|
||
|
+ m_server_raceresults_table = raceresults_table_name;
|
||
|
+ }
|
||
|
+
|
||
|
+ // Extra default table _raceresults:
|
||
|
+ std::string playerresults_table_name = std::string("v") +
|
||
|
+ StringUtils::toString(ServerConfig::m_server_db_version) + "_" +
|
||
|
+ ServerConfig::m_server_uid + "_playerresults";
|
||
|
+ query = StringUtils::insertValues(
|
||
|
+ "CREATE TABLE IF NOT EXISTS %s (\n"
|
||
|
+ " race_rowid INTEGER NOT NULL, -- ROWID of the race\n"
|
||
|
+ " elapsed_time FLOAT NOT NULL, -- Total race time\n"
|
||
|
+ " player_name TEXT NOT NULL -- Player name\n"
|
||
|
+ ") WITHOUT ROWID;", playerresults_table_name.c_str());
|
||
|
+ if(easySQLQuery(query)) {
|
||
|
+ m_server_playerresults_table = playerresults_table_name;
|
||
|
+ }
|
||
|
+
|
||
|
// Default views:
|
||
|
// _full_stats
|
||
|
// Full stats with ip in human readable format and time played of each
|
||
|
@@ -2884,6 +2930,7 @@ void ServerLobby::checkRaceFinished()
|
||
|
RaceEventManager::get()->getProtocol()->requestTerminate();
|
||
|
GameProtocol::lock()->requestTerminate();
|
||
|
|
||
|
+
|
||
|
// Save race result before delete the world
|
||
|
m_result_ns->clear();
|
||
|
m_result_ns->addUInt8(LE_RACE_FINISHED);
|
||
|
@@ -2895,10 +2942,13 @@ void ServerLobby::checkRaceFinished()
|
||
|
m_result_ns->addUInt32(fastest_lap);
|
||
|
m_result_ns->encodeString(static_cast<LinearWorld*>(World::getWorld())
|
||
|
->getFastestLapKartName());
|
||
|
+ std::cout << static_cast<LinearWorld*>(World::getWorld())->getFastestLapKartName().c_str() << std::endl;
|
||
|
+ Log::info("RaceResults", "Fastest lap by %s", StringUtils::wideToUtf8(static_cast<LinearWorld*>(World::getWorld())->getFastestLapKartName()).c_str());
|
||
|
|
||
|
// all gp tracks
|
||
|
m_result_ns->addUInt8((uint8_t)m_game_setup->getTotalGrandPrixTracks())
|
||
|
.addUInt8((uint8_t)m_game_setup->getAllTracks().size());
|
||
|
+ Log::info("RaceResults", "Track number %d / %d", m_game_setup->getAllTracks().size(), m_game_setup->getTotalGrandPrixTracks());
|
||
|
for (const std::string& gp_track : m_game_setup->getAllTracks())
|
||
|
m_result_ns->encodeString(gp_track);
|
||
|
|
||
|
@@ -2917,9 +2967,13 @@ void ServerLobby::checkRaceFinished()
|
||
|
overall_time = overall_time + player->getOverallTime();
|
||
|
player->setScore(cur_score);
|
||
|
player->setOverallTime(overall_time);
|
||
|
+ Log::info("RaceResults", "Score for %s from %d to %d (%f)", StringUtils::wideToUtf8(player->getName()).c_str(), last_score, cur_score, overall_time);
|
||
|
+ }
|
||
|
+ else {
|
||
|
+ Log::info("RaceResults", "Score for player %d from %d to %d (%f)", i, last_score, cur_score, overall_time);
|
||
|
}
|
||
|
m_result_ns->addUInt32(last_score).addUInt32(cur_score)
|
||
|
- .addFloat(overall_time);
|
||
|
+ .addFloat(overall_time);
|
||
|
}
|
||
|
}
|
||
|
else if (RaceManager::get()->modeHasLaps())
|
||
|
@@ -2936,6 +2990,8 @@ void ServerLobby::checkRaceFinished()
|
||
|
ranking_changes_indication = 1;
|
||
|
m_result_ns->addUInt8(ranking_changes_indication);
|
||
|
|
||
|
+ writeRaceResults();
|
||
|
+
|
||
|
if (ServerConfig::m_ranked)
|
||
|
{
|
||
|
computeNewRankings();
|
||
|
@@ -2944,6 +3000,148 @@ void ServerLobby::checkRaceFinished()
|
||
|
m_state.store(WAIT_FOR_RACE_STOPPED);
|
||
|
} // checkRaceFinished
|
||
|
|
||
|
+int ServerLobby::getLastRowID(const std::string &table) {
|
||
|
+ int rowid = -1;
|
||
|
+ std::string query = StringUtils::insertValues("SELECT ROWID from %s ORDER BY ROWID DESC LIMIT 1;", table);
|
||
|
+
|
||
|
+ sqlite3_stmt* stmt = NULL;
|
||
|
+ int ret = sqlite3_prepare_v2(m_db, query.c_str(), -1, &stmt, 0);
|
||
|
+ if (ret == SQLITE_OK)
|
||
|
+ {
|
||
|
+ ret = sqlite3_step(stmt);
|
||
|
+ if (ret == SQLITE_ROW)
|
||
|
+ {
|
||
|
+ rowid = sqlite3_column_int(stmt, 0);
|
||
|
+ }
|
||
|
+ ret = sqlite3_finalize(stmt);
|
||
|
+ if (ret != SQLITE_OK)
|
||
|
+ {
|
||
|
+ Log::error("ServerLobby",
|
||
|
+ "Error rowid database for query %s: %s",
|
||
|
+ query.c_str(), sqlite3_errmsg(m_db));
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ Log::error("ServerLobby", "Error preparing database for query %s: %s",
|
||
|
+ query.c_str(), sqlite3_errmsg(m_db));
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ return rowid;
|
||
|
+
|
||
|
+}
|
||
|
+
|
||
|
+//-----------------------------------------------------------------------------
|
||
|
+/** Write the results of the race
|
||
|
+ */
|
||
|
+void ServerLobby::writeRaceResults()
|
||
|
+{
|
||
|
+#ifdef ENABLE_SQLITE3
|
||
|
+ std::string track_name = RaceManager::get()->getTrackName();
|
||
|
+ bool track_reverse = RaceManager::get()->getReverseTrack();
|
||
|
+ int player_count = RaceManager::get()->getNumPlayers();
|
||
|
+ int laps_number = RaceManager::get()->getNumLaps();
|
||
|
+
|
||
|
+ if (RaceManager::get()->getMinorMode() == RaceManager::MINOR_MODE_NORMAL_RACE) {
|
||
|
+ std::string query;
|
||
|
+ if (m_game_setup->isGrandPrix()) {
|
||
|
+ int race_number = m_game_setup->getAllTracks().size();
|
||
|
+ int total_races = m_game_setup->getTotalGrandPrixTracks();
|
||
|
+ if(race_number == 1) {
|
||
|
+ query = StringUtils::insertValues(
|
||
|
+ "INSERT INTO %s "
|
||
|
+ "(num_races, total_races) "
|
||
|
+ "VALUES (%d, %d);",
|
||
|
+ m_server_grandprixresults_table,
|
||
|
+ race_number,
|
||
|
+ total_races
|
||
|
+ );
|
||
|
+ if(easySQLQuery(query)) {
|
||
|
+ m_grand_prix_rowid = getLastRowID(m_server_grandprixresults_table);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else {
|
||
|
+ query = StringUtils::insertValues(
|
||
|
+ "UPDATE %s "
|
||
|
+ "SET num_races = %d "
|
||
|
+ "WHERE ROWID = %d;",
|
||
|
+ m_server_grandprixresults_table,
|
||
|
+ race_number,
|
||
|
+ m_grand_prix_rowid
|
||
|
+ );
|
||
|
+ easySQLQuery(query);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if(m_grand_prix_rowid >= 0) {
|
||
|
+ query = StringUtils::insertValues(
|
||
|
+ "INSERT INTO %s "
|
||
|
+ "(grandprix_rowid, track_name, num_laps, total_laps, fastest_lap_time, fastest_lap_player) "
|
||
|
+ "VALUES (%d, \"%s\", %d, %d, %f, \"%s\");",
|
||
|
+ m_server_raceresults_table,
|
||
|
+ m_grand_prix_rowid,
|
||
|
+ track_name,
|
||
|
+ laps_number,
|
||
|
+ 0,
|
||
|
+ 0.,
|
||
|
+ ""
|
||
|
+ );
|
||
|
+ }
|
||
|
+ else {
|
||
|
+ query = StringUtils::insertValues(
|
||
|
+ "INSERT INTO %s "
|
||
|
+ "(track_name, num_laps, total_laps, fastest_lap_time, fastest_lap_player) "
|
||
|
+ "VALUES (\"%s\", %d, %d, %f, \"%s\");",
|
||
|
+ m_server_raceresults_table,
|
||
|
+ track_name,
|
||
|
+ laps_number,
|
||
|
+ 0,
|
||
|
+ 0.,
|
||
|
+ ""
|
||
|
+ );
|
||
|
+ }
|
||
|
+ if(easySQLQuery(query)) {
|
||
|
+ int race_rowid = getLastRowID(m_server_raceresults_table);
|
||
|
+ Log::info("RaceResults", "Row ID: %d", race_rowid);
|
||
|
+ if(race_rowid >= 0) {
|
||
|
+ for (int i = 0; i < player_count; i++) {
|
||
|
+ double elapsed_time = RaceManager::get()->getKartRaceTime(i);
|
||
|
+ std::string player_name = StringUtils::wideToUtf8(
|
||
|
+ RaceManager::get()->getKartInfo(i).getPlayerName());
|
||
|
+ //int grand_prix_rank = RaceManager::get()->getKartGPRank(i);
|
||
|
+ query = StringUtils::insertValues(
|
||
|
+ "INSERT INTO %s "
|
||
|
+ "(race_rowid, elapsed_time, player_name) "
|
||
|
+ "VALUES (%d, %f, ?);",
|
||
|
+ m_server_playerresults_table,
|
||
|
+ race_rowid,
|
||
|
+ elapsed_time
|
||
|
+ );
|
||
|
+ easySQLQuery(query, [player_name](sqlite3_stmt* stmt) {
|
||
|
+ if (sqlite3_bind_text(stmt, 1, player_name.c_str(),
|
||
|
+ -1, SQLITE_TRANSIENT) != SQLITE_OK)
|
||
|
+ {
|
||
|
+ Log::error("easySQLQuery", "Failed to bind %s.",
|
||
|
+ player_name.c_str());
|
||
|
+ }
|
||
|
+ });
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if(m_game_setup->isGrandPrix()) {
|
||
|
+ int race_number = m_game_setup->getAllTracks().size();
|
||
|
+ int total_races = m_game_setup->getTotalGrandPrixTracks();
|
||
|
+
|
||
|
+ if(race_number == total_races) {
|
||
|
+ m_grand_prix_rowid = -1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+#endif
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
//-----------------------------------------------------------------------------
|
||
|
/** Compute the new player's rankings used in ranked servers
|
||
|
*/
|
||
|
diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp
|
||
|
index 53d3aceda..780ef2d4e 100644
|
||
|
--- a/src/network/protocols/server_lobby.hpp
|
||
|
+++ b/src/network/protocols/server_lobby.hpp
|
||
|
@@ -85,6 +85,14 @@ private:
|
||
|
|
||
|
std::string m_server_stats_table;
|
||
|
|
||
|
+ std::string m_server_grandprixresults_table;
|
||
|
+
|
||
|
+ std::string m_server_raceresults_table;
|
||
|
+
|
||
|
+ std::string m_server_playerresults_table;
|
||
|
+
|
||
|
+ int m_grand_prix_rowid;
|
||
|
+
|
||
|
bool m_ip_ban_table_exists;
|
||
|
|
||
|
bool m_ipv6_ban_table_exists;
|
||
|
@@ -377,6 +385,8 @@ private:
|
||
|
void testBannedForOnlineId(STKPeer* peer, uint32_t online_id) const;
|
||
|
void writeDisconnectInfoTable(STKPeer* peer);
|
||
|
void writePlayerReport(Event* event);
|
||
|
+ int getLastRowID(const std::string &table);
|
||
|
+ void writeRaceResults();
|
||
|
bool supportsAI();
|
||
|
void updateAddons();
|
||
|
public:
|