From 62b6e328d56768ee3ba4f15f2aa98fd0f5e42b7d Mon Sep 17 00:00:00 2001 From: D1GQ <83262852+D1GQ@users.noreply.github.com> Date: Tue, 17 Mar 2026 14:20:19 -0500 Subject: [PATCH] Add xml back to HandshakeHandler --- src/Modules/HandshakeHandler.cs | 60 +++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/src/Modules/HandshakeHandler.cs b/src/Modules/HandshakeHandler.cs index 3bd3889..2db7f3b 100644 --- a/src/Modules/HandshakeHandler.cs +++ b/src/Modules/HandshakeHandler.cs @@ -1,4 +1,4 @@ -using BepInEx.Unity.IL2CPP.Utils; +using BepInEx.Unity.IL2CPP.Utils; using BetterAmongUs.Data; using BetterAmongUs.Data.Config; using BetterAmongUs.Enums; @@ -12,6 +12,9 @@ using UnityEngine; namespace BetterAmongUs.Modules; +/// +/// Handles the secure handshake process between BetterAmongUs clients using Diffie-Hellman key exchange. +/// internal sealed class HandshakeHandler { [HideFromIl2Cpp] @@ -23,11 +26,17 @@ internal sealed class HandshakeHandler [HideFromIl2Cpp] private ExtendedPlayerInfo extendedData { get; } + /// + /// Initiates the wait period before sending the secret to another player. + /// internal void WaitSendSecretToPlayer() { extendedData.StartCoroutine(CoWaitSendSecretToPlayer()); } + /// + /// Coroutine that waits for player initialization before sending the secret. + /// private IEnumerator CoWaitSendSecretToPlayer() { if (!BAUConfigs.SendBetterRpc.Value) yield break; @@ -42,6 +51,9 @@ internal sealed class HandshakeHandler SendSecretToPlayer(); } + /// + /// Resends the secret to the player if not already verified. + /// internal void ResendSecretToPlayer() { if (!BAUConfigs.SendBetterRpc.Value) return; @@ -51,6 +63,10 @@ internal sealed class HandshakeHandler SendSecretToPlayer(); } + /// + /// Sends the local client's public key and temporary key to another player. + /// + // Local client sends to client private void SendSecretToPlayer() { if (extendedData._Data.Object.IsLocalPlayer()) return; @@ -66,6 +82,11 @@ internal sealed class HandshakeHandler }, extendedData._Data.ClientId); } + /// + /// Handles receiving a secret from another player and generates a shared secret. + /// + /// MessageReader containing the sender's public key and temporary key. + // Client receives from local client internal void HandleSecretFromSender(MessageReader reader) { if (extendedData._Data?.Object?.IsLocalPlayer() == true) return; @@ -74,11 +95,17 @@ internal sealed class HandshakeHandler byte[] sendersPublicKey = reader.ReadBytes(); int tempKey = reader.ReadInt32(); + // Logger.Log($"Received public key ({sendersPublicKey.Length} bytes) from {_Data.PlayerName}"); + SharedSecret.UseFallback = !senderSupportsCrypto; SharedSecret.SetRemoteTempKey(tempKey); byte[] secret = SharedSecret.GenerateSharedSecret(sendersPublicKey); - if (secret.Length == 0) return; + if (secret.Length == 0) + { + // Logger.Error("Failed to generate shared secret!"); + return; + } extendedData.IsBetterUser = true; @@ -87,11 +114,18 @@ internal sealed class HandshakeHandler ResendSecretToPlayer(); } + /// + /// Sends the hash of the generated shared secret back to the original sender for verification. + /// + /// The temporary key received from the sender. + /// The client ID of the sender. + // Client sends back to local client private void SendSecretHashToSender(int tempKey, int senderClientId) { if (!BAUConfigs.SendBetterRpc.Value) return; int hash = SharedSecret.GetSharedSecretHash(); + // Logger.Log($"Sending secret hash: {hash} (tempKey: {tempKey})"); RPC.SendCustomRpcPacked(CustomRPC.CheckSecretHashFromPlayer, writer => { @@ -100,6 +134,10 @@ internal sealed class HandshakeHandler }, senderClientId); } + /// + /// Handles receiving a secret hash from another player for verification. + /// + /// MessageReader containing the temporary key and hash. internal void HandleSecretHashFromPlayer(MessageReader reader) { int tempKey = reader.ReadInt32(); @@ -109,6 +147,9 @@ internal sealed class HandshakeHandler TryHandlePendingVerificationData(); } + /// + /// Attempts to verify pending handshake data if all required information is available. + /// internal void TryHandlePendingVerificationData() { if (!_pendingVerificationData.HasValue) return; @@ -116,14 +157,24 @@ internal sealed class HandshakeHandler var data = _pendingVerificationData.Value; + // Logger.Log($"Received hash check: TempKey={data.tempKey} (ours={SharedSecret.GetTempKey()}), Hash={data.receivedHash} (ours={SharedSecret.GetSharedSecretHash()})"); + if (data.tempKey != SharedSecret.GetTempKey()) + { + // Logger.Warning($"Invalid tempKey from {extendedData._Data?.PlayerName}"); return; + } extendedData.IsBetterUser = true; if (data.receivedHash == SharedSecret.GetSharedSecretHash()) { extendedData.IsVerifiedBetterUser = true; + // Logger.Log($"Verified player: {extendedData._Data?.PlayerName}"); + } + else + { + // Logger.Warning($"Hash mismatch from {extendedData._Data?.PlayerName}"); } _pendingVerificationData = null; @@ -132,5 +183,8 @@ internal sealed class HandshakeHandler private (int tempKey, int receivedHash)? _pendingVerificationData = null; private bool HasSendSharedSecret { get; set; } + /// + /// Gets the SharedSecretExchange instance for secure key exchange. + /// internal SharedSecretExchange SharedSecret { get; set; } = new(); -} \ No newline at end of file +}