diff --git a/SharpChat/ChatContext.cs b/SharpChat/ChatContext.cs index 08bbd2d..37deb7c 100644 --- a/SharpChat/ChatContext.cs +++ b/SharpChat/ChatContext.cs @@ -92,7 +92,7 @@ namespace SharpChat { foreach(ChatUser user in Users) if(!Connections.Any(conn => conn.User == user)) { - HandleDisconnect(user, UserDisconnectReason.TimeOut); + HandleDisconnect(user, ChatUserDisconnectReason.TimeOut); Logger.Write($"Timed out {user} (no more connections)."); } } @@ -205,7 +205,7 @@ namespace SharpChat { } } - public void BanUser(ChatUser user, TimeSpan duration, UserDisconnectReason reason = UserDisconnectReason.Kicked) { + public void BanUser(ChatUser user, TimeSpan duration, ChatUserDisconnectReason reason = ChatUserDisconnectReason.Kicked) { if(duration > TimeSpan.Zero) { DateTimeOffset expires = duration >= TimeSpan.MaxValue ? DateTimeOffset.MaxValue : DateTimeOffset.Now + duration; SendTo(user, new ForceDisconnectPacket(expires)); @@ -220,6 +220,19 @@ namespace SharpChat { HandleDisconnect(user, reason); } + public void HandleChannelEventLog(string channelName, Action handler) { + foreach(StoredEventInfo msg in Events.GetChannelEventLog(channelName)) + handler(msg.Type switch { + "user:connect" => new UserConnectLogPacket(msg.Created, msg.Sender?.LegacyName ?? string.Empty), + "user:disconnect" => new UserDisconnectLogPacket( + msg.Created, + msg.Sender?.LegacyNameWithStatus ?? string.Empty, + (ChatUserDisconnectReason)msg.Data.RootElement.GetProperty("reason").GetByte() + ), + _ => new MessagePopulatePacket(msg), + }); + } + public void HandleJoin(ChatUser user, ChatChannel chan, ChatConnection conn, int maxMsgLength) { if(!IsInChannel(user, chan)) { SendTo(chan, new UserConnectPacket( @@ -246,8 +259,7 @@ namespace SharpChat { user => new UsersPopulatePacket.ListEntry(user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions, true) ).OrderByDescending(user => user.Rank).ToArray())); - foreach(StoredEventInfo msg in Events.GetChannelEventLog(chan.Name)) - conn.Send(new MessagePopulatePacket(msg)); + HandleChannelEventLog(chan.Name, p => conn.Send(p)); conn.Send(new ChannelsPopulatePacket(Channels.Where(c => c.Rank <= user.Rank).Select( channel => new ChannelsPopulatePacket.ListEntry(channel.Name, channel.HasPassword, channel.IsTemporary) @@ -259,7 +271,7 @@ namespace SharpChat { UserLastChannel[user.UserId] = chan; } - public void HandleDisconnect(ChatUser user, UserDisconnectReason reason = UserDisconnectReason.Leave) { + public void HandleDisconnect(ChatUser user, ChatUserDisconnectReason reason = ChatUserDisconnectReason.Leave) { UpdateUser(user, status: ChatUserStatus.Offline); Users.Remove(user); UserLastChannel.Remove(user.UserId); @@ -316,9 +328,7 @@ namespace SharpChat { user => new UsersPopulatePacket.ListEntry(user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions, true) ).OrderByDescending(u => u.Rank).ToArray())); - foreach(StoredEventInfo msg in Events.GetChannelEventLog(chan.Name)) - SendTo(user, new MessagePopulatePacket(msg)); - + HandleChannelEventLog(chan.Name, p => SendTo(user, p)); ForceChannel(user, chan); ChannelUsers.Remove(new ChannelUserAssoc(user.UserId, oldChan.Name)); diff --git a/SharpChat/ChatUserDisconnectReason.cs b/SharpChat/ChatUserDisconnectReason.cs new file mode 100644 index 0000000..50fb2f1 --- /dev/null +++ b/SharpChat/ChatUserDisconnectReason.cs @@ -0,0 +1,8 @@ +namespace SharpChat { + public enum ChatUserDisconnectReason { + Leave, + TimeOut, + Kicked, + Flood, + } +} diff --git a/SharpChat/Packet/AuthSuccessPacket.cs b/SharpChat/Packet/AuthSuccessPacket.cs index f5c4476..5fba87e 100644 --- a/SharpChat/Packet/AuthSuccessPacket.cs +++ b/SharpChat/Packet/AuthSuccessPacket.cs @@ -20,11 +20,11 @@ namespace SharpChat.Packet { int maxMsgLength ) { UserId = userId; - UserName = userName ?? throw new ArgumentNullException(nameof(userName)); + UserName = userName; UserColour = userColour; UserRank = userRank; UserPerms = userPerms; - ChannelName = channelName ?? throw new ArgumentNullException(nameof(channelName)); + ChannelName = channelName; MaxMessageLength = maxMsgLength; } diff --git a/SharpChat/Packet/ChannelCreatePacket.cs b/SharpChat/Packet/ChannelCreatePacket.cs index c8e4e9f..c25ecbe 100644 --- a/SharpChat/Packet/ChannelCreatePacket.cs +++ b/SharpChat/Packet/ChannelCreatePacket.cs @@ -11,7 +11,7 @@ namespace SharpChat.Packet { bool channelHasPassword, bool channelIsTemporary ) { - ChannelName = channelName ?? throw new ArgumentNullException(nameof(channelName)); + ChannelName = channelName; ChannelHasPassword = channelHasPassword; ChannelIsTemporary = channelIsTemporary; } diff --git a/SharpChat/Packet/ChannelUpdatePacket.cs b/SharpChat/Packet/ChannelUpdatePacket.cs index 8972a07..acef1fd 100644 --- a/SharpChat/Packet/ChannelUpdatePacket.cs +++ b/SharpChat/Packet/ChannelUpdatePacket.cs @@ -13,8 +13,8 @@ namespace SharpChat.Packet { bool channelHasPassword, bool channelIsTemporary ) { - ChannelNamePrevious = channelNamePrevious ?? throw new ArgumentNullException(nameof(channelNamePrevious)); - ChannelNameNew = channelNameNew ?? throw new ArgumentNullException(nameof(channelNameNew)); + ChannelNamePrevious = channelNamePrevious; + ChannelNameNew = channelNameNew; ChannelHasPassword = channelHasPassword; ChannelIsTemporary = channelIsTemporary; } diff --git a/SharpChat/Packet/ChannelsPopulatePacket.cs b/SharpChat/Packet/ChannelsPopulatePacket.cs index acf6a2d..fa7a4a5 100644 --- a/SharpChat/Packet/ChannelsPopulatePacket.cs +++ b/SharpChat/Packet/ChannelsPopulatePacket.cs @@ -8,7 +8,7 @@ namespace SharpChat.Packet { private readonly ListEntry[] Entries; public ChannelsPopulatePacket(ListEntry[] entries) { - Entries = entries ?? throw new ArgumentNullException(nameof(entries)); + Entries = entries; } public override string Pack() { diff --git a/SharpChat/Packet/MessageAddPacket.cs b/SharpChat/Packet/MessageAddPacket.cs index e8642cb..5985224 100644 --- a/SharpChat/Packet/MessageAddPacket.cs +++ b/SharpChat/Packet/MessageAddPacket.cs @@ -18,7 +18,7 @@ namespace SharpChat.Packet { ) : base(msgId) { Created = created.ToUnixTimeSeconds(); UserId = userId < 0 ? -1 : userId; - Body = body ?? throw new ArgumentNullException(nameof(body)); + Body = body; IsAction = isAction; IsPrivate = isPrivate; } diff --git a/SharpChat/Packet/MessagePopulatePacket.cs b/SharpChat/Packet/MessagePopulatePacket.cs index 6f11812..fa084a2 100644 --- a/SharpChat/Packet/MessagePopulatePacket.cs +++ b/SharpChat/Packet/MessagePopulatePacket.cs @@ -56,10 +56,6 @@ namespace SharpChat.Packet { sb.Append(body); break; - case "user:connect": - sb.AppendFormat("{0}\t0\fjoin\f{1}", V1_CHATBOT, Event.Sender?.LegacyName); - break; - case "chan:join": sb.AppendFormat("{0}\t0\fjchan\f{1}", V1_CHATBOT, Event.Sender?.LegacyName); break; @@ -67,21 +63,6 @@ namespace SharpChat.Packet { case "chan:leave": sb.AppendFormat("{0}\t0\flchan\f{1}", V1_CHATBOT, Event.Sender?.LegacyName); break; - - case "user:disconnect": - sb.AppendFormat( - "{0}\t0\f{1}\f{2}", - V1_CHATBOT, - (UserDisconnectReason)Event.Data.RootElement.GetProperty("reason").GetByte() switch { - UserDisconnectReason.Flood => "flood", - UserDisconnectReason.Kicked => "kick", - UserDisconnectReason.TimeOut => "timeout", - UserDisconnectReason.Leave => "leave", - _ => "leave", - }, - Event.Sender?.LegacyName - ); - break; } sb.AppendFormat( diff --git a/SharpChat/Packet/UserConnectLogPacket.cs b/SharpChat/Packet/UserConnectLogPacket.cs new file mode 100644 index 0000000..383a4d2 --- /dev/null +++ b/SharpChat/Packet/UserConnectLogPacket.cs @@ -0,0 +1,25 @@ +using System; + +namespace SharpChat.Packet { + public class UserConnectLogPacket : ServerPacket { + private readonly long Timestamp; + private readonly string UserName; + + public UserConnectLogPacket( + DateTimeOffset timestamp, + string userName + ) { + Timestamp = timestamp.ToUnixTimeSeconds(); + UserName = userName; + } + + public override string Pack() { + return string.Format( + "7\t1\t{0}\t-1\tChatBot\tinherit\t\t0\fjoin\f{1}\t{2}\t0\t10010", + Timestamp, + UserName, + SequenceId + ); + } + } +} diff --git a/SharpChat/Packet/UserConnectPacket.cs b/SharpChat/Packet/UserConnectPacket.cs index 8aa66d1..8f3a737 100644 --- a/SharpChat/Packet/UserConnectPacket.cs +++ b/SharpChat/Packet/UserConnectPacket.cs @@ -19,7 +19,7 @@ namespace SharpChat.Packet { ) { Joined = joined; UserId = userId; - UserName = userName ?? throw new ArgumentNullException(nameof(userName)); + UserName = userName; UserColour = userColour; UserRank = userRank; UserPerms = userPerms; diff --git a/SharpChat/Packet/UserDisconnectLogPacket.cs b/SharpChat/Packet/UserDisconnectLogPacket.cs new file mode 100644 index 0000000..fe3d24e --- /dev/null +++ b/SharpChat/Packet/UserDisconnectLogPacket.cs @@ -0,0 +1,35 @@ +using System; + +namespace SharpChat.Packet { + public class UserDisconnectLogPacket : ServerPacket { + private readonly long Timestamp; + private readonly string UserName; + private readonly ChatUserDisconnectReason Reason; + + public UserDisconnectLogPacket( + DateTimeOffset timestamp, + string userName, + ChatUserDisconnectReason reason + ) { + Timestamp = timestamp.ToUnixTimeSeconds(); + UserName = userName; + Reason = reason; + } + + public override string Pack() { + return string.Format( + "7\t1\t{0}\t-1\tChatBot\tinherit\t\t0\f{1}\f{2}\t{3}\t0\t10010", + Timestamp, + Reason switch { + ChatUserDisconnectReason.Leave => "leave", + ChatUserDisconnectReason.TimeOut => "timeout", + ChatUserDisconnectReason.Kicked => "kick", + ChatUserDisconnectReason.Flood => "flood", + _ => "leave", + }, + UserName, + SequenceId + ); + } + } +} diff --git a/SharpChat/Packet/UserDisconnectPacket.cs b/SharpChat/Packet/UserDisconnectPacket.cs index 2f039ee..9f4c334 100644 --- a/SharpChat/Packet/UserDisconnectPacket.cs +++ b/SharpChat/Packet/UserDisconnectPacket.cs @@ -1,28 +1,21 @@ using System; namespace SharpChat.Packet { - public enum UserDisconnectReason { - Leave, - TimeOut, - Kicked, - Flood, - } - public class UserDisconnectPacket : ServerPacket { private readonly long Timestamp; private readonly long UserId; private readonly string UserName; - private readonly UserDisconnectReason Reason; + private readonly ChatUserDisconnectReason Reason; public UserDisconnectPacket( DateTimeOffset timestamp, long userId, string userName, - UserDisconnectReason reason + ChatUserDisconnectReason reason ) { Timestamp = timestamp.ToUnixTimeSeconds(); UserId = userId; - UserName = userName ?? throw new ArgumentNullException(nameof(userName)); + UserName = userName; Reason = reason; } @@ -32,10 +25,10 @@ namespace SharpChat.Packet { UserId, UserName, Reason switch { - UserDisconnectReason.Leave => "leave", - UserDisconnectReason.TimeOut => "timeout", - UserDisconnectReason.Kicked => "kick", - UserDisconnectReason.Flood => "flood", + ChatUserDisconnectReason.Leave => "leave", + ChatUserDisconnectReason.TimeOut => "timeout", + ChatUserDisconnectReason.Kicked => "kick", + ChatUserDisconnectReason.Flood => "flood", _ => "leave", }, Timestamp, diff --git a/SharpChat/SockChatServer.cs b/SharpChat/SockChatServer.cs index eead5a6..bbf640e 100644 --- a/SharpChat/SockChatServer.cs +++ b/SharpChat/SockChatServer.cs @@ -186,7 +186,7 @@ namespace SharpChat { if(banDuration == TimeSpan.MinValue) { Context.SendTo(conn.User, new FloodWarningPacket()); } else { - Context.BanUser(conn.User, banDuration, UserDisconnectReason.Flood); + Context.BanUser(conn.User, banDuration, ChatUserDisconnectReason.Flood); if(banDuration > TimeSpan.Zero) Misuzu.CreateBanAsync(