2015-12-05 10:27:00 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Security.Cryptography;
|
2015-12-10 01:22:09 +00:00
|
|
|
|
using Discord.Commands;
|
|
|
|
|
using Discord;
|
2016-01-21 02:17:01 +00:00
|
|
|
|
using NadekoBot.Modules;
|
2016-01-28 09:09:07 +00:00
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Drawing;
|
2015-12-05 10:27:00 +00:00
|
|
|
|
|
2016-01-30 04:24:32 +00:00
|
|
|
|
namespace NadekoBot.Extensions {
|
2015-12-05 10:27:00 +00:00
|
|
|
|
public static class Extensions
|
|
|
|
|
{
|
2015-12-09 21:51:20 +00:00
|
|
|
|
public static string Scramble(this string word) {
|
|
|
|
|
|
|
|
|
|
var letters = word.ToArray();
|
2016-01-30 04:24:32 +00:00
|
|
|
|
int count = 0;
|
|
|
|
|
for (int i = 0; i < letters.Length; i++) {
|
|
|
|
|
if (letters[i] == ' ')
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
count++;
|
|
|
|
|
if (count <= letters.Length / 5)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (count % 3 == 0)
|
2015-12-09 21:51:20 +00:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (letters[i] != ' ')
|
|
|
|
|
letters[i] = '_';
|
|
|
|
|
}
|
|
|
|
|
return "`"+string.Join(" ", letters)+"`";
|
|
|
|
|
}
|
2016-01-30 11:08:30 +00:00
|
|
|
|
public static string TrimTo(this string str, int num) {
|
|
|
|
|
if (num < 0)
|
|
|
|
|
throw new ArgumentException("TrimTo argument cannot be less than 0");
|
|
|
|
|
if (num == 0)
|
|
|
|
|
return String.Empty;
|
|
|
|
|
if (num <= 3)
|
|
|
|
|
return String.Join("", str.Select(c => '.'));
|
|
|
|
|
if (str.Length < num)
|
|
|
|
|
return str;
|
|
|
|
|
return string.Join("", str.Take(num - 3)) + "...";
|
|
|
|
|
}
|
2016-01-31 08:22:47 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Removes trailing S or ES (if specified) on the given string if the num is 1
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="str"></param>
|
|
|
|
|
/// <param name="num"></param>
|
|
|
|
|
/// <param name="es"></param>
|
|
|
|
|
/// <returns>String with the correct singular/plural form</returns>
|
|
|
|
|
public static string SnPl(this string str, int? num,bool es = false) {
|
|
|
|
|
if (str == null)
|
|
|
|
|
throw new ArgumentNullException(nameof(str));
|
|
|
|
|
if (num == null)
|
|
|
|
|
throw new ArgumentNullException(nameof(num));
|
|
|
|
|
return num == 1 ? str.Remove(str.Length - 1, es ? 2 : 1) : str;
|
|
|
|
|
}
|
2015-12-09 21:51:20 +00:00
|
|
|
|
|
2015-12-10 01:22:09 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sends a message to the channel from which this command is called.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e">EventArg</param>
|
|
|
|
|
/// <param name="message">Message to be sent</param>
|
|
|
|
|
/// <returns></returns>
|
2015-12-12 22:39:58 +00:00
|
|
|
|
public static async Task<Message> Send(this CommandEventArgs e, string message)
|
2015-12-30 04:44:36 +00:00
|
|
|
|
=> await e.Channel.SendMessage(message);
|
2015-12-13 02:54:21 +00:00
|
|
|
|
|
2015-12-10 01:22:09 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sends a message to the channel from which MessageEventArg came.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e">EventArg</param>
|
|
|
|
|
/// <param name="message">Message to be sent</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static async Task Send(this MessageEventArgs e, string message)
|
|
|
|
|
{
|
2016-02-04 06:24:40 +00:00
|
|
|
|
if (string.IsNullOrWhiteSpace(message))
|
|
|
|
|
return;
|
2015-12-30 04:44:36 +00:00
|
|
|
|
await e.Channel.SendMessage(message);
|
2015-12-10 01:22:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-12-13 02:54:21 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sends a message to this channel.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="c"></param>
|
|
|
|
|
/// <param name="message"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static async Task Send(this Channel c, string message)
|
|
|
|
|
{
|
2015-12-30 04:44:36 +00:00
|
|
|
|
await c.SendMessage(message);
|
2015-12-13 02:54:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sends a private message to this user.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="c"></param>
|
|
|
|
|
/// <param name="message"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static async Task Send(this User u, string message)
|
|
|
|
|
{
|
2015-12-30 04:44:36 +00:00
|
|
|
|
await u.SendMessage(message);
|
2015-12-13 02:54:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Replies to a user who invoked this command, message start with that user's mention.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e"></param>
|
|
|
|
|
/// <param name="message"></param>
|
|
|
|
|
/// <returns></returns>
|
2015-12-10 01:22:09 +00:00
|
|
|
|
public static async Task Reply(this CommandEventArgs e, string message)
|
|
|
|
|
{
|
2015-12-13 02:54:21 +00:00
|
|
|
|
await e.Send(e.User.Mention + " " + message);
|
2015-12-10 01:22:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-12-13 02:54:21 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Replies to a user who invoked this command, message start with that user's mention.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="e"></param>
|
|
|
|
|
/// <param name="message"></param>
|
|
|
|
|
/// <returns></returns>
|
2015-12-10 01:22:09 +00:00
|
|
|
|
public static async Task Reply(this MessageEventArgs e, string message)
|
|
|
|
|
{
|
2015-12-13 02:54:21 +00:00
|
|
|
|
await e.Send(e.User.Mention + " " + message);
|
2015-12-10 01:22:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-12-13 02:54:21 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Randomizes element order in a list
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
|
/// <param name="list"></param>
|
2015-12-05 10:27:00 +00:00
|
|
|
|
public static void Shuffle<T>(this IList<T> list)
|
|
|
|
|
{
|
|
|
|
|
RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
|
|
|
|
|
int n = list.Count;
|
|
|
|
|
while (n > 1)
|
|
|
|
|
{
|
|
|
|
|
byte[] box = new byte[1];
|
|
|
|
|
do provider.GetBytes(box);
|
|
|
|
|
while (!(box[0] < n * (Byte.MaxValue / n)));
|
|
|
|
|
int k = (box[0] % n);
|
|
|
|
|
n--;
|
|
|
|
|
T value = list[k];
|
|
|
|
|
list[k] = list[n];
|
|
|
|
|
list[n] = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-12-30 04:44:36 +00:00
|
|
|
|
|
2016-01-21 02:17:01 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Shortens a string URL
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
|
/// <param name="source"></param>
|
|
|
|
|
/// <param name="action"></param>
|
2016-02-04 13:17:15 +00:00
|
|
|
|
public static async Task<string> ShortenUrl(this string str) => await Searches.ShortenUrl(str);
|
2016-01-21 22:22:55 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the program runtime
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
|
/// <param name="source"></param>
|
|
|
|
|
/// <param name="action"></param>
|
|
|
|
|
public static string GetRuntime(this DiscordClient c) => ".Net Framework 4.5.2";
|
2016-01-21 02:17:01 +00:00
|
|
|
|
|
2015-12-30 04:44:36 +00:00
|
|
|
|
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) {
|
|
|
|
|
foreach (T element in source) {
|
|
|
|
|
action(element);
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-01-25 06:55:46 +00:00
|
|
|
|
|
|
|
|
|
//http://www.dotnetperls.com/levenshtein
|
|
|
|
|
public static int LevenshteinDistance(this string s, string t) {
|
|
|
|
|
int n = s.Length;
|
|
|
|
|
int m = t.Length;
|
|
|
|
|
int[,] d = new int[n + 1, m + 1];
|
|
|
|
|
|
|
|
|
|
// Step 1
|
|
|
|
|
if (n == 0) {
|
|
|
|
|
return m;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m == 0) {
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Step 2
|
|
|
|
|
for (int i = 0; i <= n; d[i, 0] = i++) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j <= m; d[0, j] = j++) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Step 3
|
|
|
|
|
for (int i = 1; i <= n; i++) {
|
|
|
|
|
//Step 4
|
|
|
|
|
for (int j = 1; j <= m; j++) {
|
|
|
|
|
// Step 5
|
|
|
|
|
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
|
|
|
|
|
|
|
|
|
|
// Step 6
|
|
|
|
|
d[i, j] = Math.Min(
|
|
|
|
|
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
|
|
|
|
|
d[i - 1, j - 1] + cost);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Step 7
|
|
|
|
|
return d[n, m];
|
|
|
|
|
}
|
2016-01-26 19:18:48 +00:00
|
|
|
|
|
|
|
|
|
public static int KiB(this int value) => value * 1024;
|
|
|
|
|
public static int KB(this int value) => value * 1000;
|
|
|
|
|
|
|
|
|
|
public static int MiB(this int value) => value.KiB() * 1024;
|
|
|
|
|
public static int MB(this int value) => value.KB() * 1000;
|
|
|
|
|
|
|
|
|
|
public static int GiB(this int value) => value.MiB() * 1024;
|
|
|
|
|
public static int GB(this int value) => value.MB() * 1000;
|
|
|
|
|
|
2016-01-28 09:09:07 +00:00
|
|
|
|
public static Stream ToStream(this System.Drawing.Image img, System.Drawing.Imaging.ImageFormat format = null) {
|
|
|
|
|
if (format == null)
|
|
|
|
|
format = System.Drawing.Imaging.ImageFormat.Jpeg;
|
|
|
|
|
MemoryStream stream = new MemoryStream();
|
|
|
|
|
img.Save(stream, format);
|
|
|
|
|
stream.Position = 0;
|
|
|
|
|
return stream;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Merges Images into 1 Image and returns a bitmap.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="images">The Images you want to merge.</param>
|
|
|
|
|
/// <returns>Merged bitmap</returns>
|
|
|
|
|
public static Bitmap Merge(this IEnumerable<Image> images) {
|
|
|
|
|
if (images.Count() == 0) return null;
|
|
|
|
|
int width = images.Sum(i => i.Width);
|
|
|
|
|
int height = images.First().Height;
|
|
|
|
|
Bitmap bitmap = new Bitmap(width, height);
|
|
|
|
|
var r = new Random();
|
|
|
|
|
int offsetx = 0;
|
|
|
|
|
foreach (var img in images) {
|
|
|
|
|
Bitmap bm = new Bitmap(img);
|
|
|
|
|
for (int w = 0; w < img.Width; w++) {
|
|
|
|
|
for (int h = 0; h < img.Height; h++) {
|
|
|
|
|
bitmap.SetPixel(w + offsetx, h, bm.GetPixel(w, h));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
offsetx += img.Width;
|
|
|
|
|
}
|
|
|
|
|
return bitmap;
|
|
|
|
|
}
|
2015-12-05 10:27:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|