├── .gitignore ├── CodeIsNotAmongUs.sln ├── CodeIsNotAmongUs ├── .gitignore ├── CodeIsNotAmongUs.csproj ├── CodeIsNotAmongUsPlugin.cs ├── MeetingHudMode.cs └── Patches │ ├── CustomRegion.cs │ ├── HideCode.cs │ ├── RemovePlayerLimit │ ├── ColorPatches.cs │ ├── MeetingHudModes │ │ ├── Pagination.cs │ │ └── Scrolling.cs │ ├── MeetingPatches.cs │ ├── RemovePlayerLimit.cs │ └── TaskPatches.cs │ └── ShowAllOptions.cs └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | /packages/ 4 | riderModule.iml 5 | /_ReSharper.Caches/ 6 | .idea -------------------------------------------------------------------------------- /CodeIsNotAmongUs.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeIsNotAmongUs", "CodeIsNotAmongUs\CodeIsNotAmongUs.csproj", "{A964FB9D-5276-4AE8-BF7C-A89F086AE692}" 4 | EndProject 5 | Global 6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 7 | Debug|Any CPU = Debug|Any CPU 8 | Release|Any CPU = Release|Any CPU 9 | EndGlobalSection 10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 11 | {A964FB9D-5276-4AE8-BF7C-A89F086AE692}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 12 | {A964FB9D-5276-4AE8-BF7C-A89F086AE692}.Debug|Any CPU.Build.0 = Debug|Any CPU 13 | {A964FB9D-5276-4AE8-BF7C-A89F086AE692}.Release|Any CPU.ActiveCfg = Release|Any CPU 14 | {A964FB9D-5276-4AE8-BF7C-A89F086AE692}.Release|Any CPU.Build.0 = Release|Any CPU 15 | EndGlobalSection 16 | EndGlobal 17 | -------------------------------------------------------------------------------- /CodeIsNotAmongUs/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | /packages/ 4 | riderModule.iml 5 | /_ReSharper.Caches/ 6 | .idea -------------------------------------------------------------------------------- /CodeIsNotAmongUs/CodeIsNotAmongUs.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netstandard2.1 4 | 1.0.0 5 | latest 6 | 2020.12.9s 7 | NuclearPowered/Mappings:0.1.2 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /CodeIsNotAmongUs/CodeIsNotAmongUsPlugin.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using BepInEx.Configuration; 3 | using BepInEx.IL2CPP; 4 | using CodeIsNotAmongUs.Patches; 5 | using CodeIsNotAmongUs.Patches.RemovePlayerLimit; 6 | using HarmonyLib; 7 | using Reactor; 8 | 9 | namespace CodeIsNotAmongUs 10 | { 11 | [BepInPlugin(Id)] 12 | [BepInProcess("Among Us.exe")] 13 | [BepInDependency(ReactorPlugin.Id)] 14 | public class CodeIsNotAmongUsPlugin : BasePlugin 15 | { 16 | public const string Id = "pl.js6pak.CodeIsNotAmongUs"; 17 | 18 | public Harmony Harmony { get; } = new Harmony(Id); 19 | 20 | public ConfigEntry HideCode { get; private set; } 21 | public ConfigEntry ShowAllOptions { get; private set; } 22 | public ConfigEntry MeetingHudMode { get; internal set; } 23 | 24 | public override void Load() 25 | { 26 | HideCode = Config.Bind("Tweaks", "Hide code", false, "Hides code while in lobby (its printed out in the logs)"); 27 | ShowAllOptions = Config.Bind("Tweaks", "Show all options", true, "Allows changing options like map, impostor count, player max count in lobby"); 28 | MeetingHudMode = Config.Bind("RemovePlayerLimit", "MeetingHud Mode", CodeIsNotAmongUs.MeetingHudMode.Pagination); 29 | 30 | CustomRegion.Initialize(this); 31 | RemovePlayerLimit.Initialize(); 32 | ColorPatches.Initialize(); 33 | Harmony.PatchAll(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /CodeIsNotAmongUs/MeetingHudMode.cs: -------------------------------------------------------------------------------- 1 | namespace CodeIsNotAmongUs 2 | { 3 | public enum MeetingHudMode 4 | { 5 | Scrolling, 6 | Pagination 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /CodeIsNotAmongUs/Patches/CustomRegion.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Reflection; 4 | using BepInEx.Configuration; 5 | using HarmonyLib; 6 | 7 | namespace CodeIsNotAmongUs.Patches 8 | { 9 | internal static class CustomRegion 10 | { 11 | private static List _defaultRegions; 12 | 13 | private static readonly PropertyInfo _orphanedEntriesProperty = AccessTools.Property(typeof(ConfigFile), "OrphanedEntries"); 14 | private const string Section = "Custom regions"; 15 | 16 | public static void Initialize(CodeIsNotAmongUsPlugin plugin) 17 | { 18 | _defaultRegions = ServerManager.DefaultRegions.ToList(); 19 | 20 | var config = plugin.Config; 21 | 22 | config.ConfigReloaded += (_, _) => Reload(config); 23 | Reload(config); 24 | } 25 | 26 | public static void Reload(ConfigFile config) 27 | { 28 | var orphanedEntries = (Dictionary) _orphanedEntriesProperty.GetValue(config); 29 | 30 | var regions = orphanedEntries.Where(x => x.Key.Section == Section).ToList(); 31 | 32 | if (!regions.Any()) 33 | { 34 | orphanedEntries.Add(new ConfigDefinition(Section, "localhost"), "127.0.0.1:22023"); 35 | config.Save(); 36 | 37 | Reload(config); 38 | return; 39 | } 40 | 41 | var newRegions = _defaultRegions.ToList(); 42 | 43 | foreach (var pair in regions) 44 | { 45 | newRegions.Add(pair.Key.Key, pair.Value); 46 | } 47 | 48 | ServerManager.DefaultRegions = newRegions.ToArray(); 49 | } 50 | 51 | private static void Add(this IList regions, string name, string rawIp) 52 | { 53 | var split = rawIp.Split(':'); 54 | var ip = split[0]; 55 | var port = ushort.TryParse(split.ElementAtOrDefault(1), out var p) ? p : (ushort) 22023; 56 | 57 | regions.Insert(0, new RegionInfo( 58 | name, ip, new[] 59 | { 60 | new ServerInfo($"{name}-Master-1", ip, port) 61 | }) 62 | ); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /CodeIsNotAmongUs/Patches/HideCode.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using Reactor; 3 | 4 | namespace CodeIsNotAmongUs.Patches 5 | { 6 | [HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.Start))] 7 | internal static class HideCode 8 | { 9 | public static void Postfix(GameStartManager __instance) 10 | { 11 | var plugin = PluginSingleton.Instance; 12 | 13 | if (plugin.HideCode.Value) 14 | { 15 | __instance.GameRoomName.Text = "Room\r\nhidden"; 16 | plugin.Log.LogInfo($"Room code ({GameCode.IntToGameNameV2(AmongUsClient.Instance.GameId)}) hidden"); 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /CodeIsNotAmongUs/Patches/RemovePlayerLimit/ColorPatches.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Reflection; 4 | using HarmonyLib; 5 | using UnityEngine; 6 | 7 | namespace CodeIsNotAmongUs.Patches.RemovePlayerLimit 8 | { 9 | internal static class ColorPatches 10 | { 11 | public static void Initialize() 12 | { 13 | AddColor("Cyan", Color32(0, 150, 136), Color32(0, 121, 107)); 14 | AddColor("Gray", Color32(117, 117, 117), Color32(97, 97, 97)); 15 | AddColor("Tan", Color32(145, 137, 119), Color32(81, 66, 62)); 16 | } 17 | 18 | private static Color32 Color32(byte r, byte g, byte b) 19 | { 20 | return new Color32(r, g, b, 255); 21 | } 22 | 23 | private static void AddColor(string name, Color32 color, Color32 shadow) 24 | { 25 | Telemetry.ColorNames = Telemetry.ColorNames.AddItem(name).ToArray(); 26 | MedScanMinigame.ColorNames = MedScanMinigame.ColorNames.AddItem(name).ToArray(); 27 | 28 | Palette.PlayerColors = Palette.PlayerColors.AddItem(color).ToArray(); 29 | Palette.ShadowColors = Palette.ShadowColors.AddItem(shadow).ToArray(); 30 | } 31 | 32 | [HarmonyPatch(typeof(PlayerTab), nameof(PlayerTab.UpdateAvailableColors))] 33 | public static class UpdateAvailableColorsPatch 34 | { 35 | public static bool Prefix(PlayerTab __instance) 36 | { 37 | PlayerControl.SetPlayerMaterialColors(PlayerControl.LocalPlayer.Data.ColorId, __instance.DemoImage); 38 | for (var i = 0; i < Palette.PlayerColors.Length; i++) 39 | { 40 | __instance.AvailableColors.Add(i); 41 | } 42 | 43 | return false; 44 | } 45 | } 46 | 47 | // [HarmonyPatch(typeof(PlayerTab.c__DisplayClass10_0), nameof(PlayerTab.c__DisplayClass10_0.OnEnable))] // inlined SelectColor 48 | [HarmonyPatch] 49 | public static class SelectColorPatch 50 | { 51 | public static IEnumerable TargetMethods() 52 | { 53 | yield return typeof(PlayerTab.c__DisplayClass10_0).GetMethod("Method_Internal_Void_0"); // TODO unhollower being mean 54 | } 55 | 56 | public static bool Prefix(PlayerTab.c__DisplayClass10_0 __instance) 57 | { 58 | var colorId = __instance.j; 59 | 60 | SaveManager.BodyColor = (byte) colorId; 61 | if (PlayerControl.LocalPlayer) 62 | { 63 | PlayerControl.LocalPlayer.CmdCheckColor((byte) colorId); 64 | } 65 | 66 | return false; 67 | } 68 | } 69 | 70 | [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.CheckColor))] 71 | public static class CheckColorPatch 72 | { 73 | public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] byte bodyColor) 74 | { 75 | __instance.RpcSetColor(bodyColor); 76 | return false; 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /CodeIsNotAmongUs/Patches/RemovePlayerLimit/MeetingHudModes/Pagination.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using HarmonyLib; 3 | using Reactor; 4 | using UnityEngine; 5 | 6 | namespace CodeIsNotAmongUs.Patches.RemovePlayerLimit.MeetingHudModes 7 | { 8 | internal static class Pagination 9 | { 10 | private static bool Enabled => PluginSingleton.Instance.MeetingHudMode.Value == MeetingHudMode.Pagination; 11 | 12 | public static int Page { get; set; } 13 | 14 | private static string _lastText; 15 | 16 | private static void UpdatePageText(MeetingHud meetingHud, int maxPages) 17 | { 18 | if (meetingHud.TimerText.Text == _lastText) 19 | return; 20 | 21 | meetingHud.TimerText.Text = _lastText = meetingHud.TimerText.Text + $" ({Page + 1}/{maxPages})"; 22 | } 23 | 24 | [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Update))] 25 | public static class ButtonsPatch 26 | { 27 | public static void Postfix(MeetingHud __instance) 28 | { 29 | if (!Enabled) 30 | return; 31 | 32 | var maxPages = (int) Mathf.Ceil(__instance.playerStates.Count / 10f); 33 | 34 | Page = Input.mouseScrollDelta.y switch 35 | { 36 | > 0 => Mathf.Clamp(Page - 1, 0, maxPages - 1), 37 | < 0 => Mathf.Clamp(Page + 1, 0, maxPages - 1), 38 | _ => Page 39 | }; 40 | 41 | UpdatePageText(__instance, maxPages); 42 | 43 | var i = 0; 44 | 45 | foreach (var playerVoteArea in __instance.playerStates.ToArray().OrderBy(x => x.isDead).ThenBy(x => x.NameText.Text)) 46 | { 47 | var active = i >= 10 * Page && i < 10 * (Page + 1); 48 | playerVoteArea.gameObject.SetActive(active); 49 | 50 | if (active) 51 | { 52 | var paged = i - Page * 10; 53 | var x = paged % 2; 54 | var y = paged / 2; 55 | playerVoteArea.transform.localPosition = __instance.VoteOrigin + new Vector3(__instance.VoteButtonOffsets.x * x, __instance.VoteButtonOffsets.y * y, -1f); 56 | } 57 | 58 | i++; 59 | } 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /CodeIsNotAmongUs/Patches/RemovePlayerLimit/MeetingHudModes/Scrolling.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using HarmonyLib; 3 | using Reactor; 4 | using UnityEngine; 5 | 6 | namespace CodeIsNotAmongUs.Patches.RemovePlayerLimit.MeetingHudModes 7 | { 8 | internal static class Scrolling 9 | { 10 | private static bool Enabled => PluginSingleton.Instance.MeetingHudMode.Value == MeetingHudMode.Scrolling; 11 | 12 | public static float Scroll { get; set; } 13 | 14 | [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))] 15 | public static class StartPatch 16 | { 17 | public static void Postfix(MeetingHud __instance) 18 | { 19 | if (!Enabled) 20 | return; 21 | 22 | var original = __instance.transform.FindChild("Background").FindChild("baseGlass").gameObject; 23 | var mask = Object.Instantiate(original); 24 | mask.name = "Scrolling mask"; 25 | mask.transform.position = original.transform.position; 26 | // mask.transform.localScale = new Vector3(0.8f, 0.8f, 1f); 27 | var spriteRenderer = mask.GetComponent(); 28 | spriteRenderer.color = Color.red; 29 | var spriteMask = mask.AddComponent(); 30 | spriteMask.sprite = spriteRenderer.sprite; 31 | // Object.Destroy(spriteRenderer); 32 | } 33 | } 34 | 35 | [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Update))] 36 | public static class ButtonsPatch 37 | { 38 | public static void Postfix(MeetingHud __instance) 39 | { 40 | if (!Enabled) 41 | return; 42 | 43 | var maxPages = (int) Mathf.Ceil(__instance.playerStates.Count / 10f); 44 | 45 | Scroll = Mathf.Clamp(Scroll + Input.mouseScrollDelta.y, -maxPages, 0); 46 | System.Console.WriteLine("maxPages " + maxPages); 47 | System.Console.WriteLine("scroll " + Scroll); 48 | 49 | var i = 0; 50 | 51 | foreach (var playerVoteArea in __instance.playerStates.ToArray().OrderBy(x => x.isDead).ThenBy(x => x.NameText.Text)) 52 | { 53 | var x = i % 2; 54 | var y = i / 2 + Scroll / 2f; 55 | playerVoteArea.transform.localPosition = __instance.VoteOrigin + new Vector3(__instance.VoteButtonOffsets.x * x, __instance.VoteButtonOffsets.y * y, -1f); 56 | 57 | foreach (var renderer in playerVoteArea.GetComponentsInChildren()) 58 | { 59 | renderer.maskInteraction = SpriteMaskInteraction.VisibleInsideMask; 60 | } 61 | 62 | i++; 63 | } 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /CodeIsNotAmongUs/Patches/RemovePlayerLimit/MeetingPatches.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using HarmonyLib; 3 | using Hazel; 4 | using UnhollowerBaseLib; 5 | using UnityEngine; 6 | using Object = Il2CppSystem.Object; 7 | 8 | namespace CodeIsNotAmongUs.Patches.RemovePlayerLimit 9 | { 10 | public static class MeetingPatches 11 | { 12 | [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.CheckForEndVoting))] 13 | public static class CheckForEndVotingPatch 14 | { 15 | // "api" for all mayors out there :) 16 | public static byte GetVotePower(PlayerVoteArea playerVoteArea) 17 | { 18 | return 1; 19 | } 20 | 21 | public static int IndexOfMax(T[] self, out bool tie) 22 | { 23 | var max = self.Max(); 24 | 25 | if (self.Count(x => x.Equals(max)) > 1) 26 | { 27 | tie = true; 28 | return -1; 29 | } 30 | 31 | tie = false; 32 | return self.ToList().IndexOf(max); 33 | } 34 | 35 | public static bool Prefix(MeetingHud __instance) 36 | { 37 | var playerStates = __instance.playerStates; 38 | if (playerStates.All(ps => ps != null && (ps.isDead || ps.didVote))) 39 | { 40 | var self = new byte[playerStates.Max(x => x.TargetPlayerId) + 2]; 41 | foreach (var playerVoteArea in playerStates) 42 | { 43 | if (playerVoteArea.didVote && !playerVoteArea.isDead) 44 | { 45 | // -2 none, -1 skip, 0+ players 46 | if (playerVoteArea.votedFor == -2) 47 | continue; 48 | 49 | var votedFor = playerVoteArea.votedFor + 1; 50 | if (votedFor >= 0 && votedFor < self.Length) 51 | { 52 | self[votedFor] += GetVotePower(playerVoteArea); 53 | } 54 | } 55 | } 56 | 57 | var maxIdx = IndexOfMax(self, out var tie) - 1; 58 | var exiled = GameData.Instance.AllPlayers.ToArray().FirstOrDefault(v => v != null && v.PlayerId == maxIdx); 59 | 60 | var states = playerStates.Select(ps => ps != null ? ps.GetState() : (byte) 0).ToArray(); 61 | var votes = playerStates.Select(s => (byte) s.votedFor).ToArray(); 62 | 63 | var messageWriter = AmongUsClient.Instance.StartRpc(__instance.NetId, 23, SendOption.Reliable); 64 | messageWriter.WriteBytesAndSize(states); 65 | messageWriter.WriteBytesAndSize(votes); 66 | messageWriter.Write(exiled != null && exiled.Object != null ? exiled.Object.PlayerId : byte.MaxValue); 67 | messageWriter.Write(tie); 68 | messageWriter.EndMessage(); 69 | 70 | VotingComplete(__instance, states, votes, exiled, tie); 71 | } 72 | 73 | return false; 74 | } 75 | } 76 | 77 | [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.HandleRpc))] 78 | public static class MeetingHudHandleRpcPatch 79 | { 80 | public static bool Prefix(MeetingHud __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader) 81 | { 82 | if (callId == (int) RpcCalls.VotingComplete) 83 | { 84 | var states = reader.ReadBytesAndSize(); 85 | var votes = reader.ReadBytesAndSize(); 86 | var playerById = GameData.Instance.GetPlayerById(reader.ReadByte()); 87 | var tie = reader.ReadBoolean(); 88 | VotingComplete(__instance, states, votes, playerById, tie); 89 | 90 | return false; 91 | } 92 | 93 | return true; 94 | } 95 | } 96 | 97 | private static void VotingComplete(MeetingHud __instance, byte[] states, byte[] votes, GameData.PlayerInfo exiled, bool tie) 98 | { 99 | if (__instance.state == MeetingHud.VoteStates.Results) 100 | { 101 | return; 102 | } 103 | 104 | __instance.state = MeetingHud.VoteStates.Results; 105 | __instance.resultsStartedAt = __instance.discussionTimer; 106 | __instance.exiledPlayer = exiled; 107 | __instance.wasTie = tie; 108 | __instance.SkipVoteButton.gameObject.SetActive(false); 109 | __instance.SkippedVoting.gameObject.SetActive(true); 110 | AmongUsClient.Instance.DisconnectHandlers.Remove(__instance.Cast()); 111 | PopulateResults(__instance, states, votes); 112 | __instance.SetupProceedButton(); 113 | } 114 | 115 | private static void PopulateResults(MeetingHud __instance, byte[] states, byte[] votes) 116 | { 117 | __instance.TitleText.Text = DestroyableSingleton.Instance.GetString(StringNames.MeetingVotingResults, new Il2CppReferenceArray(0)); 118 | var skippedCount = 0; 119 | for (var i = 0; i < __instance.playerStates.Length; i++) 120 | { 121 | var playerVoteArea = __instance.playerStates[i]; 122 | playerVoteArea.ClearForResults(); 123 | var votedCount = 0; 124 | for (var j = 0; j < states.Length; j++) 125 | { 126 | if ((states[j] & 128) == 0) 127 | { 128 | { 129 | if (j > __instance.playerStates.Length) 130 | { 131 | break; 132 | } 133 | 134 | var playerById = GameData.Instance.GetPlayerById((byte) __instance.playerStates[j].TargetPlayerId); 135 | var votedFor = (int) votes[j]; 136 | 137 | var voted = votedFor == playerVoteArea.TargetPlayerId; 138 | var skipped = i == 0 && (votedFor == -1 || votedFor == 255); 139 | 140 | if (voted || skipped) 141 | { 142 | var spriteRenderer = UnityEngine.Object.Instantiate(__instance.PlayerVotePrefab, skipped ? __instance.SkippedVoting.transform : playerVoteArea.transform, true); 143 | if (PlayerControl.GameOptions.AnonymousVotes) 144 | { 145 | PlayerControl.SetPlayerMaterialColors(Palette.Black, spriteRenderer); 146 | } 147 | else 148 | { 149 | PlayerControl.SetPlayerMaterialColors(playerById.ColorId, spriteRenderer); 150 | } 151 | 152 | var transform = spriteRenderer.transform; 153 | transform.localPosition = __instance.CounterOrigin + new Vector3(__instance.CounterOffsets.x * (skipped ? skippedCount : votedCount), 0f, 0f); 154 | 155 | if (__instance.playerStates.Length <= 15) 156 | { 157 | transform.localScale = Vector3.zero; 158 | __instance.StartCoroutine(Effects.Bloop(Mathf.Min(skipped ? skippedCount : votedCount, 10), transform, 1, 0.5f)); 159 | } 160 | 161 | if (skipped) 162 | { 163 | skippedCount++; 164 | } 165 | else 166 | { 167 | votedCount++; 168 | } 169 | } 170 | } 171 | } 172 | } 173 | } 174 | } 175 | 176 | [HarmonyPatch(typeof(PlayerVoteArea), nameof(PlayerVoteArea.GetState))] 177 | public static class GetStatePatch 178 | { 179 | public static bool Prefix(PlayerVoteArea __instance, out byte __result) 180 | { 181 | __result = (byte) ((__instance.isDead ? 128 : 0) | (__instance.didVote ? 64 : 0) | (__instance.didReport ? 32 : 0)); 182 | return false; 183 | } 184 | } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /CodeIsNotAmongUs/Patches/RemovePlayerLimit/RemovePlayerLimit.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Linq; 3 | using HarmonyLib; 4 | using Reactor; 5 | using UnhollowerBaseLib; 6 | using UnityEngine; 7 | 8 | namespace CodeIsNotAmongUs.Patches.RemovePlayerLimit 9 | { 10 | public static class RemovePlayerLimit 11 | { 12 | public static void Initialize() 13 | { 14 | GameOptionsData.MaxImpostors = GameOptionsData.RecommendedImpostors = Enumerable.Repeat((int) byte.MaxValue, byte.MaxValue).ToArray(); 15 | } 16 | 17 | [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.Start))] 18 | public static class HitBufferPatch 19 | { 20 | public static void Postfix(PlayerControl __instance) 21 | { 22 | __instance.hitBuffer = new Il2CppReferenceArray(200); 23 | } 24 | } 25 | 26 | [HarmonyPatch(typeof(GameData), nameof(GameData.GetAvailableId))] 27 | public static class GetAvailableIdPatch 28 | { 29 | public static bool Prefix(GameData __instance, out sbyte __result) 30 | { 31 | var i = (sbyte) 0; 32 | 33 | while (__instance.AllPlayers.ToArray().Any(p => p.PlayerId == i)) 34 | { 35 | i++; 36 | } 37 | 38 | __result = i; 39 | 40 | return false; 41 | } 42 | } 43 | 44 | public static bool IsInCutscene { get; private set; } 45 | 46 | [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.SetInfected))] 47 | public static class SetInfectedPatch 48 | { 49 | public static void Postfix() 50 | { 51 | if (TutorialManager.InstanceExists) 52 | return; 53 | 54 | IsInCutscene = true; 55 | Coroutines.Start(Coroutine()); 56 | } 57 | 58 | public static IEnumerator Coroutine() 59 | { 60 | yield return new WaitForSeconds(5); 61 | 62 | IsInCutscene = false; 63 | HudManager.Instance.SetHudActive(true); 64 | } 65 | } 66 | 67 | [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.CanMove), MethodType.Getter)] 68 | public static class CanMovePatch 69 | { 70 | public static bool Prefix(ref bool __result) 71 | { 72 | if (IsInCutscene) 73 | { 74 | return __result = false; 75 | } 76 | 77 | return true; 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /CodeIsNotAmongUs/Patches/RemovePlayerLimit/TaskPatches.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using UnityEngine; 3 | 4 | namespace CodeIsNotAmongUs.Patches.RemovePlayerLimit 5 | { 6 | internal static class TaskPatches 7 | { 8 | [HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.GetSpawnLocation))] 9 | public static class GetSpawnLocationPatch 10 | { 11 | public static void Prefix([HarmonyArgument(0)] ref int playerId, [HarmonyArgument(1)] ref int numPlayer) 12 | { 13 | playerId %= 10; 14 | numPlayer = Mathf.Max(numPlayer, 10); 15 | } 16 | } 17 | 18 | [HarmonyPatch(typeof(KeyMinigame), nameof(KeyMinigame.Start))] 19 | public static class KeyMinigamePatch 20 | { 21 | public static void Postfix(KeyMinigame __instance) 22 | { 23 | var localPlayer = PlayerControl.LocalPlayer; 24 | __instance.targetSlotId = localPlayer != null ? localPlayer.PlayerId % 10 : 0; 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /CodeIsNotAmongUs/Patches/ShowAllOptions.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using Reactor; 3 | using UnhollowerBaseLib; 4 | using UnityEngine; 5 | 6 | namespace CodeIsNotAmongUs.Patches 7 | { 8 | [HarmonyPatch(typeof(GameSettingMenu), nameof(GameSettingMenu.OnEnable))] 9 | internal static class ShowAllOptions 10 | { 11 | public static void Prefix(GameSettingMenu __instance) 12 | { 13 | if (PluginSingleton.Instance.ShowAllOptions.Value) 14 | { 15 | __instance.HideForOnline = new Il2CppReferenceArray(0); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Code is not among us 2 | 3 | Among Us tweaks: 4 | 5 | - use custom servers (without bloated winforms) 6 | - hide lobby code ingame 7 | - remove player limit (or at least make it 127) 8 | - show all options (allows changing options like map, impostor count, player max count in lobby) --------------------------------------------------------------------------------