All modules compile, except log commands. Working on todos now

This commit is contained in:
Master Kwoth
2017-05-28 01:51:22 +02:00
parent a4973ffbb3
commit dfb4c778d2
125 changed files with 954 additions and 1063 deletions

View File

@@ -24,38 +24,6 @@ namespace NadekoBot.Modules.Administration
_admin = admin;
}
////todo permissions
//[NadekoCommand, Usage, Description, Aliases]
//[RequireContext(ContextType.Guild)]
//[RequireUserPermission(GuildPermission.Administrator)]
//public async Task ResetPermissions()
//{
// using (var uow = _db.UnitOfWork)
// {
// var config = uow.GuildConfigs.GcWithPermissionsv2For(Context.Guild.Id);
// config.Permissions = Permissionv2.GetDefaultPermlist;
// await uow.CompleteAsync();
// UpdateCache(config);
// }
// await ReplyConfirmLocalized("perms_reset").ConfigureAwait(false);
//}
//[NadekoCommand, Usage, Description, Aliases]
//[OwnerOnly]
//public async Task ResetGlobalPermissions()
//{
// using (var uow = _db.UnitOfWork)
// {
// var gc = uow.BotConfig.GetOrCreate();
// gc.BlockedCommands.Clear();
// gc.BlockedModules.Clear();
// GlobalPermissionCommands.BlockedCommands.Clear();
// GlobalPermissionCommands.BlockedModules.Clear();
// await uow.CompleteAsync();
// }
// await ReplyConfirmLocalized("global_perms_reset").ConfigureAwait(false);
//}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.Administrator)]

View File

@@ -400,9 +400,9 @@ namespace NadekoBot.Modules.Administration
});
//Blacklist
var blacklist = new HashSet<BlacklistItem>(oldConfig.ServerBlacklist.Select(server => new BlacklistItem() { ItemId = server, Type = BlacklistItem.BlacklistType.Server }));
blacklist.AddRange(oldConfig.ChannelBlacklist.Select(channel => new BlacklistItem() { ItemId = channel, Type = BlacklistItem.BlacklistType.Channel }));
blacklist.AddRange(oldConfig.UserBlacklist.Select(user => new BlacklistItem() { ItemId = user, Type = BlacklistItem.BlacklistType.User }));
var blacklist = new HashSet<BlacklistItem>(oldConfig.ServerBlacklist.Select(server => new BlacklistItem() { ItemId = server, Type = BlacklistType.Server }));
blacklist.AddRange(oldConfig.ChannelBlacklist.Select(channel => new BlacklistItem() { ItemId = channel, Type = BlacklistType.Channel }));
blacklist.AddRange(oldConfig.UserBlacklist.Select(user => new BlacklistItem() { ItemId = user, Type = BlacklistType.User }));
botConfig.Blacklist = blacklist;
//Eightball

View File

@@ -1,16 +1,9 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Attributes;
using NadekoBot.Services;
using NadekoBot.Services.Administration;
using NadekoBot.Services.Database.Models;
using NLog;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Administration

View File

@@ -1,18 +1,13 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Administration;
using NadekoBot.Services.Database.Models;
using NLog;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Administration

View File

@@ -12,9 +12,6 @@ using Discord.WebSocket;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
using Microsoft.EntityFrameworkCore;
using System.Collections.Immutable;
using NadekoBot.DataStructures;
using NLog;
using NadekoBot.Services.Administration;
namespace NadekoBot.Modules.Administration

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Concurrent;
using System.Linq;
using Discord;
using Discord.Commands;
@@ -32,7 +31,7 @@ namespace NadekoBot.Modules.Administration
[RequireUserPermission(GuildPermission.ManageRoles)]
[RequireUserPermission(GuildPermission.ManageChannels)]
[RequireBotPermission(GuildPermission.ManageRoles)]
// todo wait for the fix [RequireBotPermission(GuildPermission.ManageChannels)]
//todo discord.net [RequireBotPermission(GuildPermission.ManageChannels)]
[RequireContext(ContextType.Guild)]
public async Task VcRole([Remainder]IRole role = null)
{

View File

@@ -1,18 +1,13 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Administration;
using NLog;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Administration

View File

@@ -1,6 +1,5 @@
using Discord;
using Discord.Commands;
using ImageSharp;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Modules.Gambling.Models;

View File

@@ -6,7 +6,6 @@ using NadekoBot.Attributes;
using NadekoBot.DataStructures;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Database;
using NadekoBot.Services.Database.Models;
using System;
using System.Collections.Generic;

View File

@@ -1,5 +1,4 @@
using System;
using Discord;
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;

View File

@@ -10,7 +10,6 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

View File

@@ -1,5 +1,4 @@
using Discord;
using Discord.Commands;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using System.Text;

View File

@@ -1,17 +1,12 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
using NadekoBot.Services.Games;
using NLog;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
@@ -81,9 +76,7 @@ namespace NadekoBot.Modules.Games
var imgData = _games.GetRandomCurrencyImage();
//todo upload all currency images to transfer.sh and use that one as cdn
//and then
//todo 81 upload all currency images to transfer.sh and use that one as cdn
var msgToSend = GetText("planted",
Format.Bold(Context.User.ToString()),
amount + _bc.CurrencySign,

View File

@@ -1,5 +1,4 @@
using System;
using Discord;
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using NadekoBot.Attributes;
@@ -9,7 +8,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ImageSharp.Processing;
using NadekoBot.Services;
namespace NadekoBot.Modules.Games

View File

@@ -4,16 +4,7 @@ using NadekoBot.Services;
using System.Threading.Tasks;
using NadekoBot.Attributes;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Collections.Immutable;
using System.IO;
using System.Threading;
using NadekoBot.Extensions;
using System.Net.Http;
using ImageSharp;
using NadekoBot.DataStructures;
using NLog;
using NadekoBot.Services.Games;
namespace NadekoBot.Modules.Games

View File

@@ -357,7 +357,6 @@ namespace NadekoBot.Modules.Music
var cancelSource = new CancellationTokenSource();
var gusr = (IGuildUser)Context.User;
//todo use grouping
while (ids.Any() && !cancelSource.IsCancellationRequested)
{
var tasks = Task.WhenAll(ids.Take(5).Select(async id =>

View File

@@ -3,7 +3,6 @@ using Discord.Commands;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NLog;
using System;
using System.Globalization;
using System.Threading.Tasks;

View File

@@ -1,12 +1,4 @@
using Discord;
using NadekoBot.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules
namespace NadekoBot.Modules
{
public static class NadekoModuleExtensions
{

View File

@@ -1,14 +1,13 @@
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Modules.Games.Trivia;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
using NadekoBot.Services.Permissions;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using static NadekoBot.Services.Database.Models.BlacklistItem;
namespace NadekoBot.Modules.Permissions
{
@@ -23,19 +22,19 @@ namespace NadekoBot.Modules.Permissions
[Group]
public class BlacklistCommands : NadekoSubmodule
{
public static ConcurrentHashSet<ulong> BlacklistedUsers { get; set; }
public static ConcurrentHashSet<ulong> BlacklistedGuilds { get; set; }
public static ConcurrentHashSet<ulong> BlacklistedChannels { get; set; }
private readonly BlacklistService _bs;
private readonly DbHandler _db;
private readonly IBotCredentials _creds;
static BlacklistCommands()
private ConcurrentHashSet<ulong> BlacklistedUsers => _bs.BlacklistedUsers;
private ConcurrentHashSet<ulong> BlacklistedGuilds => _bs.BlacklistedGuilds;
private ConcurrentHashSet<ulong> BlacklistedChannels => _bs.BlacklistedChannels;
public BlacklistCommands(BlacklistService bs, DbHandler db, IBotCredentials creds)
{
using (var uow = DbHandler.UnitOfWork())
{
var blacklist = uow.BotConfig.GetOrCreate().Blacklist;
BlacklistedUsers = new ConcurrentHashSet<ulong>(blacklist.Where(bi => bi.Type == BlacklistType.User).Select(c => c.ItemId));
BlacklistedGuilds = new ConcurrentHashSet<ulong>(blacklist.Where(bi => bi.Type == BlacklistType.Server).Select(c => c.ItemId));
BlacklistedChannels = new ConcurrentHashSet<ulong>(blacklist.Where(bi => bi.Type == BlacklistType.Channel).Select(c => c.ItemId));
}
_bs = bs;
_db = db;
_creds = creds;
}
[NadekoCommand, Usage, Description, Aliases]
@@ -65,10 +64,10 @@ namespace NadekoBot.Modules.Permissions
private async Task Blacklist(AddRemove action, ulong id, BlacklistType type)
{
if(action == AddRemove.Add && NadekoBot.Credentials.OwnerIds.Contains(id))
if(action == AddRemove.Add && _creds.OwnerIds.Contains(id))
return;
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
if (action == AddRemove.Add)
{

View File

@@ -5,6 +5,7 @@ using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
using NadekoBot.Services.Permissions;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
@@ -13,24 +14,23 @@ namespace NadekoBot.Modules.Permissions
{
public partial class Permissions
{
public class ActiveCooldown
{
public string Command { get; set; }
public ulong UserId { get; set; }
}
[Group]
public class CmdCdsCommands : NadekoSubmodule
{
public static ConcurrentDictionary<ulong, ConcurrentHashSet<CommandCooldown>> CommandCooldowns { get; }
private static ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>> activeCooldowns { get; } = new ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>>();
private readonly DbHandler _db;
private readonly CmdCdService _service;
static CmdCdsCommands()
private ConcurrentDictionary<ulong, ConcurrentHashSet<CommandCooldown>> CommandCooldowns
=> _service.CommandCooldowns;
private ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>> ActiveCooldowns
=> _service.ActiveCooldowns;
public CmdCdsCommands(CmdCdService service, DbHandler db)
{
var configs = NadekoBot.AllGuildConfigs;
CommandCooldowns = new ConcurrentDictionary<ulong, ConcurrentHashSet<CommandCooldown>>(configs.ToDictionary(k => k.GuildId, v => new ConcurrentHashSet<CommandCooldown>(v.CommandCooldowns)));
_service = service;
_db = db;
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task CmdCooldown(CommandInfo command, int secs)
@@ -42,7 +42,7 @@ namespace NadekoBot.Modules.Permissions
return;
}
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var config = uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.CommandCooldowns));
var localSet = CommandCooldowns.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<CommandCooldown>());
@@ -63,7 +63,7 @@ namespace NadekoBot.Modules.Permissions
}
if (secs == 0)
{
var activeCds = activeCooldowns.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<ActiveCooldown>());
var activeCds = ActiveCooldowns.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<ActiveCooldown>());
activeCds.RemoveWhere(ac => ac.Command == command.Aliases.First().ToLowerInvariant());
await ReplyConfirmLocalized("cmdcd_cleared",
Format.Bold(command.Aliases.First())).ConfigureAwait(false);
@@ -89,15 +89,15 @@ namespace NadekoBot.Modules.Permissions
await channel.SendTableAsync("", localSet.Select(c => c.CommandName + ": " + c.Seconds + GetText("sec")), s => $"{s,-30}", 2).ConfigureAwait(false);
}
public static bool HasCooldown(CommandInfo cmd, IGuild guild, IUser user)
public bool HasCooldown(CommandInfo cmd, IGuild guild, IUser user)
{
if (guild == null)
return false;
var cmdcds = CmdCdsCommands.CommandCooldowns.GetOrAdd(guild.Id, new ConcurrentHashSet<CommandCooldown>());
var cmdcds = CommandCooldowns.GetOrAdd(guild.Id, new ConcurrentHashSet<CommandCooldown>());
CommandCooldown cdRule;
if ((cdRule = cmdcds.FirstOrDefault(cc => cc.CommandName == cmd.Aliases.First().ToLowerInvariant())) != null)
{
var activeCdsForGuild = activeCooldowns.GetOrAdd(guild.Id, new ConcurrentHashSet<ActiveCooldown>());
var activeCdsForGuild = ActiveCooldowns.GetOrAdd(guild.Id, new ConcurrentHashSet<ActiveCooldown>());
if (activeCdsForGuild.FirstOrDefault(ac => ac.UserId == user.Id && ac.Command == cmd.Aliases.First().ToLowerInvariant()) != null)
{
return true;

View File

@@ -1,16 +1,6 @@
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Database;
using NadekoBot.Services.Database.Models;
using System;
using Discord.Commands;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Permissions
{
@@ -67,7 +57,7 @@ namespace NadekoBot.Modules.Permissions
// Cost = cost
// };
// using (var uow = DbHandler.UnitOfWork())
// using (var uow = _db.UnitOfWork)
// {
// var bc = uow.BotConfig.GetOrCreate();

View File

@@ -4,8 +4,8 @@ using Microsoft.EntityFrameworkCore;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Permissions;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Permissions
@@ -15,46 +15,13 @@ namespace NadekoBot.Modules.Permissions
[Group]
public class FilterCommands : NadekoSubmodule
{
public static ConcurrentHashSet<ulong> InviteFilteringChannels { get; }
public static ConcurrentHashSet<ulong> InviteFilteringServers { get; }
private readonly DbHandler _db;
private readonly FilterService _service;
//serverid, filteredwords
private static ConcurrentDictionary<ulong, ConcurrentHashSet<string>> serverFilteredWords { get; }
public static ConcurrentHashSet<ulong> WordFilteringChannels { get; }
public static ConcurrentHashSet<ulong> WordFilteringServers { get; }
public static ConcurrentHashSet<string> FilteredWordsForChannel(ulong channelId, ulong guildId)
public FilterCommands(FilterService service, DbHandler db)
{
ConcurrentHashSet<string> words = new ConcurrentHashSet<string>();
if(WordFilteringChannels.Contains(channelId))
serverFilteredWords.TryGetValue(guildId, out words);
return words;
}
public static ConcurrentHashSet<string> FilteredWordsForServer(ulong guildId)
{
var words = new ConcurrentHashSet<string>();
if(WordFilteringServers.Contains(guildId))
serverFilteredWords.TryGetValue(guildId, out words);
return words;
}
static FilterCommands()
{
var guildConfigs = NadekoBot.AllGuildConfigs;
InviteFilteringServers = new ConcurrentHashSet<ulong>(guildConfigs.Where(gc => gc.FilterInvites).Select(gc => gc.GuildId));
InviteFilteringChannels = new ConcurrentHashSet<ulong>(guildConfigs.SelectMany(gc => gc.FilterInvitesChannelIds.Select(fci => fci.ChannelId)));
var dict = guildConfigs.ToDictionary(gc => gc.GuildId, gc => new ConcurrentHashSet<string>(gc.FilteredWords.Select(fw => fw.Word)));
serverFilteredWords = new ConcurrentDictionary<ulong, ConcurrentHashSet<string>>(dict);
var serverFiltering = guildConfigs.Where(gc => gc.FilterWords);
WordFilteringServers = new ConcurrentHashSet<ulong>(serverFiltering.Select(gc => gc.GuildId));
WordFilteringChannels = new ConcurrentHashSet<ulong>(guildConfigs.SelectMany(gc => gc.FilterWordsChannelIds.Select(fwci => fwci.ChannelId)));
_service = service;
_db = db;
}
[NadekoCommand, Usage, Description, Aliases]
@@ -64,21 +31,21 @@ namespace NadekoBot.Modules.Permissions
var channel = (ITextChannel)Context.Channel;
bool enabled;
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var config = uow.GuildConfigs.For(channel.Guild.Id, set => set);
enabled = config.FilterInvites = !config.FilterInvites;
await uow.CompleteAsync().ConfigureAwait(false);
}
if (enabled)
{
InviteFilteringServers.Add(channel.Guild.Id);
_service.InviteFilteringServers.Add(channel.Guild.Id);
await ReplyConfirmLocalized("invite_filter_server_on").ConfigureAwait(false);
}
else
{
InviteFilteringServers.TryRemove(channel.Guild.Id);
_service.InviteFilteringServers.TryRemove(channel.Guild.Id);
await ReplyConfirmLocalized("invite_filter_server_off").ConfigureAwait(false);
}
}
@@ -90,7 +57,7 @@ namespace NadekoBot.Modules.Permissions
var channel = (ITextChannel)Context.Channel;
int removed;
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var config = uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.FilterInvitesChannelIds));
removed = config.FilterInvitesChannelIds.RemoveWhere(fc => fc.ChannelId == channel.Id);
@@ -106,7 +73,7 @@ namespace NadekoBot.Modules.Permissions
if (removed == 0)
{
InviteFilteringChannels.Add(channel.Id);
_service.InviteFilteringChannels.Add(channel.Id);
await ReplyConfirmLocalized("invite_filter_channel_on").ConfigureAwait(false);
}
else
@@ -122,7 +89,7 @@ namespace NadekoBot.Modules.Permissions
var channel = (ITextChannel)Context.Channel;
bool enabled;
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var config = uow.GuildConfigs.For(channel.Guild.Id, set => set);
enabled = config.FilterWords = !config.FilterWords;
@@ -131,12 +98,12 @@ namespace NadekoBot.Modules.Permissions
if (enabled)
{
WordFilteringServers.Add(channel.Guild.Id);
_service.WordFilteringServers.Add(channel.Guild.Id);
await ReplyConfirmLocalized("word_filter_server_on").ConfigureAwait(false);
}
else
{
WordFilteringServers.TryRemove(channel.Guild.Id);
_service.WordFilteringServers.TryRemove(channel.Guild.Id);
await ReplyConfirmLocalized("word_filter_server_off").ConfigureAwait(false);
}
}
@@ -148,7 +115,7 @@ namespace NadekoBot.Modules.Permissions
var channel = (ITextChannel)Context.Channel;
int removed;
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var config = uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.FilterWordsChannelIds));
removed = config.FilterWordsChannelIds.RemoveWhere(fc => fc.ChannelId == channel.Id);
@@ -164,12 +131,12 @@ namespace NadekoBot.Modules.Permissions
if (removed == 0)
{
WordFilteringChannels.Add(channel.Id);
_service.WordFilteringChannels.Add(channel.Id);
await ReplyConfirmLocalized("word_filter_channel_on").ConfigureAwait(false);
}
else
{
WordFilteringChannels.TryRemove(channel.Id);
_service.WordFilteringChannels.TryRemove(channel.Id);
await ReplyConfirmLocalized("word_filter_channel_off").ConfigureAwait(false);
}
}
@@ -186,7 +153,7 @@ namespace NadekoBot.Modules.Permissions
return;
int removed;
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var config = uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.FilteredWords));
@@ -198,7 +165,7 @@ namespace NadekoBot.Modules.Permissions
await uow.CompleteAsync().ConfigureAwait(false);
}
var filteredWords = serverFilteredWords.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<string>());
var filteredWords = _service.ServerFilteredWords.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<string>());
if (removed == 0)
{
@@ -218,8 +185,7 @@ namespace NadekoBot.Modules.Permissions
{
var channel = (ITextChannel)Context.Channel;
ConcurrentHashSet<string> filteredWords;
serverFilteredWords.TryGetValue(channel.Guild.Id, out filteredWords);
_service.ServerFilteredWords.TryGetValue(channel.Guild.Id, out ConcurrentHashSet<string> filteredWords);
await channel.SendConfirmAsync(GetText("filter_word_list"), string.Join("\n", filteredWords))
.ConfigureAwait(false);

View File

@@ -1,16 +1,11 @@
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.DataStructures;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Database;
using NadekoBot.Services.Permissions;
using NadekoBot.TypeReaders;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Permissions
@@ -20,20 +15,20 @@ namespace NadekoBot.Modules.Permissions
[Group]
public class GlobalPermissionCommands : NadekoSubmodule
{
public static readonly ConcurrentHashSet<string> BlockedModules;
public static readonly ConcurrentHashSet<string> BlockedCommands;
private GlobalPermissionService _service;
private readonly DbHandler _db;
static GlobalPermissionCommands()
public GlobalPermissionCommands(GlobalPermissionService service, DbHandler db)
{
BlockedModules = new ConcurrentHashSet<string>(NadekoBot.BotConfig.BlockedModules.Select(x => x.Name));
BlockedCommands = new ConcurrentHashSet<string>(NadekoBot.BotConfig.BlockedCommands.Select(x => x.Name));
_service = service;
_db = db;
}
[NadekoCommand, Usage, Description, Aliases]
[OwnerOnly]
public async Task Lgp()
{
if (!BlockedModules.Any() && !BlockedCommands.Any())
if (!_service.BlockedModules.Any() && !_service.BlockedCommands.Any())
{
await ReplyErrorLocalized("lgp_none").ConfigureAwait(false);
return;
@@ -41,11 +36,11 @@ namespace NadekoBot.Modules.Permissions
var embed = new EmbedBuilder().WithOkColor();
if (BlockedModules.Any())
embed.AddField(efb => efb.WithName(GetText("blocked_modules")).WithValue(string.Join("\n", BlockedModules)).WithIsInline(false));
if (_service.BlockedModules.Any())
embed.AddField(efb => efb.WithName(GetText("blocked_modules")).WithValue(string.Join("\n", _service.BlockedModules)).WithIsInline(false));
if (BlockedCommands.Any())
embed.AddField(efb => efb.WithName(GetText("blocked_commands")).WithValue(string.Join("\n", BlockedCommands)).WithIsInline(false));
if (_service.BlockedCommands.Any())
embed.AddField(efb => efb.WithName(GetText("blocked_commands")).WithValue(string.Join("\n", _service.BlockedCommands)).WithIsInline(false));
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
@@ -55,9 +50,9 @@ namespace NadekoBot.Modules.Permissions
public async Task Gmod(ModuleOrCrInfo module)
{
var moduleName = module.Name.ToLowerInvariant();
if (BlockedModules.Add(moduleName))
if (_service.BlockedModules.Add(moduleName))
{
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var bc = uow.BotConfig.GetOrCreate();
bc.BlockedModules.Add(new Services.Database.Models.BlockedCmdOrMdl
@@ -69,9 +64,9 @@ namespace NadekoBot.Modules.Permissions
await ReplyConfirmLocalized("gmod_add", Format.Bold(module.Name)).ConfigureAwait(false);
return;
}
else if (BlockedModules.TryRemove(moduleName))
else if (_service.BlockedModules.TryRemove(moduleName))
{
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var bc = uow.BotConfig.GetOrCreate();
bc.BlockedModules.RemoveWhere(x => x.Name == moduleName);
@@ -87,9 +82,9 @@ namespace NadekoBot.Modules.Permissions
public async Task Gcmd(CommandOrCrInfo cmd)
{
var commandName = cmd.Name.ToLowerInvariant();
if (BlockedCommands.Add(commandName))
if (_service.BlockedCommands.Add(commandName))
{
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var bc = uow.BotConfig.GetOrCreate();
bc.BlockedCommands.Add(new Services.Database.Models.BlockedCmdOrMdl
@@ -101,9 +96,9 @@ namespace NadekoBot.Modules.Permissions
await ReplyConfirmLocalized("gcmd_add", Format.Bold(cmd.Name)).ConfigureAwait(false);
return;
}
else if (BlockedCommands.TryRemove(commandName))
else if (_service.BlockedCommands.TryRemove(commandName))
{
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var bc = uow.BotConfig.GetOrCreate();
bc.BlockedCommands.RemoveWhere(x => x.Name == commandName);

View File

@@ -0,0 +1,62 @@
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
using NadekoBot.Services.Permissions;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Permissions.Commands
{
public partial class Permissions
{
[Group]
public class ResetPermissionsCommands : NadekoSubmodule
{
private readonly PermissionsService _service;
private readonly DbHandler _db;
private readonly GlobalPermissionService _globalPerms;
public ResetPermissionsCommands(PermissionsService service, GlobalPermissionService globalPerms, DbHandler db)
{
_service = service;
_db = db;
_globalPerms = globalPerms;
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.Administrator)]
public async Task ResetPermissions()
{
//todo 80 move to service
using (var uow = _db.UnitOfWork)
{
var config = uow.GuildConfigs.GcWithPermissionsv2For(Context.Guild.Id);
config.Permissions = Permissionv2.GetDefaultPermlist;
await uow.CompleteAsync();
_service.UpdateCache(config);
}
await ReplyConfirmLocalized("perms_reset").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[OwnerOnly]
public async Task ResetGlobalPermissions()
{
//todo 80 move to service
using (var uow = _db.UnitOfWork)
{
var gc = uow.BotConfig.GetOrCreate();
gc.BlockedCommands.Clear();
gc.BlockedModules.Clear();
_globalPerms.BlockedCommands.Clear();
_globalPerms.BlockedModules.Clear();
await uow.CompleteAsync();
}
await ReplyConfirmLocalized("global_perms_reset").ConfigureAwait(false);
}
}
}
}

View File

@@ -1,130 +0,0 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using NadekoBot.Services.Database.Models;
using System;
using System.Collections.Generic;
using System.Linq;
namespace NadekoBot.Modules.Permissions
{
public static class PermissionExtensions
{
public static bool CheckPermissions(this IEnumerable<Permissionv2> permsEnumerable, IUserMessage message,
string commandName, string moduleName, out int permIndex)
{
var perms = permsEnumerable as List<Permissionv2> ?? permsEnumerable.ToList();
for (int i = perms.Count - 1; i >= 0; i--)
{
var perm = perms[i];
var result = perm.CheckPermission(message, commandName, moduleName);
if (result == null)
{
continue;
}
permIndex = i;
return result.Value;
}
permIndex = -1; //defaut behaviour
return true;
}
//null = not applicable
//true = applicable, allowed
//false = applicable, not allowed
public static bool? CheckPermission(this Permissionv2 perm, IUserMessage message, string commandName, string moduleName)
{
if (!((perm.SecondaryTarget == SecondaryPermissionType.Command &&
perm.SecondaryTargetName.ToLowerInvariant() == commandName.ToLowerInvariant()) ||
(perm.SecondaryTarget == SecondaryPermissionType.Module &&
perm.SecondaryTargetName.ToLowerInvariant() == moduleName.ToLowerInvariant()) ||
perm.SecondaryTarget == SecondaryPermissionType.AllModules))
return null;
var guildUser = message.Author as IGuildUser;
switch (perm.PrimaryTarget)
{
case PrimaryPermissionType.User:
if (perm.PrimaryTargetId == message.Author.Id)
return perm.State;
break;
case PrimaryPermissionType.Channel:
if (perm.PrimaryTargetId == message.Channel.Id)
return perm.State;
break;
case PrimaryPermissionType.Role:
if (guildUser == null)
break;
if (guildUser.RoleIds.Contains(perm.PrimaryTargetId))
return perm.State;
break;
case PrimaryPermissionType.Server:
if (guildUser == null)
break;
return perm.State;
}
return null;
}
public static string GetCommand(this Permissionv2 perm, SocketGuild guild = null)
{
var com = "";
switch (perm.PrimaryTarget)
{
case PrimaryPermissionType.User:
com += "u";
break;
case PrimaryPermissionType.Channel:
com += "c";
break;
case PrimaryPermissionType.Role:
com += "r";
break;
case PrimaryPermissionType.Server:
com += "s";
break;
}
switch (perm.SecondaryTarget)
{
case SecondaryPermissionType.Module:
com += "m";
break;
case SecondaryPermissionType.Command:
com += "c";
break;
case SecondaryPermissionType.AllModules:
com = "a" + com + "m";
break;
}
com += " " + (perm.SecondaryTargetName != "*" ? perm.SecondaryTargetName + " " : "") + (perm.State ? "enable" : "disable") + " ";
switch (perm.PrimaryTarget)
{
case PrimaryPermissionType.User:
com += guild?.GetUser(perm.PrimaryTargetId)?.ToString() ?? $"<@{perm.PrimaryTargetId}>";
break;
case PrimaryPermissionType.Channel:
com += $"<#{perm.PrimaryTargetId}>";
break;
case PrimaryPermissionType.Role:
com += guild?.GetRole(perm.PrimaryTargetId)?.ToString() ?? $"<@&{perm.PrimaryTargetId}>";
break;
case PrimaryPermissionType.Server:
break;
}
return NadekoBot.ModulePrefixes[typeof(Permissions).Name] + com;
}
public static IEnumerable<Permission> AsEnumerable(this Permission perm)
{
do yield return perm;
while ((perm = perm.Next) != null);
}
}
}

View File

@@ -6,169 +6,34 @@ using Discord.Commands;
using NadekoBot.Services;
using Discord;
using NadekoBot.Services.Database.Models;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Discord.WebSocket;
using System.Diagnostics;
using Microsoft.EntityFrameworkCore;
using NadekoBot.DataStructures;
using NadekoBot.TypeReaders;
using NLog;
using NadekoBot.Services.Permissions;
namespace NadekoBot.Modules.Permissions
{
[NadekoModule("Permissions", ";")]
public partial class Permissions : NadekoTopLevelModule
{
//guildid, root permission
public static ConcurrentDictionary<ulong, PermissionCache> Cache { get; } =
new ConcurrentDictionary<ulong, PermissionCache>();
private readonly DbHandler _db;
private readonly PermissionsService _service;
static Permissions()
public Permissions(PermissionsService service, DbHandler db)
{
var log = LogManager.GetCurrentClassLogger();
var sw = Stopwatch.StartNew();
TryMigratePermissions();
using (var uow = DbHandler.UnitOfWork())
{
foreach (var x in uow.GuildConfigs.Permissionsv2ForAll())
{
Cache.TryAdd(x.GuildId, new PermissionCache()
{
Verbose = x.VerbosePermissions,
PermRole = x.PermissionRole,
Permissions = new PermissionsCollection<Permissionv2>(x.Permissions)
});
}
}
sw.Stop();
log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
}
public static PermissionCache GetCache(ulong guildId)
{
PermissionCache pc;
if (!Permissions.Cache.TryGetValue(guildId, out pc))
{
using (var uow = DbHandler.UnitOfWork())
{
var config = uow.GuildConfigs.For(guildId,
set => set.Include(x => x.Permissions));
Permissions.UpdateCache(config);
}
Permissions.Cache.TryGetValue(guildId, out pc);
if (pc == null)
throw new Exception("Cache is null.");
}
return pc;
}
private static void TryMigratePermissions()
{
var log = LogManager.GetCurrentClassLogger();
using (var uow = DbHandler.UnitOfWork())
{
var oldCache = new ConcurrentDictionary<ulong, OldPermissionCache>(uow.GuildConfigs
.OldPermissionsForAll()
.Where(x => x.RootPermission != null) // there is a check inside already, but just in case
.ToDictionary(k => k.GuildId,
v => new OldPermissionCache()
{
RootPermission = v.RootPermission,
Verbose = v.VerbosePermissions,
PermRole = v.PermissionRole
}));
if (oldCache.Any())
{
log.Info("Old permissions found. Performing one-time migration to v2.");
var i = 0;
foreach (var oc in oldCache)
{
if (i % 3 == 0)
log.Info("Migrating Permissions #" + i + " - GuildId: " + oc.Key);
i++;
var gc = uow.GuildConfigs.GcWithPermissionsv2For(oc.Key);
var oldPerms = oc.Value.RootPermission.AsEnumerable().Reverse().ToList();
uow._context.Set<Permission>().RemoveRange(oldPerms);
gc.RootPermission = null;
if (oldPerms.Count > 2)
{
var newPerms = oldPerms.Take(oldPerms.Count - 1)
.Select(x => x.Tov2())
.ToList();
var allowPerm = Permissionv2.AllowAllPerm;
var firstPerm = newPerms[0];
if (allowPerm.State != firstPerm.State ||
allowPerm.PrimaryTarget != firstPerm.PrimaryTarget ||
allowPerm.SecondaryTarget != firstPerm.SecondaryTarget ||
allowPerm.PrimaryTargetId != firstPerm.PrimaryTargetId ||
allowPerm.SecondaryTargetName != firstPerm.SecondaryTargetName)
newPerms.Insert(0, Permissionv2.AllowAllPerm);
Cache.TryAdd(oc.Key, new PermissionCache
{
Permissions = new PermissionsCollection<Permissionv2>(newPerms),
Verbose = gc.VerbosePermissions,
PermRole = gc.PermissionRole,
});
gc.Permissions = newPerms;
}
}
log.Info("Permission migration to v2 is done.");
uow.Complete();
}
}
}
private static async Task AddPermissions(ulong guildId, params Permissionv2[] perms)
{
using (var uow = DbHandler.UnitOfWork())
{
var config = uow.GuildConfigs.GcWithPermissionsv2For(guildId);
//var orderedPerms = new PermissionsCollection<Permissionv2>(config.Permissions);
var max = config.Permissions.Max(x => x.Index); //have to set its index to be the highest
foreach (var perm in perms)
{
perm.Index = ++max;
config.Permissions.Add(perm);
}
await uow.CompleteAsync().ConfigureAwait(false);
UpdateCache(config);
}
}
public static void UpdateCache(GuildConfig config)
{
Cache.AddOrUpdate(config.GuildId, new PermissionCache()
{
Permissions = new PermissionsCollection<Permissionv2>(config.Permissions),
PermRole = config.PermissionRole,
Verbose = config.VerbosePermissions
}, (id, old) =>
{
old.Permissions = new PermissionsCollection<Permissionv2>(config.Permissions);
old.PermRole = config.PermissionRole;
old.Verbose = config.VerbosePermissions;
return old;
});
_db = db;
_service = service;
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Verbose(PermissionAction action)
{
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var config = uow.GuildConfigs.GcWithPermissionsv2For(Context.Guild.Id);
config.VerbosePermissions = action.Value;
await uow.CompleteAsync().ConfigureAwait(false);
UpdateCache(config);
_service.UpdateCache(config);
}
if (action.Value)
{
@@ -187,7 +52,7 @@ namespace NadekoBot.Modules.Permissions
if (role != null && role == role.Guild.EveryoneRole)
return;
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var config = uow.GuildConfigs.GcWithPermissionsv2For(Context.Guild.Id);
if (role == null)
@@ -197,7 +62,7 @@ namespace NadekoBot.Modules.Permissions
}
config.PermissionRole = role.Name.Trim();
await uow.CompleteAsync().ConfigureAwait(false);
UpdateCache(config);
_service.UpdateCache(config);
}
await ReplyConfirmLocalized("permrole_changed", Format.Bold(role.Name)).ConfigureAwait(false);
@@ -210,10 +75,9 @@ namespace NadekoBot.Modules.Permissions
if (page < 1)
return;
PermissionCache permCache;
IList<Permissionv2> perms;
if (Cache.TryGetValue(Context.Guild.Id, out permCache))
if (_service.Cache.TryGetValue(Context.Guild.Id, out var permCache))
{
perms = permCache.Permissions.Source.ToList();
}
@@ -249,7 +113,7 @@ namespace NadekoBot.Modules.Permissions
try
{
Permissionv2 p;
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var config = uow.GuildConfigs.GcWithPermissionsv2For(Context.Guild.Id);
var permsCol = new PermissionsCollection<Permissionv2>(config.Permissions);
@@ -257,7 +121,7 @@ namespace NadekoBot.Modules.Permissions
permsCol.RemoveAt(index);
uow._context.Remove(p);
await uow.CompleteAsync().ConfigureAwait(false);
UpdateCache(config);
_service.UpdateCache(config);
}
await ReplyConfirmLocalized("removed",
index + 1,
@@ -280,7 +144,7 @@ namespace NadekoBot.Modules.Permissions
try
{
Permissionv2 fromPerm;
using (var uow = DbHandler.UnitOfWork())
using (var uow = _db.UnitOfWork)
{
var config = uow.GuildConfigs.GcWithPermissionsv2For(Context.Guild.Id);
var permsCol = new PermissionsCollection<Permissionv2>(config.Permissions);
@@ -304,7 +168,7 @@ namespace NadekoBot.Modules.Permissions
permsCol.RemoveAt(from);
permsCol.Insert(to, fromPerm);
await uow.CompleteAsync().ConfigureAwait(false);
UpdateCache(config);
_service.UpdateCache(config);
}
await ReplyConfirmLocalized("moved_permission",
Format.Code(fromPerm.GetCommand((SocketGuild) Context.Guild)),
@@ -324,7 +188,7 @@ namespace NadekoBot.Modules.Permissions
[RequireContext(ContextType.Guild)]
public async Task SrvrCmd(CommandOrCrInfo command, PermissionAction action)
{
await AddPermissions(Context.Guild.Id, new Permissionv2
await _service.AddPermissions(Context.Guild.Id, new Permissionv2
{
PrimaryTarget = PrimaryPermissionType.Server,
PrimaryTargetId = 0,
@@ -351,7 +215,7 @@ namespace NadekoBot.Modules.Permissions
[RequireContext(ContextType.Guild)]
public async Task SrvrMdl(ModuleOrCrInfo module, PermissionAction action)
{
await AddPermissions(Context.Guild.Id, new Permissionv2
await _service.AddPermissions(Context.Guild.Id, new Permissionv2
{
PrimaryTarget = PrimaryPermissionType.Server,
PrimaryTargetId = 0,
@@ -378,7 +242,7 @@ namespace NadekoBot.Modules.Permissions
[RequireContext(ContextType.Guild)]
public async Task UsrCmd(CommandOrCrInfo command, PermissionAction action, [Remainder] IGuildUser user)
{
await AddPermissions(Context.Guild.Id, new Permissionv2
await _service.AddPermissions(Context.Guild.Id, new Permissionv2
{
PrimaryTarget = PrimaryPermissionType.User,
PrimaryTargetId = user.Id,
@@ -407,7 +271,7 @@ namespace NadekoBot.Modules.Permissions
[RequireContext(ContextType.Guild)]
public async Task UsrMdl(ModuleOrCrInfo module, PermissionAction action, [Remainder] IGuildUser user)
{
await AddPermissions(Context.Guild.Id, new Permissionv2
await _service.AddPermissions(Context.Guild.Id, new Permissionv2
{
PrimaryTarget = PrimaryPermissionType.User,
PrimaryTargetId = user.Id,
@@ -439,7 +303,7 @@ namespace NadekoBot.Modules.Permissions
if (role == role.Guild.EveryoneRole)
return;
await AddPermissions(Context.Guild.Id, new Permissionv2
await _service.AddPermissions(Context.Guild.Id, new Permissionv2
{
PrimaryTarget = PrimaryPermissionType.Role,
PrimaryTargetId = role.Id,
@@ -471,7 +335,7 @@ namespace NadekoBot.Modules.Permissions
if (role == role.Guild.EveryoneRole)
return;
await AddPermissions(Context.Guild.Id, new Permissionv2
await _service.AddPermissions(Context.Guild.Id, new Permissionv2
{
PrimaryTarget = PrimaryPermissionType.Role,
PrimaryTargetId = role.Id,
@@ -501,7 +365,7 @@ namespace NadekoBot.Modules.Permissions
[RequireContext(ContextType.Guild)]
public async Task ChnlCmd(CommandOrCrInfo command, PermissionAction action, [Remainder] ITextChannel chnl)
{
await AddPermissions(Context.Guild.Id, new Permissionv2
await _service.AddPermissions(Context.Guild.Id, new Permissionv2
{
PrimaryTarget = PrimaryPermissionType.Channel,
PrimaryTargetId = chnl.Id,
@@ -530,7 +394,7 @@ namespace NadekoBot.Modules.Permissions
[RequireContext(ContextType.Guild)]
public async Task ChnlMdl(ModuleOrCrInfo module, PermissionAction action, [Remainder] ITextChannel chnl)
{
await AddPermissions(Context.Guild.Id, new Permissionv2
await _service.AddPermissions(Context.Guild.Id, new Permissionv2
{
PrimaryTarget = PrimaryPermissionType.Channel,
PrimaryTargetId = chnl.Id,
@@ -559,7 +423,7 @@ namespace NadekoBot.Modules.Permissions
[RequireContext(ContextType.Guild)]
public async Task AllChnlMdls(PermissionAction action, [Remainder] ITextChannel chnl)
{
await AddPermissions(Context.Guild.Id, new Permissionv2
await _service.AddPermissions(Context.Guild.Id, new Permissionv2
{
PrimaryTarget = PrimaryPermissionType.Channel,
PrimaryTargetId = chnl.Id,
@@ -587,7 +451,7 @@ namespace NadekoBot.Modules.Permissions
if (role == role.Guild.EveryoneRole)
return;
await AddPermissions(Context.Guild.Id, new Permissionv2
await _service.AddPermissions(Context.Guild.Id, new Permissionv2
{
PrimaryTarget = PrimaryPermissionType.Role,
PrimaryTargetId = role.Id,
@@ -612,7 +476,7 @@ namespace NadekoBot.Modules.Permissions
[RequireContext(ContextType.Guild)]
public async Task AllUsrMdls(PermissionAction action, [Remainder] IUser user)
{
await AddPermissions(Context.Guild.Id, new Permissionv2
await _service.AddPermissions(Context.Guild.Id, new Permissionv2
{
PrimaryTarget = PrimaryPermissionType.User,
PrimaryTargetId = user.Id,
@@ -655,7 +519,7 @@ namespace NadekoBot.Modules.Permissions
State = true,
};
await AddPermissions(Context.Guild.Id,
await _service.AddPermissions(Context.Guild.Id,
newPerm,
allowUser);

View File

@@ -1,14 +1,9 @@
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Modules.Searches.Models;
using NadekoBot.Services;
using NadekoBot.Services.Searches;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

View File

@@ -1,5 +1,4 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace NadekoBot.Modules.Searches.Commands.Models
{

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches.Commands.Models
namespace NadekoBot.Modules.Searches.Commands.Models
{
public struct GoogleSearchResult
{

View File

@@ -1,6 +1,4 @@
using Newtonsoft.Json;
using System;
using System.Text.RegularExpressions;
namespace NadekoBot.Modules.Searches.Models
{

View File

@@ -1,9 +1,4 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches.Commands.Models
{

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace NadekoBot.Modules.Searches.Commands.Models
{

View File

@@ -1,5 +1,4 @@
using Discord;
using Discord.API;
using NadekoBot.Extensions;
using NadekoBot.Services;
using Newtonsoft.Json;

View File

@@ -2,12 +2,8 @@
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Modules.Searches.Models;
using NadekoBot.Services.Searches;
using Newtonsoft.Json;
using NLog;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

View File

@@ -3,7 +3,6 @@ using Discord;
using System.Linq;
using System.Threading.Tasks;
using NadekoBot.Services;
using System.Threading;
using System.Collections.Generic;
using NadekoBot.Services.Database.Models;
using NadekoBot.Attributes;

View File

@@ -2,11 +2,8 @@
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using System;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Linq;
using Discord.WebSocket;
using NadekoBot.Services.Searches;
using NadekoBot.Services;

View File

@@ -6,6 +6,7 @@ using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
using NadekoBot.Services.Utility;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;

View File

@@ -3,9 +3,8 @@ using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services;
using System;
using NadekoBot.Services.Utility;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility

View File

@@ -11,7 +11,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord.WebSocket;
using NadekoBot.Modules.Utility.Models;
using NadekoBot.Services.Utility;
namespace NadekoBot.Modules.Utility
{
@@ -20,11 +20,11 @@ namespace NadekoBot.Modules.Utility
[Group]
public class RepeatCommands : NadekoSubmodule
{
private readonly UtilityService _service;
private readonly MessageRepeaterService _service;
private readonly DiscordShardedClient _client;
private readonly DbHandler _db;
public RepeatCommands(UtilityService service, DiscordShardedClient client, DbHandler db)
public RepeatCommands(MessageRepeaterService service, DiscordShardedClient client, DbHandler db)
{
_service = service;
_client = client;

View File

@@ -4,12 +4,10 @@ using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
using NLog;
using NadekoBot.Services.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility
@@ -19,10 +17,10 @@ namespace NadekoBot.Modules.Utility
[Group]
public class RemindCommands : NadekoSubmodule
{
private readonly UtilityService _service;
private readonly RemindService _service;
private readonly DbHandler _db;
public RemindCommands(UtilityService service, DbHandler db)
public RemindCommands(RemindService service, DbHandler db)
{
_service = service;
_db = db;
@@ -63,7 +61,7 @@ namespace NadekoBot.Modules.Utility
public async Task RemindInternal(ulong targetId, bool isPrivate, string timeStr, [Remainder] string message)
{
var m = _service.Remind.Regex.Match(timeStr);
var m = _service.Regex.Match(timeStr);
if (m.Length == 0)
{
@@ -74,7 +72,7 @@ namespace NadekoBot.Modules.Utility
string output = "";
var namesAndValues = new Dictionary<string, int>();
foreach (var groupName in _service.Remind.Regex.GetGroupNames())
foreach (var groupName in _service.Regex.GetGroupNames())
{
if (groupName == "0") continue;
int value;
@@ -134,7 +132,7 @@ namespace NadekoBot.Modules.Utility
{
// ignored
}
await _service.Remind.StartReminder(rem);
await _service.StartReminder(rem);
}
[NadekoCommand, Usage, Description, Aliases]

View File

@@ -2,6 +2,7 @@
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services.Utility;
using System;
using System.Linq;
using System.Threading.Tasks;
@@ -13,9 +14,9 @@ namespace NadekoBot.Modules.Utility
[Group]
public class UnitConverterCommands : NadekoSubmodule
{
private readonly UtilityService _service;
private readonly ConverterService _service;
public UnitConverterCommands(UtilityService service)
public UnitConverterCommands(ConverterService service)
{
_service = service;
}
@@ -23,7 +24,7 @@ namespace NadekoBot.Modules.Utility
[NadekoCommand, Usage, Description, Aliases]
public async Task ConvertList()
{
var res = _service.Converter.Units.GroupBy(x => x.UnitType)
var res = _service.Units.GroupBy(x => x.UnitType)
.Aggregate(new EmbedBuilder().WithTitle(GetText("convertlist"))
.WithColor(NadekoBot.OkColor),
(embed, g) => embed.AddField(efb =>
@@ -35,8 +36,8 @@ namespace NadekoBot.Modules.Utility
[NadekoCommand, Usage, Description, Aliases]
public async Task Convert(string origin, string target, decimal value)
{
var originUnit = _service.Converter.Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(origin.ToLowerInvariant()));
var targetUnit = _service.Converter.Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(target.ToLowerInvariant()));
var originUnit = _service.Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(origin.ToLowerInvariant()));
var targetUnit = _service.Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(target.ToLowerInvariant()));
if (originUnit == null || targetUnit == null)
{
await ReplyErrorLocalized("convert_not_found", Format.Bold(origin), Format.Bold(target)).ConfigureAwait(false);

View File

@@ -1,9 +1,4 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility.Models
{

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility.Models
namespace NadekoBot.Modules.Utility.Models
{
public class Attributes
{

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility.Models
namespace NadekoBot.Modules.Utility.Models
{
public class DiscordConnection
{

View File

@@ -1,114 +0,0 @@
using Discord;
using Discord.Net;
using Discord.WebSocket;
using Microsoft.Extensions.Logging;
using NadekoBot.Extensions;
using NadekoBot.Services.Database.Models;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility.Models
{
public class RepeatRunner
{
private readonly Logger _log;
private CancellationTokenSource source { get; set; }
private CancellationToken token { get; set; }
public Repeater Repeater { get; }
public SocketGuild Guild { get; }
public ITextChannel Channel { get; private set; }
private IUserMessage oldMsg = null;
public RepeatRunner(DiscordShardedClient client, Repeater repeater, ITextChannel channel = null)
{
_log = LogManager.GetCurrentClassLogger();
Repeater = repeater;
Channel = channel;
//todo @.@ fix all of this
Guild = client.GetGuild(repeater.GuildId);
if (Guild != null)
Task.Run(Run);
}
private async Task Run()
{
source = new CancellationTokenSource();
token = source.Token;
try
{
while (!token.IsCancellationRequested)
{
await Task.Delay(Repeater.Interval, token).ConfigureAwait(false);
await Trigger().ConfigureAwait(false);
}
}
catch (OperationCanceledException)
{
}
}
public async Task Trigger()
{
var toSend = "🔄 " + Repeater.Message;
//var lastMsgInChannel = (await Channel.GetMessagesAsync(2)).FirstOrDefault();
// if (lastMsgInChannel.Id == oldMsg?.Id) //don't send if it's the same message in the channel
// continue;
if (oldMsg != null)
try
{
await oldMsg.DeleteAsync();
}
catch
{
// ignored
}
try
{
if (Channel == null)
Channel = Guild.GetTextChannel(Repeater.ChannelId);
if (Channel != null)
oldMsg = await Channel.SendMessageAsync(toSend.SanitizeMentions()).ConfigureAwait(false);
}
catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.Forbidden)
{
_log.Warn("Missing permissions. Repeater stopped. ChannelId : {0}", Channel?.Id);
return;
}
catch (HttpException ex) when (ex.HttpCode == System.Net.HttpStatusCode.NotFound)
{
_log.Warn("Channel not found. Repeater stopped. ChannelId : {0}", Channel?.Id);
return;
}
catch (Exception ex)
{
_log.Warn(ex);
}
}
public void Reset()
{
source.Cancel();
var _ = Task.Run(Run);
}
public void Stop()
{
source.Cancel();
}
public override string ToString() =>
$"{Channel?.Mention ?? $"<#{Repeater.ChannelId}>" } " +
$"| {(int)Repeater.Interval.TotalHours}:{Repeater.Interval:mm} " +
$"| {Repeater.Message.TrimTo(33)}";
}
}

View File

@@ -15,10 +15,11 @@ using ImageSharp;
using System.Collections.Generic;
using Newtonsoft.Json;
using Discord.WebSocket;
using NadekoBot.Services;
using System.Diagnostics;
using NadekoBot.Modules;
using Color = Discord.Color;
namespace NadekoBot.Modules.Utility
namespace NadekoBot.Services.Utility
{
public partial class Utility : NadekoTopLevelModule
{
@@ -164,7 +165,7 @@ namespace NadekoBot.Modules.Utility
try
{
var color = hexColors[i];
await role.ModifyAsync(r => r.Color = new Discord.Color(color.R, color.G, color.B)).ConfigureAwait(false);
await role.ModifyAsync(r => r.Color = new Color(color.R, color.G, color.B)).ConfigureAwait(false);
++i;
if (i >= hexColors.Length)
i = 0;

View File

@@ -1,319 +0,0 @@
using Discord;
using Discord.WebSocket;
using NadekoBot.Extensions;
using NadekoBot.Modules.Utility.Models;
using NadekoBot.Services;
using NadekoBot.Services.Database.Models;
using Newtonsoft.Json;
using NLog;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility
{
public class UtilityService
{
public ConcurrentDictionary<ulong, ConcurrentDictionary<string, string>> AliasMaps { get; } = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, string>>();
//messagerepeater
//guildid/RepeatRunners
public ConcurrentDictionary<ulong, ConcurrentQueue<RepeatRunner>> Repeaters { get; set; }
public bool RepeaterReady { get; private set; }
//remind
public RemindService Remind { get; }
//unit conversion
public ConverterService Converter { get; }
public UtilityService(IEnumerable<GuildConfig> guildConfigs, DiscordShardedClient client, BotConfig config, DbHandler db)
{
//commandmap
AliasMaps = new ConcurrentDictionary<ulong, ConcurrentDictionary<string, string>>(
guildConfigs.ToDictionary(
x => x.GuildId,
x => new ConcurrentDictionary<string, string>(x.CommandAliases
.Distinct(new CommandAliasEqualityComparer())
.ToDictionary(ca => ca.Trigger, ca => ca.Mapping))));
//crossesrver
_client = client;
_client.MessageReceived += Client_MessageReceived;
//messagerepeater
var _ = Task.Run(async () =>
{
#if !GLOBAL_NADEKO
await Task.Delay(5000).ConfigureAwait(false);
#else
await Task.Delay(30000).ConfigureAwait(false);
#endif
//todo this is pretty terrible :kms: no time
Repeaters = new ConcurrentDictionary<ulong, ConcurrentQueue<RepeatRunner>>(guildConfigs
.ToDictionary(gc => gc.GuildId,
gc => new ConcurrentQueue<RepeatRunner>(gc.GuildRepeaters
.Select(gr => new RepeatRunner(client, gr))
.Where(x => x.Guild != null))));
RepeaterReady = true;
});
//reminder
Remind = new RemindService(client, config, db);
//unit converter
Converter = new ConverterService(db);
}
private async Task Client_MessageReceived(Discord.WebSocket.SocketMessage imsg)
{
try
{
if (imsg.Author.IsBot)
return;
var msg = imsg as IUserMessage;
if (msg == null)
return;
var channel = imsg.Channel as ITextChannel;
if (channel == null)
return;
if (msg.Author.Id == _client.CurrentUser.Id) return;
foreach (var subscriber in Subscribers)
{
var set = subscriber.Value;
if (!set.Contains(channel))
continue;
foreach (var chan in set.Except(new[] { channel }))
{
try
{
await chan.SendMessageAsync(GetMessage(channel, (IGuildUser)msg.Author,
msg)).ConfigureAwait(false);
}
catch
{
// ignored
}
}
}
}
catch
{
// ignored
}
}
private string GetMessage(ITextChannel channel, IGuildUser user, IUserMessage message) =>
$"**{channel.Guild.Name} | {channel.Name}** `{user.Username}`: " + message.Content.SanitizeMentions();
public readonly ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>> Subscribers =
new ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>>();
private DiscordShardedClient _client;
}
public class ConverterService
{
public class MeasurementUnit
{
public List<string> Triggers { get; set; }
public string UnitType { get; set; }
public decimal Modifier { get; set; }
}
public class Rates
{
public string Base { get; set; }
public DateTime Date { get; set; }
[JsonProperty("rates")]
public Dictionary<string, decimal> ConversionRates { get; set; }
}
public List<ConvertUnit> Units { get; set; } = new List<ConvertUnit>();
private readonly Logger _log;
private Timer _timer;
private readonly TimeSpan _updateInterval = new TimeSpan(12, 0, 0);
private readonly DbHandler _db;
public ConverterService(DbHandler db)
{
_log = LogManager.GetCurrentClassLogger();
_db = db;
try
{
var data = JsonConvert.DeserializeObject<List<MeasurementUnit>>(File.ReadAllText("data/units.json")).Select(u => new ConvertUnit()
{
Modifier = u.Modifier,
UnitType = u.UnitType,
InternalTrigger = string.Join("|", u.Triggers)
}).ToArray();
using (var uow = _db.UnitOfWork)
{
if (uow.ConverterUnits.Empty())
{
uow.ConverterUnits.AddRange(data);
uow.Complete();
}
}
Units = data.ToList();
}
catch (Exception ex)
{
_log.Warn("Could not load units: " + ex.Message);
}
_timer = new Timer(async (obj) => await UpdateCurrency(), null, _updateInterval, _updateInterval);
}
public static async Task<Rates> UpdateCurrencyRates()
{
using (var http = new HttpClient())
{
var res = await http.GetStringAsync("http://api.fixer.io/latest").ConfigureAwait(false);
return JsonConvert.DeserializeObject<Rates>(res);
}
}
public async Task UpdateCurrency()
{
try
{
var currencyRates = await UpdateCurrencyRates();
var unitTypeString = "currency";
var range = currencyRates.ConversionRates.Select(u => new ConvertUnit()
{
InternalTrigger = u.Key,
Modifier = u.Value,
UnitType = unitTypeString
}).ToArray();
var baseType = new ConvertUnit()
{
Triggers = new[] { currencyRates.Base },
Modifier = decimal.One,
UnitType = unitTypeString
};
var toRemove = Units.Where(u => u.UnitType == unitTypeString);
using (var uow = _db.UnitOfWork)
{
uow.ConverterUnits.RemoveRange(toRemove.ToArray());
uow.ConverterUnits.Add(baseType);
uow.ConverterUnits.AddRange(range);
await uow.CompleteAsync().ConfigureAwait(false);
}
Units.RemoveAll(u => u.UnitType == unitTypeString);
Units.Add(baseType);
Units.AddRange(range);
_log.Info("Updated Currency");
}
catch
{
_log.Warn("Failed updating currency. Ignore this.");
}
}
}
public class RemindService
{
public readonly Regex Regex = new Regex(@"^(?:(?<months>\d)mo)?(?:(?<weeks>\d)w)?(?:(?<days>\d{1,2})d)?(?:(?<hours>\d{1,2})h)?(?:(?<minutes>\d{1,2})m)?$",
RegexOptions.Compiled | RegexOptions.Multiline);
public string RemindMessageFormat { get; }
public readonly IDictionary<string, Func<Reminder, string>> _replacements = new Dictionary<string, Func<Reminder, string>>
{
{ "%message%" , (r) => r.Message },
{ "%user%", (r) => $"<@!{r.UserId}>" },
{ "%target%", (r) => r.IsPrivate ? "Direct Message" : $"<#{r.ChannelId}>"}
};
private readonly Logger _log;
private readonly CancellationTokenSource cancelSource;
private readonly CancellationToken cancelAllToken;
private readonly BotConfig _config;
private readonly DiscordShardedClient _client;
private readonly DbHandler _db;
public RemindService(DiscordShardedClient client, BotConfig config, DbHandler db)
{
_config = config;
_client = client;
_log = LogManager.GetCurrentClassLogger();
_db = db;
cancelSource = new CancellationTokenSource();
cancelAllToken = cancelSource.Token;
List<Reminder> reminders;
using (var uow = _db.UnitOfWork)
{
reminders = uow.Reminders.GetAll().ToList();
}
RemindMessageFormat = _config.RemindMessageFormat;
foreach (var r in reminders)
{
Task.Run(() => StartReminder(r));
}
}
public async Task StartReminder(Reminder r)
{
var t = cancelAllToken;
var now = DateTime.Now;
var time = r.When - now;
if (time.TotalMilliseconds > int.MaxValue)
return;
await Task.Delay(time, t).ConfigureAwait(false);
try
{
IMessageChannel ch;
if (r.IsPrivate)
{
var user = _client.GetGuild(r.ServerId).GetUser(r.ChannelId);
if (user == null)
return;
ch = await user.CreateDMChannelAsync().ConfigureAwait(false);
}
else
{
ch = _client.GetGuild(r.ServerId)?.GetTextChannel(r.ChannelId);
}
if (ch == null)
return;
await ch.SendMessageAsync(
_replacements.Aggregate(RemindMessageFormat,
(cur, replace) => cur.Replace(replace.Key, replace.Value(r)))
.SanitizeMentions()
).ConfigureAwait(false); //it works trust me
}
catch (Exception ex) { _log.Warn(ex); }
finally
{
using (var uow = _db.UnitOfWork)
{
uow.Reminders.Remove(r);
await uow.CompleteAsync();
}
}
}
}
public class CommandAliasEqualityComparer : IEqualityComparer<CommandAlias>
{
public bool Equals(CommandAlias x, CommandAlias y) => x.Trigger == y.Trigger;
public int GetHashCode(CommandAlias obj) => obj.Trigger.GetHashCode();
}
}