Merge pull request #26 from D1GQ/dev

v1.1.0
This commit is contained in:
D1GQ authored and GitHub committed 2024-08-24 09:33:59 -05:00
commit 165b1e7dfb
34 files changed
+1495 -117

No files matched your search

+15 -29
View File
@@ -1,10 +1,8 @@
using AmongUs.GameOptions;
using BetterAmongUs.Patches;
using HarmonyLib;
using Hazel;
using InnerNet;
using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.Rendering;
namespace BetterAmongUs;
@@ -27,15 +25,15 @@ class AntiCheat
if (SickoData.ContainsKey(hashPuid))
{
player.Kick(true, $"banned by <color=#4f92ff>Anti-Cheat</color>!\n Reason: <color=#00f583>Known Sicko Menu User</color>", true);
player.Kick(true, "{0} by <color=#4f92ff>Anti-Cheat</color>!\n Reason: <color=#00f583>Known Sicko Menu User</color>", true);
}
else if (AUMData.ContainsKey(hashPuid))
{
player.Kick(true, $"banned by <color=#4f92ff>Anti-Cheat</color>!\n Reason: <color=#4f0000>Known AUM User</color>", true);
player.Kick(true, "{0} by <color=#4f92ff>Anti-Cheat</color>!\n Reason: <color=#4f0000>Known AUM User</color>", true);
}
else if (PlayerData.ContainsKey(hashPuid))
{
player.Kick(true, $"banned by <color=#4f92ff>Anti-Cheat</color>!\n Reason: <color=#fc0000>Known Cheater</color>", true);
player.Kick(true, "{0} by <color=#4f92ff>Anti-Cheat</color>!\n Reason: <color=#fc0000>Known Cheater</color>", true);
}
}
}
@@ -104,7 +102,7 @@ class AntiCheat
if (player == PlayerControl.LocalPlayer || PlayerControl.LocalPlayer == null || player == null || !IsEnabled) return;
if (callId is unchecked((byte)CustomRPC.Sicko) && Main.AntiCheat.Value)
if (callId is unchecked((byte)CustomRPC.Sicko) && Main.AntiCheat.Value && BetterGameSettings.DetectCheatClients.GetBool())
{
if (reader.BytesRemaining == 0)
{
@@ -122,7 +120,7 @@ class AntiCheat
return;
}
if (callId is unchecked((byte)CustomRPC.AUM) && Main.AntiCheat.Value)
if (callId is unchecked((byte)CustomRPC.AUM) && Main.AntiCheat.Value && BetterGameSettings.DetectCheatClients.GetBool())
{
try
{
@@ -158,7 +156,7 @@ class AntiCheat
PlayerControl AUMPlayer = Main.AllPlayerControls.First(pc => pc.Data.PlayerName == nameString && pc.CurrentOutfit.ColorId == colorId);
if (AUMPlayer == null || !Main.AntiCheat.Value) return;
if (AUMPlayer == null || !Main.AntiCheat.Value || !BetterGameSettings.DetectCheatClients.GetBool()) return;
var flag = string.IsNullOrEmpty(nameString) && string.IsNullOrEmpty(msgString);
var flag2 = AUMData.ContainsKey(Utils.GetHashPuid(AUMPlayer));
@@ -185,7 +183,7 @@ class AntiCheat
MessageReader reader = MessageReader.Get(Oldreader);
if (PlayerControl.LocalPlayer == null || player == null || player == PlayerControl.LocalPlayer || player.BetterData().IsBetterHost || reader == null || !IsEnabled || !Main.AntiCheat.Value
|| GameStates.IsBetterHostLobby && !GameStates.IsHost) return;
|| (GameStates.IsBetterHostLobby && !GameStates.IsHost) || !BetterGameSettings.DetectInvalidRPCs.GetBool()) return;
RoleTypes? Role = player?.Data?.RoleType;
Role ??= RoleTypes.Crewmate;
@@ -230,14 +228,6 @@ class AntiCheat
{
PlayerControl target = reader.ReadNetObject<PlayerControl>();
if (GameStates.IsHost)
{
BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName((RpcCalls)callId)}");
Logger.LogCheat($"{player.BetterData().RealName} {Enum.GetName((RpcCalls)callId)}: {GameStates.IsHost}");
return;
}
if (target != null)
{
if (!player.IsImpostorTeam() || !player.IsAlive() || player.IsInVanish() || target.IsImpostorTeam())
@@ -257,7 +247,7 @@ class AntiCheat
if (reader.BytesRemaining > 0)
{
uint level = reader.ReadPackedUInt32();
if (level >= 200)
if (level >= BetterGameSettings.DetectedLevelAbove.GetInt())
{
BetterNotificationManager.NotifyCheat(player, $"Invalid Level: {level}");
Logger.LogCheat($"{player.BetterData().RealName} {Enum.GetName((RpcCalls)callId)}: {level >= 200}");
@@ -332,12 +322,6 @@ class AntiCheat
// Check game states when sabotaging
public static bool RpcUpdateSystemCheck(PlayerControl player, SystemTypes systemType, byte amount)
{
if (!GameStates.IsHost || PlayerControl.LocalPlayer == null || player == null || player == PlayerControl.LocalPlayer || player.BetterData().IsBetterHost || !IsEnabled || !Main.AntiCheat.Value
|| GameStates.IsBetterHostLobby && !GameStates.IsHost) return true;
// Needs fixing!
return true;
byte hostNum = 128; // Only host should ever send this number
byte singleFixNum = 0;
byte minLightNum = 0;
@@ -368,9 +352,11 @@ class AntiCheat
}
}
if (!GameStates.IsHost || PlayerControl.LocalPlayer == null || player == null || player == PlayerControl.LocalPlayer
|| player.BetterData().IsBetterHost || !IsEnabled || !Main.AntiCheat.Value
|| GameStates.IsBetterHostLobby && !GameStates.IsHost) return true;
if (!GameStates.IsHost || PlayerControl.LocalPlayer == null || player == null || player == PlayerControl.LocalPlayer || player.BetterData().IsBetterHost || !IsEnabled || !Main.AntiCheat.Value
|| (GameStates.IsBetterHostLobby && !GameStates.IsHost) || !BetterGameSettings.DetectInvalidRPCs.GetBool()) return true;
if (!BetterGameSettings.ExperimentalDetectInvalidSabotage.GetBool())
return true;
// Single Fix: 0
// Lights: 0-1-2-3-4
@@ -507,7 +493,7 @@ class AntiCheat
}
}
if (!IsEnabled || !Main.AntiCheat.Value || GameStates.IsBetterHostLobby && !GameStates.IsHost) return true;
if (!IsEnabled || !Main.AntiCheat.Value || (GameStates.IsBetterHostLobby && !GameStates.IsHost) || !BetterGameSettings.DetectInvalidRPCs.GetBool()) return true;
RoleTypes Role = player.Data.RoleType;
bool IsImpostor = player.IsImpostorTeam();
+89 -2
View File
@@ -1,4 +1,5 @@
using System.Text.Json;
using BetterAmongUs.Patches;
using System.Text.Json;
namespace BetterAmongUs;
@@ -7,6 +8,8 @@ class BetterDataManager
private static string filePath = GetFilePath("BetterData");
public static string filePathFolder = Path.Combine(Main.GetGamePathToAmongUs(), $"Better_Data");
public static string filePathFolderSaveInfo = Path.Combine(filePathFolder, $"SaveInfo");
public static string filePathFolderSettings = Path.Combine(filePathFolder, $"Settings");
public static string SettingsFile = Path.Combine(filePathFolderSettings, "Preset.json");
public static string banPlayerListFile = Path.Combine(filePathFolderSaveInfo, "BanPlayerList.txt");
public static string banNameListFile = Path.Combine(filePathFolderSaveInfo, "BanNameList.txt");
public static string banWordListFile = Path.Combine(filePathFolderSaveInfo, "BanWordList.txt");
@@ -23,6 +26,11 @@ class BetterDataManager
Directory.CreateDirectory(filePathFolder);
}
if (!Directory.Exists(filePathFolderSettings))
{
Directory.CreateDirectory(filePathFolderSettings);
}
if (!Directory.Exists(filePathFolderSaveInfo))
{
Directory.CreateDirectory(filePathFolderSaveInfo);
@@ -43,6 +51,15 @@ class BetterDataManager
File.WriteAllText(banWordListFile, "// Example\nStart");
}
if (!File.Exists(SettingsFile))
{
var initialData = new Dictionary<string, string>();
string json = JsonSerializer.Serialize(initialData, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(SettingsFile, json);
}
GameSettingMenuPatch.SetupSettings(true);
if (!File.Exists(filePath))
{
// Initialize with predefined categories
@@ -127,6 +144,77 @@ class BetterDataManager
return string.Empty;
}
public static void SaveSetting(int id, string input)
{
string filePath = SettingsFile;
string json = File.ReadAllText(filePath);
var jsonData = JsonSerializer.Deserialize<Dictionary<string, string>>(json) ?? new Dictionary<string, string>();
jsonData[id.ToString()] = input;
json = JsonSerializer.Serialize(jsonData, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(filePath, json);
}
public static bool CanLoadSetting(int id)
{
string filePath = SettingsFile;
string json = File.ReadAllText(filePath);
var jsonData = JsonSerializer.Deserialize<Dictionary<string, string>>(json) ?? new Dictionary<string, string>();
if (jsonData.ContainsKey(id.ToString()))
{
if (!string.IsNullOrEmpty(jsonData[id.ToString()]))
{
return true;
}
}
return false;
}
public static bool LoadBoolSetting(int id)
{
string filePath = SettingsFile;
string json = File.ReadAllText(filePath);
var jsonData = JsonSerializer.Deserialize<Dictionary<string, string>>(json) ?? new Dictionary<string, string>();
if (jsonData.ContainsKey(id.ToString()))
{
return bool.Parse(jsonData[id.ToString()]);
}
return false;
}
public static float LoadFloatSetting(int id)
{
string filePath = SettingsFile;
string json = File.ReadAllText(filePath);
var jsonData = JsonSerializer.Deserialize<Dictionary<string, string>>(json) ?? new Dictionary<string, string>();
if (jsonData.ContainsKey(id.ToString()))
{
return float.Parse(jsonData[id.ToString()]);
}
return -1f;
}
public static int LoadIntSetting(int id)
{
string filePath = SettingsFile;
string json = File.ReadAllText(filePath);
var jsonData = JsonSerializer.Deserialize<Dictionary<string, string>>(json) ?? new Dictionary<string, string>();
if (jsonData.ContainsKey(id.ToString()))
{
return int.Parse(jsonData[id.ToString()]);
}
return -1;
}
public static void SaveBanList(string friendCode = "", string hashPUID = "")
{
if (!string.IsNullOrEmpty(friendCode) || !string.IsNullOrEmpty(hashPUID))
@@ -157,7 +245,6 @@ class BetterDataManager
}
}
public static void SaveCheatData(string puid, string friendCode, string name, string category = "cheatData", string reason = "None")
{
string filePath = GetFilePath("BetterData");
+2 -2
View File
@@ -17,7 +17,7 @@ class BetterNotificationManager
if (BAUNotificationManagerObj != null)
{
if (Notifying)
if (Notifying)
{
if (text == BAUNotificationManagerObj.transform.Find("Sizer/ChatText (TMP)").GetComponent<TextMeshPro>().text)
return;
@@ -50,7 +50,7 @@ class BetterNotificationManager
if (GameStates.IsHost && kickPlayer)
{
player.Kick(true, $"banned by <color=#4f92ff>Anti-Cheat</color>!\n Reason: <color=#fc0000>{reason}</color>", true);
player.Kick(true, "{0} " + $"by <color=#4f92ff>Anti-Cheat</color>!\n Reason: <color=#fc0000>{reason}</color>", true);
}
}
+2 -2
View File
@@ -84,8 +84,8 @@ public class ClientOptionItem
// ボタン生成
ToggleButton = Object.Instantiate(mouseMoveToggle, CustomBackground.transform);
ToggleButton.transform.localPosition = new Vector3(
// 現在のオプション数を基に位置を計算
ToggleButton.transform.localPosition = new Vector3(
// 現在のオプション数を基に位置を計算
numOptions % 2 == 0 ? -1.3f : 1.3f,
2.2f - (0.5f * (numOptions / 2)),
-6f);
+13 -3
View File
@@ -35,7 +35,7 @@ static class ExtendedPlayerControl
try
{
return $"<color={Utils.Color32ToHex(Palette.PlayerColors[player.CurrentOutfit.ColorId])}>{player.Data.PlayerName}</color>";
return $"<color={Utils.Color32ToHex(Palette.PlayerColors[player.Data.DefaultOutfit.ColorId])}>{player.Data.PlayerName}</color>";
}
catch
{
@@ -108,14 +108,24 @@ static class ExtendedPlayerControl
return;
}
if (AntiCheatBan)
{
if (BetterGameSettings.WhenCheating.GetValue() == 0)
{
return;
}
ban = ban && BetterGameSettings.WhenCheating.GetValue() == 2;
}
if (setReasonInfo != "")
{
GameDataShowNotificationPatch.BetterShowNotification(player.Data, forceReasonText: setReasonInfo);
GameDataShowNotificationPatch.BetterShowNotification(player.Data, forceReasonText: string.Format(setReasonInfo, ban ? "banned" : "kicked"));
}
AmongUsClient.Instance.KickPlayer(player.GetClientId(), ban);
player.BetterData().BannedByAntiCheat = AntiCheatBan && ban;
player.BetterData().BannedByAntiCheat = AntiCheatBan;
}
// RPCs
+7 -1
View File
@@ -9,7 +9,7 @@ public static class PlayerControlDataExtension
public class ExtendedPlayerInfo
{
public NetworkedPlayerInfo? _Data { get; set; }
public string RealName { get; set; } = string.Empty;
public string? RealName { get; set; }
public Dictionary<byte, string> LastNameSetFor { get; set; } = [];
public bool IsBetterUser { get; set; } = false;
public bool IsBetterHost { get; set; } = false;
@@ -58,6 +58,11 @@ public static class PlayerControlDataExtension
if (player.IsAlive() || player.Data.RoleType == RoleTypes.GuardianAngel)
player.BetterData().RoleInfo.DeadDisplayRole = player.Data.RoleType;
}
if (string.IsNullOrEmpty(player.BetterData().RealName))
{
player.BetterData().RealName = player.Data.PlayerName;
}
}
// Get BetterData from PlayerControl
@@ -104,6 +109,7 @@ public static class PlayerControlDataExtension
playerInfo[player.Data.Puid] = new ExtendedPlayerInfo
{
_Data = player.Data,
RealName = player.Data.PlayerName,
RoleInfo = new ExtendedRoleInfo()
};
}
+2 -2
View File
@@ -19,13 +19,13 @@ class FileChecker
// Set up if unauthorized files have been found.
public static void UpdateUnauthorizedFiles()
{
if (Enabled == false) return;
if (GameStates.IsDev)
{
HasTrySpoofFriendCode = false;
}
if (Enabled == false) return;
GameObject PlayButton = GameObject.Find("Main Buttons/PlayButton");
// Disable play button
+1 -1
View File
@@ -10,7 +10,7 @@ public static class GameStates
public static bool IsDev => EOSManager.Instance?.userId != null && Main.DevUser.Contains($"{Utils.GetHashPuid(EOSManager.Instance.userId.ToString())}+{EOSManager.Instance.friendCode}");
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;
public static bool IsHideNSeek => GameOptionsManager.Instance != null && GameOptionsManager.Instance.CurrentGameOptions.GameMode is GameModes.HideNSeek or GameModes.SeekFools;
public static bool SkeldIsActive => (MapNames)GameOptionsManager.Instance.CurrentGameOptions.MapId == MapNames.Skeld;
public static bool MiraHQIsActive => (MapNames)GameOptionsManager.Instance.CurrentGameOptions.MapId == MapNames.Mira;
public static bool PolusIsActive => (MapNames)GameOptionsManager.Instance.CurrentGameOptions.MapId == MapNames.Polus;
@@ -0,0 +1,83 @@
using UnityEngine;
namespace BetterAmongUs;
public class BetterOptionCheckboxItem : BetterOptionItem
{
private ToggleOption? ThisOption;
private bool? IsChecked;
public BetterOptionItem Create(int id, GameOptionsMenu gameOptionsMenu, string name, bool DefaultValue = true, BetterOptionItem Parent = null)
{
Id = id;
Tab = gameOptionsMenu;
Name = name;
IsChecked = DefaultValue;
if (gameOptionsMenu == null)
{
Load(DefaultValue);
return this;
}
ToggleOption optionBehaviour = UnityEngine.Object.Instantiate<ToggleOption>(gameOptionsMenu.checkboxOrigin, Vector3.zero, Quaternion.identity, gameOptionsMenu.settingsContainer);
optionBehaviour.transform.localPosition = new Vector3(0.952f, 2f - StaticSpacingNum * SpacingNum, -2f);
SetUp(optionBehaviour);
optionBehaviour.OnValueChanged = new Action<OptionBehaviour>((option) => ValueChanged(id, option));
SpacingNum += StaticSpacingNumPlus;
// Set data
optionBehaviour.CheckMark.GetComponent<SpriteRenderer>().enabled = DefaultValue;
TitleText = optionBehaviour.TitleText;
Option = optionBehaviour;
ThisOption = optionBehaviour;
Load(DefaultValue);
BetterOptionItems.Add(this);
return this;
}
public void Load(bool DefaultValue)
{
if (BetterDataManager.CanLoadSetting(Id))
{
if (ThisOption == null) return;
var Bool = BetterDataManager.LoadBoolSetting(Id);
ThisOption.CheckMark.GetComponent<SpriteRenderer>().enabled = Bool;
IsChecked = Bool;
}
else
{
BetterDataManager.SaveSetting(Id, DefaultValue.ToString());
}
}
public override bool GetBool()
{
if (BetterDataManager.CanLoadSetting(Id))
{
return BetterDataManager.LoadBoolSetting(Id);
}
else
{
return IsChecked ??= false;
}
}
public override void SetData(OptionBehaviour optionBehaviour)
{
optionBehaviour.data = new BaseGameSetting
{
Title = StringNames.None,
Type = OptionTypes.Checkbox,
};
}
public override void ValueChanged(int id, OptionBehaviour optionBehaviour)
{
IsChecked = !IsChecked;
BetterDataManager.SaveSetting(Id, IsChecked.ToString());
}
}
@@ -0,0 +1,178 @@
using UnityEngine;
using static Il2CppSystem.Net.Http.Headers.Parser;
namespace BetterAmongUs;
public class BetterOptionFloatItem : BetterOptionItem
{
public float CurrentValue;
public FloatRange floatRange = new(0f, 180f);
public float Increment = 2.5f;
private NumberOption? ThisOption;
private string? PostFix;
private string? PreFix;
public BetterOptionItem Create(int id, GameOptionsMenu gameOptionsMenu, string name, float[] values, float DefaultValue, string preFix = "", string postFix = "", BetterOptionItem Parent = null)
{
Id = id;
floatRange = new(values[0], values[1]);
Increment = values[2];
if (DefaultValue < floatRange.min) DefaultValue = floatRange.min;
if (DefaultValue > floatRange.max) DefaultValue = floatRange.max;
CurrentValue = DefaultValue;
if (gameOptionsMenu == null)
{
Load(DefaultValue);
return this;
}
if (values.Length is < 3 or > 3) return null;
NumberOption optionBehaviour = UnityEngine.Object.Instantiate<NumberOption>(gameOptionsMenu.numberOptionOrigin, Vector3.zero, Quaternion.identity, gameOptionsMenu.settingsContainer);
optionBehaviour.transform.localPosition = new Vector3(0.952f, 2f - StaticSpacingNum * SpacingNum, -2f);
SetUp(optionBehaviour);
optionBehaviour.OnValueChanged = new Action<OptionBehaviour>((option) => ValueChanged(id, option));
SpacingNum += StaticSpacingNumPlus;
// Fix Game Crash
foreach (RulesCategory rulesCategory in GameManager.Instance.GameSettingsList.AllCategories)
{
optionBehaviour.data = rulesCategory.AllGameSettings.ToArray().FirstOrDefault(item => item.Type == OptionTypes.Number);
}
optionBehaviour.PlusBtn.OnClick.RemoveAllListeners();
optionBehaviour.MinusBtn.OnClick.RemoveAllListeners();
optionBehaviour.PlusBtn.OnClick.AddListener(new Action(() => Increase()));
optionBehaviour.MinusBtn.OnClick.AddListener(new Action(() => Decrease()));
// Set data
Tab = gameOptionsMenu;
Name = name;
TitleText = optionBehaviour.TitleText;
Option = optionBehaviour;
PostFix = postFix;
PreFix = preFix;
ThisOption = optionBehaviour;
Load(DefaultValue);
AdjustButtonsActiveState();
BetterOptionItems.Add(this);
return this;
}
private void AdjustButtonsActiveState()
{
if (ThisOption == null) return;
ThisOption.ValueText.text = PreFix + CurrentValue.ToString() + PostFix;
if (CurrentValue + Increment > floatRange.max)
{
ThisOption.PlusBtn.SetInteractable(false);
ThisOption.MinusBtn.SetInteractable(true);
}
else if (CurrentValue - Increment < floatRange.min)
{
ThisOption.PlusBtn.SetInteractable(true);
ThisOption.MinusBtn.SetInteractable(false);
}
else
{
ThisOption.PlusBtn.SetInteractable(true);
ThisOption.MinusBtn.SetInteractable(true);
}
BetterDataManager.SaveSetting(Id, CurrentValue.ToString());
}
public void Increase()
{
int times = 1;
if (Input.GetKey(KeyCode.LeftShift))
times = 5;
if (Input.GetKey(KeyCode.LeftControl))
times = 10;
if (CurrentValue + Increment * times <= floatRange.max)
{
CurrentValue += Increment * times;
}
AdjustButtonsActiveState();
}
public void Decrease()
{
int times = 1;
if (Input.GetKey(KeyCode.LeftShift))
times = 5;
if (Input.GetKey(KeyCode.LeftControl))
times = 10;
if (CurrentValue - Increment * times >= floatRange.min)
{
CurrentValue -= Increment * times;
}
AdjustButtonsActiveState();
}
public void Load(float DefaultValue)
{
if (BetterDataManager.CanLoadSetting(Id))
{
var Float = BetterDataManager.LoadFloatSetting(Id);
if (Float > floatRange.max || Float < floatRange.min)
{
Float = DefaultValue;
BetterDataManager.SaveSetting(Id, DefaultValue.ToString());
}
CurrentValue = Float;
}
else
{
BetterDataManager.SaveSetting(Id, DefaultValue.ToString());
}
}
public override float GetFloat()
{
if (BetterDataManager.CanLoadSetting(Id))
{
return BetterDataManager.LoadFloatSetting(Id);
}
else
{
return CurrentValue;
}
}
public override int GetInt()
{
if (BetterDataManager.CanLoadSetting(Id))
{
return (int)BetterDataManager.LoadFloatSetting(Id);
}
else
{
return (int)CurrentValue;
}
}
public override void SetData(OptionBehaviour optionBehaviour)
{
optionBehaviour.data = new BaseGameSetting
{
Title = StringNames.None,
Type = OptionTypes.Float,
};
}
public override void ValueChanged(int id, OptionBehaviour optionBehaviour)
{
}
}
+177
View File
@@ -0,0 +1,177 @@
using UnityEngine;
namespace BetterAmongUs;
public class BetterOptionIntItem : BetterOptionItem
{
public int CurrentValue;
public IntRange intRange = new(0, 180);
public int Increment = 1;
private NumberOption? ThisOption;
private string? PostFix;
private string? PreFix;
public BetterOptionItem Create(int id, GameOptionsMenu gameOptionsMenu, string name, int[] values, int DefaultValue, string preFix = "", string postFix = "", BetterOptionItem Parent = null)
{
Id = id;
intRange = new(values[0], values[1]);
Increment = values[2];
if (DefaultValue < intRange.min) DefaultValue = intRange.min;
if (DefaultValue > intRange.max) DefaultValue = intRange.max;
CurrentValue = DefaultValue;
if (gameOptionsMenu == null)
{
Load(DefaultValue);
return this;
}
if (values.Length is < 3 or > 3) return null;
NumberOption optionBehaviour = UnityEngine.Object.Instantiate<NumberOption>(gameOptionsMenu.numberOptionOrigin, Vector3.zero, Quaternion.identity, gameOptionsMenu.settingsContainer);
optionBehaviour.transform.localPosition = new Vector3(0.952f, 2f - StaticSpacingNum * SpacingNum, -2f);
SetUp(optionBehaviour);
optionBehaviour.OnValueChanged = new Action<OptionBehaviour>((option) => ValueChanged(id, option));
SpacingNum += StaticSpacingNumPlus;
// Fix Game Crash
foreach (RulesCategory rulesCategory in GameManager.Instance.GameSettingsList.AllCategories)
{
optionBehaviour.data = rulesCategory.AllGameSettings.ToArray().FirstOrDefault(item => item.Type == OptionTypes.Number);
}
optionBehaviour.PlusBtn.OnClick.RemoveAllListeners();
optionBehaviour.MinusBtn.OnClick.RemoveAllListeners();
optionBehaviour.PlusBtn.OnClick.AddListener(new Action(() => Increase()));
optionBehaviour.MinusBtn.OnClick.AddListener(new Action(() => Decrease()));
// Set data
Tab = gameOptionsMenu;
Name = name;
TitleText = optionBehaviour.TitleText;
Option = optionBehaviour;
PostFix = postFix;
PreFix = preFix;
ThisOption = optionBehaviour;
Load(DefaultValue);
AdjustButtonsActiveState();
BetterOptionItems.Add(this);
return this;
}
private void AdjustButtonsActiveState()
{
if (ThisOption == null) return;
ThisOption.ValueText.text = PreFix + CurrentValue.ToString() + PostFix;
if (CurrentValue + Increment > intRange.max)
{
ThisOption.PlusBtn.SetInteractable(false);
ThisOption.MinusBtn.SetInteractable(true);
}
else if (CurrentValue - Increment < intRange.min)
{
ThisOption.PlusBtn.SetInteractable(true);
ThisOption.MinusBtn.SetInteractable(false);
}
else
{
ThisOption.PlusBtn.SetInteractable(true);
ThisOption.MinusBtn.SetInteractable(true);
}
BetterDataManager.SaveSetting(Id, CurrentValue.ToString());
}
public void Increase()
{
int times = 1;
if (Input.GetKey(KeyCode.LeftShift))
times = 5;
if (Input.GetKey(KeyCode.LeftControl))
times = 10;
if (CurrentValue + Increment * times <= intRange.max)
{
CurrentValue += Increment * times;
}
AdjustButtonsActiveState();
}
public void Decrease()
{
int times = 1;
if (Input.GetKey(KeyCode.LeftShift))
times = 5;
if (Input.GetKey(KeyCode.LeftControl))
times = 10;
if (CurrentValue - Increment * times >= intRange.min)
{
CurrentValue -= Increment * times;
}
AdjustButtonsActiveState();
}
public void Load(int DefaultValue)
{
if (BetterDataManager.CanLoadSetting(Id))
{
var Int = BetterDataManager.LoadIntSetting(Id);
if (Int > intRange.max || Int < intRange.min)
{
Int = DefaultValue;
BetterDataManager.SaveSetting(Id, DefaultValue.ToString());
}
CurrentValue = Int;
}
else
{
BetterDataManager.SaveSetting(Id, DefaultValue.ToString());
}
}
public override float GetFloat()
{
if (BetterDataManager.CanLoadSetting(Id))
{
return BetterDataManager.LoadIntSetting(Id);
}
else
{
return CurrentValue;
}
}
public override int GetInt()
{
if (BetterDataManager.CanLoadSetting(Id))
{
return BetterDataManager.LoadIntSetting(Id);
}
else
{
return CurrentValue;
}
}
public override void SetData(OptionBehaviour optionBehaviour)
{
optionBehaviour.data = new BaseGameSetting
{
Title = StringNames.None,
Type = OptionTypes.Float,
};
}
public override void ValueChanged(int id, OptionBehaviour optionBehaviour)
{
}
}
+64
View File
@@ -0,0 +1,64 @@
using TMPro;
using UnityEngine;
namespace BetterAmongUs;
public class BetterOptionItem
{
public float StaticSpacingNum => 1f;
public float StaticSpacingNumPlus => 0.45f;
public static List<BetterOptionItem> BetterOptionItems = [];
public static float SpacingNum = 0;
public int maskLayer = 20;
public int Id = 0;
public GameOptionsMenu? Tab;
public OptionBehaviour? Option;
public string? Name = "None";
public TextMeshPro? TitleText;
public void SetUp(OptionBehaviour optionBehaviour)
{
SetData(optionBehaviour);
SpriteRenderer[] componentsInChildren = optionBehaviour.GetComponentsInChildren<SpriteRenderer>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
componentsInChildren[i].material.SetInt(PlayerMaterial.MaskLayer, maskLayer);
}
foreach (TextMeshPro textMeshPro in optionBehaviour.GetComponentsInChildren<TextMeshPro>(true))
{
textMeshPro.fontMaterial.SetFloat("_StencilComp", 3f);
textMeshPro.fontMaterial.SetFloat("_Stencil", maskLayer);
}
}
public virtual bool GetBool()
{
throw new NotImplementedException();
}
public virtual float GetFloat()
{
throw new NotImplementedException();
}
public virtual int GetInt()
{
throw new NotImplementedException();
}
public virtual int GetValue()
{
throw new NotImplementedException();
}
public virtual void SetData(OptionBehaviour optionBehaviour)
{
throw new NotImplementedException();
}
public virtual void ValueChanged(int id, OptionBehaviour optionBehaviour)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,146 @@
using UnityEngine;
namespace BetterAmongUs;
public class BetterOptionStringItem : BetterOptionItem
{
public string[] Values = [];
public int CurrentValue;
private StringOption? ThisOption;
public BetterOptionItem Create(int id, GameOptionsMenu gameOptionsMenu, string name, string[] strings, int DefaultValue = 0, BetterOptionItem Parent = null)
{
Id = id;
Values = strings;
Tab = gameOptionsMenu;
Name = name;
if (DefaultValue < 0) DefaultValue = 0;
if (DefaultValue > Values.Length) DefaultValue = Values.Length;
CurrentValue = DefaultValue;
if (gameOptionsMenu == null)
{
Load(DefaultValue);
return this;
}
StringOption optionBehaviour = UnityEngine.Object.Instantiate<StringOption>(gameOptionsMenu.stringOptionOrigin, Vector3.zero, Quaternion.identity, gameOptionsMenu.settingsContainer);
optionBehaviour.transform.localPosition = new Vector3(0.952f, 2f - StaticSpacingNum * SpacingNum, -2f);
SetUp(optionBehaviour);
optionBehaviour.OnValueChanged = new Action<OptionBehaviour>((option) => ValueChanged(id, option));
SpacingNum += StaticSpacingNumPlus;
// Fix Game Crash
foreach (RulesCategory rulesCategory in GameManager.Instance.GameSettingsList.AllCategories)
{
optionBehaviour.data = rulesCategory.AllGameSettings.ToArray().FirstOrDefault(item => item.Type == OptionTypes.String);
}
optionBehaviour.PlusBtn.OnClick.RemoveAllListeners();
optionBehaviour.MinusBtn.OnClick.RemoveAllListeners();
optionBehaviour.PlusBtn.OnClick.AddListener(new Action(() => Increase()));
optionBehaviour.MinusBtn.OnClick.AddListener(new Action(() => Decrease()));
// Set data
TitleText = optionBehaviour.TitleText;
Option = optionBehaviour;
ThisOption = optionBehaviour;
Load(DefaultValue);
AdjustButtonsActiveState();
BetterOptionItems.Add(this);
return this;
}
private void AdjustButtonsActiveState()
{
if (ThisOption == null) return;
if (CurrentValue <= Values.Length - 1 && CurrentValue >= 0)
{
ThisOption.ValueText.text = Values[CurrentValue];
}
if (CurrentValue >= Values.Length - 1)
{
ThisOption.PlusBtn.SetInteractable(false);
ThisOption.MinusBtn.SetInteractable(true);
}
else if (CurrentValue <= 0)
{
ThisOption.PlusBtn.SetInteractable(true);
ThisOption.MinusBtn.SetInteractable(false);
}
else
{
ThisOption.PlusBtn.SetInteractable(true);
ThisOption.MinusBtn.SetInteractable(true);
}
BetterDataManager.SaveSetting(Id, CurrentValue.ToString());
}
public void Increase()
{
if (CurrentValue < Values.Length)
{
CurrentValue++;
AdjustButtonsActiveState();
}
}
public void Decrease()
{
if (CurrentValue > 0)
{
CurrentValue--;
AdjustButtonsActiveState();
}
}
public void Load(int DefaultValue)
{
if (BetterDataManager.CanLoadSetting(Id))
{
var Int = BetterDataManager.LoadIntSetting(Id);
if (Int > Values.Length - 1 || Int < 0)
{
Int = DefaultValue;
BetterDataManager.SaveSetting(Id, DefaultValue.ToString());
}
CurrentValue = Int;
}
else
{
BetterDataManager.SaveSetting(Id, DefaultValue.ToString());
}
}
public override int GetValue()
{
if (BetterDataManager.CanLoadSetting(Id))
{
return BetterDataManager.LoadIntSetting(Id);
}
else
{
return CurrentValue;
}
}
public override void SetData(OptionBehaviour optionBehaviour)
{
optionBehaviour.data = new BaseGameSetting
{
Title = StringNames.None,
Type = OptionTypes.String,
};
}
public override void ValueChanged(int id, OptionBehaviour optionBehaviour)
{
}
}
@@ -0,0 +1,32 @@
using UnityEngine;
namespace BetterAmongUs;
public class BetterOptionDividerItem : BetterOptionItem
{
public BetterOptionItem Create(GameOptionsMenu gameOptionsMenu)
{
if (gameOptionsMenu == null)
{
return this;
}
SpacingNum += 0.15f;
Tab = gameOptionsMenu;
Name = "Divider";
CategoryHeaderMasked categoryHeaderMasked = UnityEngine.Object.Instantiate<CategoryHeaderMasked>(gameOptionsMenu.categoryHeaderOrigin, Vector3.zero, Quaternion.identity, gameOptionsMenu.settingsContainer);
categoryHeaderMasked.transform.localScale = Vector3.one * 0.63f;
categoryHeaderMasked.transform.localPosition = new Vector3(-0.903f, 2f - StaticSpacingNum * SpacingNum, -2f);
UnityEngine.Object.Destroy(categoryHeaderMasked.Background.gameObject);
UnityEngine.Object.Destroy(categoryHeaderMasked.Title.gameObject);
if (categoryHeaderMasked.Divider != null)
{
categoryHeaderMasked.Divider.material.SetInt(PlayerMaterial.MaskLayer, maskLayer);
}
SpacingNum += 0.45f;
return this;
}
}
@@ -0,0 +1,34 @@
using UnityEngine;
namespace BetterAmongUs;
public class BetterOptionHeaderItem : BetterOptionItem
{
public BetterOptionItem Create(GameOptionsMenu gameOptionsMenu, string name)
{
if (gameOptionsMenu == null)
{
return this;
}
SpacingNum += 0.1f;
Tab = gameOptionsMenu;
Name = name;
CategoryHeaderMasked categoryHeaderMasked = UnityEngine.Object.Instantiate<CategoryHeaderMasked>(gameOptionsMenu.categoryHeaderOrigin, Vector3.zero, Quaternion.identity, gameOptionsMenu.settingsContainer);
categoryHeaderMasked.transform.localScale = Vector3.one * 0.63f;
categoryHeaderMasked.transform.localPosition = new Vector3(-0.903f, 2f - StaticSpacingNum * SpacingNum, -2f);
categoryHeaderMasked.Title.text = name;
categoryHeaderMasked.Background.material.SetInt(PlayerMaterial.MaskLayer, maskLayer);
if (categoryHeaderMasked.Divider != null)
{
categoryHeaderMasked.Divider.material.SetInt(PlayerMaterial.MaskLayer, maskLayer);
}
categoryHeaderMasked.Title.fontMaterial.SetFloat("_StencilComp", 3f);
categoryHeaderMasked.Title.fontMaterial.SetFloat("_Stencil", maskLayer);
SpacingNum += 0.75f;
return this;
}
}
@@ -0,0 +1,46 @@
using UnityEngine;
namespace BetterAmongUs;
public class BetterOptionTitleItem : BetterOptionItem
{
public BetterOptionItem Create(GameOptionsMenu gameOptionsMenu, string name)
{
if (gameOptionsMenu == null)
{
return this;
}
ToggleOption optionBehaviour = UnityEngine.Object.Instantiate<ToggleOption>(gameOptionsMenu.checkboxOrigin, Vector3.zero, Quaternion.identity, gameOptionsMenu.settingsContainer);
optionBehaviour.transform.localPosition = new Vector3(0.952f, 2f - StaticSpacingNum * SpacingNum, -2f);
SetUp(optionBehaviour);
SpacingNum += StaticSpacingNumPlus;
UnityEngine.Object.Destroy(optionBehaviour.CheckMark.transform.parent.gameObject);
UnityEngine.Object.Destroy(optionBehaviour.GetComponent<ToggleOption>());
optionBehaviour.TitleText.alignment = TMPro.TextAlignmentOptions.Center;
optionBehaviour.TitleText.outlineColor = Color.black;
optionBehaviour.TitleText.outlineWidth = 0.2f;
optionBehaviour.TitleText.transform.localPosition += new Vector3(0f, 0.05f, 0f);
optionBehaviour.LabelBackground.color = new Color(0.6f, 0.6f, 0.6f, 1f);
optionBehaviour.LabelBackground.transform.SetLocalZ(1f);
// Set data
Tab = gameOptionsMenu;
Name = $"<b><size=150%>{name}</size></b>";
Option = optionBehaviour;
TitleText = optionBehaviour.TitleText;
BetterOptionItems.Add(this);
return this;
}
public override void SetData(OptionBehaviour optionBehaviour)
{
optionBehaviour.data = new BaseGameSetting
{
Title = StringNames.None,
Type = OptionTypes.Checkbox,
};
}
}
+22 -3
View File
@@ -1,7 +1,6 @@
using BetterAmongUs.Patches;
using HarmonyLib;
using Hazel;
using InnerNet;
namespace BetterAmongUs;
@@ -22,7 +21,7 @@ enum CustomRPC : int
}
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.HandleRpc))]
internal class RPCHandlerPatch
internal class PlayerControlRPCHandlerPatch
{
public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader)
{
@@ -58,6 +57,21 @@ internal class RPCHandlerPatch
}
}
[HarmonyPatch(typeof(PlayerPhysics), nameof(PlayerPhysics.HandleRpc))]
internal class PlayerPhysicsRPCHandlerPatch
{
public static void Prefix(PlayerPhysics __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader)
{
if (AntiCheat.CheckCancelRPC(__instance.myPlayer, callId, reader) != true)
{
Logger.LogCheat($"RPC canceled by Anti-Cheat: {Enum.GetName((RpcCalls)callId)}{Enum.GetName((CustomRPC)callId)} - {callId}");
}
AntiCheat.CheckRPC(__instance.myPlayer, callId, reader);
RPC.HandleRPC(__instance.myPlayer, callId, reader);
}
}
[HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.UpdateSystem), typeof(SystemTypes), typeof(PlayerControl), typeof(MessageReader))]
public static class MessageReaderUpdateSystemPatch
{
@@ -211,6 +225,11 @@ internal static class RPC
switch (callId)
{
case (byte)RpcCalls.SetName:
reader.ReadUInt32();
var name = reader.ReadString();
player.BetterData().RealName = name;
break;
case (byte)RpcCalls.SendChat:
var text = reader.ReadString();
@@ -224,7 +243,7 @@ internal static class RPC
}
// Check banned words
if (Main.UseBannedList.Value)
if (BetterGameSettings.UseBanWordList.GetBool())
{
try
{
+2
View File
@@ -132,6 +132,8 @@ public static class Utils
// Get name for role
public static string GetRoleName(RoleTypes role) => Main.GetRoleName[(int)role];
// Get color for role
public static string GetRoleColor(RoleTypes role) => Main.GetRoleColor[(int)role];
// Get hex color for team
public static string GetTeamHexColor(RoleTeamTypes team)
{
+4 -2
View File
@@ -53,8 +53,9 @@ class ChatPatch
class ChatControllerPatch
{
[HarmonyPatch(nameof(ChatController.Update))]
[HarmonyPostfix]
public static void Update_Postfix(ChatController __instance)
[HarmonyPrefix]
[HarmonyPriority(Priority.First)]
public static void Update_Prefix(ChatController __instance)
{
for (int i = 0; i < __instance.scroller.Inner.gameObject.transform.childCount; i++)
{
@@ -107,6 +108,7 @@ class ChatPatch
[HarmonyPatch(nameof(ChatController.AddChat))]
[HarmonyPrefix]
[HarmonyPriority(Priority.First)]
public static bool AddChat_Prefix(ChatController __instance, [HarmonyArgument(0)] PlayerControl sourcePlayer, [HarmonyArgument(1)] string chatText)
{
bool censor = false;
+4 -5
View File
@@ -1,6 +1,5 @@
using HarmonyLib;
using UnityEngine;
using static Rewired.Data.UserDataStore_PlayerPrefs.ControllerAssignmentSaveInfo;
namespace BetterAmongUs.Patches;
@@ -13,7 +12,7 @@ public static class OptionsMenuBehaviourPatch
private static ClientOptionItem BetterHost;
private static ClientOptionItem BetterRoleAlgorithma;
private static ClientOptionItem BetterNotifications;
private static ClientOptionItem UseBannedList;
private static ClientOptionItem ChatInGameplay;
private static ClientOptionItem LobbyPlayerInfo;
private static ClientOptionItem DisableLobbyTheme;
private static ClientOptionItem UnlockFPS;
@@ -80,10 +79,10 @@ public static class OptionsMenuBehaviourPatch
BetterNotificationManager.Notifying = false;
}
}
if (UseBannedList == null || UseBannedList.ToggleButton == null)
if (ChatInGameplay == null || ChatInGameplay.ToggleButton == null)
{
UseBannedList = ClientOptionItem.Create("Use Ban Lists", Main.UseBannedList, __instance);
ChatInGameplay = ClientOptionItem.Create("Chat In Gameplay", Main.ChatInGameplay, __instance);
}
if (LobbyPlayerInfo == null || LobbyPlayerInfo.ToggleButton == null)
+1 -1
View File
@@ -77,7 +77,7 @@ public class ClientPatch
[HarmonyPrefix]
public static void KickPlayer_Prefix(ref int clientId, ref bool ban)
{
if (ban && Main.UseBannedList.Value)
if (ban && BetterGameSettings.UseBanPlayerList.GetBool())
{
NetworkedPlayerInfo info = Utils.PlayerFromClientId(clientId).Data;
BetterDataManager.SaveBanList(info.FriendCode, info.Puid);
+2 -2
View File
@@ -175,7 +175,7 @@ class CommandsPatch
sb.Append("\n\n");
}
Utils.AddChatPrivate(sb.ToString());
break;
break;
case "whisper" or "w":
if (HandlePlayerArgument(command, subArgs) == true)
{
@@ -410,7 +410,7 @@ class CommandsPatch
RPC.SyncAllNames(force: true);
Utils.AddChatPrivate("<color=#0dff00>All player names have been updated and synced!</color>");
}
break;
break;
case "suicide":
if (HandleIsHost(command) == true)
{
+56 -18
View File
@@ -1,5 +1,4 @@
using HarmonyLib;
using Newtonsoft.Json.Utilities;
using System.Text;
using TMPro;
using UnityEngine;
@@ -19,23 +18,6 @@ class GamePlayManager
{
AntiCheat.PauseAntiCheat();
}
// Clear unused Better Data
var keysToRemove = new List<string>();
foreach (var betterInfo in PlayerControlDataExtension.playerInfo)
{
if (!Main.AllPlayerControls.Any(pc => pc.Data.Puid == betterInfo.Key))
{
keysToRemove.Add(betterInfo.Key);
}
}
foreach (var key in keysToRemove)
{
PlayerControlDataExtension.playerInfo.Remove(key);
}
}
[HarmonyPatch(nameof(LobbyBehaviour.Start))]
[HarmonyPostfix]
@@ -58,6 +40,62 @@ class GamePlayManager
{
if (Main.DisableLobbyTheme.Value)
SoundManager.instance.StopSound(LobbyBehaviour.Instance.MapTheme);
// Clear unused Better Data
try
{
var keysToRemove = new List<string>();
foreach (var betterInfo in PlayerControlDataExtension.playerInfo)
{
if (Main.AllPlayerControls.Any(pc => pc.Data.Puid == betterInfo.Key))
continue;
keysToRemove.Add(betterInfo.Key);
}
foreach (var key in keysToRemove)
{
PlayerControlDataExtension.playerInfo.Remove(key);
}
}
catch { }
}
}
[HarmonyPatch(typeof(IntroCutscene))]
public class IntroCutscenePatch
{
[HarmonyPatch(nameof(IntroCutscene.ShowRole))]
[HarmonyPostfix]
private static void ShowRole_Postfix(IntroCutscene __instance)
{
static Color HexToColor(string hex)
{
if (hex.StartsWith("#"))
{
hex = hex.Substring(1);
}
byte r = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
byte g = byte.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
byte b = byte.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);
return new Color32(r, g, b, 255);
}
_ = new LateTask(() =>
{
Color RoleColor = HexToColor(Utils.GetRoleColor(PlayerControl.LocalPlayer.Data.RoleType));
__instance.ImpostorText.gameObject.SetActive(false);
__instance.TeamTitle.gameObject.SetActive(false);
__instance.FrontMost.gameObject.SetActive(false);
__instance.BackgroundBar.material.color = RoleColor;
__instance.YouAreText.color = RoleColor;
__instance.RoleText.color = RoleColor;
__instance.RoleBlurbText.color = RoleColor;
}, 0.0025f, shoudLog: false);
}
}
+345
View File
@@ -0,0 +1,345 @@
using AmongUs.GameOptions;
using HarmonyLib;
using UnityEngine;
namespace BetterAmongUs.Patches;
class BetterGameSettings
{
public static BetterOptionItem? WhenCheating;
public static BetterOptionItem? InvalidFriendCode;
public static BetterOptionItem? UseBanPlayerList;
public static BetterOptionItem? UseBanNameList;
public static BetterOptionItem? UseBanWordList;
public static BetterOptionItem? HideAndSeekImpNum;
public static BetterOptionItem? DetectedLevelAbove;
public static BetterOptionItem? DetectCheatClients;
public static BetterOptionItem? DetectInvalidRPCs;
public static BetterOptionItem? ExperimentalDetectInvalidSabotage;
}
[HarmonyPatch(typeof(GameSettingMenu))]
static class GameSettingMenuPatch
{
private static PassiveButton BetterSettingsButton;
public static GameOptionsMenu BetterSettingsTab;
private static List<BetterOptionItem> TitleList = [];
public static void SetupSettings(bool IsPreload = false)
{
BetterOptionItem.SpacingNum = 0;
BetterOptionItem.BetterOptionItems.Clear();
TitleList.Clear();
// Anti-Cheat Settings
{
TitleList.Add(new BetterOptionHeaderItem().Create(BetterSettingsTab, "<color=#4f92ff>Anti-Cheat Settings</color>"));
if (IsPreload || GameStates.IsHost)
{
TitleList.Add(new BetterOptionTitleItem().Create(BetterSettingsTab, $"<color=#4f92ff>Host Only</color>"));
BetterGameSettings.WhenCheating = new BetterOptionStringItem().Create(100, BetterSettingsTab, "When a player is caught cheating", ["Do Nothing", "Kick", "Ban"], 2);
BetterGameSettings.InvalidFriendCode = new BetterOptionCheckboxItem().Create(200, BetterSettingsTab, "Allow invalid friendCodes", true);
BetterGameSettings.UseBanPlayerList = new BetterOptionCheckboxItem().Create(300, BetterSettingsTab, "Use Ban Player List", true);
BetterGameSettings.UseBanNameList = new BetterOptionCheckboxItem().Create(400, BetterSettingsTab, "Use Ban Name List", true);
BetterGameSettings.UseBanWordList = new BetterOptionCheckboxItem().Create(500, BetterSettingsTab, "Use Ban Word List", true);
TitleList.Add(new BetterOptionDividerItem().Create(BetterSettingsTab));
}
TitleList.Add(new BetterOptionTitleItem().Create(BetterSettingsTab, $"<color=#4f92ff>Detections</color>"));
BetterGameSettings.DetectedLevelAbove = new BetterOptionIntItem().Create(600, BetterSettingsTab, "Detected player level = or >", [100, 5000, 5], 200, "Lv ", "");
BetterGameSettings.DetectCheatClients = new BetterOptionCheckboxItem().Create(700, BetterSettingsTab, "Detect Cheat Clients", true);
BetterGameSettings.DetectInvalidRPCs = new BetterOptionCheckboxItem().Create(800, BetterSettingsTab, "Detect Invalid RPCs", true);
TitleList.Add(new BetterOptionDividerItem().Create(BetterSettingsTab));
TitleList.Add(new BetterOptionTitleItem().Create(BetterSettingsTab, $"<color=#f20>Experimental</color>"));
BetterGameSettings.ExperimentalDetectInvalidSabotage = new BetterOptionCheckboxItem().Create(100000, BetterSettingsTab, "Detect Invalid Sabotages", false);
}
// Gameplay Settings
{
if (IsPreload || GameStates.IsHost)
{
if (IsPreload || !GameStates.IsHideNSeek)
{
new BetterOptionHeaderItem().Create(BetterSettingsTab, "<color=#d7d700>Gameplay Settings</color>");
}
else if (IsPreload || GameStates.IsHideNSeek)
{
new BetterOptionHeaderItem().Create(BetterSettingsTab, "<color=#d7d700>Hide & Seek Settings</color>");
if (IsPreload || Main.BetterRoleAlgorithma.Value)
{
new BetterOptionTitleItem().Create(BetterSettingsTab, $"<color=#4f92ff>Better Role Algorithma</color>");
BetterOptionItem.SpacingNum += 0.2f;
new BetterOptionTitleItem().Create(BetterSettingsTab, $"<color={Utils.GetRoleColor(RoleTypes.Impostor)}>Imposter</color>");
BetterGameSettings.HideAndSeekImpNum = new BetterOptionIntItem().Create(1000, BetterSettingsTab, "# Seekers", [1, 5, 1], 1, "", "");
}
}
}
}
/*
new BetterOptionCheckboxItem().Create(0, BetterSettingsTab, "CheckBox Test", true);
new BetterOptionStringItem().Create(1, BetterSettingsTab, "String Test", ["Test 1", "Test 2", "Test 3"]);
new BetterOptionFloatItem().Create(2, BetterSettingsTab, "Float Test 1", [0f, 180f, 2.5f], 0f, "");
new BetterOptionIntItem().Create(5, BetterSettingsTab, "Int Test", [0, 5, 1], 0, "");
new BetterOptionHeaderItem().Create(BetterSettingsTab, "<color=#4f92ff>Test Settings 2</color>");
*/
if (BetterSettingsTab != null)
BetterSettingsTab.scrollBar.SetYBoundsMax(1.25f * BetterOptionItem.SpacingNum / 2);
}
private static void Initialize()
{
_ = new LateTask(() =>
{
foreach (var item in BetterOptionItem.BetterOptionItems)
{
if (item != null)
{
if (item.TitleText != null)
{
item.TitleText.text = item.Name;
}
}
}
}, 0.005f, shoudLog: false);
}
[HarmonyPatch(nameof(GameSettingMenu.Update))]
[HarmonyPostfix]
public static void Update_Postfix(GameSettingMenu __instance)
{
if (BetterSettingsButton != null)
{
BetterSettingsButton.buttonText.SetText("Better Settings");
if (!BetterSettingsButton.selected && !BetterSettingsButton.activeSprites.active)
{
BetterSettingsButton.buttonText.color = new Color(0f, 1f, 0f, 1f);
}
else
{
BetterSettingsButton.buttonText.color = new Color(0.35f, 1f, 0.35f, 1f);
}
if (BetterSettingsButton.selected)
{
__instance.MenuDescriptionText.text = "Edit better settings for your lobby and gameplay.";
}
}
}
[HarmonyPatch(nameof(GameSettingMenu.Start))]
[HarmonyPostfix]
public static void Start_Postfix(GameSettingMenu __instance)
{
__instance.gameObject.transform.SetLocalY(-0.1f);
GameObject PanelSprite = __instance.gameObject.transform.Find("PanelSprite").gameObject;
if (PanelSprite != null)
{
PanelSprite.transform.SetLocalY(-0.32f);
PanelSprite.transform.localScale = new Vector3(PanelSprite.transform.localScale.x, 0.625f);
}
BetterSettingsButton = UnityEngine.Object.Instantiate(__instance.GameSettingsButton, __instance.GameSettingsButton.transform.parent);
BetterSettingsButton.name = "BetterSettings";
BetterSettingsButton.OnClick.RemoveAllListeners();
BetterSettingsButton.OnMouseOver.RemoveAllListeners();
BetterSettingsButton.activeSprites.GetComponent<SpriteRenderer>().color = new Color(0f, 1f, 0.35f, 1f);
BetterSettingsButton.inactiveSprites.GetComponent<SpriteRenderer>().color = new Color(0f, 1f, 0.35f, 1f);
BetterSettingsButton.selectedSprites.GetComponent<SpriteRenderer>().color = new Color(0f, 1f, 0.35f, 1f);
BetterSettingsButton.OnClick.AddListener(new Action(() =>
{
__instance.ChangeTab(3, false);
}));
BetterSettingsTab = UnityEngine.Object.Instantiate(__instance.GameSettingsTab, __instance.GameSettingsTab.transform.parent);
BetterSettingsTab.name = "BETTER SETTINGS TAB";
BetterSettingsTab.scrollBar.Inner.DestroyChildren();
__instance.GamePresetsButton.OnMouseOver.RemoveAllListeners();
__instance.GameSettingsButton.OnMouseOver.RemoveAllListeners();
__instance.RoleSettingsButton.OnMouseOver.RemoveAllListeners();
BetterSettingsButton.transform.position = BetterSettingsButton.transform.position - new Vector3(0f, 1.265f, 0f);
if (!GameStates.IsHideNSeek && GameStates.IsHost)
{
__instance.ChangeTab(1, false);
}
else if (GameStates.IsHost)
{
__instance.RoleSettingsButton.gameObject.SetActive(true);
__instance.RoleSettingsButton.GetComponent<PassiveButton>().enabled = false;
__instance.RoleSettingsButton.inactiveSprites.GetComponent<SpriteRenderer>().color = new(0.5f, 0.5f, 0.5f, 1f);
__instance.ChangeTab(1, false);
}
else
{
__instance.GamePresetsButton.GetComponent<PassiveButton>().enabled = false;
__instance.GameSettingsButton.GetComponent<PassiveButton>().enabled = false;
__instance.RoleSettingsButton.GetComponent<PassiveButton>().enabled = false;
__instance.GamePresetsButton.inactiveSprites.GetComponent<SpriteRenderer>().color = new(0.5f, 0.5f, 0.5f, 1f);
__instance.GameSettingsButton.inactiveSprites.GetComponent<SpriteRenderer>().color = new(0.5f, 0.5f, 0.5f, 1f);
__instance.RoleSettingsButton.inactiveSprites.GetComponent<SpriteRenderer>().color = new(0.5f, 0.5f, 0.5f, 1f);
__instance.ChangeTab(3, false);
}
SetupSettings();
}
[HarmonyPatch(nameof(GameSettingMenu.ChangeTab))]
[HarmonyPrefix]
public static void ChangeTab_Prefix(GameSettingMenu __instance, [HarmonyArgument(0)] int tabNum, [HarmonyArgument(1)] bool previewOnly)
{
if (BetterSettingsTab == null || BetterSettingsButton == null) return;
BetterSettingsTab.gameObject.SetActive(false);
BetterSettingsButton.SelectButton(false);
if ((previewOnly && Controller.currentTouchType == Controller.TouchType.Joystick) || !previewOnly)
{
switch (tabNum)
{
case 3:
BetterSettingsTab.gameObject.SetActive(true);
break;
}
}
}
[HarmonyPatch(nameof(GameSettingMenu.ChangeTab))]
[HarmonyPostfix]
public static void ChangeTab_Postfix(GameSettingMenu __instance, [HarmonyArgument(0)] int tabNum)
{
if (BetterSettingsTab == null || BetterSettingsButton == null) return;
BetterSettingsButton.buttonText.color = new Color(0f, 1f, 0f, 1f);
switch (tabNum)
{
case 3:
BetterSettingsButton.SelectButton(true);
Initialize();
break;
}
}
}
[HarmonyPatch(typeof(GameOptionsMenu))]
static class GameOptionsMenuPatch
{
[HarmonyPatch(nameof(GameOptionsMenu.CreateSettings))]
[HarmonyPrefix]
public static bool CreateSettings_Prefix(GameOptionsMenu __instance)
{
if (__instance == GameSettingMenuPatch.BetterSettingsTab)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(OptionsConsole))]
static class OptionsConsolePatch
{
[HarmonyPatch(nameof(OptionsConsole.CanUse))]
[HarmonyPrefix]
public static void CanUse_Prefix(OptionsConsole __instance)
{
__instance.HostOnly = false;
}
}
// Allow settings bypass
[HarmonyPatch(typeof(NumberOption))]
static class NumberOptionPatch
{
[HarmonyPatch(nameof(NumberOption.Increase))]
[HarmonyPrefix]
public static bool Increase_Prefix(NumberOption __instance)
{
int times = 1;
if (Input.GetKey(KeyCode.LeftShift))
times = 5;
if (Input.GetKey(KeyCode.LeftControl))
times = 10;
__instance.Value += __instance.Increment * times;
__instance.UpdateValue();
return false;
}
[HarmonyPatch(nameof(NumberOption.Decrease))]
[HarmonyPrefix]
public static bool Decrease_Prefix(NumberOption __instance)
{
int times = 1;
if (Input.GetKey(KeyCode.LeftShift))
times = 5;
if (Input.GetKey(KeyCode.LeftControl))
times = 10;
__instance.Value -= __instance.Increment * times;
__instance.UpdateValue();
return false;
}
[HarmonyPatch(nameof(NumberOption.UpdateValue))]
[HarmonyPrefix]
public static bool UpdateValue_Prefix(NumberOption __instance)
{
if (__instance.floatOptionName != FloatOptionNames.Invalid)
{
GameOptionsManager.Instance.CurrentGameOptions.SetFloat(__instance.floatOptionName, __instance.GetFloat());
return false;
}
if (__instance.intOptionName != Int32OptionNames.Invalid)
{
GameOptionsManager.Instance.CurrentGameOptions.SetInt(__instance.intOptionName, __instance.GetInt());
return false;
}
return false;
}
[HarmonyPatch(nameof(NumberOption.FixedUpdate))]
[HarmonyPrefix]
public static bool FixedUpdate_Prefix(NumberOption __instance)
{
try
{
if (__instance.MinusBtn != null && __instance.PlusBtn != null)
{
__instance.MinusBtn.SetInteractable(true);
__instance.PlusBtn.SetInteractable(true);
}
if (__instance.oldValue != __instance.Value)
{
__instance.oldValue = __instance.Value;
if (__instance.Value > __instance.ValidRange.max || __instance.Value < __instance.ValidRange.min)
{
__instance.ValueText.text = $"<color=#f20>{__instance.data.GetValueString(__instance.Value)}</color>";
}
else
{
__instance.ValueText.text = __instance.data.GetValueString(__instance.Value);
}
}
}
catch { }
return false;
}
}
+23 -2
View File
@@ -53,8 +53,29 @@ public class HudManagerPatch
if (gameStart != null)
gameStart.transform.SetLocalY(-2.8f);
if (GameStates.InGame && __instance?.Chat?.gameObject.active != true)
__instance.Chat.gameObject.SetActive(true);
// Set chat
if (GameStates.InGame)
{
if (!Main.ChatInGameplay.Value)
{
if (!PlayerControl.LocalPlayer.IsAlive())
{
__instance.Chat.gameObject.SetActive(true);
}
else if (GameStates.IsInGamePlay && !(GameStates.IsMeeting || GameStates.IsExilling))
{
__instance.Chat.gameObject.SetActive(false);
}
}
else
{
if (__instance?.Chat?.gameObject.active == false)
{
__instance.Chat.gameObject.SetActive(true);
}
}
}
}
catch { }
}
+1 -1
View File
@@ -99,7 +99,7 @@ internal class MainMenuPatch
bool Flag = __instance?.screenTint?.GetComponent<SpriteRenderer>() != null
&& !__instance.screenTint.GetComponent<SpriteRenderer>().enabled;
foreach (var item in buttonsObj)
foreach (var item in buttonsObj)
{
item.SetActive(Flag);
}
+1 -1
View File
@@ -99,7 +99,7 @@ class MeetingHudUpdatePatch
case DisconnectReasons.Hacking:
DisconnectText = "Banned By Server";
break;
default:
default:
DisconnectText = "Disconnected";
break;
}
+4 -1
View File
@@ -10,7 +10,10 @@ public class ModManagerPatch
[HarmonyPostfix]
public static void LateUpdate_Postfix(ModManager __instance)
{
__instance.ShowModStamp();
if (SplashIntroPatch.IsReallyDoneLoading)
{
__instance.ShowModStamp();
}
if (__instance.ModStamp.gameObject.active == true)
__instance.ModStamp.GetComponent<SpriteRenderer>().sprite = Utils.LoadSprite("BetterAmongUs.Resources.Images.BetterAmongUs-Mod.png", 250f);
+8 -3
View File
@@ -1,9 +1,6 @@
using AmongUs.Data;
using AmongUs.GameOptions;
using HarmonyLib;
using Hazel;
using Il2CppSystem.Linq;
using InnerNet;
using LibCpp2IL;
using System.Text;
using System.Text.RegularExpressions;
@@ -115,6 +112,14 @@ class PlayerControlPatch
{
friendCode = "No Friend Code";
friendCodeColor = "#ff0000";
if (GameStates.IsHost)
{
if (BetterGameSettings.InvalidFriendCode.GetBool())
{
player.Kick(true, "{0} by <color=#4f92ff>Anti-Cheat</color>!\n Reason: <color=#fc0000>Invalid Friend Code</color>", true);
}
}
}
if (DataManager.Settings.Gameplay.StreamerMode == true)
{
+30 -27
View File
@@ -56,7 +56,7 @@ public static class OnPlayerJoinedPatch
client.Character.RpcSendHostChat(HudManagerPatch.WelcomeMessage, sendToBetterUser: false);
// Auto ban player on ban list
if (Main.UseBannedList.Value)
if (BetterGameSettings.UseBanPlayerList.GetBool())
{
if (player != null)
{
@@ -77,34 +77,37 @@ public static class OnPlayerJoinedPatch
}
}
catch { }
try
{
// Normalize and remove spaces and special characters from names
Func<string, string> normalizeName = name => new string(name.Where(c => char.IsLetterOrDigit(c)).ToArray()).ToLower();
// Read all banned names into a HashSet with normalized names
HashSet<string> bannedNames = new HashSet<string>(
File.ReadLines(BetterDataManager.banNameListFile)
.Select(normalizeName)
.Where(name => !string.IsNullOrWhiteSpace(name))
);
string normalizedPlayerName = normalizeName(player.Data.PlayerName);
// Check if any banned name is a prefix of the player's normalized name
bool isNameBanned = bannedNames.Any(bannedName =>
normalizedPlayerName.StartsWith(bannedName)
);
if (!string.IsNullOrEmpty(normalizedPlayerName) && isNameBanned)
{
player.Kick(false, $"has been kicked due to their name being on the ban name list!");
}
}
catch { }
}
}
if (BetterGameSettings.UseBanNameList.GetBool())
{
try
{
// Normalize and remove spaces and special characters from names
Func<string, string> normalizeName = name => new string(name.Where(c => char.IsLetterOrDigit(c)).ToArray()).ToLower();
// Read all banned names into a HashSet with normalized names
HashSet<string> bannedNames = new HashSet<string>(
File.ReadLines(BetterDataManager.banNameListFile)
.Select(normalizeName)
.Where(name => !string.IsNullOrWhiteSpace(name))
);
string normalizedPlayerName = normalizeName(player.Data.PlayerName);
// Check if any banned name is a prefix of the player's normalized name
bool isNameBanned = bannedNames.Any(bannedName =>
normalizedPlayerName.StartsWith(bannedName)
);
if (!string.IsNullOrEmpty(normalizedPlayerName) && isNameBanned)
{
player.Kick(false, $"has been kicked due to their name being on the ban name list!");
}
}
catch { }
}
}
}, 2.5f, "OnPlayerJoinedPatch", false);
}
+1 -1
View File
@@ -268,7 +268,7 @@ public class RoleManagerPatch
foreach (var addplayer in Main.AllPlayerControls.Where(pc => !ImpostorMultiplier.ContainsKey(Utils.GetHashPuid(pc))))
ImpostorMultiplier[Utils.GetHashPuid(addplayer)] = 0;
int NumImpostors = 1;
int NumImpostors = BetterGameSettings.HideAndSeekImpNum.GetInt();
int NumPlayers = Main.AllPlayerControls.Length;
+77
View File
@@ -0,0 +1,77 @@
using HarmonyLib;
using UnityEngine;
namespace BetterAmongUs.Patches;
class SplashIntroPatch
{
public static bool BetterIntro = false;
public static bool IsReallyDoneLoading = false;
private static float ShowTime = 0f;
private static GameObject BetterLogo;
[HarmonyPatch(typeof(SplashManager))]
class SplashManagerPatch
{
[HarmonyPatch(nameof(SplashManager.Start))]
[HarmonyPrefix]
public static void Start_Prefix(SplashManager __instance)
{
__instance.logoAnimFinish.transform.Find("BlackOverlay").transform.SetLocalY(100f);
}
[HarmonyPatch(nameof(SplashManager.Update))]
[HarmonyPrefix]
public static bool Update_Prefix(SplashManager __instance)
{
ShowTime += Time.deltaTime;
if (ShowTime > 6f && BetterIntro)
{
UnityEngine.Object.Destroy(__instance.logoAnimFinish.GetComponent<AudioSource>());
}
if (Input.GetKeyDown(KeyCode.Mouse0) || Input.GetKeyDown(KeyCode.Mouse1))
{
if (ShowTime > 1.5f)
{
__instance.StopAllCoroutines();
UnityEngine.Object.Destroy(__instance.logoAnimFinish.gameObject);
__instance.sceneChanger.AllowFinishLoadingScene();
__instance.startedSceneLoad = true;
__instance.loadingObject.SetActive(true);
IsReallyDoneLoading = true;
}
}
if (__instance.doneLoadingRefdata && !__instance.startedSceneLoad && Time.time - __instance.startTime > __instance.minimumSecondsBeforeSceneChange)
{
if (!BetterIntro)
{
__instance.startTime = Time.time;
__instance.logoAnimFinish.gameObject.SetActive(false);
__instance.logoAnimFinish.gameObject.SetActive(true);
GameObject InnerLogo = __instance.logoAnimFinish.transform.Find("LogoRoot/ISLogo").gameObject;
BetterLogo = UnityEngine.Object.Instantiate(InnerLogo, InnerLogo.transform.parent);
GameObject.Destroy(InnerLogo);
BetterLogo.name = "BetterLogo";
BetterLogo.GetComponent<SpriteRenderer>().sprite = Utils.LoadSprite("BetterAmongUs.Resources.Images.BetterAmongUs-Logo.png", 150f);
__instance.logoAnimFinish.transform.Find("BlackOverlay").transform.SetLocalY(0f);
}
__instance.startedSceneLoad = BetterIntro;
BetterIntro = true;
if (__instance.startedSceneLoad && BetterIntro)
{
__instance.sceneChanger.AllowFinishLoadingScene();
__instance.startedSceneLoad = true;
__instance.loadingObject.SetActive(true);
IsReallyDoneLoading = true;
}
}
return false;
}
}
}
+1 -1
View File
@@ -9,6 +9,6 @@ public class VersionShowerPatch
[HarmonyPostfix]
public static void Postfix(VersionShower __instance)
{
__instance.text.text = $"<color=#0dff00>♻BetterAmongUs♻ {Main.GetVersionText()}</color> - " + __instance.text.text;
__instance.text.text = $"<color=#0dff00>♻BetterAmongUs♻ {Main.GetVersionText()}</color> - " + __instance.text.text;
}
}
+22 -7
View File
@@ -24,11 +24,11 @@ public class Main : BasePlugin
{
public const ReleaseTypes ReleaseBuildType = ReleaseTypes.Release;
public const string CanaryNum = "0";
public const string HotfixNum = "2";
public const bool IsHotFix = true;
public const string HotfixNum = "0";
public const bool IsHotFix = false;
public const string PluginGuid = "com.d1gq.betteramongus";
public const string PluginVersion = "1.0.4";
public const string ReleaseDate = "08.20.2024"; // mm/dd/yyyy
public const string PluginVersion = "1.1.0";
public const string ReleaseDate = "08.24.2024"; // mm/dd/yyyy
public const string Github = "https://github.com/D1GQ/BetterAmongUs-Public";
public const string Discord = "https://discord.gg/vjYrXpzNAn";
@@ -99,7 +99,7 @@ public class Main : BasePlugin
public static PlayerControl[] AllAlivePlayerControls => AllPlayerControls.ToArray().Where(pc => pc.IsAlive()).ToArray();
public static Dictionary<int, string> GetRoleName = new Dictionary<int, string>
public static Dictionary<int, string> GetRoleName => new Dictionary<int, string>
{
{ 0, "Crewmate" },
{ 1, "Impostor" },
@@ -114,6 +114,21 @@ public class Main : BasePlugin
{ 10, "Tracker" }
};
public static Dictionary<int, string> GetRoleColor => new Dictionary<int, string>
{
{ 0, "#8cffff" },
{ 1, "#f00202" },
{ 2, "#00d9d9" },
{ 3, "#8f8f8f" },
{ 4, "#8cffff" },
{ 5, "#f06102" },
{ 6, "#8cffff" },
{ 7, "#f00202" },
{ 8, "#fc7c7c" },
{ 9, "#d100b9" },
{ 10, "#59f002" }
};
public static ManualLogSource Logger;
public static DebugMenu debugmenu { get; set; } = null;
@@ -161,7 +176,7 @@ public class Main : BasePlugin
public static ConfigEntry<bool> BetterHost { get; private set; }
public static ConfigEntry<bool> BetterRoleAlgorithma { get; private set; }
public static ConfigEntry<bool> BetterNotifications { get; private set; }
public static ConfigEntry<bool> UseBannedList { get; private set; }
public static ConfigEntry<bool> ChatInGameplay { get; private set; }
public static ConfigEntry<bool> LobbyPlayerInfo { get; private set; }
public static ConfigEntry<bool> DisableLobbyTheme { get; private set; }
public static ConfigEntry<bool> UnlockFPS { get; private set; }
@@ -173,7 +188,7 @@ public class Main : BasePlugin
BetterHost = Config.Bind("Better Options", "BetterHost", false);
BetterRoleAlgorithma = Config.Bind("Better Options", "BetterRoleAlgorithma", true);
BetterNotifications = Config.Bind("Better Options", "BetterNotifications", true);
UseBannedList = Config.Bind("Better Options", "UseBannedList", true);
ChatInGameplay = Config.Bind("Better Options", "ChatInGameplay", true);
LobbyPlayerInfo = Config.Bind("Better Options", "LobbyPlayerInfo", true);
DisableLobbyTheme = Config.Bind("Better Options", "DisableLobbyTheme", true);
UnlockFPS = Config.Bind("Better Options", "UnlockFPS", false);