Some cleanup
This commit is contained in:
parent
da7dbb7f32
commit
732394a366
@ -24,7 +24,7 @@ namespace NadekoBot.Modules.Administration
|
||||
NadekoBot.CommandHandler.CommandExecuted += DelMsgOnCmd_Handler;
|
||||
}
|
||||
|
||||
private void DelMsgOnCmd_Handler(object sender, CommandExecutedEventArgs e)
|
||||
private async void DelMsgOnCmd_Handler(object sender, CommandExecutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -39,7 +39,7 @@ namespace NadekoBot.Modules.Administration
|
||||
}
|
||||
|
||||
if (shouldDelete)
|
||||
e.Message.DeleteAsync();
|
||||
await e.Message.DeleteAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -19,22 +19,26 @@ namespace NadekoBot.Modules.Administration
|
||||
public AutoAssignRoleCommands()
|
||||
{
|
||||
var _client = NadekoBot.Client;
|
||||
_client.UserJoined += async (user) =>
|
||||
_client.UserJoined += (user) =>
|
||||
{
|
||||
GuildConfig conf;
|
||||
using (var uow = DbHandler.UnitOfWork())
|
||||
var t = Task.Run(async () =>
|
||||
{
|
||||
conf = uow.GuildConfigs.For(user.Guild.Id);
|
||||
}
|
||||
var aarType = conf.AutoAssignRoleId.GetType();
|
||||
GuildConfig conf;
|
||||
using (var uow = DbHandler.UnitOfWork())
|
||||
{
|
||||
conf = uow.GuildConfigs.For(user.Guild.Id);
|
||||
}
|
||||
var aarType = conf.AutoAssignRoleId.GetType();
|
||||
|
||||
if (conf.AutoAssignRoleId == 0)
|
||||
return;
|
||||
if (conf.AutoAssignRoleId == 0)
|
||||
return;
|
||||
|
||||
var role = user.Guild.Roles.FirstOrDefault(r => r.Id == conf.AutoAssignRoleId);
|
||||
var role = user.Guild.Roles.FirstOrDefault(r => r.Id == conf.AutoAssignRoleId);
|
||||
|
||||
if (role != null)
|
||||
await user.AddRolesAsync(role);
|
||||
if (role != null)
|
||||
await user.AddRolesAsync(role);
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,6 @@ namespace NadekoBot.Modules.Administration
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
}
|
||||
|
@ -24,9 +24,13 @@ namespace NadekoBot.Modules.Administration
|
||||
_client.MessageReceived += _client_MessageReceived;
|
||||
}
|
||||
|
||||
private Task _client_MessageReceived(IMessage arg)
|
||||
private Task _client_MessageReceived(IMessage imsg)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var msg = imsg as IUserMessage;
|
||||
if (msg == null)
|
||||
return Task.CompletedTask;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace NadekoBot.Modules.Administration
|
||||
|
||||
private Task UserUpdatedEventHandler(IGuildUser before, IGuildUser after)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
var task = Task.Run(async () =>
|
||||
{
|
||||
var guild = before.Guild ?? after.Guild;
|
||||
var botUserPerms = guild.GetCurrentUser().GuildPermissions;
|
||||
|
@ -143,7 +143,6 @@ namespace NadekoBot.Modules.Gambling
|
||||
//update the state
|
||||
participants.ForEach(p =>
|
||||
{
|
||||
|
||||
p.Total += 1 + rng.Next(0, 10);
|
||||
if (p.Total > 60)
|
||||
{
|
||||
|
@ -107,26 +107,36 @@ namespace NadekoBot.Modules.Games
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Vote(IMessage imsg)
|
||||
private Task Vote(IMessage imsg)
|
||||
{
|
||||
var msg = imsg as ISystemMessage;
|
||||
// has to be a user message
|
||||
var msg = imsg as IUserMessage;
|
||||
if (msg == null)
|
||||
return;
|
||||
try
|
||||
return Task.CompletedTask;
|
||||
// channel must be private
|
||||
IPrivateChannel ch;
|
||||
if ((ch = msg.Channel as IPrivateChannel) == null)
|
||||
return Task.CompletedTask;
|
||||
|
||||
// has to be an integer
|
||||
int vote;
|
||||
if (!int.TryParse(msg.Content, out vote)) return Task.CompletedTask;
|
||||
|
||||
var t = Task.Run(async () =>
|
||||
{
|
||||
IPrivateChannel ch;
|
||||
if ((ch = msg.Channel as IPrivateChannel) == null)
|
||||
return;
|
||||
int vote;
|
||||
if (!int.TryParse(msg.Content, out vote)) return;
|
||||
if (vote < 1 || vote > answers.Length)
|
||||
return;
|
||||
if (participants.TryAdd(msg.Author, vote))
|
||||
try
|
||||
{
|
||||
await (ch as ITextChannel).SendMessageAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false);
|
||||
|
||||
if (vote < 1 || vote > answers.Length)
|
||||
return;
|
||||
if (participants.TryAdd(msg.Author, vote))
|
||||
{
|
||||
await (ch as ITextChannel).SendMessageAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
catch { }
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
@ -92,30 +92,34 @@ namespace NadekoBot.Modules.Games
|
||||
NadekoBot.Client.MessageReceived += AnswerReceived;
|
||||
}
|
||||
|
||||
private async Task AnswerReceived(IMessage imsg)
|
||||
private Task AnswerReceived(IMessage imsg)
|
||||
{
|
||||
var msg = imsg as IUserMessage;
|
||||
if (msg == null)
|
||||
return;
|
||||
try
|
||||
return Task.CompletedTask;
|
||||
var t = Task.Run(async () =>
|
||||
{
|
||||
if (channel== null || channel.Id != channel.Id || msg.Author.Id == NadekoBot.Client.GetCurrentUser().Id) return;
|
||||
|
||||
var guess = msg.Content;
|
||||
|
||||
var distance = CurrentSentence.LevenshteinDistance(guess);
|
||||
var decision = Judge(distance, guess.Length);
|
||||
if (decision && !finishedUserIds.Contains(msg.Author.Id))
|
||||
try
|
||||
{
|
||||
finishedUserIds.Add(msg.Author.Id);
|
||||
await channel.SendMessageAsync($"{msg.Author.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ CurrentSentence.Length / WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!").ConfigureAwait(false);
|
||||
if (finishedUserIds.Count % 2 == 0)
|
||||
if (channel == null || channel.Id != channel.Id || msg.Author.Id == NadekoBot.Client.GetCurrentUser().Id) return;
|
||||
|
||||
var guess = msg.Content;
|
||||
|
||||
var distance = CurrentSentence.LevenshteinDistance(guess);
|
||||
var decision = Judge(distance, guess.Length);
|
||||
if (decision && !finishedUserIds.Contains(msg.Author.Id))
|
||||
{
|
||||
await channel.SendMessageAsync($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n:book:**{CurrentSentence}**:book:").ConfigureAwait(false);
|
||||
finishedUserIds.Add(msg.Author.Id);
|
||||
await channel.SendMessageAsync($"{msg.Author.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ CurrentSentence.Length / WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!").ConfigureAwait(false);
|
||||
if (finishedUserIds.Count % 2 == 0)
|
||||
{
|
||||
await channel.SendMessageAsync($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n:book:**{CurrentSentence}**:book:").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
catch { }
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private bool Judge(int errors, int textLength) => errors <= textLength / 25;
|
||||
|
@ -105,34 +105,36 @@ namespace NadekoBot.Modules.Games.Trivia
|
||||
var umsg = imsg as IUserMessage;
|
||||
if (umsg == null)
|
||||
return;
|
||||
|
||||
try
|
||||
var t = Task.Run(async () =>
|
||||
{
|
||||
if (!(umsg.Channel is IGuildChannel && umsg.Channel is ITextChannel)) return;
|
||||
if ((umsg.Channel as ITextChannel).Guild != guild) return;
|
||||
if (umsg.Author.Id == (await NadekoBot.Client.GetCurrentUserAsync()).Id) return;
|
||||
|
||||
var guildUser = umsg.Author as IGuildUser;
|
||||
|
||||
var guess = false;
|
||||
await _guessLock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
if (GameActive && CurrentQuestion.IsAnswerCorrect(umsg.Content) && !triviaCancelSource.IsCancellationRequested)
|
||||
if (!(umsg.Channel is IGuildChannel && umsg.Channel is ITextChannel)) return;
|
||||
if ((umsg.Channel as ITextChannel).Guild != guild) return;
|
||||
if (umsg.Author.Id == (await NadekoBot.Client.GetCurrentUserAsync()).Id) return;
|
||||
|
||||
var guildUser = umsg.Author as IGuildUser;
|
||||
|
||||
var guess = false;
|
||||
await _guessLock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
Users.AddOrUpdate(guildUser, 0, (gu, old) => old++);
|
||||
guess = true;
|
||||
if (GameActive && CurrentQuestion.IsAnswerCorrect(umsg.Content) && !triviaCancelSource.IsCancellationRequested)
|
||||
{
|
||||
Users.AddOrUpdate(guildUser, 0, (gu, old) => old++);
|
||||
guess = true;
|
||||
}
|
||||
}
|
||||
finally { _guessLock.Release(); }
|
||||
if (!guess) return;
|
||||
triviaCancelSource.Cancel();
|
||||
await channel.SendMessageAsync($"☑️ {guildUser.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**").ConfigureAwait(false);
|
||||
if (Users[guildUser] != WinRequirement) return;
|
||||
ShouldStopGame = true;
|
||||
await channel.SendMessageAsync($":exclamation: We have a winner! It's {guildUser.Mention}.").ConfigureAwait(false);
|
||||
}
|
||||
finally { _guessLock.Release(); }
|
||||
if (!guess) return;
|
||||
triviaCancelSource.Cancel();
|
||||
await channel.SendMessageAsync($"☑️ {guildUser.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**").ConfigureAwait(false);
|
||||
if (Users[guildUser] != WinRequirement) return;
|
||||
ShouldStopGame = true;
|
||||
await channel.SendMessageAsync($":exclamation: We have a winner! It's {guildUser.Mention}.").ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
catch { }
|
||||
});
|
||||
}
|
||||
|
||||
public string GetLeaderboard()
|
||||
|
@ -1,204 +0,0 @@
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// File: ObservableConcurrentDictionary.cs
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Collections.Concurrent
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a thread-safe dictionary for use with data binding.
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">Specifies the type of the keys in this collection.</typeparam>
|
||||
/// <typeparam name="TValue">Specifies the type of the values in this collection.</typeparam>
|
||||
[DebuggerDisplay("Count={Count}")]
|
||||
public class ObservableConcurrentDictionary<TKey, TValue> :
|
||||
ICollection<KeyValuePair<TKey, TValue>>, IDictionary<TKey, TValue>,
|
||||
INotifyCollectionChanged, INotifyPropertyChanged
|
||||
{
|
||||
private readonly SynchronizationContext _context;
|
||||
private readonly ConcurrentDictionary<TKey, TValue> _dictionary;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an instance of the ObservableConcurrentDictionary class.
|
||||
/// </summary>
|
||||
public ObservableConcurrentDictionary()
|
||||
{
|
||||
_context = AsyncOperationManager.SynchronizationContext;
|
||||
_dictionary = new ConcurrentDictionary<TKey, TValue>();
|
||||
}
|
||||
|
||||
/// <summary>Event raised when the collection changes.</summary>
|
||||
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||
/// <summary>Event raised when a property on the collection changes.</summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Notifies observers of CollectionChanged or PropertyChanged of an update to the dictionary.
|
||||
/// </summary>
|
||||
private void NotifyObserversOfChange()
|
||||
{
|
||||
var collectionHandler = CollectionChanged;
|
||||
var propertyHandler = PropertyChanged;
|
||||
if (collectionHandler != null || propertyHandler != null)
|
||||
{
|
||||
_context.Post(s =>
|
||||
{
|
||||
if (collectionHandler != null)
|
||||
{
|
||||
collectionHandler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
if (propertyHandler != null)
|
||||
{
|
||||
propertyHandler(this, new PropertyChangedEventArgs("Count"));
|
||||
propertyHandler(this, new PropertyChangedEventArgs("Keys"));
|
||||
propertyHandler(this, new PropertyChangedEventArgs("Values"));
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Attempts to add an item to the dictionary, notifying observers of any changes.</summary>
|
||||
/// <param name="item">The item to be added.</param>
|
||||
/// <returns>Whether the add was successful.</returns>
|
||||
private bool TryAddWithNotification(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
return TryAddWithNotification(item.Key, item.Value);
|
||||
}
|
||||
|
||||
/// <summary>Attempts to add an item to the dictionary, notifying observers of any changes.</summary>
|
||||
/// <param name="key">The key of the item to be added.</param>
|
||||
/// <param name="value">The value of the item to be added.</param>
|
||||
/// <returns>Whether the add was successful.</returns>
|
||||
private bool TryAddWithNotification(TKey key, TValue value)
|
||||
{
|
||||
bool result = _dictionary.TryAdd(key, value);
|
||||
if (result) NotifyObserversOfChange();
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Attempts to remove an item from the dictionary, notifying observers of any changes.</summary>
|
||||
/// <param name="key">The key of the item to be removed.</param>
|
||||
/// <param name="value">The value of the item removed.</param>
|
||||
/// <returns>Whether the removal was successful.</returns>
|
||||
private bool TryRemoveWithNotification(TKey key, out TValue value)
|
||||
{
|
||||
bool result = _dictionary.TryRemove(key, out value);
|
||||
if (result) NotifyObserversOfChange();
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Attempts to add or update an item in the dictionary, notifying observers of any changes.</summary>
|
||||
/// <param name="key">The key of the item to be updated.</param>
|
||||
/// <param name="value">The new value to set for the item.</param>
|
||||
/// <returns>Whether the update was successful.</returns>
|
||||
private void UpdateWithNotification(TKey key, TValue value)
|
||||
{
|
||||
_dictionary[key] = value;
|
||||
NotifyObserversOfChange();
|
||||
}
|
||||
|
||||
#region ICollection<KeyValuePair<TKey,TValue>> Members
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
TryAddWithNotification(item);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.Clear()
|
||||
{
|
||||
((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).Clear();
|
||||
NotifyObserversOfChange();
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).Contains(item);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
||||
{
|
||||
((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
int ICollection<KeyValuePair<TKey, TValue>>.Count {
|
||||
get { return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).Count; }
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
|
||||
get { return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).IsReadOnly; }
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
TValue temp;
|
||||
return TryRemoveWithNotification(item.Key, out temp);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IEnumerable<KeyValuePair<TKey,TValue>> Members
|
||||
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
|
||||
{
|
||||
return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).GetEnumerator();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IDictionary<TKey,TValue> Members
|
||||
public void Add(TKey key, TValue value)
|
||||
{
|
||||
TryAddWithNotification(key, value);
|
||||
}
|
||||
|
||||
public bool ContainsKey(TKey key)
|
||||
{
|
||||
return _dictionary.ContainsKey(key);
|
||||
}
|
||||
|
||||
public ICollection<TKey> Keys {
|
||||
get { return _dictionary.Keys; }
|
||||
}
|
||||
|
||||
public bool Remove(TKey key)
|
||||
{
|
||||
TValue temp;
|
||||
return TryRemoveWithNotification(key, out temp);
|
||||
}
|
||||
|
||||
public bool TryGetValue(TKey key, out TValue value)
|
||||
{
|
||||
return _dictionary.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public bool TryAdd(TKey key, TValue value)
|
||||
{
|
||||
return TryAddWithNotification(key, value);
|
||||
}
|
||||
|
||||
public ICollection<TValue> Values {
|
||||
get { return _dictionary.Values; }
|
||||
}
|
||||
|
||||
public TValue this[TKey key] {
|
||||
get { return _dictionary[key]; }
|
||||
set { UpdateWithNotification(key, value); }
|
||||
}
|
||||
|
||||
public bool TryRemove(TKey key, out TValue value)
|
||||
{
|
||||
return TryRemoveWithNotification(key, out value);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -1,287 +0,0 @@
|
||||
using NadekoBot.Classes.JSONModels;
|
||||
using NadekoBot.Extensions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Authentication;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace NadekoBot.Classes
|
||||
{
|
||||
public enum RequestHttpMethod
|
||||
{
|
||||
Get,
|
||||
Post
|
||||
}
|
||||
|
||||
public static class SearchHelper
|
||||
{
|
||||
private static DateTime lastRefreshed = DateTime.MinValue;
|
||||
private static string token { get; set; } = "";
|
||||
|
||||
public static async Task<Stream> GetResponseStreamAsync(string url,
|
||||
IEnumerable<KeyValuePair<string, string>> headers = null, RequestHttpMethod method = RequestHttpMethod.Get)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
throw new ArgumentNullException(nameof(url));
|
||||
var cl = new HttpClient();
|
||||
cl.DefaultRequestHeaders.Clear();
|
||||
switch (method)
|
||||
{
|
||||
case RequestHttpMethod.Get:
|
||||
if (headers != null)
|
||||
{
|
||||
foreach (var header in headers)
|
||||
{
|
||||
cl.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value);
|
||||
}
|
||||
}
|
||||
return await cl.GetStreamAsync(url).ConfigureAwait(false);
|
||||
case RequestHttpMethod.Post:
|
||||
FormUrlEncodedContent formContent = null;
|
||||
if (headers != null)
|
||||
{
|
||||
formContent = new FormUrlEncodedContent(headers);
|
||||
}
|
||||
var message = await cl.PostAsync(url, formContent).ConfigureAwait(false);
|
||||
return await message.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
default:
|
||||
throw new NotImplementedException("That type of request is unsupported.");
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<string> GetResponseStringAsync(string url,
|
||||
IEnumerable<KeyValuePair<string, string>> headers = null,
|
||||
RequestHttpMethod method = RequestHttpMethod.Get)
|
||||
{
|
||||
|
||||
using (var streamReader = new StreamReader(await GetResponseStreamAsync(url, headers, method).ConfigureAwait(false)))
|
||||
{
|
||||
return await streamReader.ReadToEndAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<AnimeResult> GetAnimeData(string query)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(query))
|
||||
throw new ArgumentNullException(nameof(query));
|
||||
|
||||
await RefreshAnilistToken().ConfigureAwait(false);
|
||||
|
||||
var link = "http://anilist.co/api/anime/search/" + Uri.EscapeUriString(query);
|
||||
var smallContent = "";
|
||||
var cl = new RestSharp.RestClient("http://anilist.co/api");
|
||||
var rq = new RestSharp.RestRequest("/anime/search/" + Uri.EscapeUriString(query));
|
||||
rq.AddParameter("access_token", token);
|
||||
smallContent = cl.Execute(rq).Content;
|
||||
var smallObj = JArray.Parse(smallContent)[0];
|
||||
|
||||
rq = new RestSharp.RestRequest("/anime/" + smallObj["id"]);
|
||||
rq.AddParameter("access_token", token);
|
||||
var content = cl.Execute(rq).Content;
|
||||
|
||||
return await Task.Run(() => JsonConvert.DeserializeObject<AnimeResult>(content)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task<MangaResult> GetMangaData(string query)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(query))
|
||||
throw new ArgumentNullException(nameof(query));
|
||||
|
||||
await RefreshAnilistToken().ConfigureAwait(false);
|
||||
|
||||
var link = "http://anilist.co/api/anime/search/" + Uri.EscapeUriString(query);
|
||||
var smallContent = "";
|
||||
var cl = new RestSharp.RestClient("http://anilist.co/api");
|
||||
var rq = new RestSharp.RestRequest("/manga/search/" + Uri.EscapeUriString(query));
|
||||
rq.AddParameter("access_token", token);
|
||||
smallContent = cl.Execute(rq).Content;
|
||||
var smallObj = JArray.Parse(smallContent)[0];
|
||||
|
||||
rq = new RestSharp.RestRequest("/manga/" + smallObj["id"]);
|
||||
rq.AddParameter("access_token", token);
|
||||
var content = cl.Execute(rq).Content;
|
||||
|
||||
return await Task.Run(() => JsonConvert.DeserializeObject<MangaResult>(content)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static async Task RefreshAnilistToken()
|
||||
{
|
||||
if (DateTime.Now - lastRefreshed > TimeSpan.FromMinutes(29))
|
||||
lastRefreshed = DateTime.Now;
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
var headers = new Dictionary<string, string> {
|
||||
{"grant_type", "client_credentials"},
|
||||
{"client_id", "kwoth-w0ki9"},
|
||||
{"client_secret", "Qd6j4FIAi1ZK6Pc7N7V4Z"},
|
||||
};
|
||||
var content = await GetResponseStringAsync(
|
||||
"http://anilist.co/api/auth/access_token",
|
||||
headers,
|
||||
RequestHttpMethod.Post).ConfigureAwait(false);
|
||||
|
||||
token = JObject.Parse(content)["access_token"].ToString();
|
||||
}
|
||||
|
||||
public static async Task<string> FindYoutubeUrlByKeywords(string keywords)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(keywords))
|
||||
throw new ArgumentNullException(nameof(keywords), "Query not specified.");
|
||||
if (keywords.Length > 150)
|
||||
throw new ArgumentException("Query is too long.");
|
||||
|
||||
//maybe it is already a youtube url, in which case we will just extract the id and prepend it with youtube.com?v=
|
||||
var match = new Regex("(?:youtu\\.be\\/|v=)(?<id>[\\da-zA-Z\\-_]*)").Match(keywords);
|
||||
if (match.Length > 1)
|
||||
{
|
||||
return $"https://www.youtube.com/watch?v={match.Groups["id"].Value}";
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.GoogleAPIKey))
|
||||
throw new InvalidCredentialException("Google API Key is missing.");
|
||||
|
||||
var response = await GetResponseStringAsync(
|
||||
$"https://www.googleapis.com/youtube/v3/search?" +
|
||||
$"part=snippet&maxResults=1" +
|
||||
$"&q={Uri.EscapeDataString(keywords)}" +
|
||||
$"&key={NadekoBot.Credentials.GoogleAPIKey}").ConfigureAwait(false);
|
||||
JObject obj = JObject.Parse(response);
|
||||
|
||||
var data = JsonConvert.DeserializeObject<YoutubeVideoSearch>(response);
|
||||
|
||||
if (data.items.Length > 0)
|
||||
{
|
||||
var toReturn = "http://www.youtube.com/watch?v=" + data.items[0].id.videoId.ToString();
|
||||
return toReturn;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static async Task<IEnumerable<string>> GetRelatedVideoIds(string id, int count = 1)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(id))
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
var match = new Regex("(?:youtu\\.be\\/|v=)(?<id>[\\da-zA-Z\\-_]*)").Match(id);
|
||||
if (match.Length > 1)
|
||||
{
|
||||
id = match.Groups["id"].Value;
|
||||
}
|
||||
var response = await GetResponseStringAsync(
|
||||
$"https://www.googleapis.com/youtube/v3/search?" +
|
||||
$"part=snippet&maxResults={count}&type=video" +
|
||||
$"&relatedToVideoId={id}" +
|
||||
$"&key={NadekoBot.Credentials.GoogleAPIKey}").ConfigureAwait(false);
|
||||
JObject obj = JObject.Parse(response);
|
||||
|
||||
var data = JsonConvert.DeserializeObject<YoutubeVideoSearch>(response);
|
||||
|
||||
return data.items.Select(v => "http://www.youtube.com/watch?v=" + v.id.videoId);
|
||||
}
|
||||
|
||||
public static async Task<string> GetPlaylistIdByKeyword(string query)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.GoogleAPIKey))
|
||||
throw new ArgumentNullException(nameof(query));
|
||||
var match = new Regex("(?:youtu\\.be\\/|list=)(?<id>[\\da-zA-Z\\-_]*)").Match(query);
|
||||
if (match.Length > 1)
|
||||
{
|
||||
return match.Groups["id"].Value.ToString();
|
||||
}
|
||||
var link = "https://www.googleapis.com/youtube/v3/search?part=snippet" +
|
||||
"&maxResults=1&type=playlist" +
|
||||
$"&q={Uri.EscapeDataString(query)}" +
|
||||
$"&key={NadekoBot.Credentials.GoogleAPIKey}";
|
||||
|
||||
var response = await GetResponseStringAsync(link).ConfigureAwait(false);
|
||||
var data = JsonConvert.DeserializeObject<YoutubePlaylistSearch>(response);
|
||||
JObject obj = JObject.Parse(response);
|
||||
|
||||
return data.items.Length > 0 ? data.items[0].id.playlistId.ToString() : null;
|
||||
}
|
||||
|
||||
public static async Task<IList<string>> GetVideoIDs(string playlist, int number = 50)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.GoogleAPIKey))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(playlist));
|
||||
}
|
||||
if (number < 1)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
string nextPageToken = null;
|
||||
|
||||
List<string> toReturn = new List<string>();
|
||||
|
||||
do
|
||||
{
|
||||
var toGet = number > 50 ? 50 : number;
|
||||
number -= toGet;
|
||||
var link =
|
||||
$"https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails" +
|
||||
$"&maxResults={toGet}" +
|
||||
$"&playlistId={playlist}" +
|
||||
$"&key={NadekoBot.Credentials.GoogleAPIKey}";
|
||||
if (!string.IsNullOrWhiteSpace(nextPageToken))
|
||||
link += $"&pageToken={nextPageToken}";
|
||||
var response = await GetResponseStringAsync(link).ConfigureAwait(false);
|
||||
var data = await Task.Run(() => JsonConvert.DeserializeObject<PlaylistItemsSearch>(response)).ConfigureAwait(false);
|
||||
nextPageToken = data.nextPageToken;
|
||||
toReturn.AddRange(data.items.Select(i => i.contentDetails.videoId));
|
||||
} while (number > 0 && !string.IsNullOrWhiteSpace(nextPageToken));
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
public static async Task<string> ShortenUrl(string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.GoogleAPIKey)) return url;
|
||||
try
|
||||
{
|
||||
var httpWebRequest =
|
||||
(HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url?key=" +
|
||||
NadekoBot.Credentials.GoogleAPIKey);
|
||||
httpWebRequest.ContentType = "application/json";
|
||||
httpWebRequest.Method = "POST";
|
||||
|
||||
using (var streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false)))
|
||||
{
|
||||
var json = "{\"longUrl\":\"" + Uri.EscapeDataString(url) + "\"}";
|
||||
streamWriter.Write(json);
|
||||
}
|
||||
|
||||
var httpResponse = (await httpWebRequest.GetResponseAsync().ConfigureAwait(false)) as HttpWebResponse;
|
||||
var responseStream = httpResponse.GetResponseStream();
|
||||
using (var streamReader = new StreamReader(responseStream))
|
||||
{
|
||||
var responseText = await streamReader.ReadToEndAsync().ConfigureAwait(false);
|
||||
return Regex.Match(responseText, @"""id"": ?""(?<id>.+)""").Groups["id"].Value;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Shortening of this url failed: " + url);
|
||||
Console.WriteLine(ex.ToString());
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
public static string ShowInPrettyCode<T>(IEnumerable<T> items, Func<T, string> howToPrint, int cols = 3)
|
||||
{
|
||||
var i = 0;
|
||||
return "```xl\n" + string.Join("\n", items.GroupBy(item => (i++) / cols)
|
||||
.Select(ig => string.Concat(ig.Select(el => howToPrint(el)))))
|
||||
+ $"\n```";
|
||||
}
|
||||
}
|
||||
}
|
@ -1,292 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Classes
|
||||
{
|
||||
public class SpecificConfigurations
|
||||
{
|
||||
public static SpecificConfigurations Default { get; } = new SpecificConfigurations();
|
||||
public static bool Instantiated { get; private set; }
|
||||
|
||||
private const string filePath = "data/ServerSpecificConfigs.json";
|
||||
|
||||
static SpecificConfigurations() { }
|
||||
|
||||
private SpecificConfigurations()
|
||||
{
|
||||
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
configs = JsonConvert
|
||||
.DeserializeObject<ConcurrentDictionary<ulong, ServerSpecificConfig>>(
|
||||
File.ReadAllText(filePath), new JsonSerializerSettings()
|
||||
{
|
||||
Error = (s, e) =>
|
||||
{
|
||||
if (e.ErrorContext.Member.ToString() == "GenerateCurrencyChannels")
|
||||
{
|
||||
e.ErrorContext.Handled = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Deserialization failing: {ex}");
|
||||
}
|
||||
}
|
||||
if (configs == null)
|
||||
configs = new ConcurrentDictionary<ulong, ServerSpecificConfig>();
|
||||
Instantiated = true;
|
||||
}
|
||||
|
||||
private readonly ConcurrentDictionary<ulong, ServerSpecificConfig> configs;
|
||||
|
||||
public IEnumerable<ServerSpecificConfig> AllConfigs => configs.Values;
|
||||
|
||||
public ServerSpecificConfig Of(ulong id) =>
|
||||
configs.GetOrAdd(id, _ => new ServerSpecificConfig());
|
||||
|
||||
private readonly SemaphoreSlim saveLock = new SemaphoreSlim(1, 1);
|
||||
|
||||
public async Task Save()
|
||||
{
|
||||
await saveLock.WaitAsync();
|
||||
try
|
||||
{
|
||||
File.WriteAllText(filePath, JsonConvert.SerializeObject(configs, Formatting.Indented));
|
||||
}
|
||||
finally
|
||||
{
|
||||
saveLock.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ServerSpecificConfig : INotifyPropertyChanged
|
||||
{
|
||||
[JsonProperty("VoicePlusTextEnabled")]
|
||||
private bool voicePlusTextEnabled;
|
||||
[JsonIgnore]
|
||||
public bool VoicePlusTextEnabled {
|
||||
get { return voicePlusTextEnabled; }
|
||||
set {
|
||||
voicePlusTextEnabled = value;
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
[JsonProperty("SendPrivateMessageOnMention")]
|
||||
private bool sendPrivateMessageOnMention;
|
||||
[JsonIgnore]
|
||||
public bool SendPrivateMessageOnMention {
|
||||
get { return sendPrivateMessageOnMention; }
|
||||
set {
|
||||
sendPrivateMessageOnMention = value;
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("LogChannel")]
|
||||
private ulong? logServerChannel = null;
|
||||
[JsonIgnore]
|
||||
public ulong? LogServerChannel {
|
||||
get { return logServerChannel; }
|
||||
set {
|
||||
logServerChannel = value;
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
private ObservableCollection<ulong> logserverIgnoreChannels;
|
||||
public ObservableCollection<ulong> LogserverIgnoreChannels {
|
||||
get { return logserverIgnoreChannels; }
|
||||
set {
|
||||
logserverIgnoreChannels = value;
|
||||
if (value != null)
|
||||
logserverIgnoreChannels.CollectionChanged += (s, e) =>
|
||||
{
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("LogPresenceChannel")]
|
||||
private ulong? logPresenceChannel = null;
|
||||
[JsonIgnore]
|
||||
public ulong? LogPresenceChannel {
|
||||
get { return logPresenceChannel; }
|
||||
set {
|
||||
logPresenceChannel = value;
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
private ObservableConcurrentDictionary<ulong, ulong> voiceChannelLog;
|
||||
public ObservableConcurrentDictionary<ulong, ulong> VoiceChannelLog {
|
||||
get { return voiceChannelLog; }
|
||||
set {
|
||||
voiceChannelLog = value;
|
||||
if (value != null)
|
||||
voiceChannelLog.CollectionChanged += (s, e) =>
|
||||
{
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
private ObservableCollection<ulong> listOfSelfAssignableRoles;
|
||||
public ObservableCollection<ulong> ListOfSelfAssignableRoles {
|
||||
get { return listOfSelfAssignableRoles; }
|
||||
set {
|
||||
listOfSelfAssignableRoles = value;
|
||||
if (value != null)
|
||||
listOfSelfAssignableRoles.CollectionChanged += (s, e) =>
|
||||
{
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[JsonIgnore]
|
||||
private ulong autoAssignedRole = 0;
|
||||
public ulong AutoAssignedRole {
|
||||
get { return autoAssignedRole; }
|
||||
set {
|
||||
autoAssignedRole = value;
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
private ObservableConcurrentDictionary<ulong, int> generateCurrencyChannels;
|
||||
public ObservableConcurrentDictionary<ulong, int> GenerateCurrencyChannels {
|
||||
get { return generateCurrencyChannels; }
|
||||
set {
|
||||
generateCurrencyChannels = value;
|
||||
if (value != null)
|
||||
generateCurrencyChannels.CollectionChanged += (s, e) =>
|
||||
{
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
private bool autoDeleteMessagesOnCommand = false;
|
||||
public bool AutoDeleteMessagesOnCommand {
|
||||
get { return autoDeleteMessagesOnCommand; }
|
||||
set {
|
||||
autoDeleteMessagesOnCommand = value;
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
private bool exclusiveSelfAssignedRoles = false;
|
||||
public bool ExclusiveSelfAssignedRoles
|
||||
{
|
||||
get { return exclusiveSelfAssignedRoles; }
|
||||
set
|
||||
{
|
||||
exclusiveSelfAssignedRoles = value;
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[JsonIgnore]
|
||||
private ObservableCollection<StreamNotificationConfig> observingStreams;
|
||||
public ObservableCollection<StreamNotificationConfig> ObservingStreams {
|
||||
get { return observingStreams; }
|
||||
set {
|
||||
observingStreams = value;
|
||||
if (value != null)
|
||||
observingStreams.CollectionChanged += (s, e) =>
|
||||
{
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
private float defaultMusicVolume = 1f;
|
||||
public float DefaultMusicVolume {
|
||||
get { return defaultMusicVolume; }
|
||||
set {
|
||||
defaultMusicVolume = value;
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public ServerSpecificConfig()
|
||||
{
|
||||
ListOfSelfAssignableRoles = new ObservableCollection<ulong>();
|
||||
ObservingStreams = new ObservableCollection<StreamNotificationConfig>();
|
||||
GenerateCurrencyChannels = new ObservableConcurrentDictionary<ulong, int>();
|
||||
VoiceChannelLog = new ObservableConcurrentDictionary<ulong, ulong>();
|
||||
LogserverIgnoreChannels = new ObservableCollection<ulong>();
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged = async delegate { await SpecificConfigurations.Default.Save().ConfigureAwait(false); };
|
||||
|
||||
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
public class StreamNotificationConfig : IEquatable<StreamNotificationConfig>
|
||||
{
|
||||
public string Username { get; set; }
|
||||
public StreamType Type { get; set; }
|
||||
public ulong ServerId { get; set; }
|
||||
public ulong ChannelId { get; set; }
|
||||
public bool LastStatus { get; set; }
|
||||
|
||||
public enum StreamType
|
||||
{
|
||||
Twitch,
|
||||
Beam,
|
||||
Hitbox,
|
||||
YoutubeGaming
|
||||
}
|
||||
|
||||
public bool Equals(StreamNotificationConfig other) =>
|
||||
this.Username.ToLower().Trim() == other.Username.ToLower().Trim() &&
|
||||
this.Type == other.Type &&
|
||||
this.ServerId == other.ServerId;
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (int)ServerId + Username.Length + (int)Type;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
using Discord.Commands;
|
||||
using Discord.Modules;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NadekoBot.Modules.CustomReactions
|
||||
{
|
||||
public class CustomReactionsModule : DiscordModule
|
||||
{
|
||||
public override string Prefix { get; } = "";
|
||||
|
||||
private Random rng = new Random();
|
||||
|
||||
private Dictionary<Regex, Func<CommandEventArgs, Match, string>> commandFuncs;
|
||||
|
||||
public CustomReactionsModule()
|
||||
{
|
||||
commandFuncs = new Dictionary<Regex, Func<CommandEventArgs, Match, string>>
|
||||
{
|
||||
{new Regex(@"(?:%rng%|%rng:(\d{1,9})-(\d{1,9})%)"), (e,m) => {
|
||||
int start, end;
|
||||
if (m.Groups[1].Success)
|
||||
{
|
||||
start = int.Parse(m.Groups[1].Value);
|
||||
end = int.Parse(m.Groups[2].Value);
|
||||
return rng.Next(start, end).ToString();
|
||||
}else return rng.Next().ToString();
|
||||
} },
|
||||
{new Regex("%mention%"), (e,m) => NadekoBot.BotMention },
|
||||
{new Regex("%user%"), (e,m) => umsg.Author.Mention },
|
||||
{new Regex("%target%"), (e,m) => args?.Trim() ?? "" },
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public override void Install(ModuleManager manager)
|
||||
{
|
||||
manager.CreateCommands("", cgb =>
|
||||
{
|
||||
cgb.AddCheck(PermissionChecker.Instance);
|
||||
|
||||
foreach (var command in NadekoBot.Config.CustomReactions)
|
||||
{
|
||||
var commandName = command.Key.Replace("%mention%", NadekoBot.BotMention);
|
||||
|
||||
var c = cgb.CreateCommand(commandName);
|
||||
if (commandName.Contains(NadekoBot.BotMention))
|
||||
c.Alias(commandName.Replace("<@", "<@!"));
|
||||
c.Description($"Custom reaction. | `{command.Key}`")
|
||||
.Parameter("args", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
string str = command.Value[rng.Next(0, command.Value.Count())];
|
||||
commandFuncs.Keys.ForEach(key => str = key.Replace(str, m => commandFuncs[key](e, m)));
|
||||
|
||||
|
||||
await channel.SendMessageAsync(str).ConfigureAwait(false);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Modules;
|
||||
|
||||
namespace NadekoBot.Classes
|
||||
{
|
||||
/// <summary>
|
||||
/// Base DiscordCommand Class.
|
||||
/// Inherit this class to create your own command.
|
||||
/// </summary>
|
||||
public abstract class DiscordCommand
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Parent module
|
||||
/// </summary>
|
||||
protected DiscordModule Module { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Parent module's prefix
|
||||
/// </summary>
|
||||
protected string Prefix => Module.Prefix;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of discord command,
|
||||
/// use ": base(module)" in the derived class'
|
||||
/// constructor to make sure module is assigned
|
||||
/// </summary>
|
||||
/// <param name="module">Module this command resides in</param>
|
||||
protected DiscordCommand(DiscordModule module)
|
||||
{
|
||||
this.Module = module;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the CommandBuilder with values using CommandGroupBuilder
|
||||
/// </summary>
|
||||
public abstract void Init(CommandGroupBuilder cgb);
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
using Discord.Modules;
|
||||
using System.Collections.Generic;
|
||||
using NadekoBot.Classes;
|
||||
|
||||
namespace NadekoBot.Modules {
|
||||
public abstract class DiscordModule : IModule {
|
||||
protected readonly HashSet<DiscordCommand> commands = new HashSet<DiscordCommand>();
|
||||
|
||||
public abstract string Prefix { get; }
|
||||
|
||||
public abstract void Install(ModuleManager manager);
|
||||
}
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.Commands.Permissions;
|
||||
using NadekoBot.Classes.JSONModels;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions.Classes
|
||||
{
|
||||
|
||||
public class PermissionChecker : IPermissionChecker
|
||||
{
|
||||
public static PermissionChecker Instance { get; } = new PermissionChecker();
|
||||
|
||||
//key - sid:command
|
||||
//value - userid
|
||||
private ConcurrentDictionary<string, ulong> commandCooldowns = new ConcurrentDictionary<string, ulong>();
|
||||
private HashSet<ulong> timeBlackList { get; } = new HashSet<ulong>();
|
||||
|
||||
static PermissionChecker() { }
|
||||
private PermissionChecker()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
//blacklist is cleared every 1.00 seconds. That is the most time anyone will be blocked
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
timeBlackList.Clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public bool CanRun(Command command, User user, Channel channel, out string error)
|
||||
{
|
||||
error = String.Empty;
|
||||
|
||||
if (!NadekoBot.Ready)
|
||||
return false;
|
||||
|
||||
if (channel.IsPrivate || channel.Server == null)
|
||||
return command.Category == "Help";
|
||||
|
||||
if (ConfigHandler.IsUserBlacklisted(user.Id) ||
|
||||
(!channel.IsPrivate &&
|
||||
(ConfigHandler.IsServerBlacklisted(channel.Server.Id) || ConfigHandler.IsChannelBlacklisted(channel.Id))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (timeBlackList.Contains(user.Id))
|
||||
return false;
|
||||
|
||||
if (!channel.IsPrivate && !channel.Server.CurrentUser.GetPermissions(channel).SendMessages)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
timeBlackList.Add(user.Id);
|
||||
|
||||
ServerPermissions perms;
|
||||
PermissionsHandler.PermissionsDict.TryGetValue(user.Server.Id, out perms);
|
||||
|
||||
AddUserCooldown(user.Server.Id, user.Id, command.Text.ToLower());
|
||||
if (commandCooldowns.Keys.Contains(user.Server.Id + ":" + command.Text.ToLower()))
|
||||
{
|
||||
if (perms?.Verbose == true)
|
||||
error = $"{user.Mention} You have a cooldown on that command.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//is it a permission command?
|
||||
// if it is, check if the user has the correct role
|
||||
// if yes return true, if no return false
|
||||
if (command.Category == "Permissions")
|
||||
{
|
||||
Discord.Role role = null;
|
||||
try
|
||||
{
|
||||
role = PermissionHelper.ValidateRole(user.Server,
|
||||
PermissionsHandler.GetServerPermissionsRoleName(user.Server));
|
||||
}
|
||||
catch { }
|
||||
if (user.Server.Owner.Id == user.Id || (role != null && user.HasRole(role)))
|
||||
return true;
|
||||
throw new Exception($"You don't have the necessary role (**{(perms?.PermissionsControllerRole ?? "Nadeko")}**) to change permissions.");
|
||||
}
|
||||
|
||||
var permissionType = PermissionsHandler.GetPermissionBanType(command, user, channel);
|
||||
|
||||
string msg;
|
||||
|
||||
if (permissionType == PermissionsHandler.PermissionBanType.ServerBanModule &&
|
||||
command.Category.ToLower() == "nsfw")
|
||||
msg = $"**{command.Category}** module has been banned from use on this **server**.\nNSFW module is disabled by default. Server owner can type `;sm nsfw enable` to enable it.";
|
||||
else
|
||||
switch (permissionType)
|
||||
{
|
||||
case PermissionsHandler.PermissionBanType.None:
|
||||
return true;
|
||||
case PermissionsHandler.PermissionBanType.ServerBanCommand:
|
||||
msg = $"**{command.Text}** command has been banned from use on this **server**.";
|
||||
break;
|
||||
case PermissionsHandler.PermissionBanType.ServerBanModule:
|
||||
msg = $"**{command.Category}** module has been banned from use on this **server**.";
|
||||
break;
|
||||
case PermissionsHandler.PermissionBanType.ChannelBanCommand:
|
||||
msg = $"**{command.Text}** command has been banned from use on this **channel**.";
|
||||
break;
|
||||
case PermissionsHandler.PermissionBanType.ChannelBanModule:
|
||||
msg = $"**{command.Category}** module has been banned from use on this **channel**.";
|
||||
break;
|
||||
case PermissionsHandler.PermissionBanType.RoleBanCommand:
|
||||
msg = $"You do not have a **role** which permits you the usage of **{command.Text}** command.";
|
||||
break;
|
||||
case PermissionsHandler.PermissionBanType.RoleBanModule:
|
||||
msg = $"You do not have a **role** which permits you the usage of **{command.Category}** module.";
|
||||
break;
|
||||
case PermissionsHandler.PermissionBanTypumsg.AuthorBanCommand:
|
||||
msg = $"{user.Mention}, You have been banned from using **{command.Text}** command.";
|
||||
break;
|
||||
case PermissionsHandler.PermissionBanTypumsg.AuthorBanModule:
|
||||
msg = $"{user.Mention}, You have been banned from using **{command.Category}** module.";
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
if (PermissionsHandler.PermissionsDict[user.Server.Id].Verbose) //if verbose - print errors
|
||||
error = msg;
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Exception in canrun: {ex}");
|
||||
try
|
||||
{
|
||||
if (perms != null && perms.Verbose)
|
||||
//if verbose - print errors
|
||||
error = ex.Message;
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
Console.WriteLine($"SERIOUS PERMISSION ERROR {ex2}\n\nUser:{user} Server: {user?.Server?.Name}/{user?.Server?.Id}");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddUserCooldown(ulong serverId, ulong userId, string commandName)
|
||||
{
|
||||
commandCooldowns.TryAdd(commandName, userId);
|
||||
var tosave = serverId + ":" + commandName;
|
||||
Task.Run(async () =>
|
||||
{
|
||||
ServerPermissions perms;
|
||||
PermissionsHandler.PermissionsDict.TryGetValue(serverId, out perms);
|
||||
int cd;
|
||||
if (!perms.CommandCooldowns.TryGetValue(commandName, out cd))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (commandCooldowns.TryAdd(tosave, userId))
|
||||
{
|
||||
await Task.Delay(cd * 1000);
|
||||
ulong throwaway;
|
||||
commandCooldowns.TryRemove(tosave, out throwaway);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.Modules;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions.Classes
|
||||
{
|
||||
public static class PermissionHelper
|
||||
{
|
||||
public static bool ValidateBool(string passedArg)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(passedArg))
|
||||
{
|
||||
throw new ArgumentException("No value supplied! Missing argument");
|
||||
}
|
||||
switch (passedArg.ToLower())
|
||||
{
|
||||
case "1":
|
||||
case "t":
|
||||
case "true":
|
||||
case "enable":
|
||||
case "enabled":
|
||||
case "allow":
|
||||
case "unban":
|
||||
return true;
|
||||
case "0":
|
||||
case "f":
|
||||
case "false":
|
||||
case "disable":
|
||||
case "disabled":
|
||||
case "disallow":
|
||||
case "ban":
|
||||
return false;
|
||||
default:
|
||||
throw new ArgumentException("Did not receive a valid boolean value");
|
||||
}
|
||||
}
|
||||
|
||||
public static string ValidateModule(string mod)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(mod))
|
||||
throw new ArgumentNullException(nameof(mod));
|
||||
|
||||
foreach (var m in NadekoBot.Client.GetService<ModuleService>().Modules)
|
||||
{
|
||||
if (m.Name.ToLower().Equals(mod.Trim().ToLower()))
|
||||
return m.Name;
|
||||
}
|
||||
throw new ArgumentException("That module does not exist.");
|
||||
}
|
||||
|
||||
public static string ValidateCommand(string commandText)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(commandText))
|
||||
throw new ArgumentNullException(nameof(commandText));
|
||||
|
||||
var normalizedCmdTxt = commandText.Trim().ToUpperInvariant();
|
||||
|
||||
foreach (var com in NadekoBot.Client.GetService<CommandService>().AllCommands)
|
||||
{
|
||||
if (com.Text.ToUpperInvariant().Equals(normalizedCmdTxt) || com.Aliases.Select(c=>c.ToUpperInvariant()).Contains(normalizedCmdTxt))
|
||||
return com.Text;
|
||||
}
|
||||
throw new NullReferenceException("That command does not exist.");
|
||||
}
|
||||
|
||||
public static Role ValidateRole(Server server, string roleName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(roleName))
|
||||
throw new ArgumentNullException(nameof(roleName));
|
||||
|
||||
if (roleName.Trim() == "everyone")
|
||||
roleName = "@everyone";
|
||||
var role = server.FindRoles(roleName.Trim()).FirstOrDefault();
|
||||
if (role == null)
|
||||
throw new NullReferenceException("That role does not exist.");
|
||||
return role;
|
||||
}
|
||||
|
||||
public static Channel ValidateChannel(Server server, string channelName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(channelName))
|
||||
throw new ArgumentNullException(nameof(channelName));
|
||||
var channel = server.FindChannels(channelName.Trim(), ChannelType.Text).FirstOrDefault();
|
||||
if (channel == null)
|
||||
throw new NullReferenceException("That channel does not exist.");
|
||||
return channel;
|
||||
}
|
||||
|
||||
public static User ValidateUser(Server server, string userName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(userName))
|
||||
throw new ArgumentNullException(nameof(userName));
|
||||
var user = server.FindUsers(userName.Trim()).FirstOrDefault();
|
||||
if (user == null)
|
||||
throw new NullReferenceException("That user does not exist.");
|
||||
return user;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,575 +0,0 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions.Classes
|
||||
{
|
||||
public static class PermissionsHandler
|
||||
{
|
||||
public static ConcurrentDictionary<ulong, ServerPermissions> PermissionsDict =
|
||||
new ConcurrentDictionary<ulong, ServerPermissions>();
|
||||
|
||||
public enum PermissionBanType
|
||||
{
|
||||
None, ServerBanCommand, ServerBanModule,
|
||||
ChannelBanCommand, ChannelBanModule, RoleBanCommand,
|
||||
RoleBanModule, UserBanCommand, UserBanModule
|
||||
}
|
||||
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Console.WriteLine("Reading from the permission files.");
|
||||
Directory.CreateDirectory("data/permissions");
|
||||
foreach (var file in Directory.EnumerateFiles("data/permissions/"))
|
||||
{
|
||||
try
|
||||
{
|
||||
var strippedFileName = Path.GetFileNameWithoutExtension(file);
|
||||
if (string.IsNullOrWhiteSpace(strippedFileName)) continue;
|
||||
var id = ulong.Parse(strippedFileName);
|
||||
var data = Newtonsoft.Json.JsonConvert.DeserializeObject<ServerPermissions>(File.ReadAllText(file));
|
||||
PermissionsDict.TryAdd(id, data);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
Console.WriteLine("Permission initialization complete.");
|
||||
}
|
||||
|
||||
public static Permissions GetRolePermissionsById(Server server, ulong id)
|
||||
{
|
||||
ServerPermissions serverPerms;
|
||||
if (!PermissionsDict.TryGetValue(server.Id, out serverPerms))
|
||||
return null;
|
||||
|
||||
Permissions toReturn;
|
||||
serverPerms.RolePermissions.TryGetValue(id, out toReturn);
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
public static Permissions GetUserPermissionsById(Server server, ulong id)
|
||||
{
|
||||
ServerPermissions serverPerms;
|
||||
if (!PermissionsDict.TryGetValue(server.Id, out serverPerms))
|
||||
return null;
|
||||
|
||||
Permissions toReturn;
|
||||
serverPerms.UserPermissions.TryGetValue(id, out toReturn);
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
public static Permissions GetChannelPermissionsById(Server server, ulong id)
|
||||
{
|
||||
ServerPermissions serverPerms;
|
||||
if (!PermissionsDict.TryGetValue(server.Id, out serverPerms))
|
||||
return null;
|
||||
|
||||
Permissions toReturn;
|
||||
serverPerms.ChannelPermissions.TryGetValue(id, out toReturn);
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
public static Permissions GetServerPermissions(Server server)
|
||||
{
|
||||
ServerPermissions serverPerms;
|
||||
return !PermissionsDict.TryGetValue(server.Id, out serverPerms) ? null : serverPerms.Permissions;
|
||||
}
|
||||
|
||||
public static PermissionBanType GetPermissionBanType(Command command, User user, Channel channel)
|
||||
{
|
||||
var server = user.Server;
|
||||
ServerPermissions serverPerms = PermissionsDict.GetOrAdd(server.Id, id => new ServerPermissions(id, server.Name));
|
||||
bool val;
|
||||
Permissions perm;
|
||||
//server
|
||||
if (serverPerms.Permissions.Modules.TryGetValue(command.Category, out val) && val == false)
|
||||
return PermissionBanType.ServerBanModule;
|
||||
if (serverPerms.Permissions.Commands.TryGetValue(command.Text, out val) && val == false)
|
||||
return PermissionBanType.ServerBanCommand;
|
||||
//channel
|
||||
if (serverPerms.ChannelPermissions.TryGetValue(channel.Id, out perm) &&
|
||||
perm.Modules.TryGetValue(command.Category, out val) && val == false)
|
||||
return PermissionBanType.ChannelBanModule;
|
||||
if (serverPerms.ChannelPermissions.TryGetValue(channel.Id, out perm) &&
|
||||
perm.Commands.TryGetValue(command.Text, out val) && val == false)
|
||||
return PermissionBanType.ChannelBanCommand;
|
||||
|
||||
//ROLE PART - TWO CASES
|
||||
// FIRST CASE:
|
||||
// IF EVERY ROLE USER HAS IS BANNED FROM THE MODULE,
|
||||
// THAT MEANS USER CANNOT RUN THIS COMMAND
|
||||
// IF AT LEAST ONE ROLE EXIST THAT IS NOT BANNED,
|
||||
// USER CAN RUN THE COMMAND
|
||||
var foundNotBannedRole = false;
|
||||
foreach (var role in user.Roles)
|
||||
{
|
||||
//if every role is banned from using the module -> rolebanmodule
|
||||
if (serverPerms.RolePermissions.TryGetValue(role.Id, out perm) &&
|
||||
perm.Modules.TryGetValue(command.Category, out val) && val == false)
|
||||
continue;
|
||||
foundNotBannedRole = true;
|
||||
break;
|
||||
}
|
||||
if (!foundNotBannedRole)
|
||||
return PermissionBanType.RoleBanModule;
|
||||
|
||||
// SECOND CASE:
|
||||
// IF EVERY ROLE USER HAS IS BANNED FROM THE COMMAND,
|
||||
// THAT MEANS USER CANNOT RUN THAT COMMAND
|
||||
// IF AT LEAST ONE ROLE EXISTS THAT IS NOT BANNED,
|
||||
// USER CAN RUN THE COMMAND
|
||||
foundNotBannedRole = false;
|
||||
foreach (var role in user.Roles)
|
||||
{
|
||||
//if every role is banned from using the module -> rolebanmodule
|
||||
if (serverPerms.RolePermissions.TryGetValue(role.Id, out perm) &&
|
||||
perm.Commands.TryGetValue(command.Text, out val) && val == false)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
foundNotBannedRole = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundNotBannedRole)
|
||||
return PermissionBanType.RoleBanCommand;
|
||||
|
||||
//user
|
||||
if (serverPerms.UserPermissions.TryGetValue(user.Id, out perm) &&
|
||||
perm.Modules.TryGetValue(command.Category, out val) && val == false)
|
||||
return PermissionBanTypumsg.AuthorBanModule;
|
||||
if (serverPerms.UserPermissions.TryGetValue(user.Id, out perm) &&
|
||||
perm.Commands.TryGetValue(command.Text, out val) && val == false)
|
||||
return PermissionBanTypumsg.AuthorBanCommand;
|
||||
|
||||
return PermissionBanType.None;
|
||||
}
|
||||
|
||||
private static Task WriteServerToJson(ServerPermissions serverPerms) => Task.Run(() =>
|
||||
{
|
||||
string pathToFile = $"data/permissions/{serverPerms.Id}.json";
|
||||
File.WriteAllText(pathToFile,
|
||||
Newtonsoft.Json.JsonConvert.SerializeObject(serverPerms, Newtonsoft.Json.Formatting.Indented));
|
||||
});
|
||||
|
||||
public static Task WriteToJson() => Task.Run(() =>
|
||||
{
|
||||
Directory.CreateDirectory("data/permissions/");
|
||||
foreach (var kvp in PermissionsDict)
|
||||
{
|
||||
WriteServerToJson(kvp.Value);
|
||||
}
|
||||
});
|
||||
|
||||
public static string GetServerPermissionsRoleName(Server server)
|
||||
{
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
return serverPerms.PermissionsControllerRole;
|
||||
}
|
||||
|
||||
public static async Task SetPermissionsRole(Server server, string roleName)
|
||||
{
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
serverPerms.PermissionsControllerRole = roleName;
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetVerbosity(Server server, bool val)
|
||||
{
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
serverPerms.Verbose = val;
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task CopyRolePermissions(Role fromRole, Role toRole)
|
||||
{
|
||||
var server = fromRole.Server;
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
var from = GetRolePermissionsById(server, fromRole.Id);
|
||||
if (from == null)
|
||||
serverPerms.RolePermissions.Add(fromRole.Id, from = new Permissions(fromRole.Name));
|
||||
var to = GetRolePermissionsById(server, toRole.Id);
|
||||
if (to == null)
|
||||
serverPerms.RolePermissions.Add(toRole.Id, to = new Permissions(toRole.Name));
|
||||
|
||||
to.CopyFrom(from);
|
||||
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task CopyChannelPermissions(Channel fromChannel, Channel toChannel)
|
||||
{
|
||||
var server = fromChannel.Server;
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
var from = GetChannelPermissionsById(server, fromChannel.Id);
|
||||
if (from == null)
|
||||
serverPerms.ChannelPermissions.Add(fromChannel.Id, from = new Permissions(fromChannel.Name));
|
||||
var to = GetChannelPermissionsById(server, toChannel.Id);
|
||||
if (to == null)
|
||||
serverPerms.ChannelPermissions.Add(toChannel.Id, to = new Permissions(toChannel.Name));
|
||||
|
||||
to.CopyFrom(from);
|
||||
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task CopyUserPermissions(User fromUser, User toUser)
|
||||
{
|
||||
var server = fromUser.Server;
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
var from = GetUserPermissionsById(server, fromUser.Id);
|
||||
if (from == null)
|
||||
serverPerms.UserPermissions.Add(fromUser.Id, from = new Permissions(fromUser.Name));
|
||||
var to = GetUserPermissionsById(server, toUser.Id);
|
||||
if (to == null)
|
||||
serverPerms.UserPermissions.Add(toUser.Id, to = new Permissions(toUser.Name));
|
||||
|
||||
to.CopyFrom(from);
|
||||
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetServerModulePermission(Server server, string moduleName, bool value)
|
||||
{
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
var modules = serverPerms.Permissions.Modules;
|
||||
if (modules.ContainsKey(moduleName))
|
||||
modules[moduleName] = value;
|
||||
else
|
||||
modules.TryAdd(moduleName, value);
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetServerCommandPermission(Server server, string commandName, bool value)
|
||||
{
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
var commands = serverPerms.Permissions.Commands;
|
||||
if (commands.ContainsKey(commandName))
|
||||
commands[commandName] = value;
|
||||
else
|
||||
commands.TryAdd(commandName, value);
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetChannelModulePermission(Channel channel, string moduleName, bool value)
|
||||
{
|
||||
var server = channel.Server;
|
||||
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
if (!serverPerms.ChannelPermissions.ContainsKey(channel.Id))
|
||||
serverPerms.ChannelPermissions.Add(channel.Id, new Permissions(channel.Name));
|
||||
|
||||
var modules = serverPerms.ChannelPermissions[channel.Id].Modules;
|
||||
|
||||
if (modules.ContainsKey(moduleName))
|
||||
modules[moduleName] = value;
|
||||
else
|
||||
modules.TryAdd(moduleName, value);
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetChannelCommandPermission(Channel channel, string commandName, bool value)
|
||||
{
|
||||
var server = channel.Server;
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
if (!serverPerms.ChannelPermissions.ContainsKey(channel.Id))
|
||||
serverPerms.ChannelPermissions.Add(channel.Id, new Permissions(channel.Name));
|
||||
|
||||
var commands = serverPerms.ChannelPermissions[channel.Id].Commands;
|
||||
|
||||
if (commands.ContainsKey(commandName))
|
||||
commands[commandName] = value;
|
||||
else
|
||||
commands.TryAdd(commandName, value);
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetRoleModulePermission(Role role, string moduleName, bool value)
|
||||
{
|
||||
var server = role.Server;
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
if (!serverPerms.RolePermissions.ContainsKey(role.Id))
|
||||
serverPerms.RolePermissions.Add(role.Id, new Permissions(role.Name));
|
||||
|
||||
var modules = serverPerms.RolePermissions[role.Id].Modules;
|
||||
|
||||
if (modules.ContainsKey(moduleName))
|
||||
modules[moduleName] = value;
|
||||
else
|
||||
modules.TryAdd(moduleName, value);
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetRoleCommandPermission(Role role, string commandName, bool value)
|
||||
{
|
||||
var server = role.Server;
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
if (!serverPerms.RolePermissions.ContainsKey(role.Id))
|
||||
serverPerms.RolePermissions.Add(role.Id, new Permissions(role.Name));
|
||||
|
||||
var commands = serverPerms.RolePermissions[role.Id].Commands;
|
||||
|
||||
if (commands.ContainsKey(commandName))
|
||||
commands[commandName] = value;
|
||||
else
|
||||
commands.TryAdd(commandName, value);
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetUserModulePermission(User user, string moduleName, bool value)
|
||||
{
|
||||
var server = user.Server;
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
if (!serverPerms.UserPermissions.ContainsKey(user.Id))
|
||||
serverPerms.UserPermissions.Add(user.Id, new Permissions(user.Name));
|
||||
|
||||
var modules = serverPerms.UserPermissions[user.Id].Modules;
|
||||
|
||||
if (modules.ContainsKey(moduleName))
|
||||
modules[moduleName] = value;
|
||||
else
|
||||
modules.TryAdd(moduleName, value);
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetUserCommandPermission(User user, string commandName, bool value)
|
||||
{
|
||||
var server = user.Server;
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
if (!serverPerms.UserPermissions.ContainsKey(user.Id))
|
||||
serverPerms.UserPermissions.Add(user.Id, new Permissions(user.Name));
|
||||
|
||||
var commands = serverPerms.UserPermissions[user.Id].Commands;
|
||||
|
||||
if (commands.ContainsKey(commandName))
|
||||
commands[commandName] = value;
|
||||
else
|
||||
commands.TryAdd(commandName, value);
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetServerWordPermission(Server server, bool value)
|
||||
{
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
serverPerms.Permissions.FilterWords = value;
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetChannelWordPermission(Channel channel, bool value)
|
||||
{
|
||||
var server = channel.Server;
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
if (!serverPerms.ChannelPermissions.ContainsKey(channel.Id))
|
||||
serverPerms.ChannelPermissions.Add(channel.Id, new Permissions(channel.Name));
|
||||
|
||||
serverPerms.ChannelPermissions[channel.Id].FilterWords = value;
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetServerFilterInvitesPermission(Server server, bool value)
|
||||
{
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
serverPerms.Permissions.FilterInvites = value;
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetChannelFilterInvitesPermission(Channel channel, bool value)
|
||||
{
|
||||
var server = channel.Server;
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
|
||||
if (!serverPerms.ChannelPermissions.ContainsKey(channel.Id))
|
||||
serverPerms.ChannelPermissions.Add(channel.Id, new Permissions(channel.Name));
|
||||
|
||||
serverPerms.ChannelPermissions[channel.Id].FilterInvites = value;
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task SetCommandCooldown(Server server, string commandName, int value)
|
||||
{
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
if (value == 0) {
|
||||
int throwaway;
|
||||
serverPerms.CommandCooldowns.TryRemove(commandName, out throwaway);
|
||||
}
|
||||
else {
|
||||
serverPerms.CommandCooldowns.AddOrUpdate(commandName, value, (str, v) => value);
|
||||
}
|
||||
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task AddFilteredWord(Server server, string word)
|
||||
{
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
if (serverPerms.Words.Contains(word))
|
||||
throw new InvalidOperationException("That word is already banned.");
|
||||
serverPerms.Words.Add(word);
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
public static async Task RemoveFilteredWord(Server server, string word)
|
||||
{
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
if (!serverPerms.Words.Contains(word))
|
||||
throw new InvalidOperationException("That word is not banned.");
|
||||
serverPerms.Words.Remove(word);
|
||||
await WriteServerToJson(serverPerms).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Holds a permission list
|
||||
/// </summary>
|
||||
public class Permissions
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the parent object whose permissions these are
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Module name with allowed/disallowed
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<string, bool> Modules { get; set; }
|
||||
/// <summary>
|
||||
/// Command name with allowed/disallowed
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<string, bool> Commands { get; set; }
|
||||
/// <summary>
|
||||
/// Should the bot filter invites to other discord servers (and ref links in the future)
|
||||
/// </summary>
|
||||
public bool FilterInvites { get; set; }
|
||||
/// <summary>
|
||||
/// Should the bot filter words which are specified in the Words hashset
|
||||
/// </summary>
|
||||
public bool FilterWords { get; set; }
|
||||
|
||||
public Permissions(string name)
|
||||
{
|
||||
Name = name;
|
||||
Modules = new ConcurrentDictionary<string, bool>();
|
||||
Commands = new ConcurrentDictionary<string, bool>();
|
||||
FilterInvites = false;
|
||||
FilterWords = false;
|
||||
}
|
||||
|
||||
public void CopyFrom(Permissions other)
|
||||
{
|
||||
Modules.Clear();
|
||||
foreach (var mp in other.Modules)
|
||||
Modules.AddOrUpdate(mp.Key, mp.Value, (s, b) => mp.Value);
|
||||
Commands.Clear();
|
||||
foreach (var cp in other.Commands)
|
||||
Commands.AddOrUpdate(cp.Key, cp.Value, (s, b) => cp.Value);
|
||||
FilterInvites = other.FilterInvites;
|
||||
FilterWords = other.FilterWords;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var toReturn = "";
|
||||
var bannedModules = Modules.Where(kvp => kvp.Value == false);
|
||||
var bannedModulesArray = bannedModules as KeyValuePair<string, bool>[] ?? bannedModules.ToArray();
|
||||
if (bannedModulesArray.Any())
|
||||
{
|
||||
toReturn += "`Banned Modules:`\n";
|
||||
toReturn = bannedModulesArray.Aggregate(toReturn, (current, m) => current + $"\t`[x] {m.Key}`\n");
|
||||
}
|
||||
var bannedCommands = Commands.Where(kvp => kvp.Value == false);
|
||||
var bannedCommandsArr = bannedCommands as KeyValuePair<string, bool>[] ?? bannedCommands.ToArray();
|
||||
if (bannedCommandsArr.Any())
|
||||
{
|
||||
toReturn += "`Banned Commands:`\n";
|
||||
toReturn = bannedCommandsArr.Aggregate(toReturn, (current, c) => current + $"\t`[x] {c.Key}`\n");
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
}
|
||||
|
||||
public class ServerPermissions
|
||||
{
|
||||
/// <summary>
|
||||
/// The guy who can edit the permissions
|
||||
/// </summary>
|
||||
public string PermissionsControllerRole { get; set; }
|
||||
/// <summary>
|
||||
/// Does it print the error when a restriction occurs
|
||||
/// </summary>
|
||||
public bool Verbose { get; set; }
|
||||
/// <summary>
|
||||
/// The id of the thing (user/server/channel)
|
||||
/// </summary>
|
||||
public ulong Id { get; set; } //a string because of the role name.
|
||||
/// <summary>
|
||||
/// Permission object bound to the id of something/role name
|
||||
/// </summary>
|
||||
public Permissions Permissions { get; set; }
|
||||
/// <summary>
|
||||
/// Banned words, usually profanities, like word "java"
|
||||
/// </summary>
|
||||
public HashSet<string> Words { get; set; }
|
||||
|
||||
public Dictionary<ulong, Permissions> UserPermissions { get; set; }
|
||||
public Dictionary<ulong, Permissions> ChannelPermissions { get; set; }
|
||||
public Dictionary<ulong, Permissions> RolePermissions { get; set; }
|
||||
/// <summary>
|
||||
/// Dictionary of command names with their respective cooldowns
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<string, int> CommandCooldowns { get; set; }
|
||||
|
||||
public ServerPermissions(ulong id, string name)
|
||||
{
|
||||
Id = id;
|
||||
PermissionsControllerRole = "Nadeko";
|
||||
Verbose = true;
|
||||
|
||||
Permissions = new Permissions(name);
|
||||
Permissions.Modules.TryAdd("NSFW", false);
|
||||
UserPermissions = new Dictionary<ulong, Permissions>();
|
||||
ChannelPermissions = new Dictionary<ulong, Permissions>();
|
||||
RolePermissions = new Dictionary<ulong, Permissions>();
|
||||
CommandCooldowns = new ConcurrentDictionary<string, int>();
|
||||
Words = new HashSet<string>();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.Commands.Permissions;
|
||||
using System;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions.Classes
|
||||
{
|
||||
public static class SimpleCheckers
|
||||
{
|
||||
public static ManageRoles CanManageRoles { get; } = new ManageRoles();
|
||||
|
||||
public static Func<Command, User, Channel, bool> OwnerOnly() =>
|
||||
(com, user, ch) => NadekoBot.IsOwner(user.Id);
|
||||
|
||||
public static Func<Command, User, Channel, bool> ManageMessages() =>
|
||||
(com, user, ch) => user.ServerPermissions.ManageMessages;
|
||||
|
||||
public static Func<Command, User, Channel, bool> ManageChannels() =>
|
||||
(com, user, ch) => user.ServerPermissions.ManageChannels;
|
||||
|
||||
public static Func<Command, User, Channel, bool> ManageServer() =>
|
||||
(com, user, ch) => user.ServerPermissions.ManageServer;
|
||||
|
||||
public class ManageRoles : IPermissionChecker
|
||||
{
|
||||
public bool CanRun(Command command, User user, Channel channel, out string error)
|
||||
{
|
||||
error = string.Empty;
|
||||
if (user.ServerPermissions.ManageRoles)
|
||||
return true;
|
||||
error = "You do not have a permission to manage roles.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,117 +0,0 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
public class FilterInvitesCommand : DiscordCommand
|
||||
{
|
||||
private readonly Regex filterRegex = new Regex(@"(?:discord(?:\.gg|app\.com\/invite)\/(?<id>([\w]{16}|(?:[\w]+-?){3})))");
|
||||
|
||||
|
||||
public FilterInvitesCommand(DiscordModule module) : base(module)
|
||||
{
|
||||
NadekoBot.Client.MessageReceived += async (sender, args) =>
|
||||
{
|
||||
if (args.Channel.IsPrivate || args.User.Id == NadekoBot.Client.CurrentUser.Id) return;
|
||||
try
|
||||
{
|
||||
Classes.ServerPermissions serverPerms;
|
||||
if (!IsChannelOrServerFiltering(args.Channel, out serverPerms)) return;
|
||||
|
||||
if (filterRegex.IsMatch(args.Message.RawText))
|
||||
{
|
||||
await args.Message.Delete().ConfigureAwait(false);
|
||||
IncidentsHandler.Add(args.Server.Id, args.Channel.Id, $"User [{args.User.Name}/{args.User.Id}] posted " +
|
||||
$"INVITE LINK in [{args.Channel.Name}/{args.Channel.Id}] channel.\n" +
|
||||
$"`Full message:` {args.Message.Text}");
|
||||
if (serverPerms.Verbose)
|
||||
await args.Channel.SendMessageAsync($"{args.User.Mention} Invite links are not " +
|
||||
$"allowed on this channel.")
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
};
|
||||
}
|
||||
|
||||
private static bool IsChannelOrServerFiltering(Channel channel, out Classes.ServerPermissions serverPerms)
|
||||
{
|
||||
if (!PermissionsHandler.PermissionsDict.TryGetValue(channel.Server.Id, out serverPerms)) return false;
|
||||
|
||||
if (serverPerms.Permissions.FilterInvites)
|
||||
return true;
|
||||
|
||||
Classes.Permissions perms;
|
||||
return serverPerms.ChannelPermissions.TryGetValue(channel.Id, out perms) && perms.FilterInvites;
|
||||
}
|
||||
|
||||
public override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "chnlfilterinv")
|
||||
.Alias(Module.Prefix + "cfi")
|
||||
.Description("Enables or disables automatic deleting of invites on the channel." +
|
||||
"If no channel supplied, it will default to current one. Use ALL to apply to all existing channels at once." +
|
||||
$" | `{Prefix}cfi enable #general-chat`")
|
||||
.Parameter("bool")
|
||||
.Parameter("channel", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var chanStr = channel;
|
||||
|
||||
if (chanStr?.ToLowerInvariant().Trim() != "all")
|
||||
{
|
||||
|
||||
var chan = string.IsNullOrWhiteSpace(chanStr)
|
||||
? e.Channel
|
||||
: PermissionHelper.ValidateChannel(e.Server, chanStr);
|
||||
await PermissionsHandler.SetChannelFilterInvitesPermission(chan, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Invite Filter has been **{(state ? "enabled" : "disabled")}** for **{chan.Name}** channel.")
|
||||
.ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
//all channels
|
||||
|
||||
foreach (var curChannel in e.Server.TextChannels)
|
||||
{
|
||||
await PermissionsHandler.SetChannelFilterInvitesPermission(curChannel, state).ConfigureAwait(false);
|
||||
}
|
||||
await channel.SendMessageAsync($"Invite Filter has been **{(state ? "enabled" : "disabled")}** for **ALL** channels.")
|
||||
.ConfigureAwait(false);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync($"💢 Error: {ex.Message}")
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "srvrfilterinv")
|
||||
.Alias(Module.Prefix + "sfi")
|
||||
.Description($"Enables or disables automatic deleting of invites on the server. | `{Prefix}sfi disable`")
|
||||
.Parameter("bool")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
await PermissionsHandler.SetServerFilterInvitesPermission(e.Server, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Invite Filter has been **{(state ? "enabled" : "disabled")}** for this server.")
|
||||
.ConfigureAwait(false);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync($"💢 Error: {ex.Message}").ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
public class FilterWords : DiscordCommand
|
||||
{
|
||||
public FilterWords(DiscordModule module) : base(module)
|
||||
{
|
||||
NadekoBot.Client.MessageReceived += async (sender, args) =>
|
||||
{
|
||||
if (args.Channel.IsPrivate || args.User.Id == NadekoBot.Client.CurrentUser.Id) return;
|
||||
try
|
||||
{
|
||||
Classes.ServerPermissions serverPerms;
|
||||
if (!IsChannelOrServerFiltering(args.Channel, out serverPerms)) return;
|
||||
|
||||
var wordsInMessage = args.Message.RawText.ToLowerInvariant().Split(' ');
|
||||
if (serverPerms.Words.Any(w => wordsInMessage.Contains(w)))
|
||||
{
|
||||
await args.Message.Delete().ConfigureAwait(false);
|
||||
IncidentsHandler.Add(args.Server.Id, args.Channel.Id, $"User [{args.User.Name}/{args.User.Id}] posted " +
|
||||
$"BANNED WORD in [{args.Channel.Name}/{args.Channel.Id}] channel.\n" +
|
||||
$"`Full message:` {args.Message.Text}");
|
||||
if (serverPerms.Verbose)
|
||||
await args.Channel.SendMessageAsync($"{args.User.Mention} One or more of the words you used " +
|
||||
$"in that sentence are not allowed here.")
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
};
|
||||
}
|
||||
|
||||
private static bool IsChannelOrServerFiltering(Channel channel, out Classes.ServerPermissions serverPerms)
|
||||
{
|
||||
if (!PermissionsHandler.PermissionsDict.TryGetValue(channel.Server.Id, out serverPerms)) return false;
|
||||
|
||||
if (serverPerms.Permissions.FilterWords)
|
||||
return true;
|
||||
|
||||
Classes.Permissions perms;
|
||||
return serverPerms.ChannelPermissions.TryGetValue(channel.Id, out perms) && perms.FilterWords;
|
||||
}
|
||||
|
||||
public override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "chnlfilterwords")
|
||||
.Alias(Module.Prefix + "cfw")
|
||||
.Description("Enables or disables automatic deleting of messages containing banned words on the channel." +
|
||||
"If no channel supplied, it will default to current one. Use ALL to apply to all existing channels at once." +
|
||||
$" | `{Prefix}cfw enable #general-chat`")
|
||||
.Parameter("bool")
|
||||
.Parameter("channel", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var chanStr = channel?.ToLowerInvariant().Trim();
|
||||
|
||||
if (chanStr != "all")
|
||||
{
|
||||
var chan = string.IsNullOrWhiteSpace(chanStr)
|
||||
? e.Channel
|
||||
: PermissionHelper.ValidateChannel(e.Server, chanStr);
|
||||
await PermissionsHandler.SetChannelWordPermission(chan, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Word filtering has been **{(state ? "enabled" : "disabled")}** for **{chan.Name}** channel.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
//all channels
|
||||
|
||||
foreach (var curChannel in e.Server.TextChannels)
|
||||
{
|
||||
await PermissionsHandler.SetChannelWordPermission(curChannel, state).ConfigureAwait(false);
|
||||
}
|
||||
await channel.SendMessageAsync($"Word filtering has been **{(state ? "enabled" : "disabled")}** for **ALL** channels.").ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync($"💢 Error: {ex.Message}").ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "addfilterword")
|
||||
.Alias(Module.Prefix + "afw")
|
||||
.Description("Adds a new word to the list of filtered words" +
|
||||
$" | `{Prefix}afw poop`")
|
||||
.Parameter("word", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var word = word;
|
||||
if (string.IsNullOrWhiteSpace(word))
|
||||
return;
|
||||
await PermissionsHandler.AddFilteredWord(e.Server, word.ToLowerInvariant().Trim()).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Successfully added new filtered word.").ConfigureAwait(false);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync($"💢 Error: {ex.Message}").ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "rmvfilterword")
|
||||
.Alias(Module.Prefix + "rfw")
|
||||
.Description("Removes the word from the list of filtered words" +
|
||||
$" | `{Prefix}rw poop`")
|
||||
.Parameter("word", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var word = word;
|
||||
if (string.IsNullOrWhiteSpace(word))
|
||||
return;
|
||||
await PermissionsHandler.RemoveFilteredWord(e.Server, word.ToLowerInvariant().Trim()).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Successfully removed filtered word.").ConfigureAwait(false);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync($"💢 Error: {ex.Message}").ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "lstfilterwords")
|
||||
.Alias(Module.Prefix + "lfw")
|
||||
.Description("Shows a list of filtered words" +
|
||||
$" | `{Prefix}lfw`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Classes.ServerPermissions serverPerms;
|
||||
if (!PermissionsHandler.PermissionsDict.TryGetValue(e.Server.Id, out serverPerms))
|
||||
return;
|
||||
await channel.SendMessageAsync($"There are `{serverPerms.Words.Count}` filtered words.\n" +
|
||||
string.Join("\n", serverPerms.Words)).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync($"💢 Error: {ex.Message}").ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "srvrfilterwords")
|
||||
.Alias(Module.Prefix + "sfw")
|
||||
.Description($"Enables or disables automatic deleting of messages containing forbidden words on the server. | `{Prefix}sfw disable`")
|
||||
.Parameter("bool")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
await PermissionsHandler.SetServerWordPermission(e.Server, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Word filtering has been **{(state ? "enabled" : "disabled")}** on this server.")
|
||||
.ConfigureAwait(false);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync($"💢 Error: {ex.Message}").ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,834 +0,0 @@
|
||||
using Discord.Commands;
|
||||
using Discord.Modules;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Classes.JSONModels;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Games.Commands;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using NadekoBot.Modules.Permissions.Commands;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions
|
||||
{
|
||||
public class PermissionModule : DiscordModule
|
||||
{
|
||||
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Permissions;
|
||||
|
||||
public PermissionModule()
|
||||
{
|
||||
commands.Add(new FilterInvitesCommand(this));
|
||||
commands.Add(new FilterWords(this));
|
||||
}
|
||||
|
||||
public override void Install(ModuleManager manager)
|
||||
{
|
||||
manager.CreateCommands("", cgb =>
|
||||
{
|
||||
|
||||
cgb.AddCheck(PermissionChecker.Instance);
|
||||
|
||||
commands.ForEach(cmd => cmd.Init(cgb));
|
||||
|
||||
cgb.CreateCommand(Prefix + "permrole")
|
||||
.Alias(Prefix + "pr")
|
||||
.Description($"Sets a role which can change permissions. Or supply no parameters to find out the current one. Default one is 'Nadeko'. | `{Prefix}pr role`")
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(role))
|
||||
{
|
||||
await channel.SendMessageAsync($"Current permissions role is `{PermissionsHandler.GetServerPermissionsRoleName(e.Server)}`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var arg = role;
|
||||
Discord.Role role = null;
|
||||
try
|
||||
{
|
||||
role = PermissionHelper.ValidateRole(e.Server, arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
await channel.SendMessageAsync($"Role `{arg}` probably doesn't exist. Create the role with that name first.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
await PermissionsHandler.SetPermissionsRole(e.Server, role.Name).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Role `{role.Name}` is now required in order to change permissions.").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "rolepermscopy")
|
||||
.Alias(Prefix + "rpc")
|
||||
.Description($"Copies BOT PERMISSIONS (not discord permissions) from one role to another. |`{Prefix}rpc Some Role ~ Some other role`")
|
||||
.Parameter("from_to", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = from_to?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(arg) || !arg.Contains('~'))
|
||||
return;
|
||||
var args = arg.Split('~').Select(a => a.Trim()).ToArray();
|
||||
if (args.Length > 2)
|
||||
{
|
||||
await channel.SendMessageAsync("💢Invalid number of '~'s in the argument.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
var fromRole = PermissionHelper.ValidateRole(e.Server, args[0]);
|
||||
var toRole = PermissionHelper.ValidateRole(e.Server, args[1]);
|
||||
|
||||
await PermissionsHandler.CopyRolePermissions(fromRole, toRole).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Copied permission settings from **{fromRole.Name}** to **{toRole.Name}**.").ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync($"💢{ex.Message}").ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
cgb.CreateCommand(Prefix + "chnlpermscopy")
|
||||
.Alias(Prefix + "cpc")
|
||||
.Description($"Copies BOT PERMISSIONS (not discord permissions) from one channel to another. |`{Prefix}cpc Some Channel ~ Some other channel`")
|
||||
.Parameter("from_to", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = from_to?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(arg) || !arg.Contains('~'))
|
||||
return;
|
||||
var args = arg.Split('~').Select(a => a.Trim()).ToArray();
|
||||
if (args.Length > 2)
|
||||
{
|
||||
await channel.SendMessageAsync("💢Invalid number of '~'s in the argument.");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
var fromChannel = PermissionHelper.ValidateChannel(e.Server, args[0]);
|
||||
var toChannel = PermissionHelper.ValidateChannel(e.Server, args[1]);
|
||||
|
||||
await PermissionsHandler.CopyChannelPermissions(fromChannel, toChannel).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Copied permission settings from **{fromChannel.Name}** to **{toChannel.Name}**.").ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync($"💢{ex.Message}");
|
||||
}
|
||||
});
|
||||
cgb.CreateCommand(Prefix + "usrpermscopy")
|
||||
.Alias(Prefix + "upc")
|
||||
.Description($"Copies BOT PERMISSIONS (not discord permissions) from one role to another. |`{Prefix}upc @SomeUser ~ @SomeOtherUser`")
|
||||
.Parameter("from_to", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = from_to?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(arg) || !arg.Contains('~'))
|
||||
return;
|
||||
var args = arg.Split('~').Select(a => a.Trim()).ToArray();
|
||||
if (args.Length > 2)
|
||||
{
|
||||
await channel.SendMessageAsync("💢Invalid number of '~'s in the argument.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
var fromUser = PermissionHelper.ValidateUser(e.Server, args[0]);
|
||||
var toUser = PermissionHelper.ValidateUser(e.Server, args[1]);
|
||||
|
||||
await PermissionsHandler.CopyUserPermissions(fromUser, toUser).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Copied permission settings from **{fromUser.ToString()}**to * *{toUser.ToString()}**.").ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync($"💢{ex.Message}");
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "verbose")
|
||||
.Alias(Prefix + "v")
|
||||
.Description($"Sets whether to show when a command/module is blocked. | `{Prefix}verbose true`")
|
||||
.Parameter("arg", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = arg;
|
||||
var val = PermissionHelper.ValidateBool(arg);
|
||||
await PermissionsHandler.SetVerbosity(e.Server, val).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Verbosity set to {val}.").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "srvrperms")
|
||||
.Alias(Prefix + "sp")
|
||||
.Description($"Shows banned permissions for this server. | `{Prefix}sp`")
|
||||
.Do(async e =>
|
||||
{
|
||||
var perms = PermissionsHandler.GetServerPermissions(e.Server);
|
||||
if (string.IsNullOrWhiteSpace(perms?.ToString()))
|
||||
await channel.SendMessageAsync("No permissions set for this server.").ConfigureAwait(false);
|
||||
await channel.SendMessageAsync(perms.ToString()).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "roleperms")
|
||||
.Alias(Prefix + "rp")
|
||||
.Description($"Shows banned permissions for a certain role. No argument means for everyone. | `{Prefix}rp AwesomeRole`")
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = role;
|
||||
var role = e.Server.EveryoneRole;
|
||||
if (!string.IsNullOrWhiteSpace(arg))
|
||||
try
|
||||
{
|
||||
role = PermissionHelper.ValidateRole(e.Server, arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("💢 Error: " + ex.Message).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var perms = PermissionsHandler.GetRolePermissionsById(e.Server, role.Id);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(perms?.ToString()))
|
||||
await channel.SendMessageAsync($"No permissions set for **{role.Name}** role.").ConfigureAwait(false);
|
||||
await channel.SendMessageAsync(perms.ToString()).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "chnlperms")
|
||||
.Alias(Prefix + "cp")
|
||||
.Description($"Shows banned permissions for a certain channel. No argument means for this channel. | `{Prefix}cp #dev`")
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var arg = channel;
|
||||
var channel = e.Channel;
|
||||
if (!string.IsNullOrWhiteSpace(arg))
|
||||
try
|
||||
{
|
||||
channel = PermissionHelper.ValidateChannel(e.Server, arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("💢 Error: " + ex.Message).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var perms = PermissionsHandler.GetChannelPermissionsById(e.Server, channel.Id);
|
||||
if (string.IsNullOrWhiteSpace(perms?.ToString()))
|
||||
await channel.SendMessageAsync($"No permissions set for **{channel.Name}** channel.").ConfigureAwait(false);
|
||||
await channel.SendMessageAsync(perms.ToString()).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "userperms")
|
||||
.Alias(Prefix + "up")
|
||||
.Description($"Shows banned permissions for a certain user. No argument means for yourself. | `{Prefix}up Kwoth`")
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var user = umsg.Author;
|
||||
if (!string.IsNullOrWhiteSpace(user))
|
||||
try
|
||||
{
|
||||
user = PermissionHelper.ValidateUser(e.Server, user);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("💢 Error: " + ex.Message).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var perms = PermissionsHandler.GetUserPermissionsById(e.Server, user.Id);
|
||||
if (string.IsNullOrWhiteSpace(perms?.ToString()))
|
||||
await channel.SendMessageAsync($"No permissions set for user **{user.Name}**.").ConfigureAwait(false);
|
||||
await channel.SendMessageAsync(perms.ToString()).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "srvrmdl")
|
||||
.Alias(Prefix + "sm")
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Description($"Sets a module's permission at the server level. | `{Prefix}sm \"module name\" enable`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
|
||||
await PermissionsHandler.SetServerModulePermission(e.Server, module, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Module **{module}** has been **{(state ? "enabled" : "disabled")}** on this server.").ConfigureAwait(false);
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "srvrcmd").Alias(Prefix + "sc")
|
||||
.Parameter("command", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Description($"Sets a command's permission at the server level. | `{Prefix}sc \"command name\" disable`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var command = PermissionHelper.ValidateCommand(command);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
|
||||
await PermissionsHandler.SetServerCommandPermission(e.Server, command, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Command **{command}** has been **{(state ? "enabled" : "disabled")}** on this server.").ConfigureAwait(false);
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "rolemdl").Alias(Prefix + "rm")
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Description($"Sets a module's permission at the role level. | `{Prefix}rm \"module name\" enable MyRole`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
|
||||
if (role?.ToLower() == "all")
|
||||
{
|
||||
foreach (var role in e.Server.Roles)
|
||||
{
|
||||
await PermissionsHandler.SetRoleModulePermission(role, module, state).ConfigureAwait(false);
|
||||
}
|
||||
await channel.SendMessageAsync($"Module **{module}** has been **{(state ? "enabled" : "disabled")}** for **ALL** roles.").ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var role = PermissionHelper.ValidateRole(e.Server, role);
|
||||
|
||||
await PermissionsHandler.SetRoleModulePermission(role, module, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Module **{module}** has been **{(state ? "enabled" : "disabled")}** for **{role.Name}** role.").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "rolecmd").Alias(Prefix + "rc")
|
||||
.Parameter("command", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Description($"Sets a command's permission at the role level. | `{Prefix}rc \"command name\" disable MyRole`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var command = PermissionHelper.ValidateCommand(command);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
|
||||
if (role?.ToLower() == "all")
|
||||
{
|
||||
foreach (var role in e.Server.Roles)
|
||||
{
|
||||
await PermissionsHandler.SetRoleCommandPermission(role, command, state).ConfigureAwait(false);
|
||||
}
|
||||
await channel.SendMessageAsync($"Command **{command}** has been **{(state ? "enabled" : "disabled")}** for **ALL** roles.").ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var role = PermissionHelper.ValidateRole(e.Server, role);
|
||||
|
||||
await PermissionsHandler.SetRoleCommandPermission(role, command, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Command **{command}** has been **{(state ? "enabled" : "disabled")}** for **{role.Name}** role.").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "chnlmdl").Alias(Prefix + "cm")
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Description($"Sets a module's permission at the channel level. | `{Prefix}cm \"module name\" enable SomeChannel`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var channelArg = channel;
|
||||
if (channelArg?.ToLower() == "all")
|
||||
{
|
||||
foreach (var channel in e.Server.TextChannels)
|
||||
{
|
||||
await PermissionsHandler.SetChannelModulePermission(channel, module, state).ConfigureAwait(false);
|
||||
}
|
||||
await channel.SendMessageAsync($"Module **{module}** has been **{(state ? "enabled" : "disabled")}** on **ALL** channels.").ConfigureAwait(false);
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(channelArg))
|
||||
{
|
||||
await PermissionsHandler.SetChannelModulePermission(e.Channel, module, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Module **{module}** has been **{(state ? "enabled" : "disabled")}** for **{e.Channel.Name}** channel.").ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var channel = PermissionHelper.ValidateChannel(e.Server, channelArg);
|
||||
|
||||
await PermissionsHandler.SetChannelModulePermission(channel, module, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Module **{module}** has been **{(state ? "enabled" : "disabled")}** for **{channel.Name}** channel.").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "chnlcmd").Alias(Prefix + "cc")
|
||||
.Parameter("command", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Description($"Sets a command's permission at the channel level. | `{Prefix}cc \"command name\" enable SomeChannel`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var command = PermissionHelper.ValidateCommand(command);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
|
||||
if (channel?.ToLower() == "all")
|
||||
{
|
||||
foreach (var channel in e.Server.TextChannels)
|
||||
{
|
||||
await PermissionsHandler.SetChannelCommandPermission(channel, command, state).ConfigureAwait(false);
|
||||
}
|
||||
await channel.SendMessageAsync($"Command **{command}** has been **{(state ? "enabled" : "disabled")}** on **ALL** channels.").ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var channel = PermissionHelper.ValidateChannel(e.Server, channel);
|
||||
|
||||
await PermissionsHandler.SetChannelCommandPermission(channel, command, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Command **{command}** has been **{(state ? "enabled" : "disabled")}** for **{channel.Name}** channel.").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "usrmdl").Alias(Prefix + "um")
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
.Description($"Sets a module's permission at the user level. | `{Prefix}um \"module name\" enable SomeUsername`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var user = PermissionHelper.ValidateUser(e.Server, user);
|
||||
|
||||
await PermissionsHandler.SetUserModulePermission(user, module, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Module **{module}** has been **{(state ? "enabled" : "disabled")}** for user **{user.Name}**.").ConfigureAwait(false);
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "usrcmd").Alias(Prefix + "uc")
|
||||
.Parameter("command", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
.Description($"Sets a command's permission at the user level. | `{Prefix}uc \"command name\" enable SomeUsername`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var command = PermissionHelper.ValidateCommand(command);
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var user = PermissionHelper.ValidateUser(e.Server, user);
|
||||
|
||||
await PermissionsHandler.SetUserCommandPermission(user, command, state).ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"Command **{command}** has been **{(state ? "enabled" : "disabled")}** for user **{user.Name}**.").ConfigureAwait(false);
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "allsrvrmdls").Alias(Prefix + "asm")
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Description($"Sets permissions for all modules at the server level. | `{Prefix}asm [enable/disable]`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
|
||||
foreach (var module in NadekoBot.Client.GetService<ModuleService>().Modules)
|
||||
{
|
||||
await PermissionsHandler.SetServerModulePermission(e.Server, module.Name, state).ConfigureAwait(false);
|
||||
}
|
||||
await channel.SendMessageAsync($"All modules have been **{(state ? "enabled" : "disabled")}** on this server.").ConfigureAwait(false);
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "allsrvrcmds").Alias(Prefix + "asc")
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Description($"Sets permissions for all commands from a certain module at the server level. | `{Prefix}asc \"module name\" [enable/disable]`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
|
||||
foreach (var command in NadekoBot.Client.GetService<CommandService>().AllCommands.Where(c => c.Category == module))
|
||||
{
|
||||
await PermissionsHandler.SetServerCommandPermission(e.Server, command.Text, state).ConfigureAwait(false);
|
||||
}
|
||||
await channel.SendMessageAsync($"All commands from the **{module}** module have been **{(state ? "enabled" : "disabled")}** on this server.").ConfigureAwait(false);
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "allchnlmdls").Alias(Prefix + "acm")
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Description($"Sets permissions for all modules at the channel level. | `{Prefix}acm [enable/disable] SomeChannel`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var chArg = channel;
|
||||
var channel = string.IsNullOrWhiteSpace(chArg) ? e.Channel : PermissionHelper.ValidateChannel(e.Server, chArg);
|
||||
foreach (var module in NadekoBot.Client.GetService<ModuleService>().Modules)
|
||||
{
|
||||
await PermissionsHandler.SetChannelModulePermission(channel, module.Name, state).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await channel.SendMessageAsync($"All modules have been **{(state ? "enabled" : "disabled")}** for **{channel.Name}** channel.").ConfigureAwait(false);
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "allchnlcmds").Alias(Prefix + "acc")
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Description($"Sets permissions for all commands from a certain module at the channel level. | `{Prefix}acc \"module name\" [enable/disable] SomeChannel`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
var channel = PermissionHelper.ValidateChannel(e.Server, channel);
|
||||
foreach (var command in NadekoBot.Client.GetService<CommandService>().AllCommands.Where(c => c.Category == module))
|
||||
{
|
||||
await PermissionsHandler.SetChannelCommandPermission(channel, command.Text, state).ConfigureAwait(false);
|
||||
}
|
||||
await channel.SendMessageAsync($"All commands from the **{module}** module have been **{(state ? "enabled" : "disabled")}** for **{channel.Name}** channel.").ConfigureAwait(false);
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "allrolemdls").Alias(Prefix + "arm")
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Description($"Sets permissions for all modules at the role level. | `{Prefix}arm [enable/disable] MyRole`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var role = PermissionHelper.ValidateRole(e.Server, role);
|
||||
foreach (var module in NadekoBot.Client.GetService<ModuleService>().Modules)
|
||||
{
|
||||
await PermissionsHandler.SetRoleModulePermission(role, module.Name, state).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await channel.SendMessageAsync($"All modules have been **{(state ? "enabled" : "disabled")}** for **{role.Name}** role.").ConfigureAwait(false);
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "allrolecmds").Alias(Prefix + "arc")
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Description($"Sets permissions for all commands from a certain module at the role level. | `{Prefix}arc \"module name\" [enable/disable] MyRole`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var state = PermissionHelper.ValidateBool(bool);
|
||||
var module = PermissionHelper.ValidateModule(module);
|
||||
if (role?.ToLower() == "all")
|
||||
{
|
||||
foreach (var role in e.Server.Roles)
|
||||
{
|
||||
foreach (var command in NadekoBot.Client.GetService<CommandService>().AllCommands.Where(c => c.Category == module))
|
||||
{
|
||||
await PermissionsHandler.SetRoleCommandPermission(role, command.Text, state).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
await channel.SendMessageAsync($"All commands from the **{module}** module have been **{(state ? "enabled" : "disabled")}** for **all roles** role.").ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var role = PermissionHelper.ValidateRole(e.Server, role);
|
||||
|
||||
foreach (var command in NadekoBot.Client.GetService<CommandService>().AllCommands.Where(c => c.Category == module))
|
||||
{
|
||||
await PermissionsHandler.SetRoleCommandPermission(role, command.Text, state).ConfigureAwait(false);
|
||||
}
|
||||
await channel.SendMessageAsync($"All commands from the **{module}** module have been **{(state ? "enabled" : "disabled")}** for **{role.Name}** role.").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "ubl")
|
||||
.Description($"Blacklists a mentioned user. | `{Prefix}ubl [user_mention]`")
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
if (!e.Message.MentionedUsers.Any()) return;
|
||||
var usr = e.Message.MentionedUsers.First();
|
||||
NadekoBot.Config.UserBlacklist.Add(usr.Id);
|
||||
await ConfigHandler.SaveConfig().ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"`Sucessfully blacklisted user {usr.Name}`").ConfigureAwait(false);
|
||||
}).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "uubl")
|
||||
.Description($"Unblacklists a mentioned user. | `{Prefix}uubl [user_mention]`")
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
if (!e.Message.MentionedUsers.Any()) return;
|
||||
var usr = e.Message.MentionedUsers.First();
|
||||
if (NadekoBot.Config.UserBlacklist.Contains(usr.Id))
|
||||
{
|
||||
NadekoBot.Config.UserBlacklist.Remove(usr.Id);
|
||||
await ConfigHandler.SaveConfig().ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"`Sucessfully unblacklisted user {usr.Name}`").ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await channel.SendMessageAsync($"`{usr.Name} was not in blacklist`").ConfigureAwait(false);
|
||||
}
|
||||
}).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "cbl")
|
||||
.Description($"Blacklists a mentioned channel (#general for example). | `{Prefix}cbl #some_channel`")
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
if (!e.Message.MentionedChannels.Any()) return;
|
||||
var ch = e.Message.MentionedChannels.First();
|
||||
NadekoBot.Config.UserBlacklist.Add(ch.Id);
|
||||
await ConfigHandler.SaveConfig().ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"`Sucessfully blacklisted channel {ch.Name}`").ConfigureAwait(false);
|
||||
}).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "cubl")
|
||||
.Description($"Unblacklists a mentioned channel (#general for example). | `{Prefix}cubl #some_channel`")
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
if (!e.Message.MentionedChannels.Any()) return;
|
||||
var ch = e.Message.MentionedChannels.First();
|
||||
NadekoBot.Config.UserBlacklist.Remove(ch.Id);
|
||||
await ConfigHandler.SaveConfig().ConfigureAwait(false);
|
||||
await channel.SendMessageAsync($"`Sucessfully blacklisted channel {ch.Name}`").ConfigureAwait(false);
|
||||
}).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "sbl")
|
||||
.Description($"Blacklists a server by a name or id (#general for example). **BOT OWNER ONLY** | `{Prefix}sbl [servername/serverid]`")
|
||||
.Parameter("server", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
var arg = server?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(arg))
|
||||
return;
|
||||
var server = NadekoBot.Client.Servers.FirstOrDefault(s => s.Id.ToString() == arg) ??
|
||||
NadekoBot.Client.FindServers(arg.Trim()).FirstOrDefault();
|
||||
if (server == null)
|
||||
{
|
||||
await channel.SendMessageAsync("Cannot find that server").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var serverId = server.Id;
|
||||
NadekoBot.Config.ServerBlacklist.Add(serverId);
|
||||
await ConfigHandler.SaveConfig().ConfigureAwait(false);
|
||||
//cleanup trivias and typeracing
|
||||
Modules.Games.Commands.Trivia.TriviaGame trivia;
|
||||
TriviaCommands.RunningTrivias.TryRemove(serverId, out trivia);
|
||||
TypingGame typeracer;
|
||||
SpeedTyping.RunningContests.TryRemove(serverId, out typeracer);
|
||||
|
||||
await channel.SendMessageAsync($"`Sucessfully blacklisted server {server.Name}`").ConfigureAwait(false);
|
||||
}).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "cmdcooldown")
|
||||
.Alias(Prefix+ "cmdcd")
|
||||
.Description($"Sets a cooldown per user for a command. Set 0 to clear. | `{Prefix}cmdcd \"some cmd\" 5`")
|
||||
.Parameter("command", ParameterType.Required)
|
||||
.Parameter("secs",ParameterType.Required)
|
||||
.AddCheck(SimpleCheckers.ManageMessages())
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var command = PermissionHelper.ValidateCommand(command);
|
||||
var secsStr = secs.Trim();
|
||||
int secs;
|
||||
if (!int.TryParse(secsStr, out secs) || secs < 0 || secs > 3600)
|
||||
throw new ArgumentOutOfRangeException("secs", "Invalid second parameter. (Must be a number between 0 and 3600)");
|
||||
|
||||
|
||||
await PermissionsHandler.SetCommandCooldown(e.Server, command, secs).ConfigureAwait(false);
|
||||
if(secs == 0)
|
||||
await channel.SendMessageAsync($"Command **{command}** has no coooldown now.").ConfigureAwait(false);
|
||||
else
|
||||
await channel.SendMessageAsync($"Command **{command}** now has a **{secs} {(secs==1 ? "second" : "seconds")}** cooldown.").ConfigureAwait(false);
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await channel.SendMessageAsync(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await channel.SendMessageAsync("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "allcmdcooldowns")
|
||||
.Alias(Prefix + "acmdcds")
|
||||
.Description("Shows a list of all commands and their respective cooldowns. | `{Prefix}acmdcds`")
|
||||
.Do(async e =>
|
||||
{
|
||||
ServerPermissions perms;
|
||||
PermissionsHandler.PermissionsDict.TryGetValue(e.Server.Id, out perms);
|
||||
if (perms == null)
|
||||
return;
|
||||
|
||||
if (!perms.CommandCooldowns.Any())
|
||||
{
|
||||
await channel.SendMessageAsync("`No command cooldowns set.`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
await channel.SendMessageAsync(SearchHelper.ShowInPrettyCode(perms.CommandCooldowns.Select(c=>c.Key+ ": "+c.Value+" secs"),s=>$"{s,-30}",2)).ConfigureAwait(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user