Add download assets screen for mobile stk

This commit is contained in:
Benau 2019-07-24 01:33:12 +08:00
parent ed011bed4c
commit 5cc5780f28
28 changed files with 499 additions and 66 deletions

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<div x="1%" y="1%" width="100%" height="100%" layout="vertical-row">
<header id="title" text_align="center" width="80%" height="8%" align="center"
I18N="In the download assets screen" text="Download game assets"/>
<icon id="logo" align="center" proportion="1" height="30%" icon="gui/icons/logo.png"/>
<box width="80%" height="fit" layout="vertical-row" align="center">
<spacer height="20"/>
<div width="100%" height="fit" layout="horizontal-row">
<label I18N="In the download assets screen" align="center" width="fit" word_wrap="true"
text="SuperTuxKart needs to download assets required to play the game now, this will use your mobile data if you don't have a wifi connection."/>
</div>
<spacer height="40"/>
<div width="100%" height="fit" layout="horizontal-row">
<label I18N="In the download assets screen, download options of assets" align="center" width="fit"
text="Include all tracks"/>
<spacer width="10"/>
<checkbox id="all-tracks" width="fit"/>
</div>
<spacer height="10"/>
<div width="100%" height="fit" layout="horizontal-row">
<label I18N="In the download assets screen, download options of assets" align="center" width="fit"
text="Use high quality textures and music"/>
<spacer width="10"/>
<checkbox id="hd-textures" width="fit"/>
</div>
</box>
<spacer height="5%"/>
<progressbar height="1f" id="progress" width="80%" align="center"></progressbar>
<spacer height="5%"/>
<buttonbar id="buttons" height="15%" width="100%" align="center">
<icon-button id="ok" width="15%" height="15%" icon="gui/icons/green_check.png" text="OK" align="center"/>
</buttonbar>
<spacer height="2%"/>
</div>
</stkgui>

View File

@ -177,7 +177,8 @@
<minimap size="180.0" ai-icon="16.0" player-icon="20.0"/>
<urls donate="https://supertuxkart.net/Donate"
password-reset="https://online.supertuxkart.net/password-reset.php" />
password-reset="https://online.supertuxkart.net/password-reset.php"
assets-download="https://downloads.sourceforge.net/project/supertuxkart/stk-assets-mobile/"/>
<!-- Skidmark data: maximum number of skid marks, and
time for skidmarks to fade out. Maximum number will over

View File

@ -65,7 +65,6 @@ public:
// ------------------------------------------------------------------------
static void destroy()
{
assert(m_achievements_manager);
delete m_achievements_manager;
m_achievements_manager = NULL;
} // destroy

View File

@ -117,6 +117,8 @@ public:
return m_news_manager;
} // get
// ------------------------------------------------------------------------
static bool isRunning() { return m_news_manager != NULL; }
// ------------------------------------------------------------------------
static void deallocate()
{
if(m_news_manager)

View File

@ -76,7 +76,6 @@ void SFXManager::create()
*/
void SFXManager::destroy()
{
assert(m_sfx_manager);
delete m_sfx_manager;
m_sfx_manager = NULL;
} // destroy

View File

@ -247,7 +247,6 @@ public:
/** Static function to get the singleton sfx manager. */
static SFXManager *get()
{
assert(m_sfx_manager);
return m_sfx_manager;
} // get

View File

@ -82,7 +82,6 @@ public:
// ------------------------------------------------------------------------
static void destroy()
{
assert(m_player_manager);
delete m_player_manager;
m_player_manager = NULL;
} // destroy

View File

@ -496,10 +496,11 @@ void STKConfig::getAllData(const XMLNode * root)
replay_node->get("player-icon", &m_minimap_player_icon );
}
if(const XMLNode *replay_node = root->getNode("urls"))
if (const XMLNode *urls = root->getNode("urls"))
{
replay_node->get("donate", &m_donate_url );
replay_node->get("password-reset", &m_password_reset_url );
urls->get("donate", &m_donate_url);
urls->get("password-reset", &m_password_reset_url);
urls->get("assets-download", &m_assets_download_url);
}
if (const XMLNode *fonts_list = root->getNode("fonts-list"))

View File

@ -205,6 +205,7 @@ public:
/* URLs for donating and reseting the password */
std::string m_donate_url;
std::string m_password_reset_url;
std::string m_assets_download_url;
/** Lists of TTF files used in STK. */
std::vector<std::string> m_normal_ttf;

View File

@ -127,7 +127,6 @@ namespace GUIEngine
void hardResetAndGoToScreen()
{
if (m_game_mode != GAME) GUIEngine::getCurrentScreen()->tearDown();
m_menu_stack.clear();
GUIEngine::clearScreenCache();

View File

@ -880,6 +880,7 @@ namespace GUIEngine
void clearScreenCache()
{
StateManager::get()->clearMenuStack();
Screen* screen;
for_in (screen, g_loaded_screens)
{

View File

@ -176,7 +176,7 @@ bool EventHandler::OnEvent (const SEvent &event)
if (cmd == APP_CMD_PAUSE || cmd == APP_CMD_LOST_FOCUS)
{
// Make sure that pause/unpause is executed only once
if (device->isWindowMinimized() == device->isWindowFocused())
if (music_manager && device->isWindowMinimized() == device->isWindowFocused())
{
music_manager->pauseMusic();
SFXManager::get()->pauseAll();
@ -184,7 +184,7 @@ bool EventHandler::OnEvent (const SEvent &event)
}
else if (cmd == APP_CMD_RESUME || cmd == APP_CMD_GAINED_FOCUS)
{
if (device->isWindowActive())
if (music_manager && device->isWindowActive())
{
music_manager->resumeMusic();
SFXManager::get()->resumeAll();

View File

@ -90,6 +90,7 @@ InputManager::InputManager() : m_mode(BOOTSTRAP),
void InputManager::update(float dt)
{
#ifdef ENABLE_WIIUSE
if (wiimote_manager)
wiimote_manager->update();
#endif
@ -117,7 +118,8 @@ void InputManager::handleStaticAction(int key, int value)
World *world = World::getWorld();
// When no players... a cutscene
if (race_manager->getNumPlayers() == 0 && world != NULL && value > 0 &&
if (race_manager &&
race_manager->getNumPlayers() == 0 && world != NULL && value > 0 &&
(key == IRR_KEY_SPACE || key == IRR_KEY_RETURN ||
key == IRR_KEY_BUTTON_A))
{
@ -821,7 +823,8 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID,
Controller* controller = pk->getController();
if (controller != NULL) controller->action(action, abs(value));
}
else if (race_manager->isWatchingReplay() && !GUIEngine::ModalDialog::isADialogActive())
else if (race_manager &&
race_manager->isWatchingReplay() && !GUIEngine::ModalDialog::isADialogActive())
{
// Get the first ghost kart
World::getWorld()->getKart(0)

View File

@ -228,7 +228,28 @@ FileManager::FileManager()
addRootDirs(root_dir);
std::string assets_dir;
#ifdef MOBILE_STK
// Check if the bundled data includes stk-assets, if not download it later
// Check only 1 entry for now (karts)
if (!fileExists(root_dir + "/karts"))
{
assets_dir = getenv("HOME");
#ifdef IOS_STK
assets_dir += "/Library/Application Support/SuperTuxKart/stk-assets";
#elif defined (ANDROID)
assets_dir += "/stk-assets";
#endif
m_stk_assets_download_dir = assets_dir;
// Those will be filled with real data later
checkAndCreateDirectoryP(m_stk_assets_download_dir + "/karts");
checkAndCreateDirectoryP(m_stk_assets_download_dir + "/library");
checkAndCreateDirectoryP(m_stk_assets_download_dir + "/models");
checkAndCreateDirectoryP(m_stk_assets_download_dir + "/music");
checkAndCreateDirectoryP(m_stk_assets_download_dir + "/sfx");
checkAndCreateDirectoryP(m_stk_assets_download_dir + "/textures");
checkAndCreateDirectoryP(m_stk_assets_download_dir + "/tracks");
}
#else
if (getenv("SUPERTUXKART_ASSETS_DIR") != NULL)
{
assets_dir = std::string(getenv("SUPERTUXKART_ASSETS_DIR"));
@ -246,7 +267,7 @@ FileManager::FileManager()
//is this needed?
assets_dir = std::string(getenv("SUPERTUXKART_ROOT_PATH"));
}
#endif
if (!assets_dir.empty() && assets_dir != root_dir)
{
addRootDirs(assets_dir);
@ -1429,7 +1450,7 @@ bool FileManager::removeDirectory(const std::string &name) const
// We need to remove whole data directory on Android though, i.e.
// when we install newer STK version and new assets are extracted.
// So enable it only for Android for now.
#ifdef ANDROID
#ifdef MOBILE_STK
removeDirectory(file);
#endif
}

View File

@ -105,6 +105,9 @@ private:
/** Location of the certificate bundle. */
std::string m_cert_bundle_location;
/** Mobile stk specific to download stk-assets in the first. */
std::string m_stk_assets_download_dir;
std::vector<TextureSearchPath> m_texture_search_path;
std::vector<std::string>
@ -231,8 +234,12 @@ public:
{
return m_subdir_name[SHADER];
}
const std::string& getCertBundleLocation() const { return m_cert_bundle_location; }
// ------------------------------------------------------------------------
const std::string& getSTKAssetsDownloadDir() const
{ return m_stk_assets_download_dir; }
// ------------------------------------------------------------------------
const std::string& getCertBundleLocation() const
{ return m_cert_bundle_location; }
}; // FileManager

View File

@ -73,6 +73,9 @@ void ItemManager::destroy()
*/
void ItemManager::loadDefaultItemMeshes()
{
m_item_mesh.clear();
m_item_lowres_mesh.clear();
m_glow_color.clear();
m_item_mesh.resize(ItemState::ITEM_LAST-ItemState::ITEM_FIRST+1, NULL);
m_glow_color.resize(ItemState::ITEM_LAST-ItemState::ITEM_FIRST+1,
video::SColorf(255.0f, 255.0f, 255.0f) );
@ -136,6 +139,8 @@ void ItemManager::loadDefaultItemMeshes()
*/
void ItemManager::removeTextures()
{
if (m_item_mesh.empty() && m_item_lowres_mesh.empty())
return;
for(unsigned int i=0; i<ItemState::ITEM_LAST-ItemState::ITEM_FIRST+1; i++)
{
if(m_item_mesh[i])

View File

@ -234,6 +234,7 @@
#include "race/race_manager.hpp"
#include "replay/replay_play.hpp"
#include "replay/replay_recorder.hpp"
#include "states_screens/download_assets.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/online/networking_lobby.hpp"
#include "states_screens/online/register_screen.hpp"
@ -1667,6 +1668,19 @@ void initUserConfig()
// command line parameters
} // initUserConfig
//=============================================================================
void clearGlobalVariables()
{
// In android sometimes global variables is not reset when restart the app
// we clear it here as much as possible
race_manager = NULL;
music_manager = NULL;
irr_driver = NULL;
#ifdef ENABLE_WIIUSE
wiimote_manager = NULL;
#endif
} // clearGlobalVariables
//=============================================================================
void initRest()
{
@ -1696,6 +1710,34 @@ void initRest()
font_manager = new FontManager();
font_manager->loadFonts();
GUIEngine::init(device, driver, StateManager::get());
input_manager = new InputManager();
// Get into menu mode initially.
input_manager->setMode(InputManager::MENU);
#ifdef MOBILE_STK
if (DownloadAssets::getInstance()->needDownloadAssets())
{
// The screen tell user it will use wifi / cellular data to download already
int prev_state = UserConfigParams::m_internet_status;
UserConfigParams::m_internet_status = Online::RequestManager::IPERM_ALLOWED;
DownloadAssets::getInstance()->push();
main_loop = new MainLoop(0, true/*download_assets*/);
main_loop->run();
delete main_loop;
main_loop = NULL;
// Reset after finish download
UserConfigParams::m_internet_status = prev_state;
if (DownloadAssets::getInstance()->needDownloadAssets())
throw std::runtime_error("User doesn't want to download assets");
else
{
// Clean the download assets screen after downloading
GUIEngine::clear();
GUIEngine::cleanUp();
GUIEngine::clearScreenCache();
GUIEngine::init(device, driver, StateManager::get());
}
}
#endif
// This only initialises the non-network part of the add-ons manager. The
// online section of the add-ons manager will be initialised from a
@ -1864,6 +1906,7 @@ int ios_main(int argc, char *argv[])
int main(int argc, char *argv[])
#endif
{
clearGlobalVariables();
CommandLine::init(argc, argv);
CrashReporting::installHandlers();
@ -1964,14 +2007,10 @@ int main(int argc, char *argv[])
profiler.init();
initRest();
input_manager = new InputManager ();
#ifdef ENABLE_WIIUSE
wiimote_manager = new WiimoteManager();
#endif
// Get into menu mode initially.
input_manager->setMode(InputManager::MENU);
int parent_pid;
bool has_parent_process = false;
if (CommandLine::has("--parent-process", &parent_pid))
@ -2336,7 +2375,9 @@ static void cleanSuperTuxKart()
// Stop music (this request will go into the sfx manager queue, so it needs
// to be done before stopping the thread).
if (music_manager)
music_manager->stopMusic();
if (SFXManager::get())
SFXManager::get()->stopThread();
irr_driver->updateConfigIfRelevant();
AchievementsManager::destroy();
@ -2376,7 +2417,8 @@ static void cleanSuperTuxKart()
if (!ProfileWorld::isNoGraphics())
{
if (UserConfigParams::m_internet_status == Online::RequestManager::
IPERM_ALLOWED && !NewsManager::get()->waitForReadyToDeleted(2.0f))
IPERM_ALLOWED && NewsManager::isRunning() &&
!NewsManager::get()->waitForReadyToDeleted(2.0f))
{
Log::info("Thread", "News manager not stopping, exiting anyway.");
}
@ -2384,6 +2426,8 @@ static void cleanSuperTuxKart()
}
#endif
if (Online::RequestManager::isRunning())
{
if (Online::RequestManager::get()->waitForReadyToDeleted(5.0f))
{
Online::RequestManager::deallocate();
@ -2392,8 +2436,10 @@ static void cleanSuperTuxKart()
{
Log::warn("Thread", "Request Manager not aborting in time, proceeding without cleanup.");
}
}
if (!SFXManager::get()->waitForReadyToDeleted(2.0f))
if (SFXManager::get() &&
!SFXManager::get()->waitForReadyToDeleted(2.0f))
{
Log::info("Thread", "SFXManager not stopping, exiting anyway.");
}

View File

@ -68,7 +68,7 @@ LRESULT CALLBACK separateProcessProc(_In_ HWND hwnd, _In_ UINT uMsg,
#endif
// ----------------------------------------------------------------------------
MainLoop::MainLoop(unsigned parent_pid)
MainLoop::MainLoop(unsigned parent_pid, bool download_assets)
: m_abort(false), m_request_abort(false), m_ticks_adjustment(0),
m_parent_pid(parent_pid)
{
@ -77,6 +77,7 @@ MainLoop::MainLoop(unsigned parent_pid)
m_throttle_fps = true;
m_allow_large_dt = false;
m_frame_before_loading_world = false;
m_download_assets = download_assets;
#ifdef WIN32
if (parent_pid != 0)
{
@ -395,7 +396,7 @@ void MainLoop::run()
}
#ifndef SERVER_ONLY
if (CVS->isGLSL())
if (CVS->isGLSL() && !m_download_assets)
{
// Flush all command before delete world, avoid later access
SP::SPTextureManager::get()
@ -453,14 +454,20 @@ void MainLoop::run()
input_manager->update(frame_duration);
GUIEngine::update(frame_duration);
PROFILER_POP_CPU_MARKER();
if (!m_download_assets)
{
PROFILER_PUSH_CPU_MARKER("Music", 0x7F, 0x00, 0x00);
SFXManager::get()->update();
PROFILER_POP_CPU_MARKER();
}
}
// Some protocols in network will use RequestManager
if (!m_download_assets)
{
PROFILER_PUSH_CPU_MARKER("Database polling update", 0x00, 0x7F, 0x7F);
Online::RequestManager::get()->update(frame_duration);
PROFILER_POP_CPU_MARKER();
}
m_ticks_adjustment.lock();
if (m_ticks_adjustment.getData() != 0)

View File

@ -42,6 +42,8 @@ private:
bool m_frame_before_loading_world;
bool m_download_assets;
Synchronised<int> m_ticks_adjustment;
uint64_t m_curr_time;
@ -50,7 +52,7 @@ private:
float getLimitedDt();
void updateRace(int ticks, bool fast_forward);
public:
MainLoop(unsigned parent_pid);
MainLoop(unsigned parent_pid, bool download_assets = false);
~MainLoop();
void run();
/** Set the abort flag, causing the mainloop to be left. */

View File

@ -33,7 +33,6 @@
namespace Online
{
struct curl_slist* HTTPRequest::m_http_header = NULL;
const std::string API::USER_PATH = "user/";
const std::string API::SERVER_PATH = "server/";
@ -98,11 +97,6 @@ namespace Online
m_parameters = "";
m_curl_code = CURLE_OK;
m_progress.setAtomic(0);
if (m_http_header == nullptr)
{
std::string Host = "Host: " + StringUtils::getHostNameFromURL(stk_config->m_server_api);
m_http_header = curl_slist_append(m_http_header, Host.c_str());
}
m_disable_sending_log = false;
} // init
@ -193,7 +187,8 @@ namespace Online
Log::error("HTTPRequest", "Error: '%s'.", error,
curl_easy_strerror(error));
}
std::string host = "Host: " + StringUtils::getHostNameFromURL(m_url);
m_http_header = curl_slist_append(m_http_header, host.c_str());
assert(m_http_header != nullptr);
curl_easy_setopt(m_curl_session, CURLOPT_HTTPHEADER, m_http_header);
curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYPEER, 1L);
@ -271,7 +266,11 @@ namespace Online
Log::info("HTTPRequest", "Sending %s to %s", param.c_str(), m_url.c_str());
} // end log http request
curl_easy_setopt(m_curl_session, CURLOPT_POSTFIELDS, m_parameters.c_str());
if (!m_download_assets_request)
{
curl_easy_setopt(m_curl_session, CURLOPT_POSTFIELDS,
m_parameters.c_str());
}
const std::string& uagent = StringUtils::getUserAgentString();
curl_easy_setopt(m_curl_session, CURLOPT_USERAGENT, uagent.c_str());
@ -320,6 +319,11 @@ namespace Online
setProgress(-1.0f);
Request::afterOperation();
if (m_http_header)
{
curl_slist_free_all(m_http_header);
m_http_header = NULL;
}
if (m_curl_session)
{
curl_easy_cleanup(m_curl_session);
@ -360,7 +364,8 @@ namespace Online
// Check if we are asked to abort the download. If so, signal this
// back to libcurl by returning a non-zero status.
if ((RequestManager::get()->getAbort() || request->isCancelled()) &&
if (RequestManager::isRunning() &&
(RequestManager::get()->getAbort() || request->isCancelled()) &&
request->isAbortable() )
{
// Indicates to abort the current download, which means that this

View File

@ -70,9 +70,12 @@ namespace Online
/** String to store the received data in. */
std::string m_string_buffer;
static struct curl_slist* m_http_header;
struct curl_slist* m_http_header = NULL;
protected:
bool m_disable_sending_log;
/* If true, it will not call curl_easy_setopt CURLOPT_POSTFIELDS so
* it's just a GET request. */
bool m_download_assets_request = false;
virtual void prepareOperation() OVERRIDE;
virtual void operation() OVERRIDE;
@ -94,6 +97,8 @@ namespace Online
int priority = 1);
virtual ~HTTPRequest()
{
if (m_http_header)
curl_slist_free_all(m_http_header);
if (m_curl_session)
{
curl_easy_cleanup(m_curl_session);
@ -107,7 +112,9 @@ namespace Online
// ------------------------------------------------------------------------
/** Returns true if there was an error downloading the file. */
bool hadDownloadError() const { return m_curl_code != CURLE_OK; }
// ------------------------------------------------------------------------
void setDownloadAssetsRequest(bool val)
{ m_download_assets_request = val; }
// ------------------------------------------------------------------------
/** Returns the curl error message if an error has occurred.
* \pre m_curl_code!=CURLE_OK
@ -181,7 +188,8 @@ namespace Online
assert(isPreparing());
m_url = url;
} // setURL
// --------------------------------------------------------------------
const std::string& getFileName() const { return m_filename; }
}; // class HTTPRequest
} //namespace Online
#endif // HEADER_HTTP_REQUEST_HPP

View File

@ -96,7 +96,6 @@ public:
/** Destroys the singleton. */
static void destroy()
{
assert(m_profile_manager);
delete m_profile_manager;
m_profile_manager = NULL;
} // destroy

View File

@ -61,13 +61,17 @@ namespace Online
{
assert(isBusy());
// Abort as early as possible if abort is requested
if (RequestManager::get()->getAbort() && isAbortable()) return;
if (RequestManager::isRunning() &&
RequestManager::get()->getAbort() && isAbortable()) return;
prepareOperation();
if (RequestManager::get()->getAbort() && isAbortable()) return;
if (RequestManager::isRunning() &&
RequestManager::get()->getAbort() && isAbortable()) return;
operation();
if (RequestManager::get()->getAbort() && isAbortable()) return;
if (RequestManager::isRunning() &&
RequestManager::get()->getAbort() && isAbortable()) return;
setExecuted();
if (RequestManager::get()->getAbort() && isAbortable()) return;
if (RequestManager::isRunning() &&
RequestManager::get()->getAbort() && isAbortable()) return;
afterOperation();
} // execute

View File

@ -0,0 +1,206 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2019 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/download_assets.hpp"
#include "addons/zip.hpp"
#include "config/stk_config.hpp"
#include "guiengine/message_queue.hpp"
#include "guiengine/widgets/check_box_widget.hpp"
#include "guiengine/widgets/icon_button_widget.hpp"
#include "guiengine/widgets/progress_bar_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "io/file_manager.hpp"
#include "online/http_request.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include "main_loop.hpp"
#include <stdio.h>
using namespace GUIEngine;
// -----------------------------------------------------------------------------
DownloadAssets::DownloadAssets() : GUIEngine::Screen("download_assets.stkgui")
{
} // OnlineLanScreen
// -----------------------------------------------------------------------------
void DownloadAssets::beforeAddingWidget()
{
} // beforeAddingWidget
// -----------------------------------------------------------------------------
void DownloadAssets::init()
{
m_progress = getWidget<ProgressBarWidget>("progress");
m_progress->setVisible(false);
m_all_tracks = getWidget<CheckBoxWidget>("all-tracks");
m_all_tracks->setActive(true);
m_all_tracks->setVisible(true);
m_all_tracks->setState(false);
m_hd_textures = getWidget<CheckBoxWidget>("hd-textures");
m_hd_textures->setActive(true);
m_hd_textures->setVisible(true);
m_hd_textures->setState(false);
m_ok = getWidget<IconButtonWidget>("ok");
m_ok->setActive(true);
m_ok->setVisible(true);
m_downloading_now = false;
m_download_request = NULL;
// Remove any previous left over .zip (and part)
const std::string& dir = file_manager->getAddonsDir();
if (file_manager->fileExists(dir + "nonfull-nonhd.zip"))
file_manager->removeFile(dir + "nonfull-nonhd.zip");
if (file_manager->fileExists(dir + "full-nonhd.zip"))
file_manager->removeFile(dir + "full-nonhd.zip");
if (file_manager->fileExists(dir + "nonfull-hd.zip"))
file_manager->removeFile(dir + "nonfull-hd.zip");
if (file_manager->fileExists(dir + "full-hd.zip"))
file_manager->removeFile(dir + "full-hd.zip");
if (file_manager->fileExists(dir + "nonfull-nonhd.zip.part"))
file_manager->removeFile(dir + "nonfull-nonhd.zip.part");
if (file_manager->fileExists(dir + "full-nonhd.zip.part"))
file_manager->removeFile(dir + "full-nonhd.zip.part");
if (file_manager->fileExists(dir + "nonfull-hd.zip.part"))
file_manager->removeFile(dir + "nonfull-hd.zip.part");
if (file_manager->fileExists(dir + "full-hd.zip.part"))
file_manager->removeFile(dir + "full-hd.zip.part");
} // init
// -----------------------------------------------------------------------------
void DownloadAssets::eventCallback(Widget* widget, const std::string& name,
const int player_id)
{
if (m_downloading_now)
return;
if (name == "buttons")
{
const std::string& button = getWidget<GUIEngine::RibbonWidget>("buttons")
->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (button == "ok")
{
m_downloading_now = true;
m_ok->setActive(false);
m_progress->setValue(0);
m_progress->setVisible(true);
m_all_tracks->setActive(false);
m_hd_textures->setActive(false);
std::string download_url = stk_config->m_assets_download_url;
std::string filename;
if (m_all_tracks->getState())
filename = "full";
else
filename = "nonfull";
filename += "-";
if (m_hd_textures->getState())
filename += "hd";
else
filename += "nonhd";
filename += ".zip";
download_url += STK_VERSION;
download_url += "/";
download_url += filename;
m_download_request = new Online::HTTPRequest(filename,
true/*manage_memory*/);
m_download_request->setDownloadAssetsRequest(true);
m_download_request->setURL(download_url);
m_download_thread = std::thread([this]()
{
m_download_request->executeNow();
const std::string& zip = m_download_request->getFileName();
const std::string& dir =
file_manager->getSTKAssetsDownloadDir();
if (file_manager->fileExists(zip))
{
// Remove previous stk-assets version and create a new
// one
file_manager->removeDirectory(dir);
file_manager->checkAndCreateDirectory(dir);
if (extract_zip(zip, dir, true/*recursive*/))
{
std::string extract_ok =
dir + "/stk-assets." + STK_VERSION;
FILE* fp = fopen(extract_ok.c_str(), "wb");
if (!fp)
{
Log::error("FileUtils",
"Failed to create extract ok file.");
}
else
fclose(fp);
}
file_manager->removeFile(zip);
}
m_downloading_now = false;
});
}
}
} // eventCallback
// ----------------------------------------------------------------------------
bool DownloadAssets::onEscapePressed()
{
if (m_downloading_now)
return false;
return true;
} // onEscapePressed
// ----------------------------------------------------------------------------
bool DownloadAssets::needDownloadAssets()
{
const std::string& dir = file_manager->getSTKAssetsDownloadDir();
if (dir.empty())
return false;
return !file_manager->fileExists(dir + "/stk-assets." + STK_VERSION);
} // needDownloadAssets
// ----------------------------------------------------------------------------
void DownloadAssets::onUpdate(float dt)
{
if (m_download_request)
m_progress->setValue(m_download_request->getProgress() * 99.0f);
if (m_download_thread.joinable())
{
if (m_downloading_now)
return;
if (!m_downloading_now)
{
m_download_thread.join();
if (m_download_request)
{
delete m_download_request;
m_download_request = NULL;
}
}
if (!needDownloadAssets())
main_loop->abort();
else
{
// Reset the download buttons so user can redownload if needed
// I18N: Shown when there is download error for assets download
// in the first run
core::stringw msg = _("Failed to download assets, please try again later.");
MessageQueue::add(MessageQueue::MT_ERROR, msg);
DownloadAssets::init();
}
}
} // onUpdate

View File

@ -0,0 +1,83 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2019 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_DOWNLOAD_ASSETS_HPP
#define HEADER_DOWNLOAD_ASSETS_HPP
#include <atomic>
#include <string>
#include <thread>
#include <irrString.h>
#include "guiengine/screen.hpp"
namespace GUIEngine
{
class CheckBoxWidget;
class IconButtonWidget;
class ProgressBarWidget;
}
namespace Online
{
class HTTPRequest;
}
/**
* \ingroup states_screens
*/
class DownloadAssets : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<DownloadAssets>
{
protected:
DownloadAssets();
private:
GUIEngine::ProgressBarWidget* m_progress;
GUIEngine::CheckBoxWidget* m_all_tracks;
GUIEngine::CheckBoxWidget* m_hd_textures;
GUIEngine::IconButtonWidget* m_ok;
std::atomic<bool> m_downloading_now;
Online::HTTPRequest* m_download_request;
std::thread m_download_thread;
public:
friend class GUIEngine::ScreenSingleton<DownloadAssets>;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile() OVERRIDE {}
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void beforeAddingWidget() OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name,
const int playerID) OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init() OVERRIDE;
virtual bool onEscapePressed() OVERRIDE;
virtual void onUpdate(float dt) OVERRIDE;
bool needDownloadAssets();
}; // class DownloadAssets
#endif

View File

@ -218,7 +218,7 @@ void StateManager::onGameStateChange(GameState new_state)
if (new_state == MENU)
{
GUIEngine::Screen* screen = GUIEngine::getCurrentScreen();
if (screen != NULL)
if (screen != NULL && music_manager)
{
music_manager->startMusic(
GUIEngine::getCurrentScreen()->getMusic());
@ -233,14 +233,14 @@ void StateManager::onTopMostScreenChanged()
{
if (m_game_mode == MENU && GUIEngine::getCurrentScreen() != NULL)
{
if (GUIEngine::getCurrentScreen()->getMusic() != NULL)
if (GUIEngine::getCurrentScreen()->getMusic() != NULL && music_manager)
{
music_manager->startMusic(GUIEngine::getCurrentScreen()->getMusic());
}
}
else if (m_game_mode == INGAME_MENU && GUIEngine::getCurrentScreen() != NULL)
{
if (GUIEngine::getCurrentScreen()->getInGameMenuMusic() != NULL)
if (GUIEngine::getCurrentScreen()->getInGameMenuMusic() != NULL && music_manager)
{
music_manager->startMusic(GUIEngine::getCurrentScreen()->getInGameMenuMusic());
}

View File

@ -210,7 +210,7 @@ public:
// singleton
static StateManager* get();
static void deallocate();
void clearMenuStack() { m_menu_stack.clear(); }
private:
/**
* A list of all currently playing players.