Due to update 2.4.3, some mods may no longer function. FixedConfig may be necessary.
Decompiled source of MoreTeams v0.1.4
BoplMoreColors.dll
Decompiled a month agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BoplFixedMath; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.InputSystem; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BoplMoreColors")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Adds extra team colors to Bopl Battle so 5-8 players can each have a unique color.")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+5be22ba2cb08359e5e875f0a4e034318450b9419")] [assembly: AssemblyProduct("BoplMoreColors")] [assembly: AssemblyTitle("BoplMoreColors")] [assembly: AssemblyVersion("0.1.4.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BoplMoreColors { [BepInPlugin("com.geddesworks.boplmorecolors", "MoreTeams", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.geddesworks.boplmorecolors"; public const string PluginName = "MoreTeams"; public const string PluginVersion = "0.1.0"; internal static ConfigEntry<int> ExtraColorCount; internal static ConfigEntry<bool> EnableDiagnostics; private Harmony? _harmony; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; BindConfig(); _harmony = new Harmony("com.geddesworks.boplmorecolors"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); string[] array = (from method in _harmony.GetPatchedMethods().Where(delegate(MethodBase method) { Patches patchInfo = Harmony.GetPatchInfo(method); return patchInfo != null && patchInfo.Owners.Contains("com.geddesworks.boplmorecolors"); }) select method.DeclaringType?.FullName + "." + method.Name into name orderby name select name).ToArray(); Log.LogInfo((object)"MoreTeams 0.1.0 loaded."); Log.LogInfo((object)$"Extra colors to add: {ExtraColorCount.Value}."); Log.LogInfo((object)string.Format("Patched {0} methods:\n - {1}", array.Length, string.Join("\n - ", array))); } private void BindConfig() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown ExtraColorCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ExtraColorCount", 8, new ConfigDescription("Number of extra team colors to add beyond the vanilla palette.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 12), Array.Empty<object>())); EnableDiagnostics = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "EnableDiagnostics", true, "Log diagnostic info about color expansion at startup."); } internal static void LogDiag(string message) { if (EnableDiagnostics.Value) { Log.LogInfo((object)("[Diag] " + message)); } } } } namespace BoplMoreColors.Patches { [HarmonyPatch(typeof(CharacterSelectHandler), "Awake")] internal static class ColorExpansionPatch { private readonly struct ExtraColorDef { public readonly string Name; public readonly Color Color; public ExtraColorDef(string name, Color color) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) Name = name; Color = color; } } private static readonly ExtraColorDef[] ExtraColors = new ExtraColorDef[12] { new ExtraColorDef("Orange", new Color(1f, 0.55f, 0.05f)), new ExtraColorDef("Pink", new Color(1f, 0.3f, 0.6f)), new ExtraColorDef("Cyan", new Color(0f, 0.85f, 0.85f)), new ExtraColorDef("Lime", new Color(0.5f, 1f, 0.15f)), new ExtraColorDef("Maroon", new Color(0.55f, 0.05f, 0.1f)), new ExtraColorDef("Teal", new Color(0.1f, 0.55f, 0.55f)), new ExtraColorDef("Gold", new Color(1f, 0.84f, 0f)), new ExtraColorDef("Lavender", new Color(0.7f, 0.5f, 0.9f)), new ExtraColorDef("Coral", new Color(1f, 0.5f, 0.31f)), new ExtraColorDef("Mint", new Color(0.4f, 1f, 0.7f)), new ExtraColorDef("Navy", new Color(0.05f, 0.1f, 0.45f)), new ExtraColorDef("Peach", new Color(1f, 0.75f, 0.55f)) }; [HarmonyPostfix] private static void Postfix(CharacterSelectHandler __instance) { int value = Plugin.ExtraColorCount.Value; if (value > 0) { int toAdd = Mathf.Min(value, ExtraColors.Length); ExpandTeamColors(__instance, toAdd); } } private static void ExpandTeamColors(CharacterSelectHandler handler, int toAdd) { //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) CharacterSelectBox[] value = Traverse.Create((object)handler).Field<CharacterSelectBox[]>("characterSelectBoxes").Value; if (value == null || value.Length == 0) { Plugin.Log.LogWarning((object)"characterSelectBoxes is null/empty — cannot expand TeamColors."); return; } TeamColors val = null; CharacterSelectBox[] array = value; foreach (CharacterSelectBox val2 in array) { if (!((Object)(object)val2 == (Object)null)) { TeamSelector componentInChildren = ((Component)val2).GetComponentInChildren<TeamSelector>(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.teams != (Object)null) { val = componentInChildren.teams; break; } } } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"Could not find TeamColors via TeamSelector — cannot expand teams."); return; } TeamColor[] teamColors = val.teamColors; if (teamColors == null || teamColors.Length == 0) { Plugin.Log.LogWarning((object)"TeamColors.teamColors array is null/empty."); return; } Plugin.LogDiag($"Vanilla TeamColors has {teamColors.Length} teams. Adding {toAdd} extras."); TeamColor[] array2 = (TeamColor[])(object)new TeamColor[teamColors.Length + toAdd]; Array.Copy(teamColors, array2, teamColors.Length); for (int j = 0; j < toAdd; j++) { ExtraColorDef extraColorDef = ExtraColors[j]; int num = teamColors.Length + j; Color color = extraColorDef.Color; Color val3 = DarkenColor(extraColorDef.Color, 0.5f); Color saturated = SaturateColor(extraColorDef.Color, 1.3f); array2[num] = new TeamColor { team = num, fill = color, border = val3, saturated = saturated }; Plugin.LogDiag($" Team[{num}] {extraColorDef.Name}: fill=({color.r:F2},{color.g:F2},{color.b:F2}) border=({val3.r:F2},{val3.g:F2},{val3.b:F2})"); } val.teamColors = array2; Plugin.LogDiag($"TeamColors expanded to {val.Length} entries."); } private static Color DarkenColor(Color c, float factor) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) return new Color(Mathf.Clamp01(c.r * factor), Mathf.Clamp01(c.g * factor), Mathf.Clamp01(c.b * factor), 1f); } private static Color SaturateColor(Color c, float factor) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) float num = default(float); float num2 = default(float); float num3 = default(float); Color.RGBToHSV(c, ref num, ref num2, ref num3); num2 = Mathf.Clamp01(num2 * factor); num3 = Mathf.Clamp01(num3 * 1.1f); Color result = Color.HSVToRGB(num, num2, num3); result.a = 1f; return result; } } [HarmonyPatch(typeof(GameSessionHandler), "SpawnPlayers")] internal static class SpawnPlayersExpandedTeamsPatch { [HarmonyPrefix] private static bool Prefix(GameSessionHandler __instance) { List<Player> list = PlayerHandler.Get().PlayerList(); if (list.Count <= 4) { return true; } SpawnPlayersFixed(__instance, list); return false; } private static void SpawnPlayersFixed(GameSessionHandler handler, List<Player> players) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) Traverse.Create((object)handler).Field<bool>("gameInProgress").Value = true; SlimeController[] array = (SlimeController[])(object)new SlimeController[players.Count]; Traverse.Create((object)handler).Field<SlimeController[]>("slimeControllers").Value = array; int[] uniqueTeams = GetUniqueTeams(players); int num = uniqueTeams.Length; int num2 = 0; foreach (Player player in players) { if (player.Team > num2) { num2 = player.Team; } } int[] array2 = new int[num2 + 1]; Vec2[] teamSpawns = handler.teamSpawns; Vec2[] array3 = (Vec2[])(object)new Vec2[num]; for (int i = 0; i < num; i++) { array3[i] = teamSpawns[i % teamSpawns.Length]; } Fix teammateSpawnSpacing = handler.teammateSpawnSpacing; TeamColors teamColors = handler.teamColors; SlimeController playerPrefab = handler.PlayerPrefab; InputUpdater inputUpdaterPrefab = handler.InputUpdaterPrefab; List<GameObject> abilityReadyIndicators = handler.AbilityReadyIndicators; GameObject playerSpawnsRoot = handler.playerSpawnsRoot; List<InputUpdater> list = new List<InputUpdater>(); for (int j = 0; j < players.Count; j++) { Player val = players[j]; int num3 = Array.IndexOf(uniqueTeams, val.Team); val.playersAndClonesStillAlive = 1; Vec2 val2 = ((array2[val.Team] == 0) ? array3[num3] : ((array2[val.Team] == 1) ? (array3[num3] - new Vec2(teammateSpawnSpacing, teammateSpawnSpacing * (Fix)0.5)) : (array3[num3] + new Vec2(teammateSpawnSpacing, -teammateSpawnSpacing * (Fix)0.5)))); array2[val.Team]++; array[j] = FixTransform.InstantiateFixed<SlimeController>(playerPrefab, val2); array[j].playerNumber = val.Id; ((Component)array[j]).transform.SetParent(playerSpawnsRoot.transform); array[j].GetPlayerSprite().sprite = null; ((Renderer)array[j].GetPlayerSprite()).material = val.Color; List<AbilityMonoBehaviour> list2 = new List<AbilityMonoBehaviour>(); val.CurrentAbilities = new List<GameObject>(); bool flag = false; bool flag2 = true; for (int k = 0; k < val.Abilities.Count; k++) { if ((Object)(object)val.Abilities[k].GetComponent<RandomAbility>() == (Object)null) { flag2 = false; } } for (int l = 0; l < val.Abilities.Count; l++) { RandomAbility component = val.Abilities[l].GetComponent<RandomAbility>(); if ((Object)(object)component != (Object)null) { NamedSprite randomAbilityPrefab = RandomAbility.GetRandomAbilityPrefab(component.abilityIcons, component.abilityIcons_demo); flag |= randomAbilityPrefab.isOffensiveAbility; if (flag2 && !flag && l == val.Abilities.Count - 1) { randomAbilityPrefab = RandomAbility.GetRandomAbilityPrefab(component.abilityIcons, component.abilityIcons_demo); } val.AbilityIcons[l] = randomAbilityPrefab.sprite; GameObject val3 = FixTransform.InstantiateFixed(randomAbilityPrefab.associatedGameObject, Vec2.zero); val3.SetActive(false); val.CurrentAbilities.Add(val3); list2.Add(val3.GetComponent<AbilityMonoBehaviour>()); } else { GameObject val4 = FixTransform.InstantiateFixed(val.Abilities[l], Vec2.zero); val4.SetActive(false); val.CurrentAbilities.Add(val4); list2.Add(val4.GetComponent<AbilityMonoBehaviour>()); } } array[j].abilities = list2; AbilityReadyIndicator[] array4 = (AbilityReadyIndicator[])(object)new AbilityReadyIndicator[3]; for (int m = 0; m < 3; m++) { array4[m] = Object.Instantiate<GameObject>(abilityReadyIndicators[m], playerSpawnsRoot.transform).GetComponent<AbilityReadyIndicator>(); array4[m].Init(); array4[m].SetColor(teamColors.teamColors[val.Team].fill); ((Component)array4[m]).GetComponent<FollowTransform>().Leader = ((Component)array[j]).transform; ((Component)array4[m]).gameObject.SetActive(false); if (m < val.AbilityIcons.Count) { array4[m].SetSprite(val.AbilityIcons[m], true); } } array[j].AbilityReadyIndicators = array4; Traverse.Create((object)handler).Field<bool>("gameOver").Value = false; if (val.IsLocalPlayer) { InputUpdater val5 = Object.Instantiate<InputUpdater>(inputUpdaterPrefab); PlayerInput component2 = ((Component)val5).GetComponent<PlayerInput>(); val5.Claim(val.Id); val5.Init(val.Id); component2.neverAutoSwitchControlSchemes = true; component2.ActivateInput(); list.Add(val5); } } Plugin.LogDiag($"SpawnPlayersFixed: spawned {players.Count} players across {num} teams."); } private static int[] GetUniqueTeams(List<Player> players) { HashSet<int> hashSet = new HashSet<int>(); foreach (Player player in players) { hashSet.Add(player.Team); } int[] array = new int[hashSet.Count]; hashSet.CopyTo(array); Array.Sort(array); return array; } } }