AnotherReplayReader/APM.xaml.cs
2021-04-23 00:56:08 +02:00

231 lines
6.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace AnotherReplayReader
{
internal class DataValue : IComparable<DataValue>, 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<DataValue> _values;
public DataRow(string name, IEnumerable<string> values)
{
Name = name;
if (values.Count() < 6)
{
values = values.Concat(new string[6 - values.Count()]);
}
_values = values.Select(x => new DataValue(x)).ToArray();
}
}
internal static class DataTableFactory
{
static public List<DataRow> Get(Replay replay, PlayerIdentity identity)
{
var list = new List<byte>
{
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<DataRow>
{
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;
}
}
/// <summary>
/// APM.xaml 的交互逻辑
/// </summary>
internal partial class APM : Window
{
private PlayerIdentity _identity;
public APM(Replay replay, PlayerIdentity identity)
{
InitializeComponent();
_identity = identity;
if (_identity.IsUsable)
{
Dispatcher.Invoke(() =>
{
_setPlayerButton.IsEnabled = true;
_setPlayerButton.Visibility = Visibility.Visible;
});
}
else
{
Dispatcher.Invoke(() =>
{
_setPlayerButton.IsEnabled = false;
_setPlayerButton.Visibility = Visibility.Hidden;
});
}
Task.Run(() =>
{
try
{
var dataList = DataTableFactory.Get(replay, _identity);
Dispatcher.Invoke(() =>
{
_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)
{
Dispatcher.Invoke(() =>
{
MessageBox.Show($"加载录像信息失败:\r\n{e}");
});
}
});
}
private void OnSetPlayerButtonClick(object sender, RoutedEventArgs e)
{
var window1 = new Window1(_identity);
window1.ShowDialog();
}
private void OnTableMouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
_table.SelectAll();
}
}
}