ServerBrowserCollect.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <serverbrowser/ServerBrowserCollect.h>
00022 #include <serverbrowser/ServerBrowser.h>
00023 #include <XML/XMLStringBuffer.h>
00024 #include <XML/XMLFile.h>
00025 #include <client/ScorchedClient.h>
00026 #include <common/Defines.h>
00027 #include <common/OptionsMasterListServer.h>
00028 #include <time.h>
00029 
00030 ServerBrowserCollect::ServerBrowserCollect(ServerBrowserServerList &list) :
00031         list_(list),
00032         netServer_(new NetServerHTTPProtocolSend), 
00033         complete_(false), 
00034         cancel_(false)
00035 {
00036         // All messages will come to this class
00037         netServer_.setMessageHandler(this);
00038         recvPacket_ = SDLNet_AllocPacket(10000);
00039         sendPacket_ = SDLNet_AllocPacket(20);
00040         sendPacket_->len = 5;
00041         memcpy(sendPacket_->data, "ping", 5);
00042 }
00043 
00044 ServerBrowserCollect::~ServerBrowserCollect()
00045 {
00046 }
00047 
00048 bool ServerBrowserCollect::fetchServerList(
00049         const char *masterListServer,
00050         const char *masterListServerURI)
00051 {
00052         // Create the message that will be sent to the master server
00053         std::string buffer = S3D::formatStringBuffer(
00054                 "GET %s/servers.php HTTP/1.0\r\n"
00055                 "User-Agent: Scorched3D\r\n"
00056                 "Host: %s\r\n"
00057                 "Connection: close\r\n"
00058                 "\r\n"
00059                 "\r\n",
00060                 masterListServerURI,
00061                 masterListServer);
00062         sendNetBuffer_.reset();
00063         sendNetBuffer_.addDataToBuffer(buffer.c_str(), (int) buffer.size()); // Note no null
00064 
00065         complete_ = false;
00066 
00067         list_.clear();
00068 
00069         // Connect to the master server
00070         if (!netServer_.connect(masterListServer, 80))
00071         {
00072                 return false;
00073         }
00074 
00075         // Send the master server request
00076         netServer_.sendMessageServer(sendNetBuffer_);
00077         
00078         const int WaitTime =
00079                 OptionsMasterListServer::instance()->getMasterListServerTimeout();
00080         // Wait WaitTime seconds for the result
00081         time_t startTime, currentTime;
00082         startTime = currentTime = time(0);
00083         while ((currentTime - startTime < WaitTime) && !cancel_)
00084         {
00085                 // Process any waiting messages
00086                 netServer_.processMessages();
00087 
00088                 // Check if the messages have made us complete
00089                 if (complete_)
00090                 {
00091                         return (list_.getNoEntries() > 0);
00092                 }
00093 
00094                 SDL_Delay(100);
00095                 currentTime = time(0);
00096         }
00097 
00098         // Ensure that we only have one open connection to the server
00099         netServer_.disconnectAllClients();
00100 
00101         // Process any waiting messages caused by the disconnect all
00102         netServer_.processMessages();
00103 
00104         complete_ = true;
00105         return false;
00106 }
00107 
00108 bool ServerBrowserCollect::fetchLANList()
00109 {
00110         complete_ = false;
00111 
00112         if(SDLNet_Init()==-1) false;
00113 
00114         list_.clear();
00115         
00116         SDLNet_ResolveHost(&(sendPacket_->address), "255.255.255.255", S3D::ScorchedPort + 1);
00117         
00118         // Connect to the client
00119         UDPsocket udpsock = SDLNet_UDP_Open(0);
00120         if (!udpsock) return false;
00121         
00122         // Send the request for info
00123         SDLNet_UDP_Send(udpsock, -1, sendPacket_);
00124 
00125         const int WaitTime =
00126                 OptionsMasterListServer::instance()->getMasterListServerTimeout();
00127 
00128         // Accept the results
00129         time_t startTime = time(0);
00130         for (;;)
00131         {
00132                 SDL_Delay(100);
00133                 if (SDLNet_UDP_Recv(udpsock, recvPacket_))
00134                 {
00135                         unsigned int addr = SDLNet_Read32(&recvPacket_->address.host);
00136                         unsigned int port = SDLNet_Read16(&recvPacket_->address.port);
00137 
00138                         // Get the name attribute
00139                         ServerBrowserEntry newEntry;
00140                         char hostName[256];
00141                         snprintf(hostName,
00142                                         256,
00143                                         "%s:%i",
00144                                         NetInterface::getIpName(addr),
00145                                         (port - 1));
00146                         newEntry.addAttribute("address", hostName);
00147                         
00148                         // Add the new and its attributes
00149                         list_.addEntry(newEntry);
00150                 }
00151                 
00152                 time_t theTime = time(0);
00153                 if ((theTime - startTime > WaitTime) || cancel_) break;
00154         }
00155         
00156         SDLNet_UDP_Close(udpsock);
00157         complete_ = true;
00158 
00159         return true;
00160 }
00161 
00162 void ServerBrowserCollect::processMessage(NetMessage &message)
00163 {
00164         // We have received a reply from the web server
00165         if (message.getMessageType() == NetMessage::ConnectMessage)
00166         {
00167         }
00168         else if (message.getMessageType() == NetMessage::DisconnectMessage)
00169         {
00170                 complete_ = true;
00171         }
00172         else if (message.getMessageType() == NetMessage::BufferMessage)
00173         {
00174                 // Add the null to the message
00175                 message.getBuffer().addDataToBuffer("\0", 1);
00176                 const char *buffer = message.getBuffer().getBuffer();
00177 
00178                 // Find the start of the XML
00179                 while (*buffer != '<' && *buffer != '\0') buffer++;
00180                 unsigned int len = strlen(buffer);
00181 
00182                 // Parse the buffer
00183                 if (*buffer == '<')
00184                 {
00185                         XMLStringBuffer xmlBuffer;
00186                         if (xmlBuffer.create(buffer, len))
00187                         {
00188                                 // Itterate all of the keys in the buffer
00189                                 std::list<XMLNode *>::iterator childrenItor;
00190                                 std::list<XMLNode *> &children = xmlBuffer.getRootNode()->getChildren();
00191                                 for (childrenItor = children.begin();
00192                                         childrenItor != children.end();
00193                                         childrenItor++)
00194                                 {
00195                                         // Find each server node
00196                                         XMLNode *currentNode = (*childrenItor);
00197                                         if (0 == strcmp(currentNode->getName(), "server"))
00198                                         {
00199                                                 ServerBrowserEntry newEntry;
00200 
00201                                                 // Get the name attribute
00202                                                 std::string address;
00203                                                 if (currentNode->getNamedChild("name", address, false))
00204                                                 {
00205                                                         newEntry.addAttribute("address", address.c_str());
00206                                                 }
00207                                                 
00208                                                 // Get the official attribute
00209                                                 std::string type;
00210                                                 if (currentNode->getNamedChild("official", type, false))
00211                                                 {
00212                                                         newEntry.addAttribute("type", "official");
00213                                                 }
00214                                                 if (currentNode->getNamedChild("mod", type, false))
00215                                                 {
00216                                                         newEntry.addAttribute("type", "mod");
00217                                                 }
00218                                                 
00219                                                 // Add the new and its attributes
00220                                                 list_.addEntry(newEntry);
00221                                         }
00222                                 }
00223                         }
00224                 }
00225         }
00226 }
00227 
00228 bool ServerBrowserCollect::fetchFavoritesList()
00229 {
00230         list_.clear();
00231         std::set<std::string> favs = getFavourites();
00232         std::set<std::string>::iterator itor;
00233         for (itor = favs.begin();
00234                 itor != favs.end();
00235                 itor++)
00236         {
00237                 const char *fav = (*itor).c_str();
00238 
00239                 ServerBrowserEntry newEntry;
00240                 newEntry.addAttribute("address", fav);
00241 
00242                 // Add the new and its attributes
00243                 list_.addEntry(newEntry);
00244         }
00245 
00246         return true;
00247 }
00248 
00249 std::set<std::string> ServerBrowserCollect::getFavourites()
00250 {
00251         std::set<std::string> result;
00252         std::string filePath = S3D::getSettingsFile("netfavourites.xml");
00253 
00254         XMLFile file;
00255         if (!file.readFile(filePath))
00256         {
00257                 S3D::dialogMessage("Scorched3D", S3D::formatStringBuffer(
00258                         "ERROR: Failed to parse file \"%s\"\n"
00259                         "%s",
00260                         filePath.c_str(),
00261                         file.getParserError()));
00262                 return result;
00263         }
00264 
00265         // return true for an empty file
00266         if (!file.getRootNode()) return result;
00267 
00268         // Itterate all of the addresses in the file
00269         std::list<XMLNode *>::iterator childrenItor;
00270         for (childrenItor = file.getRootNode()->getChildren().begin();
00271                 childrenItor != file.getRootNode()->getChildren().end();
00272                 childrenItor++)
00273         {
00274                 XMLNode *currentNode = (*childrenItor);
00275                 result.insert(currentNode->getContent());
00276         }
00277 
00278         return result;
00279 }
00280 
00281 void ServerBrowserCollect::setFavourites(std::set<std::string> &favs)
00282 {
00283         XMLNode favouritesNode("favourites");
00284 
00285         std::set<std::string>::iterator itor;
00286         for (itor = favs.begin();
00287                 itor != favs.end();
00288                 itor++)
00289         {
00290                 const char *fav = (*itor).c_str();
00291                 favouritesNode.addChild(new XMLNode("favourite", fav));
00292         }
00293 
00294         std::string filePath = S3D::getSettingsFile("netfavourites.xml");
00295         favouritesNode.writeToFile(filePath);
00296 }
00297 

Generated on Mon Feb 16 15:14:47 2009 for Scorched3D by  doxygen 1.5.3