From 009249e41a01db7b29bfc3ad8b14908a00014fc3 Mon Sep 17 00:00:00 2001 From: lotodore Date: Sun, 5 Apr 2009 11:19:50 +0000 Subject: [PATCH] Adding stuff for server list (choosing a server). Might not compile (untested yet). --- src/net/clientthread.h | 11 ++++++ src/net/common/clientstate.cpp | 69 ++++++++++++++++++++++++--------- src/net/common/clientthread.cpp | 49 +++++++++++++++++++++++ src/serverdata.h | 42 ++++++++++++++++++++ src/session.cpp | 8 ++++ src/session.h | 2 + 6 files changed, 162 insertions(+), 19 deletions(-) create mode 100644 src/serverdata.h diff --git a/src/net/clientthread.h b/src/net/clientthread.h index 219adc36..de96d427 100644 --- a/src/net/clientthread.h +++ b/src/net/clientthread.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,8 @@ public: void SendAskKickPlayer(unsigned playerId); void SendVoteKick(bool doKick); + ServerInfo GetServerInfo(unsigned serverId) const; + GameInfo GetGameInfo(unsigned gameId) const; PlayerInfo GetPlayerInfo(unsigned playerId) const; bool GetPlayerIdFromName(const std::string &playerName, unsigned &playerId) const; @@ -89,6 +92,7 @@ protected: typedef std::list > NetPacketList; typedef std::map PlayerInfoMap; typedef std::map > AvatarDataMap; + typedef std::map ServerInfoMap; // Main function of the thread. virtual void Main(); @@ -147,6 +151,10 @@ protected: void RemoveDisconnectedPlayers(); + void AddServerInfo(unsigned serverId, const ServerInfo &info); + void ClearServerInfoMap(); + void UseServer(unsigned serverId); + unsigned GetGameIdByName(const std::string &name) const; void AddGameInfo(unsigned gameId, const GameInfo &info); void UpdateGameInfoMode(unsigned gameId, GameMode mode); @@ -188,6 +196,9 @@ private: StartData m_startData; PlayerDataList m_playerDataList; + ServerInfoMap m_serverInfoMap; + mutable boost::mutex m_serverInfoMapMutex; + GameInfoMap m_gameInfoMap; mutable boost::mutex m_gameInfoMapMutex; diff --git a/src/net/common/clientstate.cpp b/src/net/common/clientstate.cpp index d92e792e..ea6abf5c 100644 --- a/src/net/common/clientstate.cpp +++ b/src/net/common/clientstate.cpp @@ -448,36 +448,67 @@ ClientStateReadingServerList::Process(ClientThread &client) if (doc.LoadFile()) { - TiXmlHandle docHandle(&doc); - const TiXmlElement *firstServer = docHandle.FirstChild("ServerList" ).FirstChild("Server").ToElement(); - if (firstServer) + client.ClearServerInfoMap(); + int serverCount = 0; + unsigned lastServerInfoId = 0; + TiXmlHandle docHandle(&doc); + const TiXmlElement *nextServer = docHandle.FirstChild("ServerList" ).FirstChild("Server").ToElement(); + while (nextServer) { - const TiXmlNode *addrNode; - if (context.GetAddrFamily() == AF_INET6) - addrNode = firstServer->FirstChild("IPv6Address"); - else - addrNode = firstServer->FirstChild("IPv4Address"); - const TiXmlNode *portNode = firstServer->FirstChild("Port"); + ServerInfo serverInfo; + { + int tmpId; + nextServer->QueryIntAttribute("value", &tmpId); + serverInfo.id = (unsigned)tmpId; + } + const TiXmlNode *nameNode = nextServer->FirstChild("Name"); + const TiXmlNode *sponsorNode = nextServer->FirstChild("Sponsor"); + const TiXmlNode *countryNode = nextServer->FirstChild("Country"); + const TiXmlNode *addr4Node = nextServer->FirstChild("IPv4Address"); + const TiXmlNode *addr6Node = nextServer->FirstChild("IPv6Address"); + const TiXmlNode *sctpNode = nextServer->FirstChild("SCTP"); + const TiXmlNode *portNode = nextServer->FirstChild("Port"); - // Currently, only IPv4 is supported for avatar servers. - const TiXmlNode *avatarNode = firstServer->FirstChild("AvatarServerAddress"); + // IPv6 support for avatar servers depends on this address and on libcurl. + const TiXmlNode *avatarNode = nextServer->FirstChild("AvatarServerAddress"); - if (!addrNode || !addrNode->ToElement() || !portNode || !portNode->ToElement()) + if (!nameNode || !nameNode->ToElement() || !addrNode || !addr4Node->ToElement() + || !addr6Node->ToElement() || !portNode || !portNode->ToElement()) throw ClientException(__FILE__, __LINE__, ERR_SOCK_INVALID_SERVERLIST_XML, 0); - context.SetServerAddr(addrNode->ToElement()->Attribute("value")); + serverInfo.name = nameNode->ToElement()->Attribute("value"); + serverInfo.ipv4addr = addr4Node->ToElement()->Attribute("value"); + serverInfo.ipv6addr = addr6Node->ToElement()->Attribute("value"); + portNode->ToElement()->QueryIntAttribute("value", &serverInfo.port); - int tmpPort = 0; - portNode->ToElement()->QueryIntAttribute("value", &tmpPort); - context.SetServerPort((unsigned)tmpPort); - - if (avatarNode && avatarNode->ToElement()) // optional + // Optional parameters: + if (sponsorNode && sponsorNode->ToElement()) + serverInfo.sponsor = sponsorNode->ToElement()->Attribute("value"); + if (countryNode && countryNode->ToElement()) + serverInfo.country = countryNode->ToElement()->Attribute("value"); + if (sctpNode && sctpNode->ToElement()) { - context.SetAvatarServerAddr(avatarNode->ToElement()->Attribute("value")); + int tmpSctp; + sctpNode->ToElement()->QueryIntAttribute } + if (avatarNode && avatarNode->ToElement()) + serverInfo.avatarServerAddr = avatarNode->ToElement()->Attribute("value"); + client.AddServerInfo(serverInfo.id, serverInfo); + nextServer = nextServer->NextSiblingElement(); + lastServerInfoId = serverInfo.id; + serverCount++; + } + + if (serverCount == 1) + { + client.UseServer(lastServerInfoId); retVal = MSG_SOCK_SERVER_LIST_DONE; } + else if (serverCount > 0) + { + // TODO.... + } else throw ClientException(__FILE__, __LINE__, ERR_SOCK_INVALID_SERVERLIST_XML, 0); } diff --git a/src/net/common/clientthread.cpp b/src/net/common/clientthread.cpp index deefd6ec..818abf02 100644 --- a/src/net/common/clientthread.cpp +++ b/src/net/common/clientthread.cpp @@ -284,6 +284,19 @@ ClientThread::SendVoteKick(bool doKick) m_outPacketList.push_back(vote); } +ServerInfo +ClientThread::GetServerInfo(unsigned serverId) const +{ + ServerInfo tmpInfo; + boost::mutex::scoped_lock lock(m_serverInfoMapMutex); + ServerInfoMap::const_iterator pos = m_serverInfoMap.find(serverId); + if (pos != m_serverInfoMap.end()) + { + tmpInfo = pos->second; + } + return tmpInfo; +} + GameInfo ClientThread::GetGameInfo(unsigned gameId) const { @@ -941,6 +954,42 @@ ClientThread::RemoveDisconnectedPlayers() } } +void +ClientThread::AddServerInfo(unsigned serverId, const ServerInfo &info) +{ + { + boost::mutex::scoped_lock lock(m_serverInfoMapMutex); + m_serverInfoMap.insert(ServerInfoMap::value_type(serverId, info)); + } + //GetCallback().SignalNetClientServerListAdd(serverId); +} + +void +ClientThread::ClearServerInfoMap() +{ + { + boost::mutex::scoped_lock lock(m_serverInfoMapMutex); + m_serverInfoMap.clear(); + } + //GetCallback().SignalNetClientServerListClear(); +} + + +void +ClientThread::UseServer(unsigned serverId) +{ + ClientContext &context = client.GetContext(); + ServerInfo useInfo(GetServerInfo(serverId)); + + if (context.GetAddrFamily() == AF_INET6) + context.SetServerAddr(useInfo.ipv6addr); + else + context.SetServerAddr(useInfo.ipv4addr); + + context.SetServerPort((unsigned)useInfo.port); + context.SetAvatarServerAddr(useInfo.avatarServerAddr); +} + unsigned ClientThread::GetGameIdByName(const std::string &name) const { diff --git a/src/serverdata.h b/src/serverdata.h new file mode 100644 index 00000000..76c512e9 --- /dev/null +++ b/src/serverdata.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2009 by Lothar May * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +/* Server data. */ + +#ifndef _SERVERDATA_H_ +#define _SERVERDATA_H_ + +#include + + +struct ServerInfo +{ + ServerInfo() : id(0), supportsSctp(false), port(0) {} + unsigned id; + std::string name; + std::string sponsor; + std::string country; + std::string ipv4addr; + std::string ipv6addr; + bool supportsSctp; + int port; + std::string avatarServerAddr; +}; + +#endif + diff --git a/src/session.cpp b/src/session.cpp index 77270d06..9365b762 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -425,6 +425,14 @@ bool Session::isNetworkServerRunning() const return myNetServer != NULL; } +ServerInfo Session::getClientServerInfo(unsigned serverId) const +{ + ServerInfo info; + if (myNetClient) + info = myNetClient->GetServerInfo(serverId); + return info; +} + GameInfo Session::getClientGameInfo(unsigned playerId) const { GameInfo info; diff --git a/src/session.h b/src/session.h index e69e788f..97b2341a 100755 --- a/src/session.h +++ b/src/session.h @@ -19,6 +19,7 @@ ***************************************************************************/ #ifndef STDSESSION_H #define STDSESSION_H +#include "serverdata.h" #include "gamedata.h" #include "playerdata.h" #include "game_defs.h" @@ -88,6 +89,7 @@ public: bool isNetworkClientRunning() const; // TODO hack bool isNetworkServerRunning() const; // TODO hack + ServerInfo getClientServerInfo(unsigned serverId) const; GameInfo getClientGameInfo(unsigned gameId) const; PlayerInfo getClientPlayerInfo(unsigned playerId) const; ServerStats getClientStats() const;