From b5c239960381ddf9797e1bfedf1fc1e9c8a70d51 Mon Sep 17 00:00:00 2001 From: lotodore Date: Sat, 10 May 2008 15:47:48 +0000 Subject: [PATCH] Use configuration setting to decide whether to download the server list or directly connect to the server. Accept other server lists. Accept un'zlib'ed server lists. Use IPv6 address from server list if configured. --- .../connecttoserverdialogimpl.cpp | 2 + src/net/clientcontext.h | 15 +++-- src/net/clientthread.h | 3 +- src/net/common/clientcontext.cpp | 2 +- src/net/common/clientstate.cpp | 59 +++++++++++++------ src/net/common/clientthread.cpp | 7 ++- src/net/common/resolverthread.cpp | 14 ----- src/net/socket_msg.h | 31 +++++----- src/session.cpp | 11 ++-- 9 files changed, 80 insertions(+), 64 deletions(-) diff --git a/src/gui/qt/connecttoserverdialog/connecttoserverdialogimpl.cpp b/src/gui/qt/connecttoserverdialog/connecttoserverdialogimpl.cpp index 2828b032..83053905 100644 --- a/src/gui/qt/connecttoserverdialog/connecttoserverdialogimpl.cpp +++ b/src/gui/qt/connecttoserverdialog/connecttoserverdialogimpl.cpp @@ -45,6 +45,8 @@ void connectToServerDialogImpl::refresh(int actionID) { case MSG_SOCK_INIT_DONE: { label_actionMessage->setText(tr("Resolving address...")); } break; + case MSG_SOCK_SERVER_LIST_DONE : { label_actionMessage->setText(tr("Reading server list...")); } + break; case MSG_SOCK_RESOLVE_DONE: { label_actionMessage->setText(tr("Connecting to server...")); } break; case MSG_SOCK_CONNECT_DONE: { label_actionMessage->setText(tr("Starting session...")); } diff --git a/src/net/clientcontext.h b/src/net/clientcontext.h index 9649f2aa..9b7b369a 100644 --- a/src/net/clientcontext.h +++ b/src/net/clientcontext.h @@ -47,10 +47,14 @@ public: {return m_serverAddr;} void SetServerAddr(const std::string &serverAddr) {m_serverAddr = serverAddr;} - const std::string &GetAlternateServerAddr() const - {return m_alternateServerAddr;} - void SetAlternateServerAddr(const std::string &serverAddr) - {m_alternateServerAddr = serverAddr;} + const std::string &GetServerListUrl() const + {return m_serverListUrl;} + void SetServerListUrl(const std::string &serverListUrl) + {m_serverListUrl = serverListUrl;} + bool GetUseServerList() const + {return m_useServerList;} + void SetUseServerList(bool use) + {m_useServerList = use;} unsigned GetServerPort() const {return m_serverPort;} void SetServerPort(unsigned serverPort) @@ -87,7 +91,8 @@ private: int m_protocol; int m_addrFamily; std::string m_serverAddr; - std::string m_alternateServerAddr; + std::string m_serverListUrl; + bool m_useServerList; unsigned m_serverPort; std::string m_password; sockaddr_storage m_clientSockaddr; diff --git a/src/net/clientthread.h b/src/net/clientthread.h index 9003a2dc..c50dd6e2 100644 --- a/src/net/clientthread.h +++ b/src/net/clientthread.h @@ -49,7 +49,8 @@ public: // (i.e. after starting the thread). void Init( const std::string &serverAddress, - const std::string &alternateServerAddress, + const std::string &serverListUrl, + bool useServerList, unsigned serverPort, bool ipv6, bool sctp, diff --git a/src/net/common/clientcontext.cpp b/src/net/common/clientcontext.cpp index e33f697e..6de68818 100644 --- a/src/net/common/clientcontext.cpp +++ b/src/net/common/clientcontext.cpp @@ -20,7 +20,7 @@ #include ClientContext::ClientContext() -: m_protocol(0), m_addrFamily(AF_INET), m_serverPort(0) +: m_protocol(0), m_addrFamily(AF_INET), m_useServerList(false), m_serverPort(0) { bzero(&m_clientSockaddr, sizeof(m_clientSockaddr)); } diff --git a/src/net/common/clientstate.cpp b/src/net/common/clientstate.cpp index c90813b5..ed62bcd8 100644 --- a/src/net/common/clientstate.cpp +++ b/src/net/common/clientstate.cpp @@ -103,9 +103,10 @@ ClientStateInit::Process(ClientThread &client) setsockopt(context.GetSocket(), SOL_SOCKET, SO_NOSIGPIPE, (char *)&nosigpipe, sizeof(nosigpipe)); #endif - // TODO - //client.SetState(ClientStateStartResolve::Instance()); - client.SetState(ClientStateStartServerListDownload::Instance()); + if (context.GetUseServerList()) + client.SetState(ClientStateStartServerListDownload::Instance()); + else + client.SetState(ClientStateStartResolve::Instance()); return MSG_SOCK_INIT_DONE; } @@ -256,14 +257,20 @@ ClientStateStartServerListDownload::Process(ClientThread &client) const ClientContext &context = client.GetContext(); path tmpServerListPath(context.GetCacheDir()); - tmpServerListPath /= "serverlist.xml.z"; - + string serverListUrl(context.GetServerListUrl()); + // Retrieve the file name from the URL. + size_t pos = serverListUrl.find_last_of('/'); + if (pos == string::npos || ++pos >= serverListUrl.length()) + { + // TODO throw exception. + } + tmpServerListPath /= serverListUrl.substr(pos); if (exists(tmpServerListPath)) { // Download and compare md5. tmpServerListPath = change_extension(tmpServerListPath, extension(tmpServerListPath) + ".md5"); std::auto_ptr downloader(new DownloadHelper); - downloader->Init("pokerth.net/serverlist.xml.z.md5", tmpServerListPath.directory_string()); + downloader->Init(serverListUrl + ".md5", tmpServerListPath.directory_string()); ClientStateSynchronizingServerList::Instance().SetDownloadHelper(downloader.release()); client.SetState(ClientStateSynchronizingServerList::Instance()); } @@ -271,7 +278,7 @@ ClientStateStartServerListDownload::Process(ClientThread &client) { // Download server list. std::auto_ptr downloader(new DownloadHelper); - downloader->Init("pokerth.net/serverlist.xml.z", tmpServerListPath.directory_string()); + downloader->Init(serverListUrl, tmpServerListPath.directory_string()); ClientStateDownloadingServerList::Instance().SetDownloadHelper(downloader.release()); client.SetState(ClientStateDownloadingServerList::Instance()); } @@ -315,7 +322,10 @@ ClientStateSynchronizingServerList::Process(ClientThread &client) Cleanup(); ClientContext &context = client.GetContext(); path md5ServerListPath(context.GetCacheDir()); - md5ServerListPath /= "serverlist.xml.z.md5"; + + // No more checking needed as this was done before. + md5ServerListPath /= context.GetServerListUrl().substr(context.GetServerListUrl().find_last_of('/') + 1) + ".md5"; + path zippedServerListPath = change_extension(md5ServerListPath, ""); // Compare the md5 sums. string tmpMd5; @@ -424,18 +434,24 @@ ClientStateReadingServerList::Process(ClientThread &client) ClientContext &context = client.GetContext(); path zippedServerListPath(context.GetCacheDir()); - zippedServerListPath /= "serverlist.xml.z"; - path xmlServerListPath = change_extension(zippedServerListPath, ""); - - // Unzip the file. + zippedServerListPath /= context.GetServerListUrl().substr(context.GetServerListUrl().find_last_of('/') + 1); + path xmlServerListPath; + if (extension(zippedServerListPath) == ".z") { - ifstream inFile(zippedServerListPath.directory_string().c_str(), ios_base::in | ios_base::binary); - ofstream outFile(xmlServerListPath.directory_string().c_str(), ios_base::out); - boost::iostreams::filtering_streambuf in; - in.push(boost::iostreams::zlib_decompressor()); - in.push(inFile); - boost::iostreams::copy(in, outFile); + xmlServerListPath = change_extension(zippedServerListPath, ""); + + // Unzip the file using zlib. + { + ifstream inFile(zippedServerListPath.directory_string().c_str(), ios_base::in | ios_base::binary); + ofstream outFile(xmlServerListPath.directory_string().c_str(), ios_base::out); + boost::iostreams::filtering_streambuf in; + in.push(boost::iostreams::zlib_decompressor()); + in.push(inFile); + boost::iostreams::copy(in, outFile); + } } + else + xmlServerListPath = zippedServerListPath; // Parse the server address. TiXmlDocument doc(xmlServerListPath.directory_string()); @@ -446,7 +462,11 @@ ClientStateReadingServerList::Process(ClientThread &client) const TiXmlElement *firstServer = docHandle.FirstChild("ServerList" ).FirstChild("Server").ToElement(); if (firstServer) { - const TiXmlNode *addrNode = firstServer->FirstChild("IPv4Address"); + const TiXmlNode *addrNode; + if (context.GetAddrFamily() == AF_INET6) + addrNode = firstServer->FirstChild("IPv6Address"); + else + addrNode = firstServer->FirstChild("IPv4Address"); if (addrNode && addrNode->ToElement()) context.SetServerAddr(addrNode->ToElement()->Attribute("value")); const TiXmlNode *portNode = firstServer->FirstChild("Port"); @@ -455,6 +475,7 @@ ClientStateReadingServerList::Process(ClientThread &client) int tmpPort = 0; portNode->ToElement()->QueryIntAttribute("value", &tmpPort); context.SetServerPort((unsigned)tmpPort); + retVal = MSG_SOCK_SERVER_LIST_DONE; } } } diff --git a/src/net/common/clientthread.cpp b/src/net/common/clientthread.cpp index bfce15b9..f62fc298 100644 --- a/src/net/common/clientthread.cpp +++ b/src/net/common/clientthread.cpp @@ -74,8 +74,8 @@ ClientThread::~ClientThread() void ClientThread::Init( - const string &serverAddress, const string &alternateServerAddress, - unsigned serverPort, bool ipv6, bool sctp, + const string &serverAddress, const string &serverListUrl, + bool useServerList, unsigned serverPort, bool ipv6, bool sctp, const string &pwd, const string &playerName, const string &avatarFile, const string &cacheDir) { @@ -90,7 +90,8 @@ ClientThread::Init( context.SetProtocol(sctp ? SOCKET_IPPROTO_SCTP : 0); context.SetAddrFamily(ipv6 ? AF_INET6 : AF_INET); context.SetServerAddr(serverAddress); - context.SetAlternateServerAddr(alternateServerAddress); + context.SetServerListUrl(serverListUrl); + context.SetUseServerList(useServerList); context.SetServerPort(serverPort); context.SetPassword(pwd); context.SetPlayerName(playerName); diff --git a/src/net/common/resolverthread.cpp b/src/net/common/resolverthread.cpp index f9ea8c90..b8975d74 100644 --- a/src/net/common/resolverthread.cpp +++ b/src/net/common/resolverthread.cpp @@ -46,7 +46,6 @@ ResolverThread::Init(const ClientContext &context) GetContext().SetAddrFamily(context.GetAddrFamily()); GetContext().SetServerAddr(context.GetServerAddr()); - GetContext().SetAlternateServerAddr(context.GetAlternateServerAddr()); GetContext().SetServerPort(context.GetServerPort()); } @@ -80,19 +79,6 @@ ResolverThread::Main() context.GetProtocol(), (struct sockaddr *)context.GetClientSockaddr(), context.GetClientSockaddrSize()); - - if (!m_retVal && !context.GetAlternateServerAddr().empty()) - { - // Try alternate name. - m_retVal = socket_resolve( - context.GetAlternateServerAddr().c_str(), - tmpStr.str().c_str(), - context.GetAddrFamily(), - SOCK_STREAM, - context.GetProtocol(), - (struct sockaddr *)context.GetClientSockaddr(), - context.GetClientSockaddrSize()); - } } const ClientContext & diff --git a/src/net/socket_msg.h b/src/net/socket_msg.h index 1421b23a..a90fdbda 100644 --- a/src/net/socket_msg.h +++ b/src/net/socket_msg.h @@ -107,27 +107,28 @@ // The following messages are connect messages. #define MSG_SOCK_INIT_DONE 1 -#define MSG_SOCK_RESOLVE_DONE 2 -#define MSG_SOCK_CONNECT_DONE 3 -#define MSG_SOCK_SESSION_DONE 4 +#define MSG_SOCK_SERVER_LIST_DONE 2 +#define MSG_SOCK_RESOLVE_DONE 3 +#define MSG_SOCK_CONNECT_DONE 4 +#define MSG_SOCK_SESSION_DONE 5 #define MSG_SOCK_LIMIT_CONNECT MSG_SOCK_SESSION_DONE #define MSG_SOCK_LAST MSG_SOCK_SESSION_DONE // The following messages are game messages. -#define MSG_NET_GAME_CLIENT_JOIN 5 -#define MSG_NET_GAME_CLIENT_START 6 -#define MSG_NET_GAME_CLIENT_HAND_START 7 -#define MSG_NET_GAME_CLIENT_HAND_END 8 -#define MSG_NET_GAME_CLIENT_END 9 +#define MSG_NET_GAME_CLIENT_JOIN MSG_SOCK_LIMIT_CONNECT + 1 +#define MSG_NET_GAME_CLIENT_START MSG_SOCK_LIMIT_CONNECT + 2 +#define MSG_NET_GAME_CLIENT_HAND_START MSG_SOCK_LIMIT_CONNECT + 3 +#define MSG_NET_GAME_CLIENT_HAND_END MSG_SOCK_LIMIT_CONNECT + 4 +#define MSG_NET_GAME_CLIENT_END MSG_SOCK_LIMIT_CONNECT + 5 -#define MSG_NET_GAME_SERVER_START 10 -#define MSG_NET_GAME_SERVER_HAND_START 11 -#define MSG_NET_GAME_SERVER_HAND_END 12 -#define MSG_NET_GAME_SERVER_ROUND 13 -#define MSG_NET_GAME_SERVER_ACTION 14 -#define MSG_NET_GAME_SERVER_CARDS_DELAY 15 -#define MSG_NET_GAME_SERVER_END 16 +#define MSG_NET_GAME_SERVER_START MSG_SOCK_LIMIT_CONNECT + 6 +#define MSG_NET_GAME_SERVER_HAND_START MSG_SOCK_LIMIT_CONNECT + 7 +#define MSG_NET_GAME_SERVER_HAND_END MSG_SOCK_LIMIT_CONNECT + 8 +#define MSG_NET_GAME_SERVER_ROUND MSG_SOCK_LIMIT_CONNECT + 9 +#define MSG_NET_GAME_SERVER_ACTION MSG_SOCK_LIMIT_CONNECT + 10 +#define MSG_NET_GAME_SERVER_CARDS_DELAY MSG_SOCK_LIMIT_CONNECT + 11 +#define MSG_NET_GAME_SERVER_END MSG_SOCK_LIMIT_CONNECT + 12 #endif diff --git a/src/session.cpp b/src/session.cpp index 0aa87549..2023641f 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -169,13 +169,10 @@ void Session::startInternetClient() } myNetClient = new ClientThread(*myGui, *myAvatarManager); - string internetServerAddr(myConfig->readConfigString("InternetServerAddress")); - string alternateServerAddr; - if (internetServerAddr == "pokerth.6dns.org") - alternateServerAddr = "pokerth.dyndns.org"; myNetClient->Init( - internetServerAddr, - alternateServerAddr, + myConfig->readConfigString("InternetServerAddress"), + myConfig->readConfigString("InternetServerListAddress"), + myConfig->readConfigInt("InternetServerConfigMode") == 0, myConfig->readConfigInt("InternetServerPort"), myConfig->readConfigInt("InternetServerUseIpv6") == 1, myConfig->readConfigInt("InternetServerUseSctp") == 1, @@ -199,6 +196,7 @@ void Session::startNetworkClient(const string &serverAddress, unsigned serverPor myNetClient->Init( serverAddress, "", + false, serverPort, ipv6, sctp, @@ -225,6 +223,7 @@ void Session::startNetworkClientForLocalServer(const GameData &gameData) myNetClient->Init( loopbackAddr, "", + false, myConfig->readConfigInt("ServerPort"), useIpv6, myConfig->readConfigInt("ServerUseSctp") == 1,