Skip to content

Commit c932fdf

Browse files
committed
enable + disable commands
1 parent 40528ad commit c932fdf

15 files changed

Lines changed: 249 additions & 26 deletions

src/client/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@ add_library(selaura_client SHARED
1515
memory/sdk/client/ClientInstanceScreenModel.cpp
1616
memory/sdk/game/ClientInstance.cpp
1717
memory/sdk/game/MinecraftGame.cpp
18+
memory/sdk/network/LoopbackPacketSender.cpp
19+
memory/sdk/client/renderer/rendergraph/Packet.cpp
1820
feature/impl/render/fullbright.cpp
1921
feature/impl/render/paperdoll.cpp
2022
feature/impl/render/enchant_glint.cpp
2123
feature/impl/render/environment.cpp
24+
command/impl/enable_command.cpp
25+
command/impl/disable_command.cpp
2226
)
2327

2428
target_include_directories(selaura_client PRIVATE

src/client/client.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,6 @@ namespace selaura {
1717
spdlog::set_pattern("[%T] [client/%^%l%$] %v");
1818
spdlog::flush_on(spdlog::level::info);
1919

20-
auto& feature_manager = this->get<selaura::feature_manager>();
21-
feature_manager.for_each([]<typename T>(std::shared_ptr<T>& f) {
22-
f->set_enabled(true);
23-
spdlog::info("Module Loaded: {}", selaura::feature_traits<T>::name.c_str());
24-
});
25-
2620
selaura::patch_fns<
2721
&MinecraftGame::update_hk,
2822
&Dimension::Dimension_ctor_hk,
@@ -34,7 +28,8 @@ namespace selaura {
3428
&Dimension::getTimeOfDay_hk,
3529
&bgfx::d3d11::RendererContextD3D11::submit_hk,
3630
&bgfx::d3d12::RendererContextD3D12::submit_hk,
37-
&ClientInstanceScreenModel::executeCommand_hk
31+
&ClientInstanceScreenModel::executeCommand_hk,
32+
&LoopbackPacketSender::send_hk
3833
>();
3934

4035
magic_enum::enum_for_each<MinecraftPacketIds>([](auto val) {

src/client/client.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "event/event_manager.hpp"
1111
#include "feature/feature_manager.hpp"
12+
#include "command/command_handler.hpp"
1213
#include "memory/signatures.hpp"
1314

1415
#include "memory/sdk/game/MinecraftGame.hpp"
@@ -34,14 +35,14 @@ namespace selaura {
3435
};
3536

3637

37-
struct client : public client_base<selaura::event_manager, selaura::feature_manager> {
38+
struct client : public client_base<selaura::event_manager, selaura::feature_manager, selaura::command_handler> {
3839
void init();
3940
void unload();
4041
};
4142

42-
static inline std::shared_ptr<client> client_instance;
43-
inline std::shared_ptr<client> get() {
44-
return client_instance;
43+
inline std::shared_ptr<client>& get() {
44+
static std::shared_ptr<client> instance = std::make_shared<client>();
45+
return instance;
4546
}
4647

4748
inline MinecraftGame* minecraftGame;

src/client/command/command.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
#include <string>
3+
#include <vector>
4+
#include <tuple>
5+
#include <libhat/fixed_string.hpp>
6+
7+
namespace selaura {
8+
template <typename T>
9+
struct command_traits {
10+
static constexpr auto command = hat::fixed_string { "unknown" };
11+
};
12+
13+
template <typename T>
14+
struct command {
15+
virtual ~command() = default;
16+
using details = command_traits<T>;
17+
18+
virtual const std::string execute(std::vector<std::string> arguments) = 0;
19+
};
20+
};
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
#include <tuple>
3+
#include <string>
4+
#include <string_view>
5+
#include <vector>
6+
#include <sstream>
7+
#include <algorithm>
8+
9+
#include "impl/disable_command.hpp"
10+
#include "impl/enable_command.hpp"
11+
12+
namespace selaura {
13+
struct command_handler {
14+
using default_commands_t = std::tuple<
15+
enable_command,
16+
disable_command
17+
>;
18+
19+
inline std::string execute(std::string_view command_str) {
20+
std::istringstream stream(std::string{command_str});
21+
std::string verb;
22+
stream >> verb;
23+
24+
if (verb.empty())
25+
return "§cNo command entered.";
26+
27+
std::vector<std::string> args;
28+
for (std::string arg; stream >> arg;)
29+
args.emplace_back(std::move(arg));
30+
31+
return std::apply([&](auto&... cmds) -> std::string {
32+
std::string result = "§cUnknown command: " + verb;
33+
(..., (
34+
[&] {
35+
using T = std::decay_t<decltype(cmds)>;
36+
constexpr auto name = std::string_view{ command_traits<T>::command.c_str() };
37+
38+
if (verb == name)
39+
result = cmds.execute(args);
40+
}()
41+
));
42+
return result;
43+
}, default_commands);
44+
}
45+
46+
private:
47+
default_commands_t default_commands;
48+
};
49+
};
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "disable_command.hpp"
2+
3+
#include <format>
4+
#include <vector>
5+
#include <string>
6+
#include <algorithm>
7+
#include <cctype>
8+
#include "../../client.hpp"
9+
10+
namespace selaura {
11+
const std::string disable_command::execute(std::vector<std::string> arguments) {
12+
if (arguments.empty())
13+
return "§cIncorrect syntax: .disable [module_name ...]";
14+
15+
auto& feature_manager = selaura::get()->get<selaura::feature_manager>();
16+
std::vector<std::string> disabled_modules;
17+
18+
feature_manager.for_each([&]<typename T>(std::shared_ptr<T>& f) {
19+
const std::string_view name = selaura::feature_traits<T>::name;
20+
21+
auto it = std::ranges::find_if(arguments, [&](const std::string& arg) {
22+
return arg.size() == name.size() &&
23+
std::equal(arg.begin(), arg.end(), name.begin(), name.end(),
24+
[](char a, char b) {
25+
return std::tolower(static_cast<unsigned char>(a)) ==
26+
std::tolower(static_cast<unsigned char>(b));
27+
});
28+
});
29+
30+
if (it != arguments.end()) {
31+
f->set_enabled(false);
32+
disabled_modules.emplace_back(name);
33+
}
34+
});
35+
36+
if (disabled_modules.empty()) {
37+
return "§cNo matching modules found to disable.";
38+
}
39+
40+
std::string joined;
41+
for (size_t i = 0; i < disabled_modules.size(); ++i) {
42+
joined += disabled_modules[i];
43+
if (i + 1 < disabled_modules.size()) {
44+
joined += ", ";
45+
}
46+
}
47+
48+
return std::format("§aSuccessfully disabled modules: {}", joined);
49+
}
50+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
#include "../command.hpp"
3+
4+
namespace selaura {
5+
struct disable_command;
6+
7+
template <>
8+
struct command_traits<disable_command> {
9+
static constexpr auto command = hat::fixed_string{ "disable" };
10+
};
11+
12+
struct disable_command : command<disable_command> {
13+
virtual const std::string execute(std::vector<std::string> arguments) override;
14+
};
15+
};
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "enable_command.hpp"
2+
3+
#include <format>
4+
#include <vector>
5+
#include <string>
6+
#include <algorithm>
7+
#include <cctype>
8+
#include "../../client.hpp"
9+
10+
namespace selaura {
11+
const std::string enable_command::execute(std::vector<std::string> arguments) {
12+
if (arguments.empty())
13+
return "§cIncorrect syntax: .enable [module_name ...]";
14+
15+
auto& feature_manager = selaura::get()->get<selaura::feature_manager>();
16+
std::vector<std::string> enabled_modules;
17+
18+
feature_manager.for_each([&]<typename T>(std::shared_ptr<T>& f) {
19+
const std::string_view name = selaura::feature_traits<T>::name;
20+
21+
auto it = std::ranges::find_if(arguments, [&](const std::string& arg) {
22+
return arg.size() == name.size() &&
23+
std::equal(arg.begin(), arg.end(), name.begin(), name.end(),
24+
[](char a, char b) {
25+
return std::tolower(static_cast<unsigned char>(a)) ==
26+
std::tolower(static_cast<unsigned char>(b));
27+
});
28+
});
29+
30+
if (it != arguments.end()) {
31+
f->set_enabled(true);
32+
enabled_modules.emplace_back(name);
33+
}
34+
});
35+
36+
if (enabled_modules.empty()) {
37+
return "§cNo matching modules found to enable.";
38+
}
39+
40+
std::string joined;
41+
for (size_t i = 0; i < enabled_modules.size(); ++i) {
42+
joined += enabled_modules[i];
43+
if (i + 1 < enabled_modules.size()) {
44+
joined += ", ";
45+
}
46+
}
47+
48+
return std::format("§aSuccessfully enabled modules: {}", joined);
49+
}
50+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
#include "../command.hpp"
3+
4+
namespace selaura {
5+
struct enable_command;
6+
7+
template <>
8+
struct command_traits<enable_command> {
9+
static constexpr auto command = hat::fixed_string{ "enable" };
10+
};
11+
12+
struct enable_command : command<enable_command> {
13+
virtual const std::string execute(std::vector<std::string> arguments) override;
14+
};
15+
};

src/client/main.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ void init() {
1616
freopen_s(&fp, "CONOUT$", "w", stderr);
1717
freopen_s(&fp, "CONIN$", "r", stdin);
1818
#endif
19-
selaura::client_instance = std::make_shared<selaura::client>();
20-
selaura::client_instance->init();
19+
selaura::get()->init();
2120
}
2221

2322
#ifdef SELAURA_WINDOWS

0 commit comments

Comments
 (0)