From d8d0e57ce01ab7631abad828db642611ff860662 Mon Sep 17 00:00:00 2001 From: DD-Mantodea <2294632065@qq.com> Date: Sat, 7 Mar 2026 16:31:14 +0800 Subject: [PATCH 1/4] Update. --- src/Extensions/ListExt.cs | 50 +++++++++++ src/ModEntry.cs | 168 +++++++++++++++---------------------- src/Option.cs | 23 +++++ src/Patches.Merchant.cs | 11 ++- src/Patches.Network.cs | 141 +++++++++++-------------------- src/Patches.RestSite.cs | 171 +++++++++++++++++++++----------------- src/Patches.Treasure.cs | 107 +++++++++++++++--------- 7 files changed, 358 insertions(+), 313 deletions(-) create mode 100644 src/Extensions/ListExt.cs create mode 100644 src/Option.cs diff --git a/src/Extensions/ListExt.cs b/src/Extensions/ListExt.cs new file mode 100644 index 0000000..19b9005 --- /dev/null +++ b/src/Extensions/ListExt.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; + +namespace RemoveMultiplayerPlayetLimit.src.Extensions +{ + public static class ListExt + { + public static bool TryGetNext(this List list, T value, out T next) + { + return TryGetAfter(list, value, 1, out next); + } + + public static bool TryGetAfter(this List list, T value, int num, out T after) + { + after = default; + + var index = list.IndexOf(value); + + if (index != -1 && list.Count > index + num) + { + after = list[index + num]; + + return true; + } + + return false; + + } + + public static bool TryGetLast(this List list, T value, out T last) + { + return TryGetBefore(list, value, 1, out last); + } + + public static bool TryGetBefore(this List list, T value, int num, out T before) + { + before = default; + + var index = list.IndexOf(value); + + if (index != -1 && index - num >= 0) + { + before = list[index - num]; + + return true; + } + + return false; + } + } +} diff --git a/src/ModEntry.cs b/src/ModEntry.cs index 003dac2..f2f3a3f 100644 --- a/src/ModEntry.cs +++ b/src/ModEntry.cs @@ -11,176 +11,144 @@ using MegaCrit.Sts2.Core.Modding; using MegaCrit.Sts2.Core.Nodes.Rooms; using MegaCrit.Sts2.Core.Nodes.RestSite; +using MegaCrit.Sts2.Core.Multiplayer.Game.Lobby; +using RemoveMultiplayerPlayetLimit.src; +using MegaCrit.Sts2.Core.Runs; namespace RemoveMultiplayerPlayerLimit; [ModInitializer("Initialize")] public static partial class ModEntry { - private const int DefaultPlayerLimit = 8; + public static Option Option { get; set; } - private const int MinSupportedPlayerLimit = 4; + public static Harmony Harmony { get; set; } = new("Rain156.RemoveMultiplayerPlayerLimit"); - private const int MaxSupportedPlayerLimit = 16; + internal const int DefaultPlayerLimit = 8; - private const int VanillaSlotIdBits = 2; + internal const int MinSupportedPlayerLimit = 4; - private const int VanillaLobbyListLengthBits = 3; + internal const int MaxSupportedPlayerLimit = 16; - private const string ModFolderName = "RemoveMultiplayerPlayerLimit"; + internal const int VanillaSlotIdBits = 2; - private const string ConfigFileName = "config.json"; + internal const int VanillaLobbyListLengthBits = 3; - private static int TargetPlayerLimit { get; set; } = DefaultPlayerLimit; + internal const string ModFolderName = "RemoveMultiplayerPlayerLimit"; - private static int SlotIdBits { get; set; } = RequiredBitsForExclusiveUpperBound(DefaultPlayerLimit); + internal const string ConfigFileName = "config.json"; - private static int LobbyListLengthBits { get; set; } = RequiredBitsForExclusiveUpperBound(DefaultPlayerLimit + 1); + private static int SlotIdBits { get; set; } - private static int SlotIdCapacity { get; set; } = 1 << RequiredBitsForExclusiveUpperBound(DefaultPlayerLimit); + private static int LobbyListLengthBits { get; set; } - private static int LobbyListLengthCapacity { get; set; } = 1 << RequiredBitsForExclusiveUpperBound(DefaultPlayerLimit + 1); + private static int SlotIdCapacity { get; set; } - private static readonly FieldInfo? MaxPlayersField = AccessTools.Field(typeof(MegaCrit.Sts2.Core.Multiplayer.Game.Lobby.StartRunLobby), "k__BackingField"); + private static int LobbyListLengthCapacity { get; set; } public static void Initialize() { - TargetPlayerLimit = LoadOrCreatePlayerLimit(); - SlotIdBits = RequiredBitsForExclusiveUpperBound(TargetPlayerLimit); - LobbyListLengthBits = RequiredBitsForExclusiveUpperBound(TargetPlayerLimit + 1); + LoadOptions(); + + SlotIdBits = RequiredBitsForExclusiveUpperBound(Option.PlayerLimit); + + LobbyListLengthBits = RequiredBitsForExclusiveUpperBound(Option.PlayerLimit + 1); + SlotIdCapacity = 1 << SlotIdBits; + LobbyListLengthCapacity = 1 << LobbyListLengthBits; - if (TargetPlayerLimit > SlotIdCapacity) - { - throw new InvalidOperationException($"TargetPlayerLimit {TargetPlayerLimit} exceeds slot id capacity {SlotIdCapacity}."); - } - if (TargetPlayerLimit > LobbyListLengthCapacity) - { - throw new InvalidOperationException($"TargetPlayerLimit {TargetPlayerLimit} exceeds lobby list capacity {LobbyListLengthCapacity}."); - } - new Harmony("cn.remove.multiplayer.playerlimit").PatchAll(); - Log.Info($"RemoveMultiplayerPlayerLimit loaded. Target limit: {TargetPlayerLimit}, slot capacity: {SlotIdCapacity}, lobby list capacity: {LobbyListLengthCapacity}"); + + Harmony.PatchAll(); + + Log.Info($"RemoveMultiplayerPlayerLimit loaded. Target limit: {Option.PlayerLimit}, slot capacity: {SlotIdCapacity}, lobby list capacity: {LobbyListLengthCapacity}"); } - private static int LoadOrCreatePlayerLimit() + private static void LoadOptions() { - string modDirectory = ResolveModDirectory(); - Directory.CreateDirectory(modDirectory); - string configPath = Path.Combine(modDirectory, ConfigFileName); + string configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "mods", ModFolderName, ConfigFileName); + if (!File.Exists(configPath)) - { WriteDefaultConfig(configPath, DefaultPlayerLimit); - return DefaultPlayerLimit; - } + try { - using JsonDocument jsonDocument = JsonDocument.Parse(File.ReadAllText(configPath)); - if (jsonDocument.RootElement.TryGetProperty("max_player_limit", out JsonElement value) && value.ValueKind == JsonValueKind.Number && value.TryGetInt32(out int rawLimit)) + Option = JsonSerializer.Deserialize