Some cleanups (snapshot, don't run this).
This commit is contained in:
parent
68a523f76a
commit
bd23d3aa15
35 changed files with 102 additions and 209 deletions
SharpChat
ChatChannel.csChatColour.csChatCommandContext.csChatConnection.csChatContext.csChatPacketHandlerContext.csChatUser.cs
Commands
BanListCommand.csChannelCreateCommand.csChannelDeleteCommand.csChannelJoinCommand.csKickBanCommand.csMessageWhisperCommand.csPardonAddressCommand.csPardonUserCommand.csShutdownRestartCommand.csUserNickCommand.csWhoCommand.csWhoisCommand.cs
Config
EventStorage
Misuzu
Packet
MessagePopulatePacket.csUserChannelForceJoinPacket.csUserChannelJoinPacket.csUserUpdateNotificationPacket.csUserUpdatePacket.csUsersPopulatePacket.cs
PacketHandlers
SockChatServer.cs
|
@ -12,14 +12,6 @@ namespace SharpChat {
|
||||||
public bool HasPassword
|
public bool HasPassword
|
||||||
=> !string.IsNullOrWhiteSpace(Password);
|
=> !string.IsNullOrWhiteSpace(Password);
|
||||||
|
|
||||||
public ChatChannel(
|
|
||||||
ChatUser owner,
|
|
||||||
string name,
|
|
||||||
string? password = null,
|
|
||||||
bool isTemporary = false,
|
|
||||||
int rank = 0
|
|
||||||
) : this(name, password, isTemporary, rank, owner?.UserId ?? 0) {}
|
|
||||||
|
|
||||||
public ChatChannel(
|
public ChatChannel(
|
||||||
string name,
|
string name,
|
||||||
string? password = null,
|
string? password = null,
|
||||||
|
@ -44,10 +36,6 @@ namespace SharpChat {
|
||||||
&& OwnerId == user.UserId;
|
&& OwnerId == user.UserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
return Name.GetHashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool CheckName(string name) {
|
public static bool CheckName(string name) {
|
||||||
return !string.IsNullOrWhiteSpace(name) && name.All(CheckNameChar);
|
return !string.IsNullOrWhiteSpace(name) && name.All(CheckNameChar);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,19 +21,11 @@
|
||||||
Inherits = false;
|
Inherits = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object? obj) {
|
|
||||||
return obj is ChatColour colour && Equals(colour);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(ChatColour other) {
|
public bool Equals(ChatColour other) {
|
||||||
return Red == other.Red
|
return Inherits == other.Inherits
|
||||||
|
&& Red == other.Red
|
||||||
&& Green == other.Green
|
&& Green == other.Green
|
||||||
&& Blue == other.Blue
|
&& Blue == other.Blue;
|
||||||
&& Inherits == other.Inherits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
return ToMisuzu();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
|
@ -65,13 +57,5 @@
|
||||||
? None
|
? None
|
||||||
: FromRawRGB(raw);
|
: FromRawRGB(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator ==(ChatColour left, ChatColour right) {
|
|
||||||
return left.Equals(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(ChatColour left, ChatColour right) {
|
|
||||||
return !(left == right);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,35 +17,16 @@ namespace SharpChat {
|
||||||
ChatConnection connection,
|
ChatConnection connection,
|
||||||
ChatChannel channel
|
ChatChannel channel
|
||||||
) {
|
) {
|
||||||
if(text == null)
|
Chat = chat;
|
||||||
throw new ArgumentNullException(nameof(text));
|
User = user;
|
||||||
|
Connection = connection;
|
||||||
Chat = chat ?? throw new ArgumentNullException(nameof(chat));
|
Channel = channel;
|
||||||
User = user ?? throw new ArgumentNullException(nameof(user));
|
|
||||||
Connection = connection ?? throw new ArgumentNullException(nameof(connection));
|
|
||||||
Channel = channel ?? throw new ArgumentNullException(nameof(channel));
|
|
||||||
|
|
||||||
string[] parts = text[1..].Split(' ');
|
string[] parts = text[1..].Split(' ');
|
||||||
Name = parts.First().Replace(".", string.Empty);
|
Name = parts.First().Replace(".", string.Empty);
|
||||||
Args = parts.Skip(1).ToArray();
|
Args = parts.Skip(1).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChatCommandContext(
|
|
||||||
string name,
|
|
||||||
string[] args,
|
|
||||||
ChatContext chat,
|
|
||||||
ChatUser user,
|
|
||||||
ChatConnection connection,
|
|
||||||
ChatChannel channel
|
|
||||||
) {
|
|
||||||
Name = name ?? throw new ArgumentNullException(nameof(name));
|
|
||||||
Args = args ?? throw new ArgumentNullException(nameof(args));
|
|
||||||
Chat = chat ?? throw new ArgumentNullException(nameof(chat));
|
|
||||||
User = user ?? throw new ArgumentNullException(nameof(user));
|
|
||||||
Connection = connection ?? throw new ArgumentNullException(nameof(connection));
|
|
||||||
Channel = channel ?? throw new ArgumentNullException(nameof(channel));
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool NameEquals(string name) {
|
public bool NameEquals(string name) {
|
||||||
return Name.Equals(name, StringComparison.InvariantCultureIgnoreCase);
|
return Name.Equals(name, StringComparison.InvariantCultureIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,9 +84,5 @@ namespace SharpChat {
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return Id;
|
return Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
return Id.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,16 @@ namespace SharpChat {
|
||||||
|
|
||||||
public readonly SemaphoreSlim ContextAccess = new(1, 1);
|
public readonly SemaphoreSlim ContextAccess = new(1, 1);
|
||||||
|
|
||||||
public HashSet<ChatChannel> Channels { get; } = new();
|
public Dictionary<string, ChatChannel> Channels { get; } = new();
|
||||||
public HashSet<ChatConnection> Connections { get; } = new();
|
public List<ChatConnection> Connections { get; } = new();
|
||||||
public HashSet<ChatUser> Users { get; } = new();
|
public Dictionary<long, ChatUser> Users { get; } = new();
|
||||||
public IEventStorage Events { get; }
|
public IEventStorage Events { get; }
|
||||||
public HashSet<ChannelUserAssoc> ChannelUsers { get; } = new();
|
public HashSet<ChannelUserAssoc> ChannelUsers { get; } = new();
|
||||||
public Dictionary<long, RateLimiter> UserRateLimiters { get; } = new();
|
public Dictionary<long, RateLimiter> UserRateLimiters { get; } = new();
|
||||||
public Dictionary<long, ChatChannel> UserLastChannel { get; } = new();
|
public Dictionary<long, ChatChannel> UserLastChannel { get; } = new();
|
||||||
|
|
||||||
public ChatContext(IEventStorage evtStore) {
|
public ChatContext(IEventStorage evtStore) {
|
||||||
Events = evtStore ?? throw new ArgumentNullException(nameof(evtStore));
|
Events = evtStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchEvent(IChatEvent eventInfo) {
|
public void DispatchEvent(IChatEvent eventInfo) {
|
||||||
|
@ -37,11 +37,11 @@ namespace SharpChat {
|
||||||
if(mce.ChannelName?.StartsWith("@") != true)
|
if(mce.ChannelName?.StartsWith("@") != true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IEnumerable<long> uids = mce.ChannelName[1..].Split('-', 3).Select(u => long.TryParse(u, out long up) ? up : -1);
|
long[] targetIds = mce.ChannelName[1..].Split('-', 3).Select(u => long.TryParse(u, out long up) ? up : -1).ToArray();
|
||||||
if(uids.Count() != 2)
|
if(targetIds.Length != 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IEnumerable<ChatUser> users = Users.Where(u => uids.Any(uid => uid == u.UserId));
|
ChatUser[] users = Users.Where(kvp => targetIds.Contains(kvp.Key)).Select(kvp => kvp.Value).ToArray();
|
||||||
ChatUser? target = users.FirstOrDefault(u => u.UserId != mce.SenderId);
|
ChatUser? target = users.FirstOrDefault(u => u.UserId != mce.SenderId);
|
||||||
if(target == null)
|
if(target == null)
|
||||||
return;
|
return;
|
||||||
|
@ -56,7 +56,7 @@ namespace SharpChat {
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
ChatChannel? channel = Channels.FirstOrDefault(c => c.NameEquals(mce.ChannelName));
|
ChatChannel? channel = Channels.Values.FirstOrDefault(c => c.NameEquals(mce.ChannelName));
|
||||||
if(channel != null)
|
if(channel != null)
|
||||||
SendTo(channel, new MessageAddPacket(
|
SendTo(channel, new MessageAddPacket(
|
||||||
mce.MessageId,
|
mce.MessageId,
|
||||||
|
@ -88,9 +88,11 @@ namespace SharpChat {
|
||||||
Logger.Write($"Nuked connection {conn.Id} associated with {conn.User}.");
|
Logger.Write($"Nuked connection {conn.Id} associated with {conn.User}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections.RemoveWhere(conn => conn.IsDisposed);
|
int removed = Connections.RemoveAll(conn => conn.IsDisposed);
|
||||||
|
if(removed > 0)
|
||||||
|
Logger.Write($"Removed {removed} nuked connections from the list.");
|
||||||
|
|
||||||
foreach(ChatUser user in Users)
|
foreach(ChatUser user in Users.Values)
|
||||||
if(!Connections.Any(conn => conn.User == user)) {
|
if(!Connections.Any(conn => conn.User == user)) {
|
||||||
HandleDisconnect(user, ChatUserDisconnectReason.TimeOut);
|
HandleDisconnect(user, ChatUserDisconnectReason.TimeOut);
|
||||||
Logger.Write($"Timed out {user} (no more connections).");
|
Logger.Write($"Timed out {user} (no more connections).");
|
||||||
|
@ -118,7 +120,7 @@ namespace SharpChat {
|
||||||
|
|
||||||
public ChatChannel[] GetUserChannels(ChatUser user) {
|
public ChatChannel[] GetUserChannels(ChatUser user) {
|
||||||
string[] names = GetUserChannelNames(user);
|
string[] names = GetUserChannelNames(user);
|
||||||
return Channels.Where(c => names.Any(n => c.NameEquals(n))).ToArray();
|
return Channels.Values.Where(c => names.Any(n => c.NameEquals(n))).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long[] GetChannelUserIds(ChatChannel channel) {
|
public long[] GetChannelUserIds(ChatChannel channel) {
|
||||||
|
@ -126,8 +128,8 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChatUser[] GetChannelUsers(ChatChannel channel) {
|
public ChatUser[] GetChannelUsers(ChatChannel channel) {
|
||||||
long[] ids = GetChannelUserIds(channel);
|
long[] targetIds = GetChannelUserIds(channel);
|
||||||
return Users.Where(u => ids.Contains(u.UserId)).ToArray();
|
return Users.Values.Where(u => targetIds.Contains(u.UserId)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateUser(
|
public void UpdateUser(
|
||||||
|
@ -142,9 +144,6 @@ namespace SharpChat {
|
||||||
bool? isSuper = null,
|
bool? isSuper = null,
|
||||||
bool silent = false
|
bool silent = false
|
||||||
) {
|
) {
|
||||||
if(user == null)
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
|
|
||||||
bool hasChanged = false;
|
bool hasChanged = false;
|
||||||
string? previousName = null;
|
string? previousName = null;
|
||||||
|
|
||||||
|
@ -161,7 +160,7 @@ namespace SharpChat {
|
||||||
hasChanged = true;
|
hasChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(colour.HasValue && user.Colour != colour.Value) {
|
if(colour.HasValue && user.Colour.Equals(colour.Value)) {
|
||||||
user.Colour = colour.Value;
|
user.Colour = colour.Value;
|
||||||
hasChanged = true;
|
hasChanged = true;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +214,7 @@ namespace SharpChat {
|
||||||
foreach(ChatConnection conn in Connections)
|
foreach(ChatConnection conn in Connections)
|
||||||
if(conn.User == user)
|
if(conn.User == user)
|
||||||
conn.Dispose();
|
conn.Dispose();
|
||||||
Connections.RemoveWhere(conn => conn.IsDisposed);
|
Connections.RemoveAll(conn => conn.IsDisposed);
|
||||||
|
|
||||||
HandleDisconnect(user, reason);
|
HandleDisconnect(user, reason);
|
||||||
}
|
}
|
||||||
|
@ -261,11 +260,11 @@ namespace SharpChat {
|
||||||
|
|
||||||
HandleChannelEventLog(chan.Name, p => conn.Send(p));
|
HandleChannelEventLog(chan.Name, p => conn.Send(p));
|
||||||
|
|
||||||
conn.Send(new ChannelsPopulatePacket(Channels.Where(c => c.Rank <= user.Rank).Select(
|
conn.Send(new ChannelsPopulatePacket(Channels.Values.Where(c => c.Rank <= user.Rank).Select(
|
||||||
channel => new ChannelsPopulatePacket.ListEntry(channel.Name, channel.HasPassword, channel.IsTemporary)
|
channel => new ChannelsPopulatePacket.ListEntry(channel.Name, channel.HasPassword, channel.IsTemporary)
|
||||||
).ToArray()));
|
).ToArray()));
|
||||||
|
|
||||||
Users.Add(user);
|
Users.Add(user.UserId, user);
|
||||||
|
|
||||||
ChannelUsers.Add(new ChannelUserAssoc(user.UserId, chan.Name));
|
ChannelUsers.Add(new ChannelUserAssoc(user.UserId, chan.Name));
|
||||||
UserLastChannel[user.UserId] = chan;
|
UserLastChannel[user.UserId] = chan;
|
||||||
|
@ -273,7 +272,7 @@ namespace SharpChat {
|
||||||
|
|
||||||
public void HandleDisconnect(ChatUser user, ChatUserDisconnectReason reason = ChatUserDisconnectReason.Leave) {
|
public void HandleDisconnect(ChatUser user, ChatUserDisconnectReason reason = ChatUserDisconnectReason.Leave) {
|
||||||
UpdateUser(user, status: ChatUserStatus.Offline);
|
UpdateUser(user, status: ChatUserStatus.Offline);
|
||||||
Users.Remove(user);
|
Users.Remove(user.UserId);
|
||||||
UserLastChannel.Remove(user.UserId);
|
UserLastChannel.Remove(user.UserId);
|
||||||
|
|
||||||
ChatChannel[] channels = GetUserChannels(user);
|
ChatChannel[] channels = GetUserChannels(user);
|
||||||
|
@ -313,7 +312,7 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ForceChannelSwitch(ChatUser user, ChatChannel chan) {
|
public void ForceChannelSwitch(ChatUser user, ChatChannel chan) {
|
||||||
if(!Channels.Contains(chan))
|
if(!Channels.ContainsValue(chan))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ChatChannel oldChan = UserLastChannel[user.UserId];
|
ChatChannel oldChan = UserLastChannel[user.UserId];
|
||||||
|
@ -340,31 +339,18 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send(IServerPacket packet) {
|
public void Send(IServerPacket packet) {
|
||||||
if(packet == null)
|
|
||||||
throw new ArgumentNullException(nameof(packet));
|
|
||||||
|
|
||||||
foreach(ChatConnection conn in Connections)
|
foreach(ChatConnection conn in Connections)
|
||||||
if(conn.IsAuthed)
|
if(conn.IsAuthed)
|
||||||
conn.Send(packet);
|
conn.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendTo(ChatUser user, IServerPacket packet) {
|
public void SendTo(ChatUser user, IServerPacket packet) {
|
||||||
if(user == null)
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
if(packet == null)
|
|
||||||
throw new ArgumentNullException(nameof(packet));
|
|
||||||
|
|
||||||
foreach(ChatConnection conn in Connections)
|
foreach(ChatConnection conn in Connections)
|
||||||
if(conn.IsAlive && conn.User == user)
|
if(conn.IsAlive && conn.User == user)
|
||||||
conn.Send(packet);
|
conn.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendTo(ChatChannel channel, IServerPacket packet) {
|
public void SendTo(ChatChannel channel, IServerPacket packet) {
|
||||||
if(channel == null)
|
|
||||||
throw new ArgumentNullException(nameof(channel));
|
|
||||||
if(packet == null)
|
|
||||||
throw new ArgumentNullException(nameof(packet));
|
|
||||||
|
|
||||||
// might be faster to grab the users first and then cascade into that SendTo
|
// might be faster to grab the users first and then cascade into that SendTo
|
||||||
IEnumerable<ChatConnection> conns = Connections.Where(c => c.IsAuthed && IsInChannel(c.User, channel));
|
IEnumerable<ChatConnection> conns = Connections.Where(c => c.IsAuthed && IsInChannel(c.User, channel));
|
||||||
foreach(ChatConnection conn in conns)
|
foreach(ChatConnection conn in conns)
|
||||||
|
@ -372,12 +358,7 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendToUserChannels(ChatUser user, IServerPacket packet) {
|
public void SendToUserChannels(ChatUser user, IServerPacket packet) {
|
||||||
if(user == null)
|
IEnumerable<ChatChannel> chans = Channels.Values.Where(c => IsInChannel(user, c));
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
if(packet == null)
|
|
||||||
throw new ArgumentNullException(nameof(packet));
|
|
||||||
|
|
||||||
IEnumerable<ChatChannel> chans = Channels.Where(c => IsInChannel(user, c));
|
|
||||||
IEnumerable<ChatConnection> conns = Connections.Where(conn => conn.IsAuthed && ChannelUsers.Any(cu => cu.UserId == conn.User?.UserId && chans.Any(chan => chan.NameEquals(cu.ChannelName))));
|
IEnumerable<ChatConnection> conns = Connections.Where(conn => conn.IsAuthed && ChannelUsers.Any(cu => cu.UserId == conn.User?.UserId && chans.Any(chan => chan.NameEquals(cu.ChannelName))));
|
||||||
foreach(ChatConnection conn in conns)
|
foreach(ChatConnection conn in conns)
|
||||||
conn.Send(packet);
|
conn.Send(packet);
|
||||||
|
@ -388,9 +369,6 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ForceChannel(ChatUser user, ChatChannel? chan = null) {
|
public void ForceChannel(ChatUser user, ChatChannel? chan = null) {
|
||||||
if(user == null)
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
|
|
||||||
if(chan == null && !UserLastChannel.TryGetValue(user.UserId, out chan))
|
if(chan == null && !UserLastChannel.TryGetValue(user.UserId, out chan))
|
||||||
throw new ArgumentException("no channel???");
|
throw new ArgumentException("no channel???");
|
||||||
|
|
||||||
|
@ -403,9 +381,7 @@ namespace SharpChat {
|
||||||
int? minRank = null,
|
int? minRank = null,
|
||||||
string? password = null
|
string? password = null
|
||||||
) {
|
) {
|
||||||
if(channel == null)
|
if(!Channels.ContainsValue(channel))
|
||||||
throw new ArgumentNullException(nameof(channel));
|
|
||||||
if(!Channels.Contains(channel))
|
|
||||||
throw new ArgumentException("Provided channel is not registered with this manager.", nameof(channel));
|
throw new ArgumentException("Provided channel is not registered with this manager.", nameof(channel));
|
||||||
|
|
||||||
string prevName = channel.Name;
|
string prevName = channel.Name;
|
||||||
|
@ -420,7 +396,7 @@ namespace SharpChat {
|
||||||
channel.Password = password;
|
channel.Password = password;
|
||||||
|
|
||||||
// TODO: Users that no longer have access to the channel/gained access to the channel by the rank change should receive delete and create packets respectively
|
// TODO: Users that no longer have access to the channel/gained access to the channel by the rank change should receive delete and create packets respectively
|
||||||
foreach(ChatUser user in Users.Where(u => u.Rank >= channel.Rank)) {
|
foreach(ChatUser user in Users.Values.Where(u => u.Rank >= channel.Rank)) {
|
||||||
SendTo(user, new ChannelUpdatePacket(prevName, channel.Name, channel.HasPassword, channel.IsTemporary));
|
SendTo(user, new ChannelUpdatePacket(prevName, channel.Name, channel.HasPassword, channel.IsTemporary));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -429,12 +405,12 @@ namespace SharpChat {
|
||||||
if(channel == null || !Channels.Any())
|
if(channel == null || !Channels.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ChatChannel? defaultChannel = Channels.FirstOrDefault();
|
ChatChannel? defaultChannel = Channels.Values.FirstOrDefault();
|
||||||
if(defaultChannel == null)
|
if(defaultChannel == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Remove channel from the listing
|
// Remove channel from the listing
|
||||||
Channels.Remove(channel);
|
Channels.Remove(channel.Name);
|
||||||
|
|
||||||
// Move all users back to the main channel
|
// Move all users back to the main channel
|
||||||
// TODO: Replace this with a kick. SCv2 supports being in 0 channels, SCv1 should force the user back to DefaultChannel.
|
// TODO: Replace this with a kick. SCv2 supports being in 0 channels, SCv1 should force the user back to DefaultChannel.
|
||||||
|
@ -442,7 +418,7 @@ namespace SharpChat {
|
||||||
SwitchChannel(user, defaultChannel, string.Empty);
|
SwitchChannel(user, defaultChannel, string.Empty);
|
||||||
|
|
||||||
// Broadcast deletion of channel
|
// Broadcast deletion of channel
|
||||||
foreach(ChatUser user in Users.Where(u => u.Rank >= channel.Rank))
|
foreach(ChatUser user in Users.Values.Where(u => u.Rank >= channel.Rank))
|
||||||
SendTo(user, new ChannelDeletePacket(channel.Name));
|
SendTo(user, new ChannelDeletePacket(channel.Name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@ namespace SharpChat {
|
||||||
ChatContext chat,
|
ChatContext chat,
|
||||||
ChatConnection connection
|
ChatConnection connection
|
||||||
) {
|
) {
|
||||||
Text = text ?? throw new ArgumentNullException(nameof(text));
|
Text = text;
|
||||||
Chat = chat ?? throw new ArgumentNullException(nameof(chat));
|
Chat = chat;
|
||||||
Connection = connection ?? throw new ArgumentNullException(nameof(connection));
|
Connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CheckPacketId(string packetId) {
|
public bool CheckPacketId(string packetId) {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public class ChatUser : IEquatable<ChatUser> {
|
public class ChatUser {
|
||||||
public const int DEFAULT_SIZE = 30;
|
public const int DEFAULT_SIZE = 30;
|
||||||
public const int DEFAULT_MINIMUM_DELAY = 10000;
|
public const int DEFAULT_MINIMUM_DELAY = 10000;
|
||||||
public const int DEFAULT_RISKY_OFFSET = 5;
|
public const int DEFAULT_RISKY_OFFSET = 5;
|
||||||
|
@ -34,7 +34,7 @@ namespace SharpChat {
|
||||||
|
|
||||||
public ChatUser(
|
public ChatUser(
|
||||||
long userId,
|
long userId,
|
||||||
string? userName,
|
string userName,
|
||||||
ChatColour colour,
|
ChatColour colour,
|
||||||
int rank,
|
int rank,
|
||||||
ChatUserPermissions perms,
|
ChatUserPermissions perms,
|
||||||
|
@ -44,7 +44,7 @@ namespace SharpChat {
|
||||||
bool isSuper = false
|
bool isSuper = false
|
||||||
) {
|
) {
|
||||||
UserId = userId;
|
UserId = userId;
|
||||||
UserName = userName ?? throw new ArgumentNullException(nameof(userName));
|
UserName = userName;
|
||||||
Colour = colour;
|
Colour = colour;
|
||||||
Rank = rank;
|
Rank = rank;
|
||||||
Permissions = perms;
|
Permissions = perms;
|
||||||
|
@ -61,18 +61,6 @@ namespace SharpChat {
|
||||||
|| string.Equals(name, LegacyNameWithStatus, StringComparison.InvariantCultureIgnoreCase);
|
|| string.Equals(name, LegacyNameWithStatus, StringComparison.InvariantCultureIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
return UserId.GetHashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object? obj) {
|
|
||||||
return Equals(obj as ChatUser);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(ChatUser? other) {
|
|
||||||
return UserId == other?.UserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
||||||
? $"@{user1.UserId}-{user2.UserId}"
|
? $"@{user1.UserId}-{user2.UserId}"
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace SharpChat.Commands {
|
||||||
private readonly MisuzuClient Misuzu;
|
private readonly MisuzuClient Misuzu;
|
||||||
|
|
||||||
public BanListCommand(MisuzuClient msz) {
|
public BanListCommand(MisuzuClient msz) {
|
||||||
Misuzu = msz ?? throw new ArgumentNullException(nameof(msz));
|
Misuzu = msz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(ChatCommandContext ctx) {
|
||||||
|
|
|
@ -38,19 +38,20 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx.Chat.Channels.Any(c => c.NameEquals(createChanName))) {
|
if(ctx.Chat.Channels.Values.Any(c => c.NameEquals(createChanName))) {
|
||||||
ctx.Chat.SendTo(ctx.User, new ChannelNameInUseErrorPacket(createChanName));
|
ctx.Chat.SendTo(ctx.User, new ChannelNameInUseErrorPacket(createChanName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatChannel createChan = new(
|
ChatChannel createChan = new(
|
||||||
ctx.User, createChanName,
|
createChanName,
|
||||||
isTemporary: !ctx.User.Permissions.HasFlag(ChatUserPermissions.SetChannelPermanent),
|
isTemporary: !ctx.User.Permissions.HasFlag(ChatUserPermissions.SetChannelPermanent),
|
||||||
rank: createChanHierarchy
|
rank: createChanHierarchy,
|
||||||
|
ownerId: ctx.User.UserId
|
||||||
);
|
);
|
||||||
|
|
||||||
ctx.Chat.Channels.Add(createChan);
|
ctx.Chat.Channels.Add(createChan.Name, createChan);
|
||||||
foreach(ChatUser ccu in ctx.Chat.Users.Where(u => u.Rank >= ctx.Channel.Rank))
|
foreach(ChatUser ccu in ctx.Chat.Users.Values.Where(u => u.Rank >= ctx.Channel.Rank))
|
||||||
ctx.Chat.SendTo(ccu, new ChannelCreatePacket(
|
ctx.Chat.SendTo(ccu, new ChannelCreatePacket(
|
||||||
ctx.Channel.Name,
|
ctx.Channel.Name,
|
||||||
ctx.Channel.HasPassword,
|
ctx.Channel.HasPassword,
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace SharpChat.Commands {
|
||||||
}
|
}
|
||||||
|
|
||||||
string delChanName = string.Join('_', ctx.Args);
|
string delChanName = string.Join('_', ctx.Args);
|
||||||
ChatChannel? delChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(delChanName));
|
ChatChannel? delChan = ctx.Chat.Channels.Values.FirstOrDefault(c => c.NameEquals(delChanName));
|
||||||
|
|
||||||
if(delChan == null) {
|
if(delChan == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(delChanName));
|
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(delChanName));
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace SharpChat.Commands {
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(ChatCommandContext ctx) {
|
||||||
string joinChanStr = ctx.Args.FirstOrDefault() ?? string.Empty;
|
string joinChanStr = ctx.Args.FirstOrDefault() ?? string.Empty;
|
||||||
ChatChannel? joinChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(joinChanStr));
|
ChatChannel? joinChan = ctx.Chat.Channels.Values.FirstOrDefault(c => c.NameEquals(joinChanStr));
|
||||||
|
|
||||||
if(joinChan == null) {
|
if(joinChan == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(joinChanStr));
|
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(joinChanStr));
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace SharpChat.Commands {
|
||||||
private readonly MisuzuClient Misuzu;
|
private readonly MisuzuClient Misuzu;
|
||||||
|
|
||||||
public KickBanCommand(MisuzuClient msz) {
|
public KickBanCommand(MisuzuClient msz) {
|
||||||
Misuzu = msz ?? throw new ArgumentNullException(nameof(msz));
|
Misuzu = msz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(ChatCommandContext ctx) {
|
||||||
|
@ -30,7 +30,7 @@ namespace SharpChat.Commands {
|
||||||
int banReasonIndex = 1;
|
int banReasonIndex = 1;
|
||||||
ChatUser? banUser = null;
|
ChatUser? banUser = null;
|
||||||
|
|
||||||
if(string.IsNullOrEmpty(banUserTarget) || (banUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(banUserTarget))) == null) {
|
if(string.IsNullOrEmpty(banUserTarget) || (banUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.NameEquals(banUserTarget))) == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(banUserTarget));
|
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(banUserTarget));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace SharpChat.Commands {
|
||||||
}
|
}
|
||||||
|
|
||||||
string whisperUserStr = ctx.Args.FirstOrDefault() ?? string.Empty;
|
string whisperUserStr = ctx.Args.FirstOrDefault() ?? string.Empty;
|
||||||
ChatUser? whisperUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(whisperUserStr));
|
ChatUser? whisperUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.NameEquals(whisperUserStr));
|
||||||
|
|
||||||
if(whisperUser == null) {
|
if(whisperUser == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(whisperUserStr));
|
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(whisperUserStr));
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace SharpChat.Commands {
|
||||||
private readonly MisuzuClient Misuzu;
|
private readonly MisuzuClient Misuzu;
|
||||||
|
|
||||||
public PardonAddressCommand(MisuzuClient msz) {
|
public PardonAddressCommand(MisuzuClient msz) {
|
||||||
Misuzu = msz ?? throw new ArgumentNullException(nameof(msz));
|
Misuzu = msz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(ChatCommandContext ctx) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace SharpChat.Commands {
|
||||||
private readonly MisuzuClient Misuzu;
|
private readonly MisuzuClient Misuzu;
|
||||||
|
|
||||||
public PardonUserCommand(MisuzuClient msz) {
|
public PardonUserCommand(MisuzuClient msz) {
|
||||||
Misuzu = msz ?? throw new ArgumentNullException(nameof(msz));
|
Misuzu = msz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(ChatCommandContext ctx) {
|
||||||
|
@ -31,10 +31,10 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatUser? unbanUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(unbanUserTarget));
|
ChatUser? unbanUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.NameEquals(unbanUserTarget));
|
||||||
if(unbanUser == null && long.TryParse(unbanUserTarget, out long unbanUserId)) {
|
if(unbanUser == null && long.TryParse(unbanUserTarget, out long unbanUserId)) {
|
||||||
unbanUserTargetIsName = false;
|
unbanUserTargetIsName = false;
|
||||||
unbanUser = ctx.Chat.Users.FirstOrDefault(u => u.UserId == unbanUserId);
|
unbanUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.UserId == unbanUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(unbanUser != null)
|
if(unbanUser != null)
|
||||||
|
|
|
@ -8,8 +8,8 @@ namespace SharpChat.Commands {
|
||||||
private readonly Func<bool> ShutdownCheck;
|
private readonly Func<bool> ShutdownCheck;
|
||||||
|
|
||||||
public ShutdownRestartCommand(ManualResetEvent waitHandle, Func<bool> shutdownCheck) {
|
public ShutdownRestartCommand(ManualResetEvent waitHandle, Func<bool> shutdownCheck) {
|
||||||
WaitHandle = waitHandle ?? throw new ArgumentNullException(nameof(waitHandle));
|
WaitHandle = waitHandle;
|
||||||
ShutdownCheck = shutdownCheck ?? throw new ArgumentNullException(nameof(shutdownCheck));
|
ShutdownCheck = shutdownCheck;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(ChatCommandContext ctx) {
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace SharpChat.Commands {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
if(setOthersNick && long.TryParse(ctx.Args.FirstOrDefault(), out long targetUserId) && targetUserId > 0) {
|
if(setOthersNick && long.TryParse(ctx.Args.FirstOrDefault(), out long targetUserId) && targetUserId > 0) {
|
||||||
targetUser = ctx.Chat.Users.FirstOrDefault(u => u.UserId == targetUserId);
|
targetUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.UserId == targetUserId);
|
||||||
++offset;
|
++offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ namespace SharpChat.Commands {
|
||||||
else if(string.IsNullOrEmpty(nickStr))
|
else if(string.IsNullOrEmpty(nickStr))
|
||||||
nickStr = string.Empty;
|
nickStr = string.Empty;
|
||||||
|
|
||||||
if(!string.IsNullOrWhiteSpace(nickStr) && ctx.Chat.Users.Any(u => u.NameEquals(nickStr))) {
|
if(!string.IsNullOrWhiteSpace(nickStr) && ctx.Chat.Users.Values.Any(u => u.NameEquals(nickStr))) {
|
||||||
ctx.Chat.SendTo(ctx.User, new UserNameInUseErrorPacket(nickStr));
|
ctx.Chat.SendTo(ctx.User, new UserNameInUseErrorPacket(nickStr));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,13 @@ namespace SharpChat.Commands {
|
||||||
|
|
||||||
if(string.IsNullOrEmpty(channelName)) {
|
if(string.IsNullOrEmpty(channelName)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new WhoServerResponsePacket(
|
ctx.Chat.SendTo(ctx.User, new WhoServerResponsePacket(
|
||||||
ctx.Chat.Users.Select(u => u.LegacyName).ToArray(),
|
ctx.Chat.Users.Values.Select(u => u.LegacyName).ToArray(),
|
||||||
ctx.User.LegacyName
|
ctx.User.LegacyName
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatChannel? channel = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(channelName));
|
ChatChannel? channel = ctx.Chat.Channels.Values.FirstOrDefault(c => c.NameEquals(channelName));
|
||||||
|
|
||||||
if(channel == null) {
|
if(channel == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(channelName));
|
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(channelName));
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace SharpChat.Commands {
|
||||||
string ipUserStr = ctx.Args.FirstOrDefault() ?? string.Empty;
|
string ipUserStr = ctx.Args.FirstOrDefault() ?? string.Empty;
|
||||||
ChatUser? ipUser;
|
ChatUser? ipUser;
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(ipUserStr) || (ipUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(ipUserStr))) == null) {
|
if(string.IsNullOrWhiteSpace(ipUserStr) || (ipUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.NameEquals(ipUserStr))) == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(ipUserStr));
|
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(ipUserStr));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,13 @@ namespace SharpChat.Config {
|
||||||
public static implicit operator T?(CachedValue<T> val) => val.Value;
|
public static implicit operator T?(CachedValue<T> val) => val.Value;
|
||||||
|
|
||||||
public CachedValue(IConfig config, string name, TimeSpan lifetime, T? fallback) {
|
public CachedValue(IConfig config, string name, TimeSpan lifetime, T? fallback) {
|
||||||
Config = config ?? throw new ArgumentNullException(nameof(config));
|
|
||||||
Name = name ?? throw new ArgumentNullException(nameof(name));
|
|
||||||
Lifetime = lifetime;
|
|
||||||
Fallback = fallback;
|
|
||||||
if(string.IsNullOrWhiteSpace(name))
|
if(string.IsNullOrWhiteSpace(name))
|
||||||
throw new ArgumentException("Name cannot be empty.", nameof(name));
|
throw new ArgumentException("Name cannot be empty.", nameof(name));
|
||||||
|
|
||||||
|
Config = config;
|
||||||
|
Name = name;
|
||||||
|
Lifetime = lifetime;
|
||||||
|
Fallback = fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Refresh() {
|
public void Refresh() {
|
||||||
|
|
|
@ -6,10 +6,12 @@ namespace SharpChat.Config {
|
||||||
private string Prefix { get; }
|
private string Prefix { get; }
|
||||||
|
|
||||||
public ScopedConfig(IConfig config, string prefix) {
|
public ScopedConfig(IConfig config, string prefix) {
|
||||||
Config = config ?? throw new ArgumentNullException(nameof(config));
|
|
||||||
Prefix = prefix ?? throw new ArgumentNullException(nameof(prefix));
|
|
||||||
if(string.IsNullOrWhiteSpace(prefix))
|
if(string.IsNullOrWhiteSpace(prefix))
|
||||||
throw new ArgumentException("Prefix must exist.", nameof(prefix));
|
throw new ArgumentException("Prefix must exist.", nameof(prefix));
|
||||||
|
|
||||||
|
Config = config;
|
||||||
|
Prefix = prefix;
|
||||||
|
|
||||||
if(Prefix[^1] != ':')
|
if(Prefix[^1] != ':')
|
||||||
Prefix += ':';
|
Prefix += ':';
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace SharpChat.Config {
|
||||||
: this(new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite)) { }
|
: this(new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite)) { }
|
||||||
|
|
||||||
public StreamConfig(Stream stream) {
|
public StreamConfig(Stream stream) {
|
||||||
Stream = stream ?? throw new ArgumentNullException(nameof(stream));
|
Stream = stream;
|
||||||
if(!Stream.CanRead)
|
if(!Stream.CanRead)
|
||||||
throw new ArgumentException("Provided stream must be readable.", nameof(stream));
|
throw new ArgumentException("Provided stream must be readable.", nameof(stream));
|
||||||
if(!Stream.CanSeek)
|
if(!Stream.CanSeek)
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
using MySqlConnector;
|
using MySqlConnector;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Dynamic;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading.Channels;
|
|
||||||
|
|
||||||
namespace SharpChat.EventStorage
|
namespace SharpChat.EventStorage {
|
||||||
{
|
|
||||||
public partial class MariaDBEventStorage : IEventStorage {
|
public partial class MariaDBEventStorage : IEventStorage {
|
||||||
private string ConnectionString { get; }
|
private string ConnectionString { get; }
|
||||||
|
|
||||||
public MariaDBEventStorage(string connString) {
|
public MariaDBEventStorage(string connString) {
|
||||||
ConnectionString = connString ?? throw new ArgumentNullException(nameof(connString));
|
ConnectionString = connString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddEvent(
|
public void AddEvent(
|
||||||
|
@ -48,9 +45,6 @@ namespace SharpChat.EventStorage
|
||||||
object? data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
if(type == null)
|
|
||||||
throw new ArgumentNullException(nameof(type));
|
|
||||||
|
|
||||||
RunCommand(
|
RunCommand(
|
||||||
"INSERT INTO `sqc_events` (`event_id`, `event_created`, `event_type`, `event_target`, `event_flags`, `event_data`"
|
"INSERT INTO `sqc_events` (`event_id`, `event_created`, `event_type`, `event_target`, `event_flags`, `event_data`"
|
||||||
+ ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`)"
|
+ ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`)"
|
||||||
|
@ -71,9 +65,6 @@ namespace SharpChat.EventStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
public long AddEvent(string type, ChatUser user, ChatChannel channel, object? data = null, StoredEventFlags flags = StoredEventFlags.None) {
|
public long AddEvent(string type, ChatUser user, ChatChannel channel, object? data = null, StoredEventFlags flags = StoredEventFlags.None) {
|
||||||
if(type == null)
|
|
||||||
throw new ArgumentNullException(nameof(type));
|
|
||||||
|
|
||||||
long id = SharpId.Next();
|
long id = SharpId.Next();
|
||||||
|
|
||||||
AddEvent(
|
AddEvent(
|
||||||
|
@ -172,8 +163,6 @@ namespace SharpChat.EventStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveEvent(StoredEventInfo evt) {
|
public void RemoveEvent(StoredEventInfo evt) {
|
||||||
if(evt == null)
|
|
||||||
throw new ArgumentNullException(nameof(evt));
|
|
||||||
RunCommand(
|
RunCommand(
|
||||||
"UPDATE IGNORE `sqc_events` SET `event_deleted` = NOW() WHERE `event_id` = @id AND `event_deleted` IS NULL",
|
"UPDATE IGNORE `sqc_events` SET `event_deleted` = NOW() WHERE `event_id` = @id AND `event_deleted` IS NULL",
|
||||||
new MySqlParameter("id", evt.Id)
|
new MySqlParameter("id", evt.Id)
|
||||||
|
|
|
@ -40,14 +40,11 @@ namespace SharpChat.EventStorage {
|
||||||
object? data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
if(type == null)
|
|
||||||
throw new ArgumentNullException(nameof(type));
|
|
||||||
|
|
||||||
// VES is meant as an emergency fallback but this is something else
|
// VES is meant as an emergency fallback but this is something else
|
||||||
JsonDocument hack = JsonDocument.Parse(data == null ? "{}" : JsonSerializer.Serialize(data));
|
JsonDocument hack = JsonDocument.Parse(data == null ? "{}" : JsonSerializer.Serialize(data));
|
||||||
Events.Add(id, new(id, type, senderId < 1 ? null : new ChatUser(
|
Events.Add(id, new(id, type, senderId < 1 ? null : new ChatUser(
|
||||||
senderId,
|
senderId,
|
||||||
senderName,
|
senderName ?? string.Empty,
|
||||||
senderColour,
|
senderColour,
|
||||||
senderRank,
|
senderRank,
|
||||||
senderPerms,
|
senderPerms,
|
||||||
|
@ -56,9 +53,6 @@ namespace SharpChat.EventStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public long AddEvent(string type, ChatUser user, ChatChannel channel, object? data = null, StoredEventFlags flags = StoredEventFlags.None) {
|
public long AddEvent(string type, ChatUser user, ChatChannel channel, object? data = null, StoredEventFlags flags = StoredEventFlags.None) {
|
||||||
if(type == null)
|
|
||||||
throw new ArgumentNullException(nameof(type));
|
|
||||||
|
|
||||||
long id = SharpId.Next();
|
long id = SharpId.Next();
|
||||||
|
|
||||||
AddEvent(
|
AddEvent(
|
||||||
|
|
|
@ -34,9 +34,7 @@ namespace SharpChat.Misuzu {
|
||||||
private CachedValue<string> SecretKey { get; }
|
private CachedValue<string> SecretKey { get; }
|
||||||
|
|
||||||
public MisuzuClient(HttpClient httpClient, IConfig config) {
|
public MisuzuClient(HttpClient httpClient, IConfig config) {
|
||||||
if(config == null)
|
HttpClient = httpClient;
|
||||||
throw new ArgumentNullException(nameof(config));
|
|
||||||
HttpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
|
|
||||||
|
|
||||||
BaseURL = config.ReadCached("url", DEFAULT_BASE_URL);
|
BaseURL = config.ReadCached("url", DEFAULT_BASE_URL);
|
||||||
SecretKey = config.ReadCached("secret", DEFAULT_SECRET_KEY);
|
SecretKey = config.ReadCached("secret", DEFAULT_SECRET_KEY);
|
||||||
|
@ -77,8 +75,6 @@ namespace SharpChat.Misuzu {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task BumpUsersOnlineAsync(IEnumerable<(string userId, string ipAddr)> list) {
|
public async Task BumpUsersOnlineAsync(IEnumerable<(string userId, string ipAddr)> list) {
|
||||||
if(list == null)
|
|
||||||
throw new ArgumentNullException(nameof(list));
|
|
||||||
if(!list.Any())
|
if(!list.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -164,9 +160,6 @@ namespace SharpChat.Misuzu {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> RevokeBanAsync(MisuzuBanInfo banInfo, BanRevokeKind kind) {
|
public async Task<bool> RevokeBanAsync(MisuzuBanInfo banInfo, BanRevokeKind kind) {
|
||||||
if(banInfo == null)
|
|
||||||
throw new ArgumentNullException(nameof(banInfo));
|
|
||||||
|
|
||||||
string type = kind switch {
|
string type = kind switch {
|
||||||
BanRevokeKind.UserId => "user",
|
BanRevokeKind.UserId => "user",
|
||||||
BanRevokeKind.RemoteAddress => "addr",
|
BanRevokeKind.RemoteAddress => "addr",
|
||||||
|
@ -208,9 +201,9 @@ namespace SharpChat.Misuzu {
|
||||||
string reason
|
string reason
|
||||||
) {
|
) {
|
||||||
if(string.IsNullOrWhiteSpace(targetAddr))
|
if(string.IsNullOrWhiteSpace(targetAddr))
|
||||||
throw new ArgumentNullException(nameof(targetAddr));
|
throw new ArgumentException("targetAddr may not be empty", nameof(targetAddr));
|
||||||
if(string.IsNullOrWhiteSpace(modAddr))
|
if(string.IsNullOrWhiteSpace(modAddr))
|
||||||
throw new ArgumentNullException(nameof(modAddr));
|
throw new ArgumentException("modAddr may not be empty", nameof(modAddr));
|
||||||
if(duration <= TimeSpan.Zero)
|
if(duration <= TimeSpan.Zero)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace SharpChat.Packet {
|
||||||
private readonly bool Notify;
|
private readonly bool Notify;
|
||||||
|
|
||||||
public MessagePopulatePacket(StoredEventInfo evt, bool notify = false) {
|
public MessagePopulatePacket(StoredEventInfo evt, bool notify = false) {
|
||||||
Event = evt ?? throw new ArgumentNullException(nameof(evt));
|
Event = evt;
|
||||||
Notify = notify;
|
Notify = notify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace SharpChat.Packet {
|
||||||
private readonly string ChannelName;
|
private readonly string ChannelName;
|
||||||
|
|
||||||
public UserChannelForceJoinPacket(string channelName) {
|
public UserChannelForceJoinPacket(string channelName) {
|
||||||
ChannelName = channelName ?? throw new ArgumentNullException(nameof(channelName));
|
ChannelName = channelName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Pack() {
|
public override string Pack() {
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace SharpChat.Packet {
|
||||||
ChatUserPermissions userPerms
|
ChatUserPermissions userPerms
|
||||||
) {
|
) {
|
||||||
UserId = userId;
|
UserId = userId;
|
||||||
UserName = userName ?? throw new ArgumentNullException(nameof(userName));
|
UserName = userName;
|
||||||
UserColour = userColour;
|
UserColour = userColour;
|
||||||
UserRank = userRank;
|
UserRank = userRank;
|
||||||
UserPerms = userPerms;
|
UserPerms = userPerms;
|
||||||
|
|
|
@ -7,8 +7,8 @@ namespace SharpChat.Packet {
|
||||||
private readonly long Timestamp;
|
private readonly long Timestamp;
|
||||||
|
|
||||||
public UserUpdateNotificationPacket(string previousName, string newName) {
|
public UserUpdateNotificationPacket(string previousName, string newName) {
|
||||||
PreviousName = previousName ?? throw new ArgumentNullException(nameof(previousName));
|
PreviousName = previousName;
|
||||||
NewName = newName ?? throw new ArgumentNullException(nameof(newName));
|
NewName = newName;
|
||||||
Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
|
Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace SharpChat.Packet {
|
||||||
ChatUserPermissions userPerms
|
ChatUserPermissions userPerms
|
||||||
) {
|
) {
|
||||||
UserId = userId;
|
UserId = userId;
|
||||||
UserName = userName ?? throw new ArgumentNullException(nameof(userName));
|
UserName = userName;
|
||||||
UserColour = userColour;
|
UserColour = userColour;
|
||||||
UserRank = userRank;
|
UserRank = userRank;
|
||||||
UserPerms = userPerms;
|
UserPerms = userPerms;
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace SharpChat.Packet {
|
||||||
private readonly ListEntry[] Entries;
|
private readonly ListEntry[] Entries;
|
||||||
|
|
||||||
public UsersPopulatePacket(ListEntry[] entries) {
|
public UsersPopulatePacket(ListEntry[] entries) {
|
||||||
Entries = entries ?? throw new ArgumentNullException(nameof(entries));
|
Entries = entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Pack() {
|
public override string Pack() {
|
||||||
|
|
|
@ -20,10 +20,10 @@ namespace SharpChat.PacketHandlers {
|
||||||
CachedValue<int> maxMsgLength,
|
CachedValue<int> maxMsgLength,
|
||||||
CachedValue<int> maxConns
|
CachedValue<int> maxConns
|
||||||
) {
|
) {
|
||||||
Misuzu = msz ?? throw new ArgumentNullException(nameof(msz));
|
Misuzu = msz;
|
||||||
DefaultChannel = defaultChannel ?? throw new ArgumentNullException(nameof(defaultChannel));
|
DefaultChannel = defaultChannel;
|
||||||
MaxMessageLength = maxMsgLength ?? throw new ArgumentNullException(nameof(maxMsgLength));
|
MaxMessageLength = maxMsgLength;
|
||||||
MaxConnections = maxConns ?? throw new ArgumentNullException(nameof(maxConns));
|
MaxConnections = maxConns;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatPacketHandlerContext ctx) {
|
public bool IsMatch(ChatPacketHandlerContext ctx) {
|
||||||
|
@ -114,12 +114,12 @@ namespace SharpChat.PacketHandlers {
|
||||||
|
|
||||||
await ctx.Chat.ContextAccess.WaitAsync();
|
await ctx.Chat.ContextAccess.WaitAsync();
|
||||||
try {
|
try {
|
||||||
ChatUser? user = ctx.Chat.Users.FirstOrDefault(u => u.UserId == fai.UserId);
|
ChatUser? user = ctx.Chat.Users.Values.FirstOrDefault(u => u.UserId == fai.UserId);
|
||||||
|
|
||||||
if(user == null)
|
if(user == null)
|
||||||
user = new ChatUser(
|
user = new ChatUser(
|
||||||
fai.UserId,
|
fai.UserId,
|
||||||
fai.UserName,
|
fai.UserName ?? string.Empty,
|
||||||
fai.Colour,
|
fai.Colour,
|
||||||
fai.Rank,
|
fai.Rank,
|
||||||
fai.Permissions,
|
fai.Permissions,
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace SharpChat.PacketHandlers {
|
||||||
private DateTimeOffset LastBump = DateTimeOffset.MinValue;
|
private DateTimeOffset LastBump = DateTimeOffset.MinValue;
|
||||||
|
|
||||||
public PingHandler(MisuzuClient msz) {
|
public PingHandler(MisuzuClient msz) {
|
||||||
Misuzu = msz ?? throw new ArgumentNullException(nameof(msz));
|
Misuzu = msz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatPacketHandlerContext ctx) {
|
public bool IsMatch(ChatPacketHandlerContext ctx) {
|
||||||
|
@ -31,7 +31,7 @@ namespace SharpChat.PacketHandlers {
|
||||||
ctx.Chat.ContextAccess.Wait();
|
ctx.Chat.ContextAccess.Wait();
|
||||||
try {
|
try {
|
||||||
if(LastBump < DateTimeOffset.UtcNow - BumpInterval) {
|
if(LastBump < DateTimeOffset.UtcNow - BumpInterval) {
|
||||||
(string, string)[] bumpList = ctx.Chat.Users
|
(string, string)[] bumpList = ctx.Chat.Users.Values
|
||||||
.Where(u => u.Status == ChatUserStatus.Online && ctx.Chat.Connections.Any(c => c.User == u))
|
.Where(u => u.Status == ChatUserStatus.Online && ctx.Chat.Connections.Any(c => c.User == u))
|
||||||
.Select(u => (u.UserId.ToString(), ctx.Chat.GetRemoteAddresses(u).FirstOrDefault()?.ToString() ?? string.Empty))
|
.Select(u => (u.UserId.ToString(), ctx.Chat.GetRemoteAddresses(u).FirstOrDefault()?.ToString() ?? string.Empty))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
|
@ -15,15 +15,15 @@ namespace SharpChat.PacketHandlers
|
||||||
private List<IChatCommand> Commands { get; } = new();
|
private List<IChatCommand> Commands { get; } = new();
|
||||||
|
|
||||||
public SendMessageHandler(CachedValue<int> maxMsgLength) {
|
public SendMessageHandler(CachedValue<int> maxMsgLength) {
|
||||||
MaxMessageLength = maxMsgLength ?? throw new ArgumentNullException(nameof(maxMsgLength));
|
MaxMessageLength = maxMsgLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCommand(IChatCommand command) {
|
public void AddCommand(IChatCommand command) {
|
||||||
Commands.Add(command ?? throw new ArgumentNullException(nameof(command)));
|
Commands.Add(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCommands(IEnumerable<IChatCommand> commands) {
|
public void AddCommands(IEnumerable<IChatCommand> commands) {
|
||||||
Commands.AddRange(commands ?? throw new ArgumentNullException(nameof(commands)));
|
Commands.AddRange(commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatPacketHandlerContext ctx) {
|
public bool IsMatch(ChatPacketHandlerContext ctx) {
|
||||||
|
|
|
@ -41,8 +41,8 @@ namespace SharpChat {
|
||||||
public SockChatServer(HttpClient httpClient, MisuzuClient msz, IEventStorage evtStore, IConfig config) {
|
public SockChatServer(HttpClient httpClient, MisuzuClient msz, IEventStorage evtStore, IConfig config) {
|
||||||
Logger.Write("Initialising Sock Chat server...");
|
Logger.Write("Initialising Sock Chat server...");
|
||||||
|
|
||||||
HttpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
|
HttpClient = httpClient;
|
||||||
Misuzu = msz ?? throw new ArgumentNullException(nameof(msz));
|
Misuzu = msz;
|
||||||
|
|
||||||
MaxMessageLength = config.ReadCached("msgMaxLength", DEFAULT_MSG_LENGTH_MAX);
|
MaxMessageLength = config.ReadCached("msgMaxLength", DEFAULT_MSG_LENGTH_MAX);
|
||||||
MaxConnections = config.ReadCached("connMaxCount", DEFAULT_MAX_CONNECTIONS);
|
MaxConnections = config.ReadCached("connMaxCount", DEFAULT_MAX_CONNECTIONS);
|
||||||
|
@ -67,13 +67,13 @@ namespace SharpChat {
|
||||||
rank: channelCfg.SafeReadValue("minRank", 0)
|
rank: channelCfg.SafeReadValue("minRank", 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
Context.Channels.Add(channelInfo);
|
Context.Channels.Add(channelInfo.Name, channelInfo);
|
||||||
DefaultChannel ??= channelInfo;
|
DefaultChannel ??= channelInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultChannel ??= new ChatChannel("Default");
|
DefaultChannel ??= new ChatChannel("Default");
|
||||||
if(!Context.Channels.Any())
|
if(Context.Channels.Count < 1)
|
||||||
Context.Channels.Add(DefaultChannel);
|
Context.Channels.Add(DefaultChannel.Name, DefaultChannel);
|
||||||
|
|
||||||
GuestHandlers.Add(new AuthHandler(Misuzu, DefaultChannel, MaxMessageLength, MaxConnections));
|
GuestHandlers.Add(new AuthHandler(Misuzu, DefaultChannel, MaxMessageLength, MaxConnections));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue