Skip to content

Commit

Permalink
Fix equipped charms not syncing
Browse files Browse the repository at this point in the history
  • Loading branch information
Extremelyd1 committed Oct 27, 2024
1 parent c9defaf commit ad5d966
Show file tree
Hide file tree
Showing 3 changed files with 485 additions and 35 deletions.
6 changes: 6 additions & 0 deletions HKMP/Game/Client/Save/SaveDataMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ public static SaveDataMapping Instance {
/// </summary>
[JsonProperty("vectorListVariables")]
public readonly List<string> VectorListVariables;

/// <summary>
/// Deserialized list of strings that represent variable names with the type of integer list.
/// </summary>
[JsonProperty("intListVariables")]
public readonly List<string> IntListVariables;

/// <summary>
/// Initializes the class by converting the deserialized data fields into the various dictionaries and lookups.
Expand Down
86 changes: 51 additions & 35 deletions HKMP/Game/Client/Save/SaveManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ internal class SaveManager {
/// </summary>
private readonly List<PersistentFsmData> _persistentFsmData;

/// <summary>
/// Dictionary of hash codes for string list variables in the PlayerData for comparing changes against.
/// </summary>
private readonly Dictionary<string, int> _stringListHashes;

/// <summary>
/// Dictionary of BossSequenceDoor.Completion structs in the PlayerData for comparing changes against.
/// </summary>
Expand All @@ -67,9 +62,9 @@ internal class SaveManager {
private readonly Dictionary<string, BossStatue.Completion> _bsCompHashes;

/// <summary>
/// Dictionary of hash codes for vector list variables in the PlayerData for comparing changes against.
/// Dictionary of hash codes for list variables in the PlayerData for comparing changes against.
/// </summary>
private readonly Dictionary<string, int> _vectorListHashes;
private readonly Dictionary<string, int> _listHashes;

/// <summary>
/// List of FieldInfo for fields in PlayerData that are simple values that should be synced. Used for looping
Expand All @@ -95,10 +90,9 @@ public SaveManager(NetClient netClient, PacketManager packetManager, EntityManag
_saveChanges = new SaveChanges();

_persistentFsmData = new List<PersistentFsmData>();
_stringListHashes = new Dictionary<string, int>();
_bsdCompHashes = new Dictionary<string, BossSequenceDoor.Completion>();
_bsCompHashes = new Dictionary<string, BossStatue.Completion>();
_vectorListHashes = new Dictionary<string, int>();
_listHashes = new Dictionary<string, int>();
_playerDataSyncFields = new List<FieldInfo>();
}

Expand Down Expand Up @@ -308,6 +302,25 @@ byte[] EncodeVector3(Vector3 vec3Value) {
return [(byte) mapZone];
}

if (value is List<int> intListValue) {
if (intListValue.Count > byte.MaxValue) {
throw new ArgumentOutOfRangeException($"Could not encode int list length: {intListValue.Count}");
}

var length = (byte) intListValue.Count;

// Create a byte array for the encoded result that has the size of the length of the int list plus one
// for the length itself
var byteArray = new byte[length + 1];
byteArray[0] = length;

for (var i = 0; i < length; i++) {
byteArray[i + 1] = (byte) intListValue[i];
}

return byteArray;
}

throw new ArgumentException($"No encoding implementation for type: {value.GetType()}");
}

Expand Down Expand Up @@ -642,8 +655,8 @@ Func<TCheck, TCheck, bool> changeFunc

CheckUpdates<List<string>, int>(
SaveDataMapping.StringListVariables,
_stringListHashes,
GetStringListHashCode,
_listHashes,
GetListHashCode,
(hash1, hash2) => hash1 != hash2
);

Expand Down Expand Up @@ -679,8 +692,15 @@ Func<TCheck, TCheck, bool> changeFunc

CheckUpdates<List<Vector3>, int>(
SaveDataMapping.VectorListVariables,
_vectorListHashes,
GetVectorListHashCode,
_listHashes,
GetListHashCode,
(hash1, hash2) => hash1 != hash2
);

CheckUpdates<List<int>, int>(
SaveDataMapping.IntListVariables,
_listHashes,
GetListHashCode,
(hash1, hash2) => hash1 != hash2
);
}
Expand Down Expand Up @@ -800,7 +820,7 @@ private void UpdateSaveWithData(ushort index, byte[] encodedValue) {
}

// First set the new string list hash, so we don't trigger an update and subsequently a feedback loop
_stringListHashes[name] = GetStringListHashCode(list);
_listHashes[name] = GetListHashCode(list);

pd.SetVariableInternal(name, list);
} else if (type == typeof(BossSequenceDoor.Completion)) {
Expand Down Expand Up @@ -861,7 +881,7 @@ private void UpdateSaveWithData(ushort index, byte[] encodedValue) {
}

// First set the new string list hash, so we don't trigger an update and subsequently a feedback loop
_vectorListHashes[name] = GetVectorListHashCode(list);
_listHashes[name] = GetListHashCode(list);

pd.SetVariableInternal(name, list);
} else if (type == typeof(MapZone)) {
Expand All @@ -871,6 +891,18 @@ private void UpdateSaveWithData(ushort index, byte[] encodedValue) {

_lastPlayerData?.SetVariableInternal(name, (MapZone) encodedValue[0]);
pd.SetVariableInternal(name, (MapZone) encodedValue[0]);
} else if (type == typeof(List<int>)) {
var length = encodedValue[0];

var list = new List<int>();
for (var i = 0; i < length; i++) {
list.Add(encodedValue[i + 1]);
}

// First set the new string list hash, so we don't trigger an update and subsequently a feedback loop
_listHashes[name] = GetListHashCode(list);

pd.SetVariableInternal(name, list);
} else {
throw new ArgumentException($"Could not decode type: {type}");
}
Expand Down Expand Up @@ -1082,28 +1114,12 @@ Func<TCollection, object> valueFunc
}

/// <summary>
/// Get the hash code of the combined values in a string list.
/// </summary>
/// <param name="list">The list of strings to calculate the hash code for.</param>
/// <returns>0 if the list is empty, otherwise a hash code matching the specific order of strings in the list.
/// </returns>
private static int GetStringListHashCode(List<string> list) {
if (list.Count == 0) {
return 0;
}

return list
.Select(item => item.GetHashCode())
.Aggregate((total, nextCode) => total ^ nextCode);
}

/// <summary>
/// Get the hash code of the combined values in a Vector3 list.
/// Get the hash code of the combined values in a list.
/// </summary>
/// <param name="list">The list of Vector3 to calculate the hash code for.</param>
/// <returns>0 if the list is empty, otherwise a hash code matching the specific order of Vector3 in the list.
/// <param name="list">The list to calculate the hash code for.</param>
/// <returns>0 if the list is empty, otherwise a hash code matching the specific order of values in the list.
/// </returns>
private static int GetVectorListHashCode(List<Vector3> list) {
private static int GetListHashCode<T>(List<T> list) {
if (list.Count == 0) {
return 0;
}
Expand Down
Loading

0 comments on commit ad5d966

Please sign in to comment.