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 | }; |
125 | |
126 | class |
127 | { |
128 | NETADDR ; |
129 | char [CServerInfo::MAX_COMMUNITY_TYPE_LENGTH]; |
130 | |
131 | public: |
132 | (NETADDR Address, const char *pTypeName) : |
133 | m_Address(Address) |
134 | { |
135 | str_copy(dst&: m_aTypeName, src: pTypeName); |
136 | } |
137 | |
138 | NETADDR () const { return m_Address; } |
139 | const char *() const { return m_aTypeName; } |
140 | }; |
141 | |
142 | class |
143 | { |
144 | friend class CServerBrowser; |
145 | |
146 | char [CServerInfo::MAX_COMMUNITY_COUNTRY_LENGTH]; |
147 | int ; |
148 | std::vector<CCommunityCountryServer> ; |
149 | |
150 | public: |
151 | (const char *pName, int FlagId) : |
152 | m_FlagId(FlagId) |
153 | { |
154 | str_copy(dst&: m_aName, src: pName); |
155 | } |
156 | |
157 | const char *() const { return m_aName; } |
158 | int () const { return m_FlagId; } |
159 | const std::vector<CCommunityCountryServer> &() const { return m_vServers; } |
160 | }; |
161 | |
162 | class |
163 | { |
164 | char [CServerInfo::MAX_COMMUNITY_TYPE_LENGTH]; |
165 | |
166 | public: |
167 | (const char *pName) |
168 | { |
169 | str_copy(dst&: m_aName, src: pName); |
170 | } |
171 | |
172 | const char *() const { return m_aName; } |
173 | }; |
174 | |
175 | class |
176 | { |
177 | char [MAX_MAP_LENGTH]; |
178 | |
179 | public: |
180 | (const char *pName) |
181 | { |
182 | str_copy(dst&: m_aName, src: pName); |
183 | } |
184 | |
185 | const char *() const { return m_aName; } |
186 | |
187 | bool (const CCommunityMap &Other) const |
188 | { |
189 | return str_comp(a: Name(), b: Other.Name()) == 0; |
190 | } |
191 | |
192 | bool (const CCommunityMap &Other) const |
193 | { |
194 | return !(*this == Other); |
195 | } |
196 | |
197 | struct |
198 | { |
199 | size_t (const CCommunityMap &Map) const |
200 | { |
201 | return str_quickhash(str: Map.Name()); |
202 | } |
203 | }; |
204 | }; |
205 | |
206 | class |
207 | { |
208 | friend class CServerBrowser; |
209 | |
210 | char [CServerInfo::MAX_COMMUNITY_ID_LENGTH]; |
211 | char [64]; |
212 | SHA256_DIGEST ; |
213 | char [128]; |
214 | std::vector<CCommunityCountry> ; |
215 | std::vector<CCommunityType> ; |
216 | bool = false; |
217 | std::unordered_set<CCommunityMap, CCommunityMap::SHash> ; |
218 | |
219 | public: |
220 | (const char *pId, const char *pName, SHA256_DIGEST IconSha256, const char *pIconUrl) : |
221 | m_IconSha256(IconSha256) |
222 | { |
223 | str_copy(dst&: m_aId, src: pId); |
224 | str_copy(dst&: m_aName, src: pName); |
225 | str_copy(dst&: m_aIconUrl, src: pIconUrl); |
226 | } |
227 | |
228 | const char *() const { return m_aId; } |
229 | const char *() const { return m_aName; } |
230 | const char *() const { return m_aIconUrl; } |
231 | const SHA256_DIGEST &() const { return m_IconSha256; } |
232 | const std::vector<CCommunityCountry> &() const { return m_vCountries; } |
233 | const std::vector<CCommunityType> &() const { return m_vTypes; } |
234 | bool (const char *pCountryName) const; |
235 | bool (const char *pTypeName) const; |
236 | bool () const { return m_HasFinishes; } |
237 | CServerInfo::ERankState (const char *pMap) const; |
238 | }; |
239 | |
240 | class IFilterList |
241 | { |
242 | public: |
243 | virtual void Add(const char *pElement) = 0; |
244 | virtual void Remove(const char *pElement) = 0; |
245 | virtual void Clear() = 0; |
246 | virtual bool Empty() const = 0; |
247 | virtual bool Filtered(const char *pElement) const = 0; |
248 | }; |
249 | |
250 | class |
251 | { |
252 | public: |
253 | virtual void (bool Force) = 0; |
254 | virtual const std::vector<const CCommunity *> &() const = 0; |
255 | virtual const std::vector<const CCommunityCountry *> &() const = 0; |
256 | virtual const std::vector<const CCommunityType *> &() const = 0; |
257 | virtual bool () const = 0; |
258 | virtual bool () const = 0; |
259 | virtual const char *() const = 0; |
260 | }; |
261 | |
262 | class IServerBrowser : public IInterface |
263 | { |
264 | MACRO_INTERFACE("serverbrowser" ) |
265 | public: |
266 | /* Constants: Server Browser Sorting |
267 | SORT_NAME - Sort by name. |
268 | SORT_PING - Sort by ping. |
269 | SORT_MAP - Sort by map |
270 | SORT_GAMETYPE - Sort by game type. DM, TDM etc. |
271 | SORT_NUMPLAYERS - Sort after how many players there are on the server. |
272 | SORT_NUMFRIENDS - Sort after how many friends there are on the server. |
273 | */ |
274 | enum |
275 | { |
276 | SORT_NAME = 0, |
277 | SORT_PING, |
278 | SORT_MAP, |
279 | SORT_GAMETYPE, |
280 | SORT_NUMPLAYERS, |
281 | SORT_NUMFRIENDS, |
282 | |
283 | QUICK_SERVERNAME = 1, |
284 | QUICK_PLAYER = 2, |
285 | QUICK_MAPNAME = 4, |
286 | |
287 | TYPE_INTERNET = 0, |
288 | TYPE_LAN, |
289 | TYPE_FAVORITES, |
290 | , |
291 | , |
292 | , |
293 | , |
294 | , |
295 | NUM_TYPES, |
296 | }; |
297 | |
298 | static constexpr const char * = "ddnet" ; |
299 | static constexpr const char * = "none" ; |
300 | /** |
301 | * Special community value for country/type filters that |
302 | * affect all communities. |
303 | */ |
304 | static constexpr const char * = "all" ; |
305 | |
306 | static constexpr const char *SEARCH_EXCLUDE_TOKEN = ";" ; |
307 | |
308 | virtual void Refresh(int Type, bool Force = false) = 0; |
309 | virtual bool IsGettingServerlist() const = 0; |
310 | virtual bool IsRefreshing() const = 0; |
311 | virtual int LoadingProgression() const = 0; |
312 | |
313 | virtual int NumServers() const = 0; |
314 | |
315 | virtual int Players(const CServerInfo &Item) const = 0; |
316 | virtual int Max(const CServerInfo &Item) const = 0; |
317 | |
318 | virtual int NumSortedServers() const = 0; |
319 | virtual int NumSortedPlayers() const = 0; |
320 | virtual const CServerInfo *SortedGet(int Index) const = 0; |
321 | |
322 | virtual const std::vector<CCommunity> &Communities() const = 0; |
323 | virtual const CCommunity *(const char *) const = 0; |
324 | virtual std::vector<const CCommunity *> SelectedCommunities() const = 0; |
325 | virtual std::vector<const CCommunity *> FavoriteCommunities() const = 0; |
326 | virtual std::vector<const CCommunity *> CurrentCommunities() const = 0; |
327 | virtual unsigned CurrentCommunitiesHash() const = 0; |
328 | |
329 | virtual bool DDNetInfoAvailable() const = 0; |
330 | virtual SHA256_DIGEST DDNetInfoSha256() const = 0; |
331 | |
332 | virtual ICommunityCache &() = 0; |
333 | virtual const ICommunityCache &() const = 0; |
334 | virtual IFilterList &FavoriteCommunitiesFilter() = 0; |
335 | virtual IFilterList &CommunitiesFilter() = 0; |
336 | virtual IFilterList &CountriesFilter() = 0; |
337 | virtual IFilterList &TypesFilter() = 0; |
338 | virtual const IFilterList &FavoriteCommunitiesFilter() const = 0; |
339 | virtual const IFilterList &CommunitiesFilter() const = 0; |
340 | virtual const IFilterList &CountriesFilter() const = 0; |
341 | virtual const IFilterList &TypesFilter() const = 0; |
342 | virtual void CleanFilters() = 0; |
343 | |
344 | virtual int GetCurrentType() = 0; |
345 | virtual const char *GetTutorialServer() = 0; |
346 | }; |
347 | |
348 | #endif |
349 | |