Download only md5 of the server list if the list is still in the cache.

This commit is contained in:
lotodore
2008-04-29 22:46:27 +00:00
parent 3f544342a7
commit 4b04aedc3f
3 changed files with 201 additions and 45 deletions
+42
View File
@@ -124,6 +124,32 @@ protected:
ClientStateStartServerListDownload(); ClientStateStartServerListDownload();
}; };
// State: Synchronizing server list.
class ClientStateSynchronizingServerList : public ClientState
{
public:
// Access the state singleton.
static ClientStateSynchronizingServerList &Instance();
virtual ~ClientStateSynchronizingServerList();
void SetDownloadHelper(DownloadHelper *helper);
// Poll for the completion of the download.
virtual int Process(ClientThread &client);
protected:
// Protected constructor - this is a singleton.
ClientStateSynchronizingServerList();
void Cleanup();
private:
DownloadHelper *m_downloadHelper;
};
// State: Downloading the server list. // State: Downloading the server list.
class ClientStateDownloadingServerList : public ClientState class ClientStateDownloadingServerList : public ClientState
{ {
@@ -150,6 +176,22 @@ private:
DownloadHelper *m_downloadHelper; DownloadHelper *m_downloadHelper;
}; };
// State: Reading the server list.
class ClientStateReadingServerList : public ClientState
{
public:
static ClientStateReadingServerList &Instance();
virtual ~ClientStateReadingServerList();
virtual int Process(ClientThread &client);
protected:
// Protected constructor - this is a singleton.
ClientStateReadingServerList();
};
// State: Initiate server connection. // State: Initiate server connection.
class ClientStateStartConnect : public ClientState class ClientStateStartConnect : public ClientState
{ {
+2
View File
@@ -198,7 +198,9 @@ friend class ClientStateInit;
friend class ClientStateStartResolve; friend class ClientStateStartResolve;
friend class ClientStateResolving; friend class ClientStateResolving;
friend class ClientStateStartServerListDownload; friend class ClientStateStartServerListDownload;
friend class ClientStateSynchronizingServerList;
friend class ClientStateDownloadingServerList; friend class ClientStateDownloadingServerList;
friend class ClientStateReadingServerList;
friend class ClientStateStartConnect; friend class ClientStateStartConnect;
friend class ClientStateConnecting; friend class ClientStateConnecting;
friend class ClientStateStartSession; friend class ClientStateStartSession;
+127 -15
View File
@@ -29,6 +29,7 @@
#include <net/socket_msg.h> #include <net/socket_msg.h>
#include <net/downloadhelper.h> #include <net/downloadhelper.h>
#include <core/avatarmanager.h> #include <core/avatarmanager.h>
#include <core/crypthelper.h>
#include <qttoolsinterface.h> #include <qttoolsinterface.h>
#include <game.h> #include <game.h>
@@ -257,16 +258,102 @@ ClientStateStartServerListDownload::Process(ClientThread &client)
path tmpServerListPath(context.GetCacheDir()); path tmpServerListPath(context.GetCacheDir());
tmpServerListPath /= "serverlist.xml.z"; tmpServerListPath /= "serverlist.xml.z";
if (exists(tmpServerListPath))
{
// Download and compare md5.
tmpServerListPath = change_extension(tmpServerListPath, extension(tmpServerListPath) + ".md5");
std::auto_ptr<DownloadHelper> downloader(new DownloadHelper);
downloader->Init("pokerth.net/serverlist.xml.z.md5", tmpServerListPath.directory_string());
ClientStateSynchronizingServerList::Instance().SetDownloadHelper(downloader.release());
client.SetState(ClientStateSynchronizingServerList::Instance());
}
else
{
// Download server list.
std::auto_ptr<DownloadHelper> downloader(new DownloadHelper); std::auto_ptr<DownloadHelper> downloader(new DownloadHelper);
downloader->Init("pokerth.net/serverlist.xml.z", tmpServerListPath.directory_string()); downloader->Init("pokerth.net/serverlist.xml.z", tmpServerListPath.directory_string());
ClientStateDownloadingServerList::Instance().SetDownloadHelper(downloader.release()); ClientStateDownloadingServerList::Instance().SetDownloadHelper(downloader.release());
client.SetState(ClientStateDownloadingServerList::Instance()); client.SetState(ClientStateDownloadingServerList::Instance());
}
return retVal; return retVal;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ClientStateSynchronizingServerList &
ClientStateSynchronizingServerList::Instance()
{
static ClientStateSynchronizingServerList state;
return state;
}
ClientStateSynchronizingServerList::ClientStateSynchronizingServerList()
: m_downloadHelper(NULL)
{
}
ClientStateSynchronizingServerList::~ClientStateSynchronizingServerList()
{
Cleanup();
}
void
ClientStateSynchronizingServerList::SetDownloadHelper(DownloadHelper *helper)
{
Cleanup();
m_downloadHelper = helper;
}
int
ClientStateSynchronizingServerList::Process(ClientThread &client)
{
int retVal = MSG_SOCK_INTERNAL_PENDING;
if (m_downloadHelper->Process())
{
Cleanup();
ClientContext &context = client.GetContext();
path md5ServerListPath(context.GetCacheDir());
md5ServerListPath /= "serverlist.xml.z.md5";
path zippedServerListPath = change_extension(md5ServerListPath, "");
// Compare the md5 sums.
string tmpMd5;
{
ifstream inFile(md5ServerListPath.directory_string().c_str(), ios_base::in);
inFile >> tmpMd5;
// TODO error handling
}
MD5Buf downloadedMd5;
downloadedMd5.FromString(tmpMd5);
MD5Buf currentMd5;
CryptHelper::MD5Sum(zippedServerListPath.directory_string(), currentMd5);
if (downloadedMd5 == currentMd5)
{
// Server list is still current.
client.SetState(ClientStateReadingServerList::Instance());
}
else
{
// Download new server list.
remove(zippedServerListPath);
client.SetState(ClientStateStartServerListDownload::Instance());
}
}
return retVal;
}
void
ClientStateSynchronizingServerList::Cleanup()
{
delete m_downloadHelper;
m_downloadHelper = NULL;
}
//-----------------------------------------------------------------------------
ClientStateDownloadingServerList & ClientStateDownloadingServerList &
ClientStateDownloadingServerList::Instance() ClientStateDownloadingServerList::Instance()
{ {
@@ -296,16 +383,50 @@ ClientStateDownloadingServerList::Process(ClientThread &client)
{ {
int retVal = MSG_SOCK_INTERNAL_PENDING; int retVal = MSG_SOCK_INTERNAL_PENDING;
// TODO
// if (!m_resolver)
// throw ClientException(__FILE__, __LINE__, ERR_SOCK_RESOLVE_FAILED, 0);
if (m_downloadHelper->Process()) if (m_downloadHelper->Process())
{ {
Cleanup();
client.SetState(ClientStateReadingServerList::Instance());
}
return retVal;
}
void
ClientStateDownloadingServerList::Cleanup()
{
delete m_downloadHelper;
m_downloadHelper = NULL;
}
//-----------------------------------------------------------------------------
ClientStateReadingServerList &
ClientStateReadingServerList::Instance()
{
static ClientStateReadingServerList state;
return state;
}
ClientStateReadingServerList::ClientStateReadingServerList()
{
}
ClientStateReadingServerList::~ClientStateReadingServerList()
{
}
int
ClientStateReadingServerList::Process(ClientThread &client)
{
int retVal = MSG_SOCK_INTERNAL_PENDING;
ClientContext &context = client.GetContext(); ClientContext &context = client.GetContext();
path zippedServerListPath(context.GetCacheDir()); path zippedServerListPath(context.GetCacheDir());
zippedServerListPath /= "serverlist.xml.z"; zippedServerListPath /= "serverlist.xml.z";
path xmlServerListPath = change_extension(zippedServerListPath, ""); path xmlServerListPath = change_extension(zippedServerListPath, "");
// Unzip the file. // Unzip the file.
{ {
ifstream inFile(zippedServerListPath.directory_string().c_str(), ios_base::in | ios_base::binary); ifstream inFile(zippedServerListPath.directory_string().c_str(), ios_base::in | ios_base::binary);
@@ -315,6 +436,7 @@ ClientStateDownloadingServerList::Process(ClientThread &client)
in.push(inFile); in.push(inFile);
boost::iostreams::copy(in, outFile); boost::iostreams::copy(in, outFile);
} }
// Parse the server address. // Parse the server address.
TiXmlDocument doc(xmlServerListPath.directory_string()); TiXmlDocument doc(xmlServerListPath.directory_string());
@@ -324,7 +446,6 @@ ClientStateDownloadingServerList::Process(ClientThread &client)
const TiXmlElement *firstServer = docHandle.FirstChild("ServerList" ).FirstChild("Server").ToElement(); const TiXmlElement *firstServer = docHandle.FirstChild("ServerList" ).FirstChild("Server").ToElement();
if (firstServer) if (firstServer)
{ {
ClientContext &context = client.GetContext();
const TiXmlNode *addrNode = firstServer->FirstChild("IPv4Address"); const TiXmlNode *addrNode = firstServer->FirstChild("IPv4Address");
if (addrNode && addrNode->ToElement()) if (addrNode && addrNode->ToElement())
context.SetServerAddr(addrNode->ToElement()->Attribute("value")); context.SetServerAddr(addrNode->ToElement()->Attribute("value"));
@@ -337,21 +458,12 @@ ClientStateDownloadingServerList::Process(ClientThread &client)
} }
} }
} }
// TODO error handling
client.SetState(ClientStateStartResolve::Instance()); client.SetState(ClientStateStartResolve::Instance());
}
return retVal; return retVal;
} }
void
ClientStateDownloadingServerList::Cleanup()
{
delete m_downloadHelper;
m_downloadHelper = NULL;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ClientStateStartConnect & ClientStateStartConnect &