From 79e3d298ce679de0ae001baa223476ce9523fb4f Mon Sep 17 00:00:00 2001 From: Alayan-stk-2 Date: Mon, 4 Jun 2018 01:50:24 +0200 Subject: [PATCH 1/6] Correct finish time for GPs when skipping a race (#3276) * Make human players have a correct finish time when skipping a GP race * Don't compute the estimated finish time twice --- src/modes/standard_race.cpp | 38 ++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/modes/standard_race.cpp b/src/modes/standard_race.cpp index 0fa6f72d3..e701c6e6b 100644 --- a/src/modes/standard_race.cpp +++ b/src/modes/standard_race.cpp @@ -98,36 +98,56 @@ void StandardRace::endRaceEarly() std::vector active_players; // Required for debugging purposes beginSetKartPositions(); + float worse_finish_time = 0.0f; + for (unsigned int i = 1; i <= kart_amount; i++) { int kartid = m_position_index[i-1]; AbstractKart* kart = m_karts[kartid]; + if (kart->hasFinishedRace()) { + if (kart->getFinishTime() > worse_finish_time) + worse_finish_time = kart->getFinishTime(); + // Have to do this to keep endSetKartPosition happy setKartPosition(kartid, kart->getPosition()); - continue; } - if (kart->getController()->isPlayerController()) - { - // Keep active players apart for now - active_players.push_back(kartid); - } else { + float estimated_finish_time = estimateFinishTimeForKart(kart); + if (estimated_finish_time > worse_finish_time) + worse_finish_time = estimated_finish_time; + + // Keep active players apart for now + if (kart->getController()->isPlayerController()) + { + active_players.push_back(kartid); + } // AI karts finish - setKartPosition(kartid, i - (unsigned int) active_players.size()); - kart->finishedRace(estimateFinishTimeForKart(kart)); + else + { + setKartPosition(kartid, i - (unsigned int) active_players.size()); + kart->finishedRace(estimated_finish_time); + } } } // i <= kart_amount + // Now make the active players finish for (unsigned int i = 0; i < active_players.size(); i++) { int kartid = active_players[i]; int position = getNumKarts() - (int) active_players.size() + 1 + i; setKartPosition(kartid, position); - m_karts[kartid]->eliminate(); + float punished_time = estimateFinishTimeForKart(m_karts[kartid]) + + worse_finish_time - WorldStatus::getTime(); + m_karts[kartid]->finishedRace(punished_time); + + // In networked races, endRaceEarly will be called if a player + // takes too much time to finish, so don't mark him as eliminated + if (!isNetworkWorld()) + m_karts[kartid]->eliminate(); } // Finish the active players endSetKartPositions(); setPhase(RESULT_DISPLAY_PHASE); From 42d98f8ff12cda393bdf527fa20178fbf50400ee Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Sun, 3 Jun 2018 21:04:46 -0400 Subject: [PATCH 2/6] Start on UTF-8 config conversion --- src/achievements/achievement.cpp | 4 +-- src/achievements/achievements_status.cpp | 4 +-- src/challenges/challenge_status.cpp | 12 ++++---- src/challenges/story_mode_status.cpp | 4 +-- src/config/player_manager.cpp | 10 +++---- src/config/player_profile.cpp | 26 +++++++++--------- src/io/utf_writer.cpp | 35 +++++++++++++++++++----- src/io/utf_writer.hpp | 21 ++++++++++++-- src/race/grand_prix_data.cpp | 16 +++++------ src/race/highscore_manager.cpp | 8 +++--- src/race/highscores.cpp | 22 +++++++-------- 11 files changed, 99 insertions(+), 63 deletions(-) diff --git a/src/achievements/achievement.cpp b/src/achievements/achievement.cpp index d6dbb3589..7aa60397b 100644 --- a/src/achievements/achievement.cpp +++ b/src/achievements/achievement.cpp @@ -68,8 +68,8 @@ void Achievement::load(const XMLNode *node) */ void Achievement::save(UTFWriter &out) { - out << L" \n"; diff --git a/src/achievements/achievements_status.cpp b/src/achievements/achievements_status.cpp index bccf443d2..2b51abe7e 100644 --- a/src/achievements/achievements_status.cpp +++ b/src/achievements/achievements_status.cpp @@ -94,14 +94,14 @@ void AchievementsStatus::add(Achievement *achievement) */ void AchievementsStatus::save(UTFWriter &out) { - out << L" \n"; + out << " \n"; std::map::const_iterator i; for(i = m_achievements.begin(); i != m_achievements.end(); i++) { if (i->second != NULL) i->second->save(out); } - out << L" \n"; + out << " \n"; } // save // ---------------------------------------------------------------------------- diff --git a/src/challenges/challenge_status.cpp b/src/challenges/challenge_status.cpp index 1c0c36863..1397422ea 100644 --- a/src/challenges/challenge_status.cpp +++ b/src/challenges/challenge_status.cpp @@ -104,15 +104,15 @@ bool ChallengeStatus::isGrandPrix() void ChallengeStatus::save(UTFWriter& writer) { - writer << L" <" << m_data->getChallengeId(); + writer << " <" << m_data->getChallengeId(); if (isSolved(RaceManager::DIFFICULTY_BEST)) - writer << L" solved=\"best\"/>\n"; + writer << " solved=\"best\"/>\n"; else if (isSolved(RaceManager::DIFFICULTY_HARD)) - writer << L" solved=\"hard\"/>\n"; + writer << " solved=\"hard\"/>\n"; else if (isSolved(RaceManager::DIFFICULTY_MEDIUM)) - writer << L" solved=\"medium\"/>\n"; + writer << " solved=\"medium\"/>\n"; else if (isSolved(RaceManager::DIFFICULTY_EASY)) - writer << L" solved=\"easy\"/>\n"; + writer << " solved=\"easy\"/>\n"; else - writer << L" solved=\"none\"/>\n"; + writer << " solved=\"none\"/>\n"; } // save diff --git a/src/challenges/story_mode_status.cpp b/src/challenges/story_mode_status.cpp index 8fb8d820a..266f6548d 100644 --- a/src/challenges/story_mode_status.cpp +++ b/src/challenges/story_mode_status.cpp @@ -355,7 +355,7 @@ void StoryModeStatus::grandPrixFinished() */ void StoryModeStatus::save(UTFWriter &out) { - out << L" \n"; + out << " \n"; std::map::const_iterator i; for(i = m_challenges_state.begin(); i != m_challenges_state.end(); i++) @@ -363,5 +363,5 @@ void StoryModeStatus::save(UTFWriter &out) if (i->second != NULL) i->second->save(out); } - out << L" \n"; + out << " \n"; } // save diff --git a/src/config/player_manager.cpp b/src/config/player_manager.cpp index 416600b46..f52e470e4 100644 --- a/src/config/player_manager.cpp +++ b/src/config/player_manager.cpp @@ -261,14 +261,14 @@ void PlayerManager::save() std::string filename = file_manager->getUserConfigFile("players.xml"); try { - UTFWriter players_file(filename.c_str()); + UTFWriter players_file(filename.c_str(), false); - players_file << L"\n"; - players_file << L"\n"; + players_file << "\n"; + players_file << "\n"; if(m_current_player) { - players_file << L" getName(true/*ignoreRTL*/)) << L"\"/>\n"; } @@ -278,7 +278,7 @@ void PlayerManager::save() if(!player->isGuestAccount()) player->save(players_file); } - players_file << L"\n"; + players_file << "\n"; players_file.close(); } catch (std::runtime_error& e) diff --git a/src/config/player_profile.cpp b/src/config/player_profile.cpp index a7b10f42a..d9b465e16 100644 --- a/src/config/player_profile.cpp +++ b/src/config/player_profile.cpp @@ -200,21 +200,21 @@ const std::string PlayerProfile::getIconFilename() const */ void PlayerProfile::save(UTFWriter &out) { - out << L" \n"; + out << " saved-user=\"" << m_saved_user_id + << "\" saved-token=\"" << m_saved_token << "\"\n"; + out << " last-online-name=\"" << StringUtils::xmlEncode(m_last_online_name) + << "\" last-was-online=\"" << m_last_was_online << "\"\n"; + out << " remember-password=\"" << m_remember_password << "\"\n"; + out << " default-kart-color=\"" << m_default_kart_color << "\">\n"; { if(m_story_mode_status) m_story_mode_status->save(out); @@ -222,7 +222,7 @@ void PlayerProfile::save(UTFWriter &out) if(m_achievements_status) m_achievements_status->save(out); } - out << L" \n"; + out << " \n"; } // save //------------------------------------------------------------------------------ diff --git a/src/io/utf_writer.cpp b/src/io/utf_writer.cpp index 4232f20ab..9e12f3770 100644 --- a/src/io/utf_writer.cpp +++ b/src/io/utf_writer.cpp @@ -25,27 +25,40 @@ using namespace irr; // ---------------------------------------------------------------------------- -UTFWriter::UTFWriter(const char* dest) +UTFWriter::UTFWriter(const char* dest, bool wide) : m_base(dest, std::ios::out | std::ios::binary) { + m_wide = wide; + if (!m_base.is_open()) { throw std::runtime_error("Failed to open file for writing : " + std::string(dest)); } - // FIXME: make sure to properly handle endianness - // UTF-16 BOM is 0xFEFF; UTF-32 BOM is 0x0000FEFF. So this works in either case - wchar_t BOM = 0xFEFF; + if (wide) + { + // FIXME: make sure to properly handle endianness + // UTF-16 BOM is 0xFEFF; UTF-32 BOM is 0x0000FEFF. So this works in either case + wchar_t BOM = 0xFEFF; - m_base.write((char *) &BOM, sizeof(wchar_t)); + m_base.write((char *) &BOM, sizeof(wchar_t)); + } } // UTFWriter // ---------------------------------------------------------------------------- UTFWriter& UTFWriter::operator<< (const irr::core::stringw& txt) { - m_base.write((char *) txt.c_str(), txt.size() * sizeof(wchar_t)); + if (m_wide) + { + m_base.write((char *) txt.c_str(), txt.size() * sizeof(wchar_t)); + } + else + { + std::string utf8 = StringUtils::wideToUtf8(txt); + operator<<(utf8); + } return *this; } // operator<< (stringw) @@ -53,7 +66,15 @@ UTFWriter& UTFWriter::operator<< (const irr::core::stringw& txt) UTFWriter& UTFWriter::operator<< (const wchar_t*txt) { - m_base.write((char *) txt, wcslen(txt) * sizeof(wchar_t)); + if (m_wide) + { + m_base.write((char *) txt, wcslen(txt) * sizeof(wchar_t)); + } + else + { + std::string utf8 = StringUtils::wideToUtf8(txt); + operator<<(utf8); + } return *this; } // operator<< (wchar_t) diff --git a/src/io/utf_writer.hpp b/src/io/utf_writer.hpp index 02f8ebcd7..9ac71f7a5 100644 --- a/src/io/utf_writer.hpp +++ b/src/io/utf_writer.hpp @@ -34,9 +34,12 @@ class UTFWriter { std::ofstream m_base; + + /** If true, use utf-16/32 (obsolete) */ + bool m_wide; public: - UTFWriter(const char* dest); + UTFWriter(const char* dest, bool wide); void close(); UTFWriter& operator<< (const irr::core::stringw& txt); @@ -44,12 +47,24 @@ public: // ------------------------------------------------------------------------ UTFWriter& operator<< (const char *txt) { - return operator<<(irr::core::stringw(txt)); + if (m_wide) + { + return operator<<(irr::core::stringw(txt)); + } + else + { + m_base.write((char *)txt, strlen(txt)); + return *this; + } + } // operator<<(char*) // ------------------------------------------------------------------------ UTFWriter& operator<< (const std::string &txt) { - return operator<< (irr::core::stringw(txt.c_str())); + if (m_wide) + return operator<<(irr::core::stringw(txt.c_str())); + else + return operator<<(txt.c_str()); } // operator<<(std::string) // ------------------------------------------------------------------------ UTFWriter& operator<< (const bool &b) diff --git a/src/race/grand_prix_data.cpp b/src/race/grand_prix_data.cpp index 1a662f091..9e7c1460b 100644 --- a/src/race/grand_prix_data.cpp +++ b/src/race/grand_prix_data.cpp @@ -361,20 +361,20 @@ bool GrandPrixData::writeToFile() { try { - UTFWriter file(m_filename.c_str()); + UTFWriter file(m_filename.c_str(), false); if (file.is_open()) { - file << L"\n\n\n"; + file << "\n\n\n"; for (unsigned int i = 0; i < m_tracks.size(); i++) { file << - L"\t\n"; + "\t\n"; } - file << L"\n\n"; + file << "\n\n"; file.close(); diff --git a/src/race/highscore_manager.cpp b/src/race/highscore_manager.cpp index 92eff9094..e0fc094f4 100644 --- a/src/race/highscore_manager.cpp +++ b/src/race/highscore_manager.cpp @@ -150,15 +150,15 @@ void HighscoreManager::saveHighscores() try { - UTFWriter highscore_file(m_filename.c_str()); - highscore_file << L"\n"; - highscore_file << L"\n"; + UTFWriter highscore_file(m_filename.c_str(), false); + highscore_file << "\n"; + highscore_file << "\n"; for(unsigned int i=0; iwriteEntry(highscore_file); } - highscore_file << L"\n"; + highscore_file << "\n"; highscore_file.close(); } catch(std::exception &e) diff --git a/src/race/highscores.cpp b/src/race/highscores.cpp index bc5a4f2c5..9f7ca37f6 100644 --- a/src/race/highscores.cpp +++ b/src/race/highscores.cpp @@ -113,25 +113,25 @@ void Highscores::writeEntry(UTFWriter &writer) one_is_set |= m_time[i]>=0; if(!one_is_set) return; - writer << L" \n"; + writer << " \n"; for(int i=0; i 0.0f) { assert(m_kart_name[i].size() > 0); - writer << L" \n"; + writer << " \n"; } } // for i - writer << L" \n"; + writer << " \n"; } // writeEntry // ----------------------------------------------------------------------------- From c599195eeb53acbf0e40215f4aeca5eb6145c94f Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Sun, 3 Jun 2018 21:48:34 -0400 Subject: [PATCH 3/6] XML fixes --- src/config/player_profile.cpp | 2 +- src/race/grand_prix_data.cpp | 2 +- src/race/highscores.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/config/player_profile.cpp b/src/config/player_profile.cpp index d9b465e16..913c70aa5 100644 --- a/src/config/player_profile.cpp +++ b/src/config/player_profile.cpp @@ -87,7 +87,7 @@ PlayerProfile::PlayerProfile(const XMLNode* node) node->get("saved-session", &m_saved_session ); node->get("saved-user", &m_saved_user_id ); node->get("saved-token", &m_saved_token ); - node->get("last-online-name", &m_last_online_name ); + node->getAndDecode("last-online-name", &m_last_online_name ); node->get("last-was-online", &m_last_was_online ); node->get("remember-password", &m_remember_password); node->get("icon-filename", &m_icon_filename ); diff --git a/src/race/grand_prix_data.cpp b/src/race/grand_prix_data.cpp index 9e7c1460b..90ca62cb3 100644 --- a/src/race/grand_prix_data.cpp +++ b/src/race/grand_prix_data.cpp @@ -270,7 +270,7 @@ void GrandPrixData::reload() throw std::runtime_error("Wrong root node name"); } - if (!root->get("name", &m_name)) + if (!root->getAndDecode("name", &m_name)) { Log::error("GrandPrixData", "Error while trying to read grandprix file '%s': " diff --git a/src/race/highscores.cpp b/src/race/highscores.cpp index 9f7ca37f6..54daf277e 100644 --- a/src/race/highscores.cpp +++ b/src/race/highscores.cpp @@ -83,7 +83,7 @@ void Highscores::readEntry(const XMLNode &node) { const XMLNode *entry = node.getNode(i); entry->get("time", &m_time[i] ); - entry->get("name", &m_name[i] ); + entry->getAndDecode("name", &m_name[i] ); entry->get("kartname", &m_kart_name[i] ); // a non-empty entry needs a non-empty kart name. From 4275dbdac6bce36c54733b9bd13c09d3a01967a4 Mon Sep 17 00:00:00 2001 From: Deve Date: Mon, 4 Jun 2018 22:05:49 +0200 Subject: [PATCH 4/6] Fixed android build --- android/make.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/make.sh b/android/make.sh index 338a7476b..10ba5437f 100755 --- a/android/make.sh +++ b/android/make.sh @@ -237,7 +237,7 @@ if [ -f "$DIRNAME/obj/project_version" ]; then PROJECT_VERSION_PREV=$(cat "$DIRNAME/obj/project_version") if [ -z "$PROJECT_VERSION" ]; then - PROJECT_VERSION="$PROJECT_VERSION_PREV" + export PROJECT_VERSION="$PROJECT_VERSION_PREV" elif [ "$PROJECT_VERSION" != "$PROJECT_VERSION_PREV" ]; then echo "Different project version has been set. Forcing recompilation..." touch -c "$DIRNAME/Android.mk" @@ -246,7 +246,7 @@ fi if [ -z "$PROJECT_VERSION" ]; then if [ $IS_DEBUG_BUILD -ne 0 ]; then - PROJECT_VERSION="git" + export PROJECT_VERSION="git" else echo "Error: Variable PROJECT_VERSION is not set. It must have unique" \ "value for release build." From ffee5d266d8275391476925da8b894a0ec2a87a2 Mon Sep 17 00:00:00 2001 From: Deve Date: Mon, 4 Jun 2018 22:12:02 +0200 Subject: [PATCH 5/6] Prefer /sdcard/Android/data/ for extracting assets. Fixes #3266, #3281 --- src/io/assets_android.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/io/assets_android.cpp b/src/io/assets_android.cpp index 8d7a80853..17877f10c 100644 --- a/src/io/assets_android.cpp +++ b/src/io/assets_android.cpp @@ -59,18 +59,18 @@ void AssetsAndroid::init() if (getenv("SUPERTUXKART_DATADIR")) paths.push_back(getenv("SUPERTUXKART_DATADIR")); - if (getenv("EXTERNAL_STORAGE")) - paths.push_back(getenv("EXTERNAL_STORAGE")); - - if (getenv("SECONDARY_STORAGE")) - paths.push_back(getenv("SECONDARY_STORAGE")); - if (global_android_app->activity->externalDataPath) paths.push_back(global_android_app->activity->externalDataPath); if (global_android_app->activity->internalDataPath) paths.push_back(global_android_app->activity->internalDataPath); + if (getenv("EXTERNAL_STORAGE")) + paths.push_back(getenv("EXTERNAL_STORAGE")); + + if (getenv("SECONDARY_STORAGE")) + paths.push_back(getenv("SECONDARY_STORAGE")); + paths.push_back("/sdcard/"); paths.push_back("/storage/sdcard0/"); paths.push_back("/storage/sdcard1/"); From 6e7b2a2ecdfbe9537e08682942c6c072870da266 Mon Sep 17 00:00:00 2001 From: Deve Date: Mon, 4 Jun 2018 22:22:24 +0200 Subject: [PATCH 6/6] Remove write media storage permission from android manifest. This permission is not officially available in documentation and it was a hack for some devices that have access to sdcard only on system applications. --- android/AndroidManifest.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 3a3af85ee..7308272e6 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -39,8 +39,6 @@ - -