mirror of
https://github.com/D1GQ/BetterAmongUs.git
synced 2026-10-20 01:46:19 +00:00
Improved better host validation checks
This commit is contained in:
1 parent
5e0a3b1572
commit
d16b389367
3 files changed
+188
-7
No files matched your search
@@ -1,13 +1,119 @@
|
||||
using AmongUs.GameOptions;
|
||||
using Hazel;
|
||||
using InnerNet;
|
||||
using UnityEngine;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterAmongUs;
|
||||
|
||||
class BetterHostManager
|
||||
{
|
||||
public static Dictionary<byte, Dictionary<byte, string>> LastPlayerName = []; // Targetid, Playerid, Name
|
||||
private static Dictionary<byte, Dictionary<byte, string>> LastPlayerName = []; // Targetid, Playerid, Name
|
||||
private static Dictionary<PlayerControl, Vector2> LastPlayerPos = [];
|
||||
private static Dictionary<PlayerControl, Vector2> LastPlayerPosDelay = [];
|
||||
private static Dictionary<PlayerControl, float> LastPlayeridealSpeed = [];
|
||||
private static Dictionary<PlayerControl, ushort> LastPlayerMoveSequence = [];
|
||||
private static List<PlayerControl> VentStuck = [];
|
||||
|
||||
public static void Update(PlayerControl player)
|
||||
{
|
||||
if (!Main.BetterHost.Value) return;
|
||||
|
||||
var idealSpeed = player.NetTransform.idealSpeed;
|
||||
|
||||
if (player.CanMove && IsSpeedExceeding(idealSpeed) == true)
|
||||
{
|
||||
if (LastPlayerPosDelay.ContainsKey(player) && LastPlayeridealSpeed.ContainsKey(player))
|
||||
{
|
||||
if (idealSpeed > LastPlayeridealSpeed[player] - 0.5f)
|
||||
{
|
||||
player.RpcTeleport(LastPlayerPosDelay[player]);
|
||||
player.NetTransform.idealSpeed = 0f;
|
||||
Logger.Log($"invalid move speed {idealSpeed} is > {GetAverageSpeed()}, reset {player.Data.PlayerName} pos:{player.GetCustomPosition()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LastPlayeridealSpeed[player] = player.NetTransform.idealSpeed;
|
||||
|
||||
_ = new LateTask(() =>
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
LastPlayerPosDelay[player] = player.GetCustomPosition();
|
||||
}
|
||||
}, 1.25f, shoudLog: false);
|
||||
|
||||
if (GameStates.IsInGamePlay)
|
||||
{
|
||||
if (player.CanMove)
|
||||
{
|
||||
LastPlayerPos[player] = player.GetCustomPosition();
|
||||
LastPlayerMoveSequence[player] = player.NetTransform.lastSequenceId;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player.shapeshifting)
|
||||
{
|
||||
if (LastPlayerPos.ContainsKey(player))
|
||||
{
|
||||
if (LastPlayerMoveSequence[player] + 6 < player.NetTransform.lastSequenceId)
|
||||
{
|
||||
player.RpcTeleport(LastPlayerPos[player]);
|
||||
Logger.Log($"invalid move sequence, reset {player.Data.PlayerName} pos:{player.GetCustomPosition()}");
|
||||
LastPlayerMoveSequence[player] = (ushort)(player.NetTransform.lastSequenceId - 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!VentStuck.Contains(player) && player.inVent && player.Data.RoleType != RoleTypes.Engineer && !player.IsImpostorTeam())
|
||||
{
|
||||
player.MyPhysics.RpcEnterVent(player.GetPlayerVentId());
|
||||
player.MyPhysics.RpcBootFromVent(player.GetPlayerVentId());
|
||||
VentStuck.Add(player);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsSpeedExceeding(float currentSpeed)
|
||||
{
|
||||
float leniency = 1.8f;
|
||||
float thresholdSpeed = GetAverageSpeed() + leniency;
|
||||
bool isExceeding = currentSpeed > thresholdSpeed;
|
||||
return isExceeding;
|
||||
}
|
||||
|
||||
public static float GetAverageSpeed()
|
||||
{
|
||||
float speedMod = GameStates.IsHideNSeek
|
||||
? GameOptionsManager.Instance.currentHideNSeekGameOptions.PlayerSpeedMod
|
||||
: GameOptionsManager.Instance.currentNormalGameOptions.PlayerSpeedMod;
|
||||
|
||||
// Data points
|
||||
float[] mods = { 0.5f, 1.5f, 2.0f }; // Add more as needed
|
||||
float[] avgSpeeds = { 1.3f, 3.75f, 5.0f }; // Add corresponding speeds
|
||||
|
||||
int n = mods.Length;
|
||||
float sumMod = 0, sumAvgSpeed = 0, sumModAvgSpeed = 0, sumModSquared = 0;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
sumMod += mods[i];
|
||||
sumAvgSpeed += avgSpeeds[i];
|
||||
sumModAvgSpeed += mods[i] * avgSpeeds[i];
|
||||
sumModSquared += mods[i] * mods[i];
|
||||
}
|
||||
|
||||
float m = (n * sumModAvgSpeed - sumMod * sumAvgSpeed) / (n * sumModSquared - sumMod * sumMod);
|
||||
float c = (sumAvgSpeed - m * sumMod) / n;
|
||||
|
||||
float estimatedAverageSpeed = m * speedMod + c;
|
||||
|
||||
return estimatedAverageSpeed;
|
||||
}
|
||||
|
||||
public static bool CheckRange(Vector2 pos1, Vector2 pos2, float range) => Vector2.Distance(pos1, pos2) <= range;
|
||||
|
||||
public static bool CheckRPCAsHost(PlayerControl player, byte callId, MessageReader reader, ref bool canceled)
|
||||
{
|
||||
@@ -22,7 +128,10 @@ class BetterHostManager
|
||||
PlayerControl target = reader.ReadNetObject<PlayerControl>();
|
||||
if (target != null)
|
||||
{
|
||||
if (player.Data.RoleType == RoleTypes.GuardianAngel && !player.IsAlive() && !player.IsImpostorTeam())
|
||||
if (player.Data.RoleType == RoleTypes.GuardianAngel
|
||||
&& !player.IsAlive()
|
||||
&& !player.IsImpostorTeam()
|
||||
&& CheckRange(player.GetCustomPosition(), target.GetCustomPosition(), 3f))
|
||||
{
|
||||
if (target.IsAlive())
|
||||
{
|
||||
@@ -39,11 +148,25 @@ class BetterHostManager
|
||||
case (byte)RpcCalls.CheckMurder:
|
||||
{
|
||||
PlayerControl target = reader.ReadNetObject<PlayerControl>();
|
||||
|
||||
if (target != null)
|
||||
{
|
||||
if (player.IsAlive() && player.IsImpostorTeam() && !player.inMovingPlat && !player.IsInVent() && !player.IsInVanish() && !player.shapeshifting && !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
|
||||
if (player.IsAlive()
|
||||
&& player.IsImpostorTeam()
|
||||
&& !player.inMovingPlat
|
||||
&& !player.IsInVent()
|
||||
&& !player.IsInVanish()
|
||||
&& !player.shapeshifting
|
||||
&& !player.onLadder
|
||||
&& !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation()
|
||||
&& CheckRange(player.GetCustomPosition(), target.GetCustomPosition(), 3f))
|
||||
{
|
||||
if (target.IsAlive() && !target.IsImpostorTeam() && !target.inMovingPlat && !target.IsInVent() && !target.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
|
||||
if (target.IsAlive()
|
||||
&& !target.IsImpostorTeam()
|
||||
&& !target.inMovingPlat
|
||||
&& !target.IsInVent()
|
||||
&& !target.onLadder
|
||||
&& !target.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
|
||||
{
|
||||
player.RpcMurderPlayer(target, true);
|
||||
break;
|
||||
@@ -62,7 +185,13 @@ class BetterHostManager
|
||||
|
||||
if (target != null)
|
||||
{
|
||||
if (player.Data.RoleType == RoleTypes.Shapeshifter && player.IsAlive() && player.IsImpostorTeam() && !player.inMovingPlat && !player.shapeshifting && !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
|
||||
if (player.Data.RoleType == RoleTypes.Shapeshifter
|
||||
&& player.IsAlive()
|
||||
&& player.IsImpostorTeam()
|
||||
&& !player.inMovingPlat
|
||||
&& !player.shapeshifting
|
||||
&& !player.onLadder
|
||||
&& !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
|
||||
{
|
||||
if (!target.IsInVent() && flag == false)
|
||||
{
|
||||
@@ -80,7 +209,13 @@ class BetterHostManager
|
||||
|
||||
case (byte)RpcCalls.CheckVanish:
|
||||
{
|
||||
if (player.Data.RoleType == RoleTypes.Phantom && player.IsAlive() && player.IsImpostorTeam() && !player.IsInVent() && !player.inMovingPlat && !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
|
||||
if (player.Data.RoleType == RoleTypes.Phantom
|
||||
&& player.IsAlive()
|
||||
&& player.IsImpostorTeam()
|
||||
&& !player.IsInVent()
|
||||
&& !player.inMovingPlat
|
||||
&& !player.onLadder
|
||||
&& !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
|
||||
{
|
||||
|
||||
if (AmongUsClient.Instance.AmClient)
|
||||
@@ -100,7 +235,11 @@ class BetterHostManager
|
||||
{
|
||||
bool flag = reader.ReadBoolean();
|
||||
|
||||
if (player.Data.RoleType == RoleTypes.Phantom && player.IsAlive() && player.IsImpostorTeam() && !player.inMovingPlat && !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
|
||||
if (player.Data.RoleType == RoleTypes.Phantom
|
||||
&& player.IsAlive() && player.IsImpostorTeam()
|
||||
&& !player.inMovingPlat
|
||||
&& !player.onLadder
|
||||
&& !player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
|
||||
{
|
||||
if (!player.IsInVent() && flag == false)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using AmongUs.GameOptions;
|
||||
using Hazel;
|
||||
using InnerNet;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
@@ -96,6 +97,44 @@ static class ExtendedPlayerControl
|
||||
if (player == null) return;
|
||||
RPC.ExileAsync(player);
|
||||
}
|
||||
public static void RpcTeleport(this PlayerControl player, Vector2 position)
|
||||
{
|
||||
|
||||
var cancelTeleport = false;
|
||||
|
||||
if (player.inVent || player.MyPhysics.Animations.IsPlayingEnterVentAnimation())
|
||||
{
|
||||
cancelTeleport = true;
|
||||
}
|
||||
else if (player.onLadder || player.MyPhysics.Animations.IsPlayingAnyLadderAnimation())
|
||||
{
|
||||
cancelTeleport = true;
|
||||
}
|
||||
else if (player.inMovingPlat)
|
||||
{
|
||||
cancelTeleport = true;
|
||||
}
|
||||
|
||||
if (cancelTeleport)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var netTransform = player.NetTransform;
|
||||
|
||||
if (AmongUsClient.Instance.AmClient)
|
||||
{
|
||||
// +328 because lastSequenceId has delay between the host and the vanilla client
|
||||
// And this cannot forced teleport the player
|
||||
netTransform.SnapTo(position, (ushort)(netTransform.lastSequenceId + 328));
|
||||
}
|
||||
|
||||
ushort newSid = (ushort)(netTransform.lastSequenceId + 8);
|
||||
MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(netTransform.NetId, (byte)RpcCalls.SnapTo, SendOption.Reliable);
|
||||
NetHelpers.WriteVector2(position, messageWriter);
|
||||
messageWriter.Write(newSid);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(messageWriter);
|
||||
}
|
||||
|
||||
public static bool IsInRoomSelect(this PlayerControl player)
|
||||
{
|
||||
|
||||
@@ -63,7 +63,10 @@ class PlayerControlPatch
|
||||
}
|
||||
|
||||
if (GameStates.IsInGame && GameStates.IsHost)
|
||||
{
|
||||
RPC.SyncAllNames(isBetterHost: false);
|
||||
BetterHostManager.Update(__instance);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetPlayerInfo(PlayerControl player)
|
||||
|
||||
Reference in new issue
Block a user