ddnet/src/engine/shared/console.h
heinrich5991 fa4bcd5ec0 Unify logging infrastructure between IConsole and dbg_msg
This makes the "black console window" less important on Windows (or
anywhere else, for that matter), lets you see logs from other threads in
the f1 console, and removes the distinction between `IConsole::Print`
and `dbg_msg`.
2022-04-29 15:21:26 +02:00

226 lines
6.6 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 ENGINE_SHARED_CONSOLE_H
#define ENGINE_SHARED_CONSOLE_H
#include "memheap.h"
#include <base/math.h>
#include <engine/console.h>
#include <engine/storage.h>
class CConsole : public IConsole
{
class CCommand : public CCommandInfo
{
public:
CCommand *m_pNext;
int m_Flags;
bool m_Temp;
FCommandCallback m_pfnCallback;
void *m_pUserData;
virtual const CCommandInfo *NextCommandInfo(int AccessLevel, int FlagMask) const;
void SetAccessLevel(int AccessLevel) { m_AccessLevel = clamp(AccessLevel, (int)(ACCESS_LEVEL_ADMIN), (int)(ACCESS_LEVEL_USER)); }
};
class CChain
{
public:
FChainCommandCallback m_pfnChainCallback;
FCommandCallback m_pfnCallback;
void *m_pCallbackUserData;
void *m_pUserData;
};
int m_FlagMask;
bool m_StoreCommands;
const char *m_apStrokeStr[2];
CCommand *m_pFirstCommand;
class CExecFile
{
public:
const char *m_pFilename;
CExecFile *m_pPrev;
};
CExecFile *m_pFirstExec;
class CConfig *m_pConfig;
class IStorage *m_pStorage;
int m_AccessLevel;
CCommand *m_pRecycleList;
CHeap m_TempCommands;
static void Con_Chain(IResult *pResult, void *pUserData);
static void Con_Echo(IResult *pResult, void *pUserData);
static void Con_Exec(IResult *pResult, void *pUserData);
static void ConToggle(IResult *pResult, void *pUser);
static void ConToggleStroke(IResult *pResult, void *pUser);
static void ConCommandAccess(IResult *pResult, void *pUser);
static void ConCommandStatus(IConsole::IResult *pResult, void *pUser);
void ExecuteLineStroked(int Stroke, const char *pStr, int ClientID = -1, bool InterpretSemicolons = true);
FTeeHistorianCommandCallback m_pfnTeeHistorianCommandCallback;
void *m_pTeeHistorianCommandUserdata;
enum
{
CONSOLE_MAX_STR_LENGTH = 8192,
MAX_PARTS = (CONSOLE_MAX_STR_LENGTH + 1) / 2
};
class CResult : public IResult
{
public:
char m_aStringStorage[CONSOLE_MAX_STR_LENGTH + 1];
char *m_pArgsStart;
const char *m_pCommand;
const char *m_apArgs[MAX_PARTS];
CResult()
{
mem_zero(m_aStringStorage, sizeof(m_aStringStorage));
m_pArgsStart = 0;
m_pCommand = 0;
mem_zero(m_apArgs, sizeof(m_apArgs));
}
CResult &operator=(const CResult &Other)
{
if(this != &Other)
{
IResult::operator=(Other);
mem_copy(m_aStringStorage, Other.m_aStringStorage, sizeof(m_aStringStorage));
m_pArgsStart = m_aStringStorage + (Other.m_pArgsStart - Other.m_aStringStorage);
m_pCommand = m_aStringStorage + (Other.m_pCommand - Other.m_aStringStorage);
for(unsigned i = 0; i < Other.m_NumArgs; ++i)
m_apArgs[i] = m_aStringStorage + (Other.m_apArgs[i] - Other.m_aStringStorage);
}
return *this;
}
void AddArgument(const char *pArg)
{
m_apArgs[m_NumArgs++] = pArg;
}
virtual const char *GetString(unsigned Index);
virtual int GetInteger(unsigned Index);
virtual float GetFloat(unsigned Index);
virtual ColorHSLA GetColor(unsigned Index, bool Light);
virtual void RemoveArgument(unsigned Index)
{
dbg_assert(Index < m_NumArgs, "invalid argument index");
for(unsigned i = Index; i < m_NumArgs - 1; i++)
m_apArgs[i] = m_apArgs[i + 1];
m_apArgs[m_NumArgs--] = 0;
}
// DDRace
enum
{
VICTIM_NONE = -3,
VICTIM_ME = -2,
VICTIM_ALL = -1,
};
int m_Victim;
void ResetVictim();
bool HasVictim();
void SetVictim(int Victim);
void SetVictim(const char *pVictim);
virtual int GetVictim();
};
int ParseStart(CResult *pResult, const char *pString, int Length);
int ParseArgs(CResult *pResult, const char *pFormat);
/*
this function will set pFormat to the next parameter (i,s,r,v,?) it contains and
return the parameter; descriptions in brackets like [file] will be skipped;
returns '\0' if there is no next parameter; expects pFormat to point at a
parameter
*/
char NextParam(const char *&pFormat);
class CExecutionQueue
{
CHeap m_Queue;
public:
struct CQueueEntry
{
CQueueEntry *m_pNext;
FCommandCallback m_pfnCommandCallback;
void *m_pCommandUserData;
CResult m_Result;
} * m_pFirst, *m_pLast;
void AddEntry()
{
CQueueEntry *pEntry = static_cast<CQueueEntry *>(m_Queue.Allocate(sizeof(CQueueEntry)));
pEntry->m_pNext = 0;
if(!m_pFirst)
m_pFirst = pEntry;
if(m_pLast)
m_pLast->m_pNext = pEntry;
m_pLast = pEntry;
(void)new(&(pEntry->m_Result)) CResult;
}
void Reset()
{
m_Queue.Reset();
m_pFirst = m_pLast = 0;
}
} m_ExecutionQueue;
void AddCommandSorted(CCommand *pCommand);
CCommand *FindCommand(const char *pName, int FlagMask);
public:
CConfig *Config() { return m_pConfig; }
CConsole(int FlagMask);
~CConsole();
virtual void Init();
virtual const CCommandInfo *FirstCommandInfo(int AccessLevel, int FlagMask) const;
virtual const CCommandInfo *GetCommandInfo(const char *pName, int FlagMask, bool Temp);
virtual void PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback, void *pUser);
virtual void ParseArguments(int NumArgs, const char **ppArguments);
virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp);
virtual void RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp);
virtual void DeregisterTemp(const char *pName);
virtual void DeregisterTempAll();
virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser);
virtual void StoreCommands(bool Store);
virtual bool LineIsValid(const char *pStr);
virtual void ExecuteLine(const char *pStr, int ClientID = -1, bool InterpretSemicolons = true);
virtual void ExecuteLineFlag(const char *pStr, int FlagMask, int ClientID = -1, bool InterpretSemicolons = true);
virtual void ExecuteFile(const char *pFilename, int ClientID = -1, bool LogFailure = false, int StorageType = IStorage::TYPE_ALL);
virtual char *Format(char *pBuf, int Size, const char *pFrom, const char *pStr);
virtual void Print(int Level, const char *pFrom, const char *pStr, ColorRGBA PrintColor = gs_ConsoleDefaultColor);
virtual void SetTeeHistorianCommandCallback(FTeeHistorianCommandCallback pfnCallback, void *pUser);
virtual void InitChecksum(CChecksumData *pData) const;
void SetAccessLevel(int AccessLevel) { m_AccessLevel = clamp(AccessLevel, (int)(ACCESS_LEVEL_ADMIN), (int)(ACCESS_LEVEL_USER)); }
void ResetServerGameSettings();
// DDRace
static void ConUserCommandStatus(IConsole::IResult *pResult, void *pUser);
void SetFlagMask(int FlagMask) { m_FlagMask = FlagMask; }
};
#endif