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_CONSOLE_H
4#define ENGINE_CONSOLE_H
5
6#include "kernel.h"
7
8#include <base/color.h>
9
10#include <engine/storage.h>
11
12#include <memory>
13
14static constexpr ColorRGBA gs_ConsoleDefaultColor(1, 1, 1, 1);
15
16enum LEVEL : char;
17struct CChecksumData;
18
19class IConsole : public IInterface
20{
21 MACRO_INTERFACE("console")
22public:
23 // TODO: rework/cleanup
24 enum
25 {
26 OUTPUT_LEVEL_STANDARD = 0,
27 OUTPUT_LEVEL_ADDINFO,
28 OUTPUT_LEVEL_DEBUG,
29 };
30
31 enum
32 {
33 TEMPCMD_NAME_LENGTH = 64,
34 TEMPCMD_HELP_LENGTH = 192,
35 TEMPCMD_PARAMS_LENGTH = 96,
36
37 CMDLINE_LENGTH = 512,
38
39 CLIENT_ID_UNSPECIFIED = -1, // has full admin access on the server
40 CLIENT_ID_GAME = -2,
41 CLIENT_ID_NO_GAME = -3,
42
43 FILE_RECURSION_LIMIT = 16,
44 };
45
46 enum class EAccessLevel
47 {
48 ADMIN,
49 MODERATOR,
50 HELPER,
51 USER,
52 };
53
54 // TODO: rework this interface to reduce the amount of virtual calls
55 class IResult
56 {
57 protected:
58 unsigned m_NumArgs;
59
60 public:
61 IResult(int ClientId) :
62 m_NumArgs(0),
63 m_ClientId(ClientId) {}
64 virtual ~IResult() = default;
65
66 virtual int GetInteger(unsigned Index) const = 0;
67 virtual float GetFloat(unsigned Index) const = 0;
68 virtual const char *GetString(unsigned Index) const = 0;
69 virtual ColorHSLA GetColor(unsigned Index, float DarkestLighting) const = 0;
70
71 virtual void RemoveArgument(unsigned Index) = 0;
72
73 int NumArguments() const { return m_NumArgs; }
74 int m_ClientId;
75
76 // DDRace
77
78 virtual int GetVictim() const = 0;
79 };
80
81 class ICommandInfo
82 {
83 public:
84 virtual ~ICommandInfo() = default;
85 virtual const char *Name() const = 0;
86 virtual const char *Help() const = 0;
87 virtual const char *Params() const = 0;
88 virtual int Flags() const = 0;
89 virtual EAccessLevel GetAccessLevel() const = 0;
90 };
91
92 typedef void (*FTeeHistorianCommandCallback)(int ClientId, int FlagMask, const char *pCmd, IResult *pResult, void *pUser);
93 typedef void (*FPossibleCallback)(int Index, const char *pCmd, void *pUser);
94 typedef void (*FCommandCallback)(IResult *pResult, void *pUserData);
95 typedef void (*FChainCommandCallback)(IResult *pResult, void *pUserData, FCommandCallback pfnCallback, void *pCallbackUserData);
96 typedef bool (*FUnknownCommandCallback)(const char *pCommand, void *pUser); // returns true if the callback has handled the argument
97 typedef bool (*FCanUseCommandCallback)(int ClientId, const ICommandInfo *pCommand, void *pUser);
98
99 static void EmptyPossibleCommandCallback(int Index, const char *pCmd, void *pUser) {}
100 static bool EmptyUnknownCommandCallback(const char *pCommand, void *pUser) { return false; }
101
102 virtual void Init() = 0;
103 virtual const ICommandInfo *FirstCommandInfo(int ClientId, int FlagMask) const = 0;
104 virtual const ICommandInfo *NextCommandInfo(const IConsole::ICommandInfo *pInfo, int ClientId, int FlagMask) const = 0;
105 virtual const ICommandInfo *GetCommandInfo(const char *pName, int FlagMask, bool Temp) = 0;
106 virtual int PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback = EmptyPossibleCommandCallback, void *pUser = nullptr) = 0;
107 virtual void ParseArguments(int NumArgs, const char **ppArguments) = 0;
108
109 virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp) = 0;
110 virtual void RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp) = 0;
111 virtual void DeregisterTemp(const char *pName) = 0;
112 virtual void DeregisterTempAll() = 0;
113 virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser) = 0;
114 virtual void StoreCommands(bool Store) = 0;
115
116 virtual bool LineIsValid(const char *pStr) = 0;
117 virtual void ExecuteLine(const char *pStr, int ClientId = CLIENT_ID_UNSPECIFIED, bool InterpretSemicolons = true) = 0;
118 virtual void ExecuteLineFlag(const char *pStr, int FlasgMask, int ClientId = CLIENT_ID_UNSPECIFIED, bool InterpretSemicolons = true) = 0;
119 virtual void ExecuteLineStroked(int Stroke, const char *pStr, int ClientId = CLIENT_ID_UNSPECIFIED, bool InterpretSemicolons = true) = 0;
120 virtual bool ExecuteFile(const char *pFilename, int ClientId = CLIENT_ID_UNSPECIFIED, bool LogFailure = false, int StorageType = IStorage::TYPE_ALL) = 0;
121
122 /**
123 * @deprecated Prefer using the `log_*` functions from base/log.h instead of this function for the following reasons:
124 * - They support `printf`-formatting without a separate buffer.
125 * - They support all five log levels.
126 * - They do not require a pointer to `IConsole` to be used.
127 */
128 virtual void Print(int Level, const char *pFrom, const char *pStr, ColorRGBA PrintColor = gs_ConsoleDefaultColor) const = 0;
129 virtual void SetTeeHistorianCommandCallback(FTeeHistorianCommandCallback pfnCallback, void *pUser) = 0;
130 virtual void SetUnknownCommandCallback(FUnknownCommandCallback pfnCallback, void *pUser) = 0;
131 virtual void SetCanUseCommandCallback(FCanUseCommandCallback pfnCallback, void *pUser) = 0;
132 virtual void InitChecksum(CChecksumData *pData) const = 0;
133
134 static LEVEL ToLogLevel(int ConsoleLevel);
135 static int ToLogLevelFilter(int ConsoleLevel);
136
137 // DDRace
138
139 virtual bool Cheated() const = 0;
140
141 virtual int FlagMask() const = 0;
142 virtual void SetFlagMask(int FlagMask) = 0;
143};
144
145std::unique_ptr<IConsole> CreateConsole(int FlagMask);
146
147#endif // FILE_ENGINE_CONSOLE_H
148