Gameserver/configs/stkranking.patch

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"
+ ");", 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: