Split MariaDB message storage out into its own library.

This commit is contained in:
flash 2025-04-27 01:54:46 +00:00
commit f1d4051fb5
Signed by: flash
GPG key ID: 2C9C2C574D47FE3E
23 changed files with 255 additions and 228 deletions
SharpChat

View file

@ -1,5 +1,5 @@
using SharpChat.Events;
using SharpChat.EventStorage;
using SharpChat.Messages;
using SharpChat.Snowflake;
using SharpChat.SockChat;
using SharpChat.SockChat.S2CPackets;
@ -18,13 +18,13 @@ public class Context {
public HashSet<Channel> Channels { get; } = [];
public HashSet<Connection> Connections { get; } = [];
public HashSet<User> Users { get; } = [];
public EventStorage.EventStorage Events { get; }
public MessageStorage Messages { get; }
public HashSet<ChannelUserAssoc> ChannelUsers { get; } = [];
public Dictionary<string, RateLimiter> UserRateLimiters { get; } = [];
public Dictionary<string, Channel> UserLastChannel { get; } = [];
public Context(EventStorage.EventStorage evtStore) {
Events = evtStore ?? throw new ArgumentNullException(nameof(evtStore));
public Context(MessageStorage msgs) {
Messages = msgs;
RandomSnowflake = new(SnowflakeGenerator);
}
@ -71,14 +71,14 @@ public class Context {
));
}
await Events.AddEvent(
await Messages.LogMessage(
mce.MessageId, "msg:add",
mce.ChannelName,
mce.SenderId, mce.SenderName, mce.SenderColour, mce.SenderRank, mce.SenderNickName, mce.SenderPerms,
new { text = mce.MessageText },
(mce.IsBroadcast ? StoredEventFlags.Broadcast : 0)
| (mce.IsAction ? StoredEventFlags.Action : 0)
| (mce.IsPrivate ? StoredEventFlags.Private : 0)
(mce.IsBroadcast ? MessageFlags.Broadcast : 0)
| (mce.IsAction ? MessageFlags.Action : 0)
| (mce.IsPrivate ? MessageFlags.Private : 0)
);
return;
}
@ -212,7 +212,7 @@ public class Context {
if(!IsInChannel(user, chan)) {
long msgId = RandomSnowflake.Next();
await SendTo(chan, new UserConnectS2CPacket(msgId, DateTimeOffset.Now, user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions));
await Events.AddEvent(msgId, "user:connect", chan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, null, StoredEventFlags.Log);
await Messages.LogMessage(msgId, "user:connect", chan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, null, MessageFlags.Log);
}
await conn.Send(new AuthSuccessS2CPacket(
@ -236,8 +236,8 @@ public class Context {
))
));
IEnumerable<StoredEventInfo> msgs = await Events.GetChannelEventLog(chan.Name);
foreach(StoredEventInfo msg in msgs)
IEnumerable<Message> msgs = await Messages.GetMessages(chan.Name);
foreach(Message msg in msgs)
await conn.Send(new ContextMessageS2CPacket(msg));
await conn.Send(new ContextChannelsS2CPacket(
@ -263,9 +263,9 @@ public class Context {
long msgId = RandomSnowflake.Next();
await SendTo(chan, new UserDisconnectS2CPacket(msgId, DateTimeOffset.Now, user.UserId, user.LegacyNameWithStatus, reason));
await Events.AddEvent(msgId, "user:disconnect", chan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, new { reason = (int)reason }, StoredEventFlags.Log);
await Messages.LogMessage(msgId, "user:disconnect", chan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, new { reason = (int)reason }, MessageFlags.Log);
if(chan.IsTemporary && chan.IsOwner(user))
if(chan.IsTemporary && chan.IsOwner(user.UserId))
await RemoveChannel(chan);
}
}
@ -276,7 +276,7 @@ public class Context {
return;
}
if(!user.Permissions.HasFlag(UserPermissions.JoinAnyChannel) && chan.IsOwner(user)) {
if(!user.Permissions.HasFlag(UserPermissions.JoinAnyChannel) && chan.IsOwner(user.UserId)) {
if(chan.Rank > user.Rank) {
await SendTo(user, new CommandResponseS2CPacket(RandomSnowflake.Next(), LCR.CHANNEL_INSUFFICIENT_HIERARCHY, true, chan.Name));
await ForceChannel(user);
@ -294,18 +294,18 @@ public class Context {
}
public async Task ForceChannelSwitch(User user, Channel chan) {
if(!Channels.Contains(chan))
if(!Channels.Any(c => c.NameEquals(chan.Name)))
return;
Channel oldChan = UserLastChannel[user.UserId];
long leaveId = RandomSnowflake.Next();
await SendTo(oldChan, new UserChannelLeaveS2CPacket(leaveId, user.UserId));
await Events.AddEvent(leaveId, "chan:leave", oldChan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, null, StoredEventFlags.Log);
await Messages.LogMessage(leaveId, "chan:leave", oldChan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, null, MessageFlags.Log);
long joinId = RandomSnowflake.Next();
await SendTo(chan, new UserChannelJoinS2CPacket(joinId, user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions));
await Events.AddEvent(joinId, "chan:join", chan.Name, user.UserId, user.LegacyName, user.Colour, user.Rank, user.NickName, user.Permissions, null, StoredEventFlags.Log);
await Messages.LogMessage(joinId, "chan:join", chan.Name, user.UserId, user.LegacyName, user.Colour, user.Rank, user.NickName, user.Permissions, null, MessageFlags.Log);
await SendTo(user, new ContextClearS2CPacket(ContextClearS2CPacket.Mode.MessagesUsers));
await SendTo(user, new ContextUsersS2CPacket(
@ -320,8 +320,8 @@ public class Context {
))
));
IEnumerable<StoredEventInfo> msgs = await Events.GetChannelEventLog(chan.Name);
foreach(StoredEventInfo msg in msgs)
IEnumerable<Message> msgs = await Messages.GetMessages(chan.Name);
foreach(Message msg in msgs)
await SendTo(user, new ContextMessageS2CPacket(msg));
await ForceChannel(user, chan);
@ -330,7 +330,7 @@ public class Context {
ChannelUsers.Add(new ChannelUserAssoc(user.UserId, chan.Name));
UserLastChannel[user.UserId] = chan;
if(oldChan.IsTemporary && oldChan.IsOwner(user))
if(oldChan.IsTemporary && oldChan.IsOwner(user.UserId))
await RemoveChannel(oldChan);
}
@ -374,8 +374,7 @@ public class Context {
}
public async Task UpdateChannel(Channel channel, bool? temporary = null, int? hierarchy = null, string? password = null) {
ArgumentNullException.ThrowIfNull(channel);
if(!Channels.Contains(channel))
if(!Channels.Any(c => c.NameEquals(channel.Name)))
throw new ArgumentException("Provided channel is not registered with this manager.", nameof(channel));
if(temporary.HasValue)