feat: Optimize game startup

This commit is contained in:
xkeyC 2024-03-31 15:43:59 +08:00
parent c32de21fa1
commit 39a2a28dd1
8 changed files with 200 additions and 19 deletions

View File

@ -286,11 +286,21 @@ async function getRSILauncherToken(channelId) {
if (releaseR.status !== 200) return; if (releaseR.status !== 200) return;
let releaseDataJson = (await releaseR.json())['data']; let releaseDataJson = (await releaseR.json())['data'];
console.log(releaseDataJson); console.log(releaseDataJson);
// get game library
let libraryR = await fetch("api/launcher/v3/games/library", {
method: 'POST', headers: {
'x-rsi-token': $.cookie('Rsi-Token'),
},
body: releaseFormData
});
let libraryData = (await libraryR.json())["data"]
// get user avatar // get user avatar
let $avatarElement = $(".c-account-sidebar__profile-metas-avatar"); let $avatarElement = $(".c-account-sidebar__profile-metas-avatar");
let avatarUrl = $avatarElement.css("background-image"); let avatarUrl = $avatarElement.css("background-image");
// post message //post message
window.chrome.webview.postMessage({ window.chrome.webview.postMessage({
action: 'webview_rsi_login_success', data: { action: 'webview_rsi_login_success', data: {
'webToken': $.cookie('Rsi-Token'), 'webToken': $.cookie('Rsi-Token'),
@ -298,6 +308,7 @@ async function getRSILauncherToken(channelId) {
'authToken': TokenData, 'authToken': TokenData,
'releaseInfo': releaseDataJson, 'releaseInfo': releaseDataJson,
"avatar": avatarUrl, "avatar": avatarUrl,
'libraryData': libraryData,
"inputEmail": sessionStorage.getItem("inputEmail"), "inputEmail": sessionStorage.getItem("inputEmail"),
"inputPassword": sessionStorage.getItem("inputPassword") "inputPassword": sessionStorage.getItem("inputPassword")
} }
@ -316,7 +327,7 @@ function RSIAutoLogin(email, pwd) {
sessionStorage.setItem('inputPassword', ''); sessionStorage.setItem('inputPassword', '');
if (email !== "" && pwd !== "") { if (email !== "" && pwd !== "") {
$("#remember").prop("checked", true); $("#remember").prop("checked", true);
$('.c-form__submit-button-label').click(); $('.c-formLegacyEnlist__submit-button-label').click();
} }
}); });
} }

View File

@ -0,0 +1,107 @@
class RsiGameLibraryData {
RsiGameLibraryData({
this.games,
});
RsiGameLibraryData.fromJson(dynamic json) {
if (json['games'] != null) {
games = [];
json['games'].forEach((v) {
games?.add(RsiGameLibraryGamesData.fromJson(v));
});
}
}
List<RsiGameLibraryGamesData>? games;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
if (games != null) {
map['games'] = games?.map((v) => v.toJson()).toList();
}
return map;
}
}
class RsiGameLibraryGamesData {
RsiGameLibraryGamesData({
this.id,
this.name,
this.channels,
});
RsiGameLibraryGamesData.fromJson(dynamic json) {
id = json['id'];
name = json['name'];
if (json['channels'] != null) {
channels = [];
json['channels'].forEach((v) {
channels?.add(RsiGameLibraryChannelsData.fromJson(v));
});
}
}
String? id;
String? name;
List<RsiGameLibraryChannelsData>? channels;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['name'] = name;
if (channels != null) {
map['channels'] = channels?.map((v) => v.toJson()).toList();
}
return map;
}
}
class RsiGameLibraryChannelsData {
RsiGameLibraryChannelsData({
this.id,
this.name,
this.version,
this.versionLabel,
this.servicesEndpoint,
this.network,
this.platformId,
this.nid,
this.weight,
});
RsiGameLibraryChannelsData.fromJson(dynamic json) {
id = json['id'];
name = json['name'];
version = json['version'];
versionLabel = json['versionLabel'];
servicesEndpoint = json['servicesEndpoint'];
network = json['network'];
platformId = json['platformId'];
nid = json['nid'];
weight = json['weight'];
}
String? id;
String? name;
num? version;
String? versionLabel;
String? servicesEndpoint;
dynamic network;
String? platformId;
String? nid;
dynamic weight;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['name'] = name;
map['version'] = version;
map['versionLabel'] = versionLabel;
map['servicesEndpoint'] = servicesEndpoint;
map['network'] = network;
map['platformId'] = platformId;
map['nid'] = nid;
map['weight'] = weight;
return map;
}
}

View File

@ -6,24 +6,30 @@ import 'package:starcitizen_doctor/widgets/widgets.dart';
import 'home_game_login_dialog_ui_model.dart'; import 'home_game_login_dialog_ui_model.dart';
class HomeGameLoginDialogUI extends HookConsumerWidget { class HomeGameLoginDialogUI extends HookConsumerWidget {
const HomeGameLoginDialogUI({super.key}); final BuildContext launchContext;
const HomeGameLoginDialogUI(this.launchContext, {super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final loginState = ref.watch(homeGameLoginUIModelProvider); final loginState = ref.watch(homeGameLoginUIModelProvider);
useEffect(() { useEffect(() {
ref.read(homeGameLoginUIModelProvider.notifier).launchWebLogin(context); ref
.read(homeGameLoginUIModelProvider.notifier)
.launchWebLogin(launchContext);
return null; return null;
}, []); }, []);
return ContentDialog( return ContentDialog(
constraints: BoxConstraints( constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * .56, maxWidth: MediaQuery.of(context).size.width * .56,
), ),
title: (loginState.loginStatus == 2) ? null : Text(S.current.home_action_one_click_launch), title: (loginState.loginStatus == 2)
? null
: Text(S.current.home_action_one_click_launch),
content: AnimatedSize( content: AnimatedSize(
duration: const Duration(milliseconds: 230), duration: const Duration(milliseconds: 230),
child: Padding( child: Padding(
padding: const EdgeInsets.only(top: 12, bottom: 12), padding: const EdgeInsets.only(top: 12, bottom: 0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -33,7 +39,7 @@ class HomeGameLoginDialogUI extends HookConsumerWidget {
Center( Center(
child: Column( child: Column(
children: [ children: [
Text(S.current.home_title_logging_in), Text(S.current.home_title_logging_in),
const SizedBox(height: 12), const SizedBox(height: 12),
const ProgressRing(), const ProgressRing(),
if (loginState.isDeviceSupportWinHello ?? false) if (loginState.isDeviceSupportWinHello ?? false)
@ -73,10 +79,42 @@ class HomeGameLoginDialogUI extends HookConsumerWidget {
style: const TextStyle( style: const TextStyle(
fontSize: 24, fontWeight: FontWeight.bold), fontSize: 24, fontWeight: FontWeight.bold),
), ),
const SizedBox(height: 32), const SizedBox(height: 12),
if (loginState.libraryData?.games != null) ...[
Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: FluentTheme.of(context).cardColor,
borderRadius: BorderRadius.circular(12),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
for (final game in loginState.libraryData!.games!)
Padding(
padding: const EdgeInsets.only(
left: 12, right: 12),
child: Row(
children: [
Icon(
FluentIcons.skype_circle_check,
color: Colors.green,
),
const SizedBox(width: 6),
Text("${game.name}"),
],
),
)
],
),
),
const SizedBox(height: 24)
],
const SizedBox(height: 12),
Text(S.current.home_login_title_launching_game), Text(S.current.home_login_title_launching_game),
const SizedBox(height: 12), const SizedBox(height: 12),
const ProgressRing(), const ProgressRing(),
const SizedBox(height: 12),
], ],
), ),
) )
@ -87,4 +125,4 @@ class HomeGameLoginDialogUI extends HookConsumerWidget {
), ),
); );
} }
} }

View File

@ -14,6 +14,7 @@ import 'package:starcitizen_doctor/common/utils/base_utils.dart';
import 'package:starcitizen_doctor/common/utils/log.dart'; import 'package:starcitizen_doctor/common/utils/log.dart';
import 'package:starcitizen_doctor/common/utils/provider.dart'; import 'package:starcitizen_doctor/common/utils/provider.dart';
import 'package:starcitizen_doctor/common/win32/credentials.dart'; import 'package:starcitizen_doctor/common/win32/credentials.dart';
import 'package:starcitizen_doctor/data/rsi_game_library_data.dart';
import 'package:starcitizen_doctor/ui/home/home_ui_model.dart'; import 'package:starcitizen_doctor/ui/home/home_ui_model.dart';
import 'package:starcitizen_doctor/ui/webview/webview.dart'; import 'package:starcitizen_doctor/ui/webview/webview.dart';
import 'package:url_launcher/url_launcher_string.dart'; import 'package:url_launcher/url_launcher_string.dart';
@ -32,6 +33,7 @@ class HomeGameLoginState with _$HomeGameLoginState {
String? authToken, String? authToken,
String? webToken, String? webToken,
Map? releaseInfo, Map? releaseInfo,
RsiGameLibraryData? libraryData,
String? installPath, String? installPath,
bool? isDeviceSupportWinHello, bool? isDeviceSupportWinHello,
}) = _LoginStatus; }) = _LoginStatus;
@ -62,11 +64,13 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
Navigator.pop(context); Navigator.pop(context);
return; return;
} }
dPrint("web message == $message");
// final emailBox = await Hive.openBox("quick_login_email"); // final emailBox = await Hive.openBox("quick_login_email");
final data = message["data"]; final data = message["data"];
final authToken = data["authToken"]; final authToken = data["authToken"];
final webToken = data["webToken"]; final webToken = data["webToken"];
final releaseInfo = data["releaseInfo"]; final releaseInfo = data["releaseInfo"];
final libraryData = RsiGameLibraryData.fromJson(data["libraryData"]);
final avatarUrl = data["avatar"] final avatarUrl = data["avatar"]
?.toString() ?.toString()
.replaceAll("url(\"", "") .replaceAll("url(\"", "")
@ -87,6 +91,7 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
authToken: authToken, authToken: authToken,
webToken: webToken, webToken: webToken,
releaseInfo: releaseInfo, releaseInfo: releaseInfo,
libraryData: libraryData,
); );
if (isDeviceSupportWinHello) { if (isDeviceSupportWinHello) {
@ -230,18 +235,16 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
}; };
final executable = state.releaseInfo?["executable"]; final executable = state.releaseInfo?["executable"];
final launchOptions = state.releaseInfo?["launchOptions"]; final launchOptions = state.releaseInfo?["launchOptions"];
dPrint("----------launch data ====== -----------\n$launchData"); // dPrint("----------launch data ====== -----------\n$launchData");
dPrint( // dPrint(
"----------executable data ====== -----------\n${homeState.scInstalledPath}\\$executable $launchOptions"); // "----------executable data ====== -----------\n${homeState.scInstalledPath}\\$executable $launchOptions");
final launchFile = File("${homeState.scInstalledPath}\\loginData.json"); final launchFile = File("${homeState.scInstalledPath}\\loginData.json");
if (await launchFile.exists()) { if (await launchFile.exists()) {
await launchFile.delete(); await launchFile.delete();
} }
await launchFile.create(); await launchFile.create();
await launchFile.writeAsString(json.encode(launchData)); await launchFile.writeAsString(json.encode(launchData));
await Future.delayed(const Duration(seconds: 1));
await Future.delayed(const Duration(seconds: 3));
final processorAffinity = await SystemHelper.getCpuAffinity(); final processorAffinity = await SystemHelper.getCpuAffinity();
final homeUIModel = ref.read(homeUIModelProvider.notifier); final homeUIModel = ref.read(homeUIModelProvider.notifier);
if (!context.mounted) return; if (!context.mounted) return;

View File

@ -22,6 +22,7 @@ mixin _$HomeGameLoginState {
String? get authToken => throw _privateConstructorUsedError; String? get authToken => throw _privateConstructorUsedError;
String? get webToken => throw _privateConstructorUsedError; String? get webToken => throw _privateConstructorUsedError;
Map<dynamic, dynamic>? get releaseInfo => throw _privateConstructorUsedError; Map<dynamic, dynamic>? get releaseInfo => throw _privateConstructorUsedError;
RsiGameLibraryData? get libraryData => throw _privateConstructorUsedError;
String? get installPath => throw _privateConstructorUsedError; String? get installPath => throw _privateConstructorUsedError;
bool? get isDeviceSupportWinHello => throw _privateConstructorUsedError; bool? get isDeviceSupportWinHello => throw _privateConstructorUsedError;
@ -43,6 +44,7 @@ abstract class $HomeGameLoginStateCopyWith<$Res> {
String? authToken, String? authToken,
String? webToken, String? webToken,
Map<dynamic, dynamic>? releaseInfo, Map<dynamic, dynamic>? releaseInfo,
RsiGameLibraryData? libraryData,
String? installPath, String? installPath,
bool? isDeviceSupportWinHello}); bool? isDeviceSupportWinHello});
} }
@ -66,6 +68,7 @@ class _$HomeGameLoginStateCopyWithImpl<$Res, $Val extends HomeGameLoginState>
Object? authToken = freezed, Object? authToken = freezed,
Object? webToken = freezed, Object? webToken = freezed,
Object? releaseInfo = freezed, Object? releaseInfo = freezed,
Object? libraryData = freezed,
Object? installPath = freezed, Object? installPath = freezed,
Object? isDeviceSupportWinHello = freezed, Object? isDeviceSupportWinHello = freezed,
}) { }) {
@ -94,6 +97,10 @@ class _$HomeGameLoginStateCopyWithImpl<$Res, $Val extends HomeGameLoginState>
? _value.releaseInfo ? _value.releaseInfo
: releaseInfo // ignore: cast_nullable_to_non_nullable : releaseInfo // ignore: cast_nullable_to_non_nullable
as Map<dynamic, dynamic>?, as Map<dynamic, dynamic>?,
libraryData: freezed == libraryData
? _value.libraryData
: libraryData // ignore: cast_nullable_to_non_nullable
as RsiGameLibraryData?,
installPath: freezed == installPath installPath: freezed == installPath
? _value.installPath ? _value.installPath
: installPath // ignore: cast_nullable_to_non_nullable : installPath // ignore: cast_nullable_to_non_nullable
@ -121,6 +128,7 @@ abstract class _$$LoginStatusImplCopyWith<$Res>
String? authToken, String? authToken,
String? webToken, String? webToken,
Map<dynamic, dynamic>? releaseInfo, Map<dynamic, dynamic>? releaseInfo,
RsiGameLibraryData? libraryData,
String? installPath, String? installPath,
bool? isDeviceSupportWinHello}); bool? isDeviceSupportWinHello});
} }
@ -142,6 +150,7 @@ class __$$LoginStatusImplCopyWithImpl<$Res>
Object? authToken = freezed, Object? authToken = freezed,
Object? webToken = freezed, Object? webToken = freezed,
Object? releaseInfo = freezed, Object? releaseInfo = freezed,
Object? libraryData = freezed,
Object? installPath = freezed, Object? installPath = freezed,
Object? isDeviceSupportWinHello = freezed, Object? isDeviceSupportWinHello = freezed,
}) { }) {
@ -170,6 +179,10 @@ class __$$LoginStatusImplCopyWithImpl<$Res>
? _value._releaseInfo ? _value._releaseInfo
: releaseInfo // ignore: cast_nullable_to_non_nullable : releaseInfo // ignore: cast_nullable_to_non_nullable
as Map<dynamic, dynamic>?, as Map<dynamic, dynamic>?,
libraryData: freezed == libraryData
? _value.libraryData
: libraryData // ignore: cast_nullable_to_non_nullable
as RsiGameLibraryData?,
installPath: freezed == installPath installPath: freezed == installPath
? _value.installPath ? _value.installPath
: installPath // ignore: cast_nullable_to_non_nullable : installPath // ignore: cast_nullable_to_non_nullable
@ -192,6 +205,7 @@ class _$LoginStatusImpl implements _LoginStatus {
this.authToken, this.authToken,
this.webToken, this.webToken,
final Map<dynamic, dynamic>? releaseInfo, final Map<dynamic, dynamic>? releaseInfo,
this.libraryData,
this.installPath, this.installPath,
this.isDeviceSupportWinHello}) this.isDeviceSupportWinHello})
: _releaseInfo = releaseInfo; : _releaseInfo = releaseInfo;
@ -216,6 +230,8 @@ class _$LoginStatusImpl implements _LoginStatus {
return EqualUnmodifiableMapView(value); return EqualUnmodifiableMapView(value);
} }
@override
final RsiGameLibraryData? libraryData;
@override @override
final String? installPath; final String? installPath;
@override @override
@ -223,7 +239,7 @@ class _$LoginStatusImpl implements _LoginStatus {
@override @override
String toString() { String toString() {
return 'HomeGameLoginState(loginStatus: $loginStatus, nickname: $nickname, avatarUrl: $avatarUrl, authToken: $authToken, webToken: $webToken, releaseInfo: $releaseInfo, installPath: $installPath, isDeviceSupportWinHello: $isDeviceSupportWinHello)'; return 'HomeGameLoginState(loginStatus: $loginStatus, nickname: $nickname, avatarUrl: $avatarUrl, authToken: $authToken, webToken: $webToken, releaseInfo: $releaseInfo, libraryData: $libraryData, installPath: $installPath, isDeviceSupportWinHello: $isDeviceSupportWinHello)';
} }
@override @override
@ -243,6 +259,8 @@ class _$LoginStatusImpl implements _LoginStatus {
other.webToken == webToken) && other.webToken == webToken) &&
const DeepCollectionEquality() const DeepCollectionEquality()
.equals(other._releaseInfo, _releaseInfo) && .equals(other._releaseInfo, _releaseInfo) &&
(identical(other.libraryData, libraryData) ||
other.libraryData == libraryData) &&
(identical(other.installPath, installPath) || (identical(other.installPath, installPath) ||
other.installPath == installPath) && other.installPath == installPath) &&
(identical( (identical(
@ -259,6 +277,7 @@ class _$LoginStatusImpl implements _LoginStatus {
authToken, authToken,
webToken, webToken,
const DeepCollectionEquality().hash(_releaseInfo), const DeepCollectionEquality().hash(_releaseInfo),
libraryData,
installPath, installPath,
isDeviceSupportWinHello); isDeviceSupportWinHello);
@ -277,6 +296,7 @@ abstract class _LoginStatus implements HomeGameLoginState {
final String? authToken, final String? authToken,
final String? webToken, final String? webToken,
final Map<dynamic, dynamic>? releaseInfo, final Map<dynamic, dynamic>? releaseInfo,
final RsiGameLibraryData? libraryData,
final String? installPath, final String? installPath,
final bool? isDeviceSupportWinHello}) = _$LoginStatusImpl; final bool? isDeviceSupportWinHello}) = _$LoginStatusImpl;
@ -293,6 +313,8 @@ abstract class _LoginStatus implements HomeGameLoginState {
@override @override
Map<dynamic, dynamic>? get releaseInfo; Map<dynamic, dynamic>? get releaseInfo;
@override @override
RsiGameLibraryData? get libraryData;
@override
String? get installPath; String? get installPath;
@override @override
bool? get isDeviceSupportWinHello; bool? get isDeviceSupportWinHello;

View File

@ -7,7 +7,7 @@ part of 'home_game_login_dialog_ui_model.dart';
// ************************************************************************** // **************************************************************************
String _$homeGameLoginUIModelHash() => String _$homeGameLoginUIModelHash() =>
r'aba96cf64ea6146f1006ca2bd41e6e26c10adb6c'; r'55ae072fdc222a015661e50f2d8d60e95911ce14';
/// See also [HomeGameLoginUIModel]. /// See also [HomeGameLoginUIModel].
@ProviderFor(HomeGameLoginUIModel) @ProviderFor(HomeGameLoginUIModel)

View File

@ -329,7 +329,7 @@ class HomeUIModel extends _$HomeUIModel {
showDialog( showDialog(
context: context, context: context,
dismissWithEsc: false, dismissWithEsc: false,
builder: (context) => const HomeGameLoginDialogUI()); builder: (context) => HomeGameLoginDialogUI(context));
} else { } else {
final ok = await showConfirmDialogs( final ok = await showConfirmDialogs(
context, context,

View File

@ -6,7 +6,7 @@ part of 'home_ui_model.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$homeUIModelHash() => r'13dc0eb046a284bb9cb5a1da5597dae7e5287030'; String _$homeUIModelHash() => r'415891e3528a681a9c11eed5bb78070a2a08da86';
/// See also [HomeUIModel]. /// See also [HomeUIModel].
@ProviderFor(HomeUIModel) @ProviderFor(HomeUIModel)