diff --git a/China/China.vcxproj b/China/China.vcxproj
index 091839864f1ccbac8660d8f6d86827f8e5dee057..8bd65a0068e0ac83eade02e0b3012c5ba1b436b2 100644
--- a/China/China.vcxproj
+++ b/China/China.vcxproj
@@ -468,6 +468,7 @@
+
@@ -475,6 +476,7 @@
+
@@ -488,6 +490,7 @@
+
@@ -519,6 +522,7 @@
+
@@ -526,6 +530,7 @@
+
@@ -538,6 +543,7 @@
+
diff --git a/China/China.vcxproj.filters b/China/China.vcxproj.filters
index 3010c5f6ed20b110080f26603cb18fda08abb655..ef4b122f1c1995c5d1a937f46d7b96a69bbc2955 100644
--- a/China/China.vcxproj.filters
+++ b/China/China.vcxproj.filters
@@ -1,4 +1,4 @@
-
+
@@ -53,6 +53,8 @@
+
+
@@ -123,5 +125,7 @@
+
+
\ No newline at end of file
diff --git a/China/HeliumClient/Commands/Commands/AutoTextCommand.cpp b/China/HeliumClient/Commands/Commands/AutoTextCommand.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9f1ff690c68b2a95505223f8c190b685c9c084a2
--- /dev/null
+++ b/China/HeliumClient/Commands/Commands/AutoTextCommand.cpp
@@ -0,0 +1,104 @@
+#include "AutoTextCommand.h"
+
+#include "../../../Memory/GameData.h"
+
+inline constexpr std::u8string string_replace(std::u8string s, const std::u8string_view findS, const std::u8string_view replaceS) {
+ for (size_t i{};;) {
+ i = s.find(findS, i);
+ if (i != std::string::npos)
+ s.replace(i, findS.length(), replaceS);
+ else
+ return s;
+ }
+}
+
+inline constexpr std::u8string parse(std::u8string s) {
+
+ constexpr std::array, 7> patterns{ // string_view 中间含有 (char8_t)0 字符串初始化时会截断,必须标明长度
+ std::pair{u8"\\\\", std::u8string_view{u8"\\\0", 2}},
+ std::pair{u8"\\n", u8"\n"},
+ std::pair{u8"\\r", u8"\r"},
+ std::pair{u8"\\t", u8"\t"},
+ std::pair{u8"\\f", u8"\f"},
+ std::pair{u8"\\\"", u8"\""},
+ std::pair{std::u8string_view{u8"\\\0", 2}, u8"\\"}};
+ for (const auto& p : patterns)
+ s = string_replace(s, p.first, p.second);
+ return s;
+}
+
+bool AutoTextCommand_onExecute(const fast_io::vector& args) {
+ auto& mode = args[1];
+ if (args.size() == 2) {
+ if (mode == u8"list") {
+ if (SettingManager::autotextbindings.empty()) {
+ C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE, u8"[Helium] ", Utils::TextColor::RED, u8"You haven't set the macro yet");
+ } else {
+ C_GuiData::displayClientMessageC(Utils::TextColor::GRAY, u8"========================");
+ for (auto& b : SettingManager::autotextbindings) {
+ C_GuiData::displayClientMessageC(Utils::TextColor::YELLOW, fast_io::mnp::chvw(b.first), Utils::TextColor::BLUE, u8"-->", Utils::TextColor::GOLD, b.second);
+ }
+ C_GuiData::displayClientMessageC(Utils::TextColor::GRAY, u8"========================");
+ }
+ return true;
+ } else {
+ return false;
+ }
+ } else if (args.size() < 3)
+ return false;
+
+ auto& key = args[2];
+
+ if (mode == u8"set") {
+
+ if (key.size() != 1)
+ return false;
+
+ std::u8string text{};
+ for (size_t i = 3; i < args.size(); i++) {
+ if (i > 3) [[likely]]
+ text.push_back(u8' ');
+ text.append(args[i]);
+ }
+
+ SettingManager::autotextbindings[fast_io::char_category::to_c_upper(key.front())] = parse(text);
+ C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE, u8"[Helium] ", Utils::TextColor::GREEN, u8"Successfully set!");
+ return true;
+ } else if (mode == u8"reset") {
+ if (key == u8"all")
+ SettingManager::autotextbindings.clear();
+ else {
+ if (key.size() != 1)
+ return false;
+ SettingManager::autotextbindings.erase(fast_io::char_category::to_c_upper(key.front()));
+ }
+ C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE, u8"[Helium] ", Utils::TextColor::GREEN, u8"Successfully reset!");
+ return true;
+ } else {
+ return false;
+ }
+}
+
+fast_io::vector keys{};
+
+bool listKeys(fast_io::vector*) {
+ keys.clear();
+ keys.reserve(SettingManager::autotextbindings.size());
+ keys.emplace_back_unchecked(stringview_Object{u8"all", nullptr});
+ for (auto& k : SettingManager::autotextbindings)
+ keys.emplace_back_unchecked(string_Object{fast_io::u8concat(fast_io::mnp::chvw(k.first)), nullptr});
+
+ return true;
+}
+
+ICommand AutoTextCommand{
+ u8"autotext",
+ u8".autotext [set , reset |all, list]",
+ {u8"Set small macros to send message quickly", u8"设置小型宏以快速发送消息", u8"設定小型宏以快速發送消息", u8"メッセージを迅速に送信するためのミニマクロの設定"},
+ {},
+ fast_io::vector{
+ aliasList_struct{stringview_Object{u8"set", nullptr}},
+ aliasList_struct{stringview_Judge{u8"reset", &keys, &listKeys}},
+ aliasList_struct{stringview_Object{u8"list", nullptr}}}, // If empty must use fast_io::vector{}
+ nullptr,
+ &AutoTextCommand_onExecute};
\ No newline at end of file
diff --git a/China/HeliumClient/Commands/Commands/AutoTextCommand.h b/China/HeliumClient/Commands/Commands/AutoTextCommand.h
new file mode 100644
index 0000000000000000000000000000000000000000..658b8329c141df36defe5d6e4dc8a484953c83f3
--- /dev/null
+++ b/China/HeliumClient/Commands/Commands/AutoTextCommand.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "../ICommand.h"
+
+extern ICommand AutoTextCommand;
\ No newline at end of file
diff --git a/China/HeliumClient/Commands/Commands/BindCommand.cpp b/China/HeliumClient/Commands/Commands/BindCommand.cpp
index 08b0b91663f4a4a715f7903f33c18b2a54d77bd5..d0d182465c3ce2393aa5d038c5268fd13116d3dc 100644
--- a/China/HeliumClient/Commands/Commands/BindCommand.cpp
+++ b/China/HeliumClient/Commands/Commands/BindCommand.cpp
@@ -11,10 +11,10 @@ void BindCommand_onInit(ICommand* _this) {
bool BindCommand_onExecute(const fast_io::vector& args) {
if (args.size() == 2) {
- auto modOpt = ModuleManager::getModuleByName(args[1]);
+ auto modOpt{ModuleManager::getModuleByName(args[1])};
if (modOpt == nullptr)
return false;
- char8_t key = static_cast(modOpt->getKeybind());
+ char8_t key{static_cast(modOpt->getKeybind())};
if (fast_io::char_category::is_c_alnum(key)) {
switch (SettingManager::languageget) {
case 0:
@@ -151,7 +151,7 @@ bool BindCommand_onExecute(const fast_io::vector& args) {
} else {
char8_t key{};
if (args[2].front() == u8'\\') {
- std::u8string arg2 = args[2];
+ std::u8string arg2{args[2]};
arg2.erase(args[2].begin());
if (!scan(fast_io::u8ibuffer_view(arg2), fast_io::mnp::hex_get(key)))
return false;
diff --git a/China/HeliumClient/Commands/Commands/ConfigCommand.cpp b/China/HeliumClient/Commands/Commands/ConfigCommand.cpp
index b499572cd81d9023c424b6b1f2e26e3a4d034b4f..04acdb1688d037cbe32d11ed582c09638677ce7e 100644
--- a/China/HeliumClient/Commands/Commands/ConfigCommand.cpp
+++ b/China/HeliumClient/Commands/Commands/ConfigCommand.cpp
@@ -1,4 +1,4 @@
-#include "ConfigCommand.h"
+#include "ConfigCommand.h"
#include
diff --git a/China/HeliumClient/Commands/Commands/FriendCommand.cpp b/China/HeliumClient/Commands/Commands/FriendCommand.cpp
index 3b90600a9d8eca6dc8a331d314bc9b4691a70541..15b2288ace0a6b2c5eb04171ee823a41633cc3ca 100644
--- a/China/HeliumClient/Commands/Commands/FriendCommand.cpp
+++ b/China/HeliumClient/Commands/Commands/FriendCommand.cpp
@@ -1,4 +1,4 @@
-#include "FriendCommand.h"
+#include "FriendCommand.h"
#include "../../../Memory/GameData.h"
diff --git a/China/HeliumClient/Commands/Commands/OptionCommand.cpp b/China/HeliumClient/Commands/Commands/OptionCommand.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..15d72f3f2c1f47f9e028b8ee2492aacfe3a21216
--- /dev/null
+++ b/China/HeliumClient/Commands/Commands/OptionCommand.cpp
@@ -0,0 +1,94 @@
+#include "OptionCommand.h"
+#include "../../../Memory/GameData.h"
+std::map optionmap{};
+
+bool OptionCommand_onExecute(const fast_io::vector& args) {
+ if (args.size() == 2) {
+ if (args[1] == u8"list") {
+ if (optionmap.empty()) {
+ C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
+ u8"[Helium] ",
+ Utils::TextColor::YELLOW,
+ u8"OptionMap is empty!");
+ return true;
+ }
+ C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
+ u8"[Helium] ",
+ Utils::TextColor::WHITE,
+ u8"OptionMap List:");
+ for (auto& i : optionmap) {
+ if (i.second.type == 0) {
+ C_GuiData::displayClientMessageC(Utils::TextColor::GRAY,
+ i.first,
+ Utils::TextColor::WHITE,
+ u8" : ",
+ Utils::TextColor::GRAY,
+ fast_io::mnp::boolalpha(i.second._bool));
+ } else if (i.second.type == 1) {
+ C_GuiData::displayClientMessageC(Utils::TextColor::GRAY,
+ i.first,
+ Utils::TextColor::WHITE,
+ u8" : ",
+ Utils::TextColor::GRAY,
+ i.second._int);
+ } else if (i.second.type == 2) {
+ C_GuiData::displayClientMessageC(Utils::TextColor::GRAY,
+ i.first,
+ Utils::TextColor::WHITE,
+ u8" : ",
+ Utils::TextColor::GRAY,
+ i.second._float);
+ } else {
+ fast_io::fast_terminate();
+ }
+ }
+ } else {
+ return false;
+ }
+ } else if (args.size() == 3) {
+ if (args[1] != u8"cancel")
+ return false;
+ auto find = optionmap.find(args[2]);
+ if (find != optionmap.end()) {
+ optionmap.erase(find);
+ C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE,
+ u8"[Helium] ",
+ Utils::TextColor::GREEN,
+ u8"ERASE!");
+ } else {
+ return false;
+ }
+ } else if (args.size() == 5) {
+ if (args[1] != u8"modify")
+ return false;
+ if (args[3] == u8"bool") {
+ bool w{};
+ if (args[4] == u8"true") {
+ w = true;
+ } else if (args[4] == u8"false") {
+ w = false;
+ } else {
+ return false;
+ }
+ optionmap[args[2]] = option_type{.type = 0, ._bool = w};
+ } else if (args[3] == u8"int") {
+ optionmap[args[2]] = option_type{.type = 1, ._int = ICommand::assertInt(args[4])};
+ } else if (args[3] == u8"float") {
+ optionmap[args[2]] = option_type{.type = 2, ._float = ICommand::assertFloat(args[4])};
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+
+ }
+ return true;
+}
+
+ICommand OptionCommand{u8"option",
+ u8".option modify