diff --git a/AATool/AATool.csproj b/AATool/AATool.csproj
index 809fe4bb..d59750d8 100644
--- a/AATool/AATool.csproj
+++ b/AATool/AATool.csproj
@@ -150,6 +150,8 @@
+
+
@@ -478,6 +480,27 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -685,6 +708,102 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -1966,6 +2085,78 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -2263,6 +2454,12 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -2497,6 +2694,12 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -6490,6 +6693,15 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -6511,6 +6723,12 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -8876,9 +9094,7 @@
Designer
-
-
-
+
diff --git a/AATool/Data/Objectives/Criterion.cs b/AATool/Data/Objectives/Criterion.cs
index 0ee8d228..408b4f79 100644
--- a/AATool/Data/Objectives/Criterion.cs
+++ b/AATool/Data/Objectives/Criterion.cs
@@ -7,6 +7,8 @@ namespace AATool.Data.Objectives
{
public class Criterion : Objective
{
+ public static string Key(string advancement, string criterion) => $"{advancement} {criterion}";
+
public readonly Advancement Owner;
public Uuid DesignatedPlayer => this.Owner.DesignatedPlayer;
diff --git a/AATool/Data/Progress/Completion.cs b/AATool/Data/Progress/Completion.cs
index 5bd3061b..58a8bca7 100644
--- a/AATool/Data/Progress/Completion.cs
+++ b/AATool/Data/Progress/Completion.cs
@@ -1,18 +1,16 @@
using System;
using AATool.Net;
-using Newtonsoft.Json;
namespace AATool.Data.Progress
{
- [JsonObject]
public struct Completion
{
public static readonly Completion Empty = new (Uuid.Empty, default);
- [JsonProperty] public Uuid Player;
- [JsonProperty] public DateTime Timestamp;
+ public Uuid Player;
+ public DateTime Timestamp;
- [JsonIgnore] public bool IsEmpty => this.Player == Uuid.Empty;
+ public bool IsEmpty => this.Player == Uuid.Empty;
public Completion(Uuid player, DateTime timestamp)
{
diff --git a/AATool/Data/Progress/Contribution.cs b/AATool/Data/Progress/Contribution.cs
index 191ebecb..2919f3bb 100644
--- a/AATool/Data/Progress/Contribution.cs
+++ b/AATool/Data/Progress/Contribution.cs
@@ -1,38 +1,45 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using AATool.Data.Objectives;
using AATool.Net;
-using Newtonsoft.Json;
namespace AATool.Data.Progress
{
- [TypeConverter(typeof(Contribution))]
- [JsonObject]
public class Contribution : ProgressState
{
- [JsonProperty] public readonly Uuid Player;
-
- [JsonConstructor]
- public Contribution(Uuid Player,
- Dictionary Advancements,
- Dictionary<(string, string), Completion> Criteria,
- Dictionary Recipes)
- : base(Advancements, Criteria, Recipes)
- {
- this.Player = Player;
- }
+ public readonly Uuid Player;
public Contribution(Uuid Player) : base()
{
this.Player = Player;
}
- public static Contribution FromJsonString(string jsonString) =>
- JsonConvert.DeserializeObject(jsonString);
+ public Contribution(NetworkContribution network) : this(network.UUID)
+ {
+ this.Player = network.UUID;
+ this.InGameTime = network.InGameTime;
+ this.ObtainedGodApple = network.ObtainedGodApple;
- public string ToJsonString() =>
- JsonConvert.SerializeObject(this);
+ //add advancements
+ foreach (KeyValuePair advancement in network.Advancements)
+ this.Advancements[advancement.Key] = new Completion(this.Player, advancement.Value);
+ //add criteria
+ foreach (string criterion in network.Criteria)
+ this.Criteria[criterion] = default;
+ //add stats
+ foreach (KeyValuePair stat in network.PickupCounts)
+ this.PickupCounts[stat.Key] = stat.Value;
+ foreach (KeyValuePair stat in network.DropCounts)
+ this.DropCounts[stat.Key] = stat.Value;
+ foreach (KeyValuePair stat in network.MineCounts)
+ this.MineCounts[stat.Key] = stat.Value;
+ foreach (KeyValuePair stat in network.CraftCounts)
+ this.CraftCounts[stat.Key] = stat.Value;
+ foreach (KeyValuePair stat in network.UseCounts)
+ this.UseCounts[stat.Key] = stat.Value;
+ foreach (KeyValuePair stat in network.KillCounts)
+ this.KillCounts[stat.Key] = stat.Value;
+ }
public override HashSet CompletionsOf(IObjective objective)
{
@@ -45,7 +52,7 @@ public override HashSet CompletionsOf(IObjective objective)
}
else if (objective is Criterion criterion)
{
- if (this.Criteria.TryGetValue((criterion.OwnerId, criterion.Id), out Completion completion))
+ if (this.Criteria.TryGetValue(Criterion.Key(criterion.OwnerId, criterion.Id), out Completion completion))
completionists.Add(completion);
}
else if (objective is Block block)
diff --git a/AATool/Data/Progress/NetworkContribution.cs b/AATool/Data/Progress/NetworkContribution.cs
new file mode 100644
index 00000000..6efb58a5
--- /dev/null
+++ b/AATool/Data/Progress/NetworkContribution.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using AATool.Net;
+using Newtonsoft.Json;
+
+namespace AATool.Data.Progress
+{
+ [JsonObject]
+ [TypeConverter(typeof(NetworkContribution))]
+ public class NetworkContribution
+ {
+ [JsonProperty] public Uuid UUID { get; set; }
+ [JsonProperty] public Dictionary Advancements { get; set; }
+ [JsonProperty] public HashSet Criteria { get; set; }
+
+ [JsonProperty] public Dictionary PickupCounts { get; set; }
+ [JsonProperty] public Dictionary DropCounts { get; set; }
+ [JsonProperty] public Dictionary MineCounts { get; set; }
+ [JsonProperty] public Dictionary CraftCounts { get; set; }
+ [JsonProperty] public Dictionary UseCounts { get; set; }
+ [JsonProperty] public Dictionary KillCounts { get; set; }
+
+ [JsonProperty] public TimeSpan InGameTime { get; set; }
+ [JsonProperty] public double KilometersFlown { get; set; }
+ [JsonProperty] public bool ObtainedGodApple { get; set; }
+
+ public NetworkContribution()
+ {
+ this.Advancements = new();
+ this.Criteria = new();
+ this.PickupCounts = new();
+ this.DropCounts = new();
+ this.MineCounts = new();
+ this.CraftCounts = new();
+ this.UseCounts = new();
+ this.KillCounts = new();
+ }
+
+ public NetworkContribution(Contribution contribution) : this()
+ {
+ this.UUID = contribution.Player;
+ this.InGameTime = contribution.InGameTime;
+ this.ObtainedGodApple = contribution.ObtainedGodApple;
+
+ //add advancements
+ foreach (KeyValuePair advancement in contribution.Advancements)
+ this.Advancements[advancement.Key] = advancement.Value.Timestamp;
+ //add criteria
+ foreach (string criterion in contribution.Criteria.Keys)
+ this.Criteria.Add(criterion);
+
+ //add stats
+ foreach (KeyValuePair stat in contribution.PickupCounts)
+ this.PickupCounts[stat.Key] = stat.Value;
+ foreach (KeyValuePair stat in contribution.DropCounts)
+ this.DropCounts[stat.Key] = stat.Value;
+ foreach (KeyValuePair stat in contribution.MineCounts)
+ this.MineCounts[stat.Key] = stat.Value;
+ foreach (KeyValuePair stat in contribution.CraftCounts)
+ this.CraftCounts[stat.Key] = stat.Value;
+ foreach (KeyValuePair stat in contribution.UseCounts)
+ this.UseCounts[stat.Key] = stat.Value;
+ foreach (KeyValuePair stat in contribution.KillCounts)
+ this.KillCounts[stat.Key] = stat.Value;
+ }
+ }
+}
diff --git a/AATool/Data/Progress/NetworkState.cs b/AATool/Data/Progress/NetworkState.cs
new file mode 100644
index 00000000..881801c8
--- /dev/null
+++ b/AATool/Data/Progress/NetworkState.cs
@@ -0,0 +1,36 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace AATool.Data.Progress
+{
+ [JsonObject]
+ public class NetworkState
+ {
+ [JsonProperty] public List Players { get; set; }
+ [JsonProperty] public string GameCategory { get; set; }
+ [JsonProperty] public string GameVersion { get; set; }
+
+ [JsonConstructor]
+ public NetworkState()
+ {
+ this.Players = new ();
+ }
+
+ public NetworkState(WorldState state) : this()
+ {
+ //copy world state
+ foreach (Contribution player in state.Players.Values)
+ this.Players.Add(new NetworkContribution(player));
+
+ //store current game category and version
+ this.GameCategory = Tracker.CurrentCategory;
+ this.GameVersion = Tracker.CurrentVersion;
+ }
+
+ public static NetworkState FromJsonString(string jsonString) =>
+ JsonConvert.DeserializeObject(jsonString);
+
+ public string ToJsonString() =>
+ JsonConvert.SerializeObject(this);
+ }
+}
diff --git a/AATool/Data/Progress/ProgressState.cs b/AATool/Data/Progress/ProgressState.cs
index b350f900..4d10ebe6 100644
--- a/AATool/Data/Progress/ProgressState.cs
+++ b/AATool/Data/Progress/ProgressState.cs
@@ -1,50 +1,36 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using AATool.Data.Objectives;
-using Newtonsoft.Json;
namespace AATool.Data.Progress
{
- [TypeConverter(typeof(ProgressState))]
- [JsonObject]
public abstract class ProgressState
{
- [JsonProperty] public Dictionary Advancements { get; set; }
- [JsonProperty] public Dictionary Recipes { get; set; }
- [JsonProperty] public Dictionary<(string adv, string crit), Completion> Criteria { get; set; }
- [JsonProperty] public HashSet DeathMessages { get; set; }
-
- [JsonProperty] public Dictionary PickupCounts { get; set; }
- [JsonProperty] public Dictionary DropCounts { get; set; }
- [JsonProperty] public Dictionary MineCounts { get; set; }
- [JsonProperty] public Dictionary CraftCounts { get; set; }
- [JsonProperty] public Dictionary UseCounts { get; set; }
- [JsonProperty] public Dictionary KillCounts { get; set; }
-
- [JsonProperty] public TimeSpan InGameTime { get; set; }
-
- [JsonProperty] public double KilometersFlown { get; set; }
-
- [JsonProperty] public bool ObtainedGodApple { get; set; }
-
- [JsonProperty] public int Deaths { get; set; }
- [JsonProperty] public int DamageTaken { get; set; }
- [JsonProperty] public int DamageDealt { get; set; }
- [JsonProperty] public int Jumps { get; set; }
- [JsonProperty] public int Sleeps { get; set; }
- [JsonProperty] public int SaveAndQuits { get; set; }
- [JsonProperty] public int ItemsEnchanted { get; set; }
-
- [JsonConstructor]
- public ProgressState(Dictionary Advancements,
- Dictionary<(string, string), Completion> Criteria,
- Dictionary Recipes)
- {
- this.Advancements = Advancements;
- this.Criteria = Criteria;
- this.Recipes = Recipes;
- }
+ public Dictionary Advancements { get; set; }
+ public Dictionary Criteria { get; set; }
+ public Dictionary Recipes { get; set; }
+ public HashSet DeathMessages { get; set; }
+
+ public Dictionary PickupCounts { get; set; }
+ public Dictionary DropCounts { get; set; }
+ public Dictionary MineCounts { get; set; }
+ public Dictionary CraftCounts { get; set; }
+ public Dictionary UseCounts { get; set; }
+ public Dictionary KillCounts { get; set; }
+
+ public TimeSpan InGameTime { get; set; }
+
+ public double KilometersFlown { get; set; }
+
+ public bool ObtainedGodApple { get; set; }
+
+ public int Deaths { get; set; }
+ public int DamageTaken { get; set; }
+ public int DamageDealt { get; set; }
+ public int Jumps { get; set; }
+ public int Sleeps { get; set; }
+ public int SaveAndQuits { get; set; }
+ public int ItemsEnchanted { get; set; }
public ProgressState()
{
@@ -59,13 +45,14 @@ public ProgressState()
this.UseCounts = new ();
this.KillCounts = new ();
}
+
public abstract HashSet CompletionsOf(IObjective objective);
public bool AdvancementCompleted(string id) =>
this.Advancements.ContainsKey(id);
public bool CriterionCompleted(string advancement, string criterion) =>
- this.Criteria.ContainsKey((advancement, criterion));
+ this.Criteria.ContainsKey(Criterion.Key(advancement, criterion));
public bool WasPickedUp(string name) =>
this.PickupCounts.ContainsKey(name);
diff --git a/AATool/Data/Progress/WorldState.cs b/AATool/Data/Progress/WorldState.cs
index a5d2a657..319158b8 100644
--- a/AATool/Data/Progress/WorldState.cs
+++ b/AATool/Data/Progress/WorldState.cs
@@ -1,68 +1,67 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
+using System.Collections.Generic;
using AATool.Data.Objectives;
using AATool.Net;
using AATool.Utilities;
-using Newtonsoft.Json;
namespace AATool.Data.Progress
{
- [TypeConverter(typeof(WorldState))]
- [JsonObject]
public class WorldState : ProgressState
{
public static readonly WorldState Empty = new ();
- [JsonProperty] public Dictionary Players { get; set; }
+ public Dictionary Players { get; set; }
- [JsonProperty] public string GameCategory { get; set; }
- [JsonProperty] public string GameVersion { get; set; }
-
- public WorldState()
+ public WorldState() : base()
{
- this.Advancements = new ();
- this.Criteria = new ();
- this.DeathMessages = new ();
this.Players = new ();
}
- public string ToJsonString()
- {
- //store current category and version data then serialize
- this.GameCategory = Tracker.CurrentCategory;
- this.GameVersion = Tracker.CurrentVersion;
- return JsonConvert.SerializeObject(this);
- }
-
- public static WorldState FromJsonString(string jsonString)
+ public WorldState(NetworkState state) : this()
{
- try
+ //copy co-op state
+ foreach (NetworkContribution player in state.Players)
{
- //deserialize progress
- dynamic json = JsonConvert.DeserializeObject(jsonString);
- WorldState state = JsonConvert.DeserializeObject(jsonString);
+ //individual progress
+ var contribution = new Contribution(player);
+ this.Players[new Uuid(player.UUID.String)] = contribution;
- //clone complex data structures
- state.Advancements = json.CompletedAdvancements;
- state.Criteria = json.CompletedCriteria;
- state.Players = json.Players;
- state.PickupCounts = json.PickedUp;
- state.DropCounts = json.Dropped;
- state.MineCounts = json.Mined;
- state.CraftCounts = json.Crafted;
- state.UseCounts = json.Used;
- state.KillCounts = json.Killed;
+ //combined advancements
+ foreach (KeyValuePair advancement in contribution.Advancements)
+ {
+ if (!this.Advancements.TryGetValue(advancement.Key, out Completion first) || advancement.Value.Before(first.Timestamp))
+ this.Advancements[advancement.Key] = advancement.Value;
+ }
- //make sure everyone's names and avatars are loaded
- foreach (KeyValuePair contribution in state.Players)
- Player.FetchIdentityAsync(contribution.Key);
- return state;
+ //combined criteria
+ foreach (KeyValuePair criterion in contribution.Criteria)
+ {
+ if (!this.Criteria.TryGetValue(criterion.Key, out Completion first) || criterion.Value.Before(first.Timestamp))
+ this.Criteria[criterion.Key] = criterion.Value;
+ }
+
+ //combined stats
+ this.CopyStats(player.PickupCounts, this.PickupCounts);
+ this.CopyStats(player.DropCounts, this.DropCounts);
+ this.CopyStats(player.MineCounts, this.MineCounts);
+ this.CopyStats(player.CraftCounts, this.CraftCounts);
+ this.CopyStats(player.UseCounts, this.UseCounts);
+ this.CopyStats(player.KillCounts, this.KillCounts);
+
+ //enchanted golden apple
+ this.ObtainedGodApple |= contribution.ObtainedGodApple;
+
+ //ingame time
+ if (contribution.InGameTime > this.InGameTime)
+ this.InGameTime = contribution.InGameTime;
}
- catch
+ }
+
+ private void CopyStats(Dictionary source, Dictionary destination)
+ {
+ foreach (KeyValuePair statistic in source)
{
- //error deserializing world state
- return new WorldState();
+ _= destination.TryGetValue(statistic.Key, out int existing);
+ destination[statistic.Key] = existing + statistic.Value;
}
}
@@ -82,7 +81,7 @@ public override HashSet CompletionsOf(IObjective objective)
{
foreach (KeyValuePair player in this.Players)
{
- if (player.Value.Criteria.TryGetValue((criterion.Owner.Id, criterion.Id), out Completion completion))
+ if (player.Value.Criteria.TryGetValue(Criterion.Key(criterion.Owner.Id, criterion.Id), out Completion completion))
completionists.Add(completion);
}
}
@@ -90,7 +89,7 @@ public override HashSet CompletionsOf(IObjective objective)
{
foreach (KeyValuePair player in this.Players)
{
- if (player.Value.UseCounts.ContainsKey(block.Id))
+ if (player.Value.UseCounts.ContainsKey(block.Id) is true)
completionists.Add(new Completion(player.Key, default));
}
}
@@ -104,18 +103,18 @@ public override HashSet CompletionsOf(IObjective objective)
public void SyncDeathMessages()
{
- if (ActiveInstance.TryGetLog(out string log) && Player.TryGetName(Tracker.GetMainPlayer(), out string name))
+ if (!ActiveInstance.TryGetLog(out string log) || !Player.TryGetName(Tracker.GetMainPlayer(), out string name))
+ return;
+
+ log = log.ToLower();
+ foreach (Death death in Tracker.Deaths.All.Values)
{
- log = log.ToLower();
- foreach (Death death in Tracker.Deaths.All.Values)
+ foreach (string message in death.Messages)
{
- foreach (string message in death.Messages)
+ if (log.Contains($"[server thread/info]: {name.ToLower()} {message}"))
{
- if (log.Contains($"[server thread/info]: {name.ToLower()} {message}"))
- {
- this.DeathMessages.Add(death.Id);
- break;
- }
+ this.DeathMessages.Add(death.Id);
+ break;
}
}
}
diff --git a/AATool/Net/OpenTracker.cs b/AATool/Net/OpenTracker.cs
index cec56040..47015b68 100644
--- a/AATool/Net/OpenTracker.cs
+++ b/AATool/Net/OpenTracker.cs
@@ -43,7 +43,7 @@ public static async void BroadcastProgress()
try
{
string aaKey = AAKey.Strip(Config.Tracking.OpenTrackerKey);
- var content = new StringContent(aaKey + Tracker.State.ToJsonString());
+ var content = new StringContent(aaKey);// + Tracker.State.ToJsonString());
HttpResponseMessage response = await Client.PostAsync(Config.Tracking.OpenTrackerUrl, content);
string message = await response.Content.ReadAsStringAsync();
WatchUrl = message;
diff --git a/AATool/Net/Protocol.cs b/AATool/Net/Protocol.cs
index 4dd2f046..728f2e56 100644
--- a/AATool/Net/Protocol.cs
+++ b/AATool/Net/Protocol.cs
@@ -4,9 +4,9 @@ namespace AATool.Net
{
public static class Protocol
{
- public static readonly Version Version = new ("7.0");
+ public static readonly Version Version = new ("8.0");
- public const int BufferSize = 8192;
+ public const int BufferSize = 1024 * 1000;
public const char CommandPrefix = '/';
public const char DataPrefix = '$';
public const char TokenDelimiter = '\n';
diff --git a/AATool/Net/Server.cs b/AATool/Net/Server.cs
index 5dd9f220..a4073d50 100644
--- a/AATool/Net/Server.cs
+++ b/AATool/Net/Server.cs
@@ -5,6 +5,7 @@
using System.Net.Sockets;
using AATool.Configuration;
using AATool.Data.Categories;
+using AATool.Data.Progress;
using AATool.Net.Requests;
using AATool.Saves;
@@ -88,7 +89,7 @@ public void SendBlockHighlights(Socket client = null)
public void SendProgress(Socket client = null)
{
- string jsonString = Tracker.State.ToJsonString();
+ string jsonString = new NetworkState(Tracker.State).ToJsonString();
var message = Message.Progress(jsonString);
//send lobby state to client(s)
diff --git a/AATool/Net/Uuid.cs b/AATool/Net/Uuid.cs
index 194f81f3..4157e977 100644
--- a/AATool/Net/Uuid.cs
+++ b/AATool/Net/Uuid.cs
@@ -6,8 +6,7 @@ namespace AATool.Net
[JsonObject]
public readonly struct Uuid
{
- [JsonIgnore]
- public static readonly Uuid Empty = new (Guid.Empty);
+ [JsonIgnore] public static readonly Uuid Empty = new (Guid.Empty);
[JsonProperty] public readonly string String;
[JsonProperty] public readonly string ShortString;
diff --git a/AATool/Properties/AssemblyInfo.cs b/AATool/Properties/AssemblyInfo.cs
index eed88eeb..2ac4e1e1 100644
--- a/AATool/Properties/AssemblyInfo.cs
+++ b/AATool/Properties/AssemblyInfo.cs
@@ -33,6 +33,6 @@
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.5.1.1")]
-[assembly: AssemblyFileVersion("1.5.1.1")]
+[assembly: AssemblyVersion("1.5.2.0")]
+[assembly: AssemblyFileVersion("1.5.2.0")]
[assembly: NeutralResourcesLanguage("en")]
diff --git a/AATool/Saves/AchievementsFolder.cs b/AATool/Saves/AchievementsFolder.cs
index a221e764..89c3d21d 100644
--- a/AATool/Saves/AchievementsFolder.cs
+++ b/AATool/Saves/AchievementsFolder.cs
@@ -20,9 +20,9 @@ private static bool IsCompleted(string achievement, JsonStream json)
return false;
}
- private HashSet<(string adv, string crit)> GetCompletedCriteria(Advancement advancement, JsonStream json)
+ private HashSet GetCompletedCriteria(Advancement advancement, JsonStream json)
{
- HashSet<(string, string)> completed = new ();
+ HashSet completed = new ();
dynamic criteriaList = json?[advancement.Id]?["progress"];
if (criteriaList is not null)
{
@@ -34,7 +34,7 @@ private static bool IsCompleted(string achievement, JsonStream json)
{
string criterion = tokens[1];
if (advancement.Criteria.Contains(criterion))
- completed.Add((advancement.Id, criterion));
+ completed.Add(Criterion.Key(advancement.Id, criterion));
}
}
}
@@ -79,10 +79,10 @@ protected override void Update(JsonStream json, WorldState state, Contribution c
if (achievement.HasCriteria)
{
- foreach ((string adv, string crit) criterion in this.GetCompletedCriteria(achievement, json))
+ foreach (string criterion in this.GetCompletedCriteria(achievement, json))
{
state.Criteria.Add(criterion, new Completion(json.Player, default));
- contribution.Criteria.Add((criterion.adv, criterion.crit),
+ contribution.Criteria.Add(criterion,
new Completion(json.Player, default));
}
}
diff --git a/AATool/Saves/AdvancementsFolder.cs b/AATool/Saves/AdvancementsFolder.cs
index 74a704c3..d248618f 100644
--- a/AATool/Saves/AdvancementsFolder.cs
+++ b/AATool/Saves/AdvancementsFolder.cs
@@ -12,7 +12,7 @@ public class AdvancementsFolder : JsonFolder
{
private class AdvancementCompletion
{
- public readonly Dictionary<(string adv, string crit), DateTime> CriteriaTimestamps;
+ public readonly Dictionary CriteriaTimestamps;
public readonly Uuid Player;
public readonly string Id;
public readonly bool AdvancementDone;
@@ -24,13 +24,13 @@ public AdvancementCompletion(JsonStream json, dynamic token, string advancement)
this.Id = advancement;
this.Player = json.Player;
this.Timestamp = DateTime.MinValue;
- this.CriteriaTimestamps = new Dictionary<(string adv, string crit), DateTime>();
+ this.CriteriaTimestamps = new Dictionary();
this.AdvancementDone = token?["done"] == true;
}
public void AddCriterion(string adv, string crit, DateTime completed)
{
- this.CriteriaTimestamps[(adv, crit)] = completed;
+ this.CriteriaTimestamps[Criterion.Key(adv, crit)] = completed;
if (completed > this.Timestamp)
this.Timestamp = completed;
}
@@ -111,7 +111,7 @@ private void UpdateAdvancements(AdvancementCompletion advancement, WorldState st
private void UpdateCriteria(AdvancementCompletion advancement, WorldState state, Contribution contribution)
{
- foreach (KeyValuePair<(string adv, string crit), DateTime> criterion in advancement.CriteriaTimestamps)
+ foreach (KeyValuePair criterion in advancement.CriteriaTimestamps)
{
//update individual player progress
var completion = new Completion(advancement.Player, criterion.Value);
diff --git a/AATool/Tracker.cs b/AATool/Tracker.cs
index ef2f5812..996c15b8 100644
--- a/AATool/Tracker.cs
+++ b/AATool/Tracker.cs
@@ -230,6 +230,9 @@ public static string GetStatusText()
public static bool TrySetCategory(string category)
{
+ if (string.IsNullOrEmpty(category))
+ return false;
+
//check if category is the same
if (Category is not null && category == Category.Name)
return false;
@@ -477,18 +480,19 @@ private static void UpdateCurrentWorld()
private static void ParseCoOpProgress(Time time, Client client)
{
//update world from co-op server
- if (client is null || !client.TryGetData(Protocol.Headers.Progress, out string jsonString))
+ if (client is null || !client.TryGetData(Protocol.Headers.Progress, out string progress))
return;
- if (LastServerMessage != jsonString)
+ if (LastServerMessage != progress)
{
CoOpStateChanged = true;
- LastServerMessage = jsonString;
- State = WorldState.FromJsonString(jsonString);
+ LastServerMessage = progress;
+ var networkState = NetworkState.FromJsonString(progress);
+ State = new WorldState(networkState);
//sync category and version with host
- TrySetCategory(State.GameCategory);
- TrySetVersion(State.GameVersion);
+ TrySetCategory(networkState.GameCategory);
+ TrySetVersion(networkState.GameVersion);
//reload objectives if game version has changed
if (ObjectivesChanged)
diff --git a/AATool/Winforms/Controls/CMainSettings.cs b/AATool/Winforms/Controls/CMainSettings.cs
index 065f9c4c..7a635cc7 100644
--- a/AATool/Winforms/Controls/CMainSettings.cs
+++ b/AATool/Winforms/Controls/CMainSettings.cs
@@ -47,7 +47,7 @@ public void LoadSettings()
this.startupPosition.Text = Config.Main.StartupArrangement.Value.ToString();
this.UpdateMonitorList();
- this.startupMonitor.SelectedIndex = MathHelper.Clamp(Config.Main.StartupDisplay - 1, 0, this.startupMonitor.Items.Count);
+ this.startupMonitor.SelectedIndex = MathHelper.Clamp(Config.Main.StartupDisplay - 1, 0, this.startupMonitor.Items.Count - 1);
this.startupMonitor.Enabled = this.startupPosition.Text != "Remember";
//colors