mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
even more improvements & fixes
This commit is contained in:
1 parent
e92042bf54
commit
69768032eb
12 files changed
+607
-107
No files matched your search
+11
-5
@@ -130,12 +130,10 @@ public static class BedWars
|
||||
.SetGameMode(gameMode);
|
||||
|
||||
TNTDamageOption = new IntegerOptionItem(id++, "BedWars.TNTDamageOption", new(1, 100, 1), 20, tab)
|
||||
.SetValueFormat(OptionFormat.Multiplier)
|
||||
.SetColor(color)
|
||||
.SetGameMode(gameMode);
|
||||
|
||||
TNTBedDamageOption = new IntegerOptionItem(id++, "BedWars.TNTBedDamageOption", new(1, 100, 1), 10, tab)
|
||||
.SetValueFormat(OptionFormat.Multiplier)
|
||||
.SetColor(color)
|
||||
.SetGameMode(gameMode);
|
||||
|
||||
@@ -392,6 +390,7 @@ public static class BedWars
|
||||
|
||||
pc.RpcSetColor(team.GetColorId());
|
||||
pc.TP(data.Base.SpawnPosition);
|
||||
pc.RpcResetAbilityCooldown();
|
||||
|
||||
Data[pc.PlayerId] = data;
|
||||
|
||||
@@ -502,7 +501,7 @@ public static class BedWars
|
||||
(MapNames.MiraHQ, SystemTypes.Balcony) => pos.y < 2f,
|
||||
(MapNames.Polus, SystemTypes.LifeSupp) => room != null && room.RoomId == SystemTypes.BoilerRoom,
|
||||
(MapNames.Airship, SystemTypes.CargoBay) => room != null && room.RoomId == SystemTypes.Ventilation,
|
||||
(MapNames.Airship, SystemTypes.MeetingRoom) => room != null && room.RoomId == SystemTypes.GapRoom,
|
||||
(MapNames.Airship, SystemTypes.MeetingRoom) => (room != null && room.RoomId == SystemTypes.GapRoom) || __instance.inMovingPlat || __instance.onLadder || __instance.MyPhysics.Animations.IsPlayingAnyLadderAnimation(),
|
||||
(MapNames.Fungle, SystemTypes.Kitchen) => room != null && room.RoomId == SystemTypes.FishingDock,
|
||||
(MapNames.Fungle, SystemTypes.Comms) => pos is { y: > 8f, x: > 19f },
|
||||
(MapNames.Fungle, SystemTypes.Jungle) => pos is { x: > 10f, y: < -11f },
|
||||
@@ -1394,6 +1393,13 @@ public static class BedWars
|
||||
|
||||
Vector2 pos = pc.Pos();
|
||||
bool nextToBed = AllNetObjects.FindFirst(x => !x.Value.Bed.IsBroken && Vector2.Distance(x.Value.Bed.Position, pos) <= BedBreakAndProtectRange, out KeyValuePair<BedWarsTeam, NetObjectCollection> bed);
|
||||
|
||||
if (SelectedSlot < 0 || SelectedSlot >= Items.Count)
|
||||
{
|
||||
if (nextToBed) bed.Value.Bed.TryBreak(pc);
|
||||
return;
|
||||
}
|
||||
|
||||
KeyValuePair<Item, int> selected = Items.ElementAt(SelectedSlot);
|
||||
|
||||
Logger.Info($"Use selected item {selected.Key} with count {selected.Value} at position {pos} by player {pc.GetRealName()} (next to bed: {nextToBed})", "BedWars");
|
||||
@@ -1696,6 +1702,8 @@ public static class BedWars
|
||||
|
||||
public static void ApplyGameOptions(IGameOptions opt, byte playerId)
|
||||
{
|
||||
AURoleOptions.PhantomCooldown = 0.1f;
|
||||
|
||||
try { AURoleOptions.GuardianAngelCooldown = 900f; }
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
|
||||
@@ -1705,8 +1713,6 @@ public static class BedWars
|
||||
opt.SetFloat(FloatOptionNames.CrewLightMod, TrappedVision);
|
||||
opt.SetFloat(FloatOptionNames.ImpostorLightMod, TrappedVision);
|
||||
}
|
||||
|
||||
AURoleOptions.PhantomCooldown = 0.1f;
|
||||
}
|
||||
|
||||
public static bool CanUseImpostorVentButton(PlayerControl pc)
|
||||
|
||||
+448
-23
@@ -14,6 +14,7 @@ internal static class EAC
|
||||
{
|
||||
public static int DeNum;
|
||||
public static readonly HashSet<string> InvalidReports = [];
|
||||
public static readonly Dictionary<byte, float> TimeSinceLastTaskCompletion = [];
|
||||
|
||||
public static void WarnHost(int denum = 1)
|
||||
{
|
||||
@@ -37,6 +38,7 @@ internal static class EAC
|
||||
if (pc == null || reader == null) return false;
|
||||
|
||||
MessageReader sr = MessageReader.Get(reader);
|
||||
bool gameStarted = AmongUsClient.Instance.GameState is InnerNetClient.GameStates.Started or InnerNetClient.GameStates.Ended;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -67,7 +69,8 @@ internal static class EAC
|
||||
text.Contains('█') ||
|
||||
text.Contains('▌') ||
|
||||
text.Contains('▒') ||
|
||||
text.Contains("习近平"))
|
||||
text.Contains("习近平") ||
|
||||
(!pc.IsModdedClient() && text.Length > 100))
|
||||
{
|
||||
Report(pc, "Illegal messages");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent an illegal message, which has been rejected", "EAC");
|
||||
@@ -95,8 +98,6 @@ internal static class EAC
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Try to Report body out of game B");
|
||||
HandleCheat(pc, "Try to Report body out of game B");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] attempted to report a body that may have been illegally killed, but was rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
@@ -193,10 +194,23 @@ internal static class EAC
|
||||
return true;
|
||||
}
|
||||
|
||||
byte colorId = sr.ReadByte();
|
||||
|
||||
if (colorId > 17)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Invalid color");
|
||||
HandleCheat(pc, "Invalid color");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent invalid color {colorId}, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RpcCalls.SetColor when !pc.IsModdedClient() && (!Options.PlayerCanSetColor.GetBool() || !GameStates.IsLobby):
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Directly SetColor");
|
||||
HandleCheat(pc, "Directly SetColor");
|
||||
Logger.Fatal($"Directly SetColor【{pc.OwnerId}:{pc.GetRealName()}】has been rejected", "EAC");
|
||||
@@ -220,6 +234,7 @@ internal static class EAC
|
||||
case RpcCalls.MurderPlayer:
|
||||
{
|
||||
var target = sr.ReadNetObject<PlayerControl>();
|
||||
var resultFlags = (MurderResultFlags)sr.ReadInt32();
|
||||
|
||||
if (GameStates.IsLobby)
|
||||
{
|
||||
@@ -230,32 +245,57 @@ internal static class EAC
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!resultFlags.HasFlag(MurderResultFlags.FailedError) && !resultFlags.HasFlag(MurderResultFlags.FailedProtected) && target != null)
|
||||
LateTask.New(() => target.RpcRevive(), 0.1f, log: false);
|
||||
|
||||
Report(pc, "Directly Murder Player");
|
||||
HandleCheat(pc, "Directly Murder Player");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] directly killed, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
|
||||
LateTask.New(() =>
|
||||
{
|
||||
foreach (PlayerControl player in new[] { pc, target })
|
||||
{
|
||||
if (player.IsAlive() && player.Data.IsDead)
|
||||
player.RpcChangeRoleBasis(player.GetRoleMap().CustomRole);
|
||||
}
|
||||
}, 1f, "force revive after hack");
|
||||
return true;
|
||||
}
|
||||
case RpcCalls.CheckShapeshift:
|
||||
{
|
||||
if (GameStates.IsLobby)
|
||||
var target = sr.ReadNetObject<PlayerControl>();
|
||||
bool animate = sr.ReadBoolean();
|
||||
|
||||
if (!gameStarted)
|
||||
{
|
||||
Report(pc, "Lobby Check Shapeshift");
|
||||
HandleCheat(pc, "Lobby Check Shapeshift");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] directly transformed in lobby, rejected", "EAC");
|
||||
WarnHost();
|
||||
Report(pc, "Using shift button in lobby");
|
||||
HandleCheat(pc, "Using shift button in lobby");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent CheckShapeshift in lobby, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target != null && target != pc && !animate)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "No shapeshift animation");
|
||||
HandleCheat(pc, "No shapeshift animation");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent CheckShapeshift with no animation, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pc.shapeshiftTargetPlayerId != -1 && target != null && target != pc)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Shapeshifting while shapeshifted");
|
||||
HandleCheat(pc, "Shapeshifting while shapeshifted");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent CheckShapeshift while shapeshifted, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance) && target != pc)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Trying to shift during meeting");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RpcCalls.Shapeshift when !pc.IsHost():
|
||||
@@ -283,13 +323,38 @@ internal static class EAC
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
case RpcCalls.CompleteTask when GameStates.IsMeeting && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating && !pc.IsHost() && !(Main.CurrentMap == MapNames.Airship && ExileController.Instance):
|
||||
case RpcCalls.CompleteTask:
|
||||
{
|
||||
Report(pc, "Complete Task in Meeting");
|
||||
HandleCheat(pc, "Complete Task in Meeting");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] completed a task in a meeting, which has been rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
if (!gameStarted)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "CompleteTask Rpc in lobby");
|
||||
HandleCheat(pc, "CompleteTask Rpc in lobby");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent CompleteTask RPC in lobby, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TimeSinceLastTaskCompletion.TryGetValue(pc.PlayerId, out float time) && time < 0.1f)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Auto complete tasks");
|
||||
HandleCheat(pc, "Auto complete tasks");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent CompleteTask RPC too fast, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Doing task during meeting");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
TimeSinceLastTaskCompletion[pc.PlayerId] = 0f;
|
||||
break;
|
||||
}
|
||||
case RpcCalls.SetStartCounter:
|
||||
{
|
||||
@@ -318,6 +383,292 @@ internal static class EAC
|
||||
|
||||
break;
|
||||
}
|
||||
case RpcCalls.CheckVanish:
|
||||
{
|
||||
if (!gameStarted)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Using vanish button in lobby");
|
||||
HandleCheat(pc, "Using vanish button in lobby");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent CheckVanish in lobby, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Trying to vanish during meeting");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RpcCalls.CheckAppear:
|
||||
{
|
||||
if (!gameStarted)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Using appear button in lobby");
|
||||
HandleCheat(pc, "Using appear button in lobby");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] tried to appear in lobby, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Trying to appear during meeting");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RpcCalls.PlayAnimation:
|
||||
{
|
||||
if (!gameStarted)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "PlayAnimation Rpc in lobby");
|
||||
HandleCheat(pc, "PlayAnimation Rpc in lobby");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent PlayAnimation RPC in lobby, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!GameManager.Instance.LogicOptions.GetVisualTasks())
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "PlayAnimation Rpc with visuals off");
|
||||
HandleCheat(pc, "PlayAnimation Rpc with visuals off");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent PlayAnimation RPC with visuals off, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "PlayAnimation Rpc during meeting");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RpcCalls.Exiled:
|
||||
case RpcCalls.SetName:
|
||||
case RpcCalls.StartMeeting:
|
||||
case RpcCalls.SendChatNote:
|
||||
case RpcCalls.SetRole:
|
||||
case RpcCalls.ProtectPlayer:
|
||||
case RpcCalls.UseZipline:
|
||||
case RpcCalls.TriggerSpores:
|
||||
case RpcCalls.RejectShapeshift:
|
||||
{
|
||||
if (!pc.IsModdedClient())
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Invalid Rpc");
|
||||
HandleCheat(pc, "Invalid Rpc");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent invalid RPC {rpc}, rejected", "EAC");
|
||||
}
|
||||
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
case RpcCalls.SetScanner:
|
||||
{
|
||||
if (!GameManager.Instance.LogicOptions.GetVisualTasks())
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "SetScanner Rpc with visuals off");
|
||||
HandleCheat(pc, "SetScanner Rpc with visuals off");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent SetScanner RPC with visuals off, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!sr.ReadBoolean()) break;
|
||||
|
||||
if (!gameStarted)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "SetScanner Rpc in lobby");
|
||||
HandleCheat(pc, "SetScanner Rpc in lobby");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] sent SetScanner RPC in lobby, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "SetScanner Rpc during meeting");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pc.IsImpostor())
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "SetScanner Rpc as impostor");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pc.myTasks.ToArray().All(x => x.TaskType != TaskTypes.SubmitScan))
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "SetScanner Rpc without Submit Scan task");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RpcCalls.UsePlatform:
|
||||
{
|
||||
if (!gameStarted)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Using platform in lobby");
|
||||
HandleCheat(pc, "Using platform in lobby");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] tried to use platform in lobby, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GameManager.Instance.LogicOptions.MapId != 4)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Using platform on wrong map");
|
||||
HandleCheat(pc, "Using platform on wrong map");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] tried to use platform on a map that does not have platforms, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GameManager.Instance.TryCast<HideAndSeekManager>())
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Using platform in hide n seek");
|
||||
HandleCheat(pc, "Using platform in hide n seek");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] tried to use platform in hide n seek, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Using platform during meeting");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RpcCalls.CheckProtect:
|
||||
{
|
||||
var target = sr.ReadNetObject<PlayerControl>();
|
||||
|
||||
if (!gameStarted)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Using protect button in lobby");
|
||||
HandleCheat(pc, "Using protect button in lobby");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] tried to protect in lobby, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target != null && target == pc)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Using protect button on self");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target == null) break;
|
||||
|
||||
if ((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Trying to protect during meeting");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RpcCalls.CheckZipline:
|
||||
{
|
||||
if (!gameStarted)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Using zipline in lobby");
|
||||
HandleCheat(pc, "Using zipline in lobby");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] tried to use zipline in lobby, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GameManager.Instance.LogicOptions.MapId < 5)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Using zipline on wrong map");
|
||||
HandleCheat(pc, "Using zipline on wrong map");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] tried to use zipline on a map that does not have ziplines, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Using zipline during meeting");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RpcCalls.CheckSpore:
|
||||
{
|
||||
if (!gameStarted)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Triggering spore in lobby");
|
||||
HandleCheat(pc, "Triggering spore in lobby");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] tried to trigger spore in lobby, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GameManager.Instance.LogicOptions.MapId < 5)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Triggering spore on wrong map");
|
||||
HandleCheat(pc, "Triggering spore on wrong map");
|
||||
Logger.Fatal($"Player [{pc.OwnerId}:{pc.GetRealName()}] tried to trigger spore on a map that does not have spores, rejected", "EAC");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance)
|
||||
{
|
||||
WarnHost();
|
||||
Report(pc, "Triggering spore during meeting");
|
||||
sr.Recycle();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (callId)
|
||||
@@ -494,6 +845,7 @@ internal static class EAC
|
||||
|
||||
var rpcType = (RpcCalls)callId;
|
||||
MessageReader subReader = MessageReader.Get(reader);
|
||||
bool gameStarted = AmongUsClient.Instance.GameState is InnerNetClient.GameStates.Started or InnerNetClient.GameStates.Ended;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -521,6 +873,26 @@ internal static class EAC
|
||||
case RpcCalls.EnterVent:
|
||||
case RpcCalls.ExitVent:
|
||||
{
|
||||
if (!gameStarted)
|
||||
{
|
||||
WarnHost();
|
||||
Report(player, "Venting in lobby");
|
||||
HandleCheat(player, "Venting in lobby");
|
||||
Logger.Fatal($"【{player.OwnerId}:{player.GetRealName()}】 attempted to vent in lobby.", "EAC_physics");
|
||||
subReader.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance)
|
||||
{
|
||||
WarnHost();
|
||||
Report(player, "Venting during meeting");
|
||||
HandleCheat(player, "Venting during meeting");
|
||||
Logger.Fatal($"【{player.OwnerId}:{player.GetRealName()}】 attempted to vent during a meeting.", "EAC_physics");
|
||||
subReader.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
int ventid = subReader.ReadPackedInt32();
|
||||
|
||||
if (!HasVent(ventid))
|
||||
@@ -565,6 +937,34 @@ internal static class EAC
|
||||
|
||||
case RpcCalls.ClimbLadder:
|
||||
{
|
||||
if (!gameStarted)
|
||||
{
|
||||
WarnHost();
|
||||
Report(player, "Climbing ladder in lobby");
|
||||
HandleCheat(player, "Climbing ladder in lobby");
|
||||
Logger.Fatal($"【{player.OwnerId}:{player.GetRealName()}】 attempted to climb a ladder in lobby.", "EAC_physics");
|
||||
subReader.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GameManager.Instance.LogicOptions.MapId < 4)
|
||||
{
|
||||
WarnHost();
|
||||
Report(player, "Climbing ladder on wrong map");
|
||||
HandleCheat(player, "Climbing ladder on wrong map");
|
||||
Logger.Fatal($"【{player.OwnerId}:{player.GetRealName()}】 attempted to climb a ladder on a map that does not have ladders.", "EAC_physics");
|
||||
subReader.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance)
|
||||
{
|
||||
WarnHost();
|
||||
Report(player, "Climbing ladder during meeting");
|
||||
subReader.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
int ladderId = subReader.ReadPackedInt32();
|
||||
|
||||
if (!HasLadder(ladderId))
|
||||
@@ -600,6 +1000,27 @@ internal static class EAC
|
||||
return true;
|
||||
}
|
||||
|
||||
goto case RpcCalls.CancelPet;
|
||||
}
|
||||
|
||||
case RpcCalls.CancelPet:
|
||||
{
|
||||
if (player.inVent)
|
||||
{
|
||||
WarnHost();
|
||||
Report(player, "Petting in vent");
|
||||
subReader.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) || ExileController.Instance)
|
||||
{
|
||||
WarnHost();
|
||||
Report(player, "Petting during meeting");
|
||||
subReader.Recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -645,6 +1066,7 @@ internal static class EAC
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (pc.IsTrusted()) break;
|
||||
AmongUsClient.Instance.KickPlayer(pc.OwnerId, true);
|
||||
string msg0 = string.Format(GetString("Message.BannedByEAC"), pc.Data?.PlayerName, text);
|
||||
Logger.Warn(msg0, "EAC");
|
||||
@@ -653,6 +1075,7 @@ internal static class EAC
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (pc.IsTrusted()) break;
|
||||
AmongUsClient.Instance.KickPlayer(pc.OwnerId, false);
|
||||
string msg1 = string.Format(GetString("Message.KickedByEAC"), pc.Data?.PlayerName, text);
|
||||
Logger.Warn(msg1, "EAC");
|
||||
@@ -677,6 +1100,8 @@ internal static class EAC
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
if (pc.IsTrusted()) break;
|
||||
|
||||
string hashedPuid = pc.GetClient().GetHashedPuid();
|
||||
if (!BanManager.TempBanWhiteList.Contains(hashedPuid)) BanManager.TempBanWhiteList.Add(hashedPuid);
|
||||
|
||||
@@ -949,7 +1374,7 @@ internal static class CheckInvalidMovementPatch
|
||||
|
||||
public static void Postfix(PlayerControl __instance)
|
||||
{
|
||||
if (!GameStates.IsInTask || ExileController.Instance || !Options.EnableMovementChecking.GetBool() || Main.HasJustStarted || MeetingStates.FirstMeeting || Main.RealOptionsData.GetFloat(FloatOptionNames.PlayerSpeedMod) >= 1.9f || AmongUsClient.Instance.Ping >= 300 || Options.CurrentGameMode == CustomGameMode.NaturalDisasters || Utils.GetRegionName() is not ("EU" or "NA" or "AS") || __instance == null || __instance.PlayerId >= 254 || !__instance.IsAlive() || __instance.inVent) return;
|
||||
if (!GameStates.IsInTask || ExileController.Instance || !Options.EnableMovementChecking.GetBool() || Main.HasJustStarted || !Main.IntroDestroyed || MeetingStates.FirstMeeting || Main.RealOptionsData.GetFloat(FloatOptionNames.PlayerSpeedMod) >= 1.9f || AmongUsClient.Instance.Ping >= 300 || Options.CurrentGameMode == CustomGameMode.NaturalDisasters || Utils.GetRegionName() is not ("EU" or "NA" or "AS") || __instance == null || __instance.PlayerId >= 254 || !__instance.IsAlive() || __instance.inVent) return;
|
||||
|
||||
Vector2 pos = __instance.Pos();
|
||||
long now = Utils.TimeStamp;
|
||||
|
||||
@@ -87,7 +87,7 @@ internal static class ExtendedPlayerControl
|
||||
|
||||
if (player.Is(CustomRoles.Trainee) && MeetingStates.FirstMeeting) return false;
|
||||
if (player.Is(CustomRoles.Blocked) && player.GetClosestVent()?.Id != ventId) return false;
|
||||
if (!GameStates.IsInTask || ExileController.Instance || AntiBlackout.SkipTasks) return false;
|
||||
if (!GameStates.IsInTask || ExileController.Instance || AntiBlackout.SkipTasks || Main.Invisible.Contains(player.PlayerId)) return false;
|
||||
if (player.inVent && player.GetClosestVent()?.Id == ventId) return true;
|
||||
return (player.CanUseImpostorVentButton() || player.GetRoleTypes() == RoleTypes.Engineer) && Main.PlayerStates.Values.All(x => x.Role.CanUseVent(player, ventId));
|
||||
}
|
||||
@@ -1321,7 +1321,7 @@ internal static class ExtendedPlayerControl
|
||||
return Main.PlayerStates.TryGetValue(pc.PlayerId, out PlayerState state) && state.Role.CanUseSabotage(pc);
|
||||
}
|
||||
|
||||
// Next 8: From MoreGamemodes by Rabek009 (https://github.com/Rabek009/MoreGamemodes)
|
||||
// Next 6: From MoreGamemodes by Rabek009 (https://github.com/Rabek009/MoreGamemodes)
|
||||
|
||||
public static Vector2 Pos(this PlayerControl pc)
|
||||
{
|
||||
@@ -1361,44 +1361,38 @@ internal static class ExtendedPlayerControl
|
||||
}
|
||||
}
|
||||
|
||||
public static void RpcMakeInvisibleModded(this PlayerControl player)
|
||||
{
|
||||
player.MakeInvisible();
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)CustomRPC.Invisibility, SendOption.Reliable);
|
||||
writer.Write(true);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
|
||||
public static void RpcMakeVisibleModded(this PlayerControl player)
|
||||
{
|
||||
player.MakeVisible();
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)CustomRPC.Invisibility, SendOption.Reliable);
|
||||
writer.Write(false);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
|
||||
public static void RpcMakeInvisible(this PlayerControl player, bool phantom = false)
|
||||
{
|
||||
if (!Main.Invisible.Add(player.PlayerId)) return;
|
||||
if (phantom && Options.CurrentGameMode != CustomGameMode.Standard) return;
|
||||
player.RpcSetPet("");
|
||||
if (!phantom) player.RpcMakeInvisibleModded();
|
||||
|
||||
if (!phantom)
|
||||
{
|
||||
player.MakeInvisible();
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)CustomRPC.Invisibility, SendOption.Reliable);
|
||||
writer.Write(true);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
|
||||
foreach (PlayerControl pc in PlayerControl.AllPlayerControls)
|
||||
{
|
||||
if (pc.AmOwner || pc == player || (!phantom && pc.IsModdedClient()) || (phantom && pc.IsImpostor())) continue;
|
||||
|
||||
var sender = CustomRpcSender.Create("RpcMakeInvisible", SendOption.Reliable);
|
||||
sender.StartMessage(pc.GetClientId());
|
||||
sender.StartRpc(player.NetTransform.NetId, (byte)RpcCalls.SnapTo)
|
||||
sender.StartRpc(player.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(new Vector2(50f, 50f))
|
||||
.Write(player.NetTransform.lastSequenceId)
|
||||
.EndRpc();
|
||||
sender.StartRpc(player.NetTransform.NetId, (byte)RpcCalls.SnapTo)
|
||||
sender.StartRpc(player.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(new Vector2(50f, 50f))
|
||||
.Write((ushort)(player.NetTransform.lastSequenceId + 16383))
|
||||
.EndRpc();
|
||||
sender.EndMessage();
|
||||
sender.SendMessage();
|
||||
|
||||
NumSnapToCallsThisRound += 2;
|
||||
}
|
||||
|
||||
Logger.Info($"Made {player.GetNameWithRole()} invisible", "RpcMakeInvisible");
|
||||
@@ -1409,27 +1403,37 @@ internal static class ExtendedPlayerControl
|
||||
if (!Main.Invisible.Remove(player.PlayerId)) return;
|
||||
if (phantom && Options.CurrentGameMode != CustomGameMode.Standard) return;
|
||||
if (Options.UsePets.GetBool()) PetsHelper.SetPet(player, PetsHelper.GetPetId());
|
||||
if (!phantom) player.RpcMakeVisibleModded();
|
||||
|
||||
if (!phantom)
|
||||
{
|
||||
player.MakeVisible();
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)CustomRPC.Invisibility, SendOption.Reliable);
|
||||
writer.Write(false);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
|
||||
foreach (PlayerControl pc in PlayerControl.AllPlayerControls)
|
||||
{
|
||||
if (pc.AmOwner || pc == player || (!phantom && pc.IsModdedClient()) || (phantom && pc.IsImpostor())) continue;
|
||||
|
||||
var sender = CustomRpcSender.Create("RpcMakeVisible", SendOption.Reliable);
|
||||
sender.StartMessage(pc.GetClientId());
|
||||
sender.StartRpc(player.NetTransform.NetId, (byte)RpcCalls.SnapTo)
|
||||
sender.StartRpc(player.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(new Vector2(50f, 50f))
|
||||
.Write((ushort)(player.NetTransform.lastSequenceId + 32767))
|
||||
.EndRpc();
|
||||
sender.StartRpc(player.NetTransform.NetId, (byte)RpcCalls.SnapTo)
|
||||
sender.StartRpc(player.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(new Vector2(50f, 50f))
|
||||
.Write((ushort)(player.NetTransform.lastSequenceId + 32767 + 16383))
|
||||
.EndRpc();
|
||||
sender.StartRpc(player.NetTransform.NetId, (byte)RpcCalls.SnapTo)
|
||||
sender.StartRpc(player.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(player.transform.position)
|
||||
.Write(player.NetTransform.lastSequenceId)
|
||||
.EndRpc();
|
||||
sender.EndMessage();
|
||||
sender.SendMessage();
|
||||
|
||||
NumSnapToCallsThisRound += 3;
|
||||
}
|
||||
|
||||
Logger.Info($"Made {player.GetNameWithRole()} visible", "RpcMakeVisible");
|
||||
@@ -1443,35 +1447,38 @@ internal static class ExtendedPlayerControl
|
||||
foreach (PlayerControl pc in PlayerControl.AllPlayerControls)
|
||||
{
|
||||
if (pc.AmOwner || pc == player || (!phantom && pc.IsModdedClient()) || (phantom && pc.IsImpostor())) continue;
|
||||
|
||||
var sender = CustomRpcSender.Create("RpcResetInvisibility", SendOption.Reliable);
|
||||
sender.StartMessage(pc.GetClientId());
|
||||
sender.StartRpc(player.NetId, (byte)RpcCalls.Exiled)
|
||||
sender.StartRpc(player.NetId, RpcCalls.Exiled)
|
||||
.EndRpc();
|
||||
RoleTypes role = Utils.GetRoleMap(pc.PlayerId, player.PlayerId).RoleType;
|
||||
sender.StartRpc(player.NetId, (byte)RpcCalls.SetRole)
|
||||
sender.StartRpc(player.NetId, RpcCalls.SetRole)
|
||||
.Write((ushort)role)
|
||||
.Write(true)
|
||||
.EndRpc();
|
||||
sender.StartRpc(player.NetId, (byte)RpcCalls.CancelPet)
|
||||
sender.StartRpc(player.NetId, RpcCalls.CancelPet)
|
||||
.EndRpc();
|
||||
sender.StartRpc(player.NetTransform.NetId, (byte)RpcCalls.SnapTo)
|
||||
sender.StartRpc(player.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(new Vector2(50f, 50f))
|
||||
.Write((ushort)(player.NetTransform.lastSequenceId + 32767))
|
||||
.EndRpc();
|
||||
sender.StartRpc(player.NetTransform.NetId, (byte)RpcCalls.SnapTo)
|
||||
sender.StartRpc(player.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(new Vector2(50f, 50f))
|
||||
.Write((ushort)(player.NetTransform.lastSequenceId + 32767 + 16383))
|
||||
.EndRpc();
|
||||
sender.StartRpc(player.NetTransform.NetId, (byte)RpcCalls.SnapTo)
|
||||
sender.StartRpc(player.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(new Vector2(50f, 50f))
|
||||
.Write(player.NetTransform.lastSequenceId)
|
||||
.EndRpc();
|
||||
sender.StartRpc(player.NetTransform.NetId, (byte)RpcCalls.SnapTo)
|
||||
sender.StartRpc(player.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(new Vector2(50f, 50f))
|
||||
.Write((ushort)(player.NetTransform.lastSequenceId + 16383))
|
||||
.EndRpc();
|
||||
sender.EndMessage();
|
||||
sender.SendMessage();
|
||||
|
||||
NumSnapToCallsThisRound += 4;
|
||||
}
|
||||
|
||||
Logger.Info($"Reset invisibility for {player.GetNameWithRole()}", "RpcResetInvisibility");
|
||||
@@ -2053,21 +2060,21 @@ internal static class ExtendedPlayerControl
|
||||
return self.protectedByGuardianId > -1;
|
||||
}
|
||||
|
||||
public static bool IsTrusted(this PlayerControl pc)
|
||||
{
|
||||
if (pc.FriendCode.GetDevUser().up) return true;
|
||||
|
||||
if (ChatCommands.IsPlayerModerator(pc.FriendCode)) return true;
|
||||
if (ChatCommands.IsPlayerVIP(pc.FriendCode)) return true;
|
||||
if (PrivateTagManager.Tags.ContainsKey(pc.FriendCode)) return true;
|
||||
|
||||
ClientData client = pc.GetClient();
|
||||
return client != null && FastDestroyableSingleton<FriendsListManager>.Instance.IsPlayerFriend(client.ProductUserId);
|
||||
}
|
||||
|
||||
public static bool IsBeginner(this PlayerControl pc)
|
||||
{
|
||||
if (pc.IsModdedClient()) return false;
|
||||
|
||||
DevManager.TagInfo devUser = pc.FriendCode.GetDevUser();
|
||||
if (devUser.HasTag() || devUser.up) return false;
|
||||
|
||||
if (ChatCommands.IsPlayerModerator(pc.FriendCode)) return false;
|
||||
if (ChatCommands.IsPlayerVIP(pc.FriendCode)) return false;
|
||||
|
||||
if (Main.GamesPlayed.TryGetValue(pc.FriendCode, out int gamesPlayed) && gamesPlayed >= 4) return false;
|
||||
|
||||
ClientData client = pc.GetClient();
|
||||
if (client == null) return true;
|
||||
|
||||
return !FastDestroyableSingleton<FriendsListManager>.Instance.IsPlayerFriend(client.ProductUserId);
|
||||
if (pc.IsModdedClient() || pc.IsTrusted() || pc.FriendCode.GetDevUser().HasTag()) return false;
|
||||
return !Main.GamesPlayed.TryGetValue(pc.FriendCode, out int gamesPlayed) || gamesPlayed < 4;
|
||||
}
|
||||
}
|
||||
@@ -177,9 +177,11 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS
|
||||
case CustomGameMode.Speedrun:
|
||||
case CustomGameMode.HotPotato:
|
||||
case CustomGameMode.KingOfTheZones:
|
||||
case CustomGameMode.BedWars:
|
||||
SetMaxVision();
|
||||
break;
|
||||
case CustomGameMode.BedWars:
|
||||
AURoleOptions.PhantomCooldown = 0.1f;
|
||||
goto case CustomGameMode.RoomRush;
|
||||
case CustomGameMode.Quiz:
|
||||
try
|
||||
{
|
||||
|
||||
+18
-8
@@ -230,6 +230,23 @@ internal static class RPCHandlerPatch
|
||||
return (CustomRPC)id is CustomRPC.VersionCheck or CustomRPC.RequestRetryVersionCheck or CustomRPC.AntiBlackout or CustomRPC.SyncNameNotify or CustomRPC.RequestSendMessage or CustomRPC.RequestCommandProcessing or CustomRPC.Judge or CustomRPC.SetNiceSwapperVotes or CustomRPC.MeetingKill or CustomRPC.Guess or CustomRPC.MafiaRevenge or CustomRPC.BAU or CustomRPC.FFAKill or CustomRPC.TMGSync or CustomRPC.ParityCopCommand;
|
||||
}
|
||||
|
||||
private static bool CheckRateLimit(PlayerControl __instance, RpcCalls rpcType)
|
||||
{
|
||||
if (NumRPCsThisSecond.TryAdd(__instance.PlayerId, [])) LateTask.New(() => NumRPCsThisSecond.Remove(__instance.PlayerId), 1f, log: false);
|
||||
Dictionary<RpcCalls, int> calls = NumRPCsThisSecond[__instance.PlayerId];
|
||||
if (!calls.TryAdd(rpcType, 1)) calls[rpcType]++;
|
||||
|
||||
if (AmongUsClient.Instance.AmHost && !__instance.IsHost() && !(__instance.IsModdedClient() && rpcType == RpcCalls.SendChat) && (!RateLimitWhiteList.TryGetValue(__instance.PlayerId, out long expireTS) || expireTS < Utils.TimeStamp) && RpcRateLimit.TryGetValue(rpcType, out int limit) && calls[rpcType] > limit)
|
||||
{
|
||||
AmongUsClient.Instance.KickPlayer(__instance.OwnerId, false);
|
||||
Logger.SendInGame(string.Format(GetString("Warning.TooManyRPCs"), __instance.Data?.PlayerName));
|
||||
Logger.Warn($"Sent {calls[rpcType]} RPCs of type {rpcType} ({(byte)rpcType}), which exceeds the limit of {limit}. Kicking player.", "Kick");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader)
|
||||
{
|
||||
var rpcType = (RpcCalls)callId;
|
||||
@@ -247,15 +264,8 @@ internal static class RPCHandlerPatch
|
||||
|
||||
if (__instance != null)
|
||||
{
|
||||
if (NumRPCsThisSecond.TryAdd(__instance.PlayerId, [])) LateTask.New(() => NumRPCsThisSecond.Remove(__instance.PlayerId), 1f, log: false);
|
||||
Dictionary<RpcCalls, int> calls = NumRPCsThisSecond[__instance.PlayerId];
|
||||
if (!calls.TryAdd(rpcType, 1)) calls[rpcType]++;
|
||||
|
||||
if (AmongUsClient.Instance.AmHost && !__instance.IsHost() && !(__instance.IsModdedClient() && rpcType == RpcCalls.SendChat) && (!RateLimitWhiteList.TryGetValue(__instance.PlayerId, out long expireTS) || expireTS < Utils.TimeStamp) && RpcRateLimit.TryGetValue(rpcType, out int limit) && calls[rpcType] > limit)
|
||||
if (!__instance.IsTrusted() && !CheckRateLimit(__instance, rpcType))
|
||||
{
|
||||
AmongUsClient.Instance.KickPlayer(__instance.OwnerId, false);
|
||||
Logger.SendInGame(string.Format(GetString("Warning.TooManyRPCs"), __instance.Data?.PlayerName));
|
||||
Logger.Warn($"Sent {calls[rpcType]} RPCs of type {rpcType} ({callId}), which exceeds the limit of {limit}. Kicking player.", "Kick");
|
||||
subReader.Recycle();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1135,13 +1135,13 @@ public static class GameSettingMenuPatch
|
||||
var gmButton = Object.Instantiate(gMinus, gameSettingsLabel.transform, true);
|
||||
gmButton.transform.localPosition = new Vector3((((index / 7) - ((totalCols - 1) / 2f)) * 1.4f) + 0.86f, gameSettingsLabelPos.y - 1.9f - (0.22f * (index % 7)), -1f);
|
||||
|
||||
gmButton.transform.localScale = new(russian ? 0.5f : 0.4f, russian ? 0.37f : 0.3f, 1f);
|
||||
gmButton.transform.localScale = new(0.4f, 0.3f, 1f);
|
||||
var gmButtonTmp = gmButton.transform.Find("FontPlacer/Text_TMP").GetComponent<TextMeshPro>();
|
||||
gmButtonTmp.alignment = TextAlignmentOptions.Center;
|
||||
gmButtonTmp.DestroyTranslator();
|
||||
gmButtonTmp.text = Translator.GetString(gm.ToString()).ToUpper();
|
||||
gmButtonTmp.color = Main.GameModeColors[gm];
|
||||
gmButtonTmp.transform.localPosition = new(gameSettingsLabelPos.x + (!russian ? 3.35f : 3.65f), gameSettingsLabelPos.y - 1.62f, gameSettingsLabelPos.z);
|
||||
gmButtonTmp.transform.localPosition = new(gameSettingsLabelPos.x + 3.35f, gameSettingsLabelPos.y - 1.62f, gameSettingsLabelPos.z);
|
||||
gmButtonTmp.transform.localScale = new(1f, 1f, 1f);
|
||||
|
||||
var gmPassiveButton = gmButton.GetComponent<PassiveButton>();
|
||||
|
||||
@@ -1037,9 +1037,7 @@ internal static class IntroCutsceneDestroyPatch
|
||||
});
|
||||
}, 2f, "FixKillCooldownTask");
|
||||
}
|
||||
else Utils.SyncAllSettings();
|
||||
}
|
||||
else Utils.SyncAllSettings();
|
||||
}
|
||||
|
||||
switch (Options.CurrentGameMode)
|
||||
@@ -1191,6 +1189,7 @@ internal static class IntroCutsceneDestroyPatch
|
||||
if (AFKDetector.ActivateOnStart.GetBool()) LateTask.New(() => aapc.Do(AFKDetector.RecordPosition), 1f, log: false);
|
||||
|
||||
LateTask.New(() => Main.Instance.StartCoroutine(Utils.NotifyEveryoneAsync()), 3f, "NotifyEveryoneAsync On Game Start");
|
||||
LateTask.New(Utils.SyncAllSettings, 0.5f, "SyncAllSettings On Game Start");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -126,6 +126,7 @@ internal static class EndGamePatch
|
||||
Main.GamesPlayed.AddRange(Main.AllPlayerControls.ToDictionary(x => x.FriendCode, _ => 0), false);
|
||||
Main.GamesPlayed.AdjustAllValues(x => ++x);
|
||||
Main.GotShieldAnimationInfoThisGame.Clear();
|
||||
if (Main.GM.Value) Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].IsDead = false;
|
||||
break;
|
||||
case CustomGameMode.MoveAndStop:
|
||||
Main.AllPlayerControls.Do(x => MoveAndStop.HasPlayed.Add(x.FriendCode));
|
||||
|
||||
@@ -85,11 +85,34 @@ internal static class RpcMurderPlayerPatch
|
||||
if (AmongUsClient.Instance.AmClient)
|
||||
__instance.MurderPlayer(target, murderResultFlags);
|
||||
|
||||
MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(__instance.NetId, (byte)RpcCalls.MurderPlayer, SendOption.Reliable);
|
||||
messageWriter.WriteNetObject(target);
|
||||
messageWriter.Write((int)murderResultFlags);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(messageWriter);
|
||||
var sender = CustomRpcSender.Create("RpcMurderPlayer", SendOption.Reliable);
|
||||
|
||||
if (Main.Invisible.Contains(target.PlayerId) && murderResultFlags == MurderResultFlags.Succeeded)
|
||||
{
|
||||
sender.AutoStartRpc(target.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(new Vector2(50f, 50f))
|
||||
.Write((ushort)(target.NetTransform.lastSequenceId + 16383))
|
||||
.EndRpc();
|
||||
sender.AutoStartRpc(target.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(new Vector2(50f, 50f))
|
||||
.Write((ushort)(target.NetTransform.lastSequenceId + 32767))
|
||||
.EndRpc();
|
||||
sender.AutoStartRpc(target.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(new Vector2(50f, 50f))
|
||||
.Write((ushort)(target.NetTransform.lastSequenceId + 32767 + 16383))
|
||||
.EndRpc();
|
||||
sender.AutoStartRpc(target.NetTransform.NetId, RpcCalls.SnapTo)
|
||||
.WriteVector2(target.transform.position)
|
||||
.Write(target.NetTransform.lastSequenceId)
|
||||
.EndRpc();
|
||||
}
|
||||
|
||||
sender.AutoStartRpc(__instance.NetId, RpcCalls.MurderPlayer)
|
||||
.WriteNetObject(target)
|
||||
.Write((int)murderResultFlags)
|
||||
.EndRpc();
|
||||
|
||||
sender.SendMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1176,6 +1199,8 @@ internal static class ReportDeadBodyPatch
|
||||
}
|
||||
}
|
||||
|
||||
EAC.TimeSinceLastTaskCompletion.Clear();
|
||||
|
||||
Enigma.OnReportDeadBody(player, target);
|
||||
Mediumshiper.OnReportDeadBody(target);
|
||||
Mortician.OnReportDeadBody(player, target);
|
||||
@@ -1274,7 +1299,10 @@ internal static class FixedUpdatePatch
|
||||
CheckMurderPatch.Update(__instance.PlayerId);
|
||||
|
||||
if (AmongUsClient.Instance.AmHost && __instance.AmOwner)
|
||||
{
|
||||
CustomNetObject.FixedUpdate();
|
||||
EAC.TimeSinceLastTaskCompletion.AdjustAllValues(f => f + Time.fixedDeltaTime);
|
||||
}
|
||||
|
||||
byte id = __instance.PlayerId;
|
||||
|
||||
@@ -1316,7 +1344,7 @@ internal static class FixedUpdatePatch
|
||||
GhostRolesManager.AssignGhostRole(__instance);
|
||||
}
|
||||
|
||||
if (GameStates.InGame && Options.DontUpdateDeadPlayers.GetBool() && !__instance.IsAlive() && !__instance.GetCustomRole().NeedsUpdateAfterDeath() && Options.CurrentGameMode is not CustomGameMode.RoomRush and not CustomGameMode.Quiz)
|
||||
if (GameStates.InGame && Options.DontUpdateDeadPlayers.GetBool() && !(__instance.IsHost() && __instance.IsLocalPlayer()) && !__instance.IsAlive() && !__instance.GetCustomRole().NeedsUpdateAfterDeath() && Options.CurrentGameMode is not CustomGameMode.RoomRush and not CustomGameMode.Quiz)
|
||||
{
|
||||
int buffer = Options.DeepLowLoad.GetBool() ? 150 : 60;
|
||||
DeadBufferTime.TryAdd(id, buffer);
|
||||
|
||||
@@ -721,7 +721,7 @@
|
||||
"EraserInfoLong": "(Impostors):\\nDuring the meeting, Eraser can vote for any crew member as a target. The selected crew member's roles will be erased after the meeting concludes. It is important to note that players whose roles have been erased will always be considered as vanilla roles, including the game result page.",
|
||||
"OverKillerInfoLong": "(Impostors):\\nIt can be difficult to identify other dead bodies when reporting a Butcher kill, as there may be multiple dead bodies on the targets. This is due to the implementation principle, which requires the killed target to repeatedly display the animation of being killed and prevents them from participating in the meeting normally during this period. Additionally, if the Butcher kills the Avenger, the Avenger will seek revenge on everyone in anger.",
|
||||
"HangmanInfoLong": "(Impostors):\\nThe Hangman kills by strangling during shapeshifting, ignoring all target abilities. The strangled player doesn't leave a body or trigger abilities, including Veteran, Lucky, and Seer. Additional roles are also affected.",
|
||||
"SwooperInfoLong": "(Impostors):\\nThe Swooper can Vent to temporarily turn invisible and vent again to cancel their invisibility phase. This means the Swooper can never vent normally, even when swooping is on cooldown. (Note: The game will forcibly make you turn visible when the swoop duration ends, no matter if you vent or not.)",
|
||||
"SwooperInfoLong": "(Impostors):\\nThe Swooper can Vent/Vanish to temporarily turn invisible. You can kill while being invisible, unlike vanilla Phantom.",
|
||||
"CrewpostorInfoLong": "(Team Impostor):\\nYou kill the nearest player whenever you complete a task.",
|
||||
"WildlingInfoLong": "(Impostors):\\nAs the Wildling, you can shapeshift but cannot vent. When you kill, you temporarily become immune to attacks.",
|
||||
"TricksterInfoLong": "(Impostors):\\nAs the Trickster, you function as a regular Impostor but with one key difference. You appear crewmate to crewmate roles.\\n\\nThe Sheriff cannot kill you.\\nPsychic does not see you as evil.\\nSnitch cannot find you.",
|
||||
@@ -819,7 +819,7 @@
|
||||
"TotocalcioInfoLong": "(Neutrals):\\nThe Follower can start following someone by using their Kill button and switch targets by using it again. If the Follower's target wins, the Follower will win, too. They can even win after they die.",
|
||||
"SuccubusInfoLong": "(Neutrals):\\nIf there are more Cultists than Crewmates and only these two teams remain, the Cultist team wins. The Cultist can charm a non-neutral player by pressing the kill button, making them a part of the Cultist team with new victory conditions.",
|
||||
"HexMasterInfoLong": "(Neutrals):\\nAs the Hex Master, you can hex players or kill them. Hexing a player works the same as spelling as a Witch.",
|
||||
"WraithInfoLong": "(Neutrals):\\nAs the Wraith, you can use vents to go invisible temporarily. Trying to vent while invisible will cause you to become visible again.\\n\\nKill; everyone to win.",
|
||||
"WraithInfoLong": "(Neutrals):\\nAs the Wraith, you can Vent/Vanish to go invisible temporarily. You can kill while being invisible.\\n\\nKill; everyone to win.",
|
||||
"NSerialKillerInfoLong": "(Neutrals):\\nAs the Serial Killer, your job is to murder everyone to win simply.",
|
||||
"JuggernautInfoLong": "(Neutrals):\\nAs the Juggernaut, your kill cooldown decreases with each kill you make.\\n\\nKill everyone to win.",
|
||||
"VirusInfoLong": "(Neutrals):\\nThe virus' goal is to eliminate other players. When a crewmate is killed, their corpse is infected, and the reporting crewmate joins the virus team or dies if the Virus isn't voted out. The Virus team wins if they outnumber the Crewmate team.",
|
||||
|
||||
@@ -125,9 +125,25 @@ internal class Assassin : RoleBase
|
||||
{
|
||||
if (killer.IsShifted())
|
||||
{
|
||||
killer.ResetKillCooldown();
|
||||
killer.SyncSettings();
|
||||
return CanUseKillButton(killer);
|
||||
bool canUseKillButton = CanUseKillButton(killer);
|
||||
|
||||
if (canUseKillButton)
|
||||
{
|
||||
killer.ResetKillCooldown();
|
||||
killer.SyncSettings();
|
||||
|
||||
if (Main.Invisible.Contains(killer.PlayerId) && !target.Is(CustomRoles.Bait))
|
||||
{
|
||||
if (!killer.RpcCheckAndMurder(target, true)) return false;
|
||||
|
||||
RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound);
|
||||
target.Suicide(PlayerState.DeathReason.Swooped, killer);
|
||||
killer.SetKillCooldown();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return canUseKillButton;
|
||||
}
|
||||
|
||||
MarkedPlayer = target.PlayerId;
|
||||
|
||||
+16
-10
@@ -177,7 +177,9 @@ public class Swooper : RoleBase
|
||||
if (lastTime + (long)Cooldown < now)
|
||||
{
|
||||
lastTime = -10;
|
||||
if (!player.IsModdedClient()) player.Notify(GetString("SwooperCanVent"), 10f);
|
||||
|
||||
if (!player.IsModdedClient() && !(UsedRole != CustomRoles.Chameleon && UsePhantomBasis.GetBool() && (UsedRole != CustomRoles.Wraith || UsePhantomBasisForNKs.GetBool())))
|
||||
player.Notify(GetString("SwooperCanVent"), 10f);
|
||||
|
||||
SendRPC();
|
||||
CD = 0;
|
||||
@@ -193,8 +195,15 @@ public class Swooper : RoleBase
|
||||
{
|
||||
case < 0:
|
||||
lastTime = now;
|
||||
int ventId = ventedId == -10 ? Main.LastEnteredVent[player.PlayerId].Id : ventedId;
|
||||
Main.AllPlayerControls.Without(player).Do(x => player.MyPhysics.RpcExitVentDesync(ventId, x));
|
||||
|
||||
if (UsedRole == CustomRoles.Chameleon)
|
||||
{
|
||||
int ventId = ventedId == -10 ? Main.LastEnteredVent[player.PlayerId].Id : ventedId;
|
||||
Main.AllPlayerControls.Without(player).Do(x => player.MyPhysics.RpcExitVentDesync(ventId, x));
|
||||
}
|
||||
else
|
||||
player.RpcMakeVisible();
|
||||
|
||||
player.Notify(GetString("SwooperInvisStateOut"));
|
||||
player.RpcResetAbilityCooldown();
|
||||
InvisTime = -10;
|
||||
@@ -209,7 +218,7 @@ public class Swooper : RoleBase
|
||||
|
||||
bool OnCoEnterVent(PlayerPhysics __instance, int ventId)
|
||||
{
|
||||
if (!AmongUsClient.Instance.AmHost || IsInvis) return false;
|
||||
if (!AmongUsClient.Instance.AmHost || IsInvis || (UsedRole != CustomRoles.Chameleon && UsePhantomBasis.GetBool() && (UsedRole != CustomRoles.Wraith || UsePhantomBasisForNKs.GetBool()))) return false;
|
||||
|
||||
PlayerControl pc = __instance.myPlayer;
|
||||
|
||||
@@ -262,10 +271,8 @@ public class Swooper : RoleBase
|
||||
|
||||
if (CanGoInvis && (wraith || limit >= 1))
|
||||
{
|
||||
int? ventId = pc.GetClosestVent()?.Id;
|
||||
Main.AllPlayerControls.Without(pc).Do(x => pc.MyPhysics.RpcEnterVentDesync(ventId ?? 2, x));
|
||||
|
||||
ventedId = ventId ?? -10;
|
||||
pc.RpcMakeInvisible();
|
||||
|
||||
InvisTime = Utils.TimeStamp;
|
||||
if (!wraith) pc.RpcRemoveAbilityUse();
|
||||
|
||||
@@ -292,7 +299,7 @@ public class Swooper : RoleBase
|
||||
long cooldown = lastTime + (long)Cooldown - Utils.TimeStamp;
|
||||
str.Append(string.Format(GetString("SwooperInvisCooldownRemain"), cooldown + 1));
|
||||
}
|
||||
else
|
||||
else if (!(UsedRole != CustomRoles.Chameleon && UsePhantomBasis.GetBool() && (UsedRole != CustomRoles.Wraith || UsePhantomBasisForNKs.GetBool())))
|
||||
str.Append(GetString("SwooperCanVent"));
|
||||
|
||||
return str.ToString();
|
||||
@@ -300,7 +307,6 @@ public class Swooper : RoleBase
|
||||
|
||||
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
|
||||
{
|
||||
if (Medic.ProtectList.Contains(target.PlayerId)) return false;
|
||||
if (target.Is(CustomRoles.Bait)) return true;
|
||||
if (!IsInvis) return true;
|
||||
if (!killer.RpcCheckAndMurder(target, true)) return false;
|
||||
|
||||
Reference in new issue
Block a user