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_SHARED_CONSOLE_H |
4 | #define ENGINE_SHARED_CONSOLE_H |
5 | |
6 | #include "memheap.h" |
7 | #include <base/math.h> |
8 | #include <base/system.h> |
9 | #include <engine/console.h> |
10 | #include <engine/storage.h> |
11 | |
12 | class CConsole : public IConsole |
13 | { |
14 | class CCommand : public CCommandInfo |
15 | { |
16 | public: |
17 | CCommand *m_pNext; |
18 | int m_Flags; |
19 | bool m_Temp; |
20 | FCommandCallback m_pfnCallback; |
21 | void *m_pUserData; |
22 | |
23 | const CCommandInfo *NextCommandInfo(int AccessLevel, int FlagMask) const override; |
24 | |
25 | void SetAccessLevel(int AccessLevel) { m_AccessLevel = clamp(val: AccessLevel, lo: (int)(ACCESS_LEVEL_ADMIN), hi: (int)(ACCESS_LEVEL_USER)); } |
26 | }; |
27 | |
28 | class CChain |
29 | { |
30 | public: |
31 | FChainCommandCallback m_pfnChainCallback; |
32 | FCommandCallback m_pfnCallback; |
33 | void *m_pCallbackUserData; |
34 | void *m_pUserData; |
35 | }; |
36 | |
37 | int m_FlagMask; |
38 | bool m_StoreCommands; |
39 | const char *m_apStrokeStr[2]; |
40 | CCommand *m_pFirstCommand; |
41 | |
42 | class CExecFile |
43 | { |
44 | public: |
45 | const char *m_pFilename; |
46 | CExecFile *m_pPrev; |
47 | }; |
48 | |
49 | CExecFile *m_pFirstExec; |
50 | IStorage *m_pStorage; |
51 | int m_AccessLevel; |
52 | |
53 | CCommand *m_pRecycleList; |
54 | CHeap m_TempCommands; |
55 | |
56 | static void TraverseChain(FCommandCallback *ppfnCallback, void **ppUserData); |
57 | |
58 | static void Con_Chain(IResult *pResult, void *pUserData); |
59 | static void Con_Echo(IResult *pResult, void *pUserData); |
60 | static void Con_Exec(IResult *pResult, void *pUserData); |
61 | static void ConCommandAccess(IResult *pResult, void *pUser); |
62 | static void ConCommandStatus(IConsole::IResult *pResult, void *pUser); |
63 | |
64 | void ExecuteLineStroked(int Stroke, const char *pStr, int ClientId = -1, bool InterpretSemicolons = true) override; |
65 | |
66 | FTeeHistorianCommandCallback m_pfnTeeHistorianCommandCallback; |
67 | void *m_pTeeHistorianCommandUserdata; |
68 | |
69 | FUnknownCommandCallback m_pfnUnknownCommandCallback = EmptyUnknownCommandCallback; |
70 | void *m_pUnknownCommandUserdata = nullptr; |
71 | |
72 | enum |
73 | { |
74 | CONSOLE_MAX_STR_LENGTH = 8192, |
75 | MAX_PARTS = (CONSOLE_MAX_STR_LENGTH + 1) / 2 |
76 | }; |
77 | |
78 | class CResult : public IResult |
79 | { |
80 | public: |
81 | char m_aStringStorage[CONSOLE_MAX_STR_LENGTH + 1]; |
82 | char *m_pArgsStart; |
83 | |
84 | const char *m_pCommand; |
85 | const char *m_apArgs[MAX_PARTS]; |
86 | |
87 | CResult() |
88 | |
89 | { |
90 | mem_zero(block: m_aStringStorage, size: sizeof(m_aStringStorage)); |
91 | m_pArgsStart = 0; |
92 | m_pCommand = 0; |
93 | mem_zero(block: m_apArgs, size: sizeof(m_apArgs)); |
94 | } |
95 | |
96 | CResult &operator=(const CResult &Other) |
97 | { |
98 | if(this != &Other) |
99 | { |
100 | IResult::operator=(Other); |
101 | mem_copy(dest: m_aStringStorage, source: Other.m_aStringStorage, size: sizeof(m_aStringStorage)); |
102 | m_pArgsStart = m_aStringStorage + (Other.m_pArgsStart - Other.m_aStringStorage); |
103 | m_pCommand = m_aStringStorage + (Other.m_pCommand - Other.m_aStringStorage); |
104 | for(unsigned i = 0; i < Other.m_NumArgs; ++i) |
105 | m_apArgs[i] = m_aStringStorage + (Other.m_apArgs[i] - Other.m_aStringStorage); |
106 | } |
107 | return *this; |
108 | } |
109 | |
110 | void AddArgument(const char *pArg) |
111 | { |
112 | m_apArgs[m_NumArgs++] = pArg; |
113 | } |
114 | |
115 | const char *GetString(unsigned Index) const override; |
116 | int GetInteger(unsigned Index) const override; |
117 | float GetFloat(unsigned Index) const override; |
118 | ColorHSLA GetColor(unsigned Index, bool Light) const override; |
119 | |
120 | void RemoveArgument(unsigned Index) override |
121 | { |
122 | dbg_assert(Index < m_NumArgs, "invalid argument index" ); |
123 | for(unsigned i = Index; i < m_NumArgs - 1; i++) |
124 | m_apArgs[i] = m_apArgs[i + 1]; |
125 | |
126 | m_apArgs[m_NumArgs--] = 0; |
127 | } |
128 | |
129 | // DDRace |
130 | |
131 | enum |
132 | { |
133 | VICTIM_NONE = -3, |
134 | VICTIM_ME = -2, |
135 | VICTIM_ALL = -1, |
136 | }; |
137 | |
138 | int m_Victim; |
139 | void ResetVictim(); |
140 | bool HasVictim() const; |
141 | void SetVictim(int Victim); |
142 | void SetVictim(const char *pVictim); |
143 | int GetVictim() const override; |
144 | }; |
145 | |
146 | int ParseStart(CResult *pResult, const char *pString, int Length); |
147 | int ParseArgs(CResult *pResult, const char *pFormat); |
148 | |
149 | /* |
150 | this function will set pFormat to the next parameter (i,s,r,v,?) it contains and |
151 | return the parameter; descriptions in brackets like [file] will be skipped; |
152 | returns '\0' if there is no next parameter; expects pFormat to point at a |
153 | parameter |
154 | */ |
155 | char NextParam(const char *&pFormat); |
156 | |
157 | class CExecutionQueue |
158 | { |
159 | CHeap m_Queue; |
160 | |
161 | public: |
162 | struct CQueueEntry |
163 | { |
164 | CQueueEntry *m_pNext; |
165 | CCommand *m_pCommand; |
166 | CResult m_Result; |
167 | } * m_pFirst, *m_pLast; |
168 | |
169 | void AddEntry() |
170 | { |
171 | CQueueEntry *pEntry = m_Queue.Allocate<CQueueEntry>(); |
172 | pEntry->m_pNext = 0; |
173 | if(!m_pFirst) |
174 | m_pFirst = pEntry; |
175 | if(m_pLast) |
176 | m_pLast->m_pNext = pEntry; |
177 | m_pLast = pEntry; |
178 | (void)new(&(pEntry->m_Result)) CResult; |
179 | } |
180 | void Reset() |
181 | { |
182 | m_Queue.Reset(); |
183 | m_pFirst = m_pLast = 0; |
184 | } |
185 | } m_ExecutionQueue; |
186 | |
187 | void AddCommandSorted(CCommand *pCommand); |
188 | CCommand *FindCommand(const char *pName, int FlagMask); |
189 | |
190 | bool m_Cheated; |
191 | |
192 | public: |
193 | CConsole(int FlagMask); |
194 | ~CConsole(); |
195 | |
196 | void Init() override; |
197 | const CCommandInfo *FirstCommandInfo(int AccessLevel, int FlagMask) const override; |
198 | const CCommandInfo *GetCommandInfo(const char *pName, int FlagMask, bool Temp) override; |
199 | int PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback, void *pUser) override; |
200 | |
201 | void ParseArguments(int NumArgs, const char **ppArguments) override; |
202 | void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp) override; |
203 | void RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp) override; |
204 | void DeregisterTemp(const char *pName) override; |
205 | void DeregisterTempAll() override; |
206 | void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser) override; |
207 | void StoreCommands(bool Store) override; |
208 | |
209 | bool LineIsValid(const char *pStr) override; |
210 | void ExecuteLine(const char *pStr, int ClientId = -1, bool InterpretSemicolons = true) override; |
211 | void ExecuteLineFlag(const char *pStr, int FlagMask, int ClientId = -1, bool InterpretSemicolons = true) override; |
212 | bool ExecuteFile(const char *pFilename, int ClientId = -1, bool LogFailure = false, int StorageType = IStorage::TYPE_ALL) override; |
213 | |
214 | char *Format(char *pBuf, int Size, const char *pFrom, const char *pStr) override; |
215 | void Print(int Level, const char *pFrom, const char *pStr, ColorRGBA PrintColor = gs_ConsoleDefaultColor) const override; |
216 | void SetTeeHistorianCommandCallback(FTeeHistorianCommandCallback pfnCallback, void *pUser) override; |
217 | void SetUnknownCommandCallback(FUnknownCommandCallback pfnCallback, void *pUser) override; |
218 | void InitChecksum(CChecksumData *pData) const override; |
219 | |
220 | void SetAccessLevel(int AccessLevel) override { m_AccessLevel = clamp(val: AccessLevel, lo: (int)(ACCESS_LEVEL_ADMIN), hi: (int)(ACCESS_LEVEL_USER)); } |
221 | |
222 | // DDRace |
223 | |
224 | static void ConUserCommandStatus(IConsole::IResult *pResult, void *pUser); |
225 | |
226 | bool Cheated() const override { return m_Cheated; } |
227 | |
228 | int FlagMask() const override { return m_FlagMask; } |
229 | void SetFlagMask(int FlagMask) override { m_FlagMask = FlagMask; } |
230 | }; |
231 | |
232 | #endif |
233 | |