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
+}