From 454a4604416c274f2b5c2cc664874cf68ac9455f Mon Sep 17 00:00:00 2001 From: flashwave Date: Fri, 24 May 2024 00:23:31 +0000 Subject: [PATCH] Removed event flags attribute. --- SharpChat.SockChat/SockChatContext.cs | 138 +++++++++++------- SharpChatCommon/EventStorage/IEventStorage.cs | 5 +- .../EventStorage/MariaDBEventStorage.cs | 19 +-- .../MariaDBEventStorage_Migrations.cs | 13 ++ .../EventStorage/StoredEventFlags.cs | 12 -- .../EventStorage/StoredEventInfo.cs | 5 +- .../EventStorage/VirtualEventStorage.cs | 9 +- 7 files changed, 113 insertions(+), 88 deletions(-) delete mode 100644 SharpChatCommon/EventStorage/StoredEventFlags.cs diff --git a/SharpChat.SockChat/SockChatContext.cs b/SharpChat.SockChat/SockChatContext.cs index 2200cab..e5723e2 100644 --- a/SharpChat.SockChat/SockChatContext.cs +++ b/SharpChat.SockChat/SockChatContext.cs @@ -5,6 +5,7 @@ using SharpChat.SockChat.PacketsS2C; using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; using System.Threading; namespace SharpChat { @@ -65,14 +66,16 @@ namespace SharpChat { )); } + object msgData = mce.IsAction + ? new { text = mce.MessageText, action = true } + : new { text = mce.MessageText }; + Events.AddEvent( - mce.MessageId, "msg:add", - mce.ChannelName, + mce.MessageId, + "msg:add", + mce.IsBroadcast ? null : 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) + msgData ); return; } @@ -204,45 +207,78 @@ namespace SharpChat { } public void HandleChannelEventLog(string channelName, Action handler) { - foreach(StoredEventInfo msg in Events.GetChannelEventLog(channelName)) - handler(msg.Type switch { - "msg:add" => new MessageAddLogS2CPacket( - msg.Id, - msg.Created, - msg.Sender?.UserId ?? -1, - msg.Sender == null ? "ChatBot" : SockChatUtility.GetUserName(msg.Sender), - msg.Sender?.Colour ?? Colour.None, - msg.Sender?.Rank ?? 0, - msg.Sender?.Permissions ?? 0, - msg.Data.RootElement.GetProperty("text").GetString() ?? string.Empty, - msg.Flags.HasFlag(StoredEventFlags.Action), - msg.Flags.HasFlag(StoredEventFlags.Private), - msg.Flags.HasFlag(StoredEventFlags.Broadcast), - false - ), - "user:connect" => new UserConnectLogS2CPacket( - msg.Id, - msg.Created, - msg.Sender == null ? string.Empty : SockChatUtility.GetUserName(msg.Sender) - ), - "user:disconnect" => new UserDisconnectLogS2CPacket( - msg.Id, - msg.Created, - msg.Sender == null ? string.Empty : SockChatUtility.GetUserNameWithStatus(msg.Sender), - (UserDisconnectReason)msg.Data.RootElement.GetProperty("reason").GetByte() - ), - "chan:join" => new UserChannelJoinLogS2CPacket( - msg.Id, - msg.Created, - msg.Sender == null ? string.Empty : SockChatUtility.GetUserName(msg.Sender) - ), - "chan:leave" => new UserChannelLeaveLogS2CPacket( - msg.Id, - msg.Created, - msg.Sender == null ? string.Empty : SockChatUtility.GetUserName(msg.Sender) - ), - _ => throw new Exception($"Unsupported backlog type: {msg.Type}"), - }); + foreach(StoredEventInfo msg in Events.GetChannelEventLog(channelName)) { + ISockChatS2CPacket packet; + + switch(msg.Type) { + case "msg:add": + string maText = string.Empty; + if(msg.Data.RootElement.TryGetProperty("text", out JsonElement maTextElem)) + maText = maTextElem.ToString(); + + bool maAction = false; + if(msg.Data.RootElement.TryGetProperty("action", out JsonElement maIsActionElem)) + maAction = maIsActionElem.ValueKind == JsonValueKind.True; + + packet = new MessageAddLogS2CPacket( + msg.Id, + msg.Created, + msg.Sender?.UserId ?? -1, + msg.Sender == null ? "ChatBot" : SockChatUtility.GetUserName(msg.Sender), + msg.Sender?.Colour ?? Colour.None, + msg.Sender?.Rank ?? 0, + msg.Sender?.Permissions ?? 0, + maText, + maAction, + msg.ChannelName?.StartsWith('@') == true, + msg.ChannelName == null, + false + ); + break; + + case "user:connect": + packet = new UserConnectLogS2CPacket( + msg.Id, + msg.Created, + msg.Sender == null ? string.Empty : SockChatUtility.GetUserName(msg.Sender) + ); + break; + + case "user:disconnect": + UserDisconnectReason udReason = 0; + if(msg.Data.RootElement.TryGetProperty("reason", out JsonElement udElem) && udElem.TryGetByte(out byte udReasonRaw)) + udReason = (UserDisconnectReason)udReasonRaw; + + packet = new UserDisconnectLogS2CPacket( + msg.Id, + msg.Created, + msg.Sender == null ? string.Empty : SockChatUtility.GetUserNameWithStatus(msg.Sender), + udReason + ); + break; + + case "chan:join": + packet = new UserChannelJoinLogS2CPacket( + msg.Id, + msg.Created, + msg.Sender == null ? string.Empty : SockChatUtility.GetUserName(msg.Sender) + ); + break; + + case "chan:leave": + packet = new UserChannelLeaveLogS2CPacket( + msg.Id, + msg.Created, + msg.Sender == null ? string.Empty : SockChatUtility.GetUserName(msg.Sender) + ); + break; + + default: + throw new Exception($"Unsupported backlog type: {msg.Type}"); + } + + handler(packet); + } } public void HandleJoin(UserInfo user, ChannelInfo chan, SockChatConnectionInfo conn, int maxMsgLength) { @@ -267,8 +303,7 @@ namespace SharpChat { user.Rank, user.NickName, user.Permissions, - null, - StoredEventFlags.Log + null ); } @@ -330,8 +365,7 @@ namespace SharpChat { user.Rank, user.NickName, user.Permissions, - new { reason = (int)reason }, - StoredEventFlags.Log + new { reason = (int)reason } ); if(chan.IsTemporary && chan.IsOwner(user)) @@ -377,8 +411,7 @@ namespace SharpChat { user.Rank, user.NickName, user.Permissions, - null, - StoredEventFlags.Log + null ); } @@ -401,8 +434,7 @@ namespace SharpChat { user.Rank, user.NickName, user.Permissions, - null, - StoredEventFlags.Log + null ); SendTo(user, new ContextClearS2CPacket(ContextClearS2CPacket.ClearMode.MessagesUsers)); diff --git a/SharpChatCommon/EventStorage/IEventStorage.cs b/SharpChatCommon/EventStorage/IEventStorage.cs index 8b60b16..1fea29d 100644 --- a/SharpChatCommon/EventStorage/IEventStorage.cs +++ b/SharpChatCommon/EventStorage/IEventStorage.cs @@ -12,12 +12,11 @@ namespace SharpChat.EventStorage { int senderRank, string? senderNick, UserPermissions senderPerms, - object? data = null, - StoredEventFlags flags = StoredEventFlags.None + object? data = null ); void RemoveEvent(StoredEventInfo evt); StoredEventInfo? GetEvent(long seqId); - IEnumerable GetChannelEventLog(string channelName, int amount = 20, int offset = 0); + IEnumerable GetChannelEventLog(string channelName, int amount = 20, int startAt = 0); } } diff --git a/SharpChatCommon/EventStorage/MariaDBEventStorage.cs b/SharpChatCommon/EventStorage/MariaDBEventStorage.cs index 2938e7c..cb7e5e2 100644 --- a/SharpChatCommon/EventStorage/MariaDBEventStorage.cs +++ b/SharpChatCommon/EventStorage/MariaDBEventStorage.cs @@ -22,18 +22,16 @@ namespace SharpChat.EventStorage { int senderRank, string? senderNick, UserPermissions senderPerms, - object? data = null, - StoredEventFlags flags = StoredEventFlags.None + object? data = null ) { 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_data`" + ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`)" - + " VALUES (@id, NOW(), @type, @target, @flags, @data" + + " VALUES (@id, NOW(), @type, @target, @data" + ", @sender, @sender_name, @sender_colour, @sender_rank, @sender_nick, @sender_perms)", new MySqlParameter("id", id), new MySqlParameter("type", type), new MySqlParameter("target", string.IsNullOrWhiteSpace(channelName) ? null : channelName), - new MySqlParameter("flags", (byte)flags), new MySqlParameter("data", data == null ? "{}" : JsonSerializer.SerializeToUtf8Bytes(data)), new MySqlParameter("sender", senderId < 1 ? null : senderId), new MySqlParameter("sender_name", senderName), @@ -47,7 +45,7 @@ namespace SharpChat.EventStorage { public StoredEventInfo? GetEvent(long seqId) { try { using MySqlDataReader? reader = RunQuery( - "SELECT `event_id`, `event_type`, `event_flags`, `event_data`, `event_target`" + "SELECT `event_id`, `event_type`, `event_data`, `event_target`" + ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`" + ", UNIX_TIMESTAMP(`event_created`) AS `event_created`" + ", UNIX_TIMESTAMP(`event_deleted`) AS `event_deleted`" @@ -84,17 +82,16 @@ namespace SharpChat.EventStorage { DateTimeOffset.FromUnixTimeSeconds(reader.GetInt32("event_created")), reader.IsDBNull(reader.GetOrdinal("event_deleted")) ? null : DateTimeOffset.FromUnixTimeSeconds(reader.GetInt32("event_deleted")), reader.IsDBNull(reader.GetOrdinal("event_target")) ? null : Encoding.ASCII.GetString((byte[])reader["event_target"]), - JsonDocument.Parse(Encoding.ASCII.GetString((byte[])reader["event_data"])), - (StoredEventFlags)reader.GetByte("event_flags") + JsonDocument.Parse(Encoding.ASCII.GetString((byte[])reader["event_data"])) ); } - public IEnumerable GetChannelEventLog(string channelName, int amount = 20, int offset = 0) { + public IEnumerable GetChannelEventLog(string channelName, int amount = 20, int startAt = 0) { List events = new(); try { using MySqlDataReader? reader = RunQuery( - "SELECT `event_id`, `event_type`, `event_flags`, `event_data`, `event_target`" + "SELECT `event_id`, `event_type`, `event_data`, `event_target`" + ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`" + ", UNIX_TIMESTAMP(`event_created`) AS `event_created`" + ", UNIX_TIMESTAMP(`event_deleted`) AS `event_deleted`" @@ -105,7 +102,7 @@ namespace SharpChat.EventStorage { + " LIMIT @amount", new MySqlParameter("target", channelName), new MySqlParameter("amount", amount), - new MySqlParameter("offset", offset) + new MySqlParameter("offset", startAt) ); if(reader != null) diff --git a/SharpChatCommon/EventStorage/MariaDBEventStorage_Migrations.cs b/SharpChatCommon/EventStorage/MariaDBEventStorage_Migrations.cs index b780a9d..4db32bc 100644 --- a/SharpChatCommon/EventStorage/MariaDBEventStorage_Migrations.cs +++ b/SharpChatCommon/EventStorage/MariaDBEventStorage_Migrations.cs @@ -31,6 +31,19 @@ namespace SharpChat.EventStorage { DoMigration("create_events_table", CreateEventsTable); DoMigration("allow_null_target", AllowNullTarget); DoMigration("update_event_type_names", UpdateEventTypeNames); + DoMigration("deprecate_event_flags", DeprecateEventFlags); + } + + private void DeprecateEventFlags() { + // StoredEventFlags.Action is just a field in the data object + RunCommand(@"UPDATE sqc_events SET event_data = JSON_MERGE_PATCH(event_data, JSON_OBJECT('action', true)) WHERE event_flags & 1"); + + // StoredEventFlags.Broadcast can be implied by just having a NULL as the channel name + RunCommand(@"UPDATE sqc_events SET event_target = NULL WHERE event_flags & 2"); + + // StoredEventFlags.Log was never meaningfully used by anything and basically just meant "not-msg:add" + // StoredEventFlags.Private was also never meaningfully used, can be determined by checking if the channel name starts with @ + RunCommand(@"ALTER TABLE sqc_events DROP COLUMN event_flags"); } private void UpdateEventTypeNames() { diff --git a/SharpChatCommon/EventStorage/StoredEventFlags.cs b/SharpChatCommon/EventStorage/StoredEventFlags.cs deleted file mode 100644 index e84b684..0000000 --- a/SharpChatCommon/EventStorage/StoredEventFlags.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace SharpChat.EventStorage { - [Flags] - public enum StoredEventFlags { - None = 0, - Action = 1, - Broadcast = 1 << 1, - Log = 1 << 2, - Private = 1 << 3, - } -} diff --git a/SharpChatCommon/EventStorage/StoredEventInfo.cs b/SharpChatCommon/EventStorage/StoredEventInfo.cs index a5cf0bb..378e731 100644 --- a/SharpChatCommon/EventStorage/StoredEventInfo.cs +++ b/SharpChatCommon/EventStorage/StoredEventInfo.cs @@ -9,7 +9,6 @@ namespace SharpChat.EventStorage { public DateTimeOffset Created { get; set; } public DateTimeOffset? Deleted { get; set; } public string? ChannelName { get; set; } - public StoredEventFlags Flags { get; set; } public JsonDocument Data { get; set; } public StoredEventInfo( @@ -19,8 +18,7 @@ namespace SharpChat.EventStorage { DateTimeOffset created, DateTimeOffset? deleted, string? channelName, - JsonDocument data, - StoredEventFlags flags + JsonDocument data ) { Id = id; Type = type; @@ -29,7 +27,6 @@ namespace SharpChat.EventStorage { Deleted = deleted; ChannelName = channelName; Data = data; - Flags = flags; } } } diff --git a/SharpChatCommon/EventStorage/VirtualEventStorage.cs b/SharpChatCommon/EventStorage/VirtualEventStorage.cs index 7cb6806..2bae155 100644 --- a/SharpChatCommon/EventStorage/VirtualEventStorage.cs +++ b/SharpChatCommon/EventStorage/VirtualEventStorage.cs @@ -17,8 +17,7 @@ namespace SharpChat.EventStorage { int senderRank, string? senderNick, UserPermissions senderPerms, - object? data = null, - StoredEventFlags flags = StoredEventFlags.None + object? data = null ) { // VES is meant as an emergency fallback but this is something else JsonDocument hack = JsonDocument.Parse(data == null ? "{}" : JsonSerializer.Serialize(data)); @@ -29,7 +28,7 @@ namespace SharpChat.EventStorage { senderRank, senderPerms, senderNick - ), DateTimeOffset.Now, null, channelName, hack, flags)); + ), DateTimeOffset.Now, null, channelName, hack)); } public StoredEventInfo? GetEvent(long seqId) { @@ -40,10 +39,10 @@ namespace SharpChat.EventStorage { Events.Remove(evt.Id); } - public IEnumerable GetChannelEventLog(string channelName, int amount = 20, int offset = 0) { + public IEnumerable GetChannelEventLog(string channelName, int amount = 20, int startAt = 0) { IEnumerable subset = Events.Values.Where(ev => ev.ChannelName == channelName); - int start = subset.Count() - offset - amount; + int start = subset.Count() - startAt - amount; if(start < 0) { amount += start; start = 0;