diff --git a/docs/index.md b/docs/index.md index c7701724..5e67f8dc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ #NadekoBot Documentation -To invite NadekoBot to your server, click on the image bellow: +To invite public NadekoBot to your server, click on the image bellow: [![img][img]](https://discordapp.com/oauth2/authorize?client_id=170254782546575360&scope=bot&permissions=66186303) @@ -10,9 +10,7 @@ NadekoBot is an open source project, and it can be found on our [GitHub][GitHub] Here you can read current [Issues][Issues]. -If you want to contribute, be sure to PR on the **[dev][dev]** branch. - -**NadekoBot 1.1 release currently does not support x86/32bit architecture.** +If you want to contribute, be sure to PR on the **[1.4][1.4]** branch. ##Content - [About](about.md) @@ -38,4 +36,4 @@ If you want to contribute, be sure to PR on the **[dev][dev]** branch. [NadekoBot Server]: https://discord.gg/nadekobot [GitHub]: https://github.com/Kwoth/NadekoBot [Issues]: https://github.com/Kwoth/NadekoBot/issues -[dev]: https://github.com/Kwoth/NadekoBot/tree/dev +[1.4]: https://github.com/Kwoth/NadekoBot/tree/1.4 diff --git a/src/NadekoBot/DataStructures/TypeReaders/GuildDateTimeTypeReader.cs b/src/NadekoBot/DataStructures/TypeReaders/GuildDateTimeTypeReader.cs new file mode 100644 index 00000000..798caf62 --- /dev/null +++ b/src/NadekoBot/DataStructures/TypeReaders/GuildDateTimeTypeReader.cs @@ -0,0 +1,46 @@ +using Discord.Commands; +using NadekoBot.Services.Administration; +using System; +using System.Threading.Tasks; + +namespace NadekoBot.TypeReaders +{ + public class GuildDateTimeTypeReader : TypeReader + { + private readonly GuildTimezoneService _gts; + + public GuildDateTimeTypeReader(GuildTimezoneService gts) + { + _gts = gts; + } + + public override Task Read(ICommandContext context, string input) + { + if (!DateTime.TryParse(input, out var dt)) + return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Input string is in an incorrect format.")); + + var tz = _gts.GetTimeZoneOrUtc(context.Guild.Id); + + return Task.FromResult(TypeReaderResult.FromSuccess(new GuildDateTime(tz, dt))); + } + } + + public class GuildDateTime + { + public TimeZoneInfo Timezone { get; } + public DateTime CurrentGuildTime { get; } + public DateTime InputTime { get; } + public DateTime InputTimeUtc { get; } + + private GuildDateTime() { } + + public GuildDateTime(TimeZoneInfo guildTimezone, DateTime inputTime) + { + var now = DateTime.UtcNow; + Timezone = guildTimezone; + CurrentGuildTime = TimeZoneInfo.ConvertTime(now, TimeZoneInfo.Utc, Timezone); + InputTime = inputTime; + InputTimeUtc = TimeZoneInfo.ConvertTime(inputTime, Timezone, TimeZoneInfo.Utc); + } + } +} diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index ec317793..3d1f6e4d 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -9,6 +9,7 @@ using NadekoBot.Services; using NadekoBot.Attributes; using NadekoBot.Services.Database.Models; using NadekoBot.Services.Administration; +using Discord.WebSocket; namespace NadekoBot.Modules.Administration { @@ -319,7 +320,7 @@ namespace NadekoBot.Modules.Administration var user = await Context.Guild.GetCurrentUserAsync().ConfigureAwait(false); var enumerable = (await Context.Channel.GetMessagesAsync().Flatten()) - .Where(x => x.Author.Id == user.Id && DateTime.Now - x.CreatedAt < twoWeeks); + .Where(x => x.Author.Id == user.Id && DateTime.UtcNow - x.CreatedAt < twoWeeks); await Context.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false); Context.Message.DeleteAfter(3); } @@ -339,7 +340,7 @@ namespace NadekoBot.Modules.Administration await Context.Message.DeleteAsync().ConfigureAwait(false); int limit = (count < 100) ? count + 1 : 100; var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten().ConfigureAwait(false)) - .Where(x => DateTime.Now - x.CreatedAt < twoWeeks); + .Where(x => DateTime.UtcNow - x.CreatedAt < twoWeeks); if (enumerable.FirstOrDefault()?.Id == Context.Message.Id) enumerable = enumerable.Skip(1).ToArray(); else @@ -363,7 +364,7 @@ namespace NadekoBot.Modules.Administration int limit = (count < 100) ? count : 100; var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten()) - .Where(m => m.Author == user && DateTime.Now - m.CreatedAt < twoWeeks); + .Where(m => m.Author == user && DateTime.UtcNow - m.CreatedAt < twoWeeks); await Context.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false); Context.Message.DeleteAfter(3); @@ -428,45 +429,5 @@ namespace NadekoBot.Modules.Administration } await ReplyConfirmLocalized("donadd", don.Amount).ConfigureAwait(false); } - - //[NadekoCommand, Usage, Description, Aliases] - //[RequireContext(ContextType.Guild)] - //public async Task Timezones(int page = 1) - //{ - // page -= 1; - - // if (page < 0 || page > 20) - // return; - - // var timezones = TimeZoneInfo.GetSystemTimeZones(); - // var timezonesPerPage = 20; - - // await Context.Channel.SendPaginatedConfirmAsync(page + 1, (curPage) => new EmbedBuilder() - // .WithOkColor() - // .WithTitle("Available Timezones") - // .WithDescription(string.Join("\n", timezones.Skip((curPage - 1) * timezonesPerPage).Take(timezonesPerPage).Select(x => $"`{x.Id,-25}` UTC{x.BaseUtcOffset:hhmm}"))), - // timezones.Count / timezonesPerPage); - //} - - //[NadekoCommand, Usage, Description, Aliases] - //[RequireContext(ContextType.Guild)] - //public async Task Timezone([Remainder] string id) - //{ - // TimeZoneInfo tz; - // try - // { - // tz = TimeZoneInfo.FindSystemTimeZoneById(id); - // if (tz != null) - // await Context.Channel.SendConfirmAsync(tz.ToString()).ConfigureAwait(false); - // } - // catch (Exception ex) - // { - // tz = null; - // _log.Warn(ex); - // } - - // if (tz == null) - // await Context.Channel.SendErrorAsync("Timezone not found. You should specify one of the timezones listed in the 'timezones' command.").ConfigureAwait(false); - //} } } \ No newline at end of file diff --git a/src/NadekoBot/Modules/Administration/Commands/TimeZoneCommands.cs b/src/NadekoBot/Modules/Administration/Commands/TimeZoneCommands.cs new file mode 100644 index 00000000..dcfafd43 --- /dev/null +++ b/src/NadekoBot/Modules/Administration/Commands/TimeZoneCommands.cs @@ -0,0 +1,69 @@ +using Discord; +using Discord.Commands; +using Discord.WebSocket; +using NadekoBot.Attributes; +using NadekoBot.Extensions; +using NadekoBot.Services.Administration; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace NadekoBot.Modules.Administration +{ + public partial class Administration + { + [Group] + public class TimeZoneCommands : NadekoSubmodule + { + private readonly GuildTimezoneService _service; + + public TimeZoneCommands(GuildTimezoneService service) + { + _service = service; + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task Timezones(int page = 1) + { + page -= 1; + + if (page < 0 || page > 20) + return; + + var timezones = TimeZoneInfo.GetSystemTimeZones(); + var timezonesPerPage = 20; + + await Context.Channel.SendPaginatedConfirmAsync((DiscordShardedClient)Context.Client, page + 1, (curPage) => new EmbedBuilder() + .WithOkColor() + .WithTitle("Available Timezones") + .WithDescription(string.Join("\n", timezones.Skip((curPage - 1) * timezonesPerPage).Take(timezonesPerPage).Select(x => $"`{x.Id,-25}` UTC{x.BaseUtcOffset:hhmm}"))), + timezones.Count / timezonesPerPage); + } + + [NadekoCommand, Usage, Description, Aliases] + [RequireContext(ContextType.Guild)] + public async Task Timezone([Remainder] string id = null) + { + if (string.IsNullOrWhiteSpace(id)) + { + await ReplyConfirmLocalized("timezone_guild", _service.GetTimeZoneOrUtc(Context.Guild.Id)).ConfigureAwait(false); + return; + } + + TimeZoneInfo tz; + try { tz = TimeZoneInfo.FindSystemTimeZoneById(id); } catch { tz = null; } + + _service.SetTimeZone(Context.Guild.Id, tz); + + if (tz == null) + { + await Context.Channel.SendErrorAsync("Timezone not found. You should specify one of the timezones listed in the 'timezones' command.").ConfigureAwait(false); + return; + } + + await Context.Channel.SendConfirmAsync(tz.ToString()).ConfigureAwait(false); + } + } + } +} diff --git a/src/NadekoBot/Modules/Searches/Commands/LoLCommands.cs b/src/NadekoBot/Modules/Searches/Commands/LoLCommands.cs index 9730284a..589eecaf 100644 --- a/src/NadekoBot/Modules/Searches/Commands/LoLCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/LoLCommands.cs @@ -83,7 +83,7 @@ namespace NadekoBot.Modules.Searches // try // { // CachedChampionImages = CachedChampionImages -// .Where(kvp => DateTime.Now - kvp.Value.AddedAt > new TimeSpan(1, 0, 0)) +// .Where(kvp => DateTime.UtcNow - kvp.Value.AddedAt > new TimeSpan(1, 0, 0)) // .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); // } // catch { } @@ -303,7 +303,7 @@ namespace NadekoBot.Modules.Searches // smallImgSize)); // } // } -// var cachedChamp = new CachedChampion { AddedAt = DateTime.Now, ImageStream = img.ToStream(System.Drawing.Imaging.ImageFormat.Png), Name = name.ToLower() + "_" + resolvedRole }; +// var cachedChamp = new CachedChampion { AddedAt = DateTime.UtcNow, ImageStream = img.ToStream(System.Drawing.Imaging.ImageFormat.Png), Name = name.ToLower() + "_" + resolvedRole }; // CachedChampionImages.Add(cachedChamp.Name, cachedChamp); // await e.Channel.SendFile(data["title"] + "_stats.png", cachedChamp.ImageStream).ConfigureAwait(false); // } diff --git a/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs b/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs index fe2781ac..41c4a162 100644 --- a/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs +++ b/src/NadekoBot/Modules/Utility/Commands/MessageRepeater.cs @@ -148,6 +148,56 @@ namespace NadekoBot.Modules.Utility Format.Bold(rep.Repeater.Interval.Minutes.ToString()))).ConfigureAwait(false); } + //[NadekoCommand, Usage, Description, Aliases] + //[RequireContext(ContextType.Guild)] + //[RequireUserPermission(GuildPermission.ManageMessages)] + //[Priority(1)] + //public async Task Repeat(GuildTime gt, int minutes, [Remainder] string message) + //{ + // if (!_service.RepeaterReady) + // return; + // if (minutes < 1 || minutes > 10080) + // return; + + // if (string.IsNullOrWhiteSpace(message)) + // return; + + // var toAdd = new GuildRepeater() + // { + // ChannelId = Context.Channel.Id, + // GuildId = Context.Guild.Id, + // Interval = TimeSpan.FromMinutes(minutes), + // StartTimeOfDay = gt.BotTime, + // Message = message + // }; + + // using (var uow = _db.UnitOfWork) + // { + // var gc = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(x => x.GuildRepeaters)); + + // if (gc.GuildRepeaters.Count >= 5) + // return; + // gc.GuildRepeaters.Add(toAdd); + + // await uow.CompleteAsync().ConfigureAwait(false); + // } + + // var rep = new RepeatRunner(_client, toAdd, (ITextChannel)Context.Channel); + + // _service.Repeaters.AddOrUpdate(Context.Guild.Id, new ConcurrentQueue(new[] { rep }), (key, old) => + // { + // old.Enqueue(rep); + // return old; + // }); + + // await Context.Channel.SendConfirmAsync( + // "🔁 " + GetText("repeater", + // Format.Bold(((IGuildUser)Context.User).GuildPermissions.MentionEveryone ? rep.Repeater.Message : rep.Repeater.Message.SanitizeMentions()), + // Format.Bold(rep.Repeater.Interval.Days.ToString()), + // Format.Bold(rep.Repeater.Interval.Hours.ToString()), + // Format.Bold(rep.Repeater.Interval.Minutes.ToString()))).ConfigureAwait(false); + //} + [NadekoCommand, Usage, Description, Aliases] [RequireContext(ContextType.Guild)] [RequireUserPermission(GuildPermission.ManageMessages)] diff --git a/src/NadekoBot/Modules/Utility/Commands/Remind.cs b/src/NadekoBot/Modules/Utility/Commands/Remind.cs index f8907d17..448ec424 100644 --- a/src/NadekoBot/Modules/Utility/Commands/Remind.cs +++ b/src/NadekoBot/Modules/Utility/Commands/Remind.cs @@ -96,7 +96,7 @@ namespace NadekoBot.Modules.Utility namesAndValues[groupName] = value; output += m.Groups[groupName].Value + " " + groupName + " "; } - var time = DateTime.Now + new TimeSpan(30 * namesAndValues["months"] + + var time = DateTime.UtcNow + new TimeSpan(30 * namesAndValues["months"] + 7 * namesAndValues["weeks"] + namesAndValues["days"], namesAndValues["hours"], diff --git a/src/NadekoBot/NadekoBot.cs b/src/NadekoBot/NadekoBot.cs index b6730c04..51b57418 100644 --- a/src/NadekoBot/NadekoBot.cs +++ b/src/NadekoBot/NadekoBot.cs @@ -120,7 +120,7 @@ namespace NadekoBot #region utility var crossServerTextService = new CrossServerTextService(AllGuildConfigs, Client); var remindService = new RemindService(Client, BotConfig, Db); - var repeaterService = new MessageRepeaterService(Client, AllGuildConfigs); + var repeaterService = new MessageRepeaterService(this, Client, AllGuildConfigs); var converterService = new ConverterService(Db); var commandMapService = new CommandMapService(AllGuildConfigs); var patreonRewardsService = new PatreonRewardsService(Credentials, Db, Currency); @@ -164,6 +164,7 @@ namespace NadekoBot var gameVcService = new GameVoiceChannelService(Client, Db, AllGuildConfigs); var autoAssignRoleService = new AutoAssignRoleService(Client, AllGuildConfigs); var logCommandService = new LogCommandService(Client, Strings, AllGuildConfigs, Db, muteService, protectionService); + var guildTimezoneService = new GuildTimezoneService(AllGuildConfigs, Db); #endregion #region pokemon @@ -215,6 +216,7 @@ namespace NadekoBot .Add(autoAssignRoleService) .Add(protectionService) .Add(logCommandService) + .Add(guildTimezoneService) .Add(permissionsService) .Add(blacklistService) .Add(cmdcdsService) @@ -232,6 +234,7 @@ namespace NadekoBot CommandService.AddTypeReader(new ModuleTypeReader(CommandService)); CommandService.AddTypeReader(new ModuleOrCrTypeReader(CommandService)); CommandService.AddTypeReader(new GuildTypeReader(Client)); + CommandService.AddTypeReader(new GuildTypeReader(Client)); } private async Task LoginAsync(string token) diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index ac37ab05..e45c5360 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -1632,10 +1632,10 @@ songremove srm - + Remove a song by its # in the queue, or 'all' to remove all songs from the queue. - + `{0}srm 5` diff --git a/src/NadekoBot/Services/Administration/GuildTimezoneService.cs b/src/NadekoBot/Services/Administration/GuildTimezoneService.cs new file mode 100644 index 00000000..1d469211 --- /dev/null +++ b/src/NadekoBot/Services/Administration/GuildTimezoneService.cs @@ -0,0 +1,65 @@ +using NadekoBot.Extensions; +using NadekoBot.Services.Database.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Collections.Concurrent; +using NadekoBot.Services; + +namespace NadekoBot.Services.Administration +{ + public class GuildTimezoneService + { + private ConcurrentDictionary _timezones; + private readonly DbService _db; + + public GuildTimezoneService(IEnumerable gcs, DbService db) + { + _timezones = gcs + .Select(x => + { + TimeZoneInfo tz; + try + { + tz = TimeZoneInfo.FindSystemTimeZoneById(x.TimeZoneId); + } + catch + { + tz = null; + } + return (x.GuildId, tz); + }) + .Where(x => x.Item2 != null) + .ToDictionary(x => x.Item1, x => x.Item2) + .ToConcurrent(); + + _db = db; + } + + public TimeZoneInfo GetTimeZoneOrDefault(ulong guildId) + { + if (_timezones.TryGetValue(guildId, out var tz)) + return tz; + return null; + } + + public void SetTimeZone(ulong guildId, TimeZoneInfo tz) + { + using (var uow = _db.UnitOfWork) + { + var gc = uow.GuildConfigs.For(guildId, set => set); + + gc.TimeZoneId = tz?.Id; + uow.Complete(); + + if (tz == null) + _timezones.TryRemove(guildId, out tz); + else + _timezones.AddOrUpdate(guildId, tz, (key, old) => tz); + } + } + + public TimeZoneInfo GetTimeZoneOrUtc(ulong guildId) + => GetTimeZoneOrDefault(guildId) ?? TimeZoneInfo.Utc; + } +} diff --git a/src/NadekoBot/Services/Administration/LogCommandService.cs b/src/NadekoBot/Services/Administration/LogCommandService.cs index b14dcee5..51871987 100644 --- a/src/NadekoBot/Services/Administration/LogCommandService.cs +++ b/src/NadekoBot/Services/Administration/LogCommandService.cs @@ -19,8 +19,8 @@ namespace NadekoBot.Services.Administration private readonly DiscordShardedClient _client; private readonly Logger _log; - private string PrettyCurrentTime => $"【{DateTime.Now:HH:mm:ss}】"; - private string CurrentTime => $"{DateTime.Now:HH:mm:ss}"; + private string PrettyCurrentTime => $"【{DateTime.UtcNow:HH:mm:ss}】"; + private string CurrentTime => $"{DateTime.UtcNow:HH:mm:ss}"; public ConcurrentDictionary GuildLogSettings { get; } diff --git a/src/NadekoBot/Services/Database/Models/Repeater.cs b/src/NadekoBot/Services/Database/Models/Repeater.cs index f8c07bfe..6e1acb6e 100644 --- a/src/NadekoBot/Services/Database/Models/Repeater.cs +++ b/src/NadekoBot/Services/Database/Models/Repeater.cs @@ -8,6 +8,7 @@ namespace NadekoBot.Services.Database.Models public ulong ChannelId { get; set; } public string Message { get; set; } public TimeSpan Interval { get; set; } + //public TimeSpan? StartTimeOfDay { get; set; } } public class GuildRepeater : Repeater diff --git a/src/NadekoBot/Services/Games/GamesService.cs b/src/NadekoBot/Services/Games/GamesService.cs index 213ede37..d4054526 100644 --- a/src/NadekoBot/Services/Games/GamesService.cs +++ b/src/NadekoBot/Services/Games/GamesService.cs @@ -118,11 +118,11 @@ namespace NadekoBot.Services.Games var lastGeneration = LastGenerations.GetOrAdd(channel.Id, DateTime.MinValue); var rng = new NadekoRandom(); - if (DateTime.Now - TimeSpan.FromSeconds(_bc.CurrencyGenerationCooldown) < lastGeneration) //recently generated in this channel, don't generate again + if (DateTime.UtcNow - TimeSpan.FromSeconds(_bc.CurrencyGenerationCooldown) < lastGeneration) //recently generated in this channel, don't generate again return; var num = rng.Next(1, 101) + _bc.CurrencyGenerationChance * 100; - if (num > 100 && LastGenerations.TryUpdate(channel.Id, DateTime.Now, lastGeneration)) + if (num > 100 && LastGenerations.TryUpdate(channel.Id, DateTime.UtcNow, lastGeneration)) { var dropAmount = _bc.CurrencyDropAmount; diff --git a/src/NadekoBot/Services/Impl/StatsService.cs b/src/NadekoBot/Services/Impl/StatsService.cs index 60d7b39c..5daf7668 100644 --- a/src/NadekoBot/Services/Impl/StatsService.cs +++ b/src/NadekoBot/Services/Impl/StatsService.cs @@ -41,7 +41,7 @@ namespace NadekoBot.Services.Impl _client = client; _creds = creds; - _started = DateTime.Now; + _started = DateTime.UtcNow; _client.MessageReceived += _ => Task.FromResult(Interlocked.Increment(ref _messageCounter)); cmdHandler.CommandExecuted += (_, e) => Task.FromResult(Interlocked.Increment(ref _commandsRan)); @@ -166,7 +166,7 @@ Messages: {MessageCounter} [{MessagesPerSecond:F2}/sec] Heap: [{Heap} MB]"); } public TimeSpan GetUptime() => - DateTime.Now - _started; + DateTime.UtcNow - _started; public string GetUptimeString(string separator = ", ") { diff --git a/src/NadekoBot/Services/Music/Song.cs b/src/NadekoBot/Services/Music/Song.cs index 1aa9aec4..187b3b6e 100644 --- a/src/NadekoBot/Services/Music/Song.cs +++ b/src/NadekoBot/Services/Music/Song.cs @@ -144,7 +144,7 @@ namespace NadekoBot.Services.Music public async Task Play(IAudioClient voiceClient, CancellationToken cancelToken) { BytesSent = (ulong) SkipTo * 3840 * 50; - var filename = Path.Combine(MusicService.MusicDataPath, DateTime.Now.UnixTimestamp().ToString()); + var filename = Path.Combine(MusicService.MusicDataPath, DateTime.UtcNow.UnixTimestamp().ToString()); var inStream = new SongBuffer(MusicPlayer, filename, SongInfo, SkipTo, _frameBytes * 100); var bufferTask = inStream.BufferSong(cancelToken).ConfigureAwait(false); diff --git a/src/NadekoBot/Services/Utility/MessageRepeaterService.cs b/src/NadekoBot/Services/Utility/MessageRepeaterService.cs index 5ca40d1c..9966969b 100644 --- a/src/NadekoBot/Services/Utility/MessageRepeaterService.cs +++ b/src/NadekoBot/Services/Utility/MessageRepeaterService.cs @@ -15,15 +15,14 @@ namespace NadekoBot.Services.Utility public ConcurrentDictionary> Repeaters { get; set; } public bool RepeaterReady { get; private set; } - public MessageRepeaterService(DiscordShardedClient client, IEnumerable gcs) + public MessageRepeaterService(NadekoBot bot, DiscordShardedClient client, IEnumerable gcs) { + System.Console.WriteLine(bot.Ready); var _ = Task.Run(async () => { -#if !GLOBAL_NADEKO - await Task.Delay(5000).ConfigureAwait(false); -#else - await Task.Delay(30000).ConfigureAwait(false); -#endif + while (!bot.Ready) + await Task.Delay(1000); + Repeaters = new ConcurrentDictionary>(gcs .ToDictionary(gc => gc.GuildId, gc => new ConcurrentQueue(gc.GuildRepeaters diff --git a/src/NadekoBot/Services/Utility/RemindService.cs b/src/NadekoBot/Services/Utility/RemindService.cs index 9fad924b..a6dd276b 100644 --- a/src/NadekoBot/Services/Utility/RemindService.cs +++ b/src/NadekoBot/Services/Utility/RemindService.cs @@ -58,7 +58,7 @@ namespace NadekoBot.Services.Utility public async Task StartReminder(Reminder r) { var t = cancelAllToken; - var now = DateTime.Now; + var now = DateTime.UtcNow; var time = r.When - now; diff --git a/src/NadekoBot/Services/Utility/RepeatRunner.cs b/src/NadekoBot/Services/Utility/RepeatRunner.cs index e1b42aea..ecbfb3ec 100644 --- a/src/NadekoBot/Services/Utility/RepeatRunner.cs +++ b/src/NadekoBot/Services/Utility/RepeatRunner.cs @@ -14,12 +14,11 @@ namespace NadekoBot.Services.Utility { private readonly Logger _log; - private CancellationTokenSource source { get; set; } - private CancellationToken token { get; set; } public Repeater Repeater { get; } public SocketGuild Guild { get; } public ITextChannel Channel { get; private set; } private IUserMessage oldMsg = null; + private Timer _t; public RepeatRunner(DiscordShardedClient client, Repeater repeater, ITextChannel channel = null) { @@ -30,25 +29,24 @@ namespace NadekoBot.Services.Utility //todo 40 @.@ fix all of this Guild = client.GetGuild(repeater.GuildId); if (Guild != null) - Task.Run(Run); + Run(); } - private async Task Run() + private void Run() { - source = new CancellationTokenSource(); - token = source.Token; - try - { - while (!token.IsCancellationRequested) - { - await Task.Delay(Repeater.Interval, token).ConfigureAwait(false); + TimeSpan initialInterval = Repeater.Interval; - await Trigger().ConfigureAwait(false); - } - } - catch (OperationCanceledException) - { - } + //if (Repeater.StartTimeOfDay != null) + //{ + // if ((initialInterval = Repeater.StartTimeOfDay.Value - DateTime.UtcNow.TimeOfDay) < TimeSpan.Zero) + // initialInterval += TimeSpan.FromDays(1); + //} + + _t = new Timer(async (_) => { + + try { await Trigger().ConfigureAwait(false); } catch { } + + }, null, initialInterval, Repeater.Interval); } public async Task Trigger() @@ -93,13 +91,13 @@ namespace NadekoBot.Services.Utility public void Reset() { - source.Cancel(); - var _ = Task.Run(Run); + Stop(); + Run(); } public void Stop() { - source.Cancel(); + _t.Change(Timeout.Infinite, Timeout.Infinite); } public override string ToString() =>