#include "icvar.h" #include "tier2/ifilesystem.h" #include "tier1/utlstring.h" #include "tier1/utlvector.h" #include "stdarg.h" enum EConsoleMessageType { CONSOLE_MESSAGE_TYPE_MESSAGE, CONSOLE_MESSAGE_TYPE_WARNING, CONSOLE_MESSAGE_TYPE_ERROR, }; struct ConsoleMessage_t { EConsoleMessageType type; CUtlString szMessage; }; void Msg( const char* message ) { printf("%s\n", message); } void Warning( const char* message ) { } void Error( const char* message ) { } class CConsole: public IConsole { public: virtual void Init() override; virtual void Shutdown() override; // Variables virtual void RegisterVar( ConVar *cvar ) override; virtual void UnRegisterVar( ConVar *cvar ) override; virtual ConVar *FindVar( const char *pName ) override; // Commands virtual void RegisterCommand( ConCommand *cvar ) override; virtual void UnRegisterCommand( ConCommand *cvar ) override; virtual ConCommand *FindCommand( const char *pName ) override; // Command buffer virtual void Execute( void ) override; virtual void ExecuteArguments( CUtlVector &args ) override; virtual CUtlVector> ParseCommandLine( CUtlString psz ) override; virtual void AddCommand( const char *psz ) override; virtual void InsertCommand( const char *psz ) override; CUtlVector m_convars; CUtlVector m_commands; }; IConsole *Console() { static CConsole s_console; IConsole *pConsole = &s_console; return pConsole; } EXPOSE_INTERFACE_FN(Console, IConsole, CONSOLE_INTERFACE_VERSION); void CConsole::Init() { } void CConsole::Shutdown() { } void CConsole::RegisterVar( ConVar *cvar ) { m_convars.AppendTail(cvar); } void CConsole::UnRegisterVar( ConVar *cvar ) { } ConVar *CConsole::FindVar( const char *pName ) { for (auto &var: m_convars) { if (!V_strcmp(var->GetName(), pName)) return var; } return NULL; } void CConsole::RegisterCommand( ConCommand *cvar ) { m_commands.AppendTail(cvar); } void CConsole::UnRegisterCommand( ConCommand *cvar ) { } ConCommand *CConsole::FindCommand( const char *pName ) { for (auto &var: m_commands) { if (!V_strcmp(var->GetName(), pName)) return var; } return NULL; } CUtlString g_commandBuffer; //----------------------------------------------------------------------------- // Executes arguments from CConsole::Execute //----------------------------------------------------------------------------- void CConsole::ExecuteArguments( CUtlVector &args ) { if (args.GetSize()<1) return; ConCommand *cmd = CConsole::FindCommand(args[0]); if (!cmd) { V_printf("%s not found\n", args[0].GetString()); return; } CUtlBuffer strbuffer(args.GetSize()); for ( size_t i = 0; i < args.GetSize(); i++) { strbuffer[i] = args[i].GetString(); }; (cmd->GetCallback())(args.GetSize(), strbuffer); } void CConsole::Execute( void ) { CUtlVector> commands = ParseCommandLine(g_commandBuffer); g_commandBuffer = 0; for (auto &command: commands) { ExecuteArguments(command); } } //----------------------------------------------------------------------------- // Parses command buffer. //----------------------------------------------------------------------------- CUtlVector> CConsole::ParseCommandLine( CUtlString psz ) { CUtlVector arguments; CUtlVector> commands; CUtlString szArgument; bool bIsQuote = false; for ( auto &c: (CUtlVector&)psz ) { if ( c == '\"' ) { bIsQuote = !bIsQuote; continue; } if ( c == ';' || c == '\n' ) { if (bIsQuote) { continue; } if (szArgument != 0) arguments.AppendTail(szArgument); if ( arguments.GetSize() > 0 ) commands.AppendTail(arguments); szArgument = 0; arguments = {}; continue; } if ( c == '\t' || c == ' ' ) { if (bIsQuote) { szArgument.AppendTail(c); continue; } if (szArgument != 0) arguments.AppendTail(szArgument); szArgument = 0; continue; } szArgument.AppendTail(c); }; if (szArgument != 0) arguments.AppendTail(szArgument); if ( arguments.GetSize() > 0 ) commands.AppendTail(arguments); return commands; } void CConsole::AddCommand( const char *psz ) { g_commandBuffer.AppendTail(psz); } void CConsole::InsertCommand( const char *psz ) { g_commandBuffer.AppendHead(psz); }; void IConsole_Exec( int argc, char **argv) { if (argc != 2) return; V_printf("exec %s\n", argv[1]); IFileHandle *f = filesystem->Open(argv[1], FILEMODE_READ); if (!f) return; CUtlBuffer b(filesystem->Size(f)+1); filesystem->Read(f, b, b.GetSize()); b[b.GetSize()-1] = 0; Console()->AddCommand(b); Console()->AddCommand(";"); Console()->Execute(); } ConCommand IConsole_ExecCmd("exec", IConsole_Exec);