diff --git a/.gitignore b/.gitignore index c8bbd73..e8cbe54 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,6 @@ .gitignore **/bin/ **/obj/ -**/SkyBot.sln +**/SkyBot*.sln **/database.db **/Config.cs diff --git a/SkyBot/Commands/Dev/Channel.cs b/SkyBot/Commands/Dev/Channel.cs new file mode 100644 index 0000000..7007660 --- /dev/null +++ b/SkyBot/Commands/Dev/Channel.cs @@ -0,0 +1,68 @@ +using System.Collections.Concurrent; +using SkyBot.Helpers; +using SkyBot.Models; +using SkyBot.Services; +using SkyBot.Services.Messages; +using Valour.Sdk.Models; +using Valour.Shared.Authorization; + +namespace SkyBot.Commands +{ + public class ChannelCmds : ICommand + { + public string Name => "channel"; + public string[] Aliases => ["ch"]; + public string Description => "Enable or disable bot commands in a channel"; + public string Section => "Dev"; + public string Usage => "channel "; + + public async Task Execute(CommandContext ctx) + { + ConcurrentDictionary channelCache = ctx.ChannelCache; + PlanetMember member = ctx.Member; + string[] args = ctx.Args; + long channelId = ctx.ChannelId; + + if (!channelCache.TryGetValue(channelId, out var channel)) return; + + if (!PermissionHelper.IsOwner(member) && !await PermissionHelper.HasPermAsync(member, channel, [ChatChannelPermissions.ManageMessages])) + { + await MessageHelper.ReplyAsync(ctx, channel, "This is a Dev only command."); + return; + } + + if (args.Length == 0) + { + await MessageHelper.ReplyAsync(ctx, channel, "Usage: `channel `"); + return; + } + + switch (args[0].ToLower()) + { + case "disable": + if (Create.disabledChannels.Contains(channelId)) + { + await MessageHelper.ReplyAsync(ctx, channel, "This channel is already disabled."); + return; + } + Create.disabledChannels.Add(channelId); + await MessageHelper.ReplyAsync(ctx, channel, "Bot commands disabled in this channel."); + break; + + case "enable": + if (!Create.disabledChannels.Contains(channelId)) + { + await MessageHelper.ReplyAsync(ctx, channel, "This channel is not disabled."); + return; + } + Create.disabledChannels.Remove(channelId); + await MessageHelper.ReplyAsync(ctx, channel, "Bot commands enabled in this channel."); + break; + + default: + await MessageHelper.ReplyAsync(ctx, channel, "Usage: `channel `"); + break; + } + } + } +} diff --git a/SkyBot/Commands/Fun/Echo.cs b/SkyBot/Commands/Fun/Echo.cs index 42f6e64..40836fa 100644 --- a/SkyBot/Commands/Fun/Echo.cs +++ b/SkyBot/Commands/Fun/Echo.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using SkyBot.Helpers; using SkyBot.Models; using Valour.Sdk.Models; +using Valour.Shared.Authorization; namespace SkyBot.Commands { diff --git a/SkyBot/Commands/Info/Info.cs b/SkyBot/Commands/Info/Info.cs index 0a7a959..ca54630 100644 --- a/SkyBot/Commands/Info/Info.cs +++ b/SkyBot/Commands/Info/Info.cs @@ -3,10 +3,11 @@ using System.Text; using SkyBot.Helpers; using SkyBot.Models; using Valour.Sdk.Models; +using Valour.Shared.Models; namespace SkyBot.Commands { - public class Info : ICommand + public partial class Info : ICommand { public string Name => "info"; public string[] Aliases => []; @@ -44,6 +45,21 @@ namespace SkyBot.Commands } } + [System.Text.RegularExpressions.GeneratedRegex(@"«@m-(\d+)»")] + private static partial System.Text.RegularExpressions.Regex MemberMentionRegex(); + + private static long? ExtractMemberMentionId(Message message) + { + var mention = message.Mentions?.FirstOrDefault(m => m.Type == MentionType.PlanetMember); + if (mention != null) return mention.TargetId; + + var match = MemberMentionRegex().Match(message.Content ?? ""); + if (match.Success && long.TryParse(match.Groups[1].Value, out long id)) + return id; + + return null; + } + private async Task HandleUserInfo(CommandContext ctx, Channel channel) { Message message = ctx.Message; @@ -51,24 +67,18 @@ namespace SkyBot.Commands string[] args = ctx.Args; PlanetMember? target; - try + var mentionId = ExtractMemberMentionId(message); + + if (mentionId.HasValue) { - if (message.Mentions != null && message.Mentions.Any()) - { - target = await planet.FetchMemberAsync(message.Mentions.First().TargetId); - } - else if (args.Length > 1 && long.TryParse(args[1], out long memberid)) - { - target = await planet.FetchMemberAsync(memberid); - } - else - { - target = ctx.Member; - } + target = await planet.FetchMemberAsync(mentionId.Value); } - catch (Exception ex) + else if (args.Length > 1 && long.TryParse(args[1], out long memberid)) + { + target = await planet.FetchMemberAsync(memberid); + } + else { - Console.WriteLine($"Exception: {ex.Message}"); target = ctx.Member; } @@ -87,6 +97,7 @@ namespace SkyBot.Commands sb.AppendLine($"Status: `{(string.IsNullOrWhiteSpace(target.Status) ? "None" : target.Status)}`"); sb.AppendLine($"Primary Role: `{target.PrimaryRole?.Name ?? "None"}`"); sb.AppendLine($"Roles: `{string.Join(", ", target.Roles.Select(r => r.Name))}`"); + sb.AppendLine($"Valour Join Date: `{target.User.TimeJoined} UTC`"); await MessageHelper.ReplyAsync(ctx, channel, sb.ToString()); } diff --git a/SkyBot/Services/Messages/Create.cs b/SkyBot/Services/Messages/Create.cs index bb7303e..dab0ce6 100644 --- a/SkyBot/Services/Messages/Create.cs +++ b/SkyBot/Services/Messages/Create.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using SkyBot.Commands; using SkyBot.Helpers; using SkyBot.Models; +using SkyBot.Services; using Valour.Sdk.Client; using Valour.Sdk.Models; @@ -13,6 +14,7 @@ namespace SkyBot.Services.Messages { private static readonly ConcurrentDictionary _cooldowns = new(); private static readonly TimeSpan _cooldown = TimeSpan.FromSeconds(2); + public static readonly HashSet disabledChannels = new(); public static async Task MessageAsync( ValourClient client, ConcurrentDictionary channelCache, @@ -59,6 +61,9 @@ namespace SkyBot.Services.Messages _cooldowns[message.AuthorUserId] = DateTime.UtcNow; + if (disabledChannels.Contains(channelId) && command != "channel" && command != "ch") + return; + if (CommandRegistry.Commands.TryGetValue(command, out var handler)) { await handler.Execute(ctx);