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 GAME_SERVER_GAMECONTEXT_H
4#define GAME_SERVER_GAMECONTEXT_H
5
6#include <engine/console.h>
7#include <engine/server.h>
8
9#include <game/collision.h>
10#include <game/generated/protocol.h>
11#include <game/layers.h>
12#include <game/mapbugs.h>
13#include <game/voting.h>
14
15#include "eventhandler.h"
16#include "gameworld.h"
17#include "teehistorian.h"
18
19#include <memory>
20#include <string>
21
22/*
23 Tick
24 Game Context (CGameContext::tick)
25 Game World (GAMEWORLD::tick)
26 Reset world if requested (GAMEWORLD::reset)
27 All entities in the world (ENTITY::tick)
28 All entities in the world (ENTITY::tick_defered)
29 Remove entities marked for deletion (GAMEWORLD::remove_entities)
30 Game Controller (GAMECONTROLLER::tick)
31 All players (CPlayer::tick)
32
33
34 Snap
35 Game Context (CGameContext::snap)
36 Game World (GAMEWORLD::snap)
37 All entities in the world (ENTITY::snap)
38 Game Controller (GAMECONTROLLER::snap)
39 Events handler (EVENT_HANDLER::snap)
40 All players (CPlayer::snap)
41
42*/
43
44enum
45{
46 NUM_TUNEZONES = 256
47};
48
49class CCharacter;
50class IConfigManager;
51class CConfig;
52class CHeap;
53class CPlayer;
54class CScore;
55class CUnpacker;
56class IAntibot;
57class IGameController;
58class IEngine;
59class IStorage;
60struct CAntibotRoundData;
61struct CScoreRandomMapResult;
62
63struct CSnapContext
64{
65 CSnapContext(int Version, bool Sixup = false) :
66 m_ClientVersion(Version), m_Sixup(Sixup)
67 {
68 }
69
70 int GetClientVersion() const { return m_ClientVersion; }
71 bool IsSixup() const { return m_Sixup; }
72
73private:
74 int m_ClientVersion;
75 bool m_Sixup;
76};
77
78class CGameContext : public IGameServer
79{
80 IServer *m_pServer;
81 IConfigManager *m_pConfigManager;
82 CConfig *m_pConfig;
83 IConsole *m_pConsole;
84 IEngine *m_pEngine;
85 IStorage *m_pStorage;
86 IAntibot *m_pAntibot;
87 CLayers m_Layers;
88 CCollision m_Collision;
89 protocol7::CNetObjHandler m_NetObjHandler7;
90 CNetObjHandler m_NetObjHandler;
91 CTuningParams m_Tuning;
92 CTuningParams m_aTuningList[NUM_TUNEZONES];
93 std::vector<std::string> m_vCensorlist;
94
95 bool m_TeeHistorianActive;
96 CTeeHistorian m_TeeHistorian;
97 ASYNCIO *m_pTeeHistorianFile;
98 CUuid m_GameUuid;
99 CMapBugs m_MapBugs;
100 CPrng m_Prng;
101
102 bool m_Resetting;
103
104 static void CommandCallback(int ClientId, int FlagMask, const char *pCmd, IConsole::IResult *pResult, void *pUser);
105 static void TeeHistorianWrite(const void *pData, int DataSize, void *pUser);
106
107 static void ConTuneParam(IConsole::IResult *pResult, void *pUserData);
108 static void ConToggleTuneParam(IConsole::IResult *pResult, void *pUserData);
109 static void ConTuneReset(IConsole::IResult *pResult, void *pUserData);
110 static void ConTunes(IConsole::IResult *pResult, void *pUserData);
111 static void ConTuneZone(IConsole::IResult *pResult, void *pUserData);
112 static void ConTuneDumpZone(IConsole::IResult *pResult, void *pUserData);
113 static void ConTuneResetZone(IConsole::IResult *pResult, void *pUserData);
114 static void ConTuneSetZoneMsgEnter(IConsole::IResult *pResult, void *pUserData);
115 static void ConTuneSetZoneMsgLeave(IConsole::IResult *pResult, void *pUserData);
116 static void ConMapbug(IConsole::IResult *pResult, void *pUserData);
117 static void ConSwitchOpen(IConsole::IResult *pResult, void *pUserData);
118 static void ConPause(IConsole::IResult *pResult, void *pUserData);
119 static void ConChangeMap(IConsole::IResult *pResult, void *pUserData);
120 static void ConRandomMap(IConsole::IResult *pResult, void *pUserData);
121 static void ConRandomUnfinishedMap(IConsole::IResult *pResult, void *pUserData);
122 static void ConRestart(IConsole::IResult *pResult, void *pUserData);
123 static void ConBroadcast(IConsole::IResult *pResult, void *pUserData);
124 static void ConSay(IConsole::IResult *pResult, void *pUserData);
125 static void ConSetTeam(IConsole::IResult *pResult, void *pUserData);
126 static void ConSetTeamAll(IConsole::IResult *pResult, void *pUserData);
127 static void ConAddVote(IConsole::IResult *pResult, void *pUserData);
128 static void ConRemoveVote(IConsole::IResult *pResult, void *pUserData);
129 static void ConForceVote(IConsole::IResult *pResult, void *pUserData);
130 static void ConClearVotes(IConsole::IResult *pResult, void *pUserData);
131 static void ConAddMapVotes(IConsole::IResult *pResult, void *pUserData);
132 static void ConVote(IConsole::IResult *pResult, void *pUserData);
133 static void ConVotes(IConsole::IResult *pResult, void *pUserData);
134 static void ConVoteNo(IConsole::IResult *pResult, void *pUserData);
135 static void ConDrySave(IConsole::IResult *pResult, void *pUserData);
136 static void ConDumpAntibot(IConsole::IResult *pResult, void *pUserData);
137 static void ConAntibot(IConsole::IResult *pResult, void *pUserData);
138 static void ConchainSpecialMotdupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
139 static void ConchainSettingUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
140 static void ConDumpLog(IConsole::IResult *pResult, void *pUserData);
141
142 void Construct(int Resetting);
143 void Destruct(int Resetting);
144 void AddVote(const char *pDescription, const char *pCommand);
145 static int MapScan(const char *pName, int IsDir, int DirType, void *pUserData);
146
147 struct CPersistentData
148 {
149 CUuid m_PrevGameUuid;
150 };
151
152 struct CPersistentClientData
153 {
154 bool m_IsSpectator;
155 bool m_IsAfk;
156 };
157
158public:
159 IServer *Server() const { return m_pServer; }
160 IConfigManager *ConfigManager() const { return m_pConfigManager; }
161 CConfig *Config() { return m_pConfig; }
162 IConsole *Console() { return m_pConsole; }
163 IEngine *Engine() { return m_pEngine; }
164 IStorage *Storage() { return m_pStorage; }
165 CCollision *Collision() { return &m_Collision; }
166 CTuningParams *Tuning() { return &m_Tuning; }
167 CTuningParams *TuningList() { return &m_aTuningList[0]; }
168 IAntibot *Antibot() { return m_pAntibot; }
169 CTeeHistorian *TeeHistorian() { return &m_TeeHistorian; }
170 bool TeeHistorianActive() const { return m_TeeHistorianActive; }
171
172 CGameContext();
173 CGameContext(int Reset);
174 ~CGameContext();
175
176 void Clear();
177
178 CEventHandler m_Events;
179 CPlayer *m_apPlayers[MAX_CLIENTS];
180 // keep last input to always apply when none is sent
181 CNetObj_PlayerInput m_aLastPlayerInput[MAX_CLIENTS];
182 bool m_aPlayerHasInput[MAX_CLIENTS];
183
184 // returns last input if available otherwise nulled PlayerInput object
185 // ClientId has to be valid
186 CNetObj_PlayerInput GetLastPlayerInput(int ClientId) const;
187
188 IGameController *m_pController;
189 CGameWorld m_World;
190
191 // helper functions
192 class CCharacter *GetPlayerChar(int ClientId);
193 bool EmulateBug(int Bug);
194 std::vector<SSwitchers> &Switchers() { return m_World.m_Core.m_vSwitchers; }
195
196 // voting
197 void StartVote(const char *pDesc, const char *pCommand, const char *pReason, const char *pSixupDesc);
198 void EndVote();
199 void SendVoteSet(int ClientId);
200 void SendVoteStatus(int ClientId, int Total, int Yes, int No);
201 void AbortVoteKickOnDisconnect(int ClientId);
202
203 int m_VoteCreator;
204 int m_VoteType;
205 int64_t m_VoteCloseTime;
206 bool m_VoteUpdate;
207 int m_VotePos;
208 char m_aVoteDescription[VOTE_DESC_LENGTH];
209 char m_aSixupVoteDescription[VOTE_DESC_LENGTH];
210 char m_aVoteCommand[VOTE_CMD_LENGTH];
211 char m_aVoteReason[VOTE_REASON_LENGTH];
212 int m_NumVoteOptions;
213 int m_VoteEnforce;
214 char m_aaZoneEnterMsg[NUM_TUNEZONES][256]; // 0 is used for switching from or to area without tunings
215 char m_aaZoneLeaveMsg[NUM_TUNEZONES][256];
216
217 void CreateAllEntities(bool Initial);
218
219 char m_aDeleteTempfile[128];
220 void DeleteTempfile();
221
222 enum
223 {
224 VOTE_ENFORCE_UNKNOWN = 0,
225 VOTE_ENFORCE_NO,
226 VOTE_ENFORCE_YES,
227 VOTE_ENFORCE_NO_ADMIN,
228 VOTE_ENFORCE_YES_ADMIN,
229 VOTE_ENFORCE_ABORT,
230 VOTE_ENFORCE_CANCEL,
231 };
232 CHeap *m_pVoteOptionHeap;
233 CVoteOptionServer *m_pVoteOptionFirst;
234 CVoteOptionServer *m_pVoteOptionLast;
235
236 // helper functions
237 void CreateDamageInd(vec2 Pos, float AngleMod, int Amount, CClientMask Mask = CClientMask().set());
238 void CreateExplosion(vec2 Pos, int Owner, int Weapon, bool NoDamage, int ActivatedTeam, CClientMask Mask = CClientMask().set());
239 void CreateHammerHit(vec2 Pos, CClientMask Mask = CClientMask().set());
240 void CreatePlayerSpawn(vec2 Pos, CClientMask Mask = CClientMask().set());
241 void CreateDeath(vec2 Pos, int ClientId, CClientMask Mask = CClientMask().set());
242 void CreateSound(vec2 Pos, int Sound, CClientMask Mask = CClientMask().set());
243 void CreateSoundGlobal(int Sound, int Target = -1) const;
244
245 void SnapSwitchers(int SnappingClient);
246 bool SnapLaserObject(const CSnapContext &Context, int SnapId, const vec2 &To, const vec2 &From, int StartTick, int Owner = -1, int LaserType = -1, int Subtype = -1, int SwitchNumber = -1) const;
247 bool SnapPickup(const CSnapContext &Context, int SnapId, const vec2 &Pos, int Type, int SubType, int SwitchNumber) const;
248
249 enum
250 {
251 CHAT_ALL = -2,
252 CHAT_SPEC = -1,
253 CHAT_RED = 0,
254 CHAT_BLUE = 1,
255 CHAT_WHISPER_SEND = 2,
256 CHAT_WHISPER_RECV = 3,
257
258 CHAT_SIX = 1 << 0,
259 CHAT_SIXUP = 1 << 1,
260 };
261
262 // network
263 void CallVote(int ClientId, const char *pDesc, const char *pCmd, const char *pReason, const char *pChatmsg, const char *pSixupDesc = 0);
264 void SendChatTarget(int To, const char *pText, int Flags = CHAT_SIX | CHAT_SIXUP) const;
265 void SendChatTeam(int Team, const char *pText) const;
266 void SendChat(int ClientId, int Team, const char *pText, int SpamProtectionClientId = -1, int Flags = CHAT_SIX | CHAT_SIXUP);
267 void SendStartWarning(int ClientId, const char *pMessage);
268 void SendEmoticon(int ClientId, int Emoticon, int TargetClientId) const;
269 void SendWeaponPickup(int ClientId, int Weapon) const;
270 void SendMotd(int ClientId) const;
271 void SendSettings(int ClientId) const;
272 void SendBroadcast(const char *pText, int ClientId, bool IsImportant = true);
273
274 void List(int ClientId, const char *pFilter);
275
276 //
277 void CheckPureTuning();
278 void SendTuningParams(int ClientId, int Zone = 0);
279
280 const CVoteOptionServer *GetVoteOption(int Index) const;
281 void ProgressVoteOptions(int ClientId);
282
283 //
284 void LoadMapSettings();
285
286 // engine events
287 void OnInit(const void *pPersistentData) override;
288 void OnConsoleInit() override;
289 void RegisterDDRaceCommands();
290 void RegisterChatCommands();
291 void OnMapChange(char *pNewMapName, int MapNameSize) override;
292 void OnShutdown(void *pPersistentData) override;
293
294 void OnTick() override;
295 void OnPreSnap() override;
296 void OnSnap(int ClientId) override;
297 void OnPostSnap() override;
298
299 void UpdatePlayerMaps();
300
301 void *PreProcessMsg(int *pMsgId, CUnpacker *pUnpacker, int ClientId);
302 void CensorMessage(char *pCensoredMessage, const char *pMessage, int Size);
303 void OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId) override;
304 void OnSayNetMessage(const CNetMsg_Cl_Say *pMsg, int ClientId, const CUnpacker *pUnpacker);
305 void OnCallVoteNetMessage(const CNetMsg_Cl_CallVote *pMsg, int ClientId);
306 void OnVoteNetMessage(const CNetMsg_Cl_Vote *pMsg, int ClientId);
307 void OnSetTeamNetMessage(const CNetMsg_Cl_SetTeam *pMsg, int ClientId);
308 void OnIsDDNetLegacyNetMessage(const CNetMsg_Cl_IsDDNetLegacy *pMsg, int ClientId, CUnpacker *pUnpacker);
309 void OnShowOthersLegacyNetMessage(const CNetMsg_Cl_ShowOthersLegacy *pMsg, int ClientId);
310 void OnShowOthersNetMessage(const CNetMsg_Cl_ShowOthers *pMsg, int ClientId);
311 void OnShowDistanceNetMessage(const CNetMsg_Cl_ShowDistance *pMsg, int ClientId);
312 void OnSetSpectatorModeNetMessage(const CNetMsg_Cl_SetSpectatorMode *pMsg, int ClientId);
313 void OnChangeInfoNetMessage(const CNetMsg_Cl_ChangeInfo *pMsg, int ClientId);
314 void OnEmoticonNetMessage(const CNetMsg_Cl_Emoticon *pMsg, int ClientId);
315 void OnKillNetMessage(const CNetMsg_Cl_Kill *pMsg, int ClientId);
316 void OnStartInfoNetMessage(const CNetMsg_Cl_StartInfo *pMsg, int ClientId);
317
318 bool OnClientDataPersist(int ClientId, void *pData) override;
319 void OnClientConnected(int ClientId, void *pData) override;
320 void OnClientEnter(int ClientId) override;
321 void OnClientDrop(int ClientId, const char *pReason) override;
322 void OnClientPrepareInput(int ClientId, void *pInput) override;
323 void OnClientDirectInput(int ClientId, void *pInput) override;
324 void OnClientPredictedInput(int ClientId, void *pInput) override;
325 void OnClientPredictedEarlyInput(int ClientId, void *pInput) override;
326
327 void TeehistorianRecordAntibot(const void *pData, int DataSize) override;
328 void TeehistorianRecordPlayerJoin(int ClientId, bool Sixup) override;
329 void TeehistorianRecordPlayerDrop(int ClientId, const char *pReason) override;
330 void TeehistorianRecordPlayerRejoin(int ClientId) override;
331
332 bool IsClientReady(int ClientId) const override;
333 bool IsClientPlayer(int ClientId) const override;
334 int PersistentDataSize() const override { return sizeof(CPersistentData); }
335 int PersistentClientDataSize() const override { return sizeof(CPersistentClientData); }
336
337 CUuid GameUuid() const override;
338 const char *GameType() const override;
339 const char *Version() const override;
340 const char *NetVersion() const override;
341
342 // DDRace
343 void OnPreTickTeehistorian() override;
344 bool OnClientDDNetVersionKnown(int ClientId);
345 void FillAntibot(CAntibotRoundData *pData) override;
346 bool ProcessSpamProtection(int ClientId, bool RespectChatInitialDelay = true);
347 int GetDDRaceTeam(int ClientId) const;
348 // Describes the time when the first player joined the server.
349 int64_t m_NonEmptySince;
350 int64_t m_LastMapVote;
351 int GetClientVersion(int ClientId) const;
352 CClientMask ClientsMaskExcludeClientVersionAndHigher(int Version) const;
353 bool PlayerExists(int ClientId) const override { return m_apPlayers[ClientId]; }
354 // Returns true if someone is actively moderating.
355 bool PlayerModerating() const;
356 void ForceVote(int EnforcerId, bool Success);
357
358 // Checks if player can vote and notify them about the reason
359 bool RateLimitPlayerVote(int ClientId);
360 bool RateLimitPlayerMapVote(int ClientId) const;
361
362 void OnUpdatePlayerServerInfo(char *aBuf, int BufSize, int Id) override;
363
364 std::shared_ptr<CScoreRandomMapResult> m_SqlRandomMapResult;
365
366private:
367 // starting 1 to make 0 the special value "no client id"
368 uint32_t NextUniqueClientId = 1;
369 bool m_VoteWillPass;
370 CScore *m_pScore;
371
372 // DDRace Console Commands
373
374 static void ConKillPlayer(IConsole::IResult *pResult, void *pUserData);
375
376 static void ConNinja(IConsole::IResult *pResult, void *pUserData);
377 static void ConUnNinja(IConsole::IResult *pResult, void *pUserData);
378 static void ConEndlessHook(IConsole::IResult *pResult, void *pUserData);
379 static void ConUnEndlessHook(IConsole::IResult *pResult, void *pUserData);
380 static void ConSolo(IConsole::IResult *pResult, void *pUserData);
381 static void ConUnSolo(IConsole::IResult *pResult, void *pUserData);
382 static void ConFreeze(IConsole::IResult *pResult, void *pUserData);
383 static void ConUnFreeze(IConsole::IResult *pResult, void *pUserData);
384 static void ConDeep(IConsole::IResult *pResult, void *pUserData);
385 static void ConUnDeep(IConsole::IResult *pResult, void *pUserData);
386 static void ConLiveFreeze(IConsole::IResult *pResult, void *pUserData);
387 static void ConUnLiveFreeze(IConsole::IResult *pResult, void *pUserData);
388 static void ConUnSuper(IConsole::IResult *pResult, void *pUserData);
389 static void ConSuper(IConsole::IResult *pResult, void *pUserData);
390 static void ConShotgun(IConsole::IResult *pResult, void *pUserData);
391 static void ConGrenade(IConsole::IResult *pResult, void *pUserData);
392 static void ConLaser(IConsole::IResult *pResult, void *pUserData);
393 static void ConJetpack(IConsole::IResult *pResult, void *pUserData);
394 static void ConWeapons(IConsole::IResult *pResult, void *pUserData);
395 static void ConUnShotgun(IConsole::IResult *pResult, void *pUserData);
396 static void ConUnGrenade(IConsole::IResult *pResult, void *pUserData);
397 static void ConUnLaser(IConsole::IResult *pResult, void *pUserData);
398 static void ConUnJetpack(IConsole::IResult *pResult, void *pUserData);
399 static void ConUnWeapons(IConsole::IResult *pResult, void *pUserData);
400 static void ConAddWeapon(IConsole::IResult *pResult, void *pUserData);
401 static void ConRemoveWeapon(IConsole::IResult *pResult, void *pUserData);
402
403 void ModifyWeapons(IConsole::IResult *pResult, void *pUserData, int Weapon, bool Remove);
404 void MoveCharacter(int ClientId, int X, int Y, bool Raw = false);
405 static void ConGoLeft(IConsole::IResult *pResult, void *pUserData);
406 static void ConGoRight(IConsole::IResult *pResult, void *pUserData);
407 static void ConGoUp(IConsole::IResult *pResult, void *pUserData);
408 static void ConGoDown(IConsole::IResult *pResult, void *pUserData);
409 static void ConMove(IConsole::IResult *pResult, void *pUserData);
410 static void ConMoveRaw(IConsole::IResult *pResult, void *pUserData);
411
412 static void ConToTeleporter(IConsole::IResult *pResult, void *pUserData);
413 static void ConToCheckTeleporter(IConsole::IResult *pResult, void *pUserData);
414 void Teleport(CCharacter *pChr, vec2 Pos);
415 static void ConTeleport(IConsole::IResult *pResult, void *pUserData);
416
417 static void ConCredits(IConsole::IResult *pResult, void *pUserData);
418 static void ConInfo(IConsole::IResult *pResult, void *pUserData);
419 static void ConHelp(IConsole::IResult *pResult, void *pUserData);
420 static void ConSettings(IConsole::IResult *pResult, void *pUserData);
421 static void ConRules(IConsole::IResult *pResult, void *pUserData);
422 static void ConKill(IConsole::IResult *pResult, void *pUserData);
423 static void ConTogglePause(IConsole::IResult *pResult, void *pUserData);
424 static void ConTogglePauseVoted(IConsole::IResult *pResult, void *pUserData);
425 static void ConToggleSpec(IConsole::IResult *pResult, void *pUserData);
426 static void ConToggleSpecVoted(IConsole::IResult *pResult, void *pUserData);
427 static void ConForcePause(IConsole::IResult *pResult, void *pUserData);
428 static void ConTeamTop5(IConsole::IResult *pResult, void *pUserData);
429 static void ConTop(IConsole::IResult *pResult, void *pUserData);
430 static void ConTimes(IConsole::IResult *pResult, void *pUserData);
431 static void ConPoints(IConsole::IResult *pResult, void *pUserData);
432 static void ConTopPoints(IConsole::IResult *pResult, void *pUserData);
433 static void ConTimeCP(IConsole::IResult *pResult, void *pUserData);
434
435 static void ConDND(IConsole::IResult *pResult, void *pUserData);
436 static void ConMapInfo(IConsole::IResult *pResult, void *pUserData);
437 static void ConTimeout(IConsole::IResult *pResult, void *pUserData);
438 static void ConPractice(IConsole::IResult *pResult, void *pUserData);
439 static void ConSwap(IConsole::IResult *pResult, void *pUserData);
440 static void ConSave(IConsole::IResult *pResult, void *pUserData);
441 static void ConLoad(IConsole::IResult *pResult, void *pUserData);
442 static void ConMap(IConsole::IResult *pResult, void *pUserData);
443 static void ConTeamRank(IConsole::IResult *pResult, void *pUserData);
444 static void ConRank(IConsole::IResult *pResult, void *pUserData);
445 static void ConTeam(IConsole::IResult *pResult, void *pUserData);
446 static void ConLock(IConsole::IResult *pResult, void *pUserData);
447 static void ConUnlock(IConsole::IResult *pResult, void *pUserData);
448 static void ConInvite(IConsole::IResult *pResult, void *pUserData);
449 static void ConJoin(IConsole::IResult *pResult, void *pUserData);
450 static void ConTeam0Mode(IConsole::IResult *pResult, void *pUserData);
451 static void ConMe(IConsole::IResult *pResult, void *pUserData);
452 static void ConWhisper(IConsole::IResult *pResult, void *pUserData);
453 static void ConConverse(IConsole::IResult *pResult, void *pUserData);
454 static void ConSetEyeEmote(IConsole::IResult *pResult, void *pUserData);
455 static void ConEyeEmote(IConsole::IResult *pResult, void *pUserData);
456 static void ConShowOthers(IConsole::IResult *pResult, void *pUserData);
457 static void ConShowAll(IConsole::IResult *pResult, void *pUserData);
458 static void ConSpecTeam(IConsole::IResult *pResult, void *pUserData);
459 static void ConNinjaJetpack(IConsole::IResult *pResult, void *pUserData);
460 static void ConSayTime(IConsole::IResult *pResult, void *pUserData);
461 static void ConSayTimeAll(IConsole::IResult *pResult, void *pUserData);
462 static void ConTime(IConsole::IResult *pResult, void *pUserData);
463 static void ConSetTimerType(IConsole::IResult *pResult, void *pUserData);
464 static void ConRescue(IConsole::IResult *pResult, void *pUserData);
465 static void ConTeleTo(IConsole::IResult *pResult, void *pUserData);
466 static void ConTeleXY(IConsole::IResult *pResult, void *pUserData);
467 static void ConTeleCursor(IConsole::IResult *pResult, void *pUserData);
468 static void ConLastTele(IConsole::IResult *pResult, void *pUserData);
469 static void ConPracticeUnSolo(IConsole::IResult *pResult, void *pUserData);
470 static void ConPracticeSolo(IConsole::IResult *pResult, void *pUserData);
471 static void ConPracticeUnDeep(IConsole::IResult *pResult, void *pUserData);
472 static void ConPracticeDeep(IConsole::IResult *pResult, void *pUserData);
473 static void ConProtectedKill(IConsole::IResult *pResult, void *pUserData);
474
475 static void ConVoteMute(IConsole::IResult *pResult, void *pUserData);
476 static void ConVoteUnmute(IConsole::IResult *pResult, void *pUserData);
477 static void ConVoteMutes(IConsole::IResult *pResult, void *pUserData);
478 static void ConMute(IConsole::IResult *pResult, void *pUserData);
479 static void ConMuteId(IConsole::IResult *pResult, void *pUserData);
480 static void ConMuteIp(IConsole::IResult *pResult, void *pUserData);
481 static void ConUnmute(IConsole::IResult *pResult, void *pUserData);
482 static void ConUnmuteId(IConsole::IResult *pResult, void *pUserData);
483 static void ConMutes(IConsole::IResult *pResult, void *pUserData);
484 static void ConModerate(IConsole::IResult *pResult, void *pUserData);
485
486 static void ConList(IConsole::IResult *pResult, void *pUserData);
487 static void ConSetDDRTeam(IConsole::IResult *pResult, void *pUserData);
488 static void ConUninvite(IConsole::IResult *pResult, void *pUserData);
489 static void ConFreezeHammer(IConsole::IResult *pResult, void *pUserData);
490 static void ConUnFreezeHammer(IConsole::IResult *pResult, void *pUserData);
491
492 enum
493 {
494 MAX_MUTES = 128,
495 MAX_VOTE_MUTES = 128,
496 };
497 struct CMute
498 {
499 NETADDR m_Addr;
500 int m_Expire;
501 char m_aReason[128];
502 bool m_InitialChatDelay;
503 };
504
505 CMute m_aMutes[MAX_MUTES];
506 int m_NumMutes;
507 CMute m_aVoteMutes[MAX_VOTE_MUTES];
508 int m_NumVoteMutes;
509 bool TryMute(const NETADDR *pAddr, int Secs, const char *pReason, bool InitialChatDelay);
510 void Mute(const NETADDR *pAddr, int Secs, const char *pDisplayName, const char *pReason = "", bool InitialChatDelay = false);
511 bool TryVoteMute(const NETADDR *pAddr, int Secs, const char *pReason);
512 void VoteMute(const NETADDR *pAddr, int Secs, const char *pReason, const char *pDisplayName, int AuthedId);
513 bool VoteUnmute(const NETADDR *pAddr, const char *pDisplayName, int AuthedId);
514 void Whisper(int ClientId, char *pStr);
515 void WhisperId(int ClientId, int VictimId, const char *pMessage);
516 void Converse(int ClientId, char *pStr);
517 bool IsVersionBanned(int Version);
518 void UnlockTeam(int ClientId, int Team) const;
519 void AttemptJoinTeam(int ClientId, int Team);
520
521 enum
522 {
523 MAX_LOG_SECONDS = 600,
524 MAX_LOGS = 512,
525 };
526 struct CLog
527 {
528 int64_t m_Timestamp;
529 bool m_FromServer;
530 char m_aDescription[128];
531 int m_ClientVersion;
532 char m_aClientName[MAX_NAME_LENGTH];
533 char m_aClientAddrStr[NETADDR_MAXSTRSIZE];
534 };
535 CLog m_aLogs[MAX_LOGS];
536 int m_LatestLog;
537
538 void LogEvent(const char *Description, int ClientId);
539
540public:
541 CLayers *Layers() { return &m_Layers; }
542 CScore *Score() { return m_pScore; }
543
544 enum
545 {
546 VOTE_TYPE_UNKNOWN = 0,
547 VOTE_TYPE_OPTION,
548 VOTE_TYPE_KICK,
549 VOTE_TYPE_SPECTATE,
550 };
551 int m_VoteVictim;
552 int m_VoteEnforcer;
553
554 inline bool IsOptionVote() const { return m_VoteType == VOTE_TYPE_OPTION; }
555 inline bool IsKickVote() const { return m_VoteType == VOTE_TYPE_KICK; }
556 inline bool IsSpecVote() const { return m_VoteType == VOTE_TYPE_SPECTATE; }
557
558 void SendRecord(int ClientId);
559 void OnSetAuthed(int ClientId, int Level) override;
560
561 void ResetTuning();
562};
563
564#endif
565