diff --git a/SharpChat/ChatContext.cs b/SharpChat/ChatContext.cs index c9d2f72..08bbd2d 100644 --- a/SharpChat/ChatContext.cs +++ b/SharpChat/ChatContext.cs @@ -28,7 +28,7 @@ namespace SharpChat { public void DispatchEvent(IChatEvent eventInfo) { if(eventInfo is MessageCreateEvent mce) { if(mce.IsBroadcast) { - Send(new BroadcastPacket(mce.MessageText)); + Send(new MessageBroadcastPacket(mce.MessageText)); } else if(mce.IsPrivate) { // The channel name returned by GetDMChannelName should not be exposed to the user, instead @ should be displayed // e.g. nook sees @Arysil and Arysil sees @nook @@ -47,7 +47,7 @@ namespace SharpChat { return; foreach(ChatUser user in users) - SendTo(user, new ChatMessageAddPacket( + SendTo(user, new MessageAddPacket( mce.MessageId, DateTimeOffset.Now, mce.SenderId, @@ -58,7 +58,7 @@ namespace SharpChat { } else { ChatChannel? channel = Channels.FirstOrDefault(c => c.NameEquals(mce.ChannelName)); if(channel != null) - SendTo(channel, new ChatMessageAddPacket( + SendTo(channel, new MessageAddPacket( mce.MessageId, DateTimeOffset.Now, mce.SenderId, @@ -242,15 +242,15 @@ namespace SharpChat { chan.Name, maxMsgLength )); - conn.Send(new ContextUsersPacket(GetChannelUsers(chan).Except(new[] { user }).Select( - user => new ContextUsersPacket.ListEntry(user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions, true) + conn.Send(new UsersPopulatePacket(GetChannelUsers(chan).Except(new[] { user }).Select( + 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 ContextMessagePacket(msg)); + conn.Send(new MessagePopulatePacket(msg)); - conn.Send(new ContextChannelsPacket(Channels.Where(c => c.Rank <= user.Rank).Select( - channel => new ContextChannelsPacket.ListEntry(channel.Name, channel.HasPassword, channel.IsTemporary) + conn.Send(new ChannelsPopulatePacket(Channels.Where(c => c.Rank <= user.Rank).Select( + channel => new ChannelsPopulatePacket.ListEntry(channel.Name, channel.HasPassword, channel.IsTemporary) ).ToArray())); Users.Add(user); @@ -285,13 +285,13 @@ namespace SharpChat { if(!user.Can(ChatUserPermissions.JoinAnyChannel) && chan.IsOwner(user)) { if(chan.Rank > user.Rank) { - SendTo(user, new LegacyCommandResponse(LCR.CHANNEL_INSUFFICIENT_RANK, true, chan.Name)); + SendTo(user, new ChannelRankTooLowErrorPacket(chan.Name)); ForceChannel(user); return; } - if(!string.IsNullOrEmpty(chan.Password) && chan.Password != password) { - SendTo(user, new LegacyCommandResponse(LCR.CHANNEL_INVALID_PASSWORD, true, chan.Name)); + if(!string.IsNullOrEmpty(chan.Password) && chan.Password.Equals(password)) { + SendTo(user, new ChannelPasswordWrongErrorPacket(chan.Name)); ForceChannel(user); return; } @@ -312,12 +312,12 @@ namespace SharpChat { Events.AddEvent("chan:join", user, oldChan, flags: StoredEventFlags.Log); SendTo(user, new ContextClearPacket(ContextClearPacket.ClearMode.MessagesUsers)); - SendTo(user, new ContextUsersPacket(GetChannelUsers(chan).Except(new[] { user }).Select( - user => new ContextUsersPacket.ListEntry(user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions, true) + SendTo(user, new UsersPopulatePacket(GetChannelUsers(chan).Except(new[] { user }).Select( + 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 ContextMessagePacket(msg)); + SendTo(user, new MessagePopulatePacket(msg)); ForceChannel(user, chan); diff --git a/SharpChat/Commands/BanListCommand.cs b/SharpChat/Commands/BanListCommand.cs index 0a5ccf7..47b0d61 100644 --- a/SharpChat/Commands/BanListCommand.cs +++ b/SharpChat/Commands/BanListCommand.cs @@ -24,7 +24,7 @@ namespace SharpChat.Commands { } Task.Run(async () => { - ctx.Chat.SendTo(ctx.User, new BanListPacket( + ctx.Chat.SendTo(ctx.User, new BanListResponsePacket( (await Misuzu.GetBanListAsync() ?? Array.Empty()).Select( ban => string.IsNullOrEmpty(ban.UserName) ? (string.IsNullOrEmpty(ban.RemoteAddress) ? string.Empty : ban.RemoteAddress) : ban.UserName ).ToArray() diff --git a/SharpChat/Commands/CreateChannelCommand.cs b/SharpChat/Commands/ChannelCreateCommand.cs similarity index 81% rename from SharpChat/Commands/CreateChannelCommand.cs rename to SharpChat/Commands/ChannelCreateCommand.cs index c90cd45..3eec3e5 100644 --- a/SharpChat/Commands/CreateChannelCommand.cs +++ b/SharpChat/Commands/ChannelCreateCommand.cs @@ -2,7 +2,7 @@ using System.Linq; namespace SharpChat.Commands { - public class CreateChannelCommand : IChatCommand { + public class ChannelCreateCommand : IChatCommand { public bool IsMatch(ChatCommandContext ctx) { return ctx.NameEquals("create"); } @@ -27,19 +27,19 @@ namespace SharpChat.Commands { createChanHierarchy = 0; if(createChanHierarchy > ctx.User.Rank) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.INSUFFICIENT_RANK)); + ctx.Chat.SendTo(ctx.User, new ChannelRankTooHighErrorPacket()); return; } string createChanName = string.Join('_', ctx.Args.Skip(createChanHasHierarchy ? 1 : 0)); if(!ChatChannel.CheckName(createChanName)) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NAME_INVALID)); + ctx.Chat.SendTo(ctx.User, new ChannelNameFormatErrorPacket()); return; } if(ctx.Chat.Channels.Any(c => c.NameEquals(createChanName))) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_ALREADY_EXISTS, true, createChanName)); + ctx.Chat.SendTo(ctx.User, new ChannelNameInUseErrorPacket(createChanName)); return; } @@ -58,7 +58,7 @@ namespace SharpChat.Commands { )); ctx.Chat.SwitchChannel(ctx.User, createChan, createChan.Password); - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_CREATED, false, createChan.Name)); + ctx.Chat.SendTo(ctx.User, new ChannelCreateResponsePacket(createChan.Name)); } } } diff --git a/SharpChat/Commands/DeleteChannelCommand.cs b/SharpChat/Commands/ChannelDeleteCommand.cs similarity index 72% rename from SharpChat/Commands/DeleteChannelCommand.cs rename to SharpChat/Commands/ChannelDeleteCommand.cs index 9fb5a9d..6cb65b5 100644 --- a/SharpChat/Commands/DeleteChannelCommand.cs +++ b/SharpChat/Commands/ChannelDeleteCommand.cs @@ -2,7 +2,7 @@ using System.Linq; namespace SharpChat.Commands { - public class DeleteChannelCommand : IChatCommand { + public class ChannelDeleteCommand : IChatCommand { public bool IsMatch(ChatCommandContext ctx) { return ctx.NameEquals("delchan") || ( ctx.NameEquals("delete") @@ -20,17 +20,17 @@ namespace SharpChat.Commands { ChatChannel? delChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(delChanName)); if(delChan == null) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, delChanName)); + ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(delChanName)); return; } if(!ctx.User.Can(ChatUserPermissions.DeleteChannel) && delChan.IsOwner(ctx.User)) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_DELETE_FAILED, true, delChan.Name)); + ctx.Chat.SendTo(ctx.User, new ChannelDeleteNotAllowedErrorPacket(delChan.Name)); return; } ctx.Chat.RemoveChannel(delChan); - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_DELETED, false, delChan.Name)); + ctx.Chat.SendTo(ctx.User, new ChannelDeleteResponsePacket(delChan.Name)); } } } diff --git a/SharpChat/Commands/JoinChannelCommand.cs b/SharpChat/Commands/ChannelJoinCommand.cs similarity index 70% rename from SharpChat/Commands/JoinChannelCommand.cs rename to SharpChat/Commands/ChannelJoinCommand.cs index 8c00c6e..b7e1277 100644 --- a/SharpChat/Commands/JoinChannelCommand.cs +++ b/SharpChat/Commands/ChannelJoinCommand.cs @@ -2,17 +2,17 @@ using System.Linq; namespace SharpChat.Commands { - public class JoinChannelCommand : IChatCommand { + public class ChannelJoinCommand : IChatCommand { public bool IsMatch(ChatCommandContext ctx) { return ctx.NameEquals("join"); } public void Dispatch(ChatCommandContext ctx) { - string? joinChanStr = ctx.Args.FirstOrDefault(); + string joinChanStr = ctx.Args.FirstOrDefault() ?? string.Empty; ChatChannel? joinChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(joinChanStr)); if(joinChan == null) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, joinChanStr ?? string.Empty)); + ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(joinChanStr)); ctx.Chat.ForceChannel(ctx.User); return; } diff --git a/SharpChat/Commands/PasswordChannelCommand.cs b/SharpChat/Commands/ChannelPasswordCommand.cs similarity index 82% rename from SharpChat/Commands/PasswordChannelCommand.cs rename to SharpChat/Commands/ChannelPasswordCommand.cs index 8327569..f418464 100644 --- a/SharpChat/Commands/PasswordChannelCommand.cs +++ b/SharpChat/Commands/ChannelPasswordCommand.cs @@ -1,7 +1,7 @@ using SharpChat.Packet; namespace SharpChat.Commands { - public class PasswordChannelCommand : IChatCommand { + public class ChannelPasswordCommand : IChatCommand { public bool IsMatch(ChatCommandContext ctx) { return ctx.NameEquals("pwd") || ctx.NameEquals("password"); @@ -19,7 +19,7 @@ namespace SharpChat.Commands { chanPass = string.Empty; ctx.Chat.UpdateChannel(ctx.Channel, password: chanPass); - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_PASSWORD_CHANGED, false)); + ctx.Chat.SendTo(ctx.User, new ChannelPasswordChangedResponsePacket()); } } } diff --git a/SharpChat/Commands/RankChannelCommand.cs b/SharpChat/Commands/ChannelRankCommand.cs similarity index 76% rename from SharpChat/Commands/RankChannelCommand.cs rename to SharpChat/Commands/ChannelRankCommand.cs index 536a3af..58907c0 100644 --- a/SharpChat/Commands/RankChannelCommand.cs +++ b/SharpChat/Commands/ChannelRankCommand.cs @@ -2,7 +2,7 @@ using System.Linq; namespace SharpChat.Commands { - public class RankChannelCommand : IChatCommand { + public class ChannelRankCommand : IChatCommand { public bool IsMatch(ChatCommandContext ctx) { return ctx.NameEquals("rank") || ctx.NameEquals("privilege") @@ -16,12 +16,12 @@ namespace SharpChat.Commands { } if(!ctx.Args.Any() || !int.TryParse(ctx.Args.First(), out int chanHierarchy) || chanHierarchy > ctx.User.Rank) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.INSUFFICIENT_RANK)); + ctx.Chat.SendTo(ctx.User, new ChannelRankTooHighErrorPacket()); return; } ctx.Chat.UpdateChannel(ctx.Channel, minRank: chanHierarchy); - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_RANK_CHANGED, false)); + ctx.Chat.SendTo(ctx.User, new ChannelRankChangedResponsePacket()); } } } diff --git a/SharpChat/Commands/KickBanCommand.cs b/SharpChat/Commands/KickBanCommand.cs index 5aee6e0..f37bf67 100644 --- a/SharpChat/Commands/KickBanCommand.cs +++ b/SharpChat/Commands/KickBanCommand.cs @@ -25,18 +25,18 @@ namespace SharpChat.Commands { return; } - string? banUserTarget = ctx.Args.ElementAtOrDefault(0); + string banUserTarget = ctx.Args.ElementAtOrDefault(0) ?? string.Empty; string? banDurationStr = ctx.Args.ElementAtOrDefault(1); int banReasonIndex = 1; ChatUser? banUser = null; - if(banUserTarget == null || (banUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(banUserTarget))) == null) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, banUserTarget ?? string.Empty)); + if(string.IsNullOrEmpty(banUserTarget) || (banUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(banUserTarget))) == null) { + ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(banUserTarget)); return; } if(!ctx.User.IsSuper && banUser.Rank >= ctx.User.Rank && banUser != ctx.User) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.KICK_NOT_ALLOWED, true, banUser.LegacyName)); + ctx.Chat.SendTo(ctx.User, new KickBanNotAllowedErrorPacket(banUser.LegacyName)); return; } @@ -66,7 +66,7 @@ namespace SharpChat.Commands { MisuzuBanInfo? fbi = await Misuzu.CheckBanAsync(userId, userIp); if(fbi != null && fbi.IsBanned && !fbi.HasExpired) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.KICK_NOT_ALLOWED, true, banUser.LegacyName)); + ctx.Chat.SendTo(ctx.User, new KickBanNotAllowedErrorPacket(banUser.LegacyName)); return; } diff --git a/SharpChat/Commands/ActionCommand.cs b/SharpChat/Commands/MessageActionCommand.cs similarity index 93% rename from SharpChat/Commands/ActionCommand.cs rename to SharpChat/Commands/MessageActionCommand.cs index 0677350..6cc19c7 100644 --- a/SharpChat/Commands/ActionCommand.cs +++ b/SharpChat/Commands/MessageActionCommand.cs @@ -3,7 +3,7 @@ using System; using System.Linq; namespace SharpChat.Commands { - public class ActionCommand : IChatCommand { + public class MessageActionCommand : IChatCommand { public bool IsMatch(ChatCommandContext ctx) { return ctx.NameEquals("action") || ctx.NameEquals("me"); diff --git a/SharpChat/Commands/BroadcastCommand.cs b/SharpChat/Commands/MessageBroadcastCommand.cs similarity index 93% rename from SharpChat/Commands/BroadcastCommand.cs rename to SharpChat/Commands/MessageBroadcastCommand.cs index 720957f..610330c 100644 --- a/SharpChat/Commands/BroadcastCommand.cs +++ b/SharpChat/Commands/MessageBroadcastCommand.cs @@ -3,7 +3,7 @@ using SharpChat.Packet; using System; namespace SharpChat.Commands { - public class BroadcastCommand : IChatCommand { + public class MessageBroadcastCommand : IChatCommand { public bool IsMatch(ChatCommandContext ctx) { return ctx.NameEquals("say") || ctx.NameEquals("broadcast"); diff --git a/SharpChat/Commands/DeleteMessageCommand.cs b/SharpChat/Commands/MessageDeleteCommand.cs similarity index 85% rename from SharpChat/Commands/DeleteMessageCommand.cs rename to SharpChat/Commands/MessageDeleteCommand.cs index 100fab5..092c126 100644 --- a/SharpChat/Commands/DeleteMessageCommand.cs +++ b/SharpChat/Commands/MessageDeleteCommand.cs @@ -4,7 +4,7 @@ using System.Linq; namespace SharpChat.Commands { - public class DeleteMessageCommand : IChatCommand { + public class MessageDeleteCommand : IChatCommand { public bool IsMatch(ChatCommandContext ctx) { return ctx.NameEquals("delmsg") || ( ctx.NameEquals("delete") @@ -30,12 +30,12 @@ namespace SharpChat.Commands StoredEventInfo? delMsg = ctx.Chat.Events.GetEvent(delSeqId); if(delMsg == null || delMsg.Sender?.Rank > ctx.User.Rank || (!deleteAnyMessage && delMsg.Sender?.UserId != ctx.User.UserId)) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.MESSAGE_DELETE_ERROR)); + ctx.Chat.SendTo(ctx.User, new MessageDeleteNotAllowedErrorPacket()); return; } ctx.Chat.Events.RemoveEvent(delMsg); - ctx.Chat.Send(new ChatMessageDeletePacket(delMsg.Id)); + ctx.Chat.Send(new MessageDeletePacket(delMsg.Id)); } } } diff --git a/SharpChat/Commands/WhisperCommand.cs b/SharpChat/Commands/MessageWhisperCommand.cs similarity index 81% rename from SharpChat/Commands/WhisperCommand.cs rename to SharpChat/Commands/MessageWhisperCommand.cs index 17496ce..d1e657a 100644 --- a/SharpChat/Commands/WhisperCommand.cs +++ b/SharpChat/Commands/MessageWhisperCommand.cs @@ -4,7 +4,7 @@ using System; using System.Linq; namespace SharpChat.Commands { - public class WhisperCommand : IChatCommand { + public class MessageWhisperCommand : IChatCommand { public bool IsMatch(ChatCommandContext ctx) { return ctx.NameEquals("whisper") || ctx.NameEquals("msg"); @@ -16,11 +16,11 @@ namespace SharpChat.Commands { return; } - string? whisperUserStr = ctx.Args.FirstOrDefault(); + string whisperUserStr = ctx.Args.FirstOrDefault() ?? string.Empty; ChatUser? whisperUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(whisperUserStr)); if(whisperUser == null) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, whisperUserStr ?? string.Empty)); + ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(whisperUserStr)); return; } diff --git a/SharpChat/Commands/PardonAddressCommand.cs b/SharpChat/Commands/PardonAddressCommand.cs index 2f67eda..a41447c 100644 --- a/SharpChat/Commands/PardonAddressCommand.cs +++ b/SharpChat/Commands/PardonAddressCommand.cs @@ -36,15 +36,15 @@ namespace SharpChat.Commands { MisuzuBanInfo? banInfo = await Misuzu.CheckBanAsync(ipAddr: unbanAddrTarget); if(banInfo?.IsBanned != true || banInfo.HasExpired) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanAddrTarget)); + ctx.Chat.SendTo(ctx.User, new KickBanNoRecordErrorPacket(unbanAddrTarget)); return; } bool wasBanned = await Misuzu.RevokeBanAsync(banInfo, MisuzuClient.BanRevokeKind.RemoteAddress); if(wasBanned) - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_UNBANNED, false, unbanAddrTarget)); + ctx.Chat.SendTo(ctx.User, new PardonResponsePacket(unbanAddrTarget)); else - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanAddrTarget)); + ctx.Chat.SendTo(ctx.User, new KickBanNoRecordErrorPacket(unbanAddrTarget)); }).Wait(); } } diff --git a/SharpChat/Commands/PardonUserCommand.cs b/SharpChat/Commands/PardonUserCommand.cs index 455efa9..86cd39c 100644 --- a/SharpChat/Commands/PardonUserCommand.cs +++ b/SharpChat/Commands/PardonUserCommand.cs @@ -43,15 +43,15 @@ namespace SharpChat.Commands { MisuzuBanInfo? banInfo = await Misuzu.CheckBanAsync(unbanUserTarget, userIdIsName: unbanUserTargetIsName); if(banInfo?.IsBanned != true || banInfo.HasExpired) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanUserTarget)); + ctx.Chat.SendTo(ctx.User, new KickBanNoRecordErrorPacket(unbanUserTarget)); return; } bool wasBanned = await Misuzu.RevokeBanAsync(banInfo, MisuzuClient.BanRevokeKind.UserId); if(wasBanned) - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_UNBANNED, false, unbanUserTarget)); + ctx.Chat.SendTo(ctx.User, new PardonResponsePacket(unbanUserTarget)); else - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanUserTarget)); + ctx.Chat.SendTo(ctx.User, new KickBanNoRecordErrorPacket(unbanUserTarget)); }).Wait(); } } diff --git a/SharpChat/Commands/AFKCommand.cs b/SharpChat/Commands/UserAFKCommand.cs similarity index 94% rename from SharpChat/Commands/AFKCommand.cs rename to SharpChat/Commands/UserAFKCommand.cs index a7383fd..9c9a921 100644 --- a/SharpChat/Commands/AFKCommand.cs +++ b/SharpChat/Commands/UserAFKCommand.cs @@ -2,7 +2,7 @@ using System.Linq; namespace SharpChat.Commands { - public class AFKCommand : IChatCommand { + public class UserAFKCommand : IChatCommand { private const string DEFAULT = "AFK"; private const int MAX_LENGTH = 5; diff --git a/SharpChat/Commands/NickCommand.cs b/SharpChat/Commands/UserNickCommand.cs similarity index 92% rename from SharpChat/Commands/NickCommand.cs rename to SharpChat/Commands/UserNickCommand.cs index b4bd7f6..7b6fc30 100644 --- a/SharpChat/Commands/NickCommand.cs +++ b/SharpChat/Commands/UserNickCommand.cs @@ -2,7 +2,7 @@ using System.Linq; namespace SharpChat.Commands { - public class NickCommand : IChatCommand { + public class UserNickCommand : IChatCommand { public bool IsMatch(ChatCommandContext ctx) { return ctx.NameEquals("nick"); } @@ -43,7 +43,7 @@ namespace SharpChat.Commands { nickStr = string.Empty; if(!string.IsNullOrWhiteSpace(nickStr) && ctx.Chat.Users.Any(u => u.NameEquals(nickStr))) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.NAME_IN_USE, true, nickStr)); + ctx.Chat.SendTo(ctx.User, new UserNameInUseErrorPacket(nickStr)); return; } diff --git a/SharpChat/Commands/WhoCommand.cs b/SharpChat/Commands/WhoCommand.cs index 3113609..7bf0ce7 100644 --- a/SharpChat/Commands/WhoCommand.cs +++ b/SharpChat/Commands/WhoCommand.cs @@ -1,6 +1,5 @@ using SharpChat.Packet; using System.Linq; -using System.Text; namespace SharpChat.Commands { public class WhoCommand : IChatCommand { @@ -9,50 +8,33 @@ namespace SharpChat.Commands { } public void Dispatch(ChatCommandContext ctx) { - StringBuilder whoChanSB = new(); - string? whoChanStr = ctx.Args.FirstOrDefault(); + string? channelName = ctx.Args.FirstOrDefault(); - if(string.IsNullOrEmpty(whoChanStr)) { - foreach(ChatUser whoUser in ctx.Chat.Users) { - whoChanSB.Append(@"{0}, ", whoUser.LegacyName); - } - - if(whoChanSB.Length > 2) - whoChanSB.Length -= 2; - - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USERS_LISTING_SERVER, false, whoChanSB)); - } else { - ChatChannel? whoChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(whoChanStr)); - - if(whoChan == null) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, whoChanStr)); - return; - } - - if(whoChan.Rank > ctx.User.Rank || (whoChan.HasPassword && !ctx.User.Can(ChatUserPermissions.JoinAnyChannel))) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USERS_LISTING_ERROR, true, whoChanStr)); - return; - } - - foreach(ChatUser whoUser in ctx.Chat.GetChannelUsers(whoChan)) { - whoChanSB.Append(@"{0}, ", whoUser.LegacyName); - } - - if(whoChanSB.Length > 2) - whoChanSB.Length -= 2; - - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USERS_LISTING_CHANNEL, false, whoChan.Name, whoChanSB)); + if(string.IsNullOrEmpty(channelName)) { + ctx.Chat.SendTo(ctx.User, new WhoServerResponsePacket( + ctx.Chat.Users.Select(u => u.LegacyName).ToArray(), + ctx.User.LegacyName + )); + return; } + + ChatChannel? channel = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(channelName)); + + if(channel == null) { + ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(channelName)); + return; + } + + if(channel.Rank > ctx.User.Rank || (channel.HasPassword && !ctx.User.Can(ChatUserPermissions.JoinAnyChannel))) { + ctx.Chat.SendTo(ctx.User, new WhoChannelNotFoundErrorPacket(channelName)); + return; + } + + ctx.Chat.SendTo(ctx.User, new WhoChannelResponsePacket( + channel.Name, + ctx.Chat.GetChannelUsers(channel).Select(user => user.LegacyName).ToArray(), + ctx.User.LegacyName + )); } } } diff --git a/SharpChat/Commands/WhoisCommand.cs b/SharpChat/Commands/WhoisCommand.cs index 5f61f7d..917b390 100644 --- a/SharpChat/Commands/WhoisCommand.cs +++ b/SharpChat/Commands/WhoisCommand.cs @@ -15,11 +15,11 @@ namespace SharpChat.Commands { return; } - string? ipUserStr = ctx.Args.FirstOrDefault(); + string ipUserStr = ctx.Args.FirstOrDefault() ?? string.Empty; ChatUser? ipUser; if(string.IsNullOrWhiteSpace(ipUserStr) || (ipUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(ipUserStr))) == null) { - ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, ipUserStr ?? string.Empty)); + ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(ipUserStr)); return; } diff --git a/SharpChat/Packet/AuthFailPacket.cs b/SharpChat/Packet/AuthFailPacket.cs index 576c505..299a240 100644 --- a/SharpChat/Packet/AuthFailPacket.cs +++ b/SharpChat/Packet/AuthFailPacket.cs @@ -10,7 +10,7 @@ namespace SharpChat.Packet { } private readonly FailReason Reason; - private readonly DateTimeOffset Expires; + private readonly long Expires; public AuthFailPacket(FailReason reason) { Reason = reason; @@ -18,7 +18,7 @@ namespace SharpChat.Packet { public AuthFailPacket(DateTimeOffset expires) { Reason = FailReason.Banned; - Expires = expires; + Expires = expires.Year >= 2100 ? -1 : expires.ToUnixTimeSeconds(); } public override string Pack() { @@ -30,7 +30,7 @@ namespace SharpChat.Packet { }); if(Reason == FailReason.Banned) - packet += string.Format("\t{0}", Expires.Year >= 2100 ? -1 : Expires.ToUnixTimeSeconds()); + packet += string.Format("\t{0}", Expires); return packet; } diff --git a/SharpChat/Packet/BanListPacket.cs b/SharpChat/Packet/BanListResponsePacket.cs similarity index 60% rename from SharpChat/Packet/BanListPacket.cs rename to SharpChat/Packet/BanListResponsePacket.cs index 9d16c96..02e06d2 100644 --- a/SharpChat/Packet/BanListPacket.cs +++ b/SharpChat/Packet/BanListResponsePacket.cs @@ -1,24 +1,25 @@ using System; -using System.Linq; using System.Text; namespace SharpChat.Packet { - public class BanListPacket : ServerPacket { + public class BanListResponsePacket : ServerPacket { + private readonly long Timestamp; private readonly string[] Bans; - public BanListPacket(string[] bans) { - Bans = bans ?? throw new ArgumentNullException(nameof(bans)); + public BanListResponsePacket(string[] bans) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + Bans = bans; } public override string Pack() { StringBuilder sb = new(); - sb.AppendFormat("2\t{0}\t-1\t0\fbanlist\f", DateTimeOffset.Now.ToUnixTimeSeconds()); + sb.AppendFormat("2\t{0}\t-1\t0\fbanlist\f", Timestamp); foreach(string ban in Bans) sb.AppendFormat(@"{0}, ", ban); - if(Bans.Any()) + if(Bans.Length > 0) sb.Length -= 2; sb.AppendFormat("\t{0}\t10010", SequenceId); diff --git a/SharpChat/Packet/ChannelCreateResponsePacket.cs b/SharpChat/Packet/ChannelCreateResponsePacket.cs new file mode 100644 index 0000000..220e4aa --- /dev/null +++ b/SharpChat/Packet/ChannelCreateResponsePacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class ChannelCreateResponsePacket : ServerPacket { + private readonly long Timestamp; + private readonly string ChannelName; + + public ChannelCreateResponsePacket(string channelName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + ChannelName = channelName; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t0\fcrchan\f{1}\t{2}\t10010", Timestamp, ChannelName, SequenceId); + } + } +} diff --git a/SharpChat/Packet/ChannelDeleteNotAllowedErrorPacket.cs b/SharpChat/Packet/ChannelDeleteNotAllowedErrorPacket.cs new file mode 100644 index 0000000..f9ad16c --- /dev/null +++ b/SharpChat/Packet/ChannelDeleteNotAllowedErrorPacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class ChannelDeleteNotAllowedErrorPacket : ServerPacket { + private readonly long Timestamp; + private readonly string ChannelName; + + public ChannelDeleteNotAllowedErrorPacket(string channelName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + ChannelName = channelName; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\fndchan\f{1}\t{2}\t10010", Timestamp, ChannelName, SequenceId); + } + } +} diff --git a/SharpChat/Packet/ChannelDeletePacket.cs b/SharpChat/Packet/ChannelDeletePacket.cs index 5921fc9..ad3f45b 100644 --- a/SharpChat/Packet/ChannelDeletePacket.cs +++ b/SharpChat/Packet/ChannelDeletePacket.cs @@ -5,7 +5,7 @@ namespace SharpChat.Packet { private readonly string ChannelName; public ChannelDeletePacket(string channelName) { - ChannelName = channelName ?? throw new ArgumentNullException(nameof(channelName)); + ChannelName = channelName; } public override string Pack() { diff --git a/SharpChat/Packet/ChannelDeleteResponsePacket.cs b/SharpChat/Packet/ChannelDeleteResponsePacket.cs new file mode 100644 index 0000000..4a95f65 --- /dev/null +++ b/SharpChat/Packet/ChannelDeleteResponsePacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class ChannelDeleteResponsePacket : ServerPacket { + private readonly long Timestamp; + private readonly string ChannelName; + + public ChannelDeleteResponsePacket(string channelName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + ChannelName = channelName; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t0\fdelchan\f{1}\t{2}\t10010", Timestamp, ChannelName, SequenceId); + } + } +} diff --git a/SharpChat/Packet/ChannelNameFormatErrorPacket.cs b/SharpChat/Packet/ChannelNameFormatErrorPacket.cs new file mode 100644 index 0000000..db3e7ba --- /dev/null +++ b/SharpChat/Packet/ChannelNameFormatErrorPacket.cs @@ -0,0 +1,15 @@ +using System; + +namespace SharpChat.Packet { + public class ChannelNameFormatErrorPacket : ServerPacket { + private readonly long Timestamp; + + public ChannelNameFormatErrorPacket() { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\finchan\t{1}\t10010", Timestamp, SequenceId); + } + } +} diff --git a/SharpChat/Packet/ChannelNameInUseErrorPacket.cs b/SharpChat/Packet/ChannelNameInUseErrorPacket.cs new file mode 100644 index 0000000..5bf917b --- /dev/null +++ b/SharpChat/Packet/ChannelNameInUseErrorPacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class ChannelNameInUseErrorPacket : ServerPacket { + private readonly long Timestamp; + private readonly string ChannelName; + + public ChannelNameInUseErrorPacket(string channelName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + ChannelName = channelName; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\fnischan\f{1}\t{2}\t10010", Timestamp, ChannelName, SequenceId); + } + } +} diff --git a/SharpChat/Packet/ChannelNotFoundErrorPacket.cs b/SharpChat/Packet/ChannelNotFoundErrorPacket.cs new file mode 100644 index 0000000..54fa0b2 --- /dev/null +++ b/SharpChat/Packet/ChannelNotFoundErrorPacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class ChannelNotFoundErrorPacket : ServerPacket { + private readonly long Timestamp; + private readonly string ChannelName; + + public ChannelNotFoundErrorPacket(string channelName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + ChannelName = channelName; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\fnochan\f{1}\t{2}\t10010", Timestamp, ChannelName, SequenceId); + } + } +} diff --git a/SharpChat/Packet/ChannelPasswordChangedResponsePacket.cs b/SharpChat/Packet/ChannelPasswordChangedResponsePacket.cs new file mode 100644 index 0000000..e911043 --- /dev/null +++ b/SharpChat/Packet/ChannelPasswordChangedResponsePacket.cs @@ -0,0 +1,15 @@ +using System; + +namespace SharpChat.Packet { + public class ChannelPasswordChangedResponsePacket : ServerPacket { + private readonly long Timestamp; + + public ChannelPasswordChangedResponsePacket() { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t0\fcpwdchan\t{1}\t10010", Timestamp, SequenceId); + } + } +} diff --git a/SharpChat/Packet/ChannelPasswordWrongErrorPacket.cs b/SharpChat/Packet/ChannelPasswordWrongErrorPacket.cs new file mode 100644 index 0000000..26ce622 --- /dev/null +++ b/SharpChat/Packet/ChannelPasswordWrongErrorPacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class ChannelPasswordWrongErrorPacket : ServerPacket { + private readonly long Timestamp; + private readonly string ChannelName; + + public ChannelPasswordWrongErrorPacket(string channelName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + ChannelName = channelName; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\fipwchan\f{1}\t{2}\t10010", Timestamp, ChannelName, SequenceId); + } + } +} diff --git a/SharpChat/Packet/ChannelRankChangedResponsePacket.cs b/SharpChat/Packet/ChannelRankChangedResponsePacket.cs new file mode 100644 index 0000000..c948c1e --- /dev/null +++ b/SharpChat/Packet/ChannelRankChangedResponsePacket.cs @@ -0,0 +1,15 @@ +using System; + +namespace SharpChat.Packet { + public class ChannelRankChangedResponsePacket : ServerPacket { + private readonly long Timestamp; + + public ChannelRankChangedResponsePacket() { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t0\fcprivchan\t{1}\t10010", Timestamp, SequenceId); + } + } +} diff --git a/SharpChat/Packet/ChannelRankTooHighErrorPacket.cs b/SharpChat/Packet/ChannelRankTooHighErrorPacket.cs new file mode 100644 index 0000000..3bb6dd6 --- /dev/null +++ b/SharpChat/Packet/ChannelRankTooHighErrorPacket.cs @@ -0,0 +1,15 @@ +using System; + +namespace SharpChat.Packet { + public class ChannelRankTooHighErrorPacket : ServerPacket { + private readonly long Timestamp; + + public ChannelRankTooHighErrorPacket() { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\frankerr\t{1}\t10010", Timestamp, SequenceId); + } + } +} diff --git a/SharpChat/Packet/ChannelRankTooLowErrorPacket.cs b/SharpChat/Packet/ChannelRankTooLowErrorPacket.cs new file mode 100644 index 0000000..b647615 --- /dev/null +++ b/SharpChat/Packet/ChannelRankTooLowErrorPacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class ChannelRankTooLowErrorPacket : ServerPacket { + private readonly long Timestamp; + private readonly string ChannelName; + + public ChannelRankTooLowErrorPacket(string channelName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + ChannelName = channelName; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\fipchan\f{1}\t{2}\t10010", Timestamp, ChannelName, SequenceId); + } + } +} diff --git a/SharpChat/Packet/ContextChannelsPacket.cs b/SharpChat/Packet/ChannelsPopulatePacket.cs similarity index 86% rename from SharpChat/Packet/ContextChannelsPacket.cs rename to SharpChat/Packet/ChannelsPopulatePacket.cs index 33879dc..acf6a2d 100644 --- a/SharpChat/Packet/ContextChannelsPacket.cs +++ b/SharpChat/Packet/ChannelsPopulatePacket.cs @@ -2,12 +2,12 @@ using System.Text; namespace SharpChat.Packet { - public class ContextChannelsPacket : ServerPacket { + public class ChannelsPopulatePacket : ServerPacket { public record ListEntry(string Name, bool HasPassword, bool IsTemporary); private readonly ListEntry[] Entries; - public ContextChannelsPacket(ListEntry[] entries) { + public ChannelsPopulatePacket(ListEntry[] entries) { Entries = entries ?? throw new ArgumentNullException(nameof(entries)); } diff --git a/SharpChat/Packet/ForceDisconnectPacket.cs b/SharpChat/Packet/ForceDisconnectPacket.cs index 1fadabe..24e6b99 100644 --- a/SharpChat/Packet/ForceDisconnectPacket.cs +++ b/SharpChat/Packet/ForceDisconnectPacket.cs @@ -2,22 +2,17 @@ namespace SharpChat.Packet { public class ForceDisconnectPacket : ServerPacket { - private readonly DateTimeOffset Expires; + private readonly long Expires; - public ForceDisconnectPacket() { - Expires = DateTimeOffset.MinValue; - } + public ForceDisconnectPacket() {} public ForceDisconnectPacket(DateTimeOffset expires) { - Expires = expires; + Expires = expires.Year >= 2100 ? -1 : expires.ToUnixTimeSeconds(); } public override string Pack() { - if(Expires == DateTimeOffset.MinValue) - return string.Format( - "9\t1\t{0}", - Expires.Year >= 2100 ? -1 : Expires.ToUnixTimeSeconds() - ); + if(Expires != 0) + return string.Format("9\t1\t{0}", Expires); return "9\t0"; } diff --git a/SharpChat/Packet/KickBanNoRecordErrorPacket.cs b/SharpChat/Packet/KickBanNoRecordErrorPacket.cs new file mode 100644 index 0000000..21c74d0 --- /dev/null +++ b/SharpChat/Packet/KickBanNoRecordErrorPacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class KickBanNoRecordErrorPacket : ServerPacket { + private readonly long Timestamp; + private readonly string TargetName; + + public KickBanNoRecordErrorPacket(string targetName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + TargetName = targetName; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\fnotban\f{1}\t{2}\t10010", Timestamp, TargetName, SequenceId); + } + } +} diff --git a/SharpChat/Packet/KickBanNotAllowedErrorPacket.cs b/SharpChat/Packet/KickBanNotAllowedErrorPacket.cs new file mode 100644 index 0000000..3414146 --- /dev/null +++ b/SharpChat/Packet/KickBanNotAllowedErrorPacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class KickBanNotAllowedErrorPacket : ServerPacket { + private readonly long Timestamp; + private readonly string UserName; + + public KickBanNotAllowedErrorPacket(string userName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + UserName = userName; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\fkickna\f{1}\t{2}\t10010", Timestamp, UserName, SequenceId); + } + } +} diff --git a/SharpChat/Packet/LegacyCommandResponse.cs b/SharpChat/Packet/LegacyCommandResponse.cs deleted file mode 100644 index 05ea562..0000000 --- a/SharpChat/Packet/LegacyCommandResponse.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Text; - -namespace SharpChat.Packet { - public class LegacyCommandResponse : ServerPacket { - private readonly bool IsError; - private readonly string StringId; - private readonly object[] Arguments; - - public LegacyCommandResponse( - string stringId, - bool isError = true, - params object[] args - ) { - IsError = isError; - StringId = stringId; - Arguments = args; - } - - public override string Pack() { - StringBuilder sb = new(); - - sb.AppendFormat( - "2\t{0}\t-1\t{1}\f{2}", - DateTimeOffset.Now.ToUnixTimeSeconds(), - IsError ? 1 : 0, - StringId - ); - - foreach(object arg in Arguments) - sb.AppendFormat("\f{0}", arg); - - sb.AppendFormat("\t{0}\t10010", SequenceId); - - return sb.ToString(); - } - } - - // Abbreviated class name because otherwise shit gets wide - public static class LCR { - public const string CHANNEL_CREATED = "crchan"; - public const string CHANNEL_DELETED = "delchan"; - public const string CHANNEL_PASSWORD_CHANGED = "cpwdchan"; - public const string CHANNEL_RANK_CHANGED = "cprivchan"; - public const string USERS_LISTING_CHANNEL = "whochan"; - public const string USERS_LISTING_SERVER = "who"; - public const string USER_UNBANNED = "unban"; - - public const string USER_NOT_FOUND = "usernf"; - public const string NAME_IN_USE = "nameinuse"; - public const string CHANNEL_INSUFFICIENT_RANK = "ipchan"; - public const string CHANNEL_INVALID_PASSWORD = "ipwchan"; - public const string CHANNEL_NOT_FOUND = "nochan"; - public const string CHANNEL_ALREADY_EXISTS = "nischan"; - public const string CHANNEL_NAME_INVALID = "inchan"; - public const string CHANNEL_DELETE_FAILED = "ndchan"; - public const string USERS_LISTING_ERROR = "whoerr"; - public const string INSUFFICIENT_RANK = "rankerr"; - public const string MESSAGE_DELETE_ERROR = "delerr"; - public const string KICK_NOT_ALLOWED = "kickna"; - public const string USER_NOT_BANNED = "notban"; - } -} diff --git a/SharpChat/Packet/ChatMessageAddPacket.cs b/SharpChat/Packet/MessageAddPacket.cs similarity index 83% rename from SharpChat/Packet/ChatMessageAddPacket.cs rename to SharpChat/Packet/MessageAddPacket.cs index f4e5a5f..e8642cb 100644 --- a/SharpChat/Packet/ChatMessageAddPacket.cs +++ b/SharpChat/Packet/MessageAddPacket.cs @@ -1,14 +1,14 @@ using System; namespace SharpChat.Packet { - public class ChatMessageAddPacket : ServerPacket { - private readonly DateTimeOffset Created; + public class MessageAddPacket : ServerPacket { + private readonly long Created; private readonly long UserId; private readonly string Body; private readonly bool IsAction; private readonly bool IsPrivate; - public ChatMessageAddPacket( + public MessageAddPacket( long msgId, DateTimeOffset created, long userId, @@ -16,7 +16,7 @@ namespace SharpChat.Packet { bool isAction, bool isPrivate ) : base(msgId) { - Created = created; + Created = created.ToUnixTimeSeconds(); UserId = userId < 0 ? -1 : userId; Body = body ?? throw new ArgumentNullException(nameof(body)); IsAction = isAction; @@ -30,7 +30,7 @@ namespace SharpChat.Packet { return string.Format( "2\t{0}\t{1}\t{2}\t{3}\t{4}{5}{6}{7}{8}", - Created.ToUnixTimeSeconds(), + Created, UserId, body, SequenceId, diff --git a/SharpChat/Packet/BroadcastPacket.cs b/SharpChat/Packet/MessageBroadcastPacket.cs similarity index 81% rename from SharpChat/Packet/BroadcastPacket.cs rename to SharpChat/Packet/MessageBroadcastPacket.cs index fa88167..901d455 100644 --- a/SharpChat/Packet/BroadcastPacket.cs +++ b/SharpChat/Packet/MessageBroadcastPacket.cs @@ -1,11 +1,11 @@ using System; namespace SharpChat.Packet { - public class BroadcastPacket : ServerPacket { + public class MessageBroadcastPacket : ServerPacket { private readonly long Timestamp; private readonly string Body; - public BroadcastPacket(string body) { + public MessageBroadcastPacket(string body) { Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); Body = body; } diff --git a/SharpChat/Packet/MessageDeleteNotAllowedErrorPacket.cs b/SharpChat/Packet/MessageDeleteNotAllowedErrorPacket.cs new file mode 100644 index 0000000..6b9ae25 --- /dev/null +++ b/SharpChat/Packet/MessageDeleteNotAllowedErrorPacket.cs @@ -0,0 +1,15 @@ +using System; + +namespace SharpChat.Packet { + public class MessageDeleteNotAllowedErrorPacket : ServerPacket { + private readonly long Timestamp; + + public MessageDeleteNotAllowedErrorPacket() { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\fdelerr\t{1}\t10010", Timestamp, SequenceId); + } + } +} diff --git a/SharpChat/Packet/ChatMessageDeletePacket.cs b/SharpChat/Packet/MessageDeletePacket.cs similarity index 67% rename from SharpChat/Packet/ChatMessageDeletePacket.cs rename to SharpChat/Packet/MessageDeletePacket.cs index ea6a7b7..66efa78 100644 --- a/SharpChat/Packet/ChatMessageDeletePacket.cs +++ b/SharpChat/Packet/MessageDeletePacket.cs @@ -1,8 +1,8 @@ namespace SharpChat.Packet { - public class ChatMessageDeletePacket : ServerPacket { + public class MessageDeletePacket : ServerPacket { private readonly long MessageId; - public ChatMessageDeletePacket(long msgId) { + public MessageDeletePacket(long msgId) { MessageId = msgId; } diff --git a/SharpChat/Packet/ContextMessagePacket.cs b/SharpChat/Packet/MessagePopulatePacket.cs similarity index 96% rename from SharpChat/Packet/ContextMessagePacket.cs rename to SharpChat/Packet/MessagePopulatePacket.cs index 21b1dd8..6f11812 100644 --- a/SharpChat/Packet/ContextMessagePacket.cs +++ b/SharpChat/Packet/MessagePopulatePacket.cs @@ -4,11 +4,11 @@ using System.Text; namespace SharpChat.Packet { // this entire class is disgusting - public class ContextMessagePacket : ServerPacket { + public class MessagePopulatePacket : ServerPacket { private readonly StoredEventInfo Event; private readonly bool Notify; - public ContextMessagePacket(StoredEventInfo evt, bool notify = false) { + public MessagePopulatePacket(StoredEventInfo evt, bool notify = false) { Event = evt ?? throw new ArgumentNullException(nameof(evt)); Notify = notify; } diff --git a/SharpChat/Packet/PardonResponsePacket.cs b/SharpChat/Packet/PardonResponsePacket.cs new file mode 100644 index 0000000..5801eab --- /dev/null +++ b/SharpChat/Packet/PardonResponsePacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class PardonResponsePacket : ServerPacket { + private readonly long Timestamp; + private readonly string Subject; + + public PardonResponsePacket(string subject) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + Subject = subject; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t0\funban\f{1}\t{2}\t10010", Timestamp, Subject, SequenceId); + } + } +} diff --git a/SharpChat/Packet/UserDisconnectPacket.cs b/SharpChat/Packet/UserDisconnectPacket.cs index 43f8791..2f039ee 100644 --- a/SharpChat/Packet/UserDisconnectPacket.cs +++ b/SharpChat/Packet/UserDisconnectPacket.cs @@ -9,18 +9,18 @@ namespace SharpChat.Packet { } public class UserDisconnectPacket : ServerPacket { - private readonly DateTimeOffset Disconnected; + private readonly long Timestamp; private readonly long UserId; private readonly string UserName; private readonly UserDisconnectReason Reason; public UserDisconnectPacket( - DateTimeOffset disconnected, + DateTimeOffset timestamp, long userId, string userName, UserDisconnectReason reason ) { - Disconnected = disconnected; + Timestamp = timestamp.ToUnixTimeSeconds(); UserId = userId; UserName = userName ?? throw new ArgumentNullException(nameof(userName)); Reason = reason; @@ -38,7 +38,7 @@ namespace SharpChat.Packet { UserDisconnectReason.Flood => "flood", _ => "leave", }, - Disconnected.ToUnixTimeSeconds(), + Timestamp, SequenceId ); } diff --git a/SharpChat/Packet/UserNameInUseErrorPacket.cs b/SharpChat/Packet/UserNameInUseErrorPacket.cs new file mode 100644 index 0000000..14631ae --- /dev/null +++ b/SharpChat/Packet/UserNameInUseErrorPacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class UserNameInUseErrorPacket : ServerPacket { + private readonly long Timestamp; + private readonly string UserName; + + public UserNameInUseErrorPacket(string userName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + UserName = userName; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\fnameinuse\f{1}\t{2}\t10010", Timestamp, UserName, SequenceId); + } + } +} diff --git a/SharpChat/Packet/UserNotFoundErrorPacket.cs b/SharpChat/Packet/UserNotFoundErrorPacket.cs new file mode 100644 index 0000000..5d414a4 --- /dev/null +++ b/SharpChat/Packet/UserNotFoundErrorPacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class UserNotFoundErrorPacket : ServerPacket { + private readonly long Timestamp; + private readonly string UserName; + + public UserNotFoundErrorPacket(string userName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + UserName = userName; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\fusernf\f{1}\t{2}\t10010", Timestamp, UserName, SequenceId); + } + } +} diff --git a/SharpChat/Packet/UserUpdateNotificationPacket.cs b/SharpChat/Packet/UserUpdateNotificationPacket.cs index 29539d2..7c01f7b 100644 --- a/SharpChat/Packet/UserUpdateNotificationPacket.cs +++ b/SharpChat/Packet/UserUpdateNotificationPacket.cs @@ -4,18 +4,18 @@ namespace SharpChat.Packet { public class UserUpdateNotificationPacket : ServerPacket { private readonly string PreviousName; private readonly string NewName; - private readonly DateTimeOffset Timestamp; + private readonly long Timestamp; public UserUpdateNotificationPacket(string previousName, string newName) { PreviousName = previousName ?? throw new ArgumentNullException(nameof(previousName)); NewName = newName ?? throw new ArgumentNullException(nameof(newName)); - Timestamp = DateTimeOffset.Now; + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); } public override string Pack() { return string.Format( "2\t{0}\t-1\t0\fnick\f{1}\f{2}\t{3}\t10010", - Timestamp.ToUnixTimeSeconds(), + Timestamp, PreviousName, NewName, SequenceId diff --git a/SharpChat/Packet/ContextUsersPacket.cs b/SharpChat/Packet/UsersPopulatePacket.cs similarity index 92% rename from SharpChat/Packet/ContextUsersPacket.cs rename to SharpChat/Packet/UsersPopulatePacket.cs index 81d11bf..5c0b1a9 100644 --- a/SharpChat/Packet/ContextUsersPacket.cs +++ b/SharpChat/Packet/UsersPopulatePacket.cs @@ -2,12 +2,12 @@ using System.Text; namespace SharpChat.Packet { - public class ContextUsersPacket : ServerPacket { + public class UsersPopulatePacket : ServerPacket { public record ListEntry(long Id, string Name, ChatColour Colour, int Rank, ChatUserPermissions Perms, bool Visible); private readonly ListEntry[] Entries; - public ContextUsersPacket(ListEntry[] entries) { + public UsersPopulatePacket(ListEntry[] entries) { Entries = entries ?? throw new ArgumentNullException(nameof(entries)); } diff --git a/SharpChat/Packet/WhoChannelNotFoundErrorPacket.cs b/SharpChat/Packet/WhoChannelNotFoundErrorPacket.cs new file mode 100644 index 0000000..eca2055 --- /dev/null +++ b/SharpChat/Packet/WhoChannelNotFoundErrorPacket.cs @@ -0,0 +1,17 @@ +using System; + +namespace SharpChat.Packet { + public class WhoChannelNotFoundErrorPacket : ServerPacket { + private readonly long Timestamp; + private readonly string ChannelName; + + public WhoChannelNotFoundErrorPacket(string channelName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + ChannelName = channelName; + } + + public override string Pack() { + return string.Format("2\t{0}\t-1\t1\fwhoerr\f{1}\t{2}\t10010", Timestamp, ChannelName, SequenceId); + } + } +} diff --git a/SharpChat/Packet/WhoChannelResponsePacket.cs b/SharpChat/Packet/WhoChannelResponsePacket.cs new file mode 100644 index 0000000..e6556fc --- /dev/null +++ b/SharpChat/Packet/WhoChannelResponsePacket.cs @@ -0,0 +1,40 @@ +using System; +using System.Text; + +namespace SharpChat.Packet { + public class WhoChannelResponsePacket : ServerPacket { + private readonly long Timestamp; + private readonly string ChannelName; + private readonly string[] Users; + private readonly string SelfName; + + public WhoChannelResponsePacket(string channelName, string[] users, string selfName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + ChannelName = channelName; + Users = users; + SelfName = selfName; + } + + public override string Pack() { + StringBuilder sb = new(); + + sb.AppendFormat("2\t{0}\t-1\t0\fwhochan\f{1}\f", Timestamp, ChannelName); + + foreach(string userName in Users) { + sb.Append(@"{0}, ", userName); + } + + if(Users.Length > 0) + sb.Length -= 2; + + sb.AppendFormat("\t{0}\t10010", SequenceId); + + return sb.ToString(); + } + } +} diff --git a/SharpChat/Packet/WhoServerResponsePacket.cs b/SharpChat/Packet/WhoServerResponsePacket.cs new file mode 100644 index 0000000..9a2b844 --- /dev/null +++ b/SharpChat/Packet/WhoServerResponsePacket.cs @@ -0,0 +1,38 @@ +using System; +using System.Text; + +namespace SharpChat.Packet { + public class WhoServerResponsePacket : ServerPacket { + private readonly long Timestamp; + private readonly string[] Users; + private readonly string SelfName; + + public WhoServerResponsePacket(string[] users, string selfName) { + Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); + Users = users; + SelfName = selfName; + } + + public override string Pack() { + StringBuilder sb = new(); + + sb.AppendFormat("2\t{0}\t-1\t0\fwho\f", Timestamp); + + foreach(string userName in Users) { + sb.Append(@"{0}, ", userName); + } + + if(Users.Length > 0) + sb.Length -= 2; + + sb.AppendFormat("\t{0}\t10010", SequenceId); + + return sb.ToString(); + } + } +} diff --git a/SharpChat/SockChatServer.cs b/SharpChat/SockChatServer.cs index 02ee95f..eead5a6 100644 --- a/SharpChat/SockChatServer.cs +++ b/SharpChat/SockChatServer.cs @@ -83,18 +83,18 @@ namespace SharpChat { }); SendMessageHandler.AddCommands(new IChatCommand[] { - new AFKCommand(), - new NickCommand(), - new WhisperCommand(), - new ActionCommand(), + new UserAFKCommand(), + new UserNickCommand(), + new MessageWhisperCommand(), + new MessageActionCommand(), new WhoCommand(), - new JoinChannelCommand(), - new CreateChannelCommand(), - new DeleteChannelCommand(), - new PasswordChannelCommand(), - new RankChannelCommand(), - new BroadcastCommand(), - new DeleteMessageCommand(), + new ChannelJoinCommand(), + new ChannelCreateCommand(), + new ChannelDeleteCommand(), + new ChannelPasswordCommand(), + new ChannelRankCommand(), + new MessageBroadcastCommand(), + new MessageDeleteCommand(), new KickBanCommand(msz), new PardonUserCommand(msz), new PardonAddressCommand(msz),