diff --git a/sources.cmake b/sources.cmake index 0f4ff88a7..a214a603a 100644 --- a/sources.cmake +++ b/sources.cmake @@ -146,7 +146,6 @@ src/network/race_info_message.cpp src/network/race_result_message.cpp src/network/race_state.cpp src/online/current_user.cpp -src/online/http_connector.cpp src/online/http_manager.cpp src/online/messages.cpp src/online/request.cpp @@ -418,8 +417,6 @@ src/network/race_state.hpp src/network/remote_kart_info.hpp src/network/world_loaded_message.hpp src/online/current_user.hpp -src/online/http_connector.hpp -src/online/http_listener.hpp src/online/http_manager.hpp src/online/messages.hpp src/online/request.hpp diff --git a/src/guiengine/widgets/list_widget.cpp b/src/guiengine/widgets/list_widget.cpp index 3d82cd5f5..7aad575f0 100644 --- a/src/guiengine/widgets/list_widget.cpp +++ b/src/guiengine/widgets/list_widget.cpp @@ -253,6 +253,14 @@ void ListWidget::renameItem(const int row_index, const irr::core::stringw newNam renameCell(row_index, 0, newName, icon); } +// ----------------------------------------------------------------------------- +void ListWidget::renameItem(const std::string & internal_name, const irr::core::stringw newName, const int icon) +{ + CGUISTKListBox* list = getIrrlichtElement(); + assert(list != NULL); + renameCell(list->getRowByInternalName(internal_name), 0, newName, icon); +} + // ----------------------------------------------------------------------------- std::string ListWidget::getSelectionInternalName() diff --git a/src/guiengine/widgets/list_widget.hpp b/src/guiengine/widgets/list_widget.hpp index d74937a77..c56cd450a 100644 --- a/src/guiengine/widgets/list_widget.hpp +++ b/src/guiengine/widgets/list_widget.hpp @@ -178,6 +178,7 @@ namespace GUIEngine * renames first cell only */ void renameItem(const int row_num, const irr::core::stringw newName, const int icon=-1); + void renameItem(const std::string & internal_name, const irr::core::stringw newName, const int icon=-1); /** * \brief rename an item and/or change its icon based on its internal name diff --git a/src/online/current_user.cpp b/src/online/current_user.cpp index 42acd7481..7878f1387 100644 --- a/src/online/current_user.cpp +++ b/src/online/current_user.cpp @@ -22,7 +22,6 @@ #include #include #include -#include "online/http_connector.hpp" #include "config/user_config.hpp" #include "utils/translation.hpp" #include "utils/log.hpp" @@ -30,14 +29,6 @@ namespace Online{ static Synchronised user_singleton(NULL); - CurrentUser* CurrentUser::get() - { - CurrentUser* user = user_singleton.getData(); - if (user == NULL) - user = new CurrentUser(); - return user; - } // get - CurrentUser* CurrentUser::acquire() { user_singleton.lock(); @@ -97,8 +88,10 @@ namespace Online{ CurrentUser::SignInRequest * CurrentUser::requestSavedSession() { SignInRequest * request = NULL; + Log::info("CurrentUser::requestSavedSession","1"); if(m_state != US_SIGNED_IN && UserConfigParams::m_saved_session) { + Log::info("CurrentUser::requestSavedSession","2"); request = new SignInRequest(); request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php"); request->setParameter("action",std::string("saved-session")); diff --git a/src/online/current_user.hpp b/src/online/current_user.hpp index c2b4d75a2..87af2262b 100644 --- a/src/online/current_user.hpp +++ b/src/online/current_user.hpp @@ -90,10 +90,12 @@ namespace Online{ CurrentUser(); - public: - static CurrentUser* get(); //FIXME To be removed + void signIn (const SignInRequest * input); + void signOut (const SignOutRequest * input); + void createServer (const ServerCreationRequest * input); - //Singleton methods + public: + //Singleton static CurrentUser* acquire(); static void release(); static void deallocate(); @@ -114,10 +116,6 @@ namespace Online{ const irr::core::stringw &email, bool terms); - void signIn (const SignInRequest * input); - void signOut (const SignOutRequest * input); - void createServer (const ServerCreationRequest * input); - /** Returns the username if signed in. */ irr::core::stringw getUserName() const; bool isSignedIn() const { return m_state == US_SIGNED_IN; } diff --git a/src/online/http_connector.cpp b/src/online/http_connector.cpp deleted file mode 100644 index 832b2d5c9..000000000 --- a/src/online/http_connector.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2013 Glenn De Jonghe -// -// 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 "http_connector.hpp" - -#include -#include -#include -#include "io/file_manager.hpp" - - -HTTPConnector::HTTPConnector(const std::string &url){ - curl_global_init(CURL_GLOBAL_DEFAULT); - curl = curl_easy_init(); - if(!curl) - Log::error("online/http_functions", "Error while loading cURL library."); - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - if (url.substr(0, 5)!="http:") - { - Log::error("online/http_functions", "Invalid URL."); - } -} - -// ============================================================================ - - -HTTPConnector::~HTTPConnector(){ - curl_easy_cleanup(curl); - curl_global_cleanup(); -} - -// ============================================================================ - -static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) -{ - ((std::string*)userp)->append((char*)contents, size * nmemb); - return size * nmemb; -} - -XMLNode * HTTPConnector::getXMLFromPage() -{ - return file_manager->createXMLTreeFromString(getPage()); -} - -std::string HTTPConnector::getPage() -{ - - Parameters::iterator iter; - std::string postString = ""; - for (iter = m_parameters.begin(); iter != m_parameters.end(); ++iter) - { - if(iter != m_parameters.begin()) - postString.append("&"); - char * escaped = curl_easy_escape(this->curl , iter->first.c_str(), iter->first.size()); - postString.append(escaped); - curl_free(escaped); - postString.append("="); - escaped = curl_easy_escape(this->curl , iter->second.c_str(), iter->second.size()); - postString.append(escaped); - curl_free(escaped); - } - curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, postString.c_str()); - std::string readBuffer; - curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, WriteCallback); - curl_easy_setopt(this->curl, CURLOPT_FILE, &readBuffer); - res = curl_easy_perform(this->curl); - if(res != CURLE_OK) - Log::error("online/http_functions", "curl_easy_perform() failed: %s", curl_easy_strerror(res)); - else - Log::info("online/http_functions", "Received : %s", readBuffer.c_str()); - m_parameters.clear(); - return readBuffer; -} diff --git a/src/online/http_connector.hpp b/src/online/http_connector.hpp deleted file mode 100644 index f221f7f06..000000000 --- a/src/online/http_connector.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2013 Glenn De Jonghe -// -// 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 HTTP_CONNECTOR_HPP -#define HTTP_CONNECTOR_HPP - -#include -#include "io/xml_node.hpp" -#include -#include -#include "utils/string_utils.hpp" - -/** - * \brief Class to connect with a server over HTTP - * \ingroup online - */ -class HTTPConnector -{ - protected: - CURL *curl; - CURLcode res; - typedef std::map Parameters; - Parameters m_parameters; - - public: - - HTTPConnector(const std::string &url); - ~HTTPConnector(); - - //Execute - std::string getPage(); - XMLNode * getXMLFromPage(); - - //Setting parameters to be send with the next request - void setParameter(const std::string & name, const std::string &value){ - m_parameters[name] = value; - }; - void setParameter(const std::string & name, const irr::core::stringw &value){ - m_parameters[name] = irr::core::stringc(value.c_str()).c_str(); - } - template - void setParameter(const std::string & name, const T& value){ - m_parameters[name] = StringUtils::toString(value); - } - -}; //class HTTPConnector - - -#endif // HTTP_CONNECTOR_HPP - -/*EOF*/ diff --git a/src/online/messages.cpp b/src/online/messages.cpp index 5055e355c..0b1e61448 100644 --- a/src/online/messages.cpp +++ b/src/online/messages.cpp @@ -58,6 +58,13 @@ namespace Online return irr::core::stringw(_("Creating server")) + loadingDots(); } + // ------------------------------------------------------------------------ + + irr::core::stringw fetchingServers() + { + return irr::core::stringw(_("Fetching servers")) + loadingDots(); + } + // ------------------------------------------------------------------------ irr::core::stringw loadingDots(bool spaces, float interval, int max_dots) { diff --git a/src/online/messages.hpp b/src/online/messages.hpp index 64b427754..36a936d79 100644 --- a/src/online/messages.hpp +++ b/src/online/messages.hpp @@ -29,9 +29,10 @@ namespace Online irr::core::stringw loadingDots (bool spaces = true, float interval = 0.5f, int max_dots = 3); irr::core::stringw signingIn (); irr::core::stringw signingOut (); - irr::core::stringw signingUp (); + irr::core::stringw signingUp (); irr::core::stringw joiningServer (); irr::core::stringw creatingServer (); + irr::core::stringw fetchingServers (); irr::core::stringw signedInAs (const irr::core::stringw & name); } // namespace Messages }// namespace Online diff --git a/src/online/servers_manager.cpp b/src/online/servers_manager.cpp index 3bd57e53c..aa26e9bf0 100644 --- a/src/online/servers_manager.cpp +++ b/src/online/servers_manager.cpp @@ -22,56 +22,87 @@ #include #include #include -#include "online/http_connector.hpp" #include "config/user_config.hpp" #include "utils/translation.hpp" +#include "utils/time.hpp" + +#define SERVER_REFRESH_INTERVAL 5.0f namespace Online{ - static ServersManager* user_singleton = NULL; + static Synchronised manager_singleton(NULL); - ServersManager* ServersManager::get() + ServersManager* ServersManager::acquire() { - if (user_singleton == NULL) - user_singleton = new ServersManager(); - return user_singleton; - } // get + manager_singleton.lock(); + ServersManager * manager = manager_singleton.getData(); + if (manager == NULL) + { + manager_singleton.unlock(); + manager = new ServersManager(); + manager_singleton.setAtomic(manager); + manager_singleton.lock(); + } + return manager; + } + + void ServersManager::release() + { + manager_singleton.unlock(); + } void ServersManager::deallocate() { - delete user_singleton; - user_singleton = NULL; + manager_singleton.lock(); + ServersManager* manager = manager_singleton.getData(); + delete manager; + manager = NULL; + manager_singleton.unlock(); } // deallocate // ============================================================================ ServersManager::ServersManager(){ m_servers = new PtrVector; - refresh(); + m_info_message = ""; + m_last_load_time = 0.0f; } // ============================================================================ - void ServersManager::refresh() + ServersManager::RefreshRequest * ServersManager::refreshRequest() { - HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "client-user.php"); - connector->setParameter("action",std::string("get_server_list")); - - const XMLNode * result = connector->getXMLFromPage(); - std::string rec_success = ""; - if(result->get("success", &rec_success)) + RefreshRequest * request = NULL; + if(Time::getRealTime() - m_last_load_time > SERVER_REFRESH_INTERVAL) { - if (rec_success =="yes") - { - const XMLNode * servers_xml = result->getNode("servers"); - m_servers->clearAndDeleteAll(); - for (unsigned int i = 0; i < servers_xml->getNumNodes(); i++) - { - m_servers->push_back(new Server(*servers_xml->getNode(i))); - } - } + request = new RefreshRequest(); + request->setURL((std::string)UserConfigParams::m_server_multiplayer + "client-user.php"); + request->setParameter("action",std::string("get_server_list")); + HTTPManager::get()->addRequest(request); } + return request; + } + + void ServersManager::refresh(const RefreshRequest * input) + { + if (input->isSuccess()) + { + const XMLNode * servers_xml = input->getResult()->getNode("servers"); + m_servers->clearAndDeleteAll(); + for (unsigned int i = 0; i < servers_xml->getNumNodes(); i++) + { + m_servers->push_back(new Server(*servers_xml->getNode(i))); + } + m_last_load_time += Time::getRealTime(); + } + m_info_message = input->getInfo(); //FIXME error message } + void ServersManager::RefreshRequest::callback() + { + ServersManager::acquire()->refresh(this); + ServersManager::release(); + } + // ============================================================================ Server * ServersManager::getQuickPlay() { diff --git a/src/online/servers_manager.hpp b/src/online/servers_manager.hpp index 716f6d4a2..03a5768b8 100644 --- a/src/online/servers_manager.hpp +++ b/src/online/servers_manager.hpp @@ -17,10 +17,12 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef HEADER_SERVERS_MANAGER_HPP -#define HEADER_CURRENT_ONLINE_USER_HPP +#define HEADER_SERVERS_MANAGER_HPP #include "utils/ptr_vector.hpp" #include "online/server.hpp" +#include "http_manager.hpp" + namespace Online { @@ -31,26 +33,43 @@ namespace Online { */ class ServersManager { - private: - ServersManager(); - PtrVector * m_servers; - bool m_not_fetched; - Server * m_joined_server; + public: + enum RequestType + { + RT_REFRESH = 1 + }; + class RefreshRequest : public XMLRequest + { + virtual void callback (); public: - // singleton - static ServersManager* get(); - static void deallocate(); + RefreshRequest() : XMLRequest(RT_REFRESH) {} + }; - void refresh(); - PtrVector * getServers () const { return m_servers; }; - int getNumServers () const { return m_servers->size(); }; - Server * getServer (int index) const { return m_servers->get(index);}; - void sort(bool sort_desc) { m_servers->insertionSort(0, sort_desc); }; - void setJoinedServer(Server * server){ m_joined_server = server;}; - Server * getJoinedServer(){ return m_joined_server;}; - //Returns the best server to join - Server * getQuickPlay(); + private: + ServersManager(); + PtrVector * m_servers; + bool m_not_fetched; + Server * m_joined_server; + irr::core::stringw m_info_message; + float m_last_load_time; + void refresh(const RefreshRequest * input); + + public: + // Singleton + static ServersManager* acquire(); + static void release(); + static void deallocate(); + + RefreshRequest * refreshRequest(); + PtrVector * getServers () const { return m_servers; } + int getNumServers () const { return m_servers->size(); } + Server * getServer (int index) const { return m_servers->get(index); } + void sort(bool sort_desc) { m_servers->insertionSort(0, sort_desc); } + void setJoinedServer(Server * server){ m_joined_server = server; } + Server * getJoinedServer() { return m_joined_server; } + //Returns the best server to join + Server * getQuickPlay(); }; // class ServersManager diff --git a/src/states_screens/networking_lobby.cpp b/src/states_screens/networking_lobby.cpp index dd0c1ba54..16a3ede61 100644 --- a/src/states_screens/networking_lobby.cpp +++ b/src/states_screens/networking_lobby.cpp @@ -46,7 +46,8 @@ DEFINE_SCREEN_SINGLETON( NetworkingLobby ); NetworkingLobby::NetworkingLobby() : Screen("online/lobby.stkgui") { - m_server = ServersManager::get()->getJoinedServer(); + m_server = ServersManager::acquire()->getJoinedServer(); + ServersManager::release(); } // NetworkingLobby // ---------------------------------------------------------------------------- diff --git a/src/states_screens/networking_lobby_settings.cpp b/src/states_screens/networking_lobby_settings.cpp index 9909ff45c..296cdd1d5 100644 --- a/src/states_screens/networking_lobby_settings.cpp +++ b/src/states_screens/networking_lobby_settings.cpp @@ -68,12 +68,6 @@ void NetworkingLobbySettings::loadedFromFile() } // loadedFromFile -// ---------------------------------------------------------------------------- -bool NetworkingLobbySettings::hasLostConnection() -{ - return !CurrentUser::get()->isSignedIn(); -} - // ---------------------------------------------------------------------------- void NetworkingLobbySettings::beforeAddingWidget() { diff --git a/src/states_screens/networking_lobby_settings.hpp b/src/states_screens/networking_lobby_settings.hpp index d27718b12..c478954b6 100644 --- a/src/states_screens/networking_lobby_settings.hpp +++ b/src/states_screens/networking_lobby_settings.hpp @@ -46,8 +46,6 @@ private: GUIEngine::ButtonWidget * m_create_widget; GUIEngine::ButtonWidget * m_cancel_widget; - /** \brief Checks if the user is still signed in. */ - bool hasLostConnection(); /** \brief Sets which widget has to be focused. Depends on the user state. */ void setInitialFocus(); diff --git a/src/states_screens/server_selection.cpp b/src/states_screens/server_selection.cpp index a01983ef3..947a55ab0 100644 --- a/src/states_screens/server_selection.cpp +++ b/src/states_screens/server_selection.cpp @@ -21,13 +21,13 @@ #include #include "guiengine/modaldialog.hpp" -#include "guiengine/widget.hpp" #include "states_screens/dialogs/message_dialog.hpp" #include "states_screens/dialogs/server_info_dialog.hpp" #include "states_screens/state_manager.hpp" #include "utils/translation.hpp" #include "utils/string_utils.hpp" -#include "online/servers_manager.hpp" +#include "online/messages.hpp" +#include "audio/sfx_manager.hpp" using namespace Online; @@ -38,14 +38,34 @@ DEFINE_SCREEN_SINGLETON( ServerSelection ); ServerSelection::ServerSelection() : Screen("online/server_selection.stkgui") { m_selected_index = -1; - m_reload_timer = 0.0f; + m_refresh_request = NULL; + } // ServerSelection +// ---------------------------------------------------------------------------- + +ServerSelection::~ServerSelection() +{ + delete m_refresh_request; +} // ServerSelection + + +// ---------------------------------------------------------------------------- + +void ServerSelection::refresh() +{ + m_refresh_request = ServersManager::acquire()->refreshRequest(); + ServersManager::release(); + m_server_list_widget->clear(); + m_server_list_widget->addItem("spacer", L""); + m_server_list_widget->addItem("loading", Messages::fetchingServers()); +} + + // ---------------------------------------------------------------------------- void ServerSelection::loadedFromFile() { - m_back_widget = getWidget("back"); m_reload_widget = getWidget("reload"); @@ -68,40 +88,24 @@ void ServerSelection::beforeAddingWidget() void ServerSelection::init() { Screen::init(); - m_reloading = false; m_sort_desc = true; m_reload_widget->setActivated(); // Set the default sort order Server::setSortOrder(Server::SO_NAME); - loadList(); + refresh(); } // init -// ---------------------------------------------------------------------------- - -void ServerSelection::unloaded() -{ -} - -// ---------------------------------------------------------------------------- - -void ServerSelection::tearDown() -{ -} - // ---------------------------------------------------------------------------- /** Loads the list of all servers. The gui element will be * updated. * \param type Must be 'kart' or 'track'. */ -void ServerSelection::loadList(bool refresh) +void ServerSelection::loadList() { m_server_list_widget->clear(); - ServersManager * manager = ServersManager::get(); - if (refresh) - manager->refresh(); + ServersManager * manager = ServersManager::acquire(); manager->sort(m_sort_desc); - for(int i=0; i < manager->getNumServers(); i++) { Server * server = manager->getServer(i); @@ -114,7 +118,7 @@ void ServerSelection::loadList(bool refresh) row->push_back(new GUIEngine::ListWidget::ListCell(num_players,-1,1,true)); m_server_list_widget->addItem("server", row); } - + ServersManager::release(); } // loadList // ---------------------------------------------------------------------------- @@ -143,19 +147,14 @@ void ServerSelection::eventCallback( GUIEngine::Widget* widget, else if (name == "reload") { - if (!m_reloading) - { - m_reloading = true; - m_server_list_widget->clear(); - m_server_list_widget->addItem("spacer", L""); - m_server_list_widget->addItem("loading", _("Please wait while the list is being updated.")); - } + refresh(); } else if (name == m_server_list_widget->m_properties[GUIEngine::PROP_ID]) { m_selected_index = m_server_list_widget->getSelectionID(); - new ServerInfoDialog(ServersManager::get()->getServer(m_selected_index)); + new ServerInfoDialog(ServersManager::acquire()->getServer(m_selected_index)); + ServersManager::release(); } } // eventCallback @@ -180,18 +179,26 @@ void ServerSelection::setLastSelected() void ServerSelection::onUpdate(float dt, irr::video::IVideoDriver*) { - m_reload_timer += dt; - if (m_reloading) + if(m_refresh_request != NULL) { - m_reloading = false; - if(m_reload_timer > 5000.0f) + if(m_refresh_request->isDone()) { - loadList(true); - m_reload_timer = 0.0f; + if(m_refresh_request->isSuccess()) + { + loadList(); + } + else + { + sfx_manager->quickSound( "anvil" ); + new MessageDialog(m_refresh_request->getInfo()); + } + delete m_refresh_request; + m_refresh_request = NULL; + //m_options_widget->setActivated(); } else { - loadList(false); + m_server_list_widget->renameItem("loading", Messages::fetchingServers()); } } } // onUpdate diff --git a/src/states_screens/server_selection.hpp b/src/states_screens/server_selection.hpp index ea698da6c..7c603c9b8 100644 --- a/src/states_screens/server_selection.hpp +++ b/src/states_screens/server_selection.hpp @@ -19,10 +19,8 @@ #define HEADER_SERVER_SELECTION_HPP #include "guiengine/screen.hpp" -#include "guiengine/widgets/label_widget.hpp" -#include "guiengine/widgets/ribbon_widget.hpp" -#include "guiengine/widgets/list_widget.hpp" -#include "guiengine/widgets/icon_button_widget.hpp" +#include "guiengine/widgets.hpp" +#include "online/servers_manager.hpp" namespace GUIEngine { class Widget; } @@ -38,6 +36,7 @@ class ServerSelection : public GUIEngine::Screen, private: ServerSelection(); + ~ServerSelection(); GUIEngine::IconButtonWidget * m_back_widget; GUIEngine::IconButtonWidget * m_reload_widget; @@ -51,23 +50,20 @@ private: * addons_loading is being displayed. */ int m_selected_index; - bool m_reloading; - /** \brief To check (and set) if sort order is descending **/ bool m_sort_desc; - float m_reload_timer; + Online::ServersManager::RefreshRequest * m_refresh_request; + void refresh(); public: /** Load the addons into the main list.*/ - void loadList(bool refresh = false); + void loadList(); /** \brief implement callback from parent class GUIEngine::Screen */ virtual void loadedFromFile() OVERRIDE; - virtual void unloaded() OVERRIDE; - /** \brief implement callback from parent class GUIEngine::Screen */ virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID) OVERRIDE; @@ -78,7 +74,6 @@ public: virtual void onColumnClicked(int columnId); virtual void init() OVERRIDE; - virtual void tearDown() OVERRIDE; /** \brief implement callback from parent class GUIEngine::Screen */ virtual void onUpdate(float dt, irr::video::IVideoDriver*) OVERRIDE;