00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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());
00064
00065 complete_ = false;
00066
00067 list_.clear();
00068
00069
00070 if (!netServer_.connect(masterListServer, 80))
00071 {
00072 return false;
00073 }
00074
00075
00076 netServer_.sendMessageServer(sendNetBuffer_);
00077
00078 const int WaitTime =
00079 OptionsMasterListServer::instance()->getMasterListServerTimeout();
00080
00081 time_t startTime, currentTime;
00082 startTime = currentTime = time(0);
00083 while ((currentTime - startTime < WaitTime) && !cancel_)
00084 {
00085
00086 netServer_.processMessages();
00087
00088
00089 if (complete_)
00090 {
00091 return (list_.getNoEntries() > 0);
00092 }
00093
00094 SDL_Delay(100);
00095 currentTime = time(0);
00096 }
00097
00098
00099 netServer_.disconnectAllClients();
00100
00101
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
00119 UDPsocket udpsock = SDLNet_UDP_Open(0);
00120 if (!udpsock) return false;
00121
00122
00123 SDLNet_UDP_Send(udpsock, -1, sendPacket_);
00124
00125 const int WaitTime =
00126 OptionsMasterListServer::instance()->getMasterListServerTimeout();
00127
00128
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
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
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
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
00175 message.getBuffer().addDataToBuffer("\0", 1);
00176 const char *buffer = message.getBuffer().getBuffer();
00177
00178
00179 while (*buffer != '<' && *buffer != '\0') buffer++;
00180 unsigned int len = strlen(buffer);
00181
00182
00183 if (*buffer == '<')
00184 {
00185 XMLStringBuffer xmlBuffer;
00186 if (xmlBuffer.create(buffer, len))
00187 {
00188
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
00196 XMLNode *currentNode = (*childrenItor);
00197 if (0 == strcmp(currentNode->getName(), "server"))
00198 {
00199 ServerBrowserEntry newEntry;
00200
00201
00202 std::string address;
00203 if (currentNode->getNamedChild("name", address, false))
00204 {
00205 newEntry.addAttribute("address", address.c_str());
00206 }
00207
00208
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
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
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
00266 if (!file.getRootNode()) return result;
00267
00268
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