mirror of
https://github.com/RPCS3/discord-bot.git
synced 2025-03-04 07:47:08 +00:00
commit
0f4710921c
@ -34,7 +34,7 @@ namespace CompatBot.Commands
|
||||
lastUpdateInfo = db.BotState.FirstOrDefault(k => k.Key == Rpcs3UpdateStateKey)?.Value;
|
||||
}
|
||||
|
||||
[Command("compat"), Aliases("c")]
|
||||
[Command("compat"), Aliases("c", "compatibility")]
|
||||
[Description("Searches the compatibility database, USE: !compat search term")]
|
||||
public async Task Compat(CommandContext ctx, [RemainingText, Description("Game title to look up")] string title)
|
||||
{
|
||||
|
@ -68,13 +68,25 @@ namespace CompatBot.Commands
|
||||
"Boooooooo!",
|
||||
};
|
||||
|
||||
private static readonly char[] Separators = { ' ', ' ', '\r', '\n' };
|
||||
private static readonly char[] Suffixes = {',', '.', ':', ';', '!', '?', ')', '}', ']', '>', '+', '-', '/', '*', '=', '"', '\'', '`'};
|
||||
private static readonly char[] Prefixes = {'@', '(', '{', '[', '<', '!', '`', '"', '\'', '#'};
|
||||
private static readonly char[] EveryTimable = Separators.Concat(Suffixes).Concat(Prefixes).Distinct().ToArray();
|
||||
|
||||
private static readonly HashSet<string> Me = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
|
||||
{
|
||||
"I", "me", "myself", "moi"
|
||||
};
|
||||
|
||||
private static readonly HashSet<string> Your = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
|
||||
{
|
||||
"your", "you're", "yor", "ur", "yours", "your's",
|
||||
};
|
||||
|
||||
private static readonly HashSet<char> Vowels = new HashSet<char> {'a', 'e', 'i', 'o', 'u'};
|
||||
|
||||
private static readonly Regex Instead = new Regex("rate (?<instead>.+) instead", RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.Singleline);
|
||||
|
||||
[Command("credits"), Aliases("about")]
|
||||
[Description("Author Credit")]
|
||||
public async Task Credits(CommandContext ctx)
|
||||
@ -102,7 +114,7 @@ namespace CompatBot.Commands
|
||||
{
|
||||
string result = null;
|
||||
if (maxValue > 1)
|
||||
lock (rng) result = (rng.Next(maxValue) + 1).ToString();
|
||||
lock (rng) result = (rng.Next(maxValue) + 1).ToString();
|
||||
if (string.IsNullOrEmpty(result))
|
||||
await ctx.ReactWithAsync(DiscordEmoji.FromUnicode("💩"), $"How is {maxValue} a positive natural number?").ConfigureAwait(false);
|
||||
else
|
||||
@ -186,48 +198,69 @@ namespace CompatBot.Commands
|
||||
[Description("Gives a ~~random~~ expert judgment on the matter at hand")]
|
||||
public async Task Rate(CommandContext ctx, [RemainingText, Description("Something to rate")] string whatever)
|
||||
{
|
||||
var choices = RateAnswers;
|
||||
whatever = whatever.ToLowerInvariant().Trim();
|
||||
if (whatever.Contains("my", StringComparison.InvariantCultureIgnoreCase))
|
||||
whatever = string.Join(" ", whatever.Split(' ').Select(p => p.Equals("my", StringComparison.InvariantCultureIgnoreCase) ? $"<@{ctx.Message.Author.Id}>'s" : p));
|
||||
try
|
||||
{
|
||||
var whateverParts = whatever.Split(' ', StringSplitOptions.RemoveEmptyEntries) ?? new string[0];
|
||||
var choices = RateAnswers;
|
||||
var choiceFlags = new HashSet<char>();
|
||||
whatever = whatever.ToLowerInvariant();
|
||||
var matches = Instead.Matches(whatever);
|
||||
if (matches.Any())
|
||||
{
|
||||
var insteadWhatever = matches.Last().Groups["instead"].Value.TrimEager();
|
||||
if (!string.IsNullOrEmpty(insteadWhatever))
|
||||
whatever = insteadWhatever;
|
||||
}
|
||||
foreach (var attachment in ctx.Message.Attachments)
|
||||
whatever += $" {attachment.FileSize}";
|
||||
|
||||
|
||||
var nekoUser = await ctx.Client.GetUserAsync(272032356922032139ul).ConfigureAwait(false);
|
||||
var nekoMember = ctx.Client.GetMember(ctx.Guild, nekoUser);
|
||||
var nekoMatch = new HashSet<string>(new[] {nekoUser.Id.ToString(), nekoUser.Username, nekoMember?.DisplayName ?? "neko", "neko", "nekotekina",});
|
||||
var kdUser = await ctx.Client.GetUserAsync(272631898877198337ul).ConfigureAwait(false);
|
||||
var kdMember = ctx.Client.GetMember(ctx.Guild, kdUser);
|
||||
var kdMatch = new HashSet<string>(new[] {kdUser.Id.ToString(), kdUser.Username, kdMember?.DisplayName ?? "kd-11", "kd", "kd-11", "kd11", });
|
||||
var botMember = ctx.Client.GetMember(ctx.Client.CurrentUser);
|
||||
var botMatch = new HashSet<string>(new[] {botMember.Id.ToString(), botMember.Username, botMember.DisplayName, "yourself", "urself", "yoself",});
|
||||
|
||||
var prefix = DateTime.UtcNow.ToString("yyyyMMddHH");
|
||||
var nekoNick = await ctx.GetUserNameAsync(272032356922032139ul, null, "Nekotekina").ConfigureAwait(false);
|
||||
var kdNick = await ctx.GetUserNameAsync(272631898877198337, null, "kd-11").ConfigureAwait(false);
|
||||
if (whatever is string neko && (neko.Contains("272032356922032139") || neko.Contains("neko") || neko.Contains(nekoNick)))
|
||||
var words = whatever.Split(Separators);
|
||||
var result = new StringBuilder();
|
||||
for (var i = 0; i < words.Length; i++)
|
||||
{
|
||||
choices = RateAnswers.Concat(Enumerable.Repeat("Ugh", RateAnswers.Count * 3)).ToList();
|
||||
if (await new DiscordUserConverter().ConvertAsync("272032356922032139", ctx).ConfigureAwait(false) is Optional<DiscordUser> user && user.HasValue)
|
||||
whatever = user.Value.Id.ToString();
|
||||
}
|
||||
else if (whatever is string kd && (kd.Contains("272631898877198337") || kd.Contains("kd-11") || kd.Contains("kd11") || kd.Contains(kdNick) || whateverParts.Any(p => p == "kd")))
|
||||
{
|
||||
choices = RateAnswers.Concat(Enumerable.Repeat("RSX genius", RateAnswers.Count * 3)).ToList();
|
||||
if (await new DiscordUserConverter().ConvertAsync("272631898877198337", ctx).ConfigureAwait(false) is Optional<DiscordUser> user && user.HasValue)
|
||||
whatever = user.Value.Id.ToString();
|
||||
}
|
||||
else if (whatever is string sonic && (sonic == "sonic" || sonic.Contains("sonic the")))
|
||||
{
|
||||
choices = RateAnswers.Concat(Enumerable.Repeat("💩 out of 🦔", RateAnswers.Count)).Concat(new[] {"Sonic out of 🦔", "Sonic out of 10"}).ToList();
|
||||
whatever = "sonic";
|
||||
}
|
||||
else if (whateverParts.Length == 1)
|
||||
{
|
||||
DiscordUser u = null;
|
||||
if (Me.Contains(whateverParts[0]))
|
||||
var word = words[i].TrimEager();
|
||||
var suffix = "";
|
||||
var tmp = word.TrimEnd(Suffixes);
|
||||
if (tmp.Length != word.Length)
|
||||
{
|
||||
whatever = ctx.Message.Author.Id.ToString();
|
||||
u = ctx.Message.Author;
|
||||
suffix = word.Substring(tmp.Length);
|
||||
word = tmp;
|
||||
}
|
||||
else if (await new DiscordUserConverter().ConvertAsync(whateverParts[0], ctx).ConfigureAwait(false) is Optional<DiscordUser> user && user.HasValue)
|
||||
tmp = word.TrimStart(Prefixes);
|
||||
if (tmp.Length != word.Length)
|
||||
{
|
||||
whatever = user.Value.Id.ToString();
|
||||
u = user.Value;
|
||||
result.Append(word.Substring(0, word.Length - tmp.Length));
|
||||
word = tmp;
|
||||
}
|
||||
if (u != null)
|
||||
if (word.EndsWith("'s"))
|
||||
{
|
||||
suffix = "'s" + suffix;
|
||||
word = word.Substring(0, word.Length - 2);
|
||||
}
|
||||
if (Me.Contains(word))
|
||||
result.Append(ctx.Message.Author.Mention);
|
||||
else if (word == "my")
|
||||
result.Append(ctx.Message.Author.Mention).Append("'s");
|
||||
else if (botMatch.Contains(word))
|
||||
result.Append(ctx.Client.CurrentUser.Mention);
|
||||
else if (Your.Contains(word))
|
||||
result.Append(ctx.Client.CurrentUser.Mention).Append("'s");
|
||||
else if (word.StartsWith("actually") || word.StartsWith("nevermind") || word.StartsWith("nvm"))
|
||||
result.Clear();
|
||||
else if (i == 0 && await new DiscordUserConverter().ConvertAsync(word, ctx).ConfigureAwait(false) is Optional<DiscordUser> user && user.HasValue)
|
||||
{
|
||||
var u = user.Value;
|
||||
result.Append(u.Mention);
|
||||
var roles = ctx.Client.GetMember(u)?.Roles.ToList();
|
||||
if (roles?.Count > 0)
|
||||
{
|
||||
@ -238,21 +271,54 @@ namespace CompatBot.Commands
|
||||
if (role.EndsWith('s'))
|
||||
role = role.Substring(0, role.Length - 1);
|
||||
var article = Vowels.Contains(role[0]) ? "n" : "";
|
||||
choices = RateAnswers.Concat(Enumerable.Repeat($"Pretty fly for a{article} {role} guy", RateAnswers.Count / 20)).ToList();
|
||||
if (!choiceFlags.Contains('f'))
|
||||
{
|
||||
choices = RateAnswers.Concat(Enumerable.Repeat($"Pretty fly for a{article} {role} guy", RateAnswers.Count / 20)).ToList();
|
||||
choiceFlags.Add('f');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nekoMatch.Contains(word))
|
||||
{
|
||||
if (!choiceFlags.Contains('n'))
|
||||
{
|
||||
choices = RateAnswers.Concat(Enumerable.Repeat("Ugh", RateAnswers.Count * 3)).ToList();
|
||||
choiceFlags.Add('n');
|
||||
}
|
||||
result.Append(nekoUser.Mention);
|
||||
}
|
||||
else if (kdMatch.Contains(word))
|
||||
{
|
||||
if (!choiceFlags.Contains('k'))
|
||||
{
|
||||
choices = RateAnswers.Concat(Enumerable.Repeat("RSX genius", RateAnswers.Count * 3)).ToList();
|
||||
choiceFlags.Add('k');
|
||||
}
|
||||
result.Append(kdUser.Mention);
|
||||
}
|
||||
else
|
||||
result.Append(word);
|
||||
result.Append(suffix).Append(" ");
|
||||
}
|
||||
whatever = prefix + whatever?.Trim();
|
||||
whatever = result.ToString();
|
||||
var cutIdx = whatever.LastIndexOf("never mind");
|
||||
if (cutIdx > -1)
|
||||
whatever = whatever.Substring(cutIdx);
|
||||
whatever = whatever.Replace("'s's", "'s").TrimStart(EveryTimable).Trim();
|
||||
if (whatever.StartsWith("rate "))
|
||||
whatever = whatever.Substring("rate ".Length);
|
||||
if (whatever == "sonic" || whatever.Contains("sonic the"))
|
||||
choices = RateAnswers.Concat(Enumerable.Repeat("💩 out of 🦔", RateAnswers.Count)).Concat(new[] {"Sonic out of 🦔", "Sonic out of 10"}).ToList();
|
||||
var seed = (prefix + whatever).GetHashCode(StringComparison.CurrentCultureIgnoreCase);
|
||||
var seededRng = new Random(seed);
|
||||
var answer = choices[seededRng.Next(choices.Count)];
|
||||
await ctx.RespondAsync(answer).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Config.Log.Warn(e, $"Failed to rate {whatever}");
|
||||
}
|
||||
var seed = whatever.GetHashCode(StringComparison.CurrentCultureIgnoreCase);
|
||||
var seededRng = new Random(seed);
|
||||
var answer = choices[seededRng.Next(choices.Count)];
|
||||
await ctx.RespondAsync(answer).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[Command("stats"), RequiresBotModRole]
|
||||
|
@ -37,7 +37,7 @@ namespace CompatBot.Commands
|
||||
if (user.Id == Config.BotAdminId)
|
||||
{
|
||||
var dm = await user.CreateDmChannelAsync().ConfigureAwait(false);
|
||||
await dm.SendMessageAsync($@"Just letting you know that {ctx.Message.Author.Mention} just tried to strip you off of your mod role ¯\_(ツ)_/¯").ConfigureAwait(false);
|
||||
await dm.SendMessageAsync($@"Just letting you know that {ctx.Message.Author.Mention} just tried to strip you off of your mod role ¯\\_(ツ)_/¯").ConfigureAwait(false);
|
||||
await ctx.ReactWithAsync(Config.Reactions.Denied, $"{ctx.Message.Author.Mention} why would you even try this?! Alerting {user.Mention}", true).ConfigureAwait(false);
|
||||
}
|
||||
else if (await ModProvider.RemoveAsync(user.Id).ConfigureAwait(false))
|
||||
@ -78,7 +78,7 @@ namespace CompatBot.Commands
|
||||
if (sudoer.Id == Config.BotAdminId)
|
||||
{
|
||||
var dm = await sudoer.CreateDmChannelAsync().ConfigureAwait(false);
|
||||
await dm.SendMessageAsync($@"Just letting you know that {ctx.Message.Author.Mention} just tried to strip you off of your sudo permissions ¯\_(ツ)_/¯").ConfigureAwait(false);
|
||||
await dm.SendMessageAsync($@"Just letting you know that {ctx.Message.Author.Mention} just tried to strip you off of your sudo permissions ¯\\_(ツ)_/¯").ConfigureAwait(false);
|
||||
await ctx.ReactWithAsync(Config.Reactions.Denied, $"{ctx.Message.Author.Mention} why would you even try this?! Alerting {sudoer.Mention}", true).ConfigureAwait(false);
|
||||
}
|
||||
else if (ModProvider.IsMod(sudoer.Id))
|
||||
|
@ -13,25 +13,29 @@ namespace CompatBot.Utils
|
||||
{
|
||||
public static class DiscordClientExtensions
|
||||
{
|
||||
public static DiscordMember GetMember(this DiscordClient client, DiscordGuild guild, DiscordUser user)
|
||||
public static DiscordMember GetMember(this DiscordClient client, DiscordGuild guild, ulong userId)
|
||||
{
|
||||
return (from g in client.Guilds
|
||||
where g.Key == guild.Id
|
||||
from u in g.Value.Members
|
||||
where u.Id == user.Id
|
||||
where u.Id == userId
|
||||
select u
|
||||
).FirstOrDefault();
|
||||
}
|
||||
|
||||
public static DiscordMember GetMember(this DiscordClient client, DiscordUser user)
|
||||
public static DiscordMember GetMember(this DiscordClient client, DiscordGuild guild, DiscordUser user) => GetMember(client, guild, user.Id);
|
||||
|
||||
public static DiscordMember GetMember(this DiscordClient client, ulong userId)
|
||||
{
|
||||
return (from g in client.Guilds
|
||||
from u in g.Value.Members
|
||||
where u.Id == user.Id
|
||||
where u.Id == userId
|
||||
select u
|
||||
).FirstOrDefault();
|
||||
}
|
||||
|
||||
public static DiscordMember GetMember(this DiscordClient client, DiscordUser user) => GetMember(client, user.Id);
|
||||
|
||||
public static async Task<string> GetUserNameAsync(this DiscordClient client, DiscordChannel channel, ulong userId, bool? forDmPurposes = null, string defaultName = "Unknown user")
|
||||
{
|
||||
var isPrivate = forDmPurposes ?? channel.IsPrivate;
|
||||
|
Loading…
x
Reference in New Issue
Block a user