Merge pull request #8 from D1GQ/dev

Canary 5
This commit is contained in:
D1GQ authored and GitHub committed 2024-08-02 21:52:21 -05:00
commit e13f83a9e1
22 files changed
+677 -120

No files matched your search

+111 -25
View File
@@ -1,6 +1,8 @@
using AmongUs.GameOptions;
using HarmonyLib;
using Hazel;
using InnerNet;
using UnityEngine;
namespace BetterAmongUs;
@@ -11,6 +13,50 @@ class AntiCheat
public static Dictionary<string, string> AUMData = []; // HashPuid, FriendCode
private static bool IsEnabled = true;
public static void Update()
{
if (GameStates.IsInGame)
{
foreach (var kvp in ExtendedPlayerControl.TimeSinceKill)
{
ExtendedPlayerControl.TimeSinceKill[kvp.Key] += Time.deltaTime;
}
}
else
{
if (ExtendedPlayerControl.TimeSinceKill.Any())
{
ExtendedPlayerControl.TimeSinceKill.Clear();
}
}
if (GameStates.IsHost && GameStates.IsInGame)
{
RPC.SyncAllNames(isBetterHost: false);
foreach (var player in Main.AllPlayerControls)
{
var hashPuid = Utils.GetHashPuid(player);
if (SickoData.ContainsKey(hashPuid))
{
player.RpcSetName($"<color=#ffea00>{player.Data.PlayerName}</color> Has been banned by <color=#4f92ff>Anti-Cheat</color>, Reason: Known Sicko Menu User<size=0%>");
AmongUsClient.Instance.KickPlayer(player.GetClientId(), true);
}
else if (AUMData.ContainsKey(hashPuid))
{
player.RpcSetName($"<color=#ffea00>{player.Data.PlayerName}</color> Has been banned by <color=#4f92ff>Anti-Cheat</color>, Reason: Known AUM User<size=0%>");
AmongUsClient.Instance.KickPlayer(player.GetClientId(), true);
}
else if (PlayerData.ContainsKey(hashPuid))
{
player.RpcSetName($"<color=#ffea00>{player.Data.PlayerName}</color> Has been banned by <color=#4f92ff>Anti-Cheat</color>, Reason: Known Cheater<size=0%>");
AmongUsClient.Instance.KickPlayer(player.GetClientId(), true);
}
}
}
}
public static void PauseAntiCheat()
{
float time = 2f;
@@ -25,10 +71,44 @@ class AntiCheat
}
}
[HarmonyPatch(typeof(PlatformSpecificData))]
class PlatformSpecificDataPatch
{
[HarmonyPatch(nameof(PlatformSpecificData.Deserialize))]
[HarmonyPostfix]
public static void Deserialize_Postfix(PlatformSpecificData __instance)
{
_ = new LateTask(() =>
{
var player = Main.AllPlayerControls.FirstOrDefault(pc => pc.GetClient().PlatformData == __instance);
if (player != null)
{
if (__instance.Platform is Platforms.StandaloneWin10 or Platforms.Xbox)
{
if (__instance.XboxPlatformId == 0)
{
BetterNotificationManager.NotifyCheat(player, $"Platform Spoofer", newText: "Has been detected with a cheat");
}
}
if (__instance.Platform is Platforms.Playstation)
{
if (__instance.PsnPlatformId == 0)
{
BetterNotificationManager.NotifyCheat(player, $"Platform Spoofer", newText: "Has been detected with a cheat");
}
}
}
}, 1.5f, shoudLog: false);
}
}
// Handle RPC before anti cheat detection
public static void HandleRPCBeforeCheck(PlayerControl player, byte callId, MessageReader Oldreader)
{
MessageReader reader = Oldreader;
MessageReader reader = MessageReader.Get(Oldreader);
if (player == PlayerControl.LocalPlayer || PlayerControl.LocalPlayer == null || player == null || !IsEnabled) return;
@@ -41,11 +121,9 @@ class AntiCheat
if (reader.BytesRemaining == 0 && !flag)
{
AmongUsClient.Instance.ReportPlayer(player.GetClientId(), ReportReasons.Cheating_Hacking);
BetterNotificationManager.NotifyCheat(player, $"Sicko Menu", newText: "Has been detected with a cheat client");
PlayerData[Utils.GetHashPuid(player)] = player.FriendCode;
SickoData[Utils.GetHashPuid(player)] = player.FriendCode;
BetterDataManager.SaveCheatData(Utils.GetHashPuid(player), player.Data.FriendCode, player.Data.PlayerName, "cheatData", "Sicko Menu RPC");
BetterDataManager.SaveCheatData(Utils.GetHashPuid(player), player.Data.FriendCode, player.Data.PlayerName, "sickoData", "Sicko Menu RPC");
BetterNotificationManager.NotifyCheat(player, $"Sicko Menu", newText: "Has been detected with a cheat client");
}
}
@@ -65,11 +143,9 @@ class AntiCheat
if (!flag)
{
AmongUsClient.Instance.ReportPlayer(player.GetClientId(), ReportReasons.Cheating_Hacking);
BetterNotificationManager.NotifyCheat(player, $"AUM", newText: "Has been detected with a cheat client");
PlayerData[Utils.GetHashPuid(player)] = player.FriendCode;
AUMData[Utils.GetHashPuid(player)] = player.FriendCode;
BetterDataManager.SaveCheatData(Utils.GetHashPuid(player), player.Data.FriendCode, player.Data.PlayerName, "cheatData", "AUM RPC");
BetterDataManager.SaveCheatData(Utils.GetHashPuid(player), player.Data.FriendCode, player.Data.PlayerName, "aumData", "AUM RPC");
BetterNotificationManager.NotifyCheat(player, $"AUM", newText: "Has been detected with a cheat client");
}
}
}
@@ -98,11 +174,9 @@ class AntiCheat
if (!flag && !flag2)
{
AmongUsClient.Instance.ReportPlayer(player.GetClientId(), ReportReasons.Cheating_Hacking);
BetterNotificationManager.NotifyCheat(AUMPlayer, $"AUM", newText: "Has been detected with a cheat client");
PlayerData[Utils.GetHashPuid(AUMPlayer)] = AUMPlayer.FriendCode;
AUMData[Utils.GetHashPuid(AUMPlayer)] = AUMPlayer.FriendCode;
BetterDataManager.SaveCheatData(Utils.GetHashPuid(player), player.Data.FriendCode, player.Data.PlayerName, "cheatData", "AUM Chat RPC");
BetterDataManager.SaveCheatData(Utils.GetHashPuid(player), player.Data.FriendCode, player.Data.PlayerName, "aumData", "AUM Chat RPC");
BetterNotificationManager.NotifyCheat(AUMPlayer, $"AUM", newText: "Has been detected with a cheat client");
}
}
catch { }
@@ -114,10 +188,11 @@ class AntiCheat
// Check and notify for invalid rpcs
public static void CheckRPC(PlayerControl player, byte callId, MessageReader Oldreader)
{
MessageReader reader = Oldreader;
try
{
if (PlayerControl.LocalPlayer == null || player == null || player == PlayerControl.LocalPlayer || reader == null || !IsEnabled || !Main.AntiCheat.Value) return;
MessageReader reader = MessageReader.Get(Oldreader);
if (PlayerControl.LocalPlayer == null || player == null || player == PlayerControl.LocalPlayer || player.GetIsBetterHost() || reader == null || !IsEnabled || !Main.AntiCheat.Value) return;
RoleTypes? Role = player?.Data?.RoleType;
Role ??= RoleTypes.Crewmate;
@@ -125,6 +200,14 @@ class AntiCheat
bool IsCrewmate = !player.IsImpostorTeam();
string hashPuid = Utils.GetHashPuid(player);
if (callId is (byte)RpcCalls.SendChat or (byte)RpcCalls.SendQuickChat)
{
if (player.IsAlive() && GameStates.IsInGamePlay && !GameStates.IsMeeting && !GameStates.IsExilling)
BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName((RpcCalls)callId)}");
return;
}
if (callId is (byte)RpcCalls.EnterVent or (byte)RpcCalls.ExitVent)
{
if ((IsCrewmate && Role != RoleTypes.Engineer) || player.Data.IsDead)
@@ -149,24 +232,17 @@ class AntiCheat
if (target != null)
{
if (IsCrewmate || !player.IsAlive() || player.IsInVanish() || !target.IsAlive() || target.IsImpostorTeam())
if (IsCrewmate || !player.IsAlive() || player.IsInVanish() || !target.IsAlive() || target.IsImpostorTeam()
|| ExtendedPlayerControl.TimeSinceKill.TryGetValue(player, out var value) && value < (float)GameOptionsManager.Instance.currentNormalGameOptions.KillCooldown)
{
BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName((RpcCalls)callId)}");
}
}
}
return;
}
/*
if (callId is (byte)RpcCalls.SendChat or (byte)RpcCalls.SendQuickChat)
{
if (player.IsAlive() && GameStates.IsInGamePlay && !GameStates.IsMeeting && !GameStates.IsExilling)
BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName((RpcCalls)callId)}");
return;
}
*/
if (callId is (byte)RpcCalls.SetLevel)
{
if (reader.BytesRemaining > 0)
@@ -239,10 +315,11 @@ class AntiCheat
// Check notify and cancel out request for invalid rpcs
public static bool CheckCancelRPC(PlayerControl player, byte callId, MessageReader Oldreader)
{
MessageReader reader = Oldreader;
try
{
if (PlayerControl.LocalPlayer == null || player == null || player == PlayerControl.LocalPlayer || reader == null || !IsEnabled || !Main.AntiCheat.Value) return true;
MessageReader reader = MessageReader.Get(Oldreader);
if (PlayerControl.LocalPlayer == null || player == null || player == PlayerControl.LocalPlayer || player.GetIsBetterHost() || reader == null || !IsEnabled || !Main.AntiCheat.Value) return true;
RoleTypes Role = player.Data.RoleType;
bool IsImpostor = player.IsImpostorTeam();
@@ -254,6 +331,15 @@ class AntiCheat
return false;
}
if (callId is (byte)RpcCalls.StartMeeting or (byte)RpcCalls.ReportDeadBody)
{
if (GameStates.IsMeeting || GameStates.IsExilling)
{
BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName((RpcCalls)callId)}");
return false;
}
}
if (callId is (byte)RpcCalls.Shapeshift)
{
var flag = reader.ReadBoolean();
+98 -7
View File
@@ -1,13 +1,67 @@
using AmongUs.GameOptions;
using Hazel;
using InnerNet;
using UnityEngine;
using System.Text;
namespace BetterAmongUs;
class BetterHostManager
{
public static Dictionary<byte, Dictionary<byte, string>> LastPlayerName = []; // Targetid, Playerid, Name
private static Dictionary<byte, Dictionary<byte, string>> LastPlayerName = []; // Targetid, Playerid, Name
private static List<PlayerControl> VentStuck = [];
public static void Update(PlayerControl player)
{
if (!Main.BetterHost.Value) return;
// Lock up player vent button if it's invalid vent
if (!VentStuck.Contains(player) && player.inVent && !player.Is(RoleTypes.Engineer) && !player.IsImpostorTeam())
{
player.MyPhysics.RpcEnterVent(player.GetPlayerVentId());
player.MyPhysics.RpcBootFromVent(player.GetPlayerVentId());
VentStuck.Add(player);
}
}
public static bool IsSpeedExceeding(float currentSpeed)
{
float leniency = 1.8f;
float thresholdSpeed = GetAverageSpeed() + leniency;
bool isExceeding = currentSpeed > thresholdSpeed;
return isExceeding;
}
public static float GetAverageSpeed()
{
float speedMod = GameStates.IsHideNSeek
? GameOptionsManager.Instance.currentHideNSeekGameOptions.PlayerSpeedMod
: GameOptionsManager.Instance.currentNormalGameOptions.PlayerSpeedMod;
// Data points
float[] mods = { 0.5f, 1.5f, 2.0f }; // Add more as needed
float[] avgSpeeds = { 1.3f, 3.75f, 5.0f }; // Add corresponding speeds
int n = mods.Length;
float sumMod = 0, sumAvgSpeed = 0, sumModAvgSpeed = 0, sumModSquared = 0;
for (int i = 0; i < n; i++)
{
sumMod += mods[i];
sumAvgSpeed += avgSpeeds[i];
sumModAvgSpeed += mods[i] * avgSpeeds[i];
sumModSquared += mods[i] * mods[i];
}
float m = (n * sumModAvgSpeed - sumMod * sumAvgSpeed) / (n * sumModSquared - sumMod * sumMod);
float c = (sumAvgSpeed - m * sumMod) / n;
float estimatedAverageSpeed = m * speedMod + c;
return estimatedAverageSpeed;
}
public static bool CheckRange(Vector2 pos1, Vector2 pos2, float range) => Vector2.Distance(pos1, pos2) <= range;
public static bool CheckRPCAsHost(PlayerControl player, byte callId, MessageReader reader, ref bool canceled)
{
@@ -22,7 +76,10 @@ class BetterHostManager
PlayerControl target = reader.ReadNetObject<PlayerControl>();
if (target != null)
{
if (player.Data.Role is GuardianAngelRole && player.IsAlive() && !player.IsImpostorTeam())
if (player.Is(RoleTypes.GuardianAngel)
&& !player.IsAlive()
&& !player.IsImpostorTeam()
&& CheckRange(player.GetCustomPosition(), target.GetCustomPosition(), 3f))
{
if (target.IsAlive())
{
@@ -39,11 +96,26 @@ class BetterHostManager
case (byte)RpcCalls.CheckMurder:
{
PlayerControl target = reader.ReadNetObject<PlayerControl>();
if (target != null)
{
if (player.IsAlive() && player.IsImpostorTeam() && !player.inMovingPlat && !player.IsInVent() && !player.IsInVanish() && !player.shapeshifting && !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
if (player.IsAlive()
&& player.IsImpostorTeam()
&& !player.inMovingPlat
&& !player.IsInVent()
&& !player.IsInVanish()
&& !player.shapeshifting
&& !player.onLadder
&& !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation()
&& ExtendedPlayerControl.TimeSinceKill.TryGetValue(player, out var value) && value >= (float)GameOptionsManager.Instance.currentNormalGameOptions.KillCooldown
&& CheckRange(player.GetCustomPosition(), target.GetCustomPosition(), 3f))
{
if (target.IsAlive() && !target.IsImpostorTeam() && !target.inMovingPlat && !target.IsInVent() && !target.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
if (target.IsAlive()
&& !target.IsImpostorTeam()
&& !target.inMovingPlat
&& !target.IsInVent()
&& !target.onLadder
&& !target.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
{
player.RpcMurderPlayer(target, true);
break;
@@ -62,7 +134,13 @@ class BetterHostManager
if (target != null)
{
if (player.Data.RoleType == RoleTypes.Shapeshifter && player.IsAlive() && player.IsImpostorTeam() && !player.inMovingPlat && !player.shapeshifting && !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
if (player.Is(RoleTypes.Shapeshifter)
&& player.IsAlive()
&& player.IsImpostorTeam()
&& !player.inMovingPlat
&& !player.shapeshifting
&& !player.onLadder
&& !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
{
if (!target.IsInVent() && flag == false)
{
@@ -80,7 +158,13 @@ class BetterHostManager
case (byte)RpcCalls.CheckVanish:
{
if (player.Data.RoleType == RoleTypes.Phantom && player.IsAlive() && player.IsImpostorTeam() && !player.IsInVent() && !player.inMovingPlat && !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
if (player.Is(RoleTypes.Phantom)
&& player.IsAlive()
&& player.IsImpostorTeam()
&& !player.IsInVent()
&& !player.inMovingPlat
&& !player.onLadder
&& !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
{
if (AmongUsClient.Instance.AmClient)
@@ -100,7 +184,11 @@ class BetterHostManager
{
bool flag = reader.ReadBoolean();
if (player.Data.RoleType == RoleTypes.Phantom && player.IsAlive() && player.IsImpostorTeam() && !player.inMovingPlat && !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
if (player.Is(RoleTypes.Phantom)
&& player.IsAlive() && player.IsImpostorTeam()
&& !player.inMovingPlat
&& !player.onLadder
&& !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
{
if (!player.IsInVent() && flag == false)
{
@@ -159,6 +247,9 @@ class BetterHostManager
{
NewName = player.Data.PlayerName;
if (player.IsHost())
NewName = player.GetPlayerNameAndColor();
if (player.IsDev())
sbTopTag.Append("<color=#6e6e6e>(<color=#0088ff>Dev</color>)</color>+++");
+1 -1
View File
@@ -72,7 +72,7 @@ class BetterNotificationManager
BAUNotificationManagerObj.transform.position = AspectPosition.ComputeWorldPosition(localCamera, AspectPosition.EdgeAlignments.Bottom, new Vector3(-1.3f, 0.7f, localCamera.nearClipPlane + 0.1f));
showTime -= Time.deltaTime;
if (showTime <= 0f)
if (showTime <= 0f && GameStates.IsInGame)
{
BAUNotificationManagerObj.transform.Find("Sizer/ChatText (TMP)").GetComponent<TextMeshPro>().text = "";
BAUNotificationManagerObj.SetActive(false);
+200
View File
@@ -0,0 +1,200 @@
using Hazel;
using InnerNet;
using HarmonyLib;
using UnityEngine;
// Code from: https://github.com/0xDrMoe/TownofHost-Enhanced
namespace BetterAmongUs;
[HarmonyPatch(typeof(InnerNetClient))]
public class InnerNetClientPatch
{
[HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.SendInitialData))]
[HarmonyPrefix]
public static bool SendInitialDataPrefix(InnerNetClient __instance, int clientId)
{
if (!Constants.IsVersionModded() || __instance.NetworkMode != NetworkModes.OnlineGame) return true;
// We make sure other stuffs like playercontrol and Lobby behavior is spawned properly
// Then we spawn networked data for new clients
MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable);
messageWriter.StartMessage(6);
messageWriter.Write(__instance.GameId);
messageWriter.WritePacked(clientId);
Il2CppSystem.Collections.Generic.List<InnerNetObject> obj = __instance.allObjects;
lock (obj)
{
HashSet<GameObject> hashSet = new HashSet<GameObject>();
for (int i = 0; i < __instance.allObjects.Count; i++)
{
InnerNetObject innerNetObject = __instance.allObjects[i];
if (innerNetObject && (innerNetObject.OwnerId != -4 || __instance.AmModdedHost) && hashSet.Add(innerNetObject.gameObject))
{
GameManager gameManager = innerNetObject as GameManager;
if (gameManager != null)
{
__instance.SendGameManager(clientId, gameManager);
}
else
{
if (innerNetObject is not NetworkedPlayerInfo)
__instance.WriteSpawnMessage(innerNetObject, innerNetObject.OwnerId, innerNetObject.SpawnFlags, messageWriter);
}
}
}
messageWriter.EndMessage();
__instance.SendOrDisconnect(messageWriter);
messageWriter.Recycle();
}
DelaySpawnPlayerInfo(__instance, clientId);
return false;
}
private static void DelaySpawnPlayerInfo(InnerNetClient __instance, int clientId)
{
List<NetworkedPlayerInfo> players = GameData.Instance.AllPlayers.ToArray().ToList();
// We send 5 players at a time to prevent too huge packet
while (players.Count > 0)
{
var batch = players.Take(5).ToList();
MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable);
messageWriter.StartMessage(6);
messageWriter.Write(__instance.GameId);
messageWriter.WritePacked(clientId);
foreach (var player in batch)
{
if (messageWriter.Length > 1600) break;
if (player != null && player.ClientId != clientId && !player.Disconnected)
{
__instance.WriteSpawnMessage(player, player.OwnerId, player.SpawnFlags, messageWriter);
}
players.Remove(player);
}
messageWriter.EndMessage();
// Logger.Info($"send delayed network data to {clientId} , size is {messageWriter.Length}", "SendInitialDataPrefix");
__instance.SendOrDisconnect(messageWriter);
messageWriter.Recycle();
}
}
[HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.SendAllStreamedObjects))]
[HarmonyPrefix]
public static bool SendAllStreamedObjectsPrefix(InnerNetClient __instance, ref bool __result)
{
if (!Constants.IsVersionModded() || __instance.NetworkMode != NetworkModes.OnlineGame) return true;
// Bypass all NetworkedData here.
__result = false;
Il2CppSystem.Collections.Generic.List<InnerNetObject> obj = __instance.allObjects;
lock (obj)
{
for (int i = 0; i < __instance.allObjects.Count; i++)
{
InnerNetObject innerNetObject = __instance.allObjects[i];
if (innerNetObject && innerNetObject is not NetworkedPlayerInfo && innerNetObject.IsDirty && (innerNetObject.AmOwner || (innerNetObject.OwnerId == -2 && __instance.AmHost)))
{
MessageWriter messageWriter = __instance.Streams[(int)innerNetObject.sendMode];
messageWriter.StartMessage(1);
messageWriter.WritePacked(innerNetObject.NetId);
try
{
if (innerNetObject.Serialize(messageWriter, false))
{
messageWriter.EndMessage();
}
else
{
messageWriter.CancelMessage();
}
if (innerNetObject.Chunked && innerNetObject.IsDirty)
{
__result = true;
}
}
catch (Exception ex)
{
Logger.Error(ex.ToString());
messageWriter.CancelMessage();
}
}
}
}
for (int j = 0; j < __instance.Streams.Length; j++)
{
MessageWriter messageWriter2 = __instance.Streams[j];
if (messageWriter2.HasBytes(7))
{
messageWriter2.EndMessage();
__instance.SendOrDisconnect(messageWriter2);
messageWriter2.Clear((SendOption)j);
messageWriter2.StartMessage(5);
messageWriter2.Write(__instance.GameId);
}
}
return false;
}
private static byte timer = 0;
[HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.FixedUpdate))]
[HarmonyPostfix]
public static void FixedUpdatePostfix(InnerNetClient __instance)
{
// Send a networked data pre 2 fixed update should be a good practice?
if (!Constants.IsVersionModded() || __instance.NetworkMode != NetworkModes.OnlineGame) return;
if (!__instance.AmHost || __instance.Streams == null) return;
if (timer == 0)
{
timer = 1;
return;
}
var player = GameData.Instance.AllPlayers.ToArray().FirstOrDefault(x => x.IsDirty);
if (player != null)
{
timer = 0;
MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable);
messageWriter.StartMessage(5);
messageWriter.Write(__instance.GameId);
messageWriter.StartMessage(1);
messageWriter.WritePacked(player.NetId);
try
{
if (player.Serialize(messageWriter, false))
{
messageWriter.EndMessage();
}
else
{
messageWriter.CancelMessage();
player.ClearDirtyBits();
return;
}
messageWriter.EndMessage();
__instance.SendOrDisconnect(messageWriter);
messageWriter.Recycle();
}
catch (Exception ex)
{
Logger.Error(ex.ToString());
messageWriter.CancelMessage();
player.ClearDirtyBits();
}
}
}
}
[HarmonyPatch(typeof(GameData), nameof(GameData.DirtyAllData))]
internal class DirtyAllDataPatch
{
// Currently this function only occurs in CreatePlayer
// It's believed to lag host, delay the playercontrol spawn mesasge & blackout new client
// & send huge packets to all clients & completely no need to run
// Temporarily disable it until Innersloth get a better fix.
public static bool Prefix()
{
return false;
}
}
+58
View File
@@ -0,0 +1,58 @@
using Hazel;
using InnerNet;
namespace BetterAmongUs;
static class ExtendedInnerNetClient
{
/// <summary>
/// Starts the RPC desynchronization process for the given player, call ID, and send option.
/// </summary>
/// <param name="client">The InnerNetClient instance.</param>
/// <param name="playerNetId">The network ID of the player.</param>
/// <param name="callId">The RPC call ID.</param>
/// <param name="option">The send option for the RPC.</param>
/// <param name="ignoreClientId">The client ID to ignore. Default is -1, which means no client is ignored.</param>
/// <returns>A list of MessageWriter instances for the RPC calls.</returns>
/// <example>
/// <code>
/// List&lt;MessageWriter&gt; messageWriter = AmongUsClient.Instance.StartRpcDesync(PlayerNetId, (byte)RpcCalls, SendOption, ClientId);
/// messageWriter.ForEach(mW => mW.Write("RPC TEST"));
/// AmongUsClient.Instance.FinishRpcDesync(messageWriter);
/// </code>
/// </example>
/*
List<MessageWriter> messageWriter = AmongUsClient.Instance.StartRpcDesync(PlayerNetId, (byte)RpcCalls, SendOption, ClientId);
messageWriter.ForEach(mW => mW.Write("RPC TEST"));
AmongUsClient.Instance.FinishRpcDesync(messageWriter);
*/
public static List<MessageWriter> StartRpcDesync(this InnerNetClient client, uint playerNetId, byte callId, SendOption option, int ignoreClientId = -1)
{
List<MessageWriter> messageWriters = [];
if (ignoreClientId < 0)
{
messageWriters.Add(client.StartRpcImmediately(playerNetId, callId, option, -1));
}
else
{
foreach (var allClients in AmongUsClient.Instance.allClients.ToArray().Where(c => c.Id != ignoreClientId))
{
messageWriters.Add(client.StartRpcImmediately(playerNetId, callId, option, allClients.Id));
}
}
return messageWriters;
}
public static void FinishRpcDesync(this InnerNetClient client, List<MessageWriter> messageWriters)
{
foreach (var msg in messageWriters)
{
msg.EndMessage();
msg.EndMessage();
client.SendOrDisconnect(msg);
msg.Recycle();
}
}
}
+7
View File
@@ -1,12 +1,15 @@
using AmongUs.GameOptions;
using Hazel;
using InnerNet;
using TMPro;
using UnityEngine;
using static Il2CppSystem.Net.Http.Headers.Parser;
namespace BetterAmongUs;
static class ExtendedPlayerControl
{
public static Dictionary<PlayerControl, float> TimeSinceKill = [];
// Get players client
public static ClientData? GetClient(this PlayerControl player)
{
@@ -27,6 +30,8 @@ static class ExtendedPlayerControl
var client = player.GetClient();
return client == null ? -1 : client.Id;
}
// Get player name with outfit color
public static string GetPlayerNameAndColor(this PlayerControl player) => $"<color={Utils.Color32ToHex(Palette.PlayerColors[player.CurrentOutfit.ColorId])}>{player.Data.PlayerName}</color>";
// Set players over head text
public static void SetPlayerTextInfo(this PlayerControl player, string text, bool isBottom = false, bool isInfo = false)
{
@@ -150,6 +155,8 @@ static class ExtendedPlayerControl
return "#8cffff";
}
}
// Check if player is role type
public static bool Is(this PlayerControl player, RoleTypes role) => player?.Data?.RoleType == role;
// Check if player is on imposter team
public static bool IsImpostorTeam(this PlayerControl player) => player?.Data != null && (player.Data.RoleType is RoleTypes.Impostor or RoleTypes.ImpostorGhost or RoleTypes.Shapeshifter or RoleTypes.Phantom);
// Check if player is a imposter teammate
+1 -1
View File
@@ -16,7 +16,7 @@ static class ExtendedPlayerInfo
public static bool GetIsBetterHost(this PlayerControl player)
{
if (IsBetterHost.ContainsKey(player))
if (player.IsHost() && IsBetterHost.ContainsKey(player))
return IsBetterHost[player];
else
return false;
+5
View File
@@ -20,6 +20,11 @@ class FileChecker
{
if (Enabled == false) return;
if (GameStates.IsDev)
{
HasTrySpoofFriendCode = false;
}
GameObject PlayButton = GameObject.Find("Main Buttons/PlayButton");
// Disable play button
+5 -4
View File
@@ -1,4 +1,5 @@
using AmongUs.GameOptions;
using BetterAmongUs.Patches;
namespace BetterAmongUs;
@@ -7,7 +8,7 @@ namespace BetterAmongUs;
public static class GameStates
{
/**********Check Game Status***********/
public static bool IsDev => Main.DevUser.Contains(Utils.GetHashPuid(EOSManager.Instance.ProductUserId));
public static bool IsDev => EOSManager.Instance?.userId != null && Main.DevUser.Contains(Utils.GetHashPuid(EOSManager.Instance.userId.ToString()));
public static bool InGame => Main.AllPlayerControls.Any();
public static bool IsNormalGame => GameOptionsManager.Instance.CurrentGameOptions.GameMode is GameModes.Normal or GameModes.NormalFools;
public static bool IsHideNSeek => GameOptionsManager.Instance.CurrentGameOptions.GameMode is GameModes.HideNSeek or GameModes.SeekFools;
@@ -20,7 +21,7 @@ public static class GameStates
public static bool IsInGame => InGame;
public static bool IsLobby => AmongUsClient.Instance?.GameState == InnerNet.InnerNetClient.GameStates.Joined;
public static bool IsInIntro => IntroCutscene.Instance != null;
public static bool IsInGamePlay => (InGame && !IsLobby && !IsInIntro) || IsFreePlay;
public static bool IsInGamePlay => (InGame && IsShip && !IsLobby && !IsInIntro) || IsFreePlay;
public static bool IsEnded => AmongUsClient.Instance?.GameState == InnerNet.InnerNetClient.GameStates.Ended;
public static bool IsNotJoined => AmongUsClient.Instance?.GameState == InnerNet.InnerNetClient.GameStates.NotJoined;
public static bool IsOnlineGame => AmongUsClient.Instance?.NetworkMode == NetworkModes.OnlineGame;
@@ -42,9 +43,9 @@ public static class GameStates
public static bool IsProceeding => IsMeeting && MeetingHud.Instance?.state is MeetingHud.VoteStates.Proceeding;
public static bool IsExilling => ExileController.Instance != null && !(AirshipIsActive && Minigame.Instance != null && Minigame.Instance.isActiveAndEnabled);
public static bool IsCountDown => GameStartManager.InstanceExists && GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown;
/**********TOP ZOOM.cs***********/
public static bool IsShip => ShipStatus.Instance != null;
public static bool IsHost => AmongUsClient.Instance.AmHost;
public static bool IsHost => AmongUsClient.Instance != null && AmongUsClient.Instance.AmHost;
public static bool IsBetterHostLobby => Main.BetterHost.Value || Main.AllPlayerControls.Any(pc => pc.GetIsBetterHost());
public static bool IsCanMove => PlayerControl.LocalPlayer?.CanMove is true;
public static bool IsDead => PlayerControl.LocalPlayer?.Data?.IsDead is true;
}
+48 -30
View File
@@ -41,14 +41,16 @@ internal class RPCHandlerPatch
Logger.LogCheat($"RPC canceled by Host: {Enum.GetName((RpcCalls)callId)}{Enum.GetName((CustomRPC)callId)} - {callId}");
}
return false;
}
}
AntiCheat.CheckRPC(__instance, callId, reader);
RPC.HandleRPC(__instance, callId, reader);
return true;
}
public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader)
{
AntiCheat.CheckRPC(__instance, callId, reader);
RPC.HandleRPC(__instance, callId, reader);
{
RPC.HandleCustomRPC(__instance, callId, reader);
}
}
@@ -77,15 +79,7 @@ internal static class RPC
player.Exiled();
}
public static async Task WaitForChatCooldown()
{
while (3f - HudManager.Instance.Chat.timeSinceLastMessage > 0f)
{
await Task.Delay(100);
}
}
public static async void SendHostChatToPlayer(PlayerControl player, string text, string? title = "", bool sendToBetterUser = true)
public static void SendHostChatToPlayer(PlayerControl player, string text, string? title = "", bool sendToBetterUser = true)
{
if (!GameStates.IsHost) return;
@@ -102,10 +96,7 @@ internal static class RPC
return;
}
return;
await WaitForChatCooldown();
/*
PlayerControl asPlayer = Main.AllPlayerControls.Where(pc => pc.IsAlive()).OrderBy(pc => pc == PlayerControl.LocalPlayer ? 0 : 1).First();
var oldName = asPlayer.CurrentOutfit.PlayerName;
@@ -121,46 +112,73 @@ internal static class RPC
messageWriter.Write(text);
AmongUsClient.Instance.FinishRpcImmediately(messageWriter);
MessageWriter writer2 = AmongUsClient.Instance.StartRpcImmediately(asPlayer.NetId, (byte)RpcCalls.SetName, SendOption.None, player.GetClientId());
writer2.Write(asPlayer.Data.NetId);
writer2.Write(oldName);
AmongUsClient.Instance.FinishRpcImmediately(writer2);
_ = new LateTask(() =>
{
MessageWriter writer2 = AmongUsClient.Instance.StartRpcImmediately(asPlayer.NetId, (byte)RpcCalls.SetName, SendOption.None, player.GetClientId());
writer2.Write(asPlayer.Data.NetId);
writer2.Write(oldName);
AmongUsClient.Instance.FinishRpcImmediately(writer2);
SyncAllNames();
SyncAllNames(force: true);
}, 0.08f, shoudLog: false);
*/
}
public static void HandleRPC(PlayerControl player, byte callId, MessageReader reader)
public static void HandleCustomRPC(PlayerControl player, byte callId, MessageReader oldReader)
{
if (PlayerControl.LocalPlayer == null || player == null || player == PlayerControl.LocalPlayer || player.Data == null) return;
if (!Enum.IsDefined(typeof(CustomRPC), (int)unchecked(callId))) return;
MessageReader reader = MessageReader.Get(oldReader);
switch (callId)
{
case (byte)CustomRPC.BetterCheck:
if (reader.ReadByte() == player.Data.NetId)
{
var IsBetterHost = reader.ReadBoolean();
if (!player.IsHost() && IsBetterHost)
{
BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName((RpcCalls)callId)} called as BetterHost");
break;
}
player.SetIsBetterUser(true);
player.SetIsBetterHost(reader.ReadBoolean());
player.SetIsBetterHost(IsBetterHost);
}
break;
case (byte)CustomRPC.AddChat:
Utils.AddChatPrivate(reader.ReadString(), reader.ReadString());
break;
case (byte)CustomRPC.VersionCheck:
case (byte)CustomRPC.VersionCheck or (byte)CustomRPC.RequestRetryVersionCheck:
if (player.IsHost())
{
var BAU = "<color=#278720>♻</color><color=#0ed400><b>BetterAmongUs</b></color><color=#278720>♻</color>";
Utils.DisconnectSelf($"{BAU} does not support <color=#ff9cdc><b>TOHE</b></color>");
}
break;
}
}
public static void HandleRPC(PlayerControl player, byte callId, MessageReader oldReader)
{
if (PlayerControl.LocalPlayer == null || player == null || player == PlayerControl.LocalPlayer || player.Data == null) return;
MessageReader reader = MessageReader.Get(oldReader);
switch (callId)
{
case (byte)RpcCalls.SendChat:
var text = reader.ReadString();
if (player.IsHost() && player != PlayerControl.LocalPlayer)
{
if (reader.BytesRemaining > 0)
if (text.ToLower() == "/allow")
{
if (reader.ReadString().ToLower() == "/allow")
{
CommandsPatch.Permission = player;
}
CommandsPatch.Permission = player;
BetterNotificationManager.Notify($"{player.GetPlayerNameAndColor()} has granted permission!");
}
}
break;
+3 -3
View File
@@ -1,4 +1,5 @@
using HarmonyLib;
using AmongUs.GameOptions;
using HarmonyLib;
using UnityEngine;
namespace BetterAmongUs;
@@ -11,8 +12,7 @@ public static class Zoom
public static void Postfix()
{
if ((GameStates.IsShip && !GameStates.IsMeeting && GameStates.IsCanMove && PlayerControl.LocalPlayer.Data.IsDead) ||
(GameStates.IsLobby && GameStates.IsCanMove))
if (GameStates.IsCanMove && !PlayerControl.LocalPlayer.Is(RoleTypes.GuardianAngel) && (!GameStates.IsInGamePlay || !PlayerControl.LocalPlayer.IsAlive()))
{
if (Camera.main.orthographicSize > 3.0f)
resetButtons = true;
+48 -1
View File
@@ -1,6 +1,9 @@
using AmongUs.Data;
using Assets.CoreScripts;
using HarmonyLib;
using Hazel;
using System.Text;
using System.Text.RegularExpressions;
using TMPro;
using UnityEngine;
@@ -13,6 +16,39 @@ class ChatPatch
public static List<string> ChatHistory = [];
public static int CurrentHistorySelection = -1;
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.RpcSendChat))]
class RpcSendChatPatch
{
public static bool Prefix(PlayerControl __instance, string chatText, ref bool __result)
{
if (string.IsNullOrWhiteSpace(chatText))
{
__result = false;
return false;
}
if (!GameStates.IsBetterHostLobby)
{
__result = false;
return true;
}
chatText = Regex.Replace(chatText, "<.*?>", string.Empty);
if (AmongUsClient.Instance.AmClient && DestroyableSingleton<HudManager>.Instance)
{
DestroyableSingleton<HudManager>.Instance.Chat.AddChat(__instance, chatText, true);
}
if (chatText.IndexOf("who", StringComparison.OrdinalIgnoreCase) >= 0)
{
DestroyableSingleton<UnityTelemetry>.Instance.SendWho();
}
chatText = "\n" + chatText;
MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(__instance.NetId, 13, SendOption.Reliable);
messageWriter.Write(chatText);
messageWriter.EndMessage();
__result = true;
return false;
}
}
[HarmonyPatch(typeof(ChatController))]
class ChatControllerPatch
{
@@ -24,8 +60,16 @@ class ChatPatch
{
GameObject chatItem = __instance.scroller.Inner.transform.GetChild(i).gameObject;
chatItem.transform.Find("Background").GetComponent<SpriteRenderer>().color = new Color(0.05f, 0.05f, 0.05f, 1f);
chatItem.transform.Find("ChatText (TMP)").GetComponent<TextMeshPro>().color = new Color(1f, 1f, 1f, 1f);
chatItem.transform.Find("Background").GetComponent<SpriteRenderer>().color = new Color(0.05f, 0.05f, 0.05f, 1f);
if (chatItem.transform.Find("PoolablePlayer/xMark") != null)
{
if (chatItem.transform.Find("PoolablePlayer/xMark").GetComponent<SpriteRenderer>().enabled == true)
{
chatItem.transform.Find("Background").GetComponent<SpriteRenderer>().color = new Color(0.05f, 0.05f, 0.05f, 0.5f);
}
}
}
// Free chat color
@@ -37,6 +81,9 @@ class ChatPatch
__instance.quickChatField.background.color = new Color32(40, 40, 40, byte.MaxValue);
__instance.quickChatField.text.color = Color.white;
__instance.quickChatButton.transform.Find("QuickChatIcon").GetComponent<SpriteRenderer>().color = new Color(0.5f, 0.5f, 0.5f, 1f);
__instance.openKeyboardButton.transform.Find("OpenKeyboardIcon").GetComponent<SpriteRenderer>().color = new Color(0.5f, 0.5f, 0.5f, 1f);
if ((Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) && Input.GetKeyDown(KeyCode.X))
{
ClipboardHelper.PutClipboardString(__instance.freeChatField.textArea.text);
+11 -3
View File
@@ -22,9 +22,17 @@ public static class OptionsMenuBehaviourPatch
[HarmonyPrefix]
public static void Start_Postfix(OptionsMenuBehaviour __instance)
{
static bool toggleCheckInGame(string buttonName)
static bool toggleCheckInGamePlay(string buttonName)
{
bool flag = GameStates.IsInGame && !GameStates.IsLobby || GameStates.IsFreePlay;
if (flag)
BetterNotificationManager.Notify($"Unable to toggle {buttonName} while in gameplay!", 2.5f);
return flag;
}
static bool toggleCheckInGame(string buttonName)
{
bool flag = GameStates.IsInGame;
if (flag)
BetterNotificationManager.Notify($"Unable to toggle {buttonName} while in game!", 2.5f);
@@ -40,7 +48,7 @@ public static class OptionsMenuBehaviourPatch
if (BetterHost == null || BetterHost.ToggleButton == null)
{
BetterHost = ClientOptionItem.Create("<color=#4f92ff>Better Host</color>", Main.BetterHost, __instance, BetterHostButtonToggle, () => !toggleCheckInGame("<color=#4f92ff>Better Host</color>"));
BetterHost = ClientOptionItem.Create("<color=#4f92ff>Better Host</color>", Main.BetterHost, __instance, BetterHostButtonToggle, () => !toggleCheckInGamePlay("<color=#4f92ff>Better Host</color>"));
static void BetterHostButtonToggle()
{
var flag = GameStates.IsHost && Main.BetterHost.Value;
@@ -55,7 +63,7 @@ public static class OptionsMenuBehaviourPatch
if (BetterRoleAlgorithma == null || BetterRoleAlgorithma.ToggleButton == null)
{
BetterRoleAlgorithma = ClientOptionItem.Create("<color=#4f92ff>Better Role Algorithma</color>", Main.BetterRoleAlgorithma, __instance, toggleCheck: () => !toggleCheckInGame("<color=#4f92ff>Better Role Algorithma</color>"));
BetterRoleAlgorithma = ClientOptionItem.Create("<color=#4f92ff>Better Role Algorithma</color>", Main.BetterRoleAlgorithma, __instance, toggleCheck: () => !toggleCheckInGamePlay("<color=#4f92ff>Better Role Algorithma</color>"));
}
if (LobbyPlayerInfo == null || LobbyPlayerInfo.ToggleButton == null)
+13 -11
View File
@@ -125,7 +125,7 @@ class CommandsPatch
{
Directory.CreateDirectory(logFolderPath);
}
string logFileName = "log-" + DateTime.Now.ToString("yyyy.MM.dd-HH.mm.ss") + ".log";
string logFileName = "log-" + Main.GetVersionText().Replace(' ', '-').ToLower() + "-" + DateTime.Now.ToString("yyyy.MM.dd-HH.mm.ss") + ".log";
string newLogFilePath = Path.Combine(logFolderPath, logFileName);
File.WriteAllText(newLogFilePath, newLog);
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo()
@@ -140,6 +140,8 @@ class CommandsPatch
UseShellExecute = true,
Verb = "open"
});
Utils.AddChatPrivate($"Dump logs at <color=#b1b1b1>'{newLogFilePath}'</color>");
break;
case "player":
if (HandlePlayerArgument(command, subArgs) == true)
@@ -150,10 +152,10 @@ class CommandsPatch
var format2 = "├ •";
var format3 = "└ •";
sb.Append($"<size=150%><color={hexColor}><b>{player?.Data?.PlayerName}</color> Info:</b></size>\n");
sb.Append($"{format1} <color=#525252>ID: {player?.Data?.PlayerId}</color>\n");
sb.Append($"{format2} <color=#525252>HashPUID: {Utils.GetHashPuid($"{player?.Data?.Puid}")}</color>\n");
sb.Append($"{format2} <color=#525252>Platform: {Utils.GetPlatformName(player)}</color>\n");
sb.Append($"{format3} <color=#525252>FriendCode: {player?.Data?.FriendCode}</color>");
sb.Append($"{format1} <color=#c1c1c1>ID: {player?.Data?.PlayerId}</color>\n");
sb.Append($"{format2} <color=#c1c1c1>HashPUID: {Utils.GetHashPuid($"{player?.Data?.Puid}")}</color>\n");
sb.Append($"{format2} <color=#c1c1c1>Platform: {Utils.GetPlatformName(player)}</color>\n");
sb.Append($"{format3} <color=#c1c1c1>FriendCode: {player?.Data?.FriendCode}</color>");
Utils.AddChatPrivate(sb.ToString());
}
break;
@@ -162,10 +164,10 @@ class CommandsPatch
{
var hexColor = Utils.Color32ToHex(Palette.PlayerColors[player.CurrentOutfit.ColorId]);
sb.Append($"<color={hexColor}><b>{player?.Data?.PlayerName}</color> Info:</b>\n");
sb.Append($"<color=#525252>{player?.Data?.PlayerId}</color> - ");
sb.Append($"<color=#525252>{Utils.GetHashPuid($"{player?.Data?.Puid}")}</color> - ");
sb.Append($"<color=#525252>{Utils.GetPlatformName(player)}</color> - ");
sb.Append($"<color=#525252>{player?.Data?.FriendCode}</color>");
sb.Append($"<color=#c1c1c1>{player?.Data?.PlayerId}</color> - ");
sb.Append($"<color=#c1c1c1>{Utils.GetHashPuid($"{player?.Data?.Puid}")}</color> - ");
sb.Append($"<color=#c1c1c1>{Utils.GetPlatformName(player)}</color> - ");
sb.Append($"<color=#c1c1c1>{player?.Data?.FriendCode}</color>");
sb.Append("\n\n");
}
Utils.AddChatPrivate(sb.ToString());
@@ -176,12 +178,11 @@ class CommandsPatch
if (UseCommandInGame() == true)
{
var player = cmdTarget;
var hexColor = Utils.Color32ToHex(Palette.PlayerColors[player.CurrentOutfit.ColorId]);
MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)RpcCalls.SendChat, SendOption.None, player.GetClientId());
messageWriter.Write(string.Join(" ", command[2..].ToArray()));
AmongUsClient.Instance.FinishRpcImmediately(messageWriter);
Utils.AddChatPrivate($"{string.Join(" ", command[2..].ToArray())}", overrideName: $"<color=#696969>Sent Private Message to</color> <color={hexColor}><b>{player.Data.PlayerName}</b></color>");
Utils.AddChatPrivate($"{string.Join(" ", command[2..].ToArray())}", overrideName: $"<color=#696969>Sent Private Message to</color> <b>{player.GetPlayerNameAndColor()}</b>");
}
}
break;
@@ -373,6 +374,7 @@ class CommandsPatch
if (HandleIsHost(command) == true)
{
RPC.SyncAllNames(force: true);
Utils.AddChatPrivate("<color=#0dff00>All player names have been updated and synced!</color>");
}
break;
default:
+15 -3
View File
@@ -10,7 +10,7 @@ class GamePlayManager
{
[HarmonyPatch(nameof(LobbyBehaviour.OnDestroy))]
[HarmonyPrefix]
private static void Prefix(/*LobbyBehaviour __instance*/)
private static void OnDestroy_Prefix(/*LobbyBehaviour __instance*/)
{
if (GameStates.IsInGame)
{
@@ -19,7 +19,7 @@ class GamePlayManager
}
[HarmonyPatch(nameof(LobbyBehaviour.Start))]
[HarmonyPostfix]
private static void Postfix(/*LobbyBehaviour __instance*/)
private static void Start_Postfix(/*LobbyBehaviour __instance*/)
{
_ = new LateTask(() =>
{
@@ -29,6 +29,15 @@ class GamePlayManager
}
}, 1.5f, "LobbyBehaviourPatch SyncAllNames");
}
// Disabled annoying music
[HarmonyPatch(nameof(LobbyBehaviour.Update))]
[HarmonyPostfix]
public static void Update_Postfix(/*LobbyBehaviour __instance*/)
{
if (Main.DisableLobbyTheme.Value)
SoundManager.instance.StopSound(LobbyBehaviour.Instance.MapTheme);
}
}
[HarmonyPatch(typeof(GameManager))]
@@ -55,7 +64,10 @@ class GamePlayManager
[HarmonyPrefix]
private static void Prefix(GameStartManager __instance)
{
__instance.MinPlayers = 1;
if (GameStates.IsDev)
{
__instance.MinPlayers = 1;
}
}
}
}
-19
View File
@@ -1,19 +0,0 @@
using HarmonyLib;
namespace BetterAmongUs.Patches;
public class LobbyPatch
{
[HarmonyPatch(typeof(LobbyBehaviour))]
internal class LobbyBehaviourPatch
{
// Disabled annoying music
[HarmonyPatch(nameof(LobbyBehaviour.Update))]
[HarmonyPostfix]
public static void Postfix(PingTracker __instance)
{
if (Main.DisableLobbyTheme.Value)
SoundManager.instance.StopSound(LobbyBehaviour.Instance.MapTheme);
}
}
}
+1
View File
@@ -15,6 +15,7 @@ public class ModManagerPatch
if (__instance.ModStamp.gameObject.active == true)
__instance.ModStamp.GetComponent<SpriteRenderer>().sprite = Utils.LoadSprite("BetterAmongUs.Resources.Images.BetterAmongUs-Mod.png", 250f);
AntiCheat.Update();
FileChecker.UpdateUnauthorizedFiles();
LateTask.Update(Time.deltaTime);
BetterNotificationManager.Update();
+1 -2
View File
@@ -40,8 +40,7 @@ public class PingTrackerPatch
// Add Host Info if not in lobby
if (GameStates.IsInGamePlay && Host != null)
{
string hostColor = Utils.Color32ToHex(Palette.PlayerColors[Host.CurrentOutfit.ColorId]);
sb.AppendFormat("<size=75%>Host: <color={0}>{1}</color></size>\n", hostColor, Host.CurrentOutfit.PlayerName);
sb.AppendFormat("<size=75%>Host: {0}</size>\n", Host.GetPlayerNameAndColor());
}
__instance.aspectPosition.DistanceFromEdge = new Vector3(4f, 0.1f, -5);
+9 -7
View File
@@ -14,8 +14,8 @@ class PlayerControlPatch
{
public static float infotime = 0f;
[HarmonyPatch(nameof(PlayerControl.FixedUpdate))]
[HarmonyPostfix]
public static void FixedUpdate_Postfix(PlayerControl __instance)
[HarmonyPrefix]
public static void FixedUpdate_Prefix(PlayerControl __instance)
{
// Set up player text info
var NameText = GameObject.Find($"{__instance.gameObject.transform.name}/Names/NameText_TMP");
@@ -59,11 +59,13 @@ class PlayerControlPatch
if (infotime <= 0)
{
SetPlayerInfo(__instance);
infotime = 0.4f;
infotime = 0.6f;
}
if (GameStates.IsInGame && GameStates.IsHost)
RPC.SyncAllNames(isBetterHost: false);
{
BetterHostManager.Update(__instance);
}
}
public static void SetPlayerInfo(PlayerControl player)
@@ -144,8 +146,7 @@ class PlayerControlPatch
{
if (Main.LobbyPlayerInfo.Value == true)
{
string hexColor = Utils.Color32ToHex(Palette.PlayerColors[Host.CurrentOutfit.ColorId]);
NewName = $"<color={hexColor}>{player.Data.PlayerName}</color>";
NewName = player.GetPlayerNameAndColor();
}
}
if (player.IsImpostorTeammate() && player != PlayerControl.LocalPlayer)
@@ -185,7 +186,7 @@ class PlayerControlPatch
}
}
if (!GameStates.IsInGamePlay)
if (GameStates.IsLobby)
{
if (Main.LobbyPlayerInfo.Value == true)
{
@@ -226,6 +227,7 @@ class PlayerControlPatch
if (PlayerControl.LocalPlayer.IsImpostorTeam() && GameStates.IsInGamePlay && !GameStates.IsHideNSeek && HudManager.Instance.CrewmatesKilled.isActiveAndEnabled)
HudManager.Instance?.NotifyOfDeath();
ExtendedPlayerControl.TimeSinceKill[__instance] = 0f;
Logger.LogPrivate($"{__instance.Data.PlayerName} Has killed {target.Data.PlayerName} as {Utils.GetRoleName(__instance.Data.RoleType)}", "EventLog");
}
+1 -1
View File
@@ -65,7 +65,7 @@ public static class OnPlayerJoinedPatch
if (Main.BetterHost.Value)
client.Character.RpcSendHostChat(HudManagerPatch.WelcomeMessage, sendToBetterUser: false);
}
}, 1.5f, "OnPlayerJoinedPatch", false);
}, 2.5f, "OnPlayerJoinedPatch", false);
}
}
[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.OnPlayerLeft))]
+38
View File
@@ -0,0 +1,38 @@
using HarmonyLib;
namespace BetterAmongUs.Patches;
[HarmonyPatch(typeof(Constants), nameof(Constants.GetBroadcastVersion))]
class ServerUpdatePatch
{
static void Postfix(ref int __result)
{
var region = ServerManager.Instance.CurrentRegion.Name;
if (GameStates.IsLocalGame)
{
}
if (GameStates.IsOnlineGame)
{
if (region.Contains("MNA") || region.Contains("MEU") || region.Contains("MAS"))
{
__result += 25;
}
}
}
}
[HarmonyPatch(typeof(Constants), nameof(Constants.IsVersionModded))]
public static class IsVersionModdedPatch
{
public static bool Prefix(ref bool __result)
{
var region = ServerManager.Instance.CurrentRegion.Name;
if (region.Contains("MNA") || region.Contains("MEU") || region.Contains("MAS"))
{
__result = true;
return false;
}
return true;
}
}
+3 -2
View File
@@ -2,6 +2,7 @@
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BetterAmongUs.Patches;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Innersloth.IO;
@@ -21,12 +22,12 @@ public enum ReleaseTypes : int
public class Main : BasePlugin
{
public const ReleaseTypes ReleaseBuildType = ReleaseTypes.Canary;
public const string CanaryNum = "4";
public const string CanaryNum = "5";
public const string HotfixNum = "0";
public const bool IsHotFix = false;
public const string PluginGuid = "com.d1gq.betteramongus";
public const string PluginVersion = "1.0.0";
public const string ReleaseDate = "07.29.2024"; // dd/mm/yyyy
public const string ReleaseDate = "08.01.2024"; // mm/dd/yyyy
public const string Github = "https://github.com/D1GQ/BetterAmongUs";
public const string Discord = "https://discord.gg/";