From 731fb36f3af20a1691962e65c5b151c42a36bf93 Mon Sep 17 00:00:00 2001 From: Xilophor Date: Fri, 7 Mar 2025 23:05:38 -0500 Subject: [PATCH 1/7] "Bandaid" fix for the metadata breaking when over 8192 string length. Added a sort to help make sure the Everyone requirement plugins are higher priority when converting to JSON. Also made a modifiable max lobby metadata string length for any mods that may require more metadata. --- LobbyCompatibility/Features/PluginHelper.cs | 71 +++++++++++++++---- LobbyCompatibility/Models/PluginInfoRecord.cs | 32 ++++++++- .../SteamMatchmakingOnLobbyCreatedPostfix.cs | 9 ++- 3 files changed, 93 insertions(+), 19 deletions(-) diff --git a/LobbyCompatibility/Features/PluginHelper.cs b/LobbyCompatibility/Features/PluginHelper.cs index 56ac787..2b9c135 100644 --- a/LobbyCompatibility/Features/PluginHelper.cs +++ b/LobbyCompatibility/Features/PluginHelper.cs @@ -21,6 +21,30 @@ namespace LobbyCompatibility.Features; /// public static class PluginHelper { + /// + /// The absolute maximum string size for ALL steam lobby metadata is 8192 (2^13). + /// We want to give a large enough margin for the checksum, vanilla game metadata, and any other modded metadata. + /// + private const int MaxPluginMetadataLength = 7800; + + /// + /// The average json string size of a plugin. + /// + /// Calculated from `{"i":"BMX.LobbyCompatibility","v":"1.4.1","c":null,"s":null}` + private const int AveragePluginJsonLength = 60; + + /// + /// The current maximum string size for the plugin field in lobby metadata. + /// + /// WARNING: The absolute maximum string size for ALL steam lobby metadata is 8192 (2^13). + public static int CurrentMaxPluginMetadataLength { get; private set; } = MaxPluginMetadataLength; + + /// + /// The maximum string size for ALL steam lobby metadata is 8192 (2^13). + /// We want to give a large margin for the checksum, vanilla game metadata, and any other modded metadata. + /// + private static int AverageMaxLobbyMetadataModCount => CurrentMaxPluginMetadataLength / AveragePluginJsonLength; + /// /// PluginInfos registered through the register command, rather than found using the attribute. /// @@ -64,6 +88,16 @@ public static void RegisterPlugin(string guid, Version version, CompatibilityLev _cachedChecksum = null; } + /// + /// Reduce the maximum string length for the plugins field in the lobby metadata. + /// Useful if you need larger space for lobby metadata for your mod. + /// + /// The max allowed length of LobbyCompatibility's plugin field on the lobby. Maxes out at (7800 on startup). + public static void ReduceMaxLobbyMetadataStringLength(int length) + { + CurrentMaxPluginMetadataLength = length < CurrentMaxPluginMetadataLength ? length : CurrentMaxPluginMetadataLength; + } + /// /// Check if a plugin has the attribute. /// @@ -129,24 +163,35 @@ internal static IEnumerable GetAllPluginInfo() } /// - /// Creates a list of json strings containing the metadata of all plugins, to add to the lobby. + /// Creates a json string containing the metadata of the maximum amount of plugins, sorted by highest compatibility requirement first. /// - /// A list of json strings containing the metadata of all plugins. - internal static IEnumerable GetLobbyPluginsMetadata(List? plugins = null) + /// A json strings containing the maximum allowed mod count, as dictated by . + internal static string GetLobbyPluginsMetadata(List? plugins = null) { - var json = JsonConvert.SerializeObject(plugins ?? GetAllPluginInfo().ToList(), new VersionConverter()); + plugins ??= GetAllPluginInfo().ToList(); - // The maximum string size for steam lobby metadata is 8192 (2^13). - // We want one less than the maximum to allow space for a delimiter - var maxChunkLength = 8191; - - for (var i = 0; i < json.Length; i += maxChunkLength) - { - if (maxChunkLength + i > json.Length) - maxChunkLength = json.Length - i; + plugins.Sort(); + + var allowedPluginInfoRecords = plugins.Take(AverageMaxLobbyMetadataModCount).ToList(); - yield return json.Substring(i, maxChunkLength); + if (allowedPluginInfoRecords.Sum(record => record.JsonLength) + 1 + allowedPluginInfoRecords.Count > CurrentMaxPluginMetadataLength) + { + do + { + allowedPluginInfoRecords.RemoveAt(allowedPluginInfoRecords.Count - 1); + } while (allowedPluginInfoRecords.Sum(record => record.JsonLength) + 1 + allowedPluginInfoRecords.Count > CurrentMaxPluginMetadataLength); + + return JsonConvert.SerializeObject(plugins, new VersionConverter()); } + + do + { + allowedPluginInfoRecords.Add(plugins[allowedPluginInfoRecords.Count]); + } while (allowedPluginInfoRecords.Sum(record => record.JsonLength) + 1 + allowedPluginInfoRecords.Count <= CurrentMaxPluginMetadataLength); + + allowedPluginInfoRecords.RemoveAt(allowedPluginInfoRecords.Count - 1); + + return JsonConvert.SerializeObject(plugins, new VersionConverter()); } /// diff --git a/LobbyCompatibility/Models/PluginInfoRecord.cs b/LobbyCompatibility/Models/PluginInfoRecord.cs index 276afcd..21a865b 100644 --- a/LobbyCompatibility/Models/PluginInfoRecord.cs +++ b/LobbyCompatibility/Models/PluginInfoRecord.cs @@ -33,4 +33,34 @@ public record PluginInfoRecord( [property:JsonIgnore] VariableCompatibilityCheckDelegate? VariableCompatibilityCheck = null -); \ No newline at end of file +) +{ + private int? _jsonLength; + + /// + /// The calculated length of the json string. + /// + public int JsonLength => _jsonLength ??= 25 + GUID.Length + Version.ToString().Length + + (CompatibilityLevel.HasValue ? 1 : 4) + (VersionStrictness.HasValue ? 1 : 4); + + public int CompareTo(PluginInfoRecord other) + { + if (CompatibilityLevel != other.CompatibilityLevel) + { + if (CompatibilityLevel is null) return -1; + if (other.CompatibilityLevel is null) return 1; + + return (CompatibilityLevel ?? 0) - (other.CompatibilityLevel ?? 0); + } + + if (VersionStrictness != other.VersionStrictness) + { + if (VersionStrictness is null) return -1; + if (other.VersionStrictness is null) return 1; + + return (VersionStrictness ?? 0) - (other.VersionStrictness ?? 0); + } + + return string.Compare(GUID, other.GUID, StringComparison.Ordinal); + } +} \ No newline at end of file diff --git a/LobbyCompatibility/Patches/SteamMatchmakingOnLobbyCreatedPostfix.cs b/LobbyCompatibility/Patches/SteamMatchmakingOnLobbyCreatedPostfix.cs index 46ea4c7..4f5112f 100644 --- a/LobbyCompatibility/Patches/SteamMatchmakingOnLobbyCreatedPostfix.cs +++ b/LobbyCompatibility/Patches/SteamMatchmakingOnLobbyCreatedPostfix.cs @@ -29,11 +29,10 @@ private static void Postfix(Result result, ref Lobby lobby) // Modded is flagged as true, since we're using mods lobby.SetData(LobbyMetadata.Modded, "true"); - // Add paginated plugin metadata to the lobby so clients can check if they have the required plugins - var pluginsString = PluginHelper.GetLobbyPluginsMetadata(pluginInfo).ToArray(); - // Add each page - with a delimiter if there's another page - for (var i = 0; i < pluginsString.Length; i++) - lobby.SetData($"{LobbyMetadata.Plugins}{i}", $"{pluginsString[i]}{(i < pluginsString.Length - 1 ? "@" : string.Empty)}"); + // Add plugin metadata to the lobby so clients can check if they have the required plugins + var pluginsString = PluginHelper.GetLobbyPluginsMetadata(pluginInfo); + + lobby.SetData($"{LobbyMetadata.Plugins}0", pluginsString); // Set the joinable modded metadata to the same value as the original joinable metadata, in case it wasn't originally joinable lobby.SetData(LobbyMetadata.JoinableModded, lobby.GetData(LobbyMetadata.Joinable)); From 439dd8357002de137bb804f7d84e8c7084dae216 Mon Sep 17 00:00:00 2001 From: Xilophor Date: Fri, 7 Mar 2025 23:13:10 -0500 Subject: [PATCH 2/7] Moved the lobby parsing over to LobbyHelper --- LobbyCompatibility/Features/LobbyHelper.cs | 95 ++++++++++++++++++- LobbyCompatibility/Features/PluginHelper.cs | 85 ----------------- .../Patches/LobbyDataIsJoinablePostfix.cs | 2 +- .../SteamMatchmakingOnLobbyCreatedPostfix.cs | 2 +- 4 files changed, 95 insertions(+), 89 deletions(-) diff --git a/LobbyCompatibility/Features/LobbyHelper.cs b/LobbyCompatibility/Features/LobbyHelper.cs index fc26bdf..9764096 100644 --- a/LobbyCompatibility/Features/LobbyHelper.cs +++ b/LobbyCompatibility/Features/LobbyHelper.cs @@ -5,6 +5,8 @@ using HarmonyLib; using LobbyCompatibility.Enums; using LobbyCompatibility.Models; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using Steamworks; using Steamworks.Data; @@ -22,6 +24,30 @@ public static class LobbyHelper private static List? _clientPlugins; public static LobbyDiff LatestLobbyDiff { get; private set; } = new(new List()); private static Dictionary LobbyDiffCache { get; } = new(); + + /// + /// The absolute maximum string size for ALL steam lobby metadata is 8192 (2^13). + /// We want to give a large enough margin for the checksum, vanilla game metadata, and any other modded metadata. + /// + private const int MaxPluginMetadataLength = 7800; + + /// + /// The average json string size of a plugin. + /// + /// Calculated from `{"i":"BMX.LobbyCompatibility","v":"1.4.1","c":null,"s":null}` + private const int AveragePluginJsonLength = 60; + + /// + /// The current maximum string size for the plugin field in lobby metadata. + /// + /// WARNING: The absolute maximum string size for ALL steam lobby metadata is 8192 (2^13). + public static int CurrentMaxPluginMetadataLength { get; private set; } = MaxPluginMetadataLength; + + /// + /// The maximum string size for ALL steam lobby metadata is 8192 (2^13). + /// We want to give a large margin for the checksum, vanilla game metadata, and any other modded metadata. + /// + private static int AverageMaxLobbyMetadataModCount => CurrentMaxPluginMetadataLength / AveragePluginJsonLength; /// /// Get a from a . @@ -37,6 +63,16 @@ public static class LobbyHelper /// The from the . public static LobbyDiff GetLobbyDiff(IEnumerable> lobbyData) => GetLobbyDiff(null, null, lobbyData); + /// + /// Reduce the maximum string length for the plugins field in the lobby metadata. + /// Useful if you need larger space for lobby metadata for your mod. + /// + /// The max allowed length of LobbyCompatibility's plugin field on the lobby. Maxes out at (7800 on startup). + public static void ReduceMaxLobbyMetadataStringLength(int length) + { + CurrentMaxPluginMetadataLength = length < CurrentMaxPluginMetadataLength ? length : CurrentMaxPluginMetadataLength; + } + /// /// Get a from a or . /// @@ -54,8 +90,11 @@ internal static LobbyDiff GetLobbyDiff(Lobby? lobby, string? lobbyPluginString, var lobbyDataList = lobbyData?.ToList(); - var lobbyPlugins = PluginHelper - .ParseLobbyPluginsMetadata(lobbyPluginString ?? (lobby.HasValue ? GetLobbyPlugins(lobby.Value) : (lobbyDataList != null ? GetLobbyPlugins(lobbyDataList) : string.Empty))).ToList(); + var lobbyPlugins = ParseLobbyPluginsMetadata(lobbyPluginString ?? (lobby.HasValue + ? GetLobbyPlugins(lobby.Value) + : lobbyDataList != null + ? GetLobbyPlugins(lobbyDataList) + : string.Empty)).ToList(); _clientPlugins = PluginHelper.GetAllPluginInfo().CalculateCompatibilityLevel(lobby, lobbyDataList); var pluginDiffs = new List(); @@ -177,6 +216,58 @@ internal static string GetLobbyPlugins(List> lobbyD .Join(delimiter: string.Empty) .Replace("@", string.Empty); } + + /// + /// Creates a json string containing the metadata of the maximum amount of plugins, sorted by highest compatibility requirement first. + /// + /// A json strings containing the maximum allowed mod count, as dictated by . + internal static string GetLobbyPluginsMetadata(List? plugins = null) + { + plugins ??= PluginHelper.GetAllPluginInfo().ToList(); + + plugins.Sort(); + + var allowedPluginInfoRecords = plugins.Take(AverageMaxLobbyMetadataModCount).ToList(); + + if (allowedPluginInfoRecords.Sum(record => record.JsonLength) + 1 + allowedPluginInfoRecords.Count > CurrentMaxPluginMetadataLength) + { + do + { + allowedPluginInfoRecords.RemoveAt(allowedPluginInfoRecords.Count - 1); + } while (allowedPluginInfoRecords.Sum(record => record.JsonLength) + 1 + allowedPluginInfoRecords.Count > CurrentMaxPluginMetadataLength); + + return JsonConvert.SerializeObject(plugins, new VersionConverter()); + } + + do + { + allowedPluginInfoRecords.Add(plugins[allowedPluginInfoRecords.Count]); + } while (allowedPluginInfoRecords.Sum(record => record.JsonLength) + 1 + allowedPluginInfoRecords.Count <= CurrentMaxPluginMetadataLength); + + allowedPluginInfoRecords.RemoveAt(allowedPluginInfoRecords.Count - 1); + + return JsonConvert.SerializeObject(plugins, new VersionConverter()); + } + + /// + /// Parses a json string containing the metadata of all plugins. + /// + /// The json string to parse. + /// A list of plugins in the APIPluginInfo format. + internal static IEnumerable ParseLobbyPluginsMetadata(string json) + { + try + { + return JsonConvert.DeserializeObject>(json, new VersionConverter()) ?? + new List(); + } + catch (Exception e) + { + LobbyCompatibilityPlugin.Logger?.LogError("Failed to parse lobby plugins metadata."); + LobbyCompatibilityPlugin.Logger?.LogDebug(e); + throw; + } + } public static string GetCompatibilityHeader(PluginDiffResult pluginDiffResult) { diff --git a/LobbyCompatibility/Features/PluginHelper.cs b/LobbyCompatibility/Features/PluginHelper.cs index 2b9c135..7f3f062 100644 --- a/LobbyCompatibility/Features/PluginHelper.cs +++ b/LobbyCompatibility/Features/PluginHelper.cs @@ -21,29 +21,6 @@ namespace LobbyCompatibility.Features; /// public static class PluginHelper { - /// - /// The absolute maximum string size for ALL steam lobby metadata is 8192 (2^13). - /// We want to give a large enough margin for the checksum, vanilla game metadata, and any other modded metadata. - /// - private const int MaxPluginMetadataLength = 7800; - - /// - /// The average json string size of a plugin. - /// - /// Calculated from `{"i":"BMX.LobbyCompatibility","v":"1.4.1","c":null,"s":null}` - private const int AveragePluginJsonLength = 60; - - /// - /// The current maximum string size for the plugin field in lobby metadata. - /// - /// WARNING: The absolute maximum string size for ALL steam lobby metadata is 8192 (2^13). - public static int CurrentMaxPluginMetadataLength { get; private set; } = MaxPluginMetadataLength; - - /// - /// The maximum string size for ALL steam lobby metadata is 8192 (2^13). - /// We want to give a large margin for the checksum, vanilla game metadata, and any other modded metadata. - /// - private static int AverageMaxLobbyMetadataModCount => CurrentMaxPluginMetadataLength / AveragePluginJsonLength; /// /// PluginInfos registered through the register command, rather than found using the attribute. @@ -88,16 +65,6 @@ public static void RegisterPlugin(string guid, Version version, CompatibilityLev _cachedChecksum = null; } - /// - /// Reduce the maximum string length for the plugins field in the lobby metadata. - /// Useful if you need larger space for lobby metadata for your mod. - /// - /// The max allowed length of LobbyCompatibility's plugin field on the lobby. Maxes out at (7800 on startup). - public static void ReduceMaxLobbyMetadataStringLength(int length) - { - CurrentMaxPluginMetadataLength = length < CurrentMaxPluginMetadataLength ? length : CurrentMaxPluginMetadataLength; - } - /// /// Check if a plugin has the attribute. /// @@ -162,58 +129,6 @@ internal static IEnumerable GetAllPluginInfo() return pluginInfos.Concat(RegisteredPluginInfoRecords); } - /// - /// Creates a json string containing the metadata of the maximum amount of plugins, sorted by highest compatibility requirement first. - /// - /// A json strings containing the maximum allowed mod count, as dictated by . - internal static string GetLobbyPluginsMetadata(List? plugins = null) - { - plugins ??= GetAllPluginInfo().ToList(); - - plugins.Sort(); - - var allowedPluginInfoRecords = plugins.Take(AverageMaxLobbyMetadataModCount).ToList(); - - if (allowedPluginInfoRecords.Sum(record => record.JsonLength) + 1 + allowedPluginInfoRecords.Count > CurrentMaxPluginMetadataLength) - { - do - { - allowedPluginInfoRecords.RemoveAt(allowedPluginInfoRecords.Count - 1); - } while (allowedPluginInfoRecords.Sum(record => record.JsonLength) + 1 + allowedPluginInfoRecords.Count > CurrentMaxPluginMetadataLength); - - return JsonConvert.SerializeObject(plugins, new VersionConverter()); - } - - do - { - allowedPluginInfoRecords.Add(plugins[allowedPluginInfoRecords.Count]); - } while (allowedPluginInfoRecords.Sum(record => record.JsonLength) + 1 + allowedPluginInfoRecords.Count <= CurrentMaxPluginMetadataLength); - - allowedPluginInfoRecords.RemoveAt(allowedPluginInfoRecords.Count - 1); - - return JsonConvert.SerializeObject(plugins, new VersionConverter()); - } - - /// - /// Parses a json string containing the metadata of all plugins. - /// - /// The json string to parse. - /// A list of plugins in the APIPluginInfo format. - internal static IEnumerable ParseLobbyPluginsMetadata(string json) - { - try - { - return JsonConvert.DeserializeObject>(json, new VersionConverter()) ?? - new List(); - } - catch (Exception e) - { - LobbyCompatibilityPlugin.Logger?.LogError("Failed to parse lobby plugins metadata."); - LobbyCompatibilityPlugin.Logger?.LogDebug(e); - throw; - } - } - /// /// Checks if a plugin matches the version of a target, according to the source's version strictness. /// diff --git a/LobbyCompatibility/Patches/LobbyDataIsJoinablePostfix.cs b/LobbyCompatibility/Patches/LobbyDataIsJoinablePostfix.cs index bb34233..80c6d8d 100644 --- a/LobbyCompatibility/Patches/LobbyDataIsJoinablePostfix.cs +++ b/LobbyCompatibility/Patches/LobbyDataIsJoinablePostfix.cs @@ -47,7 +47,7 @@ private static bool Postfix(bool isJoinable, ref Lobby lobby) } var matchesPluginRequirements = - PluginHelper.MatchesTargetRequirements(PluginHelper.ParseLobbyPluginsMetadata(lobbyPluginString)); + PluginHelper.MatchesTargetRequirements(LobbyHelper.ParseLobbyPluginsMetadata(lobbyPluginString)); if (!matchesPluginRequirements) { diff --git a/LobbyCompatibility/Patches/SteamMatchmakingOnLobbyCreatedPostfix.cs b/LobbyCompatibility/Patches/SteamMatchmakingOnLobbyCreatedPostfix.cs index 4f5112f..57cefa4 100644 --- a/LobbyCompatibility/Patches/SteamMatchmakingOnLobbyCreatedPostfix.cs +++ b/LobbyCompatibility/Patches/SteamMatchmakingOnLobbyCreatedPostfix.cs @@ -30,7 +30,7 @@ private static void Postfix(Result result, ref Lobby lobby) lobby.SetData(LobbyMetadata.Modded, "true"); // Add plugin metadata to the lobby so clients can check if they have the required plugins - var pluginsString = PluginHelper.GetLobbyPluginsMetadata(pluginInfo); + var pluginsString = LobbyHelper.GetLobbyPluginsMetadata(pluginInfo); lobby.SetData($"{LobbyMetadata.Plugins}0", pluginsString); From 14f35b0dd353a006f90d0e38fc0b5da93d913c3b Mon Sep 17 00:00:00 2001 From: Xilophor Date: Fri, 7 Mar 2025 23:19:03 -0500 Subject: [PATCH 3/7] Simplify the plugin metadata parsing --- LobbyCompatibility/Features/LobbyHelper.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/LobbyCompatibility/Features/LobbyHelper.cs b/LobbyCompatibility/Features/LobbyHelper.cs index 9764096..fea97ea 100644 --- a/LobbyCompatibility/Features/LobbyHelper.cs +++ b/LobbyCompatibility/Features/LobbyHelper.cs @@ -59,7 +59,7 @@ public static class LobbyHelper /// /// Get a from a . /// - /// The lobby to get the diff from. + /// The lobby to get the diff from. /// The from the . public static LobbyDiff GetLobbyDiff(IEnumerable> lobbyData) => GetLobbyDiff(null, null, lobbyData); @@ -182,18 +182,12 @@ internal static LobbyDiff GetLobbyDiff(Lobby? lobby, string? lobbyPluginString, /// A json from the . internal static string GetLobbyPlugins(Lobby lobby) { - var lobbyPluginStrings = new List(); - if (GameNetworkManager.Instance && !GameNetworkManager.Instance.disableSteam) { - var i = 0; - do lobbyPluginStrings.Insert(i, lobby.GetData($"{LobbyMetadata.Plugins}{i}")); - while (lobbyPluginStrings[i++].Contains("@")); + return lobby.GetData($"{LobbyMetadata.Plugins}0"); } - return lobbyPluginStrings - .Join(delimiter: string.Empty) - .Replace("@", string.Empty); + return string.Empty; } /// From b95b87df833f13f09aad9035d74a895a0abb00c5 Mon Sep 17 00:00:00 2001 From: Xilophor Date: Fri, 7 Mar 2025 23:20:23 -0500 Subject: [PATCH 4/7] Removed unused usings in PluginHelper --- LobbyCompatibility/Features/PluginHelper.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/LobbyCompatibility/Features/PluginHelper.cs b/LobbyCompatibility/Features/PluginHelper.cs index 7f3f062..2332c7d 100644 --- a/LobbyCompatibility/Features/PluginHelper.cs +++ b/LobbyCompatibility/Features/PluginHelper.cs @@ -8,8 +8,6 @@ using LobbyCompatibility.Attributes; using LobbyCompatibility.Enums; using LobbyCompatibility.Models; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using Steamworks.Data; namespace LobbyCompatibility.Features; From e9448890cc2f5e4bc16f432e9b1f0f98fe5c4d87 Mon Sep 17 00:00:00 2001 From: Xilophor Date: Sat, 8 Mar 2025 00:04:21 -0500 Subject: [PATCH 5/7] Fix incorrect sorting --- LobbyCompatibility/Models/PluginInfoRecord.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/LobbyCompatibility/Models/PluginInfoRecord.cs b/LobbyCompatibility/Models/PluginInfoRecord.cs index 21a865b..0043165 100644 --- a/LobbyCompatibility/Models/PluginInfoRecord.cs +++ b/LobbyCompatibility/Models/PluginInfoRecord.cs @@ -33,7 +33,7 @@ public record PluginInfoRecord( [property:JsonIgnore] VariableCompatibilityCheckDelegate? VariableCompatibilityCheck = null -) +) : IComparable { private int? _jsonLength; @@ -47,18 +47,18 @@ public int CompareTo(PluginInfoRecord other) { if (CompatibilityLevel != other.CompatibilityLevel) { - if (CompatibilityLevel is null) return -1; - if (other.CompatibilityLevel is null) return 1; + if (CompatibilityLevel is null) return 1; + if (other.CompatibilityLevel is null) return -1; - return (CompatibilityLevel ?? 0) - (other.CompatibilityLevel ?? 0); + return (other.CompatibilityLevel ?? 0) - (CompatibilityLevel ?? 0); } if (VersionStrictness != other.VersionStrictness) { - if (VersionStrictness is null) return -1; - if (other.VersionStrictness is null) return 1; + if (VersionStrictness is null) return 1; + if (other.VersionStrictness is null) return -1; - return (VersionStrictness ?? 0) - (other.VersionStrictness ?? 0); + return (other.VersionStrictness ?? 0) - (VersionStrictness ?? 0); } return string.Compare(GUID, other.GUID, StringComparison.Ordinal); From 4fd73942dd6c8893c6b70c7516184d889f10aa13 Mon Sep 17 00:00:00 2001 From: Xilophor Date: Sat, 8 Mar 2025 00:04:36 -0500 Subject: [PATCH 6/7] Fix incorrect JSON data --- LobbyCompatibility/Features/LobbyHelper.cs | 4 ++-- LobbyCompatibility/Models/PluginInfoRecord.cs | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/LobbyCompatibility/Features/LobbyHelper.cs b/LobbyCompatibility/Features/LobbyHelper.cs index fea97ea..57afed9 100644 --- a/LobbyCompatibility/Features/LobbyHelper.cs +++ b/LobbyCompatibility/Features/LobbyHelper.cs @@ -230,7 +230,7 @@ internal static string GetLobbyPluginsMetadata(List? plugins = allowedPluginInfoRecords.RemoveAt(allowedPluginInfoRecords.Count - 1); } while (allowedPluginInfoRecords.Sum(record => record.JsonLength) + 1 + allowedPluginInfoRecords.Count > CurrentMaxPluginMetadataLength); - return JsonConvert.SerializeObject(plugins, new VersionConverter()); + return JsonConvert.SerializeObject(allowedPluginInfoRecords, new VersionConverter()); } do @@ -240,7 +240,7 @@ internal static string GetLobbyPluginsMetadata(List? plugins = allowedPluginInfoRecords.RemoveAt(allowedPluginInfoRecords.Count - 1); - return JsonConvert.SerializeObject(plugins, new VersionConverter()); + return JsonConvert.SerializeObject(allowedPluginInfoRecords, new VersionConverter()); } /// diff --git a/LobbyCompatibility/Models/PluginInfoRecord.cs b/LobbyCompatibility/Models/PluginInfoRecord.cs index 0043165..e32abda 100644 --- a/LobbyCompatibility/Models/PluginInfoRecord.cs +++ b/LobbyCompatibility/Models/PluginInfoRecord.cs @@ -35,11 +35,13 @@ public record PluginInfoRecord( VariableCompatibilityCheckDelegate? VariableCompatibilityCheck = null ) : IComparable { + [JsonIgnore] private int? _jsonLength; /// /// The calculated length of the json string. /// + [JsonIgnore] public int JsonLength => _jsonLength ??= 25 + GUID.Length + Version.ToString().Length + (CompatibilityLevel.HasValue ? 1 : 4) + (VersionStrictness.HasValue ? 1 : 4); From e4990c3aee2722494c2c855ee610a3dca346443f Mon Sep 17 00:00:00 2001 From: Xilophor Date: Sun, 11 May 2025 12:37:00 -0400 Subject: [PATCH 7/7] Update lobby metadata reduction method as requested. --- LobbyCompatibility/Features/LobbyHelper.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/LobbyCompatibility/Features/LobbyHelper.cs b/LobbyCompatibility/Features/LobbyHelper.cs index 57afed9..c2eaae0 100644 --- a/LobbyCompatibility/Features/LobbyHelper.cs +++ b/LobbyCompatibility/Features/LobbyHelper.cs @@ -64,13 +64,13 @@ public static class LobbyHelper public static LobbyDiff GetLobbyDiff(IEnumerable> lobbyData) => GetLobbyDiff(null, null, lobbyData); /// - /// Reduce the maximum string length for the plugins field in the lobby metadata. + /// Reserve space in the lobby metadata. /// Useful if you need larger space for lobby metadata for your mod. /// - /// The max allowed length of LobbyCompatibility's plugin field on the lobby. Maxes out at (7800 on startup). - public static void ReduceMaxLobbyMetadataStringLength(int length) + /// The amount to metadata space in bytes space to reserve. The amound of bytes LobbyCompatibility will use is reduced by this amount. + public static void ReserveLobbyMetadataSpace(int length) { - CurrentMaxPluginMetadataLength = length < CurrentMaxPluginMetadataLength ? length : CurrentMaxPluginMetadataLength; + CurrentMaxPluginMetadataLength -= length; } ///