mirror of
https://github.com/D1GQ/BetterAmongUs.git
synced 2026-10-19 15:51:52 +00:00
rework bau Handshake
This commit is contained in:
1 parent
6277698f72
commit
29ad77aaa4
12 files changed
+338
-108
No files matched your search
@@ -0,0 +1,72 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace BetterAmongUs.Data;
|
||||
|
||||
internal class SharedSecretExchange
|
||||
{
|
||||
private readonly ECDiffieHellman dh;
|
||||
private byte[] publicKey;
|
||||
private int tempKey;
|
||||
private byte[] sharedSecret = [];
|
||||
|
||||
internal SharedSecretExchange()
|
||||
{
|
||||
dh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256);
|
||||
publicKey = dh.ExportSubjectPublicKeyInfo();
|
||||
var random = new Random();
|
||||
tempKey = random.Next();
|
||||
}
|
||||
|
||||
internal byte[] GetPublicKey()
|
||||
{
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
internal int GetTempKey()
|
||||
{
|
||||
return tempKey;
|
||||
}
|
||||
|
||||
internal byte[] GetSharedSecret() => sharedSecret;
|
||||
|
||||
internal byte[] GenerateSharedSecret(byte[] otherPartyPublicKey)
|
||||
{
|
||||
if (sharedSecret.Length > 0) return sharedSecret;
|
||||
|
||||
try
|
||||
{
|
||||
using ECDiffieHellman otherPartyDH = ECDiffieHellman.Create();
|
||||
otherPartyDH.ImportSubjectPublicKeyInfo(otherPartyPublicKey, out _);
|
||||
|
||||
sharedSecret = dh.DeriveKeyMaterial(otherPartyDH.PublicKey);
|
||||
dh.Dispose();
|
||||
return sharedSecret;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error generating shared secret: {ex.Message}");
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
internal int GetSharedSecretHash()
|
||||
{
|
||||
if (sharedSecret.Length == 0)
|
||||
return 0;
|
||||
|
||||
using SHA256 sha256 = SHA256.Create();
|
||||
byte[] hashBytes = sha256.ComputeHash(sharedSecret);
|
||||
int numericHash = BitConverter.ToInt32(hashBytes, 0);
|
||||
return Math.Abs(numericHash);
|
||||
}
|
||||
|
||||
internal bool HasBeenCleared { get; private set; }
|
||||
internal void ClearData()
|
||||
{
|
||||
if (HasBeenCleared) return;
|
||||
HasBeenCleared = true;
|
||||
publicKey = [];
|
||||
tempKey = 0;
|
||||
sharedSecret = [];
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,47 @@
|
||||
using BetterAmongUs.Modules;
|
||||
using BepInEx.Unity.IL2CPP.Utils;
|
||||
using BetterAmongUs.Modules;
|
||||
using HarmonyLib;
|
||||
using Il2CppInterop.Runtime.Attributes;
|
||||
using System.Collections;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BetterAmongUs.Helpers;
|
||||
|
||||
[MonoExtension(typeof(PlayerControl))]
|
||||
internal class ExtendedPlayerControl : MonoBehaviour, IMonoExtension
|
||||
internal class ExtendedPlayerControl : MonoBehaviour, IMonoExtension<PlayerControl>
|
||||
{
|
||||
public MonoBehaviour? BaseMono { get; set; }
|
||||
internal PlayerControl? _Player { get; set; }
|
||||
public PlayerControl? BaseMono { get; set; }
|
||||
internal PlayerControl? _Player => BaseMono;
|
||||
internal TextMeshPro? InfoTextInfo { get; set; }
|
||||
internal TextMeshPro? InfoTextTop { get; set; }
|
||||
internal TextMeshPro? InfoTextBottom { get; set; }
|
||||
|
||||
private void Start()
|
||||
private void Awake()
|
||||
{
|
||||
MonoExtensionManager.RegisterExtension(this);
|
||||
if (!MonoExtensionManager.RegisterExtension(this)) return;
|
||||
this.StartCoroutine(CoAddBetterData());
|
||||
}
|
||||
|
||||
[HideFromIl2Cpp]
|
||||
private IEnumerator CoAddBetterData()
|
||||
{
|
||||
while (_Player?.Data == null)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
TryCreateExtendedData(_Player.Data);
|
||||
_Player.DirtyNameDelay();
|
||||
}
|
||||
|
||||
internal static void TryCreateExtendedData(NetworkedPlayerInfo data)
|
||||
{
|
||||
if (data.BetterData() == null)
|
||||
{
|
||||
ExtendedPlayerInfo newBetterData = data.gameObject.AddComponent<ExtendedPlayerInfo>();
|
||||
newBetterData.SetInfo(data);
|
||||
data.DirtyNameDelay(3f);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
@@ -64,7 +89,6 @@ internal static class PlayerControlExtension
|
||||
if (pc.BetterPlayerControl() == null)
|
||||
{
|
||||
ExtendedPlayerControl newExtendedPc = pc.gameObject.AddComponent<ExtendedPlayerControl>();
|
||||
newExtendedPc._Player = pc;
|
||||
newExtendedPc.InfoTextInfo = InfoText_Info_TMP;
|
||||
newExtendedPc.InfoTextTop = InfoText_T_TMP;
|
||||
newExtendedPc.InfoTextBottom = InfoText_B_TMP;
|
||||
|
||||
@@ -1,33 +1,38 @@
|
||||
using AmongUs.GameOptions;
|
||||
using BepInEx.Unity.IL2CPP.Utils;
|
||||
using BetterAmongUs.Items;
|
||||
using BetterAmongUs.Managers;
|
||||
using BetterAmongUs.Modules;
|
||||
using HarmonyLib;
|
||||
using InnerNet;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BetterAmongUs.Helpers;
|
||||
|
||||
[MonoExtension(typeof(NetworkedPlayerInfo))]
|
||||
internal class ExtendedPlayerInfo : MonoBehaviour, IMonoExtension
|
||||
internal class ExtendedPlayerInfo : MonoBehaviour, IMonoExtension<NetworkedPlayerInfo>
|
||||
{
|
||||
public MonoBehaviour? BaseMono { get; set; }
|
||||
internal ExtendedPlayerInfo()
|
||||
{
|
||||
HandshakeHandler = new(this);
|
||||
}
|
||||
|
||||
public NetworkedPlayerInfo? BaseMono { get; set; }
|
||||
internal NetworkedPlayerInfo? _Data => BaseMono;
|
||||
|
||||
private bool hasSet = false;
|
||||
internal void SetInfo(NetworkedPlayerInfo data)
|
||||
{
|
||||
if (hasSet) return;
|
||||
MyUserData = UserData.GetPlayerUserData(data);
|
||||
_Data = data;
|
||||
_PlayerId = data.PlayerId;
|
||||
hasSet = true;
|
||||
}
|
||||
|
||||
private float timeAccumulator = 0f;
|
||||
|
||||
private void Start()
|
||||
private void Awake()
|
||||
{
|
||||
MonoExtensionManager.RegisterExtension(this);
|
||||
if (!MonoExtensionManager.RegisterExtension(this)) return;
|
||||
this.StartCoroutine(HandshakeHandler.CoSendSecretToPlayer());
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
@@ -73,9 +78,9 @@ internal class ExtendedPlayerInfo : MonoBehaviour, IMonoExtension
|
||||
}
|
||||
}
|
||||
|
||||
internal HandshakeHandler HandshakeHandler { get; }
|
||||
internal UserData? MyUserData { get; private set; } = UserData.AllUsers.First();
|
||||
internal byte _PlayerId { get; private set; }
|
||||
internal NetworkedPlayerInfo? _Data { get; private set; }
|
||||
internal string? RealName { get; private set; }
|
||||
internal bool IsDirtyInfo { get; set; } = true;
|
||||
internal Dictionary<byte, string> LastNameSetFor { get; set; } = [];
|
||||
@@ -112,42 +117,6 @@ internal class ExtendedRoleInfo
|
||||
|
||||
internal static class PlayerControlDataExtension
|
||||
{
|
||||
[HarmonyPatch(typeof(NetworkedPlayerInfo))]
|
||||
class NetworkedPlayerInfoPatch
|
||||
{
|
||||
[HarmonyPatch(nameof(NetworkedPlayerInfo.Init))]
|
||||
[HarmonyPostfix]
|
||||
internal static void Init_Postfix(NetworkedPlayerInfo __instance)
|
||||
{
|
||||
TryCreateExtendedData(__instance);
|
||||
}
|
||||
|
||||
[HarmonyPatch(nameof(NetworkedPlayerInfo.Serialize))]
|
||||
[HarmonyPostfix]
|
||||
internal static void Serialize_Postfix(NetworkedPlayerInfo __instance)
|
||||
{
|
||||
__instance.DirtyNameDelay();
|
||||
}
|
||||
|
||||
[HarmonyPatch(nameof(NetworkedPlayerInfo.Deserialize))]
|
||||
[HarmonyPostfix]
|
||||
internal static void Deserialize_Postfix(NetworkedPlayerInfo __instance)
|
||||
{
|
||||
TryCreateExtendedData(__instance);
|
||||
__instance.DirtyNameDelay();
|
||||
}
|
||||
|
||||
internal static void TryCreateExtendedData(NetworkedPlayerInfo data)
|
||||
{
|
||||
if (data.BetterData() == null)
|
||||
{
|
||||
ExtendedPlayerInfo newBetterData = data.gameObject.AddComponent<ExtendedPlayerInfo>();
|
||||
newBetterData.SetInfo(data);
|
||||
data.DirtyNameDelay(3f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get BetterData from PlayerControl
|
||||
internal static ExtendedPlayerInfo? BetterData(this PlayerControl player)
|
||||
{
|
||||
|
||||
@@ -62,6 +62,27 @@ static class InnerNetClientHelper
|
||||
return bools;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an array of bytes to a MessageWriter in a packed format, combining two bytes into one to save space.
|
||||
/// </summary>
|
||||
internal static void WriteBytes(this MessageWriter writer, IEnumerable<byte> bytesEnumerable)
|
||||
{
|
||||
byte[] bytes = bytesEnumerable.ToArray();
|
||||
|
||||
writer.Write(bytes.Length);
|
||||
writer.Write(bytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an array of bytes from a MessageReader that were previously packed using WritePackedBytes.
|
||||
/// </summary>
|
||||
internal static byte[] ReadBytes(this MessageReader reader)
|
||||
{
|
||||
int count = reader.ReadInt32();
|
||||
var bytes = reader.ReadBytes(count);
|
||||
return [.. bytes];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an array of bytes to a MessageWriter in a packed format, combining two bytes into one to save space.
|
||||
/// </summary>
|
||||
|
||||
@@ -363,10 +363,13 @@ internal class NetworkManager
|
||||
|
||||
private static bool PlayerRpc(PlayerControl player, byte callId, MessageReader reader)
|
||||
{
|
||||
player.BetterData().AntiCheatInfo.RPCSentPS++;
|
||||
if (player.BetterData().AntiCheatInfo.RPCSentPS >= ExtendedAntiCheatInfo.MaxRPCSent)
|
||||
if (player.BetterData() != null)
|
||||
{
|
||||
return false;
|
||||
player.BetterData().AntiCheatInfo.RPCSentPS++;
|
||||
if (player.BetterData().AntiCheatInfo.RPCSentPS >= ExtendedAntiCheatInfo.MaxRPCSent)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BetterAntiCheat.HandleCheatRPCBeforeCheck(player, callId, reader);
|
||||
|
||||
@@ -106,7 +106,7 @@ internal static class GameState
|
||||
internal static bool IsHost => AmongUsClient.Instance != null && AmongUsClient.Instance.AmHost;
|
||||
internal static bool IsPrivateOnlyLobby => (Main.PrivateOnlyLobby.Value || AmongUsClient.Instance.AmLocalHost) && IsHost;
|
||||
internal static bool IsBetterHostLobby => PlayerControl.LocalPlayer.IsHost() || Main.AllPlayerControls.Any(pc => pc.IsHost() && pc.BetterData().IsBetterUser && pc.BetterData().IsVerifiedBetterUser);
|
||||
internal static bool IsTOHEHostLobby => Main.AllPlayerControls.Any(pc => pc.IsHost() && pc.BetterData().IsTOHEHost);
|
||||
internal static bool IsTOHEHostLobby => InGame && Main.AllPlayerControls.Any(pc => pc.IsHost() && pc.BetterData()?.IsTOHEHost == true);
|
||||
internal static bool IsCanMove => PlayerControl.LocalPlayer?.CanMove is true;
|
||||
internal static bool IsDead => PlayerControl.LocalPlayer?.Data?.IsDead is true;
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
using BetterAmongUs.Data;
|
||||
using BetterAmongUs.Helpers;
|
||||
using Hazel;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BetterAmongUs.Modules;
|
||||
|
||||
internal class HandshakeHandler(ExtendedPlayerInfo extendedPlayerInfo)
|
||||
{
|
||||
private readonly ExtendedPlayerInfo extendedData = extendedPlayerInfo;
|
||||
|
||||
internal IEnumerator CoSendSecretToPlayer()
|
||||
{
|
||||
if (!Main.SendBetterRpc.Value) yield break;
|
||||
|
||||
while (extendedData._Data?.Object == null || PlayerControl.LocalPlayer == null)
|
||||
{
|
||||
if (GameState.IsFreePlay) yield break;
|
||||
yield return null;
|
||||
}
|
||||
yield return new WaitForSeconds(1f);
|
||||
|
||||
SendSecretToPlayer();
|
||||
}
|
||||
|
||||
internal void ResendSecretToPlayer()
|
||||
{
|
||||
if (!Main.SendBetterRpc.Value) return;
|
||||
if (HasSendSharedSecret && extendedData.IsVerifiedBetterUser) return;
|
||||
|
||||
HasSendSharedSecret = false;
|
||||
SendSecretToPlayer();
|
||||
}
|
||||
|
||||
// Local client sends to client
|
||||
private void SendSecretToPlayer()
|
||||
{
|
||||
if (extendedData._Data.Object.IsLocalPlayer()) return;
|
||||
if (HasSendSharedSecret) return;
|
||||
|
||||
HasSendSharedSecret = true;
|
||||
var writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SendSecret, SendOption.Reliable, extendedData._Data.ClientId);
|
||||
writer.WriteBytes(SharedSecret.GetPublicKey());
|
||||
writer.Write(SharedSecret.GetTempKey());
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
|
||||
// Client receives from local client
|
||||
internal void HandleSecretFromSender(MessageReader reader)
|
||||
{
|
||||
if (extendedData._Data?.Object?.IsLocalPlayer() == true) return;
|
||||
|
||||
byte[] sendersPublicKey = reader.ReadBytes();
|
||||
int tempKey = reader.ReadInt32();
|
||||
|
||||
// Logger.Log($"Received public key ({sendersPublicKey.Length} bytes) from {_Data.PlayerName}");
|
||||
|
||||
byte[] secret = SharedSecret.GenerateSharedSecret(sendersPublicKey);
|
||||
if (secret.Length == 0)
|
||||
{
|
||||
// Logger.Error("Failed to generate shared secret!");
|
||||
return;
|
||||
}
|
||||
extendedData.IsBetterUser = true;
|
||||
TryHandlePendingVerificationData();
|
||||
extendedData._Data?.Object?.DirtyName();
|
||||
SendSecretHashToSender(tempKey, extendedData._Data.ClientId);
|
||||
ResendSecretToPlayer();
|
||||
}
|
||||
|
||||
// Client sends back to local client
|
||||
private void SendSecretHashToSender(int tempKey, int senderClientId)
|
||||
{
|
||||
if (!Main.SendBetterRpc.Value) return;
|
||||
|
||||
int hash = SharedSecret.GetSharedSecretHash();
|
||||
// Logger.Log($"Sending secret hash: {hash} (tempKey: {tempKey})");
|
||||
|
||||
var writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.CheckSecret, SendOption.Reliable, senderClientId);
|
||||
writer.Write(tempKey);
|
||||
writer.Write(hash);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
|
||||
internal void HandleSecretHashFromPlayer(MessageReader reader)
|
||||
{
|
||||
int tempKey = reader.ReadInt32();
|
||||
int receivedHash = reader.ReadInt32();
|
||||
_pendingVerificationData = (tempKey, receivedHash);
|
||||
TryHandlePendingVerificationData();
|
||||
}
|
||||
|
||||
internal void TryHandlePendingVerificationData()
|
||||
{
|
||||
if (_pendingVerificationData?.tempKey == null || _pendingVerificationData?.receivedHash == null) return;
|
||||
if (SharedSecret.GetSharedSecret().Length == 0) return;
|
||||
|
||||
var tempKey = _pendingVerificationData?.tempKey;
|
||||
var receivedHash = _pendingVerificationData?.receivedHash;
|
||||
|
||||
// Logger.Log($"Received hash check: TempKey={tempKey} (ours={SharedSecret.GetTempKey()}), Hash={receivedHash} (ours={SharedSecret.GetSharedSecretHash()})");
|
||||
|
||||
if (tempKey != SharedSecret.GetTempKey())
|
||||
{
|
||||
// Logger.Warning($"Invalid tempKey from {_Data.PlayerName}");
|
||||
return;
|
||||
}
|
||||
|
||||
extendedData.IsBetterUser = true;
|
||||
|
||||
if (receivedHash == SharedSecret.GetSharedSecretHash())
|
||||
{
|
||||
extendedData.IsVerifiedBetterUser = true;
|
||||
extendedData._Data.Object?.DirtyName();
|
||||
// Logger.Log($"Verified player: {_Data.PlayerName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Logger.Warning($"Hash mismatch from {_Data.PlayerName}");
|
||||
}
|
||||
|
||||
_pendingVerificationData = null;
|
||||
}
|
||||
|
||||
private (int tempKey, int receivedHash)? _pendingVerificationData = null;
|
||||
private bool HasSendSharedSecret { get; set; }
|
||||
internal SharedSecretExchange SharedSecret { get; set; } = new();
|
||||
}
|
||||
+41
-27
@@ -1,33 +1,32 @@
|
||||
using Il2CppInterop.Runtime;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BetterAmongUs.Modules;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
internal class MonoExtensionAttribute : Attribute
|
||||
{
|
||||
internal Type MonoType { get; }
|
||||
internal Il2CppSystem.Type MonoIl2CppType { get; }
|
||||
|
||||
internal MonoExtensionAttribute(Type monoType)
|
||||
{
|
||||
MonoType = monoType;
|
||||
MonoIl2CppType = Il2CppType.From(monoType);
|
||||
}
|
||||
}
|
||||
|
||||
internal interface IMonoExtension
|
||||
{
|
||||
MonoBehaviour? BaseMono { get; set; }
|
||||
}
|
||||
|
||||
internal interface IMonoExtension<T> : IMonoExtension where T : MonoBehaviour
|
||||
{
|
||||
new T? BaseMono { get; set; }
|
||||
|
||||
MonoBehaviour? IMonoExtension.BaseMono
|
||||
{
|
||||
get => BaseMono;
|
||||
set => BaseMono = value as T;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class MonoExtensionManager
|
||||
{
|
||||
private static readonly Dictionary<Type, List<ExtensionPair>> _extensionsByBaseType = [];
|
||||
|
||||
internal static T? Get<T>(MonoBehaviour mono) where T : class, IMonoExtension
|
||||
{
|
||||
if (mono == null) return null;
|
||||
|
||||
if (_extensionsByBaseType.TryGetValue(mono.GetType(), out var extensions))
|
||||
{
|
||||
foreach (var pair in extensions)
|
||||
@@ -62,40 +61,55 @@ internal static class MonoExtensionManager
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool RegisterExtension(IMonoExtension extension)
|
||||
internal static bool RegisterExtension(this IMonoExtension extension)
|
||||
{
|
||||
var monoAttribute = extension.GetType().GetCustomAttribute<MonoExtensionAttribute>();
|
||||
// Try to find IMonoExtension<T> implementation
|
||||
Type? genericInterface = extension.GetType()
|
||||
.GetInterfaces()
|
||||
.FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMonoExtension<>));
|
||||
|
||||
if (monoAttribute == null || !monoAttribute.MonoType.IsAssignableTo(typeof(MonoBehaviour)))
|
||||
if (genericInterface == null)
|
||||
{
|
||||
if (extension is MonoBehaviour mono)
|
||||
UnityEngine.Object.Destroy(mono);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get T from IMonoExtension<T>
|
||||
Type monoType = genericInterface.GetGenericArguments()[0];
|
||||
|
||||
if (!monoType.IsAssignableTo(typeof(MonoBehaviour)))
|
||||
{
|
||||
if (extension is MonoBehaviour mono)
|
||||
{
|
||||
UnityEngine.Object.Destroy(mono);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var monoBehaviour = extension as MonoBehaviour;
|
||||
if (monoBehaviour == null) return false;
|
||||
if (monoBehaviour == null)
|
||||
return false;
|
||||
|
||||
var baseComponent = monoBehaviour.GetComponent(monoAttribute.MonoIl2CppType) as MonoBehaviour;
|
||||
// Get the base component (including inactive ones)
|
||||
var baseComponent = monoBehaviour.GetComponentInChildren(Il2CppType.From(monoType), true) as MonoBehaviour;
|
||||
if (baseComponent == null)
|
||||
{
|
||||
UnityEngine.Object.Destroy(monoBehaviour);
|
||||
return false;
|
||||
}
|
||||
|
||||
var existingExtensions = monoBehaviour.GetComponents(Il2CppType.From(extension.GetType()));
|
||||
// Check for duplicate extensions (including inactive ones)
|
||||
var existingExtensions = monoBehaviour.GetComponentsInChildren(Il2CppType.From(extension.GetType()), true);
|
||||
if (existingExtensions.Length > 1)
|
||||
{
|
||||
UnityEngine.Object.Destroy(monoBehaviour);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_extensionsByBaseType.TryGetValue(monoAttribute.MonoType, out var extensions))
|
||||
// Register the extension
|
||||
if (!_extensionsByBaseType.TryGetValue(monoType, out var extensions))
|
||||
{
|
||||
extensions = [];
|
||||
_extensionsByBaseType[monoAttribute.MonoType] = extensions;
|
||||
_extensionsByBaseType[monoType] = extensions;
|
||||
}
|
||||
|
||||
extensions.Add(new ExtensionPair { Base = baseComponent, Extension = extension });
|
||||
@@ -104,7 +118,7 @@ internal static class MonoExtensionManager
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static void UnregisterExtension(IMonoExtension extension)
|
||||
internal static void UnregisterExtension(this IMonoExtension extension)
|
||||
{
|
||||
if (extension.BaseMono == null) return;
|
||||
|
||||
@@ -128,7 +142,7 @@ internal static class MonoExtensionManager
|
||||
|
||||
private struct ExtensionPair
|
||||
{
|
||||
public MonoBehaviour? Base;
|
||||
public IMonoExtension? Extension;
|
||||
internal MonoBehaviour? Base;
|
||||
internal IMonoExtension? Extension;
|
||||
}
|
||||
}
|
||||
+18
-14
@@ -1,5 +1,4 @@
|
||||
using BetterAmongUs.Helpers;
|
||||
using BetterAmongUs.Managers;
|
||||
using Hazel;
|
||||
|
||||
namespace BetterAmongUs.Modules;
|
||||
@@ -18,7 +17,9 @@ enum CustomRPC : int
|
||||
RequestRetryVersionCheck = 81,
|
||||
|
||||
//Better Among Us
|
||||
BetterCheck = 150,
|
||||
LegacyBetterCheck = 150,
|
||||
SendSecret,
|
||||
CheckSecret,
|
||||
}
|
||||
|
||||
enum HandleGameDataTags : byte
|
||||
@@ -48,17 +49,6 @@ internal static class RPC
|
||||
}
|
||||
}
|
||||
|
||||
internal static void RpcBetterCheck()
|
||||
{
|
||||
if (!Main.SendBetterRpc.Value) return;
|
||||
|
||||
MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.BetterCheck, SendOption.None, -1);
|
||||
messageWriter.Write(true);
|
||||
messageWriter.Write(Main.ModSignature.ToString());
|
||||
messageWriter.Write(Main.GetVersionText().Replace(" ", ""));
|
||||
AmongUsClient.Instance.FinishRpcImmediately(messageWriter);
|
||||
}
|
||||
|
||||
internal static void RpcSetNamePrivate(PlayerControl player, string name, PlayerControl target)
|
||||
{
|
||||
if (!GameState.IsHost || !GameState.IsVanillaServer)
|
||||
@@ -89,25 +79,29 @@ internal static class RPC
|
||||
|
||||
switch (callId)
|
||||
{
|
||||
case (byte)CustomRPC.BetterCheck:
|
||||
case (byte)CustomRPC.LegacyBetterCheck:
|
||||
{
|
||||
var SetBetterUser = reader.ReadBoolean();
|
||||
var Signature = reader.ReadString();
|
||||
var Version = reader.ReadString();
|
||||
var IsVerified = Signature == Main.ModSignature.ToString();
|
||||
|
||||
/*
|
||||
if (string.IsNullOrEmpty(Signature) || string.IsNullOrEmpty(Version))
|
||||
{
|
||||
BetterNotificationManager.NotifyCheat(player, $"Invalid Action RPC: {Enum.GetName((CustomRPC)callId)} called with invalid info");
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
player.BetterData().IsBetterUser = SetBetterUser;
|
||||
|
||||
/*
|
||||
if (IsVerified)
|
||||
{
|
||||
player.BetterData().IsVerifiedBetterUser = true;
|
||||
}
|
||||
*/
|
||||
|
||||
Logger.Log($"Received better user RPC from: {player.Data.PlayerName}:{player.Data.FriendCode}:{Utils.GetHashPuid(player)} - " +
|
||||
$"BetterUser: {SetBetterUser} - " +
|
||||
@@ -118,6 +112,16 @@ internal static class RPC
|
||||
Utils.DirtyAllNames();
|
||||
}
|
||||
break;
|
||||
case (byte)CustomRPC.SendSecret:
|
||||
{
|
||||
player.BetterData().HandshakeHandler.HandleSecretFromSender(reader);
|
||||
}
|
||||
break;
|
||||
case (byte)CustomRPC.CheckSecret:
|
||||
{
|
||||
player.BetterData().HandshakeHandler.HandleSecretHashFromPlayer(reader);
|
||||
}
|
||||
break;
|
||||
/*
|
||||
case (byte)CustomRPC.VersionCheck or (byte)CustomRPC.RequestRetryVersionCheck:
|
||||
if (player.IsHost())
|
||||
|
||||
@@ -64,7 +64,11 @@ internal static class OptionsMenuBehaviourPatch
|
||||
{
|
||||
if (GameState.IsInGame)
|
||||
{
|
||||
RPC.RpcBetterCheck();
|
||||
foreach (var player in Main.AllPlayerControls)
|
||||
{
|
||||
if (player.IsLocalPlayer()) continue;
|
||||
player.BetterData().HandshakeHandler.ResendSecretToPlayer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,13 +16,6 @@ class GamePlayManager
|
||||
[HarmonyPostfix]
|
||||
private static void Start_Postfix(/*LobbyBehaviour __instance*/)
|
||||
{
|
||||
_ = new LateTask(() =>
|
||||
{
|
||||
if (GameState.IsInGame)
|
||||
{
|
||||
RPC.RpcBetterCheck();
|
||||
}
|
||||
}, 1.5f, "LobbyBehaviourPatch SyncAllNames");
|
||||
}
|
||||
|
||||
// Disabled annoying music
|
||||
|
||||
@@ -38,9 +38,6 @@ internal static class OnPlayerJoinedPatch
|
||||
{
|
||||
var player = Utils.PlayerFromClientId(client.Id);
|
||||
|
||||
// Send Better Among Us Check RPC
|
||||
RPC.RpcBetterCheck();
|
||||
|
||||
// Auto ban player on ban list
|
||||
if (BetterGameSettings.UseBanPlayerList.GetBool())
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user