parent
311312930b
commit
7305ad5cd7
|
|
@ -420,8 +420,8 @@ namespace GakumasLocal::HookMain {
|
|||
|
||||
|
||||
// 用于本地化 MasterDB
|
||||
DEFINE_HOOK(void, MessageExtensions_MergeFrom, (void* message, void* span, void* mtd)) {
|
||||
MessageExtensions_MergeFrom_Orig(message, span, mtd);
|
||||
DEFINE_HOOK(void, MessageExtensions_MergeFrom, (void* message, void* span, bool discardUnknownFields, void* registry, void* mtd)) {
|
||||
MessageExtensions_MergeFrom_Orig(message, span, discardUnknownFields, registry, mtd);
|
||||
if (message) {
|
||||
auto ret_klass = Il2cppUtils::get_class_from_instance(message);
|
||||
if (ret_klass) {
|
||||
|
|
@ -472,6 +472,250 @@ namespace GakumasLocal::HookMain {
|
|||
// return Il2cppString::New("[I18]" + ret->ToString());
|
||||
}
|
||||
|
||||
#pragma region UnlockLive
|
||||
enum class GetIdolIdType {
|
||||
MusicId,
|
||||
CostumeId,
|
||||
CostumeHeadId
|
||||
};
|
||||
|
||||
std::vector<std::string> GetIdolMusicIdAll(const std::string& charaNameId = "", GetIdolIdType getType = GetIdolIdType::MusicId) {
|
||||
// 传入例: fktn
|
||||
// System.Collections.Generic.List`1<valuetype [mscorlib]System.ValueTuple`2<class Campus.Common.Proto.Client.Master.IdolCardSkin, class Campus.Common.Proto.Client.Master.Music>>
|
||||
static auto get_IdolCardSkinMaster = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Master", "MasterManager", "get_IdolCardSkinMaster");
|
||||
static auto Master_GetAllWithSortByKey = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Master", "IdolCardSkinMaster", "GetAllWithSortByKey");
|
||||
static auto IdolCardSkin_get_Id = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "get_Id");
|
||||
static auto IdolCardSkin_get_IdolCardId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "get_IdolCardId");
|
||||
static auto IdolCardSkin_GetMusic = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "GetMusic");
|
||||
static auto IdolCardSkin_get_MusicId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "get_MusicId");
|
||||
static auto IdolCardSkin_get_CostumeId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "get_CostumeId");
|
||||
static auto IdolCardSkin_get_CostumeHeadId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "get_CostumeHeadId");
|
||||
static auto GetLiveMusics = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.OutGame",
|
||||
"PictureBookWindowPresenter", "GetLiveMusics");
|
||||
|
||||
auto idolCardSkinMaster = get_IdolCardSkinMaster->Invoke<void*>(nullptr); // IdolCardSkinMaster
|
||||
|
||||
std::vector<std::string> ret{};
|
||||
|
||||
if (!idolCardSkinMaster) {
|
||||
Log::ErrorFmt("get_IdolCardSkinMaster failed: %p", idolCardSkinMaster);
|
||||
return ret;
|
||||
}
|
||||
// List<IdolCardSkin>
|
||||
auto idolCardSkinList = Master_GetAllWithSortByKey->Invoke<Il2cppTypes::List<void*>*>(idolCardSkinMaster, 0x0, nullptr);
|
||||
|
||||
auto idolCardSkins = idolCardSkinList->ToArray()->ToVector();
|
||||
const auto checkStartCharaId = "i_card-" + charaNameId;
|
||||
// Log::DebugFmt("checkStartCharaId: %s", checkStartCharaId.c_str());
|
||||
|
||||
// origMusics->Clear();
|
||||
Il2cppJson::Method* idGetFunc = nullptr;
|
||||
switch (getType) {
|
||||
case GetIdolIdType::MusicId: idGetFunc = IdolCardSkin_get_MusicId;
|
||||
break;
|
||||
case GetIdolIdType::CostumeId: idGetFunc = IdolCardSkin_get_CostumeId;
|
||||
break;
|
||||
case GetIdolIdType::CostumeHeadId: idGetFunc = IdolCardSkin_get_CostumeHeadId;
|
||||
break;
|
||||
default:
|
||||
idGetFunc = IdolCardSkin_get_MusicId;
|
||||
}
|
||||
|
||||
for (auto i : idolCardSkins) {
|
||||
if (!i) continue;
|
||||
// auto charaId = IdolCardSkin_get_Id->Invoke<Il2cppString*>(i);
|
||||
auto targetId = idGetFunc->Invoke<Il2cppString*>(i);
|
||||
auto cardId = IdolCardSkin_get_IdolCardId->Invoke<Il2cppString*>(i)->ToString();
|
||||
auto music = IdolCardSkin_GetMusic->Invoke<void*>(i);
|
||||
|
||||
if (charaNameId.empty() || cardId.starts_with(checkStartCharaId)) {
|
||||
std::string musicIdStr = targetId->ToString();
|
||||
// Log::DebugFmt("Add cardId: %s, musicId: %s", cardId.c_str(), musicIdStr.c_str());
|
||||
if (std::find(ret.begin(), ret.end(), musicIdStr) == ret.end()) {
|
||||
ret.emplace_back(musicIdStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* AddIdsToUserDataCollectionFromMaster(void* origList, std::vector<std::string>& allIds,
|
||||
Il2cppJson::Method* get_CostumeId, Il2cppJson::Method* set_CostumeId, Il2cppJson::Method* Clone) {
|
||||
std::unordered_set<std::string> existIds{};
|
||||
Il2cppUtils::Tools::CSListEditor listEditor(origList);
|
||||
if (listEditor.get_Count() <= 0) {
|
||||
return origList;
|
||||
}
|
||||
|
||||
for (auto i : listEditor) {
|
||||
auto costumeId = get_CostumeId->Invoke<Il2cppString*>(i);
|
||||
if (!costumeId) continue;
|
||||
existIds.emplace(costumeId->ToString());
|
||||
}
|
||||
|
||||
for (auto& i : allIds) {
|
||||
if (i.empty()) continue;
|
||||
// Log::DebugFmt("Try add %s", i.c_str());
|
||||
if (existIds.contains(i)) continue;
|
||||
|
||||
auto userCostume = Clone->Invoke<void*>(listEditor.get_Item(0));
|
||||
set_CostumeId->Invoke<void>(userCostume, Il2cppString::New(i));
|
||||
listEditor.Add(userCostume);
|
||||
}
|
||||
return origList;
|
||||
}
|
||||
|
||||
DEFINE_HOOK(bool, UserIdolCardSkinCollection_Exists, (void* self, Il2cppString* id, void* mtd)) { // Live默认选择
|
||||
auto ret = UserIdolCardSkinCollection_Exists_Orig(self, id, mtd);
|
||||
// Log::DebugFmt("UserIdolCardSkinCollection_Exists: %s, ret: %d", id->ToString().c_str(), ret);
|
||||
if (!(Config::dbgMode && Config::unlockAllLive)) return ret;
|
||||
|
||||
if (id) {
|
||||
std::string idStr = id->ToString();
|
||||
if (idStr.starts_with("music") || idStr.starts_with("i_card-skin")) { // eg. music-all-kllj-006, i_card-skin-hski-3-002
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
if (Config::dbgMode && Config::unlockAllLive) {
|
||||
isUnlocked = true;
|
||||
isReleased = true;
|
||||
hasLiveSkin = true;
|
||||
}
|
||||
PictureBookLiveThumbnailView_SetDataAsync_Orig(self, liveData, characterId, isReleased, isUnlocked, isNew, hasLiveSkin, ct, mtd);
|
||||
}
|
||||
|
||||
DEFINE_HOOK(void*, UserCostumeCollection_FindBy, (void* self, void* predicate, void* mtd)) {
|
||||
// Log::DebugFmt("UserCostumeCollection_FindBy");
|
||||
auto ret = UserCostumeCollection_FindBy_Orig(self, predicate, mtd);
|
||||
if (!(Config::dbgMode && Config::unlockAllLiveCostume)) return ret;
|
||||
|
||||
auto this_klass = Il2cppUtils::get_class_from_instance(self);
|
||||
// auto predicate_klass = Il2cppUtils::get_class_from_instance(predicate); // System::Predicate`1
|
||||
// Log::DebugFmt("UserCostumeCollection_FindBy this: %s::%s, predicate: %s::%s", this_klass->namespaze, this_klass->name,
|
||||
// predicate_klass->namespaze, predicate_klass->name);
|
||||
|
||||
/*
|
||||
static auto UserCostumeCollection_klass = Il2cppUtils::GetClass("Assembly-CSharp.dll", "Campus.Common.User",
|
||||
"UserCostumeCollection");
|
||||
static auto UserCostumeCollection_GetAllList_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(
|
||||
UserCostumeCollection_klass->address, "GetAllList", 1);*/
|
||||
static auto UserCostumeCollection_GetAllList_mtd_pointer = Il2cppUtils::GetMethodPointerIl2cpp("Assembly-CSharp.dll", "Campus.Common.User",
|
||||
"UserCostumeCollection", "GetAllList", 1);
|
||||
static auto UserCostumeCollection_GetAllList = reinterpret_cast<void* (*)(void*, void*)>(UserCostumeCollection_GetAllList_mtd_pointer);
|
||||
|
||||
std::string thisKlassName(this_klass->name);
|
||||
// Campus.Common.User::UserCostumeHeadCollection || Campus.Common.User::UserCostumeCollection
|
||||
// 两个 class 的 GetAllList 均使用的父类 Qua.UserDataManagement.UserDataCollectionBase`2 的方法,地址一致
|
||||
if (thisKlassName == "UserCostumeHeadCollection") {
|
||||
static auto UserCostume_Clone = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostumeHead", "Clone");
|
||||
static auto UserCostume_get_CostumeHeadId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostumeHead", "get_CostumeHeadId");
|
||||
static auto UserCostume_set_CostumeHeadId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostumeHead", "set_CostumeHeadId");
|
||||
|
||||
// auto ret_klass = Il2cppUtils::get_class_from_instance(ret); // WhereEnumerableIterator
|
||||
auto origList = UserCostumeCollection_GetAllList(self, nullptr);
|
||||
|
||||
auto allIds = GetIdolMusicIdAll("", GetIdolIdType::CostumeHeadId);
|
||||
|
||||
// List<Campus.Common.Proto.Client.Transaction.UserCostumeHead>
|
||||
return AddIdsToUserDataCollectionFromMaster(origList, allIds, UserCostume_get_CostumeHeadId, UserCostume_set_CostumeHeadId, UserCostume_Clone);
|
||||
}
|
||||
else if (thisKlassName == "UserCostumeCollection") {
|
||||
// static auto UserCostume_klass = Il2cppUtils::GetClass("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostume");
|
||||
static auto UserCostume_Clone = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostume", "Clone");
|
||||
static auto UserCostume_get_CostumeId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostume", "get_CostumeId");
|
||||
static auto UserCostume_set_CostumeId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostume", "set_CostumeId");
|
||||
|
||||
// auto ret_klass = Il2cppUtils::get_class_from_instance(ret); // WhereEnumerableIterator
|
||||
auto origList = UserCostumeCollection_GetAllList(self, nullptr);
|
||||
|
||||
auto allIds = GetIdolMusicIdAll("", GetIdolIdType::CostumeId);
|
||||
|
||||
// List<Campus.Common.Proto.Client.Transaction.UserCostume>
|
||||
return AddIdsToUserDataCollectionFromMaster(origList, allIds, UserCostume_get_CostumeId, UserCostume_set_CostumeId, UserCostume_Clone);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* PictureBookWindowPresenter_instance = nullptr;
|
||||
std::string PictureBookWindowPresenter_charaId;
|
||||
DEFINE_HOOK(void*, PictureBookWindowPresenter_GetLiveMusics, (void* self, Il2cppString* charaId, void* mtd)) {
|
||||
// Log::DebugFmt("GetLiveMusics: %s", charaId->ToString().c_str());
|
||||
|
||||
if (Config::dbgMode && Config::unlockAllLive) {
|
||||
PictureBookWindowPresenter_instance = self;
|
||||
PictureBookWindowPresenter_charaId = charaId->ToString();
|
||||
|
||||
static auto PictureBookWindowPresenter_klass = Il2cppUtils::get_class_from_instance(self);
|
||||
static auto existsMusicIds_field = Il2cppJson::InvokeIl2cpp<Il2cppUtils::FieldInfo*>(
|
||||
"il2cpp_class_get_field_from_name",
|
||||
PictureBookWindowPresenter_klass,
|
||||
"_existsMusicIds"
|
||||
);
|
||||
/*
|
||||
static auto PictureBookWindowPresenter_klass = Il2cppUtils::GetClass("Assembly-CSharp.dll", "Campus.OutGame",
|
||||
"PictureBookWindowPresenter");
|
||||
static auto existsMusicIds_field = PictureBookWindowPresenter_klass->Get<UnityResolve::Field>("_existsMusicIds");*/
|
||||
// auto existsMusicIds = Il2cppUtils::ClassGetFieldValue<Il2cppTypes::List<Il2cppString*>*>(self, existsMusicIds_field);
|
||||
auto existsMusicIds = Il2cppUtils::ClassGetFieldValue<void*>(self, existsMusicIds_field);
|
||||
|
||||
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(
|
||||
"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 = reinterpret_cast<void (*)(void*, void*)>(List_String_ctor_mtd->methodPointer);
|
||||
|
||||
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 = Il2cppJson::InvokeIl2cpp<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) {
|
||||
// Log::DebugFmt("GetLiveMusics - Add: %s", i.c_str()); // eg. music-all-amao-001, music-char-hski-001
|
||||
//newListEditor.Add(Il2cppString::New(i));
|
||||
auto newList = Il2cppJson::InvokeIl2cpp<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, newDict);
|
||||
existsMusicIds = reinterpret_cast<decltype(existsMusicIds)>(newDict);
|
||||
// Log::DebugFmt("GetLiveMusics - set end: %d", fullIds.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return PictureBookWindowPresenter_GetLiveMusics_Orig(self, charaId, mtd);
|
||||
}
|
||||
|
||||
DEFINE_HOOK(void, PictureBookLiveSelectScreenModel_ctor, (void* self, void* transitionParam, Il2cppTypes::List<void*>* musics, void* mtd)) {
|
||||
// Log::DebugFmt("PictureBookLiveSelectScreenModel_ctor");
|
||||
|
||||
if (Config::dbgMode && Config::unlockAllLive) {
|
||||
static auto GetLiveMusics = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.OutGame",
|
||||
"PictureBookWindowPresenter", "GetLiveMusics");
|
||||
if (PictureBookWindowPresenter_instance && !PictureBookWindowPresenter_charaId.empty()) {
|
||||
auto fullMusics = GetLiveMusics->Invoke<Il2cppTypes::List<void*>*>(PictureBookWindowPresenter_instance,
|
||||
Il2cppString::New(PictureBookWindowPresenter_charaId));
|
||||
return PictureBookLiveSelectScreenModel_ctor_Orig(self, transitionParam, fullMusics, mtd);
|
||||
}
|
||||
}
|
||||
|
||||
return PictureBookLiveSelectScreenModel_ctor_Orig(self, transitionParam, musics, mtd);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
void StartInjectFunctions() {
|
||||
const auto hookInstaller = Plugin::GetInstance().GetHookInstaller();
|
||||
|
|
@ -529,7 +773,8 @@ namespace GakumasLocal::HookMain {
|
|||
ADD_HOOK(MessageExtensions_MergeFrom, Il2cppUtils::GetMethodPointer("Google.Protobuf.dll", "Google.Protobuf",
|
||||
"MessageExtensions", "MergeFrom",
|
||||
// {"Google.Protobuf.IMessage", "System.ReadOnlySpan<System.Byte>"}
|
||||
{"IMessage", "ReadOnlySpan`1[Byte]"}
|
||||
// {"IMessage", "ReadOnlySpan`1[Byte]"}
|
||||
{"IMessage", "ReadOnlySpan`1[Byte]", "Boolean", "ExtensionRegistry"}
|
||||
));
|
||||
|
||||
|
||||
|
|
@ -554,6 +799,24 @@ namespace GakumasLocal::HookMain {
|
|||
Il2cppUtils::GetMethodPointer("campus-submodule.Runtime.dll", "Campus.Common",
|
||||
"ScreenOrientationControllerBase", "InternalSetOrientationAsync", 3));
|
||||
|
||||
#pragma region UnlockLive
|
||||
ADD_HOOK(UserIdolCardSkinCollection_Exists, Il2cppUtils::GetMethodPointerIl2cpp("Assembly-CSharp.dll", "Campus.Common.User",
|
||||
"UserIdolCardSkinCollection", "Exists", 1));
|
||||
ADD_HOOK(PictureBookLiveThumbnailView_SetDataAsync,
|
||||
Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.OutGame.PictureBook",
|
||||
"PictureBookLiveThumbnailView", "SetDataAsync"));
|
||||
|
||||
ADD_HOOK(UserCostumeCollection_FindBy, Il2cppUtils::GetMethodPointerIl2cpp("Assembly-CSharp.dll", "Campus.Common.User",
|
||||
"UserCostumeCollection", "FindBy", 1));
|
||||
ADD_HOOK(PictureBookWindowPresenter_GetLiveMusics,
|
||||
Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.OutGame",
|
||||
"PictureBookWindowPresenter", "GetLiveMusics"));
|
||||
ADD_HOOK(PictureBookLiveSelectScreenModel_ctor,
|
||||
Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.OutGame",
|
||||
"PictureBookLiveSelectScreenModel", ".ctor"));
|
||||
|
||||
#pragma endregion
|
||||
|
||||
}
|
||||
// 77 2640 5000
|
||||
|
||||
|
|
|
|||
|
|
@ -120,6 +120,10 @@ namespace Il2cppUtils {
|
|||
uint8_t is_marshaled_from_native : 1;
|
||||
};
|
||||
|
||||
struct Il2CppAssembly {
|
||||
void* image;
|
||||
};
|
||||
|
||||
static Il2CppClassHead* get_class_from_instance(const void* instance) {
|
||||
#ifdef GKMS_IOS
|
||||
return static_cast<Il2CppClassHead*>(*static_cast<void* const*>(__builtin_assume_aligned(instance, alignof(void*))));
|
||||
|
|
@ -156,31 +160,33 @@ namespace Il2cppUtils {
|
|||
}
|
||||
|
||||
inline Il2CppClassHead* GetIl2cppClassFromName(const char* assemblyName, const char* nameSpaceName, const char* className) {
|
||||
Log::Info("GetMethodIl2cpp 0");
|
||||
// Log::Info("GetMethodIl2cpp 0");
|
||||
static auto domain = Il2cppJson::InvokeIl2cpp<void*>("il2cpp_domain_get");
|
||||
if (!domain)
|
||||
{
|
||||
Log::ErrorFmt("GetMethodIl2cpp error: failed to get domain.");
|
||||
return nullptr;
|
||||
}
|
||||
auto assembly = Il2cppJson::InvokeIl2cpp<void*>("il2cpp_domain_assembly_open", domain, assemblyName);
|
||||
|
||||
Il2cppJson::InvokeIl2cpp<void*>("il2cpp_thread_attach", domain);
|
||||
|
||||
auto assembly = Il2cppJson::InvokeIl2cpp<Il2CppAssembly*>("il2cpp_domain_assembly_open", domain, assemblyName);
|
||||
if (!assembly)
|
||||
{
|
||||
Log::ErrorFmt("GetMethodIl2cpp error: failed to get assembly: %s", assemblyName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// auto assembly = Il2cppJson::InvokeIl2cpp<void*>("il2cpp_domain_assembly_open+1", assemblyName);
|
||||
// UnityResolve::Invoke<void*>("il2cpp_thread_attach", domain);
|
||||
Log::Info("GetMethodIl2cpp 1");
|
||||
auto image = Il2cppJson::InvokeIl2cpp<void*>("il2cpp_assembly_get_image", assembly);
|
||||
// Log::Info("GetMethodIl2cpp 1");
|
||||
// auto image = Il2cppJson::InvokeIl2cpp<void*>("il2cpp_assembly_get_image", assembly);
|
||||
auto image = assembly->image;
|
||||
if (!image) {
|
||||
Log::ErrorFmt("GetMethodIl2cpp error: assembly %s not found.", assemblyName);
|
||||
return nullptr;
|
||||
}
|
||||
Log::InfoFmt("GetMethodIl2cpp 2, assembly: %p, image: %p, nameSpace: %s, class: %s", assembly, image, nameSpaceName, className);
|
||||
// Log::InfoFmt("GetMethodIl2cpp 2, assembly: %p, image: %p, nameSpace: %s, class: %s", assembly, image, nameSpaceName, className);
|
||||
auto klass = Il2cppJson::InvokeIl2cpp<Il2CppClassHead*>("il2cpp_class_from_name", image, nameSpaceName, className);
|
||||
Log::Info("GetMethodIl2cpp 3");
|
||||
// Log::Info("GetMethodIl2cpp 3");
|
||||
if (!klass) {
|
||||
Log::ErrorFmt("GetMethodIl2cpp error: Class %s::%s not found.", nameSpaceName, className);
|
||||
return nullptr;
|
||||
|
|
@ -192,11 +198,11 @@ namespace Il2cppUtils {
|
|||
const char* className, const char* methodName, const int argsCount) {
|
||||
auto klass = GetIl2cppClassFromName(assemblyName, nameSpaceName, className);
|
||||
if (!klass) return nullptr;
|
||||
Log::Info("GetMethodIl2cpp 4");
|
||||
// Log::Info("GetMethodIl2cpp 4");
|
||||
auto ret = Il2cppJson::InvokeIl2cpp<MethodInfo*>("il2cpp_class_get_method_from_name", klass, methodName, argsCount);
|
||||
Log::Info("GetMethodIl2cpp 5");
|
||||
// Log::Info("GetMethodIl2cpp 5");
|
||||
if (!ret) {
|
||||
Log::ErrorFmt("GetMethodIl2cpp error: method %s::%s.%s not found.", nameSpaceName, className, methodName);
|
||||
// Log::ErrorFmt("GetMethodIl2cpp error: method %s::%s.%s not found.", nameSpaceName, className, methodName);
|
||||
return nullptr;
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -251,6 +257,17 @@ namespace Il2cppUtils {
|
|||
return reinterpret_cast<void*>(method->address);
|
||||
}
|
||||
|
||||
inline void* GetMethodPointerIl2cpp(const char* assemblyName,
|
||||
const char* nameSpaceName,
|
||||
const char* className,
|
||||
const char* methodName,
|
||||
const int argsCount)
|
||||
{
|
||||
const auto method = GetMethodIl2cpp(assemblyName, nameSpaceName, className, methodName, argsCount);
|
||||
if (!method) return nullptr;
|
||||
return reinterpret_cast<void*>(method->methodPointer);
|
||||
}
|
||||
|
||||
template <typename RType>
|
||||
static auto ClassGetFieldValue(void* obj, FieldInfo* field) -> RType {
|
||||
return *reinterpret_cast<RType*>(reinterpret_cast<uintptr_t>(obj) + field->offset);
|
||||
|
|
@ -464,9 +481,9 @@ namespace Il2cppUtils {
|
|||
// dic_klass = dicClass;
|
||||
this->dict = dict;
|
||||
|
||||
get_Item_method = Il2cppJson::InvokeIl2cpp<MethodInfo*>("il2cpp_class_get_method_from_name", "get_Item", 1);
|
||||
Add_method = Il2cppJson::InvokeIl2cpp<MethodInfo*>("il2cpp_class_get_method_from_name", "Add", 2);
|
||||
ContainsKey_method = Il2cppJson::InvokeIl2cpp<MethodInfo*>("il2cpp_class_get_method_from_name", "ContainsKey", 1);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -29,8 +29,9 @@ inline std::map<std::string, uintptr_t>& GetIl2cppAddressMap() {
|
|||
{ "il2cpp_class_from_system_type", 0x9DCC028 },
|
||||
{ "il2cpp_init", 0x9D70D90 },
|
||||
{ "il2cpp_class_from_name", 0x9DCE4A4 },
|
||||
{ "il2cpp_assembly_get_image", 0x7C11B50 },
|
||||
// { "il2cpp_assembly_get_image", 0x7C11B50 },
|
||||
{ "il2cpp_domain_get", 0x9DB81AC },
|
||||
{ "il2cpp_thread_attach", 0x9DBB684 },
|
||||
{ "il2cpp_domain_assembly_open", 0x9D70EE4 },
|
||||
{ "il2cpp_domain_assembly_open+1", 0x9DA374C },
|
||||
{ "il2cpp_resolve_icall", 0x9D71304 },
|
||||
|
|
@ -42,7 +43,6 @@ inline std::map<std::string, uintptr_t>& GetIl2cppAddressMap() {
|
|||
// il2cpp_class_get_type
|
||||
// il2cpp_field_static_set_value
|
||||
// il2cpp_runtime_invoke
|
||||
// il2cpp_thread_attach
|
||||
// il2cpp_domain_get_assemblies
|
||||
// il2cpp_image_get_filename
|
||||
// il2cpp_image_get_name
|
||||
|
|
@ -65,6 +65,10 @@ auto InvokeIl2cpp(const std::string& name, Args... args) -> Return {
|
|||
// GakumasLocal::Log::InfoFmt("InvokeIl2cpp: %s", name.c_str());
|
||||
return InvokeAddress<Return>(GetUnityBaseAddress() + it->second, args...);
|
||||
}
|
||||
else
|
||||
{
|
||||
GakumasLocal::Log::ErrorFmt("Il2cpp Method: %s not found!", name.c_str());
|
||||
}
|
||||
// GakumasLocal::Log::InfoFmt("InvokeIl2cpp failed: %s", name.c_str());
|
||||
|
||||
// return nullptr;
|
||||
|
|
|
|||
|
|
@ -161,4 +161,75 @@ namespace Il2cppTypes
|
|||
return UnityResolve::Invoke<Array*, void*, void*, std::uintptr_t>("mono_array_new", pDomain, kalss->address, size);
|
||||
}*/
|
||||
};
|
||||
|
||||
|
||||
template <typename Type>
|
||||
struct List : Il2CppObject {
|
||||
Array<Type>* pList;
|
||||
int size{};
|
||||
int version{};
|
||||
void* syncRoot{};
|
||||
|
||||
auto ToArray() -> Array<Type>* { return pList; }
|
||||
|
||||
/*
|
||||
static auto New(const Class* kalss, const std::uintptr_t size) -> List* {
|
||||
auto pList = new List<Type>();
|
||||
pList->pList = Array<Type>::New(kalss, size);
|
||||
pList->size = size;
|
||||
}*/
|
||||
|
||||
auto operator[](const unsigned int m_uIndex) -> Type& { return pList->At(m_uIndex); }
|
||||
/*
|
||||
auto Add(Type pDate) -> void {
|
||||
if (!this) return;
|
||||
static Method* method;
|
||||
if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get<Method>("Add");
|
||||
if (method) return method->Invoke<void>(this, pDate);
|
||||
}
|
||||
|
||||
auto Remove(Type pDate) -> bool {
|
||||
if (!this) return false;
|
||||
static Method* method;
|
||||
if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get<Method>("Remove");
|
||||
if (method) return method->Invoke<bool>(this, pDate);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto RemoveAt(int index) -> void {
|
||||
if (!this) return;
|
||||
static Method* method;
|
||||
if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get<Method>("RemoveAt");
|
||||
if (method) return method->Invoke<void>(this, index);
|
||||
}
|
||||
|
||||
auto ForEach(void(*action)(Type pDate)) -> void {
|
||||
if (!this) return;
|
||||
static Method* method;
|
||||
if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get<Method>("ForEach");
|
||||
if (method) return method->Invoke<void>(this, action);
|
||||
}
|
||||
|
||||
auto GetRange(int index, int count) -> List* {
|
||||
if (!this) return {};
|
||||
static Method* method;
|
||||
if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get<Method>("GetRange");
|
||||
if (method) return method->Invoke<List*>(this, index, count);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto Clear() -> void {
|
||||
if (!this) return;
|
||||
static Method* method;
|
||||
if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get<Method>("Clear");
|
||||
if (method) return method->Invoke<void>(this);
|
||||
}
|
||||
|
||||
auto Sort(int (*comparison)(Type* pX, Type* pY)) -> void {
|
||||
if (!this) return;
|
||||
static Method* method;
|
||||
if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get<Method>("Sort", { "*" });
|
||||
if (method) return method->Invoke<void>(this, comparison);
|
||||
}*/
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue