Update 2.7

Add Profile Changer
Skip Cutscene (Video Movie)
This commit is contained in:
RyujinZX 2022-06-08 07:52:24 +03:00
parent d01c6f442e
commit b3dbe7eedd
9 changed files with 401 additions and 81 deletions

View File

@ -53,6 +53,7 @@
<ClInclude Include="src\user\cheat\visuals\CameraZoom.h" /> <ClInclude Include="src\user\cheat\visuals\CameraZoom.h" />
<ClInclude Include="src\user\cheat\visuals\FPSUnlock.h" /> <ClInclude Include="src\user\cheat\visuals\FPSUnlock.h" />
<ClInclude Include="src\user\cheat\visuals\NoFog.h" /> <ClInclude Include="src\user\cheat\visuals\NoFog.h" />
<ClInclude Include="src\user\cheat\visuals\ProfileChanger.h" />
<ClInclude Include="src\user\cheat\visuals\ShowChestIndicator.h" /> <ClInclude Include="src\user\cheat\visuals\ShowChestIndicator.h" />
<ClInclude Include="src\user\cheat\world\AutoCook.h" /> <ClInclude Include="src\user\cheat\world\AutoCook.h" />
<ClInclude Include="src\user\cheat\world\AutoFish.h" /> <ClInclude Include="src\user\cheat\world\AutoFish.h" />
@ -163,6 +164,7 @@
<ClCompile Include="src\user\cheat\visuals\CameraZoom.cpp" /> <ClCompile Include="src\user\cheat\visuals\CameraZoom.cpp" />
<ClCompile Include="src\user\cheat\visuals\FPSUnlock.cpp" /> <ClCompile Include="src\user\cheat\visuals\FPSUnlock.cpp" />
<ClCompile Include="src\user\cheat\visuals\NoFog.cpp" /> <ClCompile Include="src\user\cheat\visuals\NoFog.cpp" />
<ClCompile Include="src\user\cheat\visuals\ProfileChanger.cpp" />
<ClCompile Include="src\user\cheat\visuals\ShowChestIndicator.cpp" /> <ClCompile Include="src\user\cheat\visuals\ShowChestIndicator.cpp" />
<ClCompile Include="src\user\cheat\world\AutoCook.cpp" /> <ClCompile Include="src\user\cheat\world\AutoCook.cpp" />
<ClCompile Include="src\user\cheat\world\AutoFish.cpp" /> <ClCompile Include="src\user\cheat\world\AutoFish.cpp" />

View File

@ -225,6 +225,9 @@
<ClInclude Include="src\user\cheat\world\AutoCook.h"> <ClInclude Include="src\user\cheat\world\AutoCook.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\user\cheat\visuals\ProfileChanger.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Font Include="res\Ruda-Bold.ttf" /> <Font Include="res\Ruda-Bold.ttf" />
@ -408,6 +411,9 @@
<ClCompile Include="src\user\cheat\debugger.cpp"> <ClCompile Include="src\user\cheat\debugger.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\user\cheat\visuals\ProfileChanger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="res\res.rc"> <ResourceCompile Include="res\res.rc">

View File

@ -14,32 +14,32 @@
uintptr_t il2cpp_get_mono_base_address() uintptr_t il2cpp_get_mono_base_address()
{ {
static HMODULE hMono = GetModuleHandle("mono.dll"); static HMODULE hMono = GetModuleHandle("mono.dll");
if (hMono != NULL) if (hMono != NULL)
return (uintptr_t)hMono; return (uintptr_t)hMono;
HMODULE hModules[1024] = {}; HMODULE hModules[1024] = {};
DWORD cbNeeded = 0; DWORD cbNeeded = 0;
BOOL result = EnumProcessModules(GetCurrentProcess(), hModules, sizeof(hModules), &cbNeeded); BOOL result = EnumProcessModules(GetCurrentProcess(), hModules, sizeof(hModules), &cbNeeded);
if (result == FALSE) if (result == FALSE)
return NULL; return NULL;
for (int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) for (int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
{ {
if (hModules[i] == NULL) if (hModules[i] == NULL)
continue; continue;
if (GetProcAddress(hModules[i], "il2cpp_thread_attach") != NULL) if (GetProcAddress(hModules[i], "il2cpp_thread_attach") != NULL)
return (uintptr_t)hModules[i]; return (uintptr_t)hModules[i];
} }
return 0; return 0;
} }
uintptr_t il2cppi_get_base_address() { uintptr_t il2cppi_get_base_address() {
return (uintptr_t) GetModuleHandleW(L"UserAssembly.dll"); return (uintptr_t)GetModuleHandleW(L"UserAssembly.dll");
} }
uintptr_t il2cppi_get_unity_address() { uintptr_t il2cppi_get_unity_address() {
@ -49,13 +49,13 @@ uintptr_t il2cppi_get_unity_address() {
// Helper function to open a new console window and redirect stdout there // Helper function to open a new console window and redirect stdout there
void il2cppi_new_console() { void il2cppi_new_console() {
AllocConsole(); AllocConsole();
freopen_s((FILE**) stdout, "CONOUT$", "w", stdout); freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
freopen_s((FILE**) stderr, "CONOUT$", "w", stderr); freopen_s((FILE**)stderr, "CONOUT$", "w", stderr);
} }
void il2cppi_close_console() { void il2cppi_close_console() {
fclose(stdout); fclose(stdout);
fclose(stderr); fclose(stderr);
FreeConsole(); FreeConsole();
} }
@ -85,6 +85,11 @@ std::string il2cppi_to_string(app::String* str) {
return il2cppi_to_string(reinterpret_cast<Il2CppString*>(str)); return il2cppi_to_string(reinterpret_cast<Il2CppString*>(str));
} }
app::String* string_to_il2cppi(std::string input) {
return app::Marshal_PtrToStringAnsi((void*)input.c_str(), nullptr);
}
std::string to_hex_string(app::Byte__Array* barray, int length) { std::string to_hex_string(app::Byte__Array* barray, int length) {
if (barray == nullptr) if (barray == nullptr)
return std::string(); return std::string();

View File

@ -46,7 +46,7 @@ struct UniLinkListNode
}; };
template<class ElementT> template<class ElementT>
struct UniLinkList struct UniLinkList
{ {
void* klass; void* klass;
MonitorData* monitor; MonitorData* monitor;
@ -127,15 +127,15 @@ struct __declspec(align(8)) UniDict {
MonitorData* monitor; MonitorData* monitor;
void* buckets; void* buckets;
UniArray<UniDictEntry<KeyT, ValT>>* entries; UniArray<UniDictEntry<KeyT, ValT>>* entries;
int32_t count; int32_t count;
int32_t version; int32_t version;
int32_t freeList; int32_t freeList;
int32_t freeCount; int32_t freeCount;
void* comparer; void* comparer;
void* keys; void* keys;
void* values; void* values;
std::vector<std::pair<KeyT, ValT>> pairs() std::vector<std::pair<KeyT, ValT>> pairs()
{ {
auto pairs = std::vector<std::pair<KeyT, ValT>>(); auto pairs = std::vector<std::pair<KeyT, ValT>>();
@ -153,8 +153,8 @@ struct __declspec(align(8)) UniDict {
break; break;
if (entry.hashCode > 0) if (entry.hashCode > 0)
pairs.push_back({ entry.key, entry.value }); pairs.push_back({ entry.key, entry.value });
index++; index++;
} }
@ -165,11 +165,11 @@ struct __declspec(align(8)) UniDict {
template<class T> template<class T>
T* CastTo(void* pObject, void* pClass) T* CastTo(void* pObject, void* pClass)
{ {
auto object = reinterpret_cast<app::Object*>(pObject); auto object = reinterpret_cast<app::Object*>(pObject);
if (object == nullptr || object->klass == nullptr || object->klass != pClass) if (object == nullptr || object->klass == nullptr || object->klass != pClass)
return nullptr; return nullptr;
return reinterpret_cast<T*>(object); return reinterpret_cast<T*>(object);
} }
inline app::Vector3 operator + (const app::Vector3& A, const app::Vector3& B) inline app::Vector3 operator + (const app::Vector3& A, const app::Vector3& B)
@ -204,12 +204,12 @@ inline app::Vector3 operator / (const app::Vector3& A, const float k)
inline app::Vector3 operator - (const app::Vector3& A) inline app::Vector3 operator - (const app::Vector3& A)
{ {
return { -A.x, -A.y, -A.z}; return { -A.x, -A.y, -A.z };
} }
inline app::Vector2 operator + (const app::Vector2& A, const float k) inline app::Vector2 operator + (const app::Vector2& A, const float k)
{ {
return { A.x + k, A.y + k}; return { A.x + k, A.y + k };
} }
inline app::Vector2 operator - (const app::Vector2& A, const app::Vector2& B) inline app::Vector2 operator - (const app::Vector2& A, const app::Vector2& B)
@ -219,46 +219,46 @@ inline app::Vector2 operator - (const app::Vector2& A, const app::Vector2& B)
inline app::Vector2 operator - (const app::Vector2& A, const float k) inline app::Vector2 operator - (const app::Vector2& A, const float k)
{ {
return { A.x - k, A.y - k}; return { A.x - k, A.y - k };
} }
inline app::Vector2 operator + (const app::Vector2& A, const app::Vector2& B) inline app::Vector2 operator + (const app::Vector2& A, const app::Vector2& B)
{ {
return { A.x + B.x, A.y + B.y }; return { A.x + B.x, A.y + B.y };
} }
inline app::Vector2 operator * (const app::Vector2& A, const float k) inline app::Vector2 operator * (const app::Vector2& A, const float k)
{ {
return { A.x * k, A.y * k }; return { A.x * k, A.y * k };
} }
inline app::Vector2 operator * (const app::Vector2& A, const app::Vector2& B) inline app::Vector2 operator * (const app::Vector2& A, const app::Vector2& B)
{ {
return { A.x * B.x, A.y * B.y }; return { A.x * B.x, A.y * B.y };
} }
inline app::Vector2 operator / (const app::Vector2& A, const float k) inline app::Vector2 operator / (const app::Vector2& A, const float k)
{ {
return { A.x / k, A.y / k }; return { A.x / k, A.y / k };
} }
inline app::Vector2 operator - (const app::Vector2& A) inline app::Vector2 operator - (const app::Vector2& A)
{ {
return { -A.x, -A.y }; return { -A.x, -A.y };
} }
inline float GetVectorMagnitude(const app::Vector3& A) inline float GetVectorMagnitude(const app::Vector3& A)
{ {
return sqrtf(A.x * A.x + A.y * A.y + A.z * A.z); return sqrtf(A.x * A.x + A.y * A.y + A.z * A.z);
} }
inline app::Vector3 GetVectorDirection(const app::Vector3& from, const app::Vector3& to) inline app::Vector3 GetVectorDirection(const app::Vector3& from, const app::Vector3& to)
{ {
auto dirRaw = to - from; auto dirRaw = to - from;
return dirRaw / GetVectorMagnitude(dirRaw); return dirRaw / GetVectorMagnitude(dirRaw);
} }
inline bool IsVectorZero(const app::Vector3& vector) inline bool IsVectorZero(const app::Vector3& vector)
{ {
return vector.x == 0 && vector.y == 0 && vector.z == 0; return vector.x == 0 && vector.y == 0 && vector.z == 0;
} }
@ -282,7 +282,7 @@ std::string il2cppi_to_string(app::String* str);
std::string il2cppi_to_string(app::Vector vec); std::string il2cppi_to_string(app::Vector vec);
std::string il2cppi_to_string(app::Vector2 vec); std::string il2cppi_to_string(app::Vector2 vec);
std::string il2cppi_to_string(app::Vector3 vec); std::string il2cppi_to_string(app::Vector3 vec);
app::String* string_to_il2cppi(std::string input);
std::string to_hex_string(app::Byte__Array* barray, int length); std::string to_hex_string(app::Byte__Array* barray, int length);
#endif #endif
@ -292,6 +292,6 @@ template<typename T> bool il2cppi_is_initialized(T* metadataItem) {
return *metadataItem != 0; return *metadataItem != 0;
#else #else
// Metadata >=27 (Unity 2020.2) // Metadata >=27 (Unity 2020.2)
return !((uintptr_t) *metadataItem & 1); return !((uintptr_t)*metadataItem & 1);
#endif #endif
} }

View File

@ -42,6 +42,7 @@
#include <cheat/visuals/FPSUnlock.h> #include <cheat/visuals/FPSUnlock.h>
#include <cheat/visuals/CameraZoom.h> #include <cheat/visuals/CameraZoom.h>
#include <cheat/visuals/ShowChestIndicator.h> #include <cheat/visuals/ShowChestIndicator.h>
#include <cheat/visuals/ProfileChanger.h>
#include "GenshinCM.h" #include "GenshinCM.h"
@ -95,7 +96,8 @@ namespace cheat
FEAT_INST(NoFog), FEAT_INST(NoFog),
FEAT_INST(FPSUnlock), FEAT_INST(FPSUnlock),
FEAT_INST(CameraZoom), FEAT_INST(CameraZoom),
FEAT_INST(ChestIndicator) FEAT_INST(ChestIndicator),
FEAT_INST(ProfileChanger)
}); });
#undef FEAT_INST #undef FEAT_INST

View File

@ -0,0 +1,244 @@
#include "pch-il2cpp.h"
#include "ProfileChanger.h"
#include <helpers.h>
#include <cheat/events.h>
#include <misc/cpp/imgui_stdlib.h>
#include <fstream>
namespace cheat::feature
{
namespace GameObject {
app::GameObject* WaterMark = nullptr;
}
namespace Components {
app::Component_1* WaterMark = nullptr;
app::Texture2D* CardTexture = nullptr;
app::Texture2D* AvatarTexture = nullptr;
app::Sprite* CardSprite = nullptr;
app::Sprite* AvatarSprite = nullptr;
app::Rect RectCard;
app::Rect RectAvatar;
}
// Profile Page
app::Button_1* ProfilePage(app::MonoInLevelPlayerProfilePage* __this, MethodInfo* method);
// Edit Player Info Page
static void ProfileEditPage(app::MonoFriendInformationDialog* __this, app::Sprite* value, MethodInfo* method);
ProfileChanger::ProfileChanger() : Feature(),
NF(f_Enabled, "Custom Profile", "Visuals", false),
NF(f_UID, "UID", "Visuals", false),
NF(f_NickName, "NickName", "Visuals", false),
NF(f_Level, "Level", "Visuals", false),
NF(f_Exp, "Exp", "Visuals", false),
NF(f_CurExp, "CurExp", "Visuals", 1),
NF(f_MaxExp, "MaxExp", "Visuals", 1),
NF(f_ExpBar, "ExpBar", "Visuals", false),
NF(f_ExpBarValue, "ExpBarValue", "Visuals", 20.0f),
NF(f_WorldLevel, "WorldLevel", "Visuals", false),
NF(f_Avatar, "AvatarImage", "Visuals", false),
NF(f_Card, "CardImage", "Visuals", false),
toBeUpdate(), nextUpdate(0)
{
HookManager::install(app::ProfilePage, ProfilePage);
HookManager::install(app::ProfileEditPage, ProfileEditPage);
events::GameUpdateEvent += MY_METHOD_HANDLER(ProfileChanger::OnGameUpdate);
}
const FeatureGUIInfo& ProfileChanger::GetGUIInfo() const
{
static const FeatureGUIInfo info{ "CustomProfile", "Visuals", true };
return info;
}
void ProfileChanger::DrawMain()
{
ConfigWidget(f_Enabled, "Custom Profile.");
ConfigWidget(f_UID, "Changes the uid visually.");
ConfigWidget(f_NickName, "Changes the nickname visually.");
ConfigWidget(f_Level, "Changes the level visually.");
ConfigWidget(f_Exp, "Changes the exp visually.");
if (f_Exp) {
ConfigWidget("CurExp", f_CurExp, 1, 2, 100000, "Changes the ExpBar visually.");
ConfigWidget("MaxExp", f_MaxExp, 1, 2, 100000, "Changes the ExpBar visually.");
ConfigWidget(f_ExpBar, "Changes the ExpBar visually.");
if (f_ExpBar)
ConfigWidget("ExpBarValue", f_ExpBarValue, 1, 2, 100, "Changes the ExpBar visually.");
}
ConfigWidget(f_WorldLevel, "Changes the world-level visually.");
ConfigWidget(f_Avatar, "Changes the Avatar Image visually.\n" \
"Note the size of the picture must be: 256x256.\n" \
"Example path: C:\\Avatars.png");
ConfigWidget(f_Card, "Changes the Card visually.\n" \
"Note the size of the picture must be: 840x400.\n" \
"Example path: C:\\Avatars.png");
}
bool ProfileChanger::NeedStatusDraw() const
{
return f_Enabled;
}
void ProfileChanger::DrawStatus()
{
ImGui::Text("Custom Profile");
}
ProfileChanger& ProfileChanger::GetInstance()
{
static ProfileChanger instance;
return instance;
}
void ProfileChanger::OnGameUpdate()
{
if (!f_Enabled || !f_UID)
return;
auto currentTime = util::GetCurrentTimeMillisec();
if (currentTime < nextUpdate)
return;
if (f_UID) {
if (GameObject::WaterMark == nullptr)
GameObject::WaterMark = app::GameObject_Find(string_to_il2cppi("/BetaWatermarkCanvas(Clone)/Panel/TxtUID"), nullptr);
if (GameObject::WaterMark != nullptr && Components::WaterMark == nullptr)
Components::WaterMark = app::GameObject_GetComponentByName(GameObject::WaterMark, string_to_il2cppi("Text"), nullptr);
if (Components::WaterMark != nullptr)
app::Text_set_text(reinterpret_cast<app::Text*>(Components::WaterMark), string_to_il2cppi(f_UID), nullptr);
}
nextUpdate = currentTime + (int)f_DelayUpdate;
}
bool ProfileChanger::CheckFile(const std::string& Filename) {
struct stat buffer;
return (stat(Filename.c_str(), &buffer) == 0);
}
app::Button_1* ProfilePage(app::MonoInLevelPlayerProfilePage* __this, MethodInfo* method)
{
auto& profile = ProfileChanger::GetInstance();
if (profile.f_Enabled) {
if (profile.f_UID)
app::Text_set_text(__this->fields._playerID, string_to_il2cppi(profile.f_UID), nullptr);
if (profile.f_Level)
app::Text_set_text(__this->fields._playerLv, string_to_il2cppi(profile.f_Level), nullptr);
if (profile.f_Exp) {
std::string CurExpStr = std::to_string(profile.f_CurExp);
std::string MaxExpStr = std::to_string(profile.f_MaxExp);
app::Text_set_text(__this->fields._playerExp, string_to_il2cppi(CurExpStr + "/" + MaxExpStr), nullptr);
if (profile.f_ExpBar)
{
app::Slider_1_set_minValue(__this->fields._playerExpSlider, 1, nullptr);
app::Slider_1_set_maxValue(__this->fields._playerExpSlider, 100, nullptr);
app::Slider_1_set_value(__this->fields._playerExpSlider, profile.f_ExpBarValue, nullptr);
}
}
if (profile.f_WorldLevel)
app::Text_set_text(__this->fields._playerWorldLv, string_to_il2cppi(profile.f_WorldLevel), nullptr);
if (profile.f_NickName){
auto playerModule = GET_SINGLETON(MoleMole_PlayerModule);
if (playerModule != nullptr && playerModule->fields._accountData_k__BackingField != nullptr) {
auto& accountData = playerModule->fields._accountData_k__BackingField->fields;
accountData.nickName = string_to_il2cppi(profile.f_NickName);
}
}
// Card Name png size 840x400
if (profile.f_Card){
if (profile.CheckFile(profile.f_Card)) {
Components::CardTexture = app::NativeGallery_LoadImageAtPath(string_to_il2cppi(profile.f_Card), 100, false, false, false, nullptr);
// If you don't do this check, then the UI will break after teleportation, I'm just too lazy to set up Rect manually
if (Components::RectCard.m_Width == 0)
Components::RectCard = app::Sprite_get_rect(__this->fields._nameCardPic->fields.m_Sprite, nullptr);
app::Vector2 Vec2 = { 100, 100 };
Components::CardSprite = app::Sprite_Create(Components::CardTexture, Components::RectCard, Vec2, 1, nullptr);
__this->fields._nameCardPic->fields.m_OverrideSprite = Components::CardSprite;
}
else {
std::cout << "Card Image: \n" << "not found" << std::endl;
}
}
// Avatar png size 256x256
if (profile.f_Avatar) {
if (profile.CheckFile(profile.f_Avatar)) {
Components::AvatarTexture = app::NativeGallery_LoadImageAtPath(string_to_il2cppi(profile.f_Avatar), 100, false, false, false, nullptr);
// If you don't do this check, then the UI will break after teleportation, I'm just too lazy to set up Rect manually
if (Components::RectAvatar.m_Width == 0)
Components::RectAvatar = app::Sprite_get_rect(__this->fields.playerIconImage->fields.m_Sprite, nullptr);
app::Vector2 Vec2Avatar = { 128, 128 };
Components::AvatarSprite = app::Sprite_Create(Components::AvatarTexture, Components::RectAvatar, Vec2Avatar, 1, nullptr);
__this->fields.playerIconImage->fields.m_OverrideSprite = Components::AvatarSprite;
}
else {
std::cout << "Avatar Image: \n" << "not found" << std::endl;
}
}
}
return CALL_ORIGIN(ProfilePage, __this, method);
}
static void ProfileEditPage(app::MonoFriendInformationDialog* __this, app::Sprite* value, MethodInfo* method) {
auto& profile = ProfileChanger::GetInstance();
if (profile.f_Enabled) {
if (profile.f_UID)
__this->fields._playerUID->fields.m_Text = string_to_il2cppi(profile.f_UID);
if (profile.f_Level)
__this->fields._playerLevel->fields.m_Text = string_to_il2cppi(profile.f_Level);
if (profile.f_WorldLevel)
__this->fields._worldLevel->fields.m_Text = string_to_il2cppi(profile.f_WorldLevel);
// Card Name png size 840x400
if (profile.f_Card) {
if (profile.CheckFile(profile.f_Card)) {
Components::CardTexture = app::NativeGallery_LoadImageAtPath(string_to_il2cppi(profile.f_Card), 100, false, false, false, nullptr);
// If you don't do this check, then the UI will break after teleportation, I'm just too lazy to set up Rect manually
if (Components::RectCard.m_Width == 0)
Components::RectCard = app::Sprite_get_rect(__this->fields._cardImg->fields.m_Sprite, nullptr);
app::Vector2 Vec2 = { 100, 100 };
Components::CardSprite = app::Sprite_Create(Components::CardTexture, Components::RectCard, Vec2, 1, nullptr);
__this->fields._cardImg->fields.m_OverrideSprite = Components::CardSprite;
}
else {
std::cout << "Card Image: \n" << "not found" << std::endl;
}
}
// Avatar png size 256x256
if (profile.f_Avatar) {
if (profile.CheckFile(profile.f_Avatar)) {
Components::AvatarTexture = app::NativeGallery_LoadImageAtPath(string_to_il2cppi(profile.f_Avatar), 100, false, false, false, nullptr);
if (Components::RectAvatar.m_Width == 0)
Components::RectAvatar = app::Sprite_get_rect(__this->fields._icon->fields.m_Sprite, nullptr);
app::Vector2 Vec2Avatar = { 128, 128 };
Components::AvatarSprite = app::Sprite_Create(Components::AvatarTexture, Components::RectAvatar, Vec2Avatar, 1, nullptr);
__this->fields._icon->fields.m_OverrideSprite = Components::AvatarSprite;
}
else {
std::cout << "Card Image: \n" << "not found" << std::endl;
}
}
}
return CALL_ORIGIN(ProfileEditPage, __this, value, method);
}
}

View File

@ -0,0 +1,44 @@
#pragma once
#include <cheat-base/cheat/Feature.h>
#include <cheat-base/config/config.h>
#include <cheat-base/thread-safe.h>
namespace cheat::feature
{
class ProfileChanger : public Feature
{
public:
config::Field<config::Toggle<Hotkey>> f_Enabled;
config::Field<config::Toggle<std::string>> f_UID;
config::Field<config::Toggle<std::string>> f_NickName;
config::Field<config::Toggle<std::string>> f_Level;
config::Field<config::Toggle<Hotkey>> f_Exp;
config::Field<int> f_CurExp;
config::Field<int> f_MaxExp;
config::Field<config::Toggle<Hotkey>> f_ExpBar;
config::Field<float> f_ExpBarValue;
config::Field<config::Toggle<std::string>> f_WorldLevel;
config::Field<config::Toggle<std::string>> f_Avatar; // Avatar png size 256x256
config::Field<config::Toggle<std::string>> f_Card; // Card Name png size 840x400
static ProfileChanger& GetInstance();
const FeatureGUIInfo& GetGUIInfo() const override;
void DrawMain() override;
virtual 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 = 100.f;
void OnGameUpdate();
ProfileChanger();
};
}

View File

@ -4,20 +4,23 @@
#include <helpers.h> #include <helpers.h>
#include <cheat/game/EntityManager.h> #include <cheat/game/EntityManager.h>
namespace cheat::feature namespace cheat::feature
{ {
static void InLevelCutScenePageContext_UpdateView_Hook(app::InLevelCutScenePageContext* __this, MethodInfo* method); static void InLevelCutScenePageContext_UpdateView_Hook(app::InLevelCutScenePageContext* __this, MethodInfo* method);
static void InLevelCutScenePageContext_ClearView_Hook(app::InLevelCutScenePageContext* __this, MethodInfo* method); static void InLevelCutScenePageContext_ClearView_Hook(app::InLevelCutScenePageContext* __this, MethodInfo* method);
static void CriwareMediaPlayer_Update(app::CriwareMediaPlayer* __this, MethodInfo* method);
DialogSkip::DialogSkip() : Feature(), DialogSkip::DialogSkip() : Feature(),
NF(f_Enabled, "Auto talk", "AutoTalk", false), NF(f_Enabled, "Auto talk", "AutoTalk", false),
NF(f_AutoSelectDialog, "Auto select dialog", "AutoTalk", true), NF(f_AutoSelectDialog, "Auto select dialog", "AutoTalk", true),
NF(f_ExcludeImportant, "Exclude Katheryne/Tubby", "AutoTalk", true), NF(f_ExcludeImportant, "Exclude Katheryne/Tubby", "AutoTalk", true),
NF(f_FastDialog, "Fast dialog", "AutoTalk", false), NF(f_FastDialog, "Fast dialog", "AutoTalk", false),
NF(f_TimeSpeedup, "Time Speed", "AutoTalk", 5.0f) NF(f_CutsceneUSM, "Skip Cutscenes", "AutoTalk", false),
NF(f_TimeSpeedup, "Time Speed", "AutoTalk", 5.0f)
{ {
HookManager::install(app::MoleMole_InLevelCutScenePageContext_UpdateView, InLevelCutScenePageContext_UpdateView_Hook); HookManager::install(app::MoleMole_InLevelCutScenePageContext_UpdateView, InLevelCutScenePageContext_UpdateView_Hook);
HookManager::install(app::MoleMole_InLevelCutScenePageContext_ClearView, InLevelCutScenePageContext_ClearView_Hook); HookManager::install(app::MoleMole_InLevelCutScenePageContext_ClearView, InLevelCutScenePageContext_ClearView_Hook);
HookManager::install(app::CriwareMediaPlayer_Update, CriwareMediaPlayer_Update);
} }
const FeatureGUIInfo& DialogSkip::GetGUIInfo() const const FeatureGUIInfo& DialogSkip::GetGUIInfo() const
@ -41,21 +44,25 @@ namespace cheat::feature
{ {
ConfigWidget(f_TimeSpeedup, 0.1f, 2.0f, 50.0f, "Time Speedup Multipler \nHigher Values will lead to sync issues with servers \nand is not recommended for Laggy Internet connections."); ConfigWidget(f_TimeSpeedup, 0.1f, 2.0f, 50.0f, "Time Speedup Multipler \nHigher Values will lead to sync issues with servers \nand is not recommended for Laggy Internet connections.");
} }
ConfigWidget("Skip Cutscenes", f_CutsceneUSM, "Automatically skips game movies.");
} }
bool DialogSkip::NeedStatusDraw() const bool DialogSkip::NeedStatusDraw() const
{ {
return f_Enabled; return f_Enabled || f_CutsceneUSM;
} }
void DialogSkip::DrawStatus() void DialogSkip::DrawStatus()
{ {
ImGui::Text("Dialog [%s%s%s%s%s]", if (f_Enabled)
f_AutoSelectDialog ? "Auto" : "Manual", ImGui::Text("Dialog [%s%s%s%s%s]",
f_AutoSelectDialog && (f_ExcludeImportant || f_FastDialog) ? "|" : "", f_AutoSelectDialog ? "Auto" : "Manual",
f_ExcludeImportant ? "Exc" : "", f_AutoSelectDialog && (f_ExcludeImportant || f_FastDialog) ? "|" : "",
f_ExcludeImportant && f_FastDialog ? "|" : "", f_ExcludeImportant ? "Exc" : "",
f_FastDialog ? "Fast" : "Normal"); f_ExcludeImportant && f_FastDialog ? "|" : "",
f_FastDialog ? "Fast" : "Normal");
ImGui::Text(f_CutsceneUSM ? "Skip Cutscenes" : "");
} }
DialogSkip& DialogSkip::GetInstance() DialogSkip& DialogSkip::GetInstance()
@ -64,10 +71,10 @@ namespace cheat::feature
return instance; return instance;
} }
// Raised when dialog view updating // Raised when dialog view updating
// We call free click, if auto talk enabled, that means we just emulate user click // We call free click, if auto talk enabled, that means we just emulate user click
// When appear dialog choose we create notify with dialog select first item. // When appear dialog choose we create notify with dialog select first item.
void DialogSkip::OnCutScenePageUpdate(app::InLevelCutScenePageContext* context) void DialogSkip::OnCutScenePageUpdate(app::InLevelCutScenePageContext* context)
{ {
if (!f_Enabled) if (!f_Enabled)
return; return;
@ -86,7 +93,7 @@ namespace cheat::feature
// add their own name substrings of entities to avoid // add their own name substrings of entities to avoid
// speeding up dialog on. // speeding up dialog on.
std::vector<std::string> impEntitiesNames = { std::vector<std::string> impEntitiesNames = {
"Djinn", "Djinn",
"Katheryne" "Katheryne"
}; };
auto dialogPartnerID = context->fields._inteeID; auto dialogPartnerID = context->fields._inteeID;
@ -103,25 +110,25 @@ namespace cheat::feature
} }
} }
if (talkDialog->fields._inSelect && f_AutoSelectDialog && !isImportant) if (talkDialog->fields._inSelect && f_AutoSelectDialog && !isImportant)
{ {
int32_t value = 0; int32_t value = 0;
auto object = il2cpp_value_box((Il2CppClass*)*app::Int32__TypeInfo, &value); auto object = il2cpp_value_box((Il2CppClass*)*app::Int32__TypeInfo, &value);
auto notify = app::Notify_CreateNotify_1(app::MoleMole_NotifyTypes__Enum::DialogSelectItemNotify, (app::Object*)object, nullptr); auto notify = app::Notify_CreateNotify_1(app::MoleMole_NotifyTypes__Enum::DialogSelectItemNotify, (app::Object*)object, nullptr);
app::MoleMole_TalkDialogContext_OnDialogSelectItem(talkDialog, &notify, nullptr); app::MoleMole_TalkDialogContext_OnDialogSelectItem(talkDialog, &notify, nullptr);
} }
else if (!talkDialog->fields._inSelect) else if (!talkDialog->fields._inSelect)
app::MoleMole_InLevelCutScenePageContext_OnFreeClick(context, nullptr); app::MoleMole_InLevelCutScenePageContext_OnFreeClick(context, nullptr);
} }
static void InLevelCutScenePageContext_UpdateView_Hook(app::InLevelCutScenePageContext* __this, MethodInfo* method) static void InLevelCutScenePageContext_UpdateView_Hook(app::InLevelCutScenePageContext* __this, MethodInfo* method)
{ {
CALL_ORIGIN(InLevelCutScenePageContext_UpdateView_Hook, __this, method); CALL_ORIGIN(InLevelCutScenePageContext_UpdateView_Hook, __this, method);
DialogSkip& dialogSkip = DialogSkip::GetInstance(); DialogSkip& dialogSkip = DialogSkip::GetInstance();
dialogSkip.OnCutScenePageUpdate(__this); dialogSkip.OnCutScenePageUpdate(__this);
} }
// Raised when exiting a dialog. We try to hackishly return to normal value. // Raised when exiting a dialog. We try to hackishly return to normal value.
// Should be a better way to store the pre-dialog speed using Time_get_timeScale. // Should be a better way to store the pre-dialog speed using Time_get_timeScale.
static void InLevelCutScenePageContext_ClearView_Hook(app::InLevelCutScenePageContext* __this, MethodInfo* method) static void InLevelCutScenePageContext_ClearView_Hook(app::InLevelCutScenePageContext* __this, MethodInfo* method)
@ -131,5 +138,14 @@ namespace cheat::feature
app::Time_set_timeScale(1.0f, nullptr); app::Time_set_timeScale(1.0f, nullptr);
CALL_ORIGIN(InLevelCutScenePageContext_ClearView_Hook, __this, method); CALL_ORIGIN(InLevelCutScenePageContext_ClearView_Hook, __this, method);
} }
static void CriwareMediaPlayer_Update(app::CriwareMediaPlayer* __this, MethodInfo* method)
{
DialogSkip& dialogSkip = DialogSkip::GetInstance();
if (dialogSkip.f_CutsceneUSM)
app::CriwareMediaPlayer_Skip(__this, nullptr);
return CALL_ORIGIN(CriwareMediaPlayer_Update, __this, method);
}
} }

View File

@ -2,16 +2,17 @@
#include <cheat-base/cheat/Feature.h> #include <cheat-base/cheat/Feature.h>
#include <cheat-base/config/config.h> #include <cheat-base/config/config.h>
namespace cheat::feature namespace cheat::feature
{ {
class DialogSkip : public Feature class DialogSkip : public Feature
{ {
public: public:
config::Field<config::Toggle<Hotkey>> f_Enabled; config::Field<config::Toggle<Hotkey>> f_Enabled;
config::Field<config::Toggle<Hotkey>> f_AutoSelectDialog; config::Field<config::Toggle<Hotkey>> f_AutoSelectDialog;
config::Field<config::Toggle<Hotkey>> f_ExcludeImportant; config::Field<config::Toggle<Hotkey>> f_ExcludeImportant;
config::Field<config::Toggle<Hotkey>> f_FastDialog; config::Field<config::Toggle<Hotkey>> f_FastDialog;
config::Field<config::Toggle<Hotkey>> f_CutsceneUSM;
config::Field<float> f_TimeSpeedup; config::Field<float> f_TimeSpeedup;
static DialogSkip& GetInstance(); static DialogSkip& GetInstance();
@ -23,7 +24,7 @@ namespace cheat::feature
void DrawStatus() override; void DrawStatus() override;
void OnCutScenePageUpdate(app::InLevelCutScenePageContext* context); void OnCutScenePageUpdate(app::InLevelCutScenePageContext* context);
private: private:
DialogSkip(); DialogSkip();
}; };