forked from imkindaprogrammermyself/Replays-Unpack-CS
-
Notifications
You must be signed in to change notification settings - Fork 2
/
ExtendedDataController.cs
104 lines (87 loc) · 3.87 KB
/
ExtendedDataController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using Microsoft.Extensions.Logging;
using Nodsoft.WowsReplaysUnpack.Controllers;
using Nodsoft.WowsReplaysUnpack.Core.Definitions;
using Nodsoft.WowsReplaysUnpack.Core.Entities;
using Nodsoft.WowsReplaysUnpack.Core.Models;
using Nodsoft.WowsReplaysUnpack.ExtendedData.Models;
using Nodsoft.WowsReplaysUnpack.ExtendedData.VersionMappings;
using Razorvine.Pickle;
using System.Collections;
using System.Reflection;
namespace Nodsoft.WowsReplaysUnpack.ExtendedData
{
/// <summary>
/// Defines a non-generic implementation of the <see cref="ExtendedDataController{T}" />.
/// </summary>
public sealed class ExtendedDataController : ExtendedDataController<ExtendedDataController>
{
// ReSharper disable once ContextualLoggerProblem
public ExtendedDataController(VersionMappingFactory versionMappingFactory, IDefinitionStore definitionStore, ILogger<Entity> entityLogger)
: base(versionMappingFactory, definitionStore, entityLogger) { }
}
public class ExtendedDataController<TController> : ReplayControllerBase<TController>
where TController : class, IReplayController
{
private readonly VersionMappingFactory _versionMappingFactory;
static ExtendedDataController() => Unpickler.registerConstructor("CamouflageInfo", "CamouflageInfo", new CamouflageInfo());
public ExtendedDataController(VersionMappingFactory versionMappingFactory, IDefinitionStore definitionStore, ILogger<Entity> entityLogger)
: base(definitionStore, entityLogger)
=> _versionMappingFactory = versionMappingFactory;
public ExtendedDataReplay ExtendedReplay => (ExtendedDataReplay)Replay;
/// <inheritdoc />
public override UnpackedReplay CreateUnpackedReplay(ArenaInfo arenaInfo)
{
Replay = new ExtendedDataReplay(arenaInfo);
return Replay;
}
/// <summary>
/// Triggered when a chat message is parsed from the replay.
/// </summary>
/// <param name="packetTime">The time the packet was received.</param>
/// <param name="entityId">The entity ID of the player who sent the message.</param>
/// <param name="messageGroup">The message group of the message (All/).</param>
/// <param name="messageContent">The content of the message.</param>
/// <param name="reserved1">Parameter unused</param>
[MethodSubscription("Avatar", "onChatMessage", IncludePacketTime = true)]
public void OnChatMessage(float packetTime, int entityId, string messageGroup, string messageContent, string reserved1)
{
ExtendedReplay.ChatMessages.Add(new((uint)entityId, packetTime, messageGroup, messageContent));
}
/// <summary>
/// Triggered when arena data is parsed from the replay.
/// </summary>
/// <param name="arguments">The arguments of the event.</param>
[MethodSubscription("Avatar", "onArenaStateReceived", ParamsAsDictionary = true)]
public void OnArenaStateReceived(Dictionary<string, object?> arguments)
{
byte[]? playerStatesData = (byte[]?)arguments["playersStates"];
if (playerStatesData is null)
{
return;
}
using Unpickler unpickler = new();
using MemoryStream memoryStream = new(playerStatesData);
ArrayList players = unpickler.load(memoryStream) as ArrayList ?? new();
foreach (ArrayList player in players)
{
AddPlayerToReplay(player);
}
}
private void AddPlayerToReplay(ArrayList properties)
{
IVersionMapping mapping = _versionMappingFactory.GetMappings(Replay!.ClientVersion);
ReplayPlayer replayPlayer = new(mapping.ShipConfigMapping);
foreach (object[] propertyArray in properties)
{
string? propertyName = mapping.ReplayPlayerPropertyMappings.GetValueOrDefault((int)propertyArray[0]);
if (string.IsNullOrEmpty(propertyName))
{
continue;
}
PropertyInfo? propertyInfo = ReplayPlayer.PropertyInfos.SingleOrDefault(x => x.Name == propertyName);
propertyInfo?.SetValue(replayPlayer, Convert.ChangeType(propertyArray[1], propertyInfo.PropertyType), null);
}
ExtendedReplay.ReplayPlayers.Add(replayPlayer);
}
}
}