void RealmList::UpdateRealms(bool init) { sLog->outInfo(LOG_FILTER_AUTHSERVER, "Updating Realm List..."); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); PreparedQueryResult result = LoginDatabase.Query(stmt); // Circle through results and add them to the realm map if (result) { do { Field* fields = result->Fetch(); uint32 realmId = fields[0].GetUInt32(); std::string name = fields[1].GetString(); std::string address = fields[2].GetString(); uint16 port = fields[3].GetUInt16(); uint8 icon = fields[4].GetUInt8(); RealmFlags flag = RealmFlags(fields[5].GetUInt8()); uint8 timezone = fields[6].GetUInt8(); uint8 allowedSecurityLevel = fields[7].GetUInt8(); float pop = fields[8].GetFloat(); uint32 build = fields[9].GetUInt32(); ACE_INET_Addr addr(port, address.c_str(), AF_INET); UpdateRealm(realmId, name, addr, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build); if (init) sLog->outInfo(LOG_FILTER_AUTHSERVER, "Added realm \"%s\" at %s.", name.c_str(), m_realms[name].address); } while (result->NextRow()); } }
void RealmList::UpdateRealms(bool init) { sLog->outDetail("Updating Realm List..."); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); PreparedQueryResult result = LoginDatabase.Query(stmt); // Circle through results and add them to the realm map if (result) { do { Field* fields = result->Fetch(); uint32 realmId = fields[0].GetUInt32(); const std::string& name = fields[1].GetString(); const std::string& address = fields[2].GetString(); uint16 port = fields[3].GetUInt16(); uint8 icon = fields[4].GetUInt8(); RealmFlags flag = RealmFlags(fields[5].GetUInt8()); uint8 timezone = fields[6].GetUInt8(); uint8 allowedSecurityLevel = fields[7].GetUInt8(); float pop = fields[8].GetFloat(); uint32 build = fields[9].GetUInt32(); UpdateRealm(realmId, name, address, port, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build); if (init) sLog->outString("--\n\nДобавлен реалм \"%s\".", fields[1].GetCString()); } while (result->NextRow()); } }
void RealmList::UpdateRealms(bool init) { sLog.outDetail("Updating Realm List..."); // 0 1 2 3 4 5 6 7 8 9 QueryResult_AutoPtr result = LoginDatabase.Query( "SELECT id, name, address, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE (flag & 1) = 0 ORDER BY name" ); // Circle through results and add them to the realm map if (result) { do { Field *fields = result->Fetch(); uint8 allowedSecurityLevel = fields[7].GetUInt8(); uint8 realmflags = fields[5].GetUInt8(); if (realmflags & ~(REALM_FLAG_OFFLINE|REALM_FLAG_NEW_PLAYERS|REALM_FLAG_RECOMMENDED|REALM_FLAG_SPECIFYBUILD)) { sLog.outError("Realm allowed have only OFFLINE Mask 0x2), or NEWPLAYERS (mask 0x20), or RECOMENDED (mask 0x40), or SPECIFICBUILD (mask 0x04) flags in DB"); realmflags &= (REALM_FLAG_OFFLINE|REALM_FLAG_NEW_PLAYERS|REALM_FLAG_RECOMMENDED|REALM_FLAG_SPECIFYBUILD); } UpdateRealm( fields[0].GetUInt32(), fields[1].GetCppString(),fields[2].GetCppString(),fields[3].GetUInt32(), fields[4].GetUInt8(), RealmFlags(realmflags), fields[6].GetUInt8(), (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), fields[8].GetFloat(), fields[9].GetString()); if (init) sLog.outString("Added realm \"%s\"", fields[1].GetString()); } while ( result->NextRow() ); } }
void RealmList::UpdateRealms(bool init) { sLog->outInfo(LOG_FILTER_AUTHSERVER, "Updating Realm List..."); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); PreparedQueryResult result = LoginDatabase.Query(stmt); // Circle through results and add them to the realm map if (result) { do { Field* fields = result->Fetch(); uint32 realmId = fields[0].GetUInt32(); const std::string& name = fields[1].GetString(); const std::string& address = fields[2].GetString(); uint16 port = fields[3].GetUInt16(); uint8 icon = fields[4].GetUInt8(); RealmFlags flag = RealmFlags(fields[5].GetUInt8()); uint8 timezone = fields[6].GetUInt8(); uint8 allowedSecurityLevel = fields[7].GetUInt8(); float pop = fields[8].GetFloat(); uint32 build = fields[9].GetUInt32(); UpdateRealm(realmId, name, address, port, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build); if (init) sLog->outInfo(LOG_FILTER_AUTHSERVER, "Added realm \"%s\".", fields[1].GetCString()); } while (result->NextRow()); } QueryResult firewalls = LoginDatabase.PQuery("SELECT ip FROM firewall_farms WHERE type = 0"); // Type 0 = worldserver protection if (firewalls) { m_firewallFarms.clear(); m_firewallFarms.resize(firewalls->GetRowCount()); uint32 count = 0; do { Field* fields = firewalls->Fetch(); m_firewallFarms[count] = fields[0].GetCString(); count++; } while (firewalls->NextRow()); } }
void RealmList::UpdateRealms(bool init) { TC_LOG_INFO("serveur.authentification", "Mise à jour de la liste des royaumes..."); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); PreparedQueryResult result = LoginDatabase.Query(stmt); // Circle through results and add them to the realm map if (result) { do { Field* fields = result->Fetch(); uint32 realmId = fields[0].GetUInt32(); std::string name = fields[1].GetString(); std::string externalAddress = fields[2].GetString(); std::string localAddress = fields[3].GetString(); std::string localSubmask = fields[4].GetString(); uint16 port = fields[5].GetUInt16(); uint8 icon = fields[6].GetUInt8(); RealmFlags flag = RealmFlags(fields[7].GetUInt8()); uint8 timezone = fields[8].GetUInt8(); uint8 allowedSecurityLevel = fields[9].GetUInt8(); float pop = fields[10].GetFloat(); uint32 build = fields[11].GetUInt32(); ACE_INET_Addr externalAddr(port, externalAddress.c_str(), AF_INET); ACE_INET_Addr localAddr(port, localAddress.c_str(), AF_INET); ACE_INET_Addr submask(0, localSubmask.c_str(), AF_INET); UpdateRealm(realmId, name, externalAddr, localAddr, submask, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build); if (init) TC_LOG_INFO("serveur.authentification", "Royaume \"%s\" ajoutée vers %s:%u.", name.c_str(), m_realms[name].ExternalAddress.get_host_addr(), port); } while (result->NextRow()); } }
void AuthSocket::LoadRealmlist(ByteBuffer& pkt, uint32 acctid) { switch (_build) { case 5875: // 1.12.1 case 6005: // 1.12.2 case 6141: // 1.12.3 { pkt << uint32(0); // unused value pkt << uint8(sRealmList.size()); for (RealmList::RealmMap::const_iterator i = sRealmList.begin(); i != sRealmList.end(); ++i) { uint8 AmountOfCharacters; // No SQL injection. id of realm is controlled by the database. QueryResult* result = LoginDatabase.PQuery("SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'", i->second.m_ID, acctid); if (result) { Field* fields = result->Fetch(); AmountOfCharacters = fields[0].GetUInt8(); delete result; } else AmountOfCharacters = 0; bool ok_build = std::find(i->second.realmbuilds.begin(), i->second.realmbuilds.end(), _build) != i->second.realmbuilds.end(); RealmBuildInfo const* buildInfo = ok_build ? FindBuildInfo(_build) : NULL; if (!buildInfo) buildInfo = &i->second.realmBuildInfo; RealmFlags realmflags = i->second.realmflags; // 1.x clients not support explicitly REALM_FLAG_SPECIFYBUILD, so manually form similar name as show in more recent clients std::string name = i->first; if (realmflags & REALM_FLAG_SPECIFYBUILD) { char buf[20]; snprintf(buf, 20, " (%u,%u,%u)", buildInfo->major_version, buildInfo->minor_version, buildInfo->bugfix_version); name += buf; } // Show offline state for unsupported client builds and locked realms (1.x clients not support locked state show) if (!ok_build || (i->second.allowedSecurityLevel > _accountSecurityLevel)) realmflags = RealmFlags(realmflags | REALM_FLAG_OFFLINE); pkt << uint32(i->second.icon); // realm type pkt << uint8(realmflags); // realmflags pkt << name; // name pkt << i->second.address; // address pkt << float(i->second.populationLevel); pkt << uint8(AmountOfCharacters); pkt << uint8(i->second.timezone); // realm category pkt << uint8(0x00); // unk, may be realm number/id? } pkt << uint16(0x0002); // unused value (why 2?) break; } case 8606: // 2.4.3 case 10505: // 3.2.2a case 11159: // 3.3.0a case 11403: // 3.3.2 case 11723: // 3.3.3a case 12340: // 3.3.5a case 13623: // 4.0.6a case 15050: // 4.3.0 case 15595: // 4.3.4 case 16357: // 5.1.0 case 16992: // 5.3.0 case 17055: // 5.3.0 case 17116: // 5.3.0 case 17128: // 5.3.0 case 17538: // 5.4.1 default: // and later { pkt << uint32(0); // unused value pkt << uint16(sRealmList.size()); for (RealmList::RealmMap::const_iterator i = sRealmList.begin(); i != sRealmList.end(); ++i) { uint8 AmountOfCharacters; // No SQL injection. id of realm is controlled by the database. QueryResult* result = LoginDatabase.PQuery("SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'", i->second.m_ID, acctid); if (result) { Field* fields = result->Fetch(); AmountOfCharacters = fields[0].GetUInt8(); delete result; } else AmountOfCharacters = 0; bool ok_build = std::find(i->second.realmbuilds.begin(), i->second.realmbuilds.end(), _build) != i->second.realmbuilds.end(); RealmBuildInfo const* buildInfo = ok_build ? FindBuildInfo(_build) : NULL; if (!buildInfo) buildInfo = &i->second.realmBuildInfo; uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; RealmFlags realmFlags = i->second.realmflags; // Show offline state for unsupported client builds if (!ok_build) realmFlags = RealmFlags(realmFlags | REALM_FLAG_OFFLINE); if (!buildInfo) realmFlags = RealmFlags(realmFlags & ~REALM_FLAG_SPECIFYBUILD); pkt << uint8(i->second.icon); // realm type (this is second column in Cfg_Configs.dbc) pkt << uint8(lock); // flags, if 0x01, then realm locked pkt << uint8(realmFlags); // see enum RealmFlags pkt << i->first; // name pkt << i->second.address; // address pkt << float(i->second.populationLevel); pkt << uint8(AmountOfCharacters); pkt << uint8(i->second.timezone); // realm category (Cfg_Categories.dbc) pkt << uint8(0x2C); // unk, may be realm number/id? if (realmFlags & REALM_FLAG_SPECIFYBUILD) { pkt << uint8(buildInfo->major_version); pkt << uint8(buildInfo->minor_version); pkt << uint8(buildInfo->bugfix_version); pkt << uint16(_build); } } pkt << uint16(0x0010); // unused value (why 10?) break; } } }
void RealmList::UpdateRealms(bool init, boost::system::error_code const& error) { if (error) return; TC_LOG_INFO("server.authserver", "Updating Realm List..."); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); PreparedQueryResult result = LoginDatabase.Query(stmt); // Circle through results and add them to the realm map if (result) { do { try { boost::asio::ip::tcp::resolver::iterator end; Field* fields = result->Fetch(); uint32 realmId = fields[0].GetUInt32(); std::string name = fields[1].GetString(); boost::asio::ip::tcp::resolver::query externalAddressQuery(ip::tcp::v4(), fields[2].GetString(), ""); boost::system::error_code ec; boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery, ec); if (endPoint == end || ec) { TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[2].GetString().c_str()); return; } ip::address externalAddress = (*endPoint).endpoint().address(); boost::asio::ip::tcp::resolver::query localAddressQuery(ip::tcp::v4(), fields[3].GetString(), ""); endPoint = _resolver->resolve(localAddressQuery, ec); if (endPoint == end || ec) { TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[3].GetString().c_str()); return; } ip::address localAddress = (*endPoint).endpoint().address(); boost::asio::ip::tcp::resolver::query localSubmaskQuery(ip::tcp::v4(), fields[4].GetString(), ""); endPoint = _resolver->resolve(localSubmaskQuery, ec); if (endPoint == end || ec) { TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[4].GetString().c_str()); return; } ip::address localSubmask = (*endPoint).endpoint().address(); uint16 port = fields[5].GetUInt16(); uint8 icon = fields[6].GetUInt8(); if (icon == REALM_TYPE_FFA_PVP) icon = REALM_TYPE_PVP; if (icon >= MAX_CLIENT_REALM_TYPE) icon = REALM_TYPE_NORMAL; RealmFlags flag = RealmFlags(fields[7].GetUInt8()); uint8 timezone = fields[8].GetUInt8(); uint8 allowedSecurityLevel = fields[9].GetUInt8(); float pop = fields[10].GetFloat(); uint32 build = fields[11].GetUInt32(); RealmHandle id{ realmId }; UpdateRealm(id, build, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop); if (init) TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port); } catch (std::exception& ex) { TC_LOG_ERROR("server.authserver", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what()); ABORT(); } } while (result->NextRow()); } if (_updateInterval) { _updateTimer->expires_from_now(boost::posix_time::seconds(_updateInterval)); _updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, false, std::placeholders::_1)); } }
void RealmList::UpdateRealms(bool init) { TC_LOG_INFO("server.authserver", "Updating Realm List..."); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); PreparedQueryResult result = LoginDatabase.Query(stmt); // Circle through results and add them to the realm map if (result) { do { try { boost::asio::ip::tcp::resolver::iterator end; Field* fields = result->Fetch(); uint32 realmId = fields[0].GetUInt32(); std::string name = fields[1].GetString(); boost::asio::ip::tcp::resolver::query externalAddressQuery(ip::tcp::v4(), fields[2].GetString(), ""); boost::system::error_code ec; boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery, ec); if (endPoint == end || ec) { TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[2].GetString().c_str()); return; } ip::address externalAddress = (*endPoint).endpoint().address(); boost::asio::ip::tcp::resolver::query localAddressQuery(ip::tcp::v4(), fields[3].GetString(), ""); endPoint = _resolver->resolve(localAddressQuery, ec); if (endPoint == end || ec) { TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[3].GetString().c_str()); return; } ip::address localAddress = (*endPoint).endpoint().address(); boost::asio::ip::tcp::resolver::query localSubmaskQuery(ip::tcp::v4(), fields[4].GetString(), ""); endPoint = _resolver->resolve(localSubmaskQuery, ec); if (endPoint == end || ec) { TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[4].GetString().c_str()); return; } ip::address localSubmask = (*endPoint).endpoint().address(); uint16 port = fields[5].GetUInt16(); uint8 icon = fields[6].GetUInt8(); RealmFlags flag = RealmFlags(fields[7].GetUInt8()); uint8 timezone = fields[8].GetUInt8(); uint8 allowedSecurityLevel = fields[9].GetUInt8(); float pop = fields[10].GetFloat(); uint32 build = fields[11].GetUInt32(); UpdateRealm(realmId, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build); if (init) TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.to_string().c_str(), port); } catch (std::exception& ex) { TC_LOG_ERROR("server.authserver", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what()); ASSERT(false); } } while (result->NextRow()); } }
void AuthSocket::LoadRealmlist(ByteBuffer &pkt, uint32 acctid) { switch(_build) { case 12319: // We support only 4.0.0.12319 { pkt << uint32(0); pkt << uint16(sRealmList.size()); for(RealmList::RealmMap::const_iterator i = sRealmList.begin(); i != sRealmList.end(); ++i) { uint8 AmountOfCharacters; // No SQL injection. id of realm is controlled by the database. QueryResult *result = loginDatabase.PQuery( "SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'", i->second.m_ID, acctid); if( result ) { Field *fields = result->Fetch(); AmountOfCharacters = fields[0].GetUInt8(); delete result; } else AmountOfCharacters = 0; bool ok_build = std::find(i->second.realmbuilds.begin(), i->second.realmbuilds.end(), _build) != i->second.realmbuilds.end(); RealmBuildInfo const* buildInfo = ok_build ? FindBuildInfo(_build) : NULL; if (!buildInfo) buildInfo = &i->second.realmBuildInfo; uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; RealmFlags realmFlags = i->second.realmflags; // Show offline state for unsupported client builds if (!ok_build) realmFlags = RealmFlags(realmFlags | REALM_FLAG_OFFLINE); if (!buildInfo) realmFlags = RealmFlags(realmFlags & ~REALM_FLAG_SPECIFYBUILD); pkt << uint8(i->second.icon); // realm type (this is second column in Cfg_Configs.dbc) pkt << uint8(lock); // flags, if 0x01, then realm locked pkt << uint8(realmFlags); // see enum RealmFlags pkt << i->first; // name pkt << i->second.address; // address pkt << float(i->second.populationLevel); pkt << uint8(AmountOfCharacters); pkt << uint8(i->second.timezone); // realm category (Cfg_Categories.dbc) pkt << uint8(0x2C); // unk, may be realm number/id? if (realmFlags & REALM_FLAG_SPECIFYBUILD) { pkt << uint8(buildInfo->major_version); pkt << uint8(buildInfo->minor_version); pkt << uint8(buildInfo->bugfix_version); pkt << uint16(_build); } } pkt << uint16(0x0010); break; } } }
void AuthSocket::LoadRealmlist(ByteBuffer& pkt, uint32 acctid) { RealmList::RealmListIterators iters; iters = sRealmList.GetIteratorsForBuild(_build); uint32 numRealms = sRealmList.NumRealmsForBuild(_build); ACE_INET_Addr clientAddr; peer().get_remote_addr(clientAddr); switch (_build) { case 5875: // 1.12.1 case 6005: // 1.12.2 case 6141: // 1.12.3 { pkt << uint32(0); // unused value pkt << uint8(numRealms); for (RealmList::RealmStlList::const_iterator itr = iters.first; itr != iters.second; ++itr) { clientAddr.set_port_number((*itr)->ExternalAddress.get_port_number()); uint8 AmountOfCharacters; // No SQL injection. id of realm is controlled by the database. QueryResult* result = LoginDatabase.PQuery("SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'", (*itr)->m_ID, acctid); if (result) { Field* fields = result->Fetch(); AmountOfCharacters = fields[0].GetUInt8(); delete result; } else AmountOfCharacters = 0; bool ok_build = std::find((*itr)->realmbuilds.begin(), (*itr)->realmbuilds.end(), _build) != (*itr)->realmbuilds.end(); RealmBuildInfo const* buildInfo = ok_build ? FindBuildInfo(_build) : NULL; if (!buildInfo) buildInfo = &(*itr)->realmBuildInfo; RealmFlags realmflags = (*itr)->realmflags; // 1.x clients not support explicitly REALM_FLAG_SPECIFYBUILD, so manually form similar name as show in more recent clients std::string name = (*itr)->name; if (realmflags & REALM_FLAG_SPECIFYBUILD) { char buf[20]; snprintf(buf, 20, " (%u,%u,%u)", buildInfo->major_version, buildInfo->minor_version, buildInfo->bugfix_version); name += buf; } // Show offline state for unsupported client builds and locked realms (1.x clients not support locked state show) if (!ok_build || ((*itr)->allowedSecurityLevel > _accountSecurityLevel)) realmflags = RealmFlags(realmflags | REALM_FLAG_OFFLINE); pkt << uint32((*itr)->icon); // realm type pkt << uint8(realmflags); // realmflags pkt << name; // name pkt << GetAddressString(GetAddressForClient((**itr), clientAddr)); // address pkt << float((*itr)->populationLevel); pkt << uint8(AmountOfCharacters); pkt << uint8((*itr)->timezone); // realm category pkt << uint8(0x00); // unk, may be realm number/id? } pkt << uint16(0x0002); // unused value (why 2?) break; } case 8606: // 2.4.3 case 10505: // 3.2.2a case 11159: // 3.3.0a case 11403: // 3.3.2 case 11723: // 3.3.3a case 12340: // 3.3.5a case 13623: // 4.0.6a case 15050: // 4.3.0 case 15595: // 4.3.4 case 16357: // 5.1.0 case 16992: // 5.3.0 case 17055: // 5.3.0 case 17116: // 5.3.0 case 17128: // 5.3.0 case 17538: // 5.4.1 case 17658: // 5.4.2 case 17688: // 5.4.2a case 17898: // 5.4.7 case 17930: // 5.4.7 case 17956: // 5.4.7 case 18019: // 5.4.7 case 18291: // 5.4.8 case 18414: // 5.4.8 default: // and later { pkt << uint32(0); // unused value pkt << uint16(numRealms); for (RealmList::RealmStlList::const_iterator itr = iters.first; itr != iters.second; ++itr) { clientAddr.set_port_number((*itr)->ExternalAddress.get_port_number()); uint8 AmountOfCharacters; // No SQL injection. id of realm is controlled by the database. QueryResult* result = LoginDatabase.PQuery("SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'", (*itr)->m_ID, acctid); if (result) { Field* fields = result->Fetch(); AmountOfCharacters = fields[0].GetUInt8(); delete result; } else { AmountOfCharacters = 0; } bool ok_build = std::find((*itr)->realmbuilds.begin(), (*itr)->realmbuilds.end(), _build) != (*itr)->realmbuilds.end(); RealmBuildInfo const* buildInfo = ok_build ? FindBuildInfo(_build) : NULL; if (!buildInfo) { buildInfo = &(*itr)->realmBuildInfo; } uint8 lock = ((*itr)->allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; RealmFlags realmFlags = (*itr)->realmflags; // Show offline state for unsupported client builds if (!ok_build) { realmFlags = RealmFlags(realmFlags | REALM_FLAG_OFFLINE); } if (!buildInfo) { realmFlags = RealmFlags(realmFlags & ~REALM_FLAG_SPECIFYBUILD); } pkt << uint8((*itr)->icon); // realm type (this is second column in Cfg_Configs.dbc) pkt << uint8(lock); // flags, if 0x01, then realm locked pkt << uint8(realmFlags); // see enum RealmFlags pkt << (*itr)->name; // name pkt << GetAddressString(GetAddressForClient((**itr), clientAddr)); // address pkt << float((*itr)->populationLevel); pkt << uint8(AmountOfCharacters); pkt << uint8((*itr)->timezone); // realm category (Cfg_Categories.dbc) pkt << uint8(0x2C); // unk, may be realm number/id? if (realmFlags & REALM_FLAG_SPECIFYBUILD) { pkt << uint8(buildInfo->major_version); pkt << uint8(buildInfo->minor_version); pkt << uint8(buildInfo->bugfix_version); pkt << uint16(_build); } } pkt << uint16(0x0010); // unused value (why 10?) break; } } }
void RealmList::UpdateRealms(boost::system::error_code const& error) { if (error) return; TC_LOG_DEBUG("realmlist", "Updating Realm List..."); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); PreparedQueryResult result = LoginDatabase.Query(stmt); // Circle through results and add them to the realm map if (result) { do { try { boost::asio::ip::tcp::resolver::iterator end; Field* fields = result->Fetch(); std::string name = fields[1].GetString(); boost::asio::ip::tcp::resolver::query externalAddressQuery(ip::tcp::v4(), fields[2].GetString(), ""); boost::system::error_code ec; boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery, ec); if (endPoint == end || ec) { TC_LOG_ERROR("realmlist", "Could not resolve address %s", fields[2].GetString().c_str()); continue; } ip::address externalAddress = (*endPoint).endpoint().address(); boost::asio::ip::tcp::resolver::query localAddressQuery(ip::tcp::v4(), fields[3].GetString(), ""); endPoint = _resolver->resolve(localAddressQuery, ec); if (endPoint == end || ec) { TC_LOG_ERROR("realmlist", "Could not resolve address %s", fields[3].GetString().c_str()); continue; } ip::address localAddress = (*endPoint).endpoint().address(); boost::asio::ip::tcp::resolver::query localSubmaskQuery(ip::tcp::v4(), fields[4].GetString(), ""); endPoint = _resolver->resolve(localSubmaskQuery, ec); if (endPoint == end || ec) { TC_LOG_ERROR("realmlist", "Could not resolve address %s", fields[4].GetString().c_str()); continue; } ip::address localSubmask = (*endPoint).endpoint().address(); uint16 port = fields[5].GetUInt16(); uint8 icon = fields[6].GetUInt8(); RealmFlags flag = RealmFlags(fields[7].GetUInt8()); uint8 timezone = fields[8].GetUInt8(); uint8 allowedSecurityLevel = fields[9].GetUInt8(); float pop = fields[10].GetFloat(); uint32 realmId = fields[0].GetUInt32(); uint32 build = fields[11].GetUInt32(); uint8 region = fields[12].GetUInt8(); uint8 battlegroup = fields[13].GetUInt8(); Battlenet::RealmId id{ region, battlegroup, realmId, build }; UpdateRealm(id, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop); TC_LOG_TRACE("realmlist", "Realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port); } catch (std::exception& ex) { TC_LOG_ERROR("realmlist", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what()); ASSERT(false); } } while (result->NextRow()); } std::vector<Realm const*> updatedRealms; std::vector<Battlenet::RealmId> deletedRealms; for (RealmMap::value_type& pair : _realms) { if (pair.second.Updated) updatedRealms.push_back(&pair.second); else if (!pair.second.Keep) deletedRealms.push_back(pair.first); pair.second.Updated = false; pair.second.Keep = false; } for (Battlenet::RealmId const& deleted : deletedRealms) _realms.erase(deleted); if (!updatedRealms.empty() || !deletedRealms.empty()) { sSessionMgr.LockedForEach([&updatedRealms, &deletedRealms](Battlenet::Session* session) { if (session->IsSubscribedToRealmListUpdates()) session->UpdateRealms(updatedRealms, deletedRealms); }); } if (_updateInterval) { _updateTimer->expires_from_now(boost::posix_time::seconds(_updateInterval)); _updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, std::placeholders::_1)); } }