Message forwarding with appropriate commands

This commit is contained in:
Kwoth 2016-10-10 10:06:06 +02:00
parent 6f0a78613e
commit e92db040be
5 changed files with 199 additions and 4 deletions

View File

@ -0,0 +1,89 @@
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Services;
using NadekoBot.Services.Database;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Administration
{
public partial class Administration
{
[Group]
public class DMForwardCommands
{
private static bool ForwardDMs { get; set; }
private static bool ForwardDMsToAllOwners { get; set; }
static DMForwardCommands()
{
using (var uow = DbHandler.UnitOfWork())
{
var config = uow.BotConfig.GetOrCreate();
ForwardDMs = config.ForwardMessages;
ForwardDMsToAllOwners = config.ForwardToAllOwners;
}
}
[NadekoCommand, Usage, Description, Aliases]
[OwnerOnly]
public async Task ForwardMessages(IUserMessage imsg)
{
var channel = imsg.Channel;
using (var uow = DbHandler.UnitOfWork())
{
var config = uow.BotConfig.GetOrCreate();
ForwardDMs = config.ForwardMessages = !config.ForwardMessages;
uow.Complete();
}
if (ForwardDMs)
await channel.SendMessageAsync("`I will forward DMs from now on.`").ConfigureAwait(false);
else
await channel.SendMessageAsync("`I will stop forwarding DMs.`").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[OwnerOnly]
public async Task ForwardToAll(IUserMessage imsg)
{
var channel = imsg.Channel;
using (var uow = DbHandler.UnitOfWork())
{
var config = uow.BotConfig.GetOrCreate();
ForwardDMsToAllOwners = config.ForwardToAllOwners = !config.ForwardToAllOwners;
uow.Complete();
}
if (ForwardDMsToAllOwners)
await channel.SendMessageAsync("`I will forward DMs to all owners.`").ConfigureAwait(false);
else
await channel.SendMessageAsync("`I will forward DMs only to the first owner.`").ConfigureAwait(false);
}
public static async Task HandleDMForwarding(IMessage msg, List<IDMChannel> ownerChannels)
{
if (ForwardDMs && ownerChannels.Any())
{
var toSend = $"`I received a message from {msg.Author} ({msg.Author.Id})`: {msg.Content}";
if (ForwardDMsToAllOwners)
{
var msgs = await Task.WhenAll(ownerChannels.Where(ch => ch.Recipient.Id != msg.Author.Id)
.Select(ch => ch.SendMessageAsync(toSend))).ConfigureAwait(false);
}
else
{
var firstOwnerChannel = ownerChannels.First();
if (firstOwnerChannel.Recipient.Id != msg.Author.Id)
try { await firstOwnerChannel.SendMessageAsync(msg.Content).ConfigureAwait(false); } catch { }
}
}
}
}
}
}

View File

@ -88,6 +88,9 @@ namespace NadekoBot
{
ModulePrefixes = new ReadOnlyDictionary<string, string>(uow.BotConfig.GetOrCreate().ModulePrefixes.ToDictionary(m => m.ModuleName, m => m.Prefix));
}
// start handling messages received in commandhandler
await CommandHandler.StartHandling();
await CommandService.LoadAssembly(Assembly.GetEntryAssembly(), depMap).ConfigureAwait(false);
Console.WriteLine(await Stats.Print().ConfigureAwait(false));

View File

@ -2381,6 +2381,60 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to fwmsgs.
/// </summary>
public static string forwardmessages_cmd {
get {
return ResourceManager.GetString("forwardmessages_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Toggles forwarding of non-command messages sent to bot&apos;s DM to the bot owners.
/// </summary>
public static string forwardmessages_desc {
get {
return ResourceManager.GetString("forwardmessages_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `.fwmsgs`.
/// </summary>
public static string forwardmessages_usage {
get {
return ResourceManager.GetString("forwardmessages_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to fwtoall.
/// </summary>
public static string forwardtoall_cmd {
get {
return ResourceManager.GetString("forwardtoall_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Toggles whether messages will be forwarded to all bot owners or only to the first one specified in the credentials.json.
/// </summary>
public static string forwardtoall_desc {
get {
return ResourceManager.GetString("forwardtoall_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `.fwtoall`.
/// </summary>
public static string forwardtoall_usage {
get {
return ResourceManager.GetString("forwardtoall_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to gelbooru.
/// </summary>

View File

@ -2619,4 +2619,22 @@
<data name="shuffledeck_usage" xml:space="preserve">
<value>`$sh`</value>
</data>
<data name="forwardmessages_cmd" xml:space="preserve">
<value>fwmsgs</value>
</data>
<data name="forwardmessages_desc" xml:space="preserve">
<value>Toggles forwarding of non-command messages sent to bot's DM to the bot owners</value>
</data>
<data name="forwardmessages_usage" xml:space="preserve">
<value>`.fwmsgs`</value>
</data>
<data name="forwardtoall_cmd" xml:space="preserve">
<value>fwtoall</value>
</data>
<data name="forwardtoall_desc" xml:space="preserve">
<value>Toggles whether messages will be forwarded to all bot owners or only to the first one specified in the credentials.json</value>
</data>
<data name="forwardtoall_usage" xml:space="preserve">
<value>`.fwtoall`</value>
</data>
</root>

View File

@ -17,15 +17,30 @@ using NadekoBot.Extensions;
using static NadekoBot.Modules.Permissions.Permissions;
using System.Collections.Concurrent;
using NadekoBot.Modules.Help;
using static NadekoBot.Modules.Administration.Administration;
namespace NadekoBot.Services
{
public class IGuildUserComparer : IEqualityComparer<IGuildUser>
{
public bool Equals(IGuildUser x, IGuildUser y)
{
return x.Id == y.Id;
}
public int GetHashCode(IGuildUser obj)
{
return obj.Id.GetHashCode();
}
}
public class CommandHandler
{
private ShardedDiscordClient _client;
private ShardedDiscordClient _client;
private CommandService _commandService;
private Logger _log;
private List<IDMChannel> ownerChannels { get; set; }
public event EventHandler<CommandExecutedEventArgs> CommandExecuted = delegate { };
public CommandHandler(ShardedDiscordClient client, CommandService commandService)
@ -33,6 +48,20 @@ namespace NadekoBot.Services
_client = client;
_commandService = commandService;
_log = LogManager.GetCurrentClassLogger();
}
public async Task StartHandling()
{
ownerChannels = (await Task.WhenAll(_client.GetGuilds().SelectMany(g => g.GetUsers())
.Where(u => NadekoBot.Credentials.OwnerIds.Contains(u.Id))
.Distinct(new IGuildUserComparer())
.Select(async u => { try { return await u.CreateDMChannelAsync(); } catch { return null; } })))
.Where(ch => ch != null)
.ToList();
if (!ownerChannels.Any())
_log.Warn("No owner channels created! Make sure you've specified correct OwnerId in the credentials.json file.");
else
_log.Info($"Created {ownerChannels.Count} out of {NadekoBot.Credentials.OwnerIds.Length} owner message channels.");
_client.MessageReceived += MessageReceivedHandler;
}
@ -158,7 +187,7 @@ namespace NadekoBot.Services
if (guild != null && command != null && result.Error == CommandError.Exception)
{
if (verbose)
await msg.Channel.SendMessageAsync(":warning: " + result.ErrorReason).ConfigureAwait(false);
try { await msg.Channel.SendMessageAsync(":warning: " + result.ErrorReason).ConfigureAwait(false); } catch { }
}
}
else
@ -166,6 +195,8 @@ namespace NadekoBot.Services
if (msg.Channel is IPrivateChannel)
{
await msg.Channel.SendMessageAsync(Help.DMHelpString).ConfigureAwait(false);
await DMForwardCommands.HandleDMForwarding(msg, ownerChannels);
}
}
}
@ -185,7 +216,7 @@ namespace NadekoBot.Services
}
}
public async Task<Tuple<Command,IResult>> ExecuteCommand(IUserMessage message, string input, IGuild guild, IUser user, Permission rootPerm, string permRole, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Best) {
public async Task<Tuple<Command, IResult>> ExecuteCommand(IUserMessage message, string input, IGuild guild, IUser user, Permission rootPerm, string permRole, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Best) {
var searchResult = _commandService.Search(message, input);
if (!searchResult.IsSuccess)
return new Tuple<Command, IResult>(null, searchResult);