Skip to content

Instantly share code, notes, and snippets.

@nathan130200
Created December 29, 2019 11:58
Show Gist options
  • Save nathan130200/f321d79f5107cb6a94fcbb517634be76 to your computer and use it in GitHub Desktop.
Save nathan130200/f321d79f5107cb6a94fcbb517634be76 to your computer and use it in GitHub Desktop.
DSharpPlus: command cooldown visualizer using simple message update loop.
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DSharpPlus;
using DSharpPlus.CommandsNext;
using DSharpPlus.CommandsNext.Attributes;
using System.Threading;
using DSharpPlus.Entities;
using Hexae.Extensions;
namespace Hexae.Entities
{
public class CooldownVisualizer
{
static ConcurrentDictionary<string, CooldownVisualizer> _cache = new ConcurrentDictionary<string, CooldownVisualizer>();
public static async Task CreateOrUpdateAsync(CommandContext ctx, CooldownAttribute attribute)
{
var bucket = attribute.GetBucket(ctx)?.BucketId;
if (_cache.TryGetValue(bucket, out var visualizer))
await visualizer.ShutdownAsync();
visualizer = new CooldownVisualizer(ctx, attribute);
_cache.AddOrUpdate(bucket, visualizer, (key, old) => visualizer);
await visualizer.InitializeAsync();
}
private CommandContext _context;
private CooldownAttribute _attribute;
private CancellationTokenSource _cts;
private DiscordMessage _state;
private volatile bool _disposed;
public CooldownVisualizer(CommandContext context, CooldownAttribute attribute)
{
_context = context;
_attribute = attribute;
_cts = new CancellationTokenSource();
_disposed = false;
}
public TimeSpan GetRemaingTime()
=> _attribute.GetRemainingCooldown(_context);
public string GetRemaingTimeString()
{
var ts = this.GetRemaingTime();
var res = string.Empty;
if (ts.TotalHours >= 1)
res += ts.Hours + "h ";
if (ts.TotalMinutes >= 1)
res += ts.Minutes + "m ";
if (ts.TotalSeconds >= 1)
res += ts.Seconds + "s ";
if (ts.TotalMilliseconds >= 1 && ts.TotalSeconds <= 0)
res += ts.Milliseconds + "ms ";
return res.TrimEnd(' ');
}
public Task InitializeAsync()
{
if (_disposed)
return Task.CompletedTask;
_ = Task.Factory.StartNew(LoopAsync, _cts.Token, TaskCreationOptions.LongRunning);
return Task.CompletedTask;
}
async Task LoopAsync(object _)
{
var fnBuildEmbed = new Func<DiscordEmbedBuilder>(() => new DiscordEmbedBuilder()
.WithColor(DiscordColor.Red)
.WithDescription($"Você está ainda em cooldown: `{this.GetRemaingTimeString()}`")
.WithRequestedBy(_context.User));
_state = await _context.RespondAsync(embed: fnBuildEmbed());
while (!_disposed)
{
_state = await _state.ModifyAsync(embed: fnBuildEmbed().Build());
if (this.GetRemaingTime().TotalMilliseconds <= 500)
break;
await Task.Delay(3000);
}
await ShutdownAsync();
}
public Task ShutdownAsync()
{
if (_disposed)
return Task.CompletedTask;
_disposed = true;
if(!_cts.IsCancellationRequested)
_cts.Cancel();
if (_state != null)
_ = Task.Run(async () => await _state.DeleteAsync());
return Task.CompletedTask;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment