mirror of
https://mirror.ghproxy.com/https://github.com/StarCitizenToolBox/app.git
synced 2024-12-23 05:23:44 +08:00
初始化登录功能
This commit is contained in:
parent
59412db924
commit
6153bcf9c0
@ -24,6 +24,7 @@ linter:
|
|||||||
rules:
|
rules:
|
||||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||||
|
dangling_library_doc_comments: false
|
||||||
|
|
||||||
# Additional information about this file can be found at
|
# Additional information about this file can be found at
|
||||||
# https://dart.dev/guides/language/analysis-options
|
# https://dart.dev/guides/language/analysis-options
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/// https://github.com/CxJuice/Uex_Chinese_Translate
|
/// https://github.com/CxJuice/Uex_Chinese_Translate
|
||||||
|
|
||||||
|
/// ------- WebLocalization Script --------------
|
||||||
let SCLocalizationReplaceLocalesMap = {};
|
let SCLocalizationReplaceLocalesMap = {};
|
||||||
let enable_webview_localization_capture = false;
|
let enable_webview_localization_capture = false;
|
||||||
let SCLocalizationEnableSplitMode = false;
|
let SCLocalizationEnableSplitMode = false;
|
||||||
@ -217,3 +217,67 @@ function ReportUnTranslate(k, v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
InitWebLocalization();
|
InitWebLocalization();
|
||||||
|
|
||||||
|
|
||||||
|
/// ----- Login Script ----
|
||||||
|
async function getRSILauncherToken() {
|
||||||
|
// check login
|
||||||
|
let r = await fetch("api/launcher/v3/account/check", {
|
||||||
|
method: 'POST', headers: {
|
||||||
|
'x-rsi-token': $.cookie('Rsi-Token'),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (r.status !== 200) {
|
||||||
|
// wait login
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get claims
|
||||||
|
let claimsR = await fetch("api/launcher/v3/games/claims", {
|
||||||
|
method: 'POST', headers: {
|
||||||
|
'x-rsi-token': $.cookie('Rsi-Token'),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (claimsR.status !== 200) return;
|
||||||
|
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", {
|
||||||
|
method: 'POST', headers: {
|
||||||
|
'x-rsi-token': $.cookie('Rsi-Token'),
|
||||||
|
},
|
||||||
|
body: tokenFormData
|
||||||
|
});
|
||||||
|
|
||||||
|
if (tokenR.status !== 200) return;
|
||||||
|
let TokenData = (await tokenR.json())["data"];
|
||||||
|
console.log(TokenData);
|
||||||
|
|
||||||
|
// get release Data
|
||||||
|
let releaseFormData = new FormData();
|
||||||
|
releaseFormData.append("channelId", "LIVE");
|
||||||
|
releaseFormData.append("claims", claimsData);
|
||||||
|
releaseFormData.append("gameId", "SC");
|
||||||
|
releaseFormData.append("platformId", "prod");
|
||||||
|
let releaseR = await fetch("api/launcher/v3/games/release", {
|
||||||
|
method: 'POST', headers: {
|
||||||
|
'x-rsi-token': $.cookie('Rsi-Token'),
|
||||||
|
},
|
||||||
|
body: releaseFormData
|
||||||
|
});
|
||||||
|
if (releaseR.status !== 200) return;
|
||||||
|
let releaseDataJson = await releaseR.json();
|
||||||
|
console.log(releaseDataJson);
|
||||||
|
|
||||||
|
// post message
|
||||||
|
window.chrome.webview.postMessage({
|
||||||
|
action: 'webview_rsi_login_success', data: {
|
||||||
|
'webToken': $.cookie('Rsi-Token'),
|
||||||
|
'claims': claimsData,
|
||||||
|
'authToken': TokenData,
|
||||||
|
'releaseInfo': releaseDataJson
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -16,8 +16,7 @@ class BaseUIContainer extends ConsumerStatefulWidget {
|
|||||||
final dynamic Function() modelCreate;
|
final dynamic Function() modelCreate;
|
||||||
|
|
||||||
const BaseUIContainer(
|
const BaseUIContainer(
|
||||||
{Key? key, required this.uiCreate, required this.modelCreate})
|
{super.key, required this.uiCreate, required this.modelCreate});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// ignore: no_logic_in_create_state
|
// ignore: no_logic_in_create_state
|
||||||
|
@ -51,7 +51,7 @@ class AppUI extends BaseUI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class WindowButtons extends StatelessWidget {
|
class WindowButtons extends StatelessWidget {
|
||||||
const WindowButtons({Key? key}) : super(key: key);
|
const WindowButtons({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -388,9 +388,12 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
goWebView(String title, String url, {bool useLocalization = false}) async {
|
goWebView(String title, String url,
|
||||||
|
{bool useLocalization = false,
|
||||||
|
bool loginMode = false,
|
||||||
|
RsiLoginCallback? rsiLoginCallback}) async {
|
||||||
if (useLocalization) {
|
if (useLocalization) {
|
||||||
const tipVersion = 1;
|
const tipVersion = 2;
|
||||||
final box = await Hive.openBox("app_conf");
|
final box = await Hive.openBox("app_conf");
|
||||||
final skip =
|
final skip =
|
||||||
await box.get("skip_web_localization_tip_version", defaultValue: 0);
|
await box.get("skip_web_localization_tip_version", defaultValue: 0);
|
||||||
@ -399,15 +402,18 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
context!,
|
context!,
|
||||||
"星际公民官网汉化",
|
"星际公民官网汉化",
|
||||||
const Text(
|
const Text(
|
||||||
"该汉化功能移植自星际公民汉化组的 Tampermonkey 浏览器插件(https://greasyfork.org/zh-CN/scripts/459084),文本内容由星际公民汉化组进行更新。"
|
|
||||||
"\n\n移植后的脚本源代码随 StarCitizenDoctor 项目一起分发(https://jihulab.com/StarCitizenCN_Community/StarCitizenDoctor)。"
|
|
||||||
"\n\n\n本插功能件仅供大致浏览使用,不对任何有关本功能产生的问题负责!在涉及账号操作前请注意确认网站的原本内容!"
|
"\n\n\n本插功能件仅供大致浏览使用,不对任何有关本功能产生的问题负责!在涉及账号操作前请注意确认网站的原本内容!"
|
||||||
"\n\n\n使用此功能登录账号时请确保您的 StarCitizenDoctor 是从可信任的来源下载。",
|
"\n\n\n使用此功能登录账号时请确保您的 StarCitizenDoctor 是从可信任的来源下载。",
|
||||||
style: TextStyle(fontSize: 16),
|
style: TextStyle(fontSize: 16),
|
||||||
),
|
),
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: MediaQuery.of(context!).size.width * .6));
|
maxWidth: MediaQuery.of(context!).size.width * .6));
|
||||||
if (!ok) return;
|
if (!ok) {
|
||||||
|
if (loginMode) {
|
||||||
|
rsiLoginCallback?.call(null, false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
await box.put("skip_web_localization_tip_version", tipVersion);
|
await box.put("skip_web_localization_tip_version", tipVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -417,7 +423,8 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
"https://developer.microsoft.com/en-us/microsoft-edge/webview2/");
|
"https://developer.microsoft.com/en-us/microsoft-edge/webview2/");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final webViewModel = WebViewModel(context!);
|
final webViewModel = WebViewModel(context!,
|
||||||
|
loginMode: loginMode, loginCallback: rsiLoginCallback);
|
||||||
if (useLocalization) {
|
if (useLocalization) {
|
||||||
isFixingString = "正在初始化汉化资源...";
|
isFixingString = "正在初始化汉化资源...";
|
||||||
isFixing = true;
|
isFixing = true;
|
||||||
@ -431,7 +438,9 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
isFixing = false;
|
isFixing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
await webViewModel.initWebView(title: title);
|
await webViewModel.initWebView(
|
||||||
|
title: title,
|
||||||
|
);
|
||||||
if (await File(
|
if (await File(
|
||||||
"${AppConf.applicationSupportDir}\\webview_data\\enable_webview_localization_capture")
|
"${AppConf.applicationSupportDir}\\webview_data\\enable_webview_localization_capture")
|
||||||
.exists()) {
|
.exists()) {
|
||||||
@ -453,17 +462,19 @@ class HomeUIModel extends BaseUIModel {
|
|||||||
launchRSI() async {
|
launchRSI() async {
|
||||||
isRsiLauncherStarting = true;
|
isRsiLauncherStarting = true;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
final rsiLauncherInstalledPath = await SystemHelper.getRSILauncherPath();
|
// final rsiLauncherInstalledPath = await SystemHelper.getRSILauncherPath();
|
||||||
if (rsiLauncherInstalledPath.isEmpty) {
|
// if (rsiLauncherInstalledPath.isEmpty) {
|
||||||
|
// isRsiLauncherStarting = false;
|
||||||
|
// notifyListeners();
|
||||||
|
// showToast(context!, "未找到 RSI 启动器目录");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// SystemHelper.checkAndLaunchRSILauncher(rsiLauncherInstalledPath);
|
||||||
|
goWebView("登录 RSI 账户", "https://robertsspaceindustries.com/connect",
|
||||||
|
loginMode: true, rsiLoginCallback: (data, ok) {
|
||||||
isRsiLauncherStarting = false;
|
isRsiLauncherStarting = false;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
showToast(context!, "未找到 RSI 启动器目录");
|
}, useLocalization: true);
|
||||||
return;
|
|
||||||
}
|
|
||||||
SystemHelper.checkAndLaunchRSILauncher(rsiLauncherInstalledPath);
|
|
||||||
await Future.delayed(const Duration(seconds: 3));
|
|
||||||
isRsiLauncherStarting = false;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRSIServerStatusOK(Map map) {
|
bool isRSIServerStatusOK(Map map) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:desktop_webview_window/desktop_webview_window.dart';
|
import 'package:desktop_webview_window/desktop_webview_window.dart';
|
||||||
@ -12,6 +13,8 @@ import 'package:starcitizen_doctor/data/app_web_localization_versions_data.dart'
|
|||||||
import '../../../api/api.dart';
|
import '../../../api/api.dart';
|
||||||
import '../../../base/ui.dart';
|
import '../../../base/ui.dart';
|
||||||
|
|
||||||
|
typedef RsiLoginCallback = void Function(Map? data, bool success);
|
||||||
|
|
||||||
class WebViewModel {
|
class WebViewModel {
|
||||||
late Webview webview;
|
late Webview webview;
|
||||||
final BuildContext context;
|
final BuildContext context;
|
||||||
@ -20,7 +23,7 @@ class WebViewModel {
|
|||||||
|
|
||||||
bool get isClosed => _isClosed;
|
bool get isClosed => _isClosed;
|
||||||
|
|
||||||
WebViewModel(this.context);
|
WebViewModel(this.context, {this.loginMode = false, this.loginCallback});
|
||||||
|
|
||||||
String url = "";
|
String url = "";
|
||||||
bool canGoBack = false;
|
bool canGoBack = false;
|
||||||
@ -35,19 +38,27 @@ class WebViewModel {
|
|||||||
|
|
||||||
Map<String, String>? get curReplaceWords => _curReplaceWords;
|
Map<String, String>? get curReplaceWords => _curReplaceWords;
|
||||||
|
|
||||||
|
final bool loginMode;
|
||||||
|
|
||||||
|
bool _loginModeSuccess = false;
|
||||||
|
|
||||||
|
final RsiLoginCallback? loginCallback;
|
||||||
|
|
||||||
initWebView({String title = ""}) async {
|
initWebView({String title = ""}) async {
|
||||||
try {
|
try {
|
||||||
webview = await WebviewWindow.create(
|
webview = await WebviewWindow.create(
|
||||||
configuration: CreateConfiguration(
|
configuration: CreateConfiguration(
|
||||||
windowWidth: 1920,
|
windowWidth: loginMode ? 960 : 1920,
|
||||||
windowHeight: 1080,
|
windowHeight: loginMode ? 720 : 1080,
|
||||||
userDataFolderWindows:
|
userDataFolderWindows:
|
||||||
"${AppConf.applicationSupportDir}/webview_data",
|
"${AppConf.applicationSupportDir}/webview_data",
|
||||||
title: title));
|
title: title));
|
||||||
|
|
||||||
// webview.openDevToolsWindow();
|
// webview.openDevToolsWindow();
|
||||||
webview.isNavigating.addListener(() async {
|
webview.isNavigating.addListener(() async {
|
||||||
if (!webview.isNavigating.value && localizationResource.isNotEmpty) {
|
if (!webview.isNavigating.value && localizationResource.isNotEmpty) {
|
||||||
final uri = Uri.parse(url);
|
final uri = Uri.parse(url);
|
||||||
|
dPrint("webview Navigating uri === $uri");
|
||||||
if (uri.host.contains("robertsspaceindustries.com")) {
|
if (uri.host.contains("robertsspaceindustries.com")) {
|
||||||
// SC 官网
|
// SC 官网
|
||||||
dPrint("load script");
|
dPrint("load script");
|
||||||
@ -103,6 +114,11 @@ class WebViewModel {
|
|||||||
await Future.delayed(const Duration(milliseconds: 100));
|
await Future.delayed(const Duration(milliseconds: 100));
|
||||||
await webview.evaluateJavaScript(
|
await webview.evaluateJavaScript(
|
||||||
"WebLocalizationUpdateReplaceWords(${json.encode(replaceWords)},$enableCapture)");
|
"WebLocalizationUpdateReplaceWords(${json.encode(replaceWords)},$enableCapture)");
|
||||||
|
if (loginMode) {
|
||||||
|
dPrint("--- do rsi login ---");
|
||||||
|
await Future.delayed(const Duration(milliseconds: 200));
|
||||||
|
webview.evaluateJavaScript("getRSILauncherToken();");
|
||||||
|
}
|
||||||
} else if (uri.host.contains("www.erkul.games") ||
|
} else if (uri.host.contains("www.erkul.games") ||
|
||||||
uri.host.contains("uexcorp.space") ||
|
uri.host.contains("uexcorp.space") ||
|
||||||
uri.host.contains("ccugame.app")) {
|
uri.host.contains("ccugame.app")) {
|
||||||
@ -121,9 +137,17 @@ class WebViewModel {
|
|||||||
dPrint("OnUrlRequestCallback === $url");
|
dPrint("OnUrlRequestCallback === $url");
|
||||||
this.url = url;
|
this.url = url;
|
||||||
});
|
});
|
||||||
webview.onClose.whenComplete(() {
|
webview.onClose.whenComplete(dispose);
|
||||||
_isClosed = true;
|
if (loginMode) {
|
||||||
});
|
webview.addOnWebMessageReceivedCallback((messageString) {
|
||||||
|
final message = json.decode(messageString);
|
||||||
|
if (message["action"] == "webview_rsi_login_success") {
|
||||||
|
_loginModeSuccess = true;
|
||||||
|
loginCallback?.call(message, true);
|
||||||
|
webview.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showToast(context, "初始化失败:$e");
|
showToast(context, "初始化失败:$e");
|
||||||
}
|
}
|
||||||
@ -211,4 +235,11 @@ class WebViewModel {
|
|||||||
OnWebMessageReceivedCallback callback) {
|
OnWebMessageReceivedCallback callback) {
|
||||||
webview.removeOnWebMessageReceivedCallback(callback);
|
webview.removeOnWebMessageReceivedCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FutureOr<void> dispose() {
|
||||||
|
if (loginMode && !_loginModeSuccess) {
|
||||||
|
loginCallback?.call(null, false);
|
||||||
|
}
|
||||||
|
_isClosed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,45 +60,45 @@ fastPadding(
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> makeMarkdownView(String description) {
|
List<Widget> makeMarkdownView(String description) {
|
||||||
return MarkdownGenerator(
|
return MarkdownGenerator().buildWidgets(description,
|
||||||
config: MarkdownConfig(configs: [
|
config: MarkdownConfig(configs: [
|
||||||
LinkConfig(onTap: (url) {
|
LinkConfig(onTap: (url) {
|
||||||
if (url.startsWith("/")) {
|
if (url.startsWith("/")) {
|
||||||
url = "${AppConf.gitlabHomeUrl}/$url";
|
url = "${AppConf.gitlabHomeUrl}/$url";
|
||||||
}
|
|
||||||
launchUrlString(url);
|
|
||||||
}),
|
|
||||||
ImgConfig(builder: (String url, Map<String, String> attributes) {
|
|
||||||
return ExtendedImage.network(
|
|
||||||
url,
|
|
||||||
loadStateChanged: (ExtendedImageState state) {
|
|
||||||
switch (state.extendedImageLoadState) {
|
|
||||||
case LoadState.loading:
|
|
||||||
return const Center(
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.all(8.0),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
ProgressRing(),
|
|
||||||
SizedBox(
|
|
||||||
height: 12,
|
|
||||||
),
|
|
||||||
Text("加载图片...")
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
case LoadState.completed:
|
|
||||||
return ExtendedRawImage(
|
|
||||||
image: state.extendedImageInfo?.image,
|
|
||||||
);
|
|
||||||
case LoadState.failed:
|
|
||||||
return const Text("Loading Image error");
|
|
||||||
}
|
}
|
||||||
},
|
launchUrlString(url);
|
||||||
);
|
}),
|
||||||
})
|
ImgConfig(builder: (String url, Map<String, String> attributes) {
|
||||||
])).buildWidgets(description);
|
return ExtendedImage.network(
|
||||||
|
url,
|
||||||
|
loadStateChanged: (ExtendedImageState state) {
|
||||||
|
switch (state.extendedImageLoadState) {
|
||||||
|
case LoadState.loading:
|
||||||
|
return const Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
ProgressRing(),
|
||||||
|
SizedBox(
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
Text("加载图片...")
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case LoadState.completed:
|
||||||
|
return ExtendedRawImage(
|
||||||
|
image: state.extendedImageInfo?.image,
|
||||||
|
);
|
||||||
|
case LoadState.failed:
|
||||||
|
return const Text("Loading Image error");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
})
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
class NoScrollBehavior extends ScrollBehavior {
|
class NoScrollBehavior extends ScrollBehavior {
|
||||||
|
@ -44,7 +44,7 @@ dependencies:
|
|||||||
markdown_widget: ^2.2.0
|
markdown_widget: ^2.2.0
|
||||||
extended_image: ^8.1.1
|
extended_image: ^8.1.1
|
||||||
device_info_plus: ^9.0.3
|
device_info_plus: ^9.0.3
|
||||||
file_picker: ^5.5.0
|
file_picker: ^6.0.0
|
||||||
file_sizes: ^1.0.6
|
file_sizes: ^1.0.6
|
||||||
desktop_webview_window: ^0.2.3
|
desktop_webview_window: ^0.2.3
|
||||||
flutter_svg: ^2.0.7
|
flutter_svg: ^2.0.7
|
||||||
@ -59,7 +59,7 @@ dev_dependencies:
|
|||||||
# activated in the `analysis_options.yaml` file located at the root of your
|
# activated in the `analysis_options.yaml` file located at the root of your
|
||||||
# package. See that file for information about deactivating specific lint
|
# package. See that file for information about deactivating specific lint
|
||||||
# rules and activating additional ones.
|
# rules and activating additional ones.
|
||||||
flutter_lints: ^2.0.0
|
flutter_lints: ^3.0.0
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
Loading…
Reference in New Issue
Block a user