- Using PeriodicTimer in a few places instead of Timer

- Some small refactorings
- Fixed reference to non-existent command in bot.yml
This commit is contained in:
Kwoth
2022-01-05 08:00:25 +01:00
parent f13d7d2c80
commit 6c39044435
10 changed files with 114 additions and 111 deletions

View File

@@ -1,4 +1,5 @@
#nullable disable
using Humanizer.Localisation;
using NadekoBot.Common.ModuleBehaviors;
using System.Diagnostics;
@@ -6,7 +7,7 @@ namespace NadekoBot.Services;
public class StatsService : IStatsService, IReadyExecutor, INService, IDisposable
{
public const string BotVersion = "4.0.0";
public const string BOT_VERSION = "4.0.0";
public string Author
=> "Kwoth#2452";
@@ -18,28 +19,27 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
=> MessageCounter / GetUptime().TotalSeconds;
public long TextChannels
=> Interlocked.Read(ref _textChannels);
=> Interlocked.Read(ref textChannels);
public long VoiceChannels
=> Interlocked.Read(ref _voiceChannels);
=> Interlocked.Read(ref voiceChannels);
public long MessageCounter
=> Interlocked.Read(ref _messageCounter);
=> Interlocked.Read(ref messageCounter);
public long CommandsRan
=> Interlocked.Read(ref _commandsRan);
=> Interlocked.Read(ref commandsRan);
private readonly Process _currentProcess = Process.GetCurrentProcess();
private readonly DiscordSocketClient _client;
private readonly IBotCredentials _creds;
private readonly DateTime _started;
private long _textChannels;
private long _voiceChannels;
private long _messageCounter;
private long _commandsRan;
private long textChannels;
private long voiceChannels;
private long messageCounter;
private long commandsRan;
private readonly Timer _botlistTimer;
private readonly IHttpClientFactory _httpFactory;
public StatsService(
@@ -53,17 +53,17 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
_httpFactory = factory;
_started = DateTime.UtcNow;
_client.MessageReceived += _ => Task.FromResult(Interlocked.Increment(ref _messageCounter));
cmdHandler.CommandExecuted += (_, _) => Task.FromResult(Interlocked.Increment(ref _commandsRan));
_client.MessageReceived += _ => Task.FromResult(Interlocked.Increment(ref messageCounter));
cmdHandler.CommandExecuted += (_, _) => Task.FromResult(Interlocked.Increment(ref commandsRan));
_client.ChannelCreated += c =>
{
var _ = Task.Run(() =>
{
if (c is ITextChannel)
Interlocked.Increment(ref _textChannels);
Interlocked.Increment(ref textChannels);
else if (c is IVoiceChannel)
Interlocked.Increment(ref _voiceChannels);
Interlocked.Increment(ref voiceChannels);
});
return Task.CompletedTask;
@@ -74,9 +74,9 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
var _ = Task.Run(() =>
{
if (c is ITextChannel)
Interlocked.Decrement(ref _textChannels);
Interlocked.Decrement(ref textChannels);
else if (c is IVoiceChannel)
Interlocked.Decrement(ref _voiceChannels);
Interlocked.Decrement(ref voiceChannels);
});
return Task.CompletedTask;
@@ -88,8 +88,8 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
{
var tc = g.Channels.Count(cx => cx is ITextChannel);
var vc = g.Channels.Count - tc;
Interlocked.Add(ref _textChannels, tc);
Interlocked.Add(ref _voiceChannels, vc);
Interlocked.Add(ref textChannels, tc);
Interlocked.Add(ref voiceChannels, vc);
});
return Task.CompletedTask;
};
@@ -100,8 +100,8 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
{
var tc = g.Channels.Count(cx => cx is ITextChannel);
var vc = g.Channels.Count - tc;
Interlocked.Add(ref _textChannels, tc);
Interlocked.Add(ref _voiceChannels, vc);
Interlocked.Add(ref textChannels, tc);
Interlocked.Add(ref voiceChannels, vc);
});
return Task.CompletedTask;
};
@@ -112,8 +112,8 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
{
var tc = g.Channels.Count(cx => cx is ITextChannel);
var vc = g.Channels.Count - tc;
Interlocked.Add(ref _textChannels, -tc);
Interlocked.Add(ref _voiceChannels, -vc);
Interlocked.Add(ref textChannels, -tc);
Interlocked.Add(ref voiceChannels, -vc);
});
return Task.CompletedTask;
@@ -125,60 +125,57 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
{
var tc = g.Channels.Count(cx => cx is ITextChannel);
var vc = g.Channels.Count - tc;
Interlocked.Add(ref _textChannels, -tc);
Interlocked.Add(ref _voiceChannels, -vc);
Interlocked.Add(ref textChannels, -tc);
Interlocked.Add(ref voiceChannels, -vc);
});
return Task.CompletedTask;
};
_botlistTimer = new(async _ =>
{
if (string.IsNullOrWhiteSpace(_creds.BotListToken))
return;
try
{
using var http = _httpFactory.CreateClient();
using var content = new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "shard_count", _creds.TotalShards.ToString() },
{ "shard_id", client.ShardId.ToString() },
{ "server_count", client.Guilds.Count().ToString() }
});
content.Headers.Clear();
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
http.DefaultRequestHeaders.Add("Authorization", _creds.BotListToken);
using (await http.PostAsync(
new Uri($"https://discordbots.org/api/bots/{client.CurrentUser.Id}/stats"),
content)) { }
}
catch (Exception ex)
{
Log.Error(ex, "Error ");
// ignored
}
},
null,
TimeSpan.FromMinutes(5),
TimeSpan.FromHours(1));
}
public async Task OnReadyAsync()
{
var guilds = _client.Guilds;
textChannels = guilds.Sum(g => g.Channels.Count(cx => cx is ITextChannel));
voiceChannels = guilds.Sum(g => g.Channels.Count(cx => cx is IVoiceChannel));
var timer = new PeriodicTimer(TimeSpan.FromHours(1));
do
{
if (string.IsNullOrWhiteSpace(_creds.BotListToken))
continue;
try
{
using var http = _httpFactory.CreateClient();
using var content = new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "shard_count", _creds.TotalShards.ToString() },
{ "shard_id", _client.ShardId.ToString() },
{ "server_count", _client.Guilds.Count().ToString() }
});
content.Headers.Clear();
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
http.DefaultRequestHeaders.Add("Authorization", _creds.BotListToken);
using var res = await http.PostAsync(
new Uri($"https://discordbots.org/api/bots/{_client.CurrentUser.Id}/stats"),
content);
}
catch (Exception ex)
{
Log.Error(ex, "Error in botlist post");
}
} while (await timer.WaitForNextTickAsync());
}
public TimeSpan GetUptime()
=> DateTime.UtcNow - _started;
public string GetUptimeString(string separator = ", ")
{
var time = GetUptime();
return $"{time.Days} days{separator}{time.Hours} hours{separator}{time.Minutes} minutes";
}
public Task OnReadyAsync()
{
var guilds = _client.Guilds;
_textChannels = guilds.Sum(g => g.Channels.Count(cx => cx is ITextChannel));
_voiceChannels = guilds.Sum(g => g.Channels.Count(cx => cx is IVoiceChannel));
return Task.CompletedTask;
return time.Humanize(3, maxUnit: TimeUnit.Day, minUnit: TimeUnit.Minute);
}
public double GetPrivateMemory()