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:
@@ -45,6 +45,8 @@ void connectToServerDialogImpl::refresh(int actionID) {
|
|||||||
|
|
||||||
case MSG_SOCK_INIT_DONE: { label_actionMessage->setText(tr("Resolving address...")); }
|
case MSG_SOCK_INIT_DONE: { label_actionMessage->setText(tr("Resolving address...")); }
|
||||||
break;
|
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...")); }
|
case MSG_SOCK_RESOLVE_DONE: { label_actionMessage->setText(tr("Connecting to server...")); }
|
||||||
break;
|
break;
|
||||||
case MSG_SOCK_CONNECT_DONE: { label_actionMessage->setText(tr("Starting session...")); }
|
case MSG_SOCK_CONNECT_DONE: { label_actionMessage->setText(tr("Starting session...")); }
|
||||||
|
|||||||
+10
-5
@@ -47,10 +47,14 @@ public:
|
|||||||
{return m_serverAddr;}
|
{return m_serverAddr;}
|
||||||
void SetServerAddr(const std::string &serverAddr)
|
void SetServerAddr(const std::string &serverAddr)
|
||||||
{m_serverAddr = serverAddr;}
|
{m_serverAddr = serverAddr;}
|
||||||
const std::string &GetAlternateServerAddr() const
|
const std::string &GetServerListUrl() const
|
||||||
{return m_alternateServerAddr;}
|
{return m_serverListUrl;}
|
||||||
void SetAlternateServerAddr(const std::string &serverAddr)
|
void SetServerListUrl(const std::string &serverListUrl)
|
||||||
{m_alternateServerAddr = serverAddr;}
|
{m_serverListUrl = serverListUrl;}
|
||||||
|
bool GetUseServerList() const
|
||||||
|
{return m_useServerList;}
|
||||||
|
void SetUseServerList(bool use)
|
||||||
|
{m_useServerList = use;}
|
||||||
unsigned GetServerPort() const
|
unsigned GetServerPort() const
|
||||||
{return m_serverPort;}
|
{return m_serverPort;}
|
||||||
void SetServerPort(unsigned serverPort)
|
void SetServerPort(unsigned serverPort)
|
||||||
@@ -87,7 +91,8 @@ private:
|
|||||||
int m_protocol;
|
int m_protocol;
|
||||||
int m_addrFamily;
|
int m_addrFamily;
|
||||||
std::string m_serverAddr;
|
std::string m_serverAddr;
|
||||||
std::string m_alternateServerAddr;
|
std::string m_serverListUrl;
|
||||||
|
bool m_useServerList;
|
||||||
unsigned m_serverPort;
|
unsigned m_serverPort;
|
||||||
std::string m_password;
|
std::string m_password;
|
||||||
sockaddr_storage m_clientSockaddr;
|
sockaddr_storage m_clientSockaddr;
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ public:
|
|||||||
// (i.e. after starting the thread).
|
// (i.e. after starting the thread).
|
||||||
void Init(
|
void Init(
|
||||||
const std::string &serverAddress,
|
const std::string &serverAddress,
|
||||||
const std::string &alternateServerAddress,
|
const std::string &serverListUrl,
|
||||||
|
bool useServerList,
|
||||||
unsigned serverPort,
|
unsigned serverPort,
|
||||||
bool ipv6,
|
bool ipv6,
|
||||||
bool sctp,
|
bool sctp,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#include <net/clientcontext.h>
|
#include <net/clientcontext.h>
|
||||||
|
|
||||||
ClientContext::ClientContext()
|
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));
|
bzero(&m_clientSockaddr, sizeof(m_clientSockaddr));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,9 +103,10 @@ ClientStateInit::Process(ClientThread &client)
|
|||||||
setsockopt(context.GetSocket(), SOL_SOCKET, SO_NOSIGPIPE, (char *)&nosigpipe, sizeof(nosigpipe));
|
setsockopt(context.GetSocket(), SOL_SOCKET, SO_NOSIGPIPE, (char *)&nosigpipe, sizeof(nosigpipe));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO
|
if (context.GetUseServerList())
|
||||||
//client.SetState(ClientStateStartResolve::Instance());
|
client.SetState(ClientStateStartServerListDownload::Instance());
|
||||||
client.SetState(ClientStateStartServerListDownload::Instance());
|
else
|
||||||
|
client.SetState(ClientStateStartResolve::Instance());
|
||||||
|
|
||||||
return MSG_SOCK_INIT_DONE;
|
return MSG_SOCK_INIT_DONE;
|
||||||
}
|
}
|
||||||
@@ -256,14 +257,20 @@ ClientStateStartServerListDownload::Process(ClientThread &client)
|
|||||||
|
|
||||||
const ClientContext &context = client.GetContext();
|
const ClientContext &context = client.GetContext();
|
||||||
path tmpServerListPath(context.GetCacheDir());
|
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))
|
if (exists(tmpServerListPath))
|
||||||
{
|
{
|
||||||
// Download and compare md5.
|
// Download and compare md5.
|
||||||
tmpServerListPath = change_extension(tmpServerListPath, extension(tmpServerListPath) + ".md5");
|
tmpServerListPath = change_extension(tmpServerListPath, extension(tmpServerListPath) + ".md5");
|
||||||
std::auto_ptr<DownloadHelper> downloader(new DownloadHelper);
|
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());
|
ClientStateSynchronizingServerList::Instance().SetDownloadHelper(downloader.release());
|
||||||
client.SetState(ClientStateSynchronizingServerList::Instance());
|
client.SetState(ClientStateSynchronizingServerList::Instance());
|
||||||
}
|
}
|
||||||
@@ -271,7 +278,7 @@ ClientStateStartServerListDownload::Process(ClientThread &client)
|
|||||||
{
|
{
|
||||||
// Download server list.
|
// 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(serverListUrl, tmpServerListPath.directory_string());
|
||||||
ClientStateDownloadingServerList::Instance().SetDownloadHelper(downloader.release());
|
ClientStateDownloadingServerList::Instance().SetDownloadHelper(downloader.release());
|
||||||
client.SetState(ClientStateDownloadingServerList::Instance());
|
client.SetState(ClientStateDownloadingServerList::Instance());
|
||||||
}
|
}
|
||||||
@@ -315,7 +322,10 @@ ClientStateSynchronizingServerList::Process(ClientThread &client)
|
|||||||
Cleanup();
|
Cleanup();
|
||||||
ClientContext &context = client.GetContext();
|
ClientContext &context = client.GetContext();
|
||||||
path md5ServerListPath(context.GetCacheDir());
|
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, "");
|
path zippedServerListPath = change_extension(md5ServerListPath, "");
|
||||||
// Compare the md5 sums.
|
// Compare the md5 sums.
|
||||||
string tmpMd5;
|
string tmpMd5;
|
||||||
@@ -424,18 +434,24 @@ ClientStateReadingServerList::Process(ClientThread &client)
|
|||||||
|
|
||||||
ClientContext &context = client.GetContext();
|
ClientContext &context = client.GetContext();
|
||||||
path zippedServerListPath(context.GetCacheDir());
|
path zippedServerListPath(context.GetCacheDir());
|
||||||
zippedServerListPath /= "serverlist.xml.z";
|
zippedServerListPath /= context.GetServerListUrl().substr(context.GetServerListUrl().find_last_of('/') + 1);
|
||||||
path xmlServerListPath = change_extension(zippedServerListPath, "");
|
path xmlServerListPath;
|
||||||
|
if (extension(zippedServerListPath) == ".z")
|
||||||
// Unzip the file.
|
|
||||||
{
|
{
|
||||||
ifstream inFile(zippedServerListPath.directory_string().c_str(), ios_base::in | ios_base::binary);
|
xmlServerListPath = change_extension(zippedServerListPath, "");
|
||||||
ofstream outFile(xmlServerListPath.directory_string().c_str(), ios_base::out);
|
|
||||||
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
|
// Unzip the file using zlib.
|
||||||
in.push(boost::iostreams::zlib_decompressor());
|
{
|
||||||
in.push(inFile);
|
ifstream inFile(zippedServerListPath.directory_string().c_str(), ios_base::in | ios_base::binary);
|
||||||
boost::iostreams::copy(in, outFile);
|
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.
|
// Parse the server address.
|
||||||
TiXmlDocument doc(xmlServerListPath.directory_string());
|
TiXmlDocument doc(xmlServerListPath.directory_string());
|
||||||
@@ -446,7 +462,11 @@ ClientStateReadingServerList::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)
|
||||||
{
|
{
|
||||||
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())
|
if (addrNode && addrNode->ToElement())
|
||||||
context.SetServerAddr(addrNode->ToElement()->Attribute("value"));
|
context.SetServerAddr(addrNode->ToElement()->Attribute("value"));
|
||||||
const TiXmlNode *portNode = firstServer->FirstChild("Port");
|
const TiXmlNode *portNode = firstServer->FirstChild("Port");
|
||||||
@@ -455,6 +475,7 @@ ClientStateReadingServerList::Process(ClientThread &client)
|
|||||||
int tmpPort = 0;
|
int tmpPort = 0;
|
||||||
portNode->ToElement()->QueryIntAttribute("value", &tmpPort);
|
portNode->ToElement()->QueryIntAttribute("value", &tmpPort);
|
||||||
context.SetServerPort((unsigned)tmpPort);
|
context.SetServerPort((unsigned)tmpPort);
|
||||||
|
retVal = MSG_SOCK_SERVER_LIST_DONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ ClientThread::~ClientThread()
|
|||||||
|
|
||||||
void
|
void
|
||||||
ClientThread::Init(
|
ClientThread::Init(
|
||||||
const string &serverAddress, const string &alternateServerAddress,
|
const string &serverAddress, const string &serverListUrl,
|
||||||
unsigned serverPort, bool ipv6, bool sctp,
|
bool useServerList, unsigned serverPort, bool ipv6, bool sctp,
|
||||||
const string &pwd, const string &playerName, const string &avatarFile,
|
const string &pwd, const string &playerName, const string &avatarFile,
|
||||||
const string &cacheDir)
|
const string &cacheDir)
|
||||||
{
|
{
|
||||||
@@ -90,7 +90,8 @@ ClientThread::Init(
|
|||||||
context.SetProtocol(sctp ? SOCKET_IPPROTO_SCTP : 0);
|
context.SetProtocol(sctp ? SOCKET_IPPROTO_SCTP : 0);
|
||||||
context.SetAddrFamily(ipv6 ? AF_INET6 : AF_INET);
|
context.SetAddrFamily(ipv6 ? AF_INET6 : AF_INET);
|
||||||
context.SetServerAddr(serverAddress);
|
context.SetServerAddr(serverAddress);
|
||||||
context.SetAlternateServerAddr(alternateServerAddress);
|
context.SetServerListUrl(serverListUrl);
|
||||||
|
context.SetUseServerList(useServerList);
|
||||||
context.SetServerPort(serverPort);
|
context.SetServerPort(serverPort);
|
||||||
context.SetPassword(pwd);
|
context.SetPassword(pwd);
|
||||||
context.SetPlayerName(playerName);
|
context.SetPlayerName(playerName);
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ ResolverThread::Init(const ClientContext &context)
|
|||||||
|
|
||||||
GetContext().SetAddrFamily(context.GetAddrFamily());
|
GetContext().SetAddrFamily(context.GetAddrFamily());
|
||||||
GetContext().SetServerAddr(context.GetServerAddr());
|
GetContext().SetServerAddr(context.GetServerAddr());
|
||||||
GetContext().SetAlternateServerAddr(context.GetAlternateServerAddr());
|
|
||||||
GetContext().SetServerPort(context.GetServerPort());
|
GetContext().SetServerPort(context.GetServerPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,19 +79,6 @@ ResolverThread::Main()
|
|||||||
context.GetProtocol(),
|
context.GetProtocol(),
|
||||||
(struct sockaddr *)context.GetClientSockaddr(),
|
(struct sockaddr *)context.GetClientSockaddr(),
|
||||||
context.GetClientSockaddrSize());
|
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 &
|
const ClientContext &
|
||||||
|
|||||||
+16
-15
@@ -107,27 +107,28 @@
|
|||||||
|
|
||||||
// The following messages are connect messages.
|
// The following messages are connect messages.
|
||||||
#define MSG_SOCK_INIT_DONE 1
|
#define MSG_SOCK_INIT_DONE 1
|
||||||
#define MSG_SOCK_RESOLVE_DONE 2
|
#define MSG_SOCK_SERVER_LIST_DONE 2
|
||||||
#define MSG_SOCK_CONNECT_DONE 3
|
#define MSG_SOCK_RESOLVE_DONE 3
|
||||||
#define MSG_SOCK_SESSION_DONE 4
|
#define MSG_SOCK_CONNECT_DONE 4
|
||||||
|
#define MSG_SOCK_SESSION_DONE 5
|
||||||
|
|
||||||
#define MSG_SOCK_LIMIT_CONNECT MSG_SOCK_SESSION_DONE
|
#define MSG_SOCK_LIMIT_CONNECT MSG_SOCK_SESSION_DONE
|
||||||
#define MSG_SOCK_LAST MSG_SOCK_SESSION_DONE
|
#define MSG_SOCK_LAST MSG_SOCK_SESSION_DONE
|
||||||
|
|
||||||
// The following messages are game messages.
|
// The following messages are game messages.
|
||||||
#define MSG_NET_GAME_CLIENT_JOIN 5
|
#define MSG_NET_GAME_CLIENT_JOIN MSG_SOCK_LIMIT_CONNECT + 1
|
||||||
#define MSG_NET_GAME_CLIENT_START 6
|
#define MSG_NET_GAME_CLIENT_START MSG_SOCK_LIMIT_CONNECT + 2
|
||||||
#define MSG_NET_GAME_CLIENT_HAND_START 7
|
#define MSG_NET_GAME_CLIENT_HAND_START MSG_SOCK_LIMIT_CONNECT + 3
|
||||||
#define MSG_NET_GAME_CLIENT_HAND_END 8
|
#define MSG_NET_GAME_CLIENT_HAND_END MSG_SOCK_LIMIT_CONNECT + 4
|
||||||
#define MSG_NET_GAME_CLIENT_END 9
|
#define MSG_NET_GAME_CLIENT_END MSG_SOCK_LIMIT_CONNECT + 5
|
||||||
|
|
||||||
#define MSG_NET_GAME_SERVER_START 10
|
#define MSG_NET_GAME_SERVER_START MSG_SOCK_LIMIT_CONNECT + 6
|
||||||
#define MSG_NET_GAME_SERVER_HAND_START 11
|
#define MSG_NET_GAME_SERVER_HAND_START MSG_SOCK_LIMIT_CONNECT + 7
|
||||||
#define MSG_NET_GAME_SERVER_HAND_END 12
|
#define MSG_NET_GAME_SERVER_HAND_END MSG_SOCK_LIMIT_CONNECT + 8
|
||||||
#define MSG_NET_GAME_SERVER_ROUND 13
|
#define MSG_NET_GAME_SERVER_ROUND MSG_SOCK_LIMIT_CONNECT + 9
|
||||||
#define MSG_NET_GAME_SERVER_ACTION 14
|
#define MSG_NET_GAME_SERVER_ACTION MSG_SOCK_LIMIT_CONNECT + 10
|
||||||
#define MSG_NET_GAME_SERVER_CARDS_DELAY 15
|
#define MSG_NET_GAME_SERVER_CARDS_DELAY MSG_SOCK_LIMIT_CONNECT + 11
|
||||||
#define MSG_NET_GAME_SERVER_END 16
|
#define MSG_NET_GAME_SERVER_END MSG_SOCK_LIMIT_CONNECT + 12
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+5
-6
@@ -169,13 +169,10 @@ void Session::startInternetClient()
|
|||||||
}
|
}
|
||||||
|
|
||||||
myNetClient = new ClientThread(*myGui, *myAvatarManager);
|
myNetClient = new ClientThread(*myGui, *myAvatarManager);
|
||||||
string internetServerAddr(myConfig->readConfigString("InternetServerAddress"));
|
|
||||||
string alternateServerAddr;
|
|
||||||
if (internetServerAddr == "pokerth.6dns.org")
|
|
||||||
alternateServerAddr = "pokerth.dyndns.org";
|
|
||||||
myNetClient->Init(
|
myNetClient->Init(
|
||||||
internetServerAddr,
|
myConfig->readConfigString("InternetServerAddress"),
|
||||||
alternateServerAddr,
|
myConfig->readConfigString("InternetServerListAddress"),
|
||||||
|
myConfig->readConfigInt("InternetServerConfigMode") == 0,
|
||||||
myConfig->readConfigInt("InternetServerPort"),
|
myConfig->readConfigInt("InternetServerPort"),
|
||||||
myConfig->readConfigInt("InternetServerUseIpv6") == 1,
|
myConfig->readConfigInt("InternetServerUseIpv6") == 1,
|
||||||
myConfig->readConfigInt("InternetServerUseSctp") == 1,
|
myConfig->readConfigInt("InternetServerUseSctp") == 1,
|
||||||
@@ -199,6 +196,7 @@ void Session::startNetworkClient(const string &serverAddress, unsigned serverPor
|
|||||||
myNetClient->Init(
|
myNetClient->Init(
|
||||||
serverAddress,
|
serverAddress,
|
||||||
"",
|
"",
|
||||||
|
false,
|
||||||
serverPort,
|
serverPort,
|
||||||
ipv6,
|
ipv6,
|
||||||
sctp,
|
sctp,
|
||||||
@@ -225,6 +223,7 @@ void Session::startNetworkClientForLocalServer(const GameData &gameData)
|
|||||||
myNetClient->Init(
|
myNetClient->Init(
|
||||||
loopbackAddr,
|
loopbackAddr,
|
||||||
"",
|
"",
|
||||||
|
false,
|
||||||
myConfig->readConfigInt("ServerPort"),
|
myConfig->readConfigInt("ServerPort"),
|
||||||
useIpv6,
|
useIpv6,
|
||||||
myConfig->readConfigInt("ServerUseSctp") == 1,
|
myConfig->readConfigInt("ServerUseSctp") == 1,
|
||||||
|
|||||||
Reference in New Issue
Block a user