mirror of
https://github.com/HolographicHat/Yae.git
synced 2025-12-15 02:48:12 +08:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f41fe6fb12 | ||
|
|
78bda3f49c | ||
|
|
a10dc22461 | ||
|
|
74dda750ef | ||
|
|
099270ad29 | ||
|
|
fe5b2c0c12 | ||
|
|
ed5d99745c | ||
|
|
7175cd7427 | ||
|
|
73747bcce5 | ||
|
|
b12c3209d7 | ||
|
|
5805070627 |
2
.github/workflows/dotnet.yml
vendored
2
.github/workflows/dotnet.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
|||||||
- name: Restore dependencies
|
- name: Restore dependencies
|
||||||
run: dotnet restore
|
run: dotnet restore
|
||||||
- name: Build
|
- name: Build
|
||||||
run: dotnet build --no-restore
|
run: dotnet build -c Release --no-restore
|
||||||
- name: Publish
|
- name: Publish
|
||||||
run: dotnet publish --property:OutputPath=.\publish\
|
run: dotnet publish --property:OutputPath=.\publish\
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
|
|||||||
64
.gitlab-ci.yml
Normal file
64
.gitlab-ci.yml
Normal 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
|
||||||
@@ -8,8 +8,8 @@ using std::to_string;
|
|||||||
HWND unityWnd = nullptr;
|
HWND unityWnd = nullptr;
|
||||||
HANDLE hPipe = nullptr;
|
HANDLE hPipe = nullptr;
|
||||||
|
|
||||||
// Allow Protocol: GetPlayerToken, PlayerLogin, AchievementAllDataNotify, Ping, PlayerForceExit
|
// Allow Protocol: GetPlayerTokenRsp, PlayerLoginRsp, AchievementAllDataNotify, PingRsp
|
||||||
std::set<UINT16> PacketWhitelist = { 21228, 2407, 25842, 29665, 27422, 5285, 8231, 1819 };
|
std::set<UINT16> PacketWhitelist = { 1347, 4424, 20342, 25731 };
|
||||||
|
|
||||||
bool OnPacket(KcpPacket* pkt) {
|
bool OnPacket(KcpPacket* pkt) {
|
||||||
if (pkt->data == nullptr) return true;
|
if (pkt->data == nullptr) return true;
|
||||||
@@ -30,11 +30,10 @@ bool OnPacket(KcpPacket* pkt) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
printf("Passed cmdid: %d\n", ReadMapped<UINT16>(data->vector, 2));
|
printf("Passed cmdid: %d\n", ReadMapped<UINT16>(data->vector, 2));
|
||||||
if (ReadMapped<UINT16>(data->vector, 2) == 27422) {
|
if (ReadMapped<UINT16>(data->vector, 2) == 20342) {
|
||||||
auto headLength = ReadMapped<UINT16>(data->vector, 4);
|
const auto headLength = ReadMapped<UINT16>(data->vector, 4);
|
||||||
auto dataLength = ReadMapped<UINT32>(data->vector, 6);
|
const auto dataLength = ReadMapped<UINT32>(data->vector, 6);
|
||||||
auto iStr = Genshin::ToBase64String(data, 10 + headLength, dataLength, nullptr);
|
const auto cStr = base64_encode(data->vector + 10 + headLength, dataLength) + "\n";
|
||||||
auto cStr = ToString(iStr) + "\n";
|
|
||||||
WriteFile(hPipe, cStr.c_str(), cStr.length(), nullptr, nullptr);
|
WriteFile(hPipe, cStr.c_str(), cStr.length(), nullptr, nullptr);
|
||||||
CloseHandle(hPipe);
|
CloseHandle(hPipe);
|
||||||
auto manager = Genshin::GetSingletonInstance(Genshin::GetSingletonManager(), il2cpp_string_new("GameManager"));
|
auto manager = Genshin::GetSingletonInstance(Genshin::GetSingletonManager(), il2cpp_string_new("GameManager"));
|
||||||
@@ -48,18 +47,14 @@ std::string checksum;
|
|||||||
|
|
||||||
namespace Hook {
|
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) {
|
void SetVersion(void* obj, Il2CppString* value, void* method) {
|
||||||
auto version = ToString(value);
|
const auto version = ToString(value);
|
||||||
value = string_new(version + " YaeAchievement");
|
value = string_new(version + " YaeAchievement");
|
||||||
CALL_ORIGIN(SetVersion, obj, value, method);
|
CALL_ORIGIN(SetVersion, obj, value, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KcpRecv(void* client, ClientKcpEvent* evt, void* 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) {
|
if (result == 0 || evt->fields.type != KcpEventType::EventRecvMsg) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -67,40 +62,22 @@ namespace Hook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ByteArray* UnityEngine_RecordUserData(INT type) {
|
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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID RequestLogin(LPVOID obj, LPVOID token, UINT32 uid) {
|
|
||||||
HookManager::install(Genshin::SetChecksum, SetChecksum);
|
|
||||||
CALL_ORIGIN(RequestLogin, obj, token, uid);
|
|
||||||
HookManager::detach(SetChecksum);
|
|
||||||
}
|
}
|
||||||
|
// 不再使用checksum(?
|
||||||
}
|
}
|
||||||
|
|
||||||
void Run(HMODULE* phModule) {
|
void Run(HMODULE* phModule) {
|
||||||
//AllocConsole();
|
//AllocConsole();
|
||||||
//freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
|
//freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
|
||||||
while (
|
while ((unityWnd = FindMainWindowByPID(GetCurrentProcessId())) == nullptr) {
|
||||||
GetModuleHandle("UserAssembly.dll") == nullptr ||
|
|
||||||
(unityWnd = FindMainWindowByPID(GetCurrentProcessId())) == nullptr
|
|
||||||
) {
|
|
||||||
Sleep(1000);
|
Sleep(1000);
|
||||||
}
|
}
|
||||||
Sleep(5000);
|
Sleep(5000);
|
||||||
DisableVMProtect();
|
DisableVMProtect();
|
||||||
InitIL2CPP();
|
InitIL2CPP();
|
||||||
auto enc = Genshin::GetDefaultEncoding();
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
checksum += ToString(Genshin::GetString(enc, Genshin::RecordUserData(i)));
|
|
||||||
}
|
|
||||||
HookManager::install(Genshin::KcpSend, Hook::KcpSend);
|
|
||||||
HookManager::install(Genshin::KcpRecv, Hook::KcpRecv);
|
HookManager::install(Genshin::KcpRecv, Hook::KcpRecv);
|
||||||
HookManager::install(Genshin::SetVersion, Hook::SetVersion);
|
HookManager::install(Genshin::SetVersion, Hook::SetVersion);
|
||||||
HookManager::install(Genshin::RequestLogin, Hook::RequestLogin);
|
|
||||||
HookManager::install(Genshin::UnityEngine_RecordUserData, Hook::UnityEngine_RecordUserData);
|
HookManager::install(Genshin::UnityEngine_RecordUserData, Hook::UnityEngine_RecordUserData);
|
||||||
hPipe = CreateFile(R"(\\.\pipe\YaeAchievementPipe)", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
|
hPipe = CreateFile(R"(\\.\pipe\YaeAchievementPipe)", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
DO_API(0x9cc850, 0x9ca750, Il2CppString*, il2cpp_string_new, (const char* str));
|
DO_API(0x9D1AC0, 0x9CADC0, Il2CppString*, il2cpp_string_new, (const char* str));
|
||||||
|
|||||||
@@ -2,30 +2,14 @@ using namespace Genshin;
|
|||||||
|
|
||||||
// DO_APP_FUNC(CN_OFFSET, OS_OFFSET, RETURN, FUNC_NAME, (ARGS...));
|
// DO_APP_FUNC(CN_OFFSET, OS_OFFSET, RETURN, FUNC_NAME, (ARGS...));
|
||||||
|
|
||||||
DO_APP_FUNC(0x7974040, 0x792b560, Il2CppString*, ToBase64String, (ByteArray* value, int offset, int length, void* method));
|
DO_APP_FUNC(0x258fd40, 0x2548e50, void, SetVersion, (void* obj, Il2CppString* value, void* method));
|
||||||
|
|
||||||
DO_APP_FUNC(0x21e5c10, 0x21bf5c0, void, SetVersion, (void* obj, Il2CppString* value, void* method));
|
DO_APP_FUNC(0x3220f00, 0x31c1650, void, XorEncrypt, (ByteArray** data, int length, void* method));
|
||||||
|
|
||||||
DO_APP_FUNC(0x81d1a00, 0x818d250, ByteArray*, RecordUserData, (int32_t nType));
|
DO_APP_FUNC(0x12f5df0, 0x12ddd80, bool, KcpRecv, (void* client, ClientKcpEvent* evt, void* method));
|
||||||
|
|
||||||
DO_APP_FUNC(0x3174320, 0x3133880, void, XorEncrypt, (ByteArray** data, int length, void* method));
|
DO_APP_FUNC(0x264ee90, 0x2606720, VOID, ForceQuit, (LPVOID obj));
|
||||||
|
|
||||||
DO_APP_FUNC(0x2d49720, 0x2d103a0, int, KcpSend, (void* client, KcpPacket* pkt, void* method));
|
DO_APP_FUNC(0x624d630, 0x61bd630, LPVOID, GetSingletonManager, ());
|
||||||
|
|
||||||
DO_APP_FUNC(0x3d6a920, 0x3d11e00, bool, KcpRecv, (void* client, ClientKcpEvent* evt, void* method));
|
DO_APP_FUNC(0x624d360, 0x61bd360, LPVOID, GetSingletonInstance, (LPVOID obj, Il2CppString* value));
|
||||||
|
|
||||||
DO_APP_FUNC(0x7c9c9c0, 0x7c56400, LPVOID, GetDefaultEncoding, ());
|
|
||||||
|
|
||||||
DO_APP_FUNC(0x7c9c220, 0x7c55c60, Il2CppString*, GetString, (LPVOID encoding, LPVOID bytes));
|
|
||||||
|
|
||||||
DO_APP_FUNC(0x7c9b030, 0x7c54a20, ByteArray*, GetBytes, (LPVOID encoding, LPVOID str));
|
|
||||||
|
|
||||||
DO_APP_FUNC(0x1d2e480, 0x1d0db20, VOID, RequestLogin, (LPVOID obj, LPVOID token, UINT uid));
|
|
||||||
|
|
||||||
DO_APP_FUNC(0x31285b0, 0x32ee9b0, VOID, SetChecksum, (LPVOID obj, Il2CppString* value));
|
|
||||||
|
|
||||||
DO_APP_FUNC(0xfa2eb0, 0xf99150, VOID, ForceQuit, (LPVOID obj));
|
|
||||||
|
|
||||||
DO_APP_FUNC(0x7257b20, 0x72079f0, LPVOID, GetSingletonManager, ());
|
|
||||||
|
|
||||||
DO_APP_FUNC(0x7257850, 0x7207720, LPVOID, GetSingletonInstance, (LPVOID obj, Il2CppString* value));
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,3 @@
|
|||||||
using namespace Genshin;
|
using namespace Genshin;
|
||||||
|
|
||||||
DO_UNI_FUNC(0x102fa0, 0x102fa0, ByteArray*, UnityEngine_RecordUserData, (int32_t nType));
|
DO_UNI_FUNC(0x103420, 0x103420, ByteArray*, UnityEngine_RecordUserData, (int32_t nType));
|
||||||
|
|||||||
@@ -68,3 +68,38 @@ HWND FindMainWindowByPID(DWORD pid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ VOID DisableVMProtect();
|
|||||||
bool IsLittleEndian();
|
bool IsLittleEndian();
|
||||||
HWND FindMainWindowByPID(DWORD pid);
|
HWND FindMainWindowByPID(DWORD pid);
|
||||||
string ToString(Il2CppString* str, UINT codePage = CP_ACP);
|
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 cstring_new(str) il2cpp_string_new(str)
|
||||||
#define string_new(str) cstring_new((str).c_str())
|
#define string_new(str) cstring_new((str).c_str())
|
||||||
|
|||||||
22
res/App.Designer.cs
generated
22
res/App.Designer.cs
generated
@@ -121,7 +121,9 @@ namespace YaeAchievement.res {
|
|||||||
///[3] Seelie.me
|
///[3] Seelie.me
|
||||||
///[4] Csv file
|
///[4] Csv file
|
||||||
///[5] Xunkong
|
///[5] Xunkong
|
||||||
///Input a number (0-5): .
|
///[7] Teyvat Guide
|
||||||
|
///[8] UIAF JSON File
|
||||||
|
///Input a number (0-8): .
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string ExportChoose {
|
internal static string ExportChoose {
|
||||||
get {
|
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>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to {0}.
|
/// Looks up a localized string similar to {0}.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
10
res/App.resx
10
res/App.resx
@@ -32,7 +32,9 @@
|
|||||||
[3] Seelie.me
|
[3] Seelie.me
|
||||||
[4] Csv file
|
[4] Csv file
|
||||||
[5] Xunkong
|
[5] Xunkong
|
||||||
Input a number (0-5): </value>
|
[7] Teyvat Guide
|
||||||
|
[8] UIAF JSON File
|
||||||
|
Input a number (0-8): </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ExportToCocogoatSuccess" xml:space="preserve">
|
<data name="ExportToCocogoatSuccess" xml:space="preserve">
|
||||||
<value>Successfully exported to cocogoat.</value>
|
<value>Successfully exported to cocogoat.</value>
|
||||||
@@ -129,4 +131,10 @@ Input a number (0-5): </value>
|
|||||||
<data name="NoWritePermission" xml:space="preserve">
|
<data name="NoWritePermission" xml:space="preserve">
|
||||||
<value>No write permission on {0}.</value>
|
<value>No write permission on {0}.</value>
|
||||||
</data>
|
</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>
|
</root>
|
||||||
@@ -26,8 +26,9 @@
|
|||||||
[4] 表格文件
|
[4] 表格文件
|
||||||
[5] 寻空
|
[5] 寻空
|
||||||
[6] 原魔工具箱
|
[6] 原魔工具箱
|
||||||
[7] UIAF JSON 文件
|
[7] Teyvat Guide
|
||||||
输入一个数字 (0-7): </value>
|
[8] UIAF JSON 文件
|
||||||
|
输入一个数字 (0-8): </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ExportToCocogoatSuccess" xml:space="preserve">
|
<data name="ExportToCocogoatSuccess" xml:space="preserve">
|
||||||
<value>在浏览器内进行下一步操作</value>
|
<value>在浏览器内进行下一步操作</value>
|
||||||
@@ -115,9 +116,15 @@
|
|||||||
<value>网络错误,请检查网络后重试 ({0}: {1})</value>
|
<value>网络错误,请检查网络后重试 ({0}: {1})</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="GenshinHashError" xml:space="preserve">
|
<data name="GenshinHashError" xml:space="preserve">
|
||||||
<value>请将原神更新至最新版本后重试</value>
|
<value>当前适配版本不匹配,请更新原神至最新版本后重试或等待工具更新。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="NoWritePermission" xml:space="preserve">
|
<data name="NoWritePermission" xml:space="preserve">
|
||||||
<value>无法写入文件,请更换软件所在目录后重试</value>
|
<value>无法写入文件,请更换软件所在目录后重试</value>
|
||||||
</data>
|
</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>
|
</root>
|
||||||
@@ -9,13 +9,13 @@ message Achievement {
|
|||||||
FINISHED = 2;
|
FINISHED = 2;
|
||||||
REWARD_TAKEN = 3;
|
REWARD_TAKEN = 3;
|
||||||
}
|
}
|
||||||
uint32 timestamp = 15;
|
uint32 timestamp = 3;
|
||||||
uint32 current = 14;
|
uint32 current = 14;
|
||||||
uint32 total = 4;
|
uint32 total = 8;
|
||||||
uint32 id = 5;
|
uint32 id = 1;
|
||||||
Status status = 10;
|
Status status = 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AchievementAllDataNotify {
|
message AchievementAllDataNotify {
|
||||||
repeated Achievement list = 9;
|
repeated Achievement list = 2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ public static class Export {
|
|||||||
4 => ToCSV,
|
4 => ToCSV,
|
||||||
5 => ToXunkong,
|
5 => ToXunkong,
|
||||||
6 => ToWxApp1,
|
6 => ToWxApp1,
|
||||||
7 => ToUIAFJson,
|
7 => ToTeyvatGuide,
|
||||||
8 => ToRawJson,
|
8 => ToUIAFJson,
|
||||||
|
9 => ToRawJson,
|
||||||
_ => ToCocogoat
|
_ => ToCocogoat
|
||||||
})).Invoke(data);
|
})).Invoke(data);
|
||||||
}
|
}
|
||||||
@@ -77,19 +78,38 @@ public static class Export {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void ToHuTao(AchievementAllDataNotify data) {
|
private static void ToHuTao(AchievementAllDataNotify data) {
|
||||||
if (CheckWinUIAppScheme("hutao"))
|
if (CheckWinUIAppScheme("hutao")) {
|
||||||
{
|
|
||||||
Utils.CopyToClipboard(JsonSerializer.Serialize(ExportToUIAFApp(data)));
|
Utils.CopyToClipboard(JsonSerializer.Serialize(ExportToUIAFApp(data)));
|
||||||
Utils.ShellOpen("hutao://achievement/import");
|
Utils.ShellOpen("hutao://achievement/import");
|
||||||
Console.WriteLine(App.ExportToSnapGenshinSuccess);
|
Console.WriteLine(App.ExportToSnapGenshinSuccess);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine(App.ExportToSnapGenshinNeedUpdate);
|
Console.WriteLine(App.ExportToSnapGenshinNeedUpdate);
|
||||||
Utils.ShellOpen("ms-windows-store://pdp/?productid=9PH4NXJ2JN52");
|
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
|
// ReSharper disable once InconsistentNaming
|
||||||
private static void ToUIAFJson(AchievementAllDataNotify data) {
|
private static void ToUIAFJson(AchievementAllDataNotify data) {
|
||||||
var path = Path.GetFullPath($"uiaf-{DateTime.Now:yyyyMMddHHmmss}.json");
|
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) {
|
private static void ToRawJson(AchievementAllDataNotify data) {
|
||||||
var path = Path.GetFullPath($"export-{DateTime.Now:yyyyMMddHHmmss}-raw.json");
|
var path = Path.GetFullPath($"export-{DateTime.Now:yyyyMMddHHmmss}-raw.json");
|
||||||
var text = JsonSerializer.Serialize(data, new JsonSerializerOptions {
|
var text = JsonSerializer.Serialize(data, new JsonSerializerOptions {
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ public static class GlobalVars {
|
|||||||
public static readonly string CachePath = Path.Combine(DataPath, "cache");
|
public static readonly string CachePath = Path.Combine(DataPath, "cache");
|
||||||
public static readonly string LibFilePath = Path.Combine(DataPath, "YaeAchievement.dll");
|
public static readonly string LibFilePath = Path.Combine(DataPath, "YaeAchievement.dll");
|
||||||
|
|
||||||
public const uint AppVersionCode = 40;
|
public const uint AppVersionCode = 41;
|
||||||
public const string AppVersionName = "3.0";
|
public const string AppVersionName = "3.1";
|
||||||
|
|
||||||
public const string PipeName = "YaeAchievementPipe";
|
public const string PipeName = "YaeAchievementPipe";
|
||||||
public const string BucketHost = "https://cn-cd-1259389942.file.myqcloud.com";
|
public const string BucketHost = "https://cn-cd-1259389942.file.myqcloud.com";
|
||||||
|
|||||||
Reference in New Issue
Block a user