crash ignored players
Otherwise they keep sending all their packets (including positional updates) to the server which costs bandwidth and processing power.
This commit is contained in:
parent
b418331a03
commit
07526a7c38
|
@ -148,30 +148,27 @@ public static class BanLists {
|
|||
|
||||
public static void Crash(
|
||||
Client user,
|
||||
bool permanent = false,
|
||||
bool dispose_user = true,
|
||||
int delay_ms = 0
|
||||
int delay_ms = 0
|
||||
) {
|
||||
user.Ignored = true;
|
||||
Task.Run(async () => {
|
||||
if (delay_ms > 0) {
|
||||
await Task.Delay(delay_ms);
|
||||
}
|
||||
bool permanent = user.Banned;
|
||||
await user.Send(new ChangeStagePacket {
|
||||
Id = (permanent ? "$agogus/ban4lyfe" : "$among$us/cr4sh%"),
|
||||
Stage = (permanent ? "$ejected" : "$agogusStage"),
|
||||
Scenario = (sbyte) (permanent ? 69 : 21),
|
||||
SubScenarioType = (byte) (permanent ? 21 : 69),
|
||||
});
|
||||
if (dispose_user) {
|
||||
user.Dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void CrashMultiple(string[] args, MUCH much) {
|
||||
foreach (Client user in much(args).toActUpon) {
|
||||
Crash(user, true);
|
||||
user.Banned = true;
|
||||
Crash(user);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,8 +242,9 @@ public static class BanLists {
|
|||
}
|
||||
|
||||
foreach (Client user in res.toActUpon) {
|
||||
user.Banned = true;
|
||||
BanClient(user);
|
||||
Crash(user, true);
|
||||
Crash(user);
|
||||
}
|
||||
|
||||
Save();
|
||||
|
|
|
@ -13,6 +13,7 @@ public class Client : IDisposable {
|
|||
public readonly ConcurrentDictionary<string, object?> Metadata = new ConcurrentDictionary<string, object?>(); // can be used to store any information about a player
|
||||
public bool Connected = false;
|
||||
public bool Ignored = false;
|
||||
public bool Banned = false;
|
||||
public CostumePacket? CurrentCostume = null; // required for proper client sync
|
||||
public string Name {
|
||||
get => Logger.Name;
|
||||
|
@ -52,6 +53,11 @@ public class Client : IDisposable {
|
|||
|
||||
PacketAttribute packetAttribute = Constants.PacketMap[typeof(T)];
|
||||
try {
|
||||
// don't send most packets to ignored players
|
||||
if (Ignored && packetAttribute.Type != PacketType.Init && packetAttribute.Type != PacketType.ChangeStage) {
|
||||
memory.Dispose();
|
||||
return;
|
||||
}
|
||||
Server.FillPacket(new PacketHeader {
|
||||
Id = sender?.Id ?? Id,
|
||||
Type = packetAttribute.Type,
|
||||
|
@ -71,11 +77,16 @@ public class Client : IDisposable {
|
|||
PacketHeader header = new PacketHeader();
|
||||
header.Deserialize(data.Span);
|
||||
|
||||
if (!Connected && header.Type is not PacketType.Connect) {
|
||||
if (!Connected && !Ignored && header.Type != PacketType.Connect) {
|
||||
Server.Logger.Error($"Didn't send {header.Type} to {Id} because they weren't connected yet");
|
||||
return;
|
||||
}
|
||||
|
||||
// don't send most packets to ignored players
|
||||
if (Ignored && header.Type != PacketType.Init && header.Type != PacketType.ChangeStage) {
|
||||
return;
|
||||
}
|
||||
|
||||
await Socket!.SendAsync(data[..(Constants.HeaderSize + header.PacketSize)], SocketFlags.None);
|
||||
}
|
||||
|
||||
|
|
|
@ -120,10 +120,17 @@ void logError(Task x) {
|
|||
server.PacketHandler = (c, p) => {
|
||||
switch (p) {
|
||||
case GamePacket gamePacket: {
|
||||
// crash ignored player
|
||||
if (c.Ignored) {
|
||||
c.Logger.Info($"Crashing ignored player after entering stage {gamePacket.Stage}.");
|
||||
BanLists.Crash(c, 500);
|
||||
return false;
|
||||
}
|
||||
|
||||
// crash player entering a banned stage
|
||||
if (BanLists.Enabled && BanLists.IsStageBanned(gamePacket.Stage)) {
|
||||
c.Logger.Warn($"Crashing player for entering banned stage {gamePacket.Stage}.");
|
||||
BanLists.Crash(c, false, false, 500);
|
||||
BanLists.Crash(c, 500);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -172,6 +179,11 @@ server.PacketHandler = (c, p) => {
|
|||
break;
|
||||
}
|
||||
|
||||
// ignore all other packets from ignored players
|
||||
case IPacket pack when c.Ignored: {
|
||||
return false;
|
||||
}
|
||||
|
||||
case TagPacket tagPacket: {
|
||||
// c.Logger.Info($"Got tag packet: {tagPacket.IsIt}");
|
||||
if ((tagPacket.UpdateType & TagPacket.TagUpdate.State) != 0) c.Metadata["seeking"] = tagPacket.IsIt;
|
||||
|
|
|
@ -29,12 +29,6 @@ public class Server {
|
|||
Socket socket = token.HasValue ? await serverSocket.AcceptAsync(token.Value) : await serverSocket.AcceptAsync();
|
||||
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
|
||||
|
||||
// is the IPv4 address banned?
|
||||
if (BanLists.Enabled && BanLists.IsIPv4Banned(((IPEndPoint) socket.RemoteEndPoint!).Address!)) {
|
||||
Logger.Warn($"Ignoring banned IPv4 address {socket.RemoteEndPoint}");
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.Warn($"Accepted connection for client {socket.RemoteEndPoint}");
|
||||
|
||||
// start sub thread to handle client
|
||||
|
@ -80,7 +74,7 @@ public class Server {
|
|||
public delegate void PacketReplacer<in T>(Client from, Client to, T value); // replacer must send
|
||||
|
||||
public void BroadcastReplace<T>(T packet, Client sender, PacketReplacer<T> packetReplacer) where T : struct, IPacket {
|
||||
foreach (Client client in Clients.Where(client => client.Connected && sender.Id != client.Id)) {
|
||||
foreach (Client client in Clients.Where(c => c.Connected && !c.Ignored && sender.Id != c.Id)) {
|
||||
packetReplacer(sender, client, packet);
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +91,7 @@ public class Server {
|
|||
}
|
||||
|
||||
public Task Broadcast<T>(T packet) where T : struct, IPacket {
|
||||
return Task.WhenAll(Clients.Where(c => c.Connected).Select(async client => {
|
||||
return Task.WhenAll(Clients.Where(c => c.Connected && !c.Ignored).Select(async client => {
|
||||
IMemoryOwner<byte> memory = MemoryPool<byte>.Shared.RentZero(Constants.HeaderSize + packet.Size);
|
||||
PacketHeader header = new PacketHeader {
|
||||
Id = client.Id,
|
||||
|
@ -116,7 +110,7 @@ public class Server {
|
|||
/// <param name="data">Memory owner to dispose once done</param>
|
||||
/// <param name="sender">Optional sender to not broadcast data to</param>
|
||||
public async Task Broadcast(IMemoryOwner<byte> data, Client? sender = null) {
|
||||
await Task.WhenAll(Clients.Where(c => c.Connected && c != sender).Select(client => client.Send(data.Memory, sender)));
|
||||
await Task.WhenAll(Clients.Where(c => c.Connected && !c.Ignored && c != sender).Select(client => client.Send(data.Memory, sender)));
|
||||
data.Dispose();
|
||||
}
|
||||
|
||||
|
@ -126,7 +120,7 @@ public class Server {
|
|||
/// <param name="data">Memory to send to the clients</param>
|
||||
/// <param name="sender">Optional sender to not broadcast data to</param>
|
||||
public async void Broadcast(Memory<byte> data, Client? sender = null) {
|
||||
await Task.WhenAll(Clients.Where(c => c.Connected && c != sender).Select(client => client.Send(data, sender)));
|
||||
await Task.WhenAll(Clients.Where(c => c.Connected && !c.Ignored && c != sender).Select(client => client.Send(data, sender)));
|
||||
}
|
||||
|
||||
public Client? FindExistingClient(Guid id) {
|
||||
|
@ -175,10 +169,6 @@ public class Server {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (client.Ignored) {
|
||||
memory.Dispose();
|
||||
continue;
|
||||
}
|
||||
|
||||
// connection initialization
|
||||
if (first) {
|
||||
|
@ -195,19 +185,30 @@ public class Server {
|
|||
client.Id = header.Id;
|
||||
client.Name = connect.ClientName;
|
||||
|
||||
// is the profile ID banned?
|
||||
if (BanLists.Enabled && BanLists.IsProfileBanned(client.Id)) {
|
||||
// is the IPv4 address banned?
|
||||
if (BanLists.Enabled && BanLists.IsIPv4Banned(((IPEndPoint) socket.RemoteEndPoint!).Address!)) {
|
||||
Logger.Warn($"Ignoring banned IPv4 address for {client.Name} ({client.Id}/{remote})");
|
||||
client.Ignored = true;
|
||||
client.Logger.Warn($"Ignoring banned profile ID {client.Id}");
|
||||
client.Banned = true;
|
||||
}
|
||||
// is the profile ID banned?
|
||||
else if (BanLists.Enabled && BanLists.IsProfileBanned(client.Id)) {
|
||||
client.Logger.Warn($"Ignoring banned profile ID for {client.Name} ({client.Id}/{remote})");
|
||||
client.Ignored = true;
|
||||
client.Banned = true;
|
||||
}
|
||||
|
||||
// send server init (required to crash ignored players later)
|
||||
await client.Send(new InitPacket {
|
||||
MaxPlayers = (client.Ignored ? (ushort) 1 : Settings.Instance.Server.MaxPlayers),
|
||||
});
|
||||
|
||||
// don't init or announce an ignored client to other players any further
|
||||
if (client.Ignored) {
|
||||
memory.Dispose();
|
||||
continue;
|
||||
}
|
||||
|
||||
// send server init
|
||||
await client.Send(new InitPacket {
|
||||
MaxPlayers = Settings.Instance.Server.MaxPlayers,
|
||||
});
|
||||
|
||||
bool wasFirst = connect.ConnectionType == ConnectPacket.ConnectionTypes.FirstConnection;
|
||||
|
||||
// add client to the set of connected players
|
||||
|
|
Loading…
Reference in New Issue