Refactor online namespace. Define api php file names from a single place

This commit is contained in:
Daniel Butum 2014-08-04 18:41:47 +03:00
parent 5511f55dd9
commit b3f9f9f407
30 changed files with 515 additions and 438 deletions

View File

@ -42,8 +42,8 @@ public:
UNLOCK_GP,
UNLOCK_MODE,
UNLOCK_KART,
UNLOCK_DIFFICULTY}
;
UNLOCK_DIFFICULTY
};
// ------------------------------------------------------------------------
class UnlockableFeature
{

View File

@ -156,8 +156,4 @@ public:
} // increaseAchievement
// ------------------------------------------------------------------------
}; // PlayerManager
#endif
/*EOF*/

View File

@ -45,8 +45,7 @@ void GetPeerAddress::asynchronousUpdate()
if (m_state == NONE)
{
m_request = new Online::XMLRequest();
PlayerManager::setUserDetails(m_request, "get",
"address-management.php");
PlayerManager::setUserDetails(m_request, "get", API_ADDRESS_PATH);
m_request->addParameter("peer_id",m_peer_id);
Online::RequestManager::get()->addRequest(m_request);

View File

@ -42,8 +42,7 @@ void HidePublicAddress::asynchronousUpdate()
if (m_state == NONE)
{
m_request = new Online::XMLRequest();
PlayerManager::setUserDetails(m_request, "unset",
"address-management.php");
PlayerManager::setUserDetails(m_request, "unset", API_ADDRESS_PATH);
Online::RequestManager::get()->addRequest(m_request);
m_state = REQUEST_PENDING;

View File

@ -45,7 +45,7 @@ void QuickJoinProtocol::asynchronousUpdate()
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
m_request = new Online::XMLRequest();
PlayerManager::setUserDetails(m_request, "quick-join");
m_request->setServerURL("address-management.php");
m_request->setServerURL(API_ADDRESS_PATH);
Online::RequestManager::get()->addRequest(m_request);
m_state = REQUEST_PENDING;

View File

@ -72,8 +72,7 @@ void RequestConnection::asynchronousUpdate()
case NONE:
{
m_request = new ServerJoinRequest();
PlayerManager::setUserDetails(m_request, "request-connection",
"address-management.php");
PlayerManager::setUserDetails(m_request, "request-connection", API_ADDRESS_PATH);
m_request->addParameter("server_id",m_server_id);
m_request->queue();
m_state = REQUEST_PENDING;

View File

@ -183,8 +183,7 @@ void ServerLobbyRoomProtocol::checkIncomingConnectionRequests()
last_poll_time = StkTime::getRealTime();
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
Online::XMLRequest* request = new Online::XMLRequest();
PlayerManager::setUserDetails(request, "poll-connection-requests",
"address-management.php");
PlayerManager::setUserDetails(request, "poll-connection-requests", API_ADDRESS_PATH);
request->addParameter("address",addr.ip);
request->addParameter("port",addr.port);
@ -564,7 +563,7 @@ void ServerLobbyRoomProtocol::playerMinorVote(Event* event)
* Byte 0 1 5 6 N+6 N+7 N+8
* -----------------------------------------------------------
* Size | 1 | 4 | 1 | N | 1 | 1 |
* Data | 4 | priv token | N | track name | 1 | track number (gp) |
* Data | 4 | priv token | N | track name | 1 | track number (gp) |
* -----------------------------------------------------------
*/
void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
@ -597,7 +596,7 @@ void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
* Byte 0 1 5 6 7 8 9
* ---------------------------------------------------------
* Size | 1 | 4 | 1 | 1 | 1 | 1 |
* Data | 4 | priv token | 1 | reversed | 1 | track number (gp) |
* Data | 4 | priv token | 1 | reversed | 1 | track number (gp) |
* ---------------------------------------------------------
*/
void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
@ -630,7 +629,7 @@ void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
* Byte 0 1 5 6 7 8 9
* -----------------------------------------------------
* Size | 1 | 4 | 1 | 1 | 1 | 1 |
* Data | 4 | priv token | 1 | laps | 1 | track number (gp) |
* Data | 4 | priv token | 1 | laps | 1 | track number (gp) |
* -----------------------------------------------------
*/
void ServerLobbyRoomProtocol::playerLapsVote(Event* event)

View File

@ -43,8 +43,7 @@ void ShowPublicAddress::asynchronousUpdate()
{
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
m_request = new Online::XMLRequest();
PlayerManager::setUserDetails(m_request, "set",
"address-management.php");
PlayerManager::setUserDetails(m_request, "set", API_ADDRESS_PATH);
m_request->addParameter("address",addr.ip);
m_request->addParameter("port",addr.port);
m_request->addParameter("private_port",NetworkManager::getInstance()->getHost()->getPort());

View File

@ -42,8 +42,7 @@ void StartServer::asynchronousUpdate()
{
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
m_request = new Online::XMLRequest();
PlayerManager::setUserDetails(m_request, "start-server",
"address-management.php");
PlayerManager::setUserDetails(m_request, "start-server", API_ADDRESS_PATH);
m_request->addParameter("address",addr.ip);
m_request->addParameter("port",addr.port);
m_request->addParameter("private_port",NetworkManager::getInstance()->getHost()->getPort());

View File

@ -47,8 +47,7 @@ void StopServer::asynchronousUpdate()
{
TransportAddress addr = NetworkManager::getInstance()->getPublicAddress();
m_request = new Online::XMLRequest();
PlayerManager::setUserDetails(m_request, "stop-server",
"address-management.php");
PlayerManager::setUserDetails(m_request, "stop-server", API_ADDRESS_PATH);
m_request->addParameter("address",addr.ip);
m_request->addParameter("port",addr.port);
Log::info("StopServer", "address %u, port %d", addr.ip, addr.port);

View File

@ -26,10 +26,8 @@
#endif
#include <curl/curl.h>
#include <assert.h>
namespace Online
{
/** Creates a HTTP(S) request that will have a raw string as result. (Can
@ -60,7 +58,8 @@ namespace Online
// A http request should not even be created when internet is disabled
assert(UserConfigParams::m_internet_status ==
RequestManager::IPERM_ALLOWED);
assert(filename.size()>0);
assert(filename.size() > 0);
init();
m_filename = file_manager->getAddonsFile(filename);
} // HTTPRequest(filename ...)
@ -76,6 +75,7 @@ namespace Online
// A http request should not even be created when internet is disabled
assert(UserConfigParams::m_internet_status ==
RequestManager::IPERM_ALLOWED);
init();
m_filename = file_manager->getAddonsFile(filename);
} // HTTPRequest(filename ...)
@ -100,20 +100,20 @@ namespace Online
*/
void HTTPRequest::setServerURL(const std::string& path)
{
setURL((std::string)UserConfigParams::m_server_multiplayer+path);
setURL((std::string)UserConfigParams::m_server_multiplayer + path);
} // setServerURL
// ------------------------------------------------------------------------
/** A handy shortcut that appends the given path to the URL of the addons
* server.
* \param path The path to add to the server.
* \param path The path to add to the server, without the trailing slash
*/
void HTTPRequest::setAddonsURL(const std::string& path)
{
setURL((std::string)UserConfigParams::m_server_addons
+ "/" + path);
setURL((std::string)UserConfigParams::m_server_addons + "/" + path);
} // set AddonsURL
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
/** Checks the request if it has enough (correct) information to be
* executed (and thus allowed to add to the queue).
*/
@ -128,7 +128,7 @@ namespace Online
void HTTPRequest::prepareOperation()
{
m_curl_session = curl_easy_init();
if(!m_curl_session)
if (!m_curl_session)
{
Log::error("HTTPRequest::prepareOperation",
"LibCurl session not initialized.");
@ -145,9 +145,9 @@ namespace Online
curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_LIMIT, 10);
curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_TIME, 20);
//curl_easy_setopt(m_curl_session, CURLOPT_VERBOSE, 1L);
if(m_filename.size()==0)
if (m_filename.size() == 0)
{
//https
// https, load certificate info
struct curl_slist *chunk = NULL;
chunk = curl_slist_append(chunk, "Host: api.stkaddons.net");
curl_easy_setopt(m_curl_session, CURLOPT_HTTPHEADER, chunk);
@ -163,15 +163,15 @@ namespace Online
*/
void HTTPRequest::operation()
{
if(!m_curl_session)
if (!m_curl_session)
return;
FILE *fout = NULL;
if(m_filename.size()>0)
if (m_filename.size() > 0)
{
fout = fopen((m_filename+".part").c_str(), "wb");
if(!fout)
if (!fout)
{
Log::error("HTTPRequest",
"Can't open '%s' for writing, ignored.",
@ -190,23 +190,26 @@ namespace Online
}
// All parameters added have a '&' added
if(m_parameters.size()>0)
if (m_parameters.size() > 0)
{
m_parameters.erase(m_parameters.size()-1);
}
if(m_parameters.size()==0)
if (m_parameters.size() == 0)
{
Log::info("HTTPRequest", "Downloading %s", m_url.c_str());
else if (Log::getLogLevel()<=Log::LL_INFO)
}
else if (Log::getLogLevel() <= Log::LL_INFO)
{
// Avoid printing the password or token, just replace them with *s
std::string param = m_parameters;
// List of strings whose values should not be printed. "" is the
// end indicator.
static std::string dont_print[] = { "&password=", "&token=", "&current=",
"&new1=", "&new2=", ""};
unsigned int j = 0;
while (dont_print[j].size()>0)
while (dont_print[j].size() > 0)
{
// Get the string that should be replaced.
std::size_t pos = param.find(dont_print[j]);
@ -221,11 +224,11 @@ namespace Online
} // if string found
j++;
} // while dont_print[j].size()>0
Log::info("HTTPRequest", "Sending %s to %s",
param.c_str(), m_url.c_str());
}
curl_easy_setopt(m_curl_session, CURLOPT_POSTFIELDS,
m_parameters.c_str());
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());
std::string uagent( std::string("SuperTuxKart/") + STK_VERSION );
#ifdef WIN32
uagent += (std::string)" (Windows)";
@ -243,17 +246,18 @@ namespace Online
m_curl_code = curl_easy_perform(m_curl_session);
Request::operation();
if(fout)
if (fout)
{
fclose(fout);
if(m_curl_code==CURLE_OK)
if (m_curl_code == CURLE_OK)
{
if(UserConfigParams::logAddons())
Log::info("HTTPRequest", "Download successful.");
// The behaviour of rename is unspecified if the target
// file should already exist - so remove it.
bool ok = file_manager->removeFile(m_filename);
if(!ok)
if (!ok)
{
Log::error("addons",
"Could not removed existing addons.xml file.");
@ -261,8 +265,9 @@ namespace Online
}
int ret = rename((m_filename+".part").c_str(),
m_filename.c_str() );
// In case of an error, set the status to indicate this
if(ret!=0)
if (ret != 0)
{
Log::error("addons",
"Could not rename downloaded addons.xml file!");
@ -279,10 +284,11 @@ namespace Online
*/
void HTTPRequest::afterOperation()
{
if(m_curl_code == CURLE_OK)
if (m_curl_code == CURLE_OK)
setProgress(1.0f);
else
setProgress(-1.0f);
Request::afterOperation();
curl_easy_cleanup(m_curl_session);
} // afterOperation
@ -322,7 +328,7 @@ 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( (request_manager->getAbort() || request->isCancelled()) &&
if ((request_manager->getAbort() || request->isCancelled()) &&
request->isAbortable() )
{
// Indicates to abort the current download, which means that this
@ -331,23 +337,24 @@ namespace Online
}
float f;
if(download_now < download_total)
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;
if (f >= 1.0f)
f = 0.99f;
}
else
{
// Don't set progress to 1.0f; this is done in afterOperation()
// after checking curls return code!
f= download_total==0 ? 0 : 0.99f;
f = (download_total == 0) ? 0 : 0.99f;
}
request->setProgress(f);
return 0;
} // progressDownload
} // namespace Online

View File

@ -32,6 +32,10 @@
#include <assert.h>
#include <string>
#define API_VERSION "v2"
#define API_USER_PATH "client-user.php"
#define API_ADDRESS_PATH "address-management.php"
namespace Online
{
/** A http request.
@ -78,22 +82,20 @@ namespace Online
void init();
public :
HTTPRequest(bool manage_memory = false,
int priority = 1);
HTTPRequest(const std::string &filename,
bool manage_memory = false,
int priority = 1);
HTTPRequest(const char * const filename,
bool manage_memory = false,
int priority = 1);
virtual ~HTTPRequest() {};
HTTPRequest(bool manage_memory = false, int priority = 1);
HTTPRequest(const std::string &filename, bool manage_memory = false,
int priority = 1);
HTTPRequest(const char * const filename, bool manage_memory = false,
int priority = 1);
virtual ~HTTPRequest() {}
virtual bool isAllowedToAdd() const OVERRIDE;
void setServerURL(const std::string& url);
void setAddonsURL(const std::string& path);
// ------------------------------------------------------------------------
/** Returns true if there was an error downloading the file.
*/
/** Returns true if there was an error downloading the file. */
bool hadDownloadError() const { return m_curl_code!=CURLE_OK; }
// ------------------------------------------------------------------------
/** Returns the curl error message if an error has occurred.
* \pre m_curl_code!=CURLE_OK
@ -116,47 +118,50 @@ namespace Online
} // getData
// --------------------------------------------------------------------
/** Sets a parameter to 'value' (std::string).
*/
/** Sets a parameter to 'value' (std::string). */
void addParameter(const std::string & name, const std::string &value)
{
// Call the template, so that the strings are escaped properly
addParameter(name, value.c_str());
}; // addParameter
} // addParameter
// --------------------------------------------------------------------
/** Sets a parameter to 'value' (stringw).
*/
/** Sets a parameter to 'value' (stringw). */
void addParameter(const std::string & name,
const irr::core::stringw &value)
{
core::stringc s = core::stringc(value.c_str());
// Call the template to escape strings properly
addParameter(name, s.c_str());
} // addParameter
// --------------------------------------------------------------------
/** Sets a parameter to 'value' (arbitrary types).
*/
/** Sets a parameter to 'value' (arbitrary types). */
template <typename T>
void addParameter(const std::string & name, const T& value)
{
assert(isPreparing());
std::string s = StringUtils::toString(value);
char *s1 = curl_easy_escape(m_curl_session, name.c_str(),
name.size() );
char *s1 = curl_easy_escape(m_curl_session, name.c_str(), name.size());
char *s2 = curl_easy_escape(m_curl_session, s.c_str(), s.size());
m_parameters.append(std::string(s1)+"="+s2+"&");
m_parameters.append(std::string(s1) + "=" + s2 + "&");
curl_free(s1);
curl_free(s2);
} // addParameter
// --------------------------------------------------------------------
/** Returns the current progress. */
float getProgress() const { return m_progress.getAtomic(); }
// --------------------------------------------------------------------
/** Sets the current progress. */
void setProgress(float f) { m_progress.setAtomic(f); }
void setProgress(float f) { m_progress.setAtomic(f); }
// --------------------------------------------------------------------
const std::string & getURL() const { assert(isBusy()); return m_url;}
// --------------------------------------------------------------------
/** Sets the URL for this request. */
void setURL(const std::string & url)
@ -166,8 +171,5 @@ namespace Online
} // setURL
}; // class HTTPRequest
} //namespace Online
#endif
#endif // HEADER_HTTP_REQUEST_HPP

View File

@ -16,7 +16,6 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "online/online_player_profile.hpp"
#include "achievements/achievements_manager.hpp"
@ -55,14 +54,18 @@ namespace Online
const std::string &action,
const std::string &php_script) const
{
if (php_script.size()>0)
if (php_script.size() > 0)
{
request->setServerURL(php_script);
else
request->setServerURL("client-user.php");
}
else // default path
{
request->setServerURL(API_USER_PATH);
}
if (m_profile)
request->addParameter("userid", m_profile->getID());
if(m_online_state == OS_SIGNED_IN)
if (m_online_state == OS_SIGNED_IN)
request->addParameter("token", m_token);
if (action.size() > 0)
request->addParameter("action", action);
@ -86,16 +89,17 @@ namespace Online
m_profile = NULL;
} // OnlinePlayerProfile
// ------------------------------------------------------------------------
/** Request a login using the saved credentials of the user.
*/
/** Request a login using the saved credentials of the user. */
void OnlinePlayerProfile::requestSavedSession()
{
SignInRequest * request = NULL;
SignInRequest *request = NULL;
if (m_online_state == OS_SIGNED_OUT && hasSavedSession())
{
request = new SignInRequest(true);
setUserDetails(request, "saved-session");
// The userid must be taken from the saved data,
// setUserDetails takes it from current data.
request->addParameter("userid", getSavedUserId());
@ -117,18 +121,20 @@ namespace Online
// If the player changes the online account, there can be a
// logout stil happening.
assert(m_online_state == OS_SIGNED_OUT ||
m_online_state == OS_SIGNING_OUT );
m_online_state == OS_SIGNING_OUT);
SignInRequest * request = new SignInRequest(false);
// We can't use setUserDetail here, since there is no token yet
request->setServerURL("client-user.php");
request->addParameter("action","connect");
request->addParameter("username",username);
request->addParameter("password",password);
request->setServerURL(API_USER_PATH);
request->addParameter("action", "connect");
request->addParameter("username", username);
request->addParameter("password", password);
request->addParameter("save-session",
rememberPassword() ? "true"
: "false");
request->queue();
m_online_state = OS_SIGNING_IN;
return request;
} // requestSignIn
@ -143,13 +149,13 @@ namespace Online
// If the login is successful, reset any saved session of other
// local players using the same online account (which are now invalid)
if(isSuccess())
if (isSuccess())
{
PlayerProfile *current = PlayerManager::getCurrentPlayer();
for(unsigned int i=0; i<PlayerManager::get()->getNumPlayers(); i++)
for (unsigned int i = 0; i < PlayerManager::get()->getNumPlayers(); i++)
{
PlayerProfile *player = PlayerManager::get()->getPlayer(i);
if(player!=current &&
if(player != current &&
player->hasSavedSession() &&
player->getLastOnlineName() == current->getLastOnlineName())
{
@ -157,7 +163,7 @@ namespace Online
}
}
}
if(login)
if (login)
{
if(isSuccess())
login->loginSuccessful();
@ -178,12 +184,14 @@ namespace Online
{
if (success)
{
int token_fetched = input->get("token", &m_token);
core::stringw username("");
int username_fetched = input->get("username", &username);
uint32_t userid(0);
int token_fetched = input->get("token", &m_token);
int username_fetched = input->get("username", &username);
int userid_fetched = input->get("userid", &userid);
setLastOnlineName(username);
m_profile = new OnlineProfile(userid, username, true);
assert(token_fetched && username_fetched && userid_fetched);
m_online_state = OS_SIGNED_IN;
@ -191,8 +199,10 @@ namespace Online
{
saveSession(getOnlineId(), getToken());
}
ProfileManager::get()->addPersistent(m_profile);
std::string achieved_string("");
// Even if no achievements were sent, we have to call sync
// in order to upload local achievements to the server
input->get("achieved", &achieved_string);
@ -260,6 +270,7 @@ namespace Online
{
GUIEngine::Screen *screen = GUIEngine::getCurrentScreen();
BaseUserScreen *user_screen = dynamic_cast<BaseUserScreen*>(screen);
// We can't do much of error handling here, no screen waits for
// a logout to finish, so we can only log the message to screen,
// and otherwise mark the player logged out internally.
@ -269,20 +280,21 @@ namespace Online
"There were some connection issues while signing out. "
"Report a bug if this caused issues.");
Log::warn("OnlinePlayerProfile::signOut", core::stringc(info.c_str()).c_str());
if(user_screen)
if (user_screen)
user_screen->logoutError(info);
}
else
{
if(user_screen)
if (user_screen)
user_screen->logoutSuccessful();
}
ProfileManager::get()->clearPersistent();
m_profile = NULL;
m_online_state = OS_SIGNED_OUT;
// Discard token if session should not be saved.
if(!rememberPassword())
if (!rememberPassword())
clearSession();
} // signOut
@ -293,6 +305,7 @@ namespace Online
void OnlinePlayerProfile::requestPoll() const
{
assert(m_online_state == OS_SIGNED_IN);
OnlinePlayerProfile::PollRequest * request = new OnlinePlayerProfile::PollRequest();
setUserDetails(request, "poll");
request->queue();
@ -304,127 +317,137 @@ namespace Online
*/
void OnlinePlayerProfile::PollRequest::callback()
{
if(isSuccess())
// connection error
if (!isSuccess())
{
if (!PlayerManager::getCurrentPlayer()->isLoggedIn())
return;
if (PlayerManager::getCurrentPlayer()->getProfile()->hasFetchedFriends())
Log::error("Online Player Profile", "Poll request failed");
return;
}
if (!PlayerManager::getCurrentPlayer()->isLoggedIn())
return;
if (PlayerManager::getCurrentPlayer()->getProfile()->hasFetchedFriends())
{
std::string online_friends_string("");
if (getXMLData()->get("online", &online_friends_string) == 1)
{
std::string online_friends_string("");
if(getXMLData()->get("online", &online_friends_string) == 1)
std::vector<uint32_t> online_friends =
StringUtils::splitToUInt(online_friends_string, ' ');
// flag that indicates if a current online friend went offline
bool went_offline = false;
// iterate over all friends and find out if they come online or not
// filling the notification messages
std::vector<uint32_t> friends =
PlayerManager::getCurrentPlayer()->getProfile()->getFriends();
std::vector<core::stringw> to_notify;
for (unsigned int i = 0; i < friends.size(); ++i)
{
std::vector<uint32_t> online_friends =
StringUtils::splitToUInt(online_friends_string, ' ');
bool went_offline = false;
std::vector<uint32_t> friends =
PlayerManager::getCurrentPlayer()->getProfile()->getFriends();
std::vector<core::stringw> to_notify;
for(unsigned int i = 0; i < friends.size(); ++i)
{
bool now_online = false;
std::vector<uint32_t>::iterator iter =
std::find(online_friends.begin(),
online_friends.end(), friends[i]);
if (iter != online_friends.end())
{
now_online = true;
online_friends.erase(iter);
}
OnlineProfile * profile =
ProfileManager::get()->getProfileByID(friends[i]);
OnlineProfile::RelationInfo * relation_info =
profile->getRelationInfo();
if( relation_info->isOnline() )
{
if (!now_online)
{
relation_info->setOnline(false);
went_offline = true;
}
}
else
{
if (now_online)
{
//User came online
relation_info->setOnline(true);
// Do this because a user might have accepted
// a pending friend request.
profile->setFriend();
to_notify.push_back(profile->getUserName());
}
}
bool now_online = false;
std::vector<uint32_t>::iterator found_friend =
std::find(online_friends.begin(),
online_friends.end(), friends[i]);
if (found_friend != online_friends.end())
{
now_online = true;
online_friends.erase(found_friend);
}
}
OnlineProfile * profile =
ProfileManager::get()->getProfileByID(friends[i]);
OnlineProfile::RelationInfo * relation_info =
profile->getRelationInfo();
if(to_notify.size() > 0)
{
core::stringw message("");
if(to_notify.size() == 1)
{
message = _("%s is now online.", to_notify[0]);
}
else if(to_notify.size() == 2)
{
message = _("%s and %s are now online.",
to_notify[0], to_notify[1] );
}
else if(to_notify.size() == 3)
{
message = _("%s, %s and %s are now online.",
to_notify[0], to_notify[1], to_notify[2]);
}
else if(to_notify.size() > 3)
{
message = _("%d friends are now online.",
to_notify.size());
}
MessageQueue::add(MessageQueue::MT_FRIEND, message);
}
else if(went_offline)
{
OnlineProfileFriends::getInstance()->refreshFriendsList();
}
if (relation_info->isOnline())
{
if (!now_online) // the friend went offline
{
relation_info->setOnline(false);
went_offline = true;
}
}
else
{
if (now_online) // friend came online
{
relation_info->setOnline(true);
// Do this because a user might have accepted
// a pending friend request.
profile->setFriend();
to_notify.push_back(profile->getUserName());
}
}
}
if (to_notify.size() > 0)
{
core::stringw message("");
if(to_notify.size() == 1)
{
message = _("%s is now online.", to_notify[0]);
}
else if(to_notify.size() == 2)
{
message = _("%s and %s are now online.",
to_notify[0], to_notify[1] );
}
else if(to_notify.size() == 3)
{
message = _("%s, %s and %s are now online.",
to_notify[0], to_notify[1], to_notify[2]);
}
else if(to_notify.size() > 3)
{
message = _("%d friends are now online.",
to_notify.size());
}
MessageQueue::add(MessageQueue::MT_FRIEND, message);
}
else if (went_offline)
{
OnlineProfileFriends::getInstance()->refreshFriendsList();
}
}
}
else
{
PlayerManager::getCurrentPlayer()->getProfile()->fetchFriends();
}
int friend_request_count = 0;
for (unsigned int i = 0; i < getXMLData()->getNumNodes(); i++)
{
const XMLNode * node = getXMLData()->getNode(i);
if (node->getName() == "new_friend_request")
{
OnlineProfile::RelationInfo * ri =
new OnlineProfile::RelationInfo("New", false, true, true);
OnlineProfile * p = new OnlineProfile(node);
p->setRelationInfo(ri);
ProfileManager::get()->addPersistent(p);
friend_request_count++;
}
}
if (friend_request_count > 0)
{
core::stringw message("");
if (friend_request_count > 1)
{
message = _("You have %d new friend requests!",
friend_request_count);
}
else
{
PlayerManager::getCurrentPlayer()->getProfile()->fetchFriends();
message = _("You have a new friend request!");
}
int friend_request_count = 0;
for(unsigned int i = 0; i < getXMLData()->getNumNodes(); i++)
{
const XMLNode * node = getXMLData()->getNode(i);
if(node->getName() == "new_friend_request")
{
OnlineProfile::RelationInfo * ri =
new OnlineProfile::RelationInfo("New", false, true, true);
OnlineProfile * p = new OnlineProfile(node);
p->setRelationInfo(ri);
ProfileManager::get()->addPersistent(p);
friend_request_count++;
}
}
if(friend_request_count > 0)
{
core::stringw message("");
if(friend_request_count > 1)
{
message = _("You have %d new friend requests!",
friend_request_count);
}
else
{
message = _("You have a new friend request!");
}
MessageQueue::add(MessageQueue::MT_FRIEND, message);
OnlineProfileFriends::getInstance()->refreshFriendsList();
}
MessageQueue::add(MessageQueue::MT_FRIEND, message);
OnlineProfileFriends::getInstance()->refreshFriendsList();
}
// FIXME show connection error??
// Perhaps show something after 2 misses.
} // PollRequest::callback
// ------------------------------------------------------------------------
@ -432,11 +455,12 @@ namespace Online
*/
uint32_t OnlinePlayerProfile::getOnlineId() const
{
if((m_online_state == OS_SIGNED_IN ))
if (m_online_state == OS_SIGNED_IN)
{
assert(m_profile != NULL);
return m_profile->getID();
}
return 0;
} // getOnlineId

View File

@ -37,7 +37,6 @@ class PlayerManager;
namespace Online
{
class OnlineProfile;
// ============================================================================
@ -48,75 +47,73 @@ namespace Online
*/
class OnlinePlayerProfile : public PlayerProfile
{
public:
// ----------------------------------------------------------------
class SignInRequest : public XMLRequest
{
virtual void callback ();
public:
// ----------------------------------------------------------------
class SignInRequest : public XMLRequest
{
virtual void callback ();
public:
SignInRequest(bool manage_memory = false)
: XMLRequest(manage_memory, /*priority*/10) {}
}; // SignInRequest
// ----------------------------------------------------------------
class PollRequest : public XMLRequest {
virtual void callback ();
public:
PollRequest() : XMLRequest(true) {}
}; // PollRequest
private:
std::string m_token;
OnlineProfile *m_profile;
/** The state of the player (logged in, logging in, ...) */
PlayerProfile::OnlineState m_online_state;
virtual void signIn(bool success, const XMLNode * input);
virtual void signOut(bool success, const XMLNode * input,
const irr::core::stringw &info);
virtual uint32_t getOnlineId() const;
virtual void setUserDetails(Online::HTTPRequest *request,
const std::string &action,
const std::string &php_script = "") const;
virtual void requestPoll() const;
// ----------------------------------------------------------------
/** Returns if this user is logged in. */
virtual bool isLoggedIn() const
{
return m_online_state == PlayerProfile::OS_SIGNED_IN;
} // isLoggedIn
// ----------------------------------------------------------------
/** The online state of the player (i.e. logged out, logging in,
* logged in, ...). */
PlayerProfile::OnlineState getOnlineState() const
{
return m_online_state;
} // getOnlineState
// ----------------------------------------------------------------
/** Returns a pointer to the profile associated with the current
* user. */
OnlineProfile* getProfile() const { return m_profile; }
// ----------------------------------------------------------------
/** Returns the session token of the signed in user. */
const std::string& getToken() const { return m_token; }
virtual void requestSavedSession();
virtual void requestSignOut();
virtual SignInRequest *requestSignIn(const irr::core::stringw &username,
const irr::core::stringw &password);
SignInRequest(bool manage_memory = false)
: XMLRequest(manage_memory, /*priority*/10) {}
}; // SignInRequest
// ----------------------------------------------------------------
class PollRequest : public XMLRequest
{
virtual void callback ();
public:
OnlinePlayerProfile(const XMLNode *player);
OnlinePlayerProfile(const core::stringw &name, bool is_guest = false);
virtual ~OnlinePlayerProfile() {};
// ----------------------------------------------------------------
PollRequest() : XMLRequest(true) {}
}; // PollRequest
}; // class OnlinePlayerProfile
private:
std::string m_token;
OnlineProfile *m_profile;
/** The state of the player (logged in, logging in, ...) */
PlayerProfile::OnlineState m_online_state;
virtual void signIn(bool success, const XMLNode * input);
virtual void signOut(bool success, const XMLNode * input,
const irr::core::stringw &info);
virtual uint32_t getOnlineId() const;
virtual void setUserDetails(Online::HTTPRequest *request,
const std::string &action,
const std::string &php_script = "") const;
virtual void requestPoll() const;
// ----------------------------------------------------------------
/** Returns if this user is logged in. */
virtual bool isLoggedIn() const
{
return m_online_state == PlayerProfile::OS_SIGNED_IN;
} // isLoggedIn
// ----------------------------------------------------------------
/** The online state of the player (i.e. logged out, logging in,
* logged in, ...). */
PlayerProfile::OnlineState getOnlineState() const
{
return m_online_state;
} // getOnlineState
// ----------------------------------------------------------------
/** Returns a pointer to the profile associated with the current user. */
OnlineProfile* getProfile() const { return m_profile; }
// ----------------------------------------------------------------
/** Returns the session token of the signed in user. */
const std::string& getToken() const { return m_token; }
virtual void requestSavedSession();
virtual void requestSignOut();
virtual SignInRequest *requestSignIn(const irr::core::stringw &username,
const irr::core::stringw &password);
public:
OnlinePlayerProfile(const XMLNode *player);
OnlinePlayerProfile(const core::stringw &name, bool is_guest = false);
virtual ~OnlinePlayerProfile() {}
// ----------------------------------------------------------------
}; // class OnlinePlayerProfile
} // namespace Online
#endif
/*EOF*/
#endif // HEADER_CURRENT_ONLINE_USER_HPP

View File

@ -16,7 +16,6 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "online/online_profile.hpp"
#include "config/player_manager.hpp"
@ -39,10 +38,10 @@ OnlineProfile::RelationInfo::RelationInfo(const irr::core::stringw & date,
bool is_online, bool is_pending,
bool is_asker)
{
m_date = date;
m_is_online = is_online;
m_is_pending = is_pending;
m_is_asker = is_asker;
m_date = date;
m_is_online = is_online;
m_is_pending = is_pending;
m_is_asker = is_asker;
} // RelationInfo::RelationInfo
// ----------------------------------------------------------------------------
@ -91,12 +90,11 @@ OnlineProfile::OnlineProfile(const XMLNode * xml, ConstructorType type)
if (type == C_RELATION_INFO)
{
irr::core::stringw date("");
bool is_pending = false, is_asker = false, is_online = false;
xml->get("date", &date);
std::string is_pending_string("");
bool is_pending = false;
xml->get("is_pending", &is_pending);
bool is_asker = false;
bool is_online = false;
if (is_pending)
{
xml->get("is_asker", &is_asker);
@ -113,7 +111,7 @@ OnlineProfile::OnlineProfile(const XMLNode * xml, ConstructorType type)
xml->get("id", &m_id );
xml->get("user_name", &m_username);
m_is_current_user = (m_id == PlayerManager::getCurrentOnlineId());
m_is_current_user = (m_id == PlayerManager::getCurrentOnlineId());
m_state = S_READY;
} // OnlineProfile(XMLNode)
@ -133,6 +131,7 @@ void OnlineProfile::fetchAchievements()
assert(PlayerManager::isCurrentLoggedIn());
if (m_has_fetched_achievements || m_is_current_user)
return;
m_state = S_FETCHING;
// ------------------------------------------------------------------------
@ -187,6 +186,7 @@ void OnlineProfile::fetchFriends()
assert(PlayerManager::isCurrentLoggedIn());
if (m_has_fetched_friends)
return;
m_state = S_FETCHING;
// ------------------------------------------------------------------------
@ -258,9 +258,11 @@ void OnlineProfile::removeFriend(const uint32_t id)
break;
}
else
{
++iter;
}
} // removeFriend
}
} // for friend in friends
} // removeFriend
// ----------------------------------------------------------------------------
/** Adds a friend to the friend list.
@ -269,9 +271,14 @@ void OnlineProfile::removeFriend(const uint32_t id)
void OnlineProfile::addFriend(const uint32_t id)
{
assert(m_has_fetched_friends);
// find if friend id is is already in the user list
for (unsigned int i = 0; i < m_friends.size(); i++)
if (m_friends[i] == id)
return;
{
if (m_friends[i] == id)
return;
}
m_friends.push_back(id);
} // addFriend
@ -310,18 +317,25 @@ const OnlineProfile::IDList& OnlineProfile::getAchievements()
void OnlineProfile::merge(OnlineProfile *profile)
{
assert(profile != NULL);
if (!this->m_has_fetched_friends && profile->m_has_fetched_friends)
this->m_friends = profile->m_friends;
if (!this->m_has_fetched_achievements && profile->m_has_fetched_achievements)
this->m_achievements = profile->m_achievements;
if (this->m_relation_info == NULL && profile->m_relation_info != NULL)
// profile has fetched friends, use that instead
if (!m_has_fetched_friends && profile->m_has_fetched_friends)
m_friends = profile->m_friends;
// profile has fetched achievements, use that instead
if (!m_has_fetched_achievements && profile->m_has_fetched_achievements)
m_achievements = profile->m_achievements;
// current relation is not set, use the profile one
if (m_relation_info == NULL && profile->m_relation_info != NULL)
{
this->m_relation_info = profile->m_relation_info;
m_relation_info = profile->m_relation_info;
// We don't want the destructor of the profile instance to destroy
// the relation info
profile->m_relation_info = NULL;
}
delete profile;
} // merge
delete profile;
} // merge
} // namespace Online

View File

@ -24,9 +24,7 @@
#include "utils/types.hpp"
#include "utils/ptr_vector.hpp"
#include <irrString.h>
#include <string>
namespace Online
@ -54,16 +52,21 @@ public:
bool m_is_pending;
bool m_is_asker;
irr::core::stringw m_date;
public:
RelationInfo(const irr::core::stringw & date, bool is_online,
bool is_pending, bool is_asker = false);
void setOnline(bool online);
// --------------------------------------------------------------------
bool isPending() const { return m_is_pending; }
// --------------------------------------------------------------------
bool isAsker() const { return m_is_asker; }
// --------------------------------------------------------------------
const irr::core::stringw & getDate() const { return m_date; }
// --------------------------------------------------------------------
bool isOnline() const { return m_is_online; }
}; // class RelationInfo
@ -104,12 +107,11 @@ private:
void storeAchievements(const XMLNode * input);
public:
OnlineProfile(const uint32_t & userid,
const irr::core::stringw & username,
bool is_current_user = false );
OnlineProfile(const XMLNode * xml,
ConstructorType type = C_DEFAULT);
~OnlineProfile();
OnlineProfile(const uint32_t & userid,
const irr::core::stringw & username,
bool is_current_user = false );
OnlineProfile(const XMLNode * xml, ConstructorType type = C_DEFAULT);
~OnlineProfile();
void fetchFriends();
const IDList& getFriends();
void fetchAchievements();
@ -118,49 +120,55 @@ public:
void deleteRelationalInfo();
const IDList& getAchievements();
void merge(OnlineProfile * profile);
// ------------------------------------------------------------------------
/** Returns true if the achievements for this profile have been fetched. */
bool hasFetchedAchievements() const { return m_has_fetched_achievements; }
// ------------------------------------------------------------------------
/** Returns true if the friend list for this profile has been fetched. */
bool hasFetchedFriends() const { return m_has_fetched_friends; }
// ------------------------------------------------------------------------
/** True if the profile is not fetching data atm. */
bool isReady() const { return m_state == S_READY; }
// ------------------------------------------------------------------------
/** Returns true if this item is the current user. */
bool isCurrentUser() const { return m_is_current_user; }
// ------------------------------------------------------------------------
bool isFriend() const { return m_is_friend; }
// ------------------------------------------------------------------------
void setFriend() { m_is_friend = true; }
// ------------------------------------------------------------------------
RelationInfo* getRelationInfo() { return m_relation_info; }
// ------------------------------------------------------------------------
void setRelationInfo(RelationInfo * r)
{
delete m_relation_info; m_relation_info = r;
} // setRelationInfo
// ------------------------------------------------------------------------
/** Sets the cache bit of this profile. Used by the cache eviction
* algorithm. */
void setCacheBit(bool cache_bit) { m_cache_bit = cache_bit; }
// ------------------------------------------------------------------------
/** Returns the cache bit for this profile. Used by the cache eviction
* algorithm. */
bool getCacheBit() const { return m_cache_bit; }
// ------------------------------------------------------------------------
/** Returns the online id of this profile. */
uint32_t getID() const { return m_id; }
// ------------------------------------------------------------------------
/** Returns the user name of this profile. */
const irr::core::stringw& getUserName() const { return m_username; }
// ------------------------------------------------------------------------
}; // class OnlineProfile
} // namespace Online
#endif
/*EOF*/
#endif // HEADER_ONLINE_PROFILE_HPP

View File

@ -16,7 +16,6 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "online/profile_manager.hpp"
#include "online/online_profile.hpp"
@ -50,7 +49,8 @@ ProfileManager::~ProfileManager()
{
clearPersistent();
ProfilesMap::iterator it;
for (it = m_profiles_cache.begin(); it != m_profiles_cache.end(); ++it) {
for (it = m_profiles_cache.begin(); it != m_profiles_cache.end(); ++it)
{
delete it->second;
}
} // ~ProfileManager
@ -72,8 +72,8 @@ int ProfileManager::guaranteeCacheSize(unsigned int min_num)
min_num = 100;
m_max_cache_size = min_num;
}
return m_max_cache_size;
return m_max_cache_size;
} // guaranteeCacheSize
// ------------------------------------------------------------------------
@ -88,7 +88,8 @@ OnlineProfile* ProfileManager::getProfileByID(const uint32_t id)
return m_profiles_persistent[id];
if (isInCache(id))
return m_profiles_cache[id];
//FIXME not able to get! Now this should actually fetch the info from the
// FIXME not able to get! Now this should actually fetch the info from the
// server, but I haven't come up with a good asynchronous idea yet.
return NULL;
} // getProfileByID
@ -135,12 +136,14 @@ void ProfileManager::addDirectToCache(OnlineProfile* profile)
break;
}
else
{
++iter;
}
}
} // for profile in cache
}
m_profiles_cache[profile->getID()] = profile;
assert(m_profiles_cache.size() <= m_max_cache_size);
} // addDirectToCache
// ------------------------------------------------------------------------
@ -155,6 +158,7 @@ bool ProfileManager::isInCache(const uint32_t id)
updateCacheBits(i->second);
return true;
}
return false;
} // isInCache
@ -180,6 +184,7 @@ void ProfileManager::updateCacheBits(OnlineProfile * profile)
if (!iter->second->getCacheBit())
return;
}
// All cache bits are set! Set them all to zero except the one
// currently being visited
for (iter = m_profiles_cache.begin();
@ -189,7 +194,6 @@ void ProfileManager::updateCacheBits(OnlineProfile * profile)
}
profile->setCacheBit(true);
}
} // updateCacheBits
// ------------------------------------------------------------------------
@ -232,11 +236,14 @@ void ProfileManager::deleteFromPersistent(const uint32_t id)
m_profiles_persistent.erase(id);
}
else
{
Log::warn("ProfileManager",
"Tried to remove profile with id %d from persistent while "
"not present", id);
}
} // deleteFromPersistent
// ------------------------------------------------------------------------
/** Deletes all persistent profiles.
*/
@ -265,10 +272,11 @@ void ProfileManager::moveToCache(const uint32_t id)
addToCache(profile);
}
else
{
Log::warn("ProfileManager",
"Tried to move profile with id %d from persistent to "
"cache while not present", id);
}
} // moveToCache
} // namespace Online

View File

@ -29,7 +29,6 @@
namespace Online
{
class OnlineProfile;
/** Class that manages all online profiles. Profiles are used for storing
@ -81,6 +80,7 @@ public:
assert(!m_profile_manager);
m_profile_manager = new ProfileManager();
} // create
// ----------------------------------------------------------------
/** Returns the singleton.
* \pre create has been called to create the singleton.
@ -109,6 +109,7 @@ public:
bool isInCache(const uint32_t id);
bool inPersistent(const uint32_t id);
OnlineProfile* getProfileByID(const uint32_t id);
// ----------------------------------------------------------------
/** Marks a given profile to be the currently visited one. This
* is used to mark the profiles that ave its data display (e.g.
@ -117,15 +118,12 @@ public:
{
m_currently_visiting = getProfileByID(id);
} // setVisiting
// ----------------------------------------------------------------
/** \return the instance of the profile that's currently being
* visited */
OnlineProfile* getVisitingProfile() { return m_currently_visiting; }
}; // class CurrentUser
} // namespace Online
#endif
/*EOF*/
#endif // HEADER_ONLINE_PROFILE_MANAGER_HPP

View File

@ -25,10 +25,8 @@
#include <assert.h>
namespace Online
{
// ========================================================================
/**
* Creates a request that can be handled by the RequestManager
@ -67,6 +65,7 @@ namespace Online
setExecuted();
afterOperation();
} // execute
// ------------------------------------------------------------------------
/** Executes the request now, i.e. in the main thread and without involving
* the manager thread.. This calles prepareOperation, operation, and
@ -81,5 +80,4 @@ namespace Online
setDone();
} // executeNow
} // namespace Online

View File

@ -35,7 +35,6 @@
namespace Online
{
/** Stores a request for the HTTP Manager. They will be sorted by
* prioritiy. Requests have four different states they can be in, and
* this state determines which thread can access it. This allows
@ -119,9 +118,11 @@ namespace Online
/** The actual operation to be executed. Empty as default, which
* allows to create a 'quit' request without any additional code. */
virtual void operation() {}
// --------------------------------------------------------------------
/** Virtual function to be called before an operation. */
virtual void prepareOperation() {}
// --------------------------------------------------------------------
/** Virtual function to be called after an operation. */
virtual void afterOperation() {}
@ -132,71 +133,87 @@ namespace Online
RT_QUIT = 1
};
Request(bool manage_memory, int priority, int type);
Request(bool manage_memory, int priority, int type);
virtual ~Request() {}
void execute();
void executeNow();
void queue();
// --------------------------------------------------------------------
/** Executed when a request has finished. */
virtual void callback() {}
// --------------------------------------------------------------------
/** Returns the type of the request. */
int getType() const { return m_type; }
// --------------------------------------------------------------------
/** 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; }
// --------------------------------------------------------------------
/** Sets the memory management flag of this request. This function
* must only be called by the main thread, since it is only tested by
* the main thread. */
void setManageMemory(bool m) { m_manage_memory = m; }
// --------------------------------------------------------------------
/** Returns the priority of this request. */
int getPriority() const { return m_priority; }
// --------------------------------------------------------------------
/** Signals that this request should be canceled. */
void cancel() { m_cancel.setAtomic(true); }
// --------------------------------------------------------------------
/** Returns if this request is to be canceled. */
bool isCancelled() const { return m_cancel.getAtomic(); }
// --------------------------------------------------------------------
/** Returns if this request can be aborted. */
bool isAbortable() const { return m_is_abortable.getAtomic(); }
// --------------------------------------------------------------------
/** Sets if this request is abortable or not. */
void setAbortable(bool b) { m_is_abortable.setAtomic(b); }
// --------------------------------------------------------------------
/** Sets the request state to busy. */
void setBusy()
{
assert(m_state.getAtomic()==S_PREPARING);
assert(m_state.getAtomic() == S_PREPARING);
m_state.setAtomic(S_BUSY);
} // setBusy
// --------------------------------------------------------------------
/** Sets the request to be completed. */
void setExecuted()
{
assert(m_state.getAtomic()==S_BUSY);
assert(m_state.getAtomic() == S_BUSY);
m_state.setAtomic(S_EXECUTED);
} // setExecuted
// --------------------------------------------------------------------
/** Should only be called by the manager */
void setDone()
{
assert(m_state.getAtomic()==S_EXECUTED);
assert(m_state.getAtomic() == S_EXECUTED);
m_state.setAtomic(S_DONE);
} // setDone
// --------------------------------------------------------------------
/** Returns if this request is done. */
bool isDone() const { return m_state.getAtomic() == S_DONE; }
// --------------------------------------------------------------------
/** Returns if this request is being prepared. */
bool isPreparing() const { return m_state.getAtomic() == S_PREPARING; }
// --------------------------------------------------------------------
/** Returns if this request is busy. */
bool isBusy() const { return m_state.getAtomic() == S_BUSY; }
// --------------------------------------------------------------------
/** Checks if the request has completed or done (i.e. callbacks were
* executed).
@ -204,8 +221,9 @@ namespace Online
bool hasBeenExecuted() const
{
State s = m_state.getAtomic();
return s==S_EXECUTED || s==S_DONE;
return s == S_EXECUTED || s == S_DONE;
} // hasBeenExecuted
// --------------------------------------------------------------------
/** Virtual method to check if a request has initialized all needed
* members to a valid value. */
@ -226,9 +244,5 @@ namespace Online
}
}; // class Compare
}; // class Request
} //namespace Online
#endif
#endif // HEADER_ONLINE_REQUEST_HPP

View File

@ -111,6 +111,7 @@ namespace Online
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);
@ -118,7 +119,7 @@ namespace Online
m_thread_id.setAtomic(new pthread_t());
int error = pthread_create(m_thread_id.getData(), &attr,
&RequestManager::mainLoop, this);
if(error)
if (error)
{
m_thread_id.lock();
delete m_thread_id.getData();
@ -128,10 +129,11 @@ namespace Online
errno);
}
pthread_attr_destroy(&attr);
// In case that login id was not saved (or first start of stk),
// current player would not be defined at this stage.
PlayerProfile *player = PlayerManager::getCurrentPlayer();
if(player && player->wasOnlineLastTime() &&
if (player && player->wasOnlineLastTime() &&
!UserConfigParams::m_always_show_login_screen)
{
PlayerManager::resumeSavedSession();
@ -178,6 +180,7 @@ namespace Online
request->setBusy();
m_request_queue.lock();
m_request_queue.getData().push(request);
// Wake up the network http thread
pthread_cond_signal(&m_cond_request);
m_request_queue.unlock();
@ -197,27 +200,30 @@ namespace Online
me->m_current_request = NULL;
me->m_request_queue.lock();
while( me->m_request_queue.getData().empty() ||
while (me->m_request_queue.getData().empty() ||
me->m_request_queue.getData().top()->getType() != Request::RT_QUIT)
{
bool empty = me->m_request_queue.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)
while (empty)
{
pthread_cond_wait(&me->m_cond_request, me->m_request_queue.getMutex());
empty = me->m_request_queue.getData().empty();
}
me->m_current_request = me->m_request_queue.getData().top();
me->m_request_queue.getData().pop();
if(me->m_current_request->getType()==Request::RT_QUIT)
if (me->m_current_request->getType() == Request::RT_QUIT)
break;
me->m_request_queue.unlock();
me->m_current_request->execute();
me->addResult(me->m_current_request);
me->m_request_queue.lock();
} // while
} // while handle all requests
// Signal that the request manager can now be deleted.
// We signal this even before cleaning up memory, since there's no
@ -225,16 +231,18 @@ namespace Online
me->setCanBeDeleted();
// At this stage we have the lock for m_request_queue
while(!me->m_request_queue.getData().empty())
while (!me->m_request_queue.getData().empty())
{
Online::Request * request = me->m_request_queue.getData().top();
Online::Request *request = me->m_request_queue.getData().top();
me->m_request_queue.getData().pop();
// Manage memory can be ignored here, all requests
// need to be freed.
delete request;
}
me->m_request_queue.unlock();
pthread_exit(NULL);
return 0;
} // mainLoop
@ -259,13 +267,13 @@ namespace Online
{
Request * request = NULL;
m_result_queue.lock();
if(!m_result_queue.getData().empty())
if (!m_result_queue.getData().empty())
{
request = m_result_queue.getData().front();
m_result_queue.getData().pop();
}
m_result_queue.unlock();
if(request != NULL)
if (request != NULL)
{
request->callback();
if(request->manageMemory())
@ -298,7 +306,8 @@ namespace Online
float interval = GAME_POLLING_INTERVAL;
if (StateManager::get()->getGameState() == GUIEngine::MENU)
interval = MENU_POLLING_INTERVAL;
if(m_time_since_poll > interval)
if (m_time_since_poll > interval)
{
m_time_since_poll = 0;
PlayerManager::requestOnlinePoll();
@ -306,7 +315,3 @@ namespace Online
} // update
} // namespace Online

View File

@ -39,10 +39,8 @@
#include <queue>
#include <pthread.h>
namespace Online
{
/** A class to execute requests in a separate thread. Typically the
* requests involve a http(s) requests to be sent to the stk server, and
* receive an answer (e.g. to sign in; or to download an addon). The
@ -86,11 +84,14 @@ namespace Online
* 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 };
enum InternetPermission
{
IPERM_NOT_ASKED = 0,
IPERM_ALLOWED = 1,
IPERM_NOT_ALLOWED = 2
};
protected:
/** Time passed since the last poll request. */
float m_time_since_poll;
/** The current requested being worked on. */
@ -119,7 +120,7 @@ namespace Online
void addResult(Online::Request *request);
void handleResultQueue();
static void *mainLoop(void *obj);
static void *mainLoop(void *obj);
RequestManager(); //const std::string &url
~RequestManager();
@ -136,12 +137,9 @@ namespace Online
void startNetworkThread();
void stopNetworkThread();
bool getAbort(){ return m_abort.getAtomic(); };
bool getAbort(){ return m_abort.getAtomic(); }
void update(float dt);
}; //class RequestManager
} // namespace Online
#endif // request_manager_HPP
/*EOF*/

View File

@ -24,12 +24,14 @@
#include "utils/constants.hpp"
#include "utils/string_utils.hpp"
namespace Online{
Server::SortOrder Server::m_sort_order=Server::SO_NAME; //FIXME change to some other default
namespace Online
{
Server::SortOrder Server::m_sort_order = Server::SO_NAME;
Server::Server(const XMLNode & xml)
{
assert(xml.getName() == "server");
m_name = "";
m_satisfaction_score = 0;
m_server_id = 0;
@ -45,7 +47,7 @@ namespace Online{
xml.get("max_players", &m_max_players);
xml.get("current_players", &m_current_players);
}; // Server(const XML&)
} // Server(const XML&)
// ----------------------------------------------------------------------------
/**

View File

@ -31,7 +31,8 @@
class XMLNode;
namespace Online{
namespace Online
{
/**
* \ingroup online
*/
@ -40,54 +41,64 @@ namespace Online{
public:
/** Set the sort order used in the comparison function. */
enum SortOrder { SO_SCORE = 1, // Sorted on satisfaction score
SO_NAME = 2, // Sorted alphabetically by name
SO_PLAYERS = 4
enum SortOrder
{
SO_SCORE = 1, // Sorted on satisfaction score
SO_NAME = 2, // Sorted alphabetically by name
SO_PLAYERS = 4
};
protected:
/** The name to be displayed. */
/** The server name to be displayed. */
irr::core::stringw m_name;
std::string m_lower_case_name; //Used for comparison
std::string m_lower_case_name; // Used for comparison
uint32_t m_server_id;
uint32_t m_host_id;
/** The maximum number of players that the server supports */
int m_max_players;
/** The number of players currently on the server */
int m_current_players;
/** The score/rating given */
float m_satisfaction_score;
/** The sort order to be used in the comparison. */
static SortOrder m_sort_order;
Server() {};
Server() {}
public:
/** Initialises the object from an XML node. */
Server(const XMLNode & xml);
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
/** Sets the sort order used in the comparison function. It is static, so
* that each instance can access the sort order. */
static void setSortOrder(SortOrder so) { m_sort_order = so; }
// ------------------------------------------------------------------------
/** Returns the name of the server. */
const irr::core::stringw& getName() const { return m_name; }
const std::string & getLowerCaseName() const { return m_lower_case_name; }
// ------------------------------------------------------------------------
const float getScore() const { return m_satisfaction_score; }
// ------------------------------------------------------------------------
/** Returns the ID of this server. */
const uint32_t getServerId() const { return m_server_id; }
const uint32_t getHostId() const { return m_host_id; }
const int getMaxPlayers() const { return m_max_players; }
const int getCurrentPlayers() const { return m_current_players; }
// ------------------------------------------------------------------------
bool filterByWords(const irr::core::stringw words) const;
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
/** Compares two servers according to the sort order currently defined.
* \param a The addon to compare this addon to.
*/
@ -106,10 +117,10 @@ namespace Online{
return m_current_players < server.getCurrentPlayers();
break;
} // switch
return true;
} // operator<
}; // Server
} // namespace Online
#endif
#endif // HEADER_SERVER_HPP

View File

@ -16,7 +16,6 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "online/servers_manager.hpp"
#include <string>
@ -28,14 +27,15 @@
#define SERVER_REFRESH_INTERVAL 5.0f
namespace Online{
namespace Online
{
static ServersManager* manager_singleton(NULL);
ServersManager* ServersManager::get()
{
if (manager_singleton == NULL)
manager_singleton = new ServersManager();
return manager_singleton;
}
@ -46,12 +46,14 @@ namespace Online{
} // deallocate
// ============================================================================
ServersManager::ServersManager(){
ServersManager::ServersManager()
{
m_last_load_time.setAtomic(0.0f);
m_joined_server.setAtomic(NULL);
}
ServersManager::~ServersManager(){
ServersManager::~ServersManager()
{
cleanUpServers();
MutexLocker(m_joined_server);
delete m_joined_server.getData();
@ -75,27 +77,31 @@ namespace Online{
if(StkTime::getRealTime() - m_last_load_time.getAtomic() > SERVER_REFRESH_INTERVAL)
{
request = new RefreshRequest();
request->setServerURL("client-user.php");
request->addParameter("action","get_server_list");
request->setServerURL(API_USER_PATH);
request->addParameter("action", "get_server_list");
if (request_now)
RequestManager::get()->addRequest(request);
}
return request;
}
void ServersManager::refresh(bool success, const XMLNode * input)
{
if (success)
if (!success)
{
const XMLNode * servers_xml = input->getNode("servers");
cleanUpServers();
for (unsigned int i = 0; i < servers_xml->getNumNodes(); i++)
{
addServer(new Server(*servers_xml->getNode(i)));
}
m_last_load_time.setAtomic((float)StkTime::getRealTime());
Log::error("Server Manager", "Could not refresh server list");
return;
}
//FIXME error message
const XMLNode * servers_xml = input->getNode("servers");
cleanUpServers();
for (unsigned int i = 0; i < servers_xml->getNumNodes(); i++)
{
addServer(new Server(*servers_xml->getNode(i)));
}
m_last_load_time.setAtomic((float)StkTime::getRealTime());
}
void ServersManager::RefreshRequest::callback()
@ -117,7 +123,8 @@ namespace Online{
{
MutexLocker(m_joined_server);
delete m_joined_server.getData();
//It's a copy!
// It's a copy!
m_joined_server.getData() = new Server(*getServerByID(id));
}
@ -135,6 +142,7 @@ namespace Online{
m_sorted_servers.lock();
m_sorted_servers.getData().push_back(server);
m_sorted_servers.unlock();
m_mapped_servers.lock();
m_mapped_servers.getData()[server->getServerId()] = server;
m_mapped_servers.unlock();
@ -168,7 +176,8 @@ namespace Online{
}
// ============================================================================
void ServersManager::sort(bool sort_desc){
void ServersManager::sort(bool sort_desc)
{
MutexLocker(m_sorted_servers);
m_sorted_servers.getData().insertionSort(0, sort_desc);
}

View File

@ -26,11 +26,8 @@
#include "online/xml_request.hpp"
#include "utils/synchronised.hpp"
namespace Online {
namespace Online
{
/**
* \brief
* \ingroup online
@ -51,8 +48,10 @@ namespace Online {
~ServersManager();
/** Sorted vector of servers */
Synchronised<PtrVector<Server> > m_sorted_servers;
/** Maps server id's to the same servers*/
Synchronised<std::map<uint32_t, Server*> > m_mapped_servers;
/** This is a pointer to a copy of the server, the moment it got joined */
Synchronised<Server *> m_joined_server;
@ -74,14 +73,10 @@ namespace Online {
const Server * getServerBySort (int index) const;
void sort(bool sort_desc);
Server * getJoinedServer() const;
//Returns the best server to join
// Returns the best server to join
const Server * getQuickPlay() const;
}; // class ServersManager
} // namespace Online
#endif
/*EOF*/
#endif // HEADER_SERVERS_MANAGER_HPP

View File

@ -24,15 +24,12 @@
#ifdef WIN32
# include <winsock2.h>
#endif
#include <curl/curl.h>
#include <assert.h>
namespace Online
{
/** Creates a HTTP(S) request that will automatically parse the answer into
* a XML structure.
* \param manage_memory whether or not the RequestManager should take care of
@ -61,22 +58,26 @@ namespace Online
void XMLRequest::afterOperation()
{
m_xml_data = file_manager->createXMLTreeFromString(getData());
if(hadDownloadError())
if (hadDownloadError())
{
Log::error("XMLRequest::afterOperation",
"curl_easy_perform() failed: %s",
getDownloadErrorMessage());
}
m_success = false;
std::string rec_success;
if(m_xml_data->get("success", &rec_success))
if (m_xml_data->get("success", &rec_success))
{
m_success = rec_success =="yes";
m_success = (rec_success == "yes");
m_xml_data->get("info", &m_info);
}
else
{
m_info = _("Unable to connect to the server. Check your internet "
"connection or try again later.");
}
HTTPRequest::afterOperation();
} // afterOperation
} // namespace Online

View File

@ -53,7 +53,7 @@ namespace Online
virtual void afterOperation() OVERRIDE;
public :
XMLRequest(bool manage_memory = false, int priority = 1);
XMLRequest(bool manage_memory = false, int priority = 1);
virtual ~XMLRequest();
// ------------------------------------------------------------------------
@ -73,7 +73,7 @@ namespace Online
* \pre request had to be executed.
* \return get the info from the request reply
*/
const irr::core::stringw & getInfo() const
const irr::core::stringw & getInfo() const
{
assert(hasBeenExecuted());
return m_info;
@ -90,8 +90,5 @@ namespace Online
} // isSuccess
}; // class XMLRequest
} //namespace Online
#endif
#endif // HEADER_XML_REQUEST_HPP

View File

@ -191,7 +191,7 @@ void OnlineScreen::doQuickPlay()
}
PlayerManager::setUserDetails(request2, "request-connection");
request2->setServerURL("address-management.php");
request2->setServerURL(API_ADDRESS_PATH);
request2->addParameter("server_id", server->getServerId());
request2->executeNow();

View File

@ -72,9 +72,9 @@ void RegisterScreen::init()
getWidget<TextBoxWidget>("local_username")->setText(username);
TextBoxWidget *password_widget = getWidget<TextBoxWidget>("password");
password_widget->setPasswordBox(true,L'*');
password_widget->setPasswordBox(true, L'*');
password_widget = getWidget<TextBoxWidget>("password_confirm");
password_widget->setPasswordBox(true,L'*');
password_widget->setPasswordBox(true, L'*');
m_info_widget = getWidget<LabelWidget>("info");
assert(m_info_widget);
@ -147,7 +147,7 @@ void RegisterScreen::makeEntryFieldsVisible(bool online)
*/
void RegisterScreen::handleLocalName(const stringw &local_name)
{
if (local_name.size()==0)
if (local_name.size() == 0)
return;
// If a local player with that name does not exist, create one
@ -267,8 +267,8 @@ void RegisterScreen::acceptTerms()
core::stringw password_confirm= getWidget<TextBoxWidget>("password_confirm")->getText().trim();
core::stringw email = getWidget<TextBoxWidget>("email")->getText().trim();
m_signup_request = new XMLRequest();
m_signup_request->setServerURL("client-user.php");
m_signup_request = new XMLRequest();
m_signup_request->setServerURL(API_USER_PATH);
m_signup_request->addParameter("action", "register" );
m_signup_request->addParameter("username", username );
m_signup_request->addParameter("password", password );