feat: handle pets
This commit is contained in:
parent
60d766ced4
commit
d93a189c5c
15
Client.cs
15
Client.cs
@ -6,7 +6,7 @@ using Newtonsoft.Json.Linq;
|
|||||||
namespace PartyDamage;
|
namespace PartyDamage;
|
||||||
|
|
||||||
public class Client : IDisposable {
|
public class Client : IDisposable {
|
||||||
private ClientWebSocket WebSocket { get; }
|
private ClientWebSocket? WebSocket { get; set; }
|
||||||
private CancellationTokenSource TokenSource { get; }
|
private CancellationTokenSource TokenSource { get; }
|
||||||
private Task? MainTask { get; set; }
|
private Task? MainTask { get; set; }
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
@ -14,7 +14,6 @@ public class Client : IDisposable {
|
|||||||
internal CombatData? Data { get; private set; }
|
internal CombatData? Data { get; private set; }
|
||||||
|
|
||||||
internal Client() {
|
internal Client() {
|
||||||
this.WebSocket = new ClientWebSocket();
|
|
||||||
this.TokenSource = new CancellationTokenSource();
|
this.TokenSource = new CancellationTokenSource();
|
||||||
this.MainTask = Task.Run(async () => {
|
this.MainTask = Task.Run(async () => {
|
||||||
while (!this._disposed) {
|
while (!this._disposed) {
|
||||||
@ -37,10 +36,11 @@ public class Client : IDisposable {
|
|||||||
|
|
||||||
this._disposed = true;
|
this._disposed = true;
|
||||||
this.TokenSource.Cancel();
|
this.TokenSource.Cancel();
|
||||||
this.WebSocket.Dispose();
|
this.WebSocket?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Main() {
|
private async Task Main() {
|
||||||
|
this.WebSocket = new ClientWebSocket();
|
||||||
await this.WebSocket.ConnectAsync(new Uri("ws://127.0.0.1:10501/ws"), this.TokenSource.Token);
|
await this.WebSocket.ConnectAsync(new Uri("ws://127.0.0.1:10501/ws"), this.TokenSource.Token);
|
||||||
const string msg = "{\"call\": \"subscribe\", \"events\": [\"CombatData\"]}";
|
const string msg = "{\"call\": \"subscribe\", \"events\": [\"CombatData\"]}";
|
||||||
var msgBytes = Encoding.UTF8.GetBytes(msg);
|
var msgBytes = Encoding.UTF8.GetBytes(msg);
|
||||||
@ -60,8 +60,13 @@ public class Client : IDisposable {
|
|||||||
|
|
||||||
var jobj = JObject.Parse(text);
|
var jobj = JObject.Parse(text);
|
||||||
if (jobj["type"]?.Value<string>() == "CombatData") {
|
if (jobj["type"]?.Value<string>() == "CombatData") {
|
||||||
var data = JsonConvert.DeserializeObject<CombatData>(text);
|
var data = JsonConvert.DeserializeObject<RawCombatData>(text);
|
||||||
this.Data = data;
|
if (data == null) {
|
||||||
|
this.Data = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Data = new CombatData(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
107
CombatData.cs
107
CombatData.cs
@ -1,89 +1,38 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
using Newtonsoft.Json.Serialization;
|
|
||||||
|
|
||||||
namespace PartyDamage;
|
namespace PartyDamage;
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class CombatData {
|
public class CombatData {
|
||||||
public Encounter Encounter;
|
public Encounter Encounter { get; }
|
||||||
|
public Dictionary<string, Combatant> Combatants { get; } = [];
|
||||||
|
|
||||||
[JsonProperty("Combatant")]
|
public CombatData(RawCombatData raw) {
|
||||||
public Dictionary<string, Combatant> Combatants;
|
foreach (var (key, value) in raw.Combatants) {
|
||||||
|
this.Combatants[key] = new Combatant {
|
||||||
|
Name = value.Name,
|
||||||
|
EncDps = TryFloat(value.EncDps),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Encounter = new Encounter {
|
||||||
|
Title = raw.Encounter.Title,
|
||||||
|
EncDps = TryFloat(raw.Encounter.EncDps),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float TryFloat(string input, float def = float.NaN) {
|
||||||
|
if (!float.TryParse(input, out var result)) {
|
||||||
|
result = def;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
[JsonObject(NamingStrategyType = typeof(SnakeCaseNamingStrategy))]
|
|
||||||
public class Encounter {
|
public class Encounter {
|
||||||
[JsonProperty("n")]
|
public string Title { get; init; }
|
||||||
public char N;
|
public float EncDps { get; init; }
|
||||||
|
|
||||||
[JsonProperty("t")]
|
|
||||||
public char T;
|
|
||||||
|
|
||||||
public string Title;
|
|
||||||
|
|
||||||
public string Duration;
|
|
||||||
|
|
||||||
public string Damage;
|
|
||||||
|
|
||||||
public string Dps;
|
|
||||||
|
|
||||||
[JsonProperty("encdps")]
|
|
||||||
public string EncDps;
|
|
||||||
|
|
||||||
public string Hits;
|
|
||||||
|
|
||||||
[JsonProperty("crithits")]
|
|
||||||
public string CritHits;
|
|
||||||
|
|
||||||
public string Misses;
|
|
||||||
|
|
||||||
[JsonProperty("hitfailed")]
|
|
||||||
public string HitFailed;
|
|
||||||
|
|
||||||
public string Swings;
|
|
||||||
|
|
||||||
public string Healed;
|
|
||||||
|
|
||||||
[JsonProperty("enchps")]
|
|
||||||
public string EncHps;
|
|
||||||
|
|
||||||
[JsonProperty("CurrentZoneName")]
|
|
||||||
public string CurrentZoneName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
[JsonObject(NamingStrategyType = typeof(SnakeCaseNamingStrategy))]
|
|
||||||
public class Combatant {
|
public class Combatant {
|
||||||
public string Name;
|
public string Name { get; init; }
|
||||||
|
public float EncDps { get; init; }
|
||||||
public string Duration;
|
}
|
||||||
|
|
||||||
public string Damage;
|
|
||||||
|
|
||||||
public string Dps;
|
|
||||||
|
|
||||||
[JsonProperty("encdps")]
|
|
||||||
public string EncDps;
|
|
||||||
|
|
||||||
// seems like newtonsoft gets confused if we don't also specify this one
|
|
||||||
[JsonProperty("ENCDPS")]
|
|
||||||
public string EncDps2;
|
|
||||||
|
|
||||||
public string Hits;
|
|
||||||
|
|
||||||
[JsonProperty("crithits")]
|
|
||||||
public string CritHits;
|
|
||||||
|
|
||||||
public string Misses;
|
|
||||||
|
|
||||||
[JsonProperty("hitfailed")]
|
|
||||||
public string HitFailed;
|
|
||||||
|
|
||||||
public string Swings;
|
|
||||||
|
|
||||||
public string Healed;
|
|
||||||
|
|
||||||
[JsonProperty("enchps")]
|
|
||||||
public string EncHps;
|
|
||||||
}
|
|
36
Plugin.cs
36
Plugin.cs
@ -52,6 +52,15 @@ public class Plugin : IDalamudPlugin {
|
|||||||
|
|
||||||
var numPlayers = list->PartyMembers.Length;
|
var numPlayers = list->PartyMembers.Length;
|
||||||
foreach (var combatant in data.Combatants.Values) {
|
foreach (var combatant in data.Combatants.Values) {
|
||||||
|
if (combatant.Name.EndsWith(" (YOU)")) {
|
||||||
|
var name = combatant.Name[..^6];
|
||||||
|
var nameNode = list->Pet.Name;
|
||||||
|
if (nameNode != null && nameNode->NodeText.ToString() == name) {
|
||||||
|
this.UpdateMember(list->Pet, combatant);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var idx = combatant.Name == "YOU"
|
var idx = combatant.Name == "YOU"
|
||||||
? 0
|
? 0
|
||||||
: names.IndexOf(combatant.Name);
|
: names.IndexOf(combatant.Name);
|
||||||
@ -59,18 +68,21 @@ public class Plugin : IDalamudPlugin {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!float.TryParse(combatant.EncDps, out var dps)) {
|
this.UpdateMember(list->PartyMembers[idx], combatant);
|
||||||
dps = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
var dpsText = dps switch {
|
|
||||||
float.PositiveInfinity => "0",
|
|
||||||
float.NegativeInfinity => "0",
|
|
||||||
< 1_000 => dps.ToString("N1"),
|
|
||||||
< 1_000_000 => $"{dps / 1_000:N1}K",
|
|
||||||
_ => $"{dps / 1_000_000:N1}M",
|
|
||||||
};
|
|
||||||
list->PartyMembers[idx].Name->SetText(dpsText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private unsafe void UpdateMember(AddonPartyList.PartyListMemberStruct member, Combatant combatant) {
|
||||||
|
var dpsText = combatant.EncDps switch {
|
||||||
|
float.NaN => "?",
|
||||||
|
float.PositiveInfinity => "0",
|
||||||
|
float.NegativeInfinity => "0",
|
||||||
|
< 1_000 => combatant.EncDps.ToString("N1"),
|
||||||
|
< 1_000_000 => $"{combatant.EncDps / 1_000:N1}K",
|
||||||
|
< 1_000_000_000 => $"{combatant.EncDps / 1_000_000:N1}M",
|
||||||
|
_ => combatant.EncDps.ToString("N1"),
|
||||||
|
};
|
||||||
|
|
||||||
|
member.Name->SetText(dpsText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
92
RawCombatData.cs
Normal file
92
RawCombatData.cs
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
|
||||||
|
namespace PartyDamage;
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class RawCombatData {
|
||||||
|
public RawEncounter Encounter;
|
||||||
|
|
||||||
|
[JsonProperty("Combatant")]
|
||||||
|
public Dictionary<string, RawCombatant> Combatants;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
[JsonObject(NamingStrategyType = typeof(SnakeCaseNamingStrategy))]
|
||||||
|
public class RawEncounter {
|
||||||
|
[JsonProperty("n")]
|
||||||
|
public char N;
|
||||||
|
|
||||||
|
[JsonProperty("t")]
|
||||||
|
public char T;
|
||||||
|
|
||||||
|
public string Title;
|
||||||
|
|
||||||
|
public string Duration;
|
||||||
|
|
||||||
|
public string Damage;
|
||||||
|
|
||||||
|
public string Dps;
|
||||||
|
|
||||||
|
[JsonProperty("encdps")]
|
||||||
|
public string EncDps;
|
||||||
|
|
||||||
|
[JsonProperty("ENCDPS")]
|
||||||
|
public string EncDps2;
|
||||||
|
|
||||||
|
public string Hits;
|
||||||
|
|
||||||
|
[JsonProperty("crithits")]
|
||||||
|
public string CritHits;
|
||||||
|
|
||||||
|
public string Misses;
|
||||||
|
|
||||||
|
[JsonProperty("hitfailed")]
|
||||||
|
public string HitFailed;
|
||||||
|
|
||||||
|
public string Swings;
|
||||||
|
|
||||||
|
public string Healed;
|
||||||
|
|
||||||
|
[JsonProperty("enchps")]
|
||||||
|
public string EncHps;
|
||||||
|
|
||||||
|
[JsonProperty("CurrentZoneName")]
|
||||||
|
public string CurrentZoneName;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
[JsonObject(NamingStrategyType = typeof(SnakeCaseNamingStrategy))]
|
||||||
|
public class RawCombatant {
|
||||||
|
public string Name;
|
||||||
|
|
||||||
|
public string Duration;
|
||||||
|
|
||||||
|
public string Damage;
|
||||||
|
|
||||||
|
public string Dps;
|
||||||
|
|
||||||
|
[JsonProperty("encdps")]
|
||||||
|
public string EncDps;
|
||||||
|
|
||||||
|
// seems like newtonsoft gets confused if we don't also specify this one
|
||||||
|
[JsonProperty("ENCDPS")]
|
||||||
|
public string EncDps2;
|
||||||
|
|
||||||
|
public string Hits;
|
||||||
|
|
||||||
|
[JsonProperty("crithits")]
|
||||||
|
public string CritHits;
|
||||||
|
|
||||||
|
public string Misses;
|
||||||
|
|
||||||
|
[JsonProperty("hitfailed")]
|
||||||
|
public string HitFailed;
|
||||||
|
|
||||||
|
public string Swings;
|
||||||
|
|
||||||
|
public string Healed;
|
||||||
|
|
||||||
|
[JsonProperty("enchps")]
|
||||||
|
public string EncHps;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user