From Sole Dove, 1 Year ago, written in C++.
Embed
  1. void AuthSession::RealmListCallback(PreparedQueryResult result)
  2. {
  3.     std::map<uint32, uint8> characterCounts;
  4.     if (result)
  5.     {
  6.         do
  7.         {
  8.             Field* fields = result->Fetch();
  9.             characterCounts[fields[0].GetUInt32()] = fields[1].GetUInt8();
  10.         } while (result->NextRow());
  11.     }
  12.  
  13.     // Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm)
  14.     ByteBuffer pkt;
  15.  
  16.     size_t RealmListSize = 0;
  17.     for (RealmList::RealmMap::value_type const& i : sRealmList->GetRealms())
  18.     {
  19.         Realm const& realm = i.second;
  20.         // don't work with realms which not compatible with the client
  21.         bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && realm.Build == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(realm.Build));
  22.  
  23.         // No SQL injection. id of realm is controlled by the database.
  24.         uint32 flag = realm.Flags;
  25.         RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.Build);
  26.         if (!okBuild)
  27.         {
  28.             if (!buildInfo)
  29.                 continue;
  30.  
  31.             flag |= REALM_FLAG_OFFLINE | REALM_FLAG_SPECIFYBUILD;   // tell the client what build the realm is for
  32.         }
  33.  
  34.         if (!buildInfo)
  35.             flag &= ~REALM_FLAG_SPECIFYBUILD;
  36.  
  37.         std::string name = realm.Name;
  38.         if (_expversion & PRE_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD)
  39.         {
  40.             std::ostringstream ss;
  41.             ss << name << " (" << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << ')';
  42.             name = ss.str();
  43.         }
  44.  
  45.         uint8 lock = (realm.AllowedSecurityLevel > _accountInfo.SecurityLevel) ? 1 : 0;
  46.  
  47.         pkt << uint8(realm.Type);                           // realm type
  48.         if (_expversion & POST_BC_EXP_FLAG)                 // only 2.x and 3.x clients
  49.             pkt << uint8(lock);                             // if 1, then realm locked
  50.         pkt << uint8(flag);                                 // RealmFlags
  51.         pkt << name;
  52.         pkt << boost::lexical_cast<std::string>(realm.GetAddressForClient(GetRemoteIpAddress()));
  53.         pkt << float(realm.PopulationLevel);
  54.         pkt << uint8(characterCounts[realm.Id.Realm]);
  55.         pkt << uint8(realm.Timezone);                       // realm category
  56.         if (_expversion & POST_BC_EXP_FLAG)                 // 2.x and 3.x clients
  57.             pkt << uint8(realm.Id.Realm);
  58.         else
  59.             pkt << uint8(0x0);                              // 1.12.1 and 1.12.2 clients
  60.  
  61.         if (_expversion & POST_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD)
  62.         {
  63.             pkt << uint8(buildInfo->MajorVersion);
  64.             pkt << uint8(buildInfo->MinorVersion);
  65.             pkt << uint8(buildInfo->BugfixVersion);
  66.             pkt << uint16(buildInfo->Build);
  67.         }
  68.  
  69.         ++RealmListSize;
  70.     }
  71.  
  72.     if (_expversion & POST_BC_EXP_FLAG)                     // 2.x and 3.x clients
  73.     {
  74.         pkt << uint8(0x10);
  75.         pkt << uint8(0x00);
  76.     }
  77.     else                                                    // 1.12.1 and 1.12.2 clients
  78.     {
  79.         pkt << uint8(0x00);
  80.         pkt << uint8(0x02);
  81.     }
  82.  
  83.     // make a ByteBuffer which stores the RealmList's size
  84.     ByteBuffer RealmListSizeBuffer;
  85.     RealmListSizeBuffer << uint32(0);
  86.     if (_expversion & POST_BC_EXP_FLAG)                     // only 2.x and 3.x clients
  87.         RealmListSizeBuffer << uint16(RealmListSize);
  88.     else
  89.         RealmListSizeBuffer << uint32(RealmListSize);
  90.  
  91.     ByteBuffer hdr;
  92.     hdr << uint8(REALM_LIST);
  93.     hdr << uint16(pkt.size() + RealmListSizeBuffer.size());
  94.     hdr.append(RealmListSizeBuffer);                        // append RealmList's size buffer
  95.     hdr.append(pkt);                                        // append realms in the realmlist
  96.     SendPacket(hdr);
  97.  
  98.     _status = STATUS_AUTHED;
  99. }