Removed old network_http and related data structure. Its function

is now either in the addons/news_manager, or in Online::RequestManager.
Also added leack check and copy-preventing to online/Request.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15034 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2014-01-13 05:21:48 +00:00
parent c8d066ce37
commit 428f74d859
20 changed files with 106 additions and 1141 deletions

View File

@ -6,10 +6,7 @@ src/achievements/achievements_manager.cpp
src/achievements/achievements_slot.cpp
src/addons/addon.cpp
src/addons/addons_manager.cpp
src/addons/inetwork_http.cpp
src/addons/network_http.cpp
src/addons/news_manager.cpp
src/addons/request.cpp
src/addons/zip.cpp
src/animations/animation_base.cpp
src/animations/ipo.cpp
@ -118,8 +115,8 @@ src/items/projectile_manager.cpp
src/items/rubber_ball.cpp
src/items/rubber_band.cpp
src/items/swatter.cpp
src/karts/abstract_kart_animation.cpp
src/karts/abstract_kart.cpp
src/karts/abstract_kart_animation.cpp
src/karts/cannon_animation.cpp
src/karts/controller/ai_base_controller.cpp
src/karts/controller/ai_properties.cpp
@ -252,8 +249,8 @@ src/states_screens/help_screen_3.cpp
src/states_screens/help_screen_4.cpp
src/states_screens/kart_selection.cpp
src/states_screens/main_menu_screen.cpp
src/states_screens/networking_lobby.cpp
src/states_screens/network_kart_selection.cpp
src/states_screens/networking_lobby.cpp
src/states_screens/offline_kart_selection.cpp
src/states_screens/online_profile_achievements.cpp
src/states_screens/online_profile_base.cpp
@ -263,13 +260,13 @@ src/states_screens/online_profile_settings.cpp
src/states_screens/online_screen.cpp
src/states_screens/online_user_search.cpp
src/states_screens/options_screen_audio.cpp
src/states_screens/options_screen_input2.cpp
src/states_screens/options_screen_input.cpp
src/states_screens/options_screen_input2.cpp
src/states_screens/options_screen_players.cpp
src/states_screens/options_screen_ui.cpp
src/states_screens/options_screen_video.cpp
src/states_screens/race_gui_base.cpp
src/states_screens/race_gui.cpp
src/states_screens/race_gui_base.cpp
src/states_screens/race_gui_overworld.cpp
src/states_screens/race_result_gui.cpp
src/states_screens/race_setup_screen.cpp
@ -329,18 +326,14 @@ src/achievements/achievements_manager.hpp
src/achievements/achievements_slot.hpp
src/addons/addon.hpp
src/addons/addons_manager.hpp
src/addons/dummy_network_http.hpp
src/addons/inetwork_http.hpp
src/addons/network_http.hpp
src/addons/news_manager.hpp
src/addons/request.hpp
src/addons/zip.hpp
src/animations/animation_base.hpp
src/animations/ipo.hpp
src/animations/three_d_animation.hpp
src/audio/dummy_sfx.hpp
src/audio/music_dummy.hpp
src/audio/music.hpp
src/audio/music_dummy.hpp
src/audio/music_information.hpp
src/audio/music_manager.hpp
src/audio/music_ogg.hpp
@ -348,8 +341,8 @@ src/audio/sfx_base.hpp
src/audio/sfx_buffer.hpp
src/audio/sfx_manager.hpp
src/audio/sfx_openal.hpp
src/challenges/challenge_data.hpp
src/challenges/challenge.hpp
src/challenges/challenge_data.hpp
src/challenges/game_slot.hpp
src/challenges/unlock_manager.hpp
src/config/device_config.hpp
@ -407,11 +400,11 @@ src/guiengine/scalable_font.hpp
src/guiengine/screen.hpp
src/guiengine/skin.hpp
src/guiengine/widget.hpp
src/guiengine/widgets.hpp
src/guiengine/widgets/bubble_widget.hpp
src/guiengine/widgets/button_widget.hpp
src/guiengine/widgets/check_box_widget.hpp
src/guiengine/widgets/dynamic_ribbon_widget.hpp
src/guiengine/widgets.hpp
src/guiengine/widgets/icon_button_widget.hpp
src/guiengine/widgets/label_widget.hpp
src/guiengine/widgets/list_widget.hpp
@ -423,8 +416,8 @@ src/guiengine/widgets/spinner_widget.hpp
src/guiengine/widgets/text_box_widget.hpp
src/input/binding.hpp
src/input/device_manager.hpp
src/input/input_device.hpp
src/input/input.hpp
src/input/input_device.hpp
src/input/input_manager.hpp
src/input/wiimote.hpp
src/input/wiimote_manager.hpp
@ -446,8 +439,8 @@ src/items/projectile_manager.hpp
src/items/rubber_ball.hpp
src/items/rubber_band.hpp
src/items/swatter.hpp
src/karts/abstract_kart_animation.hpp
src/karts/abstract_kart.hpp
src/karts/abstract_kart_animation.hpp
src/karts/cannon_animation.hpp
src/karts/controller/ai_base_controller.hpp
src/karts/controller/ai_properties.hpp
@ -459,8 +452,8 @@ src/karts/controller/player_controller.hpp
src/karts/controller/skidding_ai.hpp
src/karts/explosion_animation.hpp
src/karts/ghost_kart.hpp
src/karts/kart_gfx.hpp
src/karts/kart.hpp
src/karts/kart_gfx.hpp
src/karts/kart_model.hpp
src/karts/kart_properties.hpp
src/karts/kart_properties_manager.hpp
@ -585,8 +578,8 @@ src/states_screens/help_screen_3.hpp
src/states_screens/help_screen_4.hpp
src/states_screens/kart_selection.hpp
src/states_screens/main_menu_screen.hpp
src/states_screens/networking_lobby.hpp
src/states_screens/network_kart_selection.hpp
src/states_screens/networking_lobby.hpp
src/states_screens/offline_kart_selection.hpp
src/states_screens/online_profile_achievements.hpp
src/states_screens/online_profile_base.hpp
@ -596,13 +589,13 @@ src/states_screens/online_profile_settings.hpp
src/states_screens/online_screen.hpp
src/states_screens/online_user_search.hpp
src/states_screens/options_screen_audio.hpp
src/states_screens/options_screen_input2.hpp
src/states_screens/options_screen_input.hpp
src/states_screens/options_screen_input2.hpp
src/states_screens/options_screen_players.hpp
src/states_screens/options_screen_ui.hpp
src/states_screens/options_screen_video.hpp
src/states_screens/race_gui_base.hpp
src/states_screens/race_gui.hpp
src/states_screens/race_gui_base.hpp
src/states_screens/race_gui_overworld.hpp
src/states_screens/race_result_gui.hpp
src/states_screens/race_setup_screen.hpp
@ -633,8 +626,8 @@ src/tracks/check_sphere.hpp
src/tracks/check_structure.hpp
src/tracks/graph_node.hpp
src/tracks/lod_node_loader.hpp
src/tracks/quad_graph.hpp
src/tracks/quad.hpp
src/tracks/quad_graph.hpp
src/tracks/quad_set.hpp
src/tracks/terrain_info.hpp
src/tracks/track.hpp

View File

@ -20,7 +20,6 @@
#include "addons/addons_manager.hpp"
#include "addons/inetwork_http.hpp"
#include "addons/news_manager.hpp"
#include "addons/zip.hpp"
#include "io/file_manager.hpp"
@ -42,12 +41,15 @@
#include <string.h>
#include <vector>
using namespace Online;
AddonsManager* addons_manager = 0;
// ----------------------------------------------------------------------------
/** Initialises the non-online component of the addons manager (i.e. handling
* the list of already installed addons). The online component is initialised
* later from a separate thread in network_http (once network_http is setup).
* later from a separate thread started from the news manager (see
* NewsManager::init() ).
*/
AddonsManager::AddonsManager() : m_addons_list(std::vector<Addon>() ),
m_state(STATE_INIT)
@ -72,6 +74,14 @@ AddonsManager::~AddonsManager()
} // ~AddonsManager
// ----------------------------------------------------------------------------
/** This init function is called from a separate thread (started in
* news_manager, since the news.xml file contains the address of the
* addons.xml URL).
* \param xml The news.xml file, which inclues the data about the addons.xml
* file (in the 'include' node).
* \param force_refresh Download addons.xml, even if the usual waiting period
* between downloads hasn't passed yet.
*/
void AddonsManager::init(const XMLNode *xml,
bool force_refresh)
{
@ -82,9 +92,8 @@ void AddonsManager::init(const XMLNode *xml,
if(!include)
{
file_manager->removeFile(filename);
setErrorState();
NewsManager::get()->addNewsMessage(_("Can't access stkaddons server..."));
// Use a curl error code here:
//return CURLE_COULDNT_CONNECT;
return;
}
@ -121,16 +130,15 @@ void AddonsManager::init(const XMLNode *xml,
addons_manager->initAddons(xml_addons); // will free xml_addons
if(UserConfigParams::logAddons())
Log::info("addons", "Addons manager list downloaded");
} // init
}
// ----------------------------------------------------------------------------
/** This initialises the online portion of the addons manager. It uses the
* downloaded list of available addons. This is called by network_http before
* it goes into command-receiving mode, so we can't use any asynchronous calls
* here (though this is being called from a separate thread , so the
* main GUI is not blocked anyway). This function will update the state
* variable
* downloaded list of available addons. It is called from init(), which is
* called from a separate thread, so blocking download requests can be used
* without blocking the GUI. This function will update the state variable.
* \param xml The xml tree of addons.xml with information about all available
* addons.
*/
void AddonsManager::initAddons(const XMLNode *xml)
{
@ -144,8 +152,9 @@ void AddonsManager::initAddons(const XMLNode *xml)
{
const XMLNode *node = xml->getNode(i);
const std::string &name = node->getName();
// Ignore news/redirect, which is handled by network_http
if(name=="include" || name=="message") continue;
// Ignore news/redirect, which is handled by the NewsManager
if(name=="include" || name=="message")
continue;
if(node->getName()=="track" || node->getName()=="kart" ||
node->getName()=="arena" )
{
@ -258,7 +267,7 @@ void AddonsManager::initAddons(const XMLNode *xml)
m_state.setAtomic(STATE_READY);
if (UserConfigParams::m_internet_status == INetworkHttp::IPERM_ALLOWED)
if (UserConfigParams::m_internet_status == RequestManager::IPERM_ALLOWED)
downloadIcons();
} // initAddons

View File

@ -1,49 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2013 Lucas Baudin
// 2011 Lucas Baudin, Joerg Henrichs
//
// 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_DUMMY_NETWORK_HTTP_HPP
#define HEADER_DUMMY_NETWORK_HTTP_HPP
#include "addons/request.hpp"
#include "addons/inetwork_http.hpp"
class XMLNode;
/**
* \ingroup addonsgroup
* Dummy implementation used when curl is not available
*/
class DummyNetworkHttp : public INetworkHttp
{
public:
virtual ~DummyNetworkHttp() {}
virtual void startNetworkThread() {}
virtual void stopNetworkThread() {}
virtual void insertReInit() {}
virtual Request *downloadFileAsynchron(const std::string &url,
const std::string &save = "",
int priority = 1,
bool manage_memory=true) { return NULL; }
virtual void cancelAllDownloads() {}
}; // NetworkHttp
#endif

View File

@ -1,48 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2012-2013 Joerg Henrichs
//
// 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 "addons/dummy_network_http.hpp"
#include "addons/inetwork_http.hpp"
#include "addons/network_http.hpp"
#include <assert.h>
INetworkHttp *INetworkHttp::m_network_http = NULL;
/** Creates the network_http instance (depending on compile time options).
*/
void INetworkHttp::create()
{
assert(m_network_http == NULL);
#ifdef NO_CURL
m_network_http = new DummyNetworkHttp();
#else
m_network_http = new NetworkHttp();
#endif
} // create
// ----------------------------------------------------------------------------
/** Destroys the network_http instance.
*/
void INetworkHttp::destroy()
{
if(m_network_http)
{
delete m_network_http;
m_network_http = NULL;
}
} // destroy

View File

@ -1,67 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2013 Lucas Baudin
// Copyright (C) 2011-2013 Lucas Baudin, Joerg Henrichs
//
// 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_INETWORK_HTTP_HPP
#define HEADER_INETWORK_HTTP_HPP
#include "addons/request.hpp"
class XMLNode;
/**
* \ingroup addonsgroup
* Abstract base interface for the network manager
*/
class INetworkHttp
{
private:
/** The one instance of this object. */
static INetworkHttp *m_network_http;
public:
/** If stk has permission to access the internet (for news
* server etc).
* IPERM_NOT_ASKED: The user needs to be asked if he wants to
* grant permission
* IPERM_ALLOWED: STK is allowed to access server.
* IPERM_NOT_ALLOWED: STK must not access external servers. */
enum InternetPermission {IPERM_NOT_ASKED =0,
IPERM_ALLOWED =1,
IPERM_NOT_ALLOWED=2 };
public:
virtual ~INetworkHttp() {}
virtual void startNetworkThread() = 0;
virtual void stopNetworkThread() = 0;
virtual void insertReInit() = 0;
virtual Request *downloadFileAsynchron(const std::string &url,
const std::string &save = "",
int priority = 1,
bool manage_memory=true) = 0;
virtual void cancelAllDownloads() = 0;
static void create();
static INetworkHttp *get() { return m_network_http; }
static void destroy();
}; // NetworkHttp
#endif

View File

@ -1,592 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2013 Lucas Baudin
// Copyright (C) 2011-2013 Lucas Baudin, Joerg Henrichs
//
// 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 NO_CURL
#include "addons/network_http.hpp"
#include <curl/curl.h>
#include <errno.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include "addons/news_manager.hpp"
#include "addons/request.hpp"
#include "config/user_config.hpp"
#include "io/file_manager.hpp"
#include "states_screens/addons_screen.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "utils/string_utils.hpp"
#include "utils/time.hpp"
#include "utils/translation.hpp"
// ----------------------------------------------------------------------------
/** Create a thread that handles all network functions independent of the
* main program. NetworkHttp supports only a single thread (i.e. it's not
* possible to download two addons at the same time), which makes handling
* and synchronisation a lot easier (otherwise all objects using this object
* would need an additional handle to get the right data back).
* This separate thread is running in NetworkHttp::mainLoop, and is being
* waken up if a command is issued (e.g. using downloadFileAsynchronous).
* While UserConfigParams are modified, they can't (easily) be saved here,
* since the user might trigger another save in the menu (potentially
* ending up with an corrupted file).
*/
NetworkHttp::NetworkHttp() :
m_current_request(NULL),
m_abort(false),
m_thread_id(NULL)
{
// Don't even start the network threads if networking is disabled.
if(UserConfigParams::m_internet_status!=NetworkHttp::IPERM_ALLOWED )
return;
curl_global_init(CURL_GLOBAL_ALL);
m_curl_session = curl_easy_init();
// Abort if curl error occurred.
if(!m_curl_session)
return;
pthread_cond_init(&m_cond_request, NULL);
Request *request = new Request(Request::HC_INIT, 9999);
m_all_requests.lock();
m_all_requests.getData().push(request);
m_all_requests.unlock();
} // NetworkHttp
// ---------------------------------------------------------------------------
/** Start the actual network thread. This can not be done as part of
* the constructor, since the assignment to the global network_http
* variable has not been assigned at that stage, and the thread might
* use network_http - a very subtle race condition. So the thread can
* only be started after the assignment (in main) has been done.
*/
void NetworkHttp::startNetworkThread()
{
if(UserConfigParams::m_internet_status!=NetworkHttp::IPERM_ALLOWED )
return;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
// Should be the default, but just in case:
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
//pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
m_thread_id.setAtomic(new pthread_t());
int error = pthread_create(m_thread_id.getData(), &attr,
&NetworkHttp::mainLoop, this);
if(error)
{
m_thread_id.lock();
delete m_thread_id.getData();
m_thread_id.unlock();
m_thread_id.setAtomic(0);
Log::warn("addons", "Could not create thread, error=%d", errno);
}
pthread_attr_destroy(&attr);
} // startNetworkThread
// ---------------------------------------------------------------------------
/** The actual main loop, which is started as a separate thread from the
* constructor. After testing for a new server, fetching news, the list
* of packages to download, it will wait for commands to be issued.
* \param obj: A pointer to this object, passed on by pthread_create
*/
void *NetworkHttp::mainLoop(void *obj)
{
NetworkHttp *me=(NetworkHttp*)obj;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
//pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
me->m_current_request = NULL;
me->m_all_requests.lock();
while(me->m_all_requests.getData().empty() ||
me->m_all_requests.getData().top()->getCommand() != Request::HC_QUIT)
{
bool empty = me->m_all_requests.getData().empty();
// Wait in cond_wait for a request to arrive. The 'while' is necessary
// since "spurious wakeups from the pthread_cond_wait ... may occur"
// (pthread_cond_wait man page)!
while(empty)
{
if(UserConfigParams::logAddons())
Log::debug("addons", "No request, sleeping.");
pthread_cond_wait(&me->m_cond_request,
me->m_all_requests.getMutex());
empty = me->m_all_requests.getData().empty();
}
// Get the first (=highest priority) request and remove it from the
// queue. Only this code actually removes requests from the queue,
// so it is certain that even
me->m_current_request = me->m_all_requests.getData().top();
me->m_all_requests.getData().pop();
if(UserConfigParams::logAddons())
{
if(me->m_current_request->getCommand()==Request::HC_DOWNLOAD_FILE)
Log::info("addons", "Executing download '%s' to '%s' priority %d",
me->m_current_request->getURL().c_str(),
me->m_current_request->getSavePath().c_str(),
me->m_current_request->getPriority());
else
Log::info("addons", "Executing command '%d' priority %d.",
me->m_current_request->getCommand(),
me->m_current_request->getPriority());
}
if(me->m_current_request->getCommand()==Request::HC_QUIT)
{
delete me->m_current_request;
me->m_current_request = NULL;
break;
}
me->m_all_requests.unlock();
CURLcode status=CURLE_OK;
switch(me->m_current_request->getCommand())
{
case Request::HC_INIT:
status = me->init(false);
break;
case Request::HC_REINIT:
status = me->reInit();
break;
case Request::HC_DOWNLOAD_FILE:
status = me->downloadFileInternal(me->m_current_request);
break;
case Request::HC_QUIT:
assert(false); // quit is checked already
break;
default:
assert(false); // All commands should have been handled.
} // switch(request->getCommand())
if(me->m_current_request->manageMemory())
{
delete me->m_current_request;
me->m_current_request = NULL;
}
// We have to lock here so that we can access m_all_requests
// in the while condition at the top of the loop
me->m_all_requests.lock();
} // while !quit
if(UserConfigParams::logAddons())
Log::info("addons", "Network exiting.");
// At this stage we have the lock for m_all_requests
while(!me->m_all_requests.getData().empty())
{
Request *r = me->m_all_requests.getData().top();
me->m_all_requests.getData().pop();
// Manage memory can be ignored here, all requests
// need to be freed.
delete r;
}
me->m_all_requests.unlock();
pthread_exit(NULL);
return 0;
} // mainLoop
// ---------------------------------------------------------------------------
/** This function inserts a high priority request to quit into the request
* queue of the network thead, and also aborts any ongoing download.
* Separating this allows more time for the thread to finish cleanly,
* before it gets cancelled in the destructor.
*/
void NetworkHttp::stopNetworkThread()
{
if(UserConfigParams::m_internet_status!=NetworkHttp::IPERM_ALLOWED)
return;
// If a download should be active (which means it was cancelled by the
// user, in which case it will still be ongoing in the background)
// we can't get the mutex, and would have to wait for a timeout,
// and we couldn't finish STK. This way we request an abort of
// a download, which mean we can get the mutex and ask the service
// thread here to cancel properly.
cancelAllDownloads();
Request *r = new Request(Request::HC_QUIT, 9999);
if(UserConfigParams::logAddons())
Log::info("addons", "Inserting QUIT request.");
insertRequest(r);
} // stopNetworkThread
// ---------------------------------------------------------------------------
/** Aborts the thread running here, and returns then.
*/
NetworkHttp::~NetworkHttp()
{
if(UserConfigParams::m_internet_status!=NetworkHttp::IPERM_ALLOWED)
return;
pthread_join(*m_thread_id.getData(), NULL);
delete m_thread_id.getAtomic();
pthread_cond_destroy(&m_cond_request);
curl_easy_cleanup(m_curl_session);
m_curl_session = NULL;
curl_global_cleanup();
} // ~NetworkHttp
// ---------------------------------------------------------------------------
/** Initialises the online part of the network manager. It downloads the
* news.xml file from the server (if the frequency of downloads makes this
* necessary), and (again if necessary) the addons.xml file.
* \return 0 if an error happened and no online connection will be available,
* 1 otherwise.
*/
CURLcode NetworkHttp::init(bool forceRefresh)
{
#ifdef xx
status = loadAddonsList(xml, xml_file, forceRefresh);
// Abort requested by stk -> display no error message and return
if(status==CURLE_ABORTED_BY_CALLBACK)
return status;
if(UserConfigParams::logAddons())
Log::error("addons", "Error raised in NetworkHttp::init : %s", core::stringc(error_message).c_str());
return status;
#endif
return CURLE_OK;
} // init
// ---------------------------------------------------------------------------
/** Reinitialises the network manager. This is triggered when the users
* selects 'reload' in the addon manager screen. This function inserts
* a high priority reinit request into the request queue.
*/
void NetworkHttp::insertReInit()
{
Request *request = new Request(Request::HC_REINIT, 9999,
/*manage_memory*/true);
if(UserConfigParams::logAddons())
Log::info("addons", "Inserting reInit request.");
insertRequest(request);
} // insertReInit
// ----------------------------------------------------------------------------
/** Reinitialises the addons manager. This function is triggered when a
* reInit request is handled. It removes all queued requests, deletes
* the news.xml and addons.xml files, and trigges a reload of those files.
*/
CURLcode NetworkHttp::reInit()
{
// This also switches the addons_manager to be not ready anymore,
// so the main menu will grey out the addon manager icon.
addons_manager->reInit();
m_all_requests.lock();
// There is no clear for a priority queue
while(!m_all_requests.getData().empty())
m_all_requests.getData().pop();
m_all_requests.unlock();
if(UserConfigParams::logAddons())
Log::info("addons", "Xml files deleted, re-initialising addon manager.");
return init(true /* force refresh */);
} // reInit
// ----------------------------------------------------------------------------
/** Checks the last modified date and if necessary updates the
* list of addons.
* \param xml The news xml file which contains the data about
* the addon list.
* \param filename The filename of the news xml file. Only needed
* in case of an error (e.g. it might contain a corrupted
* url) - the file will be deleted so that on next start
* of stk it will be updated again.
* \return curl error code (esp. CURLE_OK if no error occurred)
*/
CURLcode NetworkHttp::loadAddonsList(const XMLNode *xml,
const std::string &filename,
bool forceRefresh)
{
std::string addon_list_url("");
StkTime::TimeType mtime(0);
const XMLNode *include = xml->getNode("include");
if(include)
{
include->get("file", &addon_list_url);
int64_t tmp;
include->get("mtime", &tmp);
mtime = tmp;
}
if(addon_list_url.size()==0)
{
file_manager->removeFile(filename);
NewsManager::get()->addNewsMessage(_("Can't access stkaddons server..."));
// Use a curl error code here:
return CURLE_COULDNT_CONNECT;
}
bool download = (mtime > UserConfigParams::m_addons_last_updated) || forceRefresh;
if(!download)
{
std::string filename=file_manager->getAddonsFile("addons.xml");
if(!file_manager->fileExists(filename))
download = true;
}
if (download)
Log::info("NetworkHttp", "Downloading updated addons.xml");
else
Log::info("NetworkHttp", "Using cached addons.xml");
Request r(Request::HC_DOWNLOAD_FILE, 9999, false,
addon_list_url, "addons.xml");
CURLcode status = download ? downloadFileInternal(&r)
: CURLE_OK;
if(status==CURLE_OK)
{
std::string xml_file = file_manager->getAddonsFile("addons.xml");
if(download)
UserConfigParams::m_addons_last_updated=StkTime::getTimeSinceEpoch();
const XMLNode *xml = new XMLNode(xml_file);
// addons_manager->initOnline(xml);
if(UserConfigParams::logAddons())
Log::info("addons", "Addons manager list downloaded");
return status;
}
// Aborted by STK in progress callback, don't display error message
if(status==CURLE_ABORTED_BY_CALLBACK)
return status;
Log::error("addons", "Error on download addons.xml: %d\n",
status);
return status;
} // loadAddonsList
// ----------------------------------------------------------------------------
/** Download a file. The file name isn't absolute, the server in the config
* will be added to file. The file is downloaded with a ".part" extention,
* and the file is renamed after it was downloaded successfully.
* \param request The request object containing the url and the path where
* the file is saved to.
*/
CURLcode NetworkHttp::downloadFileInternal(Request *request)
{
std::string full_save =
file_manager->getAddonsFile(request->getSavePath());
std::string full_url = request->getURL();
if(full_url.substr(0, 5)!="http:" && full_url.substr(0, 4)!="ftp:")
full_url = (std::string)UserConfigParams::m_server_addons
+ "/" + full_url;
if(UserConfigParams::logAddons())
Log::info("addons", "Downloading '%s' as '%s'.",
full_url.c_str(), request->getSavePath().c_str());
curl_easy_setopt(m_curl_session, CURLOPT_URL, full_url.c_str());
std::string uagent = (std::string)"SuperTuxKart/" + STK_VERSION;
// Add platform to user-agent string for informational purposes.
// Add more cases as necessary.
#ifdef WIN32
uagent += (std::string)" (Windows)";
#elif defined(__APPLE__)
uagent += (std::string)" (Macintosh)";
#elif defined(__FreeBSD__)
uagent += (std::string)" (FreeBSD)";
#elif defined(linux)
uagent += (std::string)" (Linux)";
#else
// Unknown system type
#endif
curl_easy_setopt(m_curl_session, CURLOPT_USERAGENT, uagent.c_str());
curl_easy_setopt(m_curl_session, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSDATA, request);
FILE * fout = fopen((full_save+".part").c_str(), "wb");
if(!fout)
{
Log::error("addons", "Can't open '%s' for writing, ignored.",
(full_save+".part").c_str());
return CURLE_WRITE_ERROR;
}
//from and out
curl_easy_setopt(m_curl_session, CURLOPT_WRITEDATA, fout );
curl_easy_setopt(m_curl_session, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSFUNCTION,
&NetworkHttp::progressDownload);
curl_easy_setopt(m_curl_session, CURLOPT_NOPROGRESS, 0);
// Timeout
// Reduce the connection phase timeout (it's 300 by default).
// Add a low speed limit to have a sort of timeout in the
// download phase. Being under 10 B/s during a certain time will
// probably only happen when no access to the net is available.
// The timeout is set to 20s, it should be enough to not produce
// false positive error.
curl_easy_setopt(m_curl_session, CURLOPT_CONNECTTIMEOUT, 20);
curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_LIMIT, 10);
curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_TIME, 20);
CURLcode status = curl_easy_perform(m_curl_session);
fclose(fout);
if(status==CURLE_OK)
{
if(UserConfigParams::logAddons())
Log::info("addons", "Download successful.");
// The behaviour of rename is unspecified if the target
// file should already exist - so remove it.
file_manager->removeFile(full_save);
int ret = rename((full_save+".part").c_str(), full_save.c_str());
// In case of an error, set the status to indicate this
if(ret!=0)
{
if(UserConfigParams::logAddons())
Log::error("addons", "Could not rename downloaded file!");
status=CURLE_WRITE_ERROR;
}
else
request->notifyAddon();
}
else
{
Log::error("addons", "Problems downloading file - return code %d.",
status);
}
request->setProgress( (status==CURLE_OK) ? 1.0f : -1.0f );
return status;
} // downloadFileInternal
// ----------------------------------------------------------------------------
/** Signals to the progress function to request any ongoing download to be
* cancelled. This function can also be called if there is actually no
* download atm. The function progressDownload checks m_abort and will
* return a non-zero value which causes libcurl to abort. */
void NetworkHttp::cancelAllDownloads()
{
if(UserConfigParams::logAddons())
Log::info("addons", "Requesting cancellation of download.");
m_abort.setAtomic(true);
} // cancelAllDownload
// ----------------------------------------------------------------------------
/** External interface to download a file asynchronously. This will wake up
* the thread and schedule it to download the file. The calling program has
* to poll using getProgress() to find out if the download has finished.
* \param url The file from the server to download.
* \param save The name to save the downloaded file under. Defaults to
* the name given in file.
* \param priority Priority of the request (must be <=99)
*/
Request *NetworkHttp::downloadFileAsynchron(const std::string &url,
const std::string &save,
int priority,
bool manage_memory)
{
// Limit priorities to 99 so that important system requests
// (init and quit) will have highest priority.
assert(priority<=99);
Request *request = new Request(Request::HC_DOWNLOAD_FILE, priority,
manage_memory,
url, (save!="") ? save : url );
if(UserConfigParams::logAddons())
Log::info("addons", "Download asynchron '%s' as '%s'.",
request->getURL().c_str(), request->getSavePath().c_str());
insertRequest(request);
return request;
} // downloadFileAsynchron
// ----------------------------------------------------------------------------
/** Inserts a request into the queue of all requests. The request will be
* sorted by priority.
* \param request The pointer to the new request to insert.
*/
void NetworkHttp::insertRequest(Request *request)
{
m_all_requests.lock();
m_all_requests.getData().push(request);
// Wake up the network http thread
pthread_cond_signal(&m_cond_request);
m_all_requests.unlock();
} // insertRequest
// ----------------------------------------------------------------------------
/** Callback function from curl: inform about progress.
* \param clientp
* \param download_total Total size of data to download.
* \param download_now How much has been downloaded so far.
* \param upload_total Total amount of upload.
* \param upload_now How muc has been uploaded so far.
*/
int NetworkHttp::progressDownload(void *clientp,
double download_total, double download_now,
double upload_total, double upload_now)
{
Request *request = (Request *)clientp;
NetworkHttp* self = (NetworkHttp*)INetworkHttp::get();
// Check if we are asked to abort the download. If so, signal this
// back to libcurl by returning a non-zero status.
if(self->m_abort.getAtomic() || request->isCancelled() )
{
if(UserConfigParams::logAddons())
{
if(self->m_abort.getAtomic())
{
// Reset abort flag so that the next download will work
// as expected.
self->m_abort.setAtomic(false);
Log::info("addons", "Global abort of downloads.");
}
else
Log::info("addons", "Cancel this download.");
}
// Indicates to abort the current download, which means that this
// thread will go back to the mainloop and handle the next request.
return 1;
}
float f;
if(download_now < download_total)
{
f = (float)download_now / (float)download_total;
// In case of floating point rouding errors make sure that
// 1.0 is only reached when downloadFileInternal is finished
if (f>=1.0f) f=0.99f;
}
else
{
// Don't set progress to 1.0f; this is done in loadFileInternal
// after checking curls return code!
f= download_total==0 ? 0 : 0.99f;
}
request->setProgress(f);
return 0;
} // progressDownload
#endif

View File

@ -1,92 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2013 Lucas Baudin
// Copyright (C) 2011-2013 Lucas Baudin, Joerg Henrichs
//
// 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_NETWORK_HTTP_HPP
#define HEADER_NETWORK_HTTP_HPP
#ifndef NO_CURL
#include <queue>
#include <pthread.h>
#include <string>
#include <vector>
#ifdef WIN32
# include <WinSock2.h>
#endif
#include <curl/curl.h>
#include "addons/inetwork_http.hpp"
#include "addons/request.hpp"
#include "utils/synchronised.hpp"
class XMLNode;
/**
* \ingroup addonsgroup
*/
class NetworkHttp : public INetworkHttp
{
private:
/** The list of pointes to all requests. */
Synchronised< std::priority_queue<Request*,
std::vector<Request*>,
Request::Compare > > m_all_requests;
/** The current requested being worked on. */
Request *m_current_request;
/** A conditional variable to wake up the main loop. */
pthread_cond_t m_cond_request;
/** Signal an abort in case that a download is still happening. */
Synchronised<bool> m_abort;
/** Thread id of the thread running in this object. */
Synchronised<pthread_t *> m_thread_id;
/** The curl session. */
CURL *m_curl_session;
static void *mainLoop(void *obj);
CURLcode init(bool forceRefresh);
CURLcode downloadFileInternal(Request *request);
static int progressDownload(void *clientp, double dltotal, double dlnow,
double ultotal, double ulnow);
void insertRequest(Request *request);
CURLcode reInit();
public:
NetworkHttp();
virtual ~NetworkHttp();
void startNetworkThread();
void stopNetworkThread();
void insertReInit();
Request *downloadFileAsynchron(const std::string &url,
const std::string &save = "",
int priority = 1,
bool manage_memory=true);
void cancelAllDownloads();
CURLcode loadAddonsList(const XMLNode *xml,
const std::string &filename,
bool forceRefresh);
}; // NetworkHttp
#endif
#endif

View File

@ -35,6 +35,7 @@ NewsManager::NewsManager() : m_news(std::vector<NewsMessage>())
{
m_current_news_message = -1;
m_error_message.setAtomic("");
m_force_refresh = false;
init(false);
} // NewsManage
@ -44,8 +45,11 @@ NewsManager::~NewsManager()
} // ~NewsManager
// ---------------------------------------------------------------------------
/** This function initialises the data for the news manager. If necessary,
* it will use a separate thread to download the news.xml file.
/** This function initialises the data for the news manager. It starts a
* separate thread to execute downloadNews() - which (if necessary) the
* news.xml file and updating the list of news messages. It also initialises
* the addons manager (which can trigger another download of news.xml).
* \param force_refresh Re-download news.xml, even if
*/
void NewsManager::init(bool force_refresh)
{
@ -59,6 +63,8 @@ void NewsManager::init(bool force_refresh)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
//pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
m_force_refresh = force_refresh;
pthread_t thread_id;
int error = pthread_create(&thread_id, &attr,
&NewsManager::downloadNews, this);
@ -80,7 +86,6 @@ void NewsManager::init(bool force_refresh)
*/
void* NewsManager::downloadNews(void *obj)
{
bool force_refresh = false;
NewsManager *me = (NewsManager*)obj;
me->clearErrorMessage();
@ -95,7 +100,7 @@ void* NewsManager::downloadNews(void *obj)
UserConfigParams::m_news_last_updated
+UserConfigParams::m_news_frequency
< StkTime::getTimeSinceEpoch() ||
force_refresh ||
me->m_force_refresh ||
!news_exists;
const XMLNode *xml = NULL;
@ -178,7 +183,7 @@ void* NewsManager::downloadNews(void *obj)
xml = new XMLNode(xml_file);
me->checkRedirect(xml);
me->updateNews(xml, xml_file);
addons_manager->init(xml, force_refresh);
addons_manager->init(xml, me->m_force_refresh);
delete xml;
}

View File

@ -91,6 +91,9 @@ private:
* any news message (usually indicating connection problems). */
Synchronised<core::stringw> m_error_message;
/** True when all .xml files should be re-downloaded. */
bool m_force_refresh;
void checkRedirect(const XMLNode *xml);
void updateNews(const XMLNode *xml,
const std::string &filename);
@ -106,7 +109,7 @@ public:
if(!m_news_manager)
m_news_manager = new NewsManager();
return m_news_manager;
} //
} // get
// ------------------------------------------------------------------------
static void deallocate()
{

View File

@ -1,63 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2011-2013 Joerg Henrichs
//
// 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 "addons/request.hpp"
#include <assert.h>
#include "addons/addon.hpp"
Request::Request(HttpCommands command, int priority, bool manage_memory)
: m_progress(0)
{
m_command = command;
m_priority = priority;
m_url = "";
m_full_path = "";
m_manage_memory = manage_memory;
m_icon_addon = NULL;
m_cancel = false;
m_progress.setAtomic(0);
} // Request
// ----------------------------------------------------------------------------
Request::Request(HttpCommands command, int priority, bool manage_memory,
const std::string &url, const std::string &save)
: m_progress(0)
{
m_command = command;
m_priority = priority;
m_url = url;
m_full_path = save;
m_icon_addon = NULL;
m_manage_memory = manage_memory;
m_cancel = false;
m_progress.setAtomic(0);
} // Request
// ----------------------------------------------------------------------------
void Request::setAddonIconNotification(Addon *a)
{
m_icon_addon = a;
} // setADdonIconNotification
// ----------------------------------------------------------------------------
void Request::notifyAddon()
{
if(m_icon_addon)
m_icon_addon->setIconReady();
} // notifyAddon

View File

@ -1,127 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2011-2013 Joerg Henrichs
//
// 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_REQUEST_HPP
#define HEADER_REQUEST_HPP
#include <string>
#include "utils/leak_check.hpp"
#include "utils/synchronised.hpp"
class Addon;
/**
* Stores a download request. They will be sorted by priorities.
* \ingroup addonsgroup
*/
class Request
{
public:
/** List of 'http commands' for this object:
* HC_INIT: Object is being initialised
* HC_DOWNLOAD_FILE : download a file
* HC_QUIT: Stop loop and terminate thread.
* HC_NEWS: Update the news
*/
enum HttpCommands {HC_QUIT,
HC_INIT,
HC_REINIT,
HC_DOWNLOAD_FILE };
private:
/** The progress indicator. 0 till it is started and the first
* packet is downloaded. At the end eithe -1 (error) or 1
* (everything ok) at the end. */
Synchronised<float> m_progress;
/** The URL to download. */
std::string m_url;
/** Where to store the file (including file name). */
std::string m_full_path;
/** The priority of this request. The higher the value the more
important this request is. */
int m_priority;
/** Cancel this request if it is active. */
bool m_cancel;
/** The actual command to use. */
HttpCommands m_command;
/** True if the memory for this Request should be managed by
* network_http (i.e. this object is freed once the request
* is handled). Otherwise the memory is not freed, so it must
* be freed by the calling function. */
bool m_manage_memory;
/** If this is a download for an icon addon, this contains a pointer
* to the addon so that we can notify the addon that the icon is
* ready. */
Addon *m_icon_addon;
public:
LEAK_CHECK()
Request(HttpCommands command, int priority,
bool manage_memory=true);
Request(HttpCommands command, int priority, bool manage_memory,
const std::string &url, const std::string &save);
void setAddonIconNotification(Addon *a);
void notifyAddon();
// ------------------------------------------------------------------------
/** Returns the URL to download from. */
const std::string &getURL() const {return m_url;}
// ------------------------------------------------------------------------
/** Returns the full save file name. */
const std::string &getSavePath() const {return m_full_path;}
// ------------------------------------------------------------------------
/** Returns the command to do for this request. */
HttpCommands getCommand() const { return m_command; }
// ------------------------------------------------------------------------
/** Returns the priority of this request. */
int getPriority() const { return m_priority; }
// ------------------------------------------------------------------------
/** Returns the current progress. */
float getProgress() const { return m_progress.getAtomic(); }
// ------------------------------------------------------------------------
/** Sets the current progress. */
void setProgress(float f) { m_progress.setAtomic(f); }
// ------------------------------------------------------------------------
/** Signals that this request should be cancelled. */
void cancel() { m_cancel = true; }
// ------------------------------------------------------------------------
/** Returns if this request is to be cancelled. */
bool isCancelled() const { return m_cancel; }
// ------------------------------------------------------------------------
/** Specifies if the memory should be managed by network_http. */
void setManageMemory(bool m) { m_manage_memory = m; }
// ------------------------------------------------------------------------
/** Returns if the memory for this object should be managed by
* by network_http (i.e. freed once the request is handled). */
bool manageMemory() const { return m_manage_memory; }
// ========================================================================
/** This class is used by the priority queue to sort requests by priority.
*/
class Compare
{
public:
/** Compares two requests, returns if the first request has a lower
* priority than the second one. */
bool operator() (const Request *a, const Request *b) const
{ return a->getPriority() < b->getPriority(); }
}; // Compare
}; // Request
#endif

View File

@ -517,7 +517,7 @@ void ParticleSystemProxy::simulateHeightmap()
void ParticleSystemProxy::simulateNoHeightmap()
{
int timediff = GUIEngine::getLatestDt() * 1000.;
int timediff = int(GUIEngine::getLatestDt() * 1000.f);
int active_count = getEmitter()->getMaxLifeTime() * getEmitter()->getMaxParticlesPerSecond() / 1000;
core::matrix4 matrix = getAbsoluteTransformation();
glUseProgram(SimpleSimulationShader::Program);

View File

@ -142,7 +142,6 @@
#include "main_loop.hpp"
#include "achievements/achievements_manager.hpp"
#include "addons/addons_manager.hpp"
#include "addons/inetwork_http.hpp"
#include "addons/news_manager.hpp"
#include "audio/music_manager.hpp"
#include "audio/sfx_manager.hpp"
@ -1020,14 +1019,9 @@ void initRest()
// separate thread running in network http.
addons_manager = new AddonsManager();
INetworkHttp::create();
Online::RequestManager::get()->startNetworkThread();
NewsManager::get(); // this will create the news manager
// Note that the network thread must be started after the assignment
// to network_http (since the thread might use network_http, otherwise
// a race condition can be introduced resulting in a crash).
INetworkHttp::get()->startNetworkThread();
Online::RequestManager::get()->startNetworkThread();
AchievementsManager::get()->init();
music_manager = new MusicManager();
sfx_manager = new SFXManager();
@ -1081,8 +1075,6 @@ static void cleanSuperTuxKart()
irr_driver->updateConfigIfRelevant();
if(INetworkHttp::get())
INetworkHttp::get()->stopNetworkThread();
if(Online::RequestManager::isRunning())
Online::RequestManager::get()->stopNetworkThread();
@ -1098,7 +1090,6 @@ static void cleanSuperTuxKart()
Referee::cleanup();
if(ReplayPlay::get()) ReplayPlay::destroy();
if(race_manager) delete race_manager;
INetworkHttp::destroy();
NewsManager::deallocate();
if(addons_manager) delete addons_manager;
NetworkManager::kill();
@ -1248,7 +1239,9 @@ int main(int argc, char *argv[] )
// Load addons.xml to get info about addons even when not
// allowed to access the internet
if (UserConfigParams::m_internet_status != INetworkHttp::IPERM_ALLOWED) {
if (UserConfigParams::m_internet_status !=
Online::RequestManager::IPERM_ALLOWED)
{
std::string xml_file = file_manager->getAddonsFile("addons.xml");
if (file_manager->fileExists(xml_file)) {
const XMLNode *xml = new XMLNode (xml_file);
@ -1278,7 +1271,7 @@ int main(int argc, char *argv[] )
}
#endif
if(UserConfigParams::m_internet_status ==
INetworkHttp::IPERM_NOT_ASKED)
Online::RequestManager::IPERM_NOT_ASKED)
{
class ConfirmServer :
public MessageDialog::IConfirmDialogListener
@ -1286,27 +1279,16 @@ int main(int argc, char *argv[] )
public:
virtual void onConfirm()
{
INetworkHttp::destroy();
UserConfigParams::m_internet_status =
INetworkHttp::IPERM_ALLOWED;
Online::RequestManager::IPERM_ALLOWED;
GUIEngine::ModalDialog::dismiss();
INetworkHttp::create();
// Note that the network thread must be started after
// the assignment to network_http (since the thread
// might use network_http, otherwise a race condition
// can be introduced resulting in a crash).
INetworkHttp::get()->startNetworkThread();
} // onConfirm
// --------------------------------------------------------
virtual void onCancel()
{
INetworkHttp::destroy();
UserConfigParams::m_internet_status =
INetworkHttp::IPERM_NOT_ALLOWED;
Online::RequestManager::IPERM_NOT_ALLOWED;
GUIEngine::ModalDialog::dismiss();
INetworkHttp::create();
INetworkHttp::get()->startNetworkThread();
} // onCancel
}; // ConfirmServer

View File

@ -21,6 +21,8 @@
#include "io/file_manager.hpp"
#include "utils/cpp2011.h"
#include "utils/leak_check.hpp"
#include "utils/no_copy.hpp"
#include "utils/string_utils.hpp"
#include "utils/synchronised.hpp"
@ -58,9 +60,11 @@ namespace Online
*
* \ingroup online
*/
class Request
class Request : public NoCopy
{
private:
LEAK_CHECK()
/** Type of the request. Has 0 as default value. */
const int m_type;
/** True if the memory for this Request should be managed by

View File

@ -48,7 +48,17 @@ namespace Online
*/
class RequestManager
{
protected:
public:
/** If stk has permission to access the internet (for news
* server etc).
* IPERM_NOT_ASKED: The user needs to be asked if he wants to
* grant permission
* IPERM_ALLOWED: STK is allowed to access server.
* IPERM_NOT_ALLOWED: STK must not access external servers. */
enum InternetPermission {IPERM_NOT_ASKED =0,
IPERM_ALLOWED =1,
IPERM_NOT_ALLOWED=2 };
protected:
float m_time_since_poll;

View File

@ -20,13 +20,14 @@
#include <iostream>
#include "addons/addons_manager.hpp"
#include "addons/inetwork_http.hpp"
#include "addons/news_manager.hpp"
#include "guiengine/CGUISpriteBank.h"
#include "guiengine/modaldialog.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "io/file_manager.hpp"
#include "online/request_manager.hpp"
#include "states_screens/dialogs/addons_loading.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "states_screens/state_manager.hpp"
@ -35,6 +36,7 @@
DEFINE_SCREEN_SINGLETON( AddonsScreen );
using namespace Online;
// ----------------------------------------------------------------------------
AddonsScreen::AddonsScreen() : Screen("addons_screen.stkgui")
@ -155,7 +157,7 @@ void AddonsScreen::init()
w_list->setIcons(m_icon_bank, (int)(m_icon_height));
m_type = "kart";
if (UserConfigParams::m_internet_status != INetworkHttp::IPERM_ALLOWED)
if (UserConfigParams::m_internet_status != RequestManager::IPERM_ALLOWED)
getWidget<GUIEngine::IconButtonWidget>("reload")->setDeactivated();
else
getWidget<GUIEngine::IconButtonWidget>("reload")->setActivated();
@ -231,8 +233,9 @@ void AddonsScreen::loadList()
if(!UserConfigParams::m_artist_debug_mode &&
!addon.testStatus(Addon::AS_APPROVED) )
continue;
if (!addon.isInstalled() && (addons_manager->wasError()
|| UserConfigParams::m_internet_status != INetworkHttp::IPERM_ALLOWED ))
if (!addon.isInstalled() && (addons_manager->wasError() ||
UserConfigParams::m_internet_status !=
RequestManager::IPERM_ALLOWED ))
continue;
// Filter by rating.
@ -424,10 +427,10 @@ void AddonsScreen::eventCallback(GUIEngine::Widget* widget,
if (!m_reloading)
{
m_reloading = true;
INetworkHttp::get()->insertReInit();
NewsManager::get()->init(true);
GUIEngine::ListWidget* w_list =
getWidget<GUIEngine::ListWidget>("list_addons");
getWidget<GUIEngine::ListWidget>("list_addons");
w_list->clear();
w_list->addItem("spacer", L"");
@ -498,7 +501,7 @@ void AddonsScreen::onUpdate(float dt, irr::video::IVideoDriver*)
{
if (m_reloading)
{
if(UserConfigParams::m_internet_status!=INetworkHttp::IPERM_ALLOWED)
if(UserConfigParams::m_internet_status!=RequestManager::IPERM_ALLOWED)
{
// not allowed to access the net. how did you get to this menu in
// the first place??

View File

@ -21,8 +21,6 @@
#include <pthread.h>
#include "addons/addons_manager.hpp"
#include "addons/inetwork_http.hpp"
#include "addons/request.hpp"
#include "config/user_config.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
@ -39,6 +37,7 @@
#include "utils/translation.hpp"
using namespace GUIEngine;
using namespace Online;
using namespace irr::gui;
// ----------------------------------------------------------------------------
@ -95,7 +94,7 @@ void AddonsLoading::beforeAddingWidgets()
* and not in error state
*/
if (m_addon.needsUpdate() && !addons_manager->wasError()
&& UserConfigParams::m_internet_status==INetworkHttp::IPERM_ALLOWED)
&& UserConfigParams::m_internet_status==RequestManager::IPERM_ALLOWED)
getWidget<IconButtonWidget> ("install")->setLabel( _("Update") );
else
r->removeChildNamed("install");
@ -279,7 +278,7 @@ void AddonsLoading::onUpdate(float delta)
new MessageDialog( _("Sorry, downloading the add-on failed"));
return;
}
else if(progress>=1.0f)
else if(m_download_request->isDone())
{
m_back_button->setLabel(_("Back"));
// No sense to update state text, since it all
@ -308,9 +307,11 @@ void AddonsLoading::startDownload()
std::string file = m_addon.getZipFileName();
std::string save = "tmp/"
+ StringUtils::getBasename(m_addon.getZipFileName());
m_download_request = INetworkHttp::get()->downloadFileAsynchron(file, save,
/*priority*/5,
/*manage memory*/false);
m_download_request = new Online::HTTPRequest(save, /*manage mem*/false,
/*priority*/5);
m_download_request->setURL(m_addon.getZipFileName());
m_download_request->queue();
} // startDownload
// ----------------------------------------------------------------------------
@ -327,7 +328,8 @@ void AddonsLoading::stopDownload()
// network_http will potentially update the request. So in
// order to avoid a memory leak, we let network_http free
// the request.
m_download_request->setManageMemory(true);
//m_download_request->setManageMemory(true);
assert(false);
m_download_request->cancel();
};
} // startDownload

View File

@ -25,7 +25,7 @@
#include "guiengine/modaldialog.hpp"
#include "utils/synchronised.hpp"
class Request;
namespace Online { class HTTPRequest; }
/**
* \ingroup states_screens
@ -53,7 +53,7 @@ private:
/** A pointer to the download request, which gives access
* to the progress of a download. */
Request *m_download_request;
Online::HTTPRequest *m_download_request;
bool m_vote_clicked;

View File

@ -21,7 +21,6 @@
#include <string>
#include "addons/inetwork_http.hpp"
#include "challenges/game_slot.hpp"
#include "challenges/unlock_manager.hpp"
#include "graphics/irr_driver.hpp"
@ -37,6 +36,7 @@
#include "modes/cutscene_world.hpp"
#include "modes/overworld.hpp"
#include "modes/demo_world.hpp"
#include "online/request_manager.hpp"
#include "states_screens/online_screen.hpp"
#include "states_screens/addons_screen.hpp"
#include "states_screens/credits.hpp"
@ -60,6 +60,7 @@
#include "utils/string_utils.hpp"
using namespace GUIEngine;
using namespace Online;
DEFINE_SCREEN_SINGLETON( MainMenuScreen );
@ -146,7 +147,7 @@ void MainMenuScreen::onUpdate(float delta, irr::video::IVideoDriver* driver)
addons_icon->setBadge(BAD_BADGE);
}
else if (addons_manager->isLoading() && UserConfigParams::m_internet_status
== INetworkHttp::IPERM_ALLOWED)
== Online::RequestManager::IPERM_ALLOWED)
{
// Addons manager is still initialising/downloading.
addons_icon->setDeactivated();
@ -391,7 +392,7 @@ void MainMenuScreen::onDisabledItemClicked(const std::string& item)
{
if (item == "addons")
{
if (UserConfigParams::m_internet_status != INetworkHttp::IPERM_ALLOWED)
if (UserConfigParams::m_internet_status != RequestManager::IPERM_ALLOWED)
{
new MessageDialog( _("The add-ons module is currently disabled in "
"the Options screen") );

View File

@ -17,7 +17,6 @@
#include "states_screens/options_screen_ui.hpp"
#include "addons/inetwork_http.hpp"
#include "audio/music_manager.hpp"
#include "audio/sfx_manager.hpp"
#include "audio/sfx_base.hpp"
@ -30,6 +29,7 @@
#include "guiengine/widgets/spinner_widget.hpp"
#include "guiengine/widget.hpp"
#include "io/file_manager.hpp"
#include "online/request_manager.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/options_screen_audio.hpp"
#include "states_screens/options_screen_input.hpp"
@ -45,6 +45,7 @@
#include <sstream>
using namespace GUIEngine;
using namespace Online;
DEFINE_SCREEN_SINGLETON( OptionsScreenUI );
@ -126,7 +127,7 @@ void OptionsScreenUI::init()
CheckBoxWidget* news = getWidget<CheckBoxWidget>("enable-internet");
assert( news != NULL );
news->setState( UserConfigParams::m_internet_status
==INetworkHttp::IPERM_ALLOWED );
==RequestManager::IPERM_ALLOWED );
// --- select the right skin in the spinner
bool currSkinFound = false;
@ -229,19 +230,9 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
{
CheckBoxWidget* news = getWidget<CheckBoxWidget>("enable-internet");
assert( news != NULL );
if(INetworkHttp::get())
{
INetworkHttp::get()->stopNetworkThread();
INetworkHttp::destroy();
}
UserConfigParams::m_internet_status =
news->getState() ? INetworkHttp::IPERM_ALLOWED
: INetworkHttp::IPERM_NOT_ALLOWED;
INetworkHttp::create();
// Note that the network thread must be started after the assignment
// to network_http (since the thread might use network_http, otherwise
// a race condition can be introduced resulting in a crash).
INetworkHttp::get()->startNetworkThread();
news->getState() ? RequestManager::IPERM_ALLOWED
: RequestManager::IPERM_NOT_ALLOWED;
}
else if (name == "language")
{