void AuthSession::RealmListCallback(PreparedQueryResult result) { std::map characterCounts; if (result) { do { Field* fields = result->Fetch(); characterCounts[fields[0].GetUInt32()] = fields[1].GetUInt8(); } while (result->NextRow()); } // Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) ByteBuffer pkt; size_t RealmListSize = 0; for (RealmList::RealmMap::value_type const& i : sRealmList->GetRealms()) { Realm const& realm = i.second; // don't work with realms which not compatible with the client bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && realm.Build == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(realm.Build)); // No SQL injection. id of realm is controlled by the database. uint32 flag = realm.Flags; RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.Build); if (!okBuild) { if (!buildInfo) continue; flag |= REALM_FLAG_OFFLINE | REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for } if (!buildInfo) flag &= ~REALM_FLAG_SPECIFYBUILD; std::string name = realm.Name; if (_expversion & PRE_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD) { std::ostringstream ss; ss << name << " (" << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << ')'; name = ss.str(); } uint8 lock = (realm.AllowedSecurityLevel > _accountInfo.SecurityLevel) ? 1 : 0; pkt << uint8(realm.Type); // realm type if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients pkt << uint8(lock); // if 1, then realm locked pkt << uint8(flag); // RealmFlags pkt << name; pkt << boost::lexical_cast(realm.GetAddressForClient(GetRemoteIpAddress())); pkt << float(realm.PopulationLevel); pkt << uint8(characterCounts[realm.Id.Realm]); pkt << uint8(realm.Timezone); // realm category if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients pkt << uint8(realm.Id.Realm); else pkt << uint8(0x0); // 1.12.1 and 1.12.2 clients if (_expversion & POST_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD) { pkt << uint8(buildInfo->MajorVersion); pkt << uint8(buildInfo->MinorVersion); pkt << uint8(buildInfo->BugfixVersion); pkt << uint16(buildInfo->Build); } ++RealmListSize; } if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients { pkt << uint8(0x10); pkt << uint8(0x00); } else // 1.12.1 and 1.12.2 clients { pkt << uint8(0x00); pkt << uint8(0x02); } // make a ByteBuffer which stores the RealmList's size ByteBuffer RealmListSizeBuffer; RealmListSizeBuffer << uint32(0); if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients RealmListSizeBuffer << uint16(RealmListSize); else RealmListSizeBuffer << uint32(RealmListSize); ByteBuffer hdr; hdr << uint8(REALM_LIST); hdr << uint16(pkt.size() + RealmListSizeBuffer.size()); hdr.append(RealmListSizeBuffer); // append RealmList's size buffer hdr.append(pkt); // append realms in the realmlist SendPacket(hdr); _status = STATUS_AUTHED; }