mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 17:28:27 -04:00
- 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:
@@ -441,9 +441,7 @@ namespace NadekoBot.Coordinator
|
|||||||
}
|
}
|
||||||
|
|
||||||
public string GetConfigText()
|
public string GetConfigText()
|
||||||
{
|
=> File.ReadAllText(CONFIG_PATH);
|
||||||
return File.ReadAllText(CONFIG_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetConfigText(string text)
|
public void SetConfigText(string text)
|
||||||
{
|
{
|
||||||
|
@@ -77,7 +77,7 @@ note: This setting is primarily used if you're afraid of raids, or you're runnin
|
|||||||
public bool GroupGreets { get; set; }
|
public bool GroupGreets { get; set; }
|
||||||
|
|
||||||
[Comment(@"Whether the bot will rotate through all specified statuses.
|
[Comment(@"Whether the bot will rotate through all specified statuses.
|
||||||
This setting can be changed via .rots command.
|
This setting can be changed via .ropl command.
|
||||||
See RotatingStatuses submodule in Administration.")]
|
See RotatingStatuses submodule in Administration.")]
|
||||||
public bool RotateStatuses { get; set; }
|
public bool RotateStatuses { get; set; }
|
||||||
|
|
||||||
|
@@ -16,7 +16,7 @@ public class MuteService : INService
|
|||||||
{
|
{
|
||||||
public enum TimerType { Mute, Ban, AddRole }
|
public enum TimerType { Mute, Ban, AddRole }
|
||||||
|
|
||||||
private static readonly OverwritePermissions denyOverwrite = new(addReactions: PermValue.Deny,
|
private static readonly OverwritePermissions _denyOverwrite = new(addReactions: PermValue.Deny,
|
||||||
sendMessages: PermValue.Deny,
|
sendMessages: PermValue.Deny,
|
||||||
attachFiles: PermValue.Deny);
|
attachFiles: PermValue.Deny);
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ public class MuteService : INService
|
|||||||
public ConcurrentDictionary<ulong, string> GuildMuteRoles { get; }
|
public ConcurrentDictionary<ulong, string> GuildMuteRoles { get; }
|
||||||
public ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> MutedUsers { get; }
|
public ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> MutedUsers { get; }
|
||||||
|
|
||||||
public ConcurrentDictionary<ulong, ConcurrentDictionary<(ulong, TimerType), Timer>> Un_Timers { get; } = new();
|
public ConcurrentDictionary<ulong, ConcurrentDictionary<(ulong, TimerType), Timer>> UnTimers { get; } = new();
|
||||||
|
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
@@ -312,7 +312,7 @@ public class MuteService : INService
|
|||||||
if (!toOverwrite.PermissionOverwrites.Any(x => x.TargetId == muteRole.Id
|
if (!toOverwrite.PermissionOverwrites.Any(x => x.TargetId == muteRole.Id
|
||||||
&& x.TargetType == PermissionTarget.Role))
|
&& x.TargetType == PermissionTarget.Role))
|
||||||
{
|
{
|
||||||
await toOverwrite.AddPermissionOverwriteAsync(muteRole, denyOverwrite);
|
await toOverwrite.AddPermissionOverwriteAsync(muteRole, _denyOverwrite);
|
||||||
|
|
||||||
await Task.Delay(200);
|
await Task.Delay(200);
|
||||||
}
|
}
|
||||||
@@ -394,12 +394,13 @@ public class MuteService : INService
|
|||||||
ulong? roleId = null)
|
ulong? roleId = null)
|
||||||
{
|
{
|
||||||
//load the unmute timers for this guild
|
//load the unmute timers for this guild
|
||||||
var userUnTimers = Un_Timers.GetOrAdd(guildId, new ConcurrentDictionary<(ulong, TimerType), Timer>());
|
var userUnTimers = UnTimers.GetOrAdd(guildId, new ConcurrentDictionary<(ulong, TimerType), Timer>());
|
||||||
|
|
||||||
//unmute timer to be added
|
//unmute timer to be added
|
||||||
var toAdd = new Timer(async _ =>
|
var toAdd = new Timer(async _ =>
|
||||||
{
|
{
|
||||||
if (type == TimerType.Ban)
|
if (type == TimerType.Ban)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RemoveTimerFromDb(guildId, userId, type);
|
RemoveTimerFromDb(guildId, userId, type);
|
||||||
@@ -409,24 +410,28 @@ public class MuteService : INService
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Warning(ex, "Couldn't unban user {0} in guild {1}", userId, guildId);
|
Log.Warning(ex, "Couldn't unban user {UserId} in guild {GuildId}", userId, guildId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (type == TimerType.AddRole)
|
else if (type == TimerType.AddRole)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RemoveTimerFromDb(guildId, userId, type);
|
RemoveTimerFromDb(guildId, userId, type);
|
||||||
StopTimer(guildId, userId, type);
|
StopTimer(guildId, userId, type);
|
||||||
var guild = _client.GetGuild(guildId);
|
var guild = _client.GetGuild(guildId);
|
||||||
var user = guild?.GetUser(userId);
|
var user = guild?.GetUser(userId);
|
||||||
var role = guild.GetRole(roleId.Value);
|
var role = guild?.GetRole(roleId.Value);
|
||||||
if (guild is not null && user is not null && user.Roles.Contains(role))
|
if (guild is not null && user is not null && user.Roles.Contains(role))
|
||||||
await user.RemoveRoleAsync(role);
|
await user.RemoveRoleAsync(role);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Warning(ex, "Couldn't remove role from user {0} in guild {1}", userId, guildId);
|
Log.Warning(ex, "Couldn't remove role from user {UserId} in guild {GuildId}", userId, guildId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// unmute the user, this will also remove the timer from the db
|
// unmute the user, this will also remove the timer from the db
|
||||||
@@ -435,8 +440,9 @@ public class MuteService : INService
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
RemoveTimerFromDb(guildId, userId, type); // if unmute errored, just remove unmute from db
|
RemoveTimerFromDb(guildId, userId, type); // if unmute errored, just remove unmute from db
|
||||||
Log.Warning(ex, "Couldn't unmute user {0} in guild {1}", userId, guildId);
|
Log.Warning(ex, "Couldn't unmute user {UserId} in guild {GuildId}", userId, guildId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
after,
|
after,
|
||||||
@@ -454,7 +460,7 @@ public class MuteService : INService
|
|||||||
|
|
||||||
public void StopTimer(ulong guildId, ulong userId, TimerType type)
|
public void StopTimer(ulong guildId, ulong userId, TimerType type)
|
||||||
{
|
{
|
||||||
if (!Un_Timers.TryGetValue(guildId, out var userTimer))
|
if (!UnTimers.TryGetValue(guildId, out var userTimer))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (userTimer.TryRemove((userId, type), out var removed)) removed.Change(Timeout.Infinite, Timeout.Infinite);
|
if (userTimer.TryRemove((userId, type), out var removed)) removed.Change(Timeout.Infinite, Timeout.Infinite);
|
||||||
|
@@ -37,7 +37,8 @@ public sealed class PlayingRotateService : INService, IReadyExecutor
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!_bss.Data.RotateStatuses) return;
|
if (!_bss.Data.RotateStatuses)
|
||||||
|
continue;
|
||||||
|
|
||||||
IReadOnlyList<RotatingPlayingStatus> rotatingStatuses;
|
IReadOnlyList<RotatingPlayingStatus> rotatingStatuses;
|
||||||
await using (var uow = _db.GetDbContext())
|
await using (var uow = _db.GetDbContext())
|
||||||
@@ -46,7 +47,7 @@ public sealed class PlayingRotateService : INService, IReadyExecutor
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rotatingStatuses.Count == 0)
|
if (rotatingStatuses.Count == 0)
|
||||||
return;
|
continue;
|
||||||
|
|
||||||
var playingStatus = index >= rotatingStatuses.Count
|
var playingStatus = index >= rotatingStatuses.Count
|
||||||
? rotatingStatuses[index = 0]
|
? rotatingStatuses[index = 0]
|
||||||
|
@@ -243,8 +243,8 @@ public partial class Administration
|
|||||||
|
|
||||||
var allShardStrings = statuses.Select(st =>
|
var allShardStrings = statuses.Select(st =>
|
||||||
{
|
{
|
||||||
var stateStr = ConnectionStateToEmoji(st);
|
|
||||||
var timeDiff = DateTime.UtcNow - st.LastUpdate;
|
var timeDiff = DateTime.UtcNow - st.LastUpdate;
|
||||||
|
var stateStr = ConnectionStateToEmoji(st);
|
||||||
var maxGuildCountLength =
|
var maxGuildCountLength =
|
||||||
statuses.Max(x => x.GuildCount).ToString().Length;
|
statuses.Max(x => x.GuildCount).ToString().Length;
|
||||||
return $"`{stateStr} "
|
return $"`{stateStr} "
|
||||||
@@ -272,9 +272,9 @@ public partial class Administration
|
|||||||
var timeDiff = DateTime.UtcNow - status.LastUpdate;
|
var timeDiff = DateTime.UtcNow - status.LastUpdate;
|
||||||
return status.ConnectionState switch
|
return status.ConnectionState switch
|
||||||
{
|
{
|
||||||
ConnectionState.Connected => "✅",
|
|
||||||
ConnectionState.Disconnected => "🔻",
|
ConnectionState.Disconnected => "🔻",
|
||||||
_ when timeDiff > TimeSpan.FromSeconds(30) => " ❗ ",
|
_ when timeDiff > TimeSpan.FromSeconds(30) => " ❗ ",
|
||||||
|
ConnectionState.Connected => "✅",
|
||||||
_ => " ⏳"
|
_ => " ⏳"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using NadekoBot.Common.ModuleBehaviors;
|
||||||
using NadekoBot.Db;
|
using NadekoBot.Db;
|
||||||
using NadekoBot.Modules.Administration.Services;
|
using NadekoBot.Modules.Administration.Services;
|
||||||
using NadekoBot.Services.Database.Models;
|
using NadekoBot.Services.Database.Models;
|
||||||
|
|
||||||
namespace NadekoBot.Modules.Administration;
|
namespace NadekoBot.Modules.Administration;
|
||||||
|
|
||||||
public sealed class LogCommandService : ILogCommandService
|
public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
||||||
{
|
{
|
||||||
public ConcurrentDictionary<ulong, LogSetting> GuildLogSettings { get; }
|
public ConcurrentDictionary<ulong, LogSetting> GuildLogSettings { get; }
|
||||||
|
|
||||||
private ConcurrentDictionary<ITextChannel, List<string>> PresenceUpdates { get; } = new();
|
private ConcurrentDictionary<ITextChannel, List<string>> PresenceUpdates { get; } = new();
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
|
|
||||||
private readonly Timer _timerReference;
|
|
||||||
private readonly IBotStrings _strings;
|
private readonly IBotStrings _strings;
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
private readonly MuteService _mute;
|
private readonly MuteService _mute;
|
||||||
@@ -58,11 +58,6 @@ public sealed class LogCommandService : ILogCommandService
|
|||||||
GuildLogSettings = configs.ToDictionary(ls => ls.GuildId).ToConcurrent();
|
GuildLogSettings = configs.ToDictionary(ls => ls.GuildId).ToConcurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
_timerReference = new(Callback,
|
|
||||||
null,
|
|
||||||
TimeSpan.FromSeconds(15),
|
|
||||||
TimeSpan.FromSeconds(15));
|
|
||||||
|
|
||||||
//_client.MessageReceived += _client_MessageReceived;
|
//_client.MessageReceived += _client_MessageReceived;
|
||||||
_client.MessageUpdated += _client_MessageUpdated;
|
_client.MessageUpdated += _client_MessageUpdated;
|
||||||
_client.MessageDeleted += _client_MessageDeleted;
|
_client.MessageDeleted += _client_MessageDeleted;
|
||||||
@@ -96,28 +91,34 @@ public sealed class LogCommandService : ILogCommandService
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Callback(object? state)
|
public async Task OnReadyAsync()
|
||||||
{
|
{
|
||||||
try
|
#if GLOBAL_NADEKO
|
||||||
|
var timer = new PeriodicTimer(TimeSpan.FromSeconds(15));
|
||||||
|
while (await timer.WaitForNextTickAsync())
|
||||||
{
|
{
|
||||||
var keys = PresenceUpdates.Keys.ToList();
|
try
|
||||||
|
{
|
||||||
await keys.Select(key =>
|
var keys = PresenceUpdates.Keys.ToList();
|
||||||
{
|
|
||||||
if (!((SocketGuild)key.Guild).CurrentUser.GetPermissions(key).SendMessages)
|
|
||||||
return Task.CompletedTask;
|
|
||||||
if (PresenceUpdates.TryRemove(key, out var msgs))
|
|
||||||
{
|
|
||||||
var title = GetText(key.Guild, strs.presence_updates);
|
|
||||||
var desc = string.Join(Environment.NewLine, msgs);
|
|
||||||
return key.SendConfirmAsync(_eb, title, desc.TrimTo(2048)!);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
await keys.Select(key =>
|
||||||
|
{
|
||||||
|
if (!((SocketGuild)key.Guild).CurrentUser.GetPermissions(key).SendMessages)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
})
|
if (PresenceUpdates.TryRemove(key, out var msgs))
|
||||||
.WhenAll();
|
{
|
||||||
|
var title = GetText(key.Guild, strs.presence_updates);
|
||||||
|
var desc = string.Join(Environment.NewLine, msgs);
|
||||||
|
return key.SendConfirmAsync(_eb, title, desc.TrimTo(2048)!);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
})
|
||||||
|
.WhenAll();
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
}
|
}
|
||||||
catch { }
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public LogSetting? GetGuildLogSettings(ulong guildId)
|
public LogSetting? GetGuildLogSettings(ulong guildId)
|
||||||
|
@@ -362,7 +362,7 @@ public partial class Help : NadekoModule<HelpService>
|
|||||||
ContentType = "application/json",
|
ContentType = "application/json",
|
||||||
ContentBody = uploadData,
|
ContentBody = uploadData,
|
||||||
// either use a path provided in the argument or the default one for public nadeko, other/cmds.json
|
// either use a path provided in the argument or the default one for public nadeko, other/cmds.json
|
||||||
Key = $"cmds/{StatsService.BotVersion}.json",
|
Key = $"cmds/{StatsService.BOT_VERSION}.json",
|
||||||
CannedACL = S3CannedACL.PublicRead
|
CannedACL = S3CannedACL.PublicRead
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -372,11 +372,11 @@ public partial class Help : NadekoModule<HelpService>
|
|||||||
var versionListString = Encoding.UTF8.GetString(ms.ToArray());
|
var versionListString = Encoding.UTF8.GetString(ms.ToArray());
|
||||||
|
|
||||||
var versionList = JsonSerializer.Deserialize<List<string>>(versionListString);
|
var versionList = JsonSerializer.Deserialize<List<string>>(versionListString);
|
||||||
if (versionList is not null && !versionList.Contains(StatsService.BotVersion))
|
if (versionList is not null && !versionList.Contains(StatsService.BOT_VERSION))
|
||||||
{
|
{
|
||||||
// save the file with new version added
|
// save the file with new version added
|
||||||
// versionList.Add(StatsService.BotVersion);
|
// versionList.Add(StatsService.BotVersion);
|
||||||
versionListString = JsonSerializer.Serialize(versionList.Prepend(StatsService.BotVersion),
|
versionListString = JsonSerializer.Serialize(versionList.Prepend(StatsService.BOT_VERSION),
|
||||||
new JsonSerializerOptions { WriteIndented = true });
|
new JsonSerializerOptions { WriteIndented = true });
|
||||||
|
|
||||||
// upload the updated version list
|
// upload the updated version list
|
||||||
@@ -395,7 +395,7 @@ public partial class Help : NadekoModule<HelpService>
|
|||||||
{
|
{
|
||||||
Log.Warning(
|
Log.Warning(
|
||||||
"Version {Version} already exists in the version file. " + "Did you forget to increment it?",
|
"Version {Version} already exists in the version file. " + "Did you forget to increment it?",
|
||||||
StatsService.BotVersion);
|
StatsService.BOT_VERSION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -253,7 +253,7 @@ public partial class Utility : NadekoModule
|
|||||||
|
|
||||||
await ctx.Channel.EmbedAsync(_eb.Create()
|
await ctx.Channel.EmbedAsync(_eb.Create()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor($"NadekoBot v{StatsService.BotVersion}",
|
.WithAuthor($"NadekoBot v{StatsService.BOT_VERSION}",
|
||||||
"https://nadeko-pictures.nyc3.digitaloceanspaces.com/other/avatar.png",
|
"https://nadeko-pictures.nyc3.digitaloceanspaces.com/other/avatar.png",
|
||||||
"https://nadekobot.readthedocs.io/en/latest/")
|
"https://nadekobot.readthedocs.io/en/latest/")
|
||||||
.AddField(GetText(strs.author), _stats.Author, true)
|
.AddField(GetText(strs.author), _stats.Author, true)
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
|
using Humanizer.Localisation;
|
||||||
using NadekoBot.Common.ModuleBehaviors;
|
using NadekoBot.Common.ModuleBehaviors;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
@@ -6,7 +7,7 @@ namespace NadekoBot.Services;
|
|||||||
|
|
||||||
public class StatsService : IStatsService, IReadyExecutor, INService, IDisposable
|
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
|
public string Author
|
||||||
=> "Kwoth#2452";
|
=> "Kwoth#2452";
|
||||||
@@ -18,28 +19,27 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
|
|||||||
=> MessageCounter / GetUptime().TotalSeconds;
|
=> MessageCounter / GetUptime().TotalSeconds;
|
||||||
|
|
||||||
public long TextChannels
|
public long TextChannels
|
||||||
=> Interlocked.Read(ref _textChannels);
|
=> Interlocked.Read(ref textChannels);
|
||||||
|
|
||||||
public long VoiceChannels
|
public long VoiceChannels
|
||||||
=> Interlocked.Read(ref _voiceChannels);
|
=> Interlocked.Read(ref voiceChannels);
|
||||||
|
|
||||||
public long MessageCounter
|
public long MessageCounter
|
||||||
=> Interlocked.Read(ref _messageCounter);
|
=> Interlocked.Read(ref messageCounter);
|
||||||
|
|
||||||
public long CommandsRan
|
public long CommandsRan
|
||||||
=> Interlocked.Read(ref _commandsRan);
|
=> Interlocked.Read(ref commandsRan);
|
||||||
|
|
||||||
private readonly Process _currentProcess = Process.GetCurrentProcess();
|
private readonly Process _currentProcess = Process.GetCurrentProcess();
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
private readonly IBotCredentials _creds;
|
private readonly IBotCredentials _creds;
|
||||||
private readonly DateTime _started;
|
private readonly DateTime _started;
|
||||||
|
|
||||||
private long _textChannels;
|
private long textChannels;
|
||||||
private long _voiceChannels;
|
private long voiceChannels;
|
||||||
private long _messageCounter;
|
private long messageCounter;
|
||||||
private long _commandsRan;
|
private long commandsRan;
|
||||||
|
|
||||||
private readonly Timer _botlistTimer;
|
|
||||||
private readonly IHttpClientFactory _httpFactory;
|
private readonly IHttpClientFactory _httpFactory;
|
||||||
|
|
||||||
public StatsService(
|
public StatsService(
|
||||||
@@ -53,17 +53,17 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
|
|||||||
_httpFactory = factory;
|
_httpFactory = factory;
|
||||||
|
|
||||||
_started = DateTime.UtcNow;
|
_started = DateTime.UtcNow;
|
||||||
_client.MessageReceived += _ => Task.FromResult(Interlocked.Increment(ref _messageCounter));
|
_client.MessageReceived += _ => Task.FromResult(Interlocked.Increment(ref messageCounter));
|
||||||
cmdHandler.CommandExecuted += (_, _) => Task.FromResult(Interlocked.Increment(ref _commandsRan));
|
cmdHandler.CommandExecuted += (_, _) => Task.FromResult(Interlocked.Increment(ref commandsRan));
|
||||||
|
|
||||||
_client.ChannelCreated += c =>
|
_client.ChannelCreated += c =>
|
||||||
{
|
{
|
||||||
var _ = Task.Run(() =>
|
var _ = Task.Run(() =>
|
||||||
{
|
{
|
||||||
if (c is ITextChannel)
|
if (c is ITextChannel)
|
||||||
Interlocked.Increment(ref _textChannels);
|
Interlocked.Increment(ref textChannels);
|
||||||
else if (c is IVoiceChannel)
|
else if (c is IVoiceChannel)
|
||||||
Interlocked.Increment(ref _voiceChannels);
|
Interlocked.Increment(ref voiceChannels);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@@ -74,9 +74,9 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
|
|||||||
var _ = Task.Run(() =>
|
var _ = Task.Run(() =>
|
||||||
{
|
{
|
||||||
if (c is ITextChannel)
|
if (c is ITextChannel)
|
||||||
Interlocked.Decrement(ref _textChannels);
|
Interlocked.Decrement(ref textChannels);
|
||||||
else if (c is IVoiceChannel)
|
else if (c is IVoiceChannel)
|
||||||
Interlocked.Decrement(ref _voiceChannels);
|
Interlocked.Decrement(ref voiceChannels);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@@ -88,8 +88,8 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
|
|||||||
{
|
{
|
||||||
var tc = g.Channels.Count(cx => cx is ITextChannel);
|
var tc = g.Channels.Count(cx => cx is ITextChannel);
|
||||||
var vc = g.Channels.Count - tc;
|
var vc = g.Channels.Count - tc;
|
||||||
Interlocked.Add(ref _textChannels, tc);
|
Interlocked.Add(ref textChannels, tc);
|
||||||
Interlocked.Add(ref _voiceChannels, vc);
|
Interlocked.Add(ref voiceChannels, vc);
|
||||||
});
|
});
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
};
|
};
|
||||||
@@ -100,8 +100,8 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
|
|||||||
{
|
{
|
||||||
var tc = g.Channels.Count(cx => cx is ITextChannel);
|
var tc = g.Channels.Count(cx => cx is ITextChannel);
|
||||||
var vc = g.Channels.Count - tc;
|
var vc = g.Channels.Count - tc;
|
||||||
Interlocked.Add(ref _textChannels, tc);
|
Interlocked.Add(ref textChannels, tc);
|
||||||
Interlocked.Add(ref _voiceChannels, vc);
|
Interlocked.Add(ref voiceChannels, vc);
|
||||||
});
|
});
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
};
|
};
|
||||||
@@ -112,8 +112,8 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
|
|||||||
{
|
{
|
||||||
var tc = g.Channels.Count(cx => cx is ITextChannel);
|
var tc = g.Channels.Count(cx => cx is ITextChannel);
|
||||||
var vc = g.Channels.Count - tc;
|
var vc = g.Channels.Count - tc;
|
||||||
Interlocked.Add(ref _textChannels, -tc);
|
Interlocked.Add(ref textChannels, -tc);
|
||||||
Interlocked.Add(ref _voiceChannels, -vc);
|
Interlocked.Add(ref voiceChannels, -vc);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@@ -125,60 +125,57 @@ public class StatsService : IStatsService, IReadyExecutor, INService, IDisposabl
|
|||||||
{
|
{
|
||||||
var tc = g.Channels.Count(cx => cx is ITextChannel);
|
var tc = g.Channels.Count(cx => cx is ITextChannel);
|
||||||
var vc = g.Channels.Count - tc;
|
var vc = g.Channels.Count - tc;
|
||||||
Interlocked.Add(ref _textChannels, -tc);
|
Interlocked.Add(ref textChannels, -tc);
|
||||||
Interlocked.Add(ref _voiceChannels, -vc);
|
Interlocked.Add(ref voiceChannels, -vc);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Task.CompletedTask;
|
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()
|
public TimeSpan GetUptime()
|
||||||
=> DateTime.UtcNow - _started;
|
=> DateTime.UtcNow - _started;
|
||||||
|
|
||||||
public string GetUptimeString(string separator = ", ")
|
public string GetUptimeString(string separator = ", ")
|
||||||
{
|
{
|
||||||
var time = GetUptime();
|
var time = GetUptime();
|
||||||
return $"{time.Days} days{separator}{time.Hours} hours{separator}{time.Minutes} minutes";
|
return time.Humanize(3, maxUnit: TimeUnit.Day, minUnit: TimeUnit.Minute);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double GetPrivateMemory()
|
public double GetPrivateMemory()
|
||||||
|
@@ -81,6 +81,6 @@ prefix: .
|
|||||||
# and (slightly) reduce the greet spam in those servers.
|
# and (slightly) reduce the greet spam in those servers.
|
||||||
groupGreets: false
|
groupGreets: false
|
||||||
# Whether the bot will rotate through all specified statuses.
|
# Whether the bot will rotate through all specified statuses.
|
||||||
# This setting can be changed via .rots command.
|
# This setting can be changed via .ropl command.
|
||||||
# See RotatingStatuses submodule in Administration.
|
# See RotatingStatuses submodule in Administration.
|
||||||
rotateStatuses: false
|
rotateStatuses: false
|
||||||
|
Reference in New Issue
Block a user