1#include <base/mem.h>
2
3#include <engine/shared/masterserver.h>
4
5#include <game/client/gameclient.h>
6
7void CClient::PreprocessConnlessPacket7(CNetChunk *pPacket)
8{
9 if(mem_comp(a: pPacket->m_pData, b: SERVERBROWSE_INFO, size: sizeof(SERVERBROWSE_INFO)) == 0)
10 {
11 CUnpacker Up;
12 Up.Reset(pData: (unsigned char *)pPacket->m_pData + sizeof(SERVERBROWSE_INFO), Size: pPacket->m_DataSize - sizeof(SERVERBROWSE_INFO));
13 CServerInfo Info = {};
14
15 auto GetString = [&Up](auto &Buf) {
16 str_copy(Buf, Up.GetString(SanitizeType: CUnpacker::SANITIZE_CC | CUnpacker::SKIP_START_WHITESPACES));
17 };
18
19 TOKEN Token = Up.GetInt();
20 GetString(Info.m_aVersion);
21 GetString(Info.m_aName);
22 str_clean_whitespaces(str: Info.m_aName);
23
24 Up.GetString(SanitizeType: CUnpacker::SANITIZE_CC | CUnpacker::SKIP_START_WHITESPACES); // Hostname
25 GetString(Info.m_aMap);
26 GetString(Info.m_aGameType);
27 Info.m_Flags = Up.GetInt();
28 Up.GetInt(); // Server level
29 Info.m_NumPlayers = Up.GetInt();
30 Info.m_MaxPlayers = Up.GetInt();
31 Info.m_NumClients = Up.GetInt();
32 Info.m_MaxClients = Up.GetInt();
33
34 for(int i = 0; i < Info.m_NumClients; i++)
35 {
36 GetString(Info.m_aClients[i].m_aName);
37 GetString(Info.m_aClients[i].m_aClan);
38 Info.m_aClients[i].m_Country = Up.GetInt();
39 if(!in_range(a: Info.m_aClients[i].m_Country, lower: CountryCode::MINIMUM, upper: CountryCode::MAXIMUM))
40 {
41 Info.m_aClients[i].m_Country = CountryCode::DEFAULT;
42 }
43 Info.m_aClients[i].m_Score = Up.GetInt();
44 Info.m_aClients[i].m_Player = !(Up.GetInt() & 1);
45 }
46
47 const bool IsNotVanilla = Info.m_MaxPlayers > VANILLA_MAX_CLIENTS || Info.m_MaxClients > VANILLA_MAX_CLIENTS;
48 CPacker Packer;
49 Packer.Reset();
50
51 auto PutInt = [&Packer](int Num) {
52 char aBuf[16];
53 str_format(buffer: aBuf, buffer_size: sizeof(aBuf), format: "%d", Num);
54 Packer.AddString(pStr: aBuf);
55 };
56
57 if(!IsNotVanilla)
58 {
59 Token = Token & 0xff;
60 }
61 PutInt(Token);
62 Packer.AddString(pStr: Info.m_aVersion);
63 Packer.AddString(pStr: Info.m_aName);
64 Packer.AddString(pStr: Info.m_aMap);
65
66 if(IsNotVanilla)
67 {
68 PutInt(0); // map crc
69 PutInt(0); // map size
70 }
71
72 Packer.AddString(pStr: Info.m_aGameType);
73
74 PutInt(Info.m_Flags);
75 PutInt(Info.m_NumPlayers);
76 PutInt(Info.m_MaxPlayers);
77 PutInt(Info.m_NumClients);
78 PutInt(Info.m_MaxClients);
79
80 if(IsNotVanilla)
81 {
82 Packer.AddString(pStr: ""); // extra info, reserved
83 }
84
85 for(int i = 0; i < Info.m_NumClients; i++)
86 {
87 Packer.AddString(pStr: Info.m_aClients[i].m_aName);
88 Packer.AddString(pStr: Info.m_aClients[i].m_aClan);
89
90 PutInt(Info.m_aClients[i].m_Country);
91 PutInt(Info.m_aClients[i].m_Score);
92 PutInt(Info.m_aClients[i].m_Player);
93
94 if(IsNotVanilla)
95 {
96 Packer.AddString(pStr: ""); // extra info, reserved
97 }
98 }
99
100 if(IsNotVanilla)
101 {
102 mem_copy(dest: (unsigned char *)pPacket->m_pData, source: SERVERBROWSE_INFO_EXTENDED, size: sizeof(SERVERBROWSE_INFO_EXTENDED));
103 }
104 mem_copy(dest: (unsigned char *)pPacket->m_pData + SERVERBROWSE_SIZE, source: Packer.Data(), size: Packer.Size());
105 pPacket->m_DataSize = SERVERBROWSE_SIZE + Packer.Size();
106 }
107}
108