mirror of
https://github.com/HolographicHat/Yae.git
synced 2025-12-13 18:08:15 +08:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf5525d2ea | ||
|
|
cf3749f887 | ||
|
|
21af4de1a6 | ||
|
|
8e0fd2d27c | ||
|
|
0348cfa365 | ||
|
|
494eda32c2 | ||
|
|
975638c1ee | ||
|
|
c82a10353f |
@@ -1,10 +1,10 @@
|
|||||||
<div align="center"><img width="100" src="https://github.com/HolographicHat/YaeAchievement/blob/master/icon.ico">
|
<div align="center"><img width="100" src="https://github.com/HolographicHat/YaeAchievement/blob/master/icon.ico">
|
||||||
|
|
||||||
# YaeAchievement
|
# YaeAchievement
|
||||||
|
|
||||||
    
|
    
|
||||||
|
|
||||||
简体中文 | [English](README_EN.md)
|
简体中文 | [English](README_EN.md) | [日本語](README_JP.md)
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
- 支持导出所有类别的成就
|
- 支持导出所有类别的成就
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
    
|
    
|
||||||
|
|
||||||
[简体中文](README.md) | English
|
[简体中文](README.md) | English | [日本語](README_JP.md)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
44
README_JP.md
Normal file
44
README_JP.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<div align="center"><img width="100" src="https://github.com/HolographicHat/YaeAchievement/blob/master/icon.ico">
|
||||||
|
|
||||||
|
# YaeAchievement
|
||||||
|
|
||||||
|
    
|
||||||
|
|
||||||
|
[简体中文](README.md) | [English](README_EN.md) | 日本語
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
- すべてのカテゴリの実績のエクスポートをサポート
|
||||||
|
- すべてのバージョンの原神をサポート
|
||||||
|
- ウィンドウサイズ、ゲーム言語などの要件はありません
|
||||||
|
|
||||||
|
## エクスポートサポート
|
||||||
|
|
||||||
|
> 数字キーに従ってエクスポート方法を選択します。<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_JP.md](Tutorial_JP.md)
|
||||||
|
|
||||||
|
## ダウンロード: [こちら](https://github.com/HolographicHat/YaeAchievement/releases/latest)
|
||||||
|
|
||||||
|
## フィードバックや問題?
|
||||||
|
[issues](https://github.com/HolographicHat/YaeAchievement/issues) または [QQ群: 913777414](https://qm.qq.com/cgi-bin/qm/qr?k=9UGz-chQVTjZa4b82RA_A41vIcBVNpms&jump_from=webapi)
|
||||||
|
|
||||||
|
## よくある質問
|
||||||
|
0. Q: 起動できない
|
||||||
|
A: [.NET Runtime 7](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-8.0.4-windows-x64-installer) をダウンロードしてインストールするか、`winget install Microsoft.DotNet.Runtime.8` を実行してください。
|
||||||
|
|
||||||
|
|
||||||
|
1. Q: 原神を起動中にエラーが発生しました: データ例外 (31-4302)
|
||||||
|
A: ソフトウェアを原神のディレクトリに配置しないでください。
|
||||||
|
|
||||||
75
Tutorial_JP.md
Normal file
75
Tutorial_JP.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
## 使用説明書
|
||||||
|
|
||||||
|
1. YaeAchievement(最新バージョン)をダウンロード:
|
||||||
|
|
||||||
|
こちらをクリック:https://github.com/HolographicHat/YaeAchievement/releases
|
||||||
|
|
||||||
|
赤枠で囲まれた「YaeAchievement.exe」という名前のファイルをクリックすると、自動的にポップアップしてダウンロードされます。このファイルをデスクトップや他の見やすいフォルダに保存することをお勧めします。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
2. .NET Runtime 7をインストール(ランタイムが既にインストールされている場合はこのステップを無視できます)
|
||||||
|
|
||||||
|
こちらをクリック:https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-8.0.4-windows-x64-installer .
|
||||||
|
|
||||||
|
または、Windows 11を使用しているか、Wingetがインストールされている場合は、`winget install Microsoft.DotNet.Runtime.7`を実行します。
|
||||||
|
|
||||||
|
ウェブページにアクセスすると、ブラウザが自動的にポップアップしてダウンロードされます。ファイルをデスクトップや他の見やすいフォルダに保存します。
|
||||||
|
|
||||||
|
ダウンロードが完了したら、dotnet-runtime-x.x.x-win-x64.exeという名前のファイルを開くと、インストールウィンドウがポップアップします。以下の図のように表示されます。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
インストールをクリックするだけです。
|
||||||
|
|
||||||
|
3. メインプログラムを開くための操作と実績エクスポートのオプション
|
||||||
|
|
||||||
|
最初のステップでダウンロードした「YaeAchievement.exe」という名前のファイルをダブルクリックして開くと、原神が起動していることを示します。以下の図のように表示されます。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
原神の起動が完了したら、ゲームに入ります。
|
||||||
|
|
||||||
|
ゲームに入ると、ツールがどのツールにエクスポートするかを選択するように促します。以下の図のように表示されます。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
グローバルユーザーの場合、[3] Seelie.meまたは[4] csvファイルにエクスポートを選択する必要があります。
|
||||||
|
|
||||||
|
選択後、各ページは次のようにツールをエクスポートします:
|
||||||
|
|
||||||
|
#### Snap.Hutao:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### Seelie.me:
|
||||||
|
|
||||||
|
この時点で、Yae Achievementは実績データがエクスポートされたことを通知します。Yae Achievement保存ディレクトリにexport-20xxxxxxxxxxxx-seelie.jsonという名前のファイルを見つけてください。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
次に、URL:https://seelie.me/settings をクリックし、ウェブサイトにアクセスしてインポートアカウントを選択します。以下の図のように表示されます。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
インポートをクリックした後、export-20xxxxxxxxxxxx-seelie.jsonという名前のファイルを選択します。以下の図のように表示されます。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
以下の図のようなプロンプトが表示されたら、インポートプロセスは成功です。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
この時点で、左側の列のAchievementsを選択して、インポートされた実績データを表示できます。
|
||||||
|
|
||||||
|
### 各ツールの紹介については、各ツールの公式ページをご覧ください:
|
||||||
|
|
||||||
|
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ファイル
|
||||||
@@ -32,7 +32,7 @@ namespace Hook {
|
|||||||
|
|
||||||
uint16_t BitConverter_ToUInt16(ByteArray* val, const int startIndex) {
|
uint16_t BitConverter_ToUInt16(ByteArray* val, const int startIndex) {
|
||||||
const auto ret = CALL_ORIGIN(BitConverter_ToUInt16, val, startIndex);
|
const auto ret = CALL_ORIGIN(BitConverter_ToUInt16, val, startIndex);
|
||||||
if (ret == 0xAB89 && ReadMapped<UINT16>(val->vector, 2) == 3199) {
|
if (ret == 0xAB89 && ReadMapped<UINT16>(val->vector, 2) == 24082) {
|
||||||
const auto headLength = ReadMapped<UINT16>(val->vector, 4);
|
const auto headLength = ReadMapped<UINT16>(val->vector, 4);
|
||||||
const auto dataLength = ReadMapped<UINT32>(val->vector, 6);
|
const auto dataLength = ReadMapped<UINT32>(val->vector, 6);
|
||||||
const auto cStr = base64_encode(val->vector + 10 + headLength, dataLength) + "\n";
|
const auto cStr = base64_encode(val->vector + 10 + headLength, dataLength) + "\n";
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ 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(0x0052A510, 0x0052ED10, ByteArray*, il2cpp_array_new_specific, (void* arrayTypeInfo, uint64_t length));
|
DO_APP_FUNC(0x002ED400, 0x002ED390, ByteArray*, il2cpp_array_new_specific, (void* arrayTypeInfo, uint64_t length));
|
||||||
|
|
||||||
DO_APP_FUNC(0x01688250, 0x0168CB50, ByteArray*, RecordUserData, (int32_t nType));
|
DO_APP_FUNC(0x0113ADC0, 0x0113AFC0, ByteArray*, RecordUserData, (int32_t nType));
|
||||||
|
|
||||||
DO_APP_FUNC(0x0FC7D610, 0x0FCA7240, uint16_t, BitConverter_ToUInt16, (ByteArray* val, int startIndex));
|
DO_APP_FUNC(0x0F826CF0, 0x0F825F10, uint16_t, BitConverter_ToUInt16, (ByteArray* val, int startIndex));
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ using std::string;
|
|||||||
void InitIL2CPP() {
|
void InitIL2CPP() {
|
||||||
TCHAR szFileName[MAX_PATH];
|
TCHAR szFileName[MAX_PATH];
|
||||||
GetModuleFileName(nullptr, szFileName, MAX_PATH);
|
GetModuleFileName(nullptr, szFileName, MAX_PATH);
|
||||||
const auto isCN = strstr(szFileName, "YuanShen.exe");
|
_strupr_s(szFileName);
|
||||||
|
const auto isCN = strstr(szFileName, "YUANSHEN.EXE");
|
||||||
const auto uBase = reinterpret_cast<uint64_t>(GetModuleHandle(isCN ? "YuanShen.exe" : "GenshinImpact.exe"));
|
const auto uBase = reinterpret_cast<uint64_t>(GetModuleHandle(isCN ? "YuanShen.exe" : "GenshinImpact.exe"));
|
||||||
#define DO_APP_FUNC(ca, oa, r, n, p) n = (r (*) p)(uBase + (isCN ? ca : oa))
|
#define DO_APP_FUNC(ca, oa, r, n, p) n = (r (*) p)(uBase + (isCN ? ca : oa))
|
||||||
#include "il2cpp-functions.h"
|
#include "il2cpp-functions.h"
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ message Achievement {
|
|||||||
FINISHED = 2;
|
FINISHED = 2;
|
||||||
REWARD_TAKEN = 3;
|
REWARD_TAKEN = 3;
|
||||||
}
|
}
|
||||||
uint32 timestamp = 7;
|
uint32 timestamp = 11;
|
||||||
uint32 current = 12;
|
uint32 current = 5;
|
||||||
uint32 total = 5;
|
uint32 total = 15;
|
||||||
uint32 id = 15;
|
uint32 id = 2;
|
||||||
Status status = 8;
|
Status status = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AchievementAllDataNotify {
|
message AchievementAllDataNotify {
|
||||||
repeated Achievement list = 11;
|
repeated Achievement list = 4;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,19 +120,14 @@ public static class Export {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void ToPaimon(AchievementAllDataNotify data) {
|
private static void ToPaimon(AchievementAllDataNotify data) {
|
||||||
var info = LoadAchievementInfo();
|
var info = LoadAchievementInfo().Items.ToDictionary(pair => pair.Key, pair => pair.Value.Group);
|
||||||
var output = new Dictionary<uint, Dictionary<uint, bool>>();
|
|
||||||
foreach (var ach in data.List.Where(a => a.Status is Status.Finished or Status.RewardTaken)) {
|
|
||||||
if (!info.Items.TryGetValue(ach.Id, out var achInfo) || achInfo == null) {
|
|
||||||
Console.WriteLine($@"Unable to find {ach.Id} in metadata.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var map = output.GetValueOrDefault(achInfo.Group, new Dictionary<uint, bool>());
|
|
||||||
map[ach.Id == 81222 ? 81219 : ach.Id] = true;
|
|
||||||
output[achInfo.Group] = map;
|
|
||||||
}
|
|
||||||
var final = new Dictionary<string, Dictionary<uint, Dictionary<uint, bool>>> {
|
var final = new Dictionary<string, Dictionary<uint, Dictionary<uint, bool>>> {
|
||||||
["achievement"] = output.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value)
|
["achievement"] = data.List
|
||||||
|
.Where(achievement => achievement.Status is Status.Finished or Status.RewardTaken)
|
||||||
|
.Where(achievement => info.ContainsKey(achievement.Id))
|
||||||
|
.GroupBy(achievement => info[achievement.Id], achievement => achievement.Id)
|
||||||
|
.OrderBy(group => group.Key)
|
||||||
|
.ToDictionary(group => group.Key, group => group.ToDictionary(id => id, _ => true))
|
||||||
};
|
};
|
||||||
var path = Path.GetFullPath($"export-{DateTime.Now:yyyyMMddHHmmss}-paimon.json");
|
var path = Path.GetFullPath($"export-{DateTime.Now:yyyyMMddHHmmss}-paimon.json");
|
||||||
if (TryWriteToFile(path, JsonSerializer.Serialize(final))) {
|
if (TryWriteToFile(path, JsonSerializer.Serialize(final))) {
|
||||||
@@ -143,7 +138,7 @@ public static class Export {
|
|||||||
private static void ToSeelie(AchievementAllDataNotify data) {
|
private static void ToSeelie(AchievementAllDataNotify data) {
|
||||||
var output = new Dictionary<uint, Dictionary<string, bool>>();
|
var output = new Dictionary<uint, Dictionary<string, bool>>();
|
||||||
foreach (var ach in data.List.Where(a => a.Status is Status.Finished or Status.RewardTaken)) {
|
foreach (var ach in data.List.Where(a => a.Status is Status.Finished or Status.RewardTaken)) {
|
||||||
output[ach.Id == 81222 ? 81219 : ach.Id] = new Dictionary<string, bool> {
|
output[ach.Id] = new Dictionary<string, bool> {
|
||||||
["done"] = true
|
["done"] = true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 = 48;
|
public const uint AppVersionCode = 51;
|
||||||
public const string AppVersionName = "3.8";
|
public const string AppVersionName = "4.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";
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ public static class Utils {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.Select(item => item?.GetValue("DisplayName") as string ?? string.Empty)
|
.Select(item => item?.GetValue("DisplayName") as string ?? string.Empty)
|
||||||
.Any(name => name.Contains("Microsoft Visual C++ 2022 X64 "));
|
.Any(name => name.Contains("Microsoft Visual C++ 2022 X64 ") || name.Contains("Microsoft Visual C++ 2015-2022 Redistributable (x64)"));
|
||||||
if (!installed) {
|
if (!installed) {
|
||||||
Console.WriteLine(App.VcRuntimeDownload);
|
Console.WriteLine(App.VcRuntimeDownload);
|
||||||
var pkgPath = Path.Combine(GlobalVars.DataPath, "vc_redist.x64.exe");
|
var pkgPath = Path.Combine(GlobalVars.DataPath, "vc_redist.x64.exe");
|
||||||
|
|||||||
Reference in New Issue
Block a user