24 Commits
2.9.0 ... 3.2.0

Author SHA1 Message Date
HolographicHat
feb7ac44da 4.2 2023-11-09 21:39:05 +08:00
HolographicHat
3924129560 Merge pull request #74 from Lightczx/master
Disable marshalling
2023-10-30 14:04:24 +08:00
Lightczx
4f7f0cdfd2 disable marshalling 2023-10-30 13:51:01 +08:00
HolographicHat
cf0753c676 Merge pull request #73 from BTMuli/master
🐛 修复 TeyvatGuide 链接错误
2023-10-16 13:42:22 +08:00
BTMuli
0b895d47ca 🐛 修复 TeyvatGuide 链接错误 2023-10-16 12:39:32 +08:00
HolographicHat
78d2722e20 Merge pull request #72 from BTMuli/master
更新文档
2023-10-15 01:16:19 +08:00
BTMuli
385c673323 🚨 revert,删除多余空格 2023-10-15 00:31:18 +08:00
BTMuli
50beb2cce7 🚨 修复 CI 报错 2023-10-15 00:18:39 +08:00
BTMuli
324a4153e0 📝 删除混入其中的表格文件 2023-10-14 23:56:24 +08:00
BTMuli
3de459aceb 📝 更新部分信息 2023-10-14 23:54:49 +08:00
BTMuli
295bb89177 📝 更新导出说明 2023-10-14 23:50:31 +08:00
HolographicHat
baaf4e8227 rollback 2023-10-13 21:22:54 +08:00
HolographicHat
f41fe6fb12 4.1
* #71
2023-09-28 18:48:00 +08:00
HolographicHat
78bda3f49c Merge pull request #70 from BTMuli/master
#67
2023-09-23 00:00:30 +08:00
BTMuli
a10dc22461 🎨 修正检测方式 2023-09-22 23:39:37 +08:00
HolographicHat
74dda750ef Merge pull request #69 from Masterain98/master
Update GitLab CI configuration
2023-09-22 21:15:21 +08:00
Masterain
099270ad29 Update .gitlab-ci.yml 2023-09-21 23:42:47 -07:00
Masterain
fe5b2c0c12 Update .gitlab-ci.yml 2023-09-21 23:35:17 -07:00
HolographicHat
ed5d99745c Merge pull request #68 from Masterain98/master
Create GitLab CI Config File
2023-09-21 23:46:58 +08:00
Masterain
7175cd7427 Create .gitlab-ci.yml 2023-09-21 00:01:13 -07:00
HolographicHat
73747bcce5 #67 2023-09-19 22:28:58 +08:00
HolographicHat
b12c3209d7 fix ci 2023-08-27 11:39:40 +08:00
HolographicHat
5805070627 4.0.1 (fix #64) 2023-08-24 00:16:44 +08:00
HolographicHat
811daba164 4.0 2023-08-16 20:00:06 +08:00
23 changed files with 277 additions and 2444 deletions

View File

@@ -20,7 +20,7 @@ jobs:
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
run: dotnet build -c Release --no-restore
- name: Publish
run: dotnet publish --property:OutputPath=.\publish\
- name: Upload artifact

64
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,64 @@
stages:
- test
- build
- release
Test:
stage: test
image: mcr.microsoft.com/windows/server
tags:
- windows
script:
- dotnet restore
- dotnet build -c Release --no-restore
- dotnet publish --property:OutputPath=.\publish\
- Move-Item -Path .\publish\publish\*.exe -Destination ..\ -Force
Build:
stage: build
only:
- tags
tags:
- windows
needs:
- job: Test
script:
- echo "This is build stage."
- Move-Item -Path ..\YaeAchievement.exe .\ -Force
after_script:
- echo "Current Job ID is $CI_JOB_ID"
- echo "THIS_JOB_ID=$CI_JOB_ID" >> build.env
artifacts:
paths:
- .\*.exe
expire_in: 90 days
reports:
dotenv: build.env
release:
stage: release
image: registry.gitlab.com/gitlab-org/release-cli:latest
only:
- tags
needs:
- job: Build
artifacts: true
variables:
TAG: '$CI_COMMIT_TAG'
script:
- echo "Create Release $TAG"
- echo "$THIS_JOB_ID"
release:
name: '$TAG'
tag_name: '$TAG'
ref: '$TAG'
description: 'Release $TAG by CI'
assets:
links:
- name: "YaeAchievement.exe"
url: "https://$CI_SERVER_SHELL_SSH_HOST/$CI_PROJECT_PATH/-/jobs/$THIS_JOB_ID/artifacts/raw/YaeAchievement.exe?inline=false"
link_type: package
- name: ".NET 7.0 Desktop Runtime"
url: "https://dotnet.microsoft.com/zh-cn/download/dotnet/thank-you/runtime-desktop-7.0.11-windows-x64-installer"
link_type: other

View File

@@ -9,9 +9,22 @@
- 支持导出所有类别的成就
- 支持官服,渠道服与国际服
- 支持导出至[椰羊](https://cocogoat.work/achievement)、[Snap·HuTao](https://github.com/DGP-Studio/Snap.HuTao)、[Paimon.moe](https://paimon.moe/achievement/)、[Seelie.me](https://seelie.me/achievements)、[寻空](https://github.com/xunkong/xunkong)和表格文件(csv)
- 没有窗口大小、游戏语言等要求
## 导出支持
> 按照数字键选择导出方式,<kbd>0</kbd> 为默认导出方式
0. [椰羊](https://cocogoat.work/achievement)
1. [胡桃工具箱](https://github.com/DGP-Studio/Snap.HuTao)
2. [Paimon.moe](https://paimon.moe/achievement/)
3. [Seelie.me](https://seelie.me/achievements)
4. 表格文件 `.csv`
5. [寻空](https://github.com/xunkong/xunkong)
6. [原魔工具箱](https://apps.apple.com/app/id1663989619)
7. [TeyvatGuide](https://github.com/BTMuli/TeyvatGuide)
8. [UIAF](https://uigf.org/standards/UIAF.html) JSON 文件
## 使用说明
→ [Tutorial.md](Tutorial.md)

View File

@@ -13,9 +13,22 @@
- Support for exporting all categories of achievements
- Supports all versions of Genshin Impact
- Support for exporting to [Cocogoat](https://cocogoat.work/achievement), [Snap·HuTao](https://github.com/DGP-Studio/Snap.HuTao), [Paimon.moe](https://paimon.moe/achievement/), [Seelie.me](https://seelie.me/achievements)、[XunKong](https://github.com/xunkong/xunkong) and form files (csv)
- There are no requirements for window size, game language, etc.
## Export support
> Select the export method according to the number keys, <kbd>0</kbd> is the default export method
0. [Cocogoat](https://cocogoat.work/achievement)
1. [Snap HuTao](https://github.com/DGP-Studio/Snap.HuTao)
2. [Paimon.moe](https://paimon.moe/achievement/)
3. [Seelie.me](https://seelie.me/achievements)
4. Form File `.csv`
5. [XunKong](https://github.com/xunkong/xunkong)
6. [YuanmoTools](https://apps.apple.com/app/id1663989619)
7. [TeyvatGuide](https://github.com/BTMuli/TeyvatGuide)
8. [UIAF](https://uigf.org/standards/UIAF.html) JSON file
## Instructions for Use:
→ [Tutorial_EN.md](Tutorial_EN.md)

View File

@@ -71,11 +71,11 @@
### 各种工具的介绍烦请移步至各工具的官方页面进行查看(下方序号对应导出序号)
0. [椰羊](https://cocogoat.work/achievement)
1. [Snap·HuTao](https://github.com/DGP-Studio/Snap.HuTao)
1. [胡桃工具箱](https://github.com/DGP-Studio/Snap.HuTao)
2. [Paimon.moe](https://paimon.moe/achievement/)
3. [Seelie.me](https://seelie.me/achievements)
4. [寻空](https://github.com/xunkong/xunkong)
4. ~~表格文件 `.csv`~~
5. [寻空](https://github.com/xunkong/xunkong)
6. [原魔工具箱](https://apps.apple.com/app/id1663989619)
7. [TeyvatGuide](https://github.com/BTMuli/TeyvatGuide)
8. [UIAF](https://uigf.org/standards/UIAF.html) JSON 文件

View File

@@ -65,9 +65,12 @@ At this time, you can select the Achievements in the left column to view the imp
### For the introduction of different tools, please visit the official page of each tool to see:
1. [Snap·HuTao](https://github.com/DGP-Studio/Snap.HuTao)
0. [Cocogoat](https://cocogoat.work/achievement)
1. [Snap HuTao](https://github.com/DGP-Studio/Snap.HuTao)
2. [Paimon.moe](https://paimon.moe/achievement/)
3. [Seelie.me](https://seelie.me/achievements)
4. ~~Form File `.csv`~~
5. [XunKong](https://github.com/xunkong/xunkong)
6. [YuanmoTools](https://apps.apple.com/app/id1663989619)
7. [Teyvat Guide](https://github.com/BTMuli/TeyvatGuide)
8. [UIAF](https://uigf.org/standards/UIAF.html) JSON file

View File

@@ -8,8 +8,8 @@ using std::to_string;
HWND unityWnd = nullptr;
HANDLE hPipe = nullptr;
// Allow Protocol: GetPlayerToken, PlayerLogin, AchievementAllDataNotify, Ping, PlayerForceExit
std::set<UINT16> PacketWhitelist = { 6929, 7187, 4356, 6011, 1268, 24845, 24404, 29313 };
// Allow Protocol: GetPlayerTokenRsp, PlayerLoginRsp, AchievementAllDataNotify, PingRsp
std::set<UINT16> PacketWhitelist = { 1574, 1548, 29462, 2794 };
bool OnPacket(KcpPacket* pkt) {
if (pkt->data == nullptr) return true;
@@ -30,11 +30,10 @@ bool OnPacket(KcpPacket* pkt) {
return false;
}
printf("Passed cmdid: %d\n", ReadMapped<UINT16>(data->vector, 2));
if (ReadMapped<UINT16>(data->vector, 2) == 1268) {
auto headLength = ReadMapped<UINT16>(data->vector, 4);
auto dataLength = ReadMapped<UINT32>(data->vector, 6);
auto iStr = Genshin::ToBase64String(data, 10 + headLength, dataLength, nullptr);
auto cStr = ToString(iStr) + "\n";
if (ReadMapped<UINT16>(data->vector, 2) == 29462) {
const auto headLength = ReadMapped<UINT16>(data->vector, 4);
const auto dataLength = ReadMapped<UINT32>(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"));
@@ -48,18 +47,14 @@ std::string checksum;
namespace Hook {
int KcpSend(void* client, KcpPacket* pkt, void* method) {
return OnPacket(pkt) ? CALL_ORIGIN(KcpSend, client, pkt, method) : 0;
}
void SetVersion(void* obj, Il2CppString* value, void* method) {
auto version = ToString(value);
const auto version = ToString(value);
value = string_new(version + " YaeAchievement");
CALL_ORIGIN(SetVersion, obj, value, method);
}
bool KcpRecv(void* client, ClientKcpEvent* evt, void* method) {
auto result = CALL_ORIGIN(KcpRecv, client, evt, method);
const auto result = CALL_ORIGIN(KcpRecv, client, evt, method);
if (result == 0 || evt->fields.type != KcpEventType::EventRecvMsg) {
return result;
}
@@ -67,9 +62,9 @@ namespace Hook {
}
ByteArray* UnityEngine_RecordUserData(INT type) {
return Genshin::GetBytes(Genshin::GetDefaultEncoding(), il2cpp_string_new(""));
return new ByteArray {};
}
VOID SetChecksum(LPVOID obj, Il2CppString* value) {
CALL_ORIGIN(SetChecksum, obj, il2cpp_string_new(checksum.c_str()));
}
@@ -84,20 +79,16 @@ namespace Hook {
void Run(HMODULE* phModule) {
//AllocConsole();
//freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
while (
GetModuleHandle("UserAssembly.dll") == nullptr ||
(unityWnd = FindMainWindowByPID(GetCurrentProcessId())) == nullptr
) {
while ((unityWnd = FindMainWindowByPID(GetCurrentProcessId())) == nullptr) {
Sleep(1000);
}
Sleep(5000);
DisableVMProtect();
InitIL2CPP();
auto enc = Genshin::GetDefaultEncoding();
for (int i = 0; i < 3; i++) {
checksum += ToString(Genshin::GetString(enc, Genshin::RecordUserData(i)));
const auto result = Genshin::RecordUserData(i);
checksum += string(reinterpret_cast<char*>(&result->vector[0]), result->max_length);
}
HookManager::install(Genshin::KcpSend, Hook::KcpSend);
HookManager::install(Genshin::KcpRecv, Hook::KcpRecv);
HookManager::install(Genshin::SetVersion, Hook::SetVersion);
HookManager::install(Genshin::RequestLogin, Hook::RequestLogin);

View File

@@ -1 +1 @@
DO_API(0x941c20, 0x93e230, Il2CppString*, il2cpp_string_new, (const char* str));
DO_API(0x4243d0, 0x420bf0, Il2CppString*, il2cpp_string_new, (const char* str));

View File

@@ -2,30 +2,20 @@ using namespace Genshin;
// DO_APP_FUNC(CN_OFFSET, OS_OFFSET, RETURN, FUNC_NAME, (ARGS...));
DO_APP_FUNC(0x728b850, 0x7247520, Il2CppString*, ToBase64String, (ByteArray* value, int offset, int length, void* method));
DO_APP_FUNC(0x1929870, 0x1922c30, void, SetVersion, (void* obj, Il2CppString* value, void* method));
DO_APP_FUNC(0x215d110, 0x214d7a0, void, SetVersion, (void* obj, Il2CppString* value, void* method));
DO_APP_FUNC(0x6e7d020, 0x6e38a10, ByteArray*, RecordUserData, (int32_t nType));
DO_APP_FUNC(0x7b4dc00, 0x7afe4e0, ByteArray*, RecordUserData, (int32_t nType));
DO_APP_FUNC(0x2b13f40, 0x2b09ce0, void, XorEncrypt, (ByteArray** data, int length, void* method));
DO_APP_FUNC(0x166e5d0, 0x1662f60, void, XorEncrypt, (ByteArray** data, int length, void* method));
DO_APP_FUNC(0x2d79560, 0x2d6e6f0, bool, KcpRecv, (void* client, ClientKcpEvent* evt, void* method));
DO_APP_FUNC(0xf71860, 0xf69870, int, KcpSend, (void* client, KcpPacket* pkt, void* method));
DO_APP_FUNC(0x20004f0, 0x1ff8530, VOID, RequestLogin, (LPVOID obj, LPVOID token, UINT uid));
DO_APP_FUNC(0x433e670, 0x4315590, bool, KcpRecv, (void* client, ClientKcpEvent* evt, void* method));
DO_APP_FUNC(0x130ead0, 0x1b90950, VOID, SetChecksum, (LPVOID obj, Il2CppString* value));
DO_APP_FUNC(0x75627b0, 0x751a960, LPVOID, GetDefaultEncoding, ());
DO_APP_FUNC(0x2266e40, 0x225eb50, VOID, ForceQuit, (LPVOID obj));
DO_APP_FUNC(0x7561ff0, 0x751a1c0, Il2CppString*, GetString, (LPVOID encoding, LPVOID bytes));
DO_APP_FUNC(0x60af410, 0x60735f0, LPVOID, GetSingletonManager, ());
DO_APP_FUNC(0x7560d90, 0x7518f90, ByteArray*, GetBytes, (LPVOID encoding, LPVOID str));
DO_APP_FUNC(0x1349850, 0x13415f0, VOID, RequestLogin, (LPVOID obj, LPVOID token, UINT uid));
DO_APP_FUNC(0x11ab1d0, 0x3e9f710, VOID, SetChecksum, (LPVOID obj, Il2CppString* value));
DO_APP_FUNC(0xd4e730, 0xd49dd0, VOID, ForceQuit, (LPVOID obj));
DO_APP_FUNC(0x607fbf0, 0x6044870, LPVOID, GetSingletonManager, ());
DO_APP_FUNC(0x607f920, 0x60445a0, LPVOID, GetSingletonInstance, (LPVOID obj, Il2CppString* value));
DO_APP_FUNC(0x60af140, 0x6073320, LPVOID, GetSingletonInstance, (LPVOID obj, Il2CppString* value));

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,3 @@
using namespace Genshin;
DO_UNI_FUNC(0x100560, 0x100560, ByteArray*, UnityEngine_RecordUserData, (int32_t nType));
DO_UNI_FUNC(0x105550, 0x105550, ByteArray*, UnityEngine_RecordUserData, (int32_t nType));

View File

@@ -68,3 +68,38 @@ HWND FindMainWindowByPID(DWORD pid) {
}
#pragma endregion
static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string base64_encode(BYTE const* buf, unsigned int bufLen) {
std::string ret;
int i = 0;
BYTE char_array_3[3];
BYTE char_array_4[4];
while (bufLen--) {
char_array_3[i++] = *buf++;
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; (i < 4); i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i) {
int j;
for (j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; j < i + 1; j++)
ret += base64_chars[char_array_4[j]];
while (i++ < 3)
ret += '=';
}
return ret;
}

View File

@@ -6,6 +6,7 @@ VOID DisableVMProtect();
bool IsLittleEndian();
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())

22
res/App.Designer.cs generated
View File

@@ -121,7 +121,9 @@ namespace YaeAchievement.res {
///[3] Seelie.me
///[4] Csv file
///[5] Xunkong
///Input a number (0-5): .
///[7] Teyvat Guide
///[8] UIAF JSON File
///Input a number (0-8): .
/// </summary>
internal static string ExportChoose {
get {
@@ -174,6 +176,24 @@ namespace YaeAchievement.res {
}
}
/// <summary>
/// Looks up a localized string similar to Please launch/update Teyvat Guide and retry..
/// </summary>
internal static string ExportToTauriFail {
get {
return ResourceManager.GetString("ExportToTauriFail", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Successfully exported to Teyvat Guide..
/// </summary>
internal static string ExportToTauriSuccess {
get {
return ResourceManager.GetString("ExportToTauriSuccess", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0}.
/// </summary>

View File

@@ -32,7 +32,9 @@
[3] Seelie.me
[4] Csv file
[5] Xunkong
Input a number (0-5): </value>
[7] Teyvat Guide
[8] UIAF JSON File
Input a number (0-8): </value>
</data>
<data name="ExportToCocogoatSuccess" xml:space="preserve">
<value>Successfully exported to cocogoat.</value>
@@ -129,4 +131,10 @@ Input a number (0-5): </value>
<data name="NoWritePermission" xml:space="preserve">
<value>No write permission on {0}.</value>
</data>
<data name="ExportToTauriSuccess" xml:space="preserve">
<value>Successfully exported to Teyvat Guide.</value>
</data>
<data name="ExportToTauriFail" xml:space="preserve">
<value>Please launch/update Teyvat Guide and retry.</value>
</data>
</root>

View File

@@ -26,8 +26,9 @@
[4] 表格文件
[5] 寻空
[6] 原魔工具箱
[7] UIAF JSON 文件
输入一个数字 (0-7): </value>
[7] Teyvat Guide
[8] UIAF JSON 文件
输入一个数字 (0-8): </value>
</data>
<data name="ExportToCocogoatSuccess" xml:space="preserve">
<value>在浏览器内进行下一步操作</value>
@@ -115,9 +116,15 @@
<value>网络错误,请检查网络后重试 ({0}: {1})</value>
</data>
<data name="GenshinHashError" xml:space="preserve">
<value>请将原神更新至最新版本后重试</value>
<value>当前适配版本不匹配,请更新原神至最新版本后重试或等待工具更新。</value>
</data>
<data name="NoWritePermission" xml:space="preserve">
<value>无法写入文件,请更换软件所在目录后重试</value>
</data>
<data name="ExportToTauriFail" xml:space="preserve">
<value>启动 Teyvat Guide 或更新 Teyvat Guide 至最新版本后重试</value>
</data>
<data name="ExportToTauriSuccess" xml:space="preserve">
<value>在 Teyvat Guide 进行下一步操作</value>
</data>
</root>

View File

@@ -9,13 +9,13 @@ message Achievement {
FINISHED = 2;
REWARD_TAKEN = 3;
}
uint32 timestamp = 3;
uint32 current = 9;
uint32 total = 11;
uint32 id = 14;
Status status = 10;
uint32 timestamp = 11;
uint32 current = 12;
uint32 total = 3;
uint32 id = 15;
Status status = 7;
}
message AchievementAllDataNotify {
repeated Achievement list = 3;
repeated Achievement list = 8;
}

View File

@@ -32,8 +32,9 @@ public static class Export {
4 => ToCSV,
5 => ToXunkong,
6 => ToWxApp1,
7 => ToUIAFJson,
8 => ToRawJson,
7 => ToTeyvatGuide,
8 => ToUIAFJson,
9 => ToRawJson,
_ => ToCocogoat
})).Invoke(data);
}
@@ -77,19 +78,38 @@ public static class Export {
}
private static void ToHuTao(AchievementAllDataNotify data) {
if (CheckWinUIAppScheme("hutao"))
{
if (CheckWinUIAppScheme("hutao")) {
Utils.CopyToClipboard(JsonSerializer.Serialize(ExportToUIAFApp(data)));
Utils.ShellOpen("hutao://achievement/import");
Console.WriteLine(App.ExportToSnapGenshinSuccess);
}
else
{
} else {
Console.WriteLine(App.ExportToSnapGenshinNeedUpdate);
Utils.ShellOpen("ms-windows-store://pdp/?productid=9PH4NXJ2JN52");
}
}
private static void ToXunkong(AchievementAllDataNotify data) {
if (CheckWinUIAppScheme("xunkong")) {
Utils.CopyToClipboard(JsonSerializer.Serialize(ExportToUIAFApp(data)));
Utils.ShellOpen("xunkong://import-achievement?caller=YaeAchievement&from=clipboard");
Console.WriteLine(App.ExportToXunkongSuccess);
} else {
Console.WriteLine(App.ExportToXunkongNeedUpdate);
Utils.ShellOpen("ms-windows-store://pdp/?productid=9N2SVG0JMT12");
}
}
private static void ToTeyvatGuide(AchievementAllDataNotify data) {
if (Process.GetProcessesByName("TeyvatGuide").Any()) {
Utils.CopyToClipboard(JsonSerializer.Serialize(ExportToUIAFApp(data)));
Utils.ShellOpen("teyvatguide://import_uigf?app=YaeAchievement");
Console.WriteLine(App.ExportToTauriSuccess);
} else {
Console.WriteLine(App.ExportToTauriFail);
Utils.ShellOpen("ms-windows-store://pdp/?productid=9NLBNNNBNSJN");
}
}
// ReSharper disable once InconsistentNaming
private static void ToUIAFJson(AchievementAllDataNotify data) {
var path = Path.GetFullPath($"uiaf-{DateTime.Now:yyyyMMddHHmmss}.json");
@@ -168,17 +188,6 @@ public static class Export {
}
}
private static void ToXunkong(AchievementAllDataNotify data) {
if (CheckWinUIAppScheme("xunkong")) {
Utils.CopyToClipboard(JsonSerializer.Serialize(ExportToUIAFApp(data)));
Utils.ShellOpen("xunkong://import-achievement?caller=YaeAchievement&from=clipboard");
Console.WriteLine(App.ExportToXunkongSuccess);
} else {
Console.WriteLine(App.ExportToXunkongNeedUpdate);
Utils.ShellOpen("ms-windows-store://pdp/?productid=9N2SVG0JMT12");
}
}
private static void ToRawJson(AchievementAllDataNotify data) {
var path = Path.GetFullPath($"export-{DateTime.Now:yyyyMMddHHmmss}-raw.json");
var text = JsonSerializer.Serialize(data, new JsonSerializerOptions {

View File

@@ -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 = 39;
public const string AppVersionName = "2.9";
public const uint AppVersionCode = 42;
public const string AppVersionName = "3.2";
public const string PipeName = "YaeAchievementPipe";
public const string BucketHost = "https://cn-cd-1259389942.file.myqcloud.com";

View File

@@ -45,7 +45,7 @@ public static class Injector {
return new Win32Exception().PrintMsgAndReturnErrCode("WriteProcessMemory fail");
}
}
var lpStartAddress = pLoadLibrary.CreateDelegate<LPTHREAD_START_ROUTINE>();
var lpStartAddress = (delegate* unmanaged[Stdcall]<void*, uint>)pLoadLibrary.Value; //THREAD_START_ROUTINE
var hThread = Native.CreateRemoteThread(hProc, default, 0, lpStartAddress, pBase, 0);
if (hThread.IsNull) {
var e = new Win32Exception();

View File

@@ -1,6 +1,6 @@
{
"$schema": "https://aka.ms/CsWin32.schema.json",
"className": "Native",
"allowMarshaling": true,
"allowMarshaling": false,
"public": true
}

View File

@@ -1,21 +1,21 @@
CreateProcess
CloseClipboard
CreateProcess
CreateRemoteThread
EmptyClipboard
GetConsoleMode
GetDC
GetDeviceCaps
GetModuleHandle
GetProcAddress
VirtualAllocEx
WriteProcessMemory
CreateRemoteThread
VirtualFreeEx
WaitForSingleObject
OpenClipboard
EmptyClipboard
GlobalLock
SetClipboardData
GlobalUnlock
CloseClipboard
GetStdHandle
GetConsoleMode
GlobalLock
GlobalUnlock
OpenClipboard
ResumeThread
SetClipboardData
SetConsoleMode
TerminateProcess
ResumeThread
GetDeviceCaps
GetDC
VirtualAllocEx
VirtualFreeEx
WaitForSingleObject
WriteProcessMemory

View File

@@ -92,7 +92,7 @@ public static class Utils {
public static void CheckUpdate(bool useLocalLib) {
var info = UpdateInfo.Parser.ParseFrom(GetBucketFileAsByteArray("schicksal/version"))!;
if (GlobalVars.AppVersionCode != info.VersionCode) {
if (GlobalVars.AppVersionCode < info.VersionCode) {
Console.WriteLine(App.UpdateNewVersion, GlobalVars.AppVersionName, info.VersionName);
Console.WriteLine(App.UpdateDescription, info.Description);
if (info.EnableAutoDownload) {