mirror of
https://github.com/StarCitizenToolBox/app.git
synced 2026-01-13 19:50:28 +00:00
feat: PartyRoomGameLogTrackerProvider
This commit is contained in:
parent
f551ccfbde
commit
3e9f82ecdf
@ -15,8 +15,8 @@ class LogAnalyzeLineData {
|
|||||||
|
|
||||||
// 格式化后的字段
|
// 格式化后的字段
|
||||||
final String? victimId; // 受害者ID (actor_death)
|
final String? victimId; // 受害者ID (actor_death)
|
||||||
final String? killerId; // 击杀者ID (actor_death)
|
|
||||||
final String? location; // 位置信息 (request_location_inventory)
|
final String? location; // 位置信息 (request_location_inventory)
|
||||||
|
final String? area; // 区域信息
|
||||||
final String? playerName; // 玩家名称 (player_login)
|
final String? playerName; // 玩家名称 (player_login)
|
||||||
|
|
||||||
const LogAnalyzeLineData({
|
const LogAnalyzeLineData({
|
||||||
@ -26,8 +26,8 @@ class LogAnalyzeLineData {
|
|||||||
this.dateTime,
|
this.dateTime,
|
||||||
this.tag,
|
this.tag,
|
||||||
this.victimId,
|
this.victimId,
|
||||||
this.killerId,
|
|
||||||
this.location,
|
this.location,
|
||||||
|
this.area,
|
||||||
this.playerName,
|
this.playerName,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -76,10 +76,10 @@ class GameLogAnalyzer {
|
|||||||
|
|
||||||
// 致命碰撞解析
|
// 致命碰撞解析
|
||||||
static final _fatalCollisionPatterns = {
|
static final _fatalCollisionPatterns = {
|
||||||
'zone': RegExp(r'\[Part:[^\]]*?Zone:\s*([^,\]]+)'),
|
'vehicle': RegExp(r'Fatal Collision occured for vehicle\s+(\S+)'),
|
||||||
|
'zone': RegExp(r'Zone:\s*([^,\]]+)'),
|
||||||
'player_pilot': RegExp(r'PlayerPilot:\s*(\d)'),
|
'player_pilot': RegExp(r'PlayerPilot:\s*(\d)'),
|
||||||
'hit_entity': RegExp(r'hitting entity:\s*(\w+)'),
|
'hit_entity': RegExp(r'hitting entity:\s*(\w+)'),
|
||||||
'hit_entity_vehicle': RegExp(r'hitting entity:[^\[]*\[Zone:\s*([^\s-]+)'),
|
|
||||||
'distance': RegExp(r'Distance:\s*([\d.]+)'),
|
'distance': RegExp(r'Distance:\s*([\d.]+)'),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,10 +93,9 @@ class GameLogAnalyzer {
|
|||||||
|
|
||||||
// 角色死亡解析
|
// 角色死亡解析
|
||||||
static final _actorDeathPattern = RegExp(
|
static final _actorDeathPattern = RegExp(
|
||||||
r"CActor::Kill: '([^']+)'.*?" // 受害者ID
|
r"Actor '([^']+)'.*?" // 受害者ID
|
||||||
r"in zone '([^']+)'.*?" // 死亡位置区域
|
r"ejected from zone '([^']+)'.*?" // 原载具/区域
|
||||||
r"killed by '([^']+)'.*?" // 击杀者ID
|
r"to zone '([^']+)'", // 目标区域
|
||||||
r"with damage type '([^']+)'", // 伤害类型
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 角色名称解析
|
// 角色名称解析
|
||||||
@ -217,7 +216,7 @@ class GameLogAnalyzer {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "Actor Death":
|
case "[ActorState] Dead":
|
||||||
data = _parseActorDeath(line, playerName, shouldCount, (isKill, isDeath, isSelfKill) {
|
data = _parseActorDeath(line, playerName, shouldCount, (isKill, isDeath, isSelfKill) {
|
||||||
if (isSelfKill) {
|
if (isSelfKill) {
|
||||||
selfKillCount++;
|
selfKillCount++;
|
||||||
@ -372,10 +371,10 @@ class GameLogAnalyzer {
|
|||||||
static String? _safeExtract(RegExp pattern, String line) => pattern.firstMatch(line)?.group(1)?.trim();
|
static String? _safeExtract(RegExp pattern, String line) => pattern.firstMatch(line)?.group(1)?.trim();
|
||||||
|
|
||||||
static LogAnalyzeLineData? _parseFatalCollision(String line) {
|
static LogAnalyzeLineData? _parseFatalCollision(String line) {
|
||||||
|
final vehicle = _safeExtract(_fatalCollisionPatterns['vehicle']!, line) ?? unknownValue;
|
||||||
final zone = _safeExtract(_fatalCollisionPatterns['zone']!, line) ?? unknownValue;
|
final zone = _safeExtract(_fatalCollisionPatterns['zone']!, line) ?? unknownValue;
|
||||||
final playerPilot = (_safeExtract(_fatalCollisionPatterns['player_pilot']!, line) ?? '0') == '1';
|
final playerPilot = (_safeExtract(_fatalCollisionPatterns['player_pilot']!, line) ?? '0') == '1';
|
||||||
final hitEntity = _safeExtract(_fatalCollisionPatterns['hit_entity']!, line) ?? unknownValue;
|
final hitEntity = _safeExtract(_fatalCollisionPatterns['hit_entity']!, line) ?? unknownValue;
|
||||||
final hitEntityVehicle = _safeExtract(_fatalCollisionPatterns['hit_entity_vehicle']!, line) ?? unknownValue;
|
|
||||||
final distance = double.tryParse(_safeExtract(_fatalCollisionPatterns['distance']!, line) ?? '') ?? 0.0;
|
final distance = double.tryParse(_safeExtract(_fatalCollisionPatterns['distance']!, line) ?? '') ?? 0.0;
|
||||||
|
|
||||||
return LogAnalyzeLineData(
|
return LogAnalyzeLineData(
|
||||||
@ -385,7 +384,7 @@ class GameLogAnalyzer {
|
|||||||
zone,
|
zone,
|
||||||
playerPilot ? '✅' : '❌',
|
playerPilot ? '✅' : '❌',
|
||||||
hitEntity,
|
hitEntity,
|
||||||
hitEntityVehicle,
|
vehicle,
|
||||||
distance.toStringAsFixed(2),
|
distance.toStringAsFixed(2),
|
||||||
),
|
),
|
||||||
dateTime: _getLogLineDateTimeString(line),
|
dateTime: _getLogLineDateTimeString(line),
|
||||||
@ -436,27 +435,25 @@ class GameLogAnalyzer {
|
|||||||
final match = _actorDeathPattern.firstMatch(line);
|
final match = _actorDeathPattern.firstMatch(line);
|
||||||
if (match != null) {
|
if (match != null) {
|
||||||
final victimId = match.group(1) ?? unknownValue;
|
final victimId = match.group(1) ?? unknownValue;
|
||||||
final zone = match.group(2) ?? unknownValue;
|
final fromZone = match.group(2) ?? unknownValue;
|
||||||
final killerId = match.group(3) ?? unknownValue;
|
final toZone = match.group(3) ?? unknownValue;
|
||||||
final damageType = match.group(4) ?? unknownValue;
|
|
||||||
|
|
||||||
if (shouldCount) {
|
if (shouldCount) {
|
||||||
if (victimId.trim() == killerId.trim()) {
|
final isDeath = victimId.trim() == playerName;
|
||||||
onDeath(false, false, true); // 自杀
|
if (isDeath) {
|
||||||
} else {
|
onDeath(false, true, false);
|
||||||
final isDeath = victimId.trim() == playerName;
|
|
||||||
final isKill = killerId.trim() == playerName;
|
|
||||||
onDeath(isKill, isDeath, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return LogAnalyzeLineData(
|
return LogAnalyzeLineData(
|
||||||
type: "actor_death",
|
type: "actor_death",
|
||||||
title: S.current.log_analyzer_filter_character_death,
|
title: S.current.log_analyzer_filter_character_death,
|
||||||
data: S.current.log_analyzer_death_details(victimId, damageType, killerId, zone),
|
data: S.current.log_analyzer_death_details(victimId, fromZone, toZone),
|
||||||
dateTime: _getLogLineDateTimeString(line),
|
dateTime: _getLogLineDateTimeString(line),
|
||||||
victimId: victimId, // 格式化字段
|
location: fromZone,
|
||||||
killerId: killerId, // 格式化字段
|
area: toZone,
|
||||||
|
victimId: victimId,
|
||||||
|
playerName: playerName,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -130,8 +130,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
static String m46(v0, v1, v2, v3, v4) =>
|
static String m46(v0, v1, v2, v3, v4) =>
|
||||||
"Area: ${v0} Player driving: ${v1} Collision entity: ${v2} \nCollision vehicle: ${v3} Collision distance: ${v4} ";
|
"Area: ${v0} Player driving: ${v1} Collision entity: ${v2} \nCollision vehicle: ${v3} Collision distance: ${v4} ";
|
||||||
|
|
||||||
static String m47(v0, v1, v2, v3) =>
|
static String m47(v0, v2, v3) =>
|
||||||
"Victim ID: ${v0} Cause of death: ${v1} \nKiller ID: ${v2} \nArea: ${v3}";
|
"Victim ID: ${v0} \nLocation: ${v2} \nArea: ${v3}";
|
||||||
|
|
||||||
static String m48(v0) => "Detailed information: ${v0}";
|
static String m48(v0) => "Detailed information: ${v0}";
|
||||||
|
|
||||||
|
|||||||
@ -119,8 +119,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
static String m46(v0, v1, v2, v3, v4) =>
|
static String m46(v0, v1, v2, v3, v4) =>
|
||||||
"エリア:${v0} プレイヤー操縦:${v1} 衝突エンティティ:${v2} \n衝突ビークル:${v3} 衝突距離:${v4} ";
|
"エリア:${v0} プレイヤー操縦:${v1} 衝突エンティティ:${v2} \n衝突ビークル:${v3} 衝突距離:${v4} ";
|
||||||
|
|
||||||
static String m47(v0, v1, v2, v3) =>
|
static String m47(v0, v2, v3) => "被害者ID:${v0} \n位置:${v2} \nエリア:${v3}";
|
||||||
"被害者ID:${v0} 死因:${v1} \n殺害者ID:${v2} \nエリア:${v3}";
|
|
||||||
|
|
||||||
static String m48(v0) => "詳細情報:${v0}";
|
static String m48(v0) => "詳細情報:${v0}";
|
||||||
|
|
||||||
|
|||||||
@ -124,8 +124,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
static String m46(v0, v1, v2, v3, v4) =>
|
static String m46(v0, v1, v2, v3, v4) =>
|
||||||
"Зона: ${v0} Управление игроком: ${v1} Объект столкновения: ${v2} \nТехника столкновения: ${v3} Дистанция столкновения: ${v4} ";
|
"Зона: ${v0} Управление игроком: ${v1} Объект столкновения: ${v2} \nТехника столкновения: ${v3} Дистанция столкновения: ${v4} ";
|
||||||
|
|
||||||
static String m47(v0, v1, v2, v3) =>
|
static String m47(v0, v2, v3) =>
|
||||||
"ID жертвы: ${v0} Причина смерти: ${v1} \nID убийцы: ${v2} \nЗона: ${v3}";
|
"ID жертвы: ${v0} \nID убийцы: ${v2} \nЗона: ${v3}";
|
||||||
|
|
||||||
static String m48(v0) => "Подробная информация: ${v0}";
|
static String m48(v0) => "Подробная информация: ${v0}";
|
||||||
|
|
||||||
|
|||||||
@ -119,8 +119,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
static String m46(v0, v1, v2, v3, v4) =>
|
static String m46(v0, v1, v2, v3, v4) =>
|
||||||
"区域:${v0} 玩家驾驶:${v1} 碰撞实体:${v2} \n碰撞载具: ${v3} 碰撞距离:${v4} ";
|
"区域:${v0} 玩家驾驶:${v1} 碰撞实体:${v2} \n碰撞载具: ${v3} 碰撞距离:${v4} ";
|
||||||
|
|
||||||
static String m47(v0, v1, v2, v3) =>
|
static String m47(v0, v2, v3) => "受害者ID:${v0} \n位置:${v2} \n区域:${v3}";
|
||||||
"受害者ID:${v0} 死因:${v1} \n击杀者ID:${v2} \n区域:${v3}";
|
|
||||||
|
|
||||||
static String m48(v0) => "详细信息:${v0}";
|
static String m48(v0) => "详细信息:${v0}";
|
||||||
|
|
||||||
@ -1406,7 +1405,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"tools_rsi_launcher_enhance_init_msg2":
|
"tools_rsi_launcher_enhance_init_msg2":
|
||||||
MessageLookupByLibrary.simpleMessage("正在从网络获取增强数据..."),
|
MessageLookupByLibrary.simpleMessage("正在从网络获取增强数据..."),
|
||||||
"tools_rsi_launcher_enhance_msg_error":
|
"tools_rsi_launcher_enhance_msg_error":
|
||||||
MessageLookupByLibrary.simpleMessage("获取增强数据失败,可能是网络问题或当前版本不支持"),
|
MessageLookupByLibrary.simpleMessage("当前版本暂不支持,請等待適配..."),
|
||||||
"tools_rsi_launcher_enhance_msg_error_get_launcher_info_error":
|
"tools_rsi_launcher_enhance_msg_error_get_launcher_info_error":
|
||||||
MessageLookupByLibrary.simpleMessage("读取启动器信息失败!"),
|
MessageLookupByLibrary.simpleMessage("读取启动器信息失败!"),
|
||||||
"tools_rsi_launcher_enhance_msg_error_get_launcher_info_error_with_args":
|
"tools_rsi_launcher_enhance_msg_error_get_launcher_info_error_with_args":
|
||||||
|
|||||||
@ -115,8 +115,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
static String m46(v0, v1, v2, v3, v4) =>
|
static String m46(v0, v1, v2, v3, v4) =>
|
||||||
"區域:${v0} 玩家駕駛:${v1} 碰撞實體:${v2} \n碰撞載具: ${v3} 碰撞距離:${v4} ";
|
"區域:${v0} 玩家駕駛:${v1} 碰撞實體:${v2} \n碰撞載具: ${v3} 碰撞距離:${v4} ";
|
||||||
|
|
||||||
static String m47(v0, v1, v2, v3) =>
|
static String m47(v0, v2, v3) => "受害者ID:${v0} \n位置:${v2} \n區域:${v3}";
|
||||||
"受害者ID:${v0} 死因:${v1} \n擊殺者ID:${v2} \n區域:${v3}";
|
|
||||||
|
|
||||||
static String m48(v0) => "詳細資訊:${v0}";
|
static String m48(v0) => "詳細資訊:${v0}";
|
||||||
|
|
||||||
@ -1397,7 +1396,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"tools_rsi_launcher_enhance_init_msg2":
|
"tools_rsi_launcher_enhance_init_msg2":
|
||||||
MessageLookupByLibrary.simpleMessage("正在從網路取得增強資料..."),
|
MessageLookupByLibrary.simpleMessage("正在從網路取得增強資料..."),
|
||||||
"tools_rsi_launcher_enhance_msg_error":
|
"tools_rsi_launcher_enhance_msg_error":
|
||||||
MessageLookupByLibrary.simpleMessage("增強資料取得失敗,可能是網路問題或目前版本不支援"),
|
MessageLookupByLibrary.simpleMessage("目前版本不支援"),
|
||||||
"tools_rsi_launcher_enhance_msg_error_get_launcher_info_error":
|
"tools_rsi_launcher_enhance_msg_error_get_launcher_info_error":
|
||||||
MessageLookupByLibrary.simpleMessage("讀取啟動器資訊失敗!"),
|
MessageLookupByLibrary.simpleMessage("讀取啟動器資訊失敗!"),
|
||||||
"tools_rsi_launcher_enhance_msg_error_get_launcher_info_error_with_args":
|
"tools_rsi_launcher_enhance_msg_error_get_launcher_info_error_with_args":
|
||||||
|
|||||||
@ -5808,18 +5808,13 @@ class S {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `Victim ID: {v0} Cause of death: {v1} \nKiller ID: {v2} \nArea: {v3}`
|
/// `Victim ID: {v0} \nLocation: {v2} \nArea: {v3}`
|
||||||
String log_analyzer_death_details(
|
String log_analyzer_death_details(Object v0, Object v2, Object v3) {
|
||||||
Object v0,
|
|
||||||
Object v1,
|
|
||||||
Object v2,
|
|
||||||
Object v3,
|
|
||||||
) {
|
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
'Victim ID: $v0 Cause of death: $v1 \nKiller ID: $v2 \nArea: $v3',
|
'Victim ID: $v0 \nLocation: $v2 \nArea: $v3',
|
||||||
name: 'log_analyzer_death_details',
|
name: 'log_analyzer_death_details',
|
||||||
desc: '',
|
desc: '',
|
||||||
args: [v0, v1, v2, v3],
|
args: [v0, v2, v3],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1141,7 +1141,7 @@
|
|||||||
"@log_analyzer_disintegration": {},
|
"@log_analyzer_disintegration": {},
|
||||||
"log_analyzer_vehicle_damage_details": "Vehicle model: {v0} \nArea: {v1} \nDamage level: {v2} ({v3}) Responsible party: {v4}",
|
"log_analyzer_vehicle_damage_details": "Vehicle model: {v0} \nArea: {v1} \nDamage level: {v2} ({v3}) Responsible party: {v4}",
|
||||||
"@log_analyzer_vehicle_damage_details": {},
|
"@log_analyzer_vehicle_damage_details": {},
|
||||||
"log_analyzer_death_details": "Victim ID: {v0} Cause of death: {v1} \nKiller ID: {v2} \nArea: {v3}",
|
"log_analyzer_death_details": "Victim ID: {v0} \nLocation: {v2} \nArea: {v3}",
|
||||||
"@log_analyzer_death_details": {},
|
"@log_analyzer_death_details": {},
|
||||||
"log_analyzer_player_login": "Player {v0} logged in...",
|
"log_analyzer_player_login": "Player {v0} logged in...",
|
||||||
"@log_analyzer_player_login": {},
|
"@log_analyzer_player_login": {},
|
||||||
|
|||||||
@ -1139,7 +1139,7 @@
|
|||||||
"@log_analyzer_disintegration": {},
|
"@log_analyzer_disintegration": {},
|
||||||
"log_analyzer_vehicle_damage_details": "ビークルモデル:{v0} \nエリア:{v1} \n損傷レベル:{v2} ({v3}) 責任者:{v4}",
|
"log_analyzer_vehicle_damage_details": "ビークルモデル:{v0} \nエリア:{v1} \n損傷レベル:{v2} ({v3}) 責任者:{v4}",
|
||||||
"@log_analyzer_vehicle_damage_details": {},
|
"@log_analyzer_vehicle_damage_details": {},
|
||||||
"log_analyzer_death_details": "被害者ID:{v0} 死因:{v1} \n殺害者ID:{v2} \nエリア:{v3}",
|
"log_analyzer_death_details": "被害者ID:{v0} \n位置:{v2} \nエリア:{v3}",
|
||||||
"@log_analyzer_death_details": {},
|
"@log_analyzer_death_details": {},
|
||||||
"log_analyzer_player_login": "プレイヤー {v0} ログイン中...",
|
"log_analyzer_player_login": "プレイヤー {v0} ログイン中...",
|
||||||
"@log_analyzer_player_login": {},
|
"@log_analyzer_player_login": {},
|
||||||
|
|||||||
@ -1139,7 +1139,7 @@
|
|||||||
"@log_analyzer_disintegration": {},
|
"@log_analyzer_disintegration": {},
|
||||||
"log_analyzer_vehicle_damage_details": "Модель техники: {v0} \nЗона: {v1} \nУровень повреждения: {v2} ({v3}) Виновник: {v4}",
|
"log_analyzer_vehicle_damage_details": "Модель техники: {v0} \nЗона: {v1} \nУровень повреждения: {v2} ({v3}) Виновник: {v4}",
|
||||||
"@log_analyzer_vehicle_damage_details": {},
|
"@log_analyzer_vehicle_damage_details": {},
|
||||||
"log_analyzer_death_details": "ID жертвы: {v0} Причина смерти: {v1} \nID убийцы: {v2} \nЗона: {v3}",
|
"log_analyzer_death_details": "ID жертвы: {v0} \nID убийцы: {v2} \nЗона: {v3}",
|
||||||
"@log_analyzer_death_details": {},
|
"@log_analyzer_death_details": {},
|
||||||
"log_analyzer_player_login": "Игрок {v0} входит в игру...",
|
"log_analyzer_player_login": "Игрок {v0} входит в игру...",
|
||||||
"@log_analyzer_player_login": {},
|
"@log_analyzer_player_login": {},
|
||||||
|
|||||||
@ -772,7 +772,7 @@
|
|||||||
"tools_rsi_launcher_enhance_title": "RSI 启动器增强",
|
"tools_rsi_launcher_enhance_title": "RSI 启动器增强",
|
||||||
"tools_rsi_launcher_enhance_msg_version": "启动器内部版本信息:{v0}",
|
"tools_rsi_launcher_enhance_msg_version": "启动器内部版本信息:{v0}",
|
||||||
"tools_rsi_launcher_enhance_msg_patch_status": "补丁状态:{v0}",
|
"tools_rsi_launcher_enhance_msg_patch_status": "补丁状态:{v0}",
|
||||||
"tools_rsi_launcher_enhance_msg_error": "获取增强数据失败,可能是网络问题或当前版本不支持",
|
"tools_rsi_launcher_enhance_msg_error": "当前版本暂不支持,請等待適配...",
|
||||||
"tools_rsi_launcher_enhance_title_localization": "RSI 启动器本地化",
|
"tools_rsi_launcher_enhance_title_localization": "RSI 启动器本地化",
|
||||||
"tools_rsi_launcher_enhance_subtitle_localization": "为 RSI 启动器增加多语言支持。",
|
"tools_rsi_launcher_enhance_subtitle_localization": "为 RSI 启动器增加多语言支持。",
|
||||||
"tools_rsi_launcher_enhance_title_download_booster": "RSI 启动器下载增强",
|
"tools_rsi_launcher_enhance_title_download_booster": "RSI 启动器下载增强",
|
||||||
@ -890,7 +890,7 @@
|
|||||||
"log_analyzer_soft_death": "软死亡",
|
"log_analyzer_soft_death": "软死亡",
|
||||||
"log_analyzer_disintegration": "解体",
|
"log_analyzer_disintegration": "解体",
|
||||||
"log_analyzer_vehicle_damage_details": "载具型号:{v0} \n区域:{v1} \n损毁等级:{v2} ({v3}) 责任方:{v4}",
|
"log_analyzer_vehicle_damage_details": "载具型号:{v0} \n区域:{v1} \n损毁等级:{v2} ({v3}) 责任方:{v4}",
|
||||||
"log_analyzer_death_details": "受害者ID:{v0} 死因:{v1} \n击杀者ID:{v2} \n区域:{v3}",
|
"log_analyzer_death_details": "受害者ID:{v0} \n位置:{v2} \n区域:{v3}",
|
||||||
"log_analyzer_player_login": "玩家 {v0} 登录 ...",
|
"log_analyzer_player_login": "玩家 {v0} 登录 ...",
|
||||||
"log_analyzer_view_local_inventory": "查看本地库存",
|
"log_analyzer_view_local_inventory": "查看本地库存",
|
||||||
"log_analyzer_player_location": "玩家ID:{v0} 位置:{v1}",
|
"log_analyzer_player_location": "玩家ID:{v0} 位置:{v1}",
|
||||||
|
|||||||
@ -907,7 +907,7 @@
|
|||||||
"@tools_rsi_launcher_enhance_msg_version": {},
|
"@tools_rsi_launcher_enhance_msg_version": {},
|
||||||
"tools_rsi_launcher_enhance_msg_patch_status": "補丁狀態:{v0}",
|
"tools_rsi_launcher_enhance_msg_patch_status": "補丁狀態:{v0}",
|
||||||
"@tools_rsi_launcher_enhance_msg_patch_status": {},
|
"@tools_rsi_launcher_enhance_msg_patch_status": {},
|
||||||
"tools_rsi_launcher_enhance_msg_error": "增強資料取得失敗,可能是網路問題或目前版本不支援",
|
"tools_rsi_launcher_enhance_msg_error": "目前版本不支援",
|
||||||
"@tools_rsi_launcher_enhance_msg_error": {},
|
"@tools_rsi_launcher_enhance_msg_error": {},
|
||||||
"tools_rsi_launcher_enhance_title_localization": "RSI 啟動器本地化",
|
"tools_rsi_launcher_enhance_title_localization": "RSI 啟動器本地化",
|
||||||
"@tools_rsi_launcher_enhance_title_localization": {},
|
"@tools_rsi_launcher_enhance_title_localization": {},
|
||||||
@ -1141,7 +1141,7 @@
|
|||||||
"@log_analyzer_disintegration": {},
|
"@log_analyzer_disintegration": {},
|
||||||
"log_analyzer_vehicle_damage_details": "載具型號:{v0} \n區域:{v1} \n損毀等級:{v2} ({v3}) 責任方:{v4}",
|
"log_analyzer_vehicle_damage_details": "載具型號:{v0} \n區域:{v1} \n損毀等級:{v2} ({v3}) 責任方:{v4}",
|
||||||
"@log_analyzer_vehicle_damage_details": {},
|
"@log_analyzer_vehicle_damage_details": {},
|
||||||
"log_analyzer_death_details": "受害者ID:{v0} 死因:{v1} \n擊殺者ID:{v2} \n區域:{v3}",
|
"log_analyzer_death_details": "受害者ID:{v0} \n位置:{v2} \n區域:{v3}",
|
||||||
"@log_analyzer_death_details": {},
|
"@log_analyzer_death_details": {},
|
||||||
"log_analyzer_player_login": "玩家 {v0} 登入 ...",
|
"log_analyzer_player_login": "玩家 {v0} 登入 ...",
|
||||||
"@log_analyzer_player_login": {},
|
"@log_analyzer_player_login": {},
|
||||||
|
|||||||
@ -75,7 +75,11 @@ class PartyRoom extends _$PartyRoom {
|
|||||||
Box? _confBox;
|
Box? _confBox;
|
||||||
StreamSubscription<partroom.RoomEvent>? _eventStreamSubscription;
|
StreamSubscription<partroom.RoomEvent>? _eventStreamSubscription;
|
||||||
Timer? _heartbeatTimer;
|
Timer? _heartbeatTimer;
|
||||||
|
Timer? _reconnectTimer;
|
||||||
bool _disposed = false;
|
bool _disposed = false;
|
||||||
|
int _reconnectAttempts = 0;
|
||||||
|
static const int _maxReconnectAttempts = 5;
|
||||||
|
static const Duration _reconnectDelay = Duration(seconds: 3);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
PartyRoomFullState build() {
|
PartyRoomFullState build() {
|
||||||
@ -398,6 +402,7 @@ class PartyRoom extends _$PartyRoom {
|
|||||||
await _stopHeartbeat();
|
await _stopHeartbeat();
|
||||||
await _stopEventStream();
|
await _stopEventStream();
|
||||||
|
|
||||||
|
_reconnectAttempts = 0;
|
||||||
_dismissRoom();
|
_dismissRoom();
|
||||||
|
|
||||||
dPrint('[PartyRoom] Left room: $roomUuid');
|
dPrint('[PartyRoom] Left room: $roomUuid');
|
||||||
@ -421,6 +426,7 @@ class PartyRoom extends _$PartyRoom {
|
|||||||
await _stopHeartbeat();
|
await _stopHeartbeat();
|
||||||
await _stopEventStream();
|
await _stopEventStream();
|
||||||
|
|
||||||
|
_reconnectAttempts = 0;
|
||||||
_dismissRoom();
|
_dismissRoom();
|
||||||
|
|
||||||
dPrint('[PartyRoom] Dismissed room: $roomUuid');
|
dPrint('[PartyRoom] Dismissed room: $roomUuid');
|
||||||
@ -754,24 +760,106 @@ class PartyRoom extends _$PartyRoom {
|
|||||||
|
|
||||||
_eventStreamSubscription = stream.listen(
|
_eventStreamSubscription = stream.listen(
|
||||||
(event) {
|
(event) {
|
||||||
|
// 重置重连计数器,因为连接正常
|
||||||
|
_reconnectAttempts = 0;
|
||||||
_handleRoomEvent(event);
|
_handleRoomEvent(event);
|
||||||
},
|
},
|
||||||
onError: (error) {
|
onError: (error) {
|
||||||
dPrint('[PartyRoom] Event stream error: $error');
|
dPrint('[PartyRoom] Event stream error: $error');
|
||||||
|
// 发生错误时尝试重连
|
||||||
|
_scheduleReconnect(roomUuid);
|
||||||
},
|
},
|
||||||
onDone: () {
|
onDone: () {
|
||||||
dPrint('[PartyRoom] Event stream closed');
|
dPrint('[PartyRoom] Event stream closed');
|
||||||
|
// 流关闭时尝试重连
|
||||||
|
_scheduleReconnect(roomUuid);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
dPrint('[PartyRoom] Event stream started');
|
dPrint('[PartyRoom] Event stream started');
|
||||||
|
// 成功启动,重置重连计数
|
||||||
|
_reconnectAttempts = 0;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dPrint('[PartyRoom] StartEventStream error: $e');
|
dPrint('[PartyRoom] StartEventStream error: $e');
|
||||||
|
// 启动失败时尝试重连
|
||||||
|
_scheduleReconnect(roomUuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 调度重连
|
||||||
|
void _scheduleReconnect(String roomUuid) {
|
||||||
|
// 如果已经销毁或不在房间内,不重连
|
||||||
|
if (_disposed || state.room.roomUuid == null || state.room.roomUuid != roomUuid) {
|
||||||
|
dPrint('[PartyRoom] Skip reconnect: disposed=$_disposed, roomUuid=${state.room.roomUuid}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已经有重连任务在进行,不重复调度
|
||||||
|
if (_reconnectTimer?.isActive ?? false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查重连次数
|
||||||
|
if (_reconnectAttempts >= _maxReconnectAttempts) {
|
||||||
|
dPrint('[PartyRoom] Max reconnect attempts reached ($_maxReconnectAttempts)');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_reconnectAttempts++;
|
||||||
|
dPrint(
|
||||||
|
'[PartyRoom] Scheduling reconnect attempt $_reconnectAttempts/$_maxReconnectAttempts in ${_reconnectDelay.inSeconds}s',
|
||||||
|
);
|
||||||
|
|
||||||
|
_reconnectTimer = Timer(_reconnectDelay, () async {
|
||||||
|
await _attemptReconnect(roomUuid);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 尝试重连
|
||||||
|
Future<void> _attemptReconnect(String roomUuid) async {
|
||||||
|
if (_disposed || state.room.roomUuid == null || state.room.roomUuid != roomUuid) {
|
||||||
|
dPrint('[PartyRoom] Abort reconnect: no longer in room');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
dPrint('[PartyRoom] Attempting to reconnect event stream...');
|
||||||
|
|
||||||
|
// 先检查自己是否还在房间内
|
||||||
|
final client = state.client.roomClient;
|
||||||
|
if (client == null) {
|
||||||
|
dPrint('[PartyRoom] Reconnect failed: client not available');
|
||||||
|
_scheduleReconnect(roomUuid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用 getMyRoom 检查是否还在房间内
|
||||||
|
final response = await client.getMyRoom(partroom.GetMyRoomRequest(), options: _getAuthCallOptions());
|
||||||
|
|
||||||
|
if (!response.hasRoom() || response.room.roomUuid != roomUuid) {
|
||||||
|
dPrint('[PartyRoom] Reconnect failed: no longer in room');
|
||||||
|
// 不在房间内,清理状态
|
||||||
|
await _stopHeartbeat();
|
||||||
|
await _stopEventStream();
|
||||||
|
_reconnectAttempts = 0;
|
||||||
|
_dismissRoom();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认还在房间内,重新启动事件流
|
||||||
|
dPrint('[PartyRoom] Still in room, restarting event stream');
|
||||||
|
await _startEventStream(roomUuid);
|
||||||
|
} catch (e) {
|
||||||
|
dPrint('[PartyRoom] Reconnect attempt failed: $e');
|
||||||
|
// 重连失败,继续调度下一次重连
|
||||||
|
_scheduleReconnect(roomUuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 停止事件流监听
|
/// 停止事件流监听
|
||||||
Future<void> _stopEventStream() async {
|
Future<void> _stopEventStream() async {
|
||||||
|
_reconnectTimer?.cancel();
|
||||||
|
_reconnectTimer = null;
|
||||||
await _eventStreamSubscription?.cancel();
|
await _eventStreamSubscription?.cancel();
|
||||||
_eventStreamSubscription = null;
|
_eventStreamSubscription = null;
|
||||||
dPrint('[PartyRoom] Event stream stopped');
|
dPrint('[PartyRoom] Event stream stopped');
|
||||||
@ -794,6 +882,21 @@ class PartyRoom extends _$PartyRoom {
|
|||||||
case partroom.RoomEventType.MEMBER_JOINED:
|
case partroom.RoomEventType.MEMBER_JOINED:
|
||||||
case partroom.RoomEventType.MEMBER_LEFT:
|
case partroom.RoomEventType.MEMBER_LEFT:
|
||||||
case partroom.RoomEventType.MEMBER_KICKED:
|
case partroom.RoomEventType.MEMBER_KICKED:
|
||||||
|
if (event.type == partroom.RoomEventType.MEMBER_KICKED) {
|
||||||
|
// 判断被踢的是不是自己
|
||||||
|
if (event.member.gameUserId == state.auth.userInfo?.gameUserId) {
|
||||||
|
// 离开房间
|
||||||
|
_dismissRoom();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if (event.type == partroom.RoomEventType.MEMBER_LEFT) {
|
||||||
|
if (event.member.gameUserId == state.auth.userInfo?.gameUserId) {
|
||||||
|
// 判断离开的是不是自己
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
// 刷新成员列表
|
// 刷新成员列表
|
||||||
if (state.room.roomUuid != null) {
|
if (state.room.roomUuid != null) {
|
||||||
getRoomMembers(state.room.roomUuid!);
|
getRoomMembers(state.room.roomUuid!);
|
||||||
|
|||||||
@ -44,7 +44,7 @@ final class PartyRoomProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$partyRoomHash() => r'02cdd156995799411eb47107d5c197f43e78629e';
|
String _$partyRoomHash() => r'd7182854c8caf5bb362c45a4e6e2ab40c2ef1b09';
|
||||||
|
|
||||||
/// PartyRoom Provider
|
/// PartyRoom Provider
|
||||||
|
|
||||||
|
|||||||
@ -105,6 +105,12 @@ class PartyRoomUIModel extends _$PartyRoomUIModel {
|
|||||||
playTime: currentGameStartTime != gameStartTime ? gameStartTime : null,
|
playTime: currentGameStartTime != gameStartTime ? gameStartTime : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (next.deathEvents?.isNotEmpty ?? false) {
|
||||||
|
for (final event in next.deathEvents!) {
|
||||||
|
ref.read(partyRoomProvider.notifier).sendSignal("special_death", params: {"location": event.$1, "area": event.$2});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 处理连接状态变化
|
/// 处理连接状态变化
|
||||||
|
|||||||
@ -41,7 +41,7 @@ final class PartyRoomUIModelProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$partyRoomUIModelHash() => r'a0b6c3632ff33f2d58882f9bc1ab58c69c2487f4';
|
String _$partyRoomUIModelHash() => r'add4703c9129465718a7850ea09025aa1ff35358';
|
||||||
|
|
||||||
abstract class _$PartyRoomUIModel extends $Notifier<PartyRoomUIState> {
|
abstract class _$PartyRoomUIModel extends $Notifier<PartyRoomUIState> {
|
||||||
PartyRoomUIState build();
|
PartyRoomUIState build();
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
@ -18,8 +19,7 @@ sealed class PartyRoomGameLogTrackerProviderState with _$PartyRoomGameLogTracker
|
|||||||
@Default(0) int kills,
|
@Default(0) int kills,
|
||||||
@Default(0) int deaths,
|
@Default(0) int deaths,
|
||||||
DateTime? gameStartTime,
|
DateTime? gameStartTime,
|
||||||
@Default([]) List<String> killedIds, // 本次迭代新增的击杀ID
|
List<(String, String)>? deathEvents,
|
||||||
@Default([]) List<String> deathIds, // 本次迭代新增的死亡ID
|
|
||||||
}) = _PartyRoomGameLogTrackerProviderState;
|
}) = _PartyRoomGameLogTrackerProviderState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +32,7 @@ class PartyRoomGameLogTrackerProvider extends _$PartyRoomGameLogTrackerProvider
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
PartyRoomGameLogTrackerProviderState build({required DateTime startTime}) {
|
PartyRoomGameLogTrackerProviderState build({required DateTime startTime}) {
|
||||||
|
startTime = DateTime.now();
|
||||||
dPrint("[PartyRoomGameLogTrackerProvider] init $startTime");
|
dPrint("[PartyRoomGameLogTrackerProvider] init $startTime");
|
||||||
ref.onDispose(() {
|
ref.onDispose(() {
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
@ -65,16 +66,9 @@ class PartyRoomGameLogTrackerProvider extends _$PartyRoomGameLogTrackerProvider
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// 游戏未启动或发生错误
|
// 游戏未启动或发生错误
|
||||||
state = state.copyWith(
|
state = state.copyWith(location: '<游戏未启动>', gameStartTime: null, kills: 0, deaths: 0);
|
||||||
location: '<游戏未启动>',
|
|
||||||
gameStartTime: null,
|
|
||||||
kills: 0,
|
|
||||||
deaths: 0,
|
|
||||||
killedIds: [],
|
|
||||||
deathIds: [],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
await Future.delayed(const Duration(seconds: 5));
|
await Future.delayed(const Duration(seconds: 10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,9 +84,7 @@ class PartyRoomGameLogTrackerProvider extends _$PartyRoomGameLogTrackerProvider
|
|||||||
// 从统计数据中直接获取最新位置(全量查找的结果)
|
// 从统计数据中直接获取最新位置(全量查找的结果)
|
||||||
final location = statistics.latestLocation == null ? '<主菜单>' : '[${statistics.latestLocation}]';
|
final location = statistics.latestLocation == null ? '<主菜单>' : '[${statistics.latestLocation}]';
|
||||||
|
|
||||||
// 计算基于 _lastQueryTime 之后的增量 ID
|
List<(String, String)> deathEvents = [];
|
||||||
final newKilledIds = <String>[];
|
|
||||||
final newDeathIds = <String>[];
|
|
||||||
|
|
||||||
if (_lastQueryTime != null) {
|
if (_lastQueryTime != null) {
|
||||||
// 遍历所有 actor_death 事件
|
// 遍历所有 actor_death 事件
|
||||||
@ -125,24 +117,15 @@ class PartyRoomGameLogTrackerProvider extends _$PartyRoomGameLogTrackerProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用格式化字段,不再重新解析
|
if (data.playerName == data.victimId) {
|
||||||
final victimId = data.victimId;
|
// 玩家死亡,增加记录
|
||||||
final killerId = data.killerId;
|
deathEvents.add((data.location ?? "-", data.area ?? "-"));
|
||||||
|
|
||||||
if (victimId != null && killerId != null && victimId != killerId) {
|
|
||||||
// 如果玩家是击杀者,记录被击杀的ID
|
|
||||||
if (killerId == statistics.playerName) {
|
|
||||||
newKilledIds.add(victimId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果玩家是受害者,记录击杀者ID
|
|
||||||
if (victimId == statistics.playerName) {
|
|
||||||
newDeathIds.add(killerId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// debugPrint(
|
||||||
|
// "[PartyRoomGameLogTrackerProvider] location $location killCount ${statistics.killCount} deathCount ${statistics.deathCount}",
|
||||||
|
// );
|
||||||
// 更新状态,只存储本次迭代的增量数据
|
// 更新状态,只存储本次迭代的增量数据
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
location: location,
|
location: location,
|
||||||
@ -151,10 +134,7 @@ class PartyRoomGameLogTrackerProvider extends _$PartyRoomGameLogTrackerProvider
|
|||||||
deaths: statistics.deathCount,
|
deaths: statistics.deathCount,
|
||||||
// 从 startTime 开始的总计数
|
// 从 startTime 开始的总计数
|
||||||
gameStartTime: statistics.gameStartTime,
|
gameStartTime: statistics.gameStartTime,
|
||||||
// 全量查找的游戏开始时间
|
deathEvents: deathEvents,
|
||||||
killedIds: newKilledIds,
|
|
||||||
// 只存储本次迭代的增量
|
|
||||||
deathIds: newDeathIds, // 只存储本次迭代的增量
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// 更新查询时间为本次查询的时刻
|
// 更新查询时间为本次查询的时刻
|
||||||
|
|||||||
@ -12,10 +12,9 @@ part of 'game_log_tracker_provider.dart';
|
|||||||
// dart format off
|
// dart format off
|
||||||
T _$identity<T>(T value) => value;
|
T _$identity<T>(T value) => value;
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$PartyRoomGameLogTrackerProviderState {
|
mixin _$PartyRoomGameLogTrackerProviderState implements DiagnosticableTreeMixin {
|
||||||
|
|
||||||
String get location; int get kills; int get deaths; DateTime? get gameStartTime; List<String> get killedIds;// 本次迭代新增的击杀ID
|
String get location; int get kills; int get deaths; DateTime? get gameStartTime; List<(String, String)>? get deathEvents;
|
||||||
List<String> get deathIds;
|
|
||||||
/// Create a copy of PartyRoomGameLogTrackerProviderState
|
/// Create a copy of PartyRoomGameLogTrackerProviderState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -23,19 +22,25 @@ mixin _$PartyRoomGameLogTrackerProviderState {
|
|||||||
$PartyRoomGameLogTrackerProviderStateCopyWith<PartyRoomGameLogTrackerProviderState> get copyWith => _$PartyRoomGameLogTrackerProviderStateCopyWithImpl<PartyRoomGameLogTrackerProviderState>(this as PartyRoomGameLogTrackerProviderState, _$identity);
|
$PartyRoomGameLogTrackerProviderStateCopyWith<PartyRoomGameLogTrackerProviderState> get copyWith => _$PartyRoomGameLogTrackerProviderStateCopyWithImpl<PartyRoomGameLogTrackerProviderState>(this as PartyRoomGameLogTrackerProviderState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
properties
|
||||||
|
..add(DiagnosticsProperty('type', 'PartyRoomGameLogTrackerProviderState'))
|
||||||
|
..add(DiagnosticsProperty('location', location))..add(DiagnosticsProperty('kills', kills))..add(DiagnosticsProperty('deaths', deaths))..add(DiagnosticsProperty('gameStartTime', gameStartTime))..add(DiagnosticsProperty('deathEvents', deathEvents));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is PartyRoomGameLogTrackerProviderState&&(identical(other.location, location) || other.location == location)&&(identical(other.kills, kills) || other.kills == kills)&&(identical(other.deaths, deaths) || other.deaths == deaths)&&(identical(other.gameStartTime, gameStartTime) || other.gameStartTime == gameStartTime)&&const DeepCollectionEquality().equals(other.killedIds, killedIds)&&const DeepCollectionEquality().equals(other.deathIds, deathIds));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is PartyRoomGameLogTrackerProviderState&&(identical(other.location, location) || other.location == location)&&(identical(other.kills, kills) || other.kills == kills)&&(identical(other.deaths, deaths) || other.deaths == deaths)&&(identical(other.gameStartTime, gameStartTime) || other.gameStartTime == gameStartTime)&&const DeepCollectionEquality().equals(other.deathEvents, deathEvents));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,location,kills,deaths,gameStartTime,const DeepCollectionEquality().hash(killedIds),const DeepCollectionEquality().hash(deathIds));
|
int get hashCode => Object.hash(runtimeType,location,kills,deaths,gameStartTime,const DeepCollectionEquality().hash(deathEvents));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
||||||
return 'PartyRoomGameLogTrackerProviderState(location: $location, kills: $kills, deaths: $deaths, gameStartTime: $gameStartTime, killedIds: $killedIds, deathIds: $deathIds)';
|
return 'PartyRoomGameLogTrackerProviderState(location: $location, kills: $kills, deaths: $deaths, gameStartTime: $gameStartTime, deathEvents: $deathEvents)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -46,7 +51,7 @@ abstract mixin class $PartyRoomGameLogTrackerProviderStateCopyWith<$Res> {
|
|||||||
factory $PartyRoomGameLogTrackerProviderStateCopyWith(PartyRoomGameLogTrackerProviderState value, $Res Function(PartyRoomGameLogTrackerProviderState) _then) = _$PartyRoomGameLogTrackerProviderStateCopyWithImpl;
|
factory $PartyRoomGameLogTrackerProviderStateCopyWith(PartyRoomGameLogTrackerProviderState value, $Res Function(PartyRoomGameLogTrackerProviderState) _then) = _$PartyRoomGameLogTrackerProviderStateCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String location, int kills, int deaths, DateTime? gameStartTime, List<String> killedIds, List<String> deathIds
|
String location, int kills, int deaths, DateTime? gameStartTime, List<(String, String)>? deathEvents
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -63,15 +68,14 @@ class _$PartyRoomGameLogTrackerProviderStateCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of PartyRoomGameLogTrackerProviderState
|
/// Create a copy of PartyRoomGameLogTrackerProviderState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? location = null,Object? kills = null,Object? deaths = null,Object? gameStartTime = freezed,Object? killedIds = null,Object? deathIds = null,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? location = null,Object? kills = null,Object? deaths = null,Object? gameStartTime = freezed,Object? deathEvents = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
location: null == location ? _self.location : location // ignore: cast_nullable_to_non_nullable
|
location: null == location ? _self.location : location // ignore: cast_nullable_to_non_nullable
|
||||||
as String,kills: null == kills ? _self.kills : kills // ignore: cast_nullable_to_non_nullable
|
as String,kills: null == kills ? _self.kills : kills // ignore: cast_nullable_to_non_nullable
|
||||||
as int,deaths: null == deaths ? _self.deaths : deaths // ignore: cast_nullable_to_non_nullable
|
as int,deaths: null == deaths ? _self.deaths : deaths // ignore: cast_nullable_to_non_nullable
|
||||||
as int,gameStartTime: freezed == gameStartTime ? _self.gameStartTime : gameStartTime // ignore: cast_nullable_to_non_nullable
|
as int,gameStartTime: freezed == gameStartTime ? _self.gameStartTime : gameStartTime // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,killedIds: null == killedIds ? _self.killedIds : killedIds // ignore: cast_nullable_to_non_nullable
|
as DateTime?,deathEvents: freezed == deathEvents ? _self.deathEvents : deathEvents // ignore: cast_nullable_to_non_nullable
|
||||||
as List<String>,deathIds: null == deathIds ? _self.deathIds : deathIds // ignore: cast_nullable_to_non_nullable
|
as List<(String, String)>?,
|
||||||
as List<String>,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,10 +157,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String location, int kills, int deaths, DateTime? gameStartTime, List<String> killedIds, List<String> deathIds)? $default,{required TResult orElse(),}) {final _that = this;
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String location, int kills, int deaths, DateTime? gameStartTime, List<(String, String)>? deathEvents)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _PartyRoomGameLogTrackerProviderState() when $default != null:
|
case _PartyRoomGameLogTrackerProviderState() when $default != null:
|
||||||
return $default(_that.location,_that.kills,_that.deaths,_that.gameStartTime,_that.killedIds,_that.deathIds);case _:
|
return $default(_that.location,_that.kills,_that.deaths,_that.gameStartTime,_that.deathEvents);case _:
|
||||||
return orElse();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -174,10 +178,10 @@ return $default(_that.location,_that.kills,_that.deaths,_that.gameStartTime,_tha
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String location, int kills, int deaths, DateTime? gameStartTime, List<String> killedIds, List<String> deathIds) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String location, int kills, int deaths, DateTime? gameStartTime, List<(String, String)>? deathEvents) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _PartyRoomGameLogTrackerProviderState():
|
case _PartyRoomGameLogTrackerProviderState():
|
||||||
return $default(_that.location,_that.kills,_that.deaths,_that.gameStartTime,_that.killedIds,_that.deathIds);}
|
return $default(_that.location,_that.kills,_that.deaths,_that.gameStartTime,_that.deathEvents);}
|
||||||
}
|
}
|
||||||
/// A variant of `when` that fallback to returning `null`
|
/// A variant of `when` that fallback to returning `null`
|
||||||
///
|
///
|
||||||
@ -191,10 +195,10 @@ return $default(_that.location,_that.kills,_that.deaths,_that.gameStartTime,_tha
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String location, int kills, int deaths, DateTime? gameStartTime, List<String> killedIds, List<String> deathIds)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String location, int kills, int deaths, DateTime? gameStartTime, List<(String, String)>? deathEvents)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _PartyRoomGameLogTrackerProviderState() when $default != null:
|
case _PartyRoomGameLogTrackerProviderState() when $default != null:
|
||||||
return $default(_that.location,_that.kills,_that.deaths,_that.gameStartTime,_that.killedIds,_that.deathIds);case _:
|
return $default(_that.location,_that.kills,_that.deaths,_that.gameStartTime,_that.deathEvents);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -205,28 +209,21 @@ return $default(_that.location,_that.kills,_that.deaths,_that.gameStartTime,_tha
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
class _PartyRoomGameLogTrackerProviderState implements PartyRoomGameLogTrackerProviderState {
|
class _PartyRoomGameLogTrackerProviderState with DiagnosticableTreeMixin implements PartyRoomGameLogTrackerProviderState {
|
||||||
const _PartyRoomGameLogTrackerProviderState({this.location = '', this.kills = 0, this.deaths = 0, this.gameStartTime, final List<String> killedIds = const [], final List<String> deathIds = const []}): _killedIds = killedIds,_deathIds = deathIds;
|
const _PartyRoomGameLogTrackerProviderState({this.location = '', this.kills = 0, this.deaths = 0, this.gameStartTime, final List<(String, String)>? deathEvents}): _deathEvents = deathEvents;
|
||||||
|
|
||||||
|
|
||||||
@override@JsonKey() final String location;
|
@override@JsonKey() final String location;
|
||||||
@override@JsonKey() final int kills;
|
@override@JsonKey() final int kills;
|
||||||
@override@JsonKey() final int deaths;
|
@override@JsonKey() final int deaths;
|
||||||
@override final DateTime? gameStartTime;
|
@override final DateTime? gameStartTime;
|
||||||
final List<String> _killedIds;
|
final List<(String, String)>? _deathEvents;
|
||||||
@override@JsonKey() List<String> get killedIds {
|
@override List<(String, String)>? get deathEvents {
|
||||||
if (_killedIds is EqualUnmodifiableListView) return _killedIds;
|
final value = _deathEvents;
|
||||||
|
if (value == null) return null;
|
||||||
|
if (_deathEvents is EqualUnmodifiableListView) return _deathEvents;
|
||||||
// ignore: implicit_dynamic_type
|
// ignore: implicit_dynamic_type
|
||||||
return EqualUnmodifiableListView(_killedIds);
|
return EqualUnmodifiableListView(value);
|
||||||
}
|
|
||||||
|
|
||||||
// 本次迭代新增的击杀ID
|
|
||||||
final List<String> _deathIds;
|
|
||||||
// 本次迭代新增的击杀ID
|
|
||||||
@override@JsonKey() List<String> get deathIds {
|
|
||||||
if (_deathIds is EqualUnmodifiableListView) return _deathIds;
|
|
||||||
// ignore: implicit_dynamic_type
|
|
||||||
return EqualUnmodifiableListView(_deathIds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -237,19 +234,25 @@ class _PartyRoomGameLogTrackerProviderState implements PartyRoomGameLogTrackerPr
|
|||||||
_$PartyRoomGameLogTrackerProviderStateCopyWith<_PartyRoomGameLogTrackerProviderState> get copyWith => __$PartyRoomGameLogTrackerProviderStateCopyWithImpl<_PartyRoomGameLogTrackerProviderState>(this, _$identity);
|
_$PartyRoomGameLogTrackerProviderStateCopyWith<_PartyRoomGameLogTrackerProviderState> get copyWith => __$PartyRoomGameLogTrackerProviderStateCopyWithImpl<_PartyRoomGameLogTrackerProviderState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
properties
|
||||||
|
..add(DiagnosticsProperty('type', 'PartyRoomGameLogTrackerProviderState'))
|
||||||
|
..add(DiagnosticsProperty('location', location))..add(DiagnosticsProperty('kills', kills))..add(DiagnosticsProperty('deaths', deaths))..add(DiagnosticsProperty('gameStartTime', gameStartTime))..add(DiagnosticsProperty('deathEvents', deathEvents));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PartyRoomGameLogTrackerProviderState&&(identical(other.location, location) || other.location == location)&&(identical(other.kills, kills) || other.kills == kills)&&(identical(other.deaths, deaths) || other.deaths == deaths)&&(identical(other.gameStartTime, gameStartTime) || other.gameStartTime == gameStartTime)&&const DeepCollectionEquality().equals(other._killedIds, _killedIds)&&const DeepCollectionEquality().equals(other._deathIds, _deathIds));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PartyRoomGameLogTrackerProviderState&&(identical(other.location, location) || other.location == location)&&(identical(other.kills, kills) || other.kills == kills)&&(identical(other.deaths, deaths) || other.deaths == deaths)&&(identical(other.gameStartTime, gameStartTime) || other.gameStartTime == gameStartTime)&&const DeepCollectionEquality().equals(other._deathEvents, _deathEvents));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,location,kills,deaths,gameStartTime,const DeepCollectionEquality().hash(_killedIds),const DeepCollectionEquality().hash(_deathIds));
|
int get hashCode => Object.hash(runtimeType,location,kills,deaths,gameStartTime,const DeepCollectionEquality().hash(_deathEvents));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
||||||
return 'PartyRoomGameLogTrackerProviderState(location: $location, kills: $kills, deaths: $deaths, gameStartTime: $gameStartTime, killedIds: $killedIds, deathIds: $deathIds)';
|
return 'PartyRoomGameLogTrackerProviderState(location: $location, kills: $kills, deaths: $deaths, gameStartTime: $gameStartTime, deathEvents: $deathEvents)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -260,7 +263,7 @@ abstract mixin class _$PartyRoomGameLogTrackerProviderStateCopyWith<$Res> implem
|
|||||||
factory _$PartyRoomGameLogTrackerProviderStateCopyWith(_PartyRoomGameLogTrackerProviderState value, $Res Function(_PartyRoomGameLogTrackerProviderState) _then) = __$PartyRoomGameLogTrackerProviderStateCopyWithImpl;
|
factory _$PartyRoomGameLogTrackerProviderStateCopyWith(_PartyRoomGameLogTrackerProviderState value, $Res Function(_PartyRoomGameLogTrackerProviderState) _then) = __$PartyRoomGameLogTrackerProviderStateCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String location, int kills, int deaths, DateTime? gameStartTime, List<String> killedIds, List<String> deathIds
|
String location, int kills, int deaths, DateTime? gameStartTime, List<(String, String)>? deathEvents
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -277,15 +280,14 @@ class __$PartyRoomGameLogTrackerProviderStateCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of PartyRoomGameLogTrackerProviderState
|
/// Create a copy of PartyRoomGameLogTrackerProviderState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? location = null,Object? kills = null,Object? deaths = null,Object? gameStartTime = freezed,Object? killedIds = null,Object? deathIds = null,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? location = null,Object? kills = null,Object? deaths = null,Object? gameStartTime = freezed,Object? deathEvents = freezed,}) {
|
||||||
return _then(_PartyRoomGameLogTrackerProviderState(
|
return _then(_PartyRoomGameLogTrackerProviderState(
|
||||||
location: null == location ? _self.location : location // ignore: cast_nullable_to_non_nullable
|
location: null == location ? _self.location : location // ignore: cast_nullable_to_non_nullable
|
||||||
as String,kills: null == kills ? _self.kills : kills // ignore: cast_nullable_to_non_nullable
|
as String,kills: null == kills ? _self.kills : kills // ignore: cast_nullable_to_non_nullable
|
||||||
as int,deaths: null == deaths ? _self.deaths : deaths // ignore: cast_nullable_to_non_nullable
|
as int,deaths: null == deaths ? _self.deaths : deaths // ignore: cast_nullable_to_non_nullable
|
||||||
as int,gameStartTime: freezed == gameStartTime ? _self.gameStartTime : gameStartTime // ignore: cast_nullable_to_non_nullable
|
as int,gameStartTime: freezed == gameStartTime ? _self.gameStartTime : gameStartTime // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,killedIds: null == killedIds ? _self._killedIds : killedIds // ignore: cast_nullable_to_non_nullable
|
as DateTime?,deathEvents: freezed == deathEvents ? _self._deathEvents : deathEvents // ignore: cast_nullable_to_non_nullable
|
||||||
as List<String>,deathIds: null == deathIds ? _self._deathIds : deathIds // ignore: cast_nullable_to_non_nullable
|
as List<(String, String)>?,
|
||||||
as List<String>,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -66,7 +66,7 @@ final class PartyRoomGameLogTrackerProviderProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$partyRoomGameLogTrackerProviderHash() =>
|
String _$partyRoomGameLogTrackerProviderHash() =>
|
||||||
r'ecb015eb46d25bfe11bbb153242fd5c4f20ef367';
|
r'3e1560b2fffc5461a41bece57b43e27f4112ad0c';
|
||||||
|
|
||||||
final class PartyRoomGameLogTrackerProviderFamily extends $Family
|
final class PartyRoomGameLogTrackerProviderFamily extends $Family
|
||||||
with
|
with
|
||||||
|
|||||||
@ -97,15 +97,12 @@ class PartyRoomMemberItem extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Expanded(
|
||||||
member.status.currentLocation.isNotEmpty ? member.status.currentLocation : '...',
|
child: Text(
|
||||||
style: TextStyle(fontSize: 12, color: Colors.white.withValues(alpha: .9)),
|
member.status.currentLocation.isNotEmpty ? member.status.currentLocation : '...',
|
||||||
overflow: TextOverflow.ellipsis,
|
style: TextStyle(fontSize: 12, color: Colors.white.withValues(alpha: .9)),
|
||||||
),
|
overflow: TextOverflow.ellipsis,
|
||||||
SizedBox(width: 4),
|
),
|
||||||
Text(
|
|
||||||
"K: ${member.status.kills} D: ${member.status.deaths}",
|
|
||||||
style: TextStyle(fontSize: 12, color: Colors.white.withValues(alpha: .6)),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -210,6 +210,11 @@ class _MessageItem extends ConsumerWidget {
|
|||||||
final userName = _getEventUserName(roomEvent);
|
final userName = _getEventUserName(roomEvent);
|
||||||
final avatarUrl = _getEventAvatarUrl(roomEvent);
|
final avatarUrl = _getEventAvatarUrl(roomEvent);
|
||||||
|
|
||||||
|
// 检查是否是死亡信号,显示特殊卡片
|
||||||
|
if (isSignal && roomEvent.signalId == 'special_death') {
|
||||||
|
return _buildDeathMessageCard(context, roomEvent, userName, avatarUrl);
|
||||||
|
}
|
||||||
|
|
||||||
final text = _getEventText(roomEvent, ref);
|
final text = _getEventText(roomEvent, ref);
|
||||||
if (text == null) return const SizedBox.shrink();
|
if (text == null) return const SizedBox.shrink();
|
||||||
|
|
||||||
@ -259,6 +264,104 @@ class _MessageItem extends ConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildDeathMessageCard(
|
||||||
|
BuildContext context,
|
||||||
|
partroom.RoomEvent roomEvent,
|
||||||
|
String userName,
|
||||||
|
String? avatarUrl,
|
||||||
|
) {
|
||||||
|
final location = roomEvent.signalParams['location'] ?? '未知位置';
|
||||||
|
final area = roomEvent.signalParams['area'] ?? '未知区域';
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets.only(bottom: 16),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildUserAvatar(userName, avatarUrl: avatarUrl, size: 28),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 用户名和时间
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
userName,
|
||||||
|
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Colors.white),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
_formatTime(roomEvent.timestamp),
|
||||||
|
style: const TextStyle(fontSize: 11, color: Color(0xFF80848E)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
// 死亡卡片
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFF2B2D31),
|
||||||
|
border: Border.all(color: const Color(0xFFED4245).withValues(alpha: 0.3)),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// 标题
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFED4245).withValues(alpha: 0.2),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: const Icon(FluentIcons.status_error_full, size: 14, color: Color(0xFFED4245)),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
const Text(
|
||||||
|
'玩家死亡',
|
||||||
|
style: TextStyle(fontSize: 14, color: Color(0xFFED4245), fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
// 位置信息
|
||||||
|
_buildInfoRow(icon: FluentIcons.location, label: '位置', value: location),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
// 区域信息
|
||||||
|
_buildInfoRow(icon: FluentIcons.map_pin, label: '区域', value: area),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildInfoRow({required IconData icon, required String label, required String value}) {
|
||||||
|
return Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Icon(icon, size: 14, color: Colors.white.withValues(alpha: .4)),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'$label: ',
|
||||||
|
style: TextStyle(fontSize: 13, color: Colors.white.withValues(alpha: .4), fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(value, style: const TextStyle(fontSize: 13, color: Color(0xFFDBDEE1))),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
String _getEventUserName(partroom.RoomEvent event) {
|
String _getEventUserName(partroom.RoomEvent event) {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case partroom.RoomEventType.SIGNAL_BROADCAST:
|
case partroom.RoomEventType.SIGNAL_BROADCAST:
|
||||||
|
|||||||
@ -123,7 +123,7 @@ class PartyRoomRegisterPage extends HookConsumerWidget {
|
|||||||
? const Color(0xFF4CAF50)
|
? const Color(0xFF4CAF50)
|
||||||
: isActive
|
: isActive
|
||||||
? const Color(0xFF4A9EFF)
|
? const Color(0xFF4A9EFF)
|
||||||
: Colors.grey.withValues(alpha: 0.3),
|
: Colors.white.withValues(alpha: 0.4),
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
child: Center(
|
child: Center(
|
||||||
@ -143,7 +143,7 @@ class PartyRoomRegisterPage extends HookConsumerWidget {
|
|||||||
title,
|
title,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
color: isActive ? const Color(0xFF4A9EFF) : Colors.grey.withValues(alpha: 0.7),
|
color: isActive ? const Color(0xFF4A9EFF) : Colors.white.withValues(alpha: 0.4),
|
||||||
fontWeight: isActive ? FontWeight.bold : FontWeight.normal,
|
fontWeight: isActive ? FontWeight.bold : FontWeight.normal,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user