fixed live

This commit is contained in:
chinosk 2025-04-27 15:50:13 +01:00
parent d02864526c
commit 7cc0c95e5c
Signed by: chinosk
GPG Key ID: 00610B08C1BF7BE9
5 changed files with 177 additions and 25 deletions

View File

@ -99,6 +99,18 @@ namespace GakumasLocal::HookMain {
return GetResolution->Invoke<Il2cppUtils::Resolution_t>(); return GetResolution->Invoke<Il2cppUtils::Resolution_t>();
} }
Il2cppString* ToJsonStr(void* object) {
static Il2cppString* (*toJsonStr)(void*) = nullptr;
if (!toJsonStr) {
toJsonStr = reinterpret_cast<Il2cppString * (*)(void*)>(Il2cppUtils::GetMethodPointer("Newtonsoft.Json.dll", "Newtonsoft.Json",
"JsonConvert", "SerializeObject", { "*" }));
}
if (!toJsonStr) {
return nullptr;
}
return toJsonStr(object);
}
DEFINE_HOOK(void, Unity_set_fieldOfView, (UnityResolve::UnityType::Camera* self, float value)) { DEFINE_HOOK(void, Unity_set_fieldOfView, (UnityResolve::UnityType::Camera* self, float value)) {
if (Config::enableFreeCamera) { if (Config::enableFreeCamera) {
if (self == mainCameraCache) { if (self == mainCameraCache) {
@ -703,24 +715,24 @@ namespace GakumasLocal::HookMain {
} }
#ifdef GKMS_WINDOWS #ifdef GKMS_WINDOWS
DEFINE_HOOK(void, PictureBookLiveThumbnailView_SetDataAsync, (void* retstr, void* self, void* liveData, bool isReleased, bool isUnlocked, bool isNew, bool hasLiveSkin, void* ct, void* mtd)) { DEFINE_HOOK(void, PictureBookLiveThumbnailView_SetDataAsync, (void* retstr, void* self, void* liveData, Il2cppString* characterId, bool isReleased, bool isUnlocked, bool isNew, bool hasLiveSkin, void* ct, void* mtd)) {
// Log::DebugFmt("PictureBookLiveThumbnailView_SetDataAsync: isReleased: %d, isUnlocked: %d, isNew: %d, hasLiveSkin: %d", isReleased, isUnlocked, isNew, hasLiveSkin); // Log::DebugFmt("PictureBookLiveThumbnailView_SetDataAsync: isReleased: %d, isUnlocked: %d, isNew: %d, hasLiveSkin: %d", isReleased, isUnlocked, isNew, hasLiveSkin);
if (Config::dbgMode && Config::unlockAllLive) { if (Config::dbgMode && Config::unlockAllLive) {
isUnlocked = true; isUnlocked = true;
isReleased = true; isReleased = true;
hasLiveSkin = true; hasLiveSkin = true;
} }
PictureBookLiveThumbnailView_SetDataAsync_Orig(retstr, self, liveData, isReleased, isUnlocked, isNew, hasLiveSkin, ct, mtd); PictureBookLiveThumbnailView_SetDataAsync_Orig(retstr, self, liveData, characterId, isReleased, isUnlocked, isNew, hasLiveSkin, ct, mtd);
} }
#else #else
DEFINE_HOOK(void, PictureBookLiveThumbnailView_SetDataAsync, (void* self, void* liveData, bool isReleased, bool isUnlocked, bool isNew, bool hasLiveSkin, void* ct, void* mtd)) { DEFINE_HOOK(void, PictureBookLiveThumbnailView_SetDataAsync, (void* self, void* liveData, Il2cppString* characterId, bool isReleased, bool isUnlocked, bool isNew, bool hasLiveSkin, void* ct, void* mtd)) {
// Log::DebugFmt("PictureBookLiveThumbnailView_SetDataAsync: isReleased: %d, isUnlocked: %d, isNew: %d, hasLiveSkin: %d", isReleased, isUnlocked, isNew, hasLiveSkin); // Log::DebugFmt("PictureBookLiveThumbnailView_SetDataAsync: isReleased: %d, isUnlocked: %d, isNew: %d, hasLiveSkin: %d", isReleased, isUnlocked, isNew, hasLiveSkin);
if (Config::dbgMode && Config::unlockAllLive) { if (Config::dbgMode && Config::unlockAllLive) {
isUnlocked = true; isUnlocked = true;
isReleased = true; isReleased = true;
hasLiveSkin = true; hasLiveSkin = true;
} }
PictureBookLiveThumbnailView_SetDataAsync_Orig(self, liveData, isReleased, isUnlocked, isNew, hasLiveSkin, ct, mtd); PictureBookLiveThumbnailView_SetDataAsync_Orig(self, liveData, characterId, isReleased, isUnlocked, isNew, hasLiveSkin, ct, mtd);
} }
#endif #endif
@ -865,6 +877,34 @@ namespace GakumasLocal::HookMain {
return ret; return ret;
} }
void* getCompletedUniTask() {
static auto unitask_klass = Il2cppUtils::GetClass("UniTask.dll", "Cysharp.Threading.Tasks", "UniTask");
static auto CompletedTask_field = unitask_klass->Get<UnityResolve::Field>("CompletedTask");
auto ret = UnityResolve::Invoke<void*>("il2cpp_object_new", unitask_klass->address);
UnityResolve::Invoke<void>("il2cpp_field_static_get_value", CompletedTask_field->address, ret);
return ret;
}
#ifdef GKMS_WINDOWS
// 绕过切歌时的等待以及网络请求
DEFINE_HOOK(void*, Produce_ViewPictureBookLiveAsync, (void* retstr, Il2cppString* musicId, Il2cppString* characterId,
void* ct, void* callOption, void* errorHandlerIl, Il2cppString* requestIdForResponseCache, void* mtd)) {
// Log::DebugFmt("Produce_ViewPictureBookLiveAsync: %s - %s", musicId->ToString().c_str(), characterId->ToString().c_str());
if (Config::unlockAllLive) return getCompletedUniTask();
return Produce_ViewPictureBookLiveAsync_Orig(retstr, musicId, characterId, ct, callOption, errorHandlerIl, requestIdForResponseCache, mtd);
}
#else
DEFINE_HOOK(void*, Produce_ViewPictureBookLiveAsync, (Il2cppString* musicId, Il2cppString* characterId,
void* ct, void* callOption, void* errorHandlerIl, Il2cppString* requestIdForResponseCache, void* mtd)) {
// Log::DebugFmt("Produce_ViewPictureBookLiveAsync: %s - %s", musicId->ToString().c_str(), characterId->ToString().c_str());
if (Config::unlockAllLive) return getCompletedUniTask();
return Produce_ViewPictureBookLiveAsync_Orig(musicId, characterId, ct, callOption, errorHandlerIl, requestIdForResponseCache, mtd);
}
#endif // GKMS_WINDOWS
void* PictureBookWindowPresenter_instance = nullptr; void* PictureBookWindowPresenter_instance = nullptr;
std::string PictureBookWindowPresenter_charaId; std::string PictureBookWindowPresenter_charaId;
DEFINE_HOOK(void*, PictureBookWindowPresenter_GetLiveMusics, (void* self, Il2cppString* charaId, void* mtd)) { DEFINE_HOOK(void*, PictureBookWindowPresenter_GetLiveMusics, (void* self, Il2cppString* charaId, void* mtd)) {
@ -877,27 +917,59 @@ namespace GakumasLocal::HookMain {
static auto PictureBookWindowPresenter_klass = Il2cppUtils::GetClass("Assembly-CSharp.dll", "Campus.OutGame", static auto PictureBookWindowPresenter_klass = Il2cppUtils::GetClass("Assembly-CSharp.dll", "Campus.OutGame",
"PictureBookWindowPresenter"); "PictureBookWindowPresenter");
static auto existsMusicIds_field = PictureBookWindowPresenter_klass->Get<UnityResolve::Field>("_existsMusicIds"); static auto existsMusicIds_field = PictureBookWindowPresenter_klass->Get<UnityResolve::Field>("_existsMusicIds");
auto existsMusicIds = Il2cppUtils::ClassGetFieldValue<UnityResolve::UnityType::List<Il2cppString*>*>(self, existsMusicIds_field); // auto existsMusicIds = Il2cppUtils::ClassGetFieldValue<UnityResolve::UnityType::List<Il2cppString*>*>(self, existsMusicIds_field);
auto existsMusicIds = Il2cppUtils::ClassGetFieldValue<UnityResolve::UnityType::Dictionary<Il2cppString*, UnityResolve::UnityType::List<Il2cppString*>>*>(self, existsMusicIds_field);
if (!existsMusicIds) { if (!existsMusicIds) {
static auto Dict_List_String_klass = Il2cppUtils::get_system_class_from_reflection_type_str(
"System.Collections.Generic.Dictionary`2[System.String, System.Collections.Generic.List`1[System.String]]");
static auto List_String_klass = Il2cppUtils::get_system_class_from_reflection_type_str( static auto List_String_klass = Il2cppUtils::get_system_class_from_reflection_type_str(
"System.Collections.Generic.List`1[System.String]"); "System.Collections.Generic.List`1[System.String]");
static auto List_String_ctor_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(List_String_klass, ".ctor", 0); static auto List_String_ctor_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(List_String_klass, ".ctor", 0);
static auto List_String_ctor = reinterpret_cast<void (*)(void*, void*)>(List_String_ctor_mtd->methodPointer); static auto List_String_ctor = reinterpret_cast<void (*)(void*, void*)>(List_String_ctor_mtd->methodPointer);
auto newList = UnityResolve::Invoke<void*>("il2cpp_object_new", List_String_klass);
List_String_ctor(newList, List_String_ctor_mtd);
Il2cppUtils::Tools::CSListEditor<Il2cppString*> newListEditor(newList);
auto fullIds = GetIdolMusicIdAll(); auto fullIds = GetIdolMusicIdAll();
static auto Dict_List_String_ctor_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(Dict_List_String_klass, ".ctor", 0);
static auto Dict_List_String_ctor = reinterpret_cast<void (*)(void*, void*)>(Dict_List_String_ctor_mtd->methodPointer);
auto newDict = UnityResolve::Invoke<void*>("il2cpp_object_new", Dict_List_String_klass);
Dict_List_String_ctor(newDict, Dict_List_String_ctor_mtd);
Il2cppUtils::Tools::CSDictEditor<Il2cppString*, void*> newDictEditor(newDict, Dict_List_String_klass);
// auto fullIds = GetIdolMusicIdAll();
for (auto& i : fullIds) { for (auto& i : fullIds) {
// Log::DebugFmt("GetLiveMusics - Add: %s", i.c_str()); // Log::DebugFmt("GetLiveMusics - Add: %s", i.c_str()); // eg. music-all-amao-001, music-char-hski-001
newListEditor.Add(Il2cppString::New(i)); //newListEditor.Add(Il2cppString::New(i));
auto newList = UnityResolve::Invoke<void*>("il2cpp_object_new", List_String_klass);
List_String_ctor(newList, List_String_ctor_mtd);
newDictEditor.Add(Il2cppString::New(i), newList);
} }
Il2cppUtils::ClassSetFieldValue(self, existsMusicIds_field, newList); Il2cppUtils::ClassSetFieldValue(self, existsMusicIds_field, newDict);
existsMusicIds = reinterpret_cast<decltype(existsMusicIds)>(newDict);
// Log::DebugFmt("GetLiveMusics - set end: %d", fullIds.size()); // Log::DebugFmt("GetLiveMusics - set end: %d", fullIds.size());
} }
/*
Il2cppUtils::Tools::CSDictEditor<Il2cppString*, void*> dicCheckEditor(existsMusicIds, Dict_List_String_klass);
for (auto& i : fullIds) {
auto currKeyStr = Il2cppString::New(i);
void* currList;
if (dicCheckEditor.ContainsKey(currKeyStr)) {
currList = dicCheckEditor.get_Item(currKeyStr);
}
else {
currList = UnityResolve::Invoke<void*>("il2cpp_object_new", List_String_klass);
List_String_ctor(currList, List_String_ctor_mtd);
}
Il2cppUtils::Tools::CSListEditor<Il2cppString*> currListEditor(currList);
if (!currListEditor.Contains(charaId)) {
currListEditor.Add(charaId);
}
}*/
} }
return PictureBookWindowPresenter_GetLiveMusics_Orig(self, charaId, mtd); return PictureBookWindowPresenter_GetLiveMusics_Orig(self, charaId, mtd);
@ -906,7 +978,7 @@ namespace GakumasLocal::HookMain {
DEFINE_HOOK(void, PictureBookLiveSelectScreenModel_ctor, (void* self, void* transitionParam, UnityResolve::UnityType::List<void*>* musics, void* mtd)) { DEFINE_HOOK(void, PictureBookLiveSelectScreenModel_ctor, (void* self, void* transitionParam, UnityResolve::UnityType::List<void*>* musics, void* mtd)) {
// Log::DebugFmt("PictureBookLiveSelectScreenModel_ctor"); // Log::DebugFmt("PictureBookLiveSelectScreenModel_ctor");
if (Config::unlockAllLive) { if (Config::dbgMode && Config::unlockAllLive) {
static auto GetLiveMusics = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.OutGame", static auto GetLiveMusics = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.OutGame",
"PictureBookWindowPresenter", "GetLiveMusics"); "PictureBookWindowPresenter", "GetLiveMusics");
if (PictureBookWindowPresenter_instance && !PictureBookWindowPresenter_charaId.empty()) { if (PictureBookWindowPresenter_instance && !PictureBookWindowPresenter_charaId.empty()) {
@ -920,17 +992,16 @@ namespace GakumasLocal::HookMain {
} }
bool needRestoreHides = false; bool needRestoreHides = false;
DEFINE_HOOK(void*, PictureBookLiveSelectScreenPresenter_MoveLiveScene, (void* self, void* produceLive, DEFINE_HOOK(void*, PictureBookLiveSelectScreenPresenter_MoveLiveScene, (void* self, void* produceLive, bool isPlayCharacterFocusCamera, void* mtd)) {
Il2cppString* characterId, Il2cppString* idolCardId, Il2cppString* costumeId, Il2cppString* costumeHeadId, void* mtd)) {
needRestoreHides = false; needRestoreHides = false;
Log::InfoFmt("MoveLiveScene: characterId: %s, idolCardId: %s, costumeId: %s, costumeHeadId: %s,", // Log::InfoFmt("MoveLiveScene: characterId: %s, idolCardId: %s, costumeId: %s, costumeHeadId: %s,",
characterId->ToString().c_str(), idolCardId->ToString().c_str(), costumeId->ToString().c_str(), costumeHeadId->ToString().c_str()); // characterId->ToString().c_str(), idolCardId->ToString().c_str(), costumeId->ToString().c_str(), costumeHeadId->ToString().c_str());
/* /*
characterId: hski, costumeId: hski-cstm-0002, costumeHeadId: costume_head_hski-cstm-0002, characterId: hski, costumeId: hski-cstm-0002, costumeHeadId: costume_head_hski-cstm-0002,
characterId: shro, costumeId: shro-cstm-0006, costumeHeadId: costume_head_shro-cstm-0006, characterId: shro, costumeId: shro-cstm-0006, costumeHeadId: costume_head_shro-cstm-0006,
*/ */
/*
if (Config::dbgMode && Config::enableLiveCustomeDress) { if (Config::dbgMode && Config::enableLiveCustomeDress) {
// 修改 LiveFixedData_GetCharacter 可以更改 Loading 角色和演唱者名字,而不变更实际登台人 // 修改 LiveFixedData_GetCharacter 可以更改 Loading 角色和演唱者名字,而不变更实际登台人
return PictureBookLiveSelectScreenPresenter_MoveLiveScene_Orig(self, produceLive, characterId, idolCardId, return PictureBookLiveSelectScreenPresenter_MoveLiveScene_Orig(self, produceLive, characterId, idolCardId,
@ -938,8 +1009,9 @@ namespace GakumasLocal::HookMain {
Config::liveCustomeHeadId.empty() ? costumeHeadId : Il2cppString::New(Config::liveCustomeHeadId), Config::liveCustomeHeadId.empty() ? costumeHeadId : Il2cppString::New(Config::liveCustomeHeadId),
mtd); mtd);
} }
*/
return PictureBookLiveSelectScreenPresenter_MoveLiveScene_Orig(self, produceLive, characterId, idolCardId, costumeId, costumeHeadId, mtd); // return PictureBookLiveSelectScreenPresenter_MoveLiveScene_Orig(self, produceLive, characterId, idolCardId, costumeId, costumeHeadId, mtd);
return PictureBookLiveSelectScreenPresenter_MoveLiveScene_Orig(self, produceLive, isPlayCharacterFocusCamera, mtd);
} }
// std::string lastMusicId; // std::string lastMusicId;
@ -1624,6 +1696,10 @@ namespace GakumasLocal::HookMain {
ADD_HOOK(PictureBookWindowPresenter_GetLiveMusics, ADD_HOOK(PictureBookWindowPresenter_GetLiveMusics,
Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.OutGame", Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.OutGame",
"PictureBookWindowPresenter", "GetLiveMusics")); "PictureBookWindowPresenter", "GetLiveMusics"));
ADD_HOOK(Produce_ViewPictureBookLiveAsync,
Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "",
"Produce", "ViewPictureBookLiveAsync"));
ADD_HOOK(PictureBookLiveSelectScreenModel_ctor, ADD_HOOK(PictureBookLiveSelectScreenModel_ctor,
Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.OutGame", Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.OutGame",
"PictureBookLiveSelectScreenModel", ".ctor")); "PictureBookLiveSelectScreenModel", ".ctor"));

View File

@ -337,17 +337,23 @@ namespace Il2cppUtils {
lst_get_Item_method = il2cpp_class_get_method_from_name(list_klass, "get_Item", 1); lst_get_Item_method = il2cpp_class_get_method_from_name(list_klass, "get_Item", 1);
lst_set_Item_method = il2cpp_class_get_method_from_name(list_klass, "set_Item", 2); lst_set_Item_method = il2cpp_class_get_method_from_name(list_klass, "set_Item", 2);
lst_Add_method = il2cpp_class_get_method_from_name(list_klass, "Add", 1); lst_Add_method = il2cpp_class_get_method_from_name(list_klass, "Add", 1);
lst_Contains_method = il2cpp_class_get_method_from_name(list_klass, "Contains", 1);
lst_get_Count = reinterpret_cast<lst_get_Count_t>(lst_get_Count_method->methodPointer); lst_get_Count = reinterpret_cast<lst_get_Count_t>(lst_get_Count_method->methodPointer);
lst_get_Item = reinterpret_cast<lst_get_Item_t>(lst_get_Item_method->methodPointer); lst_get_Item = reinterpret_cast<lst_get_Item_t>(lst_get_Item_method->methodPointer);
lst_set_Item = reinterpret_cast<lst_set_Item_t>(lst_set_Item_method->methodPointer); lst_set_Item = reinterpret_cast<lst_set_Item_t>(lst_set_Item_method->methodPointer);
lst_Add = reinterpret_cast<lst_Add_t>(lst_Add_method->methodPointer); lst_Add = reinterpret_cast<lst_Add_t>(lst_Add_method->methodPointer);
lst_Contains = reinterpret_cast<lst_Contains_t>(lst_Contains_method->methodPointer);
} }
void Add(T value) { void Add(T value) {
lst_Add(lst, value, lst_Add_method); lst_Add(lst, value, lst_Add_method);
} }
bool Contains(T value) {
return lst_Contains(lst, value, lst_Contains_method);
}
T get_Item(int index) { T get_Item(int index) {
return lst_get_Item(lst, index, lst_get_Item_method); return lst_get_Item(lst, index, lst_get_Item_method);
} }
@ -401,16 +407,86 @@ namespace Il2cppUtils {
typedef void(*lst_Add_t)(void*, T, void* mtd); typedef void(*lst_Add_t)(void*, T, void* mtd);
typedef void(*lst_set_Item_t)(void*, int, T, void* mtd); typedef void(*lst_set_Item_t)(void*, int, T, void* mtd);
typedef int(*lst_get_Count_t)(void*, void* mtd); typedef int(*lst_get_Count_t)(void*, void* mtd);
typedef bool(*lst_Contains_t)(void*, T, void* mtd);
MethodInfo* lst_get_Item_method; MethodInfo* lst_get_Item_method;
MethodInfo* lst_Add_method; MethodInfo* lst_Add_method;
MethodInfo* lst_get_Count_method; MethodInfo* lst_get_Count_method;
MethodInfo* lst_set_Item_method; MethodInfo* lst_set_Item_method;
MethodInfo* lst_Contains_method;
lst_get_Item_t lst_get_Item; lst_get_Item_t lst_get_Item;
lst_set_Item_t lst_set_Item; lst_set_Item_t lst_set_Item;
lst_Add_t lst_Add; lst_Add_t lst_Add;
lst_get_Count_t lst_get_Count; lst_get_Count_t lst_get_Count;
lst_Contains_t lst_Contains;
};
template <typename KT = void*, typename VT = void*>
class CSDictEditor {
public:
// @param dict: Dictionary instance.
// @param dictTypeStr: Reflection type. eg: "System.Collections.Generic.Dictionary`2[System.Int32, System.Int32]"
CSDictEditor(void* dict, const char* dictTypeStr) {
dic_klass = Il2cppUtils::get_system_class_from_reflection_type_str(dictTypeStr);
initDict(dict);
}
CSDictEditor(void* dict) {
dic_klass = get_class_from_instance(dict);
initDict(dict);
}
CSDictEditor(void* dict, void* dicClass) {
dic_klass = dicClass;
initDict(dict);
}
void Add(KT key, VT value) {
dic_Add(dict, key, value, Add_method);
}
bool ContainsKey(KT key) {
return dic_containsKey(dict, key, ContainsKey_method);
}
VT get_Item(KT key) {
return dic_get_Item(dict, key, get_Item_method);
}
VT operator[] (KT key) {
return get_Item(key);
}
void* dict;
void* dic_klass;
private:
void initDict(void* dict) {
// dic_klass = dicClass;
this->dict = dict;
get_Item_method = il2cpp_class_get_method_from_name(dic_klass, "get_Item", 1);
Add_method = il2cpp_class_get_method_from_name(dic_klass, "Add", 2);
ContainsKey_method = il2cpp_class_get_method_from_name(dic_klass, "ContainsKey", 1);
dic_get_Item = (dic_get_Item_t)get_Item_method->methodPointer;
dic_Add = (dic_Add_t)Add_method->methodPointer;
dic_containsKey = (dic_containsKey_t)ContainsKey_method->methodPointer;
}
typedef VT(*dic_get_Item_t)(void*, KT, void* mtd);
typedef VT(*dic_Add_t)(void*, KT, VT, void* mtd);
typedef VT(*dic_containsKey_t)(void*, KT, void* mtd);
CSDictEditor();
MethodInfo* get_Item_method;
MethodInfo* Add_method;
MethodInfo* ContainsKey_method;
dic_get_Item_t dic_get_Item;
dic_Add_t dic_Add;
dic_containsKey_t dic_containsKey;
}; };
} }

View File

@ -17,7 +17,7 @@
#include "BaseDefine.h" #include "BaseDefine.h"
#include "string_parser/StringParser.hpp" #include "string_parser/StringParser.hpp"
#include "cpprest/details/http_helpers.h" // #include "cpprest/details/http_helpers.h"
namespace GakumasLocal::Local { namespace GakumasLocal::Local {

View File

@ -396,11 +396,11 @@ namespace GkmsGUILoop {
ImGui::Checkbox(ts("unlockAllLive"), &Config::unlockAllLive); ImGui::Checkbox(ts("unlockAllLive"), &Config::unlockAllLive);
ImGui::Checkbox(ts("unlockAllLiveCostume"), &Config::unlockAllLiveCostume); ImGui::Checkbox(ts("unlockAllLiveCostume"), &Config::unlockAllLiveCostume);
ImGui::Checkbox(ts("liveUseCustomeDress"), &Config::enableLiveCustomeDress); /*ImGui::Checkbox(ts("liveUseCustomeDress"), &Config::enableLiveCustomeDress);
if (Config::enableLiveCustomeDress) { if (Config::enableLiveCustomeDress) {
InputTextString(ts("live_costume_head_id"), &Config::liveCustomeHeadId); InputTextString(ts("live_costume_head_id"), &Config::liveCustomeHeadId);
InputTextString(ts("live_custome_dress_id"), &Config::liveCustomeCostumeId); InputTextString(ts("live_custome_dress_id"), &Config::liveCustomeCostumeId);
} }*/
ImGui::Unindent(indentWidth); ImGui::Unindent(indentWidth);
} }

View File

@ -11,7 +11,7 @@
#define LogMinVersion ANDROID_LOG_DEBUG #define LogMinVersion ANDROID_LOG_DEBUG
#define PLUGIN_VERSION "3.0.3" #define PLUGIN_VERSION "3.0.4"
#define ADD_HOOK(name, addr) \ #define ADD_HOOK(name, addr) \
name##_Addr = reinterpret_cast<name##_Type>(addr); \ name##_Addr = reinterpret_cast<name##_Type>(addr); \