diff --git a/build/ISXMr.dir/Release/ISXMr.obj b/build/ISXMr.dir/Release/ISXMr.obj index 0d153de..54e04da 100644 Binary files a/build/ISXMr.dir/Release/ISXMr.obj and b/build/ISXMr.dir/Release/ISXMr.obj differ diff --git a/build/ISXMr.dir/Release/ISXMr.tlog/CL.command.1.tlog b/build/ISXMr.dir/Release/ISXMr.tlog/CL.command.1.tlog index ecbb2d1..f28798f 100644 Binary files a/build/ISXMr.dir/Release/ISXMr.tlog/CL.command.1.tlog and b/build/ISXMr.dir/Release/ISXMr.tlog/CL.command.1.tlog differ diff --git a/build/ISXMr.dir/Release/ISXMr.tlog/CL.read.1.tlog b/build/ISXMr.dir/Release/ISXMr.tlog/CL.read.1.tlog index 7b8db04..3745b6b 100644 Binary files a/build/ISXMr.dir/Release/ISXMr.tlog/CL.read.1.tlog and b/build/ISXMr.dir/Release/ISXMr.tlog/CL.read.1.tlog differ diff --git a/build/ISXMr.dir/Release/ISXMr.tlog/CL.write.1.tlog b/build/ISXMr.dir/Release/ISXMr.tlog/CL.write.1.tlog index af1aeac..dff47e6 100644 Binary files a/build/ISXMr.dir/Release/ISXMr.tlog/CL.write.1.tlog and b/build/ISXMr.dir/Release/ISXMr.tlog/CL.write.1.tlog differ diff --git a/build/ISXMr.dir/Release/MrBotApiType.obj b/build/ISXMr.dir/Release/MrBotApiType.obj index 80ede28..a6c5b6e 100644 Binary files a/build/ISXMr.dir/Release/MrBotApiType.obj and b/build/ISXMr.dir/Release/MrBotApiType.obj differ diff --git a/src/DataTypes/MrBotApiType.cpp b/src/DataTypes/MrBotApiType.cpp index d8a3f22..e11e5c6 100644 --- a/src/DataTypes/MrBotApiType.cpp +++ b/src/DataTypes/MrBotApiType.cpp @@ -53,44 +53,46 @@ unsigned long MrBotApiType::GetActorIdByName(const std::string &actorName, bool // Members bool MrBotApiType::Version(const std::vector &args, LSOBJECT &dest) { - dest.ConstCharPtr = "0.1.0"; + constexpr const char *version = "0.1.0"; + log << "MrBotApiType::Version: " << version << std::endl; + dest.ConstCharPtr = version; dest.Type = pStringType; return true; } // Methods -bool MrBotApiType::ClickActorByName(const std::vector &args) +bool MrBotApiType::ClickActorByName(const std::string name) { - if (args.size() != 1) + if (name.empty()) { - logw << "MrBotApiType::ClickActorByName: Expected 1 argument, got " << args.size() << std::endl; + logw << "MrBotApiType::ClickActorByName: Actor name is empty" << std::endl; return false; } - const auto actorId = GetActorIdByName(args[0]); + const auto actorId = GetActorIdByName(name); if (actorId == -1) { - logw << "MrBotApiType::ClickActorByName: Actor not found: " << args[0] << std::endl; + logw << "MrBotApiType::ClickActorByName: Actor not found: " << name << std::endl; return false; } return ClickActorById({std::to_string(actorId)}); } -bool MrBotApiType::ClickActorById(const std::vector &args) +bool MrBotApiType::ClickActorById(const string id) { - if (args.size() != 1) + if (id.empty()) { - logw << "MrBotApiType::ClickActorById: Expected 1 argument, got " << args.size() << std::endl; + logw << "MrBotApiType::ClickActorById: Actor id is empty" << std::endl; return false; } - log << "MrBotApiType::ClickActorById " << args[0] << std::endl; - const auto actor = ExtensionTLOs::Actor().GetActorById(std::stoul(args[0])); + log << "MrBotApiType::ClickActorById " << id << std::endl; + const auto actor = ExtensionTLOs::Actor().GetActorById(std::stoul(id)); if (!actor.has_value()) { - logw << "MrBotApiType::ClickActorById: Actor not found: " << args[0] << std::endl; + logw << "MrBotApiType::ClickActorById: Actor not found: " << id << std::endl; return false; } @@ -100,26 +102,29 @@ bool MrBotApiType::ClickActorById(const std::vector &args) return true; } -bool MrBotApiType::ApplyVerb(const std::vector &args) +bool MrBotApiType::ApplyVerb(const string actorName, const string verb) { - if (args.size() != 2) + if (actorName.empty() || verb.empty()) { - logw << "MrBotApiType::ApplyVerb: Expected 2 arguments, got " << args.size() << std::endl; + logw << "MrBotApiType::ApplyVerb: Actor name or verb is empty" << std::endl; return false; } - const auto actorId = GetActorIdByName(args[0]); + const auto actorId = GetActorIdByName(actorName); if (actorId == -1) { - logw << "MrBotApiType::ApplyVerb: Actor not found: " << args[0] << std::endl; + logw << "MrBotApiType::ApplyVerb: Actor not found: " << actorName << std::endl; return false; } - const auto verb = args[1]; - const auto command = "eq2execute apply_verb " + std::to_string(actorId) + " \"" + verb + "\""; log << "MrBotApiType::ApplyVerb: " << command << std::endl; const auto response = pISInterface->ExecuteCommand(command.c_str()); return response == 0; } + +bool MrBotApiType::ConversationBubble(const string option) +{ + return false; +} diff --git a/src/DataTypes/MrBotApiType.h b/src/DataTypes/MrBotApiType.h index 434d0ac..7dacb27 100644 --- a/src/DataTypes/MrBotApiType.h +++ b/src/DataTypes/MrBotApiType.h @@ -2,9 +2,63 @@ #include #include +#include +#include +#include #include +#include +#include +#include + #include "../isxeq2/ExtensionTLOs.h" +// Helper to get the number of arguments of a method +template +struct function_traits; + +template +struct function_traits +{ + static constexpr std::size_t arity = sizeof...(Args); + using arg_tuple = std::tuple; +}; + +template +struct function_traits +{ + static constexpr std::size_t arity = sizeof...(Args); + using arg_tuple = std::tuple; +}; + +// A helper function to convert an array of C-strings to a tuple of strings. +template +Tuple array_to_tuple_impl(char *argv[], std::index_sequence) +{ + return Tuple{std::string(argv[I])...}; +} + +template +Tuple array_to_tuple(char *argv[]) +{ + return array_to_tuple_impl(argv, std::make_index_sequence::value>{}); +} + +#define ADD_METHOD_TO_MAP(EnumType, methodName) \ + AddMethod(static_cast(EnumType::methodName), const_cast(#methodName)); \ + methodMap[EnumType::methodName] = [this](int argc, char *argv[]) { \ + constexpr auto expectedArgc = function_traits::methodName)>::arity; \ + if (argc != expectedArgc) \ + { \ + logw << "MrBotApiType::GetMethod: " #methodName ": Expected " << expectedArgc \ + << " argument(s), got " << argc << std::endl; \ + return false; \ + } \ + log << "MrBotApiType::GetMethod: " #methodName << std::endl; \ + using ArgsTuple = typename function_traits::methodName)>::arg_tuple; \ + auto args_tuple = array_to_tuple(argv); \ + return std::apply([this](auto &&...args) { return this->methodName(std::forward(args)...); }, args_tuple); \ + } + #define ADD_MEMBER_TO_MAP(EnumType, memberName, expectedArgc) \ AddMember(static_cast(EnumType::memberName), const_cast(#memberName)); \ memberMap[EnumType::memberName] = [this](int argc, char *argv[], LSOBJECT &dest) { \ @@ -19,26 +73,12 @@ return memberName(args, dest); \ } -#define ADD_METHOD_TO_MAP(EnumType, methodName, expectedArgc) \ - AddMethod(static_cast(EnumType::methodName), const_cast(#methodName)); \ - methodMap[EnumType::methodName] = [this](int argc, char *argv[]) { \ - if (argc != expectedArgc) \ - { \ - logw << "MrBotApiType::GetMethod: " #methodName ": Expected " << expectedArgc \ - << " argument(s), got " << argc << std::endl; \ - return false; \ - } \ - log << "MrBotApiType::GetMethod: " #methodName << std::endl; \ - std::vector args(argv, argv + argc); \ - return methodName(args); \ - } - class MrBotApiType : public LSTypeDefinition { public: enum class MrBotApiTypeMembers { - Version + Version, }; enum class MrBotApiTypeMethods @@ -51,9 +91,9 @@ public: MrBotApiType() : LSTypeDefinition(const_cast("mrbotapi")) { ADD_MEMBER_TO_MAP(MrBotApiTypeMembers, Version, 0); - ADD_METHOD_TO_MAP(MrBotApiTypeMethods, ClickActorByName, 1); - ADD_METHOD_TO_MAP(MrBotApiTypeMethods, ClickActorById, 1); - ADD_METHOD_TO_MAP(MrBotApiTypeMethods, ApplyVerb, 2); + ADD_METHOD_TO_MAP(MrBotApiTypeMethods, ClickActorByName); + ADD_METHOD_TO_MAP(MrBotApiTypeMethods, ClickActorById); + ADD_METHOD_TO_MAP(MrBotApiTypeMethods, ApplyVerb); } virtual bool GetMember(LSOBJECTDATA ObjectData, PLSTYPEMEMBER pMember, int argc, char *argv[], LSOBJECT &Dest); @@ -94,9 +134,10 @@ private: // Members bool Version(const std::vector &args, LSOBJECT &dest); // Methods - bool ClickActorByName(const std::vector &args); - bool ClickActorById(const std::vector &args); - bool ApplyVerb(const std::vector &args); + bool ClickActorByName(const string name); + bool ClickActorById(const string id); + bool ApplyVerb(const string actorName, const string verb); + bool ConversationBubble(const string option); static unique_ptr pMrBotApi; using MethodFunc = std::function;