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 // The id `-1` has full admin access on the server.
40 // It is used in the following cases:
41 // - Loading the config file on server start
42 // - Econ and fifo connections
43 // - Commands run on passed votes
44 //
45 // Client side it has less importance
46 // because there is no difference in access levels.
47 CLIENT_ID_UNSPECIFIED = -1,
48 CLIENT_ID_GAME = -2,
49 CLIENT_ID_NO_GAME = -3,
50
51 FILE_RECURSION_LIMIT = 16,
52 };
53
54 enum class EAccessLevel
55 {
56 ADMIN,
57 MODERATOR,
58 HELPER,
59 USER,
60 };
61
62 // TODO: rework this interface to reduce the amount of virtual calls
63 class IResult
64 {
65 protected:
66 unsigned m_NumArgs;
67
68 public:
69 IResult(int ClientId) :
70 m_NumArgs(0),
71 m_ClientId(ClientId) {}
72 virtual ~IResult() = default;
73
74 virtual int GetInteger(unsigned Index) const = 0;
75 virtual float GetFloat(unsigned Index) const = 0;
76 virtual const char *GetString(unsigned Index) const = 0;
77 virtual ColorHSLA GetColor(unsigned Index, float DarkestLighting) const = 0;
78
79 virtual void RemoveArgument(unsigned Index) = 0;
80
81 int NumArguments() const { return m_NumArgs; }
82 int m_ClientId;
83
84 // DDRace
85
86 virtual int GetVictim() const = 0;
87 };
88
89 class ICommandInfo
90 {
91 public:
92 virtual ~ICommandInfo() = default;
93 virtual const char *Name() const = 0;
94 virtual const char *Help() const = 0;
95 virtual const char *Params() const = 0;
96 virtual int Flags() const = 0;
97 virtual EAccessLevel GetAccessLevel() const = 0;
98 };
99
100 typedef void (*FTeeHistorianCommandCallback)(int ClientId, int FlagMask, const char *pCmd, IResult *pResult, void *pUser);
101 typedef void (*FPossibleCallback)(int Index, const char *pCmd, void *pUser);
102 typedef void (*FCommandCallback)(IResult *pResult, void *pUserData);
103 typedef void (*FChainCommandCallback)(IResult *pResult, void *pUserData, FCommandCallback pfnCallback, void *pCallbackUserData);
104 typedef bool (*FUnknownCommandCallback)(const char *pCommand, void *pUser); // returns true if the callback has handled the argument
105 typedef bool (*FCanUseCommandCallback)(int ClientId, const ICommandInfo *pCommand, void *pUser);
106
107 static void EmptyPossibleCommandCallback(int Index, const char *pCmd, void *pUser) {}
108 static bool EmptyUnknownCommandCallback(const char *pCommand, void *pUser) { return false; }
109
110 virtual void Init() = 0;
111 virtual const ICommandInfo *FirstCommandInfo(int ClientId, int FlagMask) const = 0;
112 virtual const ICommandInfo *NextCommandInfo(const IConsole::ICommandInfo *pInfo, int ClientId, int FlagMask) const = 0;
113 virtual const ICommandInfo *GetCommandInfo(const char *pName, int FlagMask, bool Temp) = 0;
114 virtual int PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback = EmptyPossibleCommandCallback, void *pUser = nullptr) = 0;
115 virtual void ParseArguments(int NumArgs, const char **ppArguments) = 0;
116
117 virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp) = 0;
118 virtual void RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp) = 0;
119 virtual void DeregisterTemp(const char *pName) = 0;
120 virtual void DeregisterTempAll() = 0;
121 virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser) = 0;
122 virtual void StoreCommands(bool Store) = 0;
123
124 virtual bool LineIsValid(const char *pStr) = 0;
125 virtual void ExecuteLine(const char *pStr, int ClientId, bool InterpretSemicolons = true) = 0;
126 virtual void ExecuteLineFlag(const char *pStr, int FlasgMask, int ClientId, bool InterpretSemicolons = true) = 0;
127 virtual void ExecuteLineStroked(int Stroke, const char *pStr, int ClientId, bool InterpretSemicolons = true) = 0;
128 virtual bool ExecuteFile(const char *pFilename, int ClientId, bool LogFailure = false, int StorageType = IStorage::TYPE_ALL) = 0;
129
130 /**
131 * @deprecated Prefer using the `log_*` functions from base/log.h instead of this function for the following reasons:
132 * - They support `printf`-formatting without a separate buffer.
133 * - They support all five log levels.
134 * - They do not require a pointer to `IConsole` to be used.
135 */
136 virtual void Print(int Level, const char *pFrom, const char *pStr, ColorRGBA PrintColor = gs_ConsoleDefaultColor) const = 0;
137 virtual void SetTeeHistorianCommandCallback(FTeeHistorianCommandCallback pfnCallback, void *pUser) = 0;
138 virtual void SetUnknownCommandCallback(FUnknownCommandCallback pfnCallback, void *pUser) = 0;
139 virtual void SetCanUseCommandCallback(FCanUseCommandCallback pfnCallback, void *pUser) = 0;
140 virtual void InitChecksum(CChecksumData *pData) const = 0;
141
142 static LEVEL ToLogLevel(int ConsoleLevel);
143 static int ToLogLevelFilter(int ConsoleLevel);
144
145 // DDRace
146
147 virtual bool Cheated() const = 0;
148
149 virtual int FlagMask() const = 0;
150 virtual void SetFlagMask(int FlagMask) = 0;
151};
152
153std::unique_ptr<IConsole> CreateConsole(int FlagMask);
154
155#endif // FILE_ENGINE_CONSOLE_H
156