diff --git a/src/Extensions/ListExt.cs b/src/Extensions/ListExt.cs new file mode 100644 index 0000000..25c0efc --- /dev/null +++ b/src/Extensions/ListExt.cs @@ -0,0 +1,51 @@ +using RemoveMultiplayerPlayerLimit.src; +using System.Collections.Generic; +using System.IO; + +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..368947f 100644 --- a/src/ModEntry.cs +++ b/src/ModEntry.cs @@ -1,186 +1,155 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text.Json; +using Godot; using HarmonyLib; using MegaCrit.Sts2.Core.Context; using MegaCrit.Sts2.Core.Entities.RestSite; using MegaCrit.Sts2.Core.Logging; using MegaCrit.Sts2.Core.Modding; -using MegaCrit.Sts2.Core.Nodes.Rooms; using MegaCrit.Sts2.Core.Nodes.RestSite; +using MegaCrit.Sts2.Core.Nodes.Rooms; +using MegaCrit.Sts2.Core.Runs; +using RemoveMultiplayerPlayerLimit.src; +using RemoveMultiplayerPlayetLimit.src; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text.Json; 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); - SlotIdCapacity = 1 << SlotIdBits; - LobbyListLengthCapacity = 1 << LobbyListLengthBits; - if (TargetPlayerLimit > SlotIdCapacity) + try { - throw new InvalidOperationException($"TargetPlayerLimit {TargetPlayerLimit} exceeds slot id capacity {SlotIdCapacity}."); - } - if (TargetPlayerLimit > LobbyListLengthCapacity) + LoadOptions(); + + SlotIdBits = RequiredBitsForExclusiveUpperBound(Option.PlayerLimit); + + LobbyListLengthBits = RequiredBitsForExclusiveUpperBound(Option.PlayerLimit + 1); + + SlotIdCapacity = 1 << SlotIdBits; + + LobbyListLengthCapacity = 1 << LobbyListLengthBits; + + Harmony.PatchAll(); + + Log.Info($"RemoveMultiplayerPlayerLimit loaded. Target limit: {Option.PlayerLimit}, slot capacity: {SlotIdCapacity}, lobby list capacity: {LobbyListLengthCapacity}"); + } + catch (Exception e) { - 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}"); + File.AppendAllText(Path.Combine(Pathes.RootPath, "logs.txt"), e.Message + e.StackTrace); + } } - private static int LoadOrCreatePlayerLimit() + private static void LoadOptions() { - string modDirectory = ResolveModDirectory(); - Directory.CreateDirectory(modDirectory); - string configPath = Path.Combine(modDirectory, ConfigFileName); + string configPath = Pathes.ConfigPath; + 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