mirror of
https://github.com/StarCitizenToolBox/app.git
synced 2026-02-11 17:50:23 +00:00
feat: 增加基础的游戏进程监听
This commit is contained in:
@@ -1,19 +1,14 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:fluent_ui/fluent_ui.dart' show debugPrint;
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/common/helper/log_helper.dart';
|
||||
import 'package:starcitizen_doctor/common/helper/game_log_analyzer.dart';
|
||||
import 'package:starcitizen_doctor/generated/l10n.dart';
|
||||
import 'package:watcher/watcher.dart';
|
||||
|
||||
part 'log_analyze_provider.g.dart';
|
||||
|
||||
part 'log_analyze_provider.freezed.dart';
|
||||
|
||||
final Map<String?, String> logAnalyzeSearchTypeMap = {
|
||||
null: S.current.log_analyzer_filter_all,
|
||||
"info": S.current.log_analyzer_filter_basic_info,
|
||||
@@ -26,132 +21,29 @@ final Map<String?, String> logAnalyzeSearchTypeMap = {
|
||||
"request_location_inventory": S.current.log_analyzer_filter_local_inventory,
|
||||
};
|
||||
|
||||
@freezed
|
||||
abstract class LogAnalyzeLineData with _$LogAnalyzeLineData {
|
||||
const factory LogAnalyzeLineData({
|
||||
required String type,
|
||||
required String title,
|
||||
String? data,
|
||||
String? dateTime,
|
||||
}) = _LogAnalyzeLineData;
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class ToolsLogAnalyze extends _$ToolsLogAnalyze {
|
||||
static const String unknownValue = "<Unknown>";
|
||||
|
||||
@override
|
||||
Future<List<LogAnalyzeLineData>> build(String gameInstallPath, bool listSortReverse) async {
|
||||
final logFile = File("$gameInstallPath/Game.log");
|
||||
debugPrint("[ToolsLogAnalyze] logFile: ${logFile.absolute.path}");
|
||||
if (gameInstallPath.isEmpty || !(await logFile.exists())) {
|
||||
return [
|
||||
LogAnalyzeLineData(
|
||||
type: "error",
|
||||
title: S.current.log_analyzer_no_log_file,
|
||||
)
|
||||
];
|
||||
return [const LogAnalyzeLineData(type: "error", title: "未找到日志文件")];
|
||||
}
|
||||
state = AsyncData([]);
|
||||
state = const AsyncData([]);
|
||||
_launchLogAnalyze(logFile);
|
||||
return state.value ?? [];
|
||||
}
|
||||
|
||||
String _playerName = ""; // 记录玩家名称
|
||||
int _killCount = 0; // 记录击杀其他实体次数
|
||||
int _deathCount = 0; // 记录被击杀次数
|
||||
int _selfKillCount = 0; // 记录自杀次数
|
||||
int _vehicleDestructionCount = 0; // 记录载具损毁次数 (软死亡)
|
||||
int _vehicleDestructionCountHard = 0; // 记录载具损毁次数 (解体)
|
||||
DateTime? _gameStartTime; // 记录游戏开始时间
|
||||
int _gameCrashLineNumber = -1; // 记录${S.current.log_analyzer_filter_game_crash}行号
|
||||
int _currentLineNumber = 0; // 当前行号
|
||||
void _launchLogAnalyze(File logFile) async {
|
||||
// 使用新的 GameLogAnalyzer 工具类
|
||||
final result = await GameLogAnalyzer.analyzeLogFile(logFile);
|
||||
final (results, _) = result;
|
||||
|
||||
void _launchLogAnalyze(File logFile, {int startLine = 0}) async {
|
||||
final logLines = utf8.decode((await logFile.readAsBytes()), allowMalformed: true).split("\n");
|
||||
debugPrint("[ToolsLogAnalyze] logLines: ${logLines.length}");
|
||||
if (startLine == 0) {
|
||||
_killCount = 0;
|
||||
_deathCount = 0;
|
||||
_selfKillCount = 0;
|
||||
_vehicleDestructionCount = 0;
|
||||
_vehicleDestructionCountHard = 0;
|
||||
_gameStartTime = null;
|
||||
_gameCrashLineNumber = -1;
|
||||
} else if (startLine > logLines.length) {
|
||||
// 考虑文件重新写入的情况
|
||||
ref.invalidateSelf();
|
||||
}
|
||||
_currentLineNumber = logLines.length;
|
||||
// for i in logLines
|
||||
for (var i = 0; i < logLines.length; i++) {
|
||||
// 支持追加模式
|
||||
if (i < startLine) continue;
|
||||
final line = logLines[i];
|
||||
if (line.isEmpty) continue;
|
||||
final data = _handleLogLine(line, i);
|
||||
if (data != null) {
|
||||
_appendResult(data);
|
||||
// wait for ui update
|
||||
await Future.delayed(Duration(seconds: 0));
|
||||
}
|
||||
}
|
||||
|
||||
final lastLineDateTime =
|
||||
_gameStartTime != null ? _getLogLineDateTime(logLines.lastWhere((e) => e.startsWith("<20"))) : null;
|
||||
|
||||
// 检查${S.current.log_analyzer_filter_game_crash}行号
|
||||
if (_gameCrashLineNumber > 0) {
|
||||
// crashInfo 从 logLines _gameCrashLineNumber 开始到最后一行
|
||||
final crashInfo = logLines.sublist(_gameCrashLineNumber);
|
||||
// 运行一键诊断
|
||||
final info = SCLoggerHelper.getGameRunningLogInfo(crashInfo);
|
||||
crashInfo.add(S.current.log_analyzer_one_click_diagnosis_header);
|
||||
if (info != null) {
|
||||
crashInfo.add(info.key);
|
||||
if (info.value.isNotEmpty) {
|
||||
crashInfo.add(S.current.log_analyzer_details_info(info.value));
|
||||
}
|
||||
} else {
|
||||
crashInfo.add(S.current.log_analyzer_no_crash_detected);
|
||||
}
|
||||
_appendResult(LogAnalyzeLineData(
|
||||
type: "game_crash",
|
||||
title: S.current.log_analyzer_game_crash,
|
||||
data: crashInfo.join("\n"),
|
||||
dateTime: lastLineDateTime != null ? _dateTimeFormatter.format(lastLineDateTime) : null,
|
||||
));
|
||||
}
|
||||
|
||||
// ${S.current.log_analyzer_kill_summary}
|
||||
if (_killCount > 0 || _deathCount > 0) {
|
||||
_appendResult(LogAnalyzeLineData(
|
||||
type: "statistics",
|
||||
title: S.current.log_analyzer_kill_summary,
|
||||
data: S.current.log_analyzer_kill_death_suicide_count(
|
||||
_killCount,
|
||||
_deathCount,
|
||||
_selfKillCount,
|
||||
_vehicleDestructionCount,
|
||||
_vehicleDestructionCountHard,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
// 统计${S.current.log_analyzer_play_time},_gameStartTime 减去 最后一行的时间
|
||||
if (_gameStartTime != null) {
|
||||
if (lastLineDateTime != null) {
|
||||
final duration = lastLineDateTime.difference(_gameStartTime!);
|
||||
_appendResult(LogAnalyzeLineData(
|
||||
type: "statistics",
|
||||
title: S.current.log_analyzer_play_time,
|
||||
data: S.current.log_analyzer_play_time_format(
|
||||
duration.inHours,
|
||||
duration.inMinutes.remainder(60),
|
||||
duration.inSeconds.remainder(60),
|
||||
),
|
||||
));
|
||||
}
|
||||
// 逐条添加结果以支持流式显示
|
||||
for (final data in results) {
|
||||
_appendResult(data);
|
||||
await Future.delayed(Duration.zero); // 让 UI 有机会更新
|
||||
}
|
||||
|
||||
_startListenFile(logFile);
|
||||
@@ -165,21 +57,21 @@ class ToolsLogAnalyze extends _$ToolsLogAnalyze {
|
||||
debugPrint("[ToolsLogAnalyze] startListenFile: ${logFile.absolute.path}");
|
||||
// 监听文件
|
||||
late final StreamSubscription sub;
|
||||
sub = FileWatcher(logFile.absolute.path, pollingDelay: Duration(seconds: 1)).events.listen((change) {
|
||||
sub = FileWatcher(logFile.absolute.path, pollingDelay: const Duration(seconds: 1)).events.listen((change) {
|
||||
sub.cancel();
|
||||
if (!_isListenEnabled) return;
|
||||
_isListenEnabled = false;
|
||||
debugPrint("[ToolsLogAnalyze] logFile change: ${change.type}");
|
||||
switch (change.type) {
|
||||
case ChangeType.MODIFY:
|
||||
// 移除${S.current.log_analyzer_filter_statistics}
|
||||
// 移除统计信息
|
||||
final newList = state.value?.where((e) => e.type != "statistics").toList();
|
||||
if (listSortReverse) {
|
||||
state = AsyncData(newList?.reversed.toList() ?? []);
|
||||
} else {
|
||||
state = AsyncData(newList ?? []);
|
||||
}
|
||||
return _launchLogAnalyze(logFile, startLine: _currentLineNumber);
|
||||
return _launchLogAnalyze(logFile);
|
||||
case ChangeType.ADD:
|
||||
case ChangeType.REMOVE:
|
||||
ref.invalidateSelf();
|
||||
@@ -191,67 +83,6 @@ class ToolsLogAnalyze extends _$ToolsLogAnalyze {
|
||||
});
|
||||
}
|
||||
|
||||
LogAnalyzeLineData? _handleLogLine(String line, int index) {
|
||||
// 处理 log 行,检测可以提取的内容
|
||||
if (_gameStartTime == null) {
|
||||
_gameStartTime = _getLogLineDateTime(line);
|
||||
return LogAnalyzeLineData(
|
||||
type: "info",
|
||||
title: S.current.log_analyzer_game_start,
|
||||
dateTime: _getLogLineDateTimeString(line),
|
||||
);
|
||||
}
|
||||
// 读取${S.current.log_analyzer_game_loading}时间
|
||||
final gameLoading = _logGetGameLoading(line);
|
||||
if (gameLoading != null) {
|
||||
return LogAnalyzeLineData(
|
||||
type: "info",
|
||||
title: S.current.log_analyzer_game_loading,
|
||||
data: S.current.log_analyzer_mode_loading_time(
|
||||
gameLoading.$1,
|
||||
gameLoading.$2,
|
||||
),
|
||||
dateTime: _getLogLineDateTimeString(line),
|
||||
);
|
||||
}
|
||||
|
||||
// 运行基础时间解析器
|
||||
final baseEvent = _baseEventDecoder(line);
|
||||
if (baseEvent != null) {
|
||||
switch (baseEvent) {
|
||||
case "AccountLoginCharacterStatus_Character":
|
||||
// 角色登录
|
||||
return _logGetCharacterName(line);
|
||||
case "FatalCollision":
|
||||
// 载具${S.current.log_analyzer_filter_fatal_collision}
|
||||
return _logGetFatalCollision(line);
|
||||
case "Vehicle Destruction":
|
||||
// ${S.current.log_analyzer_filter_vehicle_damaged}
|
||||
return _logGetVehicleDestruction(line);
|
||||
case "Actor Death":
|
||||
// ${S.current.log_analyzer_filter_character_death}
|
||||
return _logGetActorDeath(line);
|
||||
case "RequestLocationInventory":
|
||||
// 请求${S.current.log_analyzer_filter_local_inventory}
|
||||
return _logGetRequestLocationInventory(line);
|
||||
}
|
||||
}
|
||||
|
||||
if (line.contains("[CIG] CCIGBroker::FastShutdown")) {
|
||||
return LogAnalyzeLineData(
|
||||
type: "info",
|
||||
title: S.current.log_analyzer_game_close,
|
||||
dateTime: _getLogLineDateTimeString(line),
|
||||
);
|
||||
}
|
||||
|
||||
if (line.contains("Cloud Imperium Games public crash handler")) {
|
||||
_gameCrashLineNumber = index;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void _appendResult(LogAnalyzeLineData data) {
|
||||
// 追加结果到 state
|
||||
final currentState = state.value;
|
||||
@@ -266,195 +97,4 @@ class ToolsLogAnalyze extends _$ToolsLogAnalyze {
|
||||
state = AsyncData([data]);
|
||||
}
|
||||
}
|
||||
|
||||
final _baseRegExp = RegExp(r'\[Notice\]\s+<([^>]+)>');
|
||||
|
||||
String? _baseEventDecoder(String line) {
|
||||
// 解析 log 行的基本信息
|
||||
final match = _baseRegExp.firstMatch(line);
|
||||
if (match != null) {
|
||||
final type = match.group(1);
|
||||
return type;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
final _gameLoadingRegExp =
|
||||
RegExp(r'<[^>]+>\s+Loading screen for\s+(\w+)\s+:\s+SC_Frontend closed after\s+(\d+\.\d+)\s+seconds');
|
||||
|
||||
(String, String)? _logGetGameLoading(String line) {
|
||||
final match = _gameLoadingRegExp.firstMatch(line);
|
||||
if (match != null) {
|
||||
return (match.group(1) ?? "-", match.group(2) ?? "-");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
final DateFormat _dateTimeFormatter = DateFormat('yyyy-MM-dd HH:mm:ss:SSS');
|
||||
final _logDateTimeRegExp = RegExp(r'<(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z)>');
|
||||
|
||||
DateTime? _getLogLineDateTime(String line) {
|
||||
// 提取 log 行的时间
|
||||
final match = _logDateTimeRegExp.firstMatch(line);
|
||||
if (match != null) {
|
||||
final dateTimeString = match.group(1);
|
||||
if (dateTimeString != null) {
|
||||
return DateTime.parse(dateTimeString).toLocal();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String? _getLogLineDateTimeString(String line) {
|
||||
// 提取 log 行的时间
|
||||
final dateTime = _getLogLineDateTime(line);
|
||||
if (dateTime != null) {
|
||||
return _dateTimeFormatter.format(dateTime);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 安全提取函数
|
||||
String? safeExtract(RegExp pattern, String line) => pattern.firstMatch(line)?.group(1)?.trim();
|
||||
|
||||
LogAnalyzeLineData? _logGetFatalCollision(String line) {
|
||||
final patterns = {
|
||||
'zone': RegExp(r'\[Part:[^\]]*?Zone:\s*([^,\]]+)'),
|
||||
'player_pilot': RegExp(r'PlayerPilot:\s*(\d)'),
|
||||
'hit_entity': RegExp(r'hitting entity:\s*(\w+)'),
|
||||
'hit_entity_vehicle': RegExp(r'hitting entity:[^\[]*\[Zone:\s*([^\s-]+)'),
|
||||
'distance': RegExp(r'Distance:\s*([\d.]+)')
|
||||
};
|
||||
|
||||
final zone = safeExtract(patterns['zone']!, line) ?? unknownValue;
|
||||
final playerPilot = (safeExtract(patterns['player_pilot']!, line) ?? '0') == '1';
|
||||
final hitEntity = safeExtract(patterns['hit_entity']!, line) ?? unknownValue;
|
||||
final hitEntityVehicle = safeExtract(patterns['hit_entity_vehicle']!, line) ?? unknownValue;
|
||||
final distance = double.tryParse(safeExtract(patterns['distance']!, line) ?? '') ?? 0.0;
|
||||
return LogAnalyzeLineData(
|
||||
type: "fatal_collision",
|
||||
title: S.current.log_analyzer_filter_fatal_collision,
|
||||
data: S.current.log_analyzer_collision_details(
|
||||
zone,
|
||||
playerPilot ? '✅' : '❌',
|
||||
hitEntity,
|
||||
hitEntityVehicle,
|
||||
distance.toStringAsFixed(2),
|
||||
),
|
||||
dateTime: _getLogLineDateTimeString(line),
|
||||
);
|
||||
}
|
||||
|
||||
LogAnalyzeLineData? _logGetVehicleDestruction(String line) {
|
||||
final pattern = RegExp(r"Vehicle\s+'([^']+)'.*?" // 载具型号
|
||||
r"in zone\s+'([^']+)'.*?" // Zone
|
||||
r"destroy level \d+ to (\d+).*?" // 损毁等级
|
||||
r"caused by\s+'([^']+)'" // 责任方
|
||||
);
|
||||
final match = pattern.firstMatch(line);
|
||||
if (match != null) {
|
||||
final vehicleModel = match.group(1) ?? unknownValue;
|
||||
final zone = match.group(2) ?? unknownValue;
|
||||
final destructionLevel = int.tryParse(match.group(3) ?? '') ?? 0;
|
||||
final causedBy = match.group(4) ?? unknownValue;
|
||||
|
||||
final destructionLevelMap = {1: S.current.log_analyzer_soft_death, 2: S.current.log_analyzer_disintegration};
|
||||
|
||||
if (causedBy.trim() == _playerName) {
|
||||
if (destructionLevel == 1) {
|
||||
_vehicleDestructionCount++;
|
||||
} else if (destructionLevel == 2) {
|
||||
_vehicleDestructionCountHard++;
|
||||
}
|
||||
}
|
||||
|
||||
return LogAnalyzeLineData(
|
||||
type: "vehicle_destruction",
|
||||
title: S.current.log_analyzer_filter_vehicle_damaged,
|
||||
data: S.current.log_analyzer_vehicle_damage_details(
|
||||
vehicleModel,
|
||||
zone,
|
||||
destructionLevel.toString(),
|
||||
destructionLevelMap[destructionLevel] ?? unknownValue,
|
||||
causedBy,
|
||||
),
|
||||
dateTime: _getLogLineDateTimeString(line),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
LogAnalyzeLineData? _logGetActorDeath(String line) {
|
||||
final pattern = RegExp(r"CActor::Kill: '([^']+)'.*?" // 受害者ID
|
||||
r"in zone '([^']+)'.*?" // 死亡位置区域
|
||||
r"killed by '([^']+)'.*?" // 击杀者ID
|
||||
r"with damage type '([^']+)'" // 伤害类型
|
||||
);
|
||||
|
||||
final match = pattern.firstMatch(line);
|
||||
if (match != null) {
|
||||
final victimId = match.group(1) ?? unknownValue;
|
||||
final zone = match.group(2) ?? unknownValue;
|
||||
final killerId = match.group(3) ?? unknownValue;
|
||||
final damageType = match.group(4) ?? unknownValue;
|
||||
|
||||
if (victimId.trim() == killerId.trim()) {
|
||||
// 自杀
|
||||
_selfKillCount++;
|
||||
} else {
|
||||
if (victimId.trim() == _playerName) {
|
||||
_deathCount++;
|
||||
}
|
||||
if (killerId.trim() == _playerName) {
|
||||
_killCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return LogAnalyzeLineData(
|
||||
type: "actor_death",
|
||||
title: S.current.log_analyzer_filter_character_death,
|
||||
data: S.current.log_analyzer_death_details(
|
||||
victimId,
|
||||
damageType,
|
||||
killerId,
|
||||
zone,
|
||||
),
|
||||
dateTime: _getLogLineDateTimeString(line),
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
LogAnalyzeLineData? _logGetCharacterName(String line) {
|
||||
final pattern = RegExp(r"name\s+([^-]+)");
|
||||
final match = pattern.firstMatch(line);
|
||||
if (match != null) {
|
||||
final characterName = match.group(1)?.trim() ?? unknownValue;
|
||||
_playerName = characterName.trim(); // 更新玩家名称
|
||||
return LogAnalyzeLineData(
|
||||
type: "player_login",
|
||||
title: S.current.log_analyzer_player_login(characterName),
|
||||
dateTime: _getLogLineDateTimeString(line),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
LogAnalyzeLineData? _logGetRequestLocationInventory(String line) {
|
||||
final pattern = RegExp(r"Player\[([^\]]+)\].*?Location\[([^\]]+)\]");
|
||||
final match = pattern.firstMatch(line);
|
||||
if (match != null) {
|
||||
final playerId = match.group(1) ?? unknownValue;
|
||||
final location = match.group(2) ?? unknownValue;
|
||||
|
||||
return LogAnalyzeLineData(
|
||||
type: "request_location_inventory",
|
||||
title: S.current.log_analyzer_view_local_inventory,
|
||||
data: S.current.log_analyzer_player_location(playerId, location),
|
||||
dateTime: _getLogLineDateTimeString(line),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,280 +0,0 @@
|
||||
// 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 'log_analyze_provider.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$LogAnalyzeLineData {
|
||||
|
||||
String get type; String get title; String? get data; String? get dateTime;
|
||||
/// Create a copy of LogAnalyzeLineData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$LogAnalyzeLineDataCopyWith<LogAnalyzeLineData> get copyWith => _$LogAnalyzeLineDataCopyWithImpl<LogAnalyzeLineData>(this as LogAnalyzeLineData, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is LogAnalyzeLineData&&(identical(other.type, type) || other.type == type)&&(identical(other.title, title) || other.title == title)&&(identical(other.data, data) || other.data == data)&&(identical(other.dateTime, dateTime) || other.dateTime == dateTime));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,type,title,data,dateTime);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LogAnalyzeLineData(type: $type, title: $title, data: $data, dateTime: $dateTime)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $LogAnalyzeLineDataCopyWith<$Res> {
|
||||
factory $LogAnalyzeLineDataCopyWith(LogAnalyzeLineData value, $Res Function(LogAnalyzeLineData) _then) = _$LogAnalyzeLineDataCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String type, String title, String? data, String? dateTime
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$LogAnalyzeLineDataCopyWithImpl<$Res>
|
||||
implements $LogAnalyzeLineDataCopyWith<$Res> {
|
||||
_$LogAnalyzeLineDataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final LogAnalyzeLineData _self;
|
||||
final $Res Function(LogAnalyzeLineData) _then;
|
||||
|
||||
/// Create a copy of LogAnalyzeLineData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? type = null,Object? title = null,Object? data = freezed,Object? dateTime = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
||||
as String?,dateTime: freezed == dateTime ? _self.dateTime : dateTime // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [LogAnalyzeLineData].
|
||||
extension LogAnalyzeLineDataPatterns on LogAnalyzeLineData {
|
||||
/// 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( _LogAnalyzeLineData value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _LogAnalyzeLineData() 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( _LogAnalyzeLineData value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _LogAnalyzeLineData():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// 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( _LogAnalyzeLineData value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _LogAnalyzeLineData() 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 type, String title, String? data, String? dateTime)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _LogAnalyzeLineData() when $default != null:
|
||||
return $default(_that.type,_that.title,_that.data,_that.dateTime);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 type, String title, String? data, String? dateTime) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _LogAnalyzeLineData():
|
||||
return $default(_that.type,_that.title,_that.data,_that.dateTime);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// 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 type, String title, String? data, String? dateTime)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _LogAnalyzeLineData() when $default != null:
|
||||
return $default(_that.type,_that.title,_that.data,_that.dateTime);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _LogAnalyzeLineData implements LogAnalyzeLineData {
|
||||
const _LogAnalyzeLineData({required this.type, required this.title, this.data, this.dateTime});
|
||||
|
||||
|
||||
@override final String type;
|
||||
@override final String title;
|
||||
@override final String? data;
|
||||
@override final String? dateTime;
|
||||
|
||||
/// Create a copy of LogAnalyzeLineData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$LogAnalyzeLineDataCopyWith<_LogAnalyzeLineData> get copyWith => __$LogAnalyzeLineDataCopyWithImpl<_LogAnalyzeLineData>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _LogAnalyzeLineData&&(identical(other.type, type) || other.type == type)&&(identical(other.title, title) || other.title == title)&&(identical(other.data, data) || other.data == data)&&(identical(other.dateTime, dateTime) || other.dateTime == dateTime));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,type,title,data,dateTime);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LogAnalyzeLineData(type: $type, title: $title, data: $data, dateTime: $dateTime)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$LogAnalyzeLineDataCopyWith<$Res> implements $LogAnalyzeLineDataCopyWith<$Res> {
|
||||
factory _$LogAnalyzeLineDataCopyWith(_LogAnalyzeLineData value, $Res Function(_LogAnalyzeLineData) _then) = __$LogAnalyzeLineDataCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String type, String title, String? data, String? dateTime
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$LogAnalyzeLineDataCopyWithImpl<$Res>
|
||||
implements _$LogAnalyzeLineDataCopyWith<$Res> {
|
||||
__$LogAnalyzeLineDataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _LogAnalyzeLineData _self;
|
||||
final $Res Function(_LogAnalyzeLineData) _then;
|
||||
|
||||
/// Create a copy of LogAnalyzeLineData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? type = null,Object? title = null,Object? data = freezed,Object? dateTime = freezed,}) {
|
||||
return _then(_LogAnalyzeLineData(
|
||||
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
||||
as String?,dateTime: freezed == dateTime ? _self.dateTime : dateTime // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -50,7 +50,7 @@ final class ToolsLogAnalyzeProvider
|
||||
}
|
||||
}
|
||||
|
||||
String _$toolsLogAnalyzeHash() => r'5666c3f882e22e2192593629164bc53f8ce4aabe';
|
||||
String _$toolsLogAnalyzeHash() => r'f5079c7d35daf25b07f83bacb224484171e9c93f';
|
||||
|
||||
final class ToolsLogAnalyzeFamily extends $Family
|
||||
with
|
||||
|
||||
Reference in New Issue
Block a user