#pragma once #include "UserScript.h" #include "UserScriptWizardry.h" #include #include #include /*template struct verifier_base { static constexpr size_t argument_id = arg_number; };*/ namespace details { template struct TypeVerifier { static constexpr size_t argument_id = argument_counter; bool verify(scripting::UserScript* self, std::vector& args) { if(argument_id >= args.size()) return false; if(args.size() -1 -argument_id < 0) return false; auto& argument = args[args.size() -1 -argument_id]; std::optional> v = std::visit( wizardry::overloaded{ [&](scripting::script_variable& v) -> std::optional> {return self->getValue(v.name);}, [&](scripting::script_value& v) -> std::optional> {return v;}, }, argument ); if(not v) return false; return std::visit(wizardry::overloaded{ [](T& ) {return true;}, [](auto&) {return false;} }, v.value().get()); } }; template struct VariableVerifier { static constexpr size_t argument_id = argument_counter; bool verify(scripting::UserScript* self, std::vector& args) { if(argument_id >= args.size()) return false; if(args.size() -1 -argument_id < 0) return false; auto& argument = args[args.size() -1 -argument_id]; return std::visit( wizardry::overloaded{ [&](scripting::script_variable& v) -> bool {return self->getValue(v.name).has_value();}, [&](scripting::script_value& v) {return false;}, }, argument ); } }; template struct NoArrays { bool verify(scripting::UserScript* self, std::vector args) { for(auto& elem : std::ranges::reverse_view(args) | std::ranges::views::drop(skip)) { std::optional> v; std::visit( wizardry::overloaded{ [&](scripting::script_variable& n) {v = self->getValue(n.name);}, [&](scripting::script_value& n) {v = n;}, }, elem ); if(not v) return false; if(std::visit(wizardry::overloaded{ [](scripting::array&) {return true;}, [](auto&) {return false;} }, v.value().get())) { return false; } } return true; } }; template struct SizeEquals { bool verify(scripting::UserScript*, std::vector args) { return args.size() == sz; } }; template struct SizeAtLeast { bool verify(scripting::UserScript*, std::vector args) { return args.size() >= sz; } }; template struct OctetArrayVerifier { static constexpr size_t argument_id = argument_counter; bool verify(scripting::UserScript* self, std::vector& args) { if(argument_id >= args.size()) return false; if(args.size() -1 -argument_id < 0) return false; auto& argument = args[args.size() -1 -argument_id]; std::optional> v; std::visit( wizardry::overloaded{ [&](scripting::script_variable& elem) {v = self->getValue(elem.name);}, [&](scripting::script_value& elem) {v = elem;} }, argument ); if(not v) return false; return std::visit( wizardry::overloaded{ [](scripting::array& ary) -> bool { for(auto& elem : ary.value) { if(std::holds_alternative(elem)) { if(auto& byte = std::get(elem); byte < 0 || byte > 255) { return false; } } else { return false; } } return true; }, [] (auto&) -> bool {return false;} }, v.value().get() ); } }; } template struct Verify; template struct Verify { bool verify(scripting::UserScript* self, std::vector& args) { return n{}.verify(self, args) && Verify{}.verify(self, args); } }; template<> struct Verify<> { bool verify(scripting::UserScript*, const std::vector&) { return true; } };