using AnotherReplayReader.ReplayFile; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; namespace AnotherReplayReader { internal class DataValue : IComparable, IComparable { public int? NumberValue { get; } public string Value { get; } public DataValue(string value) { Value = value; if (int.TryParse(value, out var numberValue)) { NumberValue = numberValue; } } public override string ToString() => Value; public int CompareTo(DataValue other) { if (NumberValue.HasValue == other.NumberValue.HasValue) { if (!NumberValue.HasValue) { return Value.CompareTo(other.Value); } return NumberValue.Value.CompareTo(other.NumberValue!.Value); } return NumberValue.HasValue ? 1 : -1; } public int CompareTo(object obj) { if (obj is DataValue other) { return CompareTo(other); } throw new NotSupportedException(); } } internal class DataRow { public string Name { get; } public DataValue Player1Value => _values[0]; public DataValue Player2Value => _values[1]; public DataValue Player3Value => _values[2]; public DataValue Player4Value => _values[3]; public DataValue Player5Value => _values[4]; public DataValue Player6Value => _values[5]; private readonly IReadOnlyList _values; public DataRow(string name, IEnumerable values) { Name = name; if (values.Count() < 6) { values = values.Concat(new string[6 - values.Count()]); } _values = values.Select(x => new DataValue(x)).ToArray(); } public static List GetList(Replay replay, PlayerIdentity identity) { var list = new List { 0x0F, 0x5F, 0x12, 0x1B, 0x48, 0x52, 0xFC, 0xFD, 0x01, 0x21, 0x33, 0x34, 0x35, 0x37, 0x47, 0xF6, 0xF9, 0xF5, 0xF8, 0x2A, 0xFA, 0xFB, 0x07, 0x08, 0x05, 0x06, 0x09, 0x00, 0x0A, 0x03, 0x04, 0x28, 0x29, 0x0D, 0x0E, 0x15, 0x14, 0x36, 0x16, 0x2C, 0x1A, 0x4E, 0xFE, 0xFF, 0x32, 0x2E, 0x2F, 0x4B, 0x4C, 0x02, 0x0C, 0x10, }; var dataList = new List { new DataRow("ID", replay.Players.Select(x => x.PlayerName)) }; if (replay.Type == ReplayType.Lan && identity.IsUsable) { dataList.Add(new DataRow("局域网IP", replay.Players.Select(x => identity.QueryRealNameAndIP(x.PlayerIp)))); } var commandCounts = replay.GetCommandCounts(); foreach (var command in list) { var counts = commandCounts.TryGetValue(command, out var stored) ? stored : new int[replay.Players.Count]; dataList.Add(new DataRow(RA3Commands.GetCommandName(command), counts.Select(x => $"{x}"))); commandCounts.Remove(command); } foreach (var commandCount in commandCounts) { dataList.Add(new DataRow(RA3Commands.GetCommandName(commandCount.Key), commandCount.Value.Select(x => $"{x}"))); } return dataList; } } /// /// APM.xaml 的交互逻辑 /// internal partial class ApmWindow : Window { private readonly PlayerIdentity _identity; public ApmWindow(Replay replay, PlayerIdentity identity) { _identity = identity; InitializeComponent(); InitializeApmWindowData(replay); } private async void InitializeApmWindowData(Replay replay) { if (_identity.IsUsable) { _setPlayerButton.IsEnabled = true; _setPlayerButton.Visibility = Visibility.Visible; } else { _setPlayerButton.IsEnabled = false; _setPlayerButton.Visibility = Visibility.Hidden; } try { var dataList = await Task.Run(() => DataRow.GetList(replay, _identity)); _table.Items.Clear(); foreach (var row in dataList) { _table.Items.Add(row); } _table.Columns[1].Header = dataList[0].Player1Value; _table.Columns[2].Header = dataList[0].Player2Value; _table.Columns[3].Header = dataList[0].Player3Value; _table.Columns[4].Header = dataList[0].Player4Value; _table.Columns[5].Header = dataList[0].Player5Value; _table.Columns[6].Header = dataList[0].Player6Value; } catch (Exception e) { MessageBox.Show($"加载录像信息失败:\r\n{e}"); } } private void OnSetPlayerButtonClick(object sender, RoutedEventArgs e) { var window1 = new Window1(_identity); window1.ShowDialog(); } private void OnTableMouseDoubleClick(object sender, MouseButtonEventArgs e) { _table.SelectAll(); } } }