#pragma once #include "session.hpp" #include #include #include #include #include #include class CCommandHandler { public: CCommandHandler(); ~CCommandHandler(); struct SResult { std::string result; bool good = false; }; struct SParseResult { std::any data; bool good = false; }; struct SCommand { bool requireAdmin = true; std::string name; std::function parser; std::function exe; }; bool isCommand(const std::string &str) const; bool validCommand(const std::string &command) const; // return false if command struct is invalid bool registerCommand(const SCommand &command); SResult newCommand(const std::string &command, const std::string &args, std::shared_ptr session) const; void handleCommand(std::string input, std::shared_ptr user = nullptr) const; template struct SMakeCommandArgs { std::string name; std::function(const std::string &args)> parser; std::function exe; }; template static SCommand makeCommand(SMakeCommandArgs args) { return { .name = std::move(args.name), .parser = [parser = std::move(args.parser)](const std::string &args) -> SParseResult { auto [data, good] = parser(args); return {.data = std::any(std::move(data)), .good = good}; }, .exe = [exe = std::move(args.exe)](const std::any &parsed) -> SResult { try { return exe(std::any_cast(parsed)); } catch (const std::bad_any_cast &) { return {.result = "Invalid data type", .good = false}; } } }; } private: std::shared_ptr getCommand(const std::string &command) const; SResult exeCommand(const std::shared_ptr command, const std::string &args) const; std::vector> m_vCommands; }; inline std::unique_ptr g_pCommandHandler;