Simplify rate limiter, disabled silencing and merged BasicUser and ChatUser.
This commit is contained in:
parent
d268a419dc
commit
546e8a2c83
15 changed files with 98 additions and 115 deletions
|
@ -80,15 +80,6 @@ namespace SharpChat {
|
||||||
return Users.Where(u => ids.Contains(u.UserId)).ToArray();
|
return Users.Where(u => ids.Contains(u.UserId)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DebugPrintChannelUsers() {
|
|
||||||
lock(ChannelUsersAccess) {
|
|
||||||
Logger.Write("DebugPrintChannelUsers()");
|
|
||||||
foreach(ChannelUserAssoc cua in ChannelUsers)
|
|
||||||
Logger.Write(cua);
|
|
||||||
Logger.Write(string.Empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BanUser(ChatUser user, TimeSpan duration, UserDisconnectReason reason = UserDisconnectReason.Kicked) {
|
public void BanUser(ChatUser user, TimeSpan duration, UserDisconnectReason reason = UserDisconnectReason.Kicked) {
|
||||||
if(duration > TimeSpan.Zero)
|
if(duration > TimeSpan.Zero)
|
||||||
SendTo(user, new ForceDisconnectPacket(ForceDisconnectReason.Banned, DateTimeOffset.Now + duration));
|
SendTo(user, new ForceDisconnectPacket(ForceDisconnectReason.Banned, DateTimeOffset.Now + duration));
|
||||||
|
@ -143,7 +134,6 @@ namespace SharpChat {
|
||||||
|
|
||||||
foreach(ChatChannel chan in channels) {
|
foreach(ChatChannel chan in channels) {
|
||||||
ChannelUsers.Remove(new ChannelUserAssoc(user.UserId, chan.Name));
|
ChannelUsers.Remove(new ChannelUserAssoc(user.UserId, chan.Name));
|
||||||
DebugPrintChannelUsers();
|
|
||||||
|
|
||||||
SendTo(chan, new UserDisconnectPacket(DateTimeOffset.Now, user, reason));
|
SendTo(chan, new UserDisconnectPacket(DateTimeOffset.Now, user, reason));
|
||||||
Events.AddEvent(new UserDisconnectEvent(DateTimeOffset.Now, user, chan, reason));
|
Events.AddEvent(new UserDisconnectEvent(DateTimeOffset.Now, user, chan, reason));
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace SharpChat {
|
|
||||||
public enum ChatRateLimitState {
|
|
||||||
None,
|
|
||||||
Warning,
|
|
||||||
Kick,
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ChatRateLimiter {
|
|
||||||
private const int FLOOD_PROTECTION_AMOUNT = 30;
|
|
||||||
private const int FLOOD_PROTECTION_THRESHOLD = 10;
|
|
||||||
|
|
||||||
private readonly Queue<DateTimeOffset> TimePoints = new();
|
|
||||||
|
|
||||||
public ChatRateLimitState State {
|
|
||||||
get {
|
|
||||||
if(TimePoints.Count == FLOOD_PROTECTION_AMOUNT) {
|
|
||||||
if((TimePoints.Last() - TimePoints.First()).TotalSeconds <= FLOOD_PROTECTION_THRESHOLD)
|
|
||||||
return ChatRateLimitState.Kick;
|
|
||||||
|
|
||||||
if((TimePoints.Last() - TimePoints.Skip(5).First()).TotalSeconds <= FLOOD_PROTECTION_THRESHOLD)
|
|
||||||
return ChatRateLimitState.Warning;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ChatRateLimitState.None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddTimePoint(DateTimeOffset? dto = null) {
|
|
||||||
if(!dto.HasValue)
|
|
||||||
dto = DateTimeOffset.Now;
|
|
||||||
|
|
||||||
if(TimePoints.Count >= FLOOD_PROTECTION_AMOUNT)
|
|
||||||
TimePoints.Dequeue();
|
|
||||||
|
|
||||||
TimePoints.Enqueue(dto.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@ using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public class BasicUser : IEquatable<BasicUser> {
|
public class ChatUser : IEquatable<ChatUser> {
|
||||||
private const int RANK_NO_FLOOD = 9;
|
private const int RANK_NO_FLOOD = 9;
|
||||||
|
|
||||||
public long UserId { get; set; }
|
public long UserId { get; set; }
|
||||||
|
@ -18,6 +18,11 @@ namespace SharpChat {
|
||||||
public bool HasFloodProtection
|
public bool HasFloodProtection
|
||||||
=> Rank < RANK_NO_FLOOD;
|
=> Rank < RANK_NO_FLOOD;
|
||||||
|
|
||||||
|
public readonly RateLimiter RateLimiter = new();
|
||||||
|
|
||||||
|
// This needs to be a session thing
|
||||||
|
public ChatChannel CurrentChannel { get; set; }
|
||||||
|
|
||||||
public string DisplayName {
|
public string DisplayName {
|
||||||
get {
|
get {
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
|
@ -36,6 +41,24 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ChatUser() { }
|
||||||
|
|
||||||
|
public ChatUser(MisuzuAuthInfo auth) {
|
||||||
|
UserId = auth.UserId;
|
||||||
|
ApplyAuth(auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyAuth(MisuzuAuthInfo auth) {
|
||||||
|
Username = auth.Username;
|
||||||
|
|
||||||
|
if(Status == ChatUserStatus.Offline)
|
||||||
|
Status = ChatUserStatus.Online;
|
||||||
|
|
||||||
|
Colour = ChatColour.FromMisuzu(auth.ColourRaw);
|
||||||
|
Rank = auth.Rank;
|
||||||
|
Permissions = auth.Permissions;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Can(ChatUserPermissions perm, bool strict = false) {
|
public bool Can(ChatUserPermissions perm, bool strict = false) {
|
||||||
ChatUserPermissions perms = Permissions & perm;
|
ChatUserPermissions perms = Permissions & perm;
|
||||||
return strict ? perms == perm : perms > 0;
|
return strict ? perms == perm : perms > 0;
|
||||||
|
@ -63,56 +86,23 @@ namespace SharpChat {
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool NameEquals(string name) {
|
||||||
|
return string.Equals(name, Username, StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
|| string.Equals(name, Nickname, StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
|| string.Equals(name, DisplayName, StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
public override int GetHashCode() {
|
public override int GetHashCode() {
|
||||||
return UserId.GetHashCode();
|
return UserId.GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
public override bool Equals(object obj) {
|
||||||
return Equals(obj as BasicUser);
|
return Equals(obj as ChatUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(BasicUser other) {
|
public bool Equals(ChatUser other) {
|
||||||
return UserId == other?.UserId;
|
return UserId == other?.UserId;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class ChatUser : BasicUser {
|
|
||||||
public DateTimeOffset SilencedUntil { get; set; }
|
|
||||||
|
|
||||||
public readonly ChatRateLimiter RateLimiter = new();
|
|
||||||
|
|
||||||
// This needs to be a session thing
|
|
||||||
public ChatChannel CurrentChannel { get; set; }
|
|
||||||
|
|
||||||
public bool IsSilenced
|
|
||||||
=> DateTimeOffset.UtcNow - SilencedUntil <= TimeSpan.Zero;
|
|
||||||
|
|
||||||
public ChatUser() {}
|
|
||||||
|
|
||||||
public ChatUser(MisuzuAuthInfo auth) {
|
|
||||||
UserId = auth.UserId;
|
|
||||||
ApplyAuth(auth, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ApplyAuth(MisuzuAuthInfo auth, bool invalidateRestrictions = false) {
|
|
||||||
Username = auth.Username;
|
|
||||||
|
|
||||||
if(Status == ChatUserStatus.Offline)
|
|
||||||
Status = ChatUserStatus.Online;
|
|
||||||
|
|
||||||
Colour = ChatColour.FromMisuzu(auth.ColourRaw);
|
|
||||||
Rank = auth.Rank;
|
|
||||||
Permissions = auth.Permissions;
|
|
||||||
|
|
||||||
if(invalidateRestrictions || !IsSilenced)
|
|
||||||
SilencedUntil = auth.SilencedUntil;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool NameEquals(string name) {
|
|
||||||
return string.Equals(name, Username, StringComparison.InvariantCultureIgnoreCase)
|
|
||||||
|| string.Equals(name, Nickname, StringComparison.InvariantCultureIgnoreCase)
|
|
||||||
|| string.Equals(name, DisplayName, StringComparison.InvariantCultureIgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetDMChannelName(ChatUser user1, ChatUser user2) {
|
public static string GetDMChannelName(ChatUser user1, ChatUser user2) {
|
||||||
return user1.UserId < user2.UserId
|
return user1.UserId < user2.UserId
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(silUser.IsSilenced) {
|
if(RNG.Next() > 1 /*silUser.IsSilenced*/) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.SILENCE_ALREADY));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.SILENCE_ALREADY));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ namespace SharpChat.Commands {
|
||||||
silenceUntil = DateTimeOffset.UtcNow.AddSeconds(silenceSeconds);
|
silenceUntil = DateTimeOffset.UtcNow.AddSeconds(silenceSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
silUser.SilencedUntil = silenceUntil;
|
//silUser.SilencedUntil = silenceUntil;
|
||||||
ctx.Chat.SendTo(silUser, new LegacyCommandResponse(LCR.SILENCED, false));
|
ctx.Chat.SendTo(silUser, new LegacyCommandResponse(LCR.SILENCED, false));
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.TARGET_SILENCED, false, silUser.DisplayName));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.TARGET_SILENCED, false, silUser.DisplayName));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,12 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!unsilUser.IsSilenced) {
|
if(RNG.Next() > 1 /*!unsilUser.IsSilenced*/) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.NOT_SILENCED));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.NOT_SILENCED));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsilUser.SilencedUntil = DateTimeOffset.MinValue;
|
//unsilUser.SilencedUntil = DateTimeOffset.MinValue;
|
||||||
ctx.Chat.SendTo(unsilUser, new LegacyCommandResponse(LCR.UNSILENCED, false));
|
ctx.Chat.SendTo(unsilUser, new LegacyCommandResponse(LCR.UNSILENCED, false));
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.TARGET_UNSILENCED, false, unsilUser.DisplayName));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.TARGET_UNSILENCED, false, unsilUser.DisplayName));
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace SharpChat.EventStorage {
|
||||||
evt.DateTime = DateTimeOffset.FromUnixTimeSeconds(reader.GetInt32("event_created"));
|
evt.DateTime = DateTimeOffset.FromUnixTimeSeconds(reader.GetInt32("event_created"));
|
||||||
|
|
||||||
if(!reader.IsDBNull(reader.GetOrdinal("event_sender"))) {
|
if(!reader.IsDBNull(reader.GetOrdinal("event_sender"))) {
|
||||||
evt.Sender = new BasicUser {
|
evt.Sender = new ChatUser {
|
||||||
UserId = reader.GetInt64("event_sender"),
|
UserId = reader.GetInt64("event_sender"),
|
||||||
Username = reader.GetString("event_sender_name"),
|
Username = reader.GetString("event_sender_name"),
|
||||||
Colour = ChatColour.FromMisuzu(reader.GetInt32("event_sender_colour")),
|
Colour = ChatColour.FromMisuzu(reader.GetInt32("event_sender_colour")),
|
||||||
|
|
|
@ -4,7 +4,7 @@ using System.Text.Json.Serialization;
|
||||||
namespace SharpChat.Events {
|
namespace SharpChat.Events {
|
||||||
public class ChatMessage : IChatMessage {
|
public class ChatMessage : IChatMessage {
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public BasicUser Sender { get; set; }
|
public ChatUser Sender { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string ChannelName { get; set; }
|
public string ChannelName { get; set; }
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace SharpChat.Events {
|
||||||
|
|
||||||
public interface IChatEvent {
|
public interface IChatEvent {
|
||||||
DateTimeOffset DateTime { get; set; }
|
DateTimeOffset DateTime { get; set; }
|
||||||
BasicUser Sender { get; set; }
|
ChatUser Sender { get; set; }
|
||||||
string ChannelName { get; set; }
|
string ChannelName { get; set; }
|
||||||
ChatMessageFlags Flags { get; set; }
|
ChatMessageFlags Flags { get; set; }
|
||||||
long SequenceId { get; set; }
|
long SequenceId { get; set; }
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace SharpChat.Events {
|
||||||
public DateTimeOffset DateTime { get; set; }
|
public DateTimeOffset DateTime { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public BasicUser Sender { get; set; }
|
public ChatUser Sender { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string ChannelName { get; set; }
|
public string ChannelName { get; set; }
|
||||||
|
@ -19,7 +19,7 @@ namespace SharpChat.Events {
|
||||||
public long SequenceId { get; set; }
|
public long SequenceId { get; set; }
|
||||||
|
|
||||||
public UserChannelJoinEvent() { }
|
public UserChannelJoinEvent() { }
|
||||||
public UserChannelJoinEvent(DateTimeOffset joined, BasicUser user, ChatChannel channel) {
|
public UserChannelJoinEvent(DateTimeOffset joined, ChatUser user, ChatChannel channel) {
|
||||||
DateTime = joined;
|
DateTime = joined;
|
||||||
Sender = user;
|
Sender = user;
|
||||||
ChannelName = channel.Name;
|
ChannelName = channel.Name;
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace SharpChat.Events {
|
||||||
public DateTimeOffset DateTime { get; set; }
|
public DateTimeOffset DateTime { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public BasicUser Sender { get; set; }
|
public ChatUser Sender { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string ChannelName { get; set; }
|
public string ChannelName { get; set; }
|
||||||
|
@ -19,7 +19,7 @@ namespace SharpChat.Events {
|
||||||
public long SequenceId { get; set; }
|
public long SequenceId { get; set; }
|
||||||
|
|
||||||
public UserChannelLeaveEvent() { }
|
public UserChannelLeaveEvent() { }
|
||||||
public UserChannelLeaveEvent(DateTimeOffset parted, BasicUser user, ChatChannel channel) {
|
public UserChannelLeaveEvent(DateTimeOffset parted, ChatUser user, ChatChannel channel) {
|
||||||
DateTime = parted;
|
DateTime = parted;
|
||||||
Sender = user;
|
Sender = user;
|
||||||
ChannelName = channel.Name;
|
ChannelName = channel.Name;
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace SharpChat.Events {
|
||||||
public DateTimeOffset DateTime { get; set; }
|
public DateTimeOffset DateTime { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public BasicUser Sender { get; set; }
|
public ChatUser Sender { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string ChannelName { get; set; }
|
public string ChannelName { get; set; }
|
||||||
|
@ -19,7 +19,7 @@ namespace SharpChat.Events {
|
||||||
public long SequenceId { get; set; }
|
public long SequenceId { get; set; }
|
||||||
|
|
||||||
public UserConnectEvent() { }
|
public UserConnectEvent() { }
|
||||||
public UserConnectEvent(DateTimeOffset joined, BasicUser user, ChatChannel channel) {
|
public UserConnectEvent(DateTimeOffset joined, ChatUser user, ChatChannel channel) {
|
||||||
DateTime = joined;
|
DateTime = joined;
|
||||||
Sender = user;
|
Sender = user;
|
||||||
ChannelName = channel.Name;
|
ChannelName = channel.Name;
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace SharpChat.Events {
|
||||||
public DateTimeOffset DateTime { get; set; }
|
public DateTimeOffset DateTime { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public BasicUser Sender { get; set; }
|
public ChatUser Sender { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string ChannelName { get; set; }
|
public string ChannelName { get; set; }
|
||||||
|
@ -24,7 +24,7 @@ namespace SharpChat.Events {
|
||||||
public UserDisconnectReason Reason { get; set; }
|
public UserDisconnectReason Reason { get; set; }
|
||||||
|
|
||||||
public UserDisconnectEvent() { }
|
public UserDisconnectEvent() { }
|
||||||
public UserDisconnectEvent(DateTimeOffset parted, BasicUser user, ChatChannel channel, UserDisconnectReason reason) {
|
public UserDisconnectEvent(DateTimeOffset parted, ChatUser user, ChatChannel channel, UserDisconnectReason reason) {
|
||||||
DateTime = parted;
|
DateTime = parted;
|
||||||
Sender = user;
|
Sender = user;
|
||||||
ChannelName = channel.Name;
|
ChannelName = channel.Name;
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace SharpChat.PacketHandlers {
|
||||||
|
|
||||||
if(channel == null
|
if(channel == null
|
||||||
|| !ctx.Chat.IsInChannel(user, channel)
|
|| !ctx.Chat.IsInChannel(user, channel)
|
||||||
|| (user.IsSilenced && !user.Can(ChatUserPermissions.SilenceUser)))
|
/*|| (user.IsSilenced && !user.Can(ChatUserPermissions.SilenceUser))*/)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(user.Status != ChatUserStatus.Online) {
|
if(user.Status != ChatUserStatus.Online) {
|
||||||
|
|
45
SharpChat/RateLimiter.cs
Normal file
45
SharpChat/RateLimiter.cs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace SharpChat {
|
||||||
|
public class RateLimiter {
|
||||||
|
public const int DEFAULT_SIZE = 30;
|
||||||
|
public const int DEFAULT_MINIMUM_DELAY = 10000;
|
||||||
|
public const int DEFAULT_RISKY_OFFSET = 5;
|
||||||
|
|
||||||
|
private readonly int Size;
|
||||||
|
private readonly int MinimumDelay;
|
||||||
|
private readonly int RiskyOffset;
|
||||||
|
private readonly long[] TimePoints;
|
||||||
|
|
||||||
|
public RateLimiter(
|
||||||
|
int size = DEFAULT_SIZE,
|
||||||
|
int minDelay = DEFAULT_MINIMUM_DELAY,
|
||||||
|
int riskyOffset = DEFAULT_RISKY_OFFSET
|
||||||
|
) {
|
||||||
|
if(size < 2)
|
||||||
|
throw new ArgumentException("Size is too small.", nameof(size));
|
||||||
|
if(minDelay < 1000)
|
||||||
|
throw new ArgumentException("Minimum delay is inhuman.", nameof(minDelay));
|
||||||
|
if(riskyOffset != 0) {
|
||||||
|
if(riskyOffset >= size)
|
||||||
|
throw new ArgumentException("Risky offset may not be greater or equal to the size.", nameof(riskyOffset));
|
||||||
|
else if(riskyOffset < 0)
|
||||||
|
throw new ArgumentException("Risky offset may not be negative.", nameof(riskyOffset));
|
||||||
|
}
|
||||||
|
|
||||||
|
Size = size;
|
||||||
|
MinimumDelay = minDelay;
|
||||||
|
RiskyOffset = riskyOffset;
|
||||||
|
TimePoints = new long[Size];
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsRisky => TimePoints[RiskyOffset] != 0 && TimePoints[RiskyOffset + 1] != 0 && TimePoints[RiskyOffset] + MinimumDelay >= TimePoints[Size - 1];
|
||||||
|
public bool IsExceeded => TimePoints[0] != 0 && TimePoints[1] != 0 && TimePoints[0] + MinimumDelay >= TimePoints[Size - 1];
|
||||||
|
|
||||||
|
public void Update() {
|
||||||
|
for(int i = 1; i < Size; ++i)
|
||||||
|
TimePoints[i - 1] = TimePoints[i];
|
||||||
|
TimePoints[Size - 1] = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -101,8 +101,8 @@ namespace SharpChat {
|
||||||
new PardonUserCommand(msz),
|
new PardonUserCommand(msz),
|
||||||
new PardonAddressCommand(msz),
|
new PardonAddressCommand(msz),
|
||||||
new BanListCommand(msz),
|
new BanListCommand(msz),
|
||||||
new SilenceApplyCommand(),
|
//new SilenceApplyCommand(),
|
||||||
new SilenceRevokeCommand(),
|
//new SilenceRevokeCommand(),
|
||||||
new RemoteAddressCommand(),
|
new RemoteAddressCommand(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -182,9 +182,9 @@ namespace SharpChat {
|
||||||
|
|
||||||
// this doesn't affect non-authed connections?????
|
// this doesn't affect non-authed connections?????
|
||||||
if(conn.User is not null && conn.User.HasFloodProtection) {
|
if(conn.User is not null && conn.User.HasFloodProtection) {
|
||||||
conn.User.RateLimiter.AddTimePoint();
|
conn.User.RateLimiter.Update();
|
||||||
|
|
||||||
if(conn.User.RateLimiter.State == ChatRateLimitState.Kick) {
|
if(conn.User.RateLimiter.IsExceeded) {
|
||||||
Task.Run(async () => {
|
Task.Run(async () => {
|
||||||
TimeSpan duration = TimeSpan.FromSeconds(FloodKickLength);
|
TimeSpan duration = TimeSpan.FromSeconds(FloodKickLength);
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ namespace SharpChat {
|
||||||
Context.BanUser(conn.User, duration, UserDisconnectReason.Flood);
|
Context.BanUser(conn.User, duration, UserDisconnectReason.Flood);
|
||||||
}).Wait();
|
}).Wait();
|
||||||
return;
|
return;
|
||||||
} else if(conn.User.RateLimiter.State == ChatRateLimitState.Warning)
|
} else if(conn.User.RateLimiter.IsRisky)
|
||||||
Context.SendTo(conn.User, new FloodWarningPacket());
|
Context.SendTo(conn.User, new FloodWarningPacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue