Files
nadekobot/src/NadekoBot/Modules/Administration/GameVoiceChannel/GameVoiceChannelService.cs
Kwoth 15ee3dd638 - Added waifu price decay functionality
- Waifu prices changed to long, supporting much higher prices than before
- Fixed .yml comment indentation in some cases
- Updated changelog
2022-02-02 11:25:22 +01:00

125 lines
3.8 KiB
C#

#nullable disable
using NadekoBot.Db;
namespace NadekoBot.Modules.Administration.Services;
public class GameVoiceChannelService : INService
{
public ConcurrentHashSet<ulong> GameVoiceChannels { get; }
private readonly DbService _db;
private readonly DiscordSocketClient _client;
public GameVoiceChannelService(DiscordSocketClient client, DbService db, Bot bot)
{
_db = db;
_client = client;
GameVoiceChannels = new(bot.AllGuildConfigs
.Where(gc => gc.GameVoiceChannel is not null)
.Select(gc => gc.GameVoiceChannel!.Value));
_client.UserVoiceStateUpdated += OnUserVoiceStateUpdated;
_client.PresenceUpdated += OnPresenceUpdate;
}
private Task OnPresenceUpdate(SocketUser socketUser, SocketPresence before, SocketPresence after)
{
_ = Task.Run(async () =>
{
try
{
if (socketUser is not SocketGuildUser newUser)
return;
// 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;
//if the activity has changed, and is a playi1ng activity
foreach (var activity in after.Activities)
{
if (activity is { Type: ActivityType.Playing })
//trigger gvc
if (await TriggerGvc(newUser, activity.Name))
return;
}
}
catch (Exception ex)
{
Log.Warning(ex, "Error running GuildMemberUpdated in gvc");
}
});
return Task.CompletedTask;
}
public ulong? ToggleGameVoiceChannel(ulong guildId, ulong vchId)
{
ulong? id;
using var uow = _db.GetDbContext();
var gc = uow.GuildConfigsForId(guildId, set => set);
if (gc.GameVoiceChannel == vchId)
{
GameVoiceChannels.TryRemove(vchId);
id = gc.GameVoiceChannel = null;
}
else
{
if (gc.GameVoiceChannel is not null)
GameVoiceChannels.TryRemove(gc.GameVoiceChannel.Value);
GameVoiceChannels.Add(vchId);
id = gc.GameVoiceChannel = vchId;
}
uow.SaveChanges();
return id;
}
private Task OnUserVoiceStateUpdated(SocketUser usr, SocketVoiceState oldState, SocketVoiceState newState)
{
_ = Task.Run(async () =>
{
try
{
if (usr is not SocketGuildUser gUser)
return;
if (newState.VoiceChannel is null)
return;
if (!GameVoiceChannels.Contains(newState.VoiceChannel.Id))
return;
foreach (var game in gUser.Activities.Select(x => x.Name))
{
if (await TriggerGvc(gUser, game))
return;
}
}
catch (Exception ex)
{
Log.Warning(ex, "Error running VoiceStateUpdate in gvc");
}
});
return Task.CompletedTask;
}
private async Task<bool> TriggerGvc(SocketGuildUser gUser, string game)
{
if (string.IsNullOrWhiteSpace(game))
return false;
game = game.TrimTo(50)!.ToLowerInvariant();
var vch = gUser.Guild.VoiceChannels.FirstOrDefault(x => x.Name.ToLowerInvariant() == game);
if (vch is null)
return false;
await Task.Delay(1000);
await gUser.ModifyAsync(gu => gu.Channel = vch);
return true;
}
}