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