ddnet/src/game/server/gamecontext.h

431 lines
17 KiB
C++

/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#ifndef GAME_SERVER_GAMECONTEXT_H
#define GAME_SERVER_GAMECONTEXT_H
#include <engine/antibot.h>
#include <engine/server.h>
#include <engine/console.h>
#include <engine/shared/memheap.h>
#include <game/layers.h>
#include <game/mapbugs.h>
#include <game/voting.h>
#include "eventhandler.h"
#include "gamecontroller.h"
#include "gameworld.h"
#include "player.h"
#include "teehistorian.h"
#include "score.h"
#ifdef _MSC_VER
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
/*
Tick
Game Context (CGameContext::tick)
Game World (GAMEWORLD::tick)
Reset world if requested (GAMEWORLD::reset)
All entities in the world (ENTITY::tick)
All entities in the world (ENTITY::tick_defered)
Remove entities marked for deletion (GAMEWORLD::remove_entities)
Game Controller (GAMECONTROLLER::tick)
All players (CPlayer::tick)
Snap
Game Context (CGameContext::snap)
Game World (GAMEWORLD::snap)
All entities in the world (ENTITY::snap)
Game Controller (GAMECONTROLLER::snap)
Events handler (EVENT_HANDLER::snap)
All players (CPlayer::snap)
*/
enum
{
NUM_TUNEZONES = 256
};
class IConsole;
class IEngine;
class IStorage;
class CRandomMapResult;
class CMapVoteResult;
struct CAntibotData;
class CGameContext : public IGameServer
{
IServer *m_pServer;
IConsole *m_pConsole;
IEngine *m_pEngine;
IStorage *m_pStorage;
IAntibot *m_pAntibot;
CLayers m_Layers;
CCollision m_Collision;
CNetObjHandler m_NetObjHandler;
CTuningParams m_Tuning;
CTuningParams m_aTuningList[NUM_TUNEZONES];
bool m_TeeHistorianActive;
CTeeHistorian m_TeeHistorian;
ASYNCIO *m_pTeeHistorianFile;
CUuid m_GameUuid;
CMapBugs m_MapBugs;
std::shared_ptr<CRandomMapResult> m_pRandomMapResult;
std::shared_ptr<CMapVoteResult> m_pMapVoteResult;
static void CommandCallback(int ClientID, int FlagMask, const char *pCmd, IConsole::IResult *pResult, void *pUser);
static void TeeHistorianWrite(const void *pData, int DataSize, void *pUser);
static void ConTuneParam(IConsole::IResult *pResult, void *pUserData);
static void ConToggleTuneParam(IConsole::IResult *pResult, void *pUserData);
static void ConTuneReset(IConsole::IResult *pResult, void *pUserData);
static void ConTuneDump(IConsole::IResult *pResult, void *pUserData);
static void ConTuneZone(IConsole::IResult *pResult, void *pUserData);
static void ConTuneDumpZone(IConsole::IResult *pResult, void *pUserData);
static void ConTuneResetZone(IConsole::IResult *pResult, void *pUserData);
static void ConTuneSetZoneMsgEnter(IConsole::IResult *pResult, void *pUserData);
static void ConTuneSetZoneMsgLeave(IConsole::IResult *pResult, void *pUserData);
static void ConMapbug(IConsole::IResult *pResult, void *pUserData);
static void ConSwitchOpen(IConsole::IResult *pResult, void *pUserData);
static void ConPause(IConsole::IResult *pResult, void *pUserData);
static void ConChangeMap(IConsole::IResult *pResult, void *pUserData);
static void ConRandomMap(IConsole::IResult *pResult, void *pUserData);
static void ConRandomUnfinishedMap(IConsole::IResult *pResult, void *pUserData);
static void ConRestart(IConsole::IResult *pResult, void *pUserData);
static void ConBroadcast(IConsole::IResult *pResult, void *pUserData);
static void ConSay(IConsole::IResult *pResult, void *pUserData);
static void ConSetTeam(IConsole::IResult *pResult, void *pUserData);
static void ConSetTeamAll(IConsole::IResult *pResult, void *pUserData);
static void ConAddVote(IConsole::IResult *pResult, void *pUserData);
static void ConRemoveVote(IConsole::IResult *pResult, void *pUserData);
static void ConForceVote(IConsole::IResult *pResult, void *pUserData);
static void ConClearVotes(IConsole::IResult *pResult, void *pUserData);
static void ConVote(IConsole::IResult *pResult, void *pUserData);
static void ConVoteNo(IConsole::IResult *pResult, void *pUserData);
static void ConDrySave(IConsole::IResult *pResult, void *pUserData);
static void ConDumpAntibot(IConsole::IResult *pResult, void *pUserData);
static void ConchainSpecialMotdupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
CGameContext(int Resetting);
void Construct(int Resetting);
bool m_Resetting;
public:
IServer *Server() const { return m_pServer; }
IConsole *Console() { return m_pConsole; }
IEngine *Engine() { return m_pEngine; }
IStorage *Storage() { return m_pStorage; }
CCollision *Collision() { return &m_Collision; }
CTuningParams *Tuning() { return &m_Tuning; }
CTuningParams *TuningList() { return &m_aTuningList[0]; }
IAntibot *Antibot() { return m_pAntibot; }
CGameContext();
~CGameContext();
void Clear();
CEventHandler m_Events;
CPlayer *m_apPlayers[MAX_CLIENTS];
IGameController *m_pController;
CGameWorld m_World;
// helper functions
class CCharacter *GetPlayerChar(int ClientID);
bool EmulateBug(int Bug);
// voting
void StartVote(const char *pDesc, const char *pCommand, const char *pReason);
void EndVote();
void SendVoteSet(int ClientID);
void SendVoteStatus(int ClientID, int Total, int Yes, int No);
void AbortVoteKickOnDisconnect(int ClientID);
int m_VoteCreator;
int64 m_VoteCloseTime;
bool m_VoteUpdate;
int m_VotePos;
char m_aVoteDescription[VOTE_DESC_LENGTH];
char m_aVoteCommand[VOTE_CMD_LENGTH];
char m_aVoteReason[VOTE_REASON_LENGTH];
int m_NumVoteOptions;
int m_VoteEnforce;
char m_aaZoneEnterMsg[NUM_TUNEZONES][256]; // 0 is used for switching from or to area without tunings
char m_aaZoneLeaveMsg[NUM_TUNEZONES][256];
char m_aDeleteTempfile[128];
void DeleteTempfile();
enum
{
VOTE_ENFORCE_UNKNOWN=0,
VOTE_ENFORCE_NO,
VOTE_ENFORCE_YES,
};
CHeap *m_pVoteOptionHeap;
CVoteOptionServer *m_pVoteOptionFirst;
CVoteOptionServer *m_pVoteOptionLast;
// helper functions
void CreateDamageInd(vec2 Pos, float AngleMod, int Amount, int64_t Mask=-1);
void CreateExplosion(vec2 Pos, int Owner, int Weapon, bool NoDamage, int ActivatedTeam, int64_t Mask);
void CreateHammerHit(vec2 Pos, int64_t Mask=-1);
void CreatePlayerSpawn(vec2 Pos, int64_t Mask=-1);
void CreateDeath(vec2 Pos, int Who, int64_t Mask=-1);
void CreateSound(vec2 Pos, int Sound, int64_t Mask=-1);
void CreateSoundGlobal(int Sound, int Target=-1);
enum
{
CHAT_ALL=-2,
CHAT_SPEC=-1,
CHAT_RED=0,
CHAT_BLUE=1,
CHAT_WHISPER_SEND=2,
CHAT_WHISPER_RECV=3
};
// network
void CallVote(int ClientID, const char *aDesc, const char *aCmd, const char *pReason, const char *aChatmsg);
void SendChatTarget(int To, const char *pText);
void SendChatTeam(int Team, const char *pText);
void SendChat(int ClientID, int Team, const char *pText, int SpamProtectionClientID = -1);
void SendEmoticon(int ClientID, int Emoticon);
void SendWeaponPickup(int ClientID, int Weapon);
void SendBroadcast(const char *pText, int ClientID, bool IsImportant = true);
void List(int ClientID, const char* filter);
//
void CheckPureTuning();
void SendTuningParams(int ClientID, int Zone = 0);
struct CVoteOptionServer *GetVoteOption(int Index);
void ProgressVoteOptions(int ClientID);
//
void LoadMapSettings();
// engine events
virtual void OnInit();
virtual void OnConsoleInit();
virtual void OnMapChange(char *pNewMapName, int MapNameSize);
virtual void OnShutdown(bool FullShutdown = false);
virtual void OnTick();
virtual void OnPreSnap();
virtual void OnSnap(int ClientID);
virtual void OnPostSnap();
virtual void OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID);
virtual void OnClientConnected(int ClientID);
virtual void OnClientEnter(int ClientID);
virtual void OnClientDrop(int ClientID, const char *pReason);
virtual void OnClientDirectInput(int ClientID, void *pInput);
virtual void OnClientPredictedInput(int ClientID, void *pInput);
virtual void OnClientPredictedEarlyInput(int ClientID, void *pInput);
virtual void OnClientEngineJoin(int ClientID);
virtual void OnClientEngineDrop(int ClientID, const char *pReason);
virtual bool IsClientReady(int ClientID);
virtual bool IsClientPlayer(int ClientID);
virtual CUuid GameUuid();
virtual const char *GameType();
virtual const char *Version();
virtual const char *NetVersion();
// DDRace
virtual void FillAntibot(CAntibotRoundData *pData);
int ProcessSpamProtection(int ClientID);
int GetDDRaceTeam(int ClientID);
// Describes the time when the first player joined the server.
int64 m_NonEmptySince;
int64 m_LastMapVote;
int GetClientVersion(int ClientID);
void SetClientVersion(int ClientID, int Version);
bool PlayerExists(int ClientID) { return m_apPlayers[ClientID]; };
// Returns true if someone is actively moderating.
bool PlayerModerating();
void ForceVote(int EnforcerID, bool Success);
private:
bool m_VoteWillPass;
class IScore *m_pScore;
//DDRace Console Commands
//static void ConMute(IConsole::IResult *pResult, void *pUserData);
//static void ConUnmute(IConsole::IResult *pResult, void *pUserData);
static void ConKillPlayer(IConsole::IResult *pResult, void *pUserData);
static void ConNinja(IConsole::IResult *pResult, void *pUserData);
static void ConUnSolo(IConsole::IResult *pResult, void *pUserData);
static void ConUnDeep(IConsole::IResult *pResult, void *pUserData);
static void ConUnSuper(IConsole::IResult *pResult, void *pUserData);
static void ConSuper(IConsole::IResult *pResult, void *pUserData);
static void ConShotgun(IConsole::IResult *pResult, void *pUserData);
static void ConGrenade(IConsole::IResult *pResult, void *pUserData);
static void ConLaser(IConsole::IResult *pResult, void *pUserData);
static void ConJetpack(IConsole::IResult *pResult, void *pUserData);
static void ConWeapons(IConsole::IResult *pResult, void *pUserData);
static void ConUnShotgun(IConsole::IResult *pResult, void *pUserData);
static void ConUnGrenade(IConsole::IResult *pResult, void *pUserData);
static void ConUnLaser(IConsole::IResult *pResult, void *pUserData);
static void ConUnJetpack(IConsole::IResult *pResult, void *pUserData);
static void ConUnWeapons(IConsole::IResult *pResult, void *pUserData);
static void ConAddWeapon(IConsole::IResult *pResult, void *pUserData);
static void ConRemoveWeapon(IConsole::IResult *pResult, void *pUserData);
void ModifyWeapons(IConsole::IResult *pResult, void *pUserData, int Weapon, bool Remove);
void MoveCharacter(int ClientID, int X, int Y, bool Raw = false);
static void ConGoLeft(IConsole::IResult *pResult, void *pUserData);
static void ConGoRight(IConsole::IResult *pResult, void *pUserData);
static void ConGoUp(IConsole::IResult *pResult, void *pUserData);
static void ConGoDown(IConsole::IResult *pResult, void *pUserData);
static void ConMove(IConsole::IResult *pResult, void *pUserData);
static void ConMoveRaw(IConsole::IResult *pResult, void *pUserData);
static void ConToTeleporter(IConsole::IResult *pResult, void *pUserData);
static void ConToCheckTeleporter(IConsole::IResult *pResult, void *pUserData);
static void ConTeleport(IConsole::IResult *pResult, void *pUserData);
static void ConCredits(IConsole::IResult *pResult, void *pUserData);
static void ConInfo(IConsole::IResult *pResult, void *pUserData);
static void ConHelp(IConsole::IResult *pResult, void *pUserData);
static void ConSettings(IConsole::IResult *pResult, void *pUserData);
static void ConRules(IConsole::IResult *pResult, void *pUserData);
static void ConKill(IConsole::IResult *pResult, void *pUserData);
static void ConTogglePause(IConsole::IResult *pResult, void *pUserData);
static void ConTogglePauseVoted(IConsole::IResult *pResult, void *pUserData);
static void ConToggleSpec(IConsole::IResult *pResult, void *pUserData);
static void ConToggleSpecVoted(IConsole::IResult *pResult, void *pUserData);
static void ConForcePause(IConsole::IResult *pResult, void *pUserData);
static void ConTeamTop5(IConsole::IResult *pResult, void *pUserData);
static void ConTop5(IConsole::IResult *pResult, void *pUserData);
static void ConTimes(IConsole::IResult *pResult, void *pUserData);
static void ConPoints(IConsole::IResult *pResult, void *pUserData);
static void ConTopPoints(IConsole::IResult *pResult, void *pUserData);
static void ConUTF8(IConsole::IResult *pResult, void *pUserData);
static void ConDND(IConsole::IResult *pResult, void *pUserData);
static void ConMapInfo(IConsole::IResult *pResult, void *pUserData);
static void ConTimeout(IConsole::IResult *pResult, void *pUserData);
static void ConSave(IConsole::IResult *pResult, void *pUserData);
static void ConLoad(IConsole::IResult *pResult, void *pUserData);
static void ConMap(IConsole::IResult *pResult, void *pUserData);
static void ConTeamRank(IConsole::IResult *pResult, void *pUserData);
static void ConRank(IConsole::IResult *pResult, void *pUserData);
static void ConBroadTime(IConsole::IResult *pResult, void *pUserData);
static void ConJoinTeam(IConsole::IResult *pResult, void *pUserData);
static void ConLockTeam(IConsole::IResult *pResult, void *pUserData);
static void ConUnlockTeam(IConsole::IResult *pResult, void *pUserData);
static void ConInviteTeam(IConsole::IResult *pResult, void *pUserData);
static void ConMe(IConsole::IResult *pResult, void *pUserData);
static void ConWhisper(IConsole::IResult *pResult, void *pUserData);
static void ConConverse(IConsole::IResult *pResult, void *pUserData);
static void ConSetEyeEmote(IConsole::IResult *pResult, void *pUserData);
static void ConToggleBroadcast(IConsole::IResult *pResult, void *pUserData);
static void ConEyeEmote(IConsole::IResult *pResult, void *pUserData);
static void ConShowOthers(IConsole::IResult *pResult, void *pUserData);
static void ConShowAll(IConsole::IResult *pResult, void *pUserData);
static void ConSpecTeam(IConsole::IResult *pResult, void *pUserData);
static void ConNinjaJetpack(IConsole::IResult *pResult, void *pUserData);
static void ConSayTime(IConsole::IResult *pResult, void *pUserData);
static void ConSayTimeAll(IConsole::IResult *pResult, void *pUserData);
static void ConTime(IConsole::IResult *pResult, void *pUserData);
static void ConSetTimerType(IConsole::IResult *pResult, void *pUserData);
static void ConRescue(IConsole::IResult *pResult, void *pUserData);
static void ConProtectedKill(IConsole::IResult *pResult, void *pUserData);
static void ConVoteMute(IConsole::IResult *pResult, void *pUserData);
static void ConVoteUnmute(IConsole::IResult *pResult, void *pUserData);
static void ConVoteMutes(IConsole::IResult *pResult, void *pUserData);
static void ConMute(IConsole::IResult *pResult, void *pUserData);
static void ConMuteID(IConsole::IResult *pResult, void *pUserData);
static void ConMuteIP(IConsole::IResult *pResult, void *pUserData);
static void ConUnmute(IConsole::IResult *pResult, void *pUserData);
static void ConMutes(IConsole::IResult *pResult, void *pUserData);
static void ConModerate(IConsole::IResult *pResult, void *pUserData);
static void ConList(IConsole::IResult *pResult, void *pUserData);
static void ConSetDDRTeam(IConsole::IResult *pResult, void *pUserData);
static void ConUninvite(IConsole::IResult *pResult, void *pUserData);
static void ConFreezeHammer(IConsole::IResult *pResult, void *pUserData);
static void ConUnFreezeHammer(IConsole::IResult *pResult, void *pUserData);
enum
{
MAX_MUTES=32,
MAX_VOTE_MUTES=32,
};
struct CMute
{
NETADDR m_Addr;
int m_Expire;
char m_aReason[128];
};
CMute m_aMutes[MAX_MUTES];
int m_NumMutes;
CMute m_aVoteMutes[MAX_VOTE_MUTES];
int m_NumVoteMutes;
bool TryMute(const NETADDR *pAddr, int Secs, const char *pReason);
void Mute(const NETADDR *pAddr, int Secs, const char *pDisplayName, const char *pReason = "");
bool TryVoteMute(const NETADDR *pAddr, int Secs);
bool VoteMute(const NETADDR *pAddr, int Secs, const char *pDisplayName, int AuthedID);
bool VoteUnmute(const NETADDR *pAddr, const char *pDisplayName, int AuthedID);
void Whisper(int ClientID, char *pStr);
void WhisperID(int ClientID, int VictimID, char *pMessage);
void Converse(int ClientID, char *pStr);
bool IsVersionBanned(int Version);
void UnlockTeam(int ClientID, int Team);
public:
CLayers *Layers() { return &m_Layers; }
class IScore *Score() { return m_pScore; }
bool m_VoteKick;
bool m_VoteSpec;
int m_VoteVictim;
enum
{
VOTE_ENFORCE_NO_ADMIN = VOTE_ENFORCE_YES + 1,
VOTE_ENFORCE_YES_ADMIN
};
int m_VoteEnforcer;
void SendRecord(int ClientID);
static void SendChatResponse(const char *pLine, void *pUser, bool Highlighted = false);
static void SendChatResponseAll(const char *pLine, void *pUser);
virtual void OnSetAuthed(int ClientID,int Level);
virtual bool PlayerCollision();
virtual bool PlayerHooking();
virtual float PlayerJetpack();
void ResetTuning();
int m_ChatResponseTargetID;
int m_ChatPrintCBIndex;
};
inline int64_t CmaskAll() { return -1LL; }
inline int64_t CmaskOne(int ClientID) { return 1LL<<ClientID; }
inline int64_t CmaskUnset(int64_t Mask, int ClientID) { return Mask^CmaskOne(ClientID); }
inline int64_t CmaskAllExceptOne(int ClientID) { return CmaskUnset(CmaskAll(), ClientID); }
inline bool CmaskIsSet(int64_t Mask, int ClientID) { return (Mask&CmaskOne(ClientID)) != 0; }
#endif