1 | /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ |
2 | /* If you are missing that file, acquire a complete release at teeworlds.com. */ |
3 | #ifndef ENGINE_SERVERBROWSER_H |
4 | #define ENGINE_SERVERBROWSER_H |
5 | |
6 | #include <base/hash.h> |
7 | #include <base/system.h> |
8 | |
9 | #include <engine/map.h> |
10 | #include <engine/shared/protocol.h> |
11 | |
12 | #include "kernel.h" |
13 | |
14 | #include <unordered_set> |
15 | #include <vector> |
16 | |
17 | static constexpr const char *DDNET_INFO_FILE = "ddnet-info.json" ; |
18 | static constexpr const char *DDNET_INFO_URL = "https://info.ddnet.org/info" ; |
19 | |
20 | class CUIElement; |
21 | |
22 | class CServerInfo |
23 | { |
24 | public: |
25 | enum |
26 | { |
27 | LOC_UNKNOWN = 0, |
28 | LOC_AFRICA, |
29 | LOC_ASIA, |
30 | LOC_AUSTRALIA, |
31 | LOC_EUROPE, |
32 | LOC_NORTH_AMERICA, |
33 | LOC_SOUTH_AMERICA, |
34 | // Special case China because it has an exceptionally bad |
35 | // connection to the outside due to the Great Firewall of |
36 | // China: |
37 | // https://en.wikipedia.org/w/index.php?title=Great_Firewall&oldid=1019589632 |
38 | LOC_CHINA, |
39 | NUM_LOCS, |
40 | }; |
41 | |
42 | enum EClientScoreKind |
43 | { |
44 | CLIENT_SCORE_KIND_UNSPECIFIED, |
45 | CLIENT_SCORE_KIND_POINTS, |
46 | CLIENT_SCORE_KIND_TIME, |
47 | CLIENT_SCORE_KIND_TIME_BACKCOMPAT, |
48 | }; |
49 | |
50 | enum ERankState |
51 | { |
52 | RANK_UNAVAILABLE, |
53 | RANK_RANKED, |
54 | RANK_UNRANKED, |
55 | }; |
56 | |
57 | enum |
58 | { |
59 | = 32, |
60 | = 32, |
61 | = 32, |
62 | }; |
63 | |
64 | class CClient |
65 | { |
66 | public: |
67 | char m_aName[MAX_NAME_LENGTH]; |
68 | char m_aClan[MAX_CLAN_LENGTH]; |
69 | int m_Country; |
70 | int m_Score; |
71 | bool m_Player; |
72 | bool m_Afk; |
73 | |
74 | // skin info |
75 | char m_aSkin[24 + 1]; |
76 | bool m_CustomSkinColors; |
77 | int m_CustomSkinColorBody; |
78 | int m_CustomSkinColorFeet; |
79 | |
80 | int m_FriendState; |
81 | }; |
82 | |
83 | int m_ServerIndex; |
84 | |
85 | int m_Type; |
86 | uint64_t m_ReceivedPackets; |
87 | int m_NumReceivedClients; |
88 | |
89 | int m_NumAddresses; |
90 | NETADDR m_aAddresses[MAX_SERVER_ADDRESSES]; |
91 | |
92 | int m_QuickSearchHit; |
93 | int m_FriendState; |
94 | int m_FriendNum; |
95 | |
96 | int m_MaxClients; |
97 | int m_NumClients; |
98 | int m_MaxPlayers; |
99 | int m_NumPlayers; |
100 | int m_Flags; |
101 | EClientScoreKind m_ClientScoreKind; |
102 | TRISTATE m_Favorite; |
103 | TRISTATE m_FavoriteAllowPing; |
104 | char [MAX_COMMUNITY_ID_LENGTH]; |
105 | char [MAX_COMMUNITY_COUNTRY_LENGTH]; |
106 | char [MAX_COMMUNITY_TYPE_LENGTH]; |
107 | int m_Location; |
108 | bool m_LatencyIsEstimated; |
109 | int m_Latency; // in ms |
110 | ERankState m_HasRank; |
111 | char m_aGameType[16]; |
112 | char m_aName[64]; |
113 | char m_aMap[MAX_MAP_LENGTH]; |
114 | int m_MapCrc; |
115 | int m_MapSize; |
116 | char m_aVersion[32]; |
117 | char m_aAddress[MAX_SERVER_ADDRESSES * NETADDR_MAXSTRSIZE]; |
118 | CClient m_aClients[SERVERINFO_MAX_CLIENTS]; |
119 | int m_NumFilteredPlayers; |
120 | bool m_RequiresLogin; |
121 | |
122 | static int EstimateLatency(int Loc1, int Loc2); |
123 | static bool ParseLocation(int *pResult, const char *pString); |
124 | void InfoToString(char *pBuffer, int BufferSize) const; |
125 | }; |
126 | |
127 | class |
128 | { |
129 | NETADDR ; |
130 | char [CServerInfo::MAX_COMMUNITY_TYPE_LENGTH]; |
131 | |
132 | public: |
133 | (NETADDR Address, const char *pTypeName) : |
134 | m_Address(Address) |
135 | { |
136 | str_copy(dst&: m_aTypeName, src: pTypeName); |
137 | } |
138 | |
139 | NETADDR () const { return m_Address; } |
140 | const char *() const { return m_aTypeName; } |
141 | }; |
142 | |
143 | class |
144 | { |
145 | friend class CServerBrowser; |
146 | |
147 | char [CServerInfo::MAX_COMMUNITY_COUNTRY_LENGTH]; |
148 | int ; |
149 | std::vector<CCommunityCountryServer> ; |
150 | |
151 | public: |
152 | (const char *pName, int FlagId) : |
153 | m_FlagId(FlagId) |
154 | { |
155 | str_copy(dst&: m_aName, src: pName); |
156 | } |
157 | |
158 | const char *() const { return m_aName; } |
159 | int () const { return m_FlagId; } |
160 | const std::vector<CCommunityCountryServer> &() const { return m_vServers; } |
161 | }; |
162 | |
163 | class |
164 | { |
165 | char [CServerInfo::MAX_COMMUNITY_TYPE_LENGTH]; |
166 | |
167 | public: |
168 | (const char *pName) |
169 | { |
170 | str_copy(dst&: m_aName, src: pName); |
171 | } |
172 | |
173 | const char *() const { return m_aName; } |
174 | }; |
175 | |
176 | class |
177 | { |
178 | char [MAX_MAP_LENGTH]; |
179 | |
180 | public: |
181 | (const char *pName) |
182 | { |
183 | str_copy(dst&: m_aName, src: pName); |
184 | } |
185 | |
186 | const char *() const { return m_aName; } |
187 | |
188 | bool (const CCommunityMap &Other) const |
189 | { |
190 | return str_comp(a: Name(), b: Other.Name()) == 0; |
191 | } |
192 | |
193 | bool (const CCommunityMap &Other) const |
194 | { |
195 | return !(*this == Other); |
196 | } |
197 | |
198 | struct |
199 | { |
200 | size_t (const CCommunityMap &Map) const |
201 | { |
202 | return str_quickhash(str: Map.Name()); |
203 | } |
204 | }; |
205 | }; |
206 | |
207 | class |
208 | { |
209 | friend class CServerBrowser; |
210 | |
211 | char [CServerInfo::MAX_COMMUNITY_ID_LENGTH]; |
212 | char [64]; |
213 | SHA256_DIGEST ; |
214 | char [128]; |
215 | std::vector<CCommunityCountry> ; |
216 | std::vector<CCommunityType> ; |
217 | bool = false; |
218 | std::unordered_set<CCommunityMap, CCommunityMap::SHash> ; |
219 | |
220 | public: |
221 | (const char *pId, const char *pName, SHA256_DIGEST IconSha256, const char *pIconUrl) : |
222 | m_IconSha256(IconSha256) |
223 | { |
224 | str_copy(dst&: m_aId, src: pId); |
225 | str_copy(dst&: m_aName, src: pName); |
226 | str_copy(dst&: m_aIconUrl, src: pIconUrl); |
227 | } |
228 | |
229 | const char *() const { return m_aId; } |
230 | const char *() const { return m_aName; } |
231 | const char *() const { return m_aIconUrl; } |
232 | const SHA256_DIGEST &() const { return m_IconSha256; } |
233 | const std::vector<CCommunityCountry> &() const { return m_vCountries; } |
234 | const std::vector<CCommunityType> &() const { return m_vTypes; } |
235 | bool (const char *pCountryName) const; |
236 | bool (const char *pTypeName) const; |
237 | bool () const { return m_HasFinishes; } |
238 | CServerInfo::ERankState (const char *pMap) const; |
239 | }; |
240 | |
241 | class IFilterList |
242 | { |
243 | public: |
244 | virtual void Add(const char *pElement) = 0; |
245 | virtual void Remove(const char *pElement) = 0; |
246 | virtual void Clear() = 0; |
247 | virtual bool Empty() const = 0; |
248 | virtual bool Filtered(const char *pElement) const = 0; |
249 | }; |
250 | |
251 | class |
252 | { |
253 | public: |
254 | virtual void (bool Force) = 0; |
255 | virtual const std::vector<const CCommunity *> &() const = 0; |
256 | virtual const std::vector<const CCommunityCountry *> &() const = 0; |
257 | virtual const std::vector<const CCommunityType *> &() const = 0; |
258 | virtual bool () const = 0; |
259 | virtual bool () const = 0; |
260 | virtual const char *() const = 0; |
261 | }; |
262 | |
263 | class IServerBrowser : public IInterface |
264 | { |
265 | MACRO_INTERFACE("serverbrowser" ) |
266 | public: |
267 | /* Constants: Server Browser Sorting |
268 | SORT_NAME - Sort by name. |
269 | SORT_PING - Sort by ping. |
270 | SORT_MAP - Sort by map |
271 | SORT_GAMETYPE - Sort by game type. DM, TDM etc. |
272 | SORT_NUMPLAYERS - Sort after how many players there are on the server. |
273 | SORT_NUMFRIENDS - Sort after how many friends there are on the server. |
274 | */ |
275 | enum |
276 | { |
277 | SORT_NAME = 0, |
278 | SORT_PING, |
279 | SORT_MAP, |
280 | SORT_GAMETYPE, |
281 | SORT_NUMPLAYERS, |
282 | SORT_NUMFRIENDS, |
283 | |
284 | QUICK_SERVERNAME = 1, |
285 | QUICK_PLAYER = 2, |
286 | QUICK_MAPNAME = 4, |
287 | |
288 | TYPE_INTERNET = 0, |
289 | TYPE_LAN, |
290 | TYPE_FAVORITES, |
291 | , |
292 | , |
293 | , |
294 | , |
295 | , |
296 | NUM_TYPES, |
297 | }; |
298 | |
299 | static constexpr const char * = "ddnet" ; |
300 | static constexpr const char * = "none" ; |
301 | /** |
302 | * Special community value for country/type filters that |
303 | * affect all communities. |
304 | */ |
305 | static constexpr const char * = "all" ; |
306 | |
307 | static constexpr const char *SEARCH_EXCLUDE_TOKEN = ";" ; |
308 | |
309 | virtual void Refresh(int Type, bool Force = false) = 0; |
310 | virtual bool IsGettingServerlist() const = 0; |
311 | virtual bool IsRefreshing() const = 0; |
312 | virtual int LoadingProgression() const = 0; |
313 | |
314 | virtual int NumServers() const = 0; |
315 | |
316 | virtual int Players(const CServerInfo &Item) const = 0; |
317 | virtual int Max(const CServerInfo &Item) const = 0; |
318 | |
319 | virtual int NumSortedServers() const = 0; |
320 | virtual int NumSortedPlayers() const = 0; |
321 | virtual const CServerInfo *SortedGet(int Index) const = 0; |
322 | |
323 | virtual const std::vector<CCommunity> &Communities() const = 0; |
324 | virtual const CCommunity *(const char *) const = 0; |
325 | virtual std::vector<const CCommunity *> SelectedCommunities() const = 0; |
326 | virtual std::vector<const CCommunity *> FavoriteCommunities() const = 0; |
327 | virtual std::vector<const CCommunity *> CurrentCommunities() const = 0; |
328 | virtual unsigned CurrentCommunitiesHash() const = 0; |
329 | |
330 | virtual bool DDNetInfoAvailable() const = 0; |
331 | virtual SHA256_DIGEST DDNetInfoSha256() const = 0; |
332 | |
333 | virtual ICommunityCache &() = 0; |
334 | virtual const ICommunityCache &() const = 0; |
335 | virtual IFilterList &FavoriteCommunitiesFilter() = 0; |
336 | virtual IFilterList &CommunitiesFilter() = 0; |
337 | virtual IFilterList &CountriesFilter() = 0; |
338 | virtual IFilterList &TypesFilter() = 0; |
339 | virtual const IFilterList &FavoriteCommunitiesFilter() const = 0; |
340 | virtual const IFilterList &CommunitiesFilter() const = 0; |
341 | virtual const IFilterList &CountriesFilter() const = 0; |
342 | virtual const IFilterList &TypesFilter() const = 0; |
343 | virtual void CleanFilters() = 0; |
344 | |
345 | virtual int GetCurrentType() = 0; |
346 | virtual const char *GetTutorialServer() = 0; |
347 | }; |
348 | |
349 | #endif |
350 | |