feat: use unp4k_rs

This commit is contained in:
xkeyC 2025-12-04 15:28:56 +08:00
parent a0290cf28a
commit e3c3986379
16 changed files with 1952 additions and 276 deletions

Binary file not shown.

View File

@ -6,10 +6,7 @@ import 'package:flutter/services.dart';
import 'package:starcitizen_doctor/common/utils/log.dart';
class BinaryModuleConf {
static const _modules = {
"aria2c": "0",
"unp4kc": "1",
};
static const _modules = {"aria2c": "0"};
static Future extractModule(List<String> modules, String workingDir) async {
for (var m in _modules.entries) {
@ -18,11 +15,8 @@ class BinaryModuleConf {
final version = m.value;
final dir = "$workingDir\\$name";
final versionFile = File("$dir\\version");
if (kReleaseMode &&
await versionFile.exists() &&
(await versionFile.readAsString()).trim() == version) {
dPrint(
"BinaryModuleConf.extractModule skip $name version == $version");
if (kReleaseMode && await versionFile.exists() && (await versionFile.readAsString()).trim() == version) {
dPrint("BinaryModuleConf.extractModule skip $name version == $version");
continue;
}
// write model file

View File

@ -0,0 +1,50 @@
// This file is automatically generated, so please do not edit it.
// @generated by `flutter_rust_bridge`@ 2.11.1.
// 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';
import 'package:freezed_annotation/freezed_annotation.dart' hide protected;
part 'unp4k_api.freezed.dart';
/// P4K
Future<BigInt> p4KOpen({required String p4KPath}) =>
RustLib.instance.api.crateApiUnp4KApiP4KOpen(p4KPath: p4KPath);
///
Future<List<P4kFileItem>> p4KGetAllFiles() =>
RustLib.instance.api.crateApiUnp4KApiP4KGetAllFiles();
///
Future<List<P4kFileItem>> p4KGetFilesInDirectory({required String directory}) =>
RustLib.instance.api.crateApiUnp4KApiP4KGetFilesInDirectory(
directory: directory,
);
///
Future<Uint8List> p4KExtractToMemory({required String filePath}) =>
RustLib.instance.api.crateApiUnp4KApiP4KExtractToMemory(filePath: filePath);
///
Future<void> p4KExtractToDisk({
required String filePath,
required String outputPath,
}) => RustLib.instance.api.crateApiUnp4KApiP4KExtractToDisk(
filePath: filePath,
outputPath: outputPath,
);
/// P4K
Future<void> p4KClose() => RustLib.instance.api.crateApiUnp4KApiP4KClose();
/// P4K
@freezed
sealed class P4kFileItem with _$P4kFileItem {
const factory P4kFileItem({
required String name,
required bool isDirectory,
required BigInt size,
required BigInt compressedSize,
}) = _P4kFileItem;
}

View File

@ -0,0 +1,274 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// 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 'unp4k_api.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$P4kFileItem {
String get name; bool get isDirectory; BigInt get size; BigInt get compressedSize;
/// Create a copy of P4kFileItem
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$P4kFileItemCopyWith<P4kFileItem> get copyWith => _$P4kFileItemCopyWithImpl<P4kFileItem>(this as P4kFileItem, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is P4kFileItem&&(identical(other.name, name) || other.name == name)&&(identical(other.isDirectory, isDirectory) || other.isDirectory == isDirectory)&&(identical(other.size, size) || other.size == size)&&(identical(other.compressedSize, compressedSize) || other.compressedSize == compressedSize));
}
@override
int get hashCode => Object.hash(runtimeType,name,isDirectory,size,compressedSize);
@override
String toString() {
return 'P4kFileItem(name: $name, isDirectory: $isDirectory, size: $size, compressedSize: $compressedSize)';
}
}
/// @nodoc
abstract mixin class $P4kFileItemCopyWith<$Res> {
factory $P4kFileItemCopyWith(P4kFileItem value, $Res Function(P4kFileItem) _then) = _$P4kFileItemCopyWithImpl;
@useResult
$Res call({
String name, bool isDirectory, BigInt size, BigInt compressedSize
});
}
/// @nodoc
class _$P4kFileItemCopyWithImpl<$Res>
implements $P4kFileItemCopyWith<$Res> {
_$P4kFileItemCopyWithImpl(this._self, this._then);
final P4kFileItem _self;
final $Res Function(P4kFileItem) _then;
/// Create a copy of P4kFileItem
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? name = null,Object? isDirectory = null,Object? size = null,Object? compressedSize = null,}) {
return _then(_self.copyWith(
name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,isDirectory: null == isDirectory ? _self.isDirectory : isDirectory // ignore: cast_nullable_to_non_nullable
as bool,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable
as BigInt,compressedSize: null == compressedSize ? _self.compressedSize : compressedSize // ignore: cast_nullable_to_non_nullable
as BigInt,
));
}
}
/// Adds pattern-matching-related methods to [P4kFileItem].
extension P4kFileItemPatterns on P4kFileItem {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _P4kFileItem value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _P4kFileItem() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _P4kFileItem value) $default,){
final _that = this;
switch (_that) {
case _P4kFileItem():
return $default(_that);}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _P4kFileItem value)? $default,){
final _that = this;
switch (_that) {
case _P4kFileItem() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String name, bool isDirectory, BigInt size, BigInt compressedSize)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _P4kFileItem() when $default != null:
return $default(_that.name,_that.isDirectory,_that.size,_that.compressedSize);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String name, bool isDirectory, BigInt size, BigInt compressedSize) $default,) {final _that = this;
switch (_that) {
case _P4kFileItem():
return $default(_that.name,_that.isDirectory,_that.size,_that.compressedSize);}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String name, bool isDirectory, BigInt size, BigInt compressedSize)? $default,) {final _that = this;
switch (_that) {
case _P4kFileItem() when $default != null:
return $default(_that.name,_that.isDirectory,_that.size,_that.compressedSize);case _:
return null;
}
}
}
/// @nodoc
class _P4kFileItem implements P4kFileItem {
const _P4kFileItem({required this.name, required this.isDirectory, required this.size, required this.compressedSize});
@override final String name;
@override final bool isDirectory;
@override final BigInt size;
@override final BigInt compressedSize;
/// Create a copy of P4kFileItem
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$P4kFileItemCopyWith<_P4kFileItem> get copyWith => __$P4kFileItemCopyWithImpl<_P4kFileItem>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _P4kFileItem&&(identical(other.name, name) || other.name == name)&&(identical(other.isDirectory, isDirectory) || other.isDirectory == isDirectory)&&(identical(other.size, size) || other.size == size)&&(identical(other.compressedSize, compressedSize) || other.compressedSize == compressedSize));
}
@override
int get hashCode => Object.hash(runtimeType,name,isDirectory,size,compressedSize);
@override
String toString() {
return 'P4kFileItem(name: $name, isDirectory: $isDirectory, size: $size, compressedSize: $compressedSize)';
}
}
/// @nodoc
abstract mixin class _$P4kFileItemCopyWith<$Res> implements $P4kFileItemCopyWith<$Res> {
factory _$P4kFileItemCopyWith(_P4kFileItem value, $Res Function(_P4kFileItem) _then) = __$P4kFileItemCopyWithImpl;
@override @useResult
$Res call({
String name, bool isDirectory, BigInt size, BigInt compressedSize
});
}
/// @nodoc
class __$P4kFileItemCopyWithImpl<$Res>
implements _$P4kFileItemCopyWith<$Res> {
__$P4kFileItemCopyWithImpl(this._self, this._then);
final _P4kFileItem _self;
final $Res Function(_P4kFileItem) _then;
/// Create a copy of P4kFileItem
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? name = null,Object? isDirectory = null,Object? size = null,Object? compressedSize = null,}) {
return _then(_P4kFileItem(
name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,isDirectory: null == isDirectory ? _self.isDirectory : isDirectory // ignore: cast_nullable_to_non_nullable
as bool,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable
as BigInt,compressedSize: null == compressedSize ? _self.compressedSize : compressedSize // ignore: cast_nullable_to_non_nullable
as BigInt,
));
}
}
// dart format on

View File

@ -7,6 +7,7 @@ import 'api/asar_api.dart';
import 'api/http_api.dart';
import 'api/ort_api.dart';
import 'api/rs_process.dart';
import 'api/unp4k_api.dart';
import 'api/win32_api.dart';
import 'dart:async';
import 'dart:convert';
@ -69,7 +70,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
String get codegenVersion => '2.11.1';
@override
int get rustContentHash => -518970253;
int get rustContentHash => -737964996;
static const kDefaultExternalLibraryLoaderConfig =
ExternalLibraryLoaderConfig(
@ -119,6 +120,25 @@ abstract class RustLibApi extends BaseApi {
required bool useXnnpack,
});
Future<void> crateApiUnp4KApiP4KClose();
Future<void> crateApiUnp4KApiP4KExtractToDisk({
required String filePath,
required String outputPath,
});
Future<Uint8List> crateApiUnp4KApiP4KExtractToMemory({
required String filePath,
});
Future<List<P4kFileItem>> crateApiUnp4KApiP4KGetAllFiles();
Future<List<P4kFileItem>> crateApiUnp4KApiP4KGetFilesInDirectory({
required String directory,
});
Future<BigInt> crateApiUnp4KApiP4KOpen({required String p4KPath});
Future<void> crateApiAsarApiRsiLauncherAsarDataWriteMainJs({
required RsiLauncherAsarData that,
required List<int> content,
@ -456,6 +476,163 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
argNames: ["modelPath", "modelKey", "quantizationSuffix", "useXnnpack"],
);
@override
Future<void> crateApiUnp4KApiP4KClose() {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
return wire.wire__crate__api__unp4k_api__p4k_close(port_);
},
codec: DcoCodec(
decodeSuccessData: dco_decode_unit,
decodeErrorData: dco_decode_AnyhowException,
),
constMeta: kCrateApiUnp4KApiP4KCloseConstMeta,
argValues: [],
apiImpl: this,
),
);
}
TaskConstMeta get kCrateApiUnp4KApiP4KCloseConstMeta =>
const TaskConstMeta(debugName: "p4k_close", argNames: []);
@override
Future<void> crateApiUnp4KApiP4KExtractToDisk({
required String filePath,
required String outputPath,
}) {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
var arg0 = cst_encode_String(filePath);
var arg1 = cst_encode_String(outputPath);
return wire.wire__crate__api__unp4k_api__p4k_extract_to_disk(
port_,
arg0,
arg1,
);
},
codec: DcoCodec(
decodeSuccessData: dco_decode_unit,
decodeErrorData: dco_decode_AnyhowException,
),
constMeta: kCrateApiUnp4KApiP4KExtractToDiskConstMeta,
argValues: [filePath, outputPath],
apiImpl: this,
),
);
}
TaskConstMeta get kCrateApiUnp4KApiP4KExtractToDiskConstMeta =>
const TaskConstMeta(
debugName: "p4k_extract_to_disk",
argNames: ["filePath", "outputPath"],
);
@override
Future<Uint8List> crateApiUnp4KApiP4KExtractToMemory({
required String filePath,
}) {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
var arg0 = cst_encode_String(filePath);
return wire.wire__crate__api__unp4k_api__p4k_extract_to_memory(
port_,
arg0,
);
},
codec: DcoCodec(
decodeSuccessData: dco_decode_list_prim_u_8_strict,
decodeErrorData: dco_decode_AnyhowException,
),
constMeta: kCrateApiUnp4KApiP4KExtractToMemoryConstMeta,
argValues: [filePath],
apiImpl: this,
),
);
}
TaskConstMeta get kCrateApiUnp4KApiP4KExtractToMemoryConstMeta =>
const TaskConstMeta(
debugName: "p4k_extract_to_memory",
argNames: ["filePath"],
);
@override
Future<List<P4kFileItem>> crateApiUnp4KApiP4KGetAllFiles() {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
return wire.wire__crate__api__unp4k_api__p4k_get_all_files(port_);
},
codec: DcoCodec(
decodeSuccessData: dco_decode_list_p_4_k_file_item,
decodeErrorData: dco_decode_AnyhowException,
),
constMeta: kCrateApiUnp4KApiP4KGetAllFilesConstMeta,
argValues: [],
apiImpl: this,
),
);
}
TaskConstMeta get kCrateApiUnp4KApiP4KGetAllFilesConstMeta =>
const TaskConstMeta(debugName: "p4k_get_all_files", argNames: []);
@override
Future<List<P4kFileItem>> crateApiUnp4KApiP4KGetFilesInDirectory({
required String directory,
}) {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
var arg0 = cst_encode_String(directory);
return wire.wire__crate__api__unp4k_api__p4k_get_files_in_directory(
port_,
arg0,
);
},
codec: DcoCodec(
decodeSuccessData: dco_decode_list_p_4_k_file_item,
decodeErrorData: dco_decode_AnyhowException,
),
constMeta: kCrateApiUnp4KApiP4KGetFilesInDirectoryConstMeta,
argValues: [directory],
apiImpl: this,
),
);
}
TaskConstMeta get kCrateApiUnp4KApiP4KGetFilesInDirectoryConstMeta =>
const TaskConstMeta(
debugName: "p4k_get_files_in_directory",
argNames: ["directory"],
);
@override
Future<BigInt> crateApiUnp4KApiP4KOpen({required String p4KPath}) {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
var arg0 = cst_encode_String(p4KPath);
return wire.wire__crate__api__unp4k_api__p4k_open(port_, arg0);
},
codec: DcoCodec(
decodeSuccessData: dco_decode_usize,
decodeErrorData: dco_decode_AnyhowException,
),
constMeta: kCrateApiUnp4KApiP4KOpenConstMeta,
argValues: [p4KPath],
apiImpl: this,
),
);
}
TaskConstMeta get kCrateApiUnp4KApiP4KOpenConstMeta =>
const TaskConstMeta(debugName: "p4k_open", argNames: ["p4KPath"]);
@override
Future<void> crateApiAsarApiRsiLauncherAsarDataWriteMainJs({
required RsiLauncherAsarData that,
@ -820,6 +997,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return (raw as List<dynamic>).map(dco_decode_String).toList();
}
@protected
List<P4kFileItem> dco_decode_list_p_4_k_file_item(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return (raw as List<dynamic>).map(dco_decode_p_4_k_file_item).toList();
}
@protected
List<int> dco_decode_list_prim_u_8_loose(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@ -886,6 +1069,20 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return raw == null ? null : dco_decode_list_prim_u_8_strict(raw);
}
@protected
P4kFileItem dco_decode_p_4_k_file_item(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 4)
throw Exception('unexpected arr length: expect 4 but see ${arr.length}');
return P4kFileItem(
name: dco_decode_String(arr[0]),
isDirectory: dco_decode_bool(arr[1]),
size: dco_decode_u_64(arr[2]),
compressedSize: dco_decode_u_64(arr[3]),
);
}
@protected
ProcessInfo dco_decode_process_info(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@ -988,6 +1185,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return;
}
@protected
BigInt dco_decode_usize(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return dcoDecodeU64(raw);
}
@protected
AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@ -1064,6 +1267,20 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return ans_;
}
@protected
List<P4kFileItem> sse_decode_list_p_4_k_file_item(
SseDeserializer deserializer,
) {
// Codec=Sse (Serialization based), see doc to use other codecs
var len_ = sse_decode_i_32(deserializer);
var ans_ = <P4kFileItem>[];
for (var idx_ = 0; idx_ < len_; ++idx_) {
ans_.add(sse_decode_p_4_k_file_item(deserializer));
}
return ans_;
}
@protected
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@ -1175,6 +1392,21 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
P4kFileItem sse_decode_p_4_k_file_item(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_name = sse_decode_String(deserializer);
var var_isDirectory = sse_decode_bool(deserializer);
var var_size = sse_decode_u_64(deserializer);
var var_compressedSize = sse_decode_u_64(deserializer);
return P4kFileItem(
name: var_name,
isDirectory: var_isDirectory,
size: var_size,
compressedSize: var_compressedSize,
);
}
@protected
ProcessInfo sse_decode_process_info(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@ -1283,6 +1515,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
// Codec=Sse (Serialization based), see doc to use other codecs
}
@protected
BigInt sse_decode_usize(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return deserializer.buffer.getBigUint64();
}
@protected
bool cst_encode_bool(bool raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
@ -1423,6 +1661,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
void sse_encode_list_p_4_k_file_item(
List<P4kFileItem> self,
SseSerializer serializer,
) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_i_32(self.length, serializer);
for (final item in self) {
sse_encode_p_4_k_file_item(item, serializer);
}
}
@protected
void sse_encode_list_prim_u_8_loose(
List<int> self,
@ -1540,6 +1790,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
void sse_encode_p_4_k_file_item(P4kFileItem self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(self.name, serializer);
sse_encode_bool(self.isDirectory, serializer);
sse_encode_u_64(self.size, serializer);
sse_encode_u_64(self.compressedSize, serializer);
}
@protected
void sse_encode_process_info(ProcessInfo self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@ -1632,4 +1891,10 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
void sse_encode_unit(void self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
}
@protected
void sse_encode_usize(BigInt self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
serializer.buffer.putBigUint64(self);
}
}

View File

@ -7,6 +7,7 @@ import 'api/asar_api.dart';
import 'api/http_api.dart';
import 'api/ort_api.dart';
import 'api/rs_process.dart';
import 'api/unp4k_api.dart';
import 'api/win32_api.dart';
import 'dart:async';
import 'dart:convert';
@ -56,6 +57,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
List<String> dco_decode_list_String(dynamic raw);
@protected
List<P4kFileItem> dco_decode_list_p_4_k_file_item(dynamic raw);
@protected
List<int> dco_decode_list_prim_u_8_loose(dynamic raw);
@ -89,6 +93,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
Uint8List? dco_decode_opt_list_prim_u_8_strict(dynamic raw);
@protected
P4kFileItem dco_decode_p_4_k_file_item(dynamic raw);
@protected
ProcessInfo dco_decode_process_info(dynamic raw);
@ -122,6 +129,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void dco_decode_unit(dynamic raw);
@protected
BigInt dco_decode_usize(dynamic raw);
@protected
AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer);
@ -159,6 +169,11 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
List<String> sse_decode_list_String(SseDeserializer deserializer);
@protected
List<P4kFileItem> sse_decode_list_p_4_k_file_item(
SseDeserializer deserializer,
);
@protected
List<int> sse_decode_list_prim_u_8_loose(SseDeserializer deserializer);
@ -196,6 +211,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
Uint8List? sse_decode_opt_list_prim_u_8_strict(SseDeserializer deserializer);
@protected
P4kFileItem sse_decode_p_4_k_file_item(SseDeserializer deserializer);
@protected
ProcessInfo sse_decode_process_info(SseDeserializer deserializer);
@ -237,6 +255,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_decode_unit(SseDeserializer deserializer);
@protected
BigInt sse_decode_usize(SseDeserializer deserializer);
@protected
ffi.Pointer<wire_cst_list_prim_u_8_strict> cst_encode_AnyhowException(
AnyhowException raw,
@ -307,6 +328,18 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return ans;
}
@protected
ffi.Pointer<wire_cst_list_p_4_k_file_item> cst_encode_list_p_4_k_file_item(
List<P4kFileItem> raw,
) {
// Codec=Cst (C-struct based), see doc to use other codecs
final ans = wire.cst_new_list_p_4_k_file_item(raw.length);
for (var i = 0; i < raw.length; ++i) {
cst_api_fill_to_wire_p_4_k_file_item(raw[i], ans.ref.ptr[i]);
}
return ans;
}
@protected
ffi.Pointer<wire_cst_list_prim_u_8_loose> cst_encode_list_prim_u_8_loose(
List<int> raw,
@ -390,6 +423,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return raw.toSigned(64).toInt();
}
@protected
int cst_encode_usize(BigInt raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
return raw.toSigned(64).toInt();
}
@protected
void cst_api_fill_to_wire_box_autoadd_rsi_launcher_asar_data(
RsiLauncherAsarData apiObj,
@ -398,6 +437,17 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
cst_api_fill_to_wire_rsi_launcher_asar_data(apiObj, wireObj.ref);
}
@protected
void cst_api_fill_to_wire_p_4_k_file_item(
P4kFileItem apiObj,
wire_cst_p_4_k_file_item wireObj,
) {
wireObj.name = cst_encode_String(apiObj.name);
wireObj.is_directory = cst_encode_bool(apiObj.isDirectory);
wireObj.size = cst_encode_u_64(apiObj.size);
wireObj.compressed_size = cst_encode_u_64(apiObj.compressedSize);
}
@protected
void cst_api_fill_to_wire_process_info(
ProcessInfo apiObj,
@ -524,6 +574,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_list_String(List<String> self, SseSerializer serializer);
@protected
void sse_encode_list_p_4_k_file_item(
List<P4kFileItem> self,
SseSerializer serializer,
);
@protected
void sse_encode_list_prim_u_8_loose(List<int> self, SseSerializer serializer);
@ -572,6 +628,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseSerializer serializer,
);
@protected
void sse_encode_p_4_k_file_item(P4kFileItem self, SseSerializer serializer);
@protected
void sse_encode_process_info(ProcessInfo self, SseSerializer serializer);
@ -619,6 +678,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_unit(void self, SseSerializer serializer);
@protected
void sse_encode_usize(BigInt self, SseSerializer serializer);
}
// Section: wire_class
@ -917,6 +979,140 @@ class RustLibWire implements BaseWire {
)
>();
void wire__crate__api__unp4k_api__p4k_close(int port_) {
return _wire__crate__api__unp4k_api__p4k_close(port_);
}
late final _wire__crate__api__unp4k_api__p4k_closePtr =
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64)>>(
'frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__p4k_close',
);
late final _wire__crate__api__unp4k_api__p4k_close =
_wire__crate__api__unp4k_api__p4k_closePtr
.asFunction<void Function(int)>();
void wire__crate__api__unp4k_api__p4k_extract_to_disk(
int port_,
ffi.Pointer<wire_cst_list_prim_u_8_strict> file_path,
ffi.Pointer<wire_cst_list_prim_u_8_strict> output_path,
) {
return _wire__crate__api__unp4k_api__p4k_extract_to_disk(
port_,
file_path,
output_path,
);
}
late final _wire__crate__api__unp4k_api__p4k_extract_to_diskPtr =
_lookup<
ffi.NativeFunction<
ffi.Void Function(
ffi.Int64,
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
)
>
>(
'frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__p4k_extract_to_disk',
);
late final _wire__crate__api__unp4k_api__p4k_extract_to_disk =
_wire__crate__api__unp4k_api__p4k_extract_to_diskPtr
.asFunction<
void Function(
int,
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
)
>();
void wire__crate__api__unp4k_api__p4k_extract_to_memory(
int port_,
ffi.Pointer<wire_cst_list_prim_u_8_strict> file_path,
) {
return _wire__crate__api__unp4k_api__p4k_extract_to_memory(
port_,
file_path,
);
}
late final _wire__crate__api__unp4k_api__p4k_extract_to_memoryPtr =
_lookup<
ffi.NativeFunction<
ffi.Void Function(
ffi.Int64,
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
)
>
>(
'frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__p4k_extract_to_memory',
);
late final _wire__crate__api__unp4k_api__p4k_extract_to_memory =
_wire__crate__api__unp4k_api__p4k_extract_to_memoryPtr
.asFunction<
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)
>();
void wire__crate__api__unp4k_api__p4k_get_all_files(int port_) {
return _wire__crate__api__unp4k_api__p4k_get_all_files(port_);
}
late final _wire__crate__api__unp4k_api__p4k_get_all_filesPtr =
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64)>>(
'frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__p4k_get_all_files',
);
late final _wire__crate__api__unp4k_api__p4k_get_all_files =
_wire__crate__api__unp4k_api__p4k_get_all_filesPtr
.asFunction<void Function(int)>();
void wire__crate__api__unp4k_api__p4k_get_files_in_directory(
int port_,
ffi.Pointer<wire_cst_list_prim_u_8_strict> directory,
) {
return _wire__crate__api__unp4k_api__p4k_get_files_in_directory(
port_,
directory,
);
}
late final _wire__crate__api__unp4k_api__p4k_get_files_in_directoryPtr =
_lookup<
ffi.NativeFunction<
ffi.Void Function(
ffi.Int64,
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
)
>
>(
'frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__p4k_get_files_in_directory',
);
late final _wire__crate__api__unp4k_api__p4k_get_files_in_directory =
_wire__crate__api__unp4k_api__p4k_get_files_in_directoryPtr
.asFunction<
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)
>();
void wire__crate__api__unp4k_api__p4k_open(
int port_,
ffi.Pointer<wire_cst_list_prim_u_8_strict> p4k_path,
) {
return _wire__crate__api__unp4k_api__p4k_open(port_, p4k_path);
}
late final _wire__crate__api__unp4k_api__p4k_openPtr =
_lookup<
ffi.NativeFunction<
ffi.Void Function(
ffi.Int64,
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
)
>
>('frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__p4k_open');
late final _wire__crate__api__unp4k_api__p4k_open =
_wire__crate__api__unp4k_api__p4k_openPtr
.asFunction<
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)
>();
void wire__crate__api__asar_api__rsi_launcher_asar_data_write_main_js(
int port_,
ffi.Pointer<wire_cst_rsi_launcher_asar_data> that,
@ -1247,6 +1443,21 @@ class RustLibWire implements BaseWire {
late final _cst_new_list_String = _cst_new_list_StringPtr
.asFunction<ffi.Pointer<wire_cst_list_String> Function(int)>();
ffi.Pointer<wire_cst_list_p_4_k_file_item> cst_new_list_p_4_k_file_item(
int len,
) {
return _cst_new_list_p_4_k_file_item(len);
}
late final _cst_new_list_p_4_k_file_itemPtr =
_lookup<
ffi.NativeFunction<
ffi.Pointer<wire_cst_list_p_4_k_file_item> Function(ffi.Int32)
>
>('frbgen_starcitizen_doctor_cst_new_list_p_4_k_file_item');
late final _cst_new_list_p_4_k_file_item = _cst_new_list_p_4_k_file_itemPtr
.asFunction<ffi.Pointer<wire_cst_list_p_4_k_file_item> Function(int)>();
ffi.Pointer<wire_cst_list_prim_u_8_loose> cst_new_list_prim_u_8_loose(
int len,
) {
@ -1370,6 +1581,26 @@ final class wire_cst_list_prim_u_8_loose extends ffi.Struct {
external int len;
}
final class wire_cst_p_4_k_file_item extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> name;
@ffi.Bool()
external bool is_directory;
@ffi.Uint64()
external int size;
@ffi.Uint64()
external int compressed_size;
}
final class wire_cst_list_p_4_k_file_item extends ffi.Struct {
external ffi.Pointer<wire_cst_p_4_k_file_item> ptr;
@ffi.Int32()
external int len;
}
final class wire_cst_process_info extends ffi.Struct {
@ffi.Uint32()
external int pid;

View File

@ -1,4 +1,3 @@
import 'dart:convert';
import 'dart:io';
import 'package:file/memory.dart';
@ -7,15 +6,11 @@ import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:path_provider/path_provider.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:starcitizen_doctor/api/analytics.dart';
import 'package:starcitizen_doctor/common/conf/binary_conf.dart';
import 'package:starcitizen_doctor/common/helper/log_helper.dart';
import 'package:starcitizen_doctor/common/rust/api/rs_process.dart';
import 'package:starcitizen_doctor/common/utils/log.dart';
import 'package:starcitizen_doctor/common/utils/provider.dart';
import 'package:starcitizen_doctor/data/app_unp4k_p4k_item_data.dart';
import 'package:starcitizen_doctor/ui/tools/tools_ui_model.dart';
import 'package:starcitizen_doctor/common/rust/api/rs_process.dart'
as rs_process;
import 'package:starcitizen_doctor/common/rust/api/unp4k_api.dart' as unp4k_api;
part 'unp4kc.freezed.dart';
@ -36,14 +31,9 @@ abstract class Unp4kcState with _$Unp4kcState {
@riverpod
class Unp4kCModel extends _$Unp4kCModel {
int? _rsPid;
@override
Unp4kcState build() {
state = Unp4kcState(
startUp: false,
curPath: '\\',
endMessage: S.current.tools_unp4k_msg_init);
state = Unp4kcState(startUp: false, curPath: '\\', endMessage: S.current.tools_unp4k_msg_init);
_init();
return state;
}
@ -52,129 +42,72 @@ class Unp4kCModel extends _$Unp4kCModel {
String getGamePath() => _toolsState.scInstalledPath;
bool _hasUnp4kRunTimeError = false;
void _init() async {
final execDir = "${appGlobalState.applicationBinaryModuleDir}\\unp4kc";
await BinaryModuleConf.extractModule(
["unp4kc"], appGlobalState.applicationBinaryModuleDir!);
final exec = "$execDir\\unp4kc.exe";
final stream = rs_process.start(
executable: exec, arguments: [], workingDirectory: execDir);
stream.listen((event) async {
switch (event.dataType) {
case RsProcessStreamDataType.output:
_rsPid = event.rsPid;
try {
final eventJson = await compute(json.decode, event.data);
_handleMessage(eventJson, event.rsPid);
} catch (e) {
dPrint("[unp4kc] json error: $e");
}
break;
case RsProcessStreamDataType.error:
dPrint("[unp4kc] stderr: ${event.data}");
if (state.errorMessage.isEmpty) {
state = state.copyWith(errorMessage: event.data);
} else {
state = state.copyWith(
errorMessage: "${state.errorMessage}\n${event.data}");
}
if (!_hasUnp4kRunTimeError) {
if (checkRunTimeError(state.errorMessage)) {
_hasUnp4kRunTimeError = true;
AnalyticsApi.touch("unp4k_no_runtime");
}
}
break;
case RsProcessStreamDataType.exit:
dPrint("[unp4kc] exit: ${event.data}");
break;
}
});
ref.onDispose(() {
state = state.copyWith(fs: null);
if (_rsPid != null) {
Process.killPid(_rsPid!);
dPrint("[unp4kc] kill ...");
}
});
}
DateTime? _loadStartTime;
void _handleMessage(Map<String, dynamic> eventJson, int rsPid) async {
final action = eventJson["action"];
final data = eventJson["data"];
final gamePath = getGamePath();
final gameP4kPath = "$gamePath\\Data.p4k";
switch (action.toString().trim()) {
case "info: startup":
rs_process.write(rsPid: rsPid, data: "$gameP4kPath\n");
break;
case "info: Reading_p4k_file":
_loadStartTime = DateTime.now();
state = state.copyWith(endMessage: S.current.tools_unp4k_msg_reading);
break;
case "info: All Ready":
state = state.copyWith(endMessage: S.current.tools_unp4k_msg_reading2);
break;
case "data: P4K_Files":
final p4kFiles = (data as List<dynamic>);
final files = <String, AppUnp4kP4kItemData>{};
final fs = MemoryFileSystem(style: FileSystemStyle.posix);
var nextAwait = 0;
for (var i = 0; i < p4kFiles.length; i++) {
final item = AppUnp4kP4kItemData.fromJson(p4kFiles[i]);
item.name = "${item.name}";
files["\\${item.name}"] = item;
await fs
.file(item.name?.replaceAll("\\", "/") ?? "")
.create(recursive: true);
if (i == nextAwait) {
state = state.copyWith(
endMessage:
S.current.tools_unp4k_msg_reading3(i, p4kFiles.length));
await Future.delayed(Duration.zero);
nextAwait += 20000;
}
try {
state = state.copyWith(endMessage: S.current.tools_unp4k_msg_reading);
final loadStartTime = DateTime.now();
// 使 Rust API P4K
await unp4k_api.p4KOpen(p4KPath: gameP4kPath);
state = state.copyWith(endMessage: S.current.tools_unp4k_msg_reading2);
//
final p4kFiles = await unp4k_api.p4KGetAllFiles();
final files = <String, AppUnp4kP4kItemData>{};
final fs = MemoryFileSystem(style: FileSystemStyle.posix);
var nextAwait = 0;
for (var i = 0; i < p4kFiles.length; i++) {
final item = p4kFiles[i];
final fileData = AppUnp4kP4kItemData(
name: item.name,
isDirectory: item.isDirectory,
size: item.size.toInt(),
compressedSize: item.compressedSize.toInt(),
);
files[item.name] = fileData;
if (!item.isDirectory) {
await fs.file(item.name.replaceAll("\\", "/")).create(recursive: true);
}
final endTime = DateTime.now();
state = state.copyWith(
files: files,
fs: fs,
endMessage: S.current.tools_unp4k_msg_read_completed(files.length,
endTime.difference(_loadStartTime!).inMilliseconds));
_loadStartTime = null;
break;
case "info: Extracted_Open":
final filePath = data.toString();
dPrint("[unp4kc] Extracted_Open file: $filePath");
const textExt = [".txt", ".xml", ".json", ".lua", ".cfg", ".ini"];
const imgExt = [".png"];
String openType = "unknown";
for (var element in textExt) {
if (filePath.toLowerCase().endsWith(element)) {
openType = "text";
}
if (i == nextAwait) {
state = state.copyWith(endMessage: S.current.tools_unp4k_msg_reading3(i, p4kFiles.length));
await Future.delayed(Duration.zero);
nextAwait += 20000;
}
for (var element in imgExt) {
if (filePath.endsWith(element)) {
openType = "image";
}
}
state = state.copyWith(
tempOpenFile: MapEntry(openType, filePath),
endMessage: S.current.tools_unp4k_msg_open_file(filePath));
break;
default:
dPrint("[unp4kc] unknown action: $action");
break;
}
final endTime = DateTime.now();
state = state.copyWith(
files: files,
fs: fs,
endMessage: S.current.tools_unp4k_msg_read_completed(
files.length,
endTime.difference(loadStartTime).inMilliseconds,
),
);
} catch (e) {
dPrint("[unp4k] error: $e");
state = state.copyWith(errorMessage: e.toString());
AnalyticsApi.touch("unp4k_error");
}
ref.onDispose(() async {
state = state.copyWith(fs: null);
try {
await unp4k_api.p4KClose();
} catch (e) {
dPrint("[unp4k] close error: $e");
}
});
}
List<AppUnp4kP4kItemData>? getFiles() {
@ -204,8 +137,7 @@ class Unp4kCModel extends _$Unp4kCModel {
result.add(f);
}
} else {
result.add(AppUnp4kP4kItemData(
name: file.path.replaceAll("/", "\\"), isDirectory: true));
result.add(AppUnp4kP4kItemData(name: file.path.replaceAll("/", "\\"), isDirectory: true));
}
}
return result;
@ -221,58 +153,67 @@ class Unp4kCModel extends _$Unp4kCModel {
Future<void> openFile(String filePath) async {
final tempDir = await getTemporaryDirectory();
final tempPath =
"${tempDir.absolute.path}\\SCToolbox_unp4kc\\${SCLoggerHelper.getGameChannelID(getGamePath())}\\";
final tempPath = "${tempDir.absolute.path}\\SCToolbox_unp4kc\\${SCLoggerHelper.getGameChannelID(getGamePath())}\\";
state = state.copyWith(
tempOpenFile: const MapEntry("loading", ""),
endMessage: S.current.tools_unp4k_msg_open_file(filePath));
tempOpenFile: const MapEntry("loading", ""),
endMessage: S.current.tools_unp4k_msg_open_file(filePath),
);
extractFile(filePath, tempPath, mode: "extract_open");
}
Future<void> extractFile(String filePath, String outputPath,
{String mode = "extract"}) async {
// remove first \\
if (filePath.startsWith("\\")) {
filePath = filePath.substring(1);
}
outputPath = "$outputPath$filePath";
dPrint("extractFile .... $filePath");
if (_rsPid != null) {
rs_process.write(
rsPid: _rsPid!, data: "$mode<:,:>$filePath<:,:>$outputPath\n");
Future<void> extractFile(String filePath, String outputPath, {String mode = "extract"}) async {
try {
// remove first \\
if (filePath.startsWith("\\")) {
filePath = filePath.substring(1);
}
final fullOutputPath = "$outputPath$filePath";
dPrint("extractFile .... $filePath -> $fullOutputPath");
await unp4k_api.p4KExtractToDisk(filePath: filePath, outputPath: fullOutputPath);
if (mode == "extract_open") {
const textExt = [".txt", ".xml", ".json", ".lua", ".cfg", ".ini"];
const imgExt = [".png"];
String openType = "unknown";
for (var element in textExt) {
if (filePath.toLowerCase().endsWith(element)) {
openType = "text";
}
}
for (var element in imgExt) {
if (filePath.endsWith(element)) {
openType = "image";
}
}
state = state.copyWith(
tempOpenFile: MapEntry(openType, fullOutputPath),
endMessage: S.current.tools_unp4k_msg_open_file(filePath),
);
}
} catch (e) {
dPrint("[unp4k] extractFile error: $e");
state = state.copyWith(errorMessage: e.toString());
}
}
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;
}
// Rust .NET runtime
return false;
}
static Future<Uint8List> unp4kTools(
String applicationBinaryModuleDir, List<String> args) async {
await BinaryModuleConf.extractModule(
["unp4kc"], applicationBinaryModuleDir);
final execDir = "$applicationBinaryModuleDir\\unp4kc";
final exec = "$execDir\\unp4kc.exe";
final r = await Process.run(exec, args);
if (r.exitCode != 0) {
Process.killPid(r.pid);
throw Exception(
"error: ${r.exitCode} , info= ${r.stdout} , err= ${r.stderr}");
/// P4K
/// [p4kPath] P4K
/// [filePath] P4K
static Future<Uint8List> extractP4kFileToMemory(String p4kPath, String filePath) async {
try {
await unp4k_api.p4KOpen(p4KPath: p4kPath);
final data = await unp4k_api.p4KExtractToMemory(filePath: filePath);
await unp4k_api.p4KClose();
return Uint8List.fromList(data);
} catch (e) {
throw Exception("extractP4kFileToMemory error: $e");
}
final eventJson = await compute(json.decode, r.stdout.toString());
if (eventJson["action"] == "data: Uint8List") {
final data = eventJson["data"];
return Uint8List.fromList((data as List).cast<int>());
}
throw Exception("error: data error");
}
}

View File

@ -41,7 +41,7 @@ final class Unp4kCModelProvider
}
}
String _$unp4kCModelHash() => r'410461980f6173fdbb5d92cbaa3f4c2f57c1ad8d';
String _$unp4kCModelHash() => r'fe88d52b11464fdbded606bacbd833c1e908b738';
abstract class _$Unp4kCModel extends $Notifier<Unp4kcState> {
Unp4kcState build();

View File

@ -13,7 +13,6 @@ import 'package:re_highlight/styles/vs2015.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:starcitizen_doctor/api/analytics.dart';
import 'package:starcitizen_doctor/common/utils/log.dart';
import 'package:starcitizen_doctor/common/utils/provider.dart';
import 'package:starcitizen_doctor/data/app_advanced_localization_data.dart';
import 'package:starcitizen_doctor/data/sc_localization_data.dart';
import 'package:starcitizen_doctor/provider/unp4kc.dart';
@ -218,11 +217,10 @@ class AdvancedLocalizationUIModel extends _$AdvancedLocalizationUIModel {
Future<String> readEnglishInI(String gameDir) async {
try {
var data = await Unp4kCModel.unp4kTools(appGlobalState.applicationBinaryModuleDir!, [
"extract_memory",
var data = await Unp4kCModel.extractP4kFileToMemory(
"$gameDir\\Data.p4k",
"Data\\Localization\\english\\global.ini",
]);
);
// remove bom
if (data.length > 3 && data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF) {
data = data.sublist(3);

View File

@ -41,7 +41,7 @@ final class PartyRoomUIModelProvider
}
}
String _$partyRoomUIModelHash() => r'add4703c9129465718a7850ea09025aa1ff35358';
String _$partyRoomUIModelHash() => r'b22ad79b6d4a877876b2534f35fb0448b34d4ad5';
abstract class _$PartyRoomUIModel extends $Notifier<PartyRoomUIState> {
PartyRoomUIState build();

View File

@ -66,7 +66,7 @@ final class PartyRoomGameLogTrackerProviderProvider
}
String _$partyRoomGameLogTrackerProviderHash() =>
r'3e1560b2fffc5461a41bece57b43e27f4112ad0c';
r'7c9413736b0a3357075ab5309f0e746f0d6e3fc3';
final class PartyRoomGameLogTrackerProviderFamily extends $Family
with

545
rust/Cargo.lock generated
View File

@ -17,6 +17,17 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "aes"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]]
name = "ahash"
version = "0.8.12"
@ -133,6 +144,15 @@ version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
name = "arbitrary"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
dependencies = [
"derive_arbitrary",
]
[[package]]
name = "asar"
version = "0.3.0"
@ -179,9 +199,9 @@ dependencies = [
[[package]]
name = "async-compression"
version = "0.4.33"
version = "0.4.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93c1f86859c1af3d514fa19e8323147ff10ea98684e6c7b307912509f50e67b2"
checksum = "0e86f6d3dc9dc4352edeea6b8e499e13e3f5dc3b964d7ca5fd411415a3498473"
dependencies = [
"compression-codecs",
"compression-core",
@ -363,6 +383,15 @@ dependencies = [
"generic-array",
]
[[package]]
name = "block-padding"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93"
dependencies = [
"generic-array",
]
[[package]]
name = "block2"
version = "0.6.2"
@ -385,6 +414,16 @@ dependencies = [
"piper",
]
[[package]]
name = "bstr"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "build-target"
version = "0.4.0"
@ -415,6 +454,15 @@ version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
[[package]]
name = "bzip2"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c"
dependencies = [
"libbz2-rs-sys",
]
[[package]]
name = "castaway"
version = "0.2.4"
@ -425,12 +473,23 @@ dependencies = [
]
[[package]]
name = "cc"
version = "1.2.46"
name = "cbc"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97463e1064cb1b1c1384ad0a0b9c8abd0988e2a91f52606c80ef14aadb63e36"
checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6"
dependencies = [
"cipher",
]
[[package]]
name = "cc"
version = "1.2.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c481bdbf0ed3b892f6f806287d72acd515b352a4ec27a208489b8c1bc839633a"
dependencies = [
"find-msvc-tools",
"jobserver",
"libc",
"shlex",
]
@ -459,10 +518,20 @@ dependencies = [
]
[[package]]
name = "clap"
version = "4.5.52"
name = "cipher"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa8120877db0e5c011242f96806ce3c94e0737ab8108532a76a3300a01db2ab8"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
"crypto-common",
"inout",
]
[[package]]
name = "clap"
version = "4.5.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8"
dependencies = [
"clap_builder",
"clap_derive",
@ -470,9 +539,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.52"
version = "4.5.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02576b399397b659c26064fbc92a75fede9d18ffd5f80ca1cd74ddab167016e1"
checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00"
dependencies = [
"anstream",
"anstyle",
@ -548,9 +617,9 @@ dependencies = [
[[package]]
name = "compression-codecs"
version = "0.4.32"
version = "0.4.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "680dc087785c5230f8e8843e2e57ac7c1c90488b6a91b88caa265410568f441b"
checksum = "302266479cb963552d11bd042013a58ef1adc56768016c8b82b4199488f2d4ad"
dependencies = [
"compression-core",
"flate2",
@ -559,9 +628,9 @@ dependencies = [
[[package]]
name = "compression-core"
version = "0.4.30"
version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a9b614a5787ef0c8802a55766480563cb3a93b435898c422ed2a359cf811582"
checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d"
[[package]]
name = "concurrent-queue"
@ -572,6 +641,19 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "console"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"unicode-width",
"windows-sys 0.61.2",
]
[[package]]
name = "console_error_panic_hook"
version = "0.1.7"
@ -602,6 +684,12 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "constant_time_eq"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
[[package]]
name = "cookie"
version = "0.18.1"
@ -656,6 +744,21 @@ dependencies = [
"libc",
]
[[package]]
name = "crc"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d"
dependencies = [
"crc-catalog",
]
[[package]]
name = "crc-catalog"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
[[package]]
name = "crc32fast"
version = "1.5.0"
@ -822,6 +925,12 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
[[package]]
name = "deflate64"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26bf8fc351c5ed29b5c2f0cbbac1b209b74f60ecd62e675a998df72c49af5204"
[[package]]
name = "delegate-attr"
version = "0.3.0"
@ -853,6 +962,17 @@ dependencies = [
"serde_core",
]
[[package]]
name = "derive_arbitrary"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "derive_builder"
version = "0.20.2"
@ -892,6 +1012,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
"subtle",
]
[[package]]
@ -936,6 +1057,12 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "encode_unicode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]]
name = "encoding_rs"
version = "0.8.35"
@ -947,9 +1074,9 @@ dependencies = [
[[package]]
name = "endi"
version = "1.1.0"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf"
checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099"
[[package]]
name = "enum-as-inner"
@ -1078,6 +1205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb"
dependencies = [
"crc32fast",
"libz-rs-sys",
"miniz_oxide",
]
@ -1298,6 +1426,25 @@ version = "0.32.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
[[package]]
name = "glob"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
[[package]]
name = "globset"
version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3"
dependencies = [
"aho-corasick",
"bstr",
"log",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "h2"
version = "0.4.12"
@ -1310,7 +1457,7 @@ dependencies = [
"futures-core",
"futures-sink",
"http",
"indexmap 2.12.0",
"indexmap 2.12.1",
"slab",
"tokio",
"tokio-util",
@ -1331,9 +1478,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
version = "0.16.0"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
[[package]]
name = "heck"
@ -1400,13 +1547,21 @@ dependencies = [
]
[[package]]
name = "http"
version = "1.3.1"
name = "hmac"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest",
]
[[package]]
name = "http"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
dependencies = [
"bytes",
"fnv",
"itoa",
]
@ -1496,9 +1651,9 @@ dependencies = [
[[package]]
name = "hyper-util"
version = "0.1.18"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56"
checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f"
dependencies = [
"base64 0.22.1",
"bytes",
@ -1671,16 +1826,39 @@ dependencies = [
[[package]]
name = "indexmap"
version = "2.12.0"
version = "2.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
dependencies = [
"equivalent",
"hashbrown 0.16.0",
"hashbrown 0.16.1",
"serde",
"serde_core",
]
[[package]]
name = "indicatif"
version = "0.18.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9375e112e4b463ec1b1c6c011953545c65a30164fbab5b581df32b3abf0dcb88"
dependencies = [
"console",
"portable-atomic",
"unicode-width",
"unit-prefix",
"web-time",
]
[[package]]
name = "inout"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
dependencies = [
"block-padding",
"generic-array",
]
[[package]]
name = "ipconfig"
version = "0.3.2"
@ -1749,10 +1927,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "js-sys"
version = "0.3.82"
name = "jobserver"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65"
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
dependencies = [
"getrandom 0.3.4",
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
dependencies = [
"once_cell",
"wasm-bindgen",
@ -1765,10 +1953,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.177"
name = "libbz2-rs-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7"
[[package]]
name = "libc"
version = "0.2.178"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
[[package]]
name = "libredox"
@ -1781,6 +1975,15 @@ dependencies = [
"redox_syscall",
]
[[package]]
name = "libz-rs-sys"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b484ba8d4f775eeca644c452a56650e544bf7e617f1d170fe7298122ead5222"
dependencies = [
"zlib-rs",
]
[[package]]
name = "linux-raw-sys"
version = "0.11.0"
@ -1810,9 +2013,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.28"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "lru-slab"
@ -1821,10 +2024,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
[[package]]
name = "mac-notification-sys"
version = "0.6.8"
name = "lzma-rust2"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ee70bb2bba058d58e252d2944582d634fc884fc9c489a966d428dedcf653e97"
checksum = "c60a23ffb90d527e23192f1246b14746e2f7f071cb84476dd879071696c18a4a"
dependencies = [
"crc",
"sha2",
]
[[package]]
name = "mac-notification-sys"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65fd3f75411f4725061682ed91f131946e912859d0044d39c4ec0aac818d7621"
dependencies = [
"cc",
"objc2",
@ -2300,6 +2513,16 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pbkdf2"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
dependencies = [
"digest",
"hmac",
]
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
@ -2397,6 +2620,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppmd-rust"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d558c559f0450f16f2a27a1f017ef38468c1090c9ce63c8e51366232d53717b4"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
@ -2449,6 +2678,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "quick-xml"
version = "0.38.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c"
dependencies = [
"memchr",
]
[[package]]
name = "quinn"
version = "0.11.9"
@ -2731,6 +2969,7 @@ dependencies = [
"serde_json",
"tokenizers",
"tokio",
"unp4k_rs",
"url",
"walkdir",
"win32job",
@ -2787,9 +3026,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
version = "1.13.0"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a"
checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c"
dependencies = [
"web-time",
"zeroize",
@ -2963,15 +3202,15 @@ dependencies = [
[[package]]
name = "serde_with"
version = "3.16.0"
version = "3.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10574371d41b0d9b2cff89418eda27da52bcaff2cc8741db26382a77c29131f1"
checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7"
dependencies = [
"base64 0.22.1",
"chrono",
"hex",
"indexmap 1.9.3",
"indexmap 2.12.0",
"indexmap 2.12.1",
"schemars 0.9.0",
"schemars 1.1.0",
"serde_core",
@ -2982,9 +3221,9 @@ dependencies = [
[[package]]
name = "serde_with_macros"
version = "3.16.0"
version = "3.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08a72d8216842fdd57820dc78d840bef99248e35fb2554ff923319e60f2d686b"
checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c"
dependencies = [
"darling 0.21.3",
"proc-macro2",
@ -2992,6 +3231,17 @@ dependencies = [
"syn",
]
[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sha2"
version = "0.10.9"
@ -3020,9 +3270,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook-registry"
version = "1.4.6"
version = "1.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b"
checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad"
dependencies = [
"libc",
]
@ -3120,9 +3370,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.110"
version = "2.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea"
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
dependencies = [
"proc-macro2",
"quote",
@ -3193,7 +3443,7 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b1e66e07de489fe43a46678dd0b8df65e0c973909df1b60ba33874e297ba9b9"
dependencies = [
"quick-xml",
"quick-xml 0.37.5",
"thiserror 2.0.17",
"windows 0.61.3",
"windows-version",
@ -3328,9 +3578,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokenizers"
version = "0.22.1"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6475a27088c98ea96d00b39a9ddfb63780d1ad4cceb6f48374349a96ab2b7842"
checksum = "b238e22d44a15349529690fb07bd645cf58149a1b1e44d6cb5bd1641ff1a6223"
dependencies = [
"ahash",
"aho-corasick",
@ -3434,7 +3684,7 @@ version = "0.23.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d"
dependencies = [
"indexmap 2.12.0",
"indexmap 2.12.1",
"toml_datetime",
"toml_parser",
"winnow",
@ -3466,9 +3716,9 @@ dependencies = [
[[package]]
name = "tower-http"
version = "0.6.6"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
checksum = "9cf146f99d442e8e68e585f5d798ccd3cad9a7835b917e09728880a862706456"
dependencies = [
"bitflags",
"bytes",
@ -3496,9 +3746,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tracing"
version = "0.1.41"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647"
dependencies = [
"pin-project-lite",
"tracing-attributes",
@ -3507,9 +3757,9 @@ dependencies = [
[[package]]
name = "tracing-attributes"
version = "0.1.30"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
dependencies = [
"proc-macro2",
"quote",
@ -3518,9 +3768,9 @@ dependencies = [
[[package]]
name = "tracing-core"
version = "0.1.34"
version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c"
dependencies = [
"once_cell",
"valuable",
@ -3538,9 +3788,9 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
version = "0.3.20"
version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5"
checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e"
dependencies = [
"sharded-slab",
"thread_local",
@ -3591,6 +3841,12 @@ version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]]
name = "unicode-width"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
[[package]]
name = "unicode-xid"
version = "0.2.6"
@ -3603,6 +3859,34 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]]
name = "unit-prefix"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3"
[[package]]
name = "unp4k_rs"
version = "0.1.0"
source = "git+https://github.com/StarCitizenToolBox/unp4k_rs?tag=V0.0.1#67f6ae242c480de9ee50ed03d31c948b68bf9522"
dependencies = [
"aes",
"anyhow",
"byteorder",
"cbc",
"clap",
"crc32fast",
"flate2",
"glob",
"globset",
"indicatif",
"quick-xml 0.38.4",
"rayon",
"thiserror 2.0.17",
"zip",
"zstd",
]
[[package]]
name = "untrusted"
version = "0.9.0"
@ -3629,9 +3913,9 @@ dependencies = [
[[package]]
name = "ureq-proto"
version = "0.5.2"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2"
checksum = "d81f9efa9df032be5934a46a068815a10a042b494b6a58cb0a1a97bb5467ed6f"
dependencies = [
"base64 0.22.1",
"http",
@ -3671,13 +3955,13 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.18.1"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"
checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
dependencies = [
"getrandom 0.3.4",
"js-sys",
"serde",
"serde_core",
"wasm-bindgen",
]
@ -3735,9 +4019,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen"
version = "0.2.105"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60"
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
dependencies = [
"cfg-if",
"once_cell",
@ -3748,9 +4032,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.55"
version = "0.4.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0"
checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c"
dependencies = [
"cfg-if",
"js-sys",
@ -3761,9 +4045,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.105"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2"
checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -3771,9 +4055,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.105"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc"
checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
dependencies = [
"bumpalo",
"proc-macro2",
@ -3784,9 +4068,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.105"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76"
checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
dependencies = [
"unicode-ident",
]
@ -3821,9 +4105,9 @@ dependencies = [
[[package]]
name = "web-sys"
version = "0.3.82"
version = "0.3.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1"
checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac"
dependencies = [
"js-sys",
"wasm-bindgen",
@ -4347,9 +4631,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "winnow"
version = "0.7.13"
version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
dependencies = [
"memchr",
]
@ -4472,18 +4756,18 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.8.27"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.27"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
dependencies = [
"proc-macro2",
"quote",
@ -4516,6 +4800,20 @@ name = "zeroize"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
dependencies = [
"zeroize_derive",
]
[[package]]
name = "zeroize_derive"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "zerotrie"
@ -4550,6 +4848,79 @@ dependencies = [
"syn",
]
[[package]]
name = "zip"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb2a05c7c36fde6c09b08576c9f7fb4cda705990f73b58fe011abf7dfb24168b"
dependencies = [
"aes",
"arbitrary",
"bzip2",
"constant_time_eq",
"crc32fast",
"deflate64",
"flate2",
"getrandom 0.3.4",
"hmac",
"indexmap 2.12.1",
"lzma-rust2",
"memchr",
"pbkdf2",
"ppmd-rust",
"sha1",
"time",
"zeroize",
"zopfli",
"zstd",
]
[[package]]
name = "zlib-rs"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36134c44663532e6519d7a6dfdbbe06f6f8192bde8ae9ed076e9b213f0e31df7"
[[package]]
name = "zopfli"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249"
dependencies = [
"bumpalo",
"crc32fast",
"log",
"simd-adler32",
]
[[package]]
name = "zstd"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "7.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d"
dependencies = [
"zstd-sys",
]
[[package]]
name = "zstd-sys"
version = "2.0.16+zstd.1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748"
dependencies = [
"cc",
"pkg-config",
]
[[package]]
name = "zvariant"
version = "5.8.0"

View File

@ -30,6 +30,7 @@ ort = { version = "2.0.0-rc.10", features = ["xnnpack", "download-binaries", "nd
tokenizers = { version = "0.22", default-features = false, features = ["onig"] }
ndarray = "0.17"
serde_json = "1.0"
unp4k_rs = { git = "https://github.com/StarCitizenToolBox/unp4k_rs", tag = "V0.0.1" }
[target.'cfg(windows)'.dependencies]
windows = { version = "0.62.2", features = [

View File

@ -6,3 +6,4 @@ pub mod rs_process;
pub mod win32_api;
pub mod asar_api;
pub mod ort_api;
pub mod unp4k_api;

196
rust/src/api/unp4k_api.rs Normal file
View File

@ -0,0 +1,196 @@
use anyhow::{anyhow, Result};
use flutter_rust_bridge::frb;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use unp4k::{P4kEntry, P4kFile};
/// P4K 文件项信息
#[frb(dart_metadata=("freezed"))]
pub struct P4kFileItem {
/// 文件名/路径
pub name: String,
/// 是否为目录
pub is_directory: bool,
/// 文件大小(字节)
pub size: u64,
/// 压缩后大小(字节)
pub compressed_size: u64,
}
// 全局 P4K 读取器实例(用于保持状态)
static GLOBAL_P4K_READER: once_cell::sync::Lazy<Arc<Mutex<Option<P4kFile>>>> =
once_cell::sync::Lazy::new(|| Arc::new(Mutex::new(None)));
static GLOBAL_P4K_FILES: once_cell::sync::Lazy<Arc<Mutex<HashMap<String, P4kEntry>>>> =
once_cell::sync::Lazy::new(|| Arc::new(Mutex::new(HashMap::new())));
/// 打开 P4K 文件
pub async fn p4k_open(p4k_path: String) -> Result<usize> {
let path = PathBuf::from(&p4k_path);
if !path.exists() {
return Err(anyhow!("P4K file not found: {}", p4k_path));
}
// 在后台线程执行阻塞操作
let (reader, file_count, files_map) = tokio::task::spawn_blocking(move || {
let reader = P4kFile::open(&path)?;
let entries = reader.entries();
let file_count = entries.len();
let mut files_map = HashMap::new();
for entry in entries {
// 将路径转换为 Windows 风格,以 \ 开头
let name = if entry.name.starts_with("\\") {
entry.name.clone()
} else {
format!("\\{}", entry.name.replace("/", "\\"))
};
files_map.insert(name, entry.clone());
}
Ok::<_, anyhow::Error>((reader, file_count, files_map))
})
.await??;
*GLOBAL_P4K_READER.lock().unwrap() = Some(reader);
*GLOBAL_P4K_FILES.lock().unwrap() = files_map;
Ok(file_count)
}
/// 获取所有文件列表
pub async fn p4k_get_all_files() -> Result<Vec<P4kFileItem>> {
let files = GLOBAL_P4K_FILES.lock().unwrap();
let mut result = Vec::with_capacity(files.len());
for (name, entry) in files.iter() {
result.push(P4kFileItem {
name: name.clone(),
is_directory: false,
size: entry.uncompressed_size,
compressed_size: entry.compressed_size,
});
}
Ok(result)
}
/// 获取指定目录下的文件列表
pub async fn p4k_get_files_in_directory(directory: String) -> Result<Vec<P4kFileItem>> {
let files = GLOBAL_P4K_FILES.lock().unwrap();
let mut result = Vec::new();
let mut dirs = std::collections::HashSet::new();
// 确保目录路径以 \ 开头和结尾
let dir_path = if !directory.starts_with("\\") {
format!("\\{}", directory)
} else {
directory.clone()
};
let dir_path = if !dir_path.ends_with("\\") {
format!("{}\\", dir_path)
} else {
dir_path
};
for (name, entry) in files.iter() {
if name.starts_with(&dir_path) {
let relative = &name[dir_path.len()..];
if let Some(slash_pos) = relative.find("\\") {
// 这是一个子目录
let subdir = &relative[..slash_pos];
if !dirs.contains(subdir) {
dirs.insert(subdir.to_string());
result.push(P4kFileItem {
name: format!("{}{}\\", dir_path, subdir),
is_directory: true,
size: 0,
compressed_size: 0,
});
}
} else {
// 这是一个文件
result.push(P4kFileItem {
name: name.clone(),
is_directory: false,
size: entry.uncompressed_size,
compressed_size: entry.compressed_size,
});
}
}
}
// 按目录优先,然后按名称排序
result.sort_by(|a, b| {
if a.is_directory && !b.is_directory {
std::cmp::Ordering::Less
} else if !a.is_directory && b.is_directory {
std::cmp::Ordering::Greater
} else {
a.name.cmp(&b.name)
}
});
Ok(result)
}
/// 提取文件到内存
pub async fn p4k_extract_to_memory(file_path: String) -> Result<Vec<u8>> {
// 规范化路径
let normalized_path = if file_path.starts_with("\\") {
file_path.clone()
} else {
format!("\\{}", file_path)
};
// 获取文件 entry 的克隆
let entry = {
let files = GLOBAL_P4K_FILES.lock().unwrap();
files
.get(&normalized_path)
.ok_or_else(|| anyhow!("File not found: {}", file_path))?
.clone()
};
// 在后台线程执行阻塞的提取操作
let data = tokio::task::spawn_blocking(move || {
let mut reader = GLOBAL_P4K_READER.lock().unwrap();
if reader.is_none() {
return Err(anyhow!("P4K reader not initialized"));
}
let data = reader.as_mut().unwrap().extract_entry(&entry)?;
Ok::<_, anyhow::Error>(data)
})
.await??;
Ok(data)
}
/// 提取文件到磁盘
pub async fn p4k_extract_to_disk(file_path: String, output_path: String) -> Result<()> {
let data = p4k_extract_to_memory(file_path).await?;
// 在后台线程执行阻塞的文件写入操作
tokio::task::spawn_blocking(move || {
let output = PathBuf::from(&output_path);
// 创建父目录
if let Some(parent) = output.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(output, data)?;
Ok::<_, anyhow::Error>(())
})
.await??;
Ok(())
}
/// 关闭 P4K 读取器
pub async fn p4k_close() -> Result<()> {
*GLOBAL_P4K_READER.lock().unwrap() = None;
GLOBAL_P4K_FILES.lock().unwrap().clear();
Ok(())
}

View File

@ -37,7 +37,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
default_rust_auto_opaque = RustAutoOpaqueNom,
);
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.11.1";
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -518970253;
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -737964996;
// Section: executor
@ -291,6 +291,155 @@ fn wire__crate__api__ort_api__load_translation_model_impl(
},
)
}
fn wire__crate__api__unp4k_api__p4k_close_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "p4k_close",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
move |context| async move {
transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || async move {
let output_ok = crate::api::unp4k_api::p4k_close().await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__api__unp4k_api__p4k_extract_to_disk_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
file_path: impl CstDecode<String>,
output_path: impl CstDecode<String>,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "p4k_extract_to_disk",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let api_file_path = file_path.cst_decode();
let api_output_path = output_path.cst_decode();
move |context| async move {
transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || async move {
let output_ok = crate::api::unp4k_api::p4k_extract_to_disk(
api_file_path,
api_output_path,
)
.await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__api__unp4k_api__p4k_extract_to_memory_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
file_path: impl CstDecode<String>,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "p4k_extract_to_memory",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let api_file_path = file_path.cst_decode();
move |context| async move {
transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || async move {
let output_ok =
crate::api::unp4k_api::p4k_extract_to_memory(api_file_path).await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__api__unp4k_api__p4k_get_all_files_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "p4k_get_all_files",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
move |context| async move {
transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || async move {
let output_ok = crate::api::unp4k_api::p4k_get_all_files().await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__api__unp4k_api__p4k_get_files_in_directory_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
directory: impl CstDecode<String>,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "p4k_get_files_in_directory",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let api_directory = directory.cst_decode();
move |context| async move {
transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || async move {
let output_ok =
crate::api::unp4k_api::p4k_get_files_in_directory(api_directory)
.await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__api__unp4k_api__p4k_open_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
p4k_path: impl CstDecode<String>,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "p4k_open",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let api_p4k_path = p4k_path.cst_decode();
move |context| async move {
transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || async move {
let output_ok = crate::api::unp4k_api::p4k_open(api_p4k_path).await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__api__asar_api__rsi_launcher_asar_data_write_main_js_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
that: impl CstDecode<crate::api::asar_api::RsiLauncherAsarData>,
@ -630,6 +779,12 @@ impl CstDecode<u8> for u8 {
self
}
}
impl CstDecode<usize> for usize {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> usize {
self
}
}
impl SseDecode for flutter_rust_bridge::for_generated::anyhow::Error {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@ -693,6 +848,20 @@ impl SseDecode for Vec<String> {
}
}
impl SseDecode for Vec<crate::api::unp4k_api::P4kFileItem> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut len_ = <i32>::sse_decode(deserializer);
let mut ans_ = vec![];
for idx_ in 0..len_ {
ans_.push(<crate::api::unp4k_api::P4kFileItem>::sse_decode(
deserializer,
));
}
return ans_;
}
}
impl SseDecode for Vec<u8> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@ -823,6 +992,22 @@ impl SseDecode for Option<Vec<u8>> {
}
}
impl SseDecode for crate::api::unp4k_api::P4kFileItem {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_name = <String>::sse_decode(deserializer);
let mut var_isDirectory = <bool>::sse_decode(deserializer);
let mut var_size = <u64>::sse_decode(deserializer);
let mut var_compressedSize = <u64>::sse_decode(deserializer);
return crate::api::unp4k_api::P4kFileItem {
name: var_name,
is_directory: var_isDirectory,
size: var_size,
compressed_size: var_compressedSize,
};
}
}
impl SseDecode for crate::api::win32_api::ProcessInfo {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@ -943,6 +1128,13 @@ impl SseDecode for () {
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {}
}
impl SseDecode for usize {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
deserializer.cursor.read_u64::<NativeEndian>().unwrap() as _
}
}
fn pde_ffi_dispatcher_primary_impl(
func_id: i32,
port: flutter_rust_bridge::for_generated::MessagePort,
@ -1024,6 +1216,29 @@ impl flutter_rust_bridge::IntoIntoDart<crate::api::http_api::MyMethod>
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::api::unp4k_api::P4kFileItem {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.name.into_into_dart().into_dart(),
self.is_directory.into_into_dart().into_dart(),
self.size.into_into_dart().into_dart(),
self.compressed_size.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::api::unp4k_api::P4kFileItem
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::api::unp4k_api::P4kFileItem>
for crate::api::unp4k_api::P4kFileItem
{
fn into_into_dart(self) -> crate::api::unp4k_api::P4kFileItem {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::api::win32_api::ProcessInfo {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
@ -1195,6 +1410,16 @@ impl SseEncode for Vec<String> {
}
}
impl SseEncode for Vec<crate::api::unp4k_api::P4kFileItem> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<i32>::sse_encode(self.len() as _, serializer);
for item in self {
<crate::api::unp4k_api::P4kFileItem>::sse_encode(item, serializer);
}
}
}
impl SseEncode for Vec<u8> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@ -1318,6 +1543,16 @@ impl SseEncode for Option<Vec<u8>> {
}
}
impl SseEncode for crate::api::unp4k_api::P4kFileItem {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<String>::sse_encode(self.name, serializer);
<bool>::sse_encode(self.is_directory, serializer);
<u64>::sse_encode(self.size, serializer);
<u64>::sse_encode(self.compressed_size, serializer);
}
}
impl SseEncode for crate::api::win32_api::ProcessInfo {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@ -1416,6 +1651,16 @@ impl SseEncode for () {
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {}
}
impl SseEncode for usize {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
serializer
.cursor
.write_u64::<NativeEndian>(self as _)
.unwrap();
}
}
#[cfg(not(target_family = "wasm"))]
mod io {
// This file is automatically generated, so please do not edit it.
@ -1508,6 +1753,16 @@ mod io {
vec.into_iter().map(CstDecode::cst_decode).collect()
}
}
impl CstDecode<Vec<crate::api::unp4k_api::P4kFileItem>> for *mut wire_cst_list_p_4_k_file_item {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> Vec<crate::api::unp4k_api::P4kFileItem> {
let vec = unsafe {
let wrap = flutter_rust_bridge::for_generated::box_from_leak_ptr(self);
flutter_rust_bridge::for_generated::vec_from_leak_ptr(wrap.ptr, wrap.len)
};
vec.into_iter().map(CstDecode::cst_decode).collect()
}
}
impl CstDecode<Vec<u8>> for *mut wire_cst_list_prim_u_8_loose {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> Vec<u8> {
@ -1546,6 +1801,17 @@ mod io {
vec.into_iter().map(CstDecode::cst_decode).collect()
}
}
impl CstDecode<crate::api::unp4k_api::P4kFileItem> for wire_cst_p_4_k_file_item {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::api::unp4k_api::P4kFileItem {
crate::api::unp4k_api::P4kFileItem {
name: self.name.cst_decode(),
is_directory: self.is_directory.cst_decode(),
size: self.size.cst_decode(),
compressed_size: self.compressed_size.cst_decode(),
}
}
}
impl CstDecode<crate::api::win32_api::ProcessInfo> for wire_cst_process_info {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::api::win32_api::ProcessInfo {
@ -1596,6 +1862,21 @@ mod io {
}
}
}
impl NewWithNullPtr for wire_cst_p_4_k_file_item {
fn new_with_null_ptr() -> Self {
Self {
name: core::ptr::null_mut(),
is_directory: Default::default(),
size: Default::default(),
compressed_size: Default::default(),
}
}
}
impl Default for wire_cst_p_4_k_file_item {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_process_info {
fn new_with_null_ptr() -> Self {
Self {
@ -1764,6 +2045,51 @@ mod io {
)
}
#[unsafe(no_mangle)]
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__p4k_close(port_: i64) {
wire__crate__api__unp4k_api__p4k_close_impl(port_)
}
#[unsafe(no_mangle)]
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__p4k_extract_to_disk(
port_: i64,
file_path: *mut wire_cst_list_prim_u_8_strict,
output_path: *mut wire_cst_list_prim_u_8_strict,
) {
wire__crate__api__unp4k_api__p4k_extract_to_disk_impl(port_, file_path, output_path)
}
#[unsafe(no_mangle)]
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__p4k_extract_to_memory(
port_: i64,
file_path: *mut wire_cst_list_prim_u_8_strict,
) {
wire__crate__api__unp4k_api__p4k_extract_to_memory_impl(port_, file_path)
}
#[unsafe(no_mangle)]
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__p4k_get_all_files(
port_: i64,
) {
wire__crate__api__unp4k_api__p4k_get_all_files_impl(port_)
}
#[unsafe(no_mangle)]
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__p4k_get_files_in_directory(
port_: i64,
directory: *mut wire_cst_list_prim_u_8_strict,
) {
wire__crate__api__unp4k_api__p4k_get_files_in_directory_impl(port_, directory)
}
#[unsafe(no_mangle)]
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__p4k_open(
port_: i64,
p4k_path: *mut wire_cst_list_prim_u_8_strict,
) {
wire__crate__api__unp4k_api__p4k_open_impl(port_, p4k_path)
}
#[unsafe(no_mangle)]
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__asar_api__rsi_launcher_asar_data_write_main_js(
port_: i64,
@ -1884,6 +2210,20 @@ mod io {
flutter_rust_bridge::for_generated::new_leak_box_ptr(wrap)
}
#[unsafe(no_mangle)]
pub extern "C" fn frbgen_starcitizen_doctor_cst_new_list_p_4_k_file_item(
len: i32,
) -> *mut wire_cst_list_p_4_k_file_item {
let wrap = wire_cst_list_p_4_k_file_item {
ptr: flutter_rust_bridge::for_generated::new_leak_vec_ptr(
<wire_cst_p_4_k_file_item>::new_with_null_ptr(),
len,
),
len,
};
flutter_rust_bridge::for_generated::new_leak_box_ptr(wrap)
}
#[unsafe(no_mangle)]
pub extern "C" fn frbgen_starcitizen_doctor_cst_new_list_prim_u_8_loose(
len: i32,
@ -1942,6 +2282,12 @@ mod io {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_list_p_4_k_file_item {
ptr: *mut wire_cst_p_4_k_file_item,
len: i32,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_list_prim_u_8_loose {
ptr: *mut u8,
len: i32,
@ -1966,6 +2312,14 @@ mod io {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_p_4_k_file_item {
name: *mut wire_cst_list_prim_u_8_strict,
is_directory: bool,
size: u64,
compressed_size: u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_process_info {
pid: u32,
name: *mut wire_cst_list_prim_u_8_strict,