diff --git a/.editorconfig b/.editorconfig index 017cd3a..1561783 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,2 +1,6 @@ [*.{cs,vb}] -dotnet_diagnostic.CA1707.severity = none \ No newline at end of file +dotnet_diagnostic.CA1707.severity = none +dotnet_diagnostic.CS1591.severity = none +dotnet_diagnostic.S125.severity = none +dotnet_diagnostic.SA1615.severity = none +dotnet_diagnostic.SA1611.severity = none \ No newline at end of file diff --git a/MiraAPI/Events/Vanilla/Map/UpdateSystemEvent.cs b/MiraAPI/Events/Vanilla/Map/UpdateSystemEvent.cs index 6b6d907..5b70090 100644 --- a/MiraAPI/Events/Vanilla/Map/UpdateSystemEvent.cs +++ b/MiraAPI/Events/Vanilla/Map/UpdateSystemEvent.cs @@ -24,6 +24,7 @@ public class UpdateSystemEvent : MiraCancelableEvent /// Initializes a new instance of the class. /// /// The SystemType being updated. + /// The player that is updating the system. /// Amount to update System to. public UpdateSystemEvent(SystemTypes systemType, PlayerControl player, byte amount) { diff --git a/MiraAPI/GameModes/CustomGameModeManager.cs b/MiraAPI/GameModes/CustomGameModeManager.cs index e4305f5..5ce22e0 100644 --- a/MiraAPI/GameModes/CustomGameModeManager.cs +++ b/MiraAPI/GameModes/CustomGameModeManager.cs @@ -21,7 +21,7 @@ public static class CustomGameModeManager } /// - /// Current gamemode. + /// Gets the current gamemode. /// public static CustomGameMode? ActiveMode { get; internal set; } = new DefaultMode(); diff --git a/MiraAPI/GameOptions/ModdedOptionsManager.cs b/MiraAPI/GameOptions/ModdedOptionsManager.cs index 7aaa154..c3e7e22 100644 --- a/MiraAPI/GameOptions/ModdedOptionsManager.cs +++ b/MiraAPI/GameOptions/ModdedOptionsManager.cs @@ -45,7 +45,9 @@ public static class ModdedOptionsManager pluginInfo.OptionGroups.Add(group); typeof(OptionGroupSingleton<>).MakeGenericType(type) +#pragma warning disable S3011 .GetField("_instance", BindingFlags.Static | BindingFlags.NonPublic)! +#pragma warning restore S3011 .SetValue(null, group); return true; diff --git a/MiraAPI/GameOptions/ModifierOptionGroup.cs b/MiraAPI/GameOptions/ModifierOptionGroup.cs index cfa2eff..3db6566 100644 --- a/MiraAPI/GameOptions/ModifierOptionGroup.cs +++ b/MiraAPI/GameOptions/ModifierOptionGroup.cs @@ -2,7 +2,9 @@ namespace MiraAPI.GameOptions; +#pragma warning disable CA1852 internal class ModifierOptionGroup : AbstractOptionGroup +#pragma warning restore CA1852 { public override string GroupName { get; } diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs index ff422f5..0ae41bd 100644 --- a/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs +++ b/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs @@ -129,7 +129,7 @@ public class ModdedEnumOption : ModdedOption where T : Enum Enum.GetNames(typeof(T)).Select(CustomStringName.CreateAndRegister).ToArray() : values.Select(CustomStringName.CreateAndRegister).ToArray(); - data.Index = Convert.ToInt32(Value); + data.Index = Convert.ToInt32(Value, NumberFormatInfo.InvariantInfo); } /// diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs index 83048f7..93b5b5f 100644 --- a/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs +++ b/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs @@ -32,9 +32,9 @@ public abstract class ModdedOption : IModdedOption public StringNames StringName { get; } /// - /// Gets the BaseGameSetting data of the option. + /// Gets or sets the BaseGameSetting data of the option. /// - public BaseGameSetting Data { get; protected init; } + public BaseGameSetting Data { get; protected set; } = null!; /// /// Gets or sets the parent mod of the option. diff --git a/MiraAPI/Hud/CustomActionButton.cs b/MiraAPI/Hud/CustomActionButton.cs index e215fda..7e0c0e2 100644 --- a/MiraAPI/Hud/CustomActionButton.cs +++ b/MiraAPI/Hud/CustomActionButton.cs @@ -180,7 +180,7 @@ public abstract class CustomActionButton if (!moveButton) return; - if (HudManagerPatches._bottomLeft == null || HudManagerPatches._bottomRight == null) + if (HudManagerPatches.BottomLeft == null || HudManagerPatches.BottomRight == null) { return; } @@ -188,17 +188,17 @@ public abstract class CustomActionButton switch (location) { case ButtonLocation.BottomLeft: - var gridArrange = HudManagerPatches._bottomLeft.GetComponent(); - var aspectPosition = HudManagerPatches._bottomLeft.GetComponent(); + var gridArrange = HudManagerPatches.BottomLeft.GetComponent(); + var aspectPosition = HudManagerPatches.BottomLeft.GetComponent(); - Button.transform.SetParent(HudManagerPatches._bottomLeft.transform); + Button.transform.SetParent(HudManagerPatches.BottomLeft.transform); gridArrange.Start(); gridArrange.ArrangeChilds(); aspectPosition.AdjustPosition(); break; case ButtonLocation.BottomRight: - Button.transform.SetParent(HudManagerPatches._bottomRight); + Button.transform.SetParent(HudManagerPatches.BottomRight); break; } } @@ -435,11 +435,11 @@ public abstract class CustomActionButton { if (CanUse()) { - Button.SetEnabled(); + Button!.SetEnabled(); } else { - Button.SetDisabled(); + Button!.SetDisabled(); } if (EffectActive) diff --git a/MiraAPI/Hud/CustomButtonManager.cs b/MiraAPI/Hud/CustomButtonManager.cs index dd10f6c..69c4b92 100644 --- a/MiraAPI/Hud/CustomButtonManager.cs +++ b/MiraAPI/Hud/CustomButtonManager.cs @@ -31,7 +31,9 @@ public static class CustomButtonManager CustomButtons.Add(button); pluginInfo.Buttons.Add(button); typeof(CustomButtonSingleton<>).MakeGenericType(buttonType) +#pragma warning disable S3011 .GetField("_instance", BindingFlags.Static | BindingFlags.NonPublic)! +#pragma warning restore S3011 .SetValue(null, button); ButtonEventTypes.Add(buttonType, typeof(MiraButtonClickEvent<>).MakeGenericType(buttonType)); diff --git a/MiraAPI/Hud/CustomButtonSingleton.cs b/MiraAPI/Hud/CustomButtonSingleton.cs index b338e61..daa5467 100644 --- a/MiraAPI/Hud/CustomButtonSingleton.cs +++ b/MiraAPI/Hud/CustomButtonSingleton.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Diagnostics.CodeAnalysis; +using System.Linq; namespace MiraAPI.Hud; @@ -13,7 +14,6 @@ public static class CustomButtonSingleton where T : CustomActionButton /// /// Gets the instance of the button. /// -#pragma warning disable CA1000 + [SuppressMessage("Design", "CA1000:Do not declare static members on generic types", Justification = "This is a utility class to get the instance of a custom action button.")] public static T Instance => _instance ??= CustomButtonManager.CustomButtons.OfType().Single(); -#pragma warning restore CA1000 } diff --git a/MiraAPI/Modifiers/ModifierDisplay/ModifierDisplayComponent.cs b/MiraAPI/Modifiers/ModifierDisplay/ModifierDisplayComponent.cs index fe23ecc..f1a614e 100644 --- a/MiraAPI/Modifiers/ModifierDisplay/ModifierDisplayComponent.cs +++ b/MiraAPI/Modifiers/ModifierDisplay/ModifierDisplayComponent.cs @@ -17,7 +17,7 @@ namespace MiraAPI.Modifiers.ModifierDisplay; /// The code used to display Mira modifiers. /// [RegisterInIl2Cpp] -public class ModifierDisplayComponent(nint ptr) : MonoBehaviour(ptr) +public class ModifierDisplayComponent(nint cppPtr) : MonoBehaviour(cppPtr) { /// /// Gets the instance of the Modifier Display. @@ -34,8 +34,8 @@ public class ModifierDisplayComponent(nint ptr) : MonoBehaviour(ptr) private PassiveButton _nextButton = null!; private PassiveButton _backButton = null!; - private int _currentPage = 0; - private const int _itemsPerPage = 3; + private int _currentPage; + private const int ItemsPerPage = 3; private readonly Dictionary _modifiers = []; @@ -142,10 +142,10 @@ public class ModifierDisplayComponent(nint ptr) : MonoBehaviour(ptr) private void UpdatePage() { - var totalPages = Mathf.CeilToInt((float)_modifiers.Count / _itemsPerPage); + var totalPages = Mathf.CeilToInt((float)_modifiers.Count / ItemsPerPage); _currentPage = Mathf.Clamp(_currentPage, 0, Mathf.Max(0, totalPages - 1)); - if (_modifiers.Count <= _itemsPerPage) + if (_modifiers.Count <= ItemsPerPage) { _modifiers.Do(x => x.Value.gameObject.SetActive(true)); _pagination.gameObject.SetActive(false); @@ -162,8 +162,8 @@ public class ModifierDisplayComponent(nint ptr) : MonoBehaviour(ptr) _backButton.gameObject.SetActive(true); _modifiers.Do(x => x.Value.gameObject.SetActive(false)); - var start = _currentPage * _itemsPerPage; - var end = Mathf.Min(start + _itemsPerPage, _modifiers.Count); + var start = _currentPage * ItemsPerPage; + var end = Mathf.Min(start + ItemsPerPage, _modifiers.Count); var modifiers = _modifiers.ToArray(); for (var i = start; i < end; i++) diff --git a/MiraAPI/Modifiers/ModifierDisplay/ModifierUiComponent.cs b/MiraAPI/Modifiers/ModifierDisplay/ModifierUiComponent.cs index a17dcc3..ef8b0bb 100644 --- a/MiraAPI/Modifiers/ModifierDisplay/ModifierUiComponent.cs +++ b/MiraAPI/Modifiers/ModifierDisplay/ModifierUiComponent.cs @@ -9,7 +9,7 @@ namespace MiraAPI.Modifiers.ModifierDisplay; /// The code placed on every Modifier HUD object. Used to handle updating. /// [RegisterInIl2Cpp] -public class ModifierUiComponent(nint ptr) : MonoBehaviour(ptr) +public class ModifierUiComponent(nint cppPtr) : MonoBehaviour(cppPtr) { /// /// Gets the modifier which this component is for. @@ -17,12 +17,13 @@ public class ModifierUiComponent(nint ptr) : MonoBehaviour(ptr) [HideFromIl2Cpp] public BaseModifier? Modifier { get; internal set; } + // ReSharper disable InconsistentNaming private SpriteRenderer modBg = null!; private TextMeshPro desc = null!; private SpriteRenderer icon = null!; private TextMeshPro nameText = null!; private RectTransform descRect = null!; - + // ReSharper restore InconsistentNaming private void Awake() { if (Modifier == null) return; diff --git a/MiraAPI/Modifiers/ModifierFactory.cs b/MiraAPI/Modifiers/ModifierFactory.cs index 8f8d005..4f84db0 100644 --- a/MiraAPI/Modifiers/ModifierFactory.cs +++ b/MiraAPI/Modifiers/ModifierFactory.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Linq.Expressions; using MiraAPI.Utilities; @@ -11,7 +12,7 @@ namespace MiraAPI.Modifiers; /// public static class ModifierFactory { - private static readonly Dictionary<(Type, Type[]), Func> _constructorCache = []; + private static readonly Dictionary<(Type, Type[]), Func> ConstructorCache = []; private static Func CreateConstructor(Type type, params object[] args) { @@ -45,13 +46,13 @@ public static class ModifierFactory /// An instance of the modifier. public static BaseModifier CreateInstance(Type type, params object[] args) { - var argTypes = args.Select(arg => arg?.GetType() ?? typeof(object)).ToArray(); + var argTypes = args.Select(arg => arg.GetType()).ToArray(); var key = (type, argTypes); - if (!_constructorCache.TryGetValue(key, out var constructor)) + if (!ConstructorCache.TryGetValue(key, out var constructor)) { constructor = CreateConstructor(type, args); - _constructorCache[key] = constructor; + ConstructorCache[key] = constructor; } return constructor(args); @@ -95,6 +96,7 @@ public static class ModifierFactory where T : BaseModifier /// /// Parameters for the constructor. /// An instance of the modifier. + [SuppressMessage("Design", "CA1000:Do not declare static members on generic types", Justification = "This is a factory class.")] public static T CreateInstance(params object[] args) { return Constructor(args); diff --git a/MiraAPI/Networking/MiraRpc.cs b/MiraAPI/Networking/MiraRpc.cs index 29703d7..28c6c7a 100644 --- a/MiraAPI/Networking/MiraRpc.cs +++ b/MiraAPI/Networking/MiraRpc.cs @@ -46,7 +46,7 @@ public enum MiraRpc : uint RemoveVote, /// - /// Custom RPC to replace Among Us CastVote + /// Custom RPC to replace Among Us CastVote. /// CastVote, } diff --git a/MiraAPI/Patches/Hud/ButtonResetPatches.cs b/MiraAPI/Patches/Hud/ButtonResetPatches.cs index b9756ce..0859bea 100644 --- a/MiraAPI/Patches/Hud/ButtonResetPatches.cs +++ b/MiraAPI/Patches/Hud/ButtonResetPatches.cs @@ -4,7 +4,7 @@ using MiraAPI.Hud; namespace MiraAPI.Patches.Hud; /// -/// Reset button patches +/// Reset button patches. /// [HarmonyPatch] public static class ButtonResetPatches diff --git a/MiraAPI/Patches/HudManagerPatches.cs b/MiraAPI/Patches/HudManagerPatches.cs index fa057d4..27a8026 100644 --- a/MiraAPI/Patches/HudManagerPatches.cs +++ b/MiraAPI/Patches/HudManagerPatches.cs @@ -13,9 +13,9 @@ namespace MiraAPI.Patches; public static class HudManagerPatches { // Custom buttons parent. - internal static GameObject? _bottomLeft; - internal static Transform? _bottomRight; - internal static Transform? _buttons; + public static GameObject? BottomLeft { get; private set; } + public static Transform? BottomRight { get; private set; } + public static Transform? Buttons { get; private set; } /* /// @@ -36,30 +36,30 @@ public static class HudManagerPatches [HarmonyPatch(nameof(HudManager.Start))] public static void StartPostfix(HudManager __instance) { - if (_buttons == null) + if (Buttons == null) { - _buttons = __instance.transform.Find("Buttons"); + Buttons = __instance.transform.Find("Buttons"); } - if (_bottomRight == null) + if (BottomRight == null) { - _bottomRight = _buttons.Find("BottomRight"); + BottomRight = Buttons.Find("BottomRight"); } - if (_bottomLeft == null) + if (BottomLeft == null) { - _bottomLeft = Object.Instantiate(_bottomRight.gameObject, _buttons); + BottomLeft = Object.Instantiate(BottomRight.gameObject, Buttons); } - foreach (var t in _bottomLeft.GetComponentsInChildren(true)) + foreach (var t in BottomLeft.GetComponentsInChildren(true)) { t.gameObject.Destroy(); } - var gridArrange = _bottomLeft.GetComponent(); - var aspectPosition = _bottomLeft.GetComponent(); + var gridArrange = BottomLeft.GetComponent(); + var aspectPosition = BottomLeft.GetComponent(); - _bottomLeft.name = "BottomLeft"; + BottomLeft.name = "BottomLeft"; gridArrange.Alignment = GridArrange.StartAlign.Right; aspectPosition.Alignment = AspectPosition.EdgeAlignments.LeftBottom; @@ -67,8 +67,8 @@ public static class HudManagerPatches { var location = button.Location switch { - ButtonLocation.BottomLeft => _bottomLeft.transform, - ButtonLocation.BottomRight => _bottomRight, + ButtonLocation.BottomLeft => BottomLeft.transform, + ButtonLocation.BottomRight => BottomRight, _ => null, }; diff --git a/MiraAPI/Patches/Menu/NameplatesTabPatches.cs b/MiraAPI/Patches/Menu/NameplatesTabPatches.cs index fee0ac7..d66c8f3 100644 --- a/MiraAPI/Patches/Menu/NameplatesTabPatches.cs +++ b/MiraAPI/Patches/Menu/NameplatesTabPatches.cs @@ -108,7 +108,7 @@ public static class NameplatesTabPatches var x = (NamePlateViewData viewdata) => { colorChip.transform.GetChild(1).GetComponent().sprite = viewdata?.Image; - //(colorChip as NameplateChip).image.sprite = viewdata?.Image; + // (colorChip as NameplateChip).image.sprite = viewdata?.Image; }; __instance.StartCoroutine(AddressableAssetExtensions.CoLoadAssetAsync(__instance, namePlate.GetAssetReference(), x)); colorChip.transform.localPosition = new Vector3(position.x, position.y, -1f); diff --git a/MiraAPI/Patches/MinigameBeginErrorPatch.cs b/MiraAPI/Patches/MinigameBeginErrorPatch.cs index 863be42..ce59415 100644 --- a/MiraAPI/Patches/MinigameBeginErrorPatch.cs +++ b/MiraAPI/Patches/MinigameBeginErrorPatch.cs @@ -3,7 +3,7 @@ namespace MiraAPI.Patches; /// -/// Used to fix the Minigame crash errors (credits Submerged/PH Gaming for the fix) +/// Used to fix the Minigame crash errors (credits Submerged/PH Gaming for the fix). /// [HarmonyPatch] public static class MinigameBeginErrorPatch diff --git a/MiraAPI/Patches/Roles/GameStartupPatch.cs b/MiraAPI/Patches/Roles/GameStartupPatch.cs index 9bb2a54..6ab234d 100644 --- a/MiraAPI/Patches/Roles/GameStartupPatch.cs +++ b/MiraAPI/Patches/Roles/GameStartupPatch.cs @@ -10,7 +10,7 @@ public static class GameStartupPatch private static bool _runOnce; /// - /// This is used for registering roles when the game opens, might be a janky solution, but it works + /// This is used for registering roles when the game opens, might be a janky solution, but it works. /// [HarmonyPostfix] [HarmonyPatch(nameof(MainMenuManager.Start))] diff --git a/MiraAPI/Patches/Roles/HauntMenuPatch.cs b/MiraAPI/Patches/Roles/HauntMenuPatch.cs index b174165..a7618a6 100644 --- a/MiraAPI/Patches/Roles/HauntMenuPatch.cs +++ b/MiraAPI/Patches/Roles/HauntMenuPatch.cs @@ -24,4 +24,4 @@ public static class HauntMenuMinigamePatch __instance.FilterText.text = role.NiceName; __instance.FilterText.color = color; } -} \ No newline at end of file +} diff --git a/MiraAPI/Patches/Roles/RoleOptionsCollectionPatch.cs b/MiraAPI/Patches/Roles/RoleOptionsCollectionPatch.cs index e2ddb4a..49840ee 100644 --- a/MiraAPI/Patches/Roles/RoleOptionsCollectionPatch.cs +++ b/MiraAPI/Patches/Roles/RoleOptionsCollectionPatch.cs @@ -12,7 +12,7 @@ namespace MiraAPI.Patches.Roles; public static class RoleOptionsCollectionPatch { /// - /// Set the role chance for custom Launchpad roles based on config + /// Set the role chance for custom Launchpad roles based on config. /// /// Return false to skip original method, true to not. [HarmonyPrefix] @@ -42,7 +42,7 @@ public static class RoleOptionsCollectionPatch } /// - /// Set the amount for custom Launchpad roles based on config + /// Set the amount for custom Launchpad roles based on config. /// /// Return false to skip original method, true to not. [HarmonyPrefix] diff --git a/MiraAPI/Patches/Roles/SabotageButtonPatch.cs b/MiraAPI/Patches/Roles/SabotageButtonPatch.cs index 6706235..258af83 100644 --- a/MiraAPI/Patches/Roles/SabotageButtonPatch.cs +++ b/MiraAPI/Patches/Roles/SabotageButtonPatch.cs @@ -4,7 +4,7 @@ using MiraAPI.Roles; namespace MiraAPI.Patches.Roles; [HarmonyPatch(typeof(SabotageButton))] -public class SabotageButtonPatch +public static class SabotageButtonPatch { /// /// Patches the Sabotage button to check if the player's custom role can use sabotage. diff --git a/MiraAPI/PluginLoading/MiraPluginManager.cs b/MiraAPI/PluginLoading/MiraPluginManager.cs index 91767b0..c68c8ce 100644 --- a/MiraAPI/PluginLoading/MiraPluginManager.cs +++ b/MiraAPI/PluginLoading/MiraPluginManager.cs @@ -162,6 +162,12 @@ public sealed class MiraPluginManager foreach (var property in type.GetProperties()) { + if (property.GetMethod?.IsStatic == true) + { + Logger.Error($"Option property {property.Name} in {type.Name} must not be static."); + continue; + } + if (property.PropertyType.IsAssignableTo(typeof(IModdedOption))) { ModdedOptionsManager.RegisterPropertyOption(type, property, pluginInfo); diff --git a/MiraAPI/Utilities/Assets/LoadableResourceAsset.cs b/MiraAPI/Utilities/Assets/LoadableResourceAsset.cs index 47ce04a..5678997 100644 --- a/MiraAPI/Utilities/Assets/LoadableResourceAsset.cs +++ b/MiraAPI/Utilities/Assets/LoadableResourceAsset.cs @@ -7,6 +7,7 @@ namespace MiraAPI.Utilities.Assets; /// A utility class for loading assets from embedded resources. /// /// The path to the embedded resource. +/// The pixels per unit for the loaded sprite. public class LoadableResourceAsset(string path, float pixelsPerUnit=100f) : LoadableAsset { private readonly Assembly _assembly = Assembly.GetCallingAssembly(); @@ -14,9 +15,9 @@ public class LoadableResourceAsset(string path, float pixelsPerUnit=100f) : Load /// public override Sprite LoadAsset() { - if (LoadedAsset != null) + if (LoadedAsset) { - return LoadedAsset; + return LoadedAsset!; } return LoadedAsset = SpriteTools.LoadSpriteFromPath(path, _assembly, pixelsPerUnit); diff --git a/MiraAPI/Utilities/Assets/SpriteTools.cs b/MiraAPI/Utilities/Assets/SpriteTools.cs index 5d438de..981d2e2 100644 --- a/MiraAPI/Utilities/Assets/SpriteTools.cs +++ b/MiraAPI/Utilities/Assets/SpriteTools.cs @@ -14,6 +14,8 @@ public static class SpriteTools /// Load a sprite from a resource path. /// /// The path to the resource. + /// The assembly containing the resource. + /// The pixels per unit for the loaded sprite. /// A sprite made from the resource. /// The resource cannot be found. public static Sprite LoadSpriteFromPath(string resourcePath, Assembly assembly, float pixelsPerUnit)