diff --git a/lib/YaeAchievementLib.vcxproj b/lib/YaeAchievementLib.vcxproj
index 9f48be0..2533cdf 100644
--- a/lib/YaeAchievementLib.vcxproj
+++ b/lib/YaeAchievementLib.vcxproj
@@ -110,12 +110,11 @@
-
+
-
diff --git a/lib/src/dllmain.cpp b/lib/src/dllmain.cpp
index 5af644c..495fc36 100644
--- a/lib/src/dllmain.cpp
+++ b/lib/src/dllmain.cpp
@@ -1,78 +1,46 @@
-#include "pch.h"
+// ReSharper disable CppCStyleCast
+// ReSharper disable CppInconsistentNaming
+// ReSharper disable CppClangTidyModernizeUseStdPrint
+// ReSharper disable CppClangTidyClangDiagnosticCastAlign
+// ReSharper disable CppClangTidyHicppMultiwayPathsCovered
+// ReSharper disable CppDefaultCaseNotHandledInSwitchStatement
+// ReSharper disable CppClangTidyClangDiagnosticCastFunctionTypeStrict
+
+#include "pch.h"
#include "util.h"
#include "il2cpp-init.h"
-using Genshin::ByteArray, Genshin::ClientKcpEvent, Genshin::KcpPacket, Genshin::KcpEventType;
-using std::to_string;
+using Genshin::ByteArray;
HWND unityWnd = nullptr;
HANDLE hPipe = nullptr;
-// Allow Protocol: GetPlayerTokenRsp, PlayerLoginRsp, AchievementAllDataNotify, PingRsp
-std::set PacketWhitelist = { 1574, 1548, 29462, 2794 };
-
-bool OnPacket(KcpPacket* pkt) {
- if (pkt->data == nullptr) return true;
- auto len = pkt->length;
- auto data = (ByteArray*)new BYTE[len + 32];
- data->max_length = len;
- memcpy(data->vector, pkt->data, len);
- Genshin::XorEncrypt(&data, len, nullptr);
- if (ReadMapped(data->vector, 0) != 0x4567) {
- delete[] data;
- return true;
- }
- if (!PacketWhitelist.contains(ReadMapped(data->vector, 2))) {
- //ifdef _DEBUG
- printf("Blocked cmdid: %d\n", ReadMapped(data->vector, 2));
- //endif
- delete[] data;
- return false;
- }
- printf("Passed cmdid: %d\n", ReadMapped(data->vector, 2));
- if (ReadMapped(data->vector, 2) == 29462) {
- const auto headLength = ReadMapped(data->vector, 4);
- const auto dataLength = ReadMapped(data->vector, 6);
- const auto cStr = base64_encode(data->vector + 10 + headLength, dataLength) + "\n";
- WriteFile(hPipe, cStr.c_str(), cStr.length(), nullptr, nullptr);
- CloseHandle(hPipe);
- auto manager = Genshin::GetSingletonInstance(Genshin::GetSingletonManager(), il2cpp_string_new("GameManager"));
- Genshin::ForceQuit(manager);
- }
- delete[] data;
- return true;
-}
-
std::string checksum;
namespace Hook {
- void SetVersion(void* obj, Il2CppString* value, void* method) {
- const auto version = ToString(value);
- value = string_new(version + " YaeAchievement");
- CALL_ORIGIN(SetVersion, obj, value, method);
- }
-
- bool KcpRecv(void* client, ClientKcpEvent* evt, void* method) {
- const auto result = CALL_ORIGIN(KcpRecv, client, evt, method);
- if (result == 0 || evt->fields.type != KcpEventType::EventRecvMsg) {
- return result;
+ ByteArray* UnityEngine_RecordUserData(const INT type) {
+ if (type == 0) {
+ const auto arr = new ByteArray {};
+ const auto len = checksum.length();
+ arr->max_length = len;
+ memcpy(&arr->vector[0], checksum.data(), len);
+ return arr;
}
- return OnPacket(evt->fields.packet) ? result : false;
- }
-
- ByteArray* UnityEngine_RecordUserData(INT type) {
return new ByteArray {};
}
- VOID SetChecksum(LPVOID obj, Il2CppString* value) {
- CALL_ORIGIN(SetChecksum, obj, il2cpp_string_new(checksum.c_str()));
- }
-
- VOID RequestLogin(LPVOID obj, LPVOID token, UINT32 uid) {
- HookManager::install(Genshin::SetChecksum, SetChecksum);
- CALL_ORIGIN(RequestLogin, obj, token, uid);
- HookManager::detach(SetChecksum);
+ void OnAchievementAllDataNotify(LPVOID obj, const LPVOID ntf) {
+ const auto cos = Genshin::il2cpp_object_new(*Genshin::CodedOutputStream__TypeInfo);
+ const auto len = Genshin::CalculateSize(ntf);
+ const auto buf = (ByteArray*) new uint8_t[0x20 + len] {};
+ buf->max_length = len;
+ Genshin::CodedOutputStreamInit(cos, buf, 0, len);
+ Genshin::ProtoWriteTo(ntf, cos);
+ const auto str = base64_encode(buf->vector, len) + "\n";
+ WriteFile(hPipe, str.c_str(), (DWORD) str.length(), nullptr, nullptr);
+ CloseHandle(hPipe);
+ ExitProcess(0);
}
}
@@ -89,9 +57,7 @@ void Run(HMODULE* phModule) {
const auto result = Genshin::RecordUserData(i);
checksum += string(reinterpret_cast(&result->vector[0]), result->max_length);
}
- HookManager::install(Genshin::KcpRecv, Hook::KcpRecv);
- HookManager::install(Genshin::SetVersion, Hook::SetVersion);
- HookManager::install(Genshin::RequestLogin, Hook::RequestLogin);
+ HookManager::install(Genshin::OnAchievementAllDataNotify, Hook::OnAchievementAllDataNotify);
HookManager::install(Genshin::UnityEngine_RecordUserData, Hook::UnityEngine_RecordUserData);
hPipe = CreateFile(R"(\\.\pipe\YaeAchievementPipe)", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
if (hPipe == INVALID_HANDLE_VALUE) {
diff --git a/lib/src/il2cpp-api-functions.h b/lib/src/il2cpp-api-functions.h
deleted file mode 100644
index b8a9c75..0000000
--- a/lib/src/il2cpp-api-functions.h
+++ /dev/null
@@ -1 +0,0 @@
-DO_API(0x4243d0, 0x420bf0, Il2CppString*, il2cpp_string_new, (const char* str));
diff --git a/lib/src/il2cpp-appdata.h b/lib/src/il2cpp-appdata.h
index 485b7e8..546829a 100644
--- a/lib/src/il2cpp-appdata.h
+++ b/lib/src/il2cpp-appdata.h
@@ -1,20 +1,19 @@
+// ReSharper disable CppClangTidyBugproneMacroParentheses
+
#pragma once
#include "il2cpp-types.h"
-// IL2CPP APIs
-#define DO_API(ca, oa, r, n, p) extern r (*n) p
-#include "il2cpp-api-functions.h"
-#undef DO_API
-
// Application-specific functions
#define DO_APP_FUNC(ca, oa, r, n, p) extern r (*n) p
+#define DO_UNI_FUNC(ca, oa, r, n, p) extern r (*n) p
namespace Genshin {
#include "il2cpp-functions.h"
}
+#undef DO_UNI_FUNC
#undef DO_APP_FUNC
-#define DO_UNI_FUNC(ca, oa, r, n, p) extern r (*n) p
+#define DO_TYPEDEF(ca, oa, n) extern n##__Class **n##__TypeInfo
namespace Genshin {
-#include "il2cpp-unity-functions.h"
+#include "il2cpp-types-ptr.h"
}
-#undef DO_UNI_FUNC
+#undef DO_TYPEDEF
\ No newline at end of file
diff --git a/lib/src/il2cpp-functions.h b/lib/src/il2cpp-functions.h
index 4ba6d1e..8455bf9 100644
--- a/lib/src/il2cpp-functions.h
+++ b/lib/src/il2cpp-functions.h
@@ -2,20 +2,16 @@ using namespace Genshin;
// DO_APP_FUNC(CN_OFFSET, OS_OFFSET, RETURN, FUNC_NAME, (ARGS...));
-DO_APP_FUNC(0x1929870, 0x1922c30, void, SetVersion, (void* obj, Il2CppString* value, void* method));
+DO_APP_FUNC(0x4F1EF0, 0x545600, LPVOID, il2cpp_object_new, (LPVOID t));
-DO_APP_FUNC(0x6e7d020, 0x6e38a10, ByteArray*, RecordUserData, (int32_t nType));
+DO_APP_FUNC(0x052818B0, 0x0529E520, ByteArray*, RecordUserData, (int32_t nType));
-DO_APP_FUNC(0x2b13f40, 0x2b09ce0, void, XorEncrypt, (ByteArray** data, int length, void* method));
+DO_APP_FUNC(0x05DCBE60, 0x05DF2F40, void, OnAchievementAllDataNotify, (LPVOID obj, LPVOID ntf));
-DO_APP_FUNC(0x2d79560, 0x2d6e6f0, bool, KcpRecv, (void* client, ClientKcpEvent* evt, void* method));
+DO_APP_FUNC(0x043EC0B0, 0x043FA380, int, CalculateSize, (LPVOID obj));
-DO_APP_FUNC(0x20004f0, 0x1ff8530, VOID, RequestLogin, (LPVOID obj, LPVOID token, UINT uid));
+DO_APP_FUNC(0x043EBFF0, 0x043FA2C0, void, ProtoWriteTo, (LPVOID obj, LPVOID output));
-DO_APP_FUNC(0x130ead0, 0x1b90950, VOID, SetChecksum, (LPVOID obj, Il2CppString* value));
+DO_APP_FUNC(0x06F08220, 0x06F3F280, void, CodedOutputStreamInit, (LPVOID obj, LPVOID buffer, int offset, int length));
-DO_APP_FUNC(0x2266e40, 0x225eb50, VOID, ForceQuit, (LPVOID obj));
-
-DO_APP_FUNC(0x60af410, 0x60735f0, LPVOID, GetSingletonManager, ());
-
-DO_APP_FUNC(0x60af140, 0x6073320, LPVOID, GetSingletonInstance, (LPVOID obj, Il2CppString* value));
+DO_UNI_FUNC(0x105970, 0x105970, ByteArray*, UnityEngine_RecordUserData, (int32_t nType));
diff --git a/lib/src/il2cpp-init.cpp b/lib/src/il2cpp-init.cpp
index ec7c369..bedc197 100644
--- a/lib/src/il2cpp-init.cpp
+++ b/lib/src/il2cpp-init.cpp
@@ -1,22 +1,22 @@
+// ReSharper disable CppClangTidyBugproneMacroParentheses
+
#include "pch.h"
#include "il2cpp-init.h"
-#define DO_API(ca, oa, r, n, p) r (*n) p
-#include "il2cpp-api-functions.h"
-#undef DO_API
-
#define DO_APP_FUNC(ca, oa, r, n, p) r (*n) p
+#define DO_UNI_FUNC(ca, oa, r, n, p) r (*n) p
namespace Genshin {
#include "il2cpp-functions.h"
}
+#undef DO_UNI_FUNC
#undef DO_APP_FUNC
-#define DO_UNI_FUNC(ca, oa, r, n, p) r (*n) p
+#define DO_TYPEDEF(ca, oa, n) n##__Class **n##__TypeInfo
namespace Genshin {
-#include "il2cpp-unity-functions.h"
+#include "il2cpp-types-ptr.h"
}
-#undef DO_UNI_FUNC
+#undef DO_TYPEDEF
using std::string;
@@ -27,13 +27,12 @@ void InitIL2CPP() {
auto hBase = GetModuleHandle("UserAssembly.dll");
auto bAddr = (UINT64)hBase;
auto cAddr = (UINT64)GetModuleHandle("UnityPlayer.dll");
- #define DO_API(ca, oa, r, n, p) n = (r (*) p)(bAddr + (isCN ? ca : oa))
- #include "il2cpp-api-functions.h"
- #undef DO_API
#define DO_APP_FUNC(ca, oa, r, n, p) n = (r (*) p)(bAddr + (isCN ? ca : oa))
- #include "il2cpp-functions.h"
- #undef DO_APP_FUNC
#define DO_UNI_FUNC(ca, oa, r, n, p) n = (r (*) p)(cAddr + (isCN ? ca : oa))
- #include "il2cpp-unity-functions.h"
+ #include "il2cpp-functions.h"
#undef DO_UNI_FUNC
+ #undef DO_APP_FUNC
+ #define DO_TYPEDEF(ca, oa, n) n##__TypeInfo = (n##__Class **)(bAddr + (isCN ? ca : oa))
+ #include "il2cpp-types-ptr.h"
+ #undef DO_TYPEDEF
}
diff --git a/lib/src/il2cpp-types-ptr.h b/lib/src/il2cpp-types-ptr.h
new file mode 100644
index 0000000..499766f
--- /dev/null
+++ b/lib/src/il2cpp-types-ptr.h
@@ -0,0 +1,2 @@
+// LFGDACFKABF
+DO_TYPEDEF(0x2965BA0, 0, CodedOutputStream);
diff --git a/lib/src/il2cpp-types.h b/lib/src/il2cpp-types.h
index 81525b3..dd428c4 100644
--- a/lib/src/il2cpp-types.h
+++ b/lib/src/il2cpp-types.h
@@ -1,3 +1,6 @@
+// ReSharper disable CppClangTidyClangDiagnosticReservedIdentifier
+// ReSharper disable CppClangTidyBugproneReservedIdentifier
+
#pragma once
#pragma region IL2CPPInternalTypes
@@ -36,30 +39,7 @@ namespace Genshin {
il2cpp_array_size_t max_length;
uint8_t vector[32];
};
-
- struct KcpPacket {
- BYTE* data;
- UINT32 length;
+
+ struct CodedOutputStream__Class {
};
-
- enum class KcpEventType : int {
- EventNotSet = -1,
- EventConnect = 0,
- EventConnectFailed = 1,
- EventDisconnect = 2,
- EventRecvMsg = 3,
- EventCount = 4,
- };
-
- struct KcpEvent_Fields {
- KcpEventType type;
- UINT32 token;
- UINT32 data;
- KcpPacket* packet;
- };
-
- struct ClientKcpEvent {
- KcpEvent_Fields fields;
- };
-
}
diff --git a/lib/src/il2cpp-unity-functions.h b/lib/src/il2cpp-unity-functions.h
deleted file mode 100644
index 76b5796..0000000
--- a/lib/src/il2cpp-unity-functions.h
+++ /dev/null
@@ -1,3 +0,0 @@
-using namespace Genshin;
-
-DO_UNI_FUNC(0x105550, 0x105550, ByteArray*, UnityEngine_RecordUserData, (int32_t nType));
diff --git a/lib/src/util.h b/lib/src/util.h
index 7787f67..9a83192 100644
--- a/lib/src/util.h
+++ b/lib/src/util.h
@@ -8,9 +8,6 @@ HWND FindMainWindowByPID(DWORD pid);
string ToString(Il2CppString* str, UINT codePage = CP_ACP);
std::string base64_encode(BYTE const* buf, unsigned int bufLen);
-#define cstring_new(str) il2cpp_string_new(str)
-#define string_new(str) cstring_new((str).c_str())
-
#define ErrorDialogT(title, msg) MessageBox(unityWnd, msg, title, MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
#define ErrorDialog(msg) ErrorDialogT("YaeAchievement", msg)
#define Win32ErrorDialog(code) ErrorDialogT("YaeAchievement", ("CRITICAL ERROR!\nError code: " + std::to_string(GetLastError()) + "-"#code"\n\nPlease take the screenshot and contact developer by GitHub Issue to solve this problem\nNOT MIHOYO/COGNOSPHERE CUSTOMER SERVICE!").c_str())
diff --git a/res/proto/AchievementAllDataNotify.proto b/res/proto/AchievementAllDataNotify.proto
index beefd50..71a621b 100644
--- a/res/proto/AchievementAllDataNotify.proto
+++ b/res/proto/AchievementAllDataNotify.proto
@@ -10,12 +10,12 @@ message Achievement {
REWARD_TAKEN = 3;
}
uint32 timestamp = 11;
- uint32 current = 12;
+ uint32 current = 15;
uint32 total = 3;
- uint32 id = 15;
- Status status = 7;
+ uint32 id = 14;
+ Status status = 8;
}
message AchievementAllDataNotify {
- repeated Achievement list = 8;
+ repeated Achievement list = 9;
}
diff --git a/src/GlobalVars.cs b/src/GlobalVars.cs
index 178d222..015c1f1 100644
--- a/src/GlobalVars.cs
+++ b/src/GlobalVars.cs
@@ -20,8 +20,8 @@ public static class GlobalVars {
public static readonly string CachePath = Path.Combine(DataPath, "cache");
public static readonly string LibFilePath = Path.Combine(DataPath, "YaeAchievement.dll");
- public const uint AppVersionCode = 42;
- public const string AppVersionName = "3.2";
+ public const uint AppVersionCode = 43;
+ public const string AppVersionName = "3.3";
public const string PipeName = "YaeAchievementPipe";
public const string BucketHost = "https://cn-cd-1259389942.file.myqcloud.com";