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 CreateFinishConfetti(vec2 Pos, CClientMask Mask = CClientMask().set());
243 void CreateSound(vec2 Pos, int Sound, CClientMask Mask = CClientMask().set());
244 void CreateSoundGlobal(int Sound, int Target = -1) const;
245
246 void SnapSwitchers(int SnappingClient);
247 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;
248 bool SnapPickup(const CSnapContext &Context, int SnapId, const vec2 &Pos, int Type, int SubType, int SwitchNumber) const;
249
250 enum
251 {
252 CHAT_SIX = 1 << 0,
253 CHAT_SIXUP = 1 << 1,
254 };
255
256 // network
257 void CallVote(int ClientId, const char *pDesc, const char *pCmd, const char *pReason, const char *pChatmsg, const char *pSixupDesc = 0);
258 void SendChatTarget(int To, const char *pText, int Flags = CHAT_SIX | CHAT_SIXUP) const;
259 void SendChatTeam(int Team, const char *pText) const;
260 void SendChat(int ClientId, int Team, const char *pText, int SpamProtectionClientId = -1, int Flags = CHAT_SIX | CHAT_SIXUP);
261 void SendStartWarning(int ClientId, const char *pMessage);
262 void SendEmoticon(int ClientId, int Emoticon, int TargetClientId) const;
263 void SendWeaponPickup(int ClientId, int Weapon) const;
264 void SendMotd(int ClientId) const;
265 void SendSettings(int ClientId) const;
266 void SendBroadcast(const char *pText, int ClientId, bool IsImportant = true);
267
268 void List(int ClientId, const char *pFilter);
269
270 //
271 void CheckPureTuning();
272 void SendTuningParams(int ClientId, int Zone = 0);
273
274 const CVoteOptionServer *GetVoteOption(int Index) const;
275 void ProgressVoteOptions(int ClientId);
276
277 //
278 void LoadMapSettings();
279
280 // engine events
281 void OnInit(const void *pPersistentData) override;
282 void OnConsoleInit() override;
283 void RegisterDDRaceCommands();
284 void RegisterChatCommands();
285 void OnMapChange(char *pNewMapName, int MapNameSize) override;
286 void OnShutdown(void *pPersistentData) override;
287
288 void OnTick() override;
289 void OnPreSnap() override;
290 void OnSnap(int ClientId) override;
291 void OnPostSnap() override;
292
293 void UpdatePlayerMaps();
294
295 void *PreProcessMsg(int *pMsgId, CUnpacker *pUnpacker, int ClientId);
296 void CensorMessage(char *pCensoredMessage, const char *pMessage, int Size);
297 void OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId) override;
298 void OnSayNetMessage(const CNetMsg_Cl_Say *pMsg, int ClientId, const CUnpacker *pUnpacker);
299 void OnCallVoteNetMessage(const CNetMsg_Cl_CallVote *pMsg, int ClientId);
300 void OnVoteNetMessage(const CNetMsg_Cl_Vote *pMsg, int ClientId);
301 void OnSetTeamNetMessage(const CNetMsg_Cl_SetTeam *pMsg, int ClientId);
302 void OnIsDDNetLegacyNetMessage(const CNetMsg_Cl_IsDDNetLegacy *pMsg, int ClientId, CUnpacker *pUnpacker);
303 void OnShowOthersLegacyNetMessage(const CNetMsg_Cl_ShowOthersLegacy *pMsg, int ClientId);
304 void OnShowOthersNetMessage(const CNetMsg_Cl_ShowOthers *pMsg, int ClientId);
305 void OnShowDistanceNetMessage(const CNetMsg_Cl_ShowDistance *pMsg, int ClientId);
306 void OnSetSpectatorModeNetMessage(const CNetMsg_Cl_SetSpectatorMode *pMsg, int ClientId);
307 void OnChangeInfoNetMessage(const CNetMsg_Cl_ChangeInfo *pMsg, int ClientId);
308 void OnEmoticonNetMessage(const CNetMsg_Cl_Emoticon *pMsg, int ClientId);
309 void OnKillNetMessage(const CNetMsg_Cl_Kill *pMsg, int ClientId);
310 void OnStartInfoNetMessage(const CNetMsg_Cl_StartInfo *pMsg, int ClientId);
311
312 bool OnClientDataPersist(int ClientId, void *pData) override;
313 void OnClientConnected(int ClientId, void *pData) override;
314 void OnClientEnter(int ClientId) override;
315 void OnClientDrop(int ClientId, const char *pReason) override;
316 void OnClientPrepareInput(int ClientId, void *pInput) override;
317 void OnClientDirectInput(int ClientId, void *pInput) override;
318 void OnClientPredictedInput(int ClientId, void *pInput) override;
319 void OnClientPredictedEarlyInput(int ClientId, void *pInput) override;
320
321 void TeehistorianRecordAntibot(const void *pData, int DataSize) override;
322 void TeehistorianRecordPlayerJoin(int ClientId, bool Sixup) override;
323 void TeehistorianRecordPlayerDrop(int ClientId, const char *pReason) override;
324 void TeehistorianRecordPlayerRejoin(int ClientId) override;
325 void TeehistorianRecordPlayerName(int ClientId, const char *pName) override;
326 void TeehistorianRecordPlayerFinish(int ClientId, int TimeTicks) override;
327 void TeehistorianRecordTeamFinish(int TeamId, int TimeTicks) override;
328
329 bool IsClientReady(int ClientId) const override;
330 bool IsClientPlayer(int ClientId) const override;
331 int PersistentDataSize() const override { return sizeof(CPersistentData); }
332 int PersistentClientDataSize() const override { return sizeof(CPersistentClientData); }
333
334 CUuid GameUuid() const override;
335 const char *GameType() const override;
336 const char *Version() const override;
337 const char *NetVersion() const override;
338
339 // DDRace
340 void OnPreTickTeehistorian() override;
341 bool OnClientDDNetVersionKnown(int ClientId);
342 void FillAntibot(CAntibotRoundData *pData) override;
343 bool ProcessSpamProtection(int ClientId, bool RespectChatInitialDelay = true);
344 int GetDDRaceTeam(int ClientId) const;
345 // Describes the time when the first player joined the server.
346 int64_t m_NonEmptySince;
347 int64_t m_LastMapVote;
348 int GetClientVersion(int ClientId) const;
349 CClientMask ClientsMaskExcludeClientVersionAndHigher(int Version) const;
350 bool PlayerExists(int ClientId) const override { return m_apPlayers[ClientId]; }
351 // Returns true if someone is actively moderating.
352 bool PlayerModerating() const;
353 void ForceVote(int EnforcerId, bool Success);
354
355 // Checks if player can vote and notify them about the reason
356 bool RateLimitPlayerVote(int ClientId);
357 bool RateLimitPlayerMapVote(int ClientId) const;
358
359 void OnUpdatePlayerServerInfo(char *aBuf, int BufSize, int Id) override;
360
361 std::shared_ptr<CScoreRandomMapResult> m_SqlRandomMapResult;
362
363private:
364 // starting 1 to make 0 the special value "no client id"
365 uint32_t NextUniqueClientId = 1;
366 bool m_VoteWillPass;
367 CScore *m_pScore;
368
369 // DDRace Console Commands
370
371 static void ConKillPlayer(IConsole::IResult *pResult, void *pUserData);
372
373 static void ConNinja(IConsole::IResult *pResult, void *pUserData);
374 static void ConUnNinja(IConsole::IResult *pResult, void *pUserData);
375 static void ConEndlessHook(IConsole::IResult *pResult, void *pUserData);
376 static void ConUnEndlessHook(IConsole::IResult *pResult, void *pUserData);
377 static void ConSolo(IConsole::IResult *pResult, void *pUserData);
378 static void ConUnSolo(IConsole::IResult *pResult, void *pUserData);
379 static void ConFreeze(IConsole::IResult *pResult, void *pUserData);
380 static void ConUnFreeze(IConsole::IResult *pResult, void *pUserData);
381 static void ConDeep(IConsole::IResult *pResult, void *pUserData);
382 static void ConUnDeep(IConsole::IResult *pResult, void *pUserData);
383 static void ConLiveFreeze(IConsole::IResult *pResult, void *pUserData);
384 static void ConUnLiveFreeze(IConsole::IResult *pResult, void *pUserData);
385 static void ConUnSuper(IConsole::IResult *pResult, void *pUserData);
386 static void ConSuper(IConsole::IResult *pResult, void *pUserData);
387 static void ConShotgun(IConsole::IResult *pResult, void *pUserData);
388 static void ConGrenade(IConsole::IResult *pResult, void *pUserData);
389 static void ConLaser(IConsole::IResult *pResult, void *pUserData);
390 static void ConJetpack(IConsole::IResult *pResult, void *pUserData);
391 static void ConWeapons(IConsole::IResult *pResult, void *pUserData);
392 static void ConUnShotgun(IConsole::IResult *pResult, void *pUserData);
393 static void ConUnGrenade(IConsole::IResult *pResult, void *pUserData);
394 static void ConUnLaser(IConsole::IResult *pResult, void *pUserData);
395 static void ConUnJetpack(IConsole::IResult *pResult, void *pUserData);
396 static void ConUnWeapons(IConsole::IResult *pResult, void *pUserData);
397 static void ConAddWeapon(IConsole::IResult *pResult, void *pUserData);
398 static void ConRemoveWeapon(IConsole::IResult *pResult, void *pUserData);
399 void ModifyWeapons(IConsole::IResult *pResult, void *pUserData, int Weapon, bool Remove);
400 void MoveCharacter(int ClientId, int X, int Y, bool Raw = false);
401 static void ConGoLeft(IConsole::IResult *pResult, void *pUserData);
402 static void ConGoRight(IConsole::IResult *pResult, void *pUserData);
403 static void ConGoUp(IConsole::IResult *pResult, void *pUserData);
404 static void ConGoDown(IConsole::IResult *pResult, void *pUserData);
405 static void ConMove(IConsole::IResult *pResult, void *pUserData);
406 static void ConMoveRaw(IConsole::IResult *pResult, void *pUserData);
407
408 static void ConToTeleporter(IConsole::IResult *pResult, void *pUserData);
409 static void ConToCheckTeleporter(IConsole::IResult *pResult, void *pUserData);
410 void Teleport(CCharacter *pChr, vec2 Pos);
411 static void ConTeleport(IConsole::IResult *pResult, void *pUserData);
412
413 static void ConCredits(IConsole::IResult *pResult, void *pUserData);
414 static void ConInfo(IConsole::IResult *pResult, void *pUserData);
415 static void ConHelp(IConsole::IResult *pResult, void *pUserData);
416 static void ConSettings(IConsole::IResult *pResult, void *pUserData);
417 static void ConRules(IConsole::IResult *pResult, void *pUserData);
418 static void ConKill(IConsole::IResult *pResult, void *pUserData);
419 static void ConTogglePause(IConsole::IResult *pResult, void *pUserData);
420 static void ConTogglePauseVoted(IConsole::IResult *pResult, void *pUserData);
421 static void ConToggleSpec(IConsole::IResult *pResult, void *pUserData);
422 static void ConToggleSpecVoted(IConsole::IResult *pResult, void *pUserData);
423 static void ConForcePause(IConsole::IResult *pResult, void *pUserData);
424 static void ConTeamTop5(IConsole::IResult *pResult, void *pUserData);
425 static void ConTop(IConsole::IResult *pResult, void *pUserData);
426 static void ConTimes(IConsole::IResult *pResult, void *pUserData);
427 static void ConPoints(IConsole::IResult *pResult, void *pUserData);
428 static void ConTopPoints(IConsole::IResult *pResult, void *pUserData);
429 static void ConTimeCP(IConsole::IResult *pResult, void *pUserData);
430
431 static void ConDND(IConsole::IResult *pResult, void *pUserData);
432 static void ConMapInfo(IConsole::IResult *pResult, void *pUserData);
433 static void ConTimeout(IConsole::IResult *pResult, void *pUserData);
434 static void ConPractice(IConsole::IResult *pResult, void *pUserData);
435 static void ConPracticeCmdList(IConsole::IResult *pResult, void *pUserData);
436 static void ConSwap(IConsole::IResult *pResult, void *pUserData);
437 static void ConSave(IConsole::IResult *pResult, void *pUserData);
438 static void ConLoad(IConsole::IResult *pResult, void *pUserData);
439 static void ConMap(IConsole::IResult *pResult, void *pUserData);
440 static void ConTeamRank(IConsole::IResult *pResult, void *pUserData);
441 static void ConRank(IConsole::IResult *pResult, void *pUserData);
442 static void ConTeam(IConsole::IResult *pResult, void *pUserData);
443 static void ConLock(IConsole::IResult *pResult, void *pUserData);
444 static void ConUnlock(IConsole::IResult *pResult, void *pUserData);
445 static void ConInvite(IConsole::IResult *pResult, void *pUserData);
446 static void ConJoin(IConsole::IResult *pResult, void *pUserData);
447 static void ConTeam0Mode(IConsole::IResult *pResult, void *pUserData);
448 static void ConMe(IConsole::IResult *pResult, void *pUserData);
449 static void ConWhisper(IConsole::IResult *pResult, void *pUserData);
450 static void ConConverse(IConsole::IResult *pResult, void *pUserData);
451 static void ConSetEyeEmote(IConsole::IResult *pResult, void *pUserData);
452 static void ConEyeEmote(IConsole::IResult *pResult, void *pUserData);
453 static void ConShowOthers(IConsole::IResult *pResult, void *pUserData);
454 static void ConShowAll(IConsole::IResult *pResult, void *pUserData);
455 static void ConSpecTeam(IConsole::IResult *pResult, void *pUserData);
456 static void ConNinjaJetpack(IConsole::IResult *pResult, void *pUserData);
457 static void ConSayTime(IConsole::IResult *pResult, void *pUserData);
458 static void ConSayTimeAll(IConsole::IResult *pResult, void *pUserData);
459 static void ConTime(IConsole::IResult *pResult, void *pUserData);
460 static void ConSetTimerType(IConsole::IResult *pResult, void *pUserData);
461 static void ConRescue(IConsole::IResult *pResult, void *pUserData);
462 static void ConRescueMode(IConsole::IResult *pResult, void *pUserData);
463 static void ConTeleTo(IConsole::IResult *pResult, void *pUserData);
464 static void ConTeleXY(IConsole::IResult *pResult, void *pUserData);
465 static void ConTeleCursor(IConsole::IResult *pResult, void *pUserData);
466 static void ConLastTele(IConsole::IResult *pResult, void *pUserData);
467
468 // Chat commands for practice mode
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 ConPracticeShotgun(IConsole::IResult *pResult, void *pUserData);
474 static void ConPracticeGrenade(IConsole::IResult *pResult, void *pUserData);
475 static void ConPracticeLaser(IConsole::IResult *pResult, void *pUserData);
476 static void ConPracticeJetpack(IConsole::IResult *pResult, void *pUserData);
477 static void ConPracticeWeapons(IConsole::IResult *pResult, void *pUserData);
478 static void ConPracticeUnShotgun(IConsole::IResult *pResult, void *pUserData);
479 static void ConPracticeUnGrenade(IConsole::IResult *pResult, void *pUserData);
480 static void ConPracticeUnLaser(IConsole::IResult *pResult, void *pUserData);
481 static void ConPracticeUnJetpack(IConsole::IResult *pResult, void *pUserData);
482 static void ConPracticeUnWeapons(IConsole::IResult *pResult, void *pUserData);
483 static void ConPracticeNinja(IConsole::IResult *pResult, void *pUserData);
484 static void ConPracticeUnNinja(IConsole::IResult *pResult, void *pUserData);
485
486 static void ConPracticeAddWeapon(IConsole::IResult *pResult, void *pUserData);
487 static void ConPracticeRemoveWeapon(IConsole::IResult *pResult, void *pUserData);
488
489 static void ConProtectedKill(IConsole::IResult *pResult, void *pUserData);
490
491 static void ConVoteMute(IConsole::IResult *pResult, void *pUserData);
492 static void ConVoteUnmute(IConsole::IResult *pResult, void *pUserData);
493 static void ConVoteMutes(IConsole::IResult *pResult, void *pUserData);
494 static void ConMute(IConsole::IResult *pResult, void *pUserData);
495 static void ConMuteId(IConsole::IResult *pResult, void *pUserData);
496 static void ConMuteIp(IConsole::IResult *pResult, void *pUserData);
497 static void ConUnmute(IConsole::IResult *pResult, void *pUserData);
498 static void ConUnmuteId(IConsole::IResult *pResult, void *pUserData);
499 static void ConMutes(IConsole::IResult *pResult, void *pUserData);
500 static void ConModerate(IConsole::IResult *pResult, void *pUserData);
501
502 static void ConList(IConsole::IResult *pResult, void *pUserData);
503 static void ConSetDDRTeam(IConsole::IResult *pResult, void *pUserData);
504 static void ConUninvite(IConsole::IResult *pResult, void *pUserData);
505 static void ConFreezeHammer(IConsole::IResult *pResult, void *pUserData);
506 static void ConUnFreezeHammer(IConsole::IResult *pResult, void *pUserData);
507
508 CCharacter *GetPracticeCharacter(IConsole::IResult *pResult);
509
510 enum
511 {
512 MAX_MUTES = 128,
513 MAX_VOTE_MUTES = 128,
514 };
515 struct CMute
516 {
517 NETADDR m_Addr;
518 int m_Expire;
519 char m_aReason[128];
520 bool m_InitialChatDelay;
521 };
522
523 CMute m_aMutes[MAX_MUTES];
524 int m_NumMutes;
525 CMute m_aVoteMutes[MAX_VOTE_MUTES];
526 int m_NumVoteMutes;
527 bool TryMute(const NETADDR *pAddr, int Secs, const char *pReason, bool InitialChatDelay);
528 void Mute(const NETADDR *pAddr, int Secs, const char *pDisplayName, const char *pReason = "", bool InitialChatDelay = false);
529 bool TryVoteMute(const NETADDR *pAddr, int Secs, const char *pReason);
530 void VoteMute(const NETADDR *pAddr, int Secs, const char *pReason, const char *pDisplayName, int AuthedId);
531 bool VoteUnmute(const NETADDR *pAddr, const char *pDisplayName, int AuthedId);
532 void Whisper(int ClientId, char *pStr);
533 void WhisperId(int ClientId, int VictimId, const char *pMessage);
534 void Converse(int ClientId, char *pStr);
535 bool IsVersionBanned(int Version);
536 void UnlockTeam(int ClientId, int Team) const;
537 void AttemptJoinTeam(int ClientId, int Team);
538
539 enum
540 {
541 MAX_LOG_SECONDS = 600,
542 MAX_LOGS = 512,
543 };
544 struct CLog
545 {
546 int64_t m_Timestamp;
547 bool m_FromServer;
548 char m_aDescription[128];
549 int m_ClientVersion;
550 char m_aClientName[MAX_NAME_LENGTH];
551 char m_aClientAddrStr[NETADDR_MAXSTRSIZE];
552 };
553 CLog m_aLogs[MAX_LOGS];
554 int m_LatestLog;
555
556 void LogEvent(const char *Description, int ClientId);
557
558public:
559 CLayers *Layers() { return &m_Layers; }
560 CScore *Score() { return m_pScore; }
561
562 enum
563 {
564 VOTE_TYPE_UNKNOWN = 0,
565 VOTE_TYPE_OPTION,
566 VOTE_TYPE_KICK,
567 VOTE_TYPE_SPECTATE,
568 };
569 int m_VoteVictim;
570 int m_VoteEnforcer;
571
572 inline bool IsOptionVote() const { return m_VoteType == VOTE_TYPE_OPTION; }
573 inline bool IsKickVote() const { return m_VoteType == VOTE_TYPE_KICK; }
574 inline bool IsSpecVote() const { return m_VoteType == VOTE_TYPE_SPECTATE; }
575
576 void SendRecord(int ClientId);
577 void OnSetAuthed(int ClientId, int Level) override;
578
579 void ResetTuning();
580};
581
582#endif
583