From 5b2c3ac6b859cf00a17d529b2579fa8dddcd2349 Mon Sep 17 00:00:00 2001 From: 140bpmdubstep Date: Mon, 13 Nov 2023 11:32:26 +0300 Subject: [PATCH] Timespan formatting --- fs24bot3/Commands/GenericCommandsModule.cs | 81 ++++++++-------------- fs24bot3/Core/Database.cs | 27 +++++++- fs24bot3/Core/LuaExecutor.cs | 61 +++++++++------- fs24bot3/Core/User.cs | 4 +- fs24bot3/Models/SQL.cs | 12 ++++ 5 files changed, 106 insertions(+), 79 deletions(-) diff --git a/fs24bot3/Commands/GenericCommandsModule.cs b/fs24bot3/Commands/GenericCommandsModule.cs index 9797ff0..b316b71 100644 --- a/fs24bot3/Commands/GenericCommandsModule.cs +++ b/fs24bot3/Commands/GenericCommandsModule.cs @@ -17,6 +17,7 @@ using Serilog; using System.Runtime.InteropServices; using KeraLua; +using System.Threading; namespace fs24bot3.Commands; public sealed class GenericCommandsModule : ModuleBase @@ -111,6 +112,13 @@ public async Task Remind(string time = "1m", [Remainder] string message = "") } var timeSegments = Regex.Matches(time, @"(\d+[ywdhms])"); + + if (!timeSegments.Any()) + { + Context.SendErrorMessage(Context.Channel, $"Неверный формат времени или неверные единицы измерения времени"); + return; + } + foreach (Match segment in timeSegments) { var value = uint.Parse(segment.Value.TrimEnd('y', 'w', 'd', 'h', 'm', 's')); @@ -140,7 +148,7 @@ public async Task Remind(string time = "1m", [Remainder] string message = "") } } - if (totalSecs < 0) + if (totalSecs <= 0) { await Context.SendSadMessage(Context.Channel, "Потерялся во времени?"); return; @@ -161,25 +169,29 @@ public async Task RemindAt(string dateTimeString, [Remainder] string message = " message = RandomMsgs.RemindMessages.Random(); } - var timeZone = Context.User.GetTimeZone(); - if (DateTime.TryParseExact(dateTimeString, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime remindDateTime)) + string[] formats = { "yyyy-MM-dd HH:mm:ss", "HH:mm", "HH:mm:ss", "yyyy-MM-dd" }; + foreach (var item in formats) { - remindDateTime = TimeZoneInfo.ConvertTimeToUtc(remindDateTime, timeZone); - - if (remindDateTime <= DateTime.UtcNow) + var timeZone = Context.User.GetTimeZone(); + if (DateTime.TryParseExact(dateTimeString, item, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime remindDateTime)) { - await Context.SendSadMessage(Context.Channel, "Потерялся во времени?"); + remindDateTime = TimeZoneInfo.ConvertTimeToUtc(remindDateTime, timeZone); + + if (remindDateTime <= DateTime.UtcNow) + { + await Context.SendSadMessage(Context.Channel, "Потерялся во времени?"); + return; + } + + TimeSpan timeUntilRemind = remindDateTime - DateTime.UtcNow; + Context.User.AddRemind(timeUntilRemind, message, Context.Channel); + await Context.SendMessage(Context.Channel, $"{message} в {dateTimeString} {TrimTimezoneName(timeZone.DisplayName)}"); return; } - - TimeSpan timeUntilRemind = remindDateTime - DateTime.UtcNow; - Context.User.AddRemind(timeUntilRemind, message, Context.Channel); - await Context.SendMessage(Context.Channel, $"{message} в {dateTimeString} {TrimTimezoneName(timeZone.DisplayName)}"); - } - else - { - Context.SendErrorMessage(Context.Channel, "Неверный формат даты и времени. Используйте 'yyyy-MM-dd HH:mm:ss'"); + continue; } + + await Context.SendSadMessage(Context.Channel, $"Неверный формат времени, допустимые форматы: {string.Join(", ", formats)}"); } [Command("delmind", "delremind", "deleteremind")] @@ -249,7 +261,7 @@ public async Task Reminds(string username = "", string locale = "ru-RU") if (usr.Username == Context.User.Username) { rems.Append( - $"id: {remind.RemindDate}: \"{remind.Message}\" в [b]{dtDateTime.ToString(rus)}" + + $"id: {remind.Id}: \"{remind.Message}\" в [b]{dtDateTime.ToString(rus)}" + $"{TrimTimezoneName(timezone.DisplayName)} [r]или через [blue]{ToReadableString(dt.Subtract(DateTime.UtcNow))}\n"); } else @@ -468,43 +480,8 @@ public async Task Namegen(uint count = 1) [Description("Калькулятор")] public async Task Calculator([Remainder] string expression) { - IntPtr pointer = IntPtr.Zero; - long currentMemoryUsage = 0; - var timeout = 2000; - var input = "return " + expression; - - NLua.Lua lua = new NLua.Lua(); - - lua.State.SetAllocFunction(((ud, ptr, osize, nsize) => - { - currentMemoryUsage += (long)nsize; - - Log.Verbose("[LUA] MEMORY ALLOCATION: {0} bytes width: {1}", - currentMemoryUsage, (int)nsize.ToUInt32()); - - if (currentMemoryUsage > LuaExecutor.MEMORY_LIMIT) - { - return IntPtr.Zero; - } - - return ptr != IntPtr.Zero && nsize.ToUInt32() > 0 ? - Marshal.ReAllocHGlobal(ptr, unchecked((IntPtr)(long)(ulong)nsize)) : - Marshal.AllocHGlobal((int)nsize.ToUInt32()); - }), ref pointer); - lua.State.Encoding = Encoding.UTF8; - - - var time = 0; - lua.State.SetHook(((_, _) => - { - if (time > timeout) - { - lua.State.Error("this calcuation is too hard for me"); - } - time++; - }), LuaHookMask.Count, 1); - + var lua = LuaExecutor.CreateLuaState(); // block danger functions lua["os.execute"] = null; diff --git a/fs24bot3/Core/Database.cs b/fs24bot3/Core/Database.cs index 5fc31ce..7ad63e3 100644 --- a/fs24bot3/Core/Database.cs +++ b/fs24bot3/Core/Database.cs @@ -17,7 +17,32 @@ public static void InitDatabase(in SQLiteConnection connection) connection.CreateTable(); connection.CreateTable(); connection.CreateTable(); - connection.CreateTable(); + + try + { + connection.CreateTable(); + } + catch (SQLiteException) + { + // Reminds: Migrate from old one to new + connection.Execute("ALTER TABLE Reminds RENAME TO RemindsOld"); + connection.CreateTable(); + var query = connection.Table().ToList(); + + foreach (var item in query) + { + connection.Insert(new SQL.Reminds + { + Channel = item.Channel, + Message = item.Message, + Nick = item.Nick, + RemindDate = item.RemindDate + }); + } + + connection.DropTable(); + } + connection.CreateTable(); connection.CreateTable(); connection.CreateTable(); diff --git a/fs24bot3/Core/LuaExecutor.cs b/fs24bot3/Core/LuaExecutor.cs index 108ceb3..18648a5 100644 --- a/fs24bot3/Core/LuaExecutor.cs +++ b/fs24bot3/Core/LuaExecutor.cs @@ -1,10 +1,13 @@ using fs24bot3.Helpers; using fs24bot3.Models; +using KeraLua; using NLua; using Serilog; using System; +using System.Reflection; using System.Runtime.InteropServices; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace fs24bot3.Core; @@ -15,8 +18,6 @@ class LuaExecutor private Bot Context; private SQL.CustomUserCommands Command { get; } - private IntPtr Pointer = IntPtr.Zero; - private long CurrentMemoryUsage = 0; public LuaExecutor(Bot context, SQL.CustomUserCommands command) { @@ -24,30 +25,51 @@ public LuaExecutor(Bot context, SQL.CustomUserCommands command) Command = command; } - public async Task Execute(string senderNick, string channel, string message, string args) + + public static NLua.Lua CreateLuaState(int timeout = 2000) { - var arr = Context.Connection.Table().ToList(); - var nick = MessageHelper.AntiHightlight(arr[new Random().Next(0, arr.Count - 1)].Nick); - var timeout = 10000; - var time = 0; + IntPtr pointer = IntPtr.Zero; + long currentMemoryUsage = 0; + + NLua.Lua lua = new NLua.Lua(); - Lua lua = new Lua(); lua.State.SetAllocFunction(((ud, ptr, osize, nsize) => { - CurrentMemoryUsage += (long)nsize; + currentMemoryUsage += (long)nsize; - Log.Verbose("[LUA] MEMORY ALLOCATION: {0} bytes width: {1}", - CurrentMemoryUsage, (int)nsize.ToUInt32()); + Log.Verbose("[LUA] MEMORY ALLOCATION: {0} bytes width: {1}", + currentMemoryUsage, (int)nsize.ToUInt32()); - if (CurrentMemoryUsage > MEMORY_LIMIT) + if (currentMemoryUsage > LuaExecutor.MEMORY_LIMIT) { return IntPtr.Zero; } - return ptr != IntPtr.Zero && nsize.ToUInt32() > 0 ? - Marshal.ReAllocHGlobal(ptr, unchecked((IntPtr)(long)(ulong)nsize)) : + return ptr != IntPtr.Zero && nsize.ToUInt32() > 0 ? + Marshal.ReAllocHGlobal(ptr, unchecked((IntPtr)(long)(ulong)nsize)) : Marshal.AllocHGlobal((int)nsize.ToUInt32()); - }), ref Pointer); + }), ref pointer); + lua.State.Encoding = Encoding.UTF8; + + + var time = 0; + lua.State.SetHook(((_, _) => + { + if (time > timeout) + { + lua.State.Error("execution timeout"); + } + time++; + }), LuaHookMask.Count, 1); + + return lua; + } + + public async Task Execute(string senderNick, string channel, string message, string args) + { + var arr = Context.Connection.Table().ToList(); + var nick = MessageHelper.AntiHightlight(arr[new Random().Next(0, arr.Count - 1)].Nick); + var lua = CreateLuaState(); lua.State.Encoding = Encoding.UTF8; // block danger functions @@ -78,15 +100,6 @@ public async Task Execute(string senderNick, string channel, string message, str senderNick, Command.Command); lua["Cmd"] = luaFunctions; - lua.State.SetHook(((_, _) => - { - if (time > timeout) - { - lua.State.Error("too long run time"); - } - time++; - }), KeraLua.LuaHookMask.Count, 1); - try { var res = (string)lua.DoString(Command.Output)[0]; diff --git a/fs24bot3/Core/User.cs b/fs24bot3/Core/User.cs index 390f15f..c5c622d 100644 --- a/fs24bot3/Core/User.cs +++ b/fs24bot3/Core/User.cs @@ -245,12 +245,12 @@ public void AddRemindAbs(DateTime time, string title) public List GetReminds() { - return Connect.Table().Where(x => x.Nick == Username).ToList(); + return Connect.Table().Where(x => x.Nick == Username).OrderBy(x => x.RemindDate).ToList(); } public bool DeleteRemind(uint id) { - var affected = Connect.Execute("DELETE FROM Reminds WHERE Nick = ? AND RemindDate = ?", Username, id); + var affected = Connect.Execute("DELETE FROM Reminds WHERE Nick = ? AND Id = ?", Username, id); return affected > 0; } diff --git a/fs24bot3/Models/SQL.cs b/fs24bot3/Models/SQL.cs index d9dce67..578ebe1 100644 --- a/fs24bot3/Models/SQL.cs +++ b/fs24bot3/Models/SQL.cs @@ -61,6 +61,18 @@ public class Warnings } public class Reminds + { + [PrimaryKey] + [AutoIncrement] + public int Id { get; set; } + public uint RemindDate { get; set; } + public string Nick { get; set; } + public string Channel { get; set; } + public string Message { get; set; } + } + + // for migration + public class RemindsOld { [PrimaryKey] public uint RemindDate { get; set; }