mirror of
https://github.com/D1GQ/BetterAmongUs.git
synced 2026-10-20 01:46:19 +00:00
Better desync method
This commit is contained in:
1 parent
31dfe39440
commit
d9d2f80afe
3 files changed
+56
-67
No files matched your search
@@ -178,57 +178,40 @@ internal static class InnerNetClientHelper
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the RPC desynchronization process for the given player, call ID, and send option.
|
||||
/// Sends an RPC message immediately to all clients that match the specified target criteria, bypassing standard
|
||||
/// synchronization mechanisms.
|
||||
/// </summary>
|
||||
/// <param name="client">The InnerNetClient instance.</param>
|
||||
/// <param name="playerNetId">The network ID of the player.</param>
|
||||
/// <param name="callId">The RPC call ID.</param>
|
||||
/// <param name="option">The send option for the RPC.</param>
|
||||
/// <param name="ignoreClientId">The client ID to ignore. Default is -1, which means no client is ignored.</param>
|
||||
/// <param name="clientCheck">Optional function to filter which clients receive the RPC.</param>
|
||||
/// <returns>A list of MessageWriter instances for the RPC calls.</returns>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// List<MessageWriter> messageWriter = AmongUsClient.Instance.StartRpcDesync(PlayerNetId, (byte)RpcCalls, SendOption, ClientId);
|
||||
/// messageWriter.ForEach(mW => mW.Write("RPC TEST"));
|
||||
/// AmongUsClient.Instance.FinishRpcDesync(messageWriter);
|
||||
/// </code>
|
||||
/// </example>
|
||||
internal static List<MessageWriter> StartRpcDesync(this InnerNetClient client, uint playerNetId, byte callId, SendOption option, int ignoreClientId = -1, Func<ClientData, bool>? clientCheck = null)
|
||||
/// <param name="client">The InnerNetClient instance used to send the RPC messages.</param>
|
||||
/// <param name="playerNetId">The network ID of the player on whose behalf the RPC is sent.</param>
|
||||
/// <param name="callId">The identifier for the RPC call to be executed.</param>
|
||||
/// <param name="option">The send option that determines how the message is delivered (e.g., reliability, ordering).</param>
|
||||
/// <param name="targetClients">A function that selects which clients should receive the RPC message. The RPC is sent only to clients for which
|
||||
/// this function returns <see langword="true"/>.</param>
|
||||
/// <param name="writeTo">An action that writes the RPC payload to the provided MessageWriter.</param>
|
||||
internal static void SendRpcImmediatelyDesync(this InnerNetClient client, uint playerNetId, RpcCalls callId, SendOption option, Func<ClientData, bool> targetClients, Action<MessageWriter> writeTo)
|
||||
{
|
||||
List<MessageWriter> messageWriters = [];
|
||||
|
||||
if (ignoreClientId < 0)
|
||||
foreach (var allClients in AmongUsClient.Instance.allClients)
|
||||
{
|
||||
messageWriters.Add(client.StartRpcImmediately(playerNetId, callId, option, -1));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var allClients in AmongUsClient.Instance.allClients.WhereIl2Cpp(c => c.Id != ignoreClientId))
|
||||
{
|
||||
if (clientCheck == null || clientCheck.Invoke(allClients))
|
||||
{
|
||||
messageWriters.Add(client.StartRpcImmediately(playerNetId, callId, option, allClients.Id));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!targetClients(allClients)) continue;
|
||||
|
||||
return messageWriters;
|
||||
client.SendRpcImmediately(playerNetId, callId, option, writeTo, allClients.Id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Completes and sends the RPC desynchronization messages.
|
||||
/// Sends a remote procedure call (RPC) message immediately to the specified player, using the provided message
|
||||
/// writer action and send option.
|
||||
/// </summary>
|
||||
/// <param name="client">The InnerNetClient instance.</param>
|
||||
/// <param name="messageWriters">The list of MessageWriters to finish and send.</param>
|
||||
internal static void FinishRpcDesync(this InnerNetClient client, List<MessageWriter> messageWriters)
|
||||
/// <param name="client">The InnerNetClient instance used to send the RPC message.</param>
|
||||
/// <param name="playerNetId">The network identifier of the target player to whom the RPC is sent.</param>
|
||||
/// <param name="callId">The identifier of the RPC call to invoke.</param>
|
||||
/// <param name="option">The send option that determines how the message is delivered (such as reliability or channel).</param>
|
||||
/// <param name="writeTo">An action that writes the RPC message content to the provided MessageWriter.</param>
|
||||
/// <param name="targetClientId">The client identifier of the specific target client. Use -1 to broadcast to all clients.</param>
|
||||
internal static void SendRpcImmediately(this InnerNetClient client, uint playerNetId, RpcCalls callId, SendOption option, Action<MessageWriter> writeTo, int targetClientId = -1)
|
||||
{
|
||||
foreach (var msg in messageWriters)
|
||||
{
|
||||
msg.EndMessage();
|
||||
msg.EndMessage();
|
||||
client.SendOrDisconnect(msg);
|
||||
msg.Recycle();
|
||||
}
|
||||
var writer = client.StartRpcImmediately(playerNetId, (byte)callId, option, targetClientId);
|
||||
writeTo(writer);
|
||||
client.FinishRpcImmediately(writer);
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -29,15 +29,15 @@ internal static class RPC
|
||||
/// <param name="targetClientId">The specific client ID to target, or -1 to broadcast to all clients.</param>
|
||||
internal static void SendCustomRpcPacked(CustomRPC customRPC, Action<MessageWriter> action, int targetClientId = -1)
|
||||
{
|
||||
var writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)RpcCalls.SetNamePlateStr, SendOption.Reliable, targetClientId);
|
||||
AmongUsClient.Instance.SendRpcImmediately(PlayerControl.LocalPlayer.NetId, RpcCalls.SetNamePlateStr, SendOption.Reliable, writer =>
|
||||
{
|
||||
writer.Write(DataManager.Player.Customization.NamePlate);
|
||||
writer.Write(PlayerControl.LocalPlayer.GetNextRpcSequenceId(RpcCalls.SetNamePlateStr));
|
||||
|
||||
writer.Write(DataManager.Player.Customization.NamePlate);
|
||||
writer.Write(PlayerControl.LocalPlayer.GetNextRpcSequenceId(RpcCalls.SetNamePlateStr));
|
||||
|
||||
writer.Write(CUSTOM_RPC_FLAG); // Flag to check if its a rpc packed into SetNamePlateStr
|
||||
writer.Write((byte)customRPC);
|
||||
action(writer);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
writer.Write(CUSTOM_RPC_FLAG); // Flag to check if its a rpc packed into SetNamePlateStr
|
||||
writer.Write((byte)customRPC);
|
||||
action(writer);
|
||||
}, targetClientId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -15,11 +15,14 @@ internal static class RoleManagerPatch
|
||||
internal static Dictionary<string, int> ImpostorMultiplier = []; // HashPuid, Multiplier
|
||||
private static readonly Random random = new();
|
||||
|
||||
// Check if client is not verified Better Among Us user
|
||||
static readonly Func<InnerNet.ClientData, bool> clientCheck = (clientData) =>
|
||||
// Check if client is verified Better Among Us user
|
||||
private static Func<InnerNet.ClientData, bool> SendTo(PlayerControl target)
|
||||
{
|
||||
return clientData?.BetterData()?.IsVerifiedBetterUser != true;
|
||||
};
|
||||
return (clientData) =>
|
||||
{
|
||||
return clientData.Id != target.GetClientId() && clientData?.BetterData()?.IsVerifiedBetterUser != true;
|
||||
};
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(RoleManager), nameof(RoleManager.SetRole))]
|
||||
[HarmonyPrefix]
|
||||
@@ -156,10 +159,11 @@ internal static class RoleManagerPatch
|
||||
{
|
||||
if (kvp.Key is not (RoleTypes.Phantom or RoleTypes.Viper))
|
||||
{
|
||||
List<MessageWriter> messageWriter = AmongUsClient.Instance.StartRpcDesync(pc.NetId, (byte)RpcCalls.SetRole, SendOption.None, pc.GetClientId(), clientCheck);
|
||||
messageWriter.ForEach(mW => mW.Write((ushort)RoleTypes.Impostor));
|
||||
messageWriter.ForEach(mW => mW.Write(false));
|
||||
AmongUsClient.Instance.FinishRpcDesync(messageWriter);
|
||||
AmongUsClient.Instance.SendRpcImmediatelyDesync(pc.NetId, RpcCalls.SetRole, SendOption.None, SendTo(pc), writer =>
|
||||
{
|
||||
writer.Write((ushort)RoleTypes.Impostor);
|
||||
writer.Write(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,10 +199,11 @@ internal static class RoleManagerPatch
|
||||
{
|
||||
if (kvp.Key is not RoleTypes.Noisemaker)
|
||||
{
|
||||
List<MessageWriter> messageWriter = AmongUsClient.Instance.StartRpcDesync(pc.NetId, (byte)RpcCalls.SetRole, SendOption.None, pc.GetClientId(), clientCheck);
|
||||
messageWriter.ForEach(mW => mW.Write((ushort)RoleTypes.Crewmate));
|
||||
messageWriter.ForEach(mW => mW.Write(false));
|
||||
AmongUsClient.Instance.FinishRpcDesync(messageWriter);
|
||||
AmongUsClient.Instance.SendRpcImmediatelyDesync(pc.NetId, RpcCalls.SetRole, SendOption.None, SendTo(pc), writer =>
|
||||
{
|
||||
writer.Write((ushort)RoleTypes.Crewmate);
|
||||
writer.Write(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,10 +357,11 @@ internal static class RoleManagerPatch
|
||||
// Desync ghost role to hide it from non-BAU players
|
||||
if (BetterGameSettings.DesyncRoles.GetBool())
|
||||
{
|
||||
List<MessageWriter> messageWriter = AmongUsClient.Instance.StartRpcDesync(player.NetId, (byte)RpcCalls.SetRole, SendOption.None, player.GetClientId(), clientCheck);
|
||||
messageWriter.ForEach(mW => mW.Write((ushort)player.Data.Role.DefaultGhostRole));
|
||||
messageWriter.ForEach(mW => mW.Write(false));
|
||||
AmongUsClient.Instance.FinishRpcDesync(messageWriter);
|
||||
AmongUsClient.Instance.SendRpcImmediatelyDesync(player.NetId, RpcCalls.SetRole, SendOption.None, SendTo(player), writer =>
|
||||
{
|
||||
writer.Write((ushort)player.Data.Role.DefaultGhostRole);
|
||||
writer.Write(false);
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Reference in new issue
Block a user