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;
let releaseDataJson = (await releaseR.json())['data'];
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
let $avatarElement = $(".c-account-sidebar__profile-metas-avatar");
let avatarUrl = $avatarElement.css("background-image");
// post message
//post message
window.chrome.webview.postMessage({
action: 'webview_rsi_login_success', data: {
'webToken': $.cookie('Rsi-Token'),
@ -298,6 +308,7 @@ async function getRSILauncherToken(channelId) {
'authToken': TokenData,
'releaseInfo': releaseDataJson,
"avatar": avatarUrl,
'libraryData': libraryData,
"inputEmail": sessionStorage.getItem("inputEmail"),
"inputPassword": sessionStorage.getItem("inputPassword")
}
@ -316,7 +327,7 @@ function RSIAutoLogin(email, pwd) {
sessionStorage.setItem('inputPassword', '');
if (email !== "" && pwd !== "") {
$("#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';
class HomeGameLoginDialogUI extends HookConsumerWidget {
const HomeGameLoginDialogUI({super.key});
final BuildContext launchContext;
const HomeGameLoginDialogUI(this.launchContext, {super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final loginState = ref.watch(homeGameLoginUIModelProvider);
useEffect(() {
ref.read(homeGameLoginUIModelProvider.notifier).launchWebLogin(context);
ref
.read(homeGameLoginUIModelProvider.notifier)
.launchWebLogin(launchContext);
return null;
}, []);
return ContentDialog(
constraints: BoxConstraints(
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(
duration: const Duration(milliseconds: 230),
child: Padding(
padding: const EdgeInsets.only(top: 12, bottom: 12),
padding: const EdgeInsets.only(top: 12, bottom: 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
@ -33,7 +39,7 @@ class HomeGameLoginDialogUI extends HookConsumerWidget {
Center(
child: Column(
children: [
Text(S.current.home_title_logging_in),
Text(S.current.home_title_logging_in),
const SizedBox(height: 12),
const ProgressRing(),
if (loginState.isDeviceSupportWinHello ?? false)
@ -73,10 +79,42 @@ class HomeGameLoginDialogUI extends HookConsumerWidget {
style: const TextStyle(
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),
const SizedBox(height: 12),
const ProgressRing(),
const SizedBox(height: 12),
],
),
)

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/provider.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/webview/webview.dart';
import 'package:url_launcher/url_launcher_string.dart';
@ -32,6 +33,7 @@ class HomeGameLoginState with _$HomeGameLoginState {
String? authToken,
String? webToken,
Map? releaseInfo,
RsiGameLibraryData? libraryData,
String? installPath,
bool? isDeviceSupportWinHello,
}) = _LoginStatus;
@ -62,11 +64,13 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
Navigator.pop(context);
return;
}
dPrint("web message == $message");
// final emailBox = await Hive.openBox("quick_login_email");
final data = message["data"];
final authToken = data["authToken"];
final webToken = data["webToken"];
final releaseInfo = data["releaseInfo"];
final libraryData = RsiGameLibraryData.fromJson(data["libraryData"]);
final avatarUrl = data["avatar"]
?.toString()
.replaceAll("url(\"", "")
@ -87,6 +91,7 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
authToken: authToken,
webToken: webToken,
releaseInfo: releaseInfo,
libraryData: libraryData,
);
if (isDeviceSupportWinHello) {
@ -230,18 +235,16 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
};
final executable = state.releaseInfo?["executable"];
final launchOptions = state.releaseInfo?["launchOptions"];
dPrint("----------launch data ====== -----------\n$launchData");
dPrint(
"----------executable data ====== -----------\n${homeState.scInstalledPath}\\$executable $launchOptions");
// dPrint("----------launch data ====== -----------\n$launchData");
// dPrint(
// "----------executable data ====== -----------\n${homeState.scInstalledPath}\\$executable $launchOptions");
final launchFile = File("${homeState.scInstalledPath}\\loginData.json");
if (await launchFile.exists()) {
await launchFile.delete();
}
await launchFile.create();
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 homeUIModel = ref.read(homeUIModelProvider.notifier);
if (!context.mounted) return;

View File

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

View File

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

View File

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

View File

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