A lot more localization, utility module done.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user