From ac9b5a22fb85adf4962f3cd14371f7673139c619 Mon Sep 17 00:00:00 2001 From: 140bpmdubstep Date: Fri, 18 Oct 2024 18:00:30 +0300 Subject: [PATCH] Permission system, URL handling and more! --- fs24bot3/Backend/Discord.cs | 4 +- fs24bot3/Backend/IRC.cs | 11 +- fs24bot3/Bot.cs | 50 ++++++--- fs24bot3/Checks/CheckAdmin.cs | 4 +- fs24bot3/Checks/FullAccount.cs | 10 +- fs24bot3/Commands/CustomCommandsModule.cs | 12 +- fs24bot3/Commands/InventoryCommandsModule.cs | 2 +- fs24bot3/Commands/SystemCommandsModule.cs | 112 +++++++++++++------ fs24bot3/Core/Database.cs | 2 +- fs24bot3/Core/User.cs | 15 ++- fs24bot3/EventProcessors/OnMsgEvent.cs | 95 ++++++++-------- fs24bot3/Models/Configuration.cs | 3 +- fs24bot3/Models/MessageGeneric.cs | 2 +- fs24bot3/Models/Permissions.cs | 95 ++++++++++++++++ fs24bot3/Models/SQL.cs | 9 +- fs24bot3/Models/Topic.cs | 33 ++---- fs24bot3/Systems/DuckDuckGoGPT.cs | 2 +- 17 files changed, 307 insertions(+), 154 deletions(-) create mode 100644 fs24bot3/Models/Permissions.cs diff --git a/fs24bot3/Backend/Discord.cs b/fs24bot3/Backend/Discord.cs index 4dbbd66..26029bf 100644 --- a/fs24bot3/Backend/Discord.cs +++ b/fs24bot3/Backend/Discord.cs @@ -111,7 +111,7 @@ private async Task MessageCreated(DiscordClient client, MessageCreateEventArgs a var msg = new MessageGeneric(args.Message.Content, args.Channel.Id.ToString(), user, messageKind); - if (!msg.Sender.UserIsIgnored() && !args.Message.Author.IsBot) + if (!msg.Sender.GetPermissions().ExecuteCommands && !args.Message.Author.IsBot) { if (msg.Kind == MessageKind.Message) { BotContext.MessageTrigger(msg); } await BotContext.ExecuteCommand(msg, "."); @@ -141,7 +141,7 @@ public async Task SendMessage(string channel, string message) public void Process() { Log.Information("Connecting to Discord..."); - Task.Run(async () => { Log.Verbose(""); + Task.Run(async () => { Log.Verbose("���"); await BotClient.ConnectAsync(); BotContext.ProccessInfinite(); }); Console.ReadLine(); diff --git a/fs24bot3/Backend/IRC.cs b/fs24bot3/Backend/IRC.cs index bd81549..8c0c555 100644 --- a/fs24bot3/Backend/IRC.cs +++ b/fs24bot3/Backend/IRC.cs @@ -107,14 +107,11 @@ private async void Client_OnIRCMessageParsed(Client client, ParsedIRCMessage mes { var msg = new MessageGeneric(in message, in BotContext.Connection, Name); var prefix = ConfigurationProvider.Config.Prefix; + var permissions = msg.Sender.GetPermissions(); + BotContext.MessageTrigger(msg); - if (!msg.Sender.UserIsIgnored()) + if (permissions.ExecuteCommands) { - if (msg.Kind == MessageKind.Message) - { - BotContext.MessageTrigger(msg); - } - await BotContext.ExecuteCommand(msg, prefix); } } @@ -199,7 +196,7 @@ public async Task SendMessage(string channel, string message) { await BotClient.SendAsync(new PrivMsgMessage(channel, split)); count += 1; - + if (count > 4) { string link = await InternetServicesHelper.UploadToTrashbin(MessageHelper.StripIRC(message), diff --git a/fs24bot3/Bot.cs b/fs24bot3/Bot.cs index ca53ec3..3c0f210 100644 --- a/fs24bot3/Bot.cs +++ b/fs24bot3/Bot.cs @@ -30,7 +30,7 @@ public class Bot public Systems.DuckDuckGoGPT Gpt { get; } public List AcknownUsers = new List(); public Profiler PProfiler { get; } - + private OnMsgEvent OnMsgEvent { get; } public enum CooldownBucketType @@ -58,7 +58,7 @@ public Bot(IMessagingClient messagingClient) }) }); Client = messagingClient; - + Service.AddModule(); Service.AddModule(); Service.AddModule(); @@ -68,7 +68,7 @@ public Bot(IMessagingClient messagingClient) Service.AddModule(); Service.AddModule(); Service.AddModule(); - + Service.AddTypeParser(new Parsers.LanugageParser()); Service.AddTypeParser(new Parsers.GoalProgressParser()); Service.AddTypeParser(new Parsers.ColorParser()); @@ -90,7 +90,7 @@ public Bot(IMessagingClient messagingClient) .Any(x => x.Aliases.Any(a => a == command.Command)); if (!commandIntenral || string.IsNullOrWhiteSpace(command.Nick)) continue; - + var user = new User(command.Nick, Connection); Log.Warning("User {0} have a command with internal name {1}!", user.Username, @@ -146,7 +146,7 @@ public async void ProccessInfinite() var reminds = Connection.Table(); foreach (var item in reminds) { - DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, + DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); dtDateTime = dtDateTime.AddSeconds(item.RemindDate).ToLocalTime(); if (dtDateTime <= DateTime.Now) @@ -163,23 +163,35 @@ public async void ProccessInfinite() public void MessageTrigger(MessageGeneric message) { - if (message.Sender.UserIsIgnored() || message.Kind == MessageKind.MessagePersonal) { return; } + if (message.Kind == MessageKind.MessagePersonal) + { + return; + } + var permissions = message.Sender.GetPermissions(); + PProfiler.BeginMeasure("msg"); + try { - PProfiler.BeginMeasure("msg"); - OnMsgEvent.InsertMessages(message); - OnMsgEvent.DestroyWallRandomly(Shop, message); - OnMsgEvent.LevelInscrease(Shop, message); - OnMsgEvent.PrintWarningInformation(message); - OnMsgEvent.HandleYoutube(message); - OnMsgEvent.HandleURL(message); - OnMsgEvent.WhoWrotesMe(message); - PProfiler.EndMeasure("msg"); + if (permissions.HandleProcessing && !permissions.Bridge) + { + OnMsgEvent.InsertMessages(message); + OnMsgEvent.DestroyWallRandomly(Shop, message); + OnMsgEvent.LevelInscrease(Shop, message); + OnMsgEvent.PrintWarningInformation(message); + OnMsgEvent.WhoWrotesMe(message); + } + + if (permissions.HandleUrls) + { + OnMsgEvent.HandleURL(message); + } } catch (Exception ex) { Log.Error("Message trigger causes a exception: {0}", ex); } + + PProfiler.EndMeasure("msg"); } static string HeuristicPrintErrorMessage(string message) @@ -239,7 +251,8 @@ await Client.SendMessage(message.Target, $"Ошибка в `{err.Parameter}` необходимый тип: `{err.Parameter.Type.Name}` вы же ввели: `{err.Value.GetType().Name}`. Введите .helpcmd {err.Parameter.Command} чтобы узнать наконец-то, как же правильно пользоватся этой командой."); break; case CommandOnCooldownResult err: - await Client.SendMessage(message.Target, $"{RandomMsgs.CommandCooldownMessages.Random()} {err.Cooldowns.FirstOrDefault().RetryAfter.ToString(@"hh\:mm\:ss")}"); + await Client.SendMessage(message.Target, + $"{RandomMsgs.CommandCooldownMessages.Random()} {err.Cooldowns.FirstOrDefault().RetryAfter.ToString(@"hh\:mm\:ss")}"); break; case ArgumentParseFailedResult err: var parserResult = err.ParserResult as DefaultArgumentParserResult; @@ -260,12 +273,13 @@ await Client.SendMessage(message.Target, break; case OverloadsFailedResult: await Client.SendMessage(message.Target, "Команда выключена..."); - break; + break; case CommandNotFoundResult _: await CustomCommandProcessor.ProcessCmd(prefix, message); break; case CommandExecutionFailedResult err: - if (err.Exception.GetType() == typeof(JsonReaderException) || err.Exception.GetType() == typeof(JsonException)) + if (err.Exception.GetType() == typeof(JsonReaderException) || + err.Exception.GetType() == typeof(JsonException)) { await Client.SendMessage(message.Target, RandomMsgs.NetworkMessages.Random()); } diff --git a/fs24bot3/Checks/CheckAdmin.cs b/fs24bot3/Checks/CheckAdmin.cs index ef80f8a..7f349f7 100644 --- a/fs24bot3/Checks/CheckAdmin.cs +++ b/fs24bot3/Checks/CheckAdmin.cs @@ -11,9 +11,11 @@ public override ValueTask CheckAsync(CommandContext _) { var context = _ as CommandProcessor.CustomCommandContext; + var permissions = context.User.GetPermissions(); + try { - return (context.User.GetUserInfo().Admin >= 1 && context.IsAuthorizedAction) || ConfigurationProvider.Config.Backend == Models.Backend.Basic + return (permissions.Admin && context.IsAuthorizedAction) || ConfigurationProvider.Config.Backend == Models.Backend.Basic ? CheckResult.Successful : CheckResult.Failed("Эта команда только для админов!"); } diff --git a/fs24bot3/Checks/FullAccount.cs b/fs24bot3/Checks/FullAccount.cs index 6cf2dcc..e9d17d8 100644 --- a/fs24bot3/Checks/FullAccount.cs +++ b/fs24bot3/Checks/FullAccount.cs @@ -3,13 +3,19 @@ using System.Threading.Tasks; namespace fs24bot3.Checks; + public sealed class FullAccount : CheckAttribute { public override ValueTask CheckAsync(CommandContext _) { var context = _ as CommandProcessor.CustomCommandContext; - return !context.FromBridge && !context.User.UserIsIgnored() && context.User != null && context.IsAuthorizedAction + if (context?.User is null) + { + return CheckResult.Failed("Нет аккаунта пользователя"); + } + + return !context.FromBridge && context.IsAuthorizedAction ? CheckResult.Successful : CheckResult.Failed("Эта команда требует аккаунт fs24_bot и авторизацию через NickServ!"); } @@ -18,4 +24,4 @@ public override string ToString() { return "Аккаунт пользователя"; } -} +} \ No newline at end of file diff --git a/fs24bot3/Commands/CustomCommandsModule.cs b/fs24bot3/Commands/CustomCommandsModule.cs index 02a2f49..b31f928 100644 --- a/fs24bot3/Commands/CustomCommandsModule.cs +++ b/fs24bot3/Commands/CustomCommandsModule.cs @@ -92,7 +92,7 @@ public async Task CustomCmdEdit(string command, CommandToggles.CommandEdit actio if (query != null && query.Command == command && query.IsLua == 0) { - if (query.Nick == Context.User.Username || Context.User.GetUserInfo().Admin == 2) + if (query.Nick == Context.User.Username || Context.User.GetPermissions().Admin) { switch (action) { @@ -198,9 +198,9 @@ await Context.SendMessage(Context.Channel, public async Task CustomCmdRepl(string command, string oldstr, string newstr = "") { var query = Context.BotCtx.Connection.Table().Where(v => v.Command.Equals(command)).FirstOrDefault(); - if (query != null && query.Command == command || Context.User.GetUserInfo().Admin == 2) + if (query != null && query.Command == command || Context.User.GetPermissions().Admin) { - if (query.Nick == Context.User.Username || Context.User.GetUserInfo().Admin == 2) + if (query.Nick == Context.User.Username || Context.User.GetPermissions().Admin) { Context.BotCtx.Connection.Execute("UPDATE CustomUserCommands SET Output = ? WHERE Command = ?", query.Output.Replace(oldstr, newstr), command); await Context.SendMessage(Context.Channel, "[blue]Команда успешно обновлена!"); @@ -222,9 +222,9 @@ public async Task CustomCmdRepl(string command, string oldstr, string newstr = " public async Task LuaUpdCoommand(string command, [Remainder] string newstr) { var query = Context.BotCtx.Connection.Table().Where(v => v.Command.Equals(command)).FirstOrDefault(); - if (query != null && query.IsLua == 1 && query.Command == command || Context.User.GetUserInfo().Admin == 2) + if (query != null && query.IsLua == 1 && query.Command == command || Context.User.GetPermissions().Admin) { - if (query.Nick == Context.User.Username || Context.User.GetUserInfo().Admin == 2) + if (query.Nick == Context.User.Username || Context.User.GetPermissions().Admin) { Context.BotCtx.Connection.Execute("UPDATE CustomUserCommands SET Output = ? WHERE Command = ?", newstr, command); await Context.SendMessage(Context.Channel, "[blue]Команда успешно обновлена!"); @@ -254,7 +254,7 @@ public async Task LuaUpdCoommandUrl(string command, string rawurl) [Checks.FullAccount] public async Task CustomCmdRem(string command) { - if (Context.User.GetUserInfo().Admin == 2) + if (Context.User.GetPermissions().Admin) { var query = Context.BotCtx.Connection.Table().Where(v => v.Command.Equals(command)).Delete(); if (query > 0) diff --git a/fs24bot3/Commands/InventoryCommandsModule.cs b/fs24bot3/Commands/InventoryCommandsModule.cs index dd0931a..f20662a 100644 --- a/fs24bot3/Commands/InventoryCommandsModule.cs +++ b/fs24bot3/Commands/InventoryCommandsModule.cs @@ -289,7 +289,7 @@ await Context.SendMessage(Context.Channel, if (query != null && query.Name == tagname) { - if (query.CreatedBy == Context.User.Username || Context.User.GetUserInfo().Admin == 2) + if (query.CreatedBy == Context.User.Username || Context.User.GetPermissions().Admin) { Context.BotCtx.Connection.Table().Where(v => v.Name.Equals(tagname)).Delete(); await Context.SendMessage(Context.Channel, diff --git a/fs24bot3/Commands/SystemCommandsModule.cs b/fs24bot3/Commands/SystemCommandsModule.cs index 7924ca6..2d58777 100644 --- a/fs24bot3/Commands/SystemCommandsModule.cs +++ b/fs24bot3/Commands/SystemCommandsModule.cs @@ -9,10 +9,12 @@ using System.IO; using System.IO.Compression; using System.Linq; +using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; namespace fs24bot3.Commands; + public sealed class SystemCommandModule : ModuleBase { public CommandService Service { get; set; } @@ -22,7 +24,8 @@ public sealed class SystemCommandModule : ModuleBase !x.Name.ToLower().Contains("paged") && x.Name.EndsWith("64")) - .Select(prop => $"{prop.Name.Replace("64", "")} = {(long)prop.GetValue(proc, null) / 1024 / 1024} MiB"))); + .Where(x => !x.Name.ToLower().Contains("paged") && x.Name.EndsWith("64")) + .Select(prop => $"{prop.Name.Replace("64", "")} = {(long)prop.GetValue(proc, null) / 1024 / 1024} MiB"))); } [Command("profiler", "prof", "performance", "perf")] @@ -65,14 +68,15 @@ public async Task SetTimeZone([Remainder] string timeZone = "") { if (string.IsNullOrWhiteSpace(timeZone)) { - var tz = string.Join("\n", TimeZoneInfo.GetSystemTimeZones().Select(x => $"id: `{x.Id}` название: {x.DisplayName}")); - await Context.SendMessage(Context.Channel, $"Часовые пояса: {Helpers.InternetServicesHelper.UploadToTrashbin(tz, "addplain").Result}"); + var tz = string.Join("\n", + TimeZoneInfo.GetSystemTimeZones().Select(x => $"id: `{x.Id}` название: {x.DisplayName}")); + await Context.SendMessage(Context.Channel, + $"Часовые пояса: {Helpers.InternetServicesHelper.UploadToTrashbin(tz, "addplain").Result}"); return; } Context.User.SetTimeZone(timeZone); await Context.SendMessage(Context.Channel, "Часовой пояс установлен!"); - } [Command("printstopwords")] @@ -128,6 +132,7 @@ public async Task Giveall(string username) { user.AddItemToInv(Context.BotCtx.Shop, item.Key, 1); } + await Context.SendMessage(Context.Channel, "Вы выдали себе все предметы!"); } @@ -171,7 +176,8 @@ public async Task Give(string username, string item, int count) User sql = new User(username, in Context.BotCtx.Connection); sql.AddItemToInv(Context.BotCtx.Shop, item, count); - await Context.SendMessage(Context.Channel, "Вы добавили предмет: " + Context.BotCtx.Shop.Items[item].Name + " пользователю " + username); + await Context.SendMessage(Context.Channel, + "Вы добавили предмет: " + Context.BotCtx.Shop.Items[item].Name + " пользователю " + username); } @@ -235,7 +241,8 @@ public async Task GiveLevel(string username, int count) [Checks.CheckAdmin] public async Task CommandMgmt(CommandToggles.Switch action, string command) { - var cmdHandle = Service.GetAllCommands().Where(x => x.Aliases.Where(al => al == command).Any()).FirstOrDefault(); + var cmdHandle = Service.GetAllCommands().Where(x => x.Aliases.Where(al => al == command).Any()) + .FirstOrDefault(); if (cmdHandle == null) { @@ -286,8 +293,10 @@ public async Task ModMgmt(CommandToggles.Switch action, string module) [Command("mods", "modules")] public async Task Mods() { - await Context.SendMessage(Context.Channel, $"[red]█[r] Выключен [green]█[r] Включен. Число в скобках: количество команд в модуле"); - await Context.SendMessage(Context.Channel, $"В данный момент загружено: {Service.GetAllModules().Count} модулей"); + await Context.SendMessage(Context.Channel, + $"[red]█[r] Выключен [green]█[r] Включен. Число в скобках: количество команд в модуле"); + await Context.SendMessage(Context.Channel, + $"В данный момент загружено: {Service.GetAllModules().Count} модулей"); string modi = string.Join(" ", Service.GetAllModules() .Select(x => $"{(x.IsEnabled ? "[green]" : "[red]")}{x.Name}[r]({x.Commands.Count})")); await Context.SendMessage(Context.Channel, modi); @@ -308,7 +317,6 @@ public async Task LoggerLevel(bool enabled = true) Context.BotCtx.Connection.Tracer = new Action(q => { Log.Warning(q); }); Context.BotCtx.Connection.Trace = enabled; await Context.SendMessage(Context.Channel, $"SQL логирование `{enabled}`"); - } [Command("delete")] @@ -327,6 +335,7 @@ public async Task DeleteUser(string users, int level = 1) { Context.BotCtx.Connection.Execute("DELETE FROM UserStats WHERE Level = ?", level); } + Context.BotCtx.Connection.Execute("VACUUM;"); await Context.SendMessage(Context.Channel, "Данные удалены!"); } @@ -335,7 +344,8 @@ public async Task DeleteUser(string users, int level = 1) [Checks.CheckAdmin] public async Task ViewUsers() { - await Context.SendMessage(Context.Channel, String.Join(' ', Context.BotCtx.Connection.Table().Select(x => $"{x.Nick}({x.Level})"))); + await Context.SendMessage(Context.Channel, + String.Join(' ', Context.BotCtx.Connection.Table().Select(x => $"{x.Nick}({x.Level})"))); } [Command("say", "writeasbot")] @@ -346,31 +356,65 @@ public async Task WriteAsBot(string channel, [Remainder] string message) await Context.SendMessage(Context.Channel, "Сообщение отправлено!"); } - [Command("ignore")] + [Command("setpermission", "setperm", "sp")] + [Description("Установка прав пользователю")] [Checks.CheckAdmin] - public async Task Ignore(CommandToggles.CommandEdit action, [Remainder] string username) + public async Task SetPermission(PermissionsFlags permission, [Remainder] string username) { var usernames = username.Split(" "); - switch (action) + + foreach (var item in usernames) { - case CommandToggles.CommandEdit.Add: - foreach (var item in usernames) - { - var ignr = new SQL.Ignore() - { - Username = item - }; - Context.BotCtx.Connection.Insert(ignr); - } - await Context.SendMessage(Context.Channel, $"Пользователь(и) {username} добавлен(ы) в игнор!"); - break; - case CommandToggles.CommandEdit.Delete: - foreach (var item in usernames) - { - Context.BotCtx.Connection.Execute("DELETE FROM Ignore WHERE Username = ?", item); - } - await Context.SendMessage(Context.Channel, $"Пользователь(и) {username} удален(ы) из игнора!"); - break; + var user = new User(item, Context.BotCtx.Connection); + var permissionClass = user.GetPermissions(); + permissionClass.TooglePermission(permission); + Context.BotCtx.Connection.InsertOrReplace(permissionClass); + } + + string fmt = username.Length > 1 ? "пользователей" : "пользователя"; + await Context.SendMessage(Context.Channel, $"Права {fmt} {string.Join(", ", usernames)} были модифицированы!"); + } + + [Command("permissions", "perms", "permlist")] + [Checks.CheckAdmin] + public async Task Permissions(string username) + { + var user = new User(username, Context.BotCtx.Connection); + var permission = user.GetPermissions(); + + if (permission == null || permission.Flags == PermissionsFlags.None) + { + await Context.SendMessage("У этого пользователя вообще нет прав..."); + return; } + + var sb = new StringBuilder(); + + if (permission.Admin) + { + sb.Append("права администратора, "); + } + + if (permission.Bridge) + { + sb.Append("мост, "); + } + + if (permission.ExecuteCommands) + { + sb.Append("выполнение команд, "); + } + + if (permission.HandleProcessing) + { + sb.Append("обработка данных, "); + } + + if (permission.HandleUrls) + { + sb.Append("обработка ссылок, "); + } + + await Context.SendMessage(Context.Channel, $"Права пользователя [b]{username}[r]: {sb}"); } -} +} \ No newline at end of file diff --git a/fs24bot3/Core/Database.cs b/fs24bot3/Core/Database.cs index 2902c69..15ebd76 100644 --- a/fs24bot3/Core/Database.cs +++ b/fs24bot3/Core/Database.cs @@ -17,7 +17,7 @@ public static void InitDatabase(in SQLiteConnection connection) connection.CreateTable(); connection.CreateTable(); connection.CreateTable(); - connection.CreateTable(); + connection.CreateTable(); connection.CreateTable(); connection.CreateTable(); diff --git a/fs24bot3/Core/User.cs b/fs24bot3/Core/User.cs index 03fe2a2..60f8ec8 100644 --- a/fs24bot3/Core/User.cs +++ b/fs24bot3/Core/User.cs @@ -69,10 +69,9 @@ public void CreateAccountIfNotExist() { Log.Warning("User {0} not found in database", Username); - var user = new SQL.UserStats() + var user = new SQL.UserStats { Nick = Username, - Admin = 0, Level = 1, Xp = 0, Need = 1000, @@ -157,10 +156,16 @@ public DateTime GetLastMessage() return dtDateTime; } - public bool UserIsIgnored() + public Permissions GetPermissions() { - Log.Verbose("Ignored: {0}", Connect.Table().Any(v => v.Username == Username)); - return Connect.Table().Any(v => v.Username.Equals(Username)); + var perms = Connect.Table().FirstOrDefault(x => x.Username == Username); + if (perms == null) + { + return new Permissions(Username); + } + + perms.ApplyValuesAsBitflags(); + return perms; } public void SetLevel(int level) diff --git a/fs24bot3/EventProcessors/OnMsgEvent.cs b/fs24bot3/EventProcessors/OnMsgEvent.cs index 531ce5b..a902643 100644 --- a/fs24bot3/EventProcessors/OnMsgEvent.cs +++ b/fs24bot3/EventProcessors/OnMsgEvent.cs @@ -13,6 +13,8 @@ using static fs24bot3.Models.OpenWeatherMapResponse; using NetIRC; using System.Collections.Generic; +using System.Net.Http; +using System.Net.Sockets; using HtmlAgilityPack; using static fs24bot3.Models.BandcampSearch; using static fs24bot3.Models.APIExec; @@ -62,6 +64,43 @@ await BotContext.Client.SendMessage(message.Target, public async void HandleURL(MessageGeneric message) { + // TODO: more convinient URL handling from different services + + foreach (var match in YoutubeRegex.Matches(message.Body)) + { + try + { + Process p = new Process(); + p.StartInfo.UseShellExecute = false; + p.StartInfo.RedirectStandardOutput = true; + p.StartInfo.FileName = ConfigurationProvider.Config.Services.YoutubeDlPath; + p.StartInfo.Arguments = "--simulate --print-json \"" + match + "\""; + p.Start(); + string output = await p.StandardOutput.ReadToEndAsync(); + await p.WaitForExitAsync(); + + var jsonOutput = + JsonConvert.DeserializeObject(output, JsonSerializerHelper.OPTIMIMAL_SETTINGS); + + if (jsonOutput != null) + { + var ts = TimeSpan.FromSeconds(jsonOutput.duration); + await BotContext.Client.SendMessage(message.Target, + $"[b]{jsonOutput.title}[r] от [b]{jsonOutput.channel}[r]. " + + $"[green]Длительность: [r][b]{ts:hh\\:mm\\:ss}[r] " + + $"[green]👍[r][b] {jsonOutput.like_count}[r] " + + $"[green]Просмотров: [r][b]{jsonOutput.view_count}[r] " + + $"[green]Дата загрузки: [r][b]{FmtUploadDate(jsonOutput.upload_date)}[r]"); + + return; + } + } + catch (Exception) + { + // ignored + } + } + foreach (var match in URLRegex.Matches(message.Body)) { var web = new HtmlWeb(); @@ -72,13 +111,20 @@ public async void HandleURL(MessageGeneric message) continue; } - var document = await web.LoadFromWebAsync(url); - string title = document.DocumentNode.SelectSingleNode("//head/title").InnerText ?? "Нет заголовка"; - var domain = url.Split("/"); + try + { + var document = await web.LoadFromWebAsync(url); + string title = document?.DocumentNode?.SelectSingleNode("//head/title")?.InnerText ?? "Нет заголовка"; + var domain = url.Split("/"); - if (domain.Length >= 3) + if (domain.Length >= 3) + { + await BotContext.Client.SendMessage(message.Target, $"[b][ {title} ][r] - {domain[2]}"); + } + } + catch (HttpRequestException) { - await BotContext.Client.SendMessage(message.Target, $"[b][ {title} ][r] - {domain[2]}"); + Log.Warning("Unable to handle URL: {0} due to request error", url); } } } @@ -91,45 +137,6 @@ public async void DestroyWallRandomly(Shop shop, MessageGeneric message) } } - public void HandleYoutube(MessageGeneric message) - { - foreach (var match in YoutubeRegex.Matches(message.Body)) - { - new Thread(async () => - { - try - { - Process p = new Process(); - p.StartInfo.UseShellExecute = false; - p.StartInfo.RedirectStandardOutput = true; - p.StartInfo.FileName = ConfigurationProvider.Config.Services.YoutubeDlPath; - p.StartInfo.Arguments = "--simulate --print-json \"" + match + "\""; - p.Start(); - string output = await p.StandardOutput.ReadToEndAsync(); - await p.WaitForExitAsync(); - - var jsonOutput = - JsonConvert.DeserializeObject(output, JsonSerializerHelper.OPTIMIMAL_SETTINGS); - - if (jsonOutput != null) - { - var ts = TimeSpan.FromSeconds(jsonOutput.duration); - await BotContext.Client.SendMessage(message.Target, - $"[b]{jsonOutput.title}[r] от [b]{jsonOutput.channel}[r]. " + - $"[green]Длительность: [r][b]{ts:hh\\:mm\\:ss}[r] " + - $"[green]👍[r][b] {jsonOutput.like_count}[r] " + - $"[green]Просмотров: [r][b]{jsonOutput.view_count}[r] " + - $"[green]Дата загрузки: [r][b]{FmtUploadDate(jsonOutput.upload_date)}[r]"); - } - } - catch (Exception) - { - // ignored - } - }).Start(); - } - } - public void InsertMessages(MessageGeneric message) { BotContext.Connection.Insert(new SQL.Messages() diff --git a/fs24bot3/Models/Configuration.cs b/fs24bot3/Models/Configuration.cs index bc5deba..d0dc4fd 100644 --- a/fs24bot3/Models/Configuration.cs +++ b/fs24bot3/Models/Configuration.cs @@ -53,14 +53,13 @@ public Configuration() Prefix = "."; LogLevel = "Verbose"; Backend = Backend.Basic; - Services = new Services() + Services = new Services { JdoodleClientID = "0", JdoodleClientSecret = "0", TrashbinUrl = "", WolframID = "0", RapidApiKey = "0", - BridgeNickname = "cheburator", FinnhubKey = "0", YoutubeDlPath = "youtube-dl", OpenWeatherMapKey = "0", diff --git a/fs24bot3/Models/MessageGeneric.cs b/fs24bot3/Models/MessageGeneric.cs index aafa172..5d6a19c 100644 --- a/fs24bot3/Models/MessageGeneric.cs +++ b/fs24bot3/Models/MessageGeneric.cs @@ -34,7 +34,7 @@ public MessageGeneric(in ParsedIRCMessage message, in SQLiteConnection connectio Kind = MessageKind.MessagePersonal; } - if (Sender.Username == ConfigurationProvider.Config.Services.BridgeNickname) + if (Sender.GetPermissions().Bridge) { // trim bridged user nickname like // //bpm140//: @ms привет diff --git a/fs24bot3/Models/Permissions.cs b/fs24bot3/Models/Permissions.cs new file mode 100644 index 0000000..6533c2e --- /dev/null +++ b/fs24bot3/Models/Permissions.cs @@ -0,0 +1,95 @@ +using System; +using Serilog; +using SQLite; + +namespace fs24bot3.Models; + +[Flags] +public enum PermissionsFlags +{ + None = 0, + ExecuteCommands = 1, + Bridge = 2, + HandleProcessing = 4, + HandleUrls = 8, + Admin = 16 +} + +// ultimate table99999 +public class Permissions +{ + [PrimaryKey] public string Username { get; set; } + public PermissionsFlags Flags { get; set; } + [Ignore] public bool ExecuteCommands { get; private set; } + [Ignore] public bool Bridge { get; private set; } + [Ignore] public bool HandleProcessing { get; private set; } + [Ignore] public bool HandleUrls { get; private set; } + [Ignore] public bool Admin { get; private set; } + + public Permissions() + { + } + + public Permissions(string username, PermissionsFlags flags) + { + Username = username; + Flags = flags; + + ApplyValuesAsBitflags(); + } + + public Permissions(string username) + { + Username = username; + Flags = PermissionsFlags.ExecuteCommands | PermissionsFlags.HandleProcessing | + PermissionsFlags.HandleUrls; + + ApplyValuesAsBitflags(); + } + + public void TooglePermission(PermissionsFlags flag) + { + Flags ^= flag; + + Log.Verbose("{0}", Flags); + } + + public void ApplyValuesAsBitflags() + { + ExecuteCommands = (Flags & PermissionsFlags.ExecuteCommands) == PermissionsFlags.ExecuteCommands; + Bridge = (Flags & PermissionsFlags.Bridge) == PermissionsFlags.Bridge; + HandleProcessing = (Flags & PermissionsFlags.HandleProcessing) == PermissionsFlags.HandleProcessing; + HandleUrls = (Flags & PermissionsFlags.HandleUrls) == PermissionsFlags.HandleUrls; + Admin = (Flags & PermissionsFlags.Admin) == PermissionsFlags.Admin; + } + + public void ConvertValuesToBitflags() + { + Flags = PermissionsFlags.None; + + if (ExecuteCommands) + { + Flags |= PermissionsFlags.ExecuteCommands; + } + + if (Bridge) + { + Flags |= PermissionsFlags.Bridge; + } + + if (HandleProcessing) + { + Flags |= PermissionsFlags.HandleProcessing; + } + + if (HandleUrls) + { + Flags |= PermissionsFlags.HandleUrls; + } + + if (Admin) + { + Flags |= PermissionsFlags.Admin; + } + } +} \ No newline at end of file diff --git a/fs24bot3/Models/SQL.cs b/fs24bot3/Models/SQL.cs index 5e87181..18952f1 100644 --- a/fs24bot3/Models/SQL.cs +++ b/fs24bot3/Models/SQL.cs @@ -14,14 +14,12 @@ public class UserStats public int Level { get; set; } public int Xp { get; set; } public int Need { get; set; } - public int Admin { get; set; } public int LastMsg { get; set; } public string Prefix { get; set; } public string Timezone { get; set; } public string City { get; set; } } - public class Cache { [PrimaryKey] @@ -135,12 +133,7 @@ public class Tags public string Tag { get; set; } } - // ultimate table99999 - public class Ignore - { - [PrimaryKey] - public string Username { get; set; } - } + public class UtfCharacters { diff --git a/fs24bot3/Models/Topic.cs b/fs24bot3/Models/Topic.cs index cb8d4bd..34d5976 100644 --- a/fs24bot3/Models/Topic.cs +++ b/fs24bot3/Models/Topic.cs @@ -1,28 +1,19 @@ using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace fs24bot3.Models +namespace fs24bot3.Models; + +public class Topic { - public class Topic - { - [JsonProperty("article")] - public string Article { get; set; } + [JsonProperty("article")] public string Article { get; set; } - [JsonProperty("language")] - public string Language { get; set; } + [JsonProperty("language")] public string Language { get; set; } - [JsonProperty("numOfTitles")] - public int NumOfTitles { get; set; } + [JsonProperty("numOfTitles")] public int NumOfTitles { get; set; } - public Topic(string article, string lauguage = "Russian", int numTitles = 1) - { - Article = article; - Language = lauguage; - NumOfTitles = numTitles; - } + public Topic(string article, string lauguage = "Russian", int numTitles = 1) + { + Article = article; + Language = lauguage; + NumOfTitles = numTitles; } -} +} \ No newline at end of file diff --git a/fs24bot3/Systems/DuckDuckGoGPT.cs b/fs24bot3/Systems/DuckDuckGoGPT.cs index 6ee661d..c15eefb 100644 --- a/fs24bot3/Systems/DuckDuckGoGPT.cs +++ b/fs24bot3/Systems/DuckDuckGoGPT.cs @@ -6,6 +6,6 @@ namespace fs24bot3.Systems; public class DuckDuckGoGPT { - public Dictionary Contexts = new(); + public readonly Dictionary Contexts = new(); public DuckDuckGoGPTHelper GlobalContext = new(); } \ No newline at end of file