/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #ifndef CRYINCLUDE_CRYSYSTEM_XCONSOLE_H #define CRYINCLUDE_CRYSYSTEM_XCONSOLE_H #pragma once #include <IConsole.h> #include <CryCrc32.h> #include "Timer.h" #include <AzFramework/Components/ConsoleBus.h> #include <AzFramework/CommandLine/CommandRegistrationBus.h> #include <AzFramework/Input/Buses/Requests/InputSystemCursorRequestBus.h> #include <AzFramework/Input/Events/InputChannelEventListener.h> #include <AzFramework/Input/Events/InputTextEventListener.h> //forward declaration struct INetwork; class CSystem; #define MAX_HISTORY_ENTRIES 50 #define LINE_BORDER 10 enum ScrollDir { sdDOWN, sdUP, sdNONE }; ////////////////////////////////////////////////////////////////////////// // Console command holds information about commands registered to console. ////////////////////////////////////////////////////////////////////////// struct CConsoleCommand { string m_sName; // Console command name string m_sCommand; // lua code that is executed when this command is invoked string m_sHelp; // optional help string - can be shown in the console with "<commandname> ?" int m_nFlags; // bitmask consist of flag starting with VF_ e.g. VF_CHEAT ConsoleCommandFunc m_func; // Pointer to console command. ////////////////////////////////////////////////////////////////////////// CConsoleCommand() : m_func(0) , m_nFlags(0) {} size_t sizeofThis () const {return sizeof(*this) + m_sName.capacity() + 1 + m_sCommand.capacity() + 1; } void GetMemoryUsage (class ICrySizer* pSizer) const { pSizer->AddObject(m_sName); pSizer->AddObject(m_sCommand); pSizer->AddObject(m_sHelp); } }; ////////////////////////////////////////////////////////////////////////// // Implements IConsoleCmdArgs. ////////////////////////////////////////////////////////////////////////// struct CConsoleCommandArgs : public IConsoleCmdArgs { CConsoleCommandArgs(string& line, std::vector<string>& args) : m_line(line) , m_args(args) {}; virtual int GetArgCount() const { return m_args.size(); }; // Get argument by index, nIndex must be in 0 <= nIndex < GetArgCount() virtual const char* GetArg(int nIndex) const { assert(nIndex >= 0 && nIndex < GetArgCount()); if (!(nIndex >= 0 && nIndex < GetArgCount())) { return NULL; } return m_args[nIndex].c_str(); } virtual const char* GetCommandLine() const { return m_line.c_str(); } private: std::vector<string>& m_args; string& m_line; }; struct string_nocase_lt { bool operator()(const char* s1, const char* s2) const { return azstricmp(s1, s2) < 0; } }; /* - very dangerous to use with STL containers struct string_nocase_lt { bool operator()( const char *s1,const char *s2 ) const { return _stricmp(s1,s2) < 0; } bool operator()( const string &s1,const string &s2 ) const { return _stricmp(s1.c_str(),s2.c_str()) < 0; } }; */ //forward declarations class ITexture; struct IRenderer; /*! engine console implementation @see IConsole */ class CXConsole : public IConsole , public AzFramework::InputChannelEventListener , public AzFramework::InputTextEventListener , public IRemoteConsoleListener , public AzFramework::ConsoleRequestBus::Handler , public AzFramework::CommandRegistrationBus::Handler { public: typedef std::deque<string> ConsoleBuffer; typedef ConsoleBuffer::iterator ConsoleBufferItor; typedef ConsoleBuffer::reverse_iterator ConsoleBufferRItor; // constructor CXConsole(); // destructor virtual ~CXConsole(); void SetStatus(bool bActive){ m_bConsoleActive = bActive; } bool GetStatus() const { return m_bConsoleActive; } // void FreeRenderResources(); // void Copy(); void Paste(); // interface IConsole --------------------------------------------------------- virtual void Release(); virtual void Init(ISystem* pSystem); virtual ICVar* RegisterString(const char* sName, const char* sValue, int nFlags, const char* help = "", ConsoleVarFunc pChangeFunc = 0); virtual ICVar* RegisterInt(const char* sName, int iValue, int nFlags, const char* help = "", ConsoleVarFunc pChangeFunc = 0); virtual ICVar* RegisterInt64(const char* sName, int64 iValue, int nFlags, const char* help = "", ConsoleVarFunc pChangeFunc = 0); virtual ICVar* RegisterFloat(const char* sName, float fValue, int nFlags, const char* help = "", ConsoleVarFunc pChangeFunc = 0); virtual ICVar* Register(const char* name, float* src, float defaultvalue, int flags = 0, const char* help = "", ConsoleVarFunc pChangeFunc = 0, bool allowModify = true); virtual ICVar* Register(const char* name, int* src, int defaultvalue, int flags = 0, const char* help = "", ConsoleVarFunc pChangeFunc = 0, bool allowModify = true); virtual ICVar* Register(const char* name, const char** src, const char* defaultvalue, int flags = 0, const char* help = "", ConsoleVarFunc pChangeFunc = 0, bool allowModify = true); virtual ICVar* Register(ICVar* pVar) { RegisterVar(pVar); return pVar; } virtual void UnregisterVariable(const char* sVarName, bool bDelete = false); virtual void SetScrollMax(int value); virtual void AddOutputPrintSink(IOutputPrintSink* inpSink); virtual void RemoveOutputPrintSink(IOutputPrintSink* inpSink); virtual void ShowConsole(bool show, const int iRequestScrollMax = -1); virtual void DumpCVars(ICVarDumpSink* pCallback, unsigned int nFlagsFilter = 0); virtual void DumpKeyBinds(IKeyBindDumpSink* pCallback); virtual void CreateKeyBind(const char* sCmd, const char* sRes); virtual const char* FindKeyBind(const char* sCmd) const; virtual void SetImage(ITexture* pImage, bool bDeleteCurrent); virtual inline ITexture* GetImage() { return m_pImage; } virtual void StaticBackground(bool bStatic) { m_bStaticBackground = bStatic; } virtual bool GetLineNo(const int indwLineNo, char* outszBuffer, const int indwBufferSize) const; virtual int GetLineCount() const; virtual ICVar* GetCVar(const char* name); virtual char* GetVariable(const char* szVarName, const char* szFileName, const char* def_val); virtual float GetVariable(const char* szVarName, const char* szFileName, float def_val); virtual void PrintLine(const char* s); virtual void PrintLinePlus(const char* s); virtual bool GetStatus(); virtual void Clear(); virtual void Update(); virtual void Draw(); virtual bool AddCommand(const char* sCommand, ConsoleCommandFunc func, int nFlags = 0, const char* sHelp = NULL); virtual bool AddCommand(const char* sName, const char* sScriptFunc, int nFlags = 0, const char* sHelp = NULL); virtual void RemoveCommand(const char* sName); virtual void ExecuteString(const char* command, const bool bSilentMode, const bool bDeferExecution = false); virtual void ExecuteConsoleCommand(const char* command) override; virtual void ResetCVarsToDefaults() override; virtual void Exit(const char* command, ...) PRINTF_PARAMS(2, 3); virtual bool IsOpened(); virtual int GetNumVars(); virtual int GetNumVisibleVars(); virtual size_t GetSortedVars(const char** pszArray, size_t numItems, const char* szPrefix = 0); virtual int GetNumCheatVars(); virtual void SetCheatVarHashRange(size_t firstVar, size_t lastVar); virtual void CalcCheatVarHash(); virtual bool IsHashCalculated(); virtual uint64 GetCheatVarHash(); virtual void FindVar(const char* substr); virtual const char* AutoComplete(const char* substr); virtual const char* AutoCompletePrev(const char* substr); virtual const char* ProcessCompletion(const char* szInputBuffer); virtual void RegisterAutoComplete(const char* sVarOrCommand, IConsoleArgumentAutoComplete* pArgAutoComplete); virtual void UnRegisterAutoComplete(const char* sVarOrCommand); virtual void ResetAutoCompletion(); virtual void GetMemoryUsage (ICrySizer* pSizer) const; virtual void ResetProgressBar(int nProgressRange); virtual void TickProgressBar(); virtual void SetLoadingImage(const char* szFilename); virtual void AddConsoleVarSink(IConsoleVarSink* pSink); virtual void RemoveConsoleVarSink(IConsoleVarSink* pSink); virtual const char* GetHistoryElement(const bool bUpOrDown); virtual void AddCommandToHistory(const char* szCommand); virtual void SetInputLine(const char* szLine); virtual void LoadConfigVar(const char* sVariable, const char* sValue); virtual void EnableActivationKey(bool bEnable); #if defined(DEDICATED_SERVER) virtual void SetClientDataProbeString(const char* pName, const char* pValue); #endif // InputChannelEventListener / InputTextEventListener bool OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) override; bool OnInputTextEventFiltered(const AZStd::string& textUTF8) override; // interface IRemoteConsoleListener ------------------------------------------------------------------ virtual void OnConsoleCommand(const char* cmd); // interface IConsoleVarSink ---------------------------------------------------------------------- virtual bool OnBeforeVarChange(ICVar* pVar, const char* sNewValue); virtual void OnAfterVarChange(ICVar* pVar); // interface CommandRegistration -------------------------------------------------------------------- bool RegisterCommand(AZStd::string_view identifier, AZStd::string_view helpText, AZ::u32 commandFlags, AzFramework::CommandFunction callback) override; bool UnregisterCommand(AZStd::string_view identifier) override; void ExecuteRegisteredCommand(IConsoleCmdArgs* pArg); ////////////////////////////////////////////////////////////////////////// // Returns // 0 if the operation failed ICVar* RegisterCVarGroup(const char* sName, const char* szFileName); virtual void PrintCheatVars(bool bUseLastHashRange); virtual char* GetCheatVarAt(uint32 nOffset); void SetProcessingGroup(bool isGroup) { m_bIsProcessingGroup = isGroup; } bool GetIsProcessingGroup(void) const { return m_bIsProcessingGroup; } protected: // ---------------------------------------------------------------------------------------- void DrawBuffer(int nScrollPos, const char* szEffect); void RegisterVar(ICVar* pCVar, ConsoleVarFunc pChangeFunc = 0); bool ProcessInput(const AzFramework::InputChannel& inputChannel); void AddLine(const char* inputStr); void AddLinePlus(const char* inputStr); void AddInputUTF8(const AZStd::string& textUTF8); void RemoveInputChar(bool bBackSpace); void ExecuteInputBuffer(); void ExecuteCommand(CConsoleCommand& cmd, string& params, bool bIgnoreDevMode = false); void ScrollConsole(); // CommandRegistration usage struct CommandRegistrationEntry { AzFramework::CommandFunction m_callback; AZStd::string m_id; AZStd::string m_helpText; }; AZStd::unordered_map<AZStd::string, CommandRegistrationEntry> m_commandRegistrationMap; #if ALLOW_AUDIT_CVARS void AuditCVars(IConsoleCmdArgs* pArg); #endif // ALLOW_AUDIT_CVARS #ifndef _RELEASE // will be removed once the HTML version is good enough void DumpCommandsVarsTxt(const char* prefix); void DumpVarsTxt(const bool includeCheat); #endif void ConsoleLogInputResponse(const char* szFormat, ...) PRINTF_PARAMS(2, 3); void ConsoleLogInput(const char* szFormat, ...) PRINTF_PARAMS(2, 3); void ConsoleWarning(const char* szFormat, ...) PRINTF_PARAMS(2, 3); void DisplayHelp(const char* help, const char* name); void DisplayVarValue(ICVar* pVar); // Arguments: // bFromConsole - true=from console, false=from outside void SplitCommands(const char* line, std::list<string>& split); void ExecuteStringInternal(const char* command, const bool bFromConsole, const bool bSilentMode = false); void ExecuteDeferredCommands(); static const char* GetFlagsString(const uint32 dwFlags); static void CmdDumpAllAnticheatVars(IConsoleCmdArgs* pArgs); static void CmdDumpLastHashedAnticheatVars(IConsoleCmdArgs* pArgs); private: // ---------------------------------------------------------- typedef std::map<const char*, ICVar*, string_nocase_lt> ConsoleVariablesMap; // key points into string stored in ICVar or in .exe/.dll typedef ConsoleVariablesMap::iterator ConsoleVariablesMapItor; typedef std::vector<std::pair<const char*, ICVar*> > ConsoleVariablesVector; void LogChangeMessage(const char* name, const bool isConst, const bool isCheat, const bool isReadOnly, const bool isDeprecated, const char* oldValue, const char* newValue, const bool isProcessingGroup, const bool allowChange); void AddCheckedCVar(ConsoleVariablesVector& vector, const ConsoleVariablesVector::value_type& value); void RemoveCheckedCVar(ConsoleVariablesVector& vector, const ConsoleVariablesVector::value_type& value); static void AddCVarsToHash(ConsoleVariablesVector::const_iterator begin, ConsoleVariablesVector::const_iterator end, CCrc32& runningNameCrc32, CCrc32& runningNameValueCrc32); static bool CVarNameLess(const std::pair<const char*, ICVar*>& lhs, const std::pair<const char*, ICVar*>& rhs); void PostLine(const char* lineOfText, size_t len); typedef std::map<string, CConsoleCommand, string_nocase_lt> ConsoleCommandsMap; typedef ConsoleCommandsMap::iterator ConsoleCommandsMapItor; typedef std::map<string, string> ConsoleBindsMap; typedef ConsoleBindsMap::iterator ConsoleBindsMapItor; typedef std::map<string, IConsoleArgumentAutoComplete*, stl::less_stricmp<string> > ArgumentAutoCompleteMap; struct SConfigVar { string m_value; bool m_partOfGroup; }; typedef std::map<string, SConfigVar, string_nocase_lt> ConfigVars; struct SDeferredCommand { string command; bool silentMode; SDeferredCommand(const string& _command, bool _silentMode) : command(_command) , silentMode(_silentMode) {} }; typedef std::list<SDeferredCommand> TDeferredCommandList; typedef std::list<IConsoleVarSink*> ConsoleVarSinks; // -------------------------------------------------------------------------------- ConsoleBuffer m_dqConsoleBuffer; ConsoleBuffer m_dqHistory; bool m_bStaticBackground; int m_nLoadingBackTexID; int m_nProgress; int m_nProgressRange; string m_sInputBuffer; string m_sReturnString; string m_sPrevTab; int m_nTabCount; ConsoleCommandsMap m_mapCommands; // ConsoleBindsMap m_mapBinds; // ConsoleVariablesMap m_mapVariables; // ConsoleVariablesVector m_randomCheckedVariables; ConsoleVariablesVector m_alwaysCheckedVariables; std::vector<IOutputPrintSink*> m_OutputSinks; // objects in this vector are not released TDeferredCommandList m_deferredCommands; // A fifo of deferred commands bool m_deferredExecution; // True when deferred commands are processed int m_waitFrames; // A counter which is used by wait_frames command CTimeValue m_waitSeconds; // An absolute timestamp which is used by wait_seconds command int m_blockCounter; // This counter is incremented whenever a blocker command (VF_BLOCKFRAME) is executed. ArgumentAutoCompleteMap m_mapArgumentAutoComplete; ConsoleVarSinks m_consoleVarSinks; ConfigVars m_configVars; // temporary data of cvars that haven't been created yet int m_nScrollPos; int m_nTempScrollMax; // for currently opened console, reset to m_nScrollMax int m_nScrollMax; // int m_nScrollLine; int m_nHistoryPos; size_t m_nCursorPos; // x position in characters ITexture* m_pImage; float m_fRepeatTimer; // relative, next repeat even in .. decreses over time, repeats when 0, only valid if m_nRepeatEvent.keyId != eKI_Unknown AzFramework::InputChannelId m_nRepeatEventId; // event that will be repeated float m_fCursorBlinkTimer; // relative, increases over time, bool m_bDrawCursor; ScrollDir m_sdScrollDir; AzFramework::SystemCursorState m_previousSystemCursorState; bool m_bConsoleActive; bool m_bActivationKeyEnable; bool m_bIsProcessingGroup; bool m_bIsConsoleKeyPressed; size_t m_nCheatHashRangeFirst; size_t m_nCheatHashRangeLast; bool m_bCheatHashDirty; uint64 m_nCheatHash; CSystem* m_pSystem; IFFont* m_pFont; IRenderer* m_pRenderer; ITimer* m_pTimer; INetwork* m_pNetwork; // EvenBalance - M. Quinn ICVar* m_pSysDeactivateConsole; static int con_display_last_messages; static int con_line_buffer_size; static int con_showonload; static int con_debug; static int con_restricted; friend void Command_SetWaitSeconds(IConsoleCmdArgs* Cmd); friend void Command_SetWaitFrames(IConsoleCmdArgs* Cmd); #if ALLOW_AUDIT_CVARS friend void Command_AuditCVars(IConsoleCmdArgs* pArg); #endif // ALLOW_AUDIT_CVARS friend void Command_DumpCommandsVars(IConsoleCmdArgs* Cmd); friend void Command_DumpVars(IConsoleCmdArgs* Cmd); friend class CConsoleHelpGen; }; #endif // CRYINCLUDE_CRYSYSTEM_XCONSOLE_H