155 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AnotherReplayReader.ReplayFile;
using System;
using System.Collections.Generic;
using System.Linq;
namespace AnotherReplayReader.Apm
{
internal class DataRow
{
public const string AverageApmRow = "APM整局游戏";
public const string PartialApmRow = "APM当前时间段";
public string Name { get; }
public bool IsDisabled { 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,
bool isDisabled = false)
{
Name = name;
IsDisabled = isDisabled;
if (values.Count() < 6)
{
values = values.Concat(new string[6 - values.Count()]);
}
_values = values.Select(x => new DataValue(x)).ToArray();
}
public static List<DataRow> GetList(ApmPlotter plotter,
ApmPlotterFilterOptions options,
PlayerIdentity identity,
TimeSpan begin,
TimeSpan end,
out int apmRowIndex)
{
// these commands should appear in this order by default
var orderedCommands = new List<byte>();
orderedCommands.AddRange(RA3Commands.UnknownCommands);
orderedCommands.AddRange(RA3Commands.AutoCommands);
orderedCommands.AddRange(new byte[]
{
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("ID", plotter.Players.Select(x => x.PlayerName))
};
var isPartial = begin > TimeSpan.Zero || end <= plotter.ReplayLength;
if (isPartial)
{
string GetStatus(Player player, int i)
{
if (player.IsComputer)
{
return "这是 AI";
}
if (begin < plotter.StricterPlayerLifes[i])
{
return "存活";
}
return begin < plotter.PlayerLifes[i]
? "变身天眼帝国,或双手离开键盘"
: "可能已离开房间";
}
dataList.Add(new("存活状态(推测)", plotter.Players.Select(GetStatus)));
}
if (plotter.Replay.Type is ReplayType.Lan && identity.IsUsable)
{
string GetIpAndName(Player player) => player.IsComputer
? "这是 AI"
: identity.QueryRealNameAndIP(player.PlayerIp) ?? string.Empty;
dataList.Add(new("局域网 IP", plotter.Players.Select(GetIpAndName)));
}
apmRowIndex = dataList.Count;
// kill-death ratio
if (plotter.Replay.Footer?.TryGetKillDeathRatios() is { } kdRatios)
{
var texts = kdRatios
.Take(plotter.Players.Length)
.Select(x => $"{x:0.##}");
dataList.Add(new("击杀阵亡比(存疑)", texts));
}
// get commands
var commandCounts = plotter.GetCommandCounts(begin, end);
// add commands in the order specified by the list
foreach (var command in orderedCommands)
{
var counts = commandCounts.TryGetValue(command, out var stored)
? stored
: new int[plotter.Players.Length];
if (!isPartial || counts.Any(x => x > 0))
{
dataList.Add(new(RA3Commands.GetCommandName(command),
counts.Select(x => $"{x}"),
options.ShouldSkip(command)));
}
commandCounts.Remove(command);
}
// add other commands
foreach (var commandCount in commandCounts)
{
dataList.Add(new(RA3Commands.GetCommandName(commandCount.Key),
commandCount.Value.Select(x => $"{x}"),
options.ShouldSkip(commandCount.Key)));
}
return dataList;
}
}
}