mirror of
https://ghfast.top/https://github.com/StarCitizenToolBox/app.git
synced 2025-05-10 05:01:23 +08:00
Compare commits
208 Commits
Author | SHA1 | Date | |
---|---|---|---|
184290aaf4 | |||
14b16f3a78 | |||
b2ec1e93a8 | |||
cb35c400f9 | |||
3c061f995c | |||
03c941c970 | |||
a2de310d84 | |||
85bc6e487b | |||
033e2824a4 | |||
3b940ead08 | |||
|
01f16201a9 | ||
|
251fe08139 | ||
|
88f9a6eccc | ||
|
404b0ec958 | ||
|
fc59eb3879 | ||
|
fef65f6c2a | ||
|
5728ed8379 | ||
|
368bf04a9a | ||
|
48ab2e28b2 | ||
|
1343ac650f | ||
|
16dab8236b | ||
72f3cbd2d7 | |||
a75a580b2d | |||
320ce177b9 | |||
a6de0364c1 | |||
|
5b8314411b | ||
ac72bcb554 | |||
71844945f2 | |||
fdc4060ac0 | |||
8dd7ef53a1 | |||
c02c98a19e | |||
|
4b875b7898 | ||
|
ac959a9faa | ||
|
26e4908101 | ||
|
41b66ca33f | ||
|
bea907b817 | ||
f5f3e4753c | |||
b18024a8ce | |||
b830b2b863 | |||
|
cb77b69fa1 | ||
|
722b0693fd | ||
|
6a90930bca | ||
|
d747294662 | ||
ebc469f3c1 | |||
6a8614406c | |||
dd8325e78b | |||
721ba6a3c2 | |||
d65eb82ece | |||
a902bf82a0 | |||
b091022799 | |||
0afa8c0386 | |||
|
53e28d7272 | ||
|
d2f21661b8 | ||
|
580498a71a | ||
|
69ee1bcc9e | ||
|
258405bcf5 | ||
|
026933c25f | ||
|
3b50830dab | ||
|
73ad2ad023 | ||
|
96aea196a6 | ||
|
f45e9849a0 | ||
|
b881e825a9 | ||
|
ac36c0c248 | ||
|
8a679a0a66 | ||
7be9bdf7c3 | |||
cfa6f18a58 | |||
43d0d8454c | |||
|
33f8866bb9 | ||
a0d4d8b32d | |||
c112a920ec | |||
|
f415ee3469 | ||
|
fe4f330e5e | ||
|
ddcd6d8f16 | ||
|
16e50e6d75 | ||
|
3ce485df5c | ||
|
61ee05f5b2 | ||
8249d577be | |||
|
5ebe438584 | ||
|
2a009a1a51 | ||
4b70ec1914 | |||
4c6a5f7565 | |||
82943020f7 | |||
4297b2f530 | |||
772f329407 | |||
f8a846e706 | |||
cd788b6fe5 | |||
|
9e4523c891 | ||
|
3dd68c7c87 | ||
a9a85607b0 | |||
11738da6a5 | |||
9789b9e1a9 | |||
56208e1909 | |||
472fdb08fb | |||
1681e2407b | |||
49cef9ed90 | |||
9f7e0dad52 | |||
281f6ee995 | |||
8d07af2253 | |||
8a58719908 | |||
0577b54f9c | |||
3c59a2ca57 | |||
0c03050f5c | |||
7e1e96707c | |||
c6ced405ef | |||
|
11a54501c0 | ||
|
74527178b7 | ||
|
1dec934d6a | ||
|
94ffcb8118 | ||
|
e9708827df | ||
|
75d9fc7e5e | ||
|
eb1ee49085 | ||
|
5fb0df38b0 | ||
|
5cb9e931c7 | ||
|
57c6dd7fd1 | ||
|
f969a084ae | ||
|
15773e6639 | ||
|
c9114bb202 | ||
|
9713c62c46 | ||
|
5822dec69e | ||
|
ae920fca8f | ||
|
bbca12e3a2 | ||
|
e31902d67e | ||
e37acfdaed | |||
f81aae82ab | |||
72cdf77a74 | |||
6df16058ac | |||
abfd31e001 | |||
53087306a8 | |||
197053380d | |||
495dfd2c94 | |||
|
968a2a957b | ||
|
3757c27939 | ||
2a940b9312 | |||
2f17dba2fa | |||
|
6e1e50f34e | ||
|
bfc0c5d3d7 | ||
8c6c980bb8 | |||
6a6360540b | |||
d905f8c13e | |||
0d70cb711a | |||
f283f4db43 | |||
3ce635075c | |||
ffd32ec7ff | |||
|
ba102bbab8 | ||
|
79d56dd267 | ||
|
134b4f0983 | ||
|
6090d772fe | ||
3da318ec71 | |||
f453821e15 | |||
|
de955f1226 | ||
|
636f5cdb53 | ||
|
340e38a8e7 | ||
|
f0a3b527cf | ||
|
d1c7f2b72b | ||
|
e5d83aea04 | ||
cf7230f980 | |||
44ec80cc73 | |||
53e44db817 | |||
41f10e408f | |||
bc25c92bba | |||
8fee9dba05 | |||
6ff0b7c902 | |||
79239de308 | |||
7def53649a | |||
4dd47d02eb | |||
4d36b5d7c1 | |||
bbd1aa91ff | |||
26e28799ff | |||
83adfbc303 | |||
a9980208d3 | |||
f88f73d3a8 | |||
|
ae14a26f08 | ||
|
c6720baa5e | ||
|
d1716bd873 | ||
|
853b9034c0 | ||
c7d70084d8 | |||
2e69068209 | |||
38a1ddab72 | |||
6265acb2ad | |||
cd812cac66 | |||
5cf8d5a0a0 | |||
a94f49eca2 | |||
62289b3b30 | |||
536daa176a | |||
cb69211a78 | |||
|
222b9e8fef | ||
|
8913fe167f | ||
|
8b78c6d052 | ||
|
f413d924ad | ||
|
ebbce1ed57 | ||
|
dc5392258f | ||
b530742634 | |||
20227fbd4b | |||
|
56d4988cfc | ||
|
47c6f2205a | ||
003a6d1cb1 | |||
|
f7dfe108c9 | ||
|
638f8760b7 | ||
3f7ee82d45 | |||
|
ad70e21e2c | ||
|
976d3474f9 | ||
|
5f0b11d6ef | ||
|
a114f052b1 | ||
32b7f2a9fc | |||
858479f28e | |||
|
c90bc803b5 | ||
40dec20b89 | |||
725277eef7 |
4
.github/workflows/windows_nightly.yml
vendored
4
.github/workflows/windows_nightly.yml
vendored
@ -61,11 +61,11 @@ jobs:
|
||||
flutter pub global activate intl_utils
|
||||
flutter pub global run intl_utils:generate
|
||||
- name: Flutter build Windows
|
||||
run: flutter build windows
|
||||
run: flutter build windows -v
|
||||
|
||||
- name: Archive build
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows
|
||||
path: build/windows/x64/runner/Release
|
||||
|
||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -42,8 +42,9 @@ app.*.map.json
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
/pubspec.lock
|
||||
/rust/target/
|
||||
/rust/Cargo.lock
|
||||
/lib/generated/l10n_temp.json
|
||||
/lib/generated/l10n_temp_fix.json
|
||||
|
||||
# FVM Version Cache
|
||||
.fvm/
|
29
.metadata
29
.metadata
@ -1,11 +1,11 @@
|
||||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled.
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf
|
||||
channel: stable
|
||||
revision: "a14f74ff3a1cbd521163c5f03d68113d50af93d3"
|
||||
channel: "stable"
|
||||
|
||||
project_type: app
|
||||
|
||||
@ -13,11 +13,26 @@ project_type: app
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf
|
||||
base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf
|
||||
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
- platform: android
|
||||
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
- platform: ios
|
||||
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
- platform: linux
|
||||
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
- platform: macos
|
||||
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
- platform: web
|
||||
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
- platform: windows
|
||||
create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf
|
||||
base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf
|
||||
create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
|
||||
|
||||
# User provided section
|
||||
|
||||
|
65
.vscode/launch.json
vendored
Normal file
65
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
{
|
||||
// 使用 IntelliSense 了解相关属性。
|
||||
// 悬停以查看现有属性的描述。
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "StarCitizenToolBox",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
},
|
||||
{
|
||||
"name": "StarCitizenToolBox (MSE mode)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"args": [
|
||||
"--dart-define=MSE=true"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "StarCitizenToolBox (profile mode)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "profile"
|
||||
},
|
||||
{
|
||||
"name": "StarCitizenToolBox (release mode)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "release"
|
||||
},
|
||||
{
|
||||
"name": "rust_builder",
|
||||
"cwd": "rust_builder",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
},
|
||||
{
|
||||
"name": "rust_builder (profile mode)",
|
||||
"cwd": "rust_builder",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "profile"
|
||||
},
|
||||
{
|
||||
"name": "rust_builder (release mode)",
|
||||
"cwd": "rust_builder",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "release"
|
||||
},
|
||||
{
|
||||
"name": "sct_dev_tools",
|
||||
"cwd": "packages\\sct_dev_tools",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
},
|
||||
{
|
||||
"name": "build_tool",
|
||||
"cwd": "rust_builder\\cargokit\\build_tool",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
}
|
||||
]
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
|
||||
该工具为 星际公民玩家 提供 一键诊断,官网及工具网站汉化,游戏汉化,游戏性能优化 等功能,致力于带来更愉快的游戏体验。
|
||||
|
||||
[](https://github.com/StarCitizenToolBox/app/actions/workflows/windows_nightly.yml)
|
||||
[](https://github.com/StarCitizenToolBox/app/actions/workflows/windows_nightly.yml) [](http://translate.42kit.com/engage/sctoolbox/)
|
||||
|
||||
[](https://apps.microsoft.com/detail/9NF3SWFWNKL1?launch=true)
|
||||
|
||||
@ -26,6 +26,5 @@
|
||||

|
||||

|
||||
### ❤️ 鸣谢
|
||||

|
||||
|
||||
特别感谢 [JetBrains](https://www.jetbrains.com/?from=SCToolbox) 为开源项目提供免费的 IDE 授权。
|
||||
特别感谢 [Visual Studio Code](https://code.visualstudio.com/) 提供免费的开发工具。
|
||||
|
@ -27,6 +27,5 @@ This tool provides Star Citizen players with one-click diagnosis, official websi
|
||||

|
||||
|
||||
### ❤️ Thanks
|
||||

|
||||
|
||||
Special thanks to [JetBrains](https://www.jetbrains.com/?from=SCToolbox) for providing free IDE licenses for open source projects.
|
||||
Special thanks to [Visual Studio Code](https://code.visualstudio.com/) for providing free development tools.
|
@ -1,21 +1,21 @@
|
||||
# SC 工具箱
|
||||
# SC 工具箱 / SCToolBox
|
||||
|
||||
[简体中文](https://github.com/StarCitizenToolBox/app/blob/main/README.md) / [繁體中文](https://github.com/StarCitizenToolBox/app/blob/main/README_zh-TW.md)
|
||||
[简体中文](https://github.com/StarCitizenToolBox/app/blob/main/README.md) / [繁體中文](https://github.com/StarCitizenToolBox/app/blob/main/README_zh-TW.md) / [English](https://github.com/StarCitizenToolBox/app/blob/main/README_en.md)
|
||||
|
||||
此工具為星際公民玩家提供疑難排解、官網及工具網站中文翻譯、遊戲翻譯、效能最佳化/畫面改善等功能,帶給您更愉快的遊戲體驗。
|
||||
這個工具能為星際公民玩家提供疑難排解、官方網站及工具網站的中文翻譯、遊戲文本在地化翻譯、效能最佳化/畫面改善等功能,讓您獲得更愉快的遊戲體驗。
|
||||
|
||||
[](https://github.com/StarCitizenToolBox/app/actions/workflows/windows_nightly.yml)
|
||||
[](https://github.com/StarCitizenToolBox/app/actions/workflows/windows_nightly.yml) [](http://translate.42kit.com/engage/sctoolbox/)
|
||||
|
||||
[](https://apps.microsoft.com/detail/9NF3SWFWNKL1?launch=true)
|
||||
|
||||
|
||||
### ✨ 功能
|
||||
- 本地化社群翻譯管理:一鍵快速安裝社群翻譯與切換遊戲語言
|
||||
- 疑難排解:來自上百名小白鼠使用者的日誌文件,可處理常見星際公民問題
|
||||
- 網站中文翻譯:為星際公民官網,星際公民工具網站提供人工精翻 (感謝星際公民中文百科計畫),亦提供[瀏覽器擴充套件 (Github)](https://github.com/xkeyC/StarCitizenBoxBrowserEx )。
|
||||
- 效能最佳化/畫面改善:為星際公民遊戲增加更細緻的效能參數控制,可用於最佳化效能,也可用於獲得更好的畫質。
|
||||
- 伺服器狀態指示器:比官網啟動器早了幾個小時增加了伺服器狀態指示功能,且指示的更為細緻。
|
||||
- 其他常用工具:包括 p4k分流下載,清除著色器快取,重新安裝EAC等多種功能在內的工具箱。
|
||||
- 社群在地化翻譯管理:一鍵即可快速完成社群翻譯安裝與切換遊戲語言
|
||||
- 疑難排解:來自上百名小白鼠使用者的日誌文件,可處理常見的星際公民遊戲問題
|
||||
- 網站中文翻譯:為星際公民官方網站及工具網站提供人工精翻 (感謝星際公民中文百科計畫),亦提供[瀏覽器擴充套件 (Github)](https://github.com/xkeyC/StarCitizenBoxBrowserEx )。
|
||||
- 效能最佳化/畫面改善:為星際公民遊戲增加更細緻的效能參數調整,能夠用於改善遊戲效能,也可以用於獲得更好的畫質。
|
||||
- 伺服器狀態指示器:比官方啟動器早了幾個小時增加了伺服器狀態指示功能,且指示的更為細緻。
|
||||
- 其他常用工具:包括 p4k 分流下載,著色器快取清理,重新安裝 EAC 反外掛軟體等多種功能在內的工具箱。
|
||||
|
||||
### 📸 螢幕截圖
|
||||

|
||||
@ -27,6 +27,5 @@
|
||||

|
||||
|
||||
### ❤️ 鳴謝
|
||||

|
||||
|
||||
特別感謝 [JetBrains](https://www.jetbrains.com/?from=SCToolbox) 為開源專案提供免費的 IDE 授權。
|
||||
特別感謝 [Visual Studio Code](https://code.visualstudio.com/) 提供的免費開發工具。
|
||||
|
@ -29,6 +29,10 @@ linter:
|
||||
analyzer:
|
||||
plugins:
|
||||
- custom_lint
|
||||
|
||||
exclude:
|
||||
- "**/*.g.dart"
|
||||
- "**/*.freezed.dart"
|
||||
errors:
|
||||
invalid_annotation_target: ignore
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
|
BIN
assets/countdown/bar_citizen.png
Normal file
BIN
assets/countdown/bar_citizen.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 59 KiB |
Binary file not shown.
Before Width: | Height: | Size: 64 KiB |
53
assets/web/input_method/index.html
Normal file
53
assets/web/input_method/index.html
Normal file
@ -0,0 +1,53 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no"/>
|
||||
<meta name="renderer" content="webkit"/>
|
||||
|
||||
<link rel="stylesheet" href="style/mdui2.css">
|
||||
<link href="style/google_icons.css" rel="stylesheet">
|
||||
<script src="js/mdui2.global.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
<title>SCToolBox Community Input Method Web</title>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="mdui-theme-light" style="position: relative;overflow: hidden">
|
||||
<mdui-top-app-bar
|
||||
scroll-behavior="shrink"
|
||||
scroll-threshold="30"
|
||||
scroll-target=".scroll-behavior-shrink">
|
||||
|
||||
<mdui-top-app-bar-title>SC汉化盒子社区输入法</mdui-top-app-bar-title>
|
||||
<div style="flex-grow: 1"></div>
|
||||
|
||||
<mdui-button-icon icon="help" onclick="onShowHelp()"></mdui-button-icon>
|
||||
|
||||
|
||||
</mdui-top-app-bar>
|
||||
|
||||
<div class="scroll-behavior-shrink" style="overflow: auto;">
|
||||
|
||||
<mdui-text-field id="input_message" style="padding-top: 6pt;padding-bottom: 6pt" rows="6" variant="outlined"
|
||||
label="输入消息..."></mdui-text-field>
|
||||
|
||||
<div style="text-align: end">
|
||||
<mdui-checkbox id="auto_copy" checked>自动复制</mdui-checkbox>
|
||||
</div>
|
||||
|
||||
<mdui-button id="send_button" icon="send" onclick="onSendMessage()" full-width>发送</mdui-button>
|
||||
|
||||
</div>
|
||||
|
||||
<mdui-snackbar id="snackbar_message" auto-close-delay="1000">Text</mdui-snackbar>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
init();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
56
assets/web/input_method/js/main.js
Normal file
56
assets/web/input_method/js/main.js
Normal file
@ -0,0 +1,56 @@
|
||||
async function init() {
|
||||
try {
|
||||
let response = await fetch("/api");
|
||||
let responseJson = await response.json();
|
||||
if (responseJson.status === "ok") {
|
||||
showMessage("服务连接成功!");
|
||||
} else {
|
||||
showMessage("服务连接失败!" + responseJson);
|
||||
}
|
||||
} catch (e) {
|
||||
showMessage("服务连接失败!" + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function onSendMessage() {
|
||||
let send_button = document.getElementById("send_button");
|
||||
let input = document.getElementById("input_message");
|
||||
let isAutoCopy = document.getElementById("auto_copy").checked;
|
||||
let messageJson = {
|
||||
"text": input.value,
|
||||
"autoCopy": isAutoCopy,
|
||||
"autoInput": false
|
||||
};
|
||||
send_button.loading = true;
|
||||
try {
|
||||
let response = await fetch("/api/send", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(messageJson)
|
||||
});
|
||||
let responseJson = await response.json();
|
||||
console.log(responseJson);
|
||||
showMessage(responseJson.message);
|
||||
if (response.ok) {
|
||||
input.value = "";
|
||||
}
|
||||
} catch (e) {
|
||||
showMessage("发送失败!" + e);
|
||||
}
|
||||
send_button.loading = false;
|
||||
}
|
||||
|
||||
function showMessage(message) {
|
||||
let snack = document.getElementById("snackbar_message");
|
||||
snack.open = false;
|
||||
snack.innerText = message;
|
||||
snack.open = true;
|
||||
}
|
||||
|
||||
function onShowHelp() {
|
||||
alert("在浏览器中输入文本,将发送给汉化盒子转码。" +
|
||||
"\n\n自动复制:勾选后自动复制转码结果到剪贴板。");
|
||||
}
|
22
assets/web/input_method/js/mdui2.global.js
Normal file
22
assets/web/input_method/js/mdui2.global.js
Normal file
File diff suppressed because one or more lines are too long
BIN
assets/web/input_method/style/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2
Normal file
BIN
assets/web/input_method/style/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2
Normal file
Binary file not shown.
23
assets/web/input_method/style/google_icons.css
Normal file
23
assets/web/input_method/style/google_icons.css
Normal file
@ -0,0 +1,23 @@
|
||||
/* fallback */
|
||||
@font-face {
|
||||
font-family: 'Material Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2) format('woff2');
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-feature-settings: 'liga';
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
1
assets/web/input_method/style/mdui2.css
Normal file
1
assets/web/input_method/style/mdui2.css
Normal file
File diff suppressed because one or more lines are too long
@ -51,7 +51,7 @@ function WebLocalizationUpdateReplaceWords(w, b) {
|
||||
let replaceWords = w.sort(function (a, b) {
|
||||
return b.word.length - a.word.length;
|
||||
});
|
||||
replaceWords.forEach(({word, replacement}) => {
|
||||
replaceWords.forEach(({ word, replacement }) => {
|
||||
SCLocalizationReplaceLocalesMap[word] = replacement;
|
||||
});
|
||||
if (window.location.hostname.startsWith("issue-council.robertsspaceindustries.com")) {
|
||||
@ -197,8 +197,6 @@ function GetSCLocalizationTranslateString(txtSrc) {
|
||||
return txtSrc
|
||||
}
|
||||
|
||||
InitWebLocalization();
|
||||
|
||||
function ReportUnTranslate(k, v) {
|
||||
|
||||
if (enable_webview_localization_capture) {
|
||||
@ -209,7 +207,7 @@ function ReportUnTranslate(k, v) {
|
||||
const jsRegex = /(?:^|[^<])<script[^>]*>[\s\S]*?<\/script>(?:[^>]|$)/i;
|
||||
if (k.trim() !== "" && !cnPattern.test(k) && !htmlPattern.test(k) && !cssRegex.test(k) && !jsRegex.test(k)
|
||||
&& enPattern.test(k) && !k.startsWith("http://") && !k.startsWith("https://")) {
|
||||
window.chrome.webview.postMessage({action: 'webview_localization_capture', key: k, value: v});
|
||||
window.chrome.webview.postMessage({ action: 'webview_localization_capture', key: k, value: v });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -222,35 +220,27 @@ async function getRSILauncherToken(channelId) {
|
||||
if (!window.location.href.includes("robertsspaceindustries.com")) return;
|
||||
|
||||
let loginBodyElement = $(".c-form.c-signIn");
|
||||
loginBodyElement.hide();
|
||||
// check login
|
||||
let r = await fetch("api/launcher/v3/account/check", {
|
||||
method: 'POST', headers: {
|
||||
'x-rsi-token': $.cookie('Rsi-Token'),
|
||||
},
|
||||
});
|
||||
if (r.status !== 200) {
|
||||
loginBodyElement.show();
|
||||
// wait login
|
||||
window.chrome.webview.postMessage({action: 'webview_rsi_login_show_window'});
|
||||
return;
|
||||
}
|
||||
|
||||
SCTShowToast("登录游戏中...");
|
||||
loginBodyElement.show();
|
||||
// wait login
|
||||
window.chrome.webview.postMessage({ action: 'webview_rsi_login_show_window' });
|
||||
|
||||
// get claims
|
||||
let claimsR = await fetch("api/launcher/v3/games/claims", {
|
||||
let claimsR = await fetch("https://robertsspaceindustries.com/api/launcher/v3/games/claims", {
|
||||
method: 'POST', headers: {
|
||||
'x-rsi-token': $.cookie('Rsi-Token'),
|
||||
},
|
||||
});
|
||||
if (claimsR.status !== 200) return;
|
||||
|
||||
loginBodyElement.hide();
|
||||
SCTShowToast("登录游戏中...");
|
||||
|
||||
let claimsData = (await claimsR.json())["data"];
|
||||
|
||||
let tokenFormData = new FormData();
|
||||
tokenFormData.append('claims', claimsData);
|
||||
tokenFormData.append('gameId', 'SC');
|
||||
let tokenR = await fetch("api/launcher/v3/games/token", {
|
||||
let tokenR = await fetch("https://robertsspaceindustries.com/api/launcher/v3/games/token", {
|
||||
method: 'POST', headers: {
|
||||
'x-rsi-token': $.cookie('Rsi-Token'),
|
||||
},
|
||||
@ -267,7 +257,7 @@ async function getRSILauncherToken(channelId) {
|
||||
releaseFormData.append("claims", claimsData);
|
||||
releaseFormData.append("gameId", "SC");
|
||||
releaseFormData.append("platformId", "prod");
|
||||
let releaseR = await fetch("api/launcher/v3/games/release", {
|
||||
let releaseR = await fetch("https://robertsspaceindustries.com/api/launcher/v3/games/release", {
|
||||
method: 'POST', headers: {
|
||||
'x-rsi-token': $.cookie('Rsi-Token'),
|
||||
},
|
||||
@ -277,7 +267,7 @@ async function getRSILauncherToken(channelId) {
|
||||
let releaseDataJson = (await releaseR.json())['data'];
|
||||
console.log(releaseDataJson);
|
||||
// get game library
|
||||
let libraryR = await fetch("api/launcher/v3/games/library", {
|
||||
let libraryR = await fetch("https://robertsspaceindustries.com/api/launcher/v3/games/library", {
|
||||
method: 'POST', headers: {
|
||||
'x-rsi-token': $.cookie('Rsi-Token'),
|
||||
},
|
||||
@ -287,8 +277,7 @@ async function getRSILauncherToken(channelId) {
|
||||
let libraryData = (await libraryR.json())["data"]
|
||||
|
||||
// get user avatar
|
||||
let $avatarElement = $(".c-account-sidebar__profile-metas-avatar");
|
||||
let avatarUrl = $avatarElement.css("background-image");
|
||||
let avatarUrl = $(".orion-c-avatar__image").attr("src");
|
||||
|
||||
//post message
|
||||
window.chrome.webview.postMessage({
|
||||
|
@ -1,11 +1,13 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/url_conf.dart';
|
||||
import 'package:starcitizen_doctor/common/io/rs_http.dart';
|
||||
import 'package:starcitizen_doctor/data/app_placard_data.dart';
|
||||
import 'package:starcitizen_doctor/data/app_torrent_data.dart';
|
||||
import 'package:starcitizen_doctor/data/app_version_data.dart';
|
||||
import 'package:starcitizen_doctor/data/countdown_festival_item_data.dart';
|
||||
import 'package:starcitizen_doctor/data/input_method_api_data.dart';
|
||||
import 'package:starcitizen_doctor/data/sc_localization_data.dart';
|
||||
|
||||
class Api {
|
||||
@ -51,6 +53,15 @@ class Api {
|
||||
return l;
|
||||
}
|
||||
|
||||
static Future<InputMethodApiData> getCommunityInputMethodIndexData() async {
|
||||
final data = await getCommunityInputMethodData("index.json");
|
||||
return InputMethodApiData.fromJson(json.decode(data));
|
||||
}
|
||||
|
||||
static Future<String> getCommunityInputMethodData(String file) async {
|
||||
return getRepoData("input_method", file);
|
||||
}
|
||||
|
||||
static Future<List<AppTorrentData>> getAppTorrentDataList() async {
|
||||
final data = await getRepoData("sc_doctor", "torrent.json");
|
||||
final dataJson = json.decode(data);
|
||||
@ -82,7 +93,32 @@ class Api {
|
||||
}
|
||||
|
||||
static Future<String> getRepoData(String dir, String name) async {
|
||||
final r = await RSHttp.getText("${URLConf.apiRepoPath}/$dir/$name");
|
||||
final r = await RSHttp.getText("${URLConf.apiRepoPath}/$dir/$name",
|
||||
withCustomDns: await isUseInternalDNS());
|
||||
return r;
|
||||
}
|
||||
|
||||
static Future<String?> doGoogleTranslate(String input) async {
|
||||
final out = await RSHttp.getText(
|
||||
"${URLConf.googleTranslateApiUrl}/translate_a/single?client=gtx&dt=t&sl=auto&tl=en&q=${Uri.encodeComponent(input)}");
|
||||
// [[["Hello","你好",null,null,10]],null,"zh-CN",null,null,null,1,[],[["zh-CN"],null,[1],["zh-CN"]]]
|
||||
final list = json.decode(out);
|
||||
if (list is List && list.isNotEmpty) {
|
||||
final data = list.first;
|
||||
if (data is List && data.isNotEmpty) {
|
||||
final text = data.first;
|
||||
if (text is List && text.isNotEmpty) {
|
||||
return text.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static Future<bool> isUseInternalDNS() async {
|
||||
final userBox = await Hive.openBox("app_conf");
|
||||
final isUseInternalDNS =
|
||||
userBox.get("isUseInternalDNS", defaultValue: false);
|
||||
return isUseInternalDNS;
|
||||
}
|
||||
}
|
||||
|
@ -12,11 +12,9 @@ class RSSApi {
|
||||
}
|
||||
|
||||
static Future<List<RssItem>> getRssText() async {
|
||||
final r1 = await RSHttp.getText(URLConf.rssTextUrl1);
|
||||
final r1f = RssFeed.parse(r1);
|
||||
final r2 = await RSHttp.getText(URLConf.rssTextUrl2);
|
||||
final r2f = RssFeed.parse(r2);
|
||||
final items = r1f.items..addAll(r2f.items);
|
||||
final items = r2f.items;
|
||||
items.sort((a, b) {
|
||||
final aDate = HttpDate.parse(a.pubDate ?? "").millisecondsSinceEpoch;
|
||||
final bDate = HttpDate.parse(b.pubDate ?? "").millisecondsSinceEpoch;
|
||||
|
14
lib/api/udb.dart
Normal file
14
lib/api/udb.dart
Normal file
@ -0,0 +1,14 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:starcitizen_doctor/common/conf/url_conf.dart';
|
||||
import 'package:starcitizen_doctor/common/io/rs_http.dart';
|
||||
import 'package:starcitizen_doctor/data/nav_api_data.dart';
|
||||
|
||||
class UDBNavApi {
|
||||
static Future<NavApiData> getNavItems({int pageNo = 1}) async {
|
||||
final r = await RSHttp.getText(URLConf.nav42KitUrl);
|
||||
if (r.isEmpty) throw "Network Error";
|
||||
final result = NavApiData.fromJson(jsonDecode(r));
|
||||
return result;
|
||||
}
|
||||
}
|
169
lib/app.dart
169
lib/app.dart
@ -3,14 +3,16 @@ import 'dart:io';
|
||||
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter_acrylic/flutter_acrylic.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hexcolor/hexcolor.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/const_conf.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/conf.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/ui/guide/guide_ui.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/performance/performance_ui.dart';
|
||||
import 'package:starcitizen_doctor/ui/splash_ui.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
@ -20,6 +22,7 @@ import 'package:window_manager/window_manager.dart';
|
||||
|
||||
import 'api/analytics.dart';
|
||||
import 'api/api.dart';
|
||||
import 'common/conf/url_conf.dart';
|
||||
import 'common/helper/system_helper.dart';
|
||||
import 'common/io/rs_http.dart';
|
||||
import 'common/rust/frb_generated.dart';
|
||||
@ -51,46 +54,40 @@ class AppGlobalState with _$AppGlobalState {
|
||||
}
|
||||
|
||||
@riverpod
|
||||
GoRouter router(RouterRef ref) {
|
||||
GoRouter router(Ref ref) {
|
||||
return GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const SplashUI()),
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const SplashUI()),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/index',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const IndexUI()),
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const IndexUI()),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: "downloader",
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const HomeDownloaderUI())),
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const HomeDownloaderUI())),
|
||||
GoRoute(
|
||||
path: 'game_doctor',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const HomeGameDoctorUI()),
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const HomeGameDoctorUI()),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'performance',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const HomePerformanceUI()),
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const HomePerformanceUI()),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'advanced_localization',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const AdvancedLocalizationUI()))
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const AdvancedLocalizationUI()))
|
||||
],
|
||||
),
|
||||
GoRoute(path: '/tools', builder: (_, __) => const SizedBox(), routes: [
|
||||
GoRoute(
|
||||
path: 'unp4kc',
|
||||
pageBuilder: (context, state) =>
|
||||
myPageBuilder(context, state, const UnP4kcUI()),
|
||||
pageBuilder: (context, state) => myPageBuilder(context, state, const UnP4kcUI()),
|
||||
),
|
||||
]),
|
||||
GoRoute(path: '/guide', pageBuilder: (context, state) => myPageBuilder(context, state, const GuideUI()))
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -103,6 +100,7 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
const Locale("zh", "TW"): NoL10n.langZHT,
|
||||
const Locale("en"): NoL10n.langEn,
|
||||
const Locale("ja"): NoL10n.langJa,
|
||||
const Locale("ru"): NoL10n.langRU,
|
||||
};
|
||||
|
||||
@override
|
||||
@ -115,27 +113,7 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
Future<void> initApp() async {
|
||||
if (_initialized) return;
|
||||
// init Data
|
||||
final userProfileDir = Platform.environment["USERPROFILE"];
|
||||
final applicationSupportDir =
|
||||
(await getApplicationSupportDirectory()).absolute.path;
|
||||
String? applicationBinaryModuleDir;
|
||||
try {
|
||||
await initDPrintFile(applicationSupportDir);
|
||||
} catch (e) {
|
||||
dPrint("initDPrintFile Error: $e");
|
||||
}
|
||||
if (ConstConf.isMSE && userProfileDir != null) {
|
||||
applicationBinaryModuleDir =
|
||||
"$userProfileDir\\AppData\\Local\\Temp\\SCToolbox\\modules";
|
||||
} else {
|
||||
applicationBinaryModuleDir = "$applicationSupportDir\\modules";
|
||||
}
|
||||
dPrint("applicationSupportDir == $applicationSupportDir");
|
||||
dPrint("applicationBinaryModuleDir == $applicationBinaryModuleDir");
|
||||
state = state.copyWith(
|
||||
applicationSupportDir: applicationSupportDir,
|
||||
applicationBinaryModuleDir: applicationBinaryModuleDir,
|
||||
);
|
||||
final applicationSupportDir = await _initAppDir();
|
||||
|
||||
// init Rust bridge
|
||||
await RustLib.init();
|
||||
@ -170,11 +148,13 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
}
|
||||
|
||||
// init powershell
|
||||
try {
|
||||
await SystemHelper.initPowershellPath();
|
||||
dPrint("---- Powershell init -----");
|
||||
} catch (e) {
|
||||
dPrint("powershell init failed : $e");
|
||||
if (Platform.isWindows) {
|
||||
try {
|
||||
await SystemHelper.initPowershellPath();
|
||||
dPrint("---- Powershell init -----");
|
||||
} catch (e) {
|
||||
dPrint("powershell init failed : $e");
|
||||
}
|
||||
}
|
||||
|
||||
// get windows info
|
||||
@ -187,19 +167,18 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
}
|
||||
|
||||
// init windows
|
||||
|
||||
windowManager.waitUntilReadyToShow().then((_) async {
|
||||
await windowManager.setTitle("SCToolBox");
|
||||
await windowManager.setSize(const Size(1280, 810));
|
||||
await windowManager.setMinimumSize(const Size(1280, 810));
|
||||
await windowManager.setSkipTaskbar(false);
|
||||
await windowManager.show();
|
||||
await Window.initialize();
|
||||
await Window.hideWindowControls();
|
||||
if (windowsDeviceInfo?.productName.contains("Windows 11") ?? false) {
|
||||
await Window.setEffect(
|
||||
effect: WindowEffect.acrylic,
|
||||
);
|
||||
if (Platform.isWindows) {
|
||||
await Window.initialize();
|
||||
await Window.hideWindowControls();
|
||||
if (windowsDeviceInfo?.productName.contains("Windows 11") ?? false) {
|
||||
await Window.setEffect(
|
||||
effect: WindowEffect.acrylic,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -212,6 +191,8 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
return "${state.applicationSupportDir}/._upgrade";
|
||||
}
|
||||
|
||||
bool isInOnlineMode() => state.networkVersionData != null;
|
||||
|
||||
// ignore: avoid_build_context_in_providers
|
||||
Future<bool> checkUpdate(BuildContext context) async {
|
||||
if (!ConstConf.isMSE) {
|
||||
@ -225,15 +206,18 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
|
||||
try {
|
||||
final networkVersionData = await Api.getAppVersion();
|
||||
dPrint("networkVersionData == ${networkVersionData.toJson()}");
|
||||
AppConf.setNetworkChannels(networkVersionData.gameChannels);
|
||||
checkActivityThemeColor(networkVersionData);
|
||||
if (ConstConf.isMSE) {
|
||||
dPrint(
|
||||
"lastVersion=${networkVersionData.mSELastVersion} ${networkVersionData.mSELastVersionCode}");
|
||||
dPrint("lastVersion=${networkVersionData.mSELastVersion} ${networkVersionData.mSELastVersionCode}");
|
||||
} else {
|
||||
dPrint(
|
||||
"lastVersion=${networkVersionData.lastVersion} ${networkVersionData.lastVersionCode}");
|
||||
dPrint("lastVersion=${networkVersionData.lastVersion} ${networkVersionData.lastVersionCode}");
|
||||
}
|
||||
state = state.copyWith(networkVersionData: networkVersionData);
|
||||
if (networkVersionData.nav42KitUrl != null) {
|
||||
URLConf.nav42KitUrl = networkVersionData.nav42KitUrl!;
|
||||
}
|
||||
} catch (e) {
|
||||
checkUpdateError = e;
|
||||
dPrint("_checkUpdate Error:$e");
|
||||
@ -243,22 +227,18 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
if (state.networkVersionData == null) {
|
||||
if (!context.mounted) return false;
|
||||
await showToast(
|
||||
context,
|
||||
S.current.app_common_network_error(
|
||||
ConstConf.appVersionDate, checkUpdateError.toString()));
|
||||
context, S.current.app_common_network_error(ConstConf.appVersionDate, checkUpdateError.toString()));
|
||||
return false;
|
||||
}
|
||||
final lastVersion = ConstConf.isMSE
|
||||
? state.networkVersionData?.mSELastVersionCode
|
||||
: state.networkVersionData?.lastVersionCode;
|
||||
if (!Platform.isWindows) return false;
|
||||
final lastVersion =
|
||||
ConstConf.isMSE ? state.networkVersionData?.mSELastVersionCode : state.networkVersionData?.lastVersionCode;
|
||||
if ((lastVersion ?? 0) > ConstConf.appVersionCode) {
|
||||
// need update
|
||||
if (!context.mounted) return false;
|
||||
|
||||
final r = await showDialog(
|
||||
dismissWithEsc: false,
|
||||
context: context,
|
||||
builder: (context) => const UpgradeDialogUI());
|
||||
final r =
|
||||
await showDialog(dismissWithEsc: false, context: context, builder: (context) => const UpgradeDialogUI());
|
||||
|
||||
if (r != true) {
|
||||
if (!context.mounted) return false;
|
||||
@ -285,8 +265,8 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
|
||||
dPrint("now == $now start == $startTime end == $endTime");
|
||||
if (now < startTime) {
|
||||
_activityThemeColorTimer = Timer(Duration(milliseconds: startTime - now),
|
||||
() => checkActivityThemeColor(networkVersionData));
|
||||
_activityThemeColorTimer =
|
||||
Timer(Duration(milliseconds: startTime - now), () => checkActivityThemeColor(networkVersionData));
|
||||
dPrint("start Timer ....");
|
||||
} else if (now >= startTime && now <= endTime) {
|
||||
dPrint("update Color ....");
|
||||
@ -294,22 +274,21 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
final colorCfg = networkVersionData.activityColors;
|
||||
state = state.copyWith(
|
||||
themeConf: ThemeConf(
|
||||
backgroundColor:
|
||||
HexColor(colorCfg?.background ?? "#132431").withOpacity(.75),
|
||||
menuColor: HexColor(colorCfg?.menu ?? "#132431").withOpacity(.95),
|
||||
backgroundColor: HexColor(colorCfg?.background ?? "#132431").withValues(alpha: .75),
|
||||
menuColor: HexColor(colorCfg?.menu ?? "#132431").withValues(alpha: .95),
|
||||
micaColor: HexColor(colorCfg?.mica ?? "#0A3142"),
|
||||
),
|
||||
);
|
||||
|
||||
// wait for end
|
||||
_activityThemeColorTimer = Timer(Duration(milliseconds: endTime - now),
|
||||
() => checkActivityThemeColor(networkVersionData));
|
||||
_activityThemeColorTimer =
|
||||
Timer(Duration(milliseconds: endTime - now), () => checkActivityThemeColor(networkVersionData));
|
||||
} else {
|
||||
dPrint("reset Color ....");
|
||||
state = state.copyWith(
|
||||
themeConf: ThemeConf(
|
||||
backgroundColor: HexColor("#132431").withOpacity(.75),
|
||||
menuColor: HexColor("#132431").withOpacity(.95),
|
||||
backgroundColor: HexColor("#132431").withValues(alpha: .75),
|
||||
menuColor: HexColor("#132431").withValues(alpha: .95),
|
||||
micaColor: HexColor("#0A3142"),
|
||||
),
|
||||
);
|
||||
@ -324,14 +303,48 @@ class AppGlobalModel extends _$AppGlobalModel {
|
||||
await appConfBox.put("app_locale", null);
|
||||
return;
|
||||
}
|
||||
final localeCode = value.countryCode != null
|
||||
? "${value.languageCode}_${value.countryCode ?? ""}"
|
||||
: value.languageCode;
|
||||
final localeCode =
|
||||
value.countryCode != null ? "${value.languageCode}_${value.countryCode ?? ""}" : value.languageCode;
|
||||
dPrint("changeLocale == $value localeCode=== $localeCode");
|
||||
await appConfBox.put("app_locale", localeCode);
|
||||
state = state.copyWith(appLocale: value);
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> _initAppDir() async {
|
||||
if (Platform.isWindows) {
|
||||
final userProfileDir = Platform.environment["USERPROFILE"];
|
||||
final applicationSupportDir = (await getApplicationSupportDirectory()).absolute.path;
|
||||
String? applicationBinaryModuleDir;
|
||||
try {
|
||||
await initDPrintFile(applicationSupportDir);
|
||||
} catch (e) {
|
||||
dPrint("initDPrintFile Error: $e");
|
||||
}
|
||||
if (ConstConf.isMSE && userProfileDir != null) {
|
||||
applicationBinaryModuleDir = "$userProfileDir\\AppData\\Local\\Temp\\SCToolbox\\modules";
|
||||
} else {
|
||||
applicationBinaryModuleDir = "$applicationSupportDir\\modules";
|
||||
}
|
||||
dPrint("applicationSupportDir == $applicationSupportDir");
|
||||
dPrint("applicationBinaryModuleDir == $applicationBinaryModuleDir");
|
||||
state = state.copyWith(
|
||||
applicationSupportDir: applicationSupportDir,
|
||||
applicationBinaryModuleDir: applicationBinaryModuleDir,
|
||||
);
|
||||
return applicationSupportDir;
|
||||
} else {
|
||||
final applicationSupportDir = (await getApplicationSupportDirectory()).absolute.path;
|
||||
final applicationBinaryModuleDir = "$applicationSupportDir/modules";
|
||||
dPrint("applicationSupportDir == $applicationSupportDir");
|
||||
dPrint("applicationBinaryModuleDir == $applicationBinaryModuleDir");
|
||||
state = state.copyWith(
|
||||
applicationSupportDir: applicationSupportDir,
|
||||
applicationBinaryModuleDir: applicationBinaryModuleDir,
|
||||
);
|
||||
return applicationSupportDir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -24,7 +24,9 @@ mixin _$AppGlobalState {
|
||||
Locale? get appLocale => throw _privateConstructorUsedError;
|
||||
Box<dynamic>? get appConfBox => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of AppGlobalState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$AppGlobalStateCopyWith<AppGlobalState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@ -57,6 +59,8 @@ class _$AppGlobalStateCopyWithImpl<$Res, $Val extends AppGlobalState>
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of AppGlobalState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -100,6 +104,8 @@ class _$AppGlobalStateCopyWithImpl<$Res, $Val extends AppGlobalState>
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
/// Create a copy of AppGlobalState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$ThemeConfCopyWith<$Res> get themeConf {
|
||||
@ -138,6 +144,8 @@ class __$$AppGlobalStateImplCopyWithImpl<$Res>
|
||||
_$AppGlobalStateImpl _value, $Res Function(_$AppGlobalStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of AppGlobalState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -249,7 +257,9 @@ class _$AppGlobalStateImpl implements _AppGlobalState {
|
||||
appLocale,
|
||||
appConfBox);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of AppGlobalState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$AppGlobalStateImplCopyWith<_$AppGlobalStateImpl> get copyWith =>
|
||||
@ -281,8 +291,11 @@ abstract class _AppGlobalState implements AppGlobalState {
|
||||
Locale? get appLocale;
|
||||
@override
|
||||
Box<dynamic>? get appConfBox;
|
||||
|
||||
/// Create a copy of AppGlobalState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$AppGlobalStateImplCopyWith<_$AppGlobalStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@ -293,7 +306,9 @@ mixin _$ThemeConf {
|
||||
Color get menuColor => throw _privateConstructorUsedError;
|
||||
Color get micaColor => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of ThemeConf
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$ThemeConfCopyWith<ThemeConf> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@ -316,6 +331,8 @@ class _$ThemeConfCopyWithImpl<$Res, $Val extends ThemeConf>
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of ThemeConf
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -359,6 +376,8 @@ class __$$ThemeConfImplCopyWithImpl<$Res>
|
||||
_$ThemeConfImpl _value, $Res Function(_$ThemeConfImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of ThemeConf
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -423,7 +442,9 @@ class _$ThemeConfImpl implements _ThemeConf {
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, backgroundColor, menuColor, micaColor);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of ThemeConf
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ThemeConfImplCopyWith<_$ThemeConfImpl> get copyWith =>
|
||||
@ -442,8 +463,11 @@ abstract class _ThemeConf implements ThemeConf {
|
||||
Color get menuColor;
|
||||
@override
|
||||
Color get micaColor;
|
||||
|
||||
/// Create a copy of ThemeConf
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$ThemeConfImplCopyWith<_$ThemeConfImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ part of 'app.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$routerHash() => r'4fb9802d06347972b530f17ea7d66724a6ded997';
|
||||
String _$routerHash() => r'cdf659da46a6dfbab2368a85be2f803f54823142';
|
||||
|
||||
/// See also [router].
|
||||
@ProviderFor(router)
|
||||
@ -19,8 +19,10 @@ final routerProvider = AutoDisposeProvider<GoRouter>.internal(
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
typedef RouterRef = AutoDisposeProviderRef<GoRouter>;
|
||||
String _$appGlobalModelHash() => r'9dccbb898714695ef8b640a5b5dfb361783a0f45';
|
||||
String _$appGlobalModelHash() => r'4e372bc744903960e4e7b146dbb394ded15e2c18';
|
||||
|
||||
/// See also [AppGlobalModel].
|
||||
@ProviderFor(AppGlobalModel)
|
||||
@ -37,4 +39,4 @@ final appGlobalModelProvider =
|
||||
|
||||
typedef _$AppGlobalModel = AutoDisposeNotifier<AppGlobalState>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
26
lib/common/conf/conf.dart
Normal file
26
lib/common/conf/conf.dart
Normal file
@ -0,0 +1,26 @@
|
||||
class ConstConf {
|
||||
static const String appVersion = "2.14.1";
|
||||
static const int appVersionCode = 65;
|
||||
static const String appVersionDate = "2025-05-08";
|
||||
static const _gameChannels = [
|
||||
"LIVE",
|
||||
"4.0_PREVIEW",
|
||||
"PTU",
|
||||
"EPTU",
|
||||
"TECH-PREVIEW",
|
||||
"HOTFIX",
|
||||
];
|
||||
static const isMSE = String.fromEnvironment("MSE", defaultValue: "false") == "true";
|
||||
static const dohAddress = "https://223.6.6.6/resolve";
|
||||
static const inputMethodServerPort = 59399;
|
||||
}
|
||||
|
||||
class AppConf {
|
||||
static List<String>? _networkGameChannels;
|
||||
|
||||
static setNetworkChannels(List<String>? channels) {
|
||||
_networkGameChannels = channels;
|
||||
}
|
||||
|
||||
static List<String> get gameChannels => _networkGameChannels ?? ConstConf._gameChannels;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
class ConstConf {
|
||||
static const String appVersion = "2.11.0 Beta";
|
||||
static const int appVersionCode = 50;
|
||||
static const String appVersionDate = "2024-5-07";
|
||||
static const gameChannels = ["LIVE", "PTU", "EPTU", "TECH-PREVIEW"];
|
||||
static const isMSE =
|
||||
String.fromEnvironment("MSE", defaultValue: "false") == "true";
|
||||
}
|
@ -1,11 +1,13 @@
|
||||
import 'package:starcitizen_doctor/api/api.dart';
|
||||
import 'package:starcitizen_doctor/common/io/doh_client.dart';
|
||||
import 'package:starcitizen_doctor/common/io/rs_http.dart';
|
||||
import 'package:starcitizen_doctor/common/rust/http_package.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
|
||||
class URLConf {
|
||||
/// HOME API
|
||||
static String gitApiHome = "https://git.sctoolbox.sccsgo.com";
|
||||
static String rssApiHome = "https://rss.sctoolbox.sccsgo.com";
|
||||
static String gitApiHome = "https://git.scbox.xkeyc.cn";
|
||||
static String rssApiHome = "https://rss.scbox.xkeyc.cn";
|
||||
static const String analyticsApiHome = "https://scbox.org";
|
||||
|
||||
static bool isUrlCheckPass = false;
|
||||
@ -29,27 +31,28 @@ class URLConf {
|
||||
static String get rssVideoUrl =>
|
||||
"$rssApiHome/bilibili/user/channel/27976358/290653";
|
||||
|
||||
static String get rssTextUrl1 => "$rssApiHome/bilibili/user/article/40102960";
|
||||
|
||||
static String get rssTextUrl2 =>
|
||||
"$rssApiHome/baidu/tieba/user/%E7%81%AC%E7%81%ACG%E7%81%AC%E7%81%AC&";
|
||||
|
||||
static const feedbackUrl = "https://txc.qq.com/products/614843";
|
||||
static const String googleTranslateApiUrl =
|
||||
"https://translate-g-proxy.xkeyc.com";
|
||||
|
||||
static const feedbackUrl = "https://support.citizenwiki.cn/all";
|
||||
static const feedbackFAQUrl = "https://support.citizenwiki.cn/t/sc-toolbox";
|
||||
static String nav42KitUrl = "https://payload.citizenwiki.cn/api/community-navs?sort=is_sponsored&depth=2&page=1&limit=1000";
|
||||
|
||||
static String get devReleaseUrl => "$gitApiHome/SCToolBox/Release/releases";
|
||||
|
||||
static Future<bool> checkHost() async {
|
||||
// 使用 DNS 获取可用列表
|
||||
final gitApiList =
|
||||
_genFinalList(await RSHttp.dnsLookupTxt("git.dns.scbox.org"));
|
||||
final gitApiList = _genFinalList(await dnsLookupTxt("git.dns.scbox.org"));
|
||||
dPrint("DNS gitApiList ==== $gitApiList");
|
||||
final fasterGit = await getFasterUrl(gitApiList);
|
||||
dPrint("gitApiList.Faster ==== $fasterGit");
|
||||
if (fasterGit != null) {
|
||||
gitApiHome = fasterGit;
|
||||
}
|
||||
final rssApiList =
|
||||
_genFinalList(await RSHttp.dnsLookupTxt("rss.dns.scbox.org"));
|
||||
final rssApiList = _genFinalList(await dnsLookupTxt("rss.dns.scbox.org"));
|
||||
final fasterRss = await getFasterUrl(rssApiList);
|
||||
dPrint("DNS rssApiList ==== $rssApiList");
|
||||
dPrint("rssApiList.Faster ==== $fasterRss");
|
||||
@ -60,6 +63,15 @@ class URLConf {
|
||||
return isUrlCheckPass;
|
||||
}
|
||||
|
||||
static Future<List<String>> dnsLookupTxt(String host) async {
|
||||
if (await Api.isUseInternalDNS()) {
|
||||
dPrint("[URLConf] use internal DNS LookupTxt $host");
|
||||
return RSHttp.dnsLookupTxt(host);
|
||||
}
|
||||
dPrint("[URLConf] use DOH LookupTxt $host");
|
||||
return (await DohClient.resolveTXT(host)) ?? [];
|
||||
}
|
||||
|
||||
static Future<String?> getFasterUrl(List<String> urls) async {
|
||||
String firstUrl = "";
|
||||
int callLen = 0;
|
||||
|
@ -1,12 +1,13 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/const_conf.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/conf.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
|
||||
class SCLoggerHelper {
|
||||
static Future<String?> getLogFilePath() async {
|
||||
if (!Platform.isWindows) return null;
|
||||
Map<String, String> envVars = Platform.environment;
|
||||
final appDataPath = envVars["appdata"];
|
||||
if (appDataPath == null) {
|
||||
@ -30,19 +31,16 @@ class SCLoggerHelper {
|
||||
}
|
||||
|
||||
static Future<List?> getLauncherLogList() async {
|
||||
final jsonLogPath = await getLogFilePath();
|
||||
if (jsonLogPath == null) return null;
|
||||
var jsonString = utf8.decode(await File(jsonLogPath).readAsBytes());
|
||||
if (jsonString.endsWith("\n")) {
|
||||
jsonString = jsonString.substring(0, jsonString.length - 3);
|
||||
if (!Platform.isWindows) return [];
|
||||
try {
|
||||
final jsonLogPath = await getLogFilePath();
|
||||
if (jsonLogPath == null) throw "no file path";
|
||||
var jsonString = utf8.decode(await File(jsonLogPath).readAsBytes());
|
||||
return jsonString.split("\n");
|
||||
} catch (e) {
|
||||
dPrint(e);
|
||||
return [];
|
||||
}
|
||||
if (jsonString.endsWith(" ")) {
|
||||
jsonString = jsonString.substring(0, jsonString.length - 3);
|
||||
}
|
||||
if (jsonString.endsWith(",")) {
|
||||
jsonString = jsonString.substring(0, jsonString.length - 3);
|
||||
}
|
||||
return json.decode("[$jsonString]");
|
||||
}
|
||||
|
||||
static Future<List<String>> getGameInstallPath(List listData,
|
||||
@ -51,6 +49,8 @@ class SCLoggerHelper {
|
||||
List<String> scInstallPaths = [];
|
||||
|
||||
checkAndAddPath(String path, bool checkExists) async {
|
||||
// 将所有连续的 \\ 替换为 \
|
||||
path = path.replaceAll(RegExp(r'\\+'), "\\");
|
||||
if (path.isNotEmpty && !scInstallPaths.contains(path)) {
|
||||
if (!checkExists) {
|
||||
dPrint("find installPath == $path");
|
||||
@ -73,23 +73,29 @@ class SCLoggerHelper {
|
||||
|
||||
try {
|
||||
for (var v in withVersion) {
|
||||
String pattern =
|
||||
r'([a-zA-Z]:\\\\[^\\\\]*\\\\[^\\\\]*\\\\StarCitizen\\\\' + v + r')';
|
||||
RegExp regExp = RegExp(pattern, caseSensitive: false);
|
||||
for (var i = listData.length - 1; i > 0; i--) {
|
||||
final m = listData[i];
|
||||
final info = m["[browser][info] "];
|
||||
if (info is String) {
|
||||
String installPath = "";
|
||||
if (info.contains("Installing Star Citizen $v")) {
|
||||
installPath = "${info.split(" at ")[1]}\\$v";
|
||||
final line = listData[i];
|
||||
final matches = regExp.allMatches(line);
|
||||
for (var match in matches) {
|
||||
await checkAndAddPath(match.group(0)!, checkExists);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scInstallPaths.isNotEmpty) {
|
||||
// 动态检测更多位置
|
||||
for (var fileName in List.from(scInstallPaths)) {
|
||||
for (var v in withVersion) {
|
||||
if (fileName.toString().endsWith(v)) {
|
||||
for (var nv in withVersion) {
|
||||
final nextName =
|
||||
"${fileName.toString().replaceAll("\\$v", "")}\\$nv";
|
||||
await checkAndAddPath(nextName, true);
|
||||
}
|
||||
}
|
||||
if (info.contains("Verifying Star Citizen $v")) {
|
||||
installPath = "${info.split(" at ")[1]}\\$v";
|
||||
}
|
||||
if (info.contains("Launching Star Citizen $v from")) {
|
||||
installPath = info
|
||||
.replaceAll("Launching Star Citizen $v from (", "")
|
||||
.replaceAll(")", "");
|
||||
}
|
||||
await checkAndAddPath(installPath, checkExists);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,26 +104,11 @@ class SCLoggerHelper {
|
||||
if (scInstallPaths.isEmpty) rethrow;
|
||||
}
|
||||
|
||||
if (scInstallPaths.isNotEmpty) {
|
||||
// 动态检测更多位置
|
||||
for (var v in withVersion) {
|
||||
for (var fileName in List.from(scInstallPaths)) {
|
||||
if (fileName.toString().endsWith(v)) {
|
||||
for (var nv in withVersion) {
|
||||
final nextName =
|
||||
"${fileName.toString().replaceAll("\\$v", "")}\\$nv";
|
||||
await checkAndAddPath(nextName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return scInstallPaths;
|
||||
}
|
||||
|
||||
static String getGameChannelID(String installPath) {
|
||||
for (var value in ConstConf.gameChannels) {
|
||||
for (var value in AppConf.gameChannels) {
|
||||
if (installPath.endsWith("\\$value")) {
|
||||
return value;
|
||||
}
|
||||
@ -184,6 +175,11 @@ class SCLoggerHelper {
|
||||
return MapEntry(S.current.doctor_game_error_low_gpu_memory,
|
||||
S.current.doctor_game_error_low_gpu_memory_info);
|
||||
}
|
||||
if (line.contains(
|
||||
"try disabling with r_vulkanDisableLayers = 1 in your user.cfg")) {
|
||||
return MapEntry(S.current.doctor_game_error_gpu_vulkan_crash,
|
||||
S.current.doctor_game_error_gpu_vulkan_crash_info);
|
||||
}
|
||||
|
||||
/// Unknown
|
||||
if (line.contains("network.replicatedEntityHandle")) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
|
||||
class SystemHelper {
|
||||
@ -8,8 +8,8 @@ class SystemHelper {
|
||||
|
||||
static initPowershellPath() async {
|
||||
try {
|
||||
var result = await Process.run(powershellPath, ["echo", "ping"]);
|
||||
if (!result.stdout.toString().startsWith("ping") &&
|
||||
var result = await Process.run(powershellPath, ["echo", "pong"]);
|
||||
if (!result.stdout.toString().startsWith("pong") &&
|
||||
powershellPath == "powershell.exe") {
|
||||
throw "powershell check failed";
|
||||
}
|
||||
@ -87,6 +87,9 @@ class SystemHelper {
|
||||
final path = confBox.get("custom_launcher_path");
|
||||
if (path != null && path != "") {
|
||||
if (await File(path).exists()) {
|
||||
if (skipEXE) {
|
||||
return "${path.toString().replaceAll("\\RSI Launcher.exe", "")}\\";
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
@ -260,13 +263,18 @@ foreach ($adapter in $adapterMemory) {
|
||||
|
||||
static Future openDir(path, {bool isFile = false}) async {
|
||||
dPrint("SystemHelper.openDir path === $path");
|
||||
await Process.run(SystemHelper.powershellPath,
|
||||
["explorer.exe", isFile ? "/select,$path" : "\"/select,\"$path\"\""]);
|
||||
if (Platform.isWindows) {
|
||||
await Process.run(SystemHelper.powershellPath,
|
||||
["explorer.exe", isFile ? "/select,$path" : "\"/select,\"$path\"\""]);
|
||||
}
|
||||
}
|
||||
|
||||
static String getHostsFilePath() {
|
||||
final envVars = Platform.environment;
|
||||
final systemRoot = envVars["SYSTEMROOT"];
|
||||
return "$systemRoot\\System32\\drivers\\etc\\hosts";
|
||||
if (Platform.isWindows) {
|
||||
final envVars = Platform.environment;
|
||||
final systemRoot = envVars["SYSTEMROOT"];
|
||||
return "$systemRoot\\System32\\drivers\\etc\\hosts";
|
||||
}
|
||||
return "/etc/hosts";
|
||||
}
|
||||
}
|
||||
|
46
lib/common/io/doh_client.dart
Normal file
46
lib/common/io/doh_client.dart
Normal file
@ -0,0 +1,46 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:starcitizen_doctor/common/conf/conf.dart';
|
||||
import 'package:starcitizen_doctor/common/io/rs_http.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/data/doh_client_response_data.dart';
|
||||
|
||||
class DohClient {
|
||||
static Future<DohClientResponseData?> resolve(
|
||||
String domain, String type) async {
|
||||
try {
|
||||
final r = await RSHttp.getText(
|
||||
"${ConstConf.dohAddress}?name=$domain&type=$type");
|
||||
final data = DohClientResponseData.fromJson(json.decode(r));
|
||||
return data;
|
||||
} catch (e) {
|
||||
dPrint("DohClient.resolve error: $e");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<String>?> resolveIP(String domain, String type) async {
|
||||
final data = await resolve(domain, type);
|
||||
if (data == null) return [];
|
||||
return data.answer?.map((e) => _removeDataPadding(e.data)).toList();
|
||||
}
|
||||
|
||||
static Future<List<String>?> resolveTXT(String domain) async {
|
||||
final data = await resolve(domain, "TXT");
|
||||
if (data == null) return [];
|
||||
return data.answer?.map((e) => _removeDataPadding(e.data)).toList();
|
||||
}
|
||||
|
||||
static String _removeDataPadding(String? data) {
|
||||
// data demo: {"data":"\"https://git.scbox.xkeyc.cn,https://gitapi.scbox.org\""}
|
||||
if (data == null) return "";
|
||||
data = data.trim();
|
||||
if (data.startsWith("\"")) {
|
||||
data = data.substring(1);
|
||||
}
|
||||
if (data.endsWith("\"")) {
|
||||
data = data.substring(0, data.length - 1);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:starcitizen_doctor/common/conf/const_conf.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/conf.dart';
|
||||
import 'package:starcitizen_doctor/common/rust/api/http_api.dart' as rust_http;
|
||||
import 'package:starcitizen_doctor/common/rust/api/http_api.dart';
|
||||
import 'package:starcitizen_doctor/common/rust/http_package.dart';
|
||||
@ -14,49 +14,73 @@ class RSHttp {
|
||||
});
|
||||
}
|
||||
|
||||
static Future<RustHttpResponse> get(String url,
|
||||
{Map<String, String>? headers, String? withIpAddress}) async {
|
||||
static Future<RustHttpResponse> get(
|
||||
String url, {
|
||||
Map<String, String>? headers,
|
||||
String? withIpAddress,
|
||||
bool? withCustomDns,
|
||||
}) async {
|
||||
final r = await rust_http.fetch(
|
||||
method: MyMethod.gets,
|
||||
url: url,
|
||||
headers: headers,
|
||||
withIpAddress: withIpAddress);
|
||||
method: MyMethod.gets,
|
||||
url: url,
|
||||
headers: headers,
|
||||
withIpAddress: withIpAddress,
|
||||
withCustomDns: withCustomDns,
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
static Future<String> getText(String url,
|
||||
{Map<String, String>? headers, String? withIpAddress}) async {
|
||||
final r = await get(url, headers: headers, withIpAddress: withIpAddress);
|
||||
static Future<String> getText(
|
||||
String url, {
|
||||
Map<String, String>? headers,
|
||||
String? withIpAddress,
|
||||
bool? withCustomDns,
|
||||
}) async {
|
||||
final r = await get(url,
|
||||
headers: headers,
|
||||
withIpAddress: withIpAddress,
|
||||
withCustomDns: withCustomDns);
|
||||
if (r.data == null) return "";
|
||||
final str = utf8.decode(r.data!);
|
||||
return str;
|
||||
}
|
||||
|
||||
static Future<RustHttpResponse> postData(String url,
|
||||
{Map<String, String>? headers,
|
||||
String? contentType,
|
||||
Uint8List? data,
|
||||
String? withIpAddress}) async {
|
||||
static Future<RustHttpResponse> postData(
|
||||
String url, {
|
||||
Map<String, String>? headers,
|
||||
String? contentType,
|
||||
Uint8List? data,
|
||||
String? withIpAddress,
|
||||
bool? withCustomDns,
|
||||
}) async {
|
||||
if (contentType != null) {
|
||||
headers ??= {};
|
||||
headers["Content-Type"] = contentType;
|
||||
}
|
||||
final r = await rust_http.fetch(
|
||||
method: MyMethod.post,
|
||||
url: url,
|
||||
headers: headers,
|
||||
inputData: data,
|
||||
withIpAddress: withIpAddress);
|
||||
method: MyMethod.post,
|
||||
url: url,
|
||||
headers: headers,
|
||||
inputData: data,
|
||||
withIpAddress: withIpAddress,
|
||||
withCustomDns: withCustomDns,
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
static Future<RustHttpResponse> head(String url,
|
||||
{Map<String, String>? headers, String? withIpAddress}) async {
|
||||
static Future<RustHttpResponse> head(
|
||||
String url, {
|
||||
Map<String, String>? headers,
|
||||
String? withIpAddress,
|
||||
bool? withCustomDns,
|
||||
}) async {
|
||||
final r = await rust_http.fetch(
|
||||
method: MyMethod.head,
|
||||
url: url,
|
||||
headers: headers,
|
||||
withIpAddress: withIpAddress);
|
||||
method: MyMethod.head,
|
||||
url: url,
|
||||
headers: headers,
|
||||
withIpAddress: withIpAddress,
|
||||
withCustomDns: withCustomDns,
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// This file is automatically generated, so please do not edit it.
|
||||
// Generated by `flutter_rust_bridge`@ 2.0.0-dev.33.
|
||||
// @generated by `flutter_rust_bridge`@ 2.9.0.
|
||||
|
||||
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||
|
||||
@ -7,8 +7,9 @@ import '../frb_generated.dart';
|
||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||
|
||||
Future<RsiLauncherAsarData> getRsiLauncherAsarData(
|
||||
{required String asarPath, dynamic hint}) =>
|
||||
RustLib.instance.api.getRsiLauncherAsarData(asarPath: asarPath, hint: hint);
|
||||
{required String asarPath}) =>
|
||||
RustLib.instance.api
|
||||
.crateApiAsarApiGetRsiLauncherAsarData(asarPath: asarPath);
|
||||
|
||||
class RsiLauncherAsarData {
|
||||
final String asarPath;
|
||||
@ -21,9 +22,9 @@ class RsiLauncherAsarData {
|
||||
required this.mainJsContent,
|
||||
});
|
||||
|
||||
Future<void> writeMainJs({required List<int> content, dynamic hint}) =>
|
||||
RustLib.instance.api.rsiLauncherAsarDataWriteMainJs(
|
||||
that: this, content: content, hint: hint);
|
||||
Future<void> writeMainJs({required List<int> content}) =>
|
||||
RustLib.instance.api.crateApiAsarApiRsiLauncherAsarDataWriteMainJs(
|
||||
that: this, content: content);
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
|
@ -1,5 +1,5 @@
|
||||
// This file is automatically generated, so please do not edit it.
|
||||
// Generated by `flutter_rust_bridge`@ 2.0.0-dev.33.
|
||||
// @generated by `flutter_rust_bridge`@ 2.9.0.
|
||||
|
||||
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||
|
||||
@ -7,9 +7,10 @@ import '../frb_generated.dart';
|
||||
import '../http_package.dart';
|
||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||
|
||||
Future<void> setDefaultHeader(
|
||||
{required Map<String, String> headers, dynamic hint}) =>
|
||||
RustLib.instance.api.setDefaultHeader(headers: headers, hint: hint);
|
||||
// These functions are ignored because they are not marked as `pub`: `_my_method_to_hyper_method`
|
||||
|
||||
Future<void> setDefaultHeader({required Map<String, String> headers}) =>
|
||||
RustLib.instance.api.crateApiHttpApiSetDefaultHeader(headers: headers);
|
||||
|
||||
Future<RustHttpResponse> fetch(
|
||||
{required MyMethod method,
|
||||
@ -17,20 +18,20 @@ Future<RustHttpResponse> fetch(
|
||||
Map<String, String>? headers,
|
||||
Uint8List? inputData,
|
||||
String? withIpAddress,
|
||||
dynamic hint}) =>
|
||||
RustLib.instance.api.fetch(
|
||||
bool? withCustomDns}) =>
|
||||
RustLib.instance.api.crateApiHttpApiFetch(
|
||||
method: method,
|
||||
url: url,
|
||||
headers: headers,
|
||||
inputData: inputData,
|
||||
withIpAddress: withIpAddress,
|
||||
hint: hint);
|
||||
withCustomDns: withCustomDns);
|
||||
|
||||
Future<List<String>> dnsLookupTxt({required String host, dynamic hint}) =>
|
||||
RustLib.instance.api.dnsLookupTxt(host: host, hint: hint);
|
||||
Future<List<String>> dnsLookupTxt({required String host}) =>
|
||||
RustLib.instance.api.crateApiHttpApiDnsLookupTxt(host: host);
|
||||
|
||||
Future<List<String>> dnsLookupIps({required String host, dynamic hint}) =>
|
||||
RustLib.instance.api.dnsLookupIps(host: host, hint: hint);
|
||||
Future<List<String>> dnsLookupIps({required String host}) =>
|
||||
RustLib.instance.api.crateApiHttpApiDnsLookupIps(host: host);
|
||||
|
||||
enum MyMethod {
|
||||
options,
|
||||
|
@ -1,26 +1,26 @@
|
||||
// This file is automatically generated, so please do not edit it.
|
||||
// Generated by `flutter_rust_bridge`@ 2.0.0-dev.33.
|
||||
// @generated by `flutter_rust_bridge`@ 2.9.0.
|
||||
|
||||
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||
|
||||
import '../frb_generated.dart';
|
||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||
|
||||
// The type `RsProcess` is not used by any `pub` functions, thus it is ignored.
|
||||
// These functions are ignored because they are not marked as `pub`: `_process_output`
|
||||
// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `RsProcess`
|
||||
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`
|
||||
|
||||
Stream<RsProcessStreamData> start(
|
||||
{required String executable,
|
||||
required List<String> arguments,
|
||||
required String workingDirectory,
|
||||
dynamic hint}) =>
|
||||
RustLib.instance.api.start(
|
||||
required String workingDirectory}) =>
|
||||
RustLib.instance.api.crateApiRsProcessStart(
|
||||
executable: executable,
|
||||
arguments: arguments,
|
||||
workingDirectory: workingDirectory,
|
||||
hint: hint);
|
||||
workingDirectory: workingDirectory);
|
||||
|
||||
Future<void> write({required int rsPid, required String data, dynamic hint}) =>
|
||||
RustLib.instance.api.write(rsPid: rsPid, data: data, hint: hint);
|
||||
Future<void> write({required int rsPid, required String data}) =>
|
||||
RustLib.instance.api.crateApiRsProcessWrite(rsPid: rsPid, data: data);
|
||||
|
||||
class RsProcessStreamData {
|
||||
final RsProcessStreamDataType dataType;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// This file is automatically generated, so please do not edit it.
|
||||
// Generated by `flutter_rust_bridge`@ 2.0.0-dev.33.
|
||||
// @generated by `flutter_rust_bridge`@ 2.9.0.
|
||||
|
||||
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||
|
||||
@ -7,18 +7,10 @@ import '../frb_generated.dart';
|
||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||
|
||||
Future<void> sendNotify(
|
||||
{String? summary,
|
||||
String? body,
|
||||
String? appName,
|
||||
String? appId,
|
||||
dynamic hint}) =>
|
||||
RustLib.instance.api.sendNotify(
|
||||
summary: summary,
|
||||
body: body,
|
||||
appName: appName,
|
||||
appId: appId,
|
||||
hint: hint);
|
||||
{String? summary, String? body, String? appName, String? appId}) =>
|
||||
RustLib.instance.api.crateApiWin32ApiSendNotify(
|
||||
summary: summary, body: body, appName: appName, appId: appId);
|
||||
|
||||
Future<bool> setForegroundWindow({required String windowName, dynamic hint}) =>
|
||||
Future<bool> setForegroundWindow({required String windowName}) =>
|
||||
RustLib.instance.api
|
||||
.setForegroundWindow(windowName: windowName, hint: hint);
|
||||
.crateApiWin32ApiSetForegroundWindow(windowName: windowName);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// This file is automatically generated, so please do not edit it.
|
||||
// Generated by `flutter_rust_bridge`@ 2.0.0-dev.33.
|
||||
// @generated by `flutter_rust_bridge`@ 2.9.0.
|
||||
|
||||
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
||||
|
||||
@ -9,7 +9,9 @@ import 'api/rs_process.dart';
|
||||
import 'api/win32_api.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'frb_generated.io.dart' if (dart.library.html) 'frb_generated.web.dart';
|
||||
import 'frb_generated.dart';
|
||||
import 'frb_generated.io.dart'
|
||||
if (dart.library.js_interop) 'frb_generated.web.dart';
|
||||
import 'http_package.dart';
|
||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||
|
||||
@ -33,6 +35,16 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Initialize flutter_rust_bridge in mock mode.
|
||||
/// No libraries for FFI are loaded.
|
||||
static void initMock({
|
||||
required RustLibApi api,
|
||||
}) {
|
||||
instance.initMockImpl(
|
||||
api: api,
|
||||
);
|
||||
}
|
||||
|
||||
/// Dispose flutter_rust_bridge
|
||||
///
|
||||
/// The call to this function is optional, since flutter_rust_bridge (and everything else)
|
||||
@ -55,7 +67,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
||||
kDefaultExternalLibraryLoaderConfig;
|
||||
|
||||
@override
|
||||
String get codegenVersion => '2.0.0-dev.33';
|
||||
String get codegenVersion => '2.9.0';
|
||||
|
||||
@override
|
||||
int get rustContentHash => 1832496273;
|
||||
@ -69,45 +81,40 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
||||
}
|
||||
|
||||
abstract class RustLibApi extends BaseApi {
|
||||
Future<RsiLauncherAsarData> getRsiLauncherAsarData(
|
||||
{required String asarPath, dynamic hint});
|
||||
Future<List<String>> crateApiHttpApiDnsLookupIps({required String host});
|
||||
|
||||
Future<void> rsiLauncherAsarDataWriteMainJs(
|
||||
{required RsiLauncherAsarData that,
|
||||
required List<int> content,
|
||||
dynamic hint});
|
||||
Future<List<String>> crateApiHttpApiDnsLookupTxt({required String host});
|
||||
|
||||
Future<List<String>> dnsLookupIps({required String host, dynamic hint});
|
||||
|
||||
Future<List<String>> dnsLookupTxt({required String host, dynamic hint});
|
||||
|
||||
Future<RustHttpResponse> fetch(
|
||||
Future<RustHttpResponse> crateApiHttpApiFetch(
|
||||
{required MyMethod method,
|
||||
required String url,
|
||||
Map<String, String>? headers,
|
||||
Uint8List? inputData,
|
||||
String? withIpAddress,
|
||||
dynamic hint});
|
||||
bool? withCustomDns});
|
||||
|
||||
Future<void> setDefaultHeader(
|
||||
{required Map<String, String> headers, dynamic hint});
|
||||
Future<RsiLauncherAsarData> crateApiAsarApiGetRsiLauncherAsarData(
|
||||
{required String asarPath});
|
||||
|
||||
Stream<RsProcessStreamData> start(
|
||||
Future<void> crateApiAsarApiRsiLauncherAsarDataWriteMainJs(
|
||||
{required RsiLauncherAsarData that, required List<int> content});
|
||||
|
||||
Future<void> crateApiWin32ApiSendNotify(
|
||||
{String? summary, String? body, String? appName, String? appId});
|
||||
|
||||
Future<void> crateApiHttpApiSetDefaultHeader(
|
||||
{required Map<String, String> headers});
|
||||
|
||||
Future<bool> crateApiWin32ApiSetForegroundWindow(
|
||||
{required String windowName});
|
||||
|
||||
Stream<RsProcessStreamData> crateApiRsProcessStart(
|
||||
{required String executable,
|
||||
required List<String> arguments,
|
||||
required String workingDirectory,
|
||||
dynamic hint});
|
||||
required String workingDirectory});
|
||||
|
||||
Future<void> write({required int rsPid, required String data, dynamic hint});
|
||||
|
||||
Future<void> sendNotify(
|
||||
{String? summary,
|
||||
String? body,
|
||||
String? appName,
|
||||
String? appId,
|
||||
dynamic hint});
|
||||
|
||||
Future<bool> setForegroundWindow({required String windowName, dynamic hint});
|
||||
Future<void> crateApiRsProcessWrite(
|
||||
{required int rsPid, required String data});
|
||||
}
|
||||
|
||||
class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
@ -119,167 +126,232 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
});
|
||||
|
||||
@override
|
||||
Future<RsiLauncherAsarData> getRsiLauncherAsarData(
|
||||
{required String asarPath, dynamic hint}) {
|
||||
Future<List<String>> crateApiHttpApiDnsLookupIps({required String host}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_String(host);
|
||||
return wire.wire__crate__api__http_api__dns_lookup_ips(port_, arg0);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_list_String,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
),
|
||||
constMeta: kCrateApiHttpApiDnsLookupIpsConstMeta,
|
||||
argValues: [host],
|
||||
apiImpl: this,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kCrateApiHttpApiDnsLookupIpsConstMeta =>
|
||||
const TaskConstMeta(
|
||||
debugName: "dns_lookup_ips",
|
||||
argNames: ["host"],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<List<String>> crateApiHttpApiDnsLookupTxt({required String host}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_String(host);
|
||||
return wire.wire__crate__api__http_api__dns_lookup_txt(port_, arg0);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_list_String,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
),
|
||||
constMeta: kCrateApiHttpApiDnsLookupTxtConstMeta,
|
||||
argValues: [host],
|
||||
apiImpl: this,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kCrateApiHttpApiDnsLookupTxtConstMeta =>
|
||||
const TaskConstMeta(
|
||||
debugName: "dns_lookup_txt",
|
||||
argNames: ["host"],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<RustHttpResponse> crateApiHttpApiFetch(
|
||||
{required MyMethod method,
|
||||
required String url,
|
||||
Map<String, String>? headers,
|
||||
Uint8List? inputData,
|
||||
String? withIpAddress,
|
||||
bool? withCustomDns}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_my_method(method);
|
||||
var arg1 = cst_encode_String(url);
|
||||
var arg2 = cst_encode_opt_Map_String_String_None(headers);
|
||||
var arg3 = cst_encode_opt_list_prim_u_8_strict(inputData);
|
||||
var arg4 = cst_encode_opt_String(withIpAddress);
|
||||
var arg5 = cst_encode_opt_box_autoadd_bool(withCustomDns);
|
||||
return wire.wire__crate__api__http_api__fetch(
|
||||
port_, arg0, arg1, arg2, arg3, arg4, arg5);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_rust_http_response,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
),
|
||||
constMeta: kCrateApiHttpApiFetchConstMeta,
|
||||
argValues: [
|
||||
method,
|
||||
url,
|
||||
headers,
|
||||
inputData,
|
||||
withIpAddress,
|
||||
withCustomDns
|
||||
],
|
||||
apiImpl: this,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kCrateApiHttpApiFetchConstMeta => const TaskConstMeta(
|
||||
debugName: "fetch",
|
||||
argNames: [
|
||||
"method",
|
||||
"url",
|
||||
"headers",
|
||||
"inputData",
|
||||
"withIpAddress",
|
||||
"withCustomDns"
|
||||
],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<RsiLauncherAsarData> crateApiAsarApiGetRsiLauncherAsarData(
|
||||
{required String asarPath}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_String(asarPath);
|
||||
return wire.wire_get_rsi_launcher_asar_data(port_, arg0);
|
||||
return wire.wire__crate__api__asar_api__get_rsi_launcher_asar_data(
|
||||
port_, arg0);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_rsi_launcher_asar_data,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
),
|
||||
constMeta: kGetRsiLauncherAsarDataConstMeta,
|
||||
constMeta: kCrateApiAsarApiGetRsiLauncherAsarDataConstMeta,
|
||||
argValues: [asarPath],
|
||||
apiImpl: this,
|
||||
hint: hint,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kGetRsiLauncherAsarDataConstMeta => const TaskConstMeta(
|
||||
TaskConstMeta get kCrateApiAsarApiGetRsiLauncherAsarDataConstMeta =>
|
||||
const TaskConstMeta(
|
||||
debugName: "get_rsi_launcher_asar_data",
|
||||
argNames: ["asarPath"],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> rsiLauncherAsarDataWriteMainJs(
|
||||
{required RsiLauncherAsarData that,
|
||||
required List<int> content,
|
||||
dynamic hint}) {
|
||||
Future<void> crateApiAsarApiRsiLauncherAsarDataWriteMainJs(
|
||||
{required RsiLauncherAsarData that, required List<int> content}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_box_autoadd_rsi_launcher_asar_data(that);
|
||||
var arg1 = cst_encode_list_prim_u_8_loose(content);
|
||||
return wire.wire_rsi_launcher_asar_data_write_main_js(
|
||||
port_, arg0, arg1);
|
||||
return wire
|
||||
.wire__crate__api__asar_api__rsi_launcher_asar_data_write_main_js(
|
||||
port_, arg0, arg1);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_unit,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
),
|
||||
constMeta: kRsiLauncherAsarDataWriteMainJsConstMeta,
|
||||
constMeta: kCrateApiAsarApiRsiLauncherAsarDataWriteMainJsConstMeta,
|
||||
argValues: [that, content],
|
||||
apiImpl: this,
|
||||
hint: hint,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kRsiLauncherAsarDataWriteMainJsConstMeta =>
|
||||
TaskConstMeta get kCrateApiAsarApiRsiLauncherAsarDataWriteMainJsConstMeta =>
|
||||
const TaskConstMeta(
|
||||
debugName: "rsi_launcher_asar_data_write_main_js",
|
||||
argNames: ["that", "content"],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<List<String>> dnsLookupIps({required String host, dynamic hint}) {
|
||||
Future<void> crateApiWin32ApiSendNotify(
|
||||
{String? summary, String? body, String? appName, String? appId}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_String(host);
|
||||
return wire.wire_dns_lookup_ips(port_, arg0);
|
||||
var arg0 = cst_encode_opt_String(summary);
|
||||
var arg1 = cst_encode_opt_String(body);
|
||||
var arg2 = cst_encode_opt_String(appName);
|
||||
var arg3 = cst_encode_opt_String(appId);
|
||||
return wire.wire__crate__api__win32_api__send_notify(
|
||||
port_, arg0, arg1, arg2, arg3);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_list_String,
|
||||
decodeSuccessData: dco_decode_unit,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
),
|
||||
constMeta: kDnsLookupIpsConstMeta,
|
||||
argValues: [host],
|
||||
constMeta: kCrateApiWin32ApiSendNotifyConstMeta,
|
||||
argValues: [summary, body, appName, appId],
|
||||
apiImpl: this,
|
||||
hint: hint,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kDnsLookupIpsConstMeta => const TaskConstMeta(
|
||||
debugName: "dns_lookup_ips",
|
||||
argNames: ["host"],
|
||||
TaskConstMeta get kCrateApiWin32ApiSendNotifyConstMeta => const TaskConstMeta(
|
||||
debugName: "send_notify",
|
||||
argNames: ["summary", "body", "appName", "appId"],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<List<String>> dnsLookupTxt({required String host, dynamic hint}) {
|
||||
Future<void> crateApiHttpApiSetDefaultHeader(
|
||||
{required Map<String, String> headers}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_String(host);
|
||||
return wire.wire_dns_lookup_txt(port_, arg0);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_list_String,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
),
|
||||
constMeta: kDnsLookupTxtConstMeta,
|
||||
argValues: [host],
|
||||
apiImpl: this,
|
||||
hint: hint,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kDnsLookupTxtConstMeta => const TaskConstMeta(
|
||||
debugName: "dns_lookup_txt",
|
||||
argNames: ["host"],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<RustHttpResponse> fetch(
|
||||
{required MyMethod method,
|
||||
required String url,
|
||||
Map<String, String>? headers,
|
||||
Uint8List? inputData,
|
||||
String? withIpAddress,
|
||||
dynamic hint}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_my_method(method);
|
||||
var arg1 = cst_encode_String(url);
|
||||
var arg2 = cst_encode_opt_Map_String_String(headers);
|
||||
var arg3 = cst_encode_opt_list_prim_u_8_strict(inputData);
|
||||
var arg4 = cst_encode_opt_String(withIpAddress);
|
||||
return wire.wire_fetch(port_, arg0, arg1, arg2, arg3, arg4);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_rust_http_response,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
),
|
||||
constMeta: kFetchConstMeta,
|
||||
argValues: [method, url, headers, inputData, withIpAddress],
|
||||
apiImpl: this,
|
||||
hint: hint,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kFetchConstMeta => const TaskConstMeta(
|
||||
debugName: "fetch",
|
||||
argNames: ["method", "url", "headers", "inputData", "withIpAddress"],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> setDefaultHeader(
|
||||
{required Map<String, String> headers, dynamic hint}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_Map_String_String(headers);
|
||||
return wire.wire_set_default_header(port_, arg0);
|
||||
var arg0 = cst_encode_Map_String_String_None(headers);
|
||||
return wire.wire__crate__api__http_api__set_default_header(port_, arg0);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_unit,
|
||||
decodeErrorData: null,
|
||||
),
|
||||
constMeta: kSetDefaultHeaderConstMeta,
|
||||
constMeta: kCrateApiHttpApiSetDefaultHeaderConstMeta,
|
||||
argValues: [headers],
|
||||
apiImpl: this,
|
||||
hint: hint,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kSetDefaultHeaderConstMeta => const TaskConstMeta(
|
||||
TaskConstMeta get kCrateApiHttpApiSetDefaultHeaderConstMeta =>
|
||||
const TaskConstMeta(
|
||||
debugName: "set_default_header",
|
||||
argNames: ["headers"],
|
||||
);
|
||||
|
||||
@override
|
||||
Stream<RsProcessStreamData> start(
|
||||
Future<bool> crateApiWin32ApiSetForegroundWindow(
|
||||
{required String windowName}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_String(windowName);
|
||||
return wire.wire__crate__api__win32_api__set_foreground_window(
|
||||
port_, arg0);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_bool,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
),
|
||||
constMeta: kCrateApiWin32ApiSetForegroundWindowConstMeta,
|
||||
argValues: [windowName],
|
||||
apiImpl: this,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kCrateApiWin32ApiSetForegroundWindowConstMeta =>
|
||||
const TaskConstMeta(
|
||||
debugName: "set_foreground_window",
|
||||
argNames: ["windowName"],
|
||||
);
|
||||
|
||||
@override
|
||||
Stream<RsProcessStreamData> crateApiRsProcessStart(
|
||||
{required String executable,
|
||||
required List<String> arguments,
|
||||
required String workingDirectory,
|
||||
dynamic hint}) {
|
||||
required String workingDirectory}) {
|
||||
final streamSink = RustStreamSink<RsProcessStreamData>();
|
||||
unawaited(handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
@ -287,103 +359,49 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
var arg1 = cst_encode_list_String(arguments);
|
||||
var arg2 = cst_encode_String(workingDirectory);
|
||||
var arg3 = cst_encode_StreamSink_rs_process_stream_data_Dco(streamSink);
|
||||
return wire.wire_start(port_, arg0, arg1, arg2, arg3);
|
||||
return wire.wire__crate__api__rs_process__start(
|
||||
port_, arg0, arg1, arg2, arg3);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_unit,
|
||||
decodeErrorData: null,
|
||||
),
|
||||
constMeta: kStartConstMeta,
|
||||
constMeta: kCrateApiRsProcessStartConstMeta,
|
||||
argValues: [executable, arguments, workingDirectory, streamSink],
|
||||
apiImpl: this,
|
||||
hint: hint,
|
||||
)));
|
||||
return streamSink.stream;
|
||||
}
|
||||
|
||||
TaskConstMeta get kStartConstMeta => const TaskConstMeta(
|
||||
TaskConstMeta get kCrateApiRsProcessStartConstMeta => const TaskConstMeta(
|
||||
debugName: "start",
|
||||
argNames: ["executable", "arguments", "workingDirectory", "streamSink"],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> write({required int rsPid, required String data, dynamic hint}) {
|
||||
Future<void> crateApiRsProcessWrite(
|
||||
{required int rsPid, required String data}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_u_32(rsPid);
|
||||
var arg1 = cst_encode_String(data);
|
||||
return wire.wire_write(port_, arg0, arg1);
|
||||
return wire.wire__crate__api__rs_process__write(port_, arg0, arg1);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_unit,
|
||||
decodeErrorData: null,
|
||||
),
|
||||
constMeta: kWriteConstMeta,
|
||||
constMeta: kCrateApiRsProcessWriteConstMeta,
|
||||
argValues: [rsPid, data],
|
||||
apiImpl: this,
|
||||
hint: hint,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kWriteConstMeta => const TaskConstMeta(
|
||||
TaskConstMeta get kCrateApiRsProcessWriteConstMeta => const TaskConstMeta(
|
||||
debugName: "write",
|
||||
argNames: ["rsPid", "data"],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> sendNotify(
|
||||
{String? summary,
|
||||
String? body,
|
||||
String? appName,
|
||||
String? appId,
|
||||
dynamic hint}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_opt_String(summary);
|
||||
var arg1 = cst_encode_opt_String(body);
|
||||
var arg2 = cst_encode_opt_String(appName);
|
||||
var arg3 = cst_encode_opt_String(appId);
|
||||
return wire.wire_send_notify(port_, arg0, arg1, arg2, arg3);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_unit,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
),
|
||||
constMeta: kSendNotifyConstMeta,
|
||||
argValues: [summary, body, appName, appId],
|
||||
apiImpl: this,
|
||||
hint: hint,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kSendNotifyConstMeta => const TaskConstMeta(
|
||||
debugName: "send_notify",
|
||||
argNames: ["summary", "body", "appName", "appId"],
|
||||
);
|
||||
|
||||
@override
|
||||
Future<bool> setForegroundWindow({required String windowName, dynamic hint}) {
|
||||
return handler.executeNormal(NormalTask(
|
||||
callFfi: (port_) {
|
||||
var arg0 = cst_encode_String(windowName);
|
||||
return wire.wire_set_foreground_window(port_, arg0);
|
||||
},
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_bool,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
),
|
||||
constMeta: kSetForegroundWindowConstMeta,
|
||||
argValues: [windowName],
|
||||
apiImpl: this,
|
||||
hint: hint,
|
||||
));
|
||||
}
|
||||
|
||||
TaskConstMeta get kSetForegroundWindowConstMeta => const TaskConstMeta(
|
||||
debugName: "set_foreground_window",
|
||||
argNames: ["windowName"],
|
||||
);
|
||||
|
||||
@protected
|
||||
AnyhowException dco_decode_AnyhowException(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
@ -391,7 +409,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
Map<String, String> dco_decode_Map_String_String(dynamic raw) {
|
||||
Map<String, String> dco_decode_Map_String_String_None(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return Map.fromEntries(dco_decode_list_record_string_string(raw)
|
||||
.map((e) => MapEntry(e.$1, e.$2)));
|
||||
@ -416,6 +434,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
return raw as bool;
|
||||
}
|
||||
|
||||
@protected
|
||||
bool dco_decode_box_autoadd_bool(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return raw as bool;
|
||||
}
|
||||
|
||||
@protected
|
||||
RsiLauncherAsarData dco_decode_box_autoadd_rsi_launcher_asar_data(
|
||||
dynamic raw) {
|
||||
@ -424,7 +448,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
int dco_decode_box_autoadd_u_64(dynamic raw) {
|
||||
BigInt dco_decode_box_autoadd_u_64(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return dco_decode_u_64(raw);
|
||||
}
|
||||
@ -472,9 +496,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
Map<String, String>? dco_decode_opt_Map_String_String(dynamic raw) {
|
||||
Map<String, String>? dco_decode_opt_Map_String_String_None(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return raw == null ? null : dco_decode_Map_String_String(raw);
|
||||
return raw == null ? null : dco_decode_Map_String_String_None(raw);
|
||||
}
|
||||
|
||||
@protected
|
||||
@ -484,7 +508,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
int? dco_decode_opt_box_autoadd_u_64(dynamic raw) {
|
||||
bool? dco_decode_opt_box_autoadd_bool(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return raw == null ? null : dco_decode_box_autoadd_bool(raw);
|
||||
}
|
||||
|
||||
@protected
|
||||
BigInt? dco_decode_opt_box_autoadd_u_64(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return raw == null ? null : dco_decode_box_autoadd_u_64(raw);
|
||||
}
|
||||
@ -548,7 +578,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
throw Exception('unexpected arr length: expect 7 but see ${arr.length}');
|
||||
return RustHttpResponse(
|
||||
statusCode: dco_decode_u_16(arr[0]),
|
||||
headers: dco_decode_Map_String_String(arr[1]),
|
||||
headers: dco_decode_Map_String_String_None(arr[1]),
|
||||
url: dco_decode_String(arr[2]),
|
||||
contentLength: dco_decode_opt_box_autoadd_u_64(arr[3]),
|
||||
version: dco_decode_my_http_version(arr[4]),
|
||||
@ -570,9 +600,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
int dco_decode_u_64(dynamic raw) {
|
||||
BigInt dco_decode_u_64(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return dcoDecodeI64OrU64(raw);
|
||||
return dcoDecodeU64(raw);
|
||||
}
|
||||
|
||||
@protected
|
||||
@ -595,7 +625,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
Map<String, String> sse_decode_Map_String_String(
|
||||
Map<String, String> sse_decode_Map_String_String_None(
|
||||
SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
var inner = sse_decode_list_record_string_string(deserializer);
|
||||
@ -623,6 +653,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
return deserializer.buffer.getUint8() != 0;
|
||||
}
|
||||
|
||||
@protected
|
||||
bool sse_decode_box_autoadd_bool(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
return (sse_decode_bool(deserializer));
|
||||
}
|
||||
|
||||
@protected
|
||||
RsiLauncherAsarData sse_decode_box_autoadd_rsi_launcher_asar_data(
|
||||
SseDeserializer deserializer) {
|
||||
@ -631,7 +667,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
int sse_decode_box_autoadd_u_64(SseDeserializer deserializer) {
|
||||
BigInt sse_decode_box_autoadd_u_64(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
return (sse_decode_u_64(deserializer));
|
||||
}
|
||||
@ -696,12 +732,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
Map<String, String>? sse_decode_opt_Map_String_String(
|
||||
Map<String, String>? sse_decode_opt_Map_String_String_None(
|
||||
SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
|
||||
if (sse_decode_bool(deserializer)) {
|
||||
return (sse_decode_Map_String_String(deserializer));
|
||||
return (sse_decode_Map_String_String_None(deserializer));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -719,7 +755,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
int? sse_decode_opt_box_autoadd_u_64(SseDeserializer deserializer) {
|
||||
bool? sse_decode_opt_box_autoadd_bool(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
|
||||
if (sse_decode_bool(deserializer)) {
|
||||
return (sse_decode_box_autoadd_bool(deserializer));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@protected
|
||||
BigInt? sse_decode_opt_box_autoadd_u_64(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
|
||||
if (sse_decode_bool(deserializer)) {
|
||||
@ -785,7 +832,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
RustHttpResponse sse_decode_rust_http_response(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
var var_statusCode = sse_decode_u_16(deserializer);
|
||||
var var_headers = sse_decode_Map_String_String(deserializer);
|
||||
var var_headers = sse_decode_Map_String_String_None(deserializer);
|
||||
var var_url = sse_decode_String(deserializer);
|
||||
var var_contentLength = sse_decode_opt_box_autoadd_u_64(deserializer);
|
||||
var var_version = sse_decode_my_http_version(deserializer);
|
||||
@ -814,9 +861,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
int sse_decode_u_64(SseDeserializer deserializer) {
|
||||
BigInt sse_decode_u_64(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
return deserializer.buffer.getUint64();
|
||||
return deserializer.buffer.getBigUint64();
|
||||
}
|
||||
|
||||
@protected
|
||||
@ -888,11 +935,11 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
void sse_encode_AnyhowException(
|
||||
AnyhowException self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
throw UnimplementedError('Unreachable ()');
|
||||
sse_encode_String(self.message, serializer);
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_Map_String_String(
|
||||
void sse_encode_Map_String_String_None(
|
||||
Map<String, String> self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
sse_encode_list_record_string_string(
|
||||
@ -906,8 +953,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
sse_encode_String(
|
||||
self.setupAndSerialize(
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_rs_process_stream_data,
|
||||
decodeErrorData: null)),
|
||||
decodeSuccessData: dco_decode_rs_process_stream_data,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
)),
|
||||
serializer);
|
||||
}
|
||||
|
||||
@ -923,6 +971,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
serializer.buffer.putUint8(self ? 1 : 0);
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_box_autoadd_bool(bool self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
sse_encode_bool(self, serializer);
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_box_autoadd_rsi_launcher_asar_data(
|
||||
RsiLauncherAsarData self, SseSerializer serializer) {
|
||||
@ -931,7 +985,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_box_autoadd_u_64(int self, SseSerializer serializer) {
|
||||
void sse_encode_box_autoadd_u_64(BigInt self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
sse_encode_u_64(self, serializer);
|
||||
}
|
||||
@ -992,13 +1046,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_Map_String_String(
|
||||
void sse_encode_opt_Map_String_String_None(
|
||||
Map<String, String>? self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
|
||||
sse_encode_bool(self != null, serializer);
|
||||
if (self != null) {
|
||||
sse_encode_Map_String_String(self, serializer);
|
||||
sse_encode_Map_String_String_None(self, serializer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1013,7 +1067,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_box_autoadd_u_64(int? self, SseSerializer serializer) {
|
||||
void sse_encode_opt_box_autoadd_bool(bool? self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
|
||||
sse_encode_bool(self != null, serializer);
|
||||
if (self != null) {
|
||||
sse_encode_box_autoadd_bool(self, serializer);
|
||||
}
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_box_autoadd_u_64(BigInt? self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
|
||||
sse_encode_bool(self != null, serializer);
|
||||
@ -1071,7 +1135,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
RustHttpResponse self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
sse_encode_u_16(self.statusCode, serializer);
|
||||
sse_encode_Map_String_String(self.headers, serializer);
|
||||
sse_encode_Map_String_String_None(self.headers, serializer);
|
||||
sse_encode_String(self.url, serializer);
|
||||
sse_encode_opt_box_autoadd_u_64(self.contentLength, serializer);
|
||||
sse_encode_my_http_version(self.version, serializer);
|
||||
@ -1092,9 +1156,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_u_64(int self, SseSerializer serializer) {
|
||||
void sse_encode_u_64(BigInt self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
serializer.buffer.putUint64(self);
|
||||
serializer.buffer.putBigUint64(self);
|
||||
}
|
||||
|
||||
@protected
|
||||
|
@ -1,5 +1,5 @@
|
||||
// This file is automatically generated, so please do not edit it.
|
||||
// Generated by `flutter_rust_bridge`@ 2.0.0-dev.33.
|
||||
// @generated by `flutter_rust_bridge`@ 2.9.0.
|
||||
|
||||
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
||||
|
||||
@ -26,7 +26,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
AnyhowException dco_decode_AnyhowException(dynamic raw);
|
||||
|
||||
@protected
|
||||
Map<String, String> dco_decode_Map_String_String(dynamic raw);
|
||||
Map<String, String> dco_decode_Map_String_String_None(dynamic raw);
|
||||
|
||||
@protected
|
||||
RustStreamSink<RsProcessStreamData>
|
||||
@ -38,12 +38,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
@protected
|
||||
bool dco_decode_bool(dynamic raw);
|
||||
|
||||
@protected
|
||||
bool dco_decode_box_autoadd_bool(dynamic raw);
|
||||
|
||||
@protected
|
||||
RsiLauncherAsarData dco_decode_box_autoadd_rsi_launcher_asar_data(
|
||||
dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_box_autoadd_u_64(dynamic raw);
|
||||
BigInt dco_decode_box_autoadd_u_64(dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_i_32(dynamic raw);
|
||||
@ -67,13 +70,16 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
MyMethod dco_decode_my_method(dynamic raw);
|
||||
|
||||
@protected
|
||||
Map<String, String>? dco_decode_opt_Map_String_String(dynamic raw);
|
||||
Map<String, String>? dco_decode_opt_Map_String_String_None(dynamic raw);
|
||||
|
||||
@protected
|
||||
String? dco_decode_opt_String(dynamic raw);
|
||||
|
||||
@protected
|
||||
int? dco_decode_opt_box_autoadd_u_64(dynamic raw);
|
||||
bool? dco_decode_opt_box_autoadd_bool(dynamic raw);
|
||||
|
||||
@protected
|
||||
BigInt? dco_decode_opt_box_autoadd_u_64(dynamic raw);
|
||||
|
||||
@protected
|
||||
Uint8List? dco_decode_opt_list_prim_u_8_strict(dynamic raw);
|
||||
@ -100,7 +106,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
int dco_decode_u_32(dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_u_64(dynamic raw);
|
||||
BigInt dco_decode_u_64(dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_u_8(dynamic raw);
|
||||
@ -112,7 +118,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
Map<String, String> sse_decode_Map_String_String(
|
||||
Map<String, String> sse_decode_Map_String_String_None(
|
||||
SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
@ -126,12 +132,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
@protected
|
||||
bool sse_decode_bool(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
bool sse_decode_box_autoadd_bool(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
RsiLauncherAsarData sse_decode_box_autoadd_rsi_launcher_asar_data(
|
||||
SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_box_autoadd_u_64(SseDeserializer deserializer);
|
||||
BigInt sse_decode_box_autoadd_u_64(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_i_32(SseDeserializer deserializer);
|
||||
@ -156,14 +165,17 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
MyMethod sse_decode_my_method(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
Map<String, String>? sse_decode_opt_Map_String_String(
|
||||
Map<String, String>? sse_decode_opt_Map_String_String_None(
|
||||
SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
String? sse_decode_opt_String(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int? sse_decode_opt_box_autoadd_u_64(SseDeserializer deserializer);
|
||||
bool? sse_decode_opt_box_autoadd_bool(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
BigInt? sse_decode_opt_box_autoadd_u_64(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
Uint8List? sse_decode_opt_list_prim_u_8_strict(SseDeserializer deserializer);
|
||||
@ -194,7 +206,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
int sse_decode_u_32(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_u_64(SseDeserializer deserializer);
|
||||
BigInt sse_decode_u_64(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_u_8(SseDeserializer deserializer);
|
||||
@ -210,8 +222,8 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
}
|
||||
|
||||
@protected
|
||||
ffi.Pointer<wire_cst_list_record_string_string> cst_encode_Map_String_String(
|
||||
Map<String, String> raw) {
|
||||
ffi.Pointer<wire_cst_list_record_string_string>
|
||||
cst_encode_Map_String_String_None(Map<String, String> raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
return cst_encode_list_record_string_string(
|
||||
raw.entries.map((e) => (e.key, e.value)).toList());
|
||||
@ -224,8 +236,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
return cst_encode_String(raw.setupAndSerialize(
|
||||
codec: DcoCodec(
|
||||
decodeSuccessData: dco_decode_rs_process_stream_data,
|
||||
decodeErrorData: null)));
|
||||
decodeSuccessData: dco_decode_rs_process_stream_data,
|
||||
decodeErrorData: dco_decode_AnyhowException,
|
||||
)));
|
||||
}
|
||||
|
||||
@protected
|
||||
@ -234,6 +247,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
return cst_encode_list_prim_u_8_strict(utf8.encoder.convert(raw));
|
||||
}
|
||||
|
||||
@protected
|
||||
ffi.Pointer<ffi.Bool> cst_encode_box_autoadd_bool(bool raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
return wire.cst_new_box_autoadd_bool(cst_encode_bool(raw));
|
||||
}
|
||||
|
||||
@protected
|
||||
ffi.Pointer<wire_cst_rsi_launcher_asar_data>
|
||||
cst_encode_box_autoadd_rsi_launcher_asar_data(RsiLauncherAsarData raw) {
|
||||
@ -244,7 +263,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
}
|
||||
|
||||
@protected
|
||||
ffi.Pointer<ffi.Uint64> cst_encode_box_autoadd_u_64(int raw) {
|
||||
ffi.Pointer<ffi.Uint64> cst_encode_box_autoadd_u_64(BigInt raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
return wire.cst_new_box_autoadd_u_64(cst_encode_u_64(raw));
|
||||
}
|
||||
@ -290,9 +309,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
|
||||
@protected
|
||||
ffi.Pointer<wire_cst_list_record_string_string>
|
||||
cst_encode_opt_Map_String_String(Map<String, String>? raw) {
|
||||
cst_encode_opt_Map_String_String_None(Map<String, String>? raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
return raw == null ? ffi.nullptr : cst_encode_Map_String_String(raw);
|
||||
return raw == null ? ffi.nullptr : cst_encode_Map_String_String_None(raw);
|
||||
}
|
||||
|
||||
@protected
|
||||
@ -303,7 +322,13 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
}
|
||||
|
||||
@protected
|
||||
ffi.Pointer<ffi.Uint64> cst_encode_opt_box_autoadd_u_64(int? raw) {
|
||||
ffi.Pointer<ffi.Bool> cst_encode_opt_box_autoadd_bool(bool? raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
return raw == null ? ffi.nullptr : cst_encode_box_autoadd_bool(raw);
|
||||
}
|
||||
|
||||
@protected
|
||||
ffi.Pointer<ffi.Uint64> cst_encode_opt_box_autoadd_u_64(BigInt? raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
return raw == null ? ffi.nullptr : cst_encode_box_autoadd_u_64(raw);
|
||||
}
|
||||
@ -316,9 +341,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
}
|
||||
|
||||
@protected
|
||||
int cst_encode_u_64(int raw) {
|
||||
int cst_encode_u_64(BigInt raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
return raw.toInt();
|
||||
return raw.toSigned(64).toInt();
|
||||
}
|
||||
|
||||
@protected
|
||||
@ -356,7 +381,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
void cst_api_fill_to_wire_rust_http_response(
|
||||
RustHttpResponse apiObj, wire_cst_rust_http_response wireObj) {
|
||||
wireObj.status_code = cst_encode_u_16(apiObj.statusCode);
|
||||
wireObj.headers = cst_encode_Map_String_String(apiObj.headers);
|
||||
wireObj.headers = cst_encode_Map_String_String_None(apiObj.headers);
|
||||
wireObj.url = cst_encode_String(apiObj.url);
|
||||
wireObj.content_length =
|
||||
cst_encode_opt_box_autoadd_u_64(apiObj.contentLength);
|
||||
@ -397,7 +422,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
AnyhowException self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_Map_String_String(
|
||||
void sse_encode_Map_String_String_None(
|
||||
Map<String, String> self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
@ -410,12 +435,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
@protected
|
||||
void sse_encode_bool(bool self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_box_autoadd_bool(bool self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_box_autoadd_rsi_launcher_asar_data(
|
||||
RsiLauncherAsarData self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_box_autoadd_u_64(int self, SseSerializer serializer);
|
||||
void sse_encode_box_autoadd_u_64(BigInt self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_i_32(int self, SseSerializer serializer);
|
||||
@ -441,14 +469,17 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
void sse_encode_my_method(MyMethod self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_Map_String_String(
|
||||
void sse_encode_opt_Map_String_String_None(
|
||||
Map<String, String>? self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_String(String? self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_box_autoadd_u_64(int? self, SseSerializer serializer);
|
||||
void sse_encode_opt_box_autoadd_bool(bool? self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_box_autoadd_u_64(BigInt? self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_list_prim_u_8_strict(
|
||||
@ -481,7 +512,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
void sse_encode_u_32(int self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_u_64(int self, SseSerializer serializer);
|
||||
void sse_encode_u_64(BigInt self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_u_8(int self, SseSerializer serializer);
|
||||
@ -531,104 +562,65 @@ class RustLibWire implements BaseWire {
|
||||
late final _store_dart_post_cobject = _store_dart_post_cobjectPtr
|
||||
.asFunction<void Function(DartPostCObjectFnType)>();
|
||||
|
||||
void wire_get_rsi_launcher_asar_data(
|
||||
void wire__crate__api__http_api__dns_lookup_ips(
|
||||
int port_,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> asar_path,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> host,
|
||||
) {
|
||||
return _wire_get_rsi_launcher_asar_data(
|
||||
return _wire__crate__api__http_api__dns_lookup_ips(
|
||||
port_,
|
||||
asar_path,
|
||||
host,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire_get_rsi_launcher_asar_dataPtr = _lookup<
|
||||
late final _wire__crate__api__http_api__dns_lookup_ipsPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||
'frbgen_starcitizen_doctor_wire_get_rsi_launcher_asar_data');
|
||||
late final _wire_get_rsi_launcher_asar_data =
|
||||
_wire_get_rsi_launcher_asar_dataPtr.asFunction<
|
||||
'frbgen_starcitizen_doctor_wire__crate__api__http_api__dns_lookup_ips');
|
||||
late final _wire__crate__api__http_api__dns_lookup_ips =
|
||||
_wire__crate__api__http_api__dns_lookup_ipsPtr.asFunction<
|
||||
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
|
||||
void wire_rsi_launcher_asar_data_write_main_js(
|
||||
int port_,
|
||||
ffi.Pointer<wire_cst_rsi_launcher_asar_data> that,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_loose> content,
|
||||
) {
|
||||
return _wire_rsi_launcher_asar_data_write_main_js(
|
||||
port_,
|
||||
that,
|
||||
content,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire_rsi_launcher_asar_data_write_main_jsPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64,
|
||||
ffi.Pointer<wire_cst_rsi_launcher_asar_data>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_loose>)>>(
|
||||
'frbgen_starcitizen_doctor_wire_rsi_launcher_asar_data_write_main_js');
|
||||
late final _wire_rsi_launcher_asar_data_write_main_js =
|
||||
_wire_rsi_launcher_asar_data_write_main_jsPtr.asFunction<
|
||||
void Function(int, ffi.Pointer<wire_cst_rsi_launcher_asar_data>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_loose>)>();
|
||||
|
||||
void wire_dns_lookup_ips(
|
||||
void wire__crate__api__http_api__dns_lookup_txt(
|
||||
int port_,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> host,
|
||||
) {
|
||||
return _wire_dns_lookup_ips(
|
||||
return _wire__crate__api__http_api__dns_lookup_txt(
|
||||
port_,
|
||||
host,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire_dns_lookup_ipsPtr = _lookup<
|
||||
late final _wire__crate__api__http_api__dns_lookup_txtPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||
'frbgen_starcitizen_doctor_wire_dns_lookup_ips');
|
||||
late final _wire_dns_lookup_ips = _wire_dns_lookup_ipsPtr.asFunction<
|
||||
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
'frbgen_starcitizen_doctor_wire__crate__api__http_api__dns_lookup_txt');
|
||||
late final _wire__crate__api__http_api__dns_lookup_txt =
|
||||
_wire__crate__api__http_api__dns_lookup_txtPtr.asFunction<
|
||||
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
|
||||
void wire_dns_lookup_txt(
|
||||
int port_,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> host,
|
||||
) {
|
||||
return _wire_dns_lookup_txt(
|
||||
port_,
|
||||
host,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire_dns_lookup_txtPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||
'frbgen_starcitizen_doctor_wire_dns_lookup_txt');
|
||||
late final _wire_dns_lookup_txt = _wire_dns_lookup_txtPtr.asFunction<
|
||||
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
|
||||
void wire_fetch(
|
||||
void wire__crate__api__http_api__fetch(
|
||||
int port_,
|
||||
int method,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> url,
|
||||
ffi.Pointer<wire_cst_list_record_string_string> headers,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> input_data,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> with_ip_address,
|
||||
ffi.Pointer<ffi.Bool> with_custom_dns,
|
||||
) {
|
||||
return _wire_fetch(
|
||||
return _wire__crate__api__http_api__fetch(
|
||||
port_,
|
||||
method,
|
||||
url,
|
||||
headers,
|
||||
input_data,
|
||||
with_ip_address,
|
||||
with_custom_dns,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire_fetchPtr = _lookup<
|
||||
late final _wire__crate__api__http_api__fetchPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64,
|
||||
@ -636,96 +628,73 @@ class RustLibWire implements BaseWire {
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_record_string_string>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||
'frbgen_starcitizen_doctor_wire_fetch');
|
||||
late final _wire_fetch = _wire_fetchPtr.asFunction<
|
||||
void Function(
|
||||
int,
|
||||
int,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_record_string_string>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<ffi.Bool>)>>(
|
||||
'frbgen_starcitizen_doctor_wire__crate__api__http_api__fetch');
|
||||
late final _wire__crate__api__http_api__fetch =
|
||||
_wire__crate__api__http_api__fetchPtr.asFunction<
|
||||
void Function(
|
||||
int,
|
||||
int,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_record_string_string>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<ffi.Bool>)>();
|
||||
|
||||
void wire_set_default_header(
|
||||
void wire__crate__api__asar_api__get_rsi_launcher_asar_data(
|
||||
int port_,
|
||||
ffi.Pointer<wire_cst_list_record_string_string> headers,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> asar_path,
|
||||
) {
|
||||
return _wire_set_default_header(
|
||||
return _wire__crate__api__asar_api__get_rsi_launcher_asar_data(
|
||||
port_,
|
||||
headers,
|
||||
asar_path,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire_set_default_headerPtr = _lookup<
|
||||
late final _wire__crate__api__asar_api__get_rsi_launcher_asar_dataPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64, ffi.Pointer<wire_cst_list_record_string_string>)>>(
|
||||
'frbgen_starcitizen_doctor_wire_set_default_header');
|
||||
late final _wire_set_default_header = _wire_set_default_headerPtr.asFunction<
|
||||
void Function(int, ffi.Pointer<wire_cst_list_record_string_string>)>();
|
||||
ffi.Int64, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||
'frbgen_starcitizen_doctor_wire__crate__api__asar_api__get_rsi_launcher_asar_data');
|
||||
late final _wire__crate__api__asar_api__get_rsi_launcher_asar_data =
|
||||
_wire__crate__api__asar_api__get_rsi_launcher_asar_dataPtr.asFunction<
|
||||
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
|
||||
void wire_start(
|
||||
void wire__crate__api__asar_api__rsi_launcher_asar_data_write_main_js(
|
||||
int port_,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> executable,
|
||||
ffi.Pointer<wire_cst_list_String> arguments,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> working_directory,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> stream_sink,
|
||||
ffi.Pointer<wire_cst_rsi_launcher_asar_data> that,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_loose> content,
|
||||
) {
|
||||
return _wire_start(
|
||||
return _wire__crate__api__asar_api__rsi_launcher_asar_data_write_main_js(
|
||||
port_,
|
||||
executable,
|
||||
arguments,
|
||||
working_directory,
|
||||
stream_sink,
|
||||
that,
|
||||
content,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire_startPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_String>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||
'frbgen_starcitizen_doctor_wire_start');
|
||||
late final _wire_start = _wire_startPtr.asFunction<
|
||||
void Function(
|
||||
int,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_String>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
late final _wire__crate__api__asar_api__rsi_launcher_asar_data_write_main_jsPtr =
|
||||
_lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64,
|
||||
ffi.Pointer<wire_cst_rsi_launcher_asar_data>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_loose>)>>(
|
||||
'frbgen_starcitizen_doctor_wire__crate__api__asar_api__rsi_launcher_asar_data_write_main_js');
|
||||
late final _wire__crate__api__asar_api__rsi_launcher_asar_data_write_main_js =
|
||||
_wire__crate__api__asar_api__rsi_launcher_asar_data_write_main_jsPtr
|
||||
.asFunction<
|
||||
void Function(int, ffi.Pointer<wire_cst_rsi_launcher_asar_data>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_loose>)>();
|
||||
|
||||
void wire_write(
|
||||
int port_,
|
||||
int rs_pid,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> data,
|
||||
) {
|
||||
return _wire_write(
|
||||
port_,
|
||||
rs_pid,
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire_writePtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(ffi.Int64, ffi.Uint32,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||
'frbgen_starcitizen_doctor_wire_write');
|
||||
late final _wire_write = _wire_writePtr.asFunction<
|
||||
void Function(int, int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
|
||||
void wire_send_notify(
|
||||
void wire__crate__api__win32_api__send_notify(
|
||||
int port_,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> summary,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> body,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> app_name,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> app_id,
|
||||
) {
|
||||
return _wire_send_notify(
|
||||
return _wire__crate__api__win32_api__send_notify(
|
||||
port_,
|
||||
summary,
|
||||
body,
|
||||
@ -734,7 +703,7 @@ class RustLibWire implements BaseWire {
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire_send_notifyPtr = _lookup<
|
||||
late final _wire__crate__api__win32_api__send_notifyPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64,
|
||||
@ -742,34 +711,125 @@ class RustLibWire implements BaseWire {
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||
'frbgen_starcitizen_doctor_wire_send_notify');
|
||||
late final _wire_send_notify = _wire_send_notifyPtr.asFunction<
|
||||
void Function(
|
||||
int,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
'frbgen_starcitizen_doctor_wire__crate__api__win32_api__send_notify');
|
||||
late final _wire__crate__api__win32_api__send_notify =
|
||||
_wire__crate__api__win32_api__send_notifyPtr.asFunction<
|
||||
void Function(
|
||||
int,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
|
||||
void wire_set_foreground_window(
|
||||
void wire__crate__api__http_api__set_default_header(
|
||||
int port_,
|
||||
ffi.Pointer<wire_cst_list_record_string_string> headers,
|
||||
) {
|
||||
return _wire__crate__api__http_api__set_default_header(
|
||||
port_,
|
||||
headers,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire__crate__api__http_api__set_default_headerPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64, ffi.Pointer<wire_cst_list_record_string_string>)>>(
|
||||
'frbgen_starcitizen_doctor_wire__crate__api__http_api__set_default_header');
|
||||
late final _wire__crate__api__http_api__set_default_header =
|
||||
_wire__crate__api__http_api__set_default_headerPtr.asFunction<
|
||||
void Function(
|
||||
int, ffi.Pointer<wire_cst_list_record_string_string>)>();
|
||||
|
||||
void wire__crate__api__win32_api__set_foreground_window(
|
||||
int port_,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> window_name,
|
||||
) {
|
||||
return _wire_set_foreground_window(
|
||||
return _wire__crate__api__win32_api__set_foreground_window(
|
||||
port_,
|
||||
window_name,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire_set_foreground_windowPtr = _lookup<
|
||||
late final _wire__crate__api__win32_api__set_foreground_windowPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||
'frbgen_starcitizen_doctor_wire_set_foreground_window');
|
||||
late final _wire_set_foreground_window =
|
||||
_wire_set_foreground_windowPtr.asFunction<
|
||||
'frbgen_starcitizen_doctor_wire__crate__api__win32_api__set_foreground_window');
|
||||
late final _wire__crate__api__win32_api__set_foreground_window =
|
||||
_wire__crate__api__win32_api__set_foreground_windowPtr.asFunction<
|
||||
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
|
||||
void wire__crate__api__rs_process__start(
|
||||
int port_,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> executable,
|
||||
ffi.Pointer<wire_cst_list_String> arguments,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> working_directory,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> stream_sink,
|
||||
) {
|
||||
return _wire__crate__api__rs_process__start(
|
||||
port_,
|
||||
executable,
|
||||
arguments,
|
||||
working_directory,
|
||||
stream_sink,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire__crate__api__rs_process__startPtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(
|
||||
ffi.Int64,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_String>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||
'frbgen_starcitizen_doctor_wire__crate__api__rs_process__start');
|
||||
late final _wire__crate__api__rs_process__start =
|
||||
_wire__crate__api__rs_process__startPtr.asFunction<
|
||||
void Function(
|
||||
int,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_String>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
|
||||
void wire__crate__api__rs_process__write(
|
||||
int port_,
|
||||
int rs_pid,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> data,
|
||||
) {
|
||||
return _wire__crate__api__rs_process__write(
|
||||
port_,
|
||||
rs_pid,
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire__crate__api__rs_process__writePtr = _lookup<
|
||||
ffi.NativeFunction<
|
||||
ffi.Void Function(ffi.Int64, ffi.Uint32,
|
||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>)>>(
|
||||
'frbgen_starcitizen_doctor_wire__crate__api__rs_process__write');
|
||||
late final _wire__crate__api__rs_process__write =
|
||||
_wire__crate__api__rs_process__writePtr.asFunction<
|
||||
void Function(
|
||||
int, int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)>();
|
||||
|
||||
ffi.Pointer<ffi.Bool> cst_new_box_autoadd_bool(
|
||||
bool value,
|
||||
) {
|
||||
return _cst_new_box_autoadd_bool(
|
||||
value,
|
||||
);
|
||||
}
|
||||
|
||||
late final _cst_new_box_autoadd_boolPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Bool> Function(ffi.Bool)>>(
|
||||
'frbgen_starcitizen_doctor_cst_new_box_autoadd_bool');
|
||||
late final _cst_new_box_autoadd_bool = _cst_new_box_autoadd_boolPtr
|
||||
.asFunction<ffi.Pointer<ffi.Bool> Function(bool)>();
|
||||
|
||||
ffi.Pointer<wire_cst_rsi_launcher_asar_data>
|
||||
cst_new_box_autoadd_rsi_launcher_asar_data() {
|
||||
return _cst_new_box_autoadd_rsi_launcher_asar_data();
|
||||
@ -871,14 +931,14 @@ class RustLibWire implements BaseWire {
|
||||
_dummy_method_to_enforce_bundlingPtr.asFunction<int Function()>();
|
||||
}
|
||||
|
||||
typedef DartPostCObjectFnType
|
||||
= ffi.Pointer<ffi.NativeFunction<DartPostCObjectFnTypeFunction>>;
|
||||
typedef DartPort = ffi.Int64;
|
||||
typedef DartDartPort = int;
|
||||
typedef DartPostCObjectFnTypeFunction = ffi.Bool Function(
|
||||
DartPort port_id, ffi.Pointer<ffi.Void> message);
|
||||
typedef DartDartPostCObjectFnTypeFunction = bool Function(
|
||||
DartDartPort port_id, ffi.Pointer<ffi.Void> message);
|
||||
typedef DartPort = ffi.Int64;
|
||||
typedef DartDartPort = int;
|
||||
typedef DartPostCObjectFnType
|
||||
= ffi.Pointer<ffi.NativeFunction<DartPostCObjectFnTypeFunction>>;
|
||||
|
||||
final class wire_cst_list_prim_u_8_strict extends ffi.Struct {
|
||||
external ffi.Pointer<ffi.Uint8> ptr;
|
||||
@ -887,6 +947,19 @@ final class wire_cst_list_prim_u_8_strict extends ffi.Struct {
|
||||
external int len;
|
||||
}
|
||||
|
||||
final class wire_cst_record_string_string extends ffi.Struct {
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> field0;
|
||||
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> field1;
|
||||
}
|
||||
|
||||
final class wire_cst_list_record_string_string extends ffi.Struct {
|
||||
external ffi.Pointer<wire_cst_record_string_string> ptr;
|
||||
|
||||
@ffi.Int32()
|
||||
external int len;
|
||||
}
|
||||
|
||||
final class wire_cst_rsi_launcher_asar_data extends ffi.Struct {
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> asar_path;
|
||||
|
||||
@ -902,19 +975,6 @@ final class wire_cst_list_prim_u_8_loose extends ffi.Struct {
|
||||
external int len;
|
||||
}
|
||||
|
||||
final class wire_cst_record_string_string extends ffi.Struct {
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> field0;
|
||||
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> field1;
|
||||
}
|
||||
|
||||
final class wire_cst_list_record_string_string extends ffi.Struct {
|
||||
external ffi.Pointer<wire_cst_record_string_string> ptr;
|
||||
|
||||
@ffi.Int32()
|
||||
external int len;
|
||||
}
|
||||
|
||||
final class wire_cst_list_String extends ffi.Struct {
|
||||
external ffi.Pointer<ffi.Pointer<wire_cst_list_prim_u_8_strict>> ptr;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// This file is automatically generated, so please do not edit it.
|
||||
// Generated by `flutter_rust_bridge`@ 2.0.0-dev.33.
|
||||
// @generated by `flutter_rust_bridge`@ 2.9.0.
|
||||
|
||||
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||
|
||||
@ -20,7 +20,7 @@ class RustHttpResponse {
|
||||
final int statusCode;
|
||||
final Map<String, String> headers;
|
||||
final String url;
|
||||
final int? contentLength;
|
||||
final BigInt? contentLength;
|
||||
final MyHttpVersion version;
|
||||
final String remoteAddr;
|
||||
final Uint8List? data;
|
||||
|
@ -7,16 +7,14 @@ import 'dart:ui' as ui;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:starcitizen_doctor/generated/l10n.dart';
|
||||
|
||||
Future showToast(BuildContext context, String msg,
|
||||
{BoxConstraints? constraints, String? title}) async {
|
||||
Future showToast(BuildContext context, String msg, {BoxConstraints? constraints, String? title}) async {
|
||||
return showBaseDialog(context,
|
||||
title: title ?? S.current.app_common_tip,
|
||||
content: Text(msg),
|
||||
actions: [
|
||||
FilledButton(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
padding: const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
child: Text(S.current.app_common_tip_i_know),
|
||||
),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
@ -25,11 +23,8 @@ Future showToast(BuildContext context, String msg,
|
||||
constraints: constraints);
|
||||
}
|
||||
|
||||
Future<bool> showConfirmDialogs(
|
||||
BuildContext context, String title, Widget content,
|
||||
{String confirm = "",
|
||||
String cancel = "",
|
||||
BoxConstraints? constraints}) async {
|
||||
Future<bool> showConfirmDialogs(BuildContext context, String title, Widget content,
|
||||
{String confirm = "", String cancel = "", BoxConstraints? constraints}) async {
|
||||
if (confirm.isEmpty) confirm = S.current.app_common_tip_confirm;
|
||||
if (cancel.isEmpty) cancel = S.current.app_common_tip_cancel;
|
||||
|
||||
@ -40,8 +35,7 @@ Future<bool> showConfirmDialogs(
|
||||
if (confirm.isNotEmpty)
|
||||
FilledButton(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
padding: const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
child: Text(confirm),
|
||||
),
|
||||
onPressed: () => Navigator.pop(context, true),
|
||||
@ -49,8 +43,7 @@ Future<bool> showConfirmDialogs(
|
||||
if (cancel.isNotEmpty)
|
||||
Button(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
padding: const EdgeInsets.only(top: 2, bottom: 2, left: 8, right: 8),
|
||||
child: Text(cancel),
|
||||
),
|
||||
onPressed: () => Navigator.pop(context, false),
|
||||
@ -62,13 +55,15 @@ Future<bool> showConfirmDialogs(
|
||||
|
||||
Future<String?> showInputDialogs(BuildContext context,
|
||||
{required String title,
|
||||
required String content,
|
||||
BoxConstraints? constraints,
|
||||
String? initialValue,
|
||||
List<TextInputFormatter>? inputFormatters}) async {
|
||||
required String content,
|
||||
BoxConstraints? constraints,
|
||||
String? initialValue,
|
||||
List<TextInputFormatter>? inputFormatters}) async {
|
||||
String? userInput;
|
||||
constraints ??=
|
||||
BoxConstraints(maxWidth: MediaQuery.of(context).size.width * .38);
|
||||
constraints ??= BoxConstraints(maxWidth: MediaQuery
|
||||
.of(context)
|
||||
.size
|
||||
.width * .38);
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
title,
|
||||
@ -79,7 +74,7 @@ Future<String?> showInputDialogs(BuildContext context,
|
||||
if (content.isNotEmpty)
|
||||
Text(
|
||||
content,
|
||||
style: TextStyle(color: Colors.white.withOpacity(.6)),
|
||||
style: TextStyle(color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextFormBox(
|
||||
@ -97,22 +92,20 @@ Future<String?> showInputDialogs(BuildContext context,
|
||||
}
|
||||
|
||||
Future showBaseDialog(BuildContext context,
|
||||
{required String title,
|
||||
required Widget content,
|
||||
List<Widget>? actions,
|
||||
BoxConstraints? constraints}) async {
|
||||
{required String title, required Widget content, List<Widget>? actions, BoxConstraints? constraints}) async {
|
||||
return await showDialog(
|
||||
context: context,
|
||||
builder: (context) => ContentDialog(
|
||||
title: Text(title),
|
||||
content: content,
|
||||
constraints: constraints ??
|
||||
const BoxConstraints(
|
||||
maxWidth: 512,
|
||||
maxHeight: 756.0,
|
||||
),
|
||||
actions: actions,
|
||||
),
|
||||
builder: (context) =>
|
||||
ContentDialog(
|
||||
title: Text(title),
|
||||
content: content,
|
||||
constraints: constraints ??
|
||||
const BoxConstraints(
|
||||
maxWidth: 512,
|
||||
maxHeight: 756.0,
|
||||
),
|
||||
actions: actions,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -120,10 +113,8 @@ bool stringIsNotEmpty(String? s) {
|
||||
return s != null && (s.isNotEmpty);
|
||||
}
|
||||
|
||||
Future<Uint8List?> widgetToPngImage(GlobalKey repaintBoundaryKey,
|
||||
{double pixelRatio = 3.0}) async {
|
||||
RenderRepaintBoundary? boundary = repaintBoundaryKey.currentContext
|
||||
?.findRenderObject() as RenderRepaintBoundary?;
|
||||
Future<Uint8List?> widgetToPngImage(GlobalKey repaintBoundaryKey, {double pixelRatio = 3.0}) async {
|
||||
RenderRepaintBoundary? boundary = repaintBoundaryKey.currentContext?.findRenderObject() as RenderRepaintBoundary?;
|
||||
if (boundary == null) return null;
|
||||
|
||||
ui.Image image = await boundary.toImage(pixelRatio: pixelRatio);
|
||||
@ -133,11 +124,25 @@ Future<Uint8List?> widgetToPngImage(GlobalKey repaintBoundaryKey,
|
||||
return pngBytes;
|
||||
}
|
||||
|
||||
double roundDoubleTo(double value, double precision) =>
|
||||
(value * precision).round() / precision;
|
||||
double roundDoubleTo(double value, double precision) => (value * precision).round() / precision;
|
||||
|
||||
int getMinNumber(List<int> list) {
|
||||
if (list.isEmpty) return 0;
|
||||
list.sort((a, b) => a.compareTo(b));
|
||||
return list.first;
|
||||
}
|
||||
|
||||
String colorToHexCode(Color color, {ignoreTransparency = false}) {
|
||||
final colorValue = color.toARGB32();
|
||||
final colorAlpha = ((0xff000000 & colorValue) >> 24);
|
||||
final r = ((0x00ff0000 & colorValue) >> 16).toRadixString(16).padLeft(2, '0');
|
||||
final g = ((0x0000ff00 & colorValue) >> 8).toRadixString(16).padLeft(2, '0');
|
||||
final b = ((0x000000ff & colorValue) >> 0).toRadixString(16).padLeft(2, '0');
|
||||
final a = colorAlpha.toRadixString(16).padLeft(2, '0');
|
||||
|
||||
if (ignoreTransparency || colorAlpha == 255) {
|
||||
return '#$r$g$b';
|
||||
} else {
|
||||
return '#$a$r$g$b';
|
||||
}
|
||||
}
|
||||
|
101
lib/common/utils/file_cache_utils.dart
Normal file
101
lib/common/utils/file_cache_utils.dart
Normal file
@ -0,0 +1,101 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:starcitizen_doctor/common/io/rs_http.dart';
|
||||
|
||||
class FileCacheUtils {
|
||||
// 存储正在进行的下载任务
|
||||
static final Map<String, Future<File>> _downloadingTasks = {};
|
||||
|
||||
// 缓存目录
|
||||
static Directory? _cacheDir;
|
||||
|
||||
/// 获取缓存目录
|
||||
static Future<Directory> _getCacheDirectory() async {
|
||||
if (_cacheDir != null) return _cacheDir!;
|
||||
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
_cacheDir = Directory(path.join(tempDir.path, 'ScToolbox_File_Cache'));
|
||||
|
||||
if (!await _cacheDir!.exists()) {
|
||||
await _cacheDir!.create(recursive: true);
|
||||
}
|
||||
|
||||
return _cacheDir!;
|
||||
}
|
||||
|
||||
/// 从URL获取文件,如果已经在下载中,则共享同一个下载任务
|
||||
static Future<File> getFile(String url) async {
|
||||
// 如果已经在下载中,直接返回正在进行的下载任务
|
||||
if (_downloadingTasks.containsKey(url)) {
|
||||
return _downloadingTasks[url]!;
|
||||
}
|
||||
|
||||
final fileTask = _downloadFile(url);
|
||||
_downloadingTasks[url] = fileTask;
|
||||
|
||||
try {
|
||||
final file = await fileTask;
|
||||
return file;
|
||||
} finally {
|
||||
// 无论成功失败,下载完成后从任务列表中移除
|
||||
_downloadingTasks.remove(url);
|
||||
}
|
||||
}
|
||||
|
||||
/// 实际进行下载的方法
|
||||
static Future<File> _downloadFile(String url) async {
|
||||
// 生成文件名 (使用URL的MD5哈希作为文件名)
|
||||
final filename = md5.convert(utf8.encode(url)).toString();
|
||||
final cacheDir = await _getCacheDirectory();
|
||||
final file = File(path.join(cacheDir.path, filename));
|
||||
|
||||
// 检查文件是否已经存在
|
||||
if (await file.exists()) {
|
||||
return file;
|
||||
}
|
||||
|
||||
// 下载文件
|
||||
final response = await RSHttp.get(url);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
await file.writeAsBytes(response.data ?? []);
|
||||
return file;
|
||||
} else {
|
||||
throw Exception('Failed to download file: ${response.statusCode}');
|
||||
}
|
||||
}
|
||||
|
||||
/// 清除特定URL的缓存
|
||||
static Future<bool> clearCache(String url) async {
|
||||
try {
|
||||
final filename = md5.convert(utf8.encode(url)).toString();
|
||||
final cacheDir = await _getCacheDirectory();
|
||||
final file = File(path.join(cacheDir.path, filename));
|
||||
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 清除所有缓存
|
||||
static Future<void> clearAllCache() async {
|
||||
try {
|
||||
final cacheDir = await _getCacheDirectory();
|
||||
if (await cacheDir.exists()) {
|
||||
await cacheDir.delete(recursive: true);
|
||||
await cacheDir.create();
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('clear All Cache Error: $e');
|
||||
}
|
||||
}
|
||||
}
|
@ -23,10 +23,10 @@ void dPrint(src) async {
|
||||
Future<void> initDPrintFile(String applicationSupportDir) async {
|
||||
final now = DateTime.now();
|
||||
final logFile =
|
||||
File("$applicationSupportDir\\logs\\${now.millisecondsSinceEpoch}.log");
|
||||
File("$applicationSupportDir/logs/${now.millisecondsSinceEpoch}.log");
|
||||
await logFile.create(recursive: true);
|
||||
_logFile = logFile;
|
||||
final logsDir = Directory("$applicationSupportDir\\logs");
|
||||
final logsDir = Directory("$applicationSupportDir/logs");
|
||||
await for (final files in logsDir.list()) {
|
||||
if (files is File) {
|
||||
final stat = await files.stat();
|
||||
|
116
lib/common/utils/multi_window_manager.dart
Normal file
116
lib/common/utils/multi_window_manager.dart
Normal file
@ -0,0 +1,116 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hexcolor/hexcolor.dart';
|
||||
import 'package:starcitizen_doctor/app.dart';
|
||||
import 'package:starcitizen_doctor/common/helper/log_helper.dart';
|
||||
import 'package:starcitizen_doctor/generated/l10n.dart';
|
||||
import 'package:starcitizen_doctor/ui/tools/log_analyze_ui/log_analyze_ui.dart';
|
||||
|
||||
import 'base_utils.dart';
|
||||
|
||||
part 'multi_window_manager.freezed.dart';
|
||||
|
||||
part 'multi_window_manager.g.dart';
|
||||
|
||||
@freezed
|
||||
class MultiWindowAppState with _$MultiWindowAppState {
|
||||
const factory MultiWindowAppState({
|
||||
required String backgroundColor,
|
||||
required String menuColor,
|
||||
required String micaColor,
|
||||
required List<String> gameInstallPaths,
|
||||
String? languageCode,
|
||||
String? countryCode,
|
||||
}) = _MultiWindowAppState;
|
||||
|
||||
factory MultiWindowAppState.fromJson(Map<String, dynamic> json) => _$MultiWindowAppStateFromJson(json);
|
||||
}
|
||||
|
||||
class MultiWindowManager {
|
||||
static Future<void> launchSubWindow(String type, String title, AppGlobalState appGlobalState) async {
|
||||
final gameInstallPaths = await SCLoggerHelper.getGameInstallPath(await SCLoggerHelper.getLauncherLogList() ?? []);
|
||||
final window = await DesktopMultiWindow.createWindow(jsonEncode({
|
||||
'window_type': type,
|
||||
'app_state': _appStateToWindowState(
|
||||
appGlobalState,
|
||||
gameInstallPaths: gameInstallPaths,
|
||||
).toJson(),
|
||||
}));
|
||||
window.setFrame(const Rect.fromLTWH(0, 0, 900, 1200));
|
||||
window.setTitle(title);
|
||||
await window.center();
|
||||
await window.show();
|
||||
// sendAppStateBroadcast(appGlobalState);
|
||||
}
|
||||
|
||||
static sendAppStateBroadcast(AppGlobalState appGlobalState) {
|
||||
DesktopMultiWindow.invokeMethod(
|
||||
0,
|
||||
'app_state_broadcast',
|
||||
_appStateToWindowState(appGlobalState).toJson(),
|
||||
);
|
||||
}
|
||||
|
||||
static MultiWindowAppState _appStateToWindowState(AppGlobalState appGlobalState, {List<String>? gameInstallPaths}) {
|
||||
return MultiWindowAppState(
|
||||
backgroundColor: colorToHexCode(appGlobalState.themeConf.backgroundColor),
|
||||
menuColor: colorToHexCode(appGlobalState.themeConf.menuColor),
|
||||
micaColor: colorToHexCode(appGlobalState.themeConf.micaColor),
|
||||
languageCode: appGlobalState.appLocale?.languageCode,
|
||||
countryCode: appGlobalState.appLocale?.countryCode,
|
||||
gameInstallPaths: gameInstallPaths ?? [],
|
||||
);
|
||||
}
|
||||
|
||||
static void runSubWindowApp(List<String> args) {
|
||||
final argument = args[2].isEmpty ? const {} : jsonDecode(args[2]) as Map<String, dynamic>;
|
||||
final windowAppState = MultiWindowAppState.fromJson(argument['app_state'] ?? {});
|
||||
Widget? windowWidget;
|
||||
switch (argument["window_type"]) {
|
||||
case "log_analyze":
|
||||
windowWidget = ToolsLogAnalyzeDialogUI(appState: windowAppState);
|
||||
break;
|
||||
default:
|
||||
throw Exception('Unknown window type');
|
||||
}
|
||||
return runApp(ProviderScope(
|
||||
child: FluentApp(
|
||||
title: "StarCitizenToolBox",
|
||||
restorationScopeId: "StarCitizenToolBox",
|
||||
themeMode: ThemeMode.dark,
|
||||
localizationsDelegates: const [
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
FluentLocalizations.delegate,
|
||||
S.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
home: windowWidget,
|
||||
theme: FluentThemeData(
|
||||
brightness: Brightness.dark,
|
||||
fontFamily: "SourceHanSansCN-Regular",
|
||||
navigationPaneTheme: NavigationPaneThemeData(
|
||||
backgroundColor: HexColor(windowAppState.backgroundColor),
|
||||
),
|
||||
menuColor: HexColor(windowAppState.menuColor),
|
||||
micaBackgroundColor: HexColor(windowAppState.micaColor),
|
||||
buttonTheme: ButtonThemeData(
|
||||
defaultButtonStyle: ButtonStyle(
|
||||
shape: WidgetStateProperty.all(RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
side: BorderSide(color: Colors.white.withValues(alpha: .01)))),
|
||||
))),
|
||||
locale: windowAppState.languageCode != null
|
||||
? Locale(windowAppState.languageCode!, windowAppState.countryCode)
|
||||
: null,
|
||||
debugShowCheckedModeBanner: false,
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
290
lib/common/utils/multi_window_manager.freezed.dart
Normal file
290
lib/common/utils/multi_window_manager.freezed.dart
Normal file
@ -0,0 +1,290 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'multi_window_manager.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||
|
||||
MultiWindowAppState _$MultiWindowAppStateFromJson(Map<String, dynamic> json) {
|
||||
return _MultiWindowAppState.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$MultiWindowAppState {
|
||||
String get backgroundColor => throw _privateConstructorUsedError;
|
||||
String get menuColor => throw _privateConstructorUsedError;
|
||||
String get micaColor => throw _privateConstructorUsedError;
|
||||
List<String> get gameInstallPaths => throw _privateConstructorUsedError;
|
||||
String? get languageCode => throw _privateConstructorUsedError;
|
||||
String? get countryCode => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this MultiWindowAppState to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of MultiWindowAppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$MultiWindowAppStateCopyWith<MultiWindowAppState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $MultiWindowAppStateCopyWith<$Res> {
|
||||
factory $MultiWindowAppStateCopyWith(
|
||||
MultiWindowAppState value, $Res Function(MultiWindowAppState) then) =
|
||||
_$MultiWindowAppStateCopyWithImpl<$Res, MultiWindowAppState>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{String backgroundColor,
|
||||
String menuColor,
|
||||
String micaColor,
|
||||
List<String> gameInstallPaths,
|
||||
String? languageCode,
|
||||
String? countryCode});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$MultiWindowAppStateCopyWithImpl<$Res, $Val extends MultiWindowAppState>
|
||||
implements $MultiWindowAppStateCopyWith<$Res> {
|
||||
_$MultiWindowAppStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of MultiWindowAppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? backgroundColor = null,
|
||||
Object? menuColor = null,
|
||||
Object? micaColor = null,
|
||||
Object? gameInstallPaths = null,
|
||||
Object? languageCode = freezed,
|
||||
Object? countryCode = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
backgroundColor: null == backgroundColor
|
||||
? _value.backgroundColor
|
||||
: backgroundColor // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
menuColor: null == menuColor
|
||||
? _value.menuColor
|
||||
: menuColor // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
micaColor: null == micaColor
|
||||
? _value.micaColor
|
||||
: micaColor // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
gameInstallPaths: null == gameInstallPaths
|
||||
? _value.gameInstallPaths
|
||||
: gameInstallPaths // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
languageCode: freezed == languageCode
|
||||
? _value.languageCode
|
||||
: languageCode // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
countryCode: freezed == countryCode
|
||||
? _value.countryCode
|
||||
: countryCode // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$MultiWindowAppStateImplCopyWith<$Res>
|
||||
implements $MultiWindowAppStateCopyWith<$Res> {
|
||||
factory _$$MultiWindowAppStateImplCopyWith(_$MultiWindowAppStateImpl value,
|
||||
$Res Function(_$MultiWindowAppStateImpl) then) =
|
||||
__$$MultiWindowAppStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{String backgroundColor,
|
||||
String menuColor,
|
||||
String micaColor,
|
||||
List<String> gameInstallPaths,
|
||||
String? languageCode,
|
||||
String? countryCode});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$MultiWindowAppStateImplCopyWithImpl<$Res>
|
||||
extends _$MultiWindowAppStateCopyWithImpl<$Res, _$MultiWindowAppStateImpl>
|
||||
implements _$$MultiWindowAppStateImplCopyWith<$Res> {
|
||||
__$$MultiWindowAppStateImplCopyWithImpl(_$MultiWindowAppStateImpl _value,
|
||||
$Res Function(_$MultiWindowAppStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of MultiWindowAppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? backgroundColor = null,
|
||||
Object? menuColor = null,
|
||||
Object? micaColor = null,
|
||||
Object? gameInstallPaths = null,
|
||||
Object? languageCode = freezed,
|
||||
Object? countryCode = freezed,
|
||||
}) {
|
||||
return _then(_$MultiWindowAppStateImpl(
|
||||
backgroundColor: null == backgroundColor
|
||||
? _value.backgroundColor
|
||||
: backgroundColor // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
menuColor: null == menuColor
|
||||
? _value.menuColor
|
||||
: menuColor // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
micaColor: null == micaColor
|
||||
? _value.micaColor
|
||||
: micaColor // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
gameInstallPaths: null == gameInstallPaths
|
||||
? _value._gameInstallPaths
|
||||
: gameInstallPaths // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
languageCode: freezed == languageCode
|
||||
? _value.languageCode
|
||||
: languageCode // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
countryCode: freezed == countryCode
|
||||
? _value.countryCode
|
||||
: countryCode // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$MultiWindowAppStateImpl implements _MultiWindowAppState {
|
||||
const _$MultiWindowAppStateImpl(
|
||||
{required this.backgroundColor,
|
||||
required this.menuColor,
|
||||
required this.micaColor,
|
||||
required final List<String> gameInstallPaths,
|
||||
this.languageCode,
|
||||
this.countryCode})
|
||||
: _gameInstallPaths = gameInstallPaths;
|
||||
|
||||
factory _$MultiWindowAppStateImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$MultiWindowAppStateImplFromJson(json);
|
||||
|
||||
@override
|
||||
final String backgroundColor;
|
||||
@override
|
||||
final String menuColor;
|
||||
@override
|
||||
final String micaColor;
|
||||
final List<String> _gameInstallPaths;
|
||||
@override
|
||||
List<String> get gameInstallPaths {
|
||||
if (_gameInstallPaths is EqualUnmodifiableListView)
|
||||
return _gameInstallPaths;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_gameInstallPaths);
|
||||
}
|
||||
|
||||
@override
|
||||
final String? languageCode;
|
||||
@override
|
||||
final String? countryCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MultiWindowAppState(backgroundColor: $backgroundColor, menuColor: $menuColor, micaColor: $micaColor, gameInstallPaths: $gameInstallPaths, languageCode: $languageCode, countryCode: $countryCode)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$MultiWindowAppStateImpl &&
|
||||
(identical(other.backgroundColor, backgroundColor) ||
|
||||
other.backgroundColor == backgroundColor) &&
|
||||
(identical(other.menuColor, menuColor) ||
|
||||
other.menuColor == menuColor) &&
|
||||
(identical(other.micaColor, micaColor) ||
|
||||
other.micaColor == micaColor) &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other._gameInstallPaths, _gameInstallPaths) &&
|
||||
(identical(other.languageCode, languageCode) ||
|
||||
other.languageCode == languageCode) &&
|
||||
(identical(other.countryCode, countryCode) ||
|
||||
other.countryCode == countryCode));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
backgroundColor,
|
||||
menuColor,
|
||||
micaColor,
|
||||
const DeepCollectionEquality().hash(_gameInstallPaths),
|
||||
languageCode,
|
||||
countryCode);
|
||||
|
||||
/// Create a copy of MultiWindowAppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$MultiWindowAppStateImplCopyWith<_$MultiWindowAppStateImpl> get copyWith =>
|
||||
__$$MultiWindowAppStateImplCopyWithImpl<_$MultiWindowAppStateImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$MultiWindowAppStateImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _MultiWindowAppState implements MultiWindowAppState {
|
||||
const factory _MultiWindowAppState(
|
||||
{required final String backgroundColor,
|
||||
required final String menuColor,
|
||||
required final String micaColor,
|
||||
required final List<String> gameInstallPaths,
|
||||
final String? languageCode,
|
||||
final String? countryCode}) = _$MultiWindowAppStateImpl;
|
||||
|
||||
factory _MultiWindowAppState.fromJson(Map<String, dynamic> json) =
|
||||
_$MultiWindowAppStateImpl.fromJson;
|
||||
|
||||
@override
|
||||
String get backgroundColor;
|
||||
@override
|
||||
String get menuColor;
|
||||
@override
|
||||
String get micaColor;
|
||||
@override
|
||||
List<String> get gameInstallPaths;
|
||||
@override
|
||||
String? get languageCode;
|
||||
@override
|
||||
String? get countryCode;
|
||||
|
||||
/// Create a copy of MultiWindowAppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$MultiWindowAppStateImplCopyWith<_$MultiWindowAppStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
31
lib/common/utils/multi_window_manager.g.dart
Normal file
31
lib/common/utils/multi_window_manager.g.dart
Normal file
@ -0,0 +1,31 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'multi_window_manager.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$MultiWindowAppStateImpl _$$MultiWindowAppStateImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$MultiWindowAppStateImpl(
|
||||
backgroundColor: json['backgroundColor'] as String,
|
||||
menuColor: json['menuColor'] as String,
|
||||
micaColor: json['micaColor'] as String,
|
||||
gameInstallPaths: (json['gameInstallPaths'] as List<dynamic>)
|
||||
.map((e) => e as String)
|
||||
.toList(),
|
||||
languageCode: json['languageCode'] as String?,
|
||||
countryCode: json['countryCode'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$MultiWindowAppStateImplToJson(
|
||||
_$MultiWindowAppStateImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'backgroundColor': instance.backgroundColor,
|
||||
'menuColor': instance.menuColor,
|
||||
'micaColor': instance.micaColor,
|
||||
'gameInstallPaths': instance.gameInstallPaths,
|
||||
'languageCode': instance.languageCode,
|
||||
'countryCode': instance.countryCode,
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:starcitizen_doctor/app.dart';
|
||||
|
||||
extension ProviderExtension on AutoDisposeNotifier {
|
||||
|
@ -1,28 +1,33 @@
|
||||
/// name : "Data.p4k"
|
||||
/// update_at : "2024-02-24 18:00"
|
||||
/// url : "https://p4k.42kit.com/3.22.1-LIVE.9072370/Data.p4k.torrent"
|
||||
/// update_at : "2024-09-03 15:00"
|
||||
/// url : "https://p4k.42kit.com/3.24.1-LIVE.9234446/Data.p4k.torrent"
|
||||
/// info : "3.24.1-LIVE.9234446"
|
||||
|
||||
class AppTorrentData {
|
||||
AppTorrentData({
|
||||
this.name,
|
||||
this.updateAt,
|
||||
this.url,});
|
||||
this.name,
|
||||
this.updateAt,
|
||||
this.url,
|
||||
this.info,
|
||||
});
|
||||
|
||||
AppTorrentData.fromJson(dynamic json) {
|
||||
name = json['name'];
|
||||
updateAt = json['update_at'];
|
||||
url = json['url'];
|
||||
info = json['info'];
|
||||
}
|
||||
String? name;
|
||||
String? updateAt;
|
||||
String? url;
|
||||
String? info;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['name'] = name;
|
||||
map['update_at'] = updateAt;
|
||||
map['url'] = url;
|
||||
map['info'] = info;
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,9 @@ class AppVersionData {
|
||||
this.mSEMinVersionCode,
|
||||
this.p4kDownloadUrl,
|
||||
this.activityColors,
|
||||
this.nav42KitUrl,
|
||||
this.gameChannels,
|
||||
this.webMirrors,
|
||||
});
|
||||
|
||||
AppVersionData.fromJson(dynamic json) {
|
||||
@ -27,10 +30,10 @@ class AppVersionData {
|
||||
mSELastVersionCode = json['MSE_lastVersionCode'];
|
||||
mSEMinVersionCode = json['MSE_minVersionCode'];
|
||||
p4kDownloadUrl = json['p4kDownloadUrl'];
|
||||
activityColors = json['activityColors'] != null
|
||||
? ActivityColors.fromJson(json['activityColors'])
|
||||
: null;
|
||||
activityColors = json['activityColors'] != null ? ActivityColors.fromJson(json['activityColors']) : null;
|
||||
gameChannels = List.from(json["game_channels"]).cast<String>();
|
||||
webMirrors = json["web_mirrors"];
|
||||
nav42KitUrl = json['nav_42kit_url'];
|
||||
}
|
||||
|
||||
String? lastVersion;
|
||||
@ -41,7 +44,9 @@ class AppVersionData {
|
||||
num? mSEMinVersionCode;
|
||||
String? p4kDownloadUrl;
|
||||
ActivityColors? activityColors;
|
||||
List<String>? gameChannels;
|
||||
Map? webMirrors;
|
||||
String? nav42KitUrl;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
@ -56,6 +61,8 @@ class AppVersionData {
|
||||
map['activityColors'] = activityColors?.toJson();
|
||||
}
|
||||
map["web_mirrors"] = webMirrors;
|
||||
map["game_channels"] = gameChannels;
|
||||
map["nav_42kit_url"] = nav42KitUrl;
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
108
lib/data/doh_client_response_data.dart
Normal file
108
lib/data/doh_client_response_data.dart
Normal file
@ -0,0 +1,108 @@
|
||||
class DohClientResponseData {
|
||||
DohClientResponseData({
|
||||
this.status,
|
||||
this.tc,
|
||||
this.rd,
|
||||
this.ra,
|
||||
this.ad,
|
||||
this.cd,
|
||||
this.question,
|
||||
this.answer,
|
||||
});
|
||||
|
||||
DohClientResponseData.fromJson(dynamic json) {
|
||||
status = json['Status'];
|
||||
tc = json['TC'];
|
||||
rd = json['RD'];
|
||||
ra = json['RA'];
|
||||
ad = json['AD'];
|
||||
cd = json['CD'];
|
||||
question = json['Question'] != null
|
||||
? DohClientResponseQuestionData.fromJson(json['Question'])
|
||||
: null;
|
||||
if (json['Answer'] != null) {
|
||||
answer = [];
|
||||
json['Answer'].forEach((v) {
|
||||
answer?.add(DohClientResponseAnswerData.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
num? status;
|
||||
bool? tc;
|
||||
bool? rd;
|
||||
bool? ra;
|
||||
bool? ad;
|
||||
bool? cd;
|
||||
DohClientResponseQuestionData? question;
|
||||
List<DohClientResponseAnswerData>? answer;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['Status'] = status;
|
||||
map['TC'] = tc;
|
||||
map['RD'] = rd;
|
||||
map['RA'] = ra;
|
||||
map['AD'] = ad;
|
||||
map['CD'] = cd;
|
||||
if (question != null) {
|
||||
map['Question'] = question?.toJson();
|
||||
}
|
||||
if (answer != null) {
|
||||
map['Answer'] = answer?.map((v) => v.toJson()).toList();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
class DohClientResponseAnswerData {
|
||||
DohClientResponseAnswerData({
|
||||
this.name,
|
||||
this.ttl,
|
||||
this.type,
|
||||
this.data,
|
||||
});
|
||||
|
||||
DohClientResponseAnswerData.fromJson(dynamic json) {
|
||||
name = json['name'];
|
||||
ttl = json['TTL'];
|
||||
type = json['type'];
|
||||
data = json['data'];
|
||||
}
|
||||
|
||||
String? name;
|
||||
num? ttl;
|
||||
num? type;
|
||||
String? data;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['name'] = name;
|
||||
map['TTL'] = ttl;
|
||||
map['type'] = type;
|
||||
map['data'] = data;
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
class DohClientResponseQuestionData {
|
||||
DohClientResponseQuestionData({
|
||||
this.name,
|
||||
this.type,
|
||||
});
|
||||
|
||||
DohClientResponseQuestionData.fromJson(dynamic json) {
|
||||
name = json['name'];
|
||||
type = json['type'];
|
||||
}
|
||||
|
||||
String? name;
|
||||
num? type;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['name'] = name;
|
||||
map['type'] = type;
|
||||
return map;
|
||||
}
|
||||
}
|
52
lib/data/input_method_api_data.dart
Normal file
52
lib/data/input_method_api_data.dart
Normal file
@ -0,0 +1,52 @@
|
||||
class InputMethodApiData {
|
||||
InputMethodApiData({
|
||||
this.enable,
|
||||
this.languages,
|
||||
});
|
||||
|
||||
InputMethodApiData.fromJson(dynamic json) {
|
||||
enable = json['enable'];
|
||||
if (json['languages'] != null) {
|
||||
languages = <String, InputMethodApiLanguageData>{};
|
||||
json['languages'].forEach((String key, dynamic v) {
|
||||
languages![key] = InputMethodApiLanguageData.fromJson(v);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool? enable;
|
||||
Map<String, InputMethodApiLanguageData>? languages;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['enable'] = enable;
|
||||
if (languages != null) {
|
||||
map['languages'] = languages!.map<String, dynamic>((key, value) {
|
||||
return MapEntry(key, value.toJson());
|
||||
});
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
class InputMethodApiLanguageData {
|
||||
InputMethodApiLanguageData({
|
||||
this.file,
|
||||
this.version,
|
||||
});
|
||||
|
||||
InputMethodApiLanguageData.fromJson(dynamic json) {
|
||||
file = json['file'];
|
||||
version = json['version'];
|
||||
}
|
||||
|
||||
String? file;
|
||||
String? version;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final map = <String, dynamic>{};
|
||||
map['file'] = file;
|
||||
map['version'] = version;
|
||||
return map;
|
||||
}
|
||||
}
|
246
lib/data/nav_api_data.dart
Normal file
246
lib/data/nav_api_data.dart
Normal file
@ -0,0 +1,246 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'nav_api_data.freezed.dart';
|
||||
|
||||
part 'nav_api_data.g.dart';
|
||||
|
||||
@freezed
|
||||
class NavApiDocsItemData with _$NavApiDocsItemData {
|
||||
const factory NavApiDocsItemData({
|
||||
@Default('') @JsonKey(name: 'id') String id,
|
||||
@Default('') @JsonKey(name: 'name') String name,
|
||||
@Default('') @JsonKey(name: 'slug') String slug,
|
||||
@Default('') @JsonKey(name: 'abstract') String abstract_,
|
||||
@Default('') @JsonKey(name: 'description') String description,
|
||||
@Default(NavApiDocsItemImageData())
|
||||
@JsonKey(name: 'image')
|
||||
NavApiDocsItemImageData image,
|
||||
@Default('') @JsonKey(name: 'link') String link,
|
||||
@Default(false) @JsonKey(name: 'is_sponsored') bool isSponsored,
|
||||
@Default(<NavApiDocsItemTagsItemData>[])
|
||||
@JsonKey(name: 'tags')
|
||||
List<NavApiDocsItemTagsItemData> tags,
|
||||
@Default('') @JsonKey(name: 'updatedAt') String updatedAt,
|
||||
@Default('') @JsonKey(name: 'createdAt') String createdAt,
|
||||
}) = _NavApiDocsItemData;
|
||||
|
||||
const NavApiDocsItemData._();
|
||||
|
||||
factory NavApiDocsItemData.fromJson(Map<String, Object?> json) =>
|
||||
_$NavApiDocsItemDataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class NavApiDocsItemImageData with _$NavApiDocsItemImageData {
|
||||
const factory NavApiDocsItemImageData({
|
||||
@Default('') @JsonKey(name: 'id') String id,
|
||||
@Default(NavApiDocsItemImageCreatedByData())
|
||||
@JsonKey(name: 'createdBy')
|
||||
NavApiDocsItemImageCreatedByData createdBy,
|
||||
@Default('') @JsonKey(name: 'title') String title,
|
||||
@Default(false) @JsonKey(name: 'original') bool original,
|
||||
@Default('') @JsonKey(name: 'credit') String credit,
|
||||
@Default('') @JsonKey(name: 'source') String source,
|
||||
@Default('') @JsonKey(name: 'license') String license,
|
||||
@JsonKey(name: 'caption') dynamic caption,
|
||||
@Default('') @JsonKey(name: 'updatedAt') String updatedAt,
|
||||
@Default('') @JsonKey(name: 'createdAt') String createdAt,
|
||||
@Default('') @JsonKey(name: 'url') String url,
|
||||
@Default('') @JsonKey(name: 'filename') String filename,
|
||||
@Default('') @JsonKey(name: 'mimeType') String mimeType,
|
||||
@Default(0) @JsonKey(name: 'filesize') int filesize,
|
||||
@Default(0) @JsonKey(name: 'width') int width,
|
||||
@Default(0) @JsonKey(name: 'height') int height,
|
||||
@Default(NavApiDocsItemImageSizesData())
|
||||
@JsonKey(name: 'sizes')
|
||||
NavApiDocsItemImageSizesData sizes,
|
||||
}) = _NavApiDocsItemImageData;
|
||||
|
||||
const NavApiDocsItemImageData._();
|
||||
|
||||
factory NavApiDocsItemImageData.fromJson(Map<String, Object?> json) =>
|
||||
_$NavApiDocsItemImageDataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class NavApiDocsItemImageCreatedByData with _$NavApiDocsItemImageCreatedByData {
|
||||
const factory NavApiDocsItemImageCreatedByData({
|
||||
@Default('') @JsonKey(name: 'id') String id,
|
||||
@Default('') @JsonKey(name: 'sub') String sub,
|
||||
@Default('') @JsonKey(name: 'external_provider') String externalProvider,
|
||||
@Default('') @JsonKey(name: 'username') String username,
|
||||
@Default('') @JsonKey(name: 'name') String name,
|
||||
@Default(<String>[]) @JsonKey(name: 'roles') List<String> roles,
|
||||
@Default('') @JsonKey(name: 'avatar_url') String avatarUrl,
|
||||
@Default('') @JsonKey(name: 'updatedAt') String updatedAt,
|
||||
@Default('') @JsonKey(name: 'createdAt') String createdAt,
|
||||
@Default('') @JsonKey(name: 'email') String email,
|
||||
@Default(0) @JsonKey(name: 'loginAttempts') int loginAttempts,
|
||||
@Default('') @JsonKey(name: 'avatar') String avatar,
|
||||
}) = _NavApiDocsItemImageCreatedByData;
|
||||
|
||||
const NavApiDocsItemImageCreatedByData._();
|
||||
|
||||
factory NavApiDocsItemImageCreatedByData.fromJson(
|
||||
Map<String, Object?> json) =>
|
||||
_$NavApiDocsItemImageCreatedByDataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class NavApiDocsItemImageSizesThumbnailData
|
||||
with _$NavApiDocsItemImageSizesThumbnailData {
|
||||
const factory NavApiDocsItemImageSizesThumbnailData({
|
||||
@Default('') @JsonKey(name: 'url') String url,
|
||||
@Default(0) @JsonKey(name: 'width') int width,
|
||||
@Default(0) @JsonKey(name: 'height') int height,
|
||||
@Default('') @JsonKey(name: 'mimeType') String mimeType,
|
||||
@Default(0) @JsonKey(name: 'filesize') int filesize,
|
||||
@Default('') @JsonKey(name: 'filename') String filename,
|
||||
}) = _NavApiDocsItemImageSizesThumbnailData;
|
||||
|
||||
const NavApiDocsItemImageSizesThumbnailData._();
|
||||
|
||||
factory NavApiDocsItemImageSizesThumbnailData.fromJson(
|
||||
Map<String, Object?> json) =>
|
||||
_$NavApiDocsItemImageSizesThumbnailDataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class NavApiDocsItemImageSizesData with _$NavApiDocsItemImageSizesData {
|
||||
const factory NavApiDocsItemImageSizesData({
|
||||
@Default(NavApiDocsItemImageSizesThumbnailData())
|
||||
@JsonKey(name: 'thumbnail')
|
||||
NavApiDocsItemImageSizesThumbnailData thumbnail,
|
||||
@Default(NavApiDocsItemImageSizesPreloadData())
|
||||
@JsonKey(name: 'preload')
|
||||
NavApiDocsItemImageSizesPreloadData preload,
|
||||
@Default(NavApiDocsItemImageSizesCardData())
|
||||
@JsonKey(name: 'card')
|
||||
NavApiDocsItemImageSizesCardData card,
|
||||
@Default(NavApiDocsItemImageSizesTabletData())
|
||||
@JsonKey(name: 'tablet')
|
||||
NavApiDocsItemImageSizesTabletData tablet,
|
||||
@Default(NavApiDocsItemImageSizesAvatarData())
|
||||
@JsonKey(name: 'avatar')
|
||||
NavApiDocsItemImageSizesAvatarData avatar,
|
||||
}) = _NavApiDocsItemImageSizesData;
|
||||
|
||||
const NavApiDocsItemImageSizesData._();
|
||||
|
||||
factory NavApiDocsItemImageSizesData.fromJson(Map<String, Object?> json) =>
|
||||
_$NavApiDocsItemImageSizesDataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class NavApiDocsItemImageSizesPreloadData
|
||||
with _$NavApiDocsItemImageSizesPreloadData {
|
||||
const factory NavApiDocsItemImageSizesPreloadData({
|
||||
@JsonKey(name: 'url') dynamic url,
|
||||
@JsonKey(name: 'width') dynamic width,
|
||||
@JsonKey(name: 'height') dynamic height,
|
||||
@JsonKey(name: 'mimeType') dynamic mimeType,
|
||||
@JsonKey(name: 'filesize') dynamic filesize,
|
||||
@JsonKey(name: 'filename') dynamic filename,
|
||||
}) = _NavApiDocsItemImageSizesPreloadData;
|
||||
|
||||
const NavApiDocsItemImageSizesPreloadData._();
|
||||
|
||||
factory NavApiDocsItemImageSizesPreloadData.fromJson(
|
||||
Map<String, Object?> json) =>
|
||||
_$NavApiDocsItemImageSizesPreloadDataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class NavApiDocsItemImageSizesCardData with _$NavApiDocsItemImageSizesCardData {
|
||||
const factory NavApiDocsItemImageSizesCardData({
|
||||
@Default('') @JsonKey(name: 'url') String url,
|
||||
@Default(0) @JsonKey(name: 'width') int width,
|
||||
@Default(0) @JsonKey(name: 'height') int height,
|
||||
@Default('') @JsonKey(name: 'mimeType') String mimeType,
|
||||
@Default(0) @JsonKey(name: 'filesize') int filesize,
|
||||
@Default('') @JsonKey(name: 'filename') String filename,
|
||||
}) = _NavApiDocsItemImageSizesCardData;
|
||||
|
||||
const NavApiDocsItemImageSizesCardData._();
|
||||
|
||||
factory NavApiDocsItemImageSizesCardData.fromJson(
|
||||
Map<String, Object?> json) =>
|
||||
_$NavApiDocsItemImageSizesCardDataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class NavApiDocsItemImageSizesTabletData
|
||||
with _$NavApiDocsItemImageSizesTabletData {
|
||||
const factory NavApiDocsItemImageSizesTabletData({
|
||||
@Default('') @JsonKey(name: 'url') String url,
|
||||
@Default(0) @JsonKey(name: 'width') int width,
|
||||
@Default(0) @JsonKey(name: 'height') int height,
|
||||
@Default('') @JsonKey(name: 'mimeType') String mimeType,
|
||||
@Default(0) @JsonKey(name: 'filesize') int filesize,
|
||||
@Default('') @JsonKey(name: 'filename') String filename,
|
||||
}) = _NavApiDocsItemImageSizesTabletData;
|
||||
|
||||
const NavApiDocsItemImageSizesTabletData._();
|
||||
|
||||
factory NavApiDocsItemImageSizesTabletData.fromJson(
|
||||
Map<String, Object?> json) =>
|
||||
_$NavApiDocsItemImageSizesTabletDataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class NavApiDocsItemImageSizesAvatarData
|
||||
with _$NavApiDocsItemImageSizesAvatarData {
|
||||
const factory NavApiDocsItemImageSizesAvatarData({
|
||||
@Default('') @JsonKey(name: 'url') String url,
|
||||
@Default(0) @JsonKey(name: 'width') int width,
|
||||
@Default(0) @JsonKey(name: 'height') int height,
|
||||
@Default('') @JsonKey(name: 'mimeType') String mimeType,
|
||||
@Default(0) @JsonKey(name: 'filesize') int filesize,
|
||||
@Default('') @JsonKey(name: 'filename') String filename,
|
||||
}) = _NavApiDocsItemImageSizesAvatarData;
|
||||
|
||||
const NavApiDocsItemImageSizesAvatarData._();
|
||||
|
||||
factory NavApiDocsItemImageSizesAvatarData.fromJson(
|
||||
Map<String, Object?> json) =>
|
||||
_$NavApiDocsItemImageSizesAvatarDataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class NavApiDocsItemTagsItemData with _$NavApiDocsItemTagsItemData {
|
||||
const factory NavApiDocsItemTagsItemData({
|
||||
@Default('') @JsonKey(name: 'id') String id,
|
||||
@Default('') @JsonKey(name: 'name') String name,
|
||||
@Default('') @JsonKey(name: 'slug') String slug,
|
||||
@Default('') @JsonKey(name: 'updatedAt') String updatedAt,
|
||||
@Default('') @JsonKey(name: 'createdAt') String createdAt,
|
||||
}) = _NavApiDocsItemTagsItemData;
|
||||
|
||||
const NavApiDocsItemTagsItemData._();
|
||||
|
||||
factory NavApiDocsItemTagsItemData.fromJson(Map<String, Object?> json) =>
|
||||
_$NavApiDocsItemTagsItemDataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class NavApiData with _$NavApiData {
|
||||
const factory NavApiData({
|
||||
@Default(<NavApiDocsItemData>[])
|
||||
@JsonKey(name: 'docs')
|
||||
List<NavApiDocsItemData> docs,
|
||||
@Default(false) @JsonKey(name: 'hasNextPage') bool hasNextPage,
|
||||
@Default(false) @JsonKey(name: 'hasPrevPage') bool hasPrevPage,
|
||||
@Default(0) @JsonKey(name: 'limit') int limit,
|
||||
@JsonKey(name: 'nextPage') dynamic nextPage,
|
||||
@Default(0) @JsonKey(name: 'page') int page,
|
||||
@Default(0) @JsonKey(name: 'pagingCounter') int pagingCounter,
|
||||
@JsonKey(name: 'prevPage') dynamic prevPage,
|
||||
@Default(0) @JsonKey(name: 'totalDocs') int totalDocs,
|
||||
@Default(0) @JsonKey(name: 'totalPages') int totalPages,
|
||||
}) = _NavApiData;
|
||||
|
||||
const NavApiData._();
|
||||
|
||||
factory NavApiData.fromJson(Map<String, Object?> json) =>
|
||||
_$NavApiDataFromJson(json);
|
||||
}
|
3959
lib/data/nav_api_data.freezed.dart
Normal file
3959
lib/data/nav_api_data.freezed.dart
Normal file
File diff suppressed because it is too large
Load Diff
336
lib/data/nav_api_data.g.dart
Normal file
336
lib/data/nav_api_data.g.dart
Normal file
@ -0,0 +1,336 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'nav_api_data.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$NavApiDocsItemDataImpl _$$NavApiDocsItemDataImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$NavApiDocsItemDataImpl(
|
||||
id: json['id'] as String? ?? '',
|
||||
name: json['name'] as String? ?? '',
|
||||
slug: json['slug'] as String? ?? '',
|
||||
abstract_: json['abstract'] as String? ?? '',
|
||||
description: json['description'] as String? ?? '',
|
||||
image: json['image'] == null
|
||||
? const NavApiDocsItemImageData()
|
||||
: NavApiDocsItemImageData.fromJson(
|
||||
json['image'] as Map<String, dynamic>),
|
||||
link: json['link'] as String? ?? '',
|
||||
isSponsored: json['is_sponsored'] as bool? ?? false,
|
||||
tags: (json['tags'] as List<dynamic>?)
|
||||
?.map((e) => NavApiDocsItemTagsItemData.fromJson(
|
||||
e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
const <NavApiDocsItemTagsItemData>[],
|
||||
updatedAt: json['updatedAt'] as String? ?? '',
|
||||
createdAt: json['createdAt'] as String? ?? '',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NavApiDocsItemDataImplToJson(
|
||||
_$NavApiDocsItemDataImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'slug': instance.slug,
|
||||
'abstract': instance.abstract_,
|
||||
'description': instance.description,
|
||||
'image': instance.image,
|
||||
'link': instance.link,
|
||||
'is_sponsored': instance.isSponsored,
|
||||
'tags': instance.tags,
|
||||
'updatedAt': instance.updatedAt,
|
||||
'createdAt': instance.createdAt,
|
||||
};
|
||||
|
||||
_$NavApiDocsItemImageDataImpl _$$NavApiDocsItemImageDataImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$NavApiDocsItemImageDataImpl(
|
||||
id: json['id'] as String? ?? '',
|
||||
createdBy: json['createdBy'] == null
|
||||
? const NavApiDocsItemImageCreatedByData()
|
||||
: NavApiDocsItemImageCreatedByData.fromJson(
|
||||
json['createdBy'] as Map<String, dynamic>),
|
||||
title: json['title'] as String? ?? '',
|
||||
original: json['original'] as bool? ?? false,
|
||||
credit: json['credit'] as String? ?? '',
|
||||
source: json['source'] as String? ?? '',
|
||||
license: json['license'] as String? ?? '',
|
||||
caption: json['caption'],
|
||||
updatedAt: json['updatedAt'] as String? ?? '',
|
||||
createdAt: json['createdAt'] as String? ?? '',
|
||||
url: json['url'] as String? ?? '',
|
||||
filename: json['filename'] as String? ?? '',
|
||||
mimeType: json['mimeType'] as String? ?? '',
|
||||
filesize: (json['filesize'] as num?)?.toInt() ?? 0,
|
||||
width: (json['width'] as num?)?.toInt() ?? 0,
|
||||
height: (json['height'] as num?)?.toInt() ?? 0,
|
||||
sizes: json['sizes'] == null
|
||||
? const NavApiDocsItemImageSizesData()
|
||||
: NavApiDocsItemImageSizesData.fromJson(
|
||||
json['sizes'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NavApiDocsItemImageDataImplToJson(
|
||||
_$NavApiDocsItemImageDataImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'createdBy': instance.createdBy,
|
||||
'title': instance.title,
|
||||
'original': instance.original,
|
||||
'credit': instance.credit,
|
||||
'source': instance.source,
|
||||
'license': instance.license,
|
||||
'caption': instance.caption,
|
||||
'updatedAt': instance.updatedAt,
|
||||
'createdAt': instance.createdAt,
|
||||
'url': instance.url,
|
||||
'filename': instance.filename,
|
||||
'mimeType': instance.mimeType,
|
||||
'filesize': instance.filesize,
|
||||
'width': instance.width,
|
||||
'height': instance.height,
|
||||
'sizes': instance.sizes,
|
||||
};
|
||||
|
||||
_$NavApiDocsItemImageCreatedByDataImpl
|
||||
_$$NavApiDocsItemImageCreatedByDataImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$NavApiDocsItemImageCreatedByDataImpl(
|
||||
id: json['id'] as String? ?? '',
|
||||
sub: json['sub'] as String? ?? '',
|
||||
externalProvider: json['external_provider'] as String? ?? '',
|
||||
username: json['username'] as String? ?? '',
|
||||
name: json['name'] as String? ?? '',
|
||||
roles: (json['roles'] as List<dynamic>?)
|
||||
?.map((e) => e as String)
|
||||
.toList() ??
|
||||
const <String>[],
|
||||
avatarUrl: json['avatar_url'] as String? ?? '',
|
||||
updatedAt: json['updatedAt'] as String? ?? '',
|
||||
createdAt: json['createdAt'] as String? ?? '',
|
||||
email: json['email'] as String? ?? '',
|
||||
loginAttempts: (json['loginAttempts'] as num?)?.toInt() ?? 0,
|
||||
avatar: json['avatar'] as String? ?? '',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NavApiDocsItemImageCreatedByDataImplToJson(
|
||||
_$NavApiDocsItemImageCreatedByDataImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'sub': instance.sub,
|
||||
'external_provider': instance.externalProvider,
|
||||
'username': instance.username,
|
||||
'name': instance.name,
|
||||
'roles': instance.roles,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'updatedAt': instance.updatedAt,
|
||||
'createdAt': instance.createdAt,
|
||||
'email': instance.email,
|
||||
'loginAttempts': instance.loginAttempts,
|
||||
'avatar': instance.avatar,
|
||||
};
|
||||
|
||||
_$NavApiDocsItemImageSizesThumbnailDataImpl
|
||||
_$$NavApiDocsItemImageSizesThumbnailDataImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$NavApiDocsItemImageSizesThumbnailDataImpl(
|
||||
url: json['url'] as String? ?? '',
|
||||
width: (json['width'] as num?)?.toInt() ?? 0,
|
||||
height: (json['height'] as num?)?.toInt() ?? 0,
|
||||
mimeType: json['mimeType'] as String? ?? '',
|
||||
filesize: (json['filesize'] as num?)?.toInt() ?? 0,
|
||||
filename: json['filename'] as String? ?? '',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NavApiDocsItemImageSizesThumbnailDataImplToJson(
|
||||
_$NavApiDocsItemImageSizesThumbnailDataImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'url': instance.url,
|
||||
'width': instance.width,
|
||||
'height': instance.height,
|
||||
'mimeType': instance.mimeType,
|
||||
'filesize': instance.filesize,
|
||||
'filename': instance.filename,
|
||||
};
|
||||
|
||||
_$NavApiDocsItemImageSizesDataImpl _$$NavApiDocsItemImageSizesDataImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$NavApiDocsItemImageSizesDataImpl(
|
||||
thumbnail: json['thumbnail'] == null
|
||||
? const NavApiDocsItemImageSizesThumbnailData()
|
||||
: NavApiDocsItemImageSizesThumbnailData.fromJson(
|
||||
json['thumbnail'] as Map<String, dynamic>),
|
||||
preload: json['preload'] == null
|
||||
? const NavApiDocsItemImageSizesPreloadData()
|
||||
: NavApiDocsItemImageSizesPreloadData.fromJson(
|
||||
json['preload'] as Map<String, dynamic>),
|
||||
card: json['card'] == null
|
||||
? const NavApiDocsItemImageSizesCardData()
|
||||
: NavApiDocsItemImageSizesCardData.fromJson(
|
||||
json['card'] as Map<String, dynamic>),
|
||||
tablet: json['tablet'] == null
|
||||
? const NavApiDocsItemImageSizesTabletData()
|
||||
: NavApiDocsItemImageSizesTabletData.fromJson(
|
||||
json['tablet'] as Map<String, dynamic>),
|
||||
avatar: json['avatar'] == null
|
||||
? const NavApiDocsItemImageSizesAvatarData()
|
||||
: NavApiDocsItemImageSizesAvatarData.fromJson(
|
||||
json['avatar'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NavApiDocsItemImageSizesDataImplToJson(
|
||||
_$NavApiDocsItemImageSizesDataImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'thumbnail': instance.thumbnail,
|
||||
'preload': instance.preload,
|
||||
'card': instance.card,
|
||||
'tablet': instance.tablet,
|
||||
'avatar': instance.avatar,
|
||||
};
|
||||
|
||||
_$NavApiDocsItemImageSizesPreloadDataImpl
|
||||
_$$NavApiDocsItemImageSizesPreloadDataImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$NavApiDocsItemImageSizesPreloadDataImpl(
|
||||
url: json['url'],
|
||||
width: json['width'],
|
||||
height: json['height'],
|
||||
mimeType: json['mimeType'],
|
||||
filesize: json['filesize'],
|
||||
filename: json['filename'],
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NavApiDocsItemImageSizesPreloadDataImplToJson(
|
||||
_$NavApiDocsItemImageSizesPreloadDataImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'url': instance.url,
|
||||
'width': instance.width,
|
||||
'height': instance.height,
|
||||
'mimeType': instance.mimeType,
|
||||
'filesize': instance.filesize,
|
||||
'filename': instance.filename,
|
||||
};
|
||||
|
||||
_$NavApiDocsItemImageSizesCardDataImpl
|
||||
_$$NavApiDocsItemImageSizesCardDataImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$NavApiDocsItemImageSizesCardDataImpl(
|
||||
url: json['url'] as String? ?? '',
|
||||
width: (json['width'] as num?)?.toInt() ?? 0,
|
||||
height: (json['height'] as num?)?.toInt() ?? 0,
|
||||
mimeType: json['mimeType'] as String? ?? '',
|
||||
filesize: (json['filesize'] as num?)?.toInt() ?? 0,
|
||||
filename: json['filename'] as String? ?? '',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NavApiDocsItemImageSizesCardDataImplToJson(
|
||||
_$NavApiDocsItemImageSizesCardDataImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'url': instance.url,
|
||||
'width': instance.width,
|
||||
'height': instance.height,
|
||||
'mimeType': instance.mimeType,
|
||||
'filesize': instance.filesize,
|
||||
'filename': instance.filename,
|
||||
};
|
||||
|
||||
_$NavApiDocsItemImageSizesTabletDataImpl
|
||||
_$$NavApiDocsItemImageSizesTabletDataImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$NavApiDocsItemImageSizesTabletDataImpl(
|
||||
url: json['url'] as String? ?? '',
|
||||
width: (json['width'] as num?)?.toInt() ?? 0,
|
||||
height: (json['height'] as num?)?.toInt() ?? 0,
|
||||
mimeType: json['mimeType'] as String? ?? '',
|
||||
filesize: (json['filesize'] as num?)?.toInt() ?? 0,
|
||||
filename: json['filename'] as String? ?? '',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NavApiDocsItemImageSizesTabletDataImplToJson(
|
||||
_$NavApiDocsItemImageSizesTabletDataImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'url': instance.url,
|
||||
'width': instance.width,
|
||||
'height': instance.height,
|
||||
'mimeType': instance.mimeType,
|
||||
'filesize': instance.filesize,
|
||||
'filename': instance.filename,
|
||||
};
|
||||
|
||||
_$NavApiDocsItemImageSizesAvatarDataImpl
|
||||
_$$NavApiDocsItemImageSizesAvatarDataImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$NavApiDocsItemImageSizesAvatarDataImpl(
|
||||
url: json['url'] as String? ?? '',
|
||||
width: (json['width'] as num?)?.toInt() ?? 0,
|
||||
height: (json['height'] as num?)?.toInt() ?? 0,
|
||||
mimeType: json['mimeType'] as String? ?? '',
|
||||
filesize: (json['filesize'] as num?)?.toInt() ?? 0,
|
||||
filename: json['filename'] as String? ?? '',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NavApiDocsItemImageSizesAvatarDataImplToJson(
|
||||
_$NavApiDocsItemImageSizesAvatarDataImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'url': instance.url,
|
||||
'width': instance.width,
|
||||
'height': instance.height,
|
||||
'mimeType': instance.mimeType,
|
||||
'filesize': instance.filesize,
|
||||
'filename': instance.filename,
|
||||
};
|
||||
|
||||
_$NavApiDocsItemTagsItemDataImpl _$$NavApiDocsItemTagsItemDataImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$NavApiDocsItemTagsItemDataImpl(
|
||||
id: json['id'] as String? ?? '',
|
||||
name: json['name'] as String? ?? '',
|
||||
slug: json['slug'] as String? ?? '',
|
||||
updatedAt: json['updatedAt'] as String? ?? '',
|
||||
createdAt: json['createdAt'] as String? ?? '',
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NavApiDocsItemTagsItemDataImplToJson(
|
||||
_$NavApiDocsItemTagsItemDataImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'slug': instance.slug,
|
||||
'updatedAt': instance.updatedAt,
|
||||
'createdAt': instance.createdAt,
|
||||
};
|
||||
|
||||
_$NavApiDataImpl _$$NavApiDataImplFromJson(Map<String, dynamic> json) =>
|
||||
_$NavApiDataImpl(
|
||||
docs: (json['docs'] as List<dynamic>?)
|
||||
?.map(
|
||||
(e) => NavApiDocsItemData.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
const <NavApiDocsItemData>[],
|
||||
hasNextPage: json['hasNextPage'] as bool? ?? false,
|
||||
hasPrevPage: json['hasPrevPage'] as bool? ?? false,
|
||||
limit: (json['limit'] as num?)?.toInt() ?? 0,
|
||||
nextPage: json['nextPage'],
|
||||
page: (json['page'] as num?)?.toInt() ?? 0,
|
||||
pagingCounter: (json['pagingCounter'] as num?)?.toInt() ?? 0,
|
||||
prevPage: json['prevPage'],
|
||||
totalDocs: (json['totalDocs'] as num?)?.toInt() ?? 0,
|
||||
totalPages: (json['totalPages'] as num?)?.toInt() ?? 0,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$NavApiDataImplToJson(_$NavApiDataImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'docs': instance.docs,
|
||||
'hasNextPage': instance.hasNextPage,
|
||||
'hasPrevPage': instance.hasPrevPage,
|
||||
'limit': instance.limit,
|
||||
'nextPage': instance.nextPage,
|
||||
'page': instance.page,
|
||||
'pagingCounter': instance.pagingCounter,
|
||||
'prevPage': instance.prevPage,
|
||||
'totalDocs': instance.totalDocs,
|
||||
'totalPages': instance.totalPages,
|
||||
};
|
@ -18,6 +18,7 @@ import 'package:intl/src/intl_helpers.dart';
|
||||
|
||||
import 'messages_en.dart' as messages_en;
|
||||
import 'messages_ja.dart' as messages_ja;
|
||||
import 'messages_ru.dart' as messages_ru;
|
||||
import 'messages_zh_CN.dart' as messages_zh_cn;
|
||||
import 'messages_zh_TW.dart' as messages_zh_tw;
|
||||
|
||||
@ -25,6 +26,7 @@ typedef Future<dynamic> LibraryLoader();
|
||||
Map<String, LibraryLoader> _deferredLibraries = {
|
||||
'en': () => new SynchronousFuture(null),
|
||||
'ja': () => new SynchronousFuture(null),
|
||||
'ru': () => new SynchronousFuture(null),
|
||||
'zh_CN': () => new SynchronousFuture(null),
|
||||
'zh_TW': () => new SynchronousFuture(null),
|
||||
};
|
||||
@ -35,6 +37,8 @@ MessageLookupByLibrary? _findExact(String localeName) {
|
||||
return messages_en.messages;
|
||||
case 'ja':
|
||||
return messages_ja.messages;
|
||||
case 'ru':
|
||||
return messages_ru.messages;
|
||||
case 'zh_CN':
|
||||
return messages_zh_cn.messages;
|
||||
case 'zh_TW':
|
||||
@ -47,8 +51,10 @@ MessageLookupByLibrary? _findExact(String localeName) {
|
||||
/// User programs should call this before using [localeName] for messages.
|
||||
Future<bool> initializeMessages(String localeName) {
|
||||
var availableLocale = Intl.verifiedLocale(
|
||||
localeName, (locale) => _deferredLibraries[locale] != null,
|
||||
onFailure: (_) => null);
|
||||
localeName,
|
||||
(locale) => _deferredLibraries[locale] != null,
|
||||
onFailure: (_) => null,
|
||||
);
|
||||
if (availableLocale == null) {
|
||||
return new SynchronousFuture(false);
|
||||
}
|
||||
@ -68,8 +74,11 @@ bool _messagesExistFor(String locale) {
|
||||
}
|
||||
|
||||
MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) {
|
||||
var actualLocale =
|
||||
Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null);
|
||||
var actualLocale = Intl.verifiedLocale(
|
||||
locale,
|
||||
_messagesExistFor,
|
||||
onFailure: (_) => null,
|
||||
);
|
||||
if (actualLocale == null) return null;
|
||||
return _findExact(actualLocale);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1727
lib/generated/intl/messages_ru.dart
Normal file
1727
lib/generated/intl/messages_ru.dart
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -4,4 +4,6 @@ class NoL10n {
|
||||
static const String langEn = 'English';
|
||||
static const String langJa = '日本語';
|
||||
static const String langFR = 'Français';
|
||||
static const String langRU = 'Русский';
|
||||
static const String langCodeZhCn = 'zh_CN';
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,90 +1,100 @@
|
||||
{
|
||||
"@@locale": "ja",
|
||||
"@@auto_translate_locale": "ja",
|
||||
"app_language_name": "日本語",
|
||||
"@app_language_name": {},
|
||||
"app_language_code": "ja",
|
||||
"@app_language_code": {},
|
||||
"app_index_version_info": "SCToolBox V {v0} {v1}",
|
||||
"app_index_version_info": "SCToolbox V{v0} {v1}",
|
||||
"@app_index_version_info": {},
|
||||
"about_check_update": "更新チェック",
|
||||
"app_shortcut_name": "SCToolboxDEV.lnk",
|
||||
"@app_shortcut_name": {},
|
||||
"about_check_update": "アップデートを確認",
|
||||
"@about_check_update": {},
|
||||
"about_online_feedback": "フィードバック",
|
||||
"about_app_description": "ローカライズだけではありません!\n\nSCToolboxは宇宙探検の強力なサポートツールです。私たちはゲーム内の一般的な問題を解決し、コミュニティローカライズ、パフォーマンス最適化、一般的なウェブサイトのローカライズなどの操作を容易にするためにプレイヤーを支援することに専念しています。",
|
||||
"@about_app_description": {},
|
||||
"about_online_feedback": "オンラインフィードバック",
|
||||
"@about_online_feedback": {},
|
||||
"about_action_qq_group": "QQグループ: 940696487",
|
||||
"@about_action_qq_group": {},
|
||||
"about_action_email": "メール: xkeyc@qq.com",
|
||||
"@about_action_email": {},
|
||||
"about_action_open_source": "オープンソース",
|
||||
"@about_action_open_source": {},
|
||||
"about_disclaimer": "これは Star Citizen の非公式ツールです、Cloud Imperium Games LLC の所有ではない。 本ソフトウェアのホストまたは使用者によって作成されていないすべての情報は、それぞれの所有者に帰属します。 \nStar Citizen®、Roberts Space Industries®、Cloud Imperium® は Cloud Imperium Rights LLC のトレードマーク。",
|
||||
"about_disclaimer": "これはStar Citizenの非公式ツールであり、Cloud Imperium企業グループに所属していません。ホストまたはユーザーによって作成されていないすべてのコンテンツは、それぞれの所有者の財産です。\nStar Citizen®、Roberts Space Industries®およびCloud Imperium®はCloud Imperium Rights LLCの登録商標です。",
|
||||
"@about_disclaimer": {},
|
||||
"about_analytics_launch": "起動",
|
||||
"@about_analytics_launch": {},
|
||||
"about_analytics_launch_game": "ゲームを起動",
|
||||
"@about_analytics_launch_game": {},
|
||||
"about_analytics_install_translation": "日本語化インストール",
|
||||
"@about_analytics_install_translation": {},
|
||||
"about_analytics_p4k_redirection": "P4Kダウンロード",
|
||||
"@about_analytics_p4k_redirection": {},
|
||||
"about_analytics_total_users": "利用者数",
|
||||
"about_analytics_total_users": "累計ユーザー",
|
||||
"@about_analytics_total_users": {},
|
||||
"about_analytics_units_user": "人",
|
||||
"about_analytics_install_translation": "ローカリゼーション インストール",
|
||||
"@about_analytics_install_translation": {},
|
||||
"about_analytics_performance_optimization": "パフォーマンス最適化",
|
||||
"@about_analytics_performance_optimization": {},
|
||||
"about_analytics_p4k_redirection": "P4K迂回",
|
||||
"@about_analytics_p4k_redirection": {},
|
||||
"about_analytics_units_user": "名",
|
||||
"@about_analytics_units_user": {},
|
||||
"about_analytics_units_times": "回",
|
||||
"@about_analytics_units_times": {},
|
||||
"about_info_latest_version": "すでに最新バージョンだ!",
|
||||
"about_info_latest_version": "最新バージョンです!",
|
||||
"@about_info_latest_version": {},
|
||||
"home_holiday_countdown": "祝日カウントダウン",
|
||||
"@home_holiday_countdown": {},
|
||||
"home_holiday_countdown_disclaimer": "* 上記の祝日は手作業で収集・管理されているため、誤りがある可能性があります、フィードバックは歓迎する!!",
|
||||
"home_holiday_countdown_disclaimer": "* 上記の祝日日付は手動で収集・管理されており、誤りがある可能性があります。フィードバックを歓迎します!",
|
||||
"@home_holiday_countdown_disclaimer": {},
|
||||
"home_action_one_click_launch": "ワンクリック起動",
|
||||
"@home_action_one_click_launch": {},
|
||||
"home_title_logging_in": "ログイン中...",
|
||||
"@home_title_logging_in": {},
|
||||
"home_login_title_welcome_back": "お帰りなさい!",
|
||||
"home_login_title_welcome_back": "おかえりなさい!",
|
||||
"@home_login_title_welcome_back": {},
|
||||
"home_login_title_launching_game": "ゲーム起動中...",
|
||||
"home_login_title_launching_game": "ゲームを起動しています...",
|
||||
"@home_login_title_launching_game": {},
|
||||
"home_action_login_rsi_account": "RSI アカウントログイン",
|
||||
"home_action_login_rsi_account": "RSIアカウントにログイン",
|
||||
"@home_action_login_rsi_account": {},
|
||||
"home_login_info_game_version_outdated": "ゲームバージョンが古すぎる",
|
||||
"home_login_info_game_version_outdated": "ゲームバージョンが古くなっています",
|
||||
"@home_login_info_game_version_outdated": {},
|
||||
"home_login_info_rsi_server_report": "RSI サーバレポートのバージョン:{v1} \n\nローカルのバージョン:{v2} \n\nRSI Launcher を使ってゲームをアップデートしてください!",
|
||||
"home_login_info_rsi_server_report": "RSIサーバーが報告するバージョン:{v1} \n\nローカルバージョン:{v2} \n\nRSI Launcherを使用してゲームを更新することをお勧めします!",
|
||||
"@home_login_info_rsi_server_report": {},
|
||||
"home_login_info_action_ignore": "無視する",
|
||||
"home_login_info_action_ignore": "無視",
|
||||
"@home_login_info_action_ignore": {},
|
||||
"home_login_action_title_box_one_click_launch": "ボックスワンクリック起動",
|
||||
"home_login_action_title_box_one_click_launch": "ツールボックスワンクリック起動",
|
||||
"@home_login_action_title_box_one_click_launch": {},
|
||||
"home_login_action_title_need_webview2_runtime": "WebView2 Runtime のインストールが必要",
|
||||
"home_login_info_one_click_launch_description": "この機能はゲームをより便利に起動するのに役立ちます。\n\nアカウントセキュリティを確保するために、この機能はローカリゼーションブラウザを使用してログイン状態を保持し、パスワード情報を保存しません(自動入力機能を有効にしていない限り)。\n\nこの機能を使用してアカウントにログインする場合は、信頼できるソースからSCToolboxをダウンロードしていることを確認してください。",
|
||||
"@home_login_info_one_click_launch_description": {},
|
||||
"home_login_action_title_need_webview2_runtime": "WebView2 Runtimeのインストールが必要です",
|
||||
"@home_login_action_title_need_webview2_runtime": {},
|
||||
"action_close": "クローズ",
|
||||
"action_close": "閉じる",
|
||||
"@action_close": {},
|
||||
"downloader_speed_limit_settings": "速度制限設定",
|
||||
"@downloader_speed_limit_settings": {},
|
||||
"downloader_action_pause_all": "すべて一時停止",
|
||||
"@downloader_action_pause_all": {},
|
||||
"downloader_action_resume_all": "すべて復元",
|
||||
"downloader_action_resume_all": "すべて再開",
|
||||
"@downloader_action_resume_all": {},
|
||||
"downloader_action_cancel_all": "すべてキャンセル",
|
||||
"@downloader_action_cancel_all": {},
|
||||
"downloader_info_no_download_tasks": "ダウンロードタスクなし",
|
||||
"downloader_info_no_download_tasks": "ダウンロードタスクはありません",
|
||||
"@downloader_info_no_download_tasks": {},
|
||||
"downloader_info_total_size": "サイズ合計:{v1}",
|
||||
"downloader_info_total_size": "合計サイズ:{v1}",
|
||||
"@downloader_info_total_size": {},
|
||||
"downloader_info_uploaded": "アップロード済み:{v0}",
|
||||
"@downloader_info_uploaded": {},
|
||||
"downloader_info_verifying": "検証中...({v2})",
|
||||
"@downloader_info_verifying": {},
|
||||
"downloader_info_downloading": "ダウンロード... ({v0}%)",
|
||||
"downloader_info_downloading": "ダウンロード中... ({v0}%)",
|
||||
"@downloader_info_downloading": {},
|
||||
"downloader_info_status": "ステータス:{v0}",
|
||||
"@downloader_info_status": {},
|
||||
"downloader_info_uploaded": "アップロード済み:{v0}",
|
||||
"@downloader_info_uploaded": {},
|
||||
"downloader_info_downloaded": "ダウンロード済み:{v0}",
|
||||
"@downloader_info_downloaded": {},
|
||||
"downloader_action_options": "オプション",
|
||||
"@downloader_action_options": {},
|
||||
"downloader_action_continue_download": "ダウンロードを続ける",
|
||||
"@downloader_action_continue_download": {},
|
||||
"downloader_action_pause_download": "ダウンロードの一時停止",
|
||||
"downloader_action_pause_download": "ダウンロードを一時停止",
|
||||
"@downloader_action_pause_download": {},
|
||||
"downloader_action_cancel_download": "ダウンロードをキャンセル",
|
||||
"@downloader_action_cancel_download": {},
|
||||
@ -92,10 +102,10 @@
|
||||
"@action_open_folder": {},
|
||||
"downloader_info_download_upload_speed": "ダウンロード: {v0}/s アップロード:{v1}/s",
|
||||
"@downloader_info_download_upload_speed": {},
|
||||
"downloader_info_waiting": "待機中",
|
||||
"@downloader_info_waiting": {},
|
||||
"downloader_info_downloading_status": "ダウンロード中...",
|
||||
"@downloader_info_downloading_status": {},
|
||||
"downloader_info_waiting": "待機中",
|
||||
"@downloader_info_waiting": {},
|
||||
"downloader_info_paused": "一時停止中",
|
||||
"@downloader_info_paused": {},
|
||||
"downloader_info_download_failed": "ダウンロード失敗",
|
||||
@ -106,14 +116,781 @@
|
||||
"@downloader_info_deleted": {},
|
||||
"downloader_title_downloading": "ダウンロード中",
|
||||
"@downloader_title_downloading": {},
|
||||
"downloader_title_ended": "終了",
|
||||
"downloader_title_ended": "終了済み",
|
||||
"@downloader_title_ended": {},
|
||||
"downloader_action_confirm_cancel_all_tasks": "すべてのタスクのキャンセルを確認する?",
|
||||
"downloader_action_confirm_cancel_all_tasks": "すべてのタスクをキャンセルしますか?",
|
||||
"@downloader_action_confirm_cancel_all_tasks": {},
|
||||
"downloader_action_confirm_cancel_download": "ダウンロードのキャンセルを確認しますか?",
|
||||
"downloader_info_manual_file_deletion_note": "ファイルが不要になった場合は、手動で削除する必要があるかもしれません。",
|
||||
"@downloader_info_manual_file_deletion_note": {},
|
||||
"downloader_action_confirm_cancel_download": "ダウンロードをキャンセルしますか?",
|
||||
"@downloader_action_confirm_cancel_download": {},
|
||||
"home_login_info_one_click_launch_description": "この機能は、ゲームをより便利に起動するのに役立ちます。\n\nアカウントのセキュリティを確保するため、この機能はローカライズブラウザを使用してログイン状態を保持し、パスワード情報を保存しません(自動入力オンの場合を除く)。\n\nこの機能を使用してアカウントにログインする際は、SCToolBox が信頼できるソースからダウンロードされていることを確認してください。",
|
||||
"@home_login_info_one_click_launch_description": {},
|
||||
"downloader_info_manual_file_deletion_note": "ダウンロードしたファイルが不要になった場合は、手動で削除する必要があります。",
|
||||
"@downloader_info_manual_file_deletion_note": {}
|
||||
}
|
||||
"downloader_info_p2p_network_note": "SCToolboxはファイルダウンロードを高速化するためにP2Pネットワークを使用しています。通信量に制限がある場合は、アップロード帯域幅を1(byte)に設定できます。",
|
||||
"@downloader_info_p2p_network_note": {},
|
||||
"downloader_info_download_unit_input_prompt": "ダウンロード単位を入力してください。例:1、100k、10m、0または空白で制限なし。",
|
||||
"@downloader_info_download_unit_input_prompt": {},
|
||||
"downloader_input_upload_speed_limit": "アップロード制限:",
|
||||
"@downloader_input_upload_speed_limit": {},
|
||||
"downloader_input_download_speed_limit": "ダウンロード制限:",
|
||||
"@downloader_input_download_speed_limit": {},
|
||||
"downloader_input_info_p2p_upload_note": "* P2Pアップロードはファイルのダウンロード中にのみ行われ、ダウンロードが完了するとP2P接続は閉じられます。シードに参加したい場合は、「アバウト」ページから私たちにご連絡ください。",
|
||||
"@downloader_input_info_p2p_upload_note": {},
|
||||
"doctor_title_one_click_diagnosis": "ワンクリック診断 -> {v0}",
|
||||
"@doctor_title_one_click_diagnosis": {},
|
||||
"doctor_action_rsi_launcher_log": "RSIランチャーログ",
|
||||
"@doctor_action_rsi_launcher_log": {},
|
||||
"doctor_action_game_run_log": "ゲーム実行ログ",
|
||||
"@doctor_action_game_run_log": {},
|
||||
"doctor_info_scan_complete_no_issues": "スキャン完了、問題は見つかりませんでした!",
|
||||
"@doctor_info_scan_complete_no_issues": {},
|
||||
"doctor_info_processing": "処理中...",
|
||||
"@doctor_info_processing": {},
|
||||
"doctor_info_game_rescue_service_note": "深宇宙治療センター(QQグループ番号:536454632)によるゲーム異常救済サービスにアクセスしようとしています。これは主にゲームのインストール失敗や頻繁なクラッシュに対応するものです。ゲームプレイの問題に関しては、グループに参加しないでください。",
|
||||
"@doctor_info_game_rescue_service_note": {},
|
||||
"doctor_info_need_help": "助けが必要ですか?クリックしてグループに参加し、無料のサポートを受けましょう!",
|
||||
"@doctor_info_need_help": {},
|
||||
"doctor_info_tool_check_result_note": "注意:このツールの検出結果は参考用です。以下の操作が理解できない場合は、スクリーンショットを経験豊富なプレイヤーに提供してください!",
|
||||
"@doctor_info_tool_check_result_note": {},
|
||||
"doctor_info_result_unsupported_os": "サポートされていないオペレーティングシステムです。ゲームが実行できない可能性があります",
|
||||
"@doctor_info_result_unsupported_os": {},
|
||||
"doctor_info_result_upgrade_system": "システムをアップグレードしてください ({v0})",
|
||||
"@doctor_info_result_upgrade_system": {},
|
||||
"doctor_info_result_missing_live_folder": "インストールディレクトリにLIVEフォルダがありません。インストールが失敗する可能性があります",
|
||||
"@doctor_info_result_missing_live_folder": {},
|
||||
"doctor_info_result_create_live_folder": "クリックして修復すると、LIVEフォルダが作成されます。完了したらインストールを再試行してください。({v0})",
|
||||
"@doctor_info_result_create_live_folder": {},
|
||||
"doctor_info_result_incompatible_nvme_device": "新しいタイプのNVMEデバイスで、RSIランチャーとの互換性がありません。インストールが失敗する可能性があります",
|
||||
"@doctor_info_result_incompatible_nvme_device": {},
|
||||
"doctor_info_result_add_registry_value": "レジストリにForcedPhysicalSectorSizeInBytes値を追加して古いデバイスをエミュレートします。ハードディスクパーティション({v0})",
|
||||
"@doctor_info_result_add_registry_value": {},
|
||||
"doctor_info_result_missing_easyanticheat_files": "EasyAntiCheatファイルが見つかりません",
|
||||
"@doctor_info_result_missing_easyanticheat_files": {},
|
||||
"doctor_info_result_verify_files_with_rsi_launcher": "LIVEフォルダ内にEasyAntiCheatファイルが見つからないか、ファイルが不完全です。RSIランチャーを使用してファイルを検証してください",
|
||||
"@doctor_info_result_verify_files_with_rsi_launcher": {},
|
||||
"doctor_info_result_easyanticheat_not_installed": "EasyAntiCheatがインストールされていないか、正常に終了していません",
|
||||
"@doctor_info_result_easyanticheat_not_installed": {},
|
||||
"doctor_info_result_install_easyanticheat": "EasyAntiCheatがインストールされていません。クリックして修復するとワンクリックでインストールします。(ゲームが正常に起動して終了するまで、この問題は常に表示されます。他の理由でゲームがクラッシュする場合は、この項目を無視できます)",
|
||||
"@doctor_info_result_install_easyanticheat": {},
|
||||
"doctor_info_result_chinese_username": "中国語ユーザー名!",
|
||||
"@doctor_info_result_chinese_username": {},
|
||||
"doctor_info_result_chinese_username_error": "中国語のユーザー名はゲームの起動/インストールエラーを引き起こす可能性があります!修復ボタンをクリックして変更チュートリアルを表示してください!",
|
||||
"@doctor_info_result_chinese_username_error": {},
|
||||
"doctor_info_result_chinese_install_path": "中国語のインストールパス!",
|
||||
"@doctor_info_result_chinese_install_path": {},
|
||||
"doctor_info_result_chinese_install_path_error": "中国語のインストールパスです!これはゲームの起動/インストールエラーを引き起こす可能性があります!({v0})、RSIランチャーでインストールパスを変更してください。",
|
||||
"@doctor_info_result_chinese_install_path_error": {},
|
||||
"doctor_info_result_low_physical_memory": "物理メモリが不足しています",
|
||||
"@doctor_info_result_low_physical_memory": {},
|
||||
"doctor_info_result_memory_requirement": "このゲームを実行するには、少なくとも16GBの物理メモリ(RAM)が必要です。(現在のサイズ:{v0})",
|
||||
"@doctor_info_result_memory_requirement": {},
|
||||
"doctor_info_result_fix_suggestion": "修正提案: {v0}",
|
||||
"@doctor_info_result_fix_suggestion": {},
|
||||
"doctor_info_result_no_solution": "現在解決策はありません。スクリーンショットを撮ってフィードバックしてください",
|
||||
"@doctor_info_result_no_solution": {},
|
||||
"doctor_info_action_fix": "修復",
|
||||
"@doctor_info_action_fix": {},
|
||||
"doctor_action_view_solution": "解決策を表示",
|
||||
"@doctor_action_view_solution": {},
|
||||
"doctor_tip_title_select_game_directory": "ホームページでゲームインストールディレクトリを選択してください。",
|
||||
"@doctor_tip_title_select_game_directory": {},
|
||||
"doctor_action_result_try_latest_windows": "ハードウェアが条件を満たしている場合は、最新のWindowsシステムをインストールしてみてください。",
|
||||
"@doctor_action_result_try_latest_windows": {},
|
||||
"doctor_action_result_create_folder_success": "フォルダの作成に成功しました。ゲームのダウンロードを続けてみてください!",
|
||||
"@doctor_action_result_create_folder_success": {},
|
||||
"doctor_action_result_create_folder_fail": "フォルダの作成に失敗しました。手動で作成してみてください。\nディレクトリ:{v0} \nエラー:{v1}",
|
||||
"@doctor_action_result_create_folder_fail": {},
|
||||
"doctor_action_result_fix_success": "修復に成功しました。再起動してからゲームのインストールを続けてみてください!レジストリの変更が他のソフトウェアに互換性の問題を引き起こす場合は、ツールのNVMEレジストリクリーナーを使用してください。",
|
||||
"@doctor_action_result_fix_success": {},
|
||||
"doctor_action_result_fix_fail": "修復に失敗しました、{v0}",
|
||||
"@doctor_action_result_fix_fail": {},
|
||||
"doctor_action_result_game_start_success": "修復に成功しました。ゲームを起動してみてください。(問題が解決しない場合は、ツールボックスの「EACを再インストール」を使用してください)",
|
||||
"@doctor_action_result_game_start_success": {},
|
||||
"doctor_action_result_redirect_warning": "リダイレクトします。チュートリアルはインターネットから取得したものですので、注意して操作してください...",
|
||||
"@doctor_action_result_redirect_warning": {},
|
||||
"doctor_action_result_issue_not_supported": "この問題は現在自動処理をサポートしていません。スクリーンショットを撮って助けを求めてください",
|
||||
"@doctor_action_result_issue_not_supported": {},
|
||||
"doctor_action_analyzing": "分析中...",
|
||||
"@doctor_action_analyzing": {},
|
||||
"doctor_action_result_analysis_no_issue": "分析完了、問題は見つかりませんでした",
|
||||
"@doctor_action_result_analysis_no_issue": {},
|
||||
"doctor_action_result_analysis_issues_found": "分析完了、{v0}個の問題が見つかりました",
|
||||
"@doctor_action_result_analysis_issues_found": {},
|
||||
"doctor_action_result_toast_scan_no_issue": "スキャン完了、問題は見つかりませんでした。それでもインストールに失敗する場合は、ツールボックスの管理者モードでRSIランチャーを試してみてください。",
|
||||
"@doctor_action_result_toast_scan_no_issue": {},
|
||||
"doctor_action_tip_checking_game_log": "確認中:Game.log",
|
||||
"@doctor_action_tip_checking_game_log": {},
|
||||
"doctor_action_info_game_abnormal_exit": "ゲームが異常終了しました:{v0}",
|
||||
"@doctor_action_info_game_abnormal_exit": {},
|
||||
"doctor_action_info_game_abnormal_exit_unknown": "ゲームが異常終了しました:不明なエラー",
|
||||
"@doctor_action_info_game_abnormal_exit_unknown": {},
|
||||
"doctor_action_info_info_feedback": "info:{v0}、右下の「グループに参加」をクリックしてフィードバックしてください。",
|
||||
"@doctor_action_info_info_feedback": {},
|
||||
"doctor_action_info_checking_eac": "確認中:EAC",
|
||||
"@doctor_action_info_checking_eac": {},
|
||||
"doctor_action_info_checking_runtime": "確認中:実行環境",
|
||||
"@doctor_action_info_checking_runtime": {},
|
||||
"doctor_action_result_info_unsupported_os": "サポートされていないオペレーティングシステム:{v0}",
|
||||
"@doctor_action_result_info_unsupported_os": {},
|
||||
"doctor_action_info_checking_install_info": "確認中:インストール情報",
|
||||
"@doctor_action_info_checking_install_info": {},
|
||||
"doctor_action_view_details": "詳細を表示",
|
||||
"@doctor_action_view_details": {},
|
||||
"home_install_location": "インストール場所:",
|
||||
"@home_install_location": {},
|
||||
"home_not_installed_or_failed": "インストールされていないか、インストールに失敗しました",
|
||||
"@home_not_installed_or_failed": {},
|
||||
"home_action_star_citizen_website_localization": "SC 公式サイト",
|
||||
"@home_action_star_citizen_website_localization": {},
|
||||
"home_action_info_roberts_space_industries_origin": "Roberts Space Industries、すべての始まり",
|
||||
"@home_action_info_roberts_space_industries_origin": {},
|
||||
"home_action_uex_localization": "UEX ローカリゼーション",
|
||||
"@home_action_uex_localization": {},
|
||||
"home_action_info_mining_refining_trade_calculator": "採掘、精製、取引計算機、価格、船舶情報",
|
||||
"@home_action_info_mining_refining_trade_calculator": {},
|
||||
"home_action_dps_calculator_localization": "DPS計算機 ローカリゼーション",
|
||||
"@home_action_dps_calculator_localization": {},
|
||||
"home_action_info_ship_upgrade_damage_value_query": "オンライン船舶アップグレード、ダメージ値と装備購入場所の照会",
|
||||
"@home_action_info_ship_upgrade_damage_value_query": {},
|
||||
"home_action_external_browser_extension": "外部ブラウザ拡張機能:",
|
||||
"@home_action_external_browser_extension": {},
|
||||
"home_action_one_click_diagnosis": "ワンクリック診断",
|
||||
"@home_action_one_click_diagnosis": {},
|
||||
"home_action_info_one_click_diagnosis_star_citizen": "Star Citizenの一般的な問題をワンクリックで診断",
|
||||
"@home_action_info_one_click_diagnosis_star_citizen": {},
|
||||
"home_action_localization_management": "ローカリゼーション管理",
|
||||
"@home_action_localization_management": {},
|
||||
"home_action_info_quick_install_localization_resources": "ローカリゼーションリソースを簡単にインストール",
|
||||
"@home_action_info_quick_install_localization_resources": {},
|
||||
"home_action_performance_optimization": "パフォーマンス最適化",
|
||||
"@home_action_performance_optimization": {},
|
||||
"home_action_info_engine_config_optimization": "エンジン設定ファイルを調整し、ゲームのパフォーマンスを最適化",
|
||||
"@home_action_info_engine_config_optimization": {},
|
||||
"home_action_rsi_status_platform": "プラットフォーム",
|
||||
"@home_action_rsi_status_platform": {},
|
||||
"home_action_rsi_status_persistent_universe": "PU",
|
||||
"@home_action_rsi_status_persistent_universe": {},
|
||||
"home_action_rsi_status_electronic_access": "EA",
|
||||
"@home_action_rsi_status_electronic_access": {},
|
||||
"home_action_rsi_status_arena_commander": "AC",
|
||||
"@home_action_rsi_status_arena_commander": {},
|
||||
"home_action_rsi_status_rsi_server_status": "RSIサーバーステータス",
|
||||
"@home_action_rsi_status_rsi_server_status": {},
|
||||
"home_action_rsi_status_status": "ステータス:",
|
||||
"@home_action_rsi_status_status": {},
|
||||
"home_announcement_details": "お知らせ詳細",
|
||||
"@home_announcement_details": {},
|
||||
"home_action_info_valid_install_location_required": "この機能には有効なインストール場所が必要です\n\nゲームのダウンロードが完了していない場合は、ダウンロードが完了するまで待ってから、この機能を使用してください。\n\nゲームのダウンロードが完了しているが認識されていない場合は、ゲームを一度起動してからツールボックスを再度開くか、設定オプションでインストール場所を手動で設定してください。",
|
||||
"@home_action_info_valid_install_location_required": {},
|
||||
"home_action_info_scanning": "スキャン中 ...",
|
||||
"@home_action_info_scanning": {},
|
||||
"home_action_info_scan_complete_valid_directories_found": "スキャン完了、{v0}個の有効なインストールディレクトリが見つかりました",
|
||||
"@home_action_info_scan_complete_valid_directories_found": {},
|
||||
"home_action_info_log_file_parse_fail": "ログファイルの解析に失敗しました!",
|
||||
"@home_action_info_log_file_parse_fail": {},
|
||||
"home_action_title_star_citizen_website_localization": "SC 公式サイトローカリゼーション",
|
||||
"@home_action_title_star_citizen_website_localization": {},
|
||||
"home_action_info_web_localization_plugin_disclaimer": "このプラグイン機能は概要閲覧のみを目的としており、この機能に関連する問題について一切責任を負いません!アカウント操作を行う前に、ウェブサイトのオリジナルコンテンツを確認してください!\n\n\nこの機能を使用してアカウントにログインする場合は、信頼できるソースからSCToolboxをダウンロードしていることを確認してください。",
|
||||
"@home_action_info_web_localization_plugin_disclaimer": {},
|
||||
"home_action_info_initializing_resources": "ローカリゼーションリソースを初期化中...",
|
||||
"@home_action_info_initializing_resources": {},
|
||||
"home_action_info_initialization_failed": "ウェブローカリゼーションリソースの初期化に失敗しました!{v0}",
|
||||
"@home_action_info_initialization_failed": {},
|
||||
"home_title_app_name": "SCToolbox",
|
||||
"@home_title_app_name": {},
|
||||
"home_localization_new_version_available": "ローカリゼーションの新しいバージョンが利用可能です!",
|
||||
"@home_localization_new_version_available": {},
|
||||
"home_localization_new_version_installed": "{v0}にインストールしたローカリゼーションに新しいバージョンがあります!",
|
||||
"@home_localization_new_version_installed": {},
|
||||
"home_info_valid_installation_required": "この機能には有効なインストール場所が必要です",
|
||||
"@home_info_valid_installation_required": {},
|
||||
"home_info_one_click_launch_warning": "ワンクリック起動機能の注意",
|
||||
"@home_info_one_click_launch_warning": {},
|
||||
"home_info_account_security_warning": "アカウントセキュリティを確保するため、ワンクリック起動機能は開発版では無効化されています。この機能はMicrosoft Storeバージョンで提供される予定です。\n\nMicrosoft Storeバージョンは、Microsoftが信頼性の高い配布ダウンロードとデジタル署名を提供し、ソフトウェアが悪意を持って改ざんされるのを効果的に防ぎます。\n\nヒント:ゲームの起動にツールボックスを使用しなくても、ローカリゼーションを使用できます。",
|
||||
"@home_info_account_security_warning": {},
|
||||
"home_action_install_microsoft_store_version": "Microsoft Storeバージョンをインストール",
|
||||
"@home_action_install_microsoft_store_version": {},
|
||||
"home_action_cancel": "キャンセル",
|
||||
"@home_action_cancel": {},
|
||||
"home_action_info_abnormal_game_exit": "ゲームが正常に終了しませんでした\nexitCode={v0}\nstdout={v1}\nstderr={v2}\n\n診断情報:{v3} \n{v4}",
|
||||
"@home_action_info_abnormal_game_exit": {},
|
||||
"home_action_info_unknown_error": "不明なエラー、ワンクリック診断を使用してグループに参加し、フィードバックしてください。",
|
||||
"@home_action_info_unknown_error": {},
|
||||
"home_action_info_check_web_link": "詳細情報を確認するには、ポップアップしたウェブリンクを確認してください。",
|
||||
"@home_action_info_check_web_link": {},
|
||||
"home_action_info_game_built_in": "ゲーム内蔵",
|
||||
"@home_action_info_game_built_in": {},
|
||||
"home_action_info_warning": "警告",
|
||||
"@home_action_info_warning": {},
|
||||
"localization_info_machine_translation_warning": "ゲーム内蔵テキストを使用しています。公式テキストは現在機械翻訳です(3.21.0まで)。下記のコミュニティローカリゼーションをインストールすることをお勧めします。",
|
||||
"@localization_info_machine_translation_warning": {},
|
||||
"localization_info_translation": "ゲームローカリゼーション",
|
||||
"@localization_info_translation": {},
|
||||
"localization_info_enabled": "有効({v0}):",
|
||||
"@localization_info_enabled": {},
|
||||
"localization_info_installed_version": "インストール済みバージョン:{v0}",
|
||||
"@localization_info_installed_version": {},
|
||||
"localization_action_translation_feedback": "ローカリゼーションフィードバック",
|
||||
"@localization_action_translation_feedback": {},
|
||||
"localization_action_uninstall_translation": "ローカリゼーションをアンインストール",
|
||||
"@localization_action_uninstall_translation": {},
|
||||
"localization_info_note": "備考:",
|
||||
"@localization_info_note": {},
|
||||
"localization_info_community_translation": "コミュニティローカリゼーション",
|
||||
"@localization_info_community_translation": {},
|
||||
"localization_info_no_translation_available": "この言語/バージョンには現在利用可能なローカリゼーションがありません。お待ちください!",
|
||||
"@localization_info_no_translation_available": {},
|
||||
"localization_action_install": "インストール",
|
||||
"@localization_action_install": {},
|
||||
"localization_info_version_number": "バージョン番号:{v0}",
|
||||
"@localization_info_version_number": {},
|
||||
"localization_info_channel": "チャネル:{v0}",
|
||||
"@localization_info_channel": {},
|
||||
"localization_info_update_time": "更新時間:{v0}",
|
||||
"@localization_info_update_time": {},
|
||||
"localization_info_installed": "インストール済み",
|
||||
"@localization_info_installed": {},
|
||||
"localization_info_unavailable": "利用不可",
|
||||
"@localization_info_unavailable": {},
|
||||
"localization_info_language": "言語: ",
|
||||
"@localization_info_language": {},
|
||||
"localization_info_remove_incompatible_translation_params": "互換性のないローカリゼーションパラメータを削除しますか",
|
||||
"@localization_info_remove_incompatible_translation_params": {},
|
||||
"localization_info_incompatible_translation_params_warning": "USER.cfgに互換性のないローカリゼーションパラメータが含まれています。これは以前のローカリゼーションファイルの残りである可能性があります。\n\nこれによりローカリゼーションが無効になったり文字化けしたりする可能性があります。確認をクリックすると、ワンクリックで削除されます(他の設定には影響しません)。",
|
||||
"@localization_info_incompatible_translation_params_warning": {},
|
||||
"localization_info_corrupted_file": "ファイルが破損しています。再ダウンロードしてください",
|
||||
"@localization_info_corrupted_file": {},
|
||||
"localization_info_installation_error": "インストールエラー!\n\n {v0}",
|
||||
"@localization_info_installation_error": {},
|
||||
"localization_info_custom_files": "カスタムファイル",
|
||||
"@localization_info_custom_files": {},
|
||||
"performance_info_graphic_optimization_hint": "グラフィック最適化のヒント",
|
||||
"@performance_info_graphic_optimization_hint": {},
|
||||
"performance_info_graphic_optimization_warning": "この機能はグラフィックカードのボトルネックの最適化に役立ちますが、CPUのボトルネックには逆効果になることがあります。グラフィックカードの性能が高い場合は、より良い画質を使用してグラフィックカードの利用率を高めることができます。",
|
||||
"@performance_info_graphic_optimization_warning": {},
|
||||
"performance_info_current_status": "現在の状態:{v0}",
|
||||
"@performance_info_current_status": {},
|
||||
"performance_info_applied": "適用済み",
|
||||
"@performance_info_applied": {},
|
||||
"performance_info_not_applied": "未適用",
|
||||
"@performance_info_not_applied": {},
|
||||
"performance_action_preset": "プリセット:",
|
||||
"@performance_action_preset": {},
|
||||
"performance_action_low": "低",
|
||||
"@performance_action_low": {},
|
||||
"performance_action_medium": "中",
|
||||
"@performance_action_medium": {},
|
||||
"performance_action_high": "高",
|
||||
"@performance_action_high": {},
|
||||
"performance_action_super": "超高",
|
||||
"@performance_action_super": {},
|
||||
"performance_action_info_preset_only_changes_graphics": "(プリセットはグラフィック設定のみを変更します)",
|
||||
"@performance_action_info_preset_only_changes_graphics": {},
|
||||
"performance_action_reset_to_default": " デフォルトに戻す ",
|
||||
"@performance_action_reset_to_default": {},
|
||||
"performance_action_apply": "適用",
|
||||
"@performance_action_apply": {},
|
||||
"performance_action_apply_and_clear_shaders": "適用してシェーダーをクリア(推奨)",
|
||||
"@performance_action_apply_and_clear_shaders": {},
|
||||
"performance_title_performance_optimization": "パフォーマンス最適化 -> {v0}",
|
||||
"@performance_title_performance_optimization": {},
|
||||
"performance_action_custom_parameters_input": "ツールボックスに収録されていないカスタムパラメーターをここに入力できます。設定例:\n\nr_displayinfo=0\nr_VSync=0",
|
||||
"@performance_action_custom_parameters_input": {},
|
||||
"performance_info_min_max_values": "{v0} 最小値: {v1} / 最大値: {v2}",
|
||||
"@performance_info_min_max_values": {},
|
||||
"performance_info_graphics": "グラフィック",
|
||||
"@performance_info_graphics": {},
|
||||
"performance_info_delete_config_file": "設定ファイルを削除中...",
|
||||
"@performance_info_delete_config_file": {},
|
||||
"performance_action_clear_shaders": "シェーダーをクリア",
|
||||
"@performance_action_clear_shaders": {},
|
||||
"performance_info_done": "完了...",
|
||||
"@performance_info_done": {},
|
||||
"performance_info_shader_clearing_warning": "シェーダーをクリアした後、最初にゲームに入るとカクつく可能性があります。ゲームの初期化が完了するまで辛抱強くお待ちください。",
|
||||
"@performance_info_shader_clearing_warning": {},
|
||||
"performance_info_generate_config_file": "設定ファイルを生成",
|
||||
"@performance_info_generate_config_file": {},
|
||||
"performance_info_write_out_config_file": "設定ファイルを書き出し",
|
||||
"@performance_info_write_out_config_file": {},
|
||||
"app_index_menu_home": "ホーム",
|
||||
"@app_index_menu_home": {},
|
||||
"app_index_menu_lobby": "ロビー",
|
||||
"@app_index_menu_lobby": {},
|
||||
"app_index_menu_tools": "ツール",
|
||||
"@app_index_menu_tools": {},
|
||||
"app_index_menu_settings": "設定",
|
||||
"@app_index_menu_settings": {},
|
||||
"app_index_menu_about": "アバウト",
|
||||
"@app_index_menu_about": {},
|
||||
"lobby_online_lobby_coming_soon": "オンラインロビー、乞うご期待!",
|
||||
"@lobby_online_lobby_coming_soon": {},
|
||||
"lobby_invitation_to_participate": "ぜひご参加ください ",
|
||||
"@lobby_invitation_to_participate": {},
|
||||
"lobby_survey": "アンケート調査。",
|
||||
"@lobby_survey": {},
|
||||
"setting_action_create_settings_shortcut": "設定ショートカットを作成",
|
||||
"@setting_action_create_settings_shortcut": {},
|
||||
"setting_action_create_desktop_shortcut": "デスクトップに「SCToolbox」ショートカットを作成",
|
||||
"@setting_action_create_desktop_shortcut": {},
|
||||
"setting_action_reset_auto_password_fill": "自動パスワード入力をリセット",
|
||||
"@setting_action_reset_auto_password_fill": {},
|
||||
"setting_action_ignore_efficiency_cores_on_launch": "ゲーム起動時に効率コアを無視(Intel第12世代以降のプロセッサに適用)",
|
||||
"@setting_action_ignore_efficiency_cores_on_launch": {},
|
||||
"setting_action_set_core_count": "設定されたコア数:{v0} (この機能はホームページのツールボックスワンクリック起動またはツールのRSIランチャー管理者モードに適用されます。0の場合、この機能は有効になりません)",
|
||||
"@setting_action_set_core_count": {},
|
||||
"setting_action_set_launcher_file": "ランチャーファイルを設定(RSI Launcher.exe)",
|
||||
"@setting_action_set_launcher_file": {},
|
||||
"setting_action_info_manual_launcher_location_setting": "ランチャーの場所を手動で設定します。インストール場所の自動スキャンができない場合のみ使用することをお勧めします",
|
||||
"@setting_action_info_manual_launcher_location_setting": {},
|
||||
"setting_action_set_game_file": "ゲームファイルを設定(StarCitizen.exe)",
|
||||
"@setting_action_set_game_file": {},
|
||||
"setting_action_info_manual_game_location_setting": "ゲームのインストール場所を手動で設定します。インストール場所の自動スキャンができない場合のみ使用することをお勧めします",
|
||||
"@setting_action_info_manual_game_location_setting": {},
|
||||
"setting_action_clear_translation_file_cache": "ローカリゼーションファイルキャッシュをクリア",
|
||||
"@setting_action_clear_translation_file_cache": {},
|
||||
"setting_action_info_cache_clearing_info": "キャッシュサイズ {v0}MB、ツールボックスがダウンロードしたローカリゼーションファイルキャッシュをクリアします。インストール済みのローカリゼーションには影響しません",
|
||||
"@setting_action_info_cache_clearing_info": {},
|
||||
"setting_action_tool_site_access_acceleration": "ツールサイトアクセス加速",
|
||||
"@setting_action_tool_site_access_acceleration": {},
|
||||
"setting_action_info_mirror_server_info": "ミラーサーバーを使用してDps、Uexなどのツールウェブサイトへのアクセスを高速化します。アクセスに異常がある場合は、この機能をオフにしてください。アカウントセキュリティを保護するために、どのような状況でもRSI公式サイトは加速されません。",
|
||||
"@setting_action_info_mirror_server_info": {},
|
||||
"setting_action_view_log": "ログを表示",
|
||||
"@setting_action_view_log": {},
|
||||
"setting_action_info_view_log_file": "SCToolboxのログファイルを表示して、ツールのバグを特定します",
|
||||
"@setting_action_info_view_log_file": {},
|
||||
"setting_action_info_confirm_reset_autofill": "自動入力をリセットしますか?",
|
||||
"@setting_action_info_confirm_reset_autofill": {},
|
||||
"setting_action_info_delete_local_account_warning": "これにより、ローカルアカウント記録が削除されるか、次回ゲームを起動するときに自動入力を選択する際に「いいえ」を選択して自動入力を無効にします。",
|
||||
"@setting_action_info_delete_local_account_warning": {},
|
||||
"setting_action_info_autofill_data_cleared": "自動入力データがクリアされました",
|
||||
"@setting_action_info_autofill_data_cleared": {},
|
||||
"setting_action_info_enter_cpu_core_to_ignore": "無視するCPUコア数を入力してください",
|
||||
"@setting_action_info_enter_cpu_core_to_ignore": {},
|
||||
"setting_action_info_cpu_core_tip": "ヒント:あなたのデバイスに効率コアがいくつあるかを入力してください。大小コア設計でないデバイスは0のままにしてください\n\nこの機能はホームページのツールボックスワンクリック起動またはツールのRSIランチャー管理者モードに適用されます。0の場合、この機能は有効になりません。",
|
||||
"@setting_action_info_cpu_core_tip": {},
|
||||
"setting_action_info_select_rsi_launcher_location": "RSIランチャーの場所を選択してください(RSI Launcher.exe)",
|
||||
"@setting_action_info_select_rsi_launcher_location": {},
|
||||
"setting_action_info_setting_success": "設定成功、対応するページで更新をクリックすると新しいパスがスキャンされます",
|
||||
"@setting_action_info_setting_success": {},
|
||||
"setting_action_info_file_error": "ファイルエラー!",
|
||||
"@setting_action_info_file_error": {},
|
||||
"setting_action_info_select_game_install_location": "ゲームのインストール場所を選択してください(StarCitizen.exe)",
|
||||
"@setting_action_info_select_game_install_location": {},
|
||||
"setting_action_info_confirm_clear_cache": "ローカリゼーションキャッシュをクリアしますか?",
|
||||
"@setting_action_info_confirm_clear_cache": {},
|
||||
"setting_action_info_clear_cache_warning": "これはインストール済みのローカリゼーションには影響しません。",
|
||||
"@setting_action_info_clear_cache_warning": {},
|
||||
"setting_action_info_microsoft_version_limitation": "Microsoft版の機能制限により、次に開かれるウィンドウで手動で「SCToolbox」をデスクトップにドラッグしてショートカットを作成してください。",
|
||||
"@setting_action_info_microsoft_version_limitation": {},
|
||||
"setting_action_info_shortcut_created": "作成完了、デスクトップに戻って確認してください",
|
||||
"@setting_action_info_shortcut_created": {},
|
||||
"app_upgrade_title_new_version_found": "新しいバージョンが見つかりました -> {v0}",
|
||||
"@app_upgrade_title_new_version_found": {},
|
||||
"app_upgrade_info_getting_new_version_details": "新しいバージョンの詳細を取得中...",
|
||||
"@app_upgrade_info_getting_new_version_details": {},
|
||||
"app_upgrade_info_update_server_tip": "ヒント:現在、コスト管理に役立つ分散サーバーを使用して更新しています。ダウンロード速度が低下する可能性がありますが、ダウンロードに問題がある場合は、ここをクリックして手動インストールに切り替えてください。",
|
||||
"@app_upgrade_info_update_server_tip": {},
|
||||
"app_upgrade_info_installing": "インストール中: ",
|
||||
"@app_upgrade_info_installing": {},
|
||||
"app_upgrade_info_downloading": "ダウンロード中: {v0}% ",
|
||||
"@app_upgrade_info_downloading": {},
|
||||
"app_upgrade_action_update_now": "今すぐ更新",
|
||||
"@app_upgrade_action_update_now": {},
|
||||
"app_upgrade_action_next_time": "次回にする",
|
||||
"@app_upgrade_action_next_time": {},
|
||||
"app_upgrade_info_download_failed": "ダウンロードに失敗しました。手動インストールを試してください!",
|
||||
"@app_upgrade_info_download_failed": {},
|
||||
"app_upgrade_info_run_failed": "実行に失敗しました。手動インストールを試してください!",
|
||||
"@app_upgrade_info_run_failed": {},
|
||||
"app_splash_checking_availability": "利用可能性を確認中、少し時間がかかる場合があります...",
|
||||
"@app_splash_checking_availability": {},
|
||||
"app_splash_checking_for_updates": "更新を確認中...",
|
||||
"@app_splash_checking_for_updates": {},
|
||||
"app_splash_almost_done": "もうすぐ完了…",
|
||||
"@app_splash_almost_done": {},
|
||||
"tools_hosts_info_rsi_official_website": "RSI公式サイト",
|
||||
"@tools_hosts_info_rsi_official_website": {},
|
||||
"tools_hosts_info_rsi_customer_service": "RSIカスタマーサービスサイト",
|
||||
"@tools_hosts_info_rsi_customer_service": {},
|
||||
"tools_hosts_info_dns_query_and_test": "DNSを問い合わせてアクセス可能性をテスト中です。しばらくお待ちください...",
|
||||
"@tools_hosts_info_dns_query_and_test": {},
|
||||
"tools_hosts_info_writing_hosts": "Hostsファイルに書き込み中 ...",
|
||||
"@tools_hosts_info_writing_hosts": {},
|
||||
"tools_hosts_info_reading_config": "設定を読み込み中 ...",
|
||||
"@tools_hosts_info_reading_config": {},
|
||||
"tools_hosts_info_hosts_acceleration": "Hosts加速",
|
||||
"@tools_hosts_info_hosts_acceleration": {},
|
||||
"tools_hosts_info_open_hosts_file": "Hostsファイルを開く",
|
||||
"@tools_hosts_info_open_hosts_file": {},
|
||||
"tools_hosts_info_status": "ステータス",
|
||||
"@tools_hosts_info_status": {},
|
||||
"tools_hosts_info_site": "サイト",
|
||||
"@tools_hosts_info_site": {},
|
||||
"tools_hosts_info_enable": "有効にする",
|
||||
"@tools_hosts_info_enable": {},
|
||||
"tools_hosts_action_one_click_acceleration": "ワンクリック加速",
|
||||
"@tools_hosts_action_one_click_acceleration": {},
|
||||
"tools_info_scanning": "スキャン中...",
|
||||
"@tools_info_scanning": {},
|
||||
"tools_info_processing_failed": "処理に失敗しました!:{v0}",
|
||||
"@tools_info_processing_failed": {},
|
||||
"tools_info_game_install_location": "ゲームインストール場所: ",
|
||||
"@tools_info_game_install_location": {},
|
||||
"tools_info_rsi_launcher_location": "RSIランチャー場所:",
|
||||
"@tools_info_rsi_launcher_location": {},
|
||||
"tools_action_view_system_info": "システム情報を表示",
|
||||
"@tools_action_view_system_info": {},
|
||||
"tools_action_info_view_critical_system_info": "診断に役立つ重要なシステム情報を表示 \n\n時間のかかる操作です、お待ちください。",
|
||||
"@tools_action_info_view_critical_system_info": {},
|
||||
"tools_action_p4k_download_repair": "P4K 分散ダウンロード / 修復",
|
||||
"@tools_action_p4k_download_repair": {},
|
||||
"tools_action_info_p4k_download_repair_tip": "Star Citizen中国語百科事典が提供する分散ダウンロードサービスを使用して、p4kのダウンロードや修復ができます。 \nバージョン情報:{v0}",
|
||||
"@tools_action_info_p4k_download_repair_tip": {},
|
||||
"tools_action_hosts_acceleration_experimental": "Hosts加速(実験的)",
|
||||
"@tools_action_hosts_acceleration_experimental": {},
|
||||
"tools_action_info_hosts_acceleration_experimental_tip": "IP情報をHostsファイルに書き込み、一部の地域でのDNS汚染による公式サイトへのログイン問題などを解決します。\nこの機能は第一段階のテスト中です。問題が発生した場合はすぐにフィードバックしてください。",
|
||||
"@tools_action_info_hosts_acceleration_experimental_tip": {},
|
||||
"tools_action_reinstall_easyanticheat": "EasyAntiCheat アンチチートを再インストール",
|
||||
"@tools_action_reinstall_easyanticheat": {},
|
||||
"tools_action_info_reinstall_eac": "EACエラーが発生し、自動修復が効かない場合は、この機能を使用してEACを再インストールしてください。",
|
||||
"@tools_action_info_reinstall_eac": {},
|
||||
"tools_action_rsi_launcher_admin_mode": "RSI Launcher 管理者モード",
|
||||
"@tools_action_rsi_launcher_admin_mode": {},
|
||||
"tools_action_info_run_rsi_as_admin": "RSIランチャーを管理者権限で実行すると、一部の問題が解決する場合があります。\n\n効率コア無視パラメータを設定している場合は、ここでも適用されます。",
|
||||
"@tools_action_info_run_rsi_as_admin": {},
|
||||
"tools_action_info_init_failed": "初期化に失敗しました。スクリーンショットを撮って開発者に報告してください。{v0}",
|
||||
"@tools_action_info_init_failed": {},
|
||||
"tools_action_rsi_launcher_log_fix": "RSI Launcher ログ修復",
|
||||
"@tools_action_rsi_launcher_log_fix": {},
|
||||
"tools_action_info_rsi_launcher_log_issue": "特定の状況でRSIランチャーのログファイルが破損し、問題スキャンが完了できなくなることがあります。このツールを使用して破損したログファイルをクリーンアップしてください。\n\n現在のログファイルサイズ:{v0} MB",
|
||||
"@tools_action_info_rsi_launcher_log_issue": {},
|
||||
"tools_action_remove_nvme_registry_patch": "nvmeレジストリパッチを削除",
|
||||
"@tools_action_remove_nvme_registry_patch": {},
|
||||
"tools_action_info_nvme_patch_issue": "nvmeパッチを使用して問題が発生した場合は、このツールを実行してください。(ゲームのインストール/更新が使用できなくなる可能性があります。)\n\n現在のパッチ状態:{v0}",
|
||||
"@tools_action_info_nvme_patch_issue": {},
|
||||
"tools_action_info_not_installed": "インストールされていません",
|
||||
"@tools_action_info_not_installed": {},
|
||||
"tools_action_info_removed_restart_effective": "削除されました、コンピュータを再起動すると有効になります!",
|
||||
"@tools_action_info_removed_restart_effective": {},
|
||||
"tools_action_write_nvme_registry_patch": "nvmeレジストリパッチを書き込む",
|
||||
"@tools_action_write_nvme_registry_patch": {},
|
||||
"tools_action_info_manual_nvme_patch": "NVMパッチを手動で書き込みます。この機能は、自分が何をしているかを理解している場合にのみ使用してください",
|
||||
"@tools_action_info_manual_nvme_patch": {},
|
||||
"tools_action_info_fix_success_restart": "修復が成功しました。コンピュータを再起動してからゲームのインストールを続けてみてください!レジストリの変更が他のソフトウェアに互換性の問題を引き起こす場合は、ツールの「NVMEレジストリクリーナー」を使用してください。",
|
||||
"@tools_action_info_fix_success_restart": {},
|
||||
"tools_action_clear_shader_cache": "シェーダーキャッシュをクリア",
|
||||
"@tools_action_clear_shader_cache": {},
|
||||
"tools_action_info_shader_cache_issue": "ゲームの表示に異常が発生した場合や、バージョン更新後に、このツールを使用して古いシェーダーをクリアできます(同時にVulkanをDX11に戻します) \n\nキャッシュサイズ:{v0} MB",
|
||||
"@tools_action_info_shader_cache_issue": {},
|
||||
"tools_action_close_photography_mode": "撮影モードを閉じる",
|
||||
"@tools_action_close_photography_mode": {},
|
||||
"tools_action_open_photography_mode": "撮影モードを開く",
|
||||
"@tools_action_open_photography_mode": {},
|
||||
"tools_action_info_restore_lens_shake": "レンズの揺れ効果を復元します。\n\n@拉邦那 Lapernum 提供のパラメータ情報。",
|
||||
"@tools_action_info_restore_lens_shake": {},
|
||||
"tools_action_info_one_key_close_lens_shake": "ゲーム内のレンズの揺れをワンクリックでオフにして、撮影操作を容易にします。\n\n @拉邦那 Lapernum 提供のパラメータ情報。",
|
||||
"@tools_action_info_one_key_close_lens_shake": {},
|
||||
"tools_action_info_log_file_parse_failed": "ログファイルの解析に失敗しました!\n「RSI Launcher ログ修復」ツールを使用してみてください!",
|
||||
"@tools_action_info_log_file_parse_failed": {},
|
||||
"tools_action_info_rsi_launcher_not_found": "RSIランチャーが見つかりません。再インストールするか、設定で手動で追加してください。",
|
||||
"@tools_action_info_rsi_launcher_not_found": {},
|
||||
"tools_action_info_star_citizen_not_found": "Star Citizenゲームのインストール場所が見つかりません。少なくとも1回ゲームを起動するか、設定で手動で追加してください。",
|
||||
"@tools_action_info_star_citizen_not_found": {},
|
||||
"tools_action_info_valid_game_directory_needed": "この機能には有効なゲームインストールディレクトリが必要です",
|
||||
"@tools_action_info_valid_game_directory_needed": {},
|
||||
"tools_action_info_eac_file_removed": "EACファイルが削除されました。次にRSIランチャーを開きます。SETTINGS -> VERIFYに移動してEACを再インストールしてください。",
|
||||
"@tools_action_info_eac_file_removed": {},
|
||||
"tools_action_info_error_occurred": "エラーが発生しました:{v0}",
|
||||
"@tools_action_info_error_occurred": {},
|
||||
"tools_action_info_system_info_content": "システム:{v0}\n\nプロセッサ:{v1}\n\nメモリサイズ:{v2}GB\n\nグラフィックカード情報:\n{v3}\n\nハードドライブ情報:\n{v4}\n\n",
|
||||
"@tools_action_info_system_info_content": {},
|
||||
"tools_action_info_rsi_launcher_directory_not_found": "RSIランチャーディレクトリが見つかりません。手動で操作してください。",
|
||||
"@tools_action_info_rsi_launcher_directory_not_found": {},
|
||||
"tools_action_info_log_file_not_exist": "ログファイルが存在しません。ゲームを一度起動またはインストールしてから、ランチャーを終了してください。問題が解決しない場合は、ランチャーを最新バージョンに更新してみてください!",
|
||||
"@tools_action_info_log_file_not_exist": {},
|
||||
"tools_action_info_cleanup_complete": "クリーンアップが完了しました。インストールまたはゲーム起動操作を完了してください。",
|
||||
"@tools_action_info_cleanup_complete": {},
|
||||
"tools_action_info_cleanup_failed": "クリーンアップに失敗しました。手動で削除してください。ファイルの場所:{v0}",
|
||||
"tools_action_info_system_info_title": "システム情報",
|
||||
"@tools_action_info_system_info_title": {},
|
||||
"tools_action_info_rsi_launcher_running_warning": "RSIランチャーが実行中です!この機能を使用する前にランチャーを閉じてください!",
|
||||
"@tools_action_info_rsi_launcher_running_warning": {},
|
||||
"tools_action_info_p4k_file_description": "P4kはStar Citizenのコアゲームファイルで、100GB以上のサイズです。SCToolboxが提供するオフラインダウンロードは、p4kファイルのダウンロードが非常に遅いユーザーをサポートするため、または公式ランチャーで修復できないp4kファイルを修正するためのものです。\n\n次に保存先を選択するダイアログが表示されます(Star Citizenフォルダでも他の場所でも選択可能)。ダウンロード完了後、P4KファイルがLIVEフォルダ内にあることを確認し、Star Citizenランチャーで検証と更新を行ってください。",
|
||||
"@tools_action_info_p4k_file_description": {},
|
||||
"tools_action_info_p4k_download_in_progress": "p4kのダウンロードタスクが既に進行中です。ダウンロードマネージャーで確認してください!",
|
||||
"@tools_action_info_p4k_download_in_progress": {},
|
||||
"tools_action_info_function_under_maintenance": "機能はメンテナンス中です。後でもう一度お試しください!",
|
||||
"@tools_action_info_function_under_maintenance": {},
|
||||
"tools_action_info_config_file_not_exist": "設定ファイルが存在しません。一度ゲームを実行してみてください",
|
||||
"@tools_action_info_config_file_not_exist": {},
|
||||
"webview_localization_name_member": "メンバー名",
|
||||
"@webview_localization_name_member": {},
|
||||
"webview_localization_total_invitations": "招待総数:",
|
||||
"@webview_localization_total_invitations": {},
|
||||
"webview_localization_unfinished_invitations": "未完了の招待",
|
||||
"@webview_localization_unfinished_invitations": {},
|
||||
"webview_localization_finished_invitations": "完了した招待",
|
||||
"@webview_localization_finished_invitations": {},
|
||||
"app_init_failed_with_reason": "初期化に失敗:{v0}",
|
||||
"@app_init_failed_with_reason": {},
|
||||
"settings_app_language": "言語",
|
||||
"settings_app_language_auto": "自動",
|
||||
"app_common_network_error": "ネットワーク接続に失敗しました! \nオフラインモードに入ります... \n\nネットワーク接続を確認するか、ソーシャルフォーラムで最新情報を入手してください。アプリ設定で組み込みDNSモードをオンにすることもお試しください。 \n現在のバージョンのビルド日:{v0}\n QQグループ:940696487 \nエラーメッセージ:{v1}",
|
||||
"app_common_upgrade_info_error": "アップデート情報の取得に失敗しました。後でもう一度お試しください。",
|
||||
"doctor_game_error_low_memory": "利用可能メモリ不足",
|
||||
"doctor_game_error_low_memory_info": "仮想メモリを増やしてみてください(1080pでは、物理メモリ+仮想メモリが64GBを超える必要があります)",
|
||||
"doctor_game_error_generic_info": "ゲームが最も一般的なクラッシュ問題を引き起こしました。トラブルシューティングガイドを確認してください",
|
||||
"doctor_game_error_gpu_crash": "グラフィックカードがクラッシュしました!トラブルシューティングガイドを確認してください",
|
||||
"doctor_game_error_socket_error": "ソケットエラーが検出されました",
|
||||
"doctor_game_error_socket_error_info": "X黑盒加速器を使用している場合は、加速モードを変更してみてください",
|
||||
"doctor_game_error_permissions_error": "権限不足",
|
||||
"doctor_game_error_permissions_error_info": "管理者権限でランチャーを実行するか、SCToolbox(Microsoft Store版)を使用して起動してみてください。",
|
||||
"doctor_game_error_game_process_error": "ゲームプロセスが使用中です",
|
||||
"doctor_game_error_game_process_error_info": "ランチャーを再起動するか、PCを再起動してみてください",
|
||||
"doctor_game_error_game_damaged_file": "ゲームプログラムファイルが破損しています",
|
||||
"doctor_game_error_game_damaged_file_info": "Bin64フォルダを削除してランチャーで検証してみてください。",
|
||||
"doctor_game_error_game_damaged_p4k_file": "P4Kファイルが破損しています",
|
||||
"doctor_game_error_game_damaged_p4k_file_info": "Data.p4kファイルを削除してランチャーで検証するか、SCToolboxの配布を使用してみてください。",
|
||||
"doctor_game_error_low_gpu_memory": "利用可能なグラフィックメモリ不足",
|
||||
"doctor_game_error_low_gpu_memory_info": "バックグラウンドで他のグラフィック集中型のゲーム/アプリを実行しないようにするか、グラフィックカードをアップグレードしてください。",
|
||||
"doctor_game_error_gpu_vulkan_crash": "GPU Vulkanクラッシュ",
|
||||
"doctor_game_error_gpu_vulkan_crash_info": "Vulkanがクラッシュしました!これはドライバーバージョンまたはゲームエンジンの問題かもしれません。GPUドライバーを更新するか、シェーダークリーニング機能を使用してDX11に戻すことをお試しください",
|
||||
"app_common_error_info": "エラーが発生しました:{v0}",
|
||||
"app_common_tip": "ヒント",
|
||||
"app_common_tip_i_know": "理解しました",
|
||||
"app_common_tip_confirm": "確認",
|
||||
"app_common_tip_cancel": "キャンセル",
|
||||
"settings_app_language_switch_info": "アプリの表示言語を切り替える",
|
||||
"home_holiday_countdown_days": "{v0}日 ",
|
||||
"home_holiday_countdown_in_progress": "進行中",
|
||||
"app_common_loading_images": "画像を読み込み中...",
|
||||
"app_splash_dialog_u_a_p_p": "ユーザー契約とプライバシーポリシー",
|
||||
"app_splash_dialog_u_a_p_p_content": "SCToolboxをお選びいただきありがとうございます。私たちは安全で便利、信頼性の高い体験を提供することに努めています。アプリを使用する前に、以下をお読みいただき同意してください:\n\n 1. このアプリケーションはGNU General Public License v3.0の下でのオープンソースソフトウェアです。ライセンスに従って自由に使用、変更、配布することができます。ソースコードは[Github.com/StarCitizenToolBox/app](https://github.com/StarCitizenToolBox/app)にあります。 \n2. このアプリケーション内のインターネットコンテンツ(ローカリゼーションファイル、ツールウェブサイト、ニュース、ビデオなどを含む)の著作権はその作者に帰属し、GPLの一部ではありません。対応するライセンス契約を遵守して使用してください。\n3. このアプリケーションの公式無料配布チャンネルは[Microsoft Store](https://apps.microsoft.com/detail/9NF3SWFWNKL1)と[Star Citizen ローカリゼーションチームの公式ウェブサイト](https://www.starcitizenzw.com/)です。他のサードパーティから入手した場合は、財産損失を避けるため慎重に判断してください。\n4. このアプリケーションはソフトウェア品質向上のため、使用中に匿名の統計データを当社サーバーに送信します。個人的なプライバシー情報は収集しません。 \n5. このアプリケーションはコミュニティサポートにより提供され、Cloud Imperium Gamesや他のサードパーティの商業会社とは直接関連していません。\n6. 私たちは限定的なコミュニティサポートを提供しています。必要な場合は、「概要」ページで連絡方法をご確認ください。",
|
||||
"tools_unp4k_msg_init": "初期化中...",
|
||||
"tools_unp4k_msg_reading": "P4Kファイルを読み込み中...",
|
||||
"tools_unp4k_msg_reading2": "ファイルを処理中...",
|
||||
"tools_unp4k_msg_reading3": "ファイルを処理中({v0}/{v1})...",
|
||||
"tools_unp4k_msg_read_completed": "読み込み完了:{v0}ファイル、所要時間:{v1} ms",
|
||||
"tools_unp4k_msg_open_file": "ファイルを開く:{v0}",
|
||||
"tools_unp4k_msg_read_file": "ファイルを読み込み中:{v0}...",
|
||||
"home_localization_advanced_title": "高度なローカリゼーション -> {v0}",
|
||||
"home_localization_advanced_msg_version": "読み込まれたローカリゼーションバージョン:{v0}",
|
||||
"home_localization_advanced_title_msg": "ローカリゼーションテキスト行数:{v0} P4Kテキスト行数:{v1}",
|
||||
"home_localization_advanced_action_install": "ローカリゼーションをインストール",
|
||||
"home_localization_advanced_action_mod_change": "テキストを再生成中...",
|
||||
"home_localization_advanced_action_mode": "モード",
|
||||
"home_localization_advanced_title_preview": "プレビュー:{v0}",
|
||||
"home_localization_advanced_json_text_location_other": "場所-その他",
|
||||
"home_localization_advanced_json_text_location_used": "場所-よく使用",
|
||||
"home_localization_advanced_json_text_things_other": "アイテム-その他",
|
||||
"home_localization_advanced_json_text_things_used": "アイテム-よく使用",
|
||||
"home_localization_advanced_json_text_vehicle_other": "ビークル-その他",
|
||||
"home_localization_advanced_json_text_vehicle_used": "ビークル-よく使用",
|
||||
"home_localization_advanced_json_text_mission_or_logs": "ミッション/ログ",
|
||||
"home_localization_advanced_json_text_subtitle": "字幕",
|
||||
"home_localization_advanced_json_text_ui_or_hud_or_menu": "UI/HUD/メニュー",
|
||||
"home_localization_advanced_json_text_un_localization": "未ローカリゼーション",
|
||||
"home_localization_advanced_json_text_others": "その他",
|
||||
"home_localization_advanced_action_mod_change_localization": "ローカリゼーション",
|
||||
"home_localization_advanced_action_mod_change_un_localization": "英語原文",
|
||||
"home_localization_advanced_action_mod_change_mixed": "バイリンガル",
|
||||
"home_localization_advanced_action_mod_change_mixed_newline": "バイリンガル(改行)",
|
||||
"home_localization_advanced_msg_classifying": "分類中...",
|
||||
"home_localization_advanced_msg_reading_p4k": "p4kファイルを読み込み中...",
|
||||
"home_localization_advanced_msg_reading_server_localization_text": "ローカリゼーションテキストを取得中...",
|
||||
"home_localization_advanced_msg_gen_localization_text": "ローカリゼーションファイルを生成中...",
|
||||
"home_localization_advanced_msg_gen_localization_install": "ローカリゼーションファイルをインストール中...",
|
||||
"home_localization_msg_version_advanced": " (高度なローカリゼーション)",
|
||||
"home_localization_msg_no_note": "このバージョンには説明がありません",
|
||||
"home_localization_action_rsi_launcher_localization": "RSIランチャーローカリゼーション",
|
||||
"home_localization_action_rsi_launcher_no_game_path_msg": "現在ゲーム本体がインストールされていないか、ゲームインストールディレクトリが選択されていません。ランチャーローカリゼーション機能のみ使用できます。ゲームのインストールが完了しているか、SCToolbox設定でゲームインストールディレクトリを追加した後に再試行してください。",
|
||||
"home_localization_action_advanced": "高度なローカリゼーション",
|
||||
"home_localization_action_install_customize": "カスタムファイルをインストール",
|
||||
"home_localization_title_localization_tools": "ローカリゼーションツール",
|
||||
"performance_json_text_dof": "被写界深度効果",
|
||||
"performance_json_text_dof_info": "モビグラスページなどの被写界深度効果を制御",
|
||||
"performance_json_text_ssdo": "スクリーンスペース光後処理",
|
||||
"performance_json_text_ssdo_info": "光の後処理レベルを調整",
|
||||
"performance_json_text_title_graphics": "グラフィック(変更後はシェーダーをクリアすることをお勧めします)",
|
||||
"performance_json_text_antialiasing": "アンチエイリアス",
|
||||
"performance_json_text_antialiasing_info": "0 オフ、1 SMAA、2 テンポラルフィルタリング+SMAA、3 テンポラルフィルタリングとプロジェクションマトリックスジッタを使用したSMAA",
|
||||
"performance_json_text_game_effects": "エフェクトレベル",
|
||||
"performance_json_text_game_effects_info": "ゲームエフェクトレベル",
|
||||
"performance_json_text_texture": "テクスチャレベル",
|
||||
"performance_json_text_texture_info": "モデルテクスチャの詳細",
|
||||
"performance_json_text_volumetric_effects": "ボリューメトリック効果",
|
||||
"performance_json_text_volumetric_effects_info": "ボリューメトリッククラウド、ボリューメトリック照明など",
|
||||
"performance_json_text_water": "水の効果",
|
||||
"performance_json_text_water_info": "様々な水のレベル",
|
||||
"performance_json_text_object_detail": "オブジェクト詳細",
|
||||
"performance_json_text_object_detail_info": "モデルオブジェクトの詳細、LODに影響など...",
|
||||
"performance_json_text_particles": "パーティクル詳細",
|
||||
"performance_json_text_physics": "物理詳細",
|
||||
"performance_json_text_physics_info": "物理効果範囲",
|
||||
"performance_json_text_shading": "シェーディング詳細",
|
||||
"performance_json_text_shading_info": "シェーダー関連",
|
||||
"performance_json_text_shadows": "影の詳細",
|
||||
"performance_json_text_shadows_info": "影の効果",
|
||||
"performance_json_text_postprocessing": "後処理詳細",
|
||||
"performance_json_text_postprocessing_info": "後処理シェーダー、モーションブラー効果など",
|
||||
"performance_json_text_renderer": "レンダラー品質",
|
||||
"performance_json_text_renderer_info": "cryengineレンダラー品質",
|
||||
"performance_json_text_shader_decal": "デカール品質",
|
||||
"performance_json_text_shader_decal_info": "(ロゴ、マークなど)",
|
||||
"performance_json_text_shader_post_process": "シェーダー品質",
|
||||
"performance_json_text_shader_fx": "FX品質",
|
||||
"performance_json_text_shader_general": "一般的な品質",
|
||||
"performance_json_text_shader_general_info": "全体的なモデル品質",
|
||||
"performance_json_text_shader_glass": "ガラス品質",
|
||||
"performance_json_text_shader_glass_info": "窓、鏡など",
|
||||
"performance_json_text_shader_hdr": "HDR品質",
|
||||
"performance_json_text_shader_hdr_info": "HDRカラーアベレーション、輝度レベル処理など",
|
||||
"performance_json_text_shader_particle": "パーティクル品質",
|
||||
"performance_json_text_shader_particle_info": "パーティクル効果の品質",
|
||||
"performance_json_text_shader_terrain": "地形品質",
|
||||
"performance_json_text_shader_shadow": "影品質",
|
||||
"performance_json_text_shader_sky": "空品質",
|
||||
"performance_json_text_particles_object_collisions": "パーティクル衝突",
|
||||
"performance_json_text_particles_object_collisions_info": "1 静的パーティクルのみ 2 動的パーティクルを含む",
|
||||
"performance_json_text_displayinfo": "画面情報(フレームレート表示)",
|
||||
"performance_json_text_displayinfo_info": "画面右上にフレームレート、サーバー情報などを表示",
|
||||
"performance_json_text_max_fps": "最大フレームレート",
|
||||
"performance_json_text_max_fps_info": "ゲームの最大フレームレートを調整、0は制限なし",
|
||||
"performance_json_text_display_session": "セッション情報を表示",
|
||||
"performance_json_text_display_session_info": "有効にするとQRコードが画面に表示され、フィードバック時にCIGが関連情報をすばやく特定できるようになります",
|
||||
"performance_json_text_vsync": "垂直同期",
|
||||
"performance_json_text_vsync_info": "画面の裂けを防ぐためにオン、フレームレートを上げるためにオフ",
|
||||
"performance_json_text_motion_blur": "モーションブラー",
|
||||
"performance_json_text_motion_blur_info": "動きの感覚を高めるためにオン、視覚的体験を向上させるためにオフ",
|
||||
"performance_json_text_fov": "視野角FOVを設定",
|
||||
"performance_json_text_ui_animation": "UIフェードインアウトアニメーション",
|
||||
"performance_json_text_custom_parameters": "カスタムパラメータ",
|
||||
"performance_json_text_title_custom": "カスタム",
|
||||
"tools_rsi_launcher_enhance_init_msg1": "ランチャー情報を読み込み中...",
|
||||
"tools_rsi_launcher_enhance_init_msg2": "ネットワークから機能強化データを取得中...",
|
||||
"tools_rsi_launcher_enhance_working_msg1": "パッチを生成中...",
|
||||
"tools_rsi_launcher_enhance_working_msg2": "パッチをインストール中、これはコンピュータのパフォーマンスによって時間がかかります...",
|
||||
"tools_rsi_launcher_enhance_title": "RSIランチャー機能強化",
|
||||
"tools_rsi_launcher_enhance_msg_version": "ランチャー内部バージョン情報:{v0}",
|
||||
"tools_rsi_launcher_enhance_msg_patch_status": "パッチ状態:{v0}",
|
||||
"tools_rsi_launcher_enhance_msg_error": "機能強化データの取得に失敗しました。ネットワークの問題または現在のバージョンがサポートされていない可能性があります",
|
||||
"tools_rsi_launcher_enhance_title_localization": "RSIランチャーローカリゼーション",
|
||||
"tools_rsi_launcher_enhance_subtitle_localization": "RSIランチャーに多言語サポートを追加します。",
|
||||
"tools_rsi_launcher_enhance_title_download_booster": "RSIランチャーダウンロード機能強化",
|
||||
"tools_rsi_launcher_enhance_subtitle_download_booster": "ゲームのダウンロード時に、より多くのスレッドを使用してダウンロード速度を向上させることができます。有効にした後、ランチャー設定でスレッド数を変更してください。",
|
||||
"tools_rsi_launcher_enhance_action_install": "機能強化パッチをインストール",
|
||||
"tools_rsi_launcher_enhance_msg_uninstall": "* 機能強化パッチをアンインストールするには、RSIランチャーを上書きインストールしてください。",
|
||||
"tools_rsi_launcher_enhance_msg_error_launcher_notfound": "RSIランチャーが見つかりません",
|
||||
"tools_rsi_launcher_enhance_msg_error_get_launcher_info_error": "ランチャー情報の読み込みに失敗しました!",
|
||||
"tools_rsi_launcher_enhance_msg_error_get_launcher_info_error_with_args": "ランチャー情報の読み込みに失敗:{v0}",
|
||||
"tools_action_rsi_launcher_enhance_info": "ランチャーローカリゼーション、ダウンロードスレッド強化",
|
||||
"tools_rsi_launcher_enhance_note_title": "RSIランチャー機能強化の使用上の注意",
|
||||
"tools_rsi_launcher_enhance_note_msg": "RSIランチャー機能強化はコミュニティ機能で、お使いのコンピューターで「RSI Launcher」を解凍し、追加の機能強化を加えます。どの機能を使用するかはあなた次第です。\n\n現在、公式(CIG)は多言語操作のみを許可していますが、ランチャーダウンロード機能強化は私たちが有用だと考える追加機能です。cigユーザー契約(https://robertsspaceindustries.com/eula)に違反すると、アカウント禁止などの深刻な結果を招く可能性があり、使用するかどうかはあなた自身の判断によります。私たちは発生する可能性のある結果(ゲームの損傷、アカウント禁止など)に対して責任を負いません。\n\nランチャーの変更内容については、https://github.com/StarCitizenToolBox/RSILauncherEnhanceでオープンソースとして公開しています。必要に応じて確認できます。\n\n何らかの理由でこの機能強化パッチをキャンセルする必要がある場合は、公式ランチャーを直接上書きインストールしてください。",
|
||||
"tools_action_unp4k": "P4Kビューア",
|
||||
"tools_action_unp4k_info": "Star Citizen p4kファイルを解凍",
|
||||
"tools_unp4k_title": "P4Kビューア -> {v0}",
|
||||
"tools_unp4k_view_file": "プレビューするファイルをクリック",
|
||||
"tools_unp4k_msg_unknown_file_type": "不明なファイルタイプ\n{v0}",
|
||||
"home_localization_select_customize_file_ini": "iniファイルを選択してください",
|
||||
"home_localization_select_customize_file": "カスタムローカリゼーションファイルを選択してください",
|
||||
"home_localization_action_select_customize_file": "iniファイルを選択するにはクリック",
|
||||
"home_localization_ptu_advanced_localization_tip_title": "高度なローカリゼーションの使用をお勧めします",
|
||||
"home_localization_ptu_advanced_localization_tip_title_info": "PTU/EPTUなどのテストチャンネルでは、現在のローカリゼーションテキストがゲームと同期していない可能性があります。高度なローカリゼーションを使用することで文字化けの発生を減らすことができます。",
|
||||
"tools_rsi_launcher_enhance_action_fold": "追加機能を折りたたむ",
|
||||
"tools_rsi_launcher_enhance_action_expand": "追加機能を展開",
|
||||
"tools_unp4k_missing_runtime": "ランタイムがありません",
|
||||
"tools_unp4k_missing_runtime_info": "この機能を使用するには.NET8ランタイムをインストールする必要があります。下のボタンをクリックしてダウンロードしてインストールし、インストールが成功したらこのページを再度開いて使用を続行してください。",
|
||||
"tools_unp4k_missing_runtime_action_install": "ランタイムをインストール",
|
||||
"settings_title_general": "一般",
|
||||
"settings_item_dns": "組み込みDNSを使用",
|
||||
"settings_item_dns_info": "有効にすると、一部の地域でのDNS汚染問題を解決する可能性があります",
|
||||
"settings_title_game": "ゲーム",
|
||||
"about_action_btn_faq": "よくある質問",
|
||||
"guide_title_welcome": "ようこそ",
|
||||
"guide_info_check_settings": "以下の設定が正しいことを確認してください。間違いがある場合は、右側のアイコンをクリックして修正してから続行してください",
|
||||
"guide_info_game_download_note": "* ゲームをダウンロード中の場合は、ダウンロードが完了した後にゲームを一度起動し、更新ボタンをクリックしてください。ランチャー機能強化ローカリゼーションのみを使用する場合は、ランチャーパスが正しいことを確認して設定完了をクリックしてください",
|
||||
"guide_action_get_help": "ヘルプを取得",
|
||||
"guide_action_complete_setup": "設定を完了",
|
||||
"guide_dialog_confirm_complete_setup": "設定を完了しますか?",
|
||||
"guide_action_info_no_launcher_path_warning": "ランチャーのインストールパスを選択していません。設定を完了しますか?\n\nガイドページを閉じた後、設定ページで手動操作する必要があります。",
|
||||
"guide_action_info_no_game_path_warning": "ゲームのインストールパスを選択していません。設定を完了しますか?\n\nガイドページを閉じた後、設定ページで手動操作する必要があります。",
|
||||
"setting_toast_select_launcher_exe": "ランチャーのexeファイルを選択:「RSI Launcher.exe」",
|
||||
"setting_toast_select_game_file": "対応するゲームファイルを選択: Bin64/StarCitizen.exe",
|
||||
"input_method_feature_maintenance": "機能はメンテナンス中です、後でもう一度お試しください",
|
||||
"input_method_community_input_method_not_installed": "コミュニティ入力メソッドサポートがインストールされていません",
|
||||
"input_method_install_community_input_method_prompt": "ローカリゼーション管理に行ってインストールしますか?\n\nすでにローカリゼーションをインストールしている場合は、アンインストールして再インストール時にコミュニティ入力メソッドサポートスイッチをオンにしてください。",
|
||||
"input_method_usage_instructions": "使用方法",
|
||||
"input_method_input_text_instructions": "上のテキストボックスにテキストを入力し、下のエンコードされたテキストをゲームのテキストボックスに貼り付け(Ctrl+V)て、チャットチャンネルでゲームがサポートしていない文字を送信できます。",
|
||||
"input_method_input_placeholder": "テキストを入力してください...",
|
||||
"input_method_encoded_text_placeholder": "ここにエンコードされたテキストが表示されます...",
|
||||
"input_method_remote_input_service": "リモート入力サービス:",
|
||||
"input_method_disclaimer": "*この機能は非公開チャンネルでのみ使用することをお勧めします。ユーザーがこの機能を公開チャンネルで使用することを選択した場合、それによって生じる結果(他のプレイヤーによるスパム報告など)はすべてユーザー自身の責任となります。\n*この機能が乱用された場合、機能を無効にする場合があります。",
|
||||
"input_method_experimental_input_method": "コミュニティ入力メソッド(実験的)",
|
||||
"input_method_auto_copy": "自動コピー",
|
||||
"input_method_confirm_enable_remote_input": "リモート入力を有効にしますか?",
|
||||
"input_method_enable_remote_input_instructions": "この機能を有効にすると、スマートフォンからリモートサービスアドレスにアクセスして、ウィンドウの切り替えなしにテキストをすばやく入力でき、ゲームの流れが中断されません。\n\nファイアウォールの通知が表示された場合は、ポップアップを展開し、すべてのネットワークタイプを手動でチェックして許可してください。そうしないと、この機能に正常にアクセスできない場合があります。",
|
||||
"input_method_address_fetch_failed": "アドレスの取得に失敗しました。PCのIPを手動で確認してください",
|
||||
"input_method_text_cannot_be_empty": "テキストを空にすることはできません!",
|
||||
"input_method_send_success": "送信成功!",
|
||||
"input_method_ip_address_not_found": "サービスにアクセスするための適切なIPアドレスが見つかりませんでした。次のアドレスをお試しください(左右に切り替え)",
|
||||
"input_method_scan_qr_code": "モバイルデバイスで次のQRコードをスキャンするか、接続に手動でアクセスしてください",
|
||||
"input_method_service_qr_code": "サービスQRコード",
|
||||
"input_method_confirm_install_advanced_localization": "高度なローカリゼーションをインストールしますか?",
|
||||
"input_method_install_community_input_method_support": "コミュニティ入力メソッドサポートをインストール",
|
||||
"input_method_community_input_method_support_version": "コミュニティ入力メソッドサポート:{v0}",
|
||||
"input_method_online_version_prompt": "この機能のオンラインスタンドアロン版も提供されています。アクセスするにはクリック >",
|
||||
"input_method_support_updated": "コミュニティ入力メソッドサポートが更新されました",
|
||||
"input_method_support_updated_to_version": "コミュニティ入力メソッドサポートが更新されました:{v0}",
|
||||
"input_method_auto_translate": "バイリンガル翻訳:",
|
||||
"input_method_auto_translate_dialog_title": "バイリンガル翻訳を有効にしますか?",
|
||||
"input_method_auto_translate_dialog_title_content": "有効にすると、Google翻訳サービスを使用して入力内容に英語の副本を追加します。応答が遅延する可能性があります。機能に異常がある場合は無効にしてください。\n\nテキストはGoogleサーバーに転送されます。Googleのプライバシーポリシーを参照してください。",
|
||||
"support_dev_thanks_message": "SCToolboxをご利用いただきありがとうございます。私は開発者のxkeyCです。\nSCToolboxはオープンソースにコミットし、プレイヤーに無料のサービスを提供することに努めています。無償のサービスは挑戦的な作業です。飲み物代を贈っていただければ大変感謝します。\n寄付された資金はサーバー費用、新機能の開発、そしてソフトウェアメンテナンスのモチベーション向上に使われます。",
|
||||
"support_dev_referral_code_message": "まだゲームに登録していないか招待コードを入力していない場合は、私のコードを検討してください:STAR-3YXS-SWTC、ここまで読んでいただきありがとうございます",
|
||||
"support_dev_title": "開発者をサポート",
|
||||
"support_dev_github_star_message": "GitHubで私のプロジェクトにスターを付けることもできます",
|
||||
"support_dev_github_star_button": "プロジェクトにスター",
|
||||
"support_dev_in_game_currency_title": "ゲーム内通貨",
|
||||
"support_dev_in_game_id": "ゲームID: xkeyC",
|
||||
"support_dev_in_game_id_copied": "ゲームIDがコピーされました",
|
||||
"support_dev_copy_button": "コピー",
|
||||
"support_dev_in_game_currency_message": "ゲーム内でaUECを送信してサポートすることができます。これは限られた時間の中で私がより良いゲーム体験を得るのに役立ちます",
|
||||
"support_dev_alipay": "Alipay",
|
||||
"support_dev_wechat": "WeChat",
|
||||
"support_dev_donation_disclaimer": "* 注意:寄付は無償の贈与であり、ソフトウェア体験において追加の特典を得ることはありません。",
|
||||
"support_dev_back_button": "戻る",
|
||||
"support_dev_scroll_hint": "下にスクロールしてさらに表示",
|
||||
"log_analyzer_filter_all": "すべて",
|
||||
"log_analyzer_filter_basic_info": "基本情報",
|
||||
"log_analyzer_filter_account_related": "アカウント関連",
|
||||
"log_analyzer_filter_fatal_collision": "致命的な衝突",
|
||||
"log_analyzer_filter_vehicle_damaged": "ビークル損傷",
|
||||
"log_analyzer_filter_character_death": "キャラクター死亡",
|
||||
"log_analyzer_filter_statistics": "統計情報",
|
||||
"log_analyzer_filter_game_crash": "ゲームクラッシュ",
|
||||
"log_analyzer_filter_local_inventory": "ローカルインベントリ",
|
||||
"log_analyzer_no_log_file": "logファイルが見つかりません",
|
||||
"log_analyzer_one_click_diagnosis_header": "----- SCToolbox ワンクリック診断 -----",
|
||||
"log_analyzer_details_info": "詳細情報:{v0}",
|
||||
"log_analyzer_no_crash_detected": "ゲームクラッシュ情報は検出されませんでした",
|
||||
"log_analyzer_game_crash": "ゲームクラッシュ ",
|
||||
"log_analyzer_kill_summary": "キル概要",
|
||||
"log_analyzer_kill_death_suicide_count": "キル数:{v0} デス数:{v1} 自殺回数:{v2} \n機体破壊(ソフトデス):{v3} 機体破壊(解体):{v4}",
|
||||
"log_analyzer_play_time": "プレイ時間",
|
||||
"log_analyzer_play_time_format": "{v0}時間{v1}分{v2}秒",
|
||||
"log_analyzer_game_start": "ゲーム起動",
|
||||
"log_analyzer_game_loading": "ゲーム読み込み",
|
||||
"log_analyzer_mode_loading_time": "モード:{v0} 所要時間:{v1}秒",
|
||||
"log_analyzer_game_close": "ゲーム終了",
|
||||
"log_analyzer_collision_details": "エリア:{v0} プレイヤー操縦:{v1} 衝突エンティティ:{v2} \n衝突ビークル:{v3} 衝突距離:{v4} ",
|
||||
"log_analyzer_soft_death": "ソフト死亡",
|
||||
"log_analyzer_disintegration": "崩壊",
|
||||
"log_analyzer_vehicle_damage_details": "ビークルモデル:{v0} \nエリア:{v1} \n損傷レベル:{v2} ({v3}) 責任者:{v4}",
|
||||
"log_analyzer_death_details": "被害者ID:{v0} 死因:{v1} \n殺害者ID:{v2} \nエリア:{v3}",
|
||||
"log_analyzer_player_login": "プレイヤー {v0} ログイン中...",
|
||||
"log_analyzer_view_local_inventory": "ローカルインベントリを表示",
|
||||
"log_analyzer_player_location": "プレイヤーID:{v0} 位置:{v1}",
|
||||
"log_analyzer_game_installation_path": "ゲームインストールパス",
|
||||
"log_analyzer_select_game_path": "ゲームインストールパスを選択してください",
|
||||
"log_analyzer_search_placeholder": "キーワードを入力して内容を検索",
|
||||
"log_analyzer_title": "logアナライザ",
|
||||
"log_analyzer_description": "プレイ記録を分析(ログイン、死亡、キルなどの情報)",
|
||||
"log_analyzer_window_title": "SCToolbox: logアナライザ"
|
||||
}
|
897
lib/l10n/intl_ru.arb
Normal file
897
lib/l10n/intl_ru.arb
Normal file
@ -0,0 +1,897 @@
|
||||
{
|
||||
"@@locale": "ru",
|
||||
"@@auto_translate_locale": "ru",
|
||||
"app_language_name": "Русский",
|
||||
"@app_language_name": {},
|
||||
"app_language_code": "ru",
|
||||
"app_index_version_info": "SCToolbox V{v0} {v1}",
|
||||
"@app_index_version_info": {},
|
||||
"app_shortcut_name": "SCToolboxDEV.lnk",
|
||||
"@app_shortcut_name": {},
|
||||
"about_check_update": "Проверить обновления",
|
||||
"@about_check_update": {},
|
||||
"about_app_description": "Не только локализация!\n\nSCToolbox — ваш надёжный помощник в исследовании вселенной. Мы стремимся решать распространённые проблемы игры и предоставлять удобные инструменты для локализации сообщества, оптимизации производительности, перевода популярных сайтов и многого другого.",
|
||||
"@about_app_description": {},
|
||||
"about_online_feedback": "Обратная связь онлайн",
|
||||
"@about_online_feedback": {},
|
||||
"about_action_qq_group": "QQ группа: 940696487",
|
||||
"@about_action_qq_group": {},
|
||||
"about_action_email": "Почта: xkeyc@qq.com",
|
||||
"@about_action_email": {},
|
||||
"about_action_open_source": "Открытый исходный код",
|
||||
"@about_action_open_source": {},
|
||||
"about_disclaimer": "Это неофициальный инструмент для Star Citizen, не связанный с группой компаний Cloud Imperium. Весь контент, не созданный хостом или пользователями этого приложения, является собственностью их соответствующих владельцев.\nStar Citizen®, Roberts Space Industries® и Cloud Imperium® являются зарегистрированными товарными знаками Cloud Imperium Rights LLC.",
|
||||
"@about_disclaimer": {},
|
||||
"about_analytics_launch": "Запуск",
|
||||
"@about_analytics_launch": {},
|
||||
"about_analytics_launch_game": "Запуск игры",
|
||||
"@about_analytics_launch_game": {},
|
||||
"about_analytics_total_users": "Всего пользователей",
|
||||
"@about_analytics_total_users": {},
|
||||
"about_analytics_install_translation": "Установка локализации",
|
||||
"@about_analytics_install_translation": {},
|
||||
"about_analytics_performance_optimization": "Оптимизация производительности",
|
||||
"@about_analytics_performance_optimization": {},
|
||||
"about_analytics_p4k_redirection": "P4K перенаправление",
|
||||
"@about_analytics_p4k_redirection": {},
|
||||
"about_analytics_units_user": "чел.",
|
||||
"@about_analytics_units_user": {},
|
||||
"about_analytics_units_times": "раз",
|
||||
"@about_analytics_units_times": {},
|
||||
"about_info_latest_version": "У вас уже установлена последняя версия!",
|
||||
"@about_info_latest_version": {},
|
||||
"home_holiday_countdown": "Обратный отсчет до праздников",
|
||||
"@home_holiday_countdown": {},
|
||||
"home_holiday_countdown_disclaimer": "* Даты праздников собираются и поддерживаются вручную и могут содержать ошибки. Обратная связь приветствуется!",
|
||||
"@home_holiday_countdown_disclaimer": {},
|
||||
"home_action_one_click_launch": "Запуск в один клик",
|
||||
"@home_action_one_click_launch": {},
|
||||
"home_title_logging_in": "Вход в систему...",
|
||||
"@home_title_logging_in": {},
|
||||
"home_login_title_welcome_back": "С возвращением!",
|
||||
"@home_login_title_welcome_back": {},
|
||||
"home_login_title_launching_game": "Запускаем игру...",
|
||||
"@home_login_title_launching_game": {},
|
||||
"home_action_login_rsi_account": "Войти в аккаунт RSI",
|
||||
"@home_action_login_rsi_account": {},
|
||||
"home_login_info_game_version_outdated": "Версия игры устарела",
|
||||
"@home_login_info_game_version_outdated": {},
|
||||
"home_login_info_rsi_server_report": "Сервер RSI сообщает версию: {v1}\n\nЛокальная версия: {v2}\n\nРекомендуется обновить игру через RSI Launcher!",
|
||||
"@home_login_info_rsi_server_report": {},
|
||||
"home_login_info_action_ignore": "Игнорировать",
|
||||
"@home_login_info_action_ignore": {},
|
||||
"home_login_action_title_box_one_click_launch": "Запуск в один клик",
|
||||
"@home_login_action_title_box_one_click_launch": {},
|
||||
"home_login_info_one_click_launch_description": "Эта функция помогает вам удобнее запускать игру.\n\nДля обеспечения безопасности аккаунта эта функция использует локализованный браузер для сохранения состояния входа, и не сохраняет информацию о вашем пароле (если вы не включили функцию автозаполнения).\n\nПри использовании этой функции для входа в аккаунт убедитесь, что вы скачали SCToolbox из надежного источника.",
|
||||
"@home_login_info_one_click_launch_description": {},
|
||||
"home_login_action_title_need_webview2_runtime": "Требуется установить WebView2 Runtime",
|
||||
"@home_login_action_title_need_webview2_runtime": {},
|
||||
"action_close": "Закрыть",
|
||||
"@action_close": {},
|
||||
"downloader_speed_limit_settings": "Настройки ограничения скорости",
|
||||
"@downloader_speed_limit_settings": {},
|
||||
"downloader_action_pause_all": "Приостановить все",
|
||||
"@downloader_action_pause_all": {},
|
||||
"downloader_action_resume_all": "Возобновить все",
|
||||
"@downloader_action_resume_all": {},
|
||||
"downloader_action_cancel_all": "Отменить все",
|
||||
"@downloader_action_cancel_all": {},
|
||||
"downloader_info_no_download_tasks": "Нет задач загрузки",
|
||||
"@downloader_info_no_download_tasks": {},
|
||||
"downloader_info_total_size": "Общий размер: {v1}",
|
||||
"@downloader_info_total_size": {},
|
||||
"downloader_info_verifying": "Проверка... ({v2})",
|
||||
"@downloader_info_verifying": {},
|
||||
"downloader_info_downloading": "Загрузка... ({v0}%)",
|
||||
"@downloader_info_downloading": {},
|
||||
"downloader_info_status": "Статус: {v0}",
|
||||
"@downloader_info_status": {},
|
||||
"downloader_info_uploaded": "Отдано: {v0}",
|
||||
"@downloader_info_uploaded": {},
|
||||
"downloader_info_downloaded": "Загружено: {v0}",
|
||||
"@downloader_info_downloaded": {},
|
||||
"downloader_action_options": "Опции",
|
||||
"@downloader_action_options": {},
|
||||
"downloader_action_continue_download": "Продолжить загрузку",
|
||||
"@downloader_action_continue_download": {},
|
||||
"downloader_action_pause_download": "Приостановить загрузку",
|
||||
"@downloader_action_pause_download": {},
|
||||
"downloader_action_cancel_download": "Отменить загрузку",
|
||||
"@downloader_action_cancel_download": {},
|
||||
"action_open_folder": "Открыть папку",
|
||||
"@action_open_folder": {},
|
||||
"downloader_info_download_upload_speed": "Загрузка: {v0}/с Отдача: {v1}/с",
|
||||
"@downloader_info_download_upload_speed": {},
|
||||
"downloader_info_downloading_status": "Загрузка...",
|
||||
"@downloader_info_downloading_status": {},
|
||||
"downloader_info_waiting": "Ожидание",
|
||||
"@downloader_info_waiting": {},
|
||||
"downloader_info_paused": "Приостановлено",
|
||||
"@downloader_info_paused": {},
|
||||
"downloader_info_download_failed": "Ошибка загрузки",
|
||||
"@downloader_info_download_failed": {},
|
||||
"downloader_info_download_completed": "Загрузка завершена",
|
||||
"@downloader_info_download_completed": {},
|
||||
"downloader_info_deleted": "Удалено",
|
||||
"@downloader_info_deleted": {},
|
||||
"downloader_title_downloading": "Загрузка",
|
||||
"@downloader_title_downloading": {},
|
||||
"downloader_title_ended": "Завершено",
|
||||
"@downloader_title_ended": {},
|
||||
"downloader_action_confirm_cancel_all_tasks": "Подтвердите отмену всех задач?",
|
||||
"@downloader_action_confirm_cancel_all_tasks": {},
|
||||
"downloader_info_manual_file_deletion_note": "Если файл больше не нужен, возможно, вам потребуется удалить загруженный файл вручную.",
|
||||
"@downloader_info_manual_file_deletion_note": {},
|
||||
"downloader_action_confirm_cancel_download": "Подтвердите отмену загрузки?",
|
||||
"@downloader_action_confirm_cancel_download": {},
|
||||
"downloader_info_p2p_network_note": "SCToolbox использует p2p сеть для ускорения загрузки файлов. Если у вас ограниченный трафик, вы можете установить ограничение скорости отдачи до 1 байта.",
|
||||
"@downloader_info_p2p_network_note": {},
|
||||
"downloader_info_download_unit_input_prompt": "Пожалуйста, введите единицу скорости загрузки, например: 1, 100k, 10m. Оставьте поле пустым или введите 0 для снятия ограничения.",
|
||||
"@downloader_info_download_unit_input_prompt": {},
|
||||
"downloader_input_upload_speed_limit": "Ограничение отдачи:",
|
||||
"@downloader_input_upload_speed_limit": {},
|
||||
"downloader_input_download_speed_limit": "Ограничение загрузки:",
|
||||
"@downloader_input_download_speed_limit": {},
|
||||
"downloader_input_info_p2p_upload_note": "* P2P отдача происходит только во время загрузки файла и отключается после завершения. Если вы хотите участвовать в раздаче, пожалуйста, свяжитесь с нами через страницу 'О программе'.",
|
||||
"@downloader_input_info_p2p_upload_note": {},
|
||||
"doctor_title_one_click_diagnosis": "Быстрая диагностика -> {v0}",
|
||||
"@doctor_title_one_click_diagnosis": {},
|
||||
"doctor_action_rsi_launcher_log": "Лог RSI Launcher",
|
||||
"@doctor_action_rsi_launcher_log": {},
|
||||
"doctor_action_game_run_log": "Лог запуска игры",
|
||||
"@doctor_action_game_run_log": {},
|
||||
"doctor_info_scan_complete_no_issues": "Сканирование завершено, проблем не обнаружено!",
|
||||
"@doctor_info_scan_complete_no_issues": {},
|
||||
"doctor_info_processing": "Обработка...",
|
||||
"@doctor_info_processing": {},
|
||||
"doctor_info_game_rescue_service_note": "Вы собираетесь перейти к сервису спасения игры, предоставляемому Центром глубокого космического лечения (QQ группа: 536454632), который в основном решает проблемы с неудачной установкой и частыми вылетами. Не присоединяйтесь к группе для вопросов по игровому процессу.",
|
||||
"@doctor_info_game_rescue_service_note": {},
|
||||
"doctor_info_need_help": "Нужна помощь? Нажмите, чтобы присоединиться к группе для бесплатной поддержки!",
|
||||
"@doctor_info_need_help": {},
|
||||
"doctor_info_tool_check_result_note": "Примечание: Результаты проверки этим инструментом предоставляются только для справки. Если вы не понимаете следующие операции, пожалуйста, предоставьте снимок экрана опытным игрокам!",
|
||||
"@doctor_info_tool_check_result_note": {},
|
||||
"doctor_info_result_unsupported_os": "Неподдерживаемая операционная система, игра может не запуститься",
|
||||
"@doctor_info_result_unsupported_os": {},
|
||||
"doctor_info_result_upgrade_system": "Пожалуйста, обновите вашу систему ({v0})",
|
||||
"@doctor_info_result_upgrade_system": {},
|
||||
"doctor_info_result_missing_live_folder": "В директории установки отсутствует папка LIVE, что может привести к сбою установки",
|
||||
"@doctor_info_result_missing_live_folder": {},
|
||||
"doctor_info_result_create_live_folder": "Нажмите исправить, чтобы создать папку LIVE, затем повторите попытку установки. ({v0})",
|
||||
"@doctor_info_result_create_live_folder": {},
|
||||
"doctor_info_result_incompatible_nvme_device": "Новое устройство NVME, временно несовместимое с RSI Launcher, может привести к сбою установки",
|
||||
"@doctor_info_result_incompatible_nvme_device": {},
|
||||
"doctor_info_result_add_registry_value": "Добавление значения ForcedPhysicalSectorSizeInBytes в реестр для эмуляции старого устройства. Раздел диска ({v0})",
|
||||
"@doctor_info_result_add_registry_value": {},
|
||||
"doctor_info_result_missing_easyanticheat_files": "Отсутствуют файлы EasyAntiCheat",
|
||||
"@doctor_info_result_missing_easyanticheat_files": {},
|
||||
"doctor_info_result_verify_files_with_rsi_launcher": "Файлы EasyAntiCheat не найдены в папке LIVE или файлы неполные. Пожалуйста, используйте RSI Launcher для проверки файлов",
|
||||
"@doctor_info_result_verify_files_with_rsi_launcher": {},
|
||||
"doctor_info_result_easyanticheat_not_installed": "EasyAntiCheat не установлен или некорректно завершен",
|
||||
"@doctor_info_result_easyanticheat_not_installed": {},
|
||||
"doctor_info_result_install_easyanticheat": "EasyAntiCheat не установлен, нажмите исправить для автоматической установки. (Эта проблема будет появляться до нормального запуска и завершения игры. Если игра вылетает по другим причинам, вы можете игнорировать этот пункт.)",
|
||||
"@doctor_info_result_install_easyanticheat": {},
|
||||
"doctor_info_result_chinese_username": "Имя пользователя на китайском!",
|
||||
"@doctor_info_result_chinese_username": {},
|
||||
"doctor_info_result_chinese_username_error": "Имя пользователя на китайском может вызвать ошибки запуска/установки игры! Нажмите кнопку исправить, чтобы увидеть руководство по изменению!",
|
||||
"@doctor_info_result_chinese_username_error": {},
|
||||
"doctor_info_result_chinese_install_path": "Путь установки на китайском!",
|
||||
"@doctor_info_result_chinese_install_path": {},
|
||||
"doctor_info_result_chinese_install_path_error": "Путь установки на китайском! Это может вызвать ошибки запуска/установки игры! ({v0}), пожалуйста, измените путь установки в RSI Launcher.",
|
||||
"@doctor_info_result_chinese_install_path_error": {},
|
||||
"doctor_info_result_low_physical_memory": "Недостаточно физической памяти",
|
||||
"@doctor_info_result_low_physical_memory": {},
|
||||
"doctor_info_result_memory_requirement": "Вам нужно как минимум 16 ГБ физической памяти (RAM) для запуска этой игры. (Текущий размер: {v0})",
|
||||
"@doctor_info_result_memory_requirement": {},
|
||||
"doctor_info_result_fix_suggestion": "Предложение по исправлению: {v0}",
|
||||
"@doctor_info_result_fix_suggestion": {},
|
||||
"doctor_info_result_no_solution": "Решение пока отсутствует, пожалуйста, сделайте снимок экрана и обратитесь за помощью",
|
||||
"@doctor_info_result_no_solution": {},
|
||||
"doctor_info_action_fix": "Исправить",
|
||||
"@doctor_info_action_fix": {},
|
||||
"doctor_action_view_solution": "Посмотреть решение",
|
||||
"@doctor_action_view_solution": {},
|
||||
"doctor_tip_title_select_game_directory": "Пожалуйста, выберите директорию установки игры на главной странице.",
|
||||
"@doctor_tip_title_select_game_directory": {},
|
||||
"doctor_action_result_try_latest_windows": "Если ваше оборудование соответствует требованиям, попробуйте установить последнюю версию Windows.",
|
||||
"@doctor_action_result_try_latest_windows": {},
|
||||
"doctor_action_result_create_folder_success": "Папка успешно создана, пожалуйста, попробуйте продолжить загрузку игры!",
|
||||
"@doctor_action_result_create_folder_success": {},
|
||||
"doctor_action_result_create_folder_fail": "Не удалось создать папку, попробуйте создать её вручную.\nПуть: {v0}\nОшибка: {v1}",
|
||||
"@doctor_action_result_create_folder_fail": {},
|
||||
"doctor_action_result_fix_success": "Исправление выполнено успешно, пожалуйста, попробуйте перезагрузить компьютер и продолжить установку игры! Если изменение реестра вызвало проблемы совместимости с другими программами, используйте очистку реестра NVME в разделе Инструменты.",
|
||||
"@doctor_action_result_fix_success": {},
|
||||
"doctor_action_result_fix_fail": "Исправление не удалось, {v0}",
|
||||
"@doctor_action_result_fix_fail": {},
|
||||
"doctor_action_result_game_start_success": "Исправлено успешно, попробуйте запустить игру. (Если проблема не устраняется, используйте 'Переустановить EAC' в наборе инструментов.)",
|
||||
"@doctor_action_result_game_start_success": {},
|
||||
"doctor_action_result_redirect_warning": "Сейчас произойдет перенаправление, руководство взято из Интернета, действуйте с осторожностью...",
|
||||
"@doctor_action_result_redirect_warning": {},
|
||||
"doctor_action_result_issue_not_supported": "Эта проблема в настоящее время не поддерживает автоматическое исправление, пожалуйста, предоставьте снимок экрана для получения помощи",
|
||||
"@doctor_action_result_issue_not_supported": {},
|
||||
"doctor_action_analyzing": "Анализ...",
|
||||
"@doctor_action_analyzing": {},
|
||||
"doctor_action_result_analysis_no_issue": "Анализ завершен, проблем не обнаружено",
|
||||
"@doctor_action_result_analysis_no_issue": {},
|
||||
"doctor_action_result_analysis_issues_found": "Анализ завершен, обнаружено {v0} проблем",
|
||||
"@doctor_action_result_analysis_issues_found": {},
|
||||
"doctor_action_result_toast_scan_no_issue": "Сканирование завершено, проблем не обнаружено. Если установка по-прежнему не удается, попробуйте использовать режим администратора для RSI Launcher в разделе инструментов.",
|
||||
"@doctor_action_result_toast_scan_no_issue": {},
|
||||
"doctor_action_tip_checking_game_log": "Проверка: Game.log",
|
||||
"@doctor_action_tip_checking_game_log": {},
|
||||
"doctor_action_info_game_abnormal_exit": "Аварийное завершение игры: {v0}",
|
||||
"@doctor_action_info_game_abnormal_exit": {},
|
||||
"doctor_action_info_game_abnormal_exit_unknown": "Аварийное завершение игры: неизвестная ошибка",
|
||||
"@doctor_action_info_game_abnormal_exit_unknown": {},
|
||||
"doctor_action_info_info_feedback": "инфо:{v0}, пожалуйста, нажмите в правом нижнем углу, чтобы присоединиться к группе для обратной связи.",
|
||||
"@doctor_action_info_info_feedback": {},
|
||||
"doctor_action_info_checking_eac": "Проверка: EAC",
|
||||
"@doctor_action_info_checking_eac": {},
|
||||
"doctor_action_info_checking_runtime": "Проверка: среды выполнения",
|
||||
"@doctor_action_info_checking_runtime": {},
|
||||
"doctor_action_result_info_unsupported_os": "Неподдерживаемая операционная система: {v0}",
|
||||
"@doctor_action_result_info_unsupported_os": {},
|
||||
"doctor_action_info_checking_install_info": "Проверка: информации об установке",
|
||||
"@doctor_action_info_checking_install_info": {},
|
||||
"doctor_action_view_details": "Подробнее",
|
||||
"@doctor_action_view_details": {},
|
||||
"home_install_location": "Место установки:",
|
||||
"@home_install_location": {},
|
||||
"home_not_installed_or_failed": "Не установлено или установка не удалась",
|
||||
"@home_not_installed_or_failed": {},
|
||||
"home_action_star_citizen_website_localization": "Локализация сайта Star Citizen",
|
||||
"@home_action_star_citizen_website_localization": {},
|
||||
"home_action_info_roberts_space_industries_origin": "Roberts Space Industries, начало всего",
|
||||
"@home_action_info_roberts_space_industries_origin": {},
|
||||
"home_action_uex_localization": "Локализация UEX",
|
||||
"@home_action_uex_localization": {},
|
||||
"home_action_info_mining_refining_trade_calculator": "Калькулятор добычи, очистки, торговли, цены, информация о кораблях",
|
||||
"@home_action_info_mining_refining_trade_calculator": {},
|
||||
"home_action_dps_calculator_localization": "Локализация DPS калькулятора",
|
||||
"@home_action_dps_calculator_localization": {},
|
||||
"home_action_info_ship_upgrade_damage_value_query": "Онлайн-модификация кораблей, запрос значений урона и мест покупки компонентов",
|
||||
"@home_action_info_ship_upgrade_damage_value_query": {},
|
||||
"home_action_external_browser_extension": "Расширение внешнего браузера:",
|
||||
"@home_action_external_browser_extension": {},
|
||||
"home_action_one_click_diagnosis": "Быстрая диагностика",
|
||||
"@home_action_one_click_diagnosis": {},
|
||||
"home_action_info_one_click_diagnosis_star_citizen": "Быстрая диагностика распространенных проблем Star Citizen",
|
||||
"@home_action_info_one_click_diagnosis_star_citizen": {},
|
||||
"home_action_localization_management": "Управление локализацией",
|
||||
"@home_action_localization_management": {},
|
||||
"home_action_info_quick_install_localization_resources": "Быстрая установка ресурсов локализации",
|
||||
"@home_action_info_quick_install_localization_resources": {},
|
||||
"home_action_performance_optimization": "Оптимизация производительности",
|
||||
"@home_action_performance_optimization": {},
|
||||
"home_action_info_engine_config_optimization": "Настройка конфигурационных файлов движка для оптимизации производительности",
|
||||
"@home_action_info_engine_config_optimization": {},
|
||||
"home_action_rsi_status_platform": "Платформа",
|
||||
"@home_action_rsi_status_platform": {},
|
||||
"home_action_rsi_status_persistent_universe": "Постоянная вселенная",
|
||||
"@home_action_rsi_status_persistent_universe": {},
|
||||
"home_action_rsi_status_electronic_access": "Электронный доступ",
|
||||
"@home_action_rsi_status_electronic_access": {},
|
||||
"home_action_rsi_status_arena_commander": "Arena Commander",
|
||||
"@home_action_rsi_status_arena_commander": {},
|
||||
"home_action_rsi_status_rsi_server_status": "Статус сервера RSI",
|
||||
"@home_action_rsi_status_rsi_server_status": {},
|
||||
"home_action_rsi_status_status": "Статус:",
|
||||
"@home_action_rsi_status_status": {},
|
||||
"home_announcement_details": "Подробности объявления",
|
||||
"@home_announcement_details": {},
|
||||
"home_action_info_valid_install_location_required": "Для этой функции требуется действительное место установки\n\nЕсли игра еще не загружена полностью, дождитесь завершения загрузки, прежде чем использовать эту функцию.\n\nЕсли загрузка игры завершена, но она не распознается, запустите игру один раз и снова откройте SCToolbox, или установите место установки вручную в настройках.",
|
||||
"@home_action_info_valid_install_location_required": {},
|
||||
"home_action_info_scanning": "Сканирование...",
|
||||
"@home_action_info_scanning": {},
|
||||
"home_action_info_scan_complete_valid_directories_found": "Сканирование завершено, найдено {v0} действительных директорий установки",
|
||||
"@home_action_info_scan_complete_valid_directories_found": {},
|
||||
"home_action_info_log_file_parse_fail": "Ошибка анализа лог-файла!",
|
||||
"@home_action_info_log_file_parse_fail": {},
|
||||
"home_action_title_star_citizen_website_localization": "Локализация сайта Star Citizen",
|
||||
"@home_action_title_star_citizen_website_localization": {},
|
||||
"home_action_info_web_localization_plugin_disclaimer": "Этот плагин предназначен только для общего просмотра и не несёт ответственности за любые проблемы, вызванные его использованием! Перед выполнением операций с аккаунтом убедитесь, что вы понимаете оригинальное содержание сайта!\n\n\nПри использовании этой функции для входа в аккаунт убедитесь, что вы скачали SCToolbox из надёжного источника.",
|
||||
"@home_action_info_web_localization_plugin_disclaimer": {},
|
||||
"home_action_info_initializing_resources": "Инициализация ресурсов локализации...",
|
||||
"@home_action_info_initializing_resources": {},
|
||||
"home_action_info_initialization_failed": "Ошибка инициализации ресурсов веб-локализации! {v0}",
|
||||
"@home_action_info_initialization_failed": {},
|
||||
"home_title_app_name": "SCToolbox",
|
||||
"@home_title_app_name": {},
|
||||
"home_localization_new_version_available": "Доступна новая версия локализации!",
|
||||
"@home_localization_new_version_available": {},
|
||||
"home_localization_new_version_installed": "Доступна новая версия локализации, установленной {v0}!",
|
||||
"@home_localization_new_version_installed": {},
|
||||
"home_info_valid_installation_required": "Для этой функции требуется действительное место установки",
|
||||
"@home_info_valid_installation_required": {},
|
||||
"home_info_one_click_launch_warning": "Предупреждение о функции запуска в один клик",
|
||||
"@home_info_one_click_launch_warning": {},
|
||||
"home_info_account_security_warning": "Для обеспечения безопасности аккаунта функция запуска в один клик отключена в версии для разработчиков. Мы предоставим эту функцию в версии из Microsoft Store.\n\nMicrosoft Store обеспечивает надежную загрузку и цифровую подпись, что эффективно защищает от несанкционированного доступа к программному обеспечению.\n\nПодсказка: Вы можете использовать локализацию без запуска игры через SCToolbox.",
|
||||
"@home_info_account_security_warning": {},
|
||||
"home_action_install_microsoft_store_version": "Установить версию из Microsoft Store",
|
||||
"@home_action_install_microsoft_store_version": {},
|
||||
"home_action_cancel": "Отмена",
|
||||
"@home_action_cancel": {},
|
||||
"home_action_info_abnormal_game_exit": "Игра завершилась ненормально\nexitCode={v0}\nstdout={v1}\nstderr={v2}\n\nДиагностическая информация: {v3}\n{v4}",
|
||||
"@home_action_info_abnormal_game_exit": {},
|
||||
"home_action_info_unknown_error": "Неизвестная ошибка, пожалуйста, используйте быструю диагностику и присоединитесь к группе для обратной связи.",
|
||||
"@home_action_info_unknown_error": {},
|
||||
"home_action_info_check_web_link": "Пожалуйста, проверьте появившуюся веб-ссылку для получения подробной информации.",
|
||||
"@home_action_info_check_web_link": {},
|
||||
"home_action_info_game_built_in": "Встроено в игру",
|
||||
"@home_action_info_game_built_in": {},
|
||||
"home_action_info_warning": "Предупреждение",
|
||||
"@home_action_info_warning": {},
|
||||
"localization_info_machine_translation_warning": "Вы используете встроенные в игру тексты. Официальные тексты в настоящее время переведены машиной (по состоянию на 3.21.0), рекомендуется установить перевод сообщества ниже.",
|
||||
"@localization_info_machine_translation_warning": {},
|
||||
"localization_info_translation": "Локализация игры",
|
||||
"@localization_info_translation": {},
|
||||
"localization_info_enabled": "Включено ({v0}):",
|
||||
"@localization_info_enabled": {},
|
||||
"localization_info_installed_version": "Установленная версия: {v0}",
|
||||
"@localization_info_installed_version": {},
|
||||
"localization_action_translation_feedback": "Отзыв о локализации",
|
||||
"@localization_action_translation_feedback": {},
|
||||
"localization_action_uninstall_translation": "Удалить локализацию",
|
||||
"@localization_action_uninstall_translation": {},
|
||||
"localization_info_note": "Примечание:",
|
||||
"@localization_info_note": {},
|
||||
"localization_info_community_translation": "Локализация сообщества",
|
||||
"@localization_info_community_translation": {},
|
||||
"localization_info_no_translation_available": "Для этого языка/версии пока нет доступной локализации, пожалуйста, ожидайте!",
|
||||
"@localization_info_no_translation_available": {},
|
||||
"localization_action_install": "Установить",
|
||||
"@localization_action_install": {},
|
||||
"localization_info_version_number": "Номер версии: {v0}",
|
||||
"@localization_info_version_number": {},
|
||||
"localization_info_channel": "Канал: {v0}",
|
||||
"@localization_info_channel": {},
|
||||
"localization_info_update_time": "Время обновления: {v0}",
|
||||
"@localization_info_update_time": {},
|
||||
"localization_info_installed": "Установлено",
|
||||
"@localization_info_installed": {},
|
||||
"localization_info_unavailable": "Недоступно",
|
||||
"@localization_info_unavailable": {},
|
||||
"localization_info_language": "Язык: ",
|
||||
"@localization_info_language": {},
|
||||
"localization_info_remove_incompatible_translation_params": "Удалить несовместимые параметры локализации",
|
||||
"@localization_info_remove_incompatible_translation_params": {},
|
||||
"localization_info_incompatible_translation_params_warning": "USER.cfg содержит несовместимые параметры локализации, это может быть остаток от предыдущих файлов локализации.\n\nЭто может привести к неработающей локализации или искаженному тексту, нажмите подтвердить, чтобы удалить эти параметры (это не повлияет на другие настройки).",
|
||||
"@localization_info_incompatible_translation_params_warning": {},
|
||||
"localization_info_corrupted_file": "Файл поврежден, пожалуйста, загрузите его заново",
|
||||
"@localization_info_corrupted_file": {},
|
||||
"localization_info_installation_error": "Ошибка установки!\n\n{v0}",
|
||||
"@localization_info_installation_error": {},
|
||||
"localization_info_custom_files": "Пользовательские файлы",
|
||||
"@localization_info_custom_files": {},
|
||||
"performance_info_graphic_optimization_hint": "Подсказка по оптимизации графики",
|
||||
"@performance_info_graphic_optimization_hint": {},
|
||||
"performance_info_graphic_optimization_warning": "Эта функция очень помогает при оптимизации узких мест видеокарты, но может иметь обратный эффект при узких местах CPU. Если у вас мощная видеокарта, попробуйте использовать более высокое качество графики для повышения утилизации видеокарты.",
|
||||
"@performance_info_graphic_optimization_warning": {},
|
||||
"performance_info_current_status": "Текущий статус: {v0}",
|
||||
"@performance_info_current_status": {},
|
||||
"performance_info_applied": "Применено",
|
||||
"@performance_info_applied": {},
|
||||
"performance_info_not_applied": "Не применено",
|
||||
"@performance_info_not_applied": {},
|
||||
"performance_action_preset": "Предустановка:",
|
||||
"@performance_action_preset": {},
|
||||
"performance_action_low": "Низкая",
|
||||
"@performance_action_low": {},
|
||||
"performance_action_medium": "Средняя",
|
||||
"@performance_action_medium": {},
|
||||
"performance_action_high": "Высокая",
|
||||
"@performance_action_high": {},
|
||||
"performance_action_super": "Супер",
|
||||
"@performance_action_super": {},
|
||||
"performance_action_info_preset_only_changes_graphics": "(Предустановки изменяют только настройки графики)",
|
||||
"@performance_action_info_preset_only_changes_graphics": {},
|
||||
"performance_action_reset_to_default": "Восстановить по умолчанию",
|
||||
"@performance_action_reset_to_default": {},
|
||||
"performance_action_apply": "Применить",
|
||||
"@performance_action_apply": {},
|
||||
"performance_action_apply_and_clear_shaders": "Применить и очистить шейдеры (рекомендуется)",
|
||||
"@performance_action_apply_and_clear_shaders": {},
|
||||
"performance_title_performance_optimization": "Оптимизация производительности -> {v0}",
|
||||
"@performance_title_performance_optimization": {},
|
||||
"performance_action_custom_parameters_input": "Здесь вы можете ввести собственные параметры, не включенные в SCToolbox. Пример конфигурации:\n\nr_displayinfo=0\nr_VSync=0",
|
||||
"@performance_action_custom_parameters_input": {},
|
||||
"performance_info_min_max_values": "{v0} Мин.: {v1} / Макс.: {v2}",
|
||||
"@performance_info_min_max_values": {},
|
||||
"performance_info_graphics": "Графика",
|
||||
"@performance_info_graphics": {},
|
||||
"performance_info_delete_config_file": "Удаление файла конфигурации...",
|
||||
"@performance_info_delete_config_file": {},
|
||||
"performance_action_clear_shaders": "Очистить шейдеры",
|
||||
"@performance_action_clear_shaders": {},
|
||||
"performance_info_done": "Готово...",
|
||||
"@performance_info_done": {},
|
||||
"performance_info_shader_clearing_warning": "После очистки шейдеров при первом входе в игру могут возникнуть задержки. Пожалуйста, дождитесь завершения инициализации игры.",
|
||||
"@performance_info_shader_clearing_warning": {},
|
||||
"performance_info_generate_config_file": "Создание файла конфигурации",
|
||||
"@performance_info_generate_config_file": {},
|
||||
"performance_info_write_out_config_file": "Запись файла конфигурации",
|
||||
"@performance_info_write_out_config_file": {},
|
||||
"app_index_menu_home": "Главная",
|
||||
"@app_index_menu_home": {},
|
||||
"app_index_menu_lobby": "Лобби",
|
||||
"@app_index_menu_lobby": {},
|
||||
"app_index_menu_tools": "Инструменты",
|
||||
"@app_index_menu_tools": {},
|
||||
"app_index_menu_settings": "Настройки",
|
||||
"@app_index_menu_settings": {},
|
||||
"app_index_menu_about": "О программе",
|
||||
"@app_index_menu_about": {},
|
||||
"lobby_online_lobby_coming_soon": "Онлайн-лобби скоро появится!",
|
||||
"@lobby_online_lobby_coming_soon": {},
|
||||
"lobby_invitation_to_participate": "Приглашаем вас принять участие в ",
|
||||
"@lobby_invitation_to_participate": {},
|
||||
"lobby_survey": "опросе.",
|
||||
"@lobby_survey": {},
|
||||
"setting_action_create_settings_shortcut": "Создать ярлык настроек",
|
||||
"@setting_action_create_settings_shortcut": {},
|
||||
"setting_action_create_desktop_shortcut": "Создать ярлык SCToolbox на рабочем столе",
|
||||
"@setting_action_create_desktop_shortcut": {},
|
||||
"setting_action_reset_auto_password_fill": "Сбросить автозаполнение пароля",
|
||||
"@setting_action_reset_auto_password_fill": {},
|
||||
"setting_action_ignore_efficiency_cores_on_launch": "Игнорировать энергоэффективные ядра при запуске игры (для процессоров Intel 12-го поколения и выше)",
|
||||
"@setting_action_ignore_efficiency_cores_on_launch": {},
|
||||
"setting_action_set_core_count": "Установленное количество ядер: {v0} (Эта функция применяется при запуске через SCToolbox или в режиме администратора RSI Launcher из набора инструментов. При значении 0 функция отключена)",
|
||||
"@setting_action_set_core_count": {},
|
||||
"setting_action_set_launcher_file": "Установить файл лаунчера (RSI Launcher.exe)",
|
||||
"@setting_action_set_launcher_file": {},
|
||||
"setting_action_info_manual_launcher_location_setting": "Ручная установка местоположения лаунчера, рекомендуется только если автоматическое сканирование мест установки не работает",
|
||||
"@setting_action_info_manual_launcher_location_setting": {},
|
||||
"setting_action_set_game_file": "Установить файл игры (StarCitizen.exe)",
|
||||
"@setting_action_set_game_file": {},
|
||||
"setting_action_info_manual_game_location_setting": "Ручная установка местоположения игры, рекомендуется только если автоматическое сканирование мест установки не работает",
|
||||
"@setting_action_info_manual_game_location_setting": {},
|
||||
"setting_action_clear_translation_file_cache": "Очистить кэш файлов локализации",
|
||||
"@setting_action_clear_translation_file_cache": {},
|
||||
"setting_action_info_cache_clearing_info": "Размер кэша {v0}MB, очистка кэша загруженных SCToolbox файлов локализации, не повлияет на установленные локализации",
|
||||
"@setting_action_info_cache_clearing_info": {},
|
||||
"setting_action_tool_site_access_acceleration": "Ускорение доступа к инструментам",
|
||||
"@setting_action_tool_site_access_acceleration": {},
|
||||
"setting_action_info_mirror_server_info": "Использовать зеркальные серверы для ускорения доступа к инструментам, таким как Dps, Uex и другие. Если возникают проблемы с доступом, отключите эту функцию. Для безопасности аккаунта, RSI сайт никогда не будет ускоряться.",
|
||||
"@setting_action_info_mirror_server_info": {},
|
||||
"setting_action_view_log": "Просмотр лога",
|
||||
"@setting_action_view_log": {},
|
||||
"setting_action_info_view_log_file": "Просмотр лог-файла SCToolbox для определения багов программы",
|
||||
"@setting_action_info_view_log_file": {},
|
||||
"setting_action_info_confirm_reset_autofill": "Подтвердить сброс автозаполнения?",
|
||||
"@setting_action_info_confirm_reset_autofill": {},
|
||||
"setting_action_info_delete_local_account_warning": "Это удалит локальную запись аккаунта или, при следующем запуске игры, выберите 'Нет' для отключения автозаполнения.",
|
||||
"@setting_action_info_delete_local_account_warning": {},
|
||||
"setting_action_info_autofill_data_cleared": "Данные автозаполнения очищены",
|
||||
"@setting_action_info_autofill_data_cleared": {},
|
||||
"setting_action_info_enter_cpu_core_to_ignore": "Введите количество ядер CPU для игнорирования",
|
||||
"@setting_action_info_enter_cpu_core_to_ignore": {},
|
||||
"setting_action_info_cpu_core_tip": "Совет: Введите количество энергоэффективных ядер вашего устройства. Для устройств без архитектуры big.LITTLE оставьте 0.\n\nЭта функция применяется при запуске через SCToolbox или в режиме администратора RSI Launcher из набора инструментов. При значении 0 функция отключена.",
|
||||
"@setting_action_info_cpu_core_tip": {},
|
||||
"setting_action_info_select_rsi_launcher_location": "Выберите местоположение RSI Launcher (RSI Launcher.exe)",
|
||||
"@setting_action_info_select_rsi_launcher_location": {},
|
||||
"setting_action_info_setting_success": "Настройка успешно выполнена, нажмите обновить на соответствующей странице для сканирования нового пути",
|
||||
"@setting_action_info_setting_success": {},
|
||||
"setting_action_info_file_error": "Ошибка файла!",
|
||||
"@setting_action_info_file_error": {},
|
||||
"setting_action_info_select_game_install_location": "Выберите место установки игры (StarCitizen.exe)",
|
||||
"@setting_action_info_select_game_install_location": {},
|
||||
"setting_action_info_confirm_clear_cache": "Подтвердите очистку кэша локализации?",
|
||||
"@setting_action_info_confirm_clear_cache": {},
|
||||
"setting_action_info_clear_cache_warning": "Это не повлияет на уже установленные локализации.",
|
||||
"@setting_action_info_clear_cache_warning": {},
|
||||
"setting_action_info_microsoft_version_limitation": "Из-за ограничений версии Microsoft, пожалуйста, в следующем окне вручную перетащите «SCToolbox» на рабочий стол для создания ярлыка.",
|
||||
"@setting_action_info_microsoft_version_limitation": {},
|
||||
"setting_action_info_shortcut_created": "Создание завершено, проверьте рабочий стол",
|
||||
"@setting_action_info_shortcut_created": {},
|
||||
"app_upgrade_title_new_version_found": "Найдена новая версия -> {v0}",
|
||||
"@app_upgrade_title_new_version_found": {},
|
||||
"app_upgrade_info_getting_new_version_details": "Получение информации о новой версии...",
|
||||
"@app_upgrade_info_getting_new_version_details": {},
|
||||
"app_upgrade_info_update_server_tip": "Примечание: Сейчас используется зеркальный сервер для обновления, что может привести к снижению скорости загрузки, но помогает нам контролировать затраты. Если возникают проблемы с загрузкой, нажмите здесь для перехода к ручной установке.",
|
||||
"@app_upgrade_info_update_server_tip": {},
|
||||
"app_upgrade_info_installing": "Установка: ",
|
||||
"@app_upgrade_info_installing": {},
|
||||
"app_upgrade_info_downloading": "Загрузка: {v0}% ",
|
||||
"@app_upgrade_info_downloading": {},
|
||||
"app_upgrade_action_update_now": "Обновить сейчас",
|
||||
"@app_upgrade_action_update_now": {},
|
||||
"app_upgrade_action_next_time": "В следующий раз",
|
||||
"@app_upgrade_action_next_time": {},
|
||||
"app_upgrade_info_download_failed": "Ошибка загрузки, пожалуйста, попробуйте установить вручную!",
|
||||
"@app_upgrade_info_download_failed": {},
|
||||
"app_upgrade_info_run_failed": "Ошибка запуска, пожалуйста, попробуйте установить вручную!",
|
||||
"@app_upgrade_info_run_failed": {},
|
||||
"app_splash_checking_availability": "Проверка доступности, это может занять некоторое время...",
|
||||
"@app_splash_checking_availability": {},
|
||||
"app_splash_checking_for_updates": "Проверка обновлений...",
|
||||
"@app_splash_checking_for_updates": {},
|
||||
"app_splash_almost_done": "Почти готово…",
|
||||
"@app_splash_almost_done": {},
|
||||
"tools_hosts_info_rsi_official_website": "Официальный сайт RSI",
|
||||
"@tools_hosts_info_rsi_official_website": {},
|
||||
"tools_hosts_info_rsi_customer_service": "Служба поддержки RSI",
|
||||
"@tools_hosts_info_rsi_customer_service": {},
|
||||
"tools_hosts_info_dns_query_and_test": "Запрос DNS и проверка доступности, пожалуйста, подождите...",
|
||||
"@tools_hosts_info_dns_query_and_test": {},
|
||||
"tools_hosts_info_writing_hosts": "Запись в файл Hosts...",
|
||||
"@tools_hosts_info_writing_hosts": {},
|
||||
"tools_hosts_info_reading_config": "Чтение конфигурации...",
|
||||
"@tools_hosts_info_reading_config": {},
|
||||
"tools_hosts_info_hosts_acceleration": "Ускорение через Hosts",
|
||||
"@tools_hosts_info_hosts_acceleration": {},
|
||||
"tools_hosts_info_open_hosts_file": "Открыть файл Hosts",
|
||||
"@tools_hosts_info_open_hosts_file": {},
|
||||
"tools_hosts_info_status": "Статус",
|
||||
"@tools_hosts_info_status": {},
|
||||
"tools_hosts_info_site": "Сайт",
|
||||
"@tools_hosts_info_site": {},
|
||||
"tools_hosts_info_enable": "Включить",
|
||||
"@tools_hosts_info_enable": {},
|
||||
"tools_hosts_action_one_click_acceleration": "Ускорение в один клик",
|
||||
"@tools_hosts_action_one_click_acceleration": {},
|
||||
"tools_info_scanning": "Сканирование...",
|
||||
"@tools_info_scanning": {},
|
||||
"tools_info_processing_failed": "Ошибка обработки: {v0}",
|
||||
"@tools_info_processing_failed": {},
|
||||
"tools_info_game_install_location": "Место установки игры: ",
|
||||
"@tools_info_game_install_location": {},
|
||||
"tools_info_rsi_launcher_location": "Местоположение RSI Launcher:",
|
||||
"@tools_info_rsi_launcher_location": {},
|
||||
"tools_action_view_system_info": "Просмотр информации о системе",
|
||||
"@tools_action_view_system_info": {},
|
||||
"tools_action_info_view_critical_system_info": "Просмотр критической информации о системе для быстрой диагностики\n\nЭто может занять время, пожалуйста, подождите.",
|
||||
"@tools_action_info_view_critical_system_info": {},
|
||||
"tools_action_p4k_download_repair": "Загрузка/восстановление P4K через зеркало",
|
||||
"@tools_action_p4k_download_repair": {},
|
||||
"tools_action_info_p4k_download_repair_tip": "Использовать сервис зеркальной загрузки от китайской Star Citizen Wiki для загрузки или восстановления файла p4k.\nИнформация о версии: {v0}",
|
||||
"@tools_action_info_p4k_download_repair_tip": {},
|
||||
"tools_action_hosts_acceleration_experimental": "Ускорение через Hosts (экспериментально)",
|
||||
"@tools_action_hosts_acceleration_experimental": {},
|
||||
"tools_action_info_hosts_acceleration_experimental_tip": "Запись IP-адресов в файл Hosts для решения проблем с DNS-загрязнением, препятствующих входу на официальный сайт в некоторых регионах.\nЭта функция находится на первом этапе тестирования, пожалуйста, сообщайте о любых проблемах.",
|
||||
"@tools_action_info_hosts_acceleration_experimental_tip": {},
|
||||
"tools_action_reinstall_easyanticheat": "Переустановка EasyAntiCheat",
|
||||
"@tools_action_reinstall_easyanticheat": {},
|
||||
"tools_action_info_reinstall_eac": "Если у вас возникают ошибки EAC и автоматическое исправление не работает, попробуйте использовать эту функцию для переустановки EAC.",
|
||||
"@tools_action_info_reinstall_eac": {},
|
||||
"tools_action_rsi_launcher_admin_mode": "Режим администратора RSI Launcher",
|
||||
"@tools_action_rsi_launcher_admin_mode": {},
|
||||
"tools_action_info_run_rsi_as_admin": "Запуск RSI Launcher от имени администратора может решить некоторые проблемы.\n\nЕсли настроены параметры блокировки энергоэффективных ядер, они также будут применены здесь.",
|
||||
"@tools_action_info_run_rsi_as_admin": {},
|
||||
"tools_action_info_init_failed": "Ошибка инициализации, пожалуйста, сделайте снимок экрана и сообщите разработчику. {v0}",
|
||||
"@tools_action_info_init_failed": {},
|
||||
"tools_action_rsi_launcher_log_fix": "Исправление лог-файла RSI Launcher",
|
||||
"@tools_action_rsi_launcher_log_fix": {},
|
||||
"tools_action_info_rsi_launcher_log_issue": "В некоторых случаях лог-файл RSI Launcher может повредиться, что мешает завершению сканирования проблем. Используйте этот инструмент для очистки поврежденных лог-файлов.\n\nТекущий размер лог-файла: {v0} МБ",
|
||||
"@tools_action_info_rsi_launcher_log_issue": {},
|
||||
"tools_action_remove_nvme_registry_patch": "Удалить патч реестра NVME",
|
||||
"@tools_action_remove_nvme_registry_patch": {},
|
||||
"tools_action_info_nvme_patch_issue": "Если у вас возникли проблемы с патчем NVME, запустите этот инструмент. (Может привести к недоступности установки/обновления игры.)\n\nСтатус патча: {v0}",
|
||||
"@tools_action_info_nvme_patch_issue": {},
|
||||
"tools_action_info_not_installed": "Не установлен",
|
||||
"@tools_action_info_not_installed": {},
|
||||
"tools_action_info_removed_restart_effective": "Удалено, изменения вступят в силу после перезагрузки!",
|
||||
"@tools_action_info_removed_restart_effective": {},
|
||||
"tools_action_write_nvme_registry_patch": "Записать патч реестра NVME",
|
||||
"@tools_action_write_nvme_registry_patch": {},
|
||||
"tools_action_info_manual_nvme_patch": "Ручная запись патча NVME, используйте эту функцию только если знаете, что делаете",
|
||||
"@tools_action_info_manual_nvme_patch": {},
|
||||
"tools_action_info_fix_success_restart": "Исправление успешно, попробуйте перезагрузить компьютер и продолжить установку игры! Если изменения реестра вызвали проблемы совместимости с другими программами, используйте инструмент очистки реестра NVME в разделе Инструменты.",
|
||||
"@tools_action_info_fix_success_restart": {},
|
||||
"tools_action_clear_shader_cache": "Очистить кэш шейдеров",
|
||||
"@tools_action_clear_shader_cache": {},
|
||||
"tools_action_info_shader_cache_issue": "Если графика игры выглядит необычно или после обновления версии, используйте этот инструмент для очистки устаревших шейдеров (также вернёт Vulkan к DX11)\n\nРазмер кэша: {v0} МБ",
|
||||
"@tools_action_info_shader_cache_issue": {},
|
||||
"tools_action_close_photography_mode": "Выключить режим фотографии",
|
||||
"@tools_action_close_photography_mode": {},
|
||||
"tools_action_open_photography_mode": "Включить режим фотографии",
|
||||
"@tools_action_open_photography_mode": {},
|
||||
"tools_action_info_restore_lens_shake": "Восстановить эффект тряски объектива.\n\nИнформация о параметрах предоставлена @拉邦那 Lapernum.",
|
||||
"@tools_action_info_restore_lens_shake": {},
|
||||
"tools_action_info_one_key_close_lens_shake": "Одним кликом отключить дрожание камеры в игре для упрощения фотосъёмки.\n\nИнформация о параметрах предоставлена @拉邦那 Lapernum.",
|
||||
"@tools_action_info_one_key_close_lens_shake": {},
|
||||
"tools_action_info_log_file_parse_failed": "Ошибка анализа лог-файла!\nПопробуйте использовать инструмент исправления лог-файла RSI Launcher!",
|
||||
"@tools_action_info_log_file_parse_failed": {},
|
||||
"tools_action_info_rsi_launcher_not_found": "RSI Launcher не найден, попробуйте переустановить его или добавить вручную в настройках.",
|
||||
"@tools_action_info_rsi_launcher_not_found": {},
|
||||
"tools_action_info_star_citizen_not_found": "Местоположение установки Star Citizen не найдено, пожалуйста, запустите игру хотя бы один раз или добавьте местоположение вручную в настройках.",
|
||||
"@tools_action_info_star_citizen_not_found": {},
|
||||
"tools_action_info_valid_game_directory_needed": "Для этой функции требуется действительная директория установки игры",
|
||||
"@tools_action_info_valid_game_directory_needed": {},
|
||||
"tools_action_info_eac_file_removed": "Файлы EAC удалены. Сейчас будет открыт RSI Launcher, пожалуйста, перейдите в SETTINGS -> VERIFY для переустановки EAC.",
|
||||
"@tools_action_info_eac_file_removed": {},
|
||||
"tools_action_info_error_occurred": "Произошла ошибка: {v0}",
|
||||
"@tools_action_info_error_occurred": {},
|
||||
"tools_action_info_system_info_content": "Система: {v0}\n\nПроцессор: {v1}\n\nОбъем памяти: {v2}GB\n\nИнформация о видеокарте:\n{v3}\n\nИнформация о жестком диске:\n{v4}\n\n",
|
||||
"@tools_action_info_system_info_content": {},
|
||||
"tools_action_info_rsi_launcher_directory_not_found": "Директория RSI Launcher не найдена, пожалуйста, выполните операцию вручную.",
|
||||
"@tools_action_info_rsi_launcher_directory_not_found": {},
|
||||
"tools_action_info_log_file_not_exist": "Лог-файл не существует, попробуйте запустить игру или начать установку и выйти из лаунчера. Если проблема не решена, попробуйте обновить лаунчер до последней версии!",
|
||||
"@tools_action_info_log_file_not_exist": {},
|
||||
"tools_action_info_cleanup_complete": "Очистка завершена, пожалуйста, выполните установку или запуск игры.",
|
||||
"@tools_action_info_cleanup_complete": {},
|
||||
"tools_action_info_cleanup_failed": "Очистка не удалась, пожалуйста, удалите файл вручную, расположение файла: {v0}",
|
||||
"@tools_action_info_cleanup_failed": {},
|
||||
"tools_action_info_system_info_title": "Информация о системе",
|
||||
"@tools_action_info_system_info_title": {},
|
||||
"tools_action_info_rsi_launcher_running_warning": "RSI Launcher запущен! Пожалуйста, сначала закройте лаунчер, прежде чем использовать эту функцию!",
|
||||
"@tools_action_info_rsi_launcher_running_warning": {},
|
||||
"tools_action_info_p4k_file_description": "P4k - это основной файл игры Star Citizen, размером более 100 ГБ. Автономное скачивание, предоставляемое SCToolbox, помогает пользователям с медленной загрузкой p4k или для исправления файла p4k, который не может быть исправлен официальным лаунчером.\n\nДалее появится диалоговое окно с запросом места сохранения (можно выбрать папку Star Citizen или другое место). После завершения загрузки убедитесь, что файл P4K находится в папке LIVE, затем используйте лаунчер Star Citizen для проверки обновлений.",
|
||||
"@tools_action_info_p4k_file_description": {},
|
||||
"tools_action_info_p4k_download_in_progress": "Загрузка p4k уже выполняется, пожалуйста, проверьте менеджер загрузок!",
|
||||
"@tools_action_info_p4k_download_in_progress": {},
|
||||
"tools_action_info_function_under_maintenance": "Функция на техническом обслуживании, пожалуйста, повторите попытку позже!",
|
||||
"@tools_action_info_function_under_maintenance": {},
|
||||
"tools_action_info_config_file_not_exist": "Конфигурационный файл не существует, попробуйте запустить игру один раз",
|
||||
"@tools_action_info_config_file_not_exist": {},
|
||||
"webview_localization_name_member": "именной участник",
|
||||
"@webview_localization_name_member": {},
|
||||
"webview_localization_total_invitations": "Всего приглашений:",
|
||||
"@webview_localization_total_invitations": {},
|
||||
"webview_localization_unfinished_invitations": "Незавершённые приглашения",
|
||||
"@webview_localization_unfinished_invitations": {},
|
||||
"webview_localization_finished_invitations": "Завершённые приглашения",
|
||||
"@webview_localization_finished_invitations": {},
|
||||
"app_init_failed_with_reason": "Ошибка инициализации: {v0}",
|
||||
"@app_init_failed_with_reason": {},
|
||||
"settings_app_language": "Язык",
|
||||
"settings_app_language_auto": "Автоматически",
|
||||
"app_common_network_error": "Ошибка подключения к сети!\nПереход в автономный режим...\n\nПожалуйста, проверьте подключение к сети или получите последние новости на социальном форуме. Попробуйте включить встроенный режим DNS в настройках приложения.\nДата сборки текущей версии: {v0}\nQQ группа: 940696487\nСообщение об ошибке: {v1}",
|
||||
"app_common_upgrade_info_error": "Не удалось получить информацию об обновлении, пожалуйста, повторите попытку позже.",
|
||||
"doctor_game_error_low_memory": "Недостаточно доступной памяти",
|
||||
"doctor_game_error_low_memory_info": "Попробуйте увеличить виртуальную память (для 1080p требуется >64 ГБ физической + виртуальной памяти)",
|
||||
"doctor_game_error_generic_info": "Игра вызвала наиболее распространенную проблему сбоя, пожалуйста, обратитесь к руководству по устранению неполадок",
|
||||
"doctor_game_error_gpu_crash": "Ваша видеокарта вышла из строя! Пожалуйста, обратитесь к руководству по устранению неполадок",
|
||||
"doctor_game_error_socket_error": "Обнаружена ошибка сокета",
|
||||
"doctor_game_error_socket_error_info": "При использовании ускорителя X Black Box попробуйте изменить режим ускорения",
|
||||
"doctor_game_error_permissions_error": "Недостаточно прав",
|
||||
"doctor_game_error_permissions_error_info": "Попробуйте запустить лаунчер от имени администратора или использовать SCToolbox (версия Microsoft Store) для запуска.",
|
||||
"doctor_game_error_game_process_error": "Процесс игры занят",
|
||||
"doctor_game_error_game_process_error_info": "Попробуйте перезапустить лаунчер или перезагрузить компьютер",
|
||||
"doctor_game_error_game_damaged_file": "Файлы программы игры повреждены",
|
||||
"doctor_game_error_game_damaged_file_info": "Попробуйте удалить папку Bin64 и проверить в лаунчере.",
|
||||
"doctor_game_error_game_damaged_p4k_file": "Файл P4K поврежден",
|
||||
"doctor_game_error_game_damaged_p4k_file_info": "Попробуйте удалить файл Data.p4k и проверить в лаунчере или использовать альтернативную загрузку через SCToolbox.",
|
||||
"doctor_game_error_low_gpu_memory": "Недостаточно видеопамяти",
|
||||
"doctor_game_error_low_gpu_memory_info": "Пожалуйста, не запускайте другие игры/приложения с высоким использованием видеокарты в фоновом режиме или замените видеокарту.",
|
||||
"doctor_game_error_gpu_vulkan_crash": "Сбой GPU Vulkan",
|
||||
"doctor_game_error_gpu_vulkan_crash_info": "Сбой Vulkan! Это может быть проблема с версией драйвера или игрового движка. Попробуйте обновить драйвер GPU или использовать функцию очистки шейдеров для возврата к DX11",
|
||||
"app_common_error_info": "Произошла ошибка: {v0}",
|
||||
"app_common_tip": "Подсказка",
|
||||
"app_common_tip_i_know": "Понятно",
|
||||
"app_common_tip_confirm": "Подтвердить",
|
||||
"app_common_tip_cancel": "Отмена",
|
||||
"settings_app_language_switch_info": "Переключить язык отображения приложения",
|
||||
"home_holiday_countdown_days": "{v0} дней",
|
||||
"home_holiday_countdown_in_progress": "В процессе",
|
||||
"app_common_loading_images": "Загрузка изображений...",
|
||||
"app_splash_dialog_u_a_p_p": "Пользовательское соглашение и политика конфиденциальности",
|
||||
"app_splash_dialog_u_a_p_p_content": "Благодарим вас за выбор SCToolbox. Мы стремимся предоставить вам безопасный, удобный и надежный пользовательский опыт. Прежде чем начать использование приложения, пожалуйста, прочтите и согласитесь со следующим:\n\n1. Это приложение является программным обеспечением с открытым исходным кодом под лицензией GNU General Public License v3.0. Вы можете свободно использовать, модифицировать и распространять это программное обеспечение в соответствии с условиями лицензии. Наш исходный код находится на: [Github.com/StarCitizenToolBox/app](https://github.com/StarCitizenToolBox/app).\n2. Авторские права на интернет-контент в этом приложении (включая, но не ограничиваясь файлами локализации, инструментальными сайтами, новостями, видео и т.д.) принадлежат их авторам и не являются частью GPL. Пожалуйста, используйте их в соответствии с соответствующими лицензионными соглашениями.\n3. Официальные каналы бесплатного распространения этого приложения: [Microsoft Store](https://apps.microsoft.com/detail/9NF3SWFWNKL1) и [Star Citizen Localization Group Website](https://www.starcitizenzw.com/). Если вы получили его из других сторонних источников, пожалуйста, тщательно проверяйте, чтобы избежать финансовых потерь.\n4. Это приложение отправляет анонимные статистические данные на наши серверы для улучшения качества программного обеспечения. Мы не собираем вашу личную информацию.\n5. Это приложение поддерживается сообществом и не имеет прямой связи с Cloud Imperium Games или другими коммерческими компаниями.\n6. Мы предоставляем ограниченную поддержку сообщества. При необходимости, пожалуйста, обратитесь к странице «О программе», чтобы узнать, как связаться с нами.",
|
||||
"tools_unp4k_msg_init": "Инициализация...",
|
||||
"tools_unp4k_msg_reading": "Чтение файла P4K...",
|
||||
"tools_unp4k_msg_reading2": "Обработка файлов...",
|
||||
"tools_unp4k_msg_reading3": "Обработка файлов ({v0}/{v1})...",
|
||||
"tools_unp4k_msg_read_completed": "Загрузка завершена: {v0} файлов, время: {v1} мс",
|
||||
"tools_unp4k_msg_open_file": "Открытие файла: {v0}",
|
||||
"tools_unp4k_msg_read_file": "Чтение файла: {v0}...",
|
||||
"home_localization_advanced_title": "Расширенная локализация -> {v0}",
|
||||
"home_localization_advanced_msg_version": "Загруженная версия локализации: {v0}",
|
||||
"home_localization_advanced_title_msg": "Строк локализации: {v0} Строк P4K: {v1}",
|
||||
"home_localization_advanced_action_install": "Установить локализацию",
|
||||
"home_localization_advanced_action_mod_change": "Пересоздание текста...",
|
||||
"home_localization_advanced_action_mode": "Режим",
|
||||
"home_localization_advanced_title_preview": "Предпросмотр: {v0}",
|
||||
"home_localization_advanced_json_text_location_other": "Места - Другое",
|
||||
"home_localization_advanced_json_text_location_used": "Места - Часто используемые",
|
||||
"home_localization_advanced_json_text_things_other": "Предметы - Другое",
|
||||
"home_localization_advanced_json_text_things_used": "Предметы - Часто используемые",
|
||||
"home_localization_advanced_json_text_vehicle_other": "Транспорт - Другое",
|
||||
"home_localization_advanced_json_text_vehicle_used": "Транспорт - Часто используемый",
|
||||
"home_localization_advanced_json_text_mission_or_logs": "Миссии/Журналы",
|
||||
"home_localization_advanced_json_text_subtitle": "Субтитры",
|
||||
"home_localization_advanced_json_text_ui_or_hud_or_menu": "UI/HUD/Меню",
|
||||
"home_localization_advanced_json_text_un_localization": "Без локализации",
|
||||
"home_localization_advanced_json_text_others": "Другое",
|
||||
"home_localization_advanced_action_mod_change_localization": "Локализация",
|
||||
"home_localization_advanced_action_mod_change_un_localization": "Английский оригинал",
|
||||
"home_localization_advanced_action_mod_change_mixed": "Двуязычный",
|
||||
"home_localization_advanced_action_mod_change_mixed_newline": "Двуязычный (с новой строки)",
|
||||
"home_localization_advanced_msg_classifying": "Классификация...",
|
||||
"home_localization_advanced_msg_reading_p4k": "Чтение файла p4k...",
|
||||
"home_localization_advanced_msg_reading_server_localization_text": "Получение текста локализации...",
|
||||
"home_localization_advanced_msg_gen_localization_text": "Создание файла локализации...",
|
||||
"home_localization_advanced_msg_gen_localization_install": "Установка файла локализации...",
|
||||
"home_localization_msg_version_advanced": " (Расширенная локализация)",
|
||||
"home_localization_msg_no_note": "Для этой версии нет описания",
|
||||
"home_localization_action_rsi_launcher_localization": "Локализация RSI Launcher",
|
||||
"home_localization_action_rsi_launcher_no_game_path_msg": "У вас не установлена игра или не выбран путь установки игры. Доступна только функция локализации лаунчера. Пожалуйста, убедитесь, что игра установлена или добавьте путь установки игры в настройках SCToolbox и повторите попытку.",
|
||||
"home_localization_action_advanced": "Расширенная локализация",
|
||||
"home_localization_action_install_customize": "Установить пользовательский файл",
|
||||
"home_localization_title_localization_tools": "Инструменты локализации",
|
||||
"performance_json_text_dof": "Глубина резкости",
|
||||
"performance_json_text_dof_info": "Управляет эффектом глубины резкости на странице браслета и т.д.",
|
||||
"performance_json_text_ssdo": "Постобработка освещения",
|
||||
"performance_json_text_ssdo_info": "Настройка уровня постобработки освещения",
|
||||
"performance_json_text_title_graphics": "Графика (рекомендуется очистить шейдеры после изменения)",
|
||||
"performance_json_text_antialiasing": "Сглаживание",
|
||||
"performance_json_text_antialiasing_info": "0 выкл., 1 SMAA, 2 Временная фильтрация + SMAA, 3 SMAA с временной фильтрацией и дрожанием проекционной матрицы",
|
||||
"performance_json_text_game_effects": "Уровень эффектов",
|
||||
"performance_json_text_game_effects_info": "Уровень игровых эффектов",
|
||||
"performance_json_text_texture": "Уровень текстур",
|
||||
"performance_json_text_texture_info": "Детализация текстур моделей",
|
||||
"performance_json_text_volumetric_effects": "Объемные эффекты",
|
||||
"performance_json_text_volumetric_effects_info": "Объемные облака, объемное освещение и т.д.",
|
||||
"performance_json_text_water": "Эффекты воды",
|
||||
"performance_json_text_water_info": "Уровень всех водных эффектов",
|
||||
"performance_json_text_object_detail": "Детализация объектов",
|
||||
"performance_json_text_object_detail_info": "Детализация моделей объектов, влияет на LOD и т.д.",
|
||||
"performance_json_text_particles": "Детализация частиц",
|
||||
"performance_json_text_physics": "Детализация физики",
|
||||
"performance_json_text_physics_info": "Диапазон физических эффектов",
|
||||
"performance_json_text_shading": "Детализация шейдеров",
|
||||
"performance_json_text_shading_info": "Связанное с шейдерами",
|
||||
"performance_json_text_shadows": "Детализация теней",
|
||||
"performance_json_text_shadows_info": "Эффекты теней",
|
||||
"performance_json_text_postprocessing": "Детализация постобработки",
|
||||
"performance_json_text_postprocessing_info": "Шейдеры постобработки, эффекты размытия в движении и т.д.",
|
||||
"performance_json_text_renderer": "Качество рендеринга",
|
||||
"performance_json_text_renderer_info": "Качество рендерера CryEngine",
|
||||
"performance_json_text_shader_decal": "Качество наклеек",
|
||||
"performance_json_text_shader_decal_info": "(логотипы, значки и т.д.)",
|
||||
"performance_json_text_shader_post_process": "Качество шейдеров",
|
||||
"performance_json_text_shader_fx": "Качество FX",
|
||||
"performance_json_text_shader_general": "Общее качество",
|
||||
"performance_json_text_shader_general_info": "Общее качество моделей",
|
||||
"performance_json_text_shader_glass": "Качество стекла",
|
||||
"performance_json_text_shader_glass_info": "Окна, зеркала и т.д.",
|
||||
"performance_json_text_shader_hdr": "Качество HDR",
|
||||
"performance_json_text_shader_hdr_info": "Обработка HDR, хроматических аберраций, уровней яркости и т.д.",
|
||||
"performance_json_text_shader_particle": "Качество частиц",
|
||||
"performance_json_text_shader_particle_info": "Качество эффектов частиц",
|
||||
"performance_json_text_shader_terrain": "Качество местности",
|
||||
"performance_json_text_shader_shadow": "Качество теней",
|
||||
"performance_json_text_shader_sky": "Качество неба",
|
||||
"performance_json_text_particles_object_collisions": "Столкновения частиц",
|
||||
"performance_json_text_particles_object_collisions_info": "1 только статические частицы 2 включая динамические частицы",
|
||||
"performance_json_text_displayinfo": "Информация на экране (показывать FPS)",
|
||||
"performance_json_text_displayinfo_info": "Показывать FPS, информацию о сервере и т.д. в правом верхнем углу экрана",
|
||||
"performance_json_text_max_fps": "Максимальный FPS",
|
||||
"performance_json_text_max_fps_info": "Регулировка максимального FPS в игре, 0 для неограниченного",
|
||||
"performance_json_text_display_session": "Показывать информацию о сессии",
|
||||
"performance_json_text_display_session_info": "Когда включено, показывает QR-код на экране для быстрого доступа CIG к соответствующей информации при обратной связи",
|
||||
"performance_json_text_vsync": "Вертикальная синхронизация",
|
||||
"performance_json_text_vsync_info": "Включите для предотвращения разрывов, выключите для повышения FPS",
|
||||
"performance_json_text_motion_blur": "Размытие в движении",
|
||||
"performance_json_text_motion_blur_info": "Включите для усиления чувства движения, выключите для улучшения восприятия",
|
||||
"performance_json_text_fov": "Настройка FOV",
|
||||
"performance_json_text_ui_animation": "Анимация затухания UI",
|
||||
"performance_json_text_custom_parameters": "Пользовательские параметры",
|
||||
"performance_json_text_title_custom": "Пользовательские",
|
||||
"tools_rsi_launcher_enhance_init_msg1": "Чтение информации о лаунчере...",
|
||||
"tools_rsi_launcher_enhance_init_msg2": "Получение данных улучшений из сети...",
|
||||
"tools_rsi_launcher_enhance_working_msg1": "Создание патча...",
|
||||
"tools_rsi_launcher_enhance_working_msg2": "Установка патча, это займет некоторое время в зависимости от производительности вашего компьютера...",
|
||||
"tools_rsi_launcher_enhance_title": "Улучшения RSI Launcher",
|
||||
"tools_rsi_launcher_enhance_msg_version": "Внутренняя версия лаунчера: {v0}",
|
||||
"tools_rsi_launcher_enhance_msg_patch_status": "Статус патча: {v0}",
|
||||
"tools_rsi_launcher_enhance_msg_error": "Не удалось получить данные улучшений, возможно проблема с сетью или текущая версия не поддерживается",
|
||||
"tools_rsi_launcher_enhance_title_localization": "Локализация RSI Launcher",
|
||||
"tools_rsi_launcher_enhance_subtitle_localization": "Добавляет поддержку нескольких языков в RSI Launcher.",
|
||||
"tools_rsi_launcher_enhance_title_download_booster": "Ускорение загрузки RSI Launcher",
|
||||
"tools_rsi_launcher_enhance_subtitle_download_booster": "Позволяет использовать больше потоков при загрузке игры для увеличения скорости, после включения измените количество потоков в настройках лаунчера.",
|
||||
"tools_rsi_launcher_enhance_action_install": "Установить патч улучшений",
|
||||
"tools_rsi_launcher_enhance_msg_uninstall": "* Чтобы удалить патч улучшений, переустановите RSI Launcher.",
|
||||
"tools_rsi_launcher_enhance_msg_error_launcher_notfound": "RSI Launcher не найден",
|
||||
"tools_rsi_launcher_enhance_msg_error_get_launcher_info_error": "Не удалось прочитать информацию о лаунчере!",
|
||||
"tools_rsi_launcher_enhance_msg_error_get_launcher_info_error_with_args": "Не удалось прочитать информацию о лаунчере: {v0}",
|
||||
"tools_action_rsi_launcher_enhance_info": "Локализация лаунчера, улучшение загрузки",
|
||||
"tools_rsi_launcher_enhance_note_title": "Замечания по использованию улучшений RSI Launcher",
|
||||
"tools_rsi_launcher_enhance_note_msg": "Улучшения RSI Launcher - это функция сообщества, которая распаковывает \"RSI Launcher\" на вашем компьютере и добавляет дополнительные функции улучшений. Какие функции использовать - решать вам.\n\nВ настоящее время CIG разрешает нам только операции с мультиязычностью. Ускорение загрузки лаунчера - это дополнительная функция, которую мы считаем полезной. Нарушение пользовательского соглашения CIG (https://robertsspaceindustries.com/eula) может привести к серьезным последствиям, включая блокировку аккаунта. Решение об использовании остается за вами, мы не несем ответственности за возможные последствия (повреждение игры, блокировка аккаунта и т.д.).\n\nДля модификаций лаунчера мы открыли исходный код на: https://github.com/StarCitizenToolBox/RSILauncherEnhance, при необходимости вы можете его изучить.\n\nЕсли по какой-либо причине вам нужно отменить этот патч улучшений, просто переустановите официальный лаунчер поверх текущего.",
|
||||
"tools_action_unp4k": "Просмотрщик P4K",
|
||||
"tools_action_unp4k_info": "Распаковать файл p4k Star Citizen",
|
||||
"tools_unp4k_title": "Просмотрщик P4K -> {v0}",
|
||||
"tools_unp4k_view_file": "Нажмите на файл для предварительного просмотра",
|
||||
"tools_unp4k_msg_unknown_file_type": "Неизвестный тип файла\n{v0}",
|
||||
"home_localization_select_customize_file_ini": "Пожалуйста, выберите ini файл",
|
||||
"home_localization_select_customize_file": "Пожалуйста, выберите пользовательский файл локализации",
|
||||
"home_localization_action_select_customize_file": "Нажмите для выбора ini файла",
|
||||
"home_localization_ptu_advanced_localization_tip_title": "Рекомендуется использовать расширенную локализацию",
|
||||
"home_localization_ptu_advanced_localization_tip_title_info": "В тестовых каналах PTU/EPTU текущий текст локализации может быть не синхронизирован с игрой. Использование расширенной локализации может уменьшить появление некорректного текста.",
|
||||
"tools_rsi_launcher_enhance_action_fold": "Свернуть дополнительные функции",
|
||||
"tools_rsi_launcher_enhance_action_expand": "Развернуть дополнительные функции",
|
||||
"tools_unp4k_missing_runtime": "Отсутствует среда выполнения",
|
||||
"tools_unp4k_missing_runtime_info": "Для использования этой функции необходимо установить среду выполнения .NET8. Пожалуйста, нажмите кнопку ниже для загрузки и установки, после успешной установки перезапустите эту страницу для продолжения использования.",
|
||||
"tools_unp4k_missing_runtime_action_install": "Установить среду выполнения",
|
||||
"settings_title_general": "Общие",
|
||||
"settings_item_dns": "Использовать встроенный DNS",
|
||||
"settings_item_dns_info": "При включении может решить проблемы с DNS-загрязнением в некоторых регионах",
|
||||
"settings_title_game": "Игра",
|
||||
"about_action_btn_faq": "Часто задаваемые вопросы",
|
||||
"guide_title_welcome": "Добро пожаловать",
|
||||
"guide_info_check_settings": "Пожалуйста, проверьте правильность следующих настроек. Если есть ошибки, нажмите на значок справа для исправления, прежде чем продолжить использование",
|
||||
"guide_info_game_download_note": "* Если ваша игра загружается, пожалуйста, запустите игру один раз после завершения загрузки и нажмите кнопку обновления. Если вы используете только локализацию лаунчера, убедитесь, что путь к лаунчеру правильный, и нажмите 'Завершить настройку'",
|
||||
"guide_action_get_help": "Получить помощь",
|
||||
"guide_action_complete_setup": "Завершить настройку",
|
||||
"guide_dialog_confirm_complete_setup": "Подтвердить завершение настройки?",
|
||||
"guide_action_info_no_launcher_path_warning": "Вы еще не выбрали путь установки лаунчера. Подтвердить завершение настройки?\n\nПосле закрытия страницы руководства вам нужно будет вручную перейти на страницу настроек.",
|
||||
"guide_action_info_no_game_path_warning": "Вы еще не выбрали путь установки игры. Подтвердить завершение настройки?\n\nПосле закрытия страницы руководства вам нужно будет вручную перейти на страницу настроек.",
|
||||
"setting_toast_select_launcher_exe": "Выберите exe файл лаунчера: \"RSI Launcher.exe\"",
|
||||
"setting_toast_select_game_file": "Выберите соответствующий файл игры: Bin64/StarCitizen.exe",
|
||||
"input_method_feature_maintenance": "Функция на техническом обслуживании, пожалуйста, повторите попытку позже",
|
||||
"input_method_community_input_method_not_installed": "Поддержка метода ввода сообщества не установлена",
|
||||
"input_method_install_community_input_method_prompt": "Перейти к управлению локализацией для установки?\n\nЕсли локализация уже установлена, удалите ее и при повторной установке включите переключатель поддержки метода ввода сообщества.",
|
||||
"input_method_usage_instructions": "Инструкция по использованию",
|
||||
"input_method_input_text_instructions": "Введите текст в текстовое поле выше и вставьте (Ctrl+V) преобразованный текст ниже в текстовое поле игры, чтобы отправить текст, который игра не поддерживает для ввода, в канал чата.",
|
||||
"input_method_input_placeholder": "Введите текст...",
|
||||
"input_method_encoded_text_placeholder": "Здесь будет преобразованный текст...",
|
||||
"input_method_remote_input_service": "Служба удаленного ввода:",
|
||||
"input_method_disclaimer": "*Рекомендуется использовать эту функцию только в непубличных каналах. Если пользователь решает использовать эту функцию в публичных каналах, он несет полную ответственность за любые последствия (включая, но не ограничиваясь, жалобы других игроков на спам).\n*Если эта функция будет использоваться неправильно, мы её отключим.",
|
||||
"input_method_experimental_input_method": "Метод ввода сообщества (экспериментальный)",
|
||||
"input_method_auto_copy": "Автоматическое копирование",
|
||||
"input_method_confirm_enable_remote_input": "Подтвердить включение удаленного ввода?",
|
||||
"input_method_enable_remote_input_instructions": "После включения этой функции вы сможете быстро вводить текст через мобильный телефон, посетив удаленный адрес сервиса, избегая необходимости переключения окон и не прерывая игровой процесс.\n\nЕсли появится предупреждение брандмауэра, разверните окно, вручную отметьте все типы сетей и разрешите доступ, иначе функция может работать некорректно.",
|
||||
"input_method_address_fetch_failed": "Не удалось получить адрес, проверьте IP компьютера вручную",
|
||||
"input_method_text_cannot_be_empty": "Текст не может быть пустым!",
|
||||
"input_method_send_success": "Успешно отправлено!",
|
||||
"input_method_ip_address_not_found": "Мы не смогли найти подходящий IP-адрес для доступа к сервису, попробуйте следующие адреса (листайте влево/вправо)",
|
||||
"input_method_scan_qr_code": "Отсканируйте QR-код с мобильного устройства или посетите ссылку вручную",
|
||||
"input_method_service_qr_code": "QR-код сервиса",
|
||||
"input_method_confirm_install_advanced_localization": "Подтвердить установку расширенной локализации?",
|
||||
"input_method_install_community_input_method_support": "Установить поддержку метода ввода сообщества",
|
||||
"input_method_community_input_method_support_version": "Поддержка метода ввода сообщества: {v0}",
|
||||
"input_method_online_version_prompt": "Доступна отдельная онлайн-версия этой функции, нажмите для перехода >",
|
||||
"input_method_support_updated": "Поддержка метода ввода сообщества обновлена",
|
||||
"input_method_support_updated_to_version": "Поддержка метода ввода сообщества обновлена до версии: {v0}",
|
||||
"input_method_auto_translate": "Двуязычный перевод:",
|
||||
"input_method_auto_translate_dialog_title": "Включить двуязычный перевод?",
|
||||
"input_method_auto_translate_dialog_title_content": "После включения будет использоваться сервис Google Translate для добавления английской версии к вашему тексту. Это может вызвать задержку отклика. Отключите функцию, если она работает некорректно.\n\nТекст будет отправляться на серверы Google, ознакомьтесь с политикой конфиденциальности Google.",
|
||||
"support_dev_thanks_message": "Спасибо за использование SCToolbox, я разработчик - xkeyC\nSCToolbox стремится быть проектом с открытым исходным кодом и предоставлять бесплатные услуги игрокам. Бесплатное обслуживание - это сложная работа, и если вы рассматриваете возможность угостить меня напитком, я буду очень признателен.\nПожертвования будут использованы на серверные расходы, разработку новых функций и поддержание мотивации для улучшения программного обеспечения.",
|
||||
"support_dev_referral_code_message": "Если вы еще не зарегистрировались в игре или не ввели реферальный код, рассмотрите мой: STAR-3YXS-SWTC, спасибо что дочитали до конца",
|
||||
"support_dev_title": "Поддержать разработчика",
|
||||
"support_dev_github_star_message": "Вы также можете поставить звезду моему проекту на GitHub",
|
||||
"support_dev_github_star_button": "Поставить звезду проекту",
|
||||
"support_dev_in_game_currency_title": "Внутриигровая валюта",
|
||||
"support_dev_in_game_id": "Игровой ID: xkeyC",
|
||||
"support_dev_in_game_id_copied": "Игровой ID скопирован",
|
||||
"support_dev_copy_button": "Копировать",
|
||||
"support_dev_in_game_currency_message": "Вы можете отправить мне aUEC в игре в качестве поддержки, это поможет мне получить лучший игровой опыт в ограниченное время",
|
||||
"support_dev_alipay": "Alipay",
|
||||
"support_dev_wechat": "WeChat",
|
||||
"support_dev_donation_disclaimer": "* Обратите внимание: пожертвования являются безвозмездными, вы не получите дополнительных преимуществ в программе.",
|
||||
"support_dev_back_button": "Назад",
|
||||
"support_dev_scroll_hint": "Прокрутите вниз для просмотра",
|
||||
"log_analyzer_filter_all": "Все",
|
||||
"log_analyzer_filter_basic_info": "Основная информация",
|
||||
"log_analyzer_filter_account_related": "Связанное с аккаунтом",
|
||||
"log_analyzer_filter_fatal_collision": "Фатальные столкновения",
|
||||
"log_analyzer_filter_vehicle_damaged": "Повреждения техники",
|
||||
"log_analyzer_filter_character_death": "Смерть персонажа",
|
||||
"log_analyzer_filter_statistics": "Статистика",
|
||||
"log_analyzer_filter_game_crash": "Сбой игры",
|
||||
"log_analyzer_filter_local_inventory": "Локальный инвентарь",
|
||||
"log_analyzer_no_log_file": "Файл логов не найден",
|
||||
"log_analyzer_one_click_diagnosis_header": "----- Экспресс-диагностика SCToolbox -----",
|
||||
"log_analyzer_details_info": "Подробная информация: {v0}",
|
||||
"log_analyzer_no_crash_detected": "Сбои игры не обнаружены",
|
||||
"log_analyzer_game_crash": "Сбой игры ",
|
||||
"log_analyzer_kill_summary": "Сводка убийств",
|
||||
"log_analyzer_kill_death_suicide_count": "Убийства: {v0} Смерти: {v1} Самоубийства: {v2} \nУничтожение техники (Мягкая смерть): {v3} Уничтожение техники (Распад): {v4}",
|
||||
"log_analyzer_play_time": "Время игры",
|
||||
"log_analyzer_play_time_format": "{v0} часов {v1} минут {v2} секунд",
|
||||
"log_analyzer_game_start": "Запуск игры",
|
||||
"log_analyzer_game_loading": "Загрузка игры",
|
||||
"log_analyzer_mode_loading_time": "Режим: {v0} Время: {v1} секунд",
|
||||
"log_analyzer_game_close": "Закрытие игры",
|
||||
"log_analyzer_collision_details": "Зона: {v0} Управление игроком: {v1} Объект столкновения: {v2} \nТехника столкновения: {v3} Дистанция столкновения: {v4} ",
|
||||
"log_analyzer_soft_death": "Мягкая смерть",
|
||||
"log_analyzer_disintegration": "Дезинтеграция",
|
||||
"log_analyzer_vehicle_damage_details": "Модель техники: {v0} \nЗона: {v1} \nУровень повреждения: {v2} ({v3}) Виновник: {v4}",
|
||||
"log_analyzer_death_details": "ID жертвы: {v0} Причина смерти: {v1} \nID убийцы: {v2} \nЗона: {v3}",
|
||||
"log_analyzer_player_login": "Игрок {v0} входит в игру...",
|
||||
"log_analyzer_view_local_inventory": "Просмотр локального инвентаря",
|
||||
"log_analyzer_player_location": "ID игрока: {v0} Местоположение: {v1}",
|
||||
"log_analyzer_game_installation_path": "Путь установки игры",
|
||||
"log_analyzer_select_game_path": "Выберите путь установки игры",
|
||||
"log_analyzer_search_placeholder": "Введите ключевые слова для поиска",
|
||||
"log_analyzer_title": "Анализатор логов",
|
||||
"log_analyzer_description": "Анализ ваших игровых записей (логин, смерти, убийства и другая информация)",
|
||||
"log_analyzer_window_title": "SCToolbox: Анализатор логов"
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"@@locale": "zh_CN",
|
||||
"@auto_translate_locale": "zh-cn",
|
||||
"@@auto_translate_locale": "zh-cn",
|
||||
"app_language_name": "简体中文",
|
||||
"@app_language_name": {},
|
||||
"app_language_code": "zh_CN",
|
||||
@ -322,8 +322,8 @@
|
||||
"@home_action_info_warning": {},
|
||||
"localization_info_machine_translation_warning": "您正在使用游戏内置文本,官方文本目前为机器翻译(截至3.21.0),建议您在下方安装社区汉化。",
|
||||
"@localization_info_machine_translation_warning": {},
|
||||
"localization_info_translation_status": "汉化状态",
|
||||
"@localization_info_translation_status": {},
|
||||
"localization_info_translation": "游戏汉化",
|
||||
"@localization_info_translation": {},
|
||||
"localization_info_enabled": "启用({v0}):",
|
||||
"@localization_info_enabled": {},
|
||||
"localization_info_installed_version": "已安装版本:{v0}",
|
||||
@ -508,8 +508,6 @@
|
||||
"@app_splash_almost_done": {},
|
||||
"tools_hosts_info_rsi_official_website": "RSI 官网",
|
||||
"@tools_hosts_info_rsi_official_website": {},
|
||||
"tools_hosts_info_rsi_zendesk": "RSI Zendesk 客服站",
|
||||
"@tools_hosts_info_rsi_zendesk": {},
|
||||
"tools_hosts_info_rsi_customer_service": "RSI 客服站",
|
||||
"@tools_hosts_info_rsi_customer_service": {},
|
||||
"tools_hosts_info_dns_query_and_test": "正在查询 DNS 并测试可访问性 请耐心等待...",
|
||||
@ -544,7 +542,7 @@
|
||||
"@tools_action_info_view_critical_system_info": {},
|
||||
"tools_action_p4k_download_repair": "P4K 分流下载 / 修复",
|
||||
"@tools_action_p4k_download_repair": {},
|
||||
"tools_action_info_p4k_download_repair_tip": "使用星际公民中文百科提供的分流下载服务,可用于下载或修复 p4k。 \n资源有限,请勿滥用。",
|
||||
"tools_action_info_p4k_download_repair_tip": "使用星际公民中文百科提供的分流下载服务,可用于下载或修复 p4k。 \n版本信息:{v0}",
|
||||
"@tools_action_info_p4k_download_repair_tip": {},
|
||||
"tools_action_hosts_acceleration_experimental": "Hosts 加速(实验性)",
|
||||
"@tools_action_hosts_acceleration_experimental": {},
|
||||
@ -580,7 +578,7 @@
|
||||
"@tools_action_info_fix_success_restart": {},
|
||||
"tools_action_clear_shader_cache": "清理着色器缓存",
|
||||
"@tools_action_clear_shader_cache": {},
|
||||
"tools_action_info_shader_cache_issue": "若游戏画面出现异常或版本更新后可使用本工具清理过期的着色器(当大于500M时,建议清理) \n\n缓存大小:{v0} MB",
|
||||
"tools_action_info_shader_cache_issue": "若游戏画面出现异常或版本更新后可使用本工具清理过期的着色器(同时会将 Vulkan 还原为 DX11) \n\n缓存大小:{v0} MB",
|
||||
"@tools_action_info_shader_cache_issue": {},
|
||||
"tools_action_close_photography_mode": "关闭摄影模式",
|
||||
"@tools_action_close_photography_mode": {},
|
||||
@ -636,7 +634,7 @@
|
||||
"@app_init_failed_with_reason": {},
|
||||
"settings_app_language": "语言",
|
||||
"settings_app_language_auto": "自动",
|
||||
"app_common_network_error": "网络异常!\n这可能是您的网络环境存在DNS污染,请尝试更换DNS。\n或服务器正在维护或遭受攻击,稍后再试。 \n进入离线模式... \n\n请谨慎在离线模式中使用。 \n当前版本构建日期:{v0}\n QQ群:940696487 \n错误信息:{v1}",
|
||||
"app_common_network_error": "网络连接失败! \n进入离线模式... \n\n请检查网络连接或在社交论坛获取最新资讯,可尝试在应用设置中方开启内置 DNS 模式 \n当前版本构建日期:{v0}\n QQ群:940696487 \n错误信息:{v1}",
|
||||
"app_common_upgrade_info_error": "获取更新信息失败,请稍后重试。",
|
||||
"doctor_game_error_low_memory": "可用内存不足",
|
||||
"doctor_game_error_low_memory_info": "请尝试增加虚拟内存( 1080p 下, 物理可用+虚拟内存需 > 64G )",
|
||||
@ -654,6 +652,8 @@
|
||||
"doctor_game_error_game_damaged_p4k_file_info": "请尝试删除 Data.p4k 文件 并在启动器校验 或 使用盒子分流。",
|
||||
"doctor_game_error_low_gpu_memory": "可用显存不足",
|
||||
"doctor_game_error_low_gpu_memory_info": "请不要在后台运行其他高显卡占用的 游戏/应用,或更换显卡。",
|
||||
"doctor_game_error_gpu_vulkan_crash": "GPU Vulkan 崩溃",
|
||||
"doctor_game_error_gpu_vulkan_crash_info": "Vulkan 崩溃!这可能是驱动版本或游戏引擎问题,请尝试更新 GPU 驱动 或 使用清理着色器功能为您回退到 DX11",
|
||||
"app_common_error_info": "出现错误: {v0}",
|
||||
"app_common_tip": "提示",
|
||||
"app_common_tip_i_know": "我知道了",
|
||||
@ -702,9 +702,12 @@
|
||||
"home_localization_msg_version_advanced": " (高级汉化)",
|
||||
"home_localization_msg_no_note": "该版本没有提供描述",
|
||||
"home_localization_action_rsi_launcher_localization": "RSI 启动器汉化",
|
||||
"home_localization_action_rsi_launcher_no_game_path_msg": "您当前未安装游戏本体或未选择游戏安装目录,只可使用启动器汉化功能。请确保游戏安装完毕或在盒子设置中添加游戏安装目录后重试。",
|
||||
"home_localization_action_advanced": "高级汉化",
|
||||
"home_localization_action_install_customize": "安装自定义文件",
|
||||
"home_localization_title_localization_tools": "汉化工具",
|
||||
"performance_json_text_dof": "景深效果",
|
||||
"performance_json_text_dof_info": "控制手环页面等的景深效果",
|
||||
"performance_json_text_ssdo": "屏幕光线后处理",
|
||||
"performance_json_text_ssdo_info": "调整光线后处理等级",
|
||||
"performance_json_text_title_graphics": "图形(修改后建议清理着色器)",
|
||||
@ -796,5 +799,104 @@
|
||||
"tools_rsi_launcher_enhance_action_expand": "展开额外功能",
|
||||
"tools_unp4k_missing_runtime": "缺少运行库",
|
||||
"tools_unp4k_missing_runtime_info": "使用此功能需安装 .NET8 运行库,请点击下方按钮下载安装,安装成功后重新打开此页面即可继续使用。",
|
||||
"tools_unp4k_missing_runtime_action_install": "安装运行库"
|
||||
}
|
||||
"tools_unp4k_missing_runtime_action_install": "安装运行库",
|
||||
"settings_title_general": "通用",
|
||||
"settings_item_dns": "使用内置 DNS",
|
||||
"settings_item_dns_info": "开启后可能解决部分地区 DNS 污染的问题",
|
||||
"settings_title_game": "游戏",
|
||||
"about_action_btn_faq": "常见问题",
|
||||
"guide_title_welcome": "欢迎",
|
||||
"guide_info_check_settings": "请检查以下设置是否正确,如有错误请点击右侧图标更正后继续使用",
|
||||
"guide_info_game_download_note": "* 若您的游戏正在下载,请在完成下载后启动一次游戏,并点击刷新按钮。若您只使用启动器增强汉化,确保启动器路径正确后点击完成设置即可",
|
||||
"guide_action_get_help": "获取帮助",
|
||||
"guide_action_complete_setup": "完成设置",
|
||||
"guide_dialog_confirm_complete_setup": "确认完成设置?",
|
||||
"guide_action_info_no_launcher_path_warning": "您尚未选择启动器安装路径,是否确认完成设置?\n\n引导页关闭后,需要您手动前往设置页操作。",
|
||||
"guide_action_info_no_game_path_warning": "您尚未选择游戏安装路径,是否确认完成设置?\n\n引导页关闭后,需要您手动前往设置页操作。",
|
||||
"setting_toast_select_launcher_exe": "选择启动器 exe 文件:“RSI Launcher.exe”",
|
||||
"setting_toast_select_game_file": "选择对应游戏文件到: Bin64/StarCitizen.exe",
|
||||
"input_method_feature_maintenance": "功能维护中,请稍后重试",
|
||||
"input_method_community_input_method_not_installed": "未安装社区输入法支持",
|
||||
"input_method_install_community_input_method_prompt": "是否前往汉化管理安装?\n\n如已安装汉化,请卸载并在重新安装时打开社区输入法支持开关。",
|
||||
"input_method_usage_instructions": "使用说明",
|
||||
"input_method_input_text_instructions": "在上方文本框中输入文字,并将下方转码后的文本粘贴( Ctrl+V )到游戏的文本框中,即可在聊天频道中发送游戏不支持输入的文字。",
|
||||
"input_method_input_placeholder": "请输入文本...",
|
||||
"input_method_encoded_text_placeholder": "这里是转码后的文本...",
|
||||
"input_method_remote_input_service": "远程输入服务:",
|
||||
"input_method_disclaimer": "*本功能建议仅在非公共频道中使用。若用户选择在公共频道中使用本功能,由此产生的任何后果(包括但不限于被其他玩家举报刷屏等),均由用户自行承担。\n*若该功能被滥用,我们将关闭该功能。",
|
||||
"input_method_experimental_input_method": "社区输入法(实验性)",
|
||||
"input_method_auto_copy": "自动复制",
|
||||
"input_method_confirm_enable_remote_input": "确认启用远程输入?",
|
||||
"input_method_enable_remote_input_instructions": "开启此功能后,可通过手机访问远程服务地址,快捷输入文字,省去切换窗口的麻烦,游戏流程不中断。\n\n若弹出防火墙提示,请展开弹窗,手动勾选所有网络类型并允许,否则可能无法正常访问此功能。",
|
||||
"input_method_address_fetch_failed": "获取地址失败,请手动查看电脑IP",
|
||||
"input_method_text_cannot_be_empty": "文本不能为空!",
|
||||
"input_method_send_success": "发送成功!",
|
||||
"input_method_ip_address_not_found": "我们没能找到合适的 ip 地址来访问服务,请您尝试以下地址(左右切换)",
|
||||
"input_method_scan_qr_code": "请使用您的移动设备扫描以下二维码,或手动访问连接",
|
||||
"input_method_service_qr_code": "服务二维码",
|
||||
"input_method_confirm_install_advanced_localization": "确认安装高级汉化?",
|
||||
"input_method_install_community_input_method_support": "安装社区输入法支持",
|
||||
"input_method_community_input_method_support_version": "社区输入法支持:{v0}",
|
||||
"input_method_online_version_prompt": "本功能另有提供在线独立版,点击访问 >",
|
||||
"input_method_support_updated": "社区输入法支持已更新",
|
||||
"input_method_support_updated_to_version": "社区输入法支持已更新到:{v0}",
|
||||
"input_method_auto_translate": "双语翻译:",
|
||||
"input_method_auto_translate_dialog_title": "启用双语翻译?",
|
||||
"input_method_auto_translate_dialog_title_content": "启用后,将使用 Google 翻译服务为您的输入内容增加英文副本,可能会导致响应滞后,若功能异常请关闭。\n\n文本将转发给 Google 服务器,请参阅 Google 的隐私政策。",
|
||||
"support_dev_thanks_message": "感谢您使用 SC汉化盒子,我是其开发者 xkeyC\n汉化盒子致力于开放源代码并为各位玩家提供免费的服务,无偿的服务是一项充满挑战的工作,若您考虑给我送点饮料钱,我将不胜感激。\n捐赠的资金将用于服务器支出、新功能的开发,以及提高软件维护的积极性。",
|
||||
"support_dev_referral_code_message": "如果您还没有注册游戏或填写邀请码,可以考虑我的: STAR-3YXS-SWTC ,感谢你看到这里",
|
||||
"support_dev_title": "支持开发者",
|
||||
"support_dev_github_star_message": "您也可以在 GitHub 上给我的项目点个 Star",
|
||||
"support_dev_github_star_button": "Star 项目",
|
||||
"support_dev_in_game_currency_title": "游戏内货币",
|
||||
"support_dev_in_game_id": "游戏ID: xkeyC",
|
||||
"support_dev_in_game_id_copied": "游戏ID已复制",
|
||||
"support_dev_copy_button": "复制",
|
||||
"support_dev_in_game_currency_message": "您可以在游戏中向我发送 aUEC 作为支持,这将会帮助我在有限的时间里获得更好的游戏体验",
|
||||
"support_dev_alipay": "支付宝",
|
||||
"support_dev_wechat": "微信",
|
||||
"support_dev_donation_disclaimer": "* 请注意:捐赠是无偿赠与,您不会在软件体验上获得额外好处。",
|
||||
"support_dev_back_button": "返回",
|
||||
"support_dev_scroll_hint": "下滑查看更多",
|
||||
"log_analyzer_filter_all": "全部",
|
||||
"log_analyzer_filter_basic_info": "基础信息",
|
||||
"log_analyzer_filter_account_related": "账户相关",
|
||||
"log_analyzer_filter_fatal_collision": "致命碰撞",
|
||||
"log_analyzer_filter_vehicle_damaged": "载具损毁",
|
||||
"log_analyzer_filter_character_death": "角色死亡",
|
||||
"log_analyzer_filter_statistics": "统计信息",
|
||||
"log_analyzer_filter_game_crash": "游戏崩溃",
|
||||
"log_analyzer_filter_local_inventory": "本地库存",
|
||||
"log_analyzer_no_log_file": "未找到 log 文件",
|
||||
"log_analyzer_one_click_diagnosis_header": "----- 汉化盒子一键诊断 -----",
|
||||
"log_analyzer_details_info": "详细信息:{v0}",
|
||||
"log_analyzer_no_crash_detected": "未检测到游戏崩溃信息",
|
||||
"log_analyzer_game_crash": "游戏崩溃 ",
|
||||
"log_analyzer_kill_summary": "击杀总结",
|
||||
"log_analyzer_kill_death_suicide_count": "击杀次数:{v0} 死亡次数:{v1} 自杀次数:{v2} \n载具损毁(软死亡):{v3} 载具损毁(解体):{v4}",
|
||||
"log_analyzer_play_time": "游玩时长",
|
||||
"log_analyzer_play_time_format": "{v0} 小时 {v1} 分钟 {v2} 秒",
|
||||
"log_analyzer_game_start": "游戏启动",
|
||||
"log_analyzer_game_loading": "游戏加载",
|
||||
"log_analyzer_mode_loading_time": "模式:{v0} 用时:{v1} 秒",
|
||||
"log_analyzer_game_close": "游戏关闭",
|
||||
"log_analyzer_collision_details": "区域:{v0} 玩家驾驶:{v1} 碰撞实体:{v2} \n碰撞载具: {v3} 碰撞距离:{v4} ",
|
||||
"log_analyzer_soft_death": "软死亡",
|
||||
"log_analyzer_disintegration": "解体",
|
||||
"log_analyzer_vehicle_damage_details": "载具型号:{v0} \n区域:{v1} \n损毁等级:{v2} ({v3}) 责任方:{v4}",
|
||||
"log_analyzer_death_details": "受害者ID:{v0} 死因:{v1} \n击杀者ID:{v2} \n区域:{v3}",
|
||||
"log_analyzer_player_login": "玩家 {v0} 登录 ...",
|
||||
"log_analyzer_view_local_inventory": "查看本地库存",
|
||||
"log_analyzer_player_location": "玩家ID:{v0} 位置:{v1}",
|
||||
"log_analyzer_game_installation_path": "游戏安装路径",
|
||||
"log_analyzer_select_game_path": "请选择游戏安装路径",
|
||||
"log_analyzer_search_placeholder": "输入关键字搜索内容",
|
||||
"log_analyzer_title": "log 分析器",
|
||||
"log_analyzer_description": "分析您的游玩记录 (登录、死亡、击杀 等信息)",
|
||||
"log_analyzer_window_title": "SC汉化盒子: log 分析器",
|
||||
"nav_title": "导航",
|
||||
"nav_third_party_service_disclaimer": "*对应链接指向的服务由第三方提供,我们不对其做任何担保,请用户自行判断使用风险 | ",
|
||||
"nav_website_navigation_data_provided_by": "网站导航数据由",
|
||||
"nav_provided_by": "提供",
|
||||
"nav_fetching_data": "正在获取数据..."
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"@@locale": "zh_TW",
|
||||
"@auto_translate_locale": "zh-cn",
|
||||
"@@auto_translate_locale": "zh-tw",
|
||||
"app_language_name": "繁體中文",
|
||||
"@app_language_name": {},
|
||||
"app_language_code": "zh_TW",
|
||||
@ -322,8 +322,8 @@
|
||||
"@home_action_info_warning": {},
|
||||
"localization_info_machine_translation_warning": "您目前正在使用遊戲內建翻譯文件,官方內建文件截止至 3.21.0 都是機器翻譯,建議安裝下方提供的社群翻譯或是來自其他來源的社群翻譯文件。",
|
||||
"@localization_info_machine_translation_warning": {},
|
||||
"localization_info_translation_status": "翻譯狀態",
|
||||
"@localization_info_translation_status": {},
|
||||
"localization_info_translation": "遊戲翻譯",
|
||||
"@localization_info_translation": {},
|
||||
"localization_info_enabled": "啟用({v0}):",
|
||||
"@localization_info_enabled": {},
|
||||
"localization_info_installed_version": "已安裝:{v0}",
|
||||
@ -508,8 +508,6 @@
|
||||
"@app_splash_almost_done": {},
|
||||
"tools_hosts_info_rsi_official_website": "RSI 官方網站",
|
||||
"@tools_hosts_info_rsi_official_website": {},
|
||||
"tools_hosts_info_rsi_zendesk": "RSI Zendesk 客服站",
|
||||
"@tools_hosts_info_rsi_zendesk": {},
|
||||
"tools_hosts_info_rsi_customer_service": "RSI 客服站",
|
||||
"@tools_hosts_info_rsi_customer_service": {},
|
||||
"tools_hosts_info_dns_query_and_test": "正在查詢 DNS 並測試可瀏覽性 請耐心等待...",
|
||||
@ -544,7 +542,7 @@
|
||||
"@tools_action_info_view_critical_system_info": {},
|
||||
"tools_action_p4k_download_repair": "P4K 分流下載 / 修復",
|
||||
"@tools_action_p4k_download_repair": {},
|
||||
"tools_action_info_p4k_download_repair_tip": "使用星際公民中文百科提供的分流下載服務,可用於下載或修復 p4k。 \n資源有限,請勿濫用。",
|
||||
"tools_action_info_p4k_download_repair_tip": "使用星際公民中文百科提供的分流下載服務,可用於下載或修復 p4k。 \n版本資訊:{v0}",
|
||||
"@tools_action_info_p4k_download_repair_tip": {},
|
||||
"tools_action_hosts_acceleration_experimental": "Hosts 加速(Beta)",
|
||||
"@tools_action_hosts_acceleration_experimental": {},
|
||||
@ -580,7 +578,7 @@
|
||||
"@tools_action_info_fix_success_restart": {},
|
||||
"tools_action_clear_shader_cache": "刪除著色器快取",
|
||||
"@tools_action_clear_shader_cache": {},
|
||||
"tools_action_info_shader_cache_issue": "若遊戲畫面出現異常或版本更新後可使用此工具清除著色器快取 \n\n建議清理:快取大於 500 MB\n快取大小:{v0} MB",
|
||||
"tools_action_info_shader_cache_issue": "若遊戲畫面出現異常或版本更新後可使用此工具清除著色器快取 \n\n(同時會將 Vulkan 還原為 DX11)\n快取大小:{v0} MB",
|
||||
"@tools_action_info_shader_cache_issue": {},
|
||||
"tools_action_close_photography_mode": "攝影模式",
|
||||
"@tools_action_close_photography_mode": {},
|
||||
@ -636,7 +634,7 @@
|
||||
"@app_init_failed_with_reason": {},
|
||||
"settings_app_language": "語言",
|
||||
"settings_app_language_auto": "自動",
|
||||
"app_common_network_error": "網路異常!\n這可能是您的網路環境存在DNS汙染,請嘗試更換DNS。\n或伺服器正在維護或遭受攻擊,稍後再試。 \n進入離線模式... \n\n請謹慎在離線模式中使用。 \n目前版本構建日期:{v0}\n QQ群:940696487 \n錯誤資訊:{v1}",
|
||||
"app_common_network_error": "網路連線失敗!\n進入離線模式... \n\n 請檢查網路連線或在社群論壇取得最新資訊,可嘗試在應用程式設定中方開啟內建DNS 模式\n目前版本建置日期: {v0}\n QQ群:940696487 \n錯誤訊息:{v1}",
|
||||
"app_common_upgrade_info_error": "獲取更新資訊失敗,請稍後重試。",
|
||||
"doctor_game_error_low_memory": "可用記憶體不足",
|
||||
"doctor_game_error_low_memory_info": "請嘗試增加虛擬記憶體( 1080p 下, 物理可用+虛擬記憶體需 > 64G )",
|
||||
@ -705,6 +703,8 @@
|
||||
"home_localization_action_advanced": "進階翻譯",
|
||||
"home_localization_action_install_customize": "安裝自訂文件",
|
||||
"home_localization_title_localization_tools": "翻譯工具",
|
||||
"performance_json_text_dof": "景深效果",
|
||||
"performance_json_text_dof_info": "控製手環頁面等的景深效果",
|
||||
"performance_json_text_ssdo": "螢幕光線後處理",
|
||||
"performance_json_text_ssdo_info": "調整光線後處理等級",
|
||||
"performance_json_text_title_graphics": "圖形(修改後建議刪除著色器快取)",
|
||||
@ -786,5 +786,119 @@
|
||||
"tools_action_unp4k_info": "解包星際公民 p4k 文件",
|
||||
"tools_unp4k_title": "P4K 查看器 -> {v0}",
|
||||
"tools_unp4k_view_file": "單擊文件以預覽",
|
||||
"tools_unp4k_msg_unknown_file_type": "未知文件類型\n{v0}"
|
||||
}
|
||||
"tools_unp4k_msg_unknown_file_type": "未知文件類型\n{v0}",
|
||||
"home_localization_action_rsi_launcher_no_game_path_msg": "您當前未安裝遊戲本體或未選擇遊戲安裝目錄,只可使用啟動器翻譯功能。請確保遊戲安裝完畢或在工具箱設置中添加遊戲安裝目錄後重試。",
|
||||
"home_localization_select_customize_file_ini": "請選擇 ini 文件",
|
||||
"home_localization_select_customize_file": "請選擇自定義翻譯文件",
|
||||
"home_localization_action_select_customize_file": "點擊選擇 ini 文件",
|
||||
"home_localization_ptu_advanced_localization_tip_title": "推薦使用高級翻譯",
|
||||
"home_localization_ptu_advanced_localization_tip_title_info": "在 PTU/EPTU 等測試頻道 ,當前翻譯文本可能與遊戲不同步,使用高級翻譯可以減少亂碼產生。",
|
||||
"tools_rsi_launcher_enhance_action_fold": "收起額外功能",
|
||||
"tools_rsi_launcher_enhance_action_expand": "展開額外功能",
|
||||
"tools_unp4k_missing_runtime": "缺少運行庫",
|
||||
"tools_unp4k_missing_runtime_info": "使用此功能需安裝 .NET8 運行庫,請點擊下方按鈕下載安裝,安裝成功後重新打開此頁面即可繼續使用。",
|
||||
"tools_unp4k_missing_runtime_action_install": "安裝運行庫",
|
||||
"doctor_game_error_gpu_vulkan_crash": "GPU Vulkan 崩潰",
|
||||
"doctor_game_error_gpu_vulkan_crash_info": "Vulkan 崩潰!這可能是驅動版本或遊戲引擎問題,請嘗試更新 GPU 驅動 或 使用清理著色器功能為您回退到 DX11",
|
||||
"settings_title_general": "通用",
|
||||
"settings_item_dns": "使用內置 DNS",
|
||||
"settings_item_dns_info": "開啟後可能解決部分地區 DNS 污染的問題",
|
||||
"settings_title_game": "遊戲",
|
||||
"about_action_btn_faq": "常見問題",
|
||||
"guide_title_welcome": "歡迎",
|
||||
"guide_info_check_settings": "請檢查以下設置是否正確,如有錯誤請點擊右側圖標更正後繼續使用",
|
||||
"guide_info_game_download_note": "* 若您的遊戲正在下載,請在完成下載後啟動一次遊戲,並點擊刷新按鈕。若您只使用啟動器增強漢化,確保啟動器路徑正確後點擊完成設置即可",
|
||||
"guide_action_get_help": "獲取幫助",
|
||||
"guide_action_complete_setup": "完成設置",
|
||||
"guide_dialog_confirm_complete_setup": "確認完成設置?",
|
||||
"guide_action_info_no_launcher_path_warning": "您尚未選擇啟動器安裝路徑,是否確認完成設置?\n\n引導頁關閉後,需要您手動前往設置頁操作。",
|
||||
"guide_action_info_no_game_path_warning": "您尚未選擇遊戲安裝路徑,是否確認完成設置?\n\n引導頁關閉後,需要您手動前往設置頁操作。",
|
||||
"setting_toast_select_launcher_exe": "選擇啟動器 exe 文件:“RSI Launcher.exe”",
|
||||
"setting_toast_select_game_file": "選擇對應遊戲文件到: Bin64/StarCitizen.exe",
|
||||
"input_method_feature_maintenance": "功能維護中,請稍後重試",
|
||||
"input_method_community_input_method_not_installed": "未安裝社區輸入法支持",
|
||||
"input_method_install_community_input_method_prompt": "是否前往漢化管理安裝?\n\n如已安裝漢化,請卸載並在重新安裝時打開社區輸入法支持開關。",
|
||||
"input_method_usage_instructions": "使用說明",
|
||||
"input_method_input_text_instructions": "在上方文本框中輸入文字,並將下方轉碼後的文本複製到遊戲的文本框中,即可在聊天頻道中發送遊戲不支持輸入的文字。",
|
||||
"input_method_input_placeholder": "請輸入文本...",
|
||||
"input_method_encoded_text_placeholder": "這裡是轉碼後的文本...",
|
||||
"input_method_remote_input_service": "遠程輸入服務:",
|
||||
"input_method_disclaimer": "*本功能建議僅在非公共頻道中使用。若用戶選擇在公共頻道中使用本功能,由此產生的任何後果(包括但不限於被其他玩家舉報刷屏等),均由用戶自行承擔。\n*若該功能被濫用,我們將關閉該功能。",
|
||||
"input_method_experimental_input_method": "社區輸入法(實驗性)",
|
||||
"input_method_auto_copy": "自動複製",
|
||||
"input_method_confirm_enable_remote_input": "確認啟用遠程輸入?",
|
||||
"input_method_enable_remote_input_instructions": "開啟此功能後,可通過手機訪問遠程服務地址,快捷輸入文字,省去切換窗口的麻煩,遊戲流程不中斷。\n\n若彈出防火牆提示,請展開彈窗,手動勾選所有網絡類型並允許,否則可能無法正常訪問此功能。",
|
||||
"input_method_address_fetch_failed": "獲取地址失敗,請手動查看電腦IP",
|
||||
"input_method_text_cannot_be_empty": "文本不能為空!",
|
||||
"input_method_send_success": "發送成功!",
|
||||
"input_method_ip_address_not_found": "我們沒能找到合適的 ip 地址來訪問服務,請您嘗試以下地址(左右切換)",
|
||||
"input_method_scan_qr_code": "請使用您的移動設備掃描以下二維碼,或手動訪問連接",
|
||||
"input_method_service_qr_code": "服務二維碼",
|
||||
"input_method_confirm_install_advanced_localization": "確認安裝高級漢化?",
|
||||
"input_method_install_community_input_method_support": "安裝社區輸入法支持",
|
||||
"input_method_community_input_method_support_version": "社區輸入法支持:{v0}",
|
||||
"input_method_online_version_prompt": "本功能另有提供在線獨立版,點擊訪問 >",
|
||||
"input_method_support_updated": "社區輸入法支持已更新",
|
||||
"input_method_support_updated_to_version": "社區輸入法支持已更新到:{v0}",
|
||||
"input_method_auto_translate": "雙語翻譯:",
|
||||
"input_method_auto_translate_dialog_title": "啟用雙語翻譯?",
|
||||
"input_method_auto_translate_dialog_title_content": "啟用後,將使用 Google 翻譯服務為您的輸入內容增加英文副本,可能會導致響應滯後,若功能異常請關閉。 \n\n文本將轉發給 Google 服務器,請參閱 Google 的隱私政策。",
|
||||
"support_dev_thanks_message": "感謝您使用 SC工具箱,我是其開發者 xkeyC\n工具箱致力於開放原始碼並為各位玩家提供免費的服務,無償的服務是一項充滿挑戰的工作,若您考慮給我送點飲料錢,我將不勝感激。\n捐贈的資金將用於伺服器支出、新功能的開發,以及提高軟體維護的積極性。",
|
||||
"support_dev_thanks_message_part1": "感謝您使用 SC工具箱,我是其開發者 xkeyC\n工具箱致力於開放原始碼並為各位玩家提供免費的服務,",
|
||||
"support_dev_thanks_message_part2": "無償的服務是一項充滿挑戰的工作,若您考慮給我送點飲料錢,我將不勝感激。\n捐贈的資金將用於伺服器支出、新功能的開發,以及提高軟體維護的積極性。",
|
||||
"support_dev_referral_code_message": "如果您還沒有註冊遊戲或填寫邀請碼,可以考慮我的: STAR-3YXS-SWTC ,感謝你看到這裡",
|
||||
"support_dev_title": "支持開發者",
|
||||
"support_dev_github_star_message": "您也可以在 GitHub 上給我的專案點個 Star",
|
||||
"support_dev_github_star_button": "Star 專案",
|
||||
"support_dev_in_game_currency_title": "遊戲內貨幣",
|
||||
"support_dev_in_game_id": "遊戲ID: xkeyC",
|
||||
"support_dev_in_game_id_copied": "遊戲ID已複製",
|
||||
"support_dev_copy_button": "複製",
|
||||
"support_dev_in_game_currency_message": "您可以在遊戲中向我發送 aUEC 作為支持,這將會幫助我在有限的時間裡獲得更好的遊戲體驗",
|
||||
"support_dev_alipay": "支付寶",
|
||||
"support_dev_wechat": "微信",
|
||||
"support_dev_donation_disclaimer": "* 請注意:捐贈是無償贈與,您不會在軟體體驗上獲得額外好處。",
|
||||
"support_dev_back_button": "返回",
|
||||
"support_dev_scroll_hint": "下滑查看更多",
|
||||
"log_analyzer_filter_all": "全部",
|
||||
"log_analyzer_filter_basic_info": "基礎資訊",
|
||||
"log_analyzer_filter_account_related": "帳戶相關",
|
||||
"log_analyzer_filter_fatal_collision": "致命碰撞",
|
||||
"log_analyzer_filter_vehicle_damaged": "載具損毀",
|
||||
"log_analyzer_filter_character_death": "角色死亡",
|
||||
"log_analyzer_filter_statistics": "統計資訊",
|
||||
"log_analyzer_filter_game_crash": "遊戲崩潰",
|
||||
"log_analyzer_filter_local_inventory": "本地庫存",
|
||||
"log_analyzer_no_log_file": "未找到 log 文件",
|
||||
"log_analyzer_one_click_diagnosis_header": "----- 工具箱疑難排解 -----",
|
||||
"log_analyzer_details_info": "詳細資訊:{v0}",
|
||||
"log_analyzer_no_crash_detected": "未檢測到遊戲崩潰資訊",
|
||||
"log_analyzer_game_crash": "遊戲崩潰 ",
|
||||
"log_analyzer_kill_summary": "擊殺總結",
|
||||
"log_analyzer_kill_death_suicide_count": "擊殺次數:{v0} 死亡次數:{v1} 自殺次數:{v2} \n載具損壞(軟死亡):{v3} 載具損壞(解體):{v4}",
|
||||
"log_analyzer_play_time": "遊玩時長",
|
||||
"log_analyzer_play_time_format": "{v0} 小時 {v1} 分鐘 {v2} 秒",
|
||||
"log_analyzer_game_start": "遊戲啟動",
|
||||
"log_analyzer_game_loading": "遊戲載入",
|
||||
"log_analyzer_mode_loading_time": "模式:{v0} 用時:{v1} 秒",
|
||||
"log_analyzer_game_close": "遊戲關閉",
|
||||
"log_analyzer_collision_details": "區域:{v0} 玩家駕駛:{v1} 碰撞實體:{v2} \n碰撞載具: {v3} 碰撞距離:{v4} ",
|
||||
"log_analyzer_soft_death": "軟死亡",
|
||||
"log_analyzer_disintegration": "解體",
|
||||
"log_analyzer_vehicle_damage_details": "載具型號:{v0} \n區域:{v1} \n損毀等級:{v2} ({v3}) 責任方:{v4}",
|
||||
"log_analyzer_death_details": "受害者ID:{v0} 死因:{v1} \n擊殺者ID:{v2} \n區域:{v3}",
|
||||
"log_analyzer_player_login": "玩家 {v0} 登入 ...",
|
||||
"log_analyzer_view_local_inventory": "查看本地庫存",
|
||||
"log_analyzer_player_location": "玩家ID:{v0} 位置:{v1}",
|
||||
"log_analyzer_game_installation_path": "遊戲安裝路徑",
|
||||
"log_analyzer_select_game_path": "請選擇遊戲安裝路徑",
|
||||
"log_analyzer_search_placeholder": "輸入關鍵字搜索內容",
|
||||
"log_analyzer_title": "log 分析器",
|
||||
"log_analyzer_description": "分析您的遊玩記錄 (登入、死亡、擊殺 等資訊)",
|
||||
"log_analyzer_window_title": "SC工具箱: log 分析器",
|
||||
"nav_title": "導航",
|
||||
"nav_third_party_service_disclaimer": "*對應鏈接指向的服務由第三方提供,我們不對其做任何擔保,請用戶自行判斷使用風險 | ",
|
||||
"nav_website_navigation_data_provided_by": "網站導航數據由",
|
||||
"nav_provided_by": "提供",
|
||||
"nav_fetching_data": "正在獲取數據..."
|
||||
}
|
@ -1,17 +1,24 @@
|
||||
import 'dart:io';
|
||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||
import 'package:desktop_webview_window/desktop_webview_window.dart';
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:starcitizen_doctor/generated/l10n.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
|
||||
import 'app.dart';
|
||||
import 'common/utils/multi_window_manager.dart';
|
||||
|
||||
void main(List<String> args) async {
|
||||
// webview window
|
||||
if (runWebViewTitleBarWidget(args,
|
||||
backgroundColor: const Color.fromRGBO(19, 36, 49, 1),
|
||||
builder: _defaultWebviewTitleBar)) {
|
||||
backgroundColor: const Color.fromRGBO(19, 36, 49, 1), builder: _defaultWebviewTitleBar)) {
|
||||
return;
|
||||
}
|
||||
if (args.firstOrNull == 'multi_window') {
|
||||
MultiWindowManager.runSubWindowApp(args);
|
||||
return;
|
||||
}
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
@ -26,16 +33,27 @@ _initWindow() async {
|
||||
TitleBarStyle.hidden,
|
||||
windowButtonVisibility: false,
|
||||
);
|
||||
await windowManager.setSize(const Size(1280, 810));
|
||||
await windowManager.setMinimumSize(const Size(1280, 810));
|
||||
await windowManager.center(animate: true);
|
||||
}
|
||||
|
||||
class App extends HookConsumerWidget {
|
||||
class App extends HookConsumerWidget with WindowListener {
|
||||
const App({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final router = ref.watch(routerProvider);
|
||||
final appState = ref.watch(appGlobalModelProvider);
|
||||
|
||||
useEffect(() {
|
||||
windowManager.addListener(this);
|
||||
windowManager.setPreventClose(true);
|
||||
return () async {
|
||||
windowManager.removeListener(this);
|
||||
};
|
||||
}, const []);
|
||||
|
||||
return FluentApp.router(
|
||||
title: "StarCitizenToolBox",
|
||||
restorationScopeId: "StarCitizenToolBox",
|
||||
@ -50,8 +68,7 @@ class App extends HookConsumerWidget {
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
builder: (context, child) {
|
||||
return MediaQuery(
|
||||
data:
|
||||
MediaQuery.of(context).copyWith(textScaler: TextScaler.noScaling),
|
||||
data: MediaQuery.of(context).copyWith(textScaler: TextScaler.noScaling),
|
||||
child: child ?? const SizedBox(),
|
||||
);
|
||||
},
|
||||
@ -65,9 +82,8 @@ class App extends HookConsumerWidget {
|
||||
micaBackgroundColor: appState.themeConf.micaColor,
|
||||
buttonTheme: ButtonThemeData(
|
||||
defaultButtonStyle: ButtonStyle(
|
||||
shape: ButtonState.all(RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
side: BorderSide(color: Colors.white.withOpacity(.01)))),
|
||||
shape: WidgetStateProperty.all(RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4), side: BorderSide(color: Colors.white.withValues(alpha: .01)))),
|
||||
))),
|
||||
locale: appState.appLocale,
|
||||
debugShowCheckedModeBanner: false,
|
||||
@ -76,6 +92,20 @@ class App extends HookConsumerWidget {
|
||||
routeInformationProvider: router.routeInformationProvider,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> onWindowClose() async {
|
||||
debugPrint("onWindowClose");
|
||||
if (await windowManager.isPreventClose()) {
|
||||
final windows = await DesktopMultiWindow.getAllSubWindowIds();
|
||||
for (final id in windows) {
|
||||
await WindowController.fromWindowId(id).close();
|
||||
}
|
||||
await windowManager.destroy();
|
||||
exit(0);
|
||||
}
|
||||
super.onWindowClose();
|
||||
}
|
||||
}
|
||||
|
||||
Widget _defaultWebviewTitleBar(BuildContext context) {
|
||||
@ -86,6 +116,7 @@ Widget _defaultWebviewTitleBar(BuildContext context) {
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
if (Platform.isMacOS) const SizedBox(width: 96),
|
||||
IconButton(
|
||||
onPressed: !state.canGoBack ? null : controller.back,
|
||||
icon: const Icon(FluentIcons.chevron_left),
|
||||
|
@ -5,7 +5,7 @@ import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'package:aria2/aria2.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:starcitizen_doctor/api/api.dart';
|
||||
import 'package:starcitizen_doctor/common/helper/system_helper.dart';
|
||||
import 'package:starcitizen_doctor/common/rust/api/rs_process.dart'
|
||||
@ -103,7 +103,7 @@ class Aria2cModel extends _$Aria2cModel {
|
||||
arguments: [
|
||||
"-V",
|
||||
"-c",
|
||||
"-x 10",
|
||||
"-x 16",
|
||||
"--dir=${state.aria2cDir}\\downloads",
|
||||
"--disable-ipv6",
|
||||
"--enable-rpc",
|
||||
@ -121,7 +121,8 @@ class Aria2cModel extends _$Aria2cModel {
|
||||
String launchError = "";
|
||||
|
||||
stream.listen((event) {
|
||||
dPrint("Aria2cManager.rs_process event === $event");
|
||||
dPrint(
|
||||
"Aria2cManager.rs_process event === [${event.rsPid}] ${event.dataType} >> ${event.data}");
|
||||
switch (event.dataType) {
|
||||
case rs_process.RsProcessStreamDataType.output:
|
||||
if (event.data.contains("IPv4 RPC: listening on TCP port")) {
|
||||
|
@ -20,7 +20,9 @@ mixin _$Aria2cModelState {
|
||||
Aria2c? get aria2c => throw _privateConstructorUsedError;
|
||||
Aria2GlobalStat? get aria2globalStat => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of Aria2cModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$Aria2cModelStateCopyWith<Aria2cModelState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@ -45,6 +47,8 @@ class _$Aria2cModelStateCopyWithImpl<$Res, $Val extends Aria2cModelState>
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of Aria2cModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -89,6 +93,8 @@ class __$$Aria2cModelStateImplCopyWithImpl<$Res>
|
||||
$Res Function(_$Aria2cModelStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of Aria2cModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -159,7 +165,9 @@ class _$Aria2cModelStateImpl
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, aria2cDir, aria2c, aria2globalStat);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of Aria2cModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$Aria2cModelStateImplCopyWith<_$Aria2cModelStateImpl> get copyWith =>
|
||||
@ -179,8 +187,11 @@ abstract class _Aria2cModelState implements Aria2cModelState {
|
||||
Aria2c? get aria2c;
|
||||
@override
|
||||
Aria2GlobalStat? get aria2globalStat;
|
||||
|
||||
/// Create a copy of Aria2cModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$Aria2cModelStateImplCopyWith<_$Aria2cModelStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ part of 'aria2c.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$aria2cModelHash() => r'8efef4661876de219510cf3e7e2d86c02405eb26';
|
||||
String _$aria2cModelHash() => r'3d51aeefd92e5291dca1f01db961f9c5496ec24f';
|
||||
|
||||
/// See also [Aria2cModel].
|
||||
@ProviderFor(Aria2cModel)
|
||||
@ -22,4 +22,4 @@ final aria2cModelProvider =
|
||||
|
||||
typedef _$Aria2cModel = AutoDisposeNotifier<Aria2cModelState>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
@ -83,10 +83,7 @@ class Unp4kCModel extends _$Unp4kCModel {
|
||||
errorMessage: "${state.errorMessage}\n${event.data}");
|
||||
}
|
||||
if (!_hasUnp4kRunTimeError) {
|
||||
if (state.errorMessage.contains(
|
||||
"You must install .NET to run this application") ||
|
||||
state.errorMessage.contains(
|
||||
"You must install or update .NET to run this application")) {
|
||||
if (checkRunTimeError(state.errorMessage)) {
|
||||
_hasUnp4kRunTimeError = true;
|
||||
AnalyticsApi.touch("unp4k_no_runtime");
|
||||
}
|
||||
@ -246,6 +243,19 @@ class Unp4kCModel extends _$Unp4kCModel {
|
||||
}
|
||||
}
|
||||
|
||||
static bool checkRunTimeError(String errorMessage) {
|
||||
if (errorMessage
|
||||
.contains("You must install .NET to run this application") ||
|
||||
errorMessage.contains(
|
||||
"You must install or update .NET to run this application") ||
|
||||
errorMessage.contains(
|
||||
"It was not possible to find any compatible framework version")) {
|
||||
AnalyticsApi.touch("unp4k_no_runtime");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static Future<Uint8List> unp4kTools(
|
||||
String applicationBinaryModuleDir, List<String> args) async {
|
||||
await BinaryModuleConf.extractModule(
|
||||
|
@ -26,7 +26,9 @@ mixin _$Unp4kcState {
|
||||
throw _privateConstructorUsedError;
|
||||
String get errorMessage => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of Unp4kcState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$Unp4kcStateCopyWith<Unp4kcState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@ -57,6 +59,8 @@ class _$Unp4kcStateCopyWithImpl<$Res, $Val extends Unp4kcState>
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of Unp4kcState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -127,6 +131,8 @@ class __$$Unp4kcStateImplCopyWithImpl<$Res>
|
||||
_$Unp4kcStateImpl _value, $Res Function(_$Unp4kcStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of Unp4kcState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -255,7 +261,9 @@ class _$Unp4kcStateImpl with DiagnosticableTreeMixin implements _Unp4kcState {
|
||||
tempOpenFile,
|
||||
errorMessage);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of Unp4kcState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$Unp4kcStateImplCopyWith<_$Unp4kcStateImpl> get copyWith =>
|
||||
@ -286,8 +294,11 @@ abstract class _Unp4kcState implements Unp4kcState {
|
||||
MapEntry<String, String>? get tempOpenFile;
|
||||
@override
|
||||
String get errorMessage;
|
||||
|
||||
/// Create a copy of Unp4kcState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$Unp4kcStateImplCopyWith<_$Unp4kcStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ part of 'unp4kc.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$unp4kCModelHash() => r'23b148d557f55aa6050f1b1e38a3465d22a09034';
|
||||
String _$unp4kCModelHash() => r'636da3fe20d1fa94917dd63934f08f8dbffc8a9d';
|
||||
|
||||
/// See also [Unp4kCModel].
|
||||
@ProviderFor(Unp4kCModel)
|
||||
@ -22,4 +22,4 @@ final unp4kCModelProvider =
|
||||
|
||||
typedef _$Unp4kCModel = AutoDisposeNotifier<Unp4kcState>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
@ -1,10 +1,12 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
import 'package:starcitizen_doctor/api/analytics.dart';
|
||||
import 'package:starcitizen_doctor/app.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/const_conf.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/conf.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/url_conf.dart';
|
||||
import 'package:starcitizen_doctor/widgets/src/flow_number_text.dart';
|
||||
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
||||
@ -16,82 +18,388 @@ class AboutUI extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isTipTextCn = useState(false);
|
||||
final pageCtrl = usePageController();
|
||||
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Spacer(),
|
||||
const SizedBox(height: 32),
|
||||
Image.asset("assets/app_logo.png", width: 128, height: 128),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
S.current.app_index_version_info(
|
||||
ConstConf.appVersion, ConstConf.isMSE ? "" : " Dev"),
|
||||
style: const TextStyle(fontSize: 18)),
|
||||
const SizedBox(height: 12),
|
||||
Button(
|
||||
onPressed: () => _onCheckUpdate(context, ref),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Text(S.current.about_check_update),
|
||||
)),
|
||||
const SizedBox(height: 32),
|
||||
Container(
|
||||
margin: const EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).cardColor,
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
S.current.about_app_description,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withOpacity(.9)),
|
||||
return PageView(
|
||||
scrollDirection: Axis.vertical,
|
||||
controller: pageCtrl,
|
||||
children: [
|
||||
_makeAbout(context, ref, isTipTextCn, pageCtrl),
|
||||
_makeDonate(context, ref, pageCtrl),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _makeAbout(BuildContext context, WidgetRef ref, ValueNotifier<bool> isTipTextCn, PageController pageCtrl) {
|
||||
return Stack(
|
||||
children: [
|
||||
Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Spacer(),
|
||||
const SizedBox(height: 32),
|
||||
Image.asset("assets/app_logo.png", width: 128, height: 128),
|
||||
const SizedBox(height: 6),
|
||||
Text(S.current.app_index_version_info(ConstConf.appVersion, ConstConf.isMSE ? "" : " Dev"),
|
||||
style: const TextStyle(fontSize: 18)),
|
||||
const SizedBox(height: 12),
|
||||
Button(
|
||||
onPressed: () => _onCheckUpdate(context, ref),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Text(S.current.about_check_update),
|
||||
)),
|
||||
const SizedBox(height: 32),
|
||||
Container(
|
||||
margin: const EdgeInsets.all(24),
|
||||
decoration:
|
||||
BoxDecoration(color: FluentTheme.of(context).cardColor, borderRadius: BorderRadius.circular(12)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
S.current.about_app_description,
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .9)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
makeAnalyticsWidget(context),
|
||||
const SizedBox(height: 24),
|
||||
makeLinksRow(),
|
||||
const Spacer(),
|
||||
Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
AnimatedSize(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width * .35,
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).cardColor.withValues(alpha: .06),
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
child: IconButton(
|
||||
icon: Padding(
|
||||
padding: const EdgeInsets.all(3),
|
||||
child: Text(
|
||||
isTipTextCn.value ? tipTextCN : tipTextEN,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontSize: 12, color: Colors.white.withValues(alpha: .9)),
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
isTipTextCn.value = !isTipTextCn.value;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 12,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Center(
|
||||
child: makeNavButton(pageCtrl, 1),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _makeDonate(BuildContext context, WidgetRef ref, PageController pageCtrl) {
|
||||
final donationTypeNotifier = useState('alipay');
|
||||
final bubbleMessages = [
|
||||
S.current.support_dev_thanks_message,
|
||||
S.current.support_dev_referral_code_message,
|
||||
];
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
makeNavButton(pageCtrl, 0),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
Text(
|
||||
S.current.support_dev_title,
|
||||
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
|
||||
// 聊天头像和气泡消息
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
child: CacheNetImage(
|
||||
url:
|
||||
"https://git.scbox.xkeyc.cn/avatars/56a93334e892ba48f4fab453b8205624d661e4f7748cdb52bed47e5dc0c85de5?size=512",
|
||||
width: 50,
|
||||
height: 50,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
for (var i = 0; i < bubbleMessages.length; i++)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8),
|
||||
child: SelectionArea(child: ChatBubble(message: bubbleMessages[i])),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 32),
|
||||
|
||||
// 捐赠方式选择
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
_donationMethodButton(
|
||||
context: context,
|
||||
title: 'AliPay',
|
||||
icon: FontAwesomeIcons.alipay,
|
||||
isSelected: donationTypeNotifier.value == 'alipay',
|
||||
color: const Color(0xFF1677FF),
|
||||
onTap: () => donationTypeNotifier.value = 'alipay',
|
||||
),
|
||||
_donationMethodButton(
|
||||
context: context,
|
||||
title: 'WeChat',
|
||||
icon: FontAwesomeIcons.weixin,
|
||||
isSelected: donationTypeNotifier.value == 'wechat',
|
||||
color: const Color(0xFF07C160),
|
||||
onTap: () => donationTypeNotifier.value = 'wechat',
|
||||
),
|
||||
_donationMethodButton(
|
||||
context: context,
|
||||
title: 'QQ',
|
||||
icon: FontAwesomeIcons.qq,
|
||||
isSelected: donationTypeNotifier.value == 'qq',
|
||||
color: const Color(0xFF12B7F5),
|
||||
onTap: () => donationTypeNotifier.value = 'qq',
|
||||
),
|
||||
_donationMethodButton(
|
||||
context: context,
|
||||
title: 'aUEC',
|
||||
icon: FontAwesomeIcons.gamepad,
|
||||
isSelected: donationTypeNotifier.value == 'uec',
|
||||
color: const Color(0xFFFFD700),
|
||||
onTap: () => donationTypeNotifier.value = 'uec',
|
||||
),
|
||||
_donationMethodButton(
|
||||
context: context,
|
||||
title: 'GitHub',
|
||||
icon: FontAwesomeIcons.github,
|
||||
isSelected: donationTypeNotifier.value == 'github',
|
||||
color: Colors.white,
|
||||
onTap: () => donationTypeNotifier.value = 'github',
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// 二维码显示区域
|
||||
Container(
|
||||
constraints: BoxConstraints(minHeight: 300),
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
transitionBuilder: (Widget child, Animation<double> animation) {
|
||||
return FadeTransition(opacity: animation, child: child);
|
||||
},
|
||||
child: _buildDonationQRCode(donationTypeNotifier.value, context),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 48),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _donationMethodButton({
|
||||
required BuildContext context,
|
||||
required String title,
|
||||
required IconData icon,
|
||||
required bool isSelected,
|
||||
required Color color,
|
||||
required VoidCallback onTap,
|
||||
}) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Button(
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.resolveWith((states) => isSelected
|
||||
? ButtonThemeData.buttonColor(context, states).withAlpha((255.0 * 0.08).round())
|
||||
: ButtonThemeData.buttonColor(context, states).withAlpha((255.0 * 0.005).round())),
|
||||
padding: WidgetStateProperty.all(EdgeInsets.symmetric(horizontal: 16, vertical: 8)),
|
||||
),
|
||||
onPressed: onTap,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(icon, color: color, size: 24),
|
||||
const SizedBox(height: 4),
|
||||
Text(title, style: TextStyle(fontSize: 12)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDonationQRCode(String type, BuildContext context) {
|
||||
// 处理 GitHub 特殊情况
|
||||
if (type == 'github') {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
key: ValueKey('github'),
|
||||
children: [
|
||||
SizedBox(height: 28),
|
||||
const Icon(FontAwesomeIcons.github, size: 64),
|
||||
const SizedBox(height: 32),
|
||||
Text(S.current.support_dev_github_star_message),
|
||||
const SizedBox(height: 32),
|
||||
Button(
|
||||
onPressed: () {
|
||||
launchUrlString("https://github.com/StarCitizenToolBox/app");
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(FontAwesomeIcons.github),
|
||||
const SizedBox(width: 12),
|
||||
Text(S.current.support_dev_github_star_button),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
makeAnalyticsWidget(context),
|
||||
const SizedBox(height: 24),
|
||||
makeLinksRow(),
|
||||
const Spacer(),
|
||||
Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
AnimatedSize(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width * .35,
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).cardColor.withOpacity(.06),
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
child: IconButton(
|
||||
icon: Padding(
|
||||
padding: const EdgeInsets.all(3),
|
||||
child: Text(
|
||||
isTipTextCn.value ? tipTextCN : tipTextEN,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(
|
||||
fontSize: 12, color: Colors.white.withOpacity(.9)),
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
isTipTextCn.value = !isTipTextCn.value;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// UEC 游戏内捐赠也特殊处理
|
||||
if (type == 'uec') {
|
||||
return Column(
|
||||
key: ValueKey('uec'),
|
||||
children: [
|
||||
Image.asset("assets/sc_logo.png", width: 128, height: 128),
|
||||
const SizedBox(height: 16),
|
||||
Text(S.current.support_dev_in_game_currency_title,
|
||||
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 8),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).cardColor.withAlpha((255 * .1).round()),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(S.current.support_dev_in_game_id, style: TextStyle(fontSize: 16)),
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
onPressed: () {
|
||||
// ${S.current.support_dev_copy_button}游戏ID到剪贴板
|
||||
Clipboard.setData(ClipboardData(text: "xkeyC"));
|
||||
showToast(context, S.current.support_dev_in_game_id_copied);
|
||||
},
|
||||
child: Text(S.current.support_dev_copy_button),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
const SizedBox(height: 22),
|
||||
Text(
|
||||
S.current.support_dev_in_game_currency_message,
|
||||
textAlign: TextAlign.start,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// 其他支付方式显示二维码
|
||||
String qrData;
|
||||
String title;
|
||||
|
||||
switch (type) {
|
||||
case 'alipay':
|
||||
qrData = DonationQrCodeData.alipay;
|
||||
title = S.current.support_dev_alipay;
|
||||
break;
|
||||
case 'wechat':
|
||||
qrData = DonationQrCodeData.wechat;
|
||||
title = S.current.support_dev_wechat;
|
||||
break;
|
||||
|
||||
case 'qq':
|
||||
qrData = DonationQrCodeData.qq;
|
||||
title = "QQ";
|
||||
break;
|
||||
default:
|
||||
qrData = "";
|
||||
title = "";
|
||||
break;
|
||||
}
|
||||
|
||||
return Column(
|
||||
key: ValueKey(type),
|
||||
children: [
|
||||
Text(title, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 16),
|
||||
Container(
|
||||
width: 200,
|
||||
height: 200,
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: QrImageView(data: qrData),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
S.current.support_dev_donation_disclaimer,
|
||||
style: TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeNavButton(PageController pageCtrl, int pageIndex) {
|
||||
return IconButton(
|
||||
icon: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(pageIndex == 0 ? FluentIcons.chevron_up : FluentIcons.chevron_down, size: 12),
|
||||
SizedBox(width: 8),
|
||||
Text(pageIndex == 0 ? S.current.support_dev_back_button : S.current.support_dev_scroll_hint),
|
||||
],
|
||||
),
|
||||
onPressed: () =>
|
||||
pageCtrl.animateToPage(pageIndex, duration: const Duration(milliseconds: 300), curve: Curves.ease),
|
||||
);
|
||||
}
|
||||
|
||||
@ -99,6 +407,22 @@ class AboutUI extends HookConsumerWidget {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Row(
|
||||
children: [
|
||||
const Icon(FontAwesomeIcons.question),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
S.current.about_action_btn_faq,
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
launchUrlString(URLConf.feedbackFAQUrl);
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 24),
|
||||
IconButton(
|
||||
icon: Row(
|
||||
children: [
|
||||
@ -106,8 +430,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
S.current.about_online_feedback,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withOpacity(.6)),
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -123,8 +446,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
S.current.about_action_qq_group,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withOpacity(.6)),
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -141,8 +463,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
S.current.about_action_email,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withOpacity(.6)),
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -158,8 +479,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
S.current.about_action_open_source,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withOpacity(.6)),
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -177,6 +497,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
static String get tipTextCN => S.current.about_disclaimer;
|
||||
|
||||
Widget makeAnalyticsWidget(BuildContext context) {
|
||||
var buildIndex = 0;
|
||||
return LoadingWidget(
|
||||
onLoadData: AnalyticsApi.getAnalyticsData,
|
||||
autoRefreshDuration: const Duration(seconds: 60),
|
||||
@ -196,20 +517,18 @@ class AboutUI extends HookConsumerWidget {
|
||||
"performance_apply",
|
||||
"p4k_download",
|
||||
].contains(item["Type"]))
|
||||
makeAnalyticsItem(
|
||||
context: context,
|
||||
name: item["Type"] as String,
|
||||
value: item["Count"] as int)
|
||||
GridItemAnimator(
|
||||
index: buildIndex++,
|
||||
child: makeAnalyticsItem(
|
||||
context: context, name: item["Type"] as String, value: item["Count"] as int),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeAnalyticsItem(
|
||||
{required BuildContext context,
|
||||
required String name,
|
||||
required int value}) {
|
||||
Widget makeAnalyticsItem({required BuildContext context, required String name, required int value}) {
|
||||
final names = {
|
||||
"launch": S.current.about_analytics_launch,
|
||||
"gameLaunch": S.current.about_analytics_launch_game,
|
||||
@ -222,13 +541,12 @@ class AboutUI extends HookConsumerWidget {
|
||||
padding: const EdgeInsets.all(12),
|
||||
margin: const EdgeInsets.only(left: 18, right: 18),
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).cardColor.withOpacity(.06),
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
color: FluentTheme.of(context).cardColor.withValues(alpha: .06), borderRadius: BorderRadius.circular(12)),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
names[name] ?? name,
|
||||
style: TextStyle(fontSize: 13, color: Colors.white.withOpacity(.6)),
|
||||
style: TextStyle(fontSize: 13, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Row(
|
||||
@ -254,8 +572,7 @@ class AboutUI extends HookConsumerWidget {
|
||||
launchUrlString("ms-windows-store://pdp/?productid=9NF3SWFWNKL1");
|
||||
return;
|
||||
} else {
|
||||
final hasUpdate =
|
||||
await ref.read(appGlobalModelProvider.notifier).checkUpdate(context);
|
||||
final hasUpdate = await ref.read(appGlobalModelProvider.notifier).checkUpdate(context);
|
||||
if (!hasUpdate) {
|
||||
if (!context.mounted) return;
|
||||
showToast(context, S.current.about_info_latest_version);
|
||||
@ -263,3 +580,36 @@ class AboutUI extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChatBubble extends StatelessWidget {
|
||||
final String message;
|
||||
|
||||
const ChatBubble({super.key, required this.message});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).accentColor.withAlpha((255.0 * .2).round()),
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(4),
|
||||
topRight: Radius.circular(18),
|
||||
bottomLeft: Radius.circular(18),
|
||||
bottomRight: Radius.circular(18),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
message,
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DonationQrCodeData {
|
||||
static const alipay = "https://qr.alipay.com/tsx16308c4uai0ticmz4j96";
|
||||
static const wechat = "wxp://f2f0J40rTCX7Vt79yooWNbiqH3U6UmwGJkqjcAYnrv9OZVzKyS5_W6trp8mo3KP-CTQ5";
|
||||
static const qq =
|
||||
"https://i.qianbao.qq.com/wallet/sqrcode.htm?m=tenpay&f=wallet&a=1&u=3334969096&n=xkeyC&ac=CAEQiK6etgwY8ZuKvgYyGOa1geWKqOaRiuS9jee7j-iQpeaUtuasvjgBQiAzY2Y4NWY3MDI1MWUxYWEwMGYyN2Q0OTM4Y2U2ODFlMw%3D%3D_xxx_sign";
|
||||
}
|
||||
|
249
lib/ui/guide/guide_ui.dart
Normal file
249
lib/ui/guide/guide_ui.dart
Normal file
@ -0,0 +1,249 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/conf.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/url_conf.dart';
|
||||
import 'package:starcitizen_doctor/ui/settings/settings_ui_model.dart';
|
||||
import 'package:starcitizen_doctor/ui/tools/tools_ui_model.dart';
|
||||
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
class GuideUI extends HookConsumerWidget {
|
||||
const GuideUI({super.key});
|
||||
|
||||
static const version = 1;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final toolsState = ref.watch(toolsUIModelProvider);
|
||||
final toolsModel = ref.read(toolsUIModelProvider.notifier);
|
||||
|
||||
final settingModel = ref.read(settingsUIModelProvider.notifier);
|
||||
|
||||
useEffect(() {
|
||||
addPostFrameCallback(() {
|
||||
toolsModel.reScanPath(context, checkActive: true, skipToast: true);
|
||||
});
|
||||
return null;
|
||||
}, []);
|
||||
|
||||
return makeDefaultPage(
|
||||
context,
|
||||
automaticallyImplyLeading: false,
|
||||
titleRow: Align(
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
child: Row(
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/app_logo_mini.png",
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
S.current.app_index_version_info(
|
||||
ConstConf.appVersion, ConstConf.isMSE ? "" : " Dev"),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
content: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image.asset("assets/app_logo.png", width: 192, height: 192),
|
||||
SizedBox(height: 12),
|
||||
Text(
|
||||
S.current.guide_title_welcome,
|
||||
style: TextStyle(
|
||||
fontSize: 38,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
Text(S.current.guide_info_check_settings),
|
||||
SizedBox(height: 32),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 32),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
makeGameLauncherPathSelect(
|
||||
context, toolsModel, toolsState, settingModel),
|
||||
const SizedBox(height: 12),
|
||||
makeGamePathSelect(
|
||||
context, toolsModel, toolsState, settingModel),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Button(
|
||||
onPressed: () => toolsModel.reScanPath(context,
|
||||
checkActive: true, skipToast: true),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: 30, bottom: 30, left: 12, right: 12),
|
||||
child: Icon(FluentIcons.refresh),
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
SizedBox(height: 12),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 32, left: 32),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
S.current.guide_info_game_download_note,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.white.withValues(alpha: .6)),
|
||||
textAlign: TextAlign.end,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 38),
|
||||
Row(
|
||||
children: [
|
||||
Spacer(),
|
||||
Button(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
child: Text(S.current.guide_action_get_help),
|
||||
),
|
||||
onPressed: () {
|
||||
launchUrlString(URLConf.feedbackFAQUrl);
|
||||
},
|
||||
),
|
||||
SizedBox(width: 24),
|
||||
FilledButton(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
child: Text(S.current.guide_action_complete_setup),
|
||||
),
|
||||
onPressed: () async {
|
||||
if (toolsState.rsiLauncherInstallPaths.isEmpty) {
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.guide_dialog_confirm_complete_setup,
|
||||
Text(S.current
|
||||
.guide_action_info_no_launcher_path_warning));
|
||||
if (!ok) return;
|
||||
}
|
||||
if (toolsState.scInstallPaths.isEmpty) {
|
||||
if (!context.mounted) return;
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.guide_dialog_confirm_complete_setup,
|
||||
Text(S
|
||||
.current.guide_action_info_no_game_path_warning));
|
||||
if (!ok) return;
|
||||
}
|
||||
final appConf = await Hive.openBox("app_conf");
|
||||
await appConf.put("guide_version", version);
|
||||
if (!context.mounted) return;
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
SizedBox(width: 32),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 128),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeGameLauncherPathSelect(BuildContext context, ToolsUIModel model,
|
||||
ToolsUIState state, SettingsUIModel settingModel) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(S.current.tools_info_rsi_launcher_location),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: 36,
|
||||
child: ComboBox<String>(
|
||||
isExpanded: true,
|
||||
value: state.rsiLauncherInstalledPath,
|
||||
items: [
|
||||
for (final path in state.rsiLauncherInstallPaths)
|
||||
ComboBoxItem(
|
||||
value: path,
|
||||
child: Text(path),
|
||||
)
|
||||
],
|
||||
onChanged: (v) {
|
||||
model.onChangeLauncherPath(v!);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Button(
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(6),
|
||||
child: Icon(FluentIcons.folder_search),
|
||||
),
|
||||
onPressed: () async {
|
||||
await settingModel.setLauncherPath(context);
|
||||
if (!context.mounted) return;
|
||||
model.reScanPath(context, checkActive: true, skipToast: true);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeGamePathSelect(BuildContext context, ToolsUIModel model,
|
||||
ToolsUIState state, SettingsUIModel settingModel) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(S.current.tools_info_game_install_location),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: 36,
|
||||
child: ComboBox<String>(
|
||||
isExpanded: true,
|
||||
value: state.scInstalledPath,
|
||||
items: [
|
||||
for (final path in state.scInstallPaths)
|
||||
ComboBoxItem(
|
||||
value: path,
|
||||
child: Text(path),
|
||||
)
|
||||
],
|
||||
onChanged: (v) {
|
||||
model.onChangeGamePath(v!);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Button(
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(6),
|
||||
child: Icon(FluentIcons.folder_search),
|
||||
),
|
||||
onPressed: () async {
|
||||
await settingModel.setGamePath(context);
|
||||
if (!context.mounted) return;
|
||||
model.reScanPath(context, checkActive: true, skipToast: true);
|
||||
})
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ class HomeCountdownDialogUI extends HookConsumerWidget {
|
||||
Navigator.of(context).pop();
|
||||
}),
|
||||
const SizedBox(width: 12),
|
||||
Text(S.current.home_holiday_countdown),
|
||||
Text(S.current.home_holiday_countdown),
|
||||
],
|
||||
),
|
||||
content: homeState.countdownFestivalListData == null
|
||||
@ -43,41 +43,44 @@ class HomeCountdownDialogUI extends HookConsumerWidget {
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final item =
|
||||
homeState.countdownFestivalListData![index];
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).cardColor,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Row(
|
||||
children: [
|
||||
if (item.icon != null && item.icon != "") ...[
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(1000),
|
||||
child: Image.asset(
|
||||
"assets/countdown/${item.icon}",
|
||||
width: 38,
|
||||
height: 38,
|
||||
return GridItemAnimator(
|
||||
index: index,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context).cardColor,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Row(
|
||||
children: [
|
||||
if (item.icon != null && item.icon != "") ...[
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(1000),
|
||||
child: Image.asset(
|
||||
"assets/countdown/${item.icon}",
|
||||
width: 38,
|
||||
height: 38,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
] else
|
||||
const SizedBox(width: 50),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"${item.name}",
|
||||
),
|
||||
CountdownTimeText(
|
||||
targetTime:
|
||||
DateTime.fromMillisecondsSinceEpoch(
|
||||
item.time ?? 0),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
const SizedBox(width: 12),
|
||||
] else
|
||||
const SizedBox(width: 50),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"${item.name}",
|
||||
),
|
||||
CountdownTimeText(
|
||||
targetTime:
|
||||
DateTime.fromMillisecondsSinceEpoch(
|
||||
item.time ?? 0),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -87,7 +90,8 @@ class HomeCountdownDialogUI extends HookConsumerWidget {
|
||||
Text(
|
||||
S.current.home_holiday_countdown_disclaimer,
|
||||
style: TextStyle(
|
||||
fontSize: 13, color: Colors.white.withOpacity(.3)),
|
||||
fontSize: 13,
|
||||
color: Colors.white.withValues(alpha: .3)),
|
||||
)
|
||||
],
|
||||
),
|
||||
@ -95,4 +99,4 @@ class HomeCountdownDialogUI extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:desktop_webview_window/desktop_webview_window.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
@ -48,7 +48,7 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
|
||||
final homeState = ref.read(homeUIModelProvider);
|
||||
if (!context.mounted) return;
|
||||
goWebView(context, S.current.home_action_login_rsi_account,
|
||||
"https://robertsspaceindustries.com/connect?jumpto=/connect",
|
||||
"https://robertsspaceindustries.com/en/connect?jumpto=%2Fconnect",
|
||||
loginMode: true, rsiLoginCallback: (message, ok) async {
|
||||
// dPrint(
|
||||
// "======rsiLoginCallback=== $ok ===== data==\n${json.encode(message)}");
|
||||
@ -63,10 +63,13 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
|
||||
final webToken = data["webToken"];
|
||||
final releaseInfo = data["releaseInfo"];
|
||||
final libraryData = RsiGameLibraryData.fromJson(data["libraryData"]);
|
||||
final avatarUrl = data["avatar"]
|
||||
var avatarUrl = data["avatar"]
|
||||
?.toString()
|
||||
.replaceAll("url(\"", "")
|
||||
.replaceAll("\")", "");
|
||||
if (avatarUrl?.startsWith("/") ?? false) {
|
||||
avatarUrl = "https://robertsspaceindustries.com$avatarUrl";
|
||||
}
|
||||
final Map<String, dynamic> payload = Jwt.parseJwt(authToken!);
|
||||
final nickname = payload["nickname"] ?? "";
|
||||
|
||||
|
@ -26,7 +26,9 @@ mixin _$HomeGameLoginState {
|
||||
String? get installPath => throw _privateConstructorUsedError;
|
||||
bool? get isDeviceSupportWinHello => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of HomeGameLoginState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$HomeGameLoginStateCopyWith<HomeGameLoginState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@ -59,6 +61,8 @@ class _$HomeGameLoginStateCopyWithImpl<$Res, $Val extends HomeGameLoginState>
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of HomeGameLoginState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -141,6 +145,8 @@ class __$$LoginStatusImplCopyWithImpl<$Res>
|
||||
_$LoginStatusImpl _value, $Res Function(_$LoginStatusImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of HomeGameLoginState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -281,7 +287,9 @@ class _$LoginStatusImpl implements _LoginStatus {
|
||||
installPath,
|
||||
isDeviceSupportWinHello);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of HomeGameLoginState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$LoginStatusImplCopyWith<_$LoginStatusImpl> get copyWith =>
|
||||
@ -318,8 +326,11 @@ abstract class _LoginStatus implements HomeGameLoginState {
|
||||
String? get installPath;
|
||||
@override
|
||||
bool? get isDeviceSupportWinHello;
|
||||
|
||||
/// Create a copy of HomeGameLoginState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$LoginStatusImplCopyWith<_$LoginStatusImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ part of 'home_game_login_dialog_ui_model.dart';
|
||||
// **************************************************************************
|
||||
|
||||
String _$homeGameLoginUIModelHash() =>
|
||||
r'e8afccb7bba7c79e766e30a27f64128918a63dd7';
|
||||
r'85533839693681a697ea7e0b5de9ac766a46d41e';
|
||||
|
||||
/// See also [HomeGameLoginUIModel].
|
||||
@ProviderFor(HomeGameLoginUIModel)
|
||||
@ -24,4 +24,4 @@ final homeGameLoginUIModelProvider = AutoDisposeNotifierProvider<
|
||||
|
||||
typedef _$HomeGameLoginUIModel = AutoDisposeNotifier<HomeGameLoginState>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
@ -37,7 +37,8 @@ class HomeMdContentDialogUI extends HookConsumerWidget {
|
||||
actions: [
|
||||
FilledButton(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8, top: 2, bottom: 2),
|
||||
padding:
|
||||
const EdgeInsets.only(left: 8, right: 8, top: 2, bottom: 2),
|
||||
child: Text(S.current.action_close),
|
||||
),
|
||||
onPressed: () {
|
||||
@ -52,4 +53,4 @@ class HomeMdContentDialogUI extends HookConsumerWidget {
|
||||
final r = await RSHttp.getText(url);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context)
|
||||
.cardColor
|
||||
.withOpacity(.06),
|
||||
.withValues(alpha: .06),
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
),
|
||||
child: Row(
|
||||
@ -232,7 +232,7 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
itemCount: model.getTasksLen(),
|
||||
)),
|
||||
Container(
|
||||
color: FluentTheme.of(context).cardColor.withOpacity(.06),
|
||||
color: FluentTheme.of(context).cardColor.withValues(alpha: .06),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 12, bottom: 3, top: 3),
|
||||
child: Row(
|
||||
|
@ -5,7 +5,7 @@ import 'package:aria2/aria2.dart';
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/common/helper/system_helper.dart';
|
||||
@ -255,7 +255,7 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
S.current.downloader_info_p2p_network_note,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white.withOpacity(.6),
|
||||
color: Colors.white.withValues(alpha: .6),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
@ -266,7 +266,8 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
TextFormBox(
|
||||
placeholder: "1、100k、10m、0",
|
||||
controller: upCtrl,
|
||||
placeholderStyle: TextStyle(color: Colors.white.withOpacity(.6)),
|
||||
placeholderStyle:
|
||||
TextStyle(color: Colors.white.withValues(alpha: .6)),
|
||||
inputFormatters: [ifr],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@ -275,7 +276,8 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
TextFormBox(
|
||||
placeholder: "1、100k、10m、0",
|
||||
controller: downCtrl,
|
||||
placeholderStyle: TextStyle(color: Colors.white.withOpacity(.6)),
|
||||
placeholderStyle:
|
||||
TextStyle(color: Colors.white.withValues(alpha: .6)),
|
||||
inputFormatters: [ifr],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
@ -283,7 +285,7 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
S.current.downloader_input_info_p2p_upload_note,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.white.withOpacity(.6),
|
||||
color: Colors.white.withValues(alpha: .6),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
@ -21,7 +21,9 @@ mixin _$HomeDownloaderUIState {
|
||||
List<Aria2Task> get stoppedTasks => throw _privateConstructorUsedError;
|
||||
Aria2GlobalStat? get globalStat => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of HomeDownloaderUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$HomeDownloaderUIStateCopyWith<HomeDownloaderUIState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@ -50,6 +52,8 @@ class _$HomeDownloaderUIStateCopyWithImpl<$Res,
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of HomeDownloaderUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -104,6 +108,8 @@ class __$$HomeDownloaderUIStateImplCopyWithImpl<$Res>
|
||||
$Res Function(_$HomeDownloaderUIStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of HomeDownloaderUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -202,7 +208,9 @@ class _$HomeDownloaderUIStateImpl implements _HomeDownloaderUIState {
|
||||
const DeepCollectionEquality().hash(_stoppedTasks),
|
||||
globalStat);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of HomeDownloaderUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$HomeDownloaderUIStateImplCopyWith<_$HomeDownloaderUIStateImpl>
|
||||
@ -225,8 +233,11 @@ abstract class _HomeDownloaderUIState implements HomeDownloaderUIState {
|
||||
List<Aria2Task> get stoppedTasks;
|
||||
@override
|
||||
Aria2GlobalStat? get globalStat;
|
||||
|
||||
/// Create a copy of HomeDownloaderUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$HomeDownloaderUIStateImplCopyWith<_$HomeDownloaderUIStateImpl>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ part of 'home_downloader_ui_model.dart';
|
||||
// **************************************************************************
|
||||
|
||||
String _$homeDownloaderUIModelHash() =>
|
||||
r'ece2e6da4576b945ead5767aea2ccacf5e3e17aa';
|
||||
r'24db9bc498a898750c5075e08a9a6c3af6ff9647';
|
||||
|
||||
/// See also [HomeDownloaderUIModel].
|
||||
@ProviderFor(HomeDownloaderUIModel)
|
||||
@ -24,4 +24,4 @@ final homeDownloaderUIModelProvider = AutoDisposeNotifierProvider<
|
||||
|
||||
typedef _$HomeDownloaderUIModel = AutoDisposeNotifier<HomeDownloaderUIState>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
@ -223,7 +223,7 @@ class HomeGameDoctorUI extends HookConsumerWidget {
|
||||
errorNames[item.key]?.value ??
|
||||
S.current.doctor_info_result_no_solution),
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withOpacity(.7)),
|
||||
fontSize: 14, color: Colors.white.withValues(alpha: .7)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -264,7 +264,8 @@ class HomeGameDoctorUI extends HookConsumerWidget {
|
||||
Text(
|
||||
item.value,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: Colors.white.withOpacity(.7)),
|
||||
fontSize: 14,
|
||||
color: Colors.white.withValues(alpha: .7)),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -103,7 +103,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
|
||||
showToast(context, S.current.doctor_action_result_redirect_warning);
|
||||
await Future.delayed(const Duration(milliseconds: 300));
|
||||
launchUrlString(
|
||||
"https://btfy.eu.org/?q=5L+u5pS5d2luZG93c+eUqOaIt+WQjeS7juS4reaWh+WIsOiLseaWhw==");
|
||||
"https://jingyan.baidu.com/article/59703552a318a08fc0074021.html");
|
||||
break;
|
||||
default:
|
||||
showToast(context, S.current.doctor_action_result_issue_not_supported);
|
||||
@ -129,7 +129,7 @@ class HomeGameDoctorUIModel extends _$HomeGameDoctorUIModel {
|
||||
final scInstalledPath = homeState.scInstalledPath!;
|
||||
|
||||
final checkResult = <MapEntry<String, String>>[];
|
||||
// TODO for debug
|
||||
// for debug
|
||||
// checkResult?.add(MapEntry("unSupport_system", "android"));
|
||||
// checkResult?.add(MapEntry("nvme_PhysicalBytes", "C"));
|
||||
// checkResult?.add(MapEntry("no_live_path", ""));
|
||||
|
@ -23,7 +23,9 @@ mixin _$HomeGameDoctorState {
|
||||
List<MapEntry<String, String>>? get checkResult =>
|
||||
throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of HomeGameDoctorState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$HomeGameDoctorStateCopyWith<HomeGameDoctorState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@ -52,6 +54,8 @@ class _$HomeGameDoctorStateCopyWithImpl<$Res, $Val extends HomeGameDoctorState>
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of HomeGameDoctorState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -110,6 +114,8 @@ class __$$HomeGameDoctorStateImplCopyWithImpl<$Res>
|
||||
$Res Function(_$HomeGameDoctorStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of HomeGameDoctorState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -208,7 +214,9 @@ class _$HomeGameDoctorStateImpl implements _HomeGameDoctorState {
|
||||
isFixingString,
|
||||
const DeepCollectionEquality().hash(_checkResult));
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of HomeGameDoctorState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$HomeGameDoctorStateImplCopyWith<_$HomeGameDoctorStateImpl> get copyWith =>
|
||||
@ -235,8 +243,11 @@ abstract class _HomeGameDoctorState implements HomeGameDoctorState {
|
||||
String get isFixingString;
|
||||
@override
|
||||
List<MapEntry<String, String>>? get checkResult;
|
||||
|
||||
/// Create a copy of HomeGameDoctorState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$HomeGameDoctorStateImplCopyWith<_$HomeGameDoctorStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ part of 'game_doctor_ui_model.dart';
|
||||
// **************************************************************************
|
||||
|
||||
String _$homeGameDoctorUIModelHash() =>
|
||||
r'137f6393bbbd76f3af0f7d0dd27d44d8473e42cc';
|
||||
r'b69a19a937ca375214a7c7e73b8288f577265625';
|
||||
|
||||
/// See also [HomeGameDoctorUIModel].
|
||||
@ProviderFor(HomeGameDoctorUIModel)
|
||||
@ -24,4 +24,4 @@ final homeGameDoctorUIModelProvider = AutoDisposeNotifierProvider<
|
||||
|
||||
typedef _$HomeGameDoctorUIModel = AutoDisposeNotifier<HomeGameDoctorState>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
@ -1,19 +1,24 @@
|
||||
import 'package:card_swiper/card_swiper.dart';
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:flutter_tilt/flutter_tilt.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:starcitizen_doctor/api/analytics.dart';
|
||||
import 'package:starcitizen_doctor/common/helper/system_helper.dart';
|
||||
import 'package:starcitizen_doctor/generated/no_l10n_strings.dart';
|
||||
import 'package:starcitizen_doctor/ui/guide/guide_ui.dart';
|
||||
import 'package:starcitizen_doctor/ui/tools/tools_ui_model.dart';
|
||||
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
import 'dialogs/home_countdown_dialog_ui.dart';
|
||||
import 'dialogs/home_md_content_dialog_ui.dart';
|
||||
import 'home_ui_model.dart';
|
||||
import 'input_method/input_method_dialog_ui.dart';
|
||||
import 'localization/localization_dialog_ui.dart';
|
||||
import 'localization/localization_ui_model.dart';
|
||||
|
||||
@ -25,6 +30,12 @@ class HomeUI extends HookConsumerWidget {
|
||||
final homeState = ref.watch(homeUIModelProvider);
|
||||
final model = ref.watch(homeUIModelProvider.notifier);
|
||||
ref.watch(localizationUIModelProvider);
|
||||
|
||||
useEffect(() {
|
||||
_checkGuide(context, model);
|
||||
return null;
|
||||
}, const []);
|
||||
|
||||
return Stack(
|
||||
children: [
|
||||
Center(
|
||||
@ -44,9 +55,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
child: Text(S.current.doctor_action_view_details),
|
||||
onPressed: () => _showPlacard(context, homeState),
|
||||
),
|
||||
onClose: homeState.appPlacardData?.alwaysShow == true
|
||||
? null
|
||||
: () => model.closePlacard(),
|
||||
onClose: homeState.appPlacardData?.alwaysShow == true ? null : () => model.closePlacard(),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
],
|
||||
@ -77,8 +86,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> makeIndex(BuildContext context, HomeUIModel model,
|
||||
HomeUIModelState homeState, WidgetRef ref) {
|
||||
List<Widget> makeIndex(BuildContext context, HomeUIModel model, HomeUIModelState homeState, WidgetRef ref) {
|
||||
double width = 280;
|
||||
return [
|
||||
Stack(
|
||||
@ -144,35 +152,32 @@ class HomeUI extends HookConsumerWidget {
|
||||
onChanged: model.onChangeInstallPath,
|
||||
),
|
||||
),
|
||||
if (S.current.app_language_code == NoL10n.langCodeZhCn) ...[
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
onPressed: homeState.webLocalizationVersionsData == null ? null : () => model.launchRSI(context),
|
||||
style: homeState.isCurGameRunning
|
||||
? null
|
||||
: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.resolveWith(_getRunButtonColor),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6),
|
||||
child: Icon(
|
||||
homeState.isCurGameRunning ? FluentIcons.stop_solid : FluentIcons.play_solid,
|
||||
color: homeState.isCurGameRunning ? Colors.red.withValues(alpha: .8) : Colors.white,
|
||||
),
|
||||
)),
|
||||
],
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
onPressed: homeState.webLocalizationVersionsData == null
|
||||
? null
|
||||
: () => model.launchRSI(context),
|
||||
style: homeState.isCurGameRunning
|
||||
? null
|
||||
: ButtonStyle(
|
||||
backgroundColor:
|
||||
ButtonState.resolveWith(_getRunButtonColor),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6),
|
||||
child: Icon(
|
||||
homeState.isCurGameRunning
|
||||
? FluentIcons.stop_solid
|
||||
: FluentIcons.play_solid,
|
||||
color: homeState.isCurGameRunning
|
||||
? Colors.red.withOpacity(.8)
|
||||
: Colors.white,
|
||||
),
|
||||
)),
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
onPressed: () =>
|
||||
SystemHelper.openDir("${homeState.scInstalledPath}"),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(6),
|
||||
child: Icon(FluentIcons.folder_open),
|
||||
onPressed: () => _checkAndGoInputMethod(context, homeState, model, ref),
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.resolveWith((_) => Colors.blue),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6),
|
||||
child: Icon(FluentIcons.keyboard_classic),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
@ -192,8 +197,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
];
|
||||
}
|
||||
|
||||
Widget makeLeftColumn(BuildContext context, HomeUIModel model, double width,
|
||||
HomeUIModelState homeState) {
|
||||
Widget makeLeftColumn(BuildContext context, HomeUIModel model, double width, HomeUIModelState homeState) {
|
||||
return Stack(
|
||||
children: [
|
||||
Column(
|
||||
@ -201,7 +205,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: FluentTheme.of(context).cardColor.withOpacity(.03),
|
||||
color: FluentTheme.of(context).cardColor.withValues(alpha: .03),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
@ -214,13 +218,10 @@ class HomeUI extends HookConsumerWidget {
|
||||
colorFilter: makeSvgColor(Colors.white),
|
||||
height: 18,
|
||||
),
|
||||
name: S.current
|
||||
.home_action_star_citizen_website_localization,
|
||||
webTitle: S.current
|
||||
.home_action_star_citizen_website_localization,
|
||||
name: S.current.home_action_star_citizen_website_localization,
|
||||
webTitle: S.current.home_action_star_citizen_website_localization,
|
||||
webURL: "https://robertsspaceindustries.com",
|
||||
info: S.current
|
||||
.home_action_info_roberts_space_industries_origin,
|
||||
info: S.current.home_action_info_roberts_space_industries_origin,
|
||||
useLocalization: true,
|
||||
width: width,
|
||||
touchKey: "webLocalization_rsi"),
|
||||
@ -238,8 +239,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
name: S.current.home_action_uex_localization,
|
||||
webTitle: S.current.home_action_uex_localization,
|
||||
webURL: "https://uexcorp.space/",
|
||||
info: S.current
|
||||
.home_action_info_mining_refining_trade_calculator,
|
||||
info: S.current.home_action_info_mining_refining_trade_calculator,
|
||||
useLocalization: true,
|
||||
width: width,
|
||||
touchKey: "webLocalization_uex"),
|
||||
@ -255,11 +255,9 @@ class HomeUI extends HookConsumerWidget {
|
||||
],
|
||||
),
|
||||
name: S.current.home_action_dps_calculator_localization,
|
||||
webTitle:
|
||||
S.current.home_action_dps_calculator_localization,
|
||||
webTitle: S.current.home_action_dps_calculator_localization,
|
||||
webURL: "https://www.erkul.games/live/calculator",
|
||||
info: S.current
|
||||
.home_action_info_ship_upgrade_damage_value_query,
|
||||
info: S.current.home_action_info_ship_upgrade_damage_value_query,
|
||||
useLocalization: true,
|
||||
width: width,
|
||||
touchKey: "webLocalization_dps"),
|
||||
@ -269,8 +267,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
Row(
|
||||
children: [
|
||||
Button(
|
||||
child:
|
||||
const FaIcon(FontAwesomeIcons.chrome, size: 18),
|
||||
child: const FaIcon(FontAwesomeIcons.chrome, size: 18),
|
||||
onPressed: () {
|
||||
launchUrlString(
|
||||
"https://chrome.google.com/webstore/detail/gocnjckojmledijgmadmacoikibcggja?authuser=0&hl=zh-CN");
|
||||
@ -286,21 +283,17 @@ class HomeUI extends HookConsumerWidget {
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
child: const FaIcon(FontAwesomeIcons.firefoxBrowser,
|
||||
size: 18),
|
||||
child: const FaIcon(FontAwesomeIcons.firefoxBrowser, size: 18),
|
||||
onPressed: () {
|
||||
launchUrlString(
|
||||
"https://addons.mozilla.org/zh-CN/firefox/"
|
||||
launchUrlString("https://addons.mozilla.org/zh-CN/firefox/"
|
||||
"addon/%E6%98%9F%E9%99%85%E5%85%AC%E6%B0%91%E7%9B%92%E5%AD%90%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8B%93%E5%B1%95/");
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Button(
|
||||
child:
|
||||
const FaIcon(FontAwesomeIcons.github, size: 18),
|
||||
child: const FaIcon(FontAwesomeIcons.github, size: 18),
|
||||
onPressed: () {
|
||||
launchUrlString(
|
||||
"https://github.com/StarCitizenToolBox/StarCitizenBoxBrowserEx");
|
||||
launchUrlString("https://github.com/StarCitizenToolBox/StarCitizenBoxBrowserEx");
|
||||
},
|
||||
),
|
||||
],
|
||||
@ -316,9 +309,8 @@ class HomeUI extends HookConsumerWidget {
|
||||
if (homeState.webLocalizationVersionsData == null)
|
||||
Positioned.fill(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withOpacity(.3),
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
decoration:
|
||||
BoxDecoration(color: Colors.black.withValues(alpha: .3), borderRadius: BorderRadius.circular(12)),
|
||||
child: const Center(
|
||||
child: ProgressRing(),
|
||||
),
|
||||
@ -327,16 +319,13 @@ class HomeUI extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeNewsCard(
|
||||
BuildContext context, HomeUIModel model, HomeUIModelState homeState) {
|
||||
Widget makeNewsCard(BuildContext context, HomeUIModel model, HomeUIModelState homeState) {
|
||||
return ScrollConfiguration(
|
||||
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
|
||||
child: Container(
|
||||
width: 316,
|
||||
height: 386,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(.1),
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
decoration: BoxDecoration(color: Colors.white.withValues(alpha: .1), borderRadius: BorderRadius.circular(12)),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
@ -351,13 +340,11 @@ class HomeUI extends HookConsumerWidget {
|
||||
),
|
||||
child: homeState.rssVideoItems == null
|
||||
? Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(.1)),
|
||||
decoration: BoxDecoration(color: Colors.white.withValues(alpha: .1)),
|
||||
child: makeLoading(context),
|
||||
)
|
||||
: Swiper(
|
||||
itemCount: getMinNumber(
|
||||
[homeState.rssVideoItems?.length ?? 0, 6]),
|
||||
itemCount: getMinNumber([homeState.rssVideoItems?.length ?? 0, 6]),
|
||||
itemBuilder: (context, index) {
|
||||
final item = homeState.rssVideoItems![index];
|
||||
return GestureDetector(
|
||||
@ -394,8 +381,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 12, right: 12, top: 4, bottom: 4),
|
||||
padding: const EdgeInsets.only(left: 12, right: 12, top: 4, bottom: 4),
|
||||
child: Row(
|
||||
children: [
|
||||
getRssIcon(item.link ?? ""),
|
||||
@ -413,7 +399,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
Icon(
|
||||
FluentIcons.chevron_right,
|
||||
size: 12,
|
||||
color: Colors.white.withOpacity(.4),
|
||||
color: Colors.white.withValues(alpha: .4),
|
||||
)
|
||||
],
|
||||
),
|
||||
@ -445,24 +431,14 @@ class HomeUI extends HookConsumerWidget {
|
||||
return const FaIcon(FontAwesomeIcons.rss, size: 14);
|
||||
}
|
||||
|
||||
Widget makeIndexActionLists(BuildContext context, HomeUIModel model,
|
||||
HomeUIModelState homeState, WidgetRef ref) {
|
||||
Widget makeIndexActionLists(BuildContext context, HomeUIModel model, HomeUIModelState homeState, WidgetRef ref) {
|
||||
final items = [
|
||||
_HomeItemData(
|
||||
"game_doctor",
|
||||
S.current.home_action_one_click_diagnosis,
|
||||
S.current.home_action_info_one_click_diagnosis_star_citizen,
|
||||
FluentIcons.auto_deploy_settings),
|
||||
_HomeItemData(
|
||||
"localization",
|
||||
S.current.home_action_localization_management,
|
||||
S.current.home_action_info_quick_install_localization_resources,
|
||||
FluentIcons.locale_language),
|
||||
_HomeItemData(
|
||||
"performance",
|
||||
S.current.home_action_performance_optimization,
|
||||
S.current.home_action_info_engine_config_optimization,
|
||||
FluentIcons.process_meta_task),
|
||||
_HomeItemData("game_doctor", S.current.home_action_one_click_diagnosis,
|
||||
S.current.home_action_info_one_click_diagnosis_star_citizen, FluentIcons.auto_deploy_settings),
|
||||
_HomeItemData("localization", S.current.home_action_localization_management,
|
||||
S.current.home_action_info_quick_install_localization_resources, FluentIcons.locale_language),
|
||||
_HomeItemData("performance", S.current.home_action_performance_optimization,
|
||||
S.current.home_action_info_engine_config_optimization, FluentIcons.process_meta_task),
|
||||
];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
@ -476,14 +452,14 @@ class HomeUI extends HookConsumerWidget {
|
||||
final item = items.elementAt(index);
|
||||
return HoverButton(
|
||||
onPressed: () => _onMenuTap(context, item.key, homeState, ref),
|
||||
builder: (BuildContext context, Set<ButtonStates> states) {
|
||||
builder: (BuildContext context, Set<WidgetState> states) {
|
||||
return Container(
|
||||
width: 300,
|
||||
height: 120,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: states.isHovering
|
||||
? FluentTheme.of(context).cardColor.withOpacity(.1)
|
||||
color: states.isHovered
|
||||
? FluentTheme.of(context).cardColor.withValues(alpha: .1)
|
||||
: FluentTheme.of(context).cardColor,
|
||||
),
|
||||
child: Padding(
|
||||
@ -492,8 +468,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(.2),
|
||||
borderRadius: BorderRadius.circular(1000)),
|
||||
color: Colors.white.withValues(alpha: .2), borderRadius: BorderRadius.circular(1000)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Icon(
|
||||
@ -515,22 +490,15 @@ class HomeUI extends HookConsumerWidget {
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
item.infoString,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white.withOpacity(.6)),
|
||||
style: TextStyle(fontSize: 14, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
)),
|
||||
if (item.key == "localization" &&
|
||||
homeState.localizationUpdateInfo != null)
|
||||
if (item.key == "localization" && homeState.localizationUpdateInfo != null)
|
||||
Container(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 3, bottom: 3, left: 8, right: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red,
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
child: Text(
|
||||
homeState.localizationUpdateInfo?.key ?? " "),
|
||||
padding: const EdgeInsets.only(top: 3, bottom: 3, left: 8, right: 8),
|
||||
decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(12)),
|
||||
child: Text(homeState.localizationUpdateInfo?.key ?? " "),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
const Icon(
|
||||
@ -594,9 +562,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
child: Text(
|
||||
info,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.white.withOpacity(.6)),
|
||||
style: TextStyle(fontSize: 12, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
)
|
||||
],
|
||||
@ -606,7 +572,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
Icon(
|
||||
FluentIcons.chevron_right,
|
||||
size: 14,
|
||||
color: Colors.white.withOpacity(.6),
|
||||
color: Colors.white.withValues(alpha: .6),
|
||||
)
|
||||
],
|
||||
),
|
||||
@ -616,12 +582,10 @@ class HomeUI extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeGameStatusCard(BuildContext context, HomeUIModel model,
|
||||
double width, HomeUIModelState homeState) {
|
||||
Widget makeGameStatusCard(BuildContext context, HomeUIModel model, double width, HomeUIModelState homeState) {
|
||||
final statusCnName = {
|
||||
"Platform": S.current.home_action_rsi_status_platform,
|
||||
"Persistent Universe":
|
||||
S.current.home_action_rsi_status_persistent_universe,
|
||||
"Persistent Universe": S.current.home_action_rsi_status_persistent_universe,
|
||||
"Electronic Access": S.current.home_action_rsi_status_electronic_access,
|
||||
"Arena Commander": S.current.home_action_rsi_status_arena_commander
|
||||
};
|
||||
@ -632,9 +596,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
model.goWebView(
|
||||
context,
|
||||
S.current.home_action_rsi_status_rsi_server_status,
|
||||
"https://status.robertsspaceindustries.com/",
|
||||
context, S.current.home_action_rsi_status_rsi_server_status, "https://status.robertsspaceindustries.com/",
|
||||
useLocalization: true);
|
||||
},
|
||||
child: Container(
|
||||
@ -660,9 +622,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
child: Center(
|
||||
child: Icon(
|
||||
FontAwesomeIcons.solidCircle,
|
||||
color: model.isRSIServerStatusOK(item)
|
||||
? Colors.green
|
||||
: Colors.red,
|
||||
color: model.isRSIServerStatusOK(item) ? Colors.green : Colors.red,
|
||||
size: 12,
|
||||
),
|
||||
),
|
||||
@ -677,7 +637,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
Icon(
|
||||
FluentIcons.chevron_right,
|
||||
size: 12,
|
||||
color: Colors.white.withOpacity(.4),
|
||||
color: Colors.white.withValues(alpha: .4),
|
||||
)
|
||||
],
|
||||
)
|
||||
@ -688,8 +648,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeActivityBanner(BuildContext context, HomeUIModel model,
|
||||
double width, HomeUIModelState homeState) {
|
||||
Widget makeActivityBanner(BuildContext context, HomeUIModel model, double width, HomeUIModelState homeState) {
|
||||
return Tilt(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
shadowConfig: const ShadowConfig(disable: true),
|
||||
@ -699,8 +658,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
width: width + 24,
|
||||
decoration: BoxDecoration(color: FluentTheme.of(context).cardColor),
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 12, right: 12, top: 8, bottom: 8),
|
||||
padding: const EdgeInsets.only(left: 12, right: 12, top: 8, bottom: 8),
|
||||
child: (homeState.countdownFestivalListData == null)
|
||||
? SizedBox(
|
||||
width: width,
|
||||
@ -713,13 +671,11 @@ class HomeUI extends HookConsumerWidget {
|
||||
width: width,
|
||||
height: 62,
|
||||
child: Swiper(
|
||||
itemCount: getMinNumber(
|
||||
[homeState.countdownFestivalListData!.length, 6]),
|
||||
itemCount: getMinNumber([homeState.countdownFestivalListData!.length, 6]),
|
||||
autoplay: true,
|
||||
autoplayDelay: 5000,
|
||||
itemBuilder: (context, index) {
|
||||
final item =
|
||||
homeState.countdownFestivalListData![index];
|
||||
final item = homeState.countdownFestivalListData![index];
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
@ -742,9 +698,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
CountdownTimeText(
|
||||
targetTime:
|
||||
DateTime.fromMillisecondsSinceEpoch(
|
||||
item.time ?? 0),
|
||||
targetTime: DateTime.fromMillisecondsSinceEpoch(item.time ?? 0),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -752,7 +706,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
Icon(
|
||||
FluentIcons.chevron_right,
|
||||
size: 14,
|
||||
color: Colors.white.withOpacity(.6),
|
||||
color: Colors.white.withValues(alpha: .6),
|
||||
)
|
||||
],
|
||||
);
|
||||
@ -774,8 +728,7 @@ class HomeUI extends HookConsumerWidget {
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return HomeMdContentDialogUI(
|
||||
title: homeState.appPlacardData?.title ??
|
||||
S.current.home_announcement_details,
|
||||
title: homeState.appPlacardData?.title ?? S.current.home_announcement_details,
|
||||
url: homeState.appPlacardData?.link,
|
||||
);
|
||||
});
|
||||
@ -784,42 +737,100 @@ class HomeUI extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
_onTapFestival(BuildContext context) {
|
||||
showDialog(
|
||||
context: context, builder: (context) => const HomeCountdownDialogUI());
|
||||
showDialog(context: context, builder: (context) => const HomeCountdownDialogUI());
|
||||
}
|
||||
|
||||
_onMenuTap(BuildContext context, String key, HomeUIModelState homeState,
|
||||
WidgetRef ref) async {
|
||||
String gameInstallReqInfo =
|
||||
S.current.home_action_info_valid_install_location_required;
|
||||
Future<void> _onMenuTap(BuildContext context, String key, HomeUIModelState homeState, WidgetRef ref) async {
|
||||
String gameInstallReqInfo = S.current.home_action_info_valid_install_location_required;
|
||||
switch (key) {
|
||||
case "localization":
|
||||
if (homeState.scInstalledPath == "not_install") {
|
||||
showToast(context, gameInstallReqInfo);
|
||||
ToolsUIModel.rsiEnhance(context, showNotGameInstallMsg: true);
|
||||
break;
|
||||
}
|
||||
final model = ref.watch(homeUIModelProvider.notifier);
|
||||
model.checkLocalizationUpdate();
|
||||
await showDialog(
|
||||
context: context,
|
||||
dismissWithEsc: false,
|
||||
builder: (BuildContext context) => const LocalizationDialogUI());
|
||||
context: context,
|
||||
dismissWithEsc: false,
|
||||
builder: (BuildContext context) => const LocalizationDialogUI(),
|
||||
);
|
||||
model.checkLocalizationUpdate(skipReload: true);
|
||||
break;
|
||||
case "performance":
|
||||
if (homeState.scInstalledPath == "not_install") {
|
||||
showToast(context, gameInstallReqInfo);
|
||||
break;
|
||||
}
|
||||
context.push("/index/$key");
|
||||
break;
|
||||
default:
|
||||
context.push("/index/$key");
|
||||
}
|
||||
}
|
||||
|
||||
Color? _getRunButtonColor(Set<ButtonStates> states) {
|
||||
if (states.isPressing) {
|
||||
Color? _getRunButtonColor(Set<WidgetState> states) {
|
||||
if (states.isPressed) {
|
||||
return const Color.fromRGBO(49, 227, 88, .5);
|
||||
}
|
||||
if (states.isHovering) {
|
||||
if (states.isPressed) {
|
||||
return const Color.fromRGBO(47, 213, 84, 1.0);
|
||||
}
|
||||
return const Color.fromRGBO(49, 227, 88, .8);
|
||||
}
|
||||
|
||||
Future _checkGuide(BuildContext context, HomeUIModel model) async {
|
||||
final appConf = await Hive.openBox("app_conf");
|
||||
final guideVersion = appConf.get("guide_version", defaultValue: 0);
|
||||
if (guideVersion < GuideUI.version) {
|
||||
await Future.delayed(Duration(milliseconds: 200));
|
||||
if (!context.mounted) return;
|
||||
await context.push("/guide");
|
||||
await model.reScanPath();
|
||||
await model.checkLocalizationUpdate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void _checkAndGoInputMethod(
|
||||
BuildContext context, HomeUIModelState homeState, HomeUIModel model, WidgetRef ref) async {
|
||||
final localizationState = ref.read(localizationUIModelProvider);
|
||||
if (localizationState.communityInputMethodLanguageData == null) {
|
||||
showToast(context, S.current.input_method_feature_maintenance);
|
||||
return;
|
||||
}
|
||||
if (localizationState.installedCommunityInputMethodSupportVersion == null) {
|
||||
final userOK = await showConfirmDialogs(context, S.current.input_method_community_input_method_not_installed,
|
||||
Text(S.current.input_method_install_community_input_method_prompt));
|
||||
if (userOK) {
|
||||
if (!context.mounted) return;
|
||||
() async {
|
||||
await _onMenuTap(context, 'localization', homeState, ref);
|
||||
final localizationState = ref.read(localizationUIModelProvider);
|
||||
if (localizationState.installedCommunityInputMethodSupportVersion != null) {
|
||||
await Future.delayed(Duration(milliseconds: 300));
|
||||
if (!context.mounted) return;
|
||||
await _goInputMethod(context, model);
|
||||
return;
|
||||
}
|
||||
}();
|
||||
|
||||
await Future.delayed(Duration(milliseconds: 300));
|
||||
final localizationModel = ref.read(localizationUIModelProvider.notifier);
|
||||
if (!context.mounted) return;
|
||||
localizationModel.checkReinstall(context);
|
||||
}
|
||||
return;
|
||||
}
|
||||
await _goInputMethod(context, model);
|
||||
}
|
||||
|
||||
Future<void> _goInputMethod(BuildContext context, HomeUIModel model) async {
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) => const InputMethodDialogUI(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _HomeItemData {
|
||||
|
@ -6,12 +6,12 @@ import 'package:dart_rss/domain/rss_item.dart';
|
||||
import 'package:desktop_webview_window/desktop_webview_window.dart';
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/api/analytics.dart';
|
||||
import 'package:starcitizen_doctor/api/api.dart';
|
||||
import 'package:starcitizen_doctor/api/rss.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/const_conf.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/conf.dart';
|
||||
import 'package:starcitizen_doctor/common/conf/url_conf.dart';
|
||||
import 'package:starcitizen_doctor/common/helper/log_helper.dart';
|
||||
import 'package:starcitizen_doctor/common/helper/system_helper.dart';
|
||||
@ -86,7 +86,7 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
return;
|
||||
}
|
||||
final scInstallPaths = await SCLoggerHelper.getGameInstallPath(listData,
|
||||
withVersion: ["LIVE", "PTU", "EPTU"], checkExists: true);
|
||||
withVersion: AppConf.gameChannels, checkExists: true);
|
||||
|
||||
String scInstalledPath = "not_install";
|
||||
|
||||
@ -338,6 +338,9 @@ class HomeUIModel extends _$HomeUIModel {
|
||||
void onChangeInstallPath(String? value) {
|
||||
if (value == null) return;
|
||||
state = state.copyWith(scInstalledPath: value);
|
||||
ref
|
||||
.read(localizationUIModelProvider.notifier)
|
||||
.onChangeGameInstallPath(value);
|
||||
}
|
||||
|
||||
doLaunchGame(
|
||||
|
@ -33,7 +33,9 @@ mixin _$HomeUIModelState {
|
||||
throw _privateConstructorUsedError;
|
||||
Map<String, bool> get isGameRunning => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of HomeUIModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$HomeUIModelStateCopyWith<HomeUIModelState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@ -70,6 +72,8 @@ class _$HomeUIModelStateCopyWithImpl<$Res, $Val extends HomeUIModelState>
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of HomeUIModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -176,6 +180,8 @@ class __$$HomeUIModelStateImplCopyWithImpl<$Res>
|
||||
$Res Function(_$HomeUIModelStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of HomeUIModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
@ -407,7 +413,9 @@ class _$HomeUIModelStateImpl implements _HomeUIModelState {
|
||||
const DeepCollectionEquality().hash(_countdownFestivalListData),
|
||||
const DeepCollectionEquality().hash(_isGameRunning));
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
/// Create a copy of HomeUIModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$HomeUIModelStateImplCopyWith<_$HomeUIModelStateImpl> get copyWith =>
|
||||
@ -457,8 +465,11 @@ abstract class _HomeUIModelState implements HomeUIModelState {
|
||||
List<CountdownFestivalItemData>? get countdownFestivalListData;
|
||||
@override
|
||||
Map<String, bool> get isGameRunning;
|
||||
|
||||
/// Create a copy of HomeUIModelState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$HomeUIModelStateImplCopyWith<_$HomeUIModelStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ part of 'home_ui_model.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$homeUIModelHash() => r'85d3242abb4264a814768a2d5ce108df46df38d9';
|
||||
String _$homeUIModelHash() => r'3ff5a689cae80acdaf95ee823da9b86615bed95f';
|
||||
|
||||
/// See also [HomeUIModel].
|
||||
@ProviderFor(HomeUIModel)
|
||||
@ -22,4 +22,4 @@ final homeUIModelProvider =
|
||||
|
||||
typedef _$HomeUIModel = AutoDisposeNotifier<HomeUIModelState>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
253
lib/ui/home/input_method/input_method_dialog_ui.dart
Normal file
253
lib/ui/home/input_method/input_method_dialog_ui.dart
Normal file
@ -0,0 +1,253 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/input_method/input_method_dialog_ui_model.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/input_method/server.dart';
|
||||
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
import 'server_qr_dialog_ui.dart';
|
||||
|
||||
class InputMethodDialogUI extends HookConsumerWidget {
|
||||
const InputMethodDialogUI({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final state = ref.watch(inputMethodDialogUIModelProvider);
|
||||
final model = ref.read(inputMethodDialogUIModelProvider.notifier);
|
||||
final serverState = ref.watch(inputMethodServerProvider);
|
||||
final serverModel = ref.read(inputMethodServerProvider.notifier);
|
||||
final srcTextCtrl = useTextEditingController();
|
||||
final destTextCtrl = useTextEditingController();
|
||||
|
||||
useEffect(() {
|
||||
model.setUpController(srcTextCtrl, destTextCtrl);
|
||||
return null;
|
||||
}, const []);
|
||||
|
||||
return ContentDialog(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * .8,
|
||||
),
|
||||
title: makeTitle(context, state, model, destTextCtrl),
|
||||
content: state.keyMaps == null
|
||||
? makeLoading(context)
|
||||
: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(height: 12),
|
||||
InfoBar(
|
||||
title: Text(S.current.input_method_usage_instructions),
|
||||
content: Text(S.current.input_method_input_text_instructions),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
GestureDetector(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(3),
|
||||
child: Text(
|
||||
S.current.input_method_online_version_prompt,
|
||||
style: TextStyle(
|
||||
color: Color(0xff4ca0e0),
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
launchUrlString("https://ime.citizenwiki.cn/");
|
||||
}),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
TextFormBox(
|
||||
placeholder: S.current.input_method_input_placeholder,
|
||||
controller: srcTextCtrl,
|
||||
maxLines: 5,
|
||||
placeholderStyle:
|
||||
TextStyle(color: Colors.white.withValues(alpha: .6)),
|
||||
style: TextStyle(fontSize: 16, color: Colors.white),
|
||||
onChanged: (str) async {
|
||||
final text = model.onTextChange("src", str);
|
||||
destTextCtrl.text = text ?? "";
|
||||
if (text != null) {
|
||||
model.checkAutoTranslate();
|
||||
}
|
||||
},
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (state.isAutoTranslateWorking)
|
||||
SizedBox(width: 24, height: 24, child: ProgressRing())
|
||||
else
|
||||
SizedBox(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: Icon(FluentIcons.down))
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
TextFormBox(
|
||||
placeholder: S.current.input_method_encoded_text_placeholder,
|
||||
controller: destTextCtrl,
|
||||
maxLines: 5,
|
||||
placeholderStyle:
|
||||
TextStyle(color: Colors.white.withValues(alpha: .6)),
|
||||
style: TextStyle(fontSize: 16, color: Colors.white),
|
||||
enabled: true,
|
||||
onChanged: (str) {
|
||||
// final text = model.onTextChange("dest", str);
|
||||
// if (text != null) {
|
||||
// srcTextCtrl.text = text;
|
||||
// }
|
||||
},
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(S.current.input_method_auto_translate),
|
||||
SizedBox(width: 6),
|
||||
ToggleSwitch(
|
||||
checked: state.isEnableAutoTranslate,
|
||||
onChanged: (b) =>
|
||||
_onSwitchAutoTranslate(context, model, b),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(width: 24),
|
||||
Row(
|
||||
children: [
|
||||
Text(S.current.input_method_remote_input_service),
|
||||
SizedBox(width: 6),
|
||||
if (serverState.isServerStartup)
|
||||
Button(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) =>
|
||||
ServerQrDialogUI(),
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
serverState.serverAddressText ?? "...",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 14),
|
||||
ToggleSwitch(
|
||||
checked: serverState.isServerStartup,
|
||||
onChanged: (b) =>
|
||||
_onSwitchServer(context, b, serverModel)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
textAlign: TextAlign.end,
|
||||
S.current.input_method_disclaimer,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.white.withValues(alpha: .6),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeTitle(BuildContext context, InputMethodDialogUIState state,
|
||||
InputMethodDialogUIModel model, TextEditingController destTextCtrl) {
|
||||
return Row(
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
FluentIcons.back,
|
||||
size: 22,
|
||||
),
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
}),
|
||||
const SizedBox(width: 12),
|
||||
Text(S.current.input_method_experimental_input_method),
|
||||
Spacer(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
S.current.input_method_auto_copy,
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
ToggleSwitch(
|
||||
checked: state.enableAutoCopy,
|
||||
onChanged: model.onSwitchAutoCopy),
|
||||
],
|
||||
),
|
||||
SizedBox(width: 24),
|
||||
FilledButton(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6),
|
||||
child: Icon(FluentIcons.copy),
|
||||
),
|
||||
onPressed: () {
|
||||
if (destTextCtrl.text.isNotEmpty) {
|
||||
Clipboard.setData(ClipboardData(text: destTextCtrl.text));
|
||||
}
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onSwitchServer(
|
||||
BuildContext context, bool value, InputMethodServer serverModel) async {
|
||||
if (value) {
|
||||
final userOK = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.input_method_confirm_enable_remote_input,
|
||||
Text(S.current.input_method_enable_remote_input_instructions));
|
||||
if (userOK) {
|
||||
// ignore: use_build_context_synchronously
|
||||
await serverModel.startServer().unwrap(context: context);
|
||||
if (!context.mounted) return;
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => ServerQrDialogUI(),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
await serverModel.stopServer().unwrap(context: context);
|
||||
}
|
||||
}
|
||||
|
||||
_onSwitchAutoTranslate(
|
||||
BuildContext context, InputMethodDialogUIModel model, bool b) async {
|
||||
if (b) {
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.input_method_auto_translate_dialog_title,
|
||||
Text(S.current.input_method_auto_translate_dialog_title_content));
|
||||
if (ok != true) return;
|
||||
}
|
||||
model.toggleAutoTranslate(b);
|
||||
}
|
||||
}
|
191
lib/ui/home/input_method/input_method_dialog_ui_model.dart
Normal file
191
lib/ui/home/input_method/input_method_dialog_ui_model.dart
Normal file
@ -0,0 +1,191 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/api/api.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/localization/localization_ui_model.dart';
|
||||
|
||||
part 'input_method_dialog_ui_model.g.dart';
|
||||
|
||||
part 'input_method_dialog_ui_model.freezed.dart';
|
||||
|
||||
@freezed
|
||||
class InputMethodDialogUIState with _$InputMethodDialogUIState {
|
||||
factory InputMethodDialogUIState(
|
||||
Map<String, String>? keyMaps,
|
||||
Map<String, String>? worldMaps, {
|
||||
@Default(false) bool enableAutoCopy,
|
||||
@Default(false) bool isEnableAutoTranslate,
|
||||
@Default(false) bool isAutoTranslateWorking,
|
||||
}) = _InputMethodDialogUIState;
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class InputMethodDialogUIModel extends _$InputMethodDialogUIModel {
|
||||
@override
|
||||
InputMethodDialogUIState build() {
|
||||
state = InputMethodDialogUIState(null, null);
|
||||
_init();
|
||||
return state;
|
||||
}
|
||||
|
||||
_init({bool skipUpdate = false}) async {
|
||||
final localizationState = ref.read(localizationUIModelProvider);
|
||||
final localizationModel = ref.read(localizationUIModelProvider.notifier);
|
||||
if (localizationState.installedCommunityInputMethodSupportVersion == null) {
|
||||
return;
|
||||
}
|
||||
if (!skipUpdate) await localizationModel.checkCommunityInputMethodUpdate();
|
||||
final keyMaps =
|
||||
await localizationModel.getCommunityInputMethodSupportData();
|
||||
dPrint("[InputMethodDialogUIModel] keyMapsLen: ${keyMaps?.length}");
|
||||
final worldMaps = keyMaps?.map((key, value) => MapEntry(value.trim(), key));
|
||||
final appBox = await Hive.openBox("app_conf");
|
||||
final enableAutoCopy = appBox.get("enableAutoCopy", defaultValue: false);
|
||||
final isEnableAutoTranslate =
|
||||
appBox.get("isEnableAutoTranslate", defaultValue: false);
|
||||
state = state.copyWith(
|
||||
keyMaps: keyMaps,
|
||||
worldMaps: worldMaps,
|
||||
enableAutoCopy: enableAutoCopy,
|
||||
isEnableAutoTranslate: isEnableAutoTranslate,
|
||||
);
|
||||
}
|
||||
|
||||
void onSwitchAutoCopy(bool value) async {
|
||||
final appBox = await Hive.openBox("app_conf");
|
||||
appBox.put("enableAutoCopy", value);
|
||||
state = state.copyWith(enableAutoCopy: value);
|
||||
}
|
||||
|
||||
String? onTextChange(String type, String str, {formWeb = false}) {
|
||||
if (state.keyMaps == null || state.worldMaps == null) return null;
|
||||
StringBuffer sb = StringBuffer();
|
||||
final r = RegExp(r'^[a-zA-Z0-9\p{P}\p{S}]+$');
|
||||
if (type == "src") {
|
||||
final map = state.worldMaps!;
|
||||
// text to code
|
||||
var leftSafe = true;
|
||||
for (var c in str.characters) {
|
||||
if (r.hasMatch((c))) {
|
||||
if (leftSafe) {
|
||||
sb.write(c);
|
||||
} else {
|
||||
sb.write(" $c");
|
||||
}
|
||||
leftSafe = true;
|
||||
continue;
|
||||
} else {
|
||||
// 特殊字符,开始转码
|
||||
final code = map[c.trim()];
|
||||
// dPrint("c:$c code: $code");
|
||||
if (code != null) {
|
||||
if (leftSafe) {
|
||||
sb.write(" ");
|
||||
}
|
||||
sb.write("@$code");
|
||||
} else {
|
||||
// 不支持转码,用空格代替
|
||||
sb.write(" ");
|
||||
}
|
||||
leftSafe = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sb.toString().trim().isEmpty) {
|
||||
return "";
|
||||
}
|
||||
final text = "[zh] ${sb.toString()}";
|
||||
if (!formWeb) {
|
||||
_handleAutoCopy(text);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
Timer? _autoCopyTimer;
|
||||
|
||||
// 打字结束后的1秒后自动复制,避免频繁复制
|
||||
void _handleAutoCopy(String text) {
|
||||
if (state.isEnableAutoTranslate) return;
|
||||
if (_autoCopyTimer != null) {
|
||||
_autoCopyTimer?.cancel();
|
||||
_autoCopyTimer = null;
|
||||
}
|
||||
if (!state.enableAutoCopy) return;
|
||||
_autoCopyTimer = Timer(const Duration(seconds: 1), () {
|
||||
if (state.enableAutoCopy) {
|
||||
dPrint("auto copy: $text");
|
||||
Clipboard.setData(ClipboardData(text: text));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
TextEditingController? _srcTextCtrl;
|
||||
TextEditingController? _destTextCtrl;
|
||||
|
||||
void setUpController(
|
||||
TextEditingController srcTextCtrl, TextEditingController destTextCtrl) {
|
||||
_srcTextCtrl = srcTextCtrl;
|
||||
_destTextCtrl = destTextCtrl;
|
||||
}
|
||||
|
||||
Future<void> onSendText(
|
||||
String text, {
|
||||
bool autoCopy = false,
|
||||
bool autoInput = false,
|
||||
}) async {
|
||||
debugPrint("[InputMethodDialogUIState] onSendText: $text");
|
||||
_srcTextCtrl?.text = text;
|
||||
_destTextCtrl?.text = onTextChange("src", text) ?? "";
|
||||
if (_destTextCtrl?.text.isEmpty ?? true) return;
|
||||
checkAutoTranslate(webMessage: true);
|
||||
if (autoCopy && !state.isAutoTranslateWorking) {
|
||||
Clipboard.setData(ClipboardData(text: _destTextCtrl?.text ?? ""));
|
||||
}
|
||||
}
|
||||
|
||||
toggleAutoTranslate(bool b) async {
|
||||
state = state.copyWith(isEnableAutoTranslate: b);
|
||||
final appConf = await Hive.openBox("app_conf");
|
||||
await appConf.put("isEnableAutoTranslate", b);
|
||||
}
|
||||
|
||||
Timer? _translateTimer;
|
||||
|
||||
Future<void> checkAutoTranslate({bool webMessage = false}) async {
|
||||
final sourceText = _srcTextCtrl?.text ?? "";
|
||||
final content = _destTextCtrl?.text ?? "";
|
||||
if (sourceText.trim().isEmpty) return;
|
||||
if (state.isEnableAutoTranslate) {
|
||||
if (_translateTimer != null) _translateTimer?.cancel();
|
||||
state = state.copyWith(isAutoTranslateWorking: true);
|
||||
_translateTimer =
|
||||
Timer(Duration(milliseconds: webMessage ? 1 : 400), () async {
|
||||
try {
|
||||
final inputText = sourceText.replaceAll("\n", " ");
|
||||
final r = await Api.doGoogleTranslate(inputText);
|
||||
if (r != null) {
|
||||
String resultText = r;
|
||||
// resultText 首字母大写
|
||||
if (content.isNotEmpty) {
|
||||
final firstChar = resultText.characters.first;
|
||||
resultText =
|
||||
resultText.replaceFirst(firstChar, firstChar.toUpperCase());
|
||||
}
|
||||
_destTextCtrl?.text = "$content \n[en] $resultText";
|
||||
if (state.enableAutoCopy || webMessage) {
|
||||
Clipboard.setData(ClipboardData(text: _destTextCtrl?.text ?? ""));
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
dPrint("[InputMethodDialogUIModel] AutoTranslate error: $e");
|
||||
}
|
||||
state = state.copyWith(isAutoTranslateWorking: false);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,261 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'input_method_dialog_ui_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||
|
||||
/// @nodoc
|
||||
mixin _$InputMethodDialogUIState {
|
||||
Map<String, String>? get keyMaps => throw _privateConstructorUsedError;
|
||||
Map<String, String>? get worldMaps => throw _privateConstructorUsedError;
|
||||
bool get enableAutoCopy => throw _privateConstructorUsedError;
|
||||
bool get isEnableAutoTranslate => throw _privateConstructorUsedError;
|
||||
bool get isAutoTranslateWorking => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of InputMethodDialogUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$InputMethodDialogUIStateCopyWith<InputMethodDialogUIState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $InputMethodDialogUIStateCopyWith<$Res> {
|
||||
factory $InputMethodDialogUIStateCopyWith(InputMethodDialogUIState value,
|
||||
$Res Function(InputMethodDialogUIState) then) =
|
||||
_$InputMethodDialogUIStateCopyWithImpl<$Res, InputMethodDialogUIState>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{Map<String, String>? keyMaps,
|
||||
Map<String, String>? worldMaps,
|
||||
bool enableAutoCopy,
|
||||
bool isEnableAutoTranslate,
|
||||
bool isAutoTranslateWorking});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$InputMethodDialogUIStateCopyWithImpl<$Res,
|
||||
$Val extends InputMethodDialogUIState>
|
||||
implements $InputMethodDialogUIStateCopyWith<$Res> {
|
||||
_$InputMethodDialogUIStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of InputMethodDialogUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? keyMaps = freezed,
|
||||
Object? worldMaps = freezed,
|
||||
Object? enableAutoCopy = null,
|
||||
Object? isEnableAutoTranslate = null,
|
||||
Object? isAutoTranslateWorking = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
keyMaps: freezed == keyMaps
|
||||
? _value.keyMaps
|
||||
: keyMaps // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, String>?,
|
||||
worldMaps: freezed == worldMaps
|
||||
? _value.worldMaps
|
||||
: worldMaps // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, String>?,
|
||||
enableAutoCopy: null == enableAutoCopy
|
||||
? _value.enableAutoCopy
|
||||
: enableAutoCopy // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
isEnableAutoTranslate: null == isEnableAutoTranslate
|
||||
? _value.isEnableAutoTranslate
|
||||
: isEnableAutoTranslate // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
isAutoTranslateWorking: null == isAutoTranslateWorking
|
||||
? _value.isAutoTranslateWorking
|
||||
: isAutoTranslateWorking // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$InputMethodDialogUIStateImplCopyWith<$Res>
|
||||
implements $InputMethodDialogUIStateCopyWith<$Res> {
|
||||
factory _$$InputMethodDialogUIStateImplCopyWith(
|
||||
_$InputMethodDialogUIStateImpl value,
|
||||
$Res Function(_$InputMethodDialogUIStateImpl) then) =
|
||||
__$$InputMethodDialogUIStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{Map<String, String>? keyMaps,
|
||||
Map<String, String>? worldMaps,
|
||||
bool enableAutoCopy,
|
||||
bool isEnableAutoTranslate,
|
||||
bool isAutoTranslateWorking});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$InputMethodDialogUIStateImplCopyWithImpl<$Res>
|
||||
extends _$InputMethodDialogUIStateCopyWithImpl<$Res,
|
||||
_$InputMethodDialogUIStateImpl>
|
||||
implements _$$InputMethodDialogUIStateImplCopyWith<$Res> {
|
||||
__$$InputMethodDialogUIStateImplCopyWithImpl(
|
||||
_$InputMethodDialogUIStateImpl _value,
|
||||
$Res Function(_$InputMethodDialogUIStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of InputMethodDialogUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? keyMaps = freezed,
|
||||
Object? worldMaps = freezed,
|
||||
Object? enableAutoCopy = null,
|
||||
Object? isEnableAutoTranslate = null,
|
||||
Object? isAutoTranslateWorking = null,
|
||||
}) {
|
||||
return _then(_$InputMethodDialogUIStateImpl(
|
||||
freezed == keyMaps
|
||||
? _value._keyMaps
|
||||
: keyMaps // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, String>?,
|
||||
freezed == worldMaps
|
||||
? _value._worldMaps
|
||||
: worldMaps // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, String>?,
|
||||
enableAutoCopy: null == enableAutoCopy
|
||||
? _value.enableAutoCopy
|
||||
: enableAutoCopy // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
isEnableAutoTranslate: null == isEnableAutoTranslate
|
||||
? _value.isEnableAutoTranslate
|
||||
: isEnableAutoTranslate // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
isAutoTranslateWorking: null == isAutoTranslateWorking
|
||||
? _value.isAutoTranslateWorking
|
||||
: isAutoTranslateWorking // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$InputMethodDialogUIStateImpl implements _InputMethodDialogUIState {
|
||||
_$InputMethodDialogUIStateImpl(
|
||||
final Map<String, String>? keyMaps, final Map<String, String>? worldMaps,
|
||||
{this.enableAutoCopy = false,
|
||||
this.isEnableAutoTranslate = false,
|
||||
this.isAutoTranslateWorking = false})
|
||||
: _keyMaps = keyMaps,
|
||||
_worldMaps = worldMaps;
|
||||
|
||||
final Map<String, String>? _keyMaps;
|
||||
@override
|
||||
Map<String, String>? get keyMaps {
|
||||
final value = _keyMaps;
|
||||
if (value == null) return null;
|
||||
if (_keyMaps is EqualUnmodifiableMapView) return _keyMaps;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableMapView(value);
|
||||
}
|
||||
|
||||
final Map<String, String>? _worldMaps;
|
||||
@override
|
||||
Map<String, String>? get worldMaps {
|
||||
final value = _worldMaps;
|
||||
if (value == null) return null;
|
||||
if (_worldMaps is EqualUnmodifiableMapView) return _worldMaps;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableMapView(value);
|
||||
}
|
||||
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool enableAutoCopy;
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool isEnableAutoTranslate;
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool isAutoTranslateWorking;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InputMethodDialogUIState(keyMaps: $keyMaps, worldMaps: $worldMaps, enableAutoCopy: $enableAutoCopy, isEnableAutoTranslate: $isEnableAutoTranslate, isAutoTranslateWorking: $isAutoTranslateWorking)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$InputMethodDialogUIStateImpl &&
|
||||
const DeepCollectionEquality().equals(other._keyMaps, _keyMaps) &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other._worldMaps, _worldMaps) &&
|
||||
(identical(other.enableAutoCopy, enableAutoCopy) ||
|
||||
other.enableAutoCopy == enableAutoCopy) &&
|
||||
(identical(other.isEnableAutoTranslate, isEnableAutoTranslate) ||
|
||||
other.isEnableAutoTranslate == isEnableAutoTranslate) &&
|
||||
(identical(other.isAutoTranslateWorking, isAutoTranslateWorking) ||
|
||||
other.isAutoTranslateWorking == isAutoTranslateWorking));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
const DeepCollectionEquality().hash(_keyMaps),
|
||||
const DeepCollectionEquality().hash(_worldMaps),
|
||||
enableAutoCopy,
|
||||
isEnableAutoTranslate,
|
||||
isAutoTranslateWorking);
|
||||
|
||||
/// Create a copy of InputMethodDialogUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$InputMethodDialogUIStateImplCopyWith<_$InputMethodDialogUIStateImpl>
|
||||
get copyWith => __$$InputMethodDialogUIStateImplCopyWithImpl<
|
||||
_$InputMethodDialogUIStateImpl>(this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _InputMethodDialogUIState implements InputMethodDialogUIState {
|
||||
factory _InputMethodDialogUIState(
|
||||
final Map<String, String>? keyMaps, final Map<String, String>? worldMaps,
|
||||
{final bool enableAutoCopy,
|
||||
final bool isEnableAutoTranslate,
|
||||
final bool isAutoTranslateWorking}) = _$InputMethodDialogUIStateImpl;
|
||||
|
||||
@override
|
||||
Map<String, String>? get keyMaps;
|
||||
@override
|
||||
Map<String, String>? get worldMaps;
|
||||
@override
|
||||
bool get enableAutoCopy;
|
||||
@override
|
||||
bool get isEnableAutoTranslate;
|
||||
@override
|
||||
bool get isAutoTranslateWorking;
|
||||
|
||||
/// Create a copy of InputMethodDialogUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$InputMethodDialogUIStateImplCopyWith<_$InputMethodDialogUIStateImpl>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
28
lib/ui/home/input_method/input_method_dialog_ui_model.g.dart
Normal file
28
lib/ui/home/input_method/input_method_dialog_ui_model.g.dart
Normal file
@ -0,0 +1,28 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'input_method_dialog_ui_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$inputMethodDialogUIModelHash() =>
|
||||
r'397b36296183404c07298d83c14f4bce590375fc';
|
||||
|
||||
/// See also [InputMethodDialogUIModel].
|
||||
@ProviderFor(InputMethodDialogUIModel)
|
||||
final inputMethodDialogUIModelProvider = AutoDisposeNotifierProvider<
|
||||
InputMethodDialogUIModel, InputMethodDialogUIState>.internal(
|
||||
InputMethodDialogUIModel.new,
|
||||
name: r'inputMethodDialogUIModelProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$inputMethodDialogUIModelHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$InputMethodDialogUIModel
|
||||
= AutoDisposeNotifier<InputMethodDialogUIState>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
217
lib/ui/home/input_method/server.dart
Normal file
217
lib/ui/home/input_method/server.dart
Normal file
@ -0,0 +1,217 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:shelf/shelf.dart';
|
||||
import 'package:shelf/shelf_io.dart' as shelf_io;
|
||||
import 'package:starcitizen_doctor/common/conf/conf.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/input_method/server_qr_dialog_ui.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/localization/localization_ui_model.dart';
|
||||
|
||||
import 'input_method_dialog_ui_model.dart';
|
||||
|
||||
part 'server.g.dart';
|
||||
|
||||
part 'server.freezed.dart';
|
||||
|
||||
@freezed
|
||||
class InputMethodServerState with _$InputMethodServerState {
|
||||
const factory InputMethodServerState({
|
||||
@Default(false) bool isServerStartup,
|
||||
String? serverAddressText,
|
||||
}) = _InputMethodServerState;
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class InputMethodServer extends _$InputMethodServer {
|
||||
@override
|
||||
InputMethodServerState build() {
|
||||
state = InputMethodServerState(isServerStartup: false);
|
||||
ref.onDispose(() {
|
||||
stopServer();
|
||||
});
|
||||
return state;
|
||||
}
|
||||
|
||||
LocalizationUIState get _localizationUIState =>
|
||||
ref.read(localizationUIModelProvider);
|
||||
|
||||
InputMethodDialogUIModel get _inputMethodDialogUIModel =>
|
||||
ref.read(inputMethodDialogUIModelProvider.notifier);
|
||||
|
||||
HttpServer? _httpServer;
|
||||
|
||||
Future<void> stopServer() async {
|
||||
if (_httpServer != null) {
|
||||
await _httpServer!.close(force: true);
|
||||
_httpServer = null;
|
||||
state = state.copyWith(
|
||||
isServerStartup: false,
|
||||
);
|
||||
dPrint("[InputMethodServer] stopServer");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> startServer() async {
|
||||
dPrint("[InputMethodServer] startServer");
|
||||
var handler =
|
||||
const Pipeline().addMiddleware(logRequests()).addHandler(_onHandler);
|
||||
|
||||
var server = await shelf_io.serve(
|
||||
handler, "0.0.0.0", ConstConf.inputMethodServerPort);
|
||||
|
||||
// Enable content compression
|
||||
server.autoCompress = true;
|
||||
|
||||
dPrint('Serving at http://${server.address.host}:${server.port}');
|
||||
|
||||
server.autoCompress = true;
|
||||
_httpServer = server;
|
||||
final address = await _findAddress();
|
||||
state = state.copyWith(
|
||||
isServerStartup: true,
|
||||
serverAddressText: address,
|
||||
);
|
||||
}
|
||||
|
||||
Future<String> _findAddress() async {
|
||||
final list = <String>[];
|
||||
final List<NetworkInterface> address = await NetworkInterface.list();
|
||||
bool has192168 = false;
|
||||
for (var value in address) {
|
||||
for (var addr in value.addresses) {
|
||||
if (addr.type == InternetAddressType.IPv4) {
|
||||
list.add("http://${addr.address}:${ConstConf.inputMethodServerPort}");
|
||||
if (addr.address.startsWith('192.168.')) {
|
||||
has192168 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (has192168) {
|
||||
list.removeWhere((element) => !element.contains('192.168.'));
|
||||
}
|
||||
if (list.isEmpty) {
|
||||
list.add(S.current.input_method_address_fetch_failed);
|
||||
}
|
||||
return list.join(", ");
|
||||
}
|
||||
|
||||
Future<Response> _onHandler(Request request) async {
|
||||
final path = request.url.path;
|
||||
dPrint("[InputMethodServer] path: $path");
|
||||
Uint8List? contentByte;
|
||||
String mimeType;
|
||||
try {
|
||||
if (path.startsWith('api')) {
|
||||
return _onHandlerApi(request);
|
||||
}
|
||||
if (path == '/' || path == '') {
|
||||
contentByte =
|
||||
(await rootBundle.load('assets/web/input_method/index.html'))
|
||||
.buffer
|
||||
.asUint8List();
|
||||
mimeType = 'text/html; charset=utf-8';
|
||||
} else {
|
||||
var dotOffset = path.lastIndexOf('.');
|
||||
if (path.substring(dotOffset) == '.png' ||
|
||||
path.substring(dotOffset) == '.ttf' ||
|
||||
path.substring(dotOffset) == '.otf') {
|
||||
contentByte = (await rootBundle.load('assets/web/input_method/$path'))
|
||||
.buffer
|
||||
.asUint8List();
|
||||
} else {
|
||||
contentByte = (await rootBundle.load('assets/web/input_method/$path'))
|
||||
.buffer
|
||||
.asUint8List();
|
||||
}
|
||||
|
||||
mimeType = dotOffset == -1
|
||||
? 'text/plain; charset=utf-8'
|
||||
: {
|
||||
'.html': 'text/html; charset=utf-8',
|
||||
'.css': 'text/css; charset=utf-8',
|
||||
'.js': 'text/javascript; charset=utf-8',
|
||||
'.csv': 'text/csv; charset=utf-8',
|
||||
'.txt': 'text/plain; charset=utf-8',
|
||||
'.ico': 'image/x-icon',
|
||||
'.jpg': 'image/jpg',
|
||||
'.jpeg': 'image/jpeg',
|
||||
'.png': 'image/png',
|
||||
'.gif': 'image/gif',
|
||||
'.svg': 'image/svg+xml',
|
||||
'.json': 'application/json',
|
||||
'.xml': 'application/xml',
|
||||
'.ttf': 'font/ttf',
|
||||
'.otf': 'font/otf'
|
||||
}[path.substring(dotOffset)] ??
|
||||
"application/octet-stream";
|
||||
}
|
||||
return Response.ok(
|
||||
contentByte,
|
||||
headers: {
|
||||
'Content-Type': mimeType,
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
debugPrint(e.toString());
|
||||
return Response.internalServerError();
|
||||
}
|
||||
}
|
||||
|
||||
Future<Response> _onHandlerApi(Request request) async {
|
||||
final path = request.url.path;
|
||||
if (path == "api") {
|
||||
if (ref.exists(serverQrStateProvider)) {
|
||||
// ignore: avoid_manual_providers_as_generated_provider_dependency
|
||||
ref.read(serverQrStateProvider.notifier).popDialog();
|
||||
}
|
||||
return Response.ok(json.encode({
|
||||
"status": "ok",
|
||||
"appVersion": ConstConf.appVersion,
|
||||
"appVersionCode": ConstConf.appVersionCode,
|
||||
"appVersionDate": ConstConf.appVersionDate,
|
||||
"isMSE": ConstConf.isMSE,
|
||||
"installedCommunityInputMethodSupportVersion":
|
||||
_localizationUIState.installedCommunityInputMethodSupportVersion,
|
||||
}));
|
||||
} else if (path.startsWith("api/send") && request.method == "POST") {
|
||||
final body = await request.readAsString();
|
||||
final data = json.decode(body);
|
||||
final text = data["text"] ?? "";
|
||||
if (text.isEmpty) {
|
||||
return Response.badRequest(
|
||||
body: json.encode({
|
||||
"result": "error",
|
||||
"message": S.current.input_method_text_cannot_be_empty,
|
||||
}));
|
||||
}
|
||||
final autoCopy = data["autoCopy"] ?? false;
|
||||
final autoInput = data["autoInput"] ?? false;
|
||||
try {
|
||||
await _inputMethodDialogUIModel.onSendText(
|
||||
text,
|
||||
autoCopy: autoCopy,
|
||||
autoInput: autoInput,
|
||||
);
|
||||
return Response.ok(json.encode({
|
||||
"result": "ok",
|
||||
"message": S.current.input_method_send_success,
|
||||
}));
|
||||
} catch (e) {
|
||||
return Response.internalServerError(
|
||||
body: json.encode({
|
||||
"result": "error",
|
||||
"message": e.toString(),
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
return Response.notFound("Not Found");
|
||||
}
|
||||
}
|
||||
}
|
171
lib/ui/home/input_method/server.freezed.dart
Normal file
171
lib/ui/home/input_method/server.freezed.dart
Normal file
@ -0,0 +1,171 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'server.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||
|
||||
/// @nodoc
|
||||
mixin _$InputMethodServerState {
|
||||
bool get isServerStartup => throw _privateConstructorUsedError;
|
||||
String? get serverAddressText => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of InputMethodServerState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$InputMethodServerStateCopyWith<InputMethodServerState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $InputMethodServerStateCopyWith<$Res> {
|
||||
factory $InputMethodServerStateCopyWith(InputMethodServerState value,
|
||||
$Res Function(InputMethodServerState) then) =
|
||||
_$InputMethodServerStateCopyWithImpl<$Res, InputMethodServerState>;
|
||||
@useResult
|
||||
$Res call({bool isServerStartup, String? serverAddressText});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$InputMethodServerStateCopyWithImpl<$Res,
|
||||
$Val extends InputMethodServerState>
|
||||
implements $InputMethodServerStateCopyWith<$Res> {
|
||||
_$InputMethodServerStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of InputMethodServerState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? isServerStartup = null,
|
||||
Object? serverAddressText = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
isServerStartup: null == isServerStartup
|
||||
? _value.isServerStartup
|
||||
: isServerStartup // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
serverAddressText: freezed == serverAddressText
|
||||
? _value.serverAddressText
|
||||
: serverAddressText // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$InputMethodServerStateImplCopyWith<$Res>
|
||||
implements $InputMethodServerStateCopyWith<$Res> {
|
||||
factory _$$InputMethodServerStateImplCopyWith(
|
||||
_$InputMethodServerStateImpl value,
|
||||
$Res Function(_$InputMethodServerStateImpl) then) =
|
||||
__$$InputMethodServerStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({bool isServerStartup, String? serverAddressText});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$InputMethodServerStateImplCopyWithImpl<$Res>
|
||||
extends _$InputMethodServerStateCopyWithImpl<$Res,
|
||||
_$InputMethodServerStateImpl>
|
||||
implements _$$InputMethodServerStateImplCopyWith<$Res> {
|
||||
__$$InputMethodServerStateImplCopyWithImpl(
|
||||
_$InputMethodServerStateImpl _value,
|
||||
$Res Function(_$InputMethodServerStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of InputMethodServerState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? isServerStartup = null,
|
||||
Object? serverAddressText = freezed,
|
||||
}) {
|
||||
return _then(_$InputMethodServerStateImpl(
|
||||
isServerStartup: null == isServerStartup
|
||||
? _value.isServerStartup
|
||||
: isServerStartup // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
serverAddressText: freezed == serverAddressText
|
||||
? _value.serverAddressText
|
||||
: serverAddressText // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$InputMethodServerStateImpl implements _InputMethodServerState {
|
||||
const _$InputMethodServerStateImpl(
|
||||
{this.isServerStartup = false, this.serverAddressText});
|
||||
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool isServerStartup;
|
||||
@override
|
||||
final String? serverAddressText;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InputMethodServerState(isServerStartup: $isServerStartup, serverAddressText: $serverAddressText)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$InputMethodServerStateImpl &&
|
||||
(identical(other.isServerStartup, isServerStartup) ||
|
||||
other.isServerStartup == isServerStartup) &&
|
||||
(identical(other.serverAddressText, serverAddressText) ||
|
||||
other.serverAddressText == serverAddressText));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, isServerStartup, serverAddressText);
|
||||
|
||||
/// Create a copy of InputMethodServerState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$InputMethodServerStateImplCopyWith<_$InputMethodServerStateImpl>
|
||||
get copyWith => __$$InputMethodServerStateImplCopyWithImpl<
|
||||
_$InputMethodServerStateImpl>(this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _InputMethodServerState implements InputMethodServerState {
|
||||
const factory _InputMethodServerState(
|
||||
{final bool isServerStartup,
|
||||
final String? serverAddressText}) = _$InputMethodServerStateImpl;
|
||||
|
||||
@override
|
||||
bool get isServerStartup;
|
||||
@override
|
||||
String? get serverAddressText;
|
||||
|
||||
/// Create a copy of InputMethodServerState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$InputMethodServerStateImplCopyWith<_$InputMethodServerStateImpl>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
26
lib/ui/home/input_method/server.g.dart
Normal file
26
lib/ui/home/input_method/server.g.dart
Normal file
@ -0,0 +1,26 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'server.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$inputMethodServerHash() => r'58ff318c051f16c76f620258520aadedbdd5057c';
|
||||
|
||||
/// See also [InputMethodServer].
|
||||
@ProviderFor(InputMethodServer)
|
||||
final inputMethodServerProvider = AutoDisposeNotifierProvider<InputMethodServer,
|
||||
InputMethodServerState>.internal(
|
||||
InputMethodServer.new,
|
||||
name: r'inputMethodServerProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$inputMethodServerHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$InputMethodServer = AutoDisposeNotifier<InputMethodServerState>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
123
lib/ui/home/input_method/server_qr_dialog_ui.dart
Normal file
123
lib/ui/home/input_method/server_qr_dialog_ui.dart
Normal file
@ -0,0 +1,123 @@
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/generated/l10n.dart';
|
||||
|
||||
import 'server.dart';
|
||||
|
||||
part 'server_qr_dialog_ui.g.dart';
|
||||
|
||||
@riverpod
|
||||
class ServerQrState extends _$ServerQrState {
|
||||
@override
|
||||
bool build() {
|
||||
return true;
|
||||
}
|
||||
|
||||
BuildContext? _context;
|
||||
|
||||
// ignore: avoid_build_context_in_providers
|
||||
void setupContext(BuildContext context) {
|
||||
_context = context;
|
||||
}
|
||||
|
||||
popDialog() {
|
||||
_context?.pop();
|
||||
}
|
||||
}
|
||||
|
||||
class ServerQrDialogUI extends HookConsumerWidget {
|
||||
const ServerQrDialogUI({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final serverState = ref.watch(inputMethodServerProvider);
|
||||
|
||||
final urls = serverState.serverAddressText?.split(",") ?? [""];
|
||||
|
||||
final hasMultipleUrls = urls.length > 1;
|
||||
|
||||
final index = useState(0);
|
||||
|
||||
final model = ref.watch(serverQrStateProvider.notifier);
|
||||
|
||||
model.setupContext(context);
|
||||
|
||||
return ContentDialog(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: MediaQuery.of(context).size.width * .4,
|
||||
),
|
||||
title: makeTitle(context),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(width: double.infinity, height: 12),
|
||||
if (hasMultipleUrls) ...[
|
||||
Text(S.current.input_method_ip_address_not_found),
|
||||
] else
|
||||
Text(
|
||||
S.current.input_method_scan_qr_code,
|
||||
style: TextStyle(color: Colors.white.withValues(alpha: .8)),
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if (hasMultipleUrls)
|
||||
IconButton(
|
||||
icon: Icon(FluentIcons.chevron_left),
|
||||
onPressed: () {
|
||||
index.value = (index.value - 1) % urls.length;
|
||||
}),
|
||||
SizedBox(width: 24),
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child: QrImageView(
|
||||
data: urls[index.value],
|
||||
size: 200,
|
||||
padding: EdgeInsets.all(12),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 24),
|
||||
if (hasMultipleUrls)
|
||||
IconButton(
|
||||
icon: Icon(FluentIcons.chevron_right),
|
||||
onPressed: () {
|
||||
index.value = (index.value + 1) % urls.length;
|
||||
}),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
Text(
|
||||
hasMultipleUrls
|
||||
? "${urls[index.value]} (${index.value + 1} / ${urls.length})"
|
||||
: urls[index.value],
|
||||
style: TextStyle(
|
||||
fontSize: 13, color: Colors.white.withValues(alpha: .6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget makeTitle(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
FluentIcons.back,
|
||||
size: 22,
|
||||
),
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
}),
|
||||
const SizedBox(width: 12),
|
||||
Text(S.current.input_method_service_qr_code),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
26
lib/ui/home/input_method/server_qr_dialog_ui.g.dart
Normal file
26
lib/ui/home/input_method/server_qr_dialog_ui.g.dart
Normal file
@ -0,0 +1,26 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'server_qr_dialog_ui.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$serverQrStateHash() => r'06f5ab53e1d6718f2a6eb0078a1adc3778787ed0';
|
||||
|
||||
/// See also [ServerQrState].
|
||||
@ProviderFor(ServerQrState)
|
||||
final serverQrStateProvider =
|
||||
AutoDisposeNotifierProvider<ServerQrState, bool>.internal(
|
||||
ServerQrState.new,
|
||||
name: r'serverQrStateProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$serverQrStateHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$ServerQrState = AutoDisposeNotifier<bool>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user