using SharpChat.Bans; using SharpChat.SockChat.S2CPackets; using System.Net; namespace SharpChat.ClientCommands; public class KickBanClientCommand(BansClient bansClient) : ClientCommand { public bool IsMatch(ClientCommandContext ctx) { return ctx.NameEquals("kick") || ctx.NameEquals("ban"); } public async Task Dispatch(ClientCommandContext ctx) { bool isBanning = ctx.NameEquals("ban"); long msgId = ctx.Chat.RandomSnowflake.Next(); if(!ctx.User.Can(isBanning ? UserPermissions.BanUser : UserPermissions.KickUser)) { await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}")); return; } string? banUserTarget = ctx.Args.ElementAtOrDefault(0); string? banDurationStr = ctx.Args.ElementAtOrDefault(1); int banReasonIndex = 1; User? banUser = null; if(banUserTarget == null || (banUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(banUserTarget))) == null) { await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.USER_NOT_FOUND, true, banUserTarget ?? "User")); return; } if(banUser.Rank >= ctx.User.Rank && banUser != ctx.User) { await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.KICK_NOT_ALLOWED, true, banUser.LegacyName)); return; } TimeSpan duration = isBanning ? TimeSpan.MaxValue : TimeSpan.Zero; if(!string.IsNullOrWhiteSpace(banDurationStr) && double.TryParse(banDurationStr, out double durationSeconds)) { if(durationSeconds < 0) { await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.COMMAND_FORMAT_ERROR)); return; } duration = TimeSpan.FromSeconds(durationSeconds); ++banReasonIndex; } if(duration <= TimeSpan.Zero) { await ctx.Chat.BanUser(banUser, duration); return; } string banReason = string.Join(' ', ctx.Args.Skip(banReasonIndex)); BanInfo? banInfo = await bansClient.BanGetAsync(banUser.UserId); if(banInfo is not null) { await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.KICK_NOT_ALLOWED, true, banUser.LegacyName)); return; } await bansClient.BanCreateAsync( BanKind.User, duration, ctx.Chat.GetRemoteAddresses(banUser).FirstOrDefault() ?? IPAddress.None, banUser.UserId, banReason, ctx.Connection.RemoteAddress, ctx.User.UserId ); await ctx.Chat.BanUser(banUser, duration); } }