2017-07-17 19:42:36 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using Discord;
|
2017-06-28 00:44:30 +00:00
|
|
|
|
using Discord.Commands;
|
|
|
|
|
using Discord.WebSocket;
|
|
|
|
|
using NadekoBot.Extensions;
|
2017-10-15 09:48:29 +00:00
|
|
|
|
using NadekoBot.Modules.Music.Services;
|
|
|
|
|
using NadekoBot.Modules.Administration.Services;
|
2017-06-28 00:44:30 +00:00
|
|
|
|
|
2017-07-17 19:42:36 +00:00
|
|
|
|
namespace NadekoBot.Common.Replacements
|
2017-06-28 00:44:30 +00:00
|
|
|
|
{
|
|
|
|
|
public class ReplacementBuilder
|
|
|
|
|
{
|
|
|
|
|
private static readonly Regex rngRegex = new Regex("%rng(?:(?<from>(?:-)?\\d+)-(?<to>(?:-)?\\d+))?%", RegexOptions.Compiled);
|
|
|
|
|
private ConcurrentDictionary<string, Func<string>> _reps = new ConcurrentDictionary<string, Func<string>>();
|
|
|
|
|
private ConcurrentDictionary<Regex, Func<Match, string>> _regex = new ConcurrentDictionary<Regex, Func<Match, string>>();
|
|
|
|
|
|
|
|
|
|
public ReplacementBuilder()
|
|
|
|
|
{
|
|
|
|
|
WithRngRegex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ReplacementBuilder WithDefault(IUser usr, IMessageChannel ch, IGuild g, DiscordSocketClient client)
|
|
|
|
|
{
|
|
|
|
|
return this.WithUser(usr)
|
|
|
|
|
.WithChannel(ch)
|
2017-07-05 11:17:59 +00:00
|
|
|
|
.WithServer(client, g)
|
2017-06-28 00:44:30 +00:00
|
|
|
|
.WithClient(client);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ReplacementBuilder WithDefault(ICommandContext ctx) =>
|
|
|
|
|
WithDefault(ctx.User, ctx.Channel, ctx.Guild, (DiscordSocketClient)ctx.Client);
|
|
|
|
|
|
|
|
|
|
public ReplacementBuilder WithClient(DiscordSocketClient client)
|
|
|
|
|
{
|
|
|
|
|
_reps.TryAdd("%mention%", () => $"<@{client.CurrentUser.Id}>");
|
|
|
|
|
_reps.TryAdd("%shardid%", () => client.ShardId.ToString());
|
|
|
|
|
_reps.TryAdd("%time%", () => DateTime.Now.ToString("HH:mm " + TimeZoneInfo.Local.StandardName.GetInitials()));
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-05 11:17:59 +00:00
|
|
|
|
public ReplacementBuilder WithServer(DiscordSocketClient client, IGuild g)
|
2017-06-28 00:44:30 +00:00
|
|
|
|
{
|
2017-07-05 11:17:59 +00:00
|
|
|
|
|
2017-06-28 00:44:30 +00:00
|
|
|
|
_reps.TryAdd("%sid%", () => g == null ? "DM" : g.Id.ToString());
|
|
|
|
|
_reps.TryAdd("%server%", () => g == null ? "DM" : g.Name);
|
2017-10-15 09:48:29 +00:00
|
|
|
|
_reps.TryAdd("%server_time%", () =>
|
|
|
|
|
{
|
|
|
|
|
TimeZoneInfo to = TimeZoneInfo.Local;
|
|
|
|
|
if (g != null)
|
|
|
|
|
{
|
|
|
|
|
if (GuildTimezoneService.AllServices.TryGetValue(client.CurrentUser.Id, out var tz))
|
|
|
|
|
to = tz.GetTimeZoneOrDefault(g.Id) ?? TimeZoneInfo.Local;
|
|
|
|
|
}
|
2017-07-05 11:17:59 +00:00
|
|
|
|
|
2017-10-15 09:48:29 +00:00
|
|
|
|
return TimeZoneInfo.ConvertTime(DateTime.UtcNow,
|
|
|
|
|
TimeZoneInfo.Utc,
|
|
|
|
|
to).ToString("HH:mm ") + to.StandardName.GetInitials();
|
|
|
|
|
});
|
2017-06-28 00:44:30 +00:00
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ReplacementBuilder WithChannel(IMessageChannel ch)
|
|
|
|
|
{
|
|
|
|
|
_reps.TryAdd("%channel%", () => (ch as ITextChannel)?.Mention ?? "#" + ch.Name);
|
|
|
|
|
_reps.TryAdd("%chname%", () => ch.Name);
|
|
|
|
|
_reps.TryAdd("%cid%", () => ch?.Id.ToString());
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ReplacementBuilder WithUser(IUser user)
|
|
|
|
|
{
|
|
|
|
|
_reps.TryAdd("%user%", () => user.Mention);
|
|
|
|
|
_reps.TryAdd("%userfull%", () => user.ToString());
|
|
|
|
|
_reps.TryAdd("%username%", () => user.Username);
|
|
|
|
|
_reps.TryAdd("%userdiscrim%", () => user.Discriminator);
|
|
|
|
|
_reps.TryAdd("%id%", () => user.Id.ToString());
|
|
|
|
|
_reps.TryAdd("%uid%", () => user.Id.ToString());
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ReplacementBuilder WithStats(DiscordSocketClient c)
|
|
|
|
|
{
|
|
|
|
|
_reps.TryAdd("%servers%", () => c.Guilds.Count.ToString());
|
|
|
|
|
_reps.TryAdd("%users%", () => c.Guilds.Sum(s => s.Users.Count).ToString());
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-15 09:48:29 +00:00
|
|
|
|
public ReplacementBuilder WithMusic(MusicService ms)
|
|
|
|
|
{
|
|
|
|
|
_reps.TryAdd("%playing%", () =>
|
|
|
|
|
{
|
|
|
|
|
var cnt = ms.MusicPlayers.Count(kvp => kvp.Value.Current.Current != null);
|
|
|
|
|
if (cnt != 1) return cnt.ToString();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var mp = ms.MusicPlayers.FirstOrDefault();
|
|
|
|
|
var title = mp.Value?.Current.Current?.Title;
|
|
|
|
|
return title ?? "No songs";
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
return "error";
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
_reps.TryAdd("%queued%", () => ms.MusicPlayers.Sum(kvp => kvp.Value.QueueArray().Songs.Length).ToString());
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2017-06-28 00:44:30 +00:00
|
|
|
|
|
|
|
|
|
public ReplacementBuilder WithRngRegex()
|
|
|
|
|
{
|
|
|
|
|
var rng = new NadekoRandom();
|
|
|
|
|
_regex.TryAdd(rngRegex, (match) =>
|
|
|
|
|
{
|
|
|
|
|
int from = 0;
|
|
|
|
|
int.TryParse(match.Groups["from"].ToString(), out from);
|
|
|
|
|
|
|
|
|
|
int to = 0;
|
|
|
|
|
int.TryParse(match.Groups["to"].ToString(), out to);
|
|
|
|
|
|
|
|
|
|
if (from == 0 && to == 0)
|
|
|
|
|
{
|
|
|
|
|
return rng.Next(0, 11).ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (from >= to)
|
|
|
|
|
return string.Empty;
|
|
|
|
|
|
|
|
|
|
return rng.Next(from, to + 1).ToString();
|
|
|
|
|
});
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ReplacementBuilder WithOverride(string key, Func<string> output)
|
|
|
|
|
{
|
|
|
|
|
_reps.AddOrUpdate(key, output, delegate { return output; });
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Replacer Build()
|
|
|
|
|
{
|
|
|
|
|
return new Replacer(_reps.Select(x => (x.Key, x.Value)).ToArray(), _regex.Select(x => (x.Key, x.Value)).ToArray());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|