00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <hn/hnprec.h>
00022 #include "server.h"
00023 #include "tag.h"
00024 #include "opcodes.h"
00025 #include "serverlist.h"
00026 #include <boost/lexical_cast.hpp>
00027 #include <boost/algorithm/string/trim.hpp>
00028 #include <boost/tokenizer.hpp>
00029
00030 namespace Detail {
00031
00032 IMPLEMENT_EVENT_TABLE(Server, Server*, int);
00033
00034
00035 Server::Server(IPV4Address addr) : Object(&ServerList::instance(), "server"),
00036 m_addr(addr), m_failedCount(), m_preference(), m_ping(), m_lastPing(),
00037 m_maxUsers(), m_softLimit(), m_hardLimit(), m_udpFlags(), m_users(), m_files(),
00038 m_lowIdUsers(), m_lastUdpQuery(), m_pingInProgress() {
00039
00040 CHECK_THROW_MSG(addr.getAddr(), "Server IP may not be null.");
00041 CHECK_THROW_MSG(addr.getPort(), "Server Port may not be null.");
00042
00043 setName(m_addr.getStr());
00044 }
00045
00046
00047 Server::~Server() {}
00048
00049
00050 Server::Server(std::istream &i) : Object(&ServerList::instance(), "server"),
00051 m_failedCount(), m_preference(), m_ping(), m_lastPing(), m_maxUsers(),
00052 m_softLimit(), m_hardLimit(), m_udpFlags(), m_users(), m_files(),
00053 m_lowIdUsers(), m_lastUdpQuery(), m_pingInProgress() {
00054 m_addr.setAddr(Utils::getVal<uint32_t>(i));
00055 m_addr.setPort(Utils::getVal<uint16_t>(i));
00056
00057
00058 CHECK_THROW_MSG(m_addr.getAddr(), "Invalid ip NULL found for server.");
00059 CHECK_THROW_MSG(m_addr.getPort(),"Invalid port NULL found for server.");
00060
00061 uint32_t tagcount = Utils::getVal<uint32_t>(i);
00062 while (tagcount-- && i) {
00063 try {
00064 Tag t(i);
00065 switch (t.getOpcode()) {
00066 case ST_NAME:
00067 setName(t.getStr());
00068 break;
00069 case ST_DESC:
00070 m_desc = t.getStr();
00071 break;
00072 case ST_DYNIP:
00073 m_dynip = t.getStr();
00074 break;
00075 case ST_VERSION:
00076 m_version = t.getStr();
00077 break;
00078 case ST_FAIL:
00079 m_failedCount = t.getInt();
00080 break;
00081 case ST_PREFERENCE:
00082 m_preference = t.getInt();
00083 break;
00084 case ST_PING:
00085 m_ping = t.getInt();
00086 break;
00087 case ST_LASTPING:
00088 m_lastPing = t.getInt();
00089 break;
00090 case ST_MAXUSERS:
00091 m_maxUsers = t.getInt();
00092 break;
00093 case ST_SOFTLIMIT:
00094 m_softLimit = t.getInt();
00095 break;
00096 case ST_HARDLIMIT:
00097 m_hardLimit = t.getInt();
00098 break;
00099 case ST_UDPFLAGS:
00100 m_udpFlags = t.getInt();
00101 break;
00102 case ST_LOWIDUSRS:
00103 m_lowIdUsers = t.getInt();
00104 break;
00105 case ST_AUXPORTLIST:
00106 addAuxPorts(t.getStr());
00107 break;
00108 default:
00109 if (!t.getName().compare("users")) {
00110 m_users = t.getInt();
00111 break;
00112 }
00113 if (!t.getName().compare("files")) {
00114 m_files = t.getInt();
00115 break;
00116 }
00117 if (!t.getName().compare("maxusers")) {
00118 m_maxUsers = t.getInt();
00119 break;
00120 }
00121 if (!t.getName().compare("lowusers")) {
00122 m_lowIdUsers = t.getInt();
00123 break;
00124 }
00125 warnUnHandled("server.met", t);
00126 break;
00127 }
00128 } catch (TagError &er) {
00129 logWarning(
00130 boost::format("Invalid tag in server.met: %s")
00131 % er.what()
00132 );
00133 }
00134 }
00135 if (getName() == "server") {
00136 setName(m_addr.getStr());
00137 }
00138 }
00139
00140 std::ostream& operator<<(std::ostream &o, const Server &s) {
00141 Utils::putVal<uint32_t>(o, s.getAddr().getAddr());
00142 Utils::putVal<uint16_t>(o, s.getAddr().getPort());
00143 std::ostringstream tmp;
00144 uint32_t tagcount = 0;
00145 if (s.getName().size()) {
00146 tmp << Tag(ST_NAME, s.getName());
00147 ++tagcount;
00148 }
00149 if (s.getDesc().size()) {
00150 tmp << Tag(ST_DESC, s.getDesc());
00151 ++tagcount;
00152 }
00153 if (s.getDynIp().size()) {
00154 tmp << Tag(ST_DYNIP, s.getDynIp());
00155 ++tagcount;
00156 }
00157 if (s.getVersion().size()) {
00158 tmp << Tag(ST_VERSION, s.getVersion());
00159 ++tagcount;
00160 }
00161 if (s.getFailedCount()) {
00162 tmp << Tag(ST_FAIL, s.getFailedCount());
00163 ++tagcount;
00164 }
00165 if (s.getPreference()) {
00166 tmp << Tag(ST_PREFERENCE, s.getPreference());
00167 ++tagcount;
00168 }
00169 if (s.getPing()) {
00170 tmp << Tag(ST_PING, s.getPing());
00171 ++tagcount;
00172 }
00173 if (s.getLastPing()) {
00174 tmp << Tag(ST_LASTPING, s.getLastPing());
00175 ++tagcount;
00176 }
00177 if (s.getMaxUsers()) {
00178 tmp << Tag(ST_MAXUSERS, s.getMaxUsers());
00179 ++tagcount;
00180 }
00181 if (s.getSoftLimit()) {
00182 tmp << Tag(ST_SOFTLIMIT, s.getSoftLimit());
00183 ++tagcount;
00184 }
00185 if (s.getHardLimit()) {
00186 tmp << Tag(ST_HARDLIMIT, s.getHardLimit());
00187 ++tagcount;
00188 }
00189 if (s.getUdpFlags()) {
00190 tmp << Tag(ST_UDPFLAGS, s.getUdpFlags());
00191 ++tagcount;
00192 }
00193 if (s.getUsers()) {
00194 tmp << Tag("users", s.getUsers());
00195 ++tagcount;
00196 }
00197 if (s.getFiles()) {
00198 tmp << Tag("files", s.getFiles());
00199 ++tagcount;
00200 }
00201 if (s.getMaxUsers()) {
00202 tmp << Tag("maxusers", s.getMaxUsers());
00203 ++tagcount;
00204 }
00205 if (s.getLowIdUsers()) {
00206 tmp << Tag("lowusers", s.getLowIdUsers());
00207 ++tagcount;
00208 }
00209 if (s.getAuxPorts().size()) {
00210 using namespace boost::algorithm;
00211 std::string buf;
00212 std::vector<uint16_t>::const_iterator it = s.m_auxPorts.begin();
00213 while (it != s.m_auxPorts.end()) {
00214 buf += boost::lexical_cast<std::string>(*it++) + ",";
00215 }
00216 trim_right_if(buf, is_any_of(","));
00217 tmp << Tag(ST_AUXPORTLIST, buf);
00218 ++tagcount;
00219 }
00220 Utils::putVal(o, tagcount);
00221 Utils::putVal(o, tmp.str(), tmp.str().size());
00222 return o;
00223 }
00224
00225 void Server::addAuxPorts(const std::string &ports) try {
00226 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
00227
00228 boost::char_separator<char> sep(",");
00229 tokenizer tok(ports, sep);
00230
00231 for (tokenizer::iterator i = tok.begin(); i != tok.end(); ++i) {
00232 m_auxPorts.push_back(boost::lexical_cast<uint16_t>(*i));
00233 }
00234 } catch (boost::bad_lexical_cast&) {
00235 logWarning("Invalid AUXPORT tag in server.met (cast failed)");
00236 }
00237 MSVC_ONLY(;)
00238
00239 }