Add download assets screen for mobile stk
This commit is contained in:
parent
ed011bed4c
commit
5cc5780f28
36
data/gui/screens/download_assets.stkgui
Normal file
36
data/gui/screens/download_assets.stkgui
Normal 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>
|
@ -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
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
|
||||
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
|
@ -65,7 +65,6 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
static void destroy()
|
||||
{
|
||||
assert(m_achievements_manager);
|
||||
delete m_achievements_manager;
|
||||
m_achievements_manager = NULL;
|
||||
} // destroy
|
||||
|
@ -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)
|
||||
|
@ -76,7 +76,6 @@ void SFXManager::create()
|
||||
*/
|
||||
void SFXManager::destroy()
|
||||
{
|
||||
assert(m_sfx_manager);
|
||||
delete m_sfx_manager;
|
||||
m_sfx_manager = NULL;
|
||||
} // destroy
|
||||
|
@ -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
|
||||
|
||||
|
@ -82,7 +82,6 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
static void destroy()
|
||||
{
|
||||
assert(m_player_manager);
|
||||
delete m_player_manager;
|
||||
m_player_manager = NULL;
|
||||
} // destroy
|
||||
|
@ -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"))
|
||||
|
@ -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;
|
||||
|
@ -127,7 +127,6 @@ namespace GUIEngine
|
||||
void hardResetAndGoToScreen()
|
||||
{
|
||||
if (m_game_mode != GAME) GUIEngine::getCurrentScreen()->tearDown();
|
||||
m_menu_stack.clear();
|
||||
|
||||
GUIEngine::clearScreenCache();
|
||||
|
||||
|
@ -880,6 +880,7 @@ namespace GUIEngine
|
||||
|
||||
void clearScreenCache()
|
||||
{
|
||||
StateManager::get()->clearMenuStack();
|
||||
Screen* screen;
|
||||
for_in (screen, g_loaded_screens)
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -90,7 +90,8 @@ InputManager::InputManager() : m_mode(BOOTSTRAP),
|
||||
void InputManager::update(float dt)
|
||||
{
|
||||
#ifdef ENABLE_WIIUSE
|
||||
wiimote_manager->update();
|
||||
if (wiimote_manager)
|
||||
wiimote_manager->update();
|
||||
#endif
|
||||
|
||||
if(m_timer_in_use)
|
||||
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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])
|
||||
|
74
src/main.cpp
74
src/main.cpp
@ -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,8 +2375,10 @@ static void cleanSuperTuxKart()
|
||||
|
||||
// Stop music (this request will go into the sfx manager queue, so it needs
|
||||
// to be done before stopping the thread).
|
||||
music_manager->stopMusic();
|
||||
SFXManager::get()->stopThread();
|
||||
if (music_manager)
|
||||
music_manager->stopMusic();
|
||||
if (SFXManager::get())
|
||||
SFXManager::get()->stopThread();
|
||||
irr_driver->updateConfigIfRelevant();
|
||||
AchievementsManager::destroy();
|
||||
Referee::cleanup();
|
||||
@ -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,16 +2426,20 @@ static void cleanSuperTuxKart()
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Online::RequestManager::get()->waitForReadyToDeleted(5.0f))
|
||||
if (Online::RequestManager::isRunning())
|
||||
{
|
||||
Online::RequestManager::deallocate();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("Thread", "Request Manager not aborting in time, proceeding without cleanup.");
|
||||
if (Online::RequestManager::get()->waitForReadyToDeleted(5.0f))
|
||||
{
|
||||
Online::RequestManager::deallocate();
|
||||
}
|
||||
else
|
||||
{
|
||||
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.");
|
||||
}
|
||||
|
@ -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();
|
||||
PROFILER_PUSH_CPU_MARKER("Music", 0x7F, 0x00, 0x00);
|
||||
SFXManager::get()->update();
|
||||
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
|
||||
PROFILER_PUSH_CPU_MARKER("Database polling update", 0x00, 0x7F, 0x7F);
|
||||
Online::RequestManager::get()->update(frame_duration);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
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)
|
||||
|
@ -31,17 +31,19 @@ class MainLoop
|
||||
private:
|
||||
/** True if the main loop should exit. */
|
||||
std::atomic_bool m_abort;
|
||||
|
||||
|
||||
std::atomic_bool m_request_abort;
|
||||
|
||||
/** True if the frame rate should be throttled. */
|
||||
bool m_throttle_fps;
|
||||
|
||||
|
||||
/** True if dt is not decreased for low fps */
|
||||
bool m_allow_large_dt;
|
||||
|
||||
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. */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -96,7 +96,6 @@ public:
|
||||
/** Destroys the singleton. */
|
||||
static void destroy()
|
||||
{
|
||||
assert(m_profile_manager);
|
||||
delete m_profile_manager;
|
||||
m_profile_manager = NULL;
|
||||
} // destroy
|
||||
|
@ -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
|
||||
|
||||
|
206
src/states_screens/download_assets.cpp
Normal file
206
src/states_screens/download_assets.cpp
Normal 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
|
83
src/states_screens/download_assets.hpp
Normal file
83
src/states_screens/download_assets.hpp
Normal 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
|
@ -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());
|
||||
}
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user