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.

This commit is contained in:
lotodore
2008-05-10 15:47:48 +00:00
parent 8aad232ef2
commit b5c2399603
9 changed files with 80 additions and 64 deletions
@@ -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...")); }
+10 -5
View File
@@ -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;
+2 -1
View File
@@ -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,
+1 -1
View File
@@ -20,7 +20,7 @@
#include <net/clientcontext.h>
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));
}
+40 -19
View File
@@ -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<DownloadHelper> 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<DownloadHelper> 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<boost::iostreams::input> 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<boost::iostreams::input> 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;
}
}
}
+4 -3
View File
@@ -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);
-14
View File
@@ -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 &
+16 -15
View File
@@ -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
+5 -6
View File
@@ -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,