NadekoBot/NadekoBot.Core/Modules/Administration/Services/VcRoleService.cs
2017-10-13 06:14:54 +02:00

120 lines
4.3 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;
using NadekoBot.Core.Services;
using NadekoBot.Core.Services.Database.Models;
using NLog;
namespace NadekoBot.Modules.Administration.Services
{
public class VcRoleService : INService
{
private readonly Logger _log;
private readonly DbService _db;
private readonly DiscordSocketClient _client;
public ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, IRole>> VcRoles { get; }
public VcRoleService(DiscordSocketClient client, NadekoBot bot, DbService db)
{
_log = LogManager.GetCurrentClassLogger();
_db = db;
_client = client;
_client.UserVoiceStateUpdated += ClientOnUserVoiceStateUpdated;
VcRoles = new ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, IRole>>();
var missingRoles = new List<VcRoleInfo>();
foreach (var gconf in bot.AllGuildConfigs)
{
var g = _client.GetGuild(gconf.GuildId);
if (g == null)
continue;
var infos = new ConcurrentDictionary<ulong, IRole>();
VcRoles.TryAdd(gconf.GuildId, infos);
foreach (var ri in gconf.VcRoleInfos)
{
var role = g.GetRole(ri.RoleId);
if (role == null)
{
missingRoles.Add(ri);
continue;
}
infos.TryAdd(ri.VoiceChannelId, role);
}
}
if(missingRoles.Any())
using (var uow = _db.UnitOfWork)
{
_log.Warn($"Removing {missingRoles.Count} missing roles from {nameof(VcRoleService)}");
uow._context.RemoveRange(missingRoles);
uow.Complete();
}
}
private Task ClientOnUserVoiceStateUpdated(SocketUser usr, SocketVoiceState oldState,
SocketVoiceState newState)
{
var gusr = usr as SocketGuildUser;
if (gusr == null)
return Task.CompletedTask;
var oldVc = oldState.VoiceChannel;
var newVc = newState.VoiceChannel;
var _ = Task.Run(async () =>
{
try
{
if (oldVc != newVc)
{
ulong guildId;
guildId = newVc?.Guild.Id ?? oldVc.Guild.Id;
if (VcRoles.TryGetValue(guildId, out ConcurrentDictionary<ulong, IRole> guildVcRoles))
{
//remove old
if (oldVc != null && guildVcRoles.TryGetValue(oldVc.Id, out IRole role))
{
try
{
await gusr.RemoveRoleAsync(role).ConfigureAwait(false);
}
catch
{
try
{
await Task.Delay(500).ConfigureAwait(false);
await gusr.RemoveRoleAsync(role).ConfigureAwait(false);
}
catch { }
}
}
//add new
if (newVc != null && guildVcRoles.TryGetValue(newVc.Id, out role))
{
if (!gusr.Roles.Contains(role))
{
await Task.Delay(500).ConfigureAwait(false);
await gusr.AddRoleAsync(role).ConfigureAwait(false);
}
}
}
}
}
catch (Exception ex)
{
_log.Warn(ex);
}
});
return Task.CompletedTask;
}
}
}