mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 01:38:27 -04:00
- .gvc should now properly trigger when a user is already in a gvc and changes his activity
- .gvc should now properly detect multiple activities - Rewrote repeat raw query bitshift to linqtodb query with division (thx kotz)
This commit is contained in:
@@ -41,7 +41,8 @@ public abstract record SmartText
|
|||||||
|
|
||||||
smartEmbedText.NormalizeFields();
|
smartEmbedText.NormalizeFields();
|
||||||
|
|
||||||
if (!smartEmbedText.IsValid) return new SmartPlainText(input);
|
if (!smartEmbedText.IsValid)
|
||||||
|
return new SmartPlainText(input);
|
||||||
|
|
||||||
return smartEmbedText;
|
return smartEmbedText;
|
||||||
}
|
}
|
||||||
|
@@ -3,8 +3,6 @@ using Newtonsoft.Json;
|
|||||||
|
|
||||||
namespace NadekoBot;
|
namespace NadekoBot;
|
||||||
|
|
||||||
// todo test smarttextembedfooter and smarttextembedauthor
|
|
||||||
|
|
||||||
public class SmartTextEmbedFooter
|
public class SmartTextEmbedFooter
|
||||||
{
|
{
|
||||||
public string Text { get; set; }
|
public string Text { get; set; }
|
||||||
|
@@ -3,10 +3,11 @@ using NadekoBot.Db;
|
|||||||
|
|
||||||
namespace NadekoBot.Modules.Administration.Services;
|
namespace NadekoBot.Modules.Administration.Services;
|
||||||
|
|
||||||
// todo if any activity...
|
// todo dateonly timeonly
|
||||||
|
// todo new apis
|
||||||
public class GameVoiceChannelService : INService
|
public class GameVoiceChannelService : INService
|
||||||
{
|
{
|
||||||
public ConcurrentHashSet<ulong> GameVoiceChannels { get; } = new();
|
public ConcurrentHashSet<ulong> GameVoiceChannels { get; }
|
||||||
|
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
@@ -16,30 +17,38 @@ public class GameVoiceChannelService : INService
|
|||||||
_db = db;
|
_db = db;
|
||||||
_client = client;
|
_client = client;
|
||||||
|
|
||||||
GameVoiceChannels = new(bot.AllGuildConfigs.Where(gc => gc.GameVoiceChannel is not null)
|
GameVoiceChannels = new(bot.AllGuildConfigs
|
||||||
.Select(gc => gc.GameVoiceChannel.Value));
|
.Where(gc => gc.GameVoiceChannel is not null)
|
||||||
|
.Select(gc => gc.GameVoiceChannel!.Value));
|
||||||
|
|
||||||
_client.UserVoiceStateUpdated += Client_UserVoiceStateUpdated;
|
_client.UserVoiceStateUpdated += OnUserVoiceStateUpdated;
|
||||||
_client.GuildMemberUpdated += _client_GuildMemberUpdated;
|
_client.PresenceUpdated += OnPresenceUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task _client_GuildMemberUpdated(Cacheable<SocketGuildUser, ulong> before, SocketGuildUser after)
|
private Task OnPresenceUpdate(SocketUser socketUser, SocketPresence before, SocketPresence after)
|
||||||
{
|
{
|
||||||
var _ = Task.Run(async () =>
|
var _ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//if the user is in the voice channel and that voice channel is gvc
|
if (socketUser is not SocketGuildUser newUser)
|
||||||
var vc = after.VoiceChannel;
|
return;
|
||||||
if (vc is null || !GameVoiceChannels.Contains(vc.Id) || !before.HasValue)
|
// if the user is in the voice channel and that voice channel is gvc
|
||||||
|
|
||||||
|
if (newUser.VoiceChannel is not { } vc
|
||||||
|
|| !GameVoiceChannels.Contains(vc.Id))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//if the activity has changed, and is a playing activity
|
//if the activity has changed, and is a playi1ng activity
|
||||||
var oldActivity = before.Value.Activities.FirstOrDefault();
|
foreach (var activity in after.Activities)
|
||||||
var newActivity = after.Activities.FirstOrDefault();
|
{
|
||||||
if (oldActivity != newActivity && newActivity is { Type: ActivityType.Playing })
|
if (activity is { Type: ActivityType.Playing })
|
||||||
//trigger gvc
|
{
|
||||||
await TriggerGvc(after, newActivity.Name);
|
//trigger gvc
|
||||||
|
if (await TriggerGvc(newUser, activity.Name))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -72,7 +81,7 @@ public class GameVoiceChannelService : INService
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task Client_UserVoiceStateUpdated(SocketUser usr, SocketVoiceState oldState, SocketVoiceState newState)
|
private Task OnUserVoiceStateUpdated(SocketUser usr, SocketVoiceState oldState, SocketVoiceState newState)
|
||||||
{
|
{
|
||||||
var _ = Task.Run(async () =>
|
var _ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
@@ -81,15 +90,17 @@ public class GameVoiceChannelService : INService
|
|||||||
if (usr is not SocketGuildUser gUser)
|
if (usr is not SocketGuildUser gUser)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var game = gUser.Activities.FirstOrDefault()?.Name;
|
if (newState.VoiceChannel is null)
|
||||||
|
|
||||||
if (oldState.VoiceChannel == newState.VoiceChannel || newState.VoiceChannel is null)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!GameVoiceChannels.Contains(newState.VoiceChannel.Id) || string.IsNullOrWhiteSpace(game))
|
if (!GameVoiceChannels.Contains(newState.VoiceChannel.Id))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await TriggerGvc(gUser, game);
|
foreach (var game in gUser.Activities.Select(x => x.Name))
|
||||||
|
{
|
||||||
|
if (await TriggerGvc(gUser, game))
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -100,18 +111,19 @@ public class GameVoiceChannelService : INService
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task TriggerGvc(SocketGuildUser gUser, string game)
|
private async Task<bool> TriggerGvc(SocketGuildUser gUser, string game)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(game))
|
if (string.IsNullOrWhiteSpace(game))
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
game = game.TrimTo(50).ToLowerInvariant();
|
game = game.TrimTo(50).ToLowerInvariant();
|
||||||
var vch = gUser.Guild.VoiceChannels.FirstOrDefault(x => x.Name.ToLowerInvariant() == game);
|
var vch = gUser.Guild.VoiceChannels.FirstOrDefault(x => x.Name.ToLowerInvariant() == game);
|
||||||
|
|
||||||
if (vch is null)
|
if (vch is null)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000);
|
||||||
await gUser.ModifyAsync(gu => gu.Channel = vch);
|
await gUser.ModifyAsync(gu => gu.Channel = vch);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -12,12 +12,8 @@ using YamlDotNet.Serialization.NamingConventions;
|
|||||||
|
|
||||||
namespace NadekoBot.Modules.NadekoExpressions;
|
namespace NadekoBot.Modules.NadekoExpressions;
|
||||||
|
|
||||||
// todo recheck whether ACTUALEXPRESSIONS perm works
|
|
||||||
// todo run db migration and rename ACTUALCUSTOMREACTIONS to ACTUALEXPRESSIONS
|
|
||||||
|
|
||||||
public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
|
public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
|
||||||
{
|
{
|
||||||
|
|
||||||
private const string MENTION_PH = "%bot.mention%";
|
private const string MENTION_PH = "%bot.mention%";
|
||||||
|
|
||||||
private const string PREPEND_EXPORT =
|
private const string PREPEND_EXPORT =
|
||||||
|
@@ -8,11 +8,10 @@ namespace NadekoBot.Modules.Utility.Services;
|
|||||||
|
|
||||||
public sealed class RepeaterService : IReadyExecutor, INService
|
public sealed class RepeaterService : IReadyExecutor, INService
|
||||||
{
|
{
|
||||||
public const int MAX_REPEATERS = 5;
|
private const int MAX_REPEATERS = 5;
|
||||||
|
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
private readonly IBotCredentials _creds;
|
private readonly IBotCredentials _creds;
|
||||||
private readonly IEmbedBuilderService _eb;
|
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
private readonly LinkedList<RunningRepeater> _repeaterQueue;
|
private readonly LinkedList<RunningRepeater> _repeaterQueue;
|
||||||
private readonly ConcurrentHashSet<int> _noRedundant;
|
private readonly ConcurrentHashSet<int> _noRedundant;
|
||||||
@@ -22,18 +21,16 @@ public sealed class RepeaterService : IReadyExecutor, INService
|
|||||||
public RepeaterService(
|
public RepeaterService(
|
||||||
DiscordSocketClient client,
|
DiscordSocketClient client,
|
||||||
DbService db,
|
DbService db,
|
||||||
IBotCredentials creds,
|
IBotCredentials creds)
|
||||||
IEmbedBuilderService eb)
|
|
||||||
{
|
{
|
||||||
_db = db;
|
_db = db;
|
||||||
_creds = creds;
|
_creds = creds;
|
||||||
_eb = eb;
|
|
||||||
_client = client;
|
_client = client;
|
||||||
|
|
||||||
var uow = _db.GetDbContext();
|
var uow = _db.GetDbContext();
|
||||||
var shardRepeaters = uow.Set<Repeater>()
|
var shardRepeaters = uow.Set<Repeater>()
|
||||||
.FromSqlInterpolated($@"select * from repeaters
|
.Where(x => ((int)(x.GuildId / Math.Pow(2, 22)) % _creds.TotalShards)
|
||||||
where ((guildid >> 22) % {_creds.TotalShards}) == {_client.ShardId};")
|
== _client.ShardId)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
@@ -51,6 +48,7 @@ where ((guildid >> 22) % {_creds.TotalShards}) == {_client.ShardId};")
|
|||||||
private async Task RunRepeatersLoop()
|
private async Task RunRepeatersLoop()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// calculate timeout for the first item
|
// calculate timeout for the first item
|
||||||
@@ -92,6 +90,7 @@ where ((guildid >> 22) % {_creds.TotalShards}) == {_client.ShardId};")
|
|||||||
Log.Error(ex, "Critical error in repeater queue: {ErrorMessage}", ex.Message);
|
Log.Error(ex, "Critical error in repeater queue: {ErrorMessage}", ex.Message);
|
||||||
await Task.Delay(5000);
|
await Task.Delay(5000);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandlePostExecute(RunningRepeater rep)
|
private async Task HandlePostExecute(RunningRepeater rep)
|
||||||
|
Reference in New Issue
Block a user