00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <XML/XMLStringBuffer.h>
00022 #include <serverbrowser/ServerBrowserRefresh.h>
00023 #include <serverbrowser/ServerBrowser.h>
00024 #include <common/Defines.h>
00025 #include <time.h>
00026
00027 ServerBrowserRefreshEntry::ServerBrowserRefreshEntry() :
00028 retries_(0), sentTime_(0), recieved_(0)
00029 {
00030 }
00031
00032 ServerBrowserRefreshEntry::ServerBrowserRefreshEntry(
00033 const char *address,
00034 int position) :
00035 address_(address),
00036 position_(position),
00037 retries_(0), sentTime_(0), recieved_(0)
00038 {
00039 }
00040
00041 ServerBrowserRefresh::ServerBrowserRefresh(ServerBrowserServerList &list) :
00042 list_(list),
00043 cancel_(false)
00044 {
00045 recvPacket_ = SDLNet_AllocPacket(10000);
00046 sendPacketStatus_ = SDLNet_AllocPacket(20);
00047 sendPacketStatus_->len = 7;
00048 memcpy(sendPacketStatus_->data, "status", 7);
00049 sendPacketPlayers_ = SDLNet_AllocPacket(20);
00050 sendPacketPlayers_->len = 8;
00051 memcpy(sendPacketPlayers_->data, "players", 8);
00052 }
00053
00054 ServerBrowserRefresh::~ServerBrowserRefresh()
00055 {
00056 }
00057
00058 void ServerBrowserRefresh::refreshList()
00059 {
00060 for (int i=0; i<list_.getNoEntries(); i++)
00061 {
00062 const char *address = list_.getEntryValue(i, "address");
00063 if (address && address[0])
00064 {
00065 ServerBrowserRefreshEntry entry(address, i);
00066 refreshEntries_.push_back(entry);
00067 }
00068 }
00069
00070 while ((!refreshEntries_.empty() || !entryMap_.empty()) && !cancel_)
00071 {
00072 time_t theTime = time(0);
00073
00074
00075 for (int i=entryMap_.size(); i<20 && !refreshEntries_.empty(); i++)
00076 {
00077 ServerBrowserRefreshEntry entry = refreshEntries_.front();
00078 refreshEntries_.pop_front();
00079
00080 sendNextEntry(entry, theTime);
00081 }
00082 SDL_Delay(1000);
00083
00084
00085 processMessages(theTime);
00086 }
00087
00088
00089 std::map<UDPsocket, ServerBrowserRefreshEntry>::iterator cleanitor;
00090 for (cleanitor = entryMap_.begin();
00091 cleanitor != entryMap_.end();
00092 cleanitor++)
00093 {
00094 UDPsocket socket = (*cleanitor).first;
00095 SDLNet_UDP_Close(socket);
00096 }
00097 refreshEntries_.clear();
00098 entryMap_.clear();
00099 }
00100
00101 void ServerBrowserRefresh::sendNextEntry(
00102 ServerBrowserRefreshEntry &entry, time_t theTime)
00103 {
00104 char buffer[256];
00105 snprintf(buffer, sizeof(buffer), "%s", entry.address_.c_str());
00106 char *port = strchr(buffer, ':');
00107 if (!port) return;
00108 *port = '\0';
00109 port++;
00110
00111 IPaddress address;
00112 if (SDLNet_ResolveHost(&address, buffer, atoi(port)+1) != 0) return;
00113
00114
00115 UDPsocket udpsock = SDLNet_UDP_Open(0);
00116 if (!udpsock) return;
00117
00118 int chan = SDLNet_UDP_Bind(udpsock, -1, &address);
00119 if (chan == -1) return;
00120
00121
00122 entry.retries_ ++;
00123 entry.sentTime_ = (unsigned int) theTime;
00124 entry.recieved_ = 0;
00125 entryMap_[udpsock] = entry;
00126
00127
00128 SDLNet_UDP_Send(udpsock, chan, sendPacketStatus_);
00129 SDLNet_UDP_Send(udpsock, chan, sendPacketPlayers_);
00130 }
00131
00132 void ServerBrowserRefresh::processMessages(time_t theTime)
00133 {
00134 std::list<UDPsocket> finished;
00135 std::map<UDPsocket, ServerBrowserRefreshEntry>::iterator itor;
00136 for (itor = entryMap_.begin();
00137 itor != entryMap_.end();
00138 itor++)
00139 {
00140 UDPsocket socket = (*itor).first;
00141 ServerBrowserRefreshEntry &entry = (*itor).second;
00142
00143 if (theTime - entry.sentTime_ > 5)
00144 {
00145 if (entry.retries_ < 3) refreshEntries_.push_back(entry);
00146 finished.push_back(socket);
00147 }
00148 else
00149 {
00150 while (SDLNet_UDP_Recv(socket, recvPacket_))
00151 {
00152 processMessage(recvPacket_, entry);
00153 entry.recieved_ ++;
00154
00155 if (entry.recieved_ == 2) finished.push_back(socket);
00156 }
00157 }
00158 }
00159
00160 while (finished.size())
00161 {
00162 UDPsocket socket = finished.front();
00163 finished.pop_front();
00164
00165 entryMap_.erase(socket);
00166 SDLNet_UDP_Close(socket);
00167 }
00168 }
00169
00170 void ServerBrowserRefresh::processMessage(UDPpacket *packet, ServerBrowserRefreshEntry &entry)
00171 {
00172 const char *buffer = (char *) packet->data;
00173 unsigned int len = packet->len - 1;
00174
00175
00176 XMLStringBuffer xmlBuffer;
00177 if (xmlBuffer.create(buffer, len))
00178 {
00179
00180 std::list<XMLNode *>::iterator childrenItor;
00181 std::list<XMLNode *> &children = xmlBuffer.getRootNode()->getParameters();
00182 for (childrenItor = children.begin();
00183 childrenItor != children.end();
00184 childrenItor++)
00185 {
00186 XMLNode *currentNode = (*childrenItor);
00187 list_.addEntryValue(entry.position_,
00188 currentNode->getName(),
00189 currentNode->getContent());
00190 }
00191 }
00192 }
00193