Compare commits

...
16 Commits
Author SHA1 Message Date
Ape 95106ddeeb Settings and settings + settings, settings 2026-02-12 23:19:07 +01:00
Ape f4c157153a Merge branch 'main' of https://github.com/ApeMV/AmongUsRevamped 2026-02-05 14:23:15 +01:00
Ape 84978edc99 Tiniest fixes ever and buttons 2026-02-05 14:23:10 +01:00
Ape 23715a848d Meow 2026-02-05 11:58:23 +01:00
Ape a7cec7787f 1.5.1 readme 2026-02-05 11:54:42 +01:00
Ape 02f7ddc63a Custom role fixes, small setting fix, winner text change 2026-02-02 20:41:26 +01:00
Ape 600234b5f2 Discodr icon 2026-02-02 15:18:40 +01:00
Ape 15d6f54982 Better options, String fix, HnS fix 2026-02-02 14:10:50 +01:00
Ape 5570d6f4ea Kick players who say start, small num fix 2026-02-01 21:14:13 +01:00
Ape e9f1c1aaf1 Lighting the stars + like so many other stuff 2026-02-01 20:19:24 +01:00
Ape a6c3220892 Starlight compatibility, small fixes 2026-02-01 15:59:29 +01:00
Ape 673386336a Dleks, Fixes, Role assigner, Sprites, Translation system 2026-01-25 20:24:09 +01:00
Ape 2ac4728f8a 1.4.0 2026-01-23 19:09:40 +01:00
Ape 88599a0680 ? ? ? ? ? ? ? ? ? ? 2026-01-23 18:44:07 +01:00
Ape 5ae6d648e3 ??????????????????????? 2026-01-23 17:39:24 +01:00
Ape 21dec84e64 I cast null reference exception 2026-01-23 00:41:37 +01:00
37 changed files with 1693 additions and 299 deletions

No files matched your search

+10 -1
View File
@@ -1,6 +1,7 @@
global using HarmonyLib;
global using System.Collections.Generic;
global using System.Linq;
global using Object = UnityEngine.Object;
using AmongUs.GameOptions;
using BepInEx;
@@ -11,6 +12,9 @@ using UnityEngine;
namespace AmongUsRevamped;
// dotnet build -c release
// dotnet build -c android
[BepInAutoPlugin]
[BepInProcess("Among Us.exe")]
public partial class Main : BasePlugin
@@ -33,12 +37,17 @@ public partial class Main : BasePlugin
public static ConfigEntry<bool> LobbyMusic { get; private set; }
public static NormalGameOptionsV10 NormalOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentNormalGameOptions : null;
public static HideNSeekGameOptionsV10 HideNSeekOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentHideNSeekGameOptions : null;
public static MapNames CurrentMap => (MapNames)NormalOptions.MapId;
public static bool HasArgumentException;
public static string CredentialsText;
public const string ModVersion = "v1.3.3";
public const string ModVersion = "v1.5.2";
public static float GameTimer;
public static readonly Dictionary<int, int> SayStartTimes = [];
public static PlayerControl[] AllPlayerControls
{
get
+17 -8
View File
@@ -1,24 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework Condition="'$(Configuration)' == 'Android'">net8.0</TargetFramework>
<TargetFramework Condition="'$(Configuration)' != 'Android'">net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
<DebugType>embedded</DebugType>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>dev</VersionSuffix>
<Description>The ultimate Host-Only mod without Modded Protocol</Description>
<Authors>Most Various</Authors>
<Authors>apemv</Authors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Release;Android</Configurations>
<Configuration Condition="'$(Configuration)' == ''">Release</Configuration>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<Configuration>Release</Configuration>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.735" Private="false" ExcludeAssets="runtime;native" />
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2025.11.18" PrivateAssets="all" />
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.735" ExcludeAssets="runtime;native" />
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2025.11.18" PrivateAssets="all" Condition="'$(Configuration)' == 'Release'"/>
<PackageReference Include="AmongUs.GameLibs.Android" Version="2025.10.14" PrivateAssets="all" Condition="'$(Configuration)' == 'Android'"/>
<PackageReference Include="BepInEx.AutoPlugin" Version="1.1.0" PrivateAssets="all" />
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.1.0-rc.1" PrivateAssets="all" ExcludeAssets="runtime" />
<EmbeddedResource Include=".\Resources\**" />
</ItemGroup>
<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != ''">
<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != '' And '$(Configuration)' != 'Android'">
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(AmongUs)/BepInEx/plugins/" UseSymboliclinksIfPossible="true" />
</Target>
</Project>
+29 -5
View File
@@ -5,22 +5,30 @@ using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
using UnityEngine;
// https://github.com/EnhancedNetwork/TownofHost-Enhanced/blob/main/Modules/BanManager.cs
namespace AmongUsRevamped;
public static class BanManager
{
public static readonly string DataPath =
#if ANDROID
Application.persistentDataPath;
#else
".";
#endif
public static string RemoveHtmlTags(this string str) => Regex.Replace(str, "<[^>]*?>", "");
private static readonly string DenyNameListPath = "./AUR-DATA/DenyNameList.txt";
private static string BanListPath = "./AUR-DATA/BanList.txt";
private static string ModeratorListPath = "./AUR-DATA/ModeratorList.txt";
private static readonly string DenyNameListPath = $"{DataPath}/AUR-DATA/DenyNameList.txt";
private static string BanListPath = $"{DataPath}/AUR-DATA/BanList.txt";
private static string ModeratorListPath = $"{DataPath}/AUR-DATA/ModeratorList.txt";
public static List<string> TempBanWhiteList = [];
public static void Init()
{
try
{
Directory.CreateDirectory("AUR-DATA");
if (!Directory.Exists($"{DataPath}/AUR-DATA")) Directory.CreateDirectory($"{DataPath}/AUR-DATA");
if (!File.Exists(DenyNameListPath))
{
@@ -120,8 +128,9 @@ public static class BanManager
try
{
Directory.CreateDirectory("AUR-DATA");
if (!Directory.Exists($"{DataPath}/AUR-DATA")) Directory.CreateDirectory($"{DataPath}/AUR-DATA");
if (!File.Exists(BanListPath)) File.Create(BanListPath).Close();
using StreamReader sr = new(BanListPath);
string line;
while ((line = sr.ReadLine()) != null)
@@ -141,6 +150,21 @@ public static class BanManager
}
return false;
}
public static bool IsPlayerInDenyName(ClientData client, string name)
{
if (name == "" || !AmongUsClient.Instance.AmHost || !Options.ApplyDenyNameList.GetBool()) return false;
var deniedNames = File.ReadAllLines(DenyNameListPath);
if (deniedNames.Where(code => !string.IsNullOrWhiteSpace(code)).Any(code => name.Contains(code, StringComparison.OrdinalIgnoreCase)))
{
AmongUsClient.Instance.KickPlayer(client.Id, false);
Logger.Info($" {name} was kicked because their name was in DenyNameList.txt", "Kick");
Logger.SendInGame($" {name} was kicked because their name was in DenyNameList.txt");
return true;
}
else return false;
}
}
[HarmonyPatch(typeof(BanMenu), nameof(BanMenu.Select))]
+221 -24
View File
@@ -4,23 +4,6 @@ using UnityEngine;
// https://github.com/tukasa0001/TownOfHost/blob/main/Modules/OptionHolder.cs
namespace AmongUsRevamped
{
[HarmonyPatch]
public static class Options
{
static Task taskOptionsLoad;
[HarmonyPatch(typeof(TranslationController), nameof(TranslationController.Initialize)), HarmonyPostfix]
public static void OptionsLoadStart()
{
taskOptionsLoad = Task.Run(Load);
}
[HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start)), HarmonyPostfix]
public static void WaitOptionsLoad()
{
taskOptionsLoad.Wait();
}
public static class CL
{
public static Color32 Hex(string hex)
@@ -41,8 +24,26 @@ namespace AmongUsRevamped
byte b = byte.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);
return new Color32(r, g, b, 255);
}
}
}
[HarmonyPatch]
public static class Options
{
static Task taskOptionsLoad;
[HarmonyPatch(typeof(TranslationController), nameof(TranslationController.Initialize)), HarmonyPostfix]
public static void OptionsLoadStart()
{
taskOptionsLoad = Task.Run(Load);
}
[HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start)), HarmonyPostfix]
public static void WaitOptionsLoad()
{
taskOptionsLoad.Wait();
}
public const int PresetId = 0;
private static readonly string[] presets =
@@ -77,6 +78,11 @@ namespace AmongUsRevamped
public static OptionItem ApplyModeratorList;
public static OptionItem ModeratorCanUseCommand;
public static OptionItem AutoKickStart;
public static OptionItem AutoKickStartAsBan;
public static OptionItem AutoKickStartTimes;
public static OptionItem AutoKickStartStrength;
public static OptionItem TabGroupAutomation;
public static OptionItem AutoSendGameInfo;
@@ -93,12 +99,46 @@ namespace AmongUsRevamped
public static OptionItem NoGameEnd;
//Gameplay
public static OptionItem TabGroupGameplayGeneral;
public static OptionItem TabGroupSabotages;
public static OptionItem DisableSabotage;
public static OptionItem DisableReactor;
public static OptionItem DisableOxygen;
public static OptionItem DisableLights;
public static OptionItem DisableComms;
public static OptionItem DisableHeli;
public static OptionItem DisableMushroomMixup;
public static OptionItem DisableCloseDoor;
public static OptionItem TabGroupGameplayGeneral;
public static OptionItem DisableReport;
public static OptionItem ChangeDecontaminationTime;
public static OptionItem DecontaminationTimeOnMiraHQ;
public static OptionItem DecontaminationDoorOpenTimeOnMiraHQ;
public static OptionItem DecontaminationTimeOnPolus;
public static OptionItem DecontaminationDoorOpenTimeOnPolus;
public static OptionItem DisableDevices;
private static OptionItem DisableSkeldDevices;
public static OptionItem DisableSkeldAdmin;
public static OptionItem DisableSkeldCamera;
private static OptionItem DisableMiraHQDevices;
public static OptionItem DisableMiraHQAdmin;
public static OptionItem DisableMiraHQDoorLog;
private static OptionItem DisablePolusDevices;
public static OptionItem DisablePolusAdmin;
public static OptionItem DisablePolusCamera;
public static OptionItem DisablePolusVital;
private static OptionItem DisableAirshipDevices;
public static OptionItem DisableAirshipCockpitAdmin;
public static OptionItem DisableAirshipRecordsAdmin;
public static OptionItem DisableAirshipCamera;
public static OptionItem DisableAirshipVital;
private static OptionItem DisableFungleDevices;
public static OptionItem DisableFungleCamera;
public static OptionItem DisableFungleVital;
public static OptionItem TabGroupTasks;
public static OptionItem OverrideTaskSettings;
@@ -220,6 +260,14 @@ namespace AmongUsRevamped
public static OptionItem CrewAutoWinsGameAfter;
public static OptionItem CantKillTime;
public static OptionItem MisfiresToSuicide;
public static OptionItem SNSDisableSabotage;
public static OptionItem SNSDisableReactor;
public static OptionItem SNSDisableOxygen;
public static OptionItem SNSDisableLights;
public static OptionItem SNSDisableComms;
public static OptionItem SNSDisableHeli;
public static OptionItem SNSDisableMushroomMixup;
public static OptionItem SNSDisableCloseDoor;
public static OptionItem TabGroupSpeedrun;
public static OptionItem SpeedrunSettingsOverride;
@@ -227,6 +275,7 @@ namespace AmongUsRevamped
// Roles
public static OptionItem TabGroupCrewmate;
public static OptionItem MayorPerc;
public static OptionItem TabGroupNeutral;
public static OptionItem JesterPerc;
@@ -264,6 +313,15 @@ namespace AmongUsRevamped
ApplyModeratorList = BooleanOptionItem.Create(60121, "Apply Moderator List", true, TabGroup.SystemSettings, false);
ModeratorCanUseCommand = BooleanOptionItem.Create(60122, "Moderators can use commands", true, TabGroup.SystemSettings, false);
AutoKickStart = BooleanOptionItem.Create(60123, "Kick Players Who Say Start", false, TabGroup.SystemSettings, false);
AutoKickStartAsBan = BooleanOptionItem.Create(60124, "Ban Instead Of Kick", false, TabGroup.SystemSettings, false)
.SetParent(AutoKickStart);
AutoKickStartTimes = IntegerOptionItem.Create(60125, "Start messages needed to kick", new(1, 10, 1), 1, TabGroup.SystemSettings, false)
.SetParent(AutoKickStart)
.SetValueFormat(OptionFormat.Times);
AutoKickStartStrength = BooleanOptionItem.Create(60126, "Strict detection mode", false, TabGroup.SystemSettings, false)
.SetParent(AutoKickStart);
TabGroupAutomation = TextOptionItem.Create(60149, "Automation", TabGroup.SystemSettings)
.SetColor(Color.yellow);
@@ -291,6 +349,9 @@ namespace AmongUsRevamped
// Custom role settings
TabGroupCrewmate = TextOptionItem.Create(100000, "Crewmate Roles", TabGroup.CustomRoleSettings)
.SetColor(CL.Hex("#8cffff"));
MayorPerc = IntegerOptionItem.Create(100001, "PLACEHOLDER", new(0, 100, 5), 0, TabGroup.CustomRoleSettings, false)
.SetValueFormat(OptionFormat.Percent)
.SetColor(CL.Hex("#204d42"));
TabGroupNeutral = TextOptionItem.Create(101000, "Neutral Roles", TabGroup.CustomRoleSettings)
.SetColor(CL.Hex("#FFFF99"));
@@ -322,6 +383,28 @@ namespace AmongUsRevamped
MisfiresToSuicide = IntegerOptionItem.Create(70052, "Suicide After Amount Of Misfires", new(1, 10, 1), 2, TabGroup.GamemodeSettings, false);
CrewAutoWinsGameAfter = IntegerOptionItem.Create(70054, "Crewmates Automatically Win After", new(0, 600, 10), 300, TabGroup.GamemodeSettings, false)
.SetValueFormat(OptionFormat.Seconds);
SNSDisableSabotage = BooleanOptionItem.Create(70055, "Disable SnS Critical Sabotages", true, TabGroup.GamemodeSettings, false)
.SetColor(Color.red);
SNSDisableReactor = BooleanOptionItem.Create(70056, "Disable Reactor Sabotage", true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableOxygen = BooleanOptionItem.Create(70057, "Disable O2 Sabotage", true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableLights = BooleanOptionItem.Create(70058, "Disable Lights Sabotage", true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableComms = BooleanOptionItem.Create(70059, "Disable Communications Sabotage", true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableHeli = BooleanOptionItem.Create(70060, "Disable Crash Course Sabotage", true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableMushroomMixup = BooleanOptionItem.Create(70061, "Disable Mushroom Mixup Sabotage", true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableCloseDoor = BooleanOptionItem.Create(70062, "Disable SnS Door Sabotages", true, TabGroup.GamemodeSettings, false)
.SetColor(Color.red);
TabGroupSpeedrun = TextOptionItem.Create(70075, "Speedrun", TabGroup.GamemodeSettings)
.SetColor(Color.blue);
@@ -329,15 +412,129 @@ namespace AmongUsRevamped
GameAutoEndsAfter = IntegerOptionItem.Create(70077, "Game automatically ends after", new(0, 600, 10), 300, TabGroup.GamemodeSettings, false)
.SetValueFormat(OptionFormat.Seconds);
// Gameplay Settings
TabGroupGameplayGeneral = TextOptionItem.Create(60564, "General", TabGroup.ModSettings)
.SetColor(Color.blue);
DisableSabotage = BooleanOptionItem.Create(60565, "Disable Critical Sabotages", false, TabGroup.ModSettings, false)
TabGroupSabotages = TextOptionItem.Create(60455, "Sabotages", TabGroup.ModSettings)
.SetColor(Color.red);
DisableSabotage = BooleanOptionItem.Create(60456, "Disable Critical Sabotages", false, TabGroup.ModSettings, false)
.SetColor(Color.red);
DisableReactor = BooleanOptionItem.Create(60457, "Disable Reactor Sabotage", false, TabGroup.ModSettings, false)
.SetParent(DisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableOxygen = BooleanOptionItem.Create(60458, "Disable O2 Sabotage", false, TabGroup.ModSettings, false)
.SetParent(DisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableLights = BooleanOptionItem.Create(60459, "Disable Lights Sabotage", false, TabGroup.ModSettings, false)
.SetParent(DisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableComms = BooleanOptionItem.Create(60460, "Disable Communications Sabotage", false, TabGroup.ModSettings, false)
.SetParent(DisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableHeli = BooleanOptionItem.Create(60461, "Disable Crash Course Sabotage", false, TabGroup.ModSettings, false)
.SetParent(DisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableMushroomMixup = BooleanOptionItem.Create(60462, "Disable Mushroom Mixup Sabotage", false, TabGroup.ModSettings, false)
.SetParent(DisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableCloseDoor = BooleanOptionItem.Create(60566, "Disable Door Sabotages", false, TabGroup.ModSettings, false)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
.SetColor(Color.red);
TabGroupGameplayGeneral = TextOptionItem.Create(60564, "General", TabGroup.ModSettings)
.SetColor(Color.blue);
DisableReport = BooleanOptionItem.Create(60520, "Disable Body Reports", false, TabGroup.ModSettings, false)
.SetColor(Color.blue);
ChangeDecontaminationTime = BooleanOptionItem.Create(60550, "Override Decontamination Time", false, TabGroup.ModSettings, false)
.SetColor(new Color32(19, 188, 233, byte.MaxValue));
DecontaminationTimeOnMiraHQ = FloatOptionItem.Create(60551, "Mira HQ Decon Duration", new(0.5f, 10f, 0.25f), 3f, TabGroup.ModSettings, false)
.SetParent(ChangeDecontaminationTime)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(new Color32(19, 188, 233, byte.MaxValue));
DecontaminationDoorOpenTimeOnMiraHQ = FloatOptionItem.Create(60552, "Mira HQ Door Open Duration", new(0.5f, 10f, 0.25f), 3f, TabGroup.ModSettings, false)
.SetParent(ChangeDecontaminationTime)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(new Color32(19, 188, 233, byte.MaxValue));
DecontaminationTimeOnPolus = FloatOptionItem.Create(60553, "Polus Decon Duration", new(0.5f, 10f, 0.25f), 3f, TabGroup.ModSettings, false)
.SetParent(ChangeDecontaminationTime)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(new Color32(19, 188, 233, byte.MaxValue));
DecontaminationDoorOpenTimeOnPolus = FloatOptionItem.Create(60554, "Polus Door Open Duration", new(0.5f, 10f, 0.25f), 3f, TabGroup.ModSettings, false)
.SetParent(ChangeDecontaminationTime)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(new Color32(19, 188, 233, byte.MaxValue));
DisableDevices = BooleanOptionItem.Create(22900, "Disable Devices", false, TabGroup.ModSettings, false)
.SetColor(Color.red);
DisableSkeldDevices = BooleanOptionItem.Create(22905, "Disable Skeld Devices", false, TabGroup.ModSettings, false)
.SetParent(DisableDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableSkeldAdmin = BooleanOptionItem.Create(22906, "Disable Skeld Admin", false, TabGroup.ModSettings, false)
.SetParent(DisableSkeldDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableSkeldCamera = BooleanOptionItem.Create(22907, "Disable Skeld Camera", false, TabGroup.ModSettings, false)
.SetParent(DisableSkeldDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableMiraHQDevices = BooleanOptionItem.Create(22908, "Disable Mira HQ Devices", false, TabGroup.ModSettings, false)
.SetParent(DisableDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableMiraHQAdmin = BooleanOptionItem.Create(22909, "Disable Mira HQ Admin", false, TabGroup.ModSettings, false)
.SetParent(DisableMiraHQDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableMiraHQDoorLog = BooleanOptionItem.Create(22910, "Disable Mira HQ DoorLogs", false, TabGroup.ModSettings, false)
.SetParent(DisableMiraHQDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisablePolusDevices = BooleanOptionItem.Create(22911, "Disable Polus Devices", false, TabGroup.ModSettings, false)
.SetParent(DisableDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisablePolusAdmin = BooleanOptionItem.Create(22912, "Disable Polus Admin", false, TabGroup.ModSettings, false)
.SetParent(DisablePolusDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisablePolusCamera = BooleanOptionItem.Create(22913, "Disable Polus Camera", false, TabGroup.ModSettings, false)
.SetParent(DisablePolusDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisablePolusVital = BooleanOptionItem.Create(22914, "Disable Polus Vitals", false, TabGroup.ModSettings, false)
.SetParent(DisablePolusDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableAirshipDevices = BooleanOptionItem.Create(22915, "Disable Airship Devices", false, TabGroup.ModSettings, false)
.SetParent(DisableDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableAirshipCockpitAdmin = BooleanOptionItem.Create(22916, "Disable Airship Cockpit Admin", false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableAirshipRecordsAdmin = BooleanOptionItem.Create(22917, "Disable Airship Records Admin", false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableAirshipCamera = BooleanOptionItem.Create(22918, "Disable Airship Camera", false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableAirshipVital = BooleanOptionItem.Create(22919, "Disable Airship Vitals", false, TabGroup.ModSettings, false)
.SetParent(DisableAirshipDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableFungleDevices = BooleanOptionItem.Create(22925, "Disable Fungle Devices", false, TabGroup.ModSettings, false)
.SetParent(DisableDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableFungleCamera = BooleanOptionItem.Create(22926, "Disable Fungle Camera", false, TabGroup.ModSettings, false)
.SetParent(DisableFungleDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
DisableFungleVital = BooleanOptionItem.Create(22927, "Disable Fungle Vitals", false, TabGroup.ModSettings, false)
.SetParent(DisableFungleDevices)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
+163
View File
@@ -0,0 +1,163 @@
using AmongUs.GameOptions;
using System;
using InnerNet;
using UnityEngine;
namespace AmongUsRevamped;
public static class CustomRoleManagement
{
public static Dictionary<byte, string> PlayerRoles = new Dictionary<byte, string>();
private static readonly System.Random random = new System.Random();
public static void AssignRoles()
{
// crewmateRoles = assigned with crewmate role base
// impostorRoles = assigned with impostor role base
List<(string roleName, int percentage)> crewmateRoles = new()
{
("Jester", Options.JesterPerc.GetInt()),
("Mayor", Options.MayorPerc.GetInt())
};
List<(string roleName, int percentage)> impostorRoles = new()
{
};
List<PlayerControl> availablePlayers = new();
foreach (var player in PlayerControl.AllPlayerControls) availablePlayers.Add(player);
availablePlayers = availablePlayers.OrderBy(x => random.Next()).ToList();
PlayerRoles.Clear();
HashSet<string> assignedRoles = new HashSet<string>();
HashSet<string> attemptedRoles = new HashSet<string>();
foreach (var player in availablePlayers)
{
bool isCrewmate = !player.Data.Role.IsImpostor;
var rolesToAssign = isCrewmate ? crewmateRoles : impostorRoles;
foreach (var (roleName, percentage) in rolesToAssign)
{
if (attemptedRoles.Contains(roleName)) continue;
attemptedRoles.Add(roleName);
int randomValue = random.Next(0, 101);
Logger.Info($"{roleName}, Value: {randomValue}, Percentage: {percentage}", "StartGameCustomRole1");
if (randomValue >= percentage) continue;
if (PlayerRoles.ContainsKey(player.PlayerId)) continue;
PlayerRoles[player.PlayerId] = roleName;
assignedRoles.Add(roleName);
Logger.Info($"({player.PlayerId}) {player.Data.PlayerName} -> {roleName}", "StartGameCustomRole2");
break;
}
}
}
public static string GetActiveRoles()
{
var crewmateRoles = new List<string>();
var neutralRoles = new List<string>();
var impostorRoles = new List<string>();
var lines = new List<string>();
if (Options.MayorPerc.GetInt() > 1) crewmateRoles.Add($"Mayor");
if (Options.JesterPerc.GetInt() > 1) neutralRoles.Add($"Jester");
void AddCategory(string header, List<string> roles)
{
if (roles.Count == 0) return;
if (lines.Count > 0) lines.Add("");
lines.Add(header);
lines.AddRange(roles);
}
AddCategory("Crewmate:", crewmateRoles);
AddCategory("Neutral:", neutralRoles);
AddCategory("Impostor:", impostorRoles);
return lines.Count > 0 ? string.Join("\n", lines) : string.Empty;
}
public static bool HandlingRoleMessages = false;
private static int PendingRoleMessages = 0;
public static void SendRoleMessages(Dictionary<string, string> roleMessages)
{
HashSet<string> sentRoles = new HashSet<string>();
var players = PlayerControl.AllPlayerControls.ToArray().ToList();
float delay = 0f;
PendingRoleMessages = 0;
HandlingRoleMessages = false;
foreach (var player in players)
{
if (!PlayerRoles.TryGetValue(player.PlayerId, out string role)) continue;
if (!roleMessages.ContainsKey(role)) continue;
if (sentRoles.Contains(role)) continue;
PendingRoleMessages++;
new LateTask(() =>
{
Utils.SendPrivateMessage(player, roleMessages[role]);
PendingRoleMessages--;
if (PendingRoleMessages <= 0)
{
PendingRoleMessages = 0;
HandlingRoleMessages = false;
}
}, delay, "SendRoleMessage");
sentRoles.Add(role);
delay += 2.2f;
}
}
public static string PlayerToCustomRole()
{
if (CustomRoleManagement.PlayerRoles.Count == 0) return string.Empty;
Dictionary<string, List<string>> roleToPlayers = new Dictionary<string, List<string>>();
foreach (var kvp in CustomRoleManagement.PlayerRoles)
{
byte playerId = kvp.Key;
string role = kvp.Value;
PlayerControl pc = null;
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p.PlayerId == playerId)
{
pc = p;
break;
}
}
if (pc == null) continue;
if (!roleToPlayers.ContainsKey(role)) roleToPlayers[role] = new List<string>();
roleToPlayers[role].Add(pc.Data.PlayerName);
}
if (roleToPlayers.Count == 0) return string.Empty;
var lines = new List<string>();
foreach (var entry in roleToPlayers)
{
string players = string.Join(", ", entry.Value);
lines.Add($"{entry.Key}: {players}");
}
return string.Join("\n", lines);
}
}
+3
View File
@@ -27,6 +27,9 @@ public static class FixedUpdate
{
nr.SetActive(false);
}
if (!AmongUsClient.Instance.AmHost) return;
DisableDevice.FixedUpdate();
}
}
+42
View File
@@ -0,0 +1,42 @@
using System;
using System.Linq.Expressions;
using System.Reflection;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using UnityEngine;
namespace AmongUsRevamped;
// Credit: TommyXL
public static class Il2CppCastHelper
{
public static T CastFast<T>(this Il2CppObjectBase obj) where T : Il2CppObjectBase
{
if (obj is T casted) return casted;
#if ANDROID
return obj.Cast<T>();
#else
return obj.Pointer.CastFast<T>();
#endif
}
private static T CastFast<T>(this IntPtr ptr) where T : Il2CppObjectBase
{
return CastHelper<T>.Cast(ptr);
}
private static class CastHelper<T> where T : Il2CppObjectBase
{
public static readonly Func<IntPtr, T> Cast;
static CastHelper()
{
ConstructorInfo constructor = typeof(T).GetConstructor([typeof(IntPtr)]);
ParameterExpression ptr = Expression.Parameter(typeof(IntPtr));
NewExpression create = Expression.New(constructor!, ptr);
Expression<Func<IntPtr, T>> lambda = Expression.Lambda<Func<IntPtr, T>>(create, ptr);
Cast = lambda.Compile();
}
}
}
+17 -13
View File
@@ -5,16 +5,24 @@ using UnityEngine;
namespace AmongUsRevamped;
#if !ANDROID
[HarmonyPatch(typeof(ControllerManager), nameof(ControllerManager.Update))]
internal class Hotkeys
{
public static int IncrementMultiplier;
public static void Postfix()
{
// I don't know which psychopath would use right keys, but I know someday, someone will complain
bool Shift = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
bool Ctrl = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
bool Enter = Input.GetKeyDown(KeyCode.Return);
if ((!AmongUsClient.Instance.IsGameStarted || !Utils.IsOnlineGame) && Utils.CanMove && PlayerControl.LocalPlayer.Collider != null)
{
PlayerControl.LocalPlayer.Collider.enabled = !Ctrl;
}
if (!AmongUsClient.Instance.AmHost) return;
if (Input.GetKey(KeyCode.L) && Shift && Enter)
{
MessageWriter writer = AmongUsClient.Instance.StartEndGame();
@@ -28,27 +36,23 @@ internal class Hotkeys
{
MeetingHud.Instance.RpcClose();
}
else
{
PlayerControl.LocalPlayer.ReportDeadBody(PlayerControl.LocalPlayer.Data);
}
}
if (Shift && GameStartManager.InstanceExists && GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown && !HudManager.Instance.Chat.IsOpenOrOpening)
if (Shift && GameStartManager.InstanceExists && GameStartManager.Instance != null && GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown && !HudManager.Instance.Chat.IsOpenOrOpening)
{
GameStartManager.Instance.countDownTimer = 0;
}
if ((!AmongUsClient.Instance.IsGameStarted || !Utils.IsOnlineGame) && Utils.CanMove && PlayerControl.LocalPlayer.Collider != null)
{
PlayerControl.LocalPlayer.Collider.enabled = !Ctrl;
}
if (Input.GetKeyDown(KeyCode.C) && GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown && !HudManager.Instance.Chat.IsOpenOrOpening && Utils.IsLobby)
if (Input.GetKeyDown(KeyCode.C) && GameStartManager.InstanceExists && GameStartManager.Instance != null && GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown && !HudManager.Instance.Chat.IsOpenOrOpening && Utils.IsLobby)
{
Logger.Info("Resetted start countdown", "KeyCommand");
GameStartManager.Instance.ResetStartState();
Logger.SendInGame("Starting countdown canceled");
}
if (Shift) IncrementMultiplier = 5;
else if (Ctrl) IncrementMultiplier = 10;
else IncrementMultiplier = 1;
}
}
}
#endif
-2
View File
@@ -4,8 +4,6 @@ using UnityEngine;
using System;
using AmongUs.GameOptions;
using Object = UnityEngine.Object;
namespace AmongUsRevamped
{
public enum CustomRPC
+144 -29
View File
@@ -12,8 +12,6 @@ using System.Security.Cryptography;
using System.Text;
using AmongUs.InnerNet.GameDataMessages;
using Object = UnityEngine.Object;
namespace AmongUsRevamped;
public static class Utils
@@ -52,28 +50,11 @@ public static class Utils
{
if (friendCode == "") return false;
var friendCodesFilePath = @"./AUR-DATA/ModeratorList.txt";
var friendCodesFilePath = @$"{BanManager.DataPath}/AUR-DATA/ModeratorList.txt";
var friendCodes = File.ReadAllLines(friendCodesFilePath);
return friendCodes.Any(code => code.Contains(friendCode));
}
public static bool IsPlayerInDenyName(ClientData client, string name)
{
if (name == "" || !AmongUsClient.Instance.AmHost || !Options.ApplyDenyNameList.GetBool()) return false;
var denyNameFilePath = @"./AUR-DATA/DenyNameList.txt";
var deniedNames = File.ReadAllLines(denyNameFilePath);
if (deniedNames.Where(code => !string.IsNullOrWhiteSpace(code)).Any(code => name.Contains(code, StringComparison.OrdinalIgnoreCase)))
{
AmongUsClient.Instance.KickPlayer(client.Id, false);
Logger.Info($" {name} was kicked because their name was in DenyNameList.txt", "Kick");
Logger.SendInGame($" {name} was kicked because their name was in DenyNameList.txt");
return true;
}
else return false;
}
public static string GetTabName(TabGroup tab)
{
switch (tab)
@@ -151,9 +132,16 @@ public static class Utils
string name = region.Name;
// Joining games shows incorrect regions
if (!AmongUsClient.Instance.AmHost)
{
name = "";
return name;
}
if (AmongUsClient.Instance.NetworkMode != NetworkModes.OnlineGame)
{
name = "Local Game";
name = "Server: Local Game";
return name;
}
@@ -162,9 +150,9 @@ public static class Utils
// Official servers
name = name switch
{
"North America" => "NA",
"Europe" => "EU",
"Asia" => "AS",
"North America" => "Server: NA",
"Europe" => "Server: EU",
"Asia" => "Server: AS",
_ => name
};
@@ -177,11 +165,11 @@ public static class Utils
{
// Modded Servers
if (ip.Contains("au-eu"))
name = "MEU";
name = "Server: MEU";
else if (ip.Contains("au-as"))
name = "MAS";
name = "Server: MAS";
else
name = "MNA";
name = "Server: MNA";
return name;
}
@@ -208,6 +196,7 @@ public static class Utils
LateTask.Tasks.Clear();
FixedUpdateInGamePatch.ProcessedModerators.Clear();
NormalGameEndChecker.ImpCheckComplete = false;
CreateOptionsPickerPatch.SetDleks2 = false;
}
public static PlayerControl[] AllAlivePlayerControls
@@ -232,6 +221,87 @@ public static class Utils
}
}
public static bool IsActive(SystemTypes type)
{
try
{
if (Utils.IsLobby || !ShipStatus.Instance || !ShipStatus.Instance.Systems.TryGetValue(type, out ISystemType systemType)) return false;
int mapId = Main.NormalOptions.MapId;
switch (type)
{
case SystemTypes.Electrical:
{
if (mapId == 5) return false;
var switchSystem = systemType.CastFast<SwitchSystem>();
return switchSystem is { IsActive: true };
}
case SystemTypes.Reactor:
{
switch (mapId)
{
case 2:
return false;
case 4:
var heliSabotageSystem = systemType.CastFast<HeliSabotageSystem>();
return heliSabotageSystem != null && heliSabotageSystem.IsActive;
default:
var reactorSystemType = systemType.CastFast<ReactorSystemType>();
return reactorSystemType is { IsActive: true };
}
}
case SystemTypes.Laboratory:
{
if (mapId != 2) return false;
var reactorSystemType = systemType.CastFast<ReactorSystemType>();
return reactorSystemType is { IsActive: true };
}
case SystemTypes.LifeSupp:
{
if (mapId is 2 or 4 or 5) return false;
var lifeSuppSystemType = systemType.CastFast<LifeSuppSystemType>();
return lifeSuppSystemType is { IsActive: true };
}
case SystemTypes.Comms:
{
if (mapId is 1 or 5)
{
var hqHudSystemType = systemType.TryCast<HqHudSystemType>();
return hqHudSystemType != null && hqHudSystemType.IsActive;
}
var hudOverrideSystemType = systemType.CastFast<HudOverrideSystemType>();
return hudOverrideSystemType is { IsActive: true };
}
case SystemTypes.HeliSabotage:
{
if (mapId != 4) return false;
var heliSabotageSystem = systemType.CastFast<HeliSabotageSystem>();
return heliSabotageSystem != null && heliSabotageSystem.IsActive;
}
case SystemTypes.MushroomMixupSabotage:
{
if (mapId != 5) return false;
var mushroomMixupSabotageSystem = systemType.CastFast<MushroomMixupSabotageSystem>();
return mushroomMixupSabotageSystem != null && mushroomMixupSabotageSystem.IsActive;
}
default:
return false;
}
}
catch (Exception e)
{
Logger.Exception(e, "IsActive");
return false;
}
}
public static void ShowLastResult(byte playerId = byte.MaxValue)
{
if (InGame)
@@ -389,13 +459,18 @@ public static class Utils
writer.Write(gameOverReason);
AmongUsClient.Instance.FinishEndGame(writer);
HandlingGameEnd = false;
Logger.Info(" -------- GAME ENDED --------", "ManualEndGame");
Logger.Info($"{gameOverReason}", "ContinueEndGame");
Logger.Info(" -------- GAME ENDED --------", "ContinueEndGame");
}
public static void DumpLog()
{
string f = $"{Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)}/AUR-logs/";
string t = DateTime.Now.ToString("yyyy-MM-dd_HH.mm.ss");
#if ANDROID
var f = $"{BanManager.DataPath}/AUR-Logs/{t}";
#else
string f = $"{Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)}/AUR-logs/";
#endif
string filename = $"{f}AUR-{Main.ModVersion}-{t}.log";
if (!Directory.Exists(f)) Directory.CreateDirectory(f);
FileInfo file = new(@$"{Environment.CurrentDirectory}/BepInEx/LogOutput.log");
@@ -404,8 +479,48 @@ public static class Utils
if (PlayerControl.LocalPlayer != null)
{
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"/Dump command activated\n\nFile: AUR-{Main.ModVersion}-{t}");
#if !ANDROID
ProcessStartInfo psi = new("Explorer.exe") { Arguments = "/e,/select," + @filename.Replace("/", "\\") };
Process.Start(psi);
#endif
}
}
private readonly static Dictionary<string, Sprite> CachedSprites = [];
public static Sprite LoadSprite(string path, float pixelsPerUnit = 1f)
{
try
{
if (CachedSprites.TryGetValue(path + pixelsPerUnit, out var sprite)) return sprite;
Texture2D texture = LoadTextureFromResources(path);
sprite = Sprite.Create(texture, new(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f), pixelsPerUnit);
sprite.hideFlags |= HideFlags.HideAndDontSave | HideFlags.DontSaveInEditor;
return CachedSprites[path + pixelsPerUnit] = sprite;
}
catch
{
Logger.Error($"Failed to read Texture: {path}", "LoadSprite");
}
return null;
}
private static unsafe Texture2D LoadTextureFromResources(string path)
{
try
{
Texture2D texture = new(2, 2, TextureFormat.ARGB32, true);
Assembly assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream(path);
var length = stream.Length;
var byteTexture = new Il2CppStructArray<byte>(length);
stream.Read(new Span<byte>(IntPtr.Add(byteTexture.Pointer, IntPtr.Size * 4).ToPointer(), (int)length));
ImageConversion.LoadImage(texture, byteTexture, false);
return texture;
}
catch
{
Logger.Error($"Failed to read Texture: {path}", "LoadTextureFromResources");
}
return null;
}
}
+4 -4
View File
@@ -4,6 +4,7 @@ using UnityEngine;
namespace AmongUsRevamped;
// https://github.com/Yumenopai/TownOfHost_Y
#if !ANDROID
[HarmonyPatch(typeof(HudManager), nameof(HudManager.Update))]
public static class Zoom
{
@@ -16,9 +17,7 @@ public static class Zoom
public static void Postfix()
{
bool canZoom =
(Utils.IsShip && !Utils.IsMeeting && Utils.CanMove && PlayerControl.LocalPlayer.Data.IsDead)
|| (Utils.IsLobby && Utils.CanMove);
bool canZoom = (Utils.IsShip && !Utils.IsMeeting && Utils.CanMove && PlayerControl.LocalPlayer.Data.IsDead) || (Utils.IsLobby && Utils.CanMove);
if (!canZoom)
{
@@ -100,4 +99,5 @@ public static class Flag
{
OneTimeList.Remove(type);
}
}
}
#endif
+93 -37
View File
@@ -5,7 +5,6 @@ using UnityEngine;
using UnityEngine.UI;
using TMPro;
// https://github.com/SuperNewRoles/SuperNewRoles/blob/master/SuperNewRoles/Patches/LobbyBehaviourPatch.cs
namespace AmongUsRevamped;
[HarmonyPatch(typeof(ChatController), nameof(ChatController.Update))]
@@ -14,6 +13,9 @@ internal static class ChatControllerUpdatePatch
public static void Postfix(ChatController __instance)
{
if (!__instance||!__instance.freeChatField||!__instance.freeChatField.textArea||!__instance.freeChatField.background||__instance.freeChatField.textArea.compoText == null||!__instance.freeChatField.textArea.outputText) return;
if (!__instance.quickChatField||!__instance.quickChatField.background||__instance.quickChatField.text==null) return;
if (Main.DarkTheme.Value)
{
__instance.freeChatField.background.color = new Color32(40, 40, 40, byte.MaxValue);
@@ -40,13 +42,15 @@ internal static class ChatBubbleSetNamePatch
{
public static void Postfix(ChatBubble __instance, [HarmonyArgument(2)] bool voted)
{
PlayerControl seer = PlayerControl.LocalPlayer;
if (!__instance||!__instance.playerInfo||!__instance.playerInfo.Object||!__instance.playerInfo.Object.Data||!__instance.TextArea||!__instance.Background) return;
PlayerControl target = __instance.playerInfo.Object;
if (Main.DarkTheme.Value)
{
__instance.Background.color = new(0.1f, 0.1f, 0.1f, 1f);
__instance.TextArea.color = Color.white;
if (__instance.playerInfo.Object.Data.IsDead && Utils.InGame) __instance.Background.color = new(0.1f, 0.1f, 0.1f, 0.7f);
}
}
@@ -55,18 +59,10 @@ internal static class ChatBubbleSetNamePatch
[HarmonyPatch(typeof(ChatController), nameof(ChatController.SendChat))]
internal static class SendChatPatch
{
public static string noKcdMode = "0 Kill Cooldown:\n\nImpostors have no kill cooldown, Crewmates have low tasks\nThink fast and pay attention!";
public static string SnSModeOne = "Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nSabotages & Meetings = Off";
public static string SnSModeTwo = $"Crew wins by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImp wins by killing\nOne wrong kill = Can't kill for {Options.CantKillTime.GetInt()}s\n{Utils.BasicIntToWord(Options.MisfiresToSuicide.GetInt())} wrong kills = suicide";
public static string speedrunMode = $"Speedrun:\n\nEveryone is a crewmate The 1st player to finish tasks wins the game Game auto ends after {Options.GameAutoEndsAfter.GetInt()}s";
public static string allCommandsFull = "Commands:\n/r - Current mode description\n/0kc, /sns, /sp - Specific mode description\n/l - Shows last winner info\n/kick, /ban - Bans or kicks a player by name\n/ckick, /cban - Bans or kicks a player by color";
public static string allCommandsOne = "Commands:\n/r - Current mode description\n/0kc, /sns, /sp - Specific mode description\n/l - Shows last winner info";
public static string allCommandsTwo = "/kick, /ban - Bans or kicks a player by name\n/ckick, /cban - Bans or kicks a player by color";
public static bool Prefix(ChatController __instance)
{
string text = __instance.freeChatField.textArea.text.Trim();
string msgtext = __instance.freeChatField.textArea.text.Trim();
string text = msgtext.ToLower();
if (!AmongUsClient.Instance.AmHost) return true;
@@ -80,13 +76,35 @@ internal static class SendChatPatch
if (text == "/h" || text == "/help" || text == "/cmd" || text == "/commands")
{
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"{allCommandsFull}");
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"{String.allCommandsFull}");
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
return false;
}
if (__instance.timeSinceLastMessage < 3f || OnGameJoinedPatch.WaitingForChat) return false;
if (text == "/eg" || text == "/endgame")
{
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
if (!Utils.InGame) return false;
MessageWriter writer = AmongUsClient.Instance.StartEndGame();
writer.Write((byte)GameOverReason.ImpostorDisconnect);
AmongUsClient.Instance.FinishEndGame(writer);
return false;
}
if (text == "/em" || text == "/endmeeting")
{
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
if ( !Utils.InGame || !Utils.IsMeeting) return false;
MeetingHud.Instance.RpcClose();
return false;
}
if (__instance.timeSinceLastMessage < 3f || OnGameJoinedPatch.WaitingForChat || CustomRoleManagement.HandlingRoleMessages) return false;
if (text == "/l" || text == "/lastgame" || text == "/win" || text == "/winner")
{
@@ -95,21 +113,27 @@ internal static class SendChatPatch
return false;
}
if (text == "/aur" || text == "/amongusrevamped" || text == "/socials" || text == "/github" || text == "/discord")
{
Utils.ChatCommand(__instance, $"{String.SocialsAll}", "", false);
return false;
}
if (text == "/0kc" || text == "/0kcd" || text == "/0killcooldown")
{
Utils.ChatCommand(__instance, $"{noKcdMode}", "", false);
Utils.ChatCommand(__instance, $"{String.noKcdMode}", "", false);
return false;
}
if (text == "/sns" || text == "/shiftandseek" || text == "/shift&seek")
{
Utils.ChatCommand(__instance, $"{SnSModeOne}", $"{SnSModeTwo}", true);
Utils.ChatCommand(__instance, $"{String.SnSModeOne}", $"{String.SnSModeTwo}", true);
return false;
}
if (text == "/sp" || text == "/sr" || text == "/speedrun")
{
Utils.ChatCommand(__instance, $"{speedrunMode}", "", false);
Utils.ChatCommand(__instance, $"{String.speedrunMode}", "", false);
return false;
}
@@ -118,25 +142,25 @@ internal static class SendChatPatch
switch (Options.Gamemode.GetValue())
{
case 0:
PlayerControl.LocalPlayer.RpcSendChat($"Custom roles:\nThere are no custom roles.");
__instance.timeSinceLastMessage = 0.8f;
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
Utils.ChatCommand(__instance, $"Enabled Custom Roles:\n\n{CustomRoleManagement.GetActiveRoles()}", "", false);
break;
case 1:
Utils.ChatCommand(__instance, $"{noKcdMode}", "", false);
Utils.ChatCommand(__instance, $"{String.noKcdMode}", "", false);
break;
case 2:
Utils.ChatCommand(__instance, $"{SnSModeOne}", $"{SnSModeTwo}", true);
Utils.ChatCommand(__instance, $"{String.SnSModeOne}", $"{String.SnSModeTwo}", true);
break;
case 3:
Utils.ChatCommand(__instance, $"{speedrunMode}", "", false);
Utils.ChatCommand(__instance, $"{String.speedrunMode}", "", false);
break;
}
__instance.timeSinceLastMessage = 0.8f;
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
return false;
}
@@ -171,7 +195,7 @@ internal static class SendChatPatch
if (!isKick && !isBan && !isColorKick && !isColorBan)
{
Logger.Info($" {PlayerControl.LocalPlayer.Data.PlayerName}: {text}", "SendChat");
Logger.Info($" {PlayerControl.LocalPlayer.Data.PlayerName}: {msgtext}", "SendChat");
return true;
}
@@ -214,7 +238,7 @@ internal static class SendChatPatch
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.HandleRpc))]
public static class RPCHandlerPatch
{
public static void Prefix(PlayerControl __instance, byte callId, MessageReader reader)
public static void Prefix(PlayerControl __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader)
{
if (!AmongUsClient.Instance.AmHost) return;
@@ -225,8 +249,40 @@ public static class RPCHandlerPatch
{
case RpcCalls.SendChat:
{
string text = subReader.ReadString();
Logger.Info($" {__instance.Data.PlayerName}: {text}", "SendChat");
string msgtext = subReader.ReadString();
string text = msgtext.ToLower();
Logger.Info($" {__instance.Data.PlayerName}: {msgtext}", "SendChat");
string[] keywords = Options.AutoKickStartStrength.GetBool() ? new[] { "start", "begin", "commence" } : new[] { "start", "begin", "commence", "s t a r t", "go" };
bool c = false;
if (Options.AutoKickStartStrength.GetBool())
{
c = keywords.Any(k => text.Contains(k));
}
else
{
c = keywords.Any(k => text == k);
}
if (c && !Utils.IsPlayerModerator(__instance.Data.FriendCode) && Options.AutoKickStart.GetBool() && !Utils.InGame)
{
int clientId = __instance.Data.ClientId;
if (!Main.SayStartTimes.ContainsKey(clientId))
Main.SayStartTimes.Add(clientId, 0);
Main.SayStartTimes[clientId]++;
if (Main.SayStartTimes[clientId] >= Options.AutoKickStartTimes.GetInt())
{
bool sBan = Options.AutoKickStartAsBan.GetBool();
AmongUsClient.Instance.KickPlayer(clientId, sBan);
Logger.Info($" {__instance.Data.PlayerName} was {(sBan ? "banned" : "kicked")} for saying start", "KickAnnoyingKids");
Logger.SendInGame($" {__instance.Data.PlayerName} was {(sBan ? "banned" : "kicked")} for saying start");
}
}
if (text == "/h" || text == "/help" || text == "/cmd" || text == "/commands")
{
@@ -235,12 +291,12 @@ public static class RPCHandlerPatch
new LateTask(() =>
{
Utils.SendPrivateMessage(__instance, $"{SendChatPatch.allCommandsOne}");
Utils.SendPrivateMessage(__instance, $"{String.allCommandsOne}");
}, 2.2f, "MHP1");
new LateTask(() =>
{
Utils.SendPrivateMessage(__instance, $"{SendChatPatch.allCommandsTwo}");
Utils.SendPrivateMessage(__instance, $"{String.allCommandsTwo}");
}, 4.4f, "MHP2");
new LateTask(() =>
@@ -259,18 +315,18 @@ public static class RPCHandlerPatch
if (text == "/0kc" || text == "/0kcd" || text == "/0killcooldown")
{
if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return;
Utils.ModeratorChatCommand($"{SendChatPatch.noKcdMode}", "", false);
Utils.ModeratorChatCommand($"{String.noKcdMode}", "", false);
}
if (text == "/sns" || text == "/shiftandseek" || text == "/shift&seek")
{
if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return;
Utils.ModeratorChatCommand($"{SendChatPatch.SnSModeOne}", $"{SendChatPatch.SnSModeTwo}", true);
Utils.ModeratorChatCommand($"{String.SnSModeOne}", $"{String.SnSModeTwo}", true);
}
if (text == "/sp" || text == "/sr" || text == "/speedrun")
{
if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return;
Utils.ModeratorChatCommand($"{SendChatPatch.speedrunMode}", "", false);
Utils.ModeratorChatCommand($"{String.speedrunMode}", "", false);
}
if (text == "/r" || text == "/roles" || text == "/gamemode" || text == "/gm")
@@ -282,15 +338,15 @@ public static class RPCHandlerPatch
break;
case 1:
Utils.ModeratorChatCommand($"{SendChatPatch.noKcdMode}", "", false);
Utils.ModeratorChatCommand($"{String.noKcdMode}", "", false);
break;
case 2:
Utils.ModeratorChatCommand($"{SendChatPatch.SnSModeOne}", $"{SendChatPatch.SnSModeTwo}", true);
Utils.ModeratorChatCommand($"{String.SnSModeOne}", $"{String.SnSModeTwo}", true);
break;
case 3:
Utils.ModeratorChatCommand($"{SendChatPatch.speedrunMode}", "", false);
Utils.ModeratorChatCommand($"{String.speedrunMode}", "", false);
break;
}
@@ -317,7 +373,7 @@ public static class RPCHandlerPatch
{
if (!Utils.IsPlayerModerator(__instance.Data.FriendCode)) return;
// Banning works by name and color. Commands are seperated incase someone has a color as their name
// Banning works by name and color. Commands are separated incase someone has a color as their name
bool isKick = text.StartsWith("/kick ");
bool isBan = text.StartsWith("/ban ");
+171 -63
View File
@@ -1,7 +1,9 @@
using System;
using System.Text;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
//https://github.com/Gurge44/EndlessHostRoles/blob/main/Patches/CredentialsPatch.cs
namespace AmongUsRevamped
@@ -123,8 +125,12 @@ namespace AmongUsRevamped
Sb.Append(Utils.InGame ? " - " : "\r\n");
Sb.Append($"<color={color}>Ping: {ping}</color>");
AppendSeparator();
Sb.Append($"Server: {Utils.GetRegionName()}");
if (Utils.GetRegionName() != "")
{
AppendSeparator();
Sb.Append(Utils.GetRegionName());
}
if (Main.ShowFps.Value && LastFPS.Count > 0)
{
@@ -166,82 +172,184 @@ namespace AmongUsRevamped
}
}
}
}
// https://github.com/3X3CODE/MainMenuEnhanced/blob/main/MainMenuEnhanced/VisualPatch.cs
[HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start))]
public static class MainMenuManagerStartPatch
{
public static void Postfix(MainMenuManager __instance)
// https://github.com/3X3CODE/MainMenuEnhanced/blob/main/MainMenuEnhanced/VisualPatch.cs
[HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start))]
public static class MainMenuManagerStartPatch
{
if (__instance == null) return;
var bg = GameObject.Find("BackgroundTexture");
if (bg != null)
private static PassiveButton template;
private static PassiveButton discordButton;
private static PassiveButton gitHubButton;
private static Transform buttonParent;
public static void Postfix(MainMenuManager __instance)
{
bg.SetActive(false);
}
if (__instance == null) return;
if (template == null) template = __instance.quitButton;
if (template == null) return;
var leftPanel = GameObject.Find("LeftPanel");
if (leftPanel != null)
{
leftPanel.gameObject.GetComponent<SpriteRenderer>().enabled = false;
}
var div = GameObject.Find("MainUI/AspectScaler/LeftPanel/Main Buttons/Divider");
if (div != null)
{
div.SetActive(false);
}
Transform tintTrans = __instance.transform.Find("MainUI/Tint");
var tint = tintTrans.gameObject;
if (tint != null)
{
tint.SetActive(false);
}
DisableObject("WindowShine");
DisableComponent("RightPanel");
DisableComponent("MaskedBlackScreen");
Transform playTransform = __instance.transform.Find("MainUI/AspectScaler/LeftPanel/Main Buttons/PlayButton/FontPlacer/Text_TMP");
if (playTransform != null)
{
var playbutton = playTransform.gameObject;
if (playbutton != null)
if (buttonParent == null) buttonParent = template.transform.parent;
if (discordButton == null)
{
if (playbutton.TryGetComponent<TextTranslatorTMP>(out var tmp))
discordButton = CreateButton(
__instance,
"DiscordButton",
new(2.1f, 4.05f, 1f),
new(88, 101, 242, byte.MaxValue),
new(148, 161, byte.MaxValue, byte.MaxValue),
() => Application.OpenURL("https://discord.gg/83Zhzhyhya"),
"Discord");
}
if (gitHubButton == null)
{
gitHubButton = CreateButton(
__instance,
"GitHubButton",
new(3.8f, 4.05f, 1f),
new(153, 153, 153, byte.MaxValue),
new(209, 209, 209, byte.MaxValue),
() => Application.OpenURL("https://github.com/ApeMV/AmongUsRevamped"),
"GitHub");
}
var bg = GameObject.Find("BackgroundTexture");
if (bg != null)
{
bg.SetActive(false);
}
var leftPanel = GameObject.Find("LeftPanel");
if (leftPanel != null)
{
leftPanel.gameObject.GetComponent<SpriteRenderer>().enabled = false;
}
var div = GameObject.Find("MainUI/AspectScaler/LeftPanel/Main Buttons/Divider");
if (div != null)
{
div.SetActive(false);
}
Transform tintTrans = __instance.transform.Find("MainUI/Tint");
var tint = tintTrans.gameObject;
if (tint != null)
{
tint.SetActive(false);
}
DisableObject("WindowShine");
DisableComponent("RightPanel");
DisableComponent("MaskedBlackScreen");
Transform playTransform = __instance.transform.Find("MainUI/AspectScaler/LeftPanel/Main Buttons/PlayButton/FontPlacer/Text_TMP");
if (playTransform != null)
{
var playbutton = playTransform.gameObject;
if (playbutton != null)
{
tmp.enabled = false;
}
if (playbutton.TryGetComponent<TextMeshPro>(out var text))
{
text.text = "Start";
if (playbutton.TryGetComponent<TextTranslatorTMP>(out var tmp))
{
tmp.enabled = false;
}
if (playbutton.TryGetComponent<TextMeshPro>(out var text))
{
text.text = "Start";
}
}
}
}
static void DisableObject(string name)
{
var obj = GameObject.Find(name);
if (obj != null)
static void DisableObject(string name)
{
obj.SetActive(false);
var obj = GameObject.Find(name);
if (obj != null)
{
obj.SetActive(false);
}
}
static void DisableComponent(string name)
{
var obj = GameObject.Find(name);
if (obj != null)
{
if (obj.TryGetComponent<SpriteRenderer>(out var renderer))
{
renderer.enabled = false;
}
}
}
}
static void DisableComponent(string name)
private static PassiveButton CreateButton(MainMenuManager menu, string name, Vector3 localPosition, Color32 normalColor, Color32 hoverColor, Action action, string label)
{
var obj = GameObject.Find(name);
if (obj != null)
var parent = menu.transform.Find("MainUI/AspectScaler/LeftPanel/Main Buttons");
if (parent == null) return null;
var button = Object.Instantiate(menu.quitButton, parent);
button.name = name;
button.transform.localPosition = localPosition;
button.transform.localScale = new Vector3(0.8f, 1f, 1f);
var aspect = button.GetComponent<AspectPosition>();
if (aspect != null)
{
if (obj.TryGetComponent<SpriteRenderer>(out var renderer))
{
renderer.enabled = false;
}
aspect.enabled = false;
}
button.OnClick = new();
button.OnClick.AddListener(action);
var buttonText = button.transform.Find("FontPlacer/Text_TMP").GetComponent<TMP_Text>();
Utils.DestroyTranslator(buttonText);
buttonText.text = label;
buttonText.fontSize = buttonText.fontSizeMax = buttonText.fontSizeMin = 3.5f;
buttonText.enableWordWrapping = false;
buttonText.horizontalAlignment = HorizontalAlignmentOptions.Center;
var normalSprite = button.inactiveSprites.GetComponent<SpriteRenderer>();
var hoverSprite = button.activeSprites.GetComponent<SpriteRenderer>();
normalSprite.color = normalColor;
hoverSprite.color = hoverColor;
button.gameObject.SetActive(true);
return button;
}
}
}
}
#if !ANDROID
[HarmonyPatch(typeof(ServerDropdown), nameof(ServerDropdown.FillServerOptions))]
public static class ServerDropdownPatch
{
public static bool Prefix(ServerDropdown __instance)
{
if (SceneManager.GetActiveScene().name == "FindAGame") return true;
SpriteRenderer bg = __instance.background;
bg.size = new Vector2(4, 1);
ServerManager sm = ServerManager.Instance;
TranslationController tc = TranslationController.Instance;
int totalCols = Mathf.Max(1, Mathf.CeilToInt(sm.AvailableRegions.Length / (float)5));
int rowLimit = Mathf.Min(sm.AvailableRegions.Length, 5);
for (var index = 0; index < sm.AvailableRegions.Length; index++)
{
IRegionInfo ri = sm.AvailableRegions[index];
var b = __instance.ButtonPool.Get<ServerListButton>();
b.transform.localPosition = new Vector3(((index / 5) - ((totalCols - 1) / 2f)) * 3.15f, __instance.y_posButton - (0.5f * (index % 5)), -1f);
b.Text.text = tc.GetStringWithDefault(ri.TranslateName, ri.Name, new Il2CppReferenceArray<Il2CppSystem.Object>(0));
b.Text.ForceMeshUpdate();
b.Button.OnClick.RemoveAllListeners();
b.Button.OnClick.AddListener((Action)(() => __instance.ChooseOption(ri)));
__instance.controllerSelectable.Add(b.Button);
}
float h = 1.2f + (0.5f * (rowLimit - 1));
float w = totalCols > 1 ? (3.15f * (totalCols - 1)) + bg.size.x : bg.size.x;
bg.transform.localPosition = new Vector3(0f, __instance.initialYPos - ((h - 1.2f) / 2f), 0f);
bg.size = new Vector2(w, h);
return false;
}
}
#endif
+32
View File
@@ -0,0 +1,32 @@
namespace AmongUsRevamped;
[HarmonyPatch(typeof(DeconSystem), nameof(DeconSystem.UpdateSystem))]
public static class DeconSystemUpdateSystemPatch
{
public static void Prefix(DeconSystem __instance)
{
if (!AmongUsClient.Instance.AmHost) return;
if (Options.ChangeDecontaminationTime.GetBool())
{
__instance.DoorOpenTime = Main.CurrentMap switch
{
MapNames.MiraHQ => Options.DecontaminationDoorOpenTimeOnMiraHQ.GetFloat(),
MapNames.Polus => Options.DecontaminationDoorOpenTimeOnPolus.GetFloat(),
_ => 3f
};
__instance.DeconTime = Main.CurrentMap switch
{
MapNames.MiraHQ => Options.DecontaminationTimeOnMiraHQ.GetFloat(),
MapNames.Polus => Options.DecontaminationTimeOnPolus.GetFloat(),
_ => 3f
};
}
else
{
__instance.DoorOpenTime = 3f;
__instance.DeconTime = 3f;
}
}
}
+196
View File
@@ -0,0 +1,196 @@
using System;
using Hazel;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using UnityEngine;
namespace AmongUsRevamped;
// https://github.com/ykundesu/SuperNewRoles/blob/master/SuperNewRoles/Mode/SuperHostRoles/BlockTool.cs
internal static class DisableDevice
{
public static readonly List<byte> DesyncComms = [];
private static int frame;
public static readonly Dictionary<string, Vector2> DevicePos = new()
{
["SkeldAdmin"] = new(3.48f, -8.62f),
["SkeldCamera"] = new(-13.06f, -2.45f),
["MiraHQAdmin"] = new(21.02f, 19.09f),
["MiraHQDoorLog"] = new(16.22f, 5.82f),
["PolusLeftAdmin"] = new(22.80f, -21.52f),
["PolusRightAdmin"] = new(24.66f, -21.52f),
["PolusCamera"] = new(2.96f, -12.74f),
["PolusVital"] = new(26.70f, -15.94f),
["DleksAdmin"] = new(-3.48f, -8.62f),
["DleksCamera"] = new(13.06f, -2.45f),
["AirshipCockpitAdmin"] = new(-22.32f, 0.91f),
["AirshipRecordsAdmin"] = new(19.89f, 12.60f),
["AirshipCamera"] = new(8.10f, -9.63f),
["AirshipVital"] = new(25.24f, -7.94f),
["FungleCamera"] = new(6.20f, 0.10f),
["FungleVital"] = new(-2.50f, -9.80f),
["SubmergedVital"] = new(5f, 32.54f),
["SubmergedLeftAdmin"] = new(-9.45f, 10.16f),
["SubmergedRightAdmin"] = new(-7.07f, 10.16f),
["SubmergedCamera"] = new(-3.41f, -34.56f)
};
public static bool DoDisable => Options.DisableDevices.GetBool();
public static float UsableDistance => Main.CurrentMap switch
{
MapNames.Skeld => 1.5f,
MapNames.MiraHQ => 2.2f,
MapNames.Polus => 1.4f,
MapNames.Dleks => 1.5f,
MapNames.Airship => 1.6f,
MapNames.Fungle => 1.7f,
_ => 2f
};
public static void FixedUpdate()
{
if (!AmongUsClient.Instance.AmHost || ShipStatus.Instance == null || !Utils.GamePastRoleSelection) return;
frame = frame == 5 ? 0 : ++frame;
if (frame != 0) return;
if (!DoDisable) return;
foreach (PlayerControl pc in Main.AllPlayerControls)
{
try
{
var doComms = false;
Vector2 PlayerPos = pc.GetTruePosition();
if (!Utils.IsActive(SystemTypes.Comms))
{
switch (Main.NormalOptions.MapId)
{
case 0:
if (Options.DisableSkeldAdmin.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["SkeldAdmin"]) <= UsableDistance;
if (Options.DisableSkeldCamera.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["SkeldCamera"]) <= UsableDistance;
break;
case 1:
if (Options.DisableMiraHQAdmin.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["MiraHQAdmin"]) <= UsableDistance;
if (Options.DisableMiraHQDoorLog.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["MiraHQDoorLog"]) <= UsableDistance;
break;
case 2:
if (Options.DisablePolusAdmin.GetBool())
{
doComms |= Vector2.Distance(PlayerPos, DevicePos["PolusLeftAdmin"]) <= UsableDistance;
doComms |= Vector2.Distance(PlayerPos, DevicePos["PolusRightAdmin"]) <= UsableDistance;
}
if (Options.DisablePolusCamera.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["PolusCamera"]) <= UsableDistance;
if (Options.DisablePolusVital.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["PolusVital"]) <= UsableDistance;
break;
case 3:
if (Options.DisableSkeldAdmin.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["DleksAdmin"]) <= UsableDistance;
if (Options.DisableSkeldCamera.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["DleksCamera"]) <= UsableDistance;
break;
case 4:
if (Options.DisableAirshipCockpitAdmin.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["AirshipCockpitAdmin"]) <= UsableDistance;
if (Options.DisableAirshipRecordsAdmin.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["AirshipRecordsAdmin"]) <= UsableDistance;
if (Options.DisableAirshipCamera.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["AirshipCamera"]) <= UsableDistance;
if (Options.DisableAirshipVital.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["AirshipVital"]) <= UsableDistance;
break;
case 5:
if (Options.DisableFungleCamera.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["FungleCamera"]) <= UsableDistance;
if (Options.DisableFungleVital.GetBool()) doComms |= Vector2.Distance(PlayerPos, DevicePos["FungleVital"]) <= UsableDistance;
break;
}
}
if (doComms && !pc.inVent)
{
if (!DesyncComms.Contains(pc.PlayerId))
{
DesyncComms.Add(pc.PlayerId);
SendDesyncRepair(pc, SystemTypes.Comms, 128);
}
}
else if (!doComms && DesyncComms.Contains(pc.PlayerId))
{
DesyncComms.Remove(pc.PlayerId);
SendDesyncRepair(pc, SystemTypes.Comms, 16);
if (Main.NormalOptions.MapId is 1 or 5) SendDesyncRepair(pc, SystemTypes.Comms, 17);
}
}
catch (Exception ex) { Logger.Exception(ex, "DisableDevice"); }
}
}
public static void SendDesyncRepair(PlayerControl target, SystemTypes systemType, byte amount)
{
if (!AmongUsClient.Instance.AmHost) return;
if (target == null || target.Data == null || target.Data.ClientId == AmongUsClient.Instance.HostId) return;
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(
ShipStatus.Instance.NetId,
(byte)RpcCalls.UpdateSystem,
SendOption.Reliable,
target.Data.ClientId
);
writer.Write((byte)systemType);
writer.WritePacked(target.NetId);
writer.Write(amount);
AmongUsClient.Instance.FinishRpcImmediately(writer);
}
}
[HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.Start))]
public class RemoveDisableDevicesPatch
{
public static void Postfix()
{
if (!Options.DisableDevices.GetBool()) return;
UpdateDisableDevices();
}
public static void UpdateDisableDevices()
{
PlayerControl player = PlayerControl.LocalPlayer;
Il2CppArrayBase<MapConsole> admins = Object.FindObjectsOfType<MapConsole>(true);
Il2CppArrayBase<SystemConsole> consoles = Object.FindObjectsOfType<SystemConsole>(true);
if (admins == null || consoles == null) return;
switch (Main.NormalOptions.MapId)
{
case 3:
case 0:
if (Options.DisableSkeldAdmin.GetBool()) admins[0].gameObject.GetComponent<CircleCollider2D>().enabled = false;
if (Options.DisableSkeldCamera.GetBool()) consoles.DoIf(x => x.name == "SurvConsole", x => x.gameObject.GetComponent<PolygonCollider2D>().enabled = false);
break;
case 1:
if (Options.DisableMiraHQAdmin.GetBool()) admins[0].gameObject.GetComponent<CircleCollider2D>().enabled = false;
if (Options.DisableMiraHQDoorLog.GetBool()) consoles.DoIf(x => x.name == "SurvLogConsole", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = false);
break;
case 2:
if (Options.DisablePolusAdmin.GetBool()) admins.Do(x => x.gameObject.GetComponent<BoxCollider2D>().enabled = false);
if (Options.DisablePolusCamera.GetBool()) consoles.DoIf(x => x.name == "Surv_Panel", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = false);
if (Options.DisablePolusVital.GetBool()) consoles.DoIf(x => x.name == "panel_vitals", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = false);
break;
case 4:
admins.Do(x =>
{
if ((Options.DisableAirshipCockpitAdmin.GetBool() && x.name == "panel_cockpit_map") ||
(Options.DisableAirshipRecordsAdmin.GetBool() && x.name == "records_admin_map"))
x.gameObject.GetComponent<BoxCollider2D>().enabled = false;
});
if (Options.DisableAirshipCamera.GetBool()) consoles.DoIf(x => x.name == "task_cams", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = false);
if (Options.DisableAirshipVital.GetBool()) consoles.DoIf(x => x.name == "panel_vitals", x => x.gameObject.GetComponent<CircleCollider2D>().enabled = false);
break;
case 5:
if (Options.DisableFungleCamera.GetBool()) consoles.DoIf(x => x.name == "BinocularsSecurityConsole", x => x.gameObject.GetComponent<PolygonCollider2D>().enabled = false);
if (Options.DisableFungleVital.GetBool()) consoles.DoIf(x => x.name == "VitalsConsole", x => x.gameObject.GetComponent<BoxCollider2D>().enabled = false);
break;
}
}
}
+9 -4
View File
@@ -16,9 +16,14 @@ public class DiscordRPC
{
if (activity == null) return;
var details = $"AmongUsRevamped {Main.ModVersion}";
var details = $"Revamped {Main.ModVersion}";
activity.Details = details;
activity.Assets = new ActivityAssets
{
LargeImage = "https://i.imgur.com/ZnC1toT.png"
};
try
{
if (activity.State != "In Menus")
@@ -31,10 +36,10 @@ public class DiscordRPC
Region = Utils.GetRegionName();
}
if (Lobbycode != "" && Region != "") details = $"AmongUsRevamped - {Lobbycode} ({Region})";
if (Lobbycode != "" && Region != "") details = $"Revamped - {Lobbycode} ({Region})";
}
else
details = $"AmongUsRevamped {Main.ModVersion}";
details = $"Revamped {Main.ModVersion}";
activity.Details = details;
}
@@ -43,7 +48,7 @@ public class DiscordRPC
{
Logger.Error("Error in updating discord rpc", "DiscordPatch");
Logger.Exception(ex, "DiscordPatch");
details = $"AmongUsRevamped v{Main.ModVersion}";
details = $"Revamped v{Main.ModVersion}";
activity.Details = details;
}
}
+219
View File
@@ -0,0 +1,219 @@
using System;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace AmongUsRevamped;
[HarmonyPatch(typeof(AmongUsDateTime), nameof(AmongUsDateTime.UtcNow), MethodType.Getter)]
public static class AmongUsDateTime_UtcNow
{
public static bool Prefix(ref Il2CppSystem.DateTime __result)
{
if (!CreateOptionsPickerPatch.SetDleks) return true;
var managedDate = new DateTime(DateTime.UtcNow.Year, 4, 2, 7, 1, 0, DateTimeKind.Utc);
__result = new Il2CppSystem.DateTime(managedDate.Ticks);
return false;
}
}
class CreateOptionsPickerPatch
{
public static bool SetDleks = false;
public static bool SetDleks2;
private static MapSelectButton DleksButton;
[HarmonyPatch]
public static class GameOptionsMapPickerPatch
{
[HarmonyPatch(typeof(GameOptionsMapPicker), nameof(GameOptionsMapPicker.SetupMapButtons))]
[HarmonyPostfix]
public static void Postfix_Initialize(CreateGameMapPicker __instance)
{
float delay = SceneManager.GetActiveScene().name == "MainMenu" ? 0.2f : 0f;
if (SceneManager.GetActiveScene().name == "FindAGame") return;
new LateTask(() =>
{
int DleksPos = 3;
MapSelectButton[] AllMapButton = __instance.transform.GetComponentsInChildren<MapSelectButton>();
AllMapButton = AllMapButton.Where(x => x.gameObject.name != "DleksButton").ToArray();
if (AllMapButton != null)
{
GameObject dlekS_ehT = null;
if (!SetDleks2 || SceneManager.GetActiveScene().name != "MainMenu")
{
dlekS_ehT = UnityEngine.Object.Instantiate(AllMapButton[0].gameObject, __instance.transform);
dlekS_ehT.name = "DleksButton";
SetDleks2 = true;
}
else
{
dlekS_ehT = __instance.transform.Find("DleksButton")?.gameObject;
}
if (dlekS_ehT == null) return;
dlekS_ehT.name = "DleksButton";
dlekS_ehT.transform.position = AllMapButton[DleksPos].transform.position;
dlekS_ehT.transform.SetSiblingIndex(DleksPos + 2);
MapSelectButton dlekS_ehT_MapButton = dlekS_ehT.GetComponent<MapSelectButton>();
DleksButton = dlekS_ehT_MapButton;
foreach (var icon in dlekS_ehT_MapButton.MapIcon)
{
if (icon == null || icon.transform == null) continue;
icon.flipX = true;
}
dlekS_ehT_MapButton.Button.OnClick.RemoveAllListeners();
dlekS_ehT_MapButton.Button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() =>
{
__instance.SelectMap(__instance.AllMapIcons[0]);
if (__instance.selectedButton)
{
__instance.selectedButton.Button.SelectButton(false);
}
__instance.selectedButton = dlekS_ehT_MapButton;
__instance.selectedButton.Button.SelectButton(true);
__instance.selectedMapId = 3;
if (!Utils.isHideNSeek)
Main.NormalOptions.MapId = 0;
else if (Utils.isHideNSeek)
Main.HideNSeekOptions.MapId = 0;
__instance.MapImage.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner.png", 100f);
__instance.MapName.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner-Wordart.png", 100f);
}));
for (int i = DleksPos; i < AllMapButton.Length; i++)
{
AllMapButton[i].transform.localPosition += new Vector3(0.625f, 0f, 0f);
}
if (DleksButton != null)
{
if (SetDleks)
{
if (__instance.selectedButton)
{
__instance.selectedButton.Button.SelectButton(false);
}
DleksButton.Button.SelectButton(true);
__instance.selectedButton = DleksButton;
__instance.selectedMapId = 3;
__instance.MapImage.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner.png", 100f);
__instance.MapName.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner-Wordart.png", 100f);
}
else
{
DleksButton.Button.SelectButton(false);
}
}
}
}, delay, "ApplyDleks");
}
[HarmonyPatch(typeof(GameOptionsMapPicker), nameof(GameOptionsMapPicker.FixedUpdate))]
[HarmonyPrefix]
public static bool Prefix_FixedUpdate(GameOptionsMapPicker __instance)
{
if (__instance == null) return true;
if (__instance.MapName == null) return false;
if (DleksButton != null) SetDleks = __instance.selectedMapId == 3;
if (__instance.selectedMapId == 3)
{
if (SceneManager.GetActiveScene().name == "FindAGame")
{
__instance.SelectMap(0);
SetDleks = false;
}
return false;
}
return true;
}
}
[HarmonyPatch(typeof(CreateOptionsPicker), nameof(CreateOptionsPicker.Awake))]
class MenuMapPickerPatch
{
public static void Postfix(CreateOptionsPicker __instance)
{
Transform mapPickerTransform = __instance.transform.Find("MapPicker");
MapPickerMenu mapPickerMenu = mapPickerTransform.Find("Map Picker Menu").GetComponent<MapPickerMenu>();
MapFilterButton airhipIconInMenu = __instance.MapMenu.MapButtons[3];
MapFilterButton fungleIconInMenu = __instance.MapMenu.MapButtons[4];
MapFilterButton skeldIconInMenu = __instance.MapMenu.MapButtons[0];
MapFilterButton dleksIconInMenuCopy = UnityEngine.Object.Instantiate(airhipIconInMenu, airhipIconInMenu.transform.parent);
Transform skeldMenuButton = mapPickerMenu.transform.Find("Skeld");
Transform polusMenuButton = mapPickerMenu.transform.Find("Polus");
Transform airshipMenuButton = mapPickerMenu.transform.Find("Airship");
Transform fungleMenuButton = mapPickerMenu.transform.Find("Fungle");
Transform dleksMenuButtonCopy = UnityEngine.Object.Instantiate(airshipMenuButton, airshipMenuButton.parent);
// Set mapid for Dleks button
PassiveButton dleksButton = dleksMenuButtonCopy.GetComponent<PassiveButton>();
dleksButton.OnClick.m_PersistentCalls.m_Calls._items[0].arguments.intArgument = (int)MapNames.Dleks;
SpriteRenderer dleksImage = dleksMenuButtonCopy.Find("Image").GetComponent<SpriteRenderer>();
dleksImage.sprite = skeldMenuButton.Find("Image").GetComponent<SpriteRenderer>().sprite;
dleksIconInMenuCopy.name = "Dleks";
dleksIconInMenuCopy.transform.localPosition = new Vector3(0.8f, airhipIconInMenu.transform.localPosition.y, airhipIconInMenu.transform.localPosition.z);
dleksIconInMenuCopy.MapId = MapNames.Dleks;
dleksIconInMenuCopy.Button = dleksButton;
dleksIconInMenuCopy.ButtonCheck = dleksMenuButtonCopy.Find("selectedCheck").GetComponent<SpriteRenderer>();
dleksIconInMenuCopy.ButtonImage = dleksImage;
dleksIconInMenuCopy.ButtonOutline = dleksImage.transform.parent.GetComponent<SpriteRenderer>();
dleksIconInMenuCopy.Icon.sprite = skeldIconInMenu.Icon.sprite;
dleksMenuButtonCopy.name = "Dleks";
dleksMenuButtonCopy.position = new Vector3(dleksMenuButtonCopy.position.x, 2f * dleksMenuButtonCopy.position.y - polusMenuButton.transform.position.y, dleksMenuButtonCopy.position.z);
fungleMenuButton.position = new Vector3(fungleMenuButton.position.x, dleksMenuButtonCopy.transform.position.y - 0.6f, fungleMenuButton.position.z);
__instance.MapMenu.MapButtons = HarmonyLib.CollectionExtensions.AddItem(__instance.MapMenu.MapButtons, dleksIconInMenuCopy).ToArray();
float xPos = -1f;
for (int index = 0; index < 6; ++index)
{
__instance.MapMenu.MapButtons[index].transform.SetLocalX(xPos);
xPos += 0.34f;
}
if (__instance.mode == SettingsMode.Host)
{
mapPickerMenu.transform.localPosition = new Vector3(mapPickerMenu.transform.localPosition.x, 0.85f, mapPickerMenu.transform.localPosition.z);
mapPickerTransform.localScale = new Vector3(0.86f, 0.85f, 1f);
mapPickerTransform.transform.localPosition = new Vector3(mapPickerTransform.transform.localPosition.x + 0.05f, mapPickerTransform.transform.localPosition.y + 0.03f, mapPickerTransform.transform.localPosition.z);
}
SwapIconOrButtomsPositions(airhipIconInMenu, dleksIconInMenuCopy);
SwapIconOrButtomsPositions(fungleIconInMenu, airhipIconInMenu);
SwapIconOrButtomsPositions(airshipMenuButton, dleksMenuButtonCopy);
__instance.MapMenu.MapButtons[5].SetFlipped(true);
mapPickerMenu.transform.Find("Backdrop").localScale *= 5;
}
private static void SwapIconOrButtomsPositions(Component one, Component two)
{
Transform transform1 = one.transform;
Transform transform2 = two.transform;
Vector3 position1 = two.transform.position;
Vector3 position2 = one.transform.position;
transform1.position = position1;
transform2.position = position2;
}
}
}
+8 -5
View File
@@ -29,7 +29,7 @@ class NormalGameEndChecker
public static bool Prefix()
{
if (Options.NoGameEnd.GetBool() || Options.Gamemode.GetValue() == 3) return false;
if (Options.NoGameEnd.GetBool() || Options.Gamemode.GetValue() == 3 || Utils.HandlingGameEnd) return false;
var allPlayers = PlayerControl.AllPlayerControls.ToArray();
@@ -39,21 +39,24 @@ class NormalGameEndChecker
ImpCheckComplete = true;
}
var customRoles = CustomRoleManagement.PlayerToCustomRole();
var impostorList = string.Join(", ", imps.Select(p => p.Data.PlayerName));
if (Utils.AliveImpostors == 0)
{
LastWinReason = $"★ Crewmates win!\n\nImpostors:\n" + string.Join("\n", imps.Select(p => p.Data.PlayerName));
LastWinReason = $"Crewmates win!\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles);
}
else if (Utils.AliveImpostors >= Utils.AliveCrewmates)
{
LastWinReason = $"★ Impostors win!\n\nImpostors:\n★" + string.Join("\n★", imps.Select(p => p.Data.PlayerName));
LastWinReason = $"Impostors win!\n\nImpostor: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles);
}
else if (GameData.Instance != null && GameData.Instance.TotalTasks > 0 && GameData.Instance.CompletedTasks >= GameData.Instance.TotalTasks)
{
LastWinReason = $"★ Crewmates win! (Tasks)\n\nImpostors:\n" + string.Join("\n", imps.Select(p => p.Data.PlayerName));
LastWinReason = $"Crewmates win! (Tasks)\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles);
}
else if (Options.Gamemode.GetValue() < 2)
{
LastWinReason = $"★ Impostors win! (Sabotage)\n\nImpostors:\n★" + string.Join("\n★", imps.Select(p => p.Data.PlayerName));
LastWinReason = $"Impostors win! (Sabotage)\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles);
}
return true;
}
+35
View File
@@ -0,0 +1,35 @@
namespace AmongUsRevamped;
class ExileControllerWrapUpPatch
{
[HarmonyPatch(typeof(ExileController), nameof(ExileController.WrapUp))]
class ExileControllerPatch
{
public static void Postfix(ExileController __instance)
{
if (!AmongUsClient.Instance.AmHost) return;
var ejectedPlayer = __instance.initData?.networkedPlayer;
if (ejectedPlayer == null) return;
PlayerControl pc = null;
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p.PlayerId == ejectedPlayer.PlayerId)
{
pc = p;
break;
}
}
Logger.Info($" {ejectedPlayer.PlayerName} was ejected", "ExileController");
if (!CustomRoleManagement.PlayerRoles.TryGetValue(ejectedPlayer.PlayerId, out var role)) return;
if (role == "Jester")
{
Utils.CustomWinnerEndGame(pc, 1);
}
}
}
}
+5 -2
View File
@@ -1,8 +1,11 @@
using System;
using Il2CppSystem.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
#if ANDROID
using System.Collections.Generic;
#else
using Il2CppSystem.Collections.Generic;
#endif
// https://github.com/Yumenopai/TownOfHost_Y/blob/main/Patches/GameOptionsPatch.cs
namespace AmongUsRevamped
-1
View File
@@ -1,7 +1,6 @@
using System;
using TMPro;
using UnityEngine;
using Object = UnityEngine.Object;
// https://github.com/Yumenopai/TownOfHost_Y/blob/main/Patches/GameSettingMenuPatch.cs
namespace AmongUsRevamped
+18 -28
View File
@@ -12,22 +12,18 @@ public static class GameStartManagerUpdatePatch
public static void Prefix(GameStartManager __instance)
{
if (!GameStartManager.InstanceExists || AmongUsClient.Instance == null || !AmongUsClient.Instance.AmHost) return;
if (__instance == null || MeetingHud.Instance != null) return;
if (AmongUsClient.Instance == null || !AmongUsClient.Instance.AmHost) return;
var data = GameData.Instance;
if (__instance.StartButton == null || __instance.GameStartText == null) return;
__instance.MinPlayers = 1;
if (Main.AutoStart.Value && OnGameJoinedPatch.AutoStartCheck && GameStartManager.InstanceExists && GameStartManager.Instance.startState != GameStartManager.StartingStates.Countdown && data != null && data.PlayerCount >= Options.PlayerAutoStart.GetInt())
if (Main.AutoStart.Value && OnGameJoinedPatch.AutoStartCheck && GameStartManager.InstanceExists && __instance.startState != GameStartManager.StartingStates.Countdown && GameData.Instance?.PlayerCount >= Options.PlayerAutoStart.GetInt())
{
GameStartManager.Instance.startState = GameStartManager.StartingStates.Countdown;
GameStartManager.Instance.countDownTimer = Options.AutoStartTimer.GetFloat();
var sb = GameStartManager.Instance?.StartButton;
if (sb != null)
{
sb.gameObject.SetActive(false);
}
__instance.startState = GameStartManager.StartingStates.Countdown;
__instance.countDownTimer = Options.AutoStartTimer.GetFloat();
__instance.StartButton.gameObject.SetActive(false);
Autostarting = true;
}
@@ -35,7 +31,6 @@ public static class GameStartManagerUpdatePatch
{
__instance.countDownTimer = Options.StartCountdown.GetInt();
CustomTimerApplied = true;
}
if (__instance.startState != GameStartManager.StartingStates.Countdown)
@@ -49,7 +44,10 @@ public static class GameStartManagerUpdatePatch
{
string warningMessage = "";
if (!AmongUsClient.Instance.AmHost) return;
if (__instance == null || MeetingHud.Instance != null) return;
if (AmongUsClient.Instance == null || !AmongUsClient.Instance.AmHost) return;
if (__instance.StartButton == null || __instance.GameStartText == null) return;
if (GameStartManagerStartPatch.warningText != null)
{
@@ -80,40 +78,32 @@ public static class GameStartManagerUpdatePatch
public class GameStartManagerStartPatch
{
public static TextMeshPro warningText;
private static Vector3 GameStartTextlocalPosition;
public static PassiveButton cancelButton;
public static void Postfix(GameStartManager __instance)
{
if (__instance == null || !Utils.IsLobby) return;
warningText = UnityEngine.Object.Instantiate(__instance.GameStartText, __instance.transform.parent);
warningText.name = "WarningText";
warningText.transform.localPosition = new(0f, __instance.transform.localPosition.y + 3f, -1f);
warningText.transform.localPosition = new Vector3(0f, __instance.transform.localPosition.y + 3f, -1f);
warningText.gameObject.SetActive(false);
cancelButton = UnityEngine.Object.Instantiate(__instance.StartButton, __instance.transform);
cancelButton.name = "CancelButton";
var cancelLabel = cancelButton.buttonText;
cancelLabel.DestroyTranslator();
cancelLabel.text = "Cancel";
//cancelButton.transform.localScale = new(0.5f, 0.5f, 1f);
var cancelButtonInactiveRenderer = cancelButton.inactiveSprites.GetComponent<SpriteRenderer>();
cancelButtonInactiveRenderer.color = new(0.8f, 0f, 0f, 1f);
var cancelButtonActiveRenderer = cancelButton.activeSprites.GetComponent<SpriteRenderer>();
cancelButtonActiveRenderer.color = Color.red;
var cancelButtonInactiveShine = cancelButton.inactiveSprites.transform.Find("Shine");
if (cancelButtonInactiveShine)
{
cancelButtonInactiveShine.gameObject.SetActive(false);
}
cancelButton.activeTextColor = cancelButton.inactiveTextColor = Color.white;
//cancelButton.transform.localPosition = new(2f, 0.13f, 0f);
GameStartTextlocalPosition = __instance.GameStartText.transform.localPosition;
cancelButton.gameObject.SetActive(false);
cancelButton.OnClick = new();
cancelButton.OnClick.AddListener((UnityEngine.Events.UnityAction)(() =>
{
__instance.ResetStartState();
}));
cancelButton.gameObject.SetActive(false);
}
}
+38
View File
@@ -0,0 +1,38 @@
using Hazel;
using InnerNet;
using System;
using UnityEngine;
namespace AmongUsRevamped;
[HarmonyPatch(typeof(HudManager), nameof(HudManager.CoShowIntro))]
internal static class CoShowIntroPatch
{
public static void Postfix(IntroCutscene __instance)
{
Logger.Info("Intro initiated", "CoShowIntro");
if (!AmongUsClient.Instance.AmHost) return;
if ((Options.Gamemode.GetValue() == 0 || Options.Gamemode.GetValue() == 1) && !Utils.isHideNSeek)
{
CustomRoleManagement.AssignRoles();
}
CustomRoleManagement.SendRoleMessages(new Dictionary<string, string>
{
{ "Jester", $"{String.Jester}"},
{ "Mayor", $"{String.Mayor}"}
});
if (!Utils.isHideNSeek) return;
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p.Data.Role.TeamType == RoleTeamTypes.Impostor)
{
p.RpcSetRole(AmongUs.GameOptions.RoleTypes.Impostor, false);
}
}
}
}
+3 -1
View File
@@ -14,6 +14,8 @@ internal static class OnGameJoinedPatch
public static bool AutoStartCheck;
public static void Postfix()
{
Logger.Info(" -------- JOINED GAME --------", "OnGameJoined");
if (!AmongUsClient.Instance.AmHost) return;
WaitingForChat = false;
@@ -78,7 +80,7 @@ class OnPlayerJoinedPatch
{
BanManager.CheckBanPlayer(Client);
Utils.IsPlayerInDenyName(Client, Client.PlayerName);
BanManager.IsPlayerInDenyName(Client, Client.PlayerName);
if (Utils.IsPlayerModerator(Client.FriendCode) && Options.ApplyModeratorList.GetBool())
{
+31 -1
View File
@@ -1,4 +1,5 @@
using InnerNet;
using Il2CppSystem.Collections;
using InnerNet;
using System;
using UnityEngine;
@@ -25,4 +26,33 @@ internal static class LobbyBehaviourUpdatePatch
SoundManager.Instance.CrossFadeSound("MapTheme", __instance.MapTheme, 0.5f);
}
}
}
[HarmonyPatch(typeof(LobbyBehaviour), nameof(LobbyBehaviour.Start))]
public class LobbyStartPatch
{
private static GameObject LobbyPaintObject;
private static Sprite LobbyPaintSprite;
public static void Prefix()
{
LobbyPaintSprite = Utils.LoadSprite("AmongUsRevamped.Resources.Images.doger.png", 290f);
}
public static void Postfix(LobbyBehaviour __instance)
{
_ = new LateTask(() =>
{
var LeftBox = GameObject.Find("Leftbox");
if (LeftBox != null)
{
LobbyPaintObject = UnityEngine.Object.Instantiate(LeftBox, LeftBox.transform.parent);
LobbyPaintObject.name = "Lobby Paint";
LobbyPaintObject.transform.localPosition = new Vector3(0.042f, -2.59f, -10.5f);
SpriteRenderer renderer = LobbyPaintObject.GetComponent<SpriteRenderer>();
renderer.sprite = LobbyPaintSprite;
}
}, 0.25f, "Co Load Dropship Decorations");
}
}
-2
View File
@@ -2,8 +2,6 @@ using System;
using TMPro;
using UnityEngine;
using Object = UnityEngine.Object;
// https://github.com/Rabek009/MoreGamemodes/blob/master/Patches/LobbyViewSettingsPatch.cs
namespace AmongUsRevamped
{
+68 -20
View File
@@ -1,25 +1,36 @@
using AmongUs.GameOptions;
using UnityEngine;
namespace AmongUsRevamped;
// https://github.com/astra1dev/AUnlocker/blob/main/src/OptionsPatches.cs
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.Increase))]
public static class NumberOption_Increase
{
public static bool Prefix(NumberOption __instance)
{
if (ModGameOptionsMenu.TabIndex >= 3) return true;
#if ANDROID
float increment = __instance.Increment;
#else
float increment = Hotkeys.IncrementMultiplier * __instance.Increment;
#endif
if (Utils.isHideNSeek || !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed)
if (Utils.isHideNSeek || Utils.IsLobby && !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed)
{
__instance.Value += __instance.Increment;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
__instance.AdjustButtonsActiveState();
return false;
if (__instance.Value + increment > __instance.ValidRange.max)
{
return true;
}
else
{
__instance.Value += increment;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
return false;
}
}
else return true;
return true;
}
}
@@ -28,17 +39,27 @@ public static class NumberOption_Decrease
{
public static bool Prefix(NumberOption __instance)
{
if (ModGameOptionsMenu.TabIndex >= 3) return true;
#if ANDROID
float increment = __instance.Increment;
#else
float increment = Hotkeys.IncrementMultiplier * __instance.Increment;
#endif
if (Utils.isHideNSeek || !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed)
if (Utils.isHideNSeek || Utils.IsLobby && !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed)
{
__instance.Value -= __instance.Increment;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
__instance.AdjustButtonsActiveState();
return false;
if (__instance.Value - increment < __instance.ValidRange.min)
{
return true;
}
else
{
__instance.Value -= increment;
__instance.UpdateValue();
__instance.OnValueChanged.Invoke(__instance);
return false;
}
}
else return true;
return true;
}
}
@@ -49,9 +70,36 @@ public static class NumberOption_Initialize
{
if (ModGameOptionsMenu.TabIndex >= 3) return;
if (Utils.isHideNSeek || !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed)
if (Utils.isHideNSeek || Utils.IsLobby && !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed)
{
__instance.ValidRange = new FloatRange(-900f, 900f);
__instance.ValidRange = new FloatRange(0f, 900f);
}
switch (__instance.Title)
{
case StringNames.GameVotingTime:
case StringNames.GameDiscussTime:
case StringNames.EscapeTime:
case StringNames.FinalEscapeTime:
__instance.Increment = 5f;
break;
case StringNames.GameKillCooldown:
__instance.Increment = 0.5f;
break;
case StringNames.GamePlayerSpeed:
case StringNames.SeekerFinalSpeed:
case StringNames.GameCrewLight:
case StringNames.GameImpostorLight:
case StringNames.CrewmateFlashlightSize:
case StringNames.ImpostorFlashlightSize:
__instance.Increment = 0.05f;
break;
default:
__instance.Increment = 1f;
break;
}
}
}
}
+1 -18
View File
@@ -5,7 +5,7 @@ using UnityEngine;
namespace AmongUsRevamped;
[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.CoStartGame))]
internal class ApplyCustomImpostorCount
internal class CoStartGamePatch
{
public static void Postfix(AmongUsClient __instance)
{
@@ -67,28 +67,11 @@ internal class ApplyCustomImpostorCount
(candidates[i], candidates[j]) = (candidates[j], candidates[i]);
}
// 1st RpcSetRole forces the role on that user. 2nd is needed to allow them to kill.
for (int i = 0; i < toAdd; i++)
{
var player = candidates[i];
player.RpcSetRole(AmongUs.GameOptions.RoleTypes.Impostor, false);
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p.Data.Role.TeamType == RoleTeamTypes.Impostor)
{
new LateTask(() =>
{
p.RpcSetRole(AmongUs.GameOptions.RoleTypes.Impostor, false);
}, 5f, "HNS Secondary RPCSetRole");
new LateTask(() =>
{
p.RpcSetRole(AmongUs.GameOptions.RoleTypes.Impostor, false);
}, 9f, "HNS Tertiary RPCSetRole");
}
}
}
}
}
+2 -2
View File
@@ -12,9 +12,9 @@ class ReportDeadBodyPatch
{
public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] NetworkedPlayerInfo target)
{
if (!AmongUsClient.Instance.AmHost) return true;
if (!AmongUsClient.Instance.AmHost || target == null || __instance == null) return true;
if (Options.DisableReport.GetBool() && target != null || Options.Gamemode.GetValue() == 2 || Options.Gamemode.GetValue() == 3)
if (Options.DisableReport.GetBool() || Options.Gamemode.GetValue() == 2 || Options.Gamemode.GetValue() == 3)
{
Logger.Info($" Stopped {__instance.Data.PlayerName} reporting the body of {target.PlayerName}", "ReportDeadBodyPatch");
return false;
+21 -6
View File
@@ -9,8 +9,6 @@ public static class SabotageSystemTypeRepairDamagePatch
{
private static bool Prefix([HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader)
{
if (!AmongUsClient.Instance.AmHost) return true;
byte amount;
{
var newReader = MessageReader.Get(msgReader);
@@ -18,12 +16,27 @@ public static class SabotageSystemTypeRepairDamagePatch
newReader.Recycle();
}
var Sabo = (SystemTypes)amount;
Logger.Info($" {player.Data.PlayerName} is trying to sabotage: {Sabo}", "SabotageCheck");
if (Options.DisableSabotage.GetBool() || Options.Gamemode.GetValue() == 2)
if (player.Data.ClientId == AmongUsClient.Instance.HostId) return true;
if (Options.Gamemode.GetValue() == 0 || Options.Gamemode.GetValue() == 1)
{
Logger.Info($" Sabotage {Sabo} by: {player.Data.PlayerName} was blocked", "SabotageCheck");
return false;
if (Sabo == SystemTypes.LifeSupp && Options.DisableOxygen.GetBool() || Sabo == SystemTypes.Reactor && Options.DisableReactor.GetBool() || Sabo == SystemTypes.Electrical && Options.DisableLights.GetBool() || Sabo == SystemTypes.Comms && Options.DisableComms.GetBool() || Sabo == SystemTypes.HeliSabotage && Options.DisableHeli.GetBool() || Sabo == SystemTypes.MushroomMixupSabotage && Options.DisableMushroomMixup.GetBool())
{
Logger.Info($" Sabotage {Sabo} by: {player.Data.PlayerName} was blocked", "SabotageCheck");
return false;
}
return true;
}
if (Options.Gamemode.GetValue() == 2)
{
if (Sabo == SystemTypes.LifeSupp && Options.SNSDisableOxygen.GetBool() || Sabo == SystemTypes.Reactor && Options.SNSDisableReactor.GetBool() || Sabo == SystemTypes.Electrical && Options.SNSDisableLights.GetBool() || Sabo == SystemTypes.Comms && Options.SNSDisableComms.GetBool() || Sabo == SystemTypes.HeliSabotage && Options.SNSDisableHeli.GetBool() || Sabo == SystemTypes.MushroomMixupSabotage && Options.SNSDisableMushroomMixup.GetBool())
{
Logger.Info($" Sabotage {Sabo} by: {player.Data.PlayerName} was blocked", "SnSSabotageCheck");
return false;
}
return true;
}
else return true;
}
@@ -60,6 +73,8 @@ public static class MessageReaderUpdateSystemPatch
or SystemTypes.Decontamination3
or SystemTypes.MedBay) return true;
if (player.Data.ClientId == AmongUsClient.Instance.HostId) return true;
var amount = MessageReader.Get(reader).ReadByte();
if (EACR.RpcUpdateSystemCheck(player, systemType, amount))
{
+1 -1
View File
@@ -21,7 +21,7 @@ internal static class AddVotePatch
Logger.Info($" Kicked {target.Data.PlayerName}, {target.Data.FriendCode}", "KickPatch");
}
return false;
return true;
}
}
+49 -22
View File
@@ -29,54 +29,81 @@
<img src="https://github.com/astra1dev/AUnlocker/assets/90265231/14226f03-a003-4efc-b27b-6df53fb394d6" width=410 height=240>****
‎
# 🎮 Features (v1.2.1):
- <b>🔶 Client Side settings:</b>
# 🎮 Features (v1.5.1):
## <b>♠️ Client Side settings:</b>
- Game Master
- Unlock FPS
- Show FPS
- Dark Theme
- Toggle Lobby Music
- <b>🔷 Technical settings:</b>
## <b>⚙️ Technical settings:</b>
- Kick/Ban players under a certain level
- Kick/Ban invalid FriendCodes
- Kick/Ban command using names
- Ckick/Cban command using colors
- Kick/Ban players who say "start"
- DenyName system
- Moderator system
- Banlist system
- Enable No Game End
- <b>🔶 Automation settings:</b>
- Auto start game and conditions for it
- Auto rejoin lobby
- Auto send winner info
- <b>🔷 Gameplay Settings:</b>
- Custom starting countdown
## <b>♻️ Automation settings:</b>
- Automatically start game and conditions for it
- Automatically rejoin lobby
- Automatically send winner info
## <b>🔧 Gameplay Settings:</b>
- Disable critical sabotages
- Disable door sabotages
- Disable body reporting
- Enable/Disable any desired tasks
- Enable/Disable any task
- All players have same tasks
- Hide and Seek: Custom Impostor count
- <b>🔶 Custom Gamemodes:</b>
## <b>🏆 Custom Gamemodes:</b>
- 0 Kill Cooldown
- Shift and Seek
- Speedrun
- <b>🔷 Extra features:</b>
- Shift + L + Enter - Force End Game
- Shift + M + Enter - Force Call/Close Meeting
- /help command
- Specific gamemode info commands -> /0kc, /sns, /sp
- Current gamemode info command -> /r
## <b>❓ Other Improvements:</b>
- ehT dlekS map (reverse Skeld)
- Ability to cancel starting countdown
- Improved main menu
- Custom anticheat system
- Zoom out in lobby or when dead
- Unlimited default Option ranges
- Near unlimited default Option ranges
- More accurate Option incrementing
- Logging for useful information
- <b>🎉 And this all without Modded Protocol!</b>
‎
- <b>🎉 And this all works in public lobbies!</b>
### Hotkeys
| HotKey | Function | Usable Scene |
| ------------------- | ------------------------------------------- | ---------------------------------- |
| `Shift`+`L`+`Enter` | Force End Game | In Game |
| `Shift`+`M`+`Enter` | Skip meeting when active | In Game |
| `C` | Cancel game start | In Starting Countdown |
| `Shift` | Start the game immediately | In Starting Countdown |
| `Shift` | 5x Option increment | In Options Menu |
| `Ctrl` | Noclip in lobby | In Lobby |
| `Ctrl` | 10x Option increment | In Options Menu |
### Chat Commands
| Command | Function |
| ------------------------------------------- | ------------------------------------------------- |
| /h<br>/help | Show command help |
| /l<br>/win | Show winner |
| /r | Show current gamemode/roles description |
| /0kc<br>/sns</br>/sp | Show respective gamemode description |
| /ban <name> | Ban a player by name |
| /kick <name> | Kick a player by name |
| /cban <color> | Ban a player by color |
| /ckick <color> | Kick a player by color |
| /dump | Copy your LogOutput file |
| /endgame | Instantly end the game |
| /endmeeting | Instantly end an ongoing meeting |
| /aur | Sends AUR socials (GitHub, Discord) |
| /color | Sets color. Can be used to bypass color limit |
‎
**Credit to these mods and their developers for their code:**
### :star: [AUnlocker](https://github.com/astra1dev/AUnlocker)
> - NumberOptionsPatch
### :star: [EHR (Formerly TOHE+)](https://github.com/Gurge44/EndlessHostRoles)
> - Dark Theme
> - Task Patching
### :star: [TOH](https://github.com/tukasa0001/TownOfHost) :
> - Ban Manager
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

+43
View File
@@ -0,0 +1,43 @@
using System.Reflection;
namespace AmongUsRevamped;
// Used post-1.4.0 incase AUR ever gets translations. Not fully updated.
/* TEMPLATE
public static string x{get{
return $"y";}}
*/
public static class String
{
public static string noKcdMode{get{
return $"0 Kill Cooldown:\n\nImpostors have no kill cooldown, Crewmates have low tasks\nThink fast and pay attention!";}}
public static string SnSModeOne{get{
return $"Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nSabotages & Meetings = Off";}}
public static string SnSModeTwo{get{
return $"Crew wins by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\n" + "Imp wins by killing\n" + (Options.MisfiresToSuicide.GetInt() == 1 ? "" : $"One wrong kill = Can't kill for {Options.CantKillTime.GetInt()}s\n") + $"{Utils.BasicIntToWord(Options.MisfiresToSuicide.GetInt())} wrong kill{(Options.MisfiresToSuicide.GetInt() == 1 ? "" : "s")} = suicide";}}
public static string speedrunMode{get{
return $"Speedrun:\n\nEveryone is a crewmate. The 1st player to finish tasks wins the game. Game auto ends after {Options.GameAutoEndsAfter.GetInt()}s";}}
public static string allCommandsFull{get{
return $"Commands:\n/r - Current mode description\n/0kc, /sns, /sp - Specific mode description\n/l - Shows last winner info\n/kick, /ban - Bans or kicks a player by name\n/ckick, /cban - Bans or kicks a player by color";}}
public static string allCommandsOne{get{
return $"Commands:\n/r - Current mode description\n/0kc, /sns, /sp - Specific mode description\n/l - Shows last winner info";}}
public static string allCommandsTwo{get{
return $"/kick, /ban - Bans or kicks a player by name\n/ckick, /cban - Bans or kicks a player by color";}}
public static string SocialsAll{get{
return $"AUR socials:\n\ng i t h u b . c o m /\nApeMV/AmongUsRevamped\n\nd i s c o r d . g g /\n83Zhzhyhya";}}
public static string Mayor{get{
return $"PRIVATE:\n\nYour role is Mayor!\n\nYou are a crewmate with i total votes. Use your voting power to eject Impostors.";}}
public static string Jester{get{
return $"PRIVATE:\n\nYour role is Jester!\nYou are NOT a crewmate!\n\nYou win by getting voted. Act as suspicious as possible.";}}
}