mirror of
https://github.com/360NENZ/Taiga74164-Akebi-GC.git
synced 2025-09-19 04:06:12 +08:00
Merge branch 'Akebi-Group:master' into master
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -7,9 +7,6 @@
|
||||
[submodule "cheat-base/vendor/magic_enum"]
|
||||
path = cheat-base/vendor/magic_enum
|
||||
url = https://github.com/Neargye/magic_enum.git
|
||||
[submodule "cheat-library/vendor/protobuf"]
|
||||
path = cheat-library/vendor/protobuf
|
||||
url = https://github.com/protocolbuffers/protobuf.git
|
||||
[submodule "cheat-library/vendor/json"]
|
||||
path = cheat-base/vendor/json
|
||||
url = https://github.com/nlohmann/json.git
|
||||
|
@ -66,17 +66,39 @@ namespace util
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static T ReadMapped(void* data, int offset, bool littleEndian = false)
|
||||
static T ReadMapped(void* data, int offset, bool is_little_endian = false)
|
||||
{
|
||||
char* cData = (char*)data;
|
||||
T result = {};
|
||||
if (IsLittleEndian() != littleEndian)
|
||||
T value; // No need to initialize, because we will fill it later
|
||||
constexpr size_t value_size = sizeof(T);
|
||||
auto ptr_src = reinterpret_cast<char*>(data) + offset;
|
||||
auto ptr_value = reinterpret_cast<char*>(&value);
|
||||
|
||||
if (IsLittleEndian() == is_little_endian)
|
||||
{
|
||||
for (int i = 0; i < sizeof(T); i++)
|
||||
((char*)&result)[i] = cData[offset + sizeof(T) - i - 1];
|
||||
return result;
|
||||
memcpy_s(ptr_value, value_size, ptr_src, value_size);
|
||||
return value;
|
||||
}
|
||||
memcpy_s(&result, sizeof(result), cData + offset, sizeof(result));
|
||||
return result;
|
||||
|
||||
for (size_t i = 0; i < value_size; i++)
|
||||
ptr_value[i] = ptr_src[value_size - i - 1];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static void WriteMapped(void* data, int offset, const T& value, bool is_little_endian = false)
|
||||
{
|
||||
constexpr size_t value_size = sizeof(T);
|
||||
auto ptr_dest = reinterpret_cast<char*>(data) + offset;
|
||||
auto ptr_value = reinterpret_cast<const char*>(&value);
|
||||
|
||||
if (IsLittleEndian() == is_little_endian)
|
||||
{
|
||||
memcpy_s(ptr_dest, value_size, ptr_value, value_size);
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < value_size; i++)
|
||||
ptr_dest[i] = ptr_value[value_size - i - 1];
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\user\cheat\visuals\TextureChanger.h" />
|
||||
<ClInclude Include="src\user\cheat\world\FakeTime.h" />
|
||||
<ClInclude Include="src\user\cheat\debugger.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WS|x64'">false</ExcludedFromBuild>
|
||||
@ -116,6 +117,7 @@
|
||||
<Font Include="res\Ruda-ExtraBold.ttf" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\user\cheat\visuals\TextureChanger.cpp" />
|
||||
<ClCompile Include="src\user\cheat\world\FakeTime.cpp" />
|
||||
<ClCompile Include="src\user\cheat\debugger.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
@ -891,8 +893,8 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>$(OutDir);$(ProjectDir)vendor\lib\</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>cheat-base.lib;ntdll.lib;libprotobufd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>cheat-base.lib;ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
@ -932,7 +934,7 @@ powershell -nop -c "& {sleep 20}"</Command>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>$(OutDir);$(ProjectDir)vendor\lib\</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>cheat-base.lib;ntdll.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
</Link>
|
||||
@ -970,7 +972,7 @@ powershell -nop -c "& {sleep 15}"</Command>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>$(OutDir)..\Release\;$(ProjectDir)vendor\lib\;$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(OutDir)..\Release\;$(OutDir)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>cheat-base.lib;ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
</Link>
|
||||
|
@ -234,6 +234,9 @@
|
||||
<ClInclude Include="src\user\cheat\visuals\EnablePeaking.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\user\cheat\visuals\TextureChanger.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Font Include="res\Ruda-Bold.ttf" />
|
||||
@ -426,6 +429,9 @@
|
||||
<ClCompile Include="src\user\cheat\visuals\EnablePeaking.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\user\cheat\visuals\TextureChanger.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="res\res.rc">
|
||||
|
@ -86,6 +86,8 @@ DO_APP_FUNC(0x066218D0, Byte__Array*, Application_RecordUserData, (int32_t nType
|
||||
|
||||
|
||||
// Networking
|
||||
DO_APP_FUNC(0x01251620, void, Kcp_KcpNative_kcp_packet_destroy, (KcpPacket_1* packet, MethodInfo* method));
|
||||
DO_APP_FUNC(0x01251820, KcpPacket_1*, Kcp_KcpNative_kcp_packet_create, (uint8_t* data, int32_t len, MethodInfo* method));
|
||||
DO_APP_FUNC(0x012519C0, int32_t, Kcp_KcpNative_kcp_client_send_packet, (void* kcp_client, KcpPacket_1* packet, MethodInfo* method));
|
||||
DO_APP_FUNC(0x00BD08A0, bool, MoleMole_KcpClient_TryDequeueEvent, (void* __this, ClientKcpEvent* evt, MethodInfo* method));
|
||||
DO_APP_FUNC(0x029C3D60, void, MoleMole_Packet_XorEncrypt, (Byte__Array** bytes, int32_t length, MethodInfo* method));
|
||||
@ -176,6 +178,11 @@ DO_APP_FUNC(0x065508C0, void, Object_1_DestroyImmediate_1, (Object_1* obj, Metho
|
||||
DO_APP_FUNC(0x06550C00, Object_1*, Object_1_Instantiate_2, (Object_1* original, MethodInfo* method));
|
||||
DO_APP_FUNC(0x041B0BB0, Object*, Object_1_Instantiate_5, (Object* original, MethodInfo* method));
|
||||
DO_APP_FUNC(0x041B0BB0, GameObject*, Object_1_Instantiate_11, (GameObject* original, MethodInfo* method));
|
||||
DO_APP_FUNC(0x06555870, int32_t, Transform_get_childCount, (Transform* __this, MethodInfo* method));
|
||||
DO_APP_FUNC(0x0652EBC0, GameObject*, Component_1_get_gameObject, (Component_1* __this, MethodInfo* method));
|
||||
DO_APP_FUNC(0x06551030, String*, Object_1_get_name, (Object_1* __this, MethodInfo* method));
|
||||
DO_APP_FUNC(0x0665DA90, Material__Array*, Renderer_GetMaterialArray, (Renderer* __this, MethodInfo* method));
|
||||
DO_APP_FUNC(0x0652FB40, void, Material_set_mainTexture, (Material* __this, Texture* value, MethodInfo* method));
|
||||
|
||||
|
||||
// Music game event
|
||||
|
@ -11414,6 +11414,12 @@ namespace app {
|
||||
struct Object_1__Fields _;
|
||||
};
|
||||
|
||||
struct Texture {
|
||||
struct Texture__Class* klass;
|
||||
MonitorData* monitor;
|
||||
struct Texture__Fields fields;
|
||||
};
|
||||
|
||||
struct Texture2D__Fields {
|
||||
struct Texture__Fields _;
|
||||
};
|
||||
@ -11424,9 +11430,6 @@ namespace app {
|
||||
struct Texture2D__Fields fields;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct Image_1__Fields {
|
||||
struct MaskableGraphic__Fields _;
|
||||
struct Sprite* m_CachedSprite;
|
||||
@ -11914,6 +11917,24 @@ namespace app {
|
||||
MonitorData* monitor;
|
||||
};
|
||||
|
||||
struct Renderer__Fields {
|
||||
struct Component_1__Fields _;
|
||||
};
|
||||
|
||||
struct Renderer {
|
||||
struct Renderer__Class* klass;
|
||||
MonitorData* monitor;
|
||||
struct Renderer__Fields fields;
|
||||
};
|
||||
|
||||
struct Material__Array {
|
||||
struct Material__Array__Class* klass;
|
||||
MonitorData* monitor;
|
||||
Il2CppArrayBounds* bounds;
|
||||
il2cpp_array_size_t max_length;
|
||||
struct Material* vector[32];
|
||||
};
|
||||
|
||||
#if !defined(_GHIDRA_) && !defined(_IDA_)
|
||||
}
|
||||
#endif
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include <cheat/visuals/HideUI.h>
|
||||
#include <cheat/visuals/Browser.h>
|
||||
#include <cheat/visuals/EnablePeaking.h>
|
||||
#include <cheat/visuals/TextureChanger.h>
|
||||
|
||||
#include "GenshinCM.h"
|
||||
|
||||
@ -109,7 +110,8 @@ namespace cheat
|
||||
FEAT_INST(PaimonFollow),
|
||||
FEAT_INST(HideUI),
|
||||
FEAT_INST(Browser),
|
||||
FEAT_INST(EnablePeaking)
|
||||
FEAT_INST(EnablePeaking),
|
||||
FEAT_INST(TextureChanger),
|
||||
|
||||
});
|
||||
#undef FEAT_INST
|
||||
|
@ -42,22 +42,48 @@ namespace cheat::feature
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool ProcessModifiedData(app::KcpPacket_1* packet)
|
||||
bool PacketSniffer::ProcessModifiedData(app::KcpPacket_1* packet)
|
||||
{
|
||||
auto modifyData = sniffer::MessageManager::WaitFor<ModifyData>();
|
||||
if (!modifyData)
|
||||
auto modify_data = sniffer::MessageManager::WaitFor<ModifyData>();
|
||||
if (!modify_data)
|
||||
return false;
|
||||
|
||||
switch (modifyData->modifyType)
|
||||
switch (modify_data->modify_type)
|
||||
{
|
||||
case PacketModifyType::Blocked:
|
||||
return true;
|
||||
|
||||
case PacketModifyType::Modified:
|
||||
{
|
||||
auto dataSize = modifyData->modifiedData.size();
|
||||
packet->data = new byte[dataSize]();
|
||||
memcpy_s(packet->data, dataSize, modifyData->modifiedData.data(), dataSize);
|
||||
packet->dataLen = static_cast<uint32_t>(dataSize);
|
||||
auto data_size = modify_data->modified_head.size() + modify_data->modified_message.size() + 12;
|
||||
char* data = new char[data_size];
|
||||
|
||||
auto head_size = static_cast<uint16_t>(modify_data->modified_head.size());
|
||||
auto message_size = static_cast<uint32_t>(modify_data->modified_message.size());
|
||||
|
||||
util::WriteMapped(data, 0, static_cast<uint16_t>(0x4567)); // Magic number
|
||||
util::WriteMapped(data, 2, modify_data->message_id); // Message id
|
||||
util::WriteMapped(data, 4, head_size); // Head size
|
||||
util::WriteMapped(data, 6, message_size); // Message size
|
||||
|
||||
// Fill content
|
||||
char* ptr_head_content = data + 10;
|
||||
memcpy_s(ptr_head_content, head_size, modify_data->modified_head.data(), head_size);
|
||||
|
||||
char* ptr_message_content = ptr_head_content + modify_data->modified_head.size();
|
||||
memcpy_s(ptr_message_content, message_size, modify_data->modified_message.data(), message_size);
|
||||
|
||||
util::WriteMapped(ptr_message_content, message_size, static_cast<uint16_t>(0x89AB));
|
||||
|
||||
EncryptXor(data, data_size);
|
||||
|
||||
// Can be memory leak.
|
||||
auto new_packet = app::Kcp_KcpNative_kcp_packet_create(reinterpret_cast<uint8_t*>(data), static_cast<int32_t>(data_size), nullptr);
|
||||
delete[] data;
|
||||
|
||||
// Will be deleted by KcpNative_kcp_client_network_thread
|
||||
// app::Kcp_KcpNative_kcp_packet_destroy(packet, nullptr);
|
||||
packet = new_packet;
|
||||
}
|
||||
break;
|
||||
case PacketModifyType::Unchanged:
|
||||
@ -88,26 +114,36 @@ namespace cheat::feature
|
||||
return !canceled;
|
||||
}
|
||||
|
||||
char* PacketSniffer::EncryptXor(void* content, uint32_t length)
|
||||
void PacketSniffer::EncryptXor(void* content, uint32_t length)
|
||||
{
|
||||
app::Byte__Array* byteArray = (app::Byte__Array*)new char[length + 0x20];
|
||||
auto byteArray = reinterpret_cast<app::Byte__Array*>(new char[length + 0x20]);
|
||||
byteArray->max_length = length;
|
||||
memcpy_s(byteArray->vector, length, content, length);
|
||||
|
||||
app::MoleMole_Packet_XorEncrypt(&byteArray, length, nullptr);
|
||||
|
||||
auto result = new char[length];
|
||||
memcpy_s(result, length, byteArray->vector, length);
|
||||
memcpy_s(content, length, byteArray->vector, length);
|
||||
delete[] byteArray;
|
||||
|
||||
return (char*)result;
|
||||
}
|
||||
|
||||
PacketData PacketSniffer::ParseRawPacketData(char* encryptedData, uint32_t length)
|
||||
{
|
||||
// Packet structure
|
||||
// * Magic word (0x4567) [2 bytes]
|
||||
// * message_id [2 bytes]
|
||||
// * head_size [2 bytes]
|
||||
// * message_size [4 bytes]
|
||||
// * head_content [<head_size> bytes]
|
||||
// * message_content [<message_size> bytes]
|
||||
// * Magic word (0x89AB) [2 bytes]
|
||||
|
||||
// Header size - 12 bytes
|
||||
|
||||
PacketData packetData = sniffer::MessageManager::CreateMessage<PacketData>();
|
||||
// Decrypting packetData
|
||||
auto data = EncryptXor(encryptedData, length);
|
||||
auto data = new char[length];
|
||||
memcpy_s(data, length, encryptedData, length);
|
||||
EncryptXor(data, length);
|
||||
|
||||
uint16_t magicHead = util::ReadMapped<uint16_t>(data, 0);
|
||||
|
||||
|
@ -30,8 +30,9 @@ namespace cheat::feature
|
||||
private:
|
||||
PacketSniffer();
|
||||
|
||||
bool ProcessModifiedData(app::KcpPacket_1* packet);
|
||||
PacketData ParseRawPacketData(char* encryptedData, uint32_t length);
|
||||
static char* EncryptXor(void* content, uint32_t length);
|
||||
static void EncryptXor(void* content, uint32_t length);
|
||||
static bool KcpClient_TryDequeueEvent_Hook(void* __this, app::ClientKcpEvent* evt, MethodInfo* method);
|
||||
static int32_t KcpNative_kcp_client_send_packet_Hook(void* kcp_client, app::KcpPacket_1* packet, MethodInfo* method);
|
||||
|
||||
|
@ -2,21 +2,27 @@
|
||||
#include "ModifyData.h"
|
||||
|
||||
ModifyData::ModifyData(const MessageHeader& header) : MessageBase(header),
|
||||
modifyType(PacketModifyType::Unchanged), modifiedData({})
|
||||
{
|
||||
|
||||
}
|
||||
modify_type(PacketModifyType::Unchanged)
|
||||
{ }
|
||||
|
||||
void ModifyData::Write(PipeTransfer* transfer)
|
||||
{
|
||||
transfer->Write<PacketModifyType>(modifyType);
|
||||
if (modifyType == PacketModifyType::Modified)
|
||||
transfer->Write(modifiedData);
|
||||
transfer->Write<PacketModifyType>(modify_type);
|
||||
if (modify_type == PacketModifyType::Modified)
|
||||
{
|
||||
transfer->Write(message_id);
|
||||
transfer->Write(modified_head);
|
||||
transfer->Write(modified_message);
|
||||
}
|
||||
}
|
||||
|
||||
void ModifyData::Read(PipeTransfer* transfer)
|
||||
{
|
||||
transfer->Read<PacketModifyType>(modifyType);
|
||||
if (modifyType == PacketModifyType::Modified)
|
||||
transfer->Read(modifiedData);
|
||||
transfer->Read<PacketModifyType>(modify_type);
|
||||
if (modify_type == PacketModifyType::Modified)
|
||||
{
|
||||
transfer->Read(message_id);
|
||||
transfer->Read(modified_head);
|
||||
transfer->Read(modified_message);
|
||||
}
|
||||
}
|
||||
|
@ -12,14 +12,17 @@ enum class PacketModifyType
|
||||
class ModifyData : public MessageBase
|
||||
{
|
||||
public:
|
||||
PacketModifyType modifyType;
|
||||
std::string modifiedData;
|
||||
PacketModifyType modify_type;
|
||||
|
||||
uint16_t message_id;
|
||||
std::string modified_head;
|
||||
std::string modified_message;
|
||||
|
||||
ModifyData(const MessageHeader& header);
|
||||
~ModifyData() {}
|
||||
|
||||
// Inherited via PipeSerializedObject
|
||||
virtual void Write(PipeTransfer* transfer) override;
|
||||
virtual void Read(PipeTransfer* transfer) override;
|
||||
void Write(PipeTransfer* transfer) override;
|
||||
void Read(PipeTransfer* transfer) override;
|
||||
};
|
||||
|
||||
|
128
cheat-library/src/user/cheat/visuals/TextureChanger.cpp
Normal file
128
cheat-library/src/user/cheat/visuals/TextureChanger.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include "pch-il2cpp.h"
|
||||
#include "TextureChanger.h"
|
||||
|
||||
#include <helpers.h>
|
||||
#include <cheat/events.h>
|
||||
#include <misc/cpp/imgui_stdlib.h>
|
||||
#include <fstream>
|
||||
|
||||
namespace cheat::feature
|
||||
{
|
||||
namespace GameObject {
|
||||
app::GameObject* AvatarRoot = nullptr;
|
||||
}
|
||||
|
||||
TextureChanger::TextureChanger() : Feature(),
|
||||
NF(f_Enabled, "Texture Changer", "Visuals::TextureChanger", false),
|
||||
NF(f_HeadPath, "Head", "Visuals::TextureChanger", false),
|
||||
NF(f_BodyPath, "Body", "Visuals::TextureChanger", false),
|
||||
NF(f_DressPath, "Dress", "Visuals::TextureChanger", false),
|
||||
toBeUpdate(), nextUpdate(0)
|
||||
{
|
||||
events::GameUpdateEvent += MY_METHOD_HANDLER(TextureChanger::OnGameUpdate);
|
||||
}
|
||||
|
||||
const FeatureGUIInfo& TextureChanger::GetGUIInfo() const
|
||||
{
|
||||
static const FeatureGUIInfo info{ "TextureChanger", "Visuals", true };
|
||||
return info;
|
||||
}
|
||||
|
||||
void TextureChanger::DrawMain()
|
||||
{
|
||||
ConfigWidget(f_Enabled, "Texture Changer.");
|
||||
ImGui::Text("Active Hero: %s", ActiveHero.c_str());
|
||||
|
||||
ConfigWidget(f_HeadPath, "Head Texture.\n" \
|
||||
"Example path: C:\\Head.png");
|
||||
|
||||
ConfigWidget(f_BodyPath, "Body Texture.\n" \
|
||||
"Example path: C:\\Body.png");
|
||||
|
||||
ConfigWidget(f_DressPath, "Dress Texture.\n" \
|
||||
"Example path: C:\\Dress.png");
|
||||
|
||||
if (ImGui::Button("Apply"))
|
||||
ApplyTexture = true;
|
||||
}
|
||||
|
||||
bool TextureChanger::NeedStatusDraw() const
|
||||
{
|
||||
return f_Enabled;
|
||||
}
|
||||
|
||||
void TextureChanger::DrawStatus()
|
||||
{
|
||||
ImGui::Text("Texture Changer");
|
||||
}
|
||||
|
||||
TextureChanger& TextureChanger::GetInstance()
|
||||
{
|
||||
static TextureChanger instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void TextureChanger::OnGameUpdate()
|
||||
{
|
||||
if (!f_Enabled)
|
||||
return;
|
||||
|
||||
auto currentTime = util::GetCurrentTimeMillisec();
|
||||
if (currentTime < nextUpdate)
|
||||
return;
|
||||
|
||||
if (ApplyTexture)
|
||||
{
|
||||
GameObject::AvatarRoot = app::GameObject_Find(string_to_il2cppi("/EntityRoot/AvatarRoot"), nullptr);
|
||||
|
||||
if (GameObject::AvatarRoot != nullptr)
|
||||
{
|
||||
auto Transform = app::GameObject_GetComponentByName(GameObject::AvatarRoot, string_to_il2cppi("Transform"), nullptr);
|
||||
auto HeroCount = app::Transform_get_childCount(reinterpret_cast<app::Transform*>(Transform), nullptr);
|
||||
|
||||
for (int i = 0; i <= HeroCount - 1; i++)
|
||||
{
|
||||
auto HeroComponent = app::Transform_GetChild(reinterpret_cast<app::Transform*>(Transform), i, nullptr);
|
||||
auto HeroGameObject = app::Component_1_get_gameObject(reinterpret_cast<app::Component_1*>(HeroComponent), nullptr);
|
||||
auto isActiveHero = app::GameObject_get_active(HeroGameObject, nullptr);
|
||||
|
||||
if (isActiveHero)
|
||||
{
|
||||
auto GameObjectName = app::Object_1_get_name(reinterpret_cast<app::Object_1*>(HeroGameObject), nullptr);
|
||||
ActiveHero = il2cppi_to_string(GameObjectName);
|
||||
auto OffsetDummy = app::GameObject_Find(string_to_il2cppi("/EntityRoot/AvatarRoot/" + il2cppi_to_string(GameObjectName) + "/OffsetDummy"), nullptr);
|
||||
auto TransformOffsetDummy = app::GameObject_GetComponentByName(OffsetDummy, string_to_il2cppi("Transform"), nullptr);
|
||||
auto TransformChildOffsetDummy = app::Transform_GetChild(reinterpret_cast<app::Transform*>(TransformOffsetDummy), 0, nullptr);
|
||||
auto OffsetGameObject = app::Component_1_get_gameObject(reinterpret_cast<app::Component_1*>(TransformChildOffsetDummy), nullptr);
|
||||
auto OffsetGameObjectName = app::Object_1_get_name(reinterpret_cast<app::Object_1*>(OffsetGameObject), nullptr);
|
||||
auto GameObjectBody = app::GameObject_Find(string_to_il2cppi("/EntityRoot/AvatarRoot/" + il2cppi_to_string(GameObjectName) + "/OffsetDummy/" + il2cppi_to_string(OffsetGameObjectName) + "/Body"), nullptr);
|
||||
auto SkinnedMeshRenderer = app::GameObject_GetComponentByName(reinterpret_cast<app::GameObject*>(GameObjectBody), string_to_il2cppi("SkinnedMeshRenderer"), nullptr);
|
||||
auto Material = app::Renderer_GetMaterialArray(reinterpret_cast<app::Renderer*>(SkinnedMeshRenderer), nullptr);
|
||||
// 0 - Hair, 1 - Body, 2 - Dress
|
||||
if (f_HeadPath && CheckFile(f_HeadPath)) {
|
||||
auto HeadTexture = app::NativeGallery_LoadImageAtPath(string_to_il2cppi(f_HeadPath), 100, false, false, false, nullptr);
|
||||
app::Material_set_mainTexture(Material->vector[0], reinterpret_cast<app::Texture*>(HeadTexture), nullptr);
|
||||
}
|
||||
if (f_BodyPath && CheckFile(f_BodyPath)) {
|
||||
auto BodyTexture = app::NativeGallery_LoadImageAtPath(string_to_il2cppi(f_BodyPath), 100, false, false, false, nullptr);
|
||||
app::Material_set_mainTexture(Material->vector[1], reinterpret_cast<app::Texture*>(BodyTexture), nullptr);
|
||||
}
|
||||
if (f_DressPath && CheckFile(f_DressPath)) {
|
||||
auto DressTexture = app::NativeGallery_LoadImageAtPath(string_to_il2cppi(f_DressPath), 100, false, false, false, nullptr);
|
||||
|
||||
if (Material->vector[2] != nullptr)
|
||||
app::Material_set_mainTexture(Material->vector[2], reinterpret_cast<app::Texture*>(DressTexture), nullptr);
|
||||
}
|
||||
ApplyTexture = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nextUpdate = currentTime + (int)f_DelayUpdate;
|
||||
}
|
||||
|
||||
bool TextureChanger::CheckFile(const std::string& Filename) {
|
||||
struct stat buffer;
|
||||
return (stat(Filename.c_str(), &buffer) == 0);
|
||||
}
|
||||
}
|
33
cheat-library/src/user/cheat/visuals/TextureChanger.h
Normal file
33
cheat-library/src/user/cheat/visuals/TextureChanger.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include <cheat-base/cheat/Feature.h>
|
||||
#include <cheat-base/config/config.h>
|
||||
#include <cheat-base/thread-safe.h>
|
||||
|
||||
namespace cheat::feature
|
||||
{
|
||||
class TextureChanger : public Feature
|
||||
{
|
||||
public:
|
||||
config::Field<config::Toggle<Hotkey>> f_Enabled;
|
||||
config::Field<config::Toggle<std::string>> f_HeadPath;
|
||||
config::Field<config::Toggle<std::string>> f_BodyPath;
|
||||
config::Field<config::Toggle<std::string>> f_DressPath;
|
||||
std::string ActiveHero = "NONE";
|
||||
bool ApplyTexture;
|
||||
|
||||
static TextureChanger& GetInstance();
|
||||
const FeatureGUIInfo& GetGUIInfo() const override;
|
||||
void DrawMain() override;
|
||||
bool NeedStatusDraw() const override;
|
||||
void DrawStatus() override;
|
||||
bool CheckFile(const std::string& name);
|
||||
private:
|
||||
SafeQueue<uint32_t> toBeUpdate;
|
||||
SafeValue<int64_t> nextUpdate;
|
||||
int f_DelayUpdate = 15;
|
||||
|
||||
void OnGameUpdate();
|
||||
TextureChanger();
|
||||
|
||||
};
|
||||
}
|
@ -35,15 +35,16 @@ void Run(HMODULE* phModule)
|
||||
|
||||
DebuggerBypassPre();
|
||||
|
||||
#ifdef _DEBUG
|
||||
LOG_DEBUG("Waiting 10sec for loading game library.");
|
||||
Sleep(10000);
|
||||
#else
|
||||
while (GetModuleHandle("UserAssembly.dll") == nullptr)
|
||||
{
|
||||
LOG_DEBUG("UserAssembly.dll isn't initialized, waiting for 2 sec.");
|
||||
Sleep(2000);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
LOG_DEBUG("Waiting 10sec for loading game library.");
|
||||
Sleep(10000);
|
||||
#else
|
||||
LOG_DEBUG("Waiting 15sec for game initialize.");
|
||||
Sleep(15000);
|
||||
#endif
|
||||
|
BIN
cheat-library/vendor/lib/libprotobuf.lib
vendored
BIN
cheat-library/vendor/lib/libprotobuf.lib
vendored
Binary file not shown.
BIN
cheat-library/vendor/lib/libprotobufd.lib
vendored
BIN
cheat-library/vendor/lib/libprotobufd.lib
vendored
Binary file not shown.
1
cheat-library/vendor/protobuf
vendored
1
cheat-library/vendor/protobuf
vendored
Submodule cheat-library/vendor/protobuf deleted from 6f99f12a6b
Reference in New Issue
Block a user