A lot more localization, utility module done.

This commit is contained in:
Kwoth
2017-02-23 03:06:37 +01:00
parent 5cdb41b65f
commit 53140940d7
10 changed files with 787 additions and 148 deletions

View File

@@ -12,7 +12,7 @@ namespace NadekoBot.Modules.Utility
public partial class Utility
{
[Group]
public class CalcCommands : ModuleBase
public class CalcCommands : NadekoSubmodule
{
[NadekoCommand, Usage, Description, Aliases]
public async Task Calculate([Remainder] string expression)
@@ -21,9 +21,9 @@ namespace NadekoBot.Modules.Utility
expr.EvaluateParameter += Expr_EvaluateParameter;
var result = expr.Evaluate();
if (expr.Error == null)
await Context.Channel.SendConfirmAsync("Result", $"{result}");
await Context.Channel.SendConfirmAsync("⚙ " + GetText("result"), result.ToString());
else
await Context.Channel.SendErrorAsync($"⚙ Error", expr.Error);
await Context.Channel.SendErrorAsync("⚙ " + GetText("error"), expr.Error);
}
private static void Expr_EvaluateParameter(string name, NCalc.ParameterArgs args)
@@ -42,29 +42,26 @@ namespace NadekoBot.Modules.Utility
[NadekoCommand, Usage, Description, Aliases]
public async Task CalcOps()
{
var selection = typeof(Math).GetTypeInfo().GetMethods().Except(typeof(object).GetTypeInfo().GetMethods()).Distinct(new MethodInfoEqualityComparer()).Select(x =>
{
return x.Name;
})
.Except(new[] { "ToString",
"Equals",
"GetHashCode",
"GetType"});
await Context.Channel.SendConfirmAsync("Available functions in calc", string.Join(", ", selection));
var selection = typeof(Math).GetTypeInfo()
.GetMethods()
.Distinct(new MethodInfoEqualityComparer())
.Select(x => x.Name)
.Except(new[]
{
"ToString",
"Equals",
"GetHashCode",
"GetType"
});
await Context.Channel.SendConfirmAsync(GetText("utility_calcops", Prefix), string.Join(", ", selection));
}
}
class MethodInfoEqualityComparer : IEqualityComparer<MethodInfo>
private class MethodInfoEqualityComparer : IEqualityComparer<MethodInfo>
{
public bool Equals(MethodInfo x, MethodInfo y) => x.Name == y.Name;
public int GetHashCode(MethodInfo obj) => obj.Name.GetHashCode();
}
class ExpressionContext
{
public double Pi { get; set; } = Math.PI;
}
}
}

View File

@@ -3,8 +3,6 @@ using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NLog;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
@@ -14,12 +12,11 @@ namespace NadekoBot.Modules.Utility
public partial class Utility
{
[Group]
public class CrossServerTextChannel : ModuleBase
public class CrossServerTextChannel : NadekoSubmodule
{
static CrossServerTextChannel()
{
_log = LogManager.GetCurrentClassLogger();
NadekoBot.Client.MessageReceived += async (imsg) =>
NadekoBot.Client.MessageReceived += async imsg =>
{
try
{
@@ -37,23 +34,32 @@ namespace NadekoBot.Modules.Utility
var set = subscriber.Value;
if (!set.Contains(channel))
continue;
foreach (var chan in set.Except(new[] { channel }))
foreach (var chan in set.Except(new[] {channel}))
{
try { await chan.SendMessageAsync(GetText(channel.Guild, channel, (IGuildUser)msg.Author, msg)).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
try
{
await chan.SendMessageAsync(GetMessage(channel, (IGuildUser) msg.Author,
msg)).ConfigureAwait(false);
}
catch
{
// ignored
}
}
}
}
catch (Exception ex) {
_log.Warn(ex);
catch
{
// ignored
}
};
}
private static string GetText(IGuild server, ITextChannel channel, IGuildUser user, IUserMessage message) =>
$"**{server.Name} | {channel.Name}** `{user.Username}`: " + message.Content.SanitizeMentions();
public static readonly ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>> Subscribers = new ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>>();
private static Logger _log { get; }
private static string GetMessage(ITextChannel channel, IGuildUser user, IUserMessage message) =>
$"**{channel.Guild.Name} | {channel.Name}** `{user.Username}`: " + message.Content.SanitizeMentions();
public static readonly ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>> Subscribers =
new ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>>();
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
@@ -64,8 +70,9 @@ namespace NadekoBot.Modules.Utility
var set = new ConcurrentHashSet<ITextChannel>();
if (Subscribers.TryAdd(token, set))
{
set.Add((ITextChannel)Context.Channel);
await ((IGuildUser)Context.User).SendConfirmAsync("This is your CSC token", token.ToString()).ConfigureAwait(false);
set.Add((ITextChannel) Context.Channel);
await ((IGuildUser) Context.User).SendConfirmAsync(GetText("csc_token"), token.ToString())
.ConfigureAwait(false);
}
}
@@ -77,8 +84,8 @@ namespace NadekoBot.Modules.Utility
ConcurrentHashSet<ITextChannel> set;
if (!Subscribers.TryGetValue(token, out set))
return;
set.Add((ITextChannel)Context.Channel);
await Context.Channel.SendConfirmAsync("Joined cross server channel.").ConfigureAwait(false);
set.Add((ITextChannel) Context.Channel);
await ReplyConfirmLocalized("csc_join").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
@@ -88,9 +95,9 @@ namespace NadekoBot.Modules.Utility
{
foreach (var subscriber in Subscribers)
{
subscriber.Value.TryRemove((ITextChannel)Context.Channel);
subscriber.Value.TryRemove((ITextChannel) Context.Channel);
}
await Context.Channel.SendMessageAsync("Left cross server channel.").ConfigureAwait(false);
await ReplyConfirmLocalized("csc_leave").ConfigureAwait(false);
}
}
}

View File

@@ -12,7 +12,7 @@ namespace NadekoBot.Modules.Utility
public partial class Utility
{
[Group]
public class InfoCommands : ModuleBase
public class InfoCommands : NadekoSubmodule
{
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
@@ -24,7 +24,7 @@ namespace NadekoBot.Modules.Utility
if (string.IsNullOrWhiteSpace(guildName))
guild = channel.Guild;
else
guild = NadekoBot.Client.GetGuilds().Where(g => g.Name.ToUpperInvariant() == guildName.ToUpperInvariant()).FirstOrDefault();
guild = NadekoBot.Client.GetGuilds().FirstOrDefault(g => g.Name.ToUpperInvariant() == guildName.ToUpperInvariant());
if (guild == null)
return;
var ownername = await guild.GetUserAsync(guild.OwnerId);
@@ -37,22 +37,22 @@ namespace NadekoBot.Modules.Utility
if (string.IsNullOrWhiteSpace(features))
features = "-";
var embed = new EmbedBuilder()
.WithAuthor(eab => eab.WithName("Server Info"))
.WithAuthor(eab => eab.WithName(GetText("server_info")))
.WithTitle(guild.Name)
.AddField(fb => fb.WithName("**ID**").WithValue(guild.Id.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName("**Owner**").WithValue(ownername.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName("**Members**").WithValue(users.Count.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName("**Text Channels**").WithValue(textchn.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName("**Voice Channels**").WithValue(voicechn.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt:dd.MM.yyyy HH:mm}").WithIsInline(true))
.AddField(fb => fb.WithName("**Region**").WithValue(guild.VoiceRegionId.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName("**Roles**").WithValue((guild.Roles.Count - 1).ToString()).WithIsInline(true))
.AddField(fb => fb.WithName("**Features**").WithValue(features).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("id")).WithValue(guild.Id.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("owner")).WithValue(ownername.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("members")).WithValue(users.Count.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("text_channels")).WithValue(textchn.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("voice_channels")).WithValue(voicechn.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("created_at")).WithValue($"{createdAt:dd.MM.yyyy HH:mm}").WithIsInline(true))
.AddField(fb => fb.WithName(GetText("region")).WithValue(guild.VoiceRegionId.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("roles")).WithValue((guild.Roles.Count - 1).ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("features")).WithValue(features).WithIsInline(true))
.WithImageUrl(guild.IconUrl)
.WithColor(NadekoBot.OkColor);
if (guild.Emojis.Any())
{
embed.AddField(fb => fb.WithName($"**Custom Emojis ({guild.Emojis.Count})**").WithValue(string.Join(" ", guild.Emojis.Shuffle().Take(20).Select(e => $"{e.Name} <:{e.Name}:{e.Id}>"))));
embed.AddField(fb => fb.WithName(GetText("custom_emojis") + $"({guild.Emojis.Count})").WithValue(string.Join(" ", guild.Emojis.Shuffle().Take(20).Select(e => $"{e.Name} <:{e.Name}:{e.Id}>"))));
}
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
@@ -69,9 +69,9 @@ namespace NadekoBot.Modules.Utility
var embed = new EmbedBuilder()
.WithTitle(ch.Name)
.WithDescription(ch.Topic?.SanitizeMentions())
.AddField(fb => fb.WithName("**ID**").WithValue(ch.Id.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt:dd.MM.yyyy HH:mm}").WithIsInline(true))
.AddField(fb => fb.WithName("**Users**").WithValue(usercount.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("id")).WithValue(ch.Id.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("created_at")).WithValue($"{createdAt:dd.MM.yyyy HH:mm}").WithIsInline(true))
.AddField(fb => fb.WithName(GetText("users")).WithValue(usercount.ToString()).WithIsInline(true))
.WithColor(NadekoBot.OkColor);
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
}
@@ -86,15 +86,15 @@ namespace NadekoBot.Modules.Utility
return;
var embed = new EmbedBuilder()
.AddField(fb => fb.WithName("**Name**").WithValue($"**{user.Username}**#{user.Discriminator}").WithIsInline(true));
.AddField(fb => fb.WithName(GetText("name")).WithValue($"**{user.Username}**#{user.Discriminator}").WithIsInline(true));
if (!string.IsNullOrWhiteSpace(user.Nickname))
{
embed.AddField(fb => fb.WithName("**Nickname**").WithValue(user.Nickname).WithIsInline(true));
embed.AddField(fb => fb.WithName(GetText("nickname")).WithValue(user.Nickname).WithIsInline(true));
}
embed.AddField(fb => fb.WithName("**ID**").WithValue(user.Id.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName("**Joined Server**").WithValue($"{user.JoinedAt?.ToString("dd.MM.yyyy HH:mm") ?? "unavail."}").WithIsInline(true))
.AddField(fb => fb.WithName("**Joined Discord**").WithValue($"{user.CreatedAt:dd.MM.yyyy HH:mm}").WithIsInline(true))
.AddField(fb => fb.WithName("**Roles**").WithValue($"**({user.RoleIds.Count - 1})** - {string.Join("\n", user.GetRoles().Take(10).Where(r => r.Id != r.Guild.EveryoneRole.Id).Select(r => r.Name)).SanitizeMentions()}").WithIsInline(true))
embed.AddField(fb => fb.WithName(GetText("id")).WithValue(user.Id.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName(GetText("joined_server")).WithValue($"{user.JoinedAt?.ToString("dd.MM.yyyy HH:mm") ?? "?"}").WithIsInline(true))
.AddField(fb => fb.WithName(GetText("joined_discord")).WithValue($"{user.CreatedAt:dd.MM.yyyy HH:mm}").WithIsInline(true))
.AddField(fb => fb.WithName(GetText("roles")).WithValue($"**({user.RoleIds.Count - 1})** - {string.Join("\n", user.GetRoles().Take(10).Where(r => r.Id != r.Guild.EveryoneRole.Id).Select(r => r.Name)).SanitizeMentions()}").WithIsInline(true))
.WithColor(NadekoBot.OkColor);
if (user.AvatarId != null)
@@ -119,12 +119,17 @@ namespace NadekoBot.Modules.Utility
StringBuilder str = new StringBuilder();
foreach (var kvp in NadekoBot.CommandHandler.UserMessagesSent.OrderByDescending(kvp => kvp.Value).Skip(page*activityPerPage).Take(activityPerPage))
{
str.AppendLine($"`{++startCount}.` **{kvp.Key}** [{kvp.Value/NadekoBot.Stats.GetUptime().TotalSeconds:F2}/s] - {kvp.Value} total");
str.AppendLine(GetText("activity_line",
++startCount,
Format.Bold(kvp.Key.ToString()),
kvp.Value / NadekoBot.Stats.GetUptime().TotalSeconds, kvp.Value));
}
await Context.Channel.EmbedAsync(new EmbedBuilder().WithTitle($"Activity Page #{page}")
await Context.Channel.EmbedAsync(new EmbedBuilder()
.WithTitle(GetText("activity_page", page))
.WithOkColor()
.WithFooter(efb => efb.WithText($"{NadekoBot.CommandHandler.UserMessagesSent.Count} users total."))
.WithFooter(efb => efb.WithText(GetText("activity_users_total",
NadekoBot.CommandHandler.UserMessagesSent.Count)))
.WithDescription(str.ToString()));
}
}

View File

@@ -5,12 +5,10 @@ using Microsoft.EntityFrameworkCore;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services;
using NadekoBot.Services.Database;
using NadekoBot.Services.Database.Models;
using NLog;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
@@ -22,14 +20,16 @@ namespace NadekoBot.Modules.Utility
public partial class Utility
{
[Group]
public class RepeatCommands : ModuleBase
public class RepeatCommands : NadekoSubmodule
{
//guildid/RepeatRunners
public static ConcurrentDictionary<ulong, ConcurrentQueue<RepeatRunner>> repeaters { get; }
public static ConcurrentDictionary<ulong, ConcurrentQueue<RepeatRunner>> Repeaters { get; set; }
private static bool _ready;
public class RepeatRunner
{
private Logger _log { get; }
private readonly Logger _log;
private CancellationTokenSource source { get; set; }
private CancellationToken token { get; set; }
@@ -39,8 +39,16 @@ namespace NadekoBot.Modules.Utility
public RepeatRunner(Repeater repeater, ITextChannel channel = null)
{
_log = LogManager.GetCurrentClassLogger();
this.Repeater = repeater;
this.Channel = channel ?? NadekoBot.Client.GetGuild(repeater.GuildId)?.GetTextChannel(repeater.ChannelId);
Repeater = repeater;
//if (channel == null)
//{
// var guild = NadekoBot.Client.GetGuild(repeater.GuildId);
// Channel = guild.GetTextChannel(repeater.ChannelId);
//}
//else
// Channel = channel;
Channel = channel ?? NadekoBot.Client.GetGuild(repeater.GuildId)?.GetTextChannel(repeater.ChannelId);
if (Channel == null)
return;
Task.Run(Run);
@@ -101,22 +109,21 @@ namespace NadekoBot.Modules.Utility
public override string ToString()
{
return $"{this.Channel.Mention} | {(int)this.Repeater.Interval.TotalHours}:{this.Repeater.Interval:mm} | {this.Repeater.Message.TrimTo(33)}";
return $"{Channel.Mention} | {(int)Repeater.Interval.TotalHours}:{Repeater.Interval:mm} | {Repeater.Message.TrimTo(33)}";
}
}
static RepeatCommands()
{
var _log = LogManager.GetCurrentClassLogger();
var sw = Stopwatch.StartNew();
repeaters = new ConcurrentDictionary<ulong, ConcurrentQueue<RepeatRunner>>(NadekoBot.AllGuildConfigs
.ToDictionary(gc => gc.GuildId,
gc => new ConcurrentQueue<RepeatRunner>(gc.GuildRepeaters.Select(gr => new RepeatRunner(gr))
.Where(gr => gr.Channel != null))));
sw.Stop();
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
var _ = Task.Run(async () =>
{
await Task.Delay(5000).ConfigureAwait(false);
Repeaters = new ConcurrentDictionary<ulong, ConcurrentQueue<RepeatRunner>>(NadekoBot.AllGuildConfigs
.ToDictionary(gc => gc.GuildId,
gc => new ConcurrentQueue<RepeatRunner>(gc.GuildRepeaters.Select(gr => new RepeatRunner(gr))
.Where(gr => gr.Channel != null))));
_ready = true;
});
}
[NadekoCommand, Usage, Description, Aliases]
@@ -124,11 +131,13 @@ namespace NadekoBot.Modules.Utility
[RequireUserPermission(GuildPermission.ManageMessages)]
public async Task RepeatInvoke(int index)
{
if (!_ready)
return;
index -= 1;
ConcurrentQueue<RepeatRunner> rep;
if (!repeaters.TryGetValue(Context.Guild.Id, out rep))
if (!Repeaters.TryGetValue(Context.Guild.Id, out rep))
{
await Context.Channel.SendErrorAsync(" **No repeating message found on this server.**").ConfigureAwait(false);
await ReplyErrorLocalized("repeat_invoke_none").ConfigureAwait(false);
return;
}
@@ -136,7 +145,7 @@ namespace NadekoBot.Modules.Utility
if (index >= repList.Count)
{
await Context.Channel.SendErrorAsync("Index out of range.").ConfigureAwait(false);
await ReplyErrorLocalized("index_out_of_range").ConfigureAwait(false);
return;
}
var repeater = repList[index].Repeater;
@@ -151,19 +160,21 @@ namespace NadekoBot.Modules.Utility
[Priority(0)]
public async Task RepeatRemove(int index)
{
if (!_ready)
return;
if (index < 1)
return;
index -= 1;
ConcurrentQueue<RepeatRunner> rep;
if (!repeaters.TryGetValue(Context.Guild.Id, out rep))
if (!Repeaters.TryGetValue(Context.Guild.Id, out rep))
return;
var repeaterList = rep.ToList();
if (index >= repeaterList.Count)
{
await Context.Channel.SendErrorAsync("Index out of range.").ConfigureAwait(false);
await ReplyErrorLocalized("index_out_of_range").ConfigureAwait(false);
return;
}
@@ -179,8 +190,9 @@ namespace NadekoBot.Modules.Utility
await uow.CompleteAsync().ConfigureAwait(false);
}
if (repeaters.TryUpdate(Context.Guild.Id, new ConcurrentQueue<RepeatRunner>(repeaterList), rep))
await Context.Channel.SendConfirmAsync("Message Repeater",$"#{index+1} stopped.\n\n{repeater.ToString()}").ConfigureAwait(false);
if (Repeaters.TryUpdate(Context.Guild.Id, new ConcurrentQueue<RepeatRunner>(repeaterList), rep))
await Context.Channel.SendConfirmAsync(GetText("message_repeater"),
GetText("repeater_stopped" , index + 1) + $"\n\n{repeater}").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
@@ -189,6 +201,8 @@ namespace NadekoBot.Modules.Utility
[Priority(1)]
public async Task Repeat(int minutes, [Remainder] string message)
{
if (!_ready)
return;
if (minutes < 1 || minutes > 10080)
return;
@@ -216,13 +230,18 @@ namespace NadekoBot.Modules.Utility
var rep = new RepeatRunner(toAdd, (ITextChannel)Context.Channel);
repeaters.AddOrUpdate(Context.Guild.Id, new ConcurrentQueue<RepeatRunner>(new[] { rep }), (key, old) =>
Repeaters.AddOrUpdate(Context.Guild.Id, new ConcurrentQueue<RepeatRunner>(new[] { rep }), (key, old) =>
{
old.Enqueue(rep);
return old;
});
await Context.Channel.SendConfirmAsync($"🔁 Repeating **\"{rep.Repeater.Message}\"** every `{rep.Repeater.Interval.Days} day(s), {rep.Repeater.Interval.Hours} hour(s) and {rep.Repeater.Interval.Minutes} minute(s)`.").ConfigureAwait(false);
await Context.Channel.SendConfirmAsync(
"🔁 " + GetText("repeater",
Format.Bold(rep.Repeater.Message),
Format.Bold(rep.Repeater.Interval.Days.ToString()),
Format.Bold(rep.Repeater.Interval.Hours.ToString()),
Format.Bold(rep.Repeater.Interval.Minutes.ToString()))).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
@@ -230,27 +249,33 @@ namespace NadekoBot.Modules.Utility
[RequireUserPermission(GuildPermission.ManageMessages)]
public async Task RepeatList()
{
if (!_ready)
return;
ConcurrentQueue<RepeatRunner> repRunners;
if (!repeaters.TryGetValue(Context.Guild.Id, out repRunners))
if (!Repeaters.TryGetValue(Context.Guild.Id, out repRunners))
{
await Context.Channel.SendConfirmAsync("No repeaters running on this server.").ConfigureAwait(false);
await ReplyConfirmLocalized("repeaters_none").ConfigureAwait(false);
return;
}
var replist = repRunners.ToList();
var sb = new StringBuilder();
for (int i = 0; i < replist.Count; i++)
for (var i = 0; i < replist.Count; i++)
{
var rep = replist[i];
sb.AppendLine($"`{i + 1}.` {rep.ToString()}");
sb.AppendLine($"`{i + 1}.` {rep}");
}
var desc = sb.ToString();
if (string.IsNullOrWhiteSpace(desc))
desc = GetText("no_active_repeaters");
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle("List Of Repeaters")
.WithDescription(sb.ToString()))
.ConfigureAwait(false);
.WithTitle(GetText("list_of_repeaters"))
.WithDescription(desc))
.ConfigureAwait(false);
}
}
}

View File

@@ -33,10 +33,11 @@ namespace NadekoBot.Modules.Utility
}
if (quotes.Any())
await Context.Channel.SendConfirmAsync($"💬 **Page {page + 1} of quotes:**\n```xl\n" + String.Join("\n", quotes.Select((q) => $"{q.Keyword,-20} by {q.AuthorName}")) + "\n```")
await Context.Channel.SendConfirmAsync(GetText("quotes_page", page + 1),
string.Join("\n", quotes.Select(q => $"{q.Keyword,-20} by {q.AuthorName}")))
.ConfigureAwait(false);
else
await Context.Channel.SendErrorAsync("No quotes on this page.").ConfigureAwait(false);
await ReplyErrorLocalized("quotes_page_none").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
@@ -72,11 +73,11 @@ namespace NadekoBot.Modules.Utility
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireContext(ContextType.Guild)]
public async Task SearchQuote(string keyword, [Remainder] string text)
{
if (string.IsNullOrWhiteSpace(keyword) || string.IsNullOrWhiteSpace(text))
return;
if (string.IsNullOrWhiteSpace(keyword) || string.IsNullOrWhiteSpace(text))
return;
keyword = keyword.ToUpperInvariant();
@@ -113,7 +114,7 @@ namespace NadekoBot.Modules.Utility
});
await uow.CompleteAsync().ConfigureAwait(false);
}
await Context.Channel.SendConfirmAsync("✅ Quote added.").ConfigureAwait(false);
await ReplyConfirmLocalized("quote_added").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
@@ -135,7 +136,7 @@ namespace NadekoBot.Modules.Utility
if (qs == null || !qs.Any())
{
sucess = false;
response = "No quotes found which you can remove.";
response = GetText("quotes_remove_none");
}
else
{
@@ -144,7 +145,7 @@ namespace NadekoBot.Modules.Utility
uow.Quotes.Remove(q);
await uow.CompleteAsync().ConfigureAwait(false);
sucess = true;
response = "🗑 **Deleted a random quote.**";
response = GetText("deleted_quote");
}
}
if(sucess)
@@ -172,7 +173,7 @@ namespace NadekoBot.Modules.Utility
await uow.CompleteAsync();
}
await Context.Channel.SendConfirmAsync($"🗑 **Deleted all quotes** with **{keyword}** keyword.");
await ReplyConfirmLocalized("quotes_deleted", Format.Bold(keyword)).ConfigureAwait(false);
}
}
}

View File

@@ -17,21 +17,21 @@ namespace NadekoBot.Modules.Utility
public partial class Utility
{
[Group]
public class RemindCommands : ModuleBase
public class RemindCommands : NadekoSubmodule
{
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)?$",
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);
private static string RemindMessageFormat { get; }
private static string remindMessageFormat { get; }
private static IDictionary<string, Func<Reminder, string>> replacements = new Dictionary<string, Func<Reminder, string>>
private static 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 static Logger _log { get; }
private new static readonly Logger _log;
static RemindCommands()
{
@@ -41,7 +41,7 @@ namespace NadekoBot.Modules.Utility
{
reminders = uow.Reminders.GetAll().ToList();
}
RemindMessageFormat = NadekoBot.BotConfig.RemindMessageFormat;
remindMessageFormat = NadekoBot.BotConfig.RemindMessageFormat;
foreach (var r in reminders)
{
@@ -58,10 +58,10 @@ namespace NadekoBot.Modules.Utility
if (time.TotalMilliseconds > int.MaxValue)
return;
await Task.Delay(time);
await Task.Delay(time).ConfigureAwait(false);
try
{
IMessageChannel ch = null;
IMessageChannel ch;
if (r.IsPrivate)
{
ch = await NadekoBot.Client.GetDMChannelAsync(r.ChannelId).ConfigureAwait(false);
@@ -74,7 +74,7 @@ namespace NadekoBot.Modules.Utility
return;
await ch.SendMessageAsync(
replacements.Aggregate(RemindMessageFormat,
_replacements.Aggregate(remindMessageFormat,
(cur, replace) => cur.Replace(replace.Key, replace.Value(r)))
.SanitizeMentions()
).ConfigureAwait(false); //it works trust me
@@ -119,27 +119,21 @@ namespace NadekoBot.Modules.Utility
{
var channel = (ITextChannel)Context.Channel;
if (ch == null)
{
await channel.SendErrorAsync($"{Context.User.Mention} Something went wrong (channel cannot be found) ;(").ConfigureAwait(false);
return;
}
var m = regex.Match(timeStr);
var m = _regex.Match(timeStr);
if (m.Length == 0)
{
await channel.SendErrorAsync("Not a valid time format. Type `-h .remind`").ConfigureAwait(false);
await ReplyErrorLocalized("remind_invalid_format").ConfigureAwait(false);
return;
}
string output = "";
var namesAndValues = new Dictionary<string, int>();
foreach (var groupName in regex.GetGroupNames())
foreach (var groupName in _regex.GetGroupNames())
{
if (groupName == "0") continue;
int value = 0;
int value;
int.TryParse(m.Groups[groupName].Value, out value);
if (string.IsNullOrEmpty(m.Groups[groupName].Value))
@@ -147,7 +141,7 @@ namespace NadekoBot.Modules.Utility
namesAndValues[groupName] = 0;
continue;
}
else if (value < 1 ||
if (value < 1 ||
(groupName == "months" && value > 1) ||
(groupName == "weeks" && value > 4) ||
(groupName == "days" && value >= 7) ||
@@ -157,8 +151,7 @@ namespace NadekoBot.Modules.Utility
await channel.SendErrorAsync($"Invalid {groupName} value.").ConfigureAwait(false);
return;
}
else
namesAndValues[groupName] = value;
namesAndValues[groupName] = value;
output += m.Groups[groupName].Value + " " + groupName + " ";
}
var time = DateTime.Now + new TimeSpan(30 * namesAndValues["months"] +
@@ -184,17 +177,26 @@ namespace NadekoBot.Modules.Utility
await uow.CompleteAsync();
}
try { await channel.SendConfirmAsync($"⏰ I will remind **\"{(ch is ITextChannel ? ((ITextChannel)ch).Name : Context.User.Username)}\"** to **\"{message.SanitizeMentions()}\"** in **{output}** `({time:d.M.yyyy.} at {time:HH:mm})`").ConfigureAwait(false); } catch { }
try
{
await channel.SendConfirmAsync(
"⏰ " + GetText("remind",
Format.Bold(ch is ITextChannel ? ((ITextChannel) ch).Name : Context.User.Username),
Format.Bold(message.SanitizeMentions()),
Format.Bold(output),
time, time)).ConfigureAwait(false);
}
catch
{
// ignored
}
await StartReminder(rem);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[OwnerOnly]
public async Task RemindTemplate([Remainder] string arg)
{
var channel = (ITextChannel)Context.Channel;
if (string.IsNullOrWhiteSpace(arg))
return;
@@ -203,7 +205,8 @@ namespace NadekoBot.Modules.Utility
uow.BotConfig.GetOrCreate().RemindMessageFormat = arg.Trim();
await uow.CompleteAsync().ConfigureAwait(false);
}
await channel.SendConfirmAsync("🆗 New remind template set.");
await ReplyConfirmLocalized("remind_template").ConfigureAwait(false);
}
}
}

View File

@@ -9,7 +9,6 @@ using Newtonsoft.Json;
using NLog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
@@ -21,12 +20,12 @@ namespace NadekoBot.Modules.Utility
public partial class Utility
{
[Group]
public class UnitConverterCommands : ModuleBase
public class UnitConverterCommands : NadekoSubmodule
{
public static List<ConvertUnit> Units { get; set; } = new List<ConvertUnit>();
private static Logger _log { get; }
private new static readonly Logger _log;
private static Timer _timer;
private static TimeSpan updateInterval = new TimeSpan(12, 0, 0);
private static readonly TimeSpan _updateInterval = new TimeSpan(12, 0, 0);
static UnitConverterCommands()
{
@@ -55,7 +54,7 @@ namespace NadekoBot.Modules.Utility
_log.Warn("Could not load units: " + e.Message);
}
_timer = new Timer(async (obj) => await UpdateCurrency(), null, (int)updateInterval.TotalMilliseconds, (int)updateInterval.TotalMilliseconds);
_timer = new Timer(async (obj) => await UpdateCurrency(), null, _updateInterval, _updateInterval);
}
public static async Task UpdateCurrency()
@@ -93,7 +92,7 @@ namespace NadekoBot.Modules.Utility
}
catch
{
_log.Warn("Failed updating currency.");
_log.Warn("Failed updating currency. Ignore this.");
}
}
@@ -101,7 +100,7 @@ namespace NadekoBot.Modules.Utility
public async Task ConvertList()
{
var res = Units.GroupBy(x => x.UnitType)
.Aggregate(new EmbedBuilder().WithTitle("__Units which can be used by the converter__")
.Aggregate(new EmbedBuilder().WithTitle(GetText("convertlist"))
.WithColor(NadekoBot.OkColor),
(embed, g) => embed.AddField(efb =>
efb.WithName(g.Key.ToTitleCase())
@@ -116,12 +115,12 @@ namespace NadekoBot.Modules.Utility
var targetUnit = Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(target.ToLowerInvariant()));
if (originUnit == null || targetUnit == null)
{
await Context.Channel.SendErrorAsync(string.Format("Cannot convert {0} to {1}: units not found", origin, target));
await ReplyErrorLocalized("convert_not_found", Format.Bold(origin), Format.Bold(target)).ConfigureAwait(false);
return;
}
if (originUnit.UnitType != targetUnit.UnitType)
{
await Context.Channel.SendErrorAsync(string.Format("Cannot convert {0} to {1}: types of unit are not equal", originUnit.Triggers.First(), targetUnit.Triggers.First()));
await ReplyErrorLocalized("convert_type_error", Format.Bold(originUnit.Triggers.First()), Format.Bold(targetUnit.Triggers.First())).ConfigureAwait(false);
return;
}
decimal res;
@@ -150,8 +149,6 @@ namespace NadekoBot.Modules.Utility
case "F":
res = res * (9m / 5m) - 459.67m;
break;
default:
break;
}
}
else
@@ -165,7 +162,7 @@ namespace NadekoBot.Modules.Utility
}
res = Math.Round(res, 4);
await Context.Channel.SendConfirmAsync(string.Format("{0} {1} is equal to {2} {3}", value, (originUnit.Triggers.First() + "s").SnPl(value.IsInteger() ? (int)value : 2), res, (targetUnit.Triggers.First() + "s").SnPl(res.IsInteger() ? (int)res : 2)));
await Context.Channel.SendConfirmAsync(GetText("convert", value, (originUnit.Triggers.First()).SnPl(value.IsInteger() ? (int)value : 2), res, (targetUnit.Triggers.First() + "s").SnPl(res.IsInteger() ? (int)res : 2)));
}
}