commit
938c8e220d
1
.gitignore
vendored
1
.gitignore
vendored
@ -22,6 +22,7 @@ obj/
|
||||
NadekoBot/bin/debug/*.*
|
||||
NadekoBot/bin/debug/data/permissions
|
||||
NadekoBot/bin/debug/data/incidents
|
||||
NadekoBot/bin/debug/data/musicdata
|
||||
NadekoBot/bin/NadekoRelease/*.*
|
||||
!NadekoBot/bin/Debug/data/currency_images/*
|
||||
Tests/bin
|
||||
|
47
DockerGuide.md
Normal file
47
DockerGuide.md
Normal file
@ -0,0 +1,47 @@
|
||||
## Docker guide with digitalocean
|
||||
|
||||
#####Prerequisites:
|
||||
- Digital ocean account (you can use my reflink to support the project and get 10$ after you register http://m.do.co/c/46b4d3d44795/ )
|
||||
- Putty (get it here http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html)
|
||||
- A bot account - (follow http://discord.kongslien.net/guide.html)
|
||||
- Common sense
|
||||
|
||||
Click on the create droplet button
|
||||
![img](http://i.imgur.com/g2ayOcC.png)
|
||||
|
||||
pick one click apps and select docker on 14.04
|
||||
|
||||
![img](http://imgur.com/065Xkme.png)
|
||||
|
||||
- pick any droplet size you want (5$ will work ok-ish on a few servers)
|
||||
- pick location closest to your discord server's location
|
||||
- Pick a hostname
|
||||
![img](http://imgur.com/ifPKB6p.png)
|
||||
|
||||
- click create
|
||||
|
||||
You will get an email from digitalocean with your creds now.
|
||||
|
||||
Open putty and type ip adress **you got in your email** with port 22
|
||||
|
||||
![img](http://imgur.com/Mh5ehsh.png)
|
||||
|
||||
console will open and you will be prompted for a username, type `root`
|
||||
type in the password you got in the email
|
||||
confirm the password you just typed in
|
||||
type in the new password
|
||||
confirm new password
|
||||
|
||||
when you are successfully logged in, type
|
||||
`docker run --name nadeko -v /nadeko:/config uirel/nadeko`
|
||||
|
||||
wait for it to download and at one point it is going to start throwing errors due to credentials.json being empty
|
||||
CTRL+C to exit that
|
||||
type `docker stop nadeko`
|
||||
type `nano /nadeko/credentials.json` and type in your credentials
|
||||
CTRL+X then CTRL+Y to save
|
||||
type `docker start nadeko`
|
||||
|
||||
Your bot is running, enjoy
|
||||
|
||||
*When you want to update the bot, just type `docker restart nadeko` as it always downloads latest prerelease*
|
@ -13,129 +13,74 @@ namespace NadekoBot.Classes
|
||||
|
||||
private string FilePath { get; } = "data/nadekobot.sqlite";
|
||||
|
||||
public SQLiteConnection Connection { get; set; }
|
||||
|
||||
static DbHandler() { }
|
||||
public DbHandler()
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
Connection = new SQLiteConnection(FilePath);
|
||||
Connection.CreateTable<Stats>();
|
||||
Connection.CreateTable<Command>();
|
||||
Connection.CreateTable<Announcement>();
|
||||
Connection.CreateTable<Request>();
|
||||
Connection.CreateTable<TypingArticle>();
|
||||
Connection.CreateTable<CurrencyState>();
|
||||
Connection.CreateTable<CurrencyTransaction>();
|
||||
Connection.CreateTable<Donator>();
|
||||
Connection.CreateTable<UserPokeTypes>();
|
||||
Connection.CreateTable<UserQuote>();
|
||||
Connection.CreateTable<Reminder>();
|
||||
Connection.CreateTable<SongInfo>();
|
||||
Connection.CreateTable<PlaylistSongInfo>();
|
||||
Connection.CreateTable<MusicPlaylist>();
|
||||
Connection.CreateTable<Incident>();
|
||||
Connection.Execute(Queries.TransactionTriggerQuery);
|
||||
try
|
||||
{
|
||||
conn.CreateTable<Stats>();
|
||||
conn.CreateTable<Command>();
|
||||
conn.CreateTable<Announcement>();
|
||||
conn.CreateTable<Request>();
|
||||
conn.CreateTable<TypingArticle>();
|
||||
conn.CreateTable<CurrencyState>();
|
||||
conn.CreateTable<CurrencyTransaction>();
|
||||
conn.CreateTable<Donator>();
|
||||
conn.CreateTable<UserPokeTypes>();
|
||||
conn.CreateTable<UserQuote>();
|
||||
conn.CreateTable<Reminder>();
|
||||
conn.CreateTable<SongInfo>();
|
||||
conn.CreateTable<PlaylistSongInfo>();
|
||||
conn.CreateTable<MusicPlaylist>();
|
||||
conn.CreateTable<Incident>();
|
||||
conn.Execute(Queries.TransactionTriggerQuery);
|
||||
try
|
||||
{
|
||||
conn.Execute(Queries.DeletePlaylistTriggerQuery);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
Connection.Execute(Queries.DeletePlaylistTriggerQuery);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
internal T FindOne<T>(Expression<Func<T, bool>> p) where T : IDataModel, new()
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
return conn.Table<T>().Where(p).FirstOrDefault();
|
||||
}
|
||||
return Connection.Table<T>().Where(p).FirstOrDefault();
|
||||
|
||||
}
|
||||
|
||||
internal IList<T> FindAll<T>(Expression<Func<T, bool>> p) where T : IDataModel, new()
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
return conn.Table<T>().Where(p).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
internal void DeleteAll<T>() where T : IDataModel
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
conn.DeleteAll<T>();
|
||||
}
|
||||
return Connection.Table<T>().Where(p).ToList();
|
||||
|
||||
}
|
||||
|
||||
internal void DeleteWhere<T>(Expression<Func<T, bool>> p) where T : IDataModel, new()
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
var id = conn.Table<T>().Where(p).FirstOrDefault()?.Id;
|
||||
if (id.HasValue)
|
||||
conn.Delete<T>(id);
|
||||
}
|
||||
}
|
||||
|
||||
internal void InsertData<T>(T o) where T : IDataModel
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
conn.Insert(o, typeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
internal void InsertMany<T>(T objects) where T : IEnumerable<IDataModel>
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
conn.InsertAll(objects);
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateData<T>(T o) where T : IDataModel
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
conn.Update(o, typeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateAll<T>(IEnumerable<T> objs) where T : IDataModel
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
conn.UpdateAll(objs);
|
||||
}
|
||||
var id = Connection.Table<T>().Where(p).FirstOrDefault()?.Id;
|
||||
if (id.HasValue)
|
||||
Connection.Delete<T>(id);
|
||||
}
|
||||
|
||||
internal HashSet<T> GetAllRows<T>() where T : IDataModel, new()
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
return new HashSet<T>(conn.Table<T>());
|
||||
}
|
||||
return new HashSet<T>(Connection.Table<T>());
|
||||
}
|
||||
|
||||
internal CurrencyState GetStateByUserId(long id)
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
return conn.Table<CurrencyState>().Where(x => x.UserId == id).FirstOrDefault();
|
||||
}
|
||||
return Connection.Table<CurrencyState>().Where(x => x.UserId == id).FirstOrDefault();
|
||||
}
|
||||
|
||||
internal T Delete<T>(int id) where T : IDataModel, new()
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
var found = conn.Find<T>(id);
|
||||
if (found != null)
|
||||
conn.Delete<T>(found.Id);
|
||||
return found;
|
||||
}
|
||||
var found = Connection.Find<T>(id);
|
||||
if (found != null)
|
||||
Connection.Delete<T>(found.Id);
|
||||
return found;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -143,14 +88,11 @@ namespace NadekoBot.Classes
|
||||
/// </summary>
|
||||
internal void Save<T>(T o) where T : IDataModel, new()
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
var found = conn.Find<T>(o.Id);
|
||||
if (found == null)
|
||||
conn.Insert(o, typeof(T));
|
||||
else
|
||||
conn.Update(o, typeof(T));
|
||||
}
|
||||
var found = Connection.Find<T>(o.Id);
|
||||
if (found == null)
|
||||
Connection.Insert(o, typeof(T));
|
||||
else
|
||||
Connection.Update(o, typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -158,20 +100,14 @@ namespace NadekoBot.Classes
|
||||
/// </summary>
|
||||
internal void SaveAll<T>(IEnumerable<T> ocol) where T : IDataModel, new()
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
foreach (var o in ocol)
|
||||
conn.InsertOrReplace(o);
|
||||
}
|
||||
foreach (var o in ocol)
|
||||
Connection.InsertOrReplace(o);
|
||||
}
|
||||
|
||||
internal T GetRandom<T>(Expression<Func<T, bool>> p) where T : IDataModel, new()
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
var r = new Random();
|
||||
return conn.Table<T>().Where(p).ToList().OrderBy(x => r.Next()).FirstOrDefault();
|
||||
}
|
||||
var r = new Random();
|
||||
return Connection.Table<T>().Where(p).ToList().OrderBy(x => r.Next()).FirstOrDefault();
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
@ -180,24 +116,19 @@ namespace NadekoBot.Classes
|
||||
/// <returns></returns>
|
||||
internal List<PlaylistData> GetPlaylistData(int num)
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
return conn.Query<PlaylistData>(
|
||||
return Connection.Query<PlaylistData>(
|
||||
@"SELECT mp.Name as 'Name',mp.Id as 'Id', mp.CreatorName as 'Creator', Count(*) as 'SongCnt' FROM MusicPlaylist as mp
|
||||
INNER JOIN PlaylistSongInfo as psi
|
||||
ON mp.Id = psi.PlaylistId
|
||||
Group BY mp.Name
|
||||
Order By mp.DateAdded desc
|
||||
Limit 20 OFFSET ?", num * 20);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal IEnumerable<CurrencyState> GetTopRichest(int n = 10)
|
||||
{
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
return conn.Table<CurrencyState>().OrderByDescending(cs => cs.Value).Take(n).ToList();
|
||||
}
|
||||
return Connection.Table<CurrencyState>().OrderByDescending(cs => cs.Value).Take(n).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace NadekoBot.Classes
|
||||
return;
|
||||
await Task.Run(() =>
|
||||
{
|
||||
DbHandler.Instance.InsertData(new DataModels.CurrencyTransaction
|
||||
DbHandler.Instance.Connection.Insert(new DataModels.CurrencyTransaction
|
||||
{
|
||||
Reason = reason,
|
||||
UserId = (long)u.Id,
|
||||
@ -36,7 +36,7 @@ namespace NadekoBot.Classes
|
||||
if (state.Value < amount)
|
||||
return false;
|
||||
|
||||
DbHandler.Instance.InsertData(new DataModels.CurrencyTransaction
|
||||
DbHandler.Instance.Connection.Insert(new DataModels.CurrencyTransaction
|
||||
{
|
||||
Reason = reason,
|
||||
UserId = (long)u.Id,
|
||||
|
@ -19,7 +19,7 @@ namespace NadekoBot.Classes
|
||||
Read = false
|
||||
};
|
||||
|
||||
DbHandler.Instance.InsertData<Incident>(incident);
|
||||
DbHandler.Instance.Connection.Insert(incident, typeof(Incident));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,20 +46,7 @@ namespace NadekoBot
|
||||
|
||||
commandService.CommandExecuted += StatsCollector_RanCommand;
|
||||
commandService.CommandFinished += CommandService_CommandFinished;
|
||||
commandService.CommandErrored += (s, e) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (e.ErrorType == CommandErrorType.Exception)
|
||||
File.AppendAllText("errors.txt", $@"Command: {e.Command}
|
||||
{e.Exception}
|
||||
-------------------------------------
|
||||
");
|
||||
}
|
||||
catch {
|
||||
Console.WriteLine("Command errored errorring");
|
||||
}
|
||||
};
|
||||
commandService.CommandErrored += CommandService_CommandFinished;
|
||||
|
||||
Task.Run(StartCollecting);
|
||||
|
||||
@ -208,7 +195,7 @@ namespace NadekoBot
|
||||
.ConfigureAwait(false);
|
||||
var connectedServers = NadekoBot.Client.Servers.Count();
|
||||
|
||||
Classes.DbHandler.Instance.InsertData(new DataModels.Stats
|
||||
Classes.DbHandler.Instance.Connection.Insert(new DataModels.Stats
|
||||
{
|
||||
OnlineUsers = onlineUsers,
|
||||
RealOnlineUsers = realOnlineUsers,
|
||||
@ -236,10 +223,31 @@ namespace NadekoBot
|
||||
|
||||
private void CommandService_CommandFinished(object sender, CommandEventArgs e)
|
||||
{
|
||||
|
||||
DateTime dt;
|
||||
if (!commandTracker.TryGetValue(e.Message.Id, out dt))
|
||||
return;
|
||||
Console.WriteLine($">>COMMAND ENDED after *{(DateTime.UtcNow - dt).TotalSeconds}s*\nCmd: {e.Command.Text}\nMsg: {e.Message.Text}\nUsr: {e.User.Name} [{e.User.Id}]\nSrvr: {e.Server?.Name ?? "PRIVATE"} [{e.Server?.Id}]\n-----");
|
||||
try
|
||||
{
|
||||
if (e is CommandErrorEventArgs)
|
||||
{
|
||||
var er = e as CommandErrorEventArgs;
|
||||
if (er.ErrorType == CommandErrorType.Exception)
|
||||
{
|
||||
File.AppendAllText("errors.txt", $@"Command: {er.Command}
|
||||
{er.Exception}
|
||||
-------------------------------------
|
||||
");
|
||||
Console.WriteLine($">>COMMAND ERRORED after *{(DateTime.UtcNow - dt).TotalSeconds}s*\nCmd: {e.Command.Text}\nMsg: {e.Message.Text}\nUsr: {e.User.Name} [{e.User.Id}]\nSrvr: {e.Server?.Name ?? "PRIVATE"} [{e.Server?.Id}]\n-----");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($">>COMMAND ENDED after *{(DateTime.UtcNow - dt).TotalSeconds}s*\nCmd: {e.Command.Text}\nMsg: {e.Message.Text}\nUsr: {e.User.Name} [{e.User.Id}]\nSrvr: {e.Server?.Name ?? "PRIVATE"} [{e.Server?.Id}]\n-----");
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private async void StatsCollector_RanCommand(object sender, CommandEventArgs e)
|
||||
@ -252,7 +260,7 @@ namespace NadekoBot
|
||||
try
|
||||
{
|
||||
commandsRan++;
|
||||
Classes.DbHandler.Instance.InsertData(new DataModels.Command
|
||||
Classes.DbHandler.Instance.Connection.Insert(new DataModels.Command
|
||||
{
|
||||
ServerId = (long)(e.Server?.Id ?? 0),
|
||||
ServerName = e.Server?.Name ?? "--Direct Message--",
|
||||
|
@ -25,16 +25,13 @@ namespace NadekoBot.Classes
|
||||
{
|
||||
private static DateTime lastRefreshed = DateTime.MinValue;
|
||||
private static string token { get; set; } = "";
|
||||
private static readonly HttpClient httpClient = new HttpClient();
|
||||
|
||||
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));
|
||||
//if its a post or there are no headers, use static httpclient
|
||||
// if there are headers and it's get, it's not threadsafe
|
||||
var cl = headers == null || method == RequestHttpMethod.Post ? httpClient : new HttpClient();
|
||||
var cl = new HttpClient();
|
||||
cl.DefaultRequestHeaders.Clear();
|
||||
switch (method)
|
||||
{
|
||||
@ -178,7 +175,7 @@ namespace NadekoBot.Classes
|
||||
return null;
|
||||
}
|
||||
|
||||
public static async Task<string> GetRelatedVideoId(string id)
|
||||
public static async Task<IEnumerable<string>> GetRelatedVideoIds(string id, int count = 1)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(id))
|
||||
throw new ArgumentNullException(nameof(id));
|
||||
@ -189,20 +186,14 @@ namespace NadekoBot.Classes
|
||||
}
|
||||
var response = await GetResponseStringAsync(
|
||||
$"https://www.googleapis.com/youtube/v3/search?" +
|
||||
$"part=snippet&maxResults=1&type=video" +
|
||||
$"part=snippet&maxResults={count}&type=video" +
|
||||
$"&relatedToVideoId={id}" +
|
||||
$"&key={NadekoBot.Creds.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;
|
||||
return data.items.Select(v => "http://www.youtube.com/watch?v=" + v.id.videoId);
|
||||
}
|
||||
|
||||
public static async Task<string> GetPlaylistIdByKeyword(string query)
|
||||
|
@ -64,7 +64,7 @@ namespace NadekoBot.Modules.Administration
|
||||
commands.ForEach(cmd => cmd.Init(cgb));
|
||||
|
||||
cgb.CreateCommand(Prefix + "delmsgoncmd")
|
||||
.Description("Toggles the automatic deletion of user's successful command message to prevent chat flood. Server Manager Only.")
|
||||
.Description($"Toggles the automatic deletion of user's successful command message to prevent chat flood. Server Manager Only. | `{Prefix}delmsgoncmd`")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -79,7 +79,7 @@ namespace NadekoBot.Modules.Administration
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "restart")
|
||||
.Description("Restarts the bot. Might not work. **Bot Owner Only**")
|
||||
.Description($"Restarts the bot. Might not work. **Bot Owner Only** | `{Prefix}restart`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -406,7 +406,7 @@ namespace NadekoBot.Modules.Administration
|
||||
{
|
||||
if (!e.User.ServerPermissions.MuteMembers)
|
||||
{
|
||||
await e.Channel.SendMessage("You do not have permission to do that.").ConfigureAwait(false);
|
||||
await e.Channel.SendMessage("I most likely don't have the permission necessary for that.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
if (!e.Message.MentionedUsers.Any())
|
||||
@ -421,7 +421,7 @@ namespace NadekoBot.Modules.Administration
|
||||
}
|
||||
catch
|
||||
{
|
||||
await e.Channel.SendMessage("I do not have permission to do that most likely.").ConfigureAwait(false);
|
||||
await e.Channel.SendMessage("I most likely don't have the permission necessary for that.").ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
@ -447,7 +447,7 @@ namespace NadekoBot.Modules.Administration
|
||||
}
|
||||
catch
|
||||
{
|
||||
await e.Channel.SendMessage("I do not have permission to do that most likely.").ConfigureAwait(false);
|
||||
await e.Channel.SendMessage("I most likely don't have the permission necessary for that.").ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
@ -474,7 +474,7 @@ namespace NadekoBot.Modules.Administration
|
||||
}
|
||||
catch
|
||||
{
|
||||
await e.Channel.SendMessage("I do not have permission to do that most likely.").ConfigureAwait(false);
|
||||
await e.Channel.SendMessage("I most likely don't have the permission necessary for that.").ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
@ -501,7 +501,7 @@ namespace NadekoBot.Modules.Administration
|
||||
}
|
||||
catch
|
||||
{
|
||||
await e.Channel.SendMessage("I do not have permission to do that most likely.").ConfigureAwait(false);
|
||||
await e.Channel.SendMessage("I most likely don't have the permission necessary for that.").ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
@ -617,7 +617,7 @@ namespace NadekoBot.Modules.Administration
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "heap")
|
||||
.Description("Shows allocated memory - **Bot Owner Only!**")
|
||||
.Description($"Shows allocated memory - **Bot Owner Only!** | `{Prefix}heap`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -628,19 +628,19 @@ namespace NadekoBot.Modules.Administration
|
||||
cgb.CreateCommand(Prefix + "prune")
|
||||
.Alias(Prefix + "clr")
|
||||
.Description(
|
||||
"`.prune` removes all nadeko's messages in the last 100 messages.`.prune X` removes last X messages from the channel (up to 100)`.prune @Someone` removes all Someone's messages in the last 100 messages.`.prune @Someone X` removes last X 'Someone's' messages in the channel. | `.prune` or `.prune 5` or `.prune @Someone` or `.prune @Someone X`")
|
||||
"`.prune` removes all nadeko's messages in the last 100 messages.`.prune X` removes last X messages from the channel (up to 100)`.prune @Someone` removes all Someone's messages in the last 100 messages.`.prune @Someone X` removes last X 'Someone's' messages in the channel. " +
|
||||
$"| `{Prefix}prune` or `{Prefix}prune 5` or `{Prefix}prune @Someone` or `{Prefix}prune @Someone X`")
|
||||
.Parameter("user_or_num", ParameterType.Optional)
|
||||
.Parameter("num", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
Message[] msgs;
|
||||
if (string.IsNullOrWhiteSpace(e.GetArg("user_or_num"))) // if nothing is set, clear nadeko's messages, no permissions required
|
||||
{
|
||||
msgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false));//.Where(m => m.User.Id == e.Server.CurrentUser.Id).ToArray();
|
||||
msgs = msgs.Where(m => m.User.Id == e.Server.CurrentUser.Id).ToArray();
|
||||
if (!msgs.Any())
|
||||
var msgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false)).Where(m => m.User?.Id == e.Server.CurrentUser.Id)?.ToArray();
|
||||
if (msgs == null || !msgs.Any())
|
||||
return;
|
||||
await e.Channel.DeleteMessages(msgs).ConfigureAwait(false);
|
||||
var toDelete = msgs as Message[] ?? msgs.ToArray();
|
||||
await e.Channel.DeleteMessages(toDelete).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
if (!e.User.GetPermissions(e.Channel).ManageMessages)
|
||||
@ -667,14 +667,14 @@ namespace NadekoBot.Modules.Administration
|
||||
val = 100;
|
||||
if (!int.TryParse(e.GetArg("num"), out val))
|
||||
val = 100;
|
||||
msgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false)).Where(m => m.User.Id == usr.Id).Take(val).ToArray();
|
||||
if (!msgs.Any())
|
||||
var mesgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false)).Where(m => m.User?.Id == usr.Id).Take(val);
|
||||
if (mesgs == null || !mesgs.Any())
|
||||
return;
|
||||
await e.Channel.DeleteMessages(msgs).ConfigureAwait(false);
|
||||
await e.Channel.DeleteMessages(mesgs as Message[] ?? mesgs.ToArray()).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "die")
|
||||
.Description("Shuts the bot down and notifies users about the restart. **Bot Owner Only!**")
|
||||
.Description($"Shuts the bot down and notifies users about the restart. **Bot Owner Only!** | `{Prefix}die`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -807,7 +807,7 @@ namespace NadekoBot.Modules.Administration
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "unstuck")
|
||||
.Description("Clears the message queue. **Bot Owner Only!**")
|
||||
.Description($"Clears the message queue. **Bot Owner Only!** | `{Prefix}unstuck`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(e =>
|
||||
{
|
||||
@ -829,7 +829,7 @@ namespace NadekoBot.Modules.Administration
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "donadd")
|
||||
.Description($"Add a donator to the database. | `.donadd Donate Amount`")
|
||||
.Description($"Add a donator to the database. | `{Prefix}donadd Donate Amount`")
|
||||
.Parameter("donator")
|
||||
.Parameter("amount")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
@ -842,7 +842,7 @@ namespace NadekoBot.Modules.Administration
|
||||
if (donator == null) return;
|
||||
try
|
||||
{
|
||||
DbHandler.Instance.InsertData(new Donator
|
||||
DbHandler.Instance.Connection.Insert(new Donator
|
||||
{
|
||||
Amount = amount,
|
||||
UserName = donator.Name,
|
||||
|
@ -34,7 +34,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "autoassignrole")
|
||||
.Alias(Module.Prefix + "aar")
|
||||
.Description($"Automaticaly assigns a specified role to every user who joins the server. Type `.aar` to disable, `.aar Role Name` to enable")
|
||||
.Description($"Automaticaly assigns a specified role to every user who joins the server. |`{Prefix}aar` to disable, `{Prefix}aar Role Name` to enable")
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.AddCheck(new SimpleCheckers.ManageRoles())
|
||||
.Do(async e =>
|
||||
|
@ -64,8 +64,8 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "scsc")
|
||||
.Description("Starts an instance of cross server channel. You will get a token as a DM" +
|
||||
"that other people will use to tune in to the same instance")
|
||||
.Description("Starts an instance of cross server channel. You will get a token as a DM " +
|
||||
$"that other people will use to tune in to the same instance. | `{Prefix}scsc`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -79,7 +79,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "jcsc")
|
||||
.Description("Joins current channel to an instance of cross server channel using the token.")
|
||||
.Description($"Joins current channel to an instance of cross server channel using the token. | `{Prefix}jcsc`")
|
||||
.Parameter("token")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
@ -95,7 +95,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "lcsc")
|
||||
.Description("Leaves Cross server channel instance from this channel")
|
||||
.Description($"Leaves Cross server channel instance from this channel. | `{Prefix}lcsc`")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Prefix + "addcustreact")
|
||||
.Alias(Prefix + "acr")
|
||||
.Description($"Add a custom reaction. Guide here: <https://github.com/Kwoth/NadekoBot/wiki/Custom-Reactions> **Bot Owner Only!** | {Prefix}acr \"hello\" I love saying hello to %user%")
|
||||
.Description($"Add a custom reaction. Guide here: <https://github.com/Kwoth/NadekoBot/wiki/Custom-Reactions> **Bot Owner Only!** | `{Prefix}acr \"hello\" I love saying hello to %user%`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Parameter("name", ParameterType.Required)
|
||||
.Parameter("message", ParameterType.Unparsed)
|
||||
@ -47,7 +47,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Prefix + "listcustreact")
|
||||
.Alias(Prefix + "lcr")
|
||||
.Description($"Lists custom reactions (paginated with 30 commands per page). Use 'all' instead of page number to get all custom reactions DM-ed to you. |{Prefix}lcr 1")
|
||||
.Description($"Lists custom reactions (paginated with 30 commands per page). Use 'all' instead of page number to get all custom reactions DM-ed to you. |`{Prefix}lcr 1`")
|
||||
.Parameter("num", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -80,7 +80,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Prefix + "showcustreact")
|
||||
.Alias(Prefix + "scr")
|
||||
.Description($"Shows all possible responses from a single custom reaction. |{Prefix}scr %mention% bb")
|
||||
.Description($"Shows all possible responses from a single custom reaction. |`{Prefix}scr %mention% bb`")
|
||||
.Parameter("name", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -106,7 +106,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Prefix + "editcustreact")
|
||||
.Alias(Prefix + "ecr")
|
||||
.Description("Edits a custom reaction, arguments are custom reactions name, index to change, and a (multiword) message **Bot Owner Only** | `.ecr \"%mention% disguise\" 2 Test 123`")
|
||||
.Description($"Edits a custom reaction, arguments are custom reactions name, index to change, and a (multiword) message **Bot Owner Only** | `{Prefix}ecr \"%mention% disguise\" 2 Test 123`")
|
||||
.Parameter("name", ParameterType.Required)
|
||||
.Parameter("index", ParameterType.Required)
|
||||
.Parameter("message", ParameterType.Unparsed)
|
||||
@ -146,7 +146,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Prefix + "delcustreact")
|
||||
.Alias(Prefix + "dcr")
|
||||
.Description("Deletes a custom reaction with given name (and index)")
|
||||
.Description($"Deletes a custom reaction with given name (and index). | `{Prefix}dcr index`")
|
||||
.Parameter("name", ParameterType.Required)
|
||||
.Parameter("index", ParameterType.Optional)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
|
@ -14,26 +14,26 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "listincidents")
|
||||
.Alias(Prefix + "lin")
|
||||
.Description("List all UNREAD incidents and flags them as read.")
|
||||
.Description($"List all UNREAD incidents and flags them as read. | `{Prefix}lin`")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
{
|
||||
var sid = (long)e.Server.Id;
|
||||
var incs = DbHandler.Instance.FindAll<Incident>(i => i.ServerId == sid && i.Read == false);
|
||||
DbHandler.Instance.UpdateAll<Incident>(incs.Select(i => { i.Read = true; return i; }));
|
||||
DbHandler.Instance.Connection.UpdateAll(incs.Select(i => { i.Read = true; return i; }));
|
||||
|
||||
await e.User.SendMessage(string.Join("\n----------------------", incs.Select(i => i.Text)));
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "listallincidents")
|
||||
.Alias(Prefix + "lain")
|
||||
.Description("Sends you a file containing all incidents and flags them as read.")
|
||||
.Description($"Sends you a file containing all incidents and flags them as read. | `{Prefix}lain`")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
{
|
||||
var sid = (long)e.Server.Id;
|
||||
var incs = DbHandler.Instance.FindAll<Incident>(i => i.ServerId == sid);
|
||||
DbHandler.Instance.UpdateAll<Incident>(incs.Select(i => { i.Read = true; return i; }));
|
||||
DbHandler.Instance.Connection.UpdateAll(incs.Select(i => { i.Read = true; return i; }));
|
||||
var data = string.Join("\n----------------------\n", incs.Select(i => i.Text));
|
||||
MemoryStream ms = new MemoryStream();
|
||||
var sw = new StreamWriter(ms);
|
||||
|
@ -4,7 +4,10 @@ using NadekoBot.Classes;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
@ -12,6 +15,8 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
private string prettyCurrentTime => $"【{DateTime.Now:HH:mm:ss}】";
|
||||
|
||||
private ConcurrentBag<KeyValuePair<Channel, string>> voicePresenceUpdates = new ConcurrentBag<KeyValuePair<Channel, string>>();
|
||||
|
||||
public LogCommand(DiscordModule module) : base(module)
|
||||
{
|
||||
NadekoBot.Client.MessageReceived += MsgRecivd;
|
||||
@ -45,6 +50,36 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
}
|
||||
catch { }
|
||||
};
|
||||
|
||||
// start the userpresence queue
|
||||
|
||||
NadekoBot.OnReady += () => Task.Run(async () =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var toSend = new Dictionary<Channel, string>();
|
||||
//take everything from the queue and merge the messages which are going to the same channel
|
||||
KeyValuePair<Channel, string> item;
|
||||
while (voicePresenceUpdates.TryTake(out item))
|
||||
{
|
||||
if (toSend.ContainsKey(item.Key))
|
||||
{
|
||||
toSend[item.Key] = toSend[item.Key] + Environment.NewLine + item.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
toSend.Add(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
//send merged messages to each channel
|
||||
foreach (var k in toSend)
|
||||
{
|
||||
try { await k.Key.SendMessage(Environment.NewLine + k.Value).ConfigureAwait(false); } catch { }
|
||||
}
|
||||
|
||||
await Task.Delay(5000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async void ChannelUpdated(object sender, ChannelUpdatedEventArgs e)
|
||||
@ -177,13 +212,13 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
if (!string.IsNullOrWhiteSpace(e.Message.Text))
|
||||
{
|
||||
await ch.SendMessage(
|
||||
$@"🕔`{prettyCurrentTime}` **New Message** `#{e.Channel.Name}`
|
||||
$@"🕔`{prettyCurrentTime}` **New Message** `#{e.Channel.Name}`
|
||||
👤`{e.User?.ToString() ?? ("NULL")}` {e.Message.Text.Unmention()}").ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await ch.SendMessage(
|
||||
$@"🕔`{prettyCurrentTime}` **File Uploaded** `#{e.Channel.Name}`
|
||||
$@"🕔`{prettyCurrentTime}` **File Uploaded** `#{e.Channel.Name}`
|
||||
👤`{e.User?.ToString() ?? ("NULL")}` {e.Message.Attachments.FirstOrDefault()?.ProxyUrl}").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@ -206,13 +241,13 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
if (!string.IsNullOrWhiteSpace(e.Message.Text))
|
||||
{
|
||||
await ch.SendMessage(
|
||||
$@"🕔`{prettyCurrentTime}` **Message** 🚮 `#{e.Channel.Name}`
|
||||
$@"🕔`{prettyCurrentTime}` **Message** 🚮 `#{e.Channel.Name}`
|
||||
👤`{e.User?.ToString() ?? ("NULL")}` {e.Message.Text.Unmention()}").ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await ch.SendMessage(
|
||||
$@"🕔`{prettyCurrentTime}` **File Deleted** `#{e.Channel.Name}`
|
||||
$@"🕔`{prettyCurrentTime}` **File Deleted** `#{e.Channel.Name}`
|
||||
👤`{e.User?.ToString() ?? ("NULL")}` {e.Message.Attachments.FirstOrDefault()?.ProxyUrl}").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@ -232,7 +267,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
await ch.SendMessage(
|
||||
$@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
$@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
👤`{e.User?.ToString() ?? ("NULL")}`
|
||||
`Old:` {e.Before.Text.Unmention()}
|
||||
`New:` {e.After.Text.Unmention()}").ConfigureAwait(false);
|
||||
@ -252,7 +287,7 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
{
|
||||
if (e.Before.Status != e.After.Status)
|
||||
{
|
||||
await ch.SendMessage($"`{prettyCurrentTime}`**{e.Before.Name}** is now **{e.After.Status}**.").ConfigureAwait(false);
|
||||
voicePresenceUpdates.Add(new KeyValuePair<Channel, string>(ch, $"`{prettyCurrentTime}`**{e.Before.Name}** is now **{e.After.Status}**."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -340,7 +375,7 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
{
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "spmom")
|
||||
.Description("Toggles whether mentions of other offline users on your server will send a pm to them.")
|
||||
.Description($"Toggles whether mentions of other offline users on your server will send a pm to them. | `{Prefix}spmom`")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -356,7 +391,7 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "logserver")
|
||||
.Description("Toggles logging in this channel. Logs every message sent/deleted/edited on the server. **Bot Owner Only!**")
|
||||
.Description($"Toggles logging in this channel. Logs every message sent/deleted/edited on the server. **Bot Owner Only!** | `{Prefix}logserver`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
@ -372,13 +407,13 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
|
||||
SpecificConfigurations.Default.Of (e.Server.Id).LogServerChannel = null;
|
||||
SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel = null;
|
||||
await e.Channel.SendMessage($"❗**NO LONGER LOGGING IN {ch.Mention} CHANNEL**❗").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
|
||||
cgb.CreateCommand(Prefix + "logignore")
|
||||
.Description($"Toggles whether the {Prefix}logserver command ignores this channel. Useful if you have hidden admin channel and public log channel.")
|
||||
.Description($"Toggles whether the {Prefix}logserver command ignores this channel. Useful if you have hidden admin channel and public log channel. | `{Prefix}logignore`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
@ -396,7 +431,7 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "userpresence")
|
||||
.Description("Starts logging to this channel when someone from the server goes online/offline/idle.")
|
||||
.Description($"Starts logging to this channel when someone from the server goes online/offline/idle. | `{Prefix}userpresence`")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -412,7 +447,7 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "voicepresence")
|
||||
.Description("Toggles logging to this channel whenever someone joins or leaves a voice channel you are in right now.")
|
||||
.Description("Toggles logging to this channel whenever someone joins or leaves a voice channel you are in right now. | `{Prefix}voicerpresence`")
|
||||
.Parameter("all", ParameterType.Optional)
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
|
@ -57,7 +57,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "repeatinvoke")
|
||||
.Alias(Module.Prefix + "repinv")
|
||||
.Description("Immediately shows the repeat message and restarts the timer.")
|
||||
.Description($"Immediately shows the repeat message and restarts the timer. | `{Prefix}repinv`")
|
||||
.AddCheck(SimpleCheckers.ManageMessages())
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -73,7 +73,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "repeat")
|
||||
.Description("Repeat a message every X minutes. If no parameters are specified, " +
|
||||
"repeat is disabled. Requires manage messages. |`.repeat 5 Hello there`")
|
||||
$"repeat is disabled. Requires manage messages. |`{Prefix}repeat 5 Hello there`")
|
||||
.Parameter("minutes", ParameterType.Optional)
|
||||
.Parameter("msg", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.ManageMessages())
|
||||
|
@ -96,14 +96,14 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "rotateplaying")
|
||||
.Alias(Module.Prefix + "ropl")
|
||||
.Description("Toggles rotation of playing status of the dynamic strings you specified earlier.")
|
||||
.Description($"Toggles rotation of playing status of the dynamic strings you specified earlier. | `{Prefix}ropl`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(DoFunc());
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "addplaying")
|
||||
.Alias(Module.Prefix + "adpl")
|
||||
.Description("Adds a specified string to the list of playing strings to rotate. " +
|
||||
"Supported placeholders: " + string.Join(", ", PlayingPlaceholders.Keys))
|
||||
"Supported placeholders: " + string.Join(", ", PlayingPlaceholders.Keys)+ $" | `{Prefix}adpl`")
|
||||
.Parameter("text", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
@ -126,7 +126,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "listplaying")
|
||||
.Alias(Module.Prefix + "lipl")
|
||||
.Description("Lists all playing statuses with their corresponding number.")
|
||||
.Description($"Lists all playing statuses with their corresponding number. | `{Prefix}lipl`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -143,7 +143,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "removeplaying")
|
||||
.Alias(Module.Prefix + "repl", Module.Prefix + "rmpl")
|
||||
.Description("Removes a playing string on a given number.")
|
||||
.Description($"Removes a playing string on a given number. | `{Prefix}rmpl`")
|
||||
.Parameter("number", ParameterType.Required)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
|
@ -41,7 +41,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "slowmode")
|
||||
.Description("Toggles slow mode. When ON, users will be able to send only 1 message every 5 seconds.")
|
||||
.Description($"Toggles slow mode. When ON, users will be able to send only 1 message every 5 seconds. | `{Prefix}slowmode`")
|
||||
.AddCheck(SimpleCheckers.ManageMessages())
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "asar")
|
||||
.Description("Adds a role, or list of roles separated by whitespace" +
|
||||
"(use quotations for multiword roles) to the list of self-assignable roles. | .asar Gamer")
|
||||
$"(use quotations for multiword roles) to the list of self-assignable roles. | {Prefix}asar Gamer")
|
||||
.Parameter("roles", ParameterType.Multiple)
|
||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||
.Do(async e =>
|
||||
@ -44,7 +44,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "rsar")
|
||||
.Description("Removes a specified role from the list of self-assignable roles.")
|
||||
.Description($"Removes a specified role from the list of self-assignable roles. | `{Prefix}rsar`")
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||
.Do(async e =>
|
||||
@ -69,14 +69,14 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "lsar")
|
||||
.Description("Lists all self-assignable roles.")
|
||||
.Description($"Lists all self-assignable roles. | `{Prefix}lsar`")
|
||||
.Parameter("roles", ParameterType.Multiple)
|
||||
.Do(async e =>
|
||||
{
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
var msg = new StringBuilder($"There are `{config.ListOfSelfAssignableRoles.Count}` self assignable roles:\n");
|
||||
var toRemove = new HashSet<ulong>();
|
||||
foreach (var roleId in config.ListOfSelfAssignableRoles.OrderBy(r=>r.ToString()))
|
||||
foreach (var roleId in config.ListOfSelfAssignableRoles.OrderBy(r => r.ToString()))
|
||||
{
|
||||
var role = e.Server.GetRole(roleId);
|
||||
if (role == null)
|
||||
@ -98,8 +98,8 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "togglexclsar").Alias(Module.Prefix +"tesar")
|
||||
.Description("toggle whether the self-assigned roles should be exclusive")
|
||||
cgb.CreateCommand(Module.Prefix + "togglexclsar").Alias(Module.Prefix + "tesar")
|
||||
.Description($"toggle whether the self-assigned roles should be exclusive | `{Prefix}tesar`")
|
||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -112,7 +112,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "iam")
|
||||
.Description("Adds a role to you that you choose. " +
|
||||
"Role must be on a list of self-assignable roles." +
|
||||
" | .iam Gamer")
|
||||
$" | {Prefix}iam Gamer")
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -146,12 +146,13 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
await e.User.AddRoles(role).ConfigureAwait(false);
|
||||
}
|
||||
catch(HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.InternalServerError)
|
||||
catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.InternalServerError)
|
||||
{
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception ex)
|
||||
{
|
||||
await e.Channel.SendMessage($":anger:`I am unable to add that role to you. I can't add roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var msg = await e.Channel.SendMessage($":ok:You now have {role.Name} role.").ConfigureAwait(false);
|
||||
await Task.Delay(3000).ConfigureAwait(false);
|
||||
@ -167,7 +168,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
.Alias(Module.Prefix + "iamn")
|
||||
.Description("Removes a role to you that you choose. " +
|
||||
"Role must be on a list of self-assignable roles." +
|
||||
" | .iamn Gamer")
|
||||
$" | {Prefix}iamn Gamer")
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "leave")
|
||||
.Description("Makes Nadeko leave the server. Either name or id required. | `.leave 123123123331`")
|
||||
.Description($"Makes Nadeko leave the server. Either name or id required. | `{Prefix}leave 123123123331`")
|
||||
.Parameter("arg", ParameterType.Required)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
|
@ -219,7 +219,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "grdel")
|
||||
.Description("Toggles automatic deletion of greet and bye messages.")
|
||||
.Description($"Toggles automatic deletion of greet and bye messages. | `{Prefix}grdel`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!e.User.ServerPermissions.ManageServer) return;
|
||||
@ -232,7 +232,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "greet")
|
||||
.Description("Toggles anouncements on the current channel when someone joins the server.")
|
||||
.Description($"Toggles anouncements on the current channel when someone joins the server. | `{Prefix}greet`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!e.User.ServerPermissions.ManageServer) return;
|
||||
@ -245,7 +245,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "greetmsg")
|
||||
.Description("Sets a new join announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current greet message. | .greetmsg Welcome to the server, %user%.")
|
||||
.Description($"Sets a new join announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current greet message. | `{Prefix}greetmsg Welcome to the server, %user%.`")
|
||||
.Parameter("msg", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -265,7 +265,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "bye")
|
||||
.Description("Toggles anouncements on the current channel when someone leaves the server.")
|
||||
.Description($"Toggles anouncements on the current channel when someone leaves the server. | `{Prefix}bye`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!e.User.ServerPermissions.ManageServer) return;
|
||||
@ -278,7 +278,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "byemsg")
|
||||
.Description("Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message. | .byemsg %user% has left the server.")
|
||||
.Description($"Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message. | `{Prefix}byemsg %user% has left the server.`")
|
||||
.Parameter("msg", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -297,7 +297,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "byepm")
|
||||
.Description("Toggles whether the good bye messages will be sent in a PM or in the text channel.")
|
||||
.Description($"Toggles whether the good bye messages will be sent in a PM or in the text channel. | `{Prefix}byepm`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!e.User.ServerPermissions.ManageServer) return;
|
||||
@ -313,7 +313,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "greetpm")
|
||||
.Description("Toggles whether the greet messages will be sent in a PM or in the text channel.")
|
||||
.Description($"Toggles whether the greet messages will be sent in a PM or in the text channel. | `{Prefix}greetpm`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!e.User.ServerPermissions.ManageServer) return;
|
||||
|
@ -1,46 +0,0 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
internal class VoiceNotificationCommand : DiscordCommand
|
||||
{
|
||||
|
||||
//voicechannel/text channel
|
||||
private readonly ConcurrentDictionary<Channel, Channel> subscribers = new ConcurrentDictionary<Channel, Channel>();
|
||||
|
||||
public Func<CommandEventArgs, Task> DoFunc() => async e =>
|
||||
{
|
||||
var arg = e.GetArg("voice_name");
|
||||
if (string.IsNullOrWhiteSpace("voice_name"))
|
||||
return;
|
||||
var voiceChannel = e.Server.FindChannels(arg, ChannelType.Voice).FirstOrDefault();
|
||||
if (voiceChannel == null)
|
||||
return;
|
||||
if (subscribers.ContainsKey(voiceChannel))
|
||||
{
|
||||
await e.Channel.SendMessage("`Voice channel notifications disabled.`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
if (subscribers.TryAdd(voiceChannel, e.Channel))
|
||||
{
|
||||
await e.Channel.SendMessage("`Voice channel notifications enabled.`").ConfigureAwait(false);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "voicenotif")
|
||||
.Description("Enables notifications on who joined/left the voice channel. |.voicenotif Karaoke club")
|
||||
.Parameter("voice_name", ParameterType.Unparsed)
|
||||
.Do(DoFunc());
|
||||
}
|
||||
|
||||
public VoiceNotificationCommand(DiscordModule module) : base(module) { }
|
||||
}
|
||||
}
|
@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "cleanv+t")
|
||||
.Alias(Module.Prefix + "cv+t")
|
||||
.Description("Deletes all text channels ending in `-voice` for which voicechannels are not found. **Use at your own risk.**")
|
||||
.Description($"Deletes all text channels ending in `-voice` for which voicechannels are not found. **Use at your own risk.** | `{Prefix}cleanv+t`")
|
||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||
.AddCheck(SimpleCheckers.ManageChannels())
|
||||
.Do(async e =>
|
||||
@ -120,7 +120,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "voice+text")
|
||||
.Alias(Module.Prefix + "v+t")
|
||||
.Description("Creates a text channel for each voice channel only users in that voice channel can see." +
|
||||
"If you are server owner, keep in mind you will see them all the time regardless.")
|
||||
$"If you are server owner, keep in mind you will see them all the time regardless. | `{Prefix}voice+text`")
|
||||
.AddCheck(SimpleCheckers.ManageChannels())
|
||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||
.Do(async e =>
|
||||
|
@ -8,7 +8,6 @@ using NadekoBot.Modules.Permissions.Classes;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -42,7 +41,7 @@ namespace NadekoBot.Modules.Conversations
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return;
|
||||
await Task.Run(() =>
|
||||
Classes.DbHandler.Instance.InsertData(new DataModels.UserQuote()
|
||||
Classes.DbHandler.Instance.Connection.Insert(new DataModels.UserQuote()
|
||||
{
|
||||
DateAdded = DateTime.Now,
|
||||
Keyword = e.GetArg("keyword").ToLowerInvariant(),
|
||||
@ -102,7 +101,7 @@ namespace NadekoBot.Modules.Conversations
|
||||
commands.ForEach(cmd => cmd.Init(cgb));
|
||||
|
||||
cgb.CreateCommand("die")
|
||||
.Description("Works only for the owner. Shuts the bot down.")
|
||||
.Description("Works only for the owner. Shuts the bot down. | `@NadekoBot die`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (NadekoBot.IsOwner(e.User.Id))
|
||||
@ -119,7 +118,7 @@ namespace NadekoBot.Modules.Conversations
|
||||
randServerSw.Start();
|
||||
|
||||
cgb.CreateCommand("do you love me")
|
||||
.Description("Replies with positive answer only to the bot owner.")
|
||||
.Description("Replies with positive answer only to the bot owner. | `@NadekoBot do you love me`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (NadekoBot.IsOwner(e.User.Id))
|
||||
@ -130,7 +129,7 @@ namespace NadekoBot.Modules.Conversations
|
||||
|
||||
cgb.CreateCommand("how are you")
|
||||
.Alias("how are you?")
|
||||
.Description("Replies positive only if bot owner is online.")
|
||||
.Description("Replies positive only if bot owner is online. | `@NadekoBot how are you`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (NadekoBot.IsOwner(e.User.Id))
|
||||
@ -150,7 +149,7 @@ namespace NadekoBot.Modules.Conversations
|
||||
});
|
||||
|
||||
cgb.CreateCommand("fire")
|
||||
.Description("Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire. | @NadekoBot fire [x]")
|
||||
.Description("Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire. | `@NadekoBot fire [x]`")
|
||||
.Parameter("times", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -174,7 +173,7 @@ namespace NadekoBot.Modules.Conversations
|
||||
});
|
||||
|
||||
cgb.CreateCommand("dump")
|
||||
.Description("Dumps all of the invites it can to dump.txt.** Owner Only.**")
|
||||
.Description("Dumps all of the invites it can to dump.txt.** Owner Only.** | `@NadekoBot dump`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!NadekoBot.IsOwner(e.User.Id)) return;
|
||||
@ -201,7 +200,7 @@ namespace NadekoBot.Modules.Conversations
|
||||
});
|
||||
|
||||
cgb.CreateCommand("ab")
|
||||
.Description("Try to get 'abalabahaha'")
|
||||
.Description("Try to get 'abalabahaha'| `@NadekoBot ab`")
|
||||
.Do(async e =>
|
||||
{
|
||||
string[] strings = { "ba", "la", "ha" };
|
||||
|
@ -1,14 +1,13 @@
|
||||
using NadekoBot.Classes;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Extensions;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Discord.Commands;
|
||||
using System.Collections.Concurrent;
|
||||
using Discord;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling.Commands
|
||||
{
|
||||
@ -23,8 +22,9 @@ namespace NadekoBot.Modules.Gambling.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Prefix + "race")
|
||||
.Description("Starts a new animal race.")
|
||||
.Do(e => {
|
||||
.Description($"Starts a new animal race. | `{Prefix}race`")
|
||||
.Do(e =>
|
||||
{
|
||||
var ar = new AnimalRace(e.Server.Id, e.Channel);
|
||||
if (ar.Fail)
|
||||
{
|
||||
@ -35,9 +35,10 @@ namespace NadekoBot.Modules.Gambling.Commands
|
||||
|
||||
cgb.CreateCommand(Prefix + "joinrace")
|
||||
.Alias(Prefix + "jr")
|
||||
.Description("Joins a new race. You can specify an amount of flowers for betting (optional). You will get YourBet*(participants-1) back if you win. | `$jr` or `$jr 5`")
|
||||
.Description($"Joins a new race. You can specify an amount of flowers for betting (optional). You will get YourBet*(participants-1) back if you win. | `{Prefix}jr` or `{Prefix}jr 5`")
|
||||
.Parameter("amount", ParameterType.Optional)
|
||||
.Do(async e => {
|
||||
.Do(async e =>
|
||||
{
|
||||
|
||||
int amount;
|
||||
if (!int.TryParse(e.GetArg("amount"), out amount) || amount < 0)
|
||||
@ -55,8 +56,10 @@ namespace NadekoBot.Modules.Gambling.Commands
|
||||
await FlowersHandler.RemoveFlowers(e.User, "BetRace", (int)amount, true).ConfigureAwait(false);
|
||||
|
||||
AnimalRace ar;
|
||||
if (!AnimalRaces.TryGetValue(e.Server.Id, out ar)) {
|
||||
if (!AnimalRaces.TryGetValue(e.Server.Id, out ar))
|
||||
{
|
||||
await e.Channel.SendMessage("No race exists on this server");
|
||||
return;
|
||||
}
|
||||
await ar.JoinRace(e.User, amount);
|
||||
|
||||
@ -93,7 +96,7 @@ namespace NadekoBot.Modules.Gambling.Commands
|
||||
{
|
||||
try
|
||||
{
|
||||
await raceChannel.SendMessage($"🏁`Race is starting in 20 seconds or when the room is full. Type $jr to join the race.`");
|
||||
await raceChannel.SendMessage($"🏁`Race is starting in 20 seconds or when the room is full. Type {NadekoBot.Config.CommandPrefixes.Gambling}jr to join the race.`");
|
||||
var t = await Task.WhenAny(Task.Delay(20000, token), fullgame);
|
||||
Started = true;
|
||||
cancelSource.Cancel();
|
||||
@ -103,7 +106,7 @@ namespace NadekoBot.Modules.Gambling.Commands
|
||||
}
|
||||
else if (participants.Count > 1)
|
||||
{
|
||||
await raceChannel.SendMessage("🏁`Game starting with " + participants.Count + " praticipants.`");
|
||||
await raceChannel.SendMessage("🏁`Game starting with " + participants.Count + " participants.`");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -127,7 +130,8 @@ namespace NadekoBot.Modules.Gambling.Commands
|
||||
AnimalRaces.TryRemove(serverId, out throwaway);
|
||||
}
|
||||
|
||||
private async Task StartRace() {
|
||||
private async Task StartRace()
|
||||
{
|
||||
var rng = new Random();
|
||||
Participant winner = null;
|
||||
Message msg = null;
|
||||
@ -163,7 +167,7 @@ namespace NadekoBot.Modules.Gambling.Commands
|
||||
|🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🏁🔚|";
|
||||
if (msg == null || messagesSinceGameStarted >= 10) // also resend the message if channel was spammed
|
||||
{
|
||||
if(msg != null)
|
||||
if (msg != null)
|
||||
try { await msg.Delete(); } catch { }
|
||||
msg = await raceChannel.SendMessage(text);
|
||||
messagesSinceGameStarted = 0;
|
||||
@ -199,10 +203,11 @@ namespace NadekoBot.Modules.Gambling.Commands
|
||||
messagesSinceGameStarted++;
|
||||
}
|
||||
|
||||
private async Task CheckForFullGameAsync(CancellationToken cancelToken) {
|
||||
private async Task CheckForFullGameAsync(CancellationToken cancelToken)
|
||||
{
|
||||
while (animals.Count > 0)
|
||||
{
|
||||
await Task.Delay(100,cancelToken);
|
||||
await Task.Delay(100, cancelToken);
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,8 +262,8 @@ namespace NadekoBot.Modules.Gambling.Commands
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var p = obj as Participant;
|
||||
return p == null?
|
||||
false:
|
||||
return p == null ?
|
||||
false :
|
||||
p.User == User;
|
||||
}
|
||||
|
||||
@ -279,7 +284,8 @@ namespace NadekoBot.Modules.Gambling.Commands
|
||||
{
|
||||
return str + "`3rd`";
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
return str + $"`{Place}th`";
|
||||
}
|
||||
|
||||
|
@ -21,18 +21,18 @@ namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "roll")
|
||||
.Description("Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice." +
|
||||
" If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | $roll or $roll 7 or $roll 3d5")
|
||||
$" If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | `{Prefix}roll` or `{Prefix}roll 7` or `{Prefix}roll 3d5`")
|
||||
.Parameter("num", ParameterType.Optional)
|
||||
.Do(RollFunc());
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "rolluo")
|
||||
.Description("Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice (unordered)." +
|
||||
" If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | $roll or $roll 7 or $roll 3d5")
|
||||
$" If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | `{Prefix}roll` or `{Prefix}roll` 7 or `{Prefix}roll 3d5`")
|
||||
.Parameter("num", ParameterType.Optional)
|
||||
.Do(RollFunc(false));
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "nroll")
|
||||
.Description("Rolls in a given range. | `$nroll 5` (rolls 0-5) or `$nroll 5-15`")
|
||||
.Description($"Rolls in a given range. | `{Prefix}nroll 5` (rolls 0-5) or `{Prefix}nroll 5-15`")
|
||||
.Parameter("range", ParameterType.Required)
|
||||
.Do(NRollFunc());
|
||||
}
|
||||
|
@ -17,13 +17,13 @@ namespace NadekoBot.Modules.Gambling
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "draw")
|
||||
.Description("Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck. | $draw [x]")
|
||||
.Description($"Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck. | `{Prefix}draw [x]`")
|
||||
.Parameter("count", ParameterType.Optional)
|
||||
.Do(DrawCardFunc());
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "shuffle")
|
||||
.Alias(Module.Prefix + "sh")
|
||||
.Description("Reshuffles all cards back into the deck.")
|
||||
.Description($"Reshuffles all cards back into the deck.|`{Prefix}shuffle`")
|
||||
.Do(ReshuffleTask());
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "flip")
|
||||
.Description("Flips coin(s) - heads or tails, and shows an image. | `$flip` or `$flip 3`")
|
||||
.Description($"Flips coin(s) - heads or tails, and shows an image. | `{Prefix}flip` or `{Prefix}flip 3`")
|
||||
.Parameter("count", ParameterType.Optional)
|
||||
.Do(FlipCoinFunc());
|
||||
|
||||
|
@ -33,7 +33,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
commands.ForEach(com => com.Init(cgb));
|
||||
|
||||
cgb.CreateCommand(Prefix + "raffle")
|
||||
.Description($"Prints a name and ID of a random user from the online list from the (optional) role. | `{Prefix}raffle` or `{Prefix}raffle RoleName")
|
||||
.Description($"Prints a name and ID of a random user from the online list from the (optional) role. | `{Prefix}raffle` or `{Prefix}raffle RoleName`")
|
||||
.Parameter("role", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -63,7 +63,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "give")
|
||||
.Description(string.Format("Give someone a certain amount of {0}s", NadekoBot.Config.CurrencyName))
|
||||
.Description(string.Format("Give someone a certain amount of {0}s", NadekoBot.Config.CurrencyName)+ $"|`{Prefix}give 1 \"@SomeGuy\"`")
|
||||
.Parameter("amount", ParameterType.Required)
|
||||
.Parameter("receiver", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -140,7 +140,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
|
||||
cgb.CreateCommand(Prefix + "betroll")
|
||||
.Alias(Prefix + "br")
|
||||
.Description($"Bets a certain amount of {NadekoBot.Config.CurrencyName}s and rolls a dice. Rolling over 66 yields x2 flowers, over 90 - x3 and 100 x10. | {Prefix}br 5")
|
||||
.Description($"Bets a certain amount of {NadekoBot.Config.CurrencyName}s and rolls a dice. Rolling over 66 yields x2 flowers, over 90 - x3 and 100 x10. | `{Prefix}br 5`")
|
||||
.Parameter("amount",ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -187,6 +187,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
|
||||
cgb.CreateCommand(Prefix + "leaderboard")
|
||||
.Alias(Prefix + "lb")
|
||||
.Description($"Displays bot currency leaderboard | {Prefix}lb")
|
||||
.Do(async e =>
|
||||
{
|
||||
var richestTemp = DbHandler.Instance.GetTopRichest();
|
||||
|
@ -20,7 +20,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "betray")
|
||||
.Description("BETRAY GAME. Betray nadeko next turn." +
|
||||
"If Nadeko cooperates - you get extra points, nadeko loses a LOT." +
|
||||
"If Nadeko betrays - you both lose some points.")
|
||||
$"If Nadeko betrays - you both lose some points. | `{Prefix}betray`")
|
||||
.Do(async e =>
|
||||
{
|
||||
await ReceiveAnswer(e, Answers.Betray).ConfigureAwait(false);
|
||||
@ -29,7 +29,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "cooperate")
|
||||
.Description("BETRAY GAME. Cooperate with nadeko next turn." +
|
||||
"If Nadeko cooperates - you both get bonus points." +
|
||||
"If Nadeko betrays - you lose A LOT, nadeko gets extra.")
|
||||
$"If Nadeko betrays - you lose A LOT, nadeko gets extra. | `{Prefix}cooperater`")
|
||||
.Do(async e =>
|
||||
{
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Text;
|
||||
|
||||
//taken from
|
||||
@ -291,13 +292,13 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
return sb.ToString(); // Return result.
|
||||
return sb.ToString().TrimTo(1995); // Return result.
|
||||
}
|
||||
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "leet")
|
||||
.Description($"Converts a text to leetspeak with 6 (1-6) severity levels | {Module.Prefix}leet 3 Hello")
|
||||
.Description($"Converts a text to leetspeak with 6 (1-6) severity levels | `{Module.Prefix}leet 3 Hello`")
|
||||
.Parameter("level", ParameterType.Required)
|
||||
.Parameter("text", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
|
@ -65,7 +65,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "pick")
|
||||
.Description("Picks a flower planted in this channel.")
|
||||
.Description($"Picks a flower planted in this channel. | `{Prefix}pick`")
|
||||
.Do(async e =>
|
||||
{
|
||||
IEnumerable<Message> msgs;
|
||||
@ -91,7 +91,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "plant")
|
||||
.Description("Spend a flower to plant it in this channel. (If bot is restarted or crashes, flower will be lost)")
|
||||
.Description($"Spend a flower to plant it in this channel. (If bot is restarted or crashes, flower will be lost) | `{Prefix}plant`")
|
||||
.Do(async e =>
|
||||
{
|
||||
await locker.WaitAsync().ConfigureAwait(false);
|
||||
@ -124,7 +124,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
|
||||
cgb.CreateCommand(Prefix + "gencurrency")
|
||||
.Alias(Prefix + "gc")
|
||||
.Description($"Toggles currency generation on this channel. Every posted message will have 2% chance to spawn a {NadekoBot.Config.CurrencyName}. Optional parameter cooldown time in minutes, 5 minutes by default. Requires Manage Messages permission. | `>gc` or `>gc 60`")
|
||||
.Description($"Toggles currency generation on this channel. Every posted message will have 2% chance to spawn a {NadekoBot.Config.CurrencyName}. Optional parameter cooldown time in minutes, 5 minutes by default. Requires Manage Messages permission. | `{Prefix}gc` or `{Prefix}gc 60`")
|
||||
.AddCheck(SimpleCheckers.ManageMessages())
|
||||
.Parameter("cd", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
|
@ -18,7 +18,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "poll")
|
||||
.Description("Creates a poll, only person who has manage server permission can do it. | >poll Question?;Answer1;Answ 2;A_3")
|
||||
.Description($"Creates a poll, only person who has manage server permission can do it. | `{Prefix}poll Question?;Answer1;Answ 2;A_3`")
|
||||
.Parameter("allargs", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -43,7 +43,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
}).ConfigureAwait(false);
|
||||
});
|
||||
cgb.CreateCommand(Module.Prefix + "pollend")
|
||||
.Description("Stops active poll on this server and prints the results in this channel.")
|
||||
.Description($"Stops active poll on this server and prints the results in this channel. | `{Prefix}pollend`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!e.User.ServerPermissions.ManageChannels)
|
||||
|
@ -168,21 +168,21 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "typestart")
|
||||
.Description("Starts a typing contest.")
|
||||
.Description($"Starts a typing contest. | `{Prefix}typestart`")
|
||||
.Do(DoFunc());
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "typestop")
|
||||
.Description("Stops a typing contest on the current channel.")
|
||||
.Description($"Stops a typing contest on the current channel. | `{Prefix}typestop`")
|
||||
.Do(QuitFunc());
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "typeadd")
|
||||
.Description("Adds a new article to the typing contest. Owner only.")
|
||||
.Description($"Adds a new article to the typing contest. Owner only. | `{Prefix}typeadd wordswords`")
|
||||
.Parameter("text", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!NadekoBot.IsOwner(e.User.Id) || string.IsNullOrWhiteSpace(e.GetArg("text"))) return;
|
||||
|
||||
DbHandler.Instance.InsertData(new TypingArticle
|
||||
DbHandler.Instance.Connection.Insert(new TypingArticle
|
||||
{
|
||||
Text = e.GetArg("text"),
|
||||
DateAdded = DateTime.Now
|
||||
|
@ -46,7 +46,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "tl")
|
||||
.Description("Shows a current trivia leaderboard.")
|
||||
.Description($"Shows a current trivia leaderboard. | `{Prefix}tl`")
|
||||
.Do(async e =>
|
||||
{
|
||||
TriviaGame trivia;
|
||||
@ -57,7 +57,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "tq")
|
||||
.Description("Quits current trivia after current question.")
|
||||
.Description($"Quits current trivia after current question. | `{Prefix}tq`")
|
||||
.Do(async e =>
|
||||
{
|
||||
TriviaGame trivia;
|
||||
|
@ -60,7 +60,7 @@ namespace NadekoBot.Modules.Games
|
||||
try
|
||||
{
|
||||
await e.Channel.SendMessage(
|
||||
$":question: **Question**: `{question}` \n🎱 **8Ball Answers**: `{NadekoBot.Config._8BallResponses[rng.Next(0, NadekoBot.Config._8BallResponses.Length)]}`")
|
||||
$":question: `Question` __**{question}**__ \n🎱 `8Ball Answers` __**{NadekoBot.Config._8BallResponses[rng.Next(0, NadekoBot.Config._8BallResponses.Length)]}**__")
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
|
@ -31,7 +31,7 @@ namespace NadekoBot.Classes.Help.Commands
|
||||
if (alias != null)
|
||||
str = $" / `{ com.Aliases.FirstOrDefault()}`";
|
||||
if (com != null)
|
||||
await e.Channel.SendMessage($@"**__Help for:__ `{com.Text}`**" + str + $"\n**Desc:** {new Regex(@"\|").Replace(com.Description, "\n**Usage:**",1)}").ConfigureAwait(false);
|
||||
await e.Channel.SendMessage($@"**__Help for:__ `{com.Text}`**" + str + $"\n**Desc:** {new Regex(@"\|").Replace(com.Description, "\n**Usage:**", 1)}").ConfigureAwait(false);
|
||||
}).ConfigureAwait(false);
|
||||
};
|
||||
public static string HelpString {
|
||||
@ -48,11 +48,11 @@ namespace NadekoBot.Classes.Help.Commands
|
||||
public Action<CommandEventArgs> DoGitFunc() => e =>
|
||||
{
|
||||
string helpstr =
|
||||
$@"######For more information and how to setup your own NadekoBot, go to: **http://github.com/Kwoth/NadekoBot/**
|
||||
######You can donate on paypal: `nadekodiscordbot@gmail.com`
|
||||
$@"######For more information and how to setup your own NadekoBot, go to: <http://github.com/Kwoth/NadekoBot/wiki>
|
||||
######You can donate on patreon: <https://patreon.com/nadekobot>
|
||||
######or paypal: `nadekodiscordbot@gmail.com`
|
||||
|
||||
#NadekoBot List Of Commands
|
||||
Version: `{NadekoStats.Instance.BotVersion}`";
|
||||
#NadekoBot List Of Commands ";
|
||||
|
||||
|
||||
string lastCategory = "";
|
||||
@ -80,16 +80,16 @@ Version: `{NadekoStats.Instance.BotVersion}`";
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "h")
|
||||
.Alias(Module.Prefix + "help", NadekoBot.BotMention + " help", NadekoBot.BotMention + " h", "~h")
|
||||
.Description("Either shows a help for a single command, or PMs you help link if no arguments are specified. | '-h !m q' or just '-h' ")
|
||||
.Description($"Either shows a help for a single command, or PMs you help link if no arguments are specified. | `{Prefix}h !m q` or just `{Prefix}h` ")
|
||||
.Parameter("command", ParameterType.Unparsed)
|
||||
.Do(HelpFunc());
|
||||
cgb.CreateCommand(Module.Prefix + "hgit")
|
||||
.Description("Generates the commandlist.md file. **Bot Owner Only!**")
|
||||
.Description($"Generates the commandlist.md file. **Bot Owner Only!** | `{Prefix}hgit`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(DoGitFunc());
|
||||
cgb.CreateCommand(Module.Prefix + "readme")
|
||||
.Alias(Module.Prefix + "guide")
|
||||
.Description("Sends a readme and a guide links to the channel.")
|
||||
.Description($"Sends a readme and a guide links to the channel. | `{Prefix}readme` or `{Prefix}guide`")
|
||||
.Do(async e =>
|
||||
await e.Channel.SendMessage(
|
||||
@"**Wiki with all info**: <https://github.com/Kwoth/NadekoBot/wiki>
|
||||
@ -102,16 +102,15 @@ Version: `{NadekoStats.Instance.BotVersion}`";
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "donate")
|
||||
.Alias("~donate")
|
||||
.Description("Instructions for helping the project!")
|
||||
.Description($"Instructions for helping the project! | `{Prefix}donate` or `~donate`")
|
||||
.Do(async e =>
|
||||
{
|
||||
await e.Channel.SendMessage(
|
||||
$@"I've created a **paypal** email for nadeko, so if you wish to support the project, you can send your donations to `nadekodiscordbot@gmail.com`
|
||||
Don't forget to leave your discord name or id in the message, so that I can reward people who help out.
|
||||
You can join nadekobot server by typing {Module.Prefix}h and you will get an invite in a private message.
|
||||
$@"You can support the project on patreon. <https://patreon.com/nadekobot> or
|
||||
You can send donations to `nadekodiscordbot@gmail.com`
|
||||
Don't forget to leave your discord name or id in the message.
|
||||
|
||||
*If you want to support in some other way or on a different platform, please message me*"
|
||||
).ConfigureAwait(false);
|
||||
**Thank you** ♥️").ConfigureAwait(false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ namespace NadekoBot.Modules.Help
|
||||
|
||||
cgb.CreateCommand(Prefix + "modules")
|
||||
.Alias(".modules")
|
||||
.Description("List all bot modules.")
|
||||
.Description($"List all bot modules. | `{Prefix}modules` or `.modules`")
|
||||
.Do(async e =>
|
||||
{
|
||||
await e.Channel.SendMessage("`List of modules:` \n• " + string.Join("\n• ", NadekoBot.Client.GetService<ModuleService>().Modules.Select(m => m.Name)) + $"\n`Type \"{Prefix}commands module_name\" to get a list of commands in that module.`")
|
||||
@ -38,7 +38,7 @@ namespace NadekoBot.Modules.Help
|
||||
|
||||
cgb.CreateCommand(Prefix + "commands")
|
||||
.Alias(".commands")
|
||||
.Description("List all of the bot's commands from a certain module.")
|
||||
.Description($"List all of the bot's commands from a certain module. | `{Prefix}commands` or `.commands`")
|
||||
.Parameter("module", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
public IReadOnlyCollection<Song> Playlist => playlist;
|
||||
|
||||
public Song CurrentSong { get; private set; }
|
||||
private CancellationTokenSource SongCancelSource { get; set; }
|
||||
public CancellationTokenSource SongCancelSource { get; private set; }
|
||||
private CancellationToken cancelToken { get; set; }
|
||||
|
||||
public bool Paused { get; set; }
|
||||
|
@ -32,7 +32,6 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
public SongInfo SongInfo { get; }
|
||||
public string QueuerName { get; set; }
|
||||
|
||||
private bool bufferingCompleted { get; set; } = false;
|
||||
public MusicPlayer MusicPlayer { get; set; }
|
||||
|
||||
public string PrettyCurrentTime()
|
||||
@ -73,78 +72,22 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
return this;
|
||||
}
|
||||
|
||||
private Task BufferSong(string filename, CancellationToken cancelToken) =>
|
||||
Task.Factory.StartNew(async () =>
|
||||
{
|
||||
Process p = null;
|
||||
try
|
||||
{
|
||||
p = Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = "ffmpeg",
|
||||
Arguments = $"-ss {skipTo} -i {SongInfo.Uri} -f s16le -ar 48000 -ac 2 pipe:1 -loglevel quiet",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = false,
|
||||
CreateNoWindow = true,
|
||||
});
|
||||
var prebufferSize = 100ul.MiB();
|
||||
using (var outStream = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.Read))
|
||||
{
|
||||
byte[] buffer = new byte[81920];
|
||||
int bytesRead;
|
||||
while ((bytesRead = await p.StandardOutput.BaseStream.ReadAsync(buffer, 0, buffer.Length, cancelToken).ConfigureAwait(false)) != 0)
|
||||
{
|
||||
await outStream.WriteAsync(buffer, 0, bytesRead, cancelToken).ConfigureAwait(false);
|
||||
while ((ulong)outStream.Length - bytesSent > prebufferSize)
|
||||
await Task.Delay(100, cancelToken);
|
||||
}
|
||||
}
|
||||
|
||||
bufferingCompleted = true;
|
||||
}
|
||||
catch (System.ComponentModel.Win32Exception) {
|
||||
var oldclr = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(@"You have not properly installed or configured FFMPEG.
|
||||
Please install and configure FFMPEG to play music.
|
||||
Check the guides for your platform on how to setup ffmpeg correctly:
|
||||
Windows Guide: https://goo.gl/SCv72y
|
||||
Linux Guide: https://goo.gl/rRhjCp");
|
||||
Console.ForegroundColor = oldclr;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Buffering stopped: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.WriteLine($"Buffering done.");
|
||||
if (p != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
p.Kill();
|
||||
}
|
||||
catch { }
|
||||
p.Dispose();
|
||||
}
|
||||
}
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
|
||||
internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken)
|
||||
{
|
||||
var filename = Path.Combine(MusicModule.MusicDataPath, DateTime.Now.UnixTimestamp().ToString());
|
||||
|
||||
var bufferTask = BufferSong(filename, cancelToken).ConfigureAwait(false);
|
||||
SongBuffer sb = new SongBuffer(filename, SongInfo, skipTo);
|
||||
var bufferTask = sb.BufferSong(cancelToken).ConfigureAwait(false);
|
||||
|
||||
var inStream = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write);
|
||||
var inStream = new FileStream(sb.GetNextFile(), FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write); ;
|
||||
|
||||
bytesSent = 0;
|
||||
|
||||
try
|
||||
{
|
||||
var prebufferingTask = CheckPrebufferingAsync(inStream, cancelToken);
|
||||
var attempt = 0;
|
||||
|
||||
var prebufferingTask = CheckPrebufferingAsync(inStream, sb, cancelToken);
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
var t = await Task.WhenAny(prebufferingTask, Task.Delay(5000, cancelToken));
|
||||
@ -162,7 +105,6 @@ Check the guides for your platform on how to setup ffmpeg correctly:
|
||||
Console.WriteLine("Prebuffering successfully completed in "+ sw.Elapsed);
|
||||
|
||||
const int blockSize = 3840;
|
||||
var attempt = 0;
|
||||
byte[] buffer = new byte[blockSize];
|
||||
while (!cancelToken.IsCancellationRequested)
|
||||
{
|
||||
@ -173,14 +115,31 @@ Check the guides for your platform on how to setup ffmpeg correctly:
|
||||
{
|
||||
bytesSent += (ulong)read;
|
||||
}
|
||||
if (read == 0)
|
||||
if (attempt++ == 20)
|
||||
if (read < blockSize)
|
||||
{
|
||||
if (sb.IsNextFileReady())
|
||||
{
|
||||
voiceClient.Wait();
|
||||
break;
|
||||
inStream.Dispose();
|
||||
inStream = new FileStream(sb.GetNextFile(), FileMode.Open, FileAccess.Read, FileShare.Write);
|
||||
read += inStream.Read(buffer, read, buffer.Length - read);
|
||||
attempt = 0;
|
||||
}
|
||||
if (read == 0)
|
||||
{
|
||||
if (sb.BufferingCompleted)
|
||||
break;
|
||||
if (attempt++ == 20)
|
||||
{
|
||||
voiceClient.Wait();
|
||||
MusicPlayer.SongCancelSource.Cancel();
|
||||
break;
|
||||
}
|
||||
else
|
||||
await Task.Delay(100, cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
await Task.Delay(100, cancelToken).ConfigureAwait(false);
|
||||
attempt = 0;
|
||||
}
|
||||
else
|
||||
attempt = 0;
|
||||
|
||||
@ -195,14 +154,16 @@ Check the guides for your platform on how to setup ffmpeg correctly:
|
||||
{
|
||||
await bufferTask;
|
||||
await Task.Run(() => voiceClient.Clear());
|
||||
inStream.Dispose();
|
||||
try { File.Delete(filename); } catch { }
|
||||
if(inStream != null)
|
||||
inStream.Dispose();
|
||||
Console.WriteLine("l");
|
||||
sb.CleanFiles();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CheckPrebufferingAsync(Stream inStream, CancellationToken cancelToken)
|
||||
private async Task CheckPrebufferingAsync(Stream inStream, SongBuffer sb, CancellationToken cancelToken)
|
||||
{
|
||||
while (!bufferingCompleted && inStream.Length < 2.MiB())
|
||||
while (!sb.BufferingCompleted && inStream.Length < 2.MiB())
|
||||
{
|
||||
await Task.Delay(100, cancelToken);
|
||||
}
|
||||
|
159
NadekoBot/Modules/Music/Classes/SongBuffer.cs
Normal file
159
NadekoBot/Modules/Music/Classes/SongBuffer.cs
Normal file
@ -0,0 +1,159 @@
|
||||
using NadekoBot.Extensions;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Music.Classes
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a buffer for a song file. It will create multiples files to ensure, that radio don't fill up disk space.
|
||||
/// It also help for large music by deleting files that are already seen.
|
||||
/// </summary>
|
||||
class SongBuffer
|
||||
{
|
||||
|
||||
public SongBuffer(string basename, SongInfo songInfo, int skipTo)
|
||||
{
|
||||
Basename = basename;
|
||||
SongInfo = songInfo;
|
||||
SkipTo = skipTo;
|
||||
}
|
||||
|
||||
private string Basename;
|
||||
|
||||
private SongInfo SongInfo;
|
||||
|
||||
private int SkipTo;
|
||||
|
||||
private static int MAX_FILE_SIZE = 20.MiB();
|
||||
|
||||
private long FileNumber = -1;
|
||||
|
||||
private long NextFileToRead = 0;
|
||||
|
||||
public bool BufferingCompleted { get; private set;} = false;
|
||||
|
||||
private ulong CurrentBufferSize = 0;
|
||||
|
||||
public Task BufferSong(CancellationToken cancelToken) =>
|
||||
Task.Factory.StartNew(async () =>
|
||||
{
|
||||
Process p = null;
|
||||
FileStream outStream = null;
|
||||
try
|
||||
{
|
||||
p = Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = "ffmpeg",
|
||||
Arguments = $"-ss {SkipTo} -i {SongInfo.Uri} -f s16le -ar 48000 -ac 2 pipe:1 -loglevel quiet",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = false,
|
||||
CreateNoWindow = true,
|
||||
});
|
||||
|
||||
byte[] buffer = new byte[81920];
|
||||
int currentFileSize = 0;
|
||||
ulong prebufferSize = 100ul.MiB();
|
||||
|
||||
outStream = new FileStream(Basename + "-" + ++FileNumber, FileMode.Append, FileAccess.Write, FileShare.Read);
|
||||
while (!p.HasExited) //Also fix low bandwidth
|
||||
{
|
||||
int bytesRead = await p.StandardOutput.BaseStream.ReadAsync(buffer, 0, buffer.Length, cancelToken).ConfigureAwait(false);
|
||||
if (currentFileSize >= MAX_FILE_SIZE)
|
||||
{
|
||||
try
|
||||
{
|
||||
outStream.Dispose();
|
||||
}catch { }
|
||||
outStream = new FileStream(Basename + "-" + ++FileNumber, FileMode.Append, FileAccess.Write, FileShare.Read);
|
||||
currentFileSize = bytesRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentFileSize += bytesRead;
|
||||
}
|
||||
CurrentBufferSize += Convert.ToUInt64(bytesRead);
|
||||
await outStream.WriteAsync(buffer, 0, bytesRead, cancelToken).ConfigureAwait(false);
|
||||
while (CurrentBufferSize > prebufferSize)
|
||||
await Task.Delay(100, cancelToken);
|
||||
}
|
||||
BufferingCompleted = true;
|
||||
}
|
||||
catch (System.ComponentModel.Win32Exception)
|
||||
{
|
||||
var oldclr = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(@"You have not properly installed or configured FFMPEG.
|
||||
Please install and configure FFMPEG to play music.
|
||||
Check the guides for your platform on how to setup ffmpeg correctly:
|
||||
Windows Guide: https://goo.gl/SCv72y
|
||||
Linux Guide: https://goo.gl/rRhjCp");
|
||||
Console.ForegroundColor = oldclr;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Buffering stopped: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(outStream != null)
|
||||
outStream.Dispose();
|
||||
Console.WriteLine($"Buffering done.");
|
||||
if (p != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
p.Kill();
|
||||
}
|
||||
catch { }
|
||||
p.Dispose();
|
||||
}
|
||||
}
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
|
||||
/// <summary>
|
||||
/// Return the next file to read, and delete the old one
|
||||
/// </summary>
|
||||
/// <returns>Name of the file to read</returns>
|
||||
public string GetNextFile()
|
||||
{
|
||||
string filename = Basename + "-" + NextFileToRead;
|
||||
|
||||
if (NextFileToRead != 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
CurrentBufferSize -= Convert.ToUInt64(new FileInfo(Basename + "-" + (NextFileToRead - 1)).Length);
|
||||
File.Delete(Basename + "-" + (NextFileToRead - 1));
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
NextFileToRead++;
|
||||
return filename;
|
||||
}
|
||||
|
||||
public bool IsNextFileReady()
|
||||
{
|
||||
return NextFileToRead <= FileNumber;
|
||||
}
|
||||
|
||||
public void CleanFiles()
|
||||
{
|
||||
for (long i = NextFileToRead - 1 ; i <= FileNumber; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(Basename + "-" + i);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -614,11 +614,11 @@ namespace NadekoBot.Modules.Music
|
||||
};
|
||||
DbHandler.Instance.SaveAll(songInfos);
|
||||
DbHandler.Instance.Save(playlist);
|
||||
DbHandler.Instance.InsertMany(songInfos.Select(s => new PlaylistSongInfo
|
||||
DbHandler.Instance.Connection.InsertAll(songInfos.Select(s => new PlaylistSongInfo
|
||||
{
|
||||
PlaylistId = playlist.Id.Value,
|
||||
SongInfoId = s.Id.Value
|
||||
}));
|
||||
}), typeof(PlaylistSongInfo));
|
||||
|
||||
await e.Channel.SendMessage($"🎵 `Saved playlist as {name}-{playlist.Id}`").ConfigureAwait(false);
|
||||
|
||||
@ -718,7 +718,7 @@ namespace NadekoBot.Modules.Music
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "goto")
|
||||
.Description($"Goes to a specific time in seconds in a song. | {Prefix}goto 30")
|
||||
.Description($"Goes to a specific time in seconds in a song. | `{Prefix}goto 30`")
|
||||
.Parameter("time")
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -756,16 +756,37 @@ namespace NadekoBot.Modules.Music
|
||||
|
||||
cgb.CreateCommand(Prefix + "getlink")
|
||||
.Alias(Prefix + "gl")
|
||||
.Description("Shows a link to the currently playing song.")
|
||||
.Description("Shows a link to the song in the queue by index, or the currently playing song by default.")
|
||||
.Parameter("index", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
return;
|
||||
var curSong = musicPlayer.CurrentSong;
|
||||
if (curSong == null)
|
||||
return;
|
||||
await e.Channel.SendMessage($"🎶`Current song:` <{curSong.SongInfo.Query}>").ConfigureAwait(false);
|
||||
int index;
|
||||
string arg = e.GetArg("index")?.Trim();
|
||||
if (!string.IsNullOrEmpty(arg) && int.TryParse(arg, out index))
|
||||
{
|
||||
|
||||
var selSong = musicPlayer.Playlist.DefaultIfEmpty(null).ElementAtOrDefault(index - 1);
|
||||
if (selSong == null)
|
||||
{
|
||||
await e.Channel.SendMessage("Could not select song, likely wrong index");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
await e.Channel.SendMessage($"🎶`Selected song {selSong.SongInfo.Title}:` <{selSong.SongInfo.Query}>").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var curSong = musicPlayer.CurrentSong;
|
||||
if (curSong == null)
|
||||
return;
|
||||
await e.Channel.SendMessage($"🎶`Current song:` <{curSong.SongInfo.Query}>").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "autoplay")
|
||||
@ -818,7 +839,7 @@ namespace NadekoBot.Modules.Music
|
||||
lastFinishedMessage = await textCh.SendMessage($"🎵`Finished`{song.PrettyName}").ConfigureAwait(false);
|
||||
if (mp.Autoplay && mp.Playlist.Count == 0 && song.SongInfo.Provider == "YouTube")
|
||||
{
|
||||
await QueueSong(queuer, textCh, voiceCh, await SearchHelper.GetRelatedVideoId(song.SongInfo.Query), silent, musicType).ConfigureAwait(false);
|
||||
await QueueSong(queuer.Server.CurrentUser, textCh, voiceCh, (await SearchHelper.GetRelatedVideoIds(song.SongInfo.Query, 4)).ToList().Shuffle().FirstOrDefault(), silent, musicType).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -4,6 +4,8 @@ using NadekoBot.Classes;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.NSFW
|
||||
{
|
||||
@ -27,16 +29,16 @@ namespace NadekoBot.Modules.NSFW
|
||||
.Do(async e =>
|
||||
{
|
||||
var tag = e.GetArg("tag")?.Trim() ?? "";
|
||||
var gel = await SearchHelper.GetGelbooruImageLink("rating%3Aexplicit+" + tag).ConfigureAwait(false);
|
||||
if (gel != null)
|
||||
await e.Channel.SendMessage(":heart: Gelbooru: " + gel)
|
||||
.ConfigureAwait(false);
|
||||
var dan = await SearchHelper.GetDanbooruImageLink("rating%3Aexplicit+" + tag).ConfigureAwait(false);
|
||||
if (dan != null)
|
||||
await e.Channel.SendMessage(":heart: Danbooru: " + dan)
|
||||
.ConfigureAwait(false);
|
||||
if (dan == null && gel == null)
|
||||
|
||||
var links = await Task.WhenAll(SearchHelper.GetGelbooruImageLink("rating%3Aexplicit+" + tag), SearchHelper.GetDanbooruImageLink("rating%3Aexplicit+" + tag)).ConfigureAwait(false);
|
||||
|
||||
if (links.All(l => l == null))
|
||||
{
|
||||
await e.Channel.SendMessage("`No results.`");
|
||||
return;
|
||||
}
|
||||
|
||||
await e.Channel.SendMessage(String.Join("\n\n", links)).ConfigureAwait(false);
|
||||
});
|
||||
cgb.CreateCommand(Prefix + "danbooru")
|
||||
.Description($"Shows a random hentai image from danbooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +) | `{Prefix}danbooru yuri+kissing`")
|
||||
@ -84,14 +86,14 @@ namespace NadekoBot.Modules.NSFW
|
||||
await e.Channel.SendMessage(await SearchHelper.GetE621ImageLink(tag).ConfigureAwait(false)).ConfigureAwait(false);
|
||||
});
|
||||
cgb.CreateCommand(Prefix + "cp")
|
||||
.Description("We all know where this will lead you to.")
|
||||
.Description($"We all know where this will lead you to. | `{Prefix}cp`")
|
||||
.Parameter("anything", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
await e.Channel.SendMessage("http://i.imgur.com/MZkY1md.jpg").ConfigureAwait(false);
|
||||
});
|
||||
cgb.CreateCommand(Prefix + "boobs")
|
||||
.Description("Real adult content.")
|
||||
.Description($"Real adult content. | `{Prefix}boobs`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -106,7 +108,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
});
|
||||
cgb.CreateCommand(Prefix + "butts")
|
||||
.Alias(Prefix + "ass", Prefix + "butt")
|
||||
.Description("Real adult content.")
|
||||
.Description($"Real adult content. | `{Prefix}butts` or `{Prefix}ass`")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
|
@ -55,7 +55,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
.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." +
|
||||
" | ;cfi enable #general-chat")
|
||||
$" | {Prefix}cfi enable #general-chat")
|
||||
.Parameter("bool")
|
||||
.Parameter("channel", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
@ -95,7 +95,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "srvrfilterinv")
|
||||
.Alias(Module.Prefix + "sfi")
|
||||
.Description("Enables or disables automatic deleting of invites on the server. | ;sfi disable")
|
||||
.Description($"Enables or disables automatic deleting of invites on the server. | {Prefix}sfi disable")
|
||||
.Parameter("bool")
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
.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." +
|
||||
" | ;cfw enable #general-chat")
|
||||
$" | {Prefix}cfw enable #general-chat")
|
||||
.Parameter("bool")
|
||||
.Parameter("channel", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
@ -89,7 +89,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "addfilterword")
|
||||
.Alias(Module.Prefix + "afw")
|
||||
.Description("Adds a new word to the list of filtered words" +
|
||||
" | ;afw poop")
|
||||
$" | {Prefix}afw poop")
|
||||
.Parameter("word", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -111,7 +111,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "rmvfilterword")
|
||||
.Alias(Module.Prefix + "rfw")
|
||||
.Description("Removes the word from the list of filtered words" +
|
||||
" | ;rw poop")
|
||||
$" | {Prefix}rw poop")
|
||||
.Parameter("word", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -133,7 +133,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "lstfilterwords")
|
||||
.Alias(Module.Prefix + "lfw")
|
||||
.Description("Shows a list of filtered words" +
|
||||
" | ;lfw")
|
||||
$" | {Prefix}lfw")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -152,7 +152,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "srvrfilterwords")
|
||||
.Alias(Module.Prefix + "sfw")
|
||||
.Description("Enables or disables automatic deleting of messages containing forbidden words on the server. | ;sfw disable")
|
||||
.Description($"Enables or disables automatic deleting of messages containing forbidden words on the server. | {Prefix}sfw disable")
|
||||
.Parameter("bool")
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
|
||||
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'.")
|
||||
.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 =>
|
||||
{
|
||||
@ -158,7 +158,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
|
||||
cgb.CreateCommand(Prefix + "srvrperms")
|
||||
.Alias(Prefix + "sp")
|
||||
.Description("Shows banned permissions for this server.")
|
||||
.Description($"Shows banned permissions for this server. | `{Prefix}sp`")
|
||||
.Do(async e =>
|
||||
{
|
||||
var perms = PermissionsHandler.GetServerPermissions(e.Server);
|
||||
|
@ -196,7 +196,7 @@ namespace NadekoBot.Modules.Pokemon
|
||||
|
||||
cgb.CreateCommand(Prefix + "movelist")
|
||||
.Alias(Prefix + "ml")
|
||||
.Description("Lists the moves you are able to use")
|
||||
.Description($"Lists the moves you are able to use | `{Prefix}ml`")
|
||||
.Do(async e =>
|
||||
{
|
||||
var userType = GetPokeType(e.User.Id);
|
||||
@ -210,7 +210,7 @@ namespace NadekoBot.Modules.Pokemon
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "heal")
|
||||
.Description($"Heals someone. Revives those who fainted. Costs a {NadekoBot.Config.CurrencyName} | {Prefix}heal @someone")
|
||||
.Description($"Heals someone. Revives those who fainted. Costs a {NadekoBot.Config.CurrencyName} | `{Prefix}heal @someone`")
|
||||
.Parameter("target", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -263,7 +263,7 @@ namespace NadekoBot.Modules.Pokemon
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "type")
|
||||
.Description($"Get the poketype of the target. | {Prefix}type @someone")
|
||||
.Description($"Get the poketype of the target. | `{Prefix}type @someone`")
|
||||
.Parameter("target", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -282,7 +282,7 @@ namespace NadekoBot.Modules.Pokemon
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "settype")
|
||||
.Description($"Set your poketype. Costs a {NadekoBot.Config.CurrencyName}. | {Prefix}settype fire")
|
||||
.Description($"Set your poketype. Costs a {NadekoBot.Config.CurrencyName}. | `{Prefix}settype fire`")
|
||||
.Parameter("targetType", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -319,11 +319,11 @@ namespace NadekoBot.Modules.Pokemon
|
||||
DbHandler.Instance.Delete<UserPokeTypes>(Dict[(long)e.User.Id]);
|
||||
}
|
||||
|
||||
DbHandler.Instance.InsertData(new UserPokeTypes
|
||||
DbHandler.Instance.Connection.Insert(new UserPokeTypes
|
||||
{
|
||||
UserId = (long)e.User.Id,
|
||||
type = targetType.Name
|
||||
});
|
||||
}, typeof(UserPokeTypes));
|
||||
|
||||
//Now for the response
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "convert")
|
||||
.Description("Convert quantities from>to. Like `~convert m>km 1000`")
|
||||
.Description($"Convert quantities from>to. | `{Prefix}convert m>km 1000`")
|
||||
.Parameter("from-to", ParameterType.Required)
|
||||
.Parameter("quantity", ParameterType.Optional)
|
||||
.Do(ConvertFunc());
|
||||
|
@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "calculate")
|
||||
.Alias(Module.Prefix + "calc")
|
||||
.Description("Evaluate a mathematical expression. | ~calc 1+1")
|
||||
.Description($"Evaluate a mathematical expression. | {Prefix}calc 1+1")
|
||||
.Parameter("expression", ParameterType.Unparsed)
|
||||
.Do(EvalFunc());
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "lolchamp")
|
||||
.Description("Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role. |~lolchamp Riven or ~lolchamp Annie sup")
|
||||
.Description($"Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role. |`{Prefix}lolchamp Riven` or `{Prefix}lolchamp Annie sup`")
|
||||
.Parameter("champ", ParameterType.Required)
|
||||
.Parameter("position", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -280,7 +280,7 @@ Assists: {general["assists"]} Ban: {general["banRate"]}%
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "lolban")
|
||||
.Description("Shows top 6 banned champions ordered by ban rate. Ban these champions and you will be Plat 5 in no time.")
|
||||
.Description($"Shows top 6 banned champions ordered by ban rate. Ban these champions and you will be Plat 5 in no time. | `{Prefix}lolban`")
|
||||
.Do(async e =>
|
||||
{
|
||||
|
||||
|
@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Prefix + "memelist")
|
||||
.Description("Pulls a list of memes you can use with `~memegen` from http://memegen.link/templates/")
|
||||
.Description($"Pulls a list of memes you can use with `~memegen` from http://memegen.link/templates/ | `{Prefix}memelist`")
|
||||
.Do(async e =>
|
||||
{
|
||||
int i = 0;
|
||||
@ -30,7 +30,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "memegen")
|
||||
.Description("Generates a meme from memelist with top and bottom text. | `~memegen biw \"gets iced coffee\" \"in the winter\"`")
|
||||
.Description($"Generates a meme from memelist with top and bottom text. | `{Prefix}memegen biw \"gets iced coffee\" \"in the winter\"`")
|
||||
.Parameter("meme", ParameterType.Required)
|
||||
.Parameter("toptext", ParameterType.Required)
|
||||
.Parameter("bottext", ParameterType.Required)
|
||||
|
@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "osu")
|
||||
.Description("Shows osu stats for a player. | `~osu Name` or `~osu Name taiko`")
|
||||
.Description($"Shows osu stats for a player. | `{Prefix}osu Name` or `{Prefix}osu Name taiko`")
|
||||
.Parameter("usr", ParameterType.Required)
|
||||
.Parameter("mode", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -56,7 +56,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "osu b")
|
||||
.Description("Shows information about an osu beatmap. |~osu b https://osu.ppy.sh/s/127712")
|
||||
.Description($"Shows information about an osu beatmap. |`{Prefix}osu b` https://osu.ppy.sh/s/127712`")
|
||||
.Parameter("map", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "osu top5")
|
||||
.Description("Displays a user's top 5 plays. |~osu top5 Name")
|
||||
.Description($"Displays a user's top 5 plays. |{Prefix}osu top5 Name")
|
||||
.Parameter("usr", ParameterType.Required)
|
||||
.Parameter("mode", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
|
@ -22,7 +22,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
{
|
||||
cgb.CreateCommand(Prefix + "pokemon")
|
||||
.Alias(Prefix + "poke")
|
||||
.Description("Searches for a pokemon.")
|
||||
.Description($"Searches for a pokemon. | `{Prefix}poke Sylveon`")
|
||||
.Parameter("pokemon", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -43,7 +43,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
|
||||
cgb.CreateCommand(Prefix + "pokemonability")
|
||||
.Alias(Prefix + "pokeab")
|
||||
.Description("Searches for a pokemon ability.")
|
||||
.Description($"Searches for a pokemon ability. | `{Prefix}pokeab \"water gun\"`")
|
||||
.Parameter("abil", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -122,7 +122,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "hitbox")
|
||||
.Alias(Module.Prefix + "hb")
|
||||
.Description("Notifies this channel when a certain user starts streaming." +
|
||||
" | ~hitbox SomeStreamer")
|
||||
$" | `{Prefix}hitbox SomeStreamer`")
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(TrackStream(StreamNotificationConfig.StreamType.Hitbox));
|
||||
@ -130,7 +130,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "twitch")
|
||||
.Alias(Module.Prefix + "tw")
|
||||
.Description("Notifies this channel when a certain user starts streaming." +
|
||||
" | ~twitch SomeStreamer")
|
||||
$" | `{Prefix}twitch SomeStreamer`")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(TrackStream(StreamNotificationConfig.StreamType.Twitch));
|
||||
@ -138,7 +138,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "beam")
|
||||
.Alias(Module.Prefix + "bm")
|
||||
.Description("Notifies this channel when a certain user starts streaming." +
|
||||
" | ~beam SomeStreamer")
|
||||
$" | `{Prefix}beam SomeStreamer`")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(TrackStream(StreamNotificationConfig.StreamType.Beam));
|
||||
@ -146,7 +146,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "checkhitbox")
|
||||
.Alias(Module.Prefix + "chhb")
|
||||
.Description("Checks if a certain user is streaming on the hitbox platform." +
|
||||
" | ~chhb SomeStreamer")
|
||||
$" | `{Prefix}chhb SomeStreamer`")
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
@ -175,7 +175,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "checktwitch")
|
||||
.Alias(Module.Prefix + "chtw")
|
||||
.Description("Checks if a certain user is streaming on the twitch platform." +
|
||||
" | ~chtw SomeStreamer")
|
||||
$" | `{Prefix}chtw SomeStreamer`")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -204,7 +204,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "checkbeam")
|
||||
.Alias(Module.Prefix + "chbm")
|
||||
.Description("Checks if a certain user is streaming on the beam platform." +
|
||||
" | ~chbm SomeStreamer")
|
||||
$" | `{Prefix}chbm SomeStreamer`")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -233,7 +233,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "removestream")
|
||||
.Alias(Module.Prefix + "rms")
|
||||
.Description("Removes notifications of a certain streamer on this channel." +
|
||||
" | ~rms SomeGuy")
|
||||
$" | `{Prefix}rms SomeGuy`")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -261,7 +261,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "liststreams")
|
||||
.Alias(Module.Prefix + "ls")
|
||||
.Description("Lists all streams you are following on this server." +
|
||||
" | ~ls")
|
||||
$" | `{Prefix}ls`")
|
||||
.Do(async e =>
|
||||
{
|
||||
|
||||
|
@ -22,7 +22,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
{
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "wowjoke")
|
||||
.Description("Get one of Kwoth's penultimate WoW jokes.")
|
||||
.Description($"Get one of Kwoth's penultimate WoW jokes. | `{Prefix}wowjoke`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!jokes.Any())
|
||||
|
@ -86,7 +86,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
cgb.CreateCommand(Prefix + "ani")
|
||||
.Alias(Prefix + "anime", Prefix + "aq")
|
||||
.Parameter("query", ParameterType.Unparsed)
|
||||
.Description("Queries anilist for an anime and shows the first result.")
|
||||
.Description($"Queries anilist for an anime and shows the first result. | `{Prefix}aq aquerion evol`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!(await SearchHelper.ValidateQuery(e.Channel, e.GetArg("query")).ConfigureAwait(false))) return;
|
||||
@ -341,7 +341,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "quote")
|
||||
.Description("Shows a random quote.")
|
||||
.Description($"Shows a random quote. | `{Prefix}quote`")
|
||||
.Do(async e =>
|
||||
{
|
||||
var quote = NadekoBot.Config.Quotes[rng.Next(0, NadekoBot.Config.Quotes.Count)].ToString();
|
||||
@ -349,7 +349,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "catfact")
|
||||
.Description("Shows a random catfact from <http://catfacts-api.appspot.com/api/facts>")
|
||||
.Description($"Shows a random catfact from <http://catfacts-api.appspot.com/api/facts> | `{Prefix}catfact`")
|
||||
.Do(async e =>
|
||||
{
|
||||
var response = await SearchHelper.GetResponseStringAsync("http://catfacts-api.appspot.com/api/facts").ConfigureAwait(false);
|
||||
@ -360,7 +360,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
|
||||
cgb.CreateCommand(Prefix + "yomama")
|
||||
.Alias(Prefix + "ym")
|
||||
.Description("Shows a random joke from <http://api.yomomma.info/>")
|
||||
.Description($"Shows a random joke from <http://api.yomomma.info/> | `{Prefix}ym`")
|
||||
.Do(async e =>
|
||||
{
|
||||
var response = await SearchHelper.GetResponseStringAsync("http://api.yomomma.info/").ConfigureAwait(false);
|
||||
@ -369,7 +369,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
|
||||
cgb.CreateCommand(Prefix + "randjoke")
|
||||
.Alias(Prefix + "rj")
|
||||
.Description("Shows a random joke from <http://tambal.azurewebsites.net/joke/random>")
|
||||
.Description($"Shows a random joke from <http://tambal.azurewebsites.net/joke/random> | `{Prefix}rj`")
|
||||
.Do(async e =>
|
||||
{
|
||||
var response = await SearchHelper.GetResponseStringAsync("http://tambal.azurewebsites.net/joke/random").ConfigureAwait(false);
|
||||
@ -378,7 +378,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
|
||||
cgb.CreateCommand(Prefix + "chucknorris")
|
||||
.Alias(Prefix + "cn")
|
||||
.Description("Shows a random chucknorris joke from <http://tambal.azurewebsites.net/joke/random>")
|
||||
.Description($"Shows a random chucknorris joke from <http://tambal.azurewebsites.net/joke/random> | `{Prefix}cn`")
|
||||
.Do(async e =>
|
||||
{
|
||||
var response = await SearchHelper.GetResponseStringAsync("http://api.icndb.com/jokes/random/").ConfigureAwait(false);
|
||||
@ -387,7 +387,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
|
||||
cgb.CreateCommand(Prefix + "magicitem")
|
||||
.Alias(Prefix + "mi")
|
||||
.Description("Shows a random magicitem from <https://1d4chan.org/wiki/List_of_/tg/%27s_magic_items>")
|
||||
.Description($"Shows a random magicitem from <https://1d4chan.org/wiki/List_of_/tg/%27s_magic_items> | `{Prefix}mi`")
|
||||
.Do(async e =>
|
||||
{
|
||||
var magicItems = JsonConvert.DeserializeObject<List<MagicItem>>(File.ReadAllText("data/magicitems.json"));
|
||||
@ -397,7 +397,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "revav")
|
||||
.Description($"Returns a google reverse image search for someone's avatar. | `{Prefix}revav \"@SomeGuy\"")
|
||||
.Description($"Returns a google reverse image search for someone's avatar. | `{Prefix}revav \"@SomeGuy\"`")
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ namespace NadekoBot.Modules.Translator
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "translangs")
|
||||
.Description("List the valid languages for translation.")
|
||||
.Description($"List the valid languages for translation. | `{Prefix}translangs` or `{Prefix}translangs language`")
|
||||
.Parameter("search", ParameterType.Optional)
|
||||
.Do(ListLanguagesFunc());
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ namespace NadekoBot.Modules.Trello
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "unbind")
|
||||
.Description("Unbinds a bot from the channel and board.")
|
||||
.Description($"Unbinds a bot from the channel and board. | `{Prefix}unbind`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!NadekoBot.IsOwner(e.User.Id)) return;
|
||||
@ -106,7 +106,7 @@ namespace NadekoBot.Modules.Trello
|
||||
|
||||
cgb.CreateCommand(Prefix + "lists")
|
||||
.Alias(Prefix + "list")
|
||||
.Description("Lists all lists yo ;)")
|
||||
.Description($"Lists all lists yo ;) | {Prefix}list")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!NadekoBot.IsOwner(e.User.Id)) return;
|
||||
|
@ -18,7 +18,7 @@ namespace NadekoBot.Modules.Utility.Commands
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "serverinfo")
|
||||
.Alias(Module.Prefix + "sinfo")
|
||||
.Description($"Shows info about the server the bot is on. If no channel is supplied, it defaults to current one. |{Module.Prefix}sinfo Some Server")
|
||||
.Description($"Shows info about the server the bot is on. If no channel is supplied, it defaults to current one. |`{Module.Prefix}sinfo Some Server`")
|
||||
.Parameter("server", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -49,7 +49,7 @@ namespace NadekoBot.Modules.Utility.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "channelinfo")
|
||||
.Alias(Module.Prefix + "cinfo")
|
||||
.Description($"Shows info about the channel. If no channel is supplied, it defaults to current one. |{Module.Prefix}cinfo #some-channel")
|
||||
.Description($"Shows info about the channel. If no channel is supplied, it defaults to current one. |`{Module.Prefix}cinfo #some-channel`")
|
||||
.Parameter("channel", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -71,7 +71,7 @@ namespace NadekoBot.Modules.Utility.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "userinfo")
|
||||
.Alias(Module.Prefix + "uinfo")
|
||||
.Description($"Shows info about the user. If no user is supplied, it defaults a user running the command. |{Module.Prefix}uinfo @SomeUser")
|
||||
.Description($"Shows info about the user. If no user is supplied, it defaults a user running the command. |`{Module.Prefix}uinfo @SomeUser`")
|
||||
.Parameter("user", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Utility.Commands
|
||||
.Description("Sends a message to you or a channel after certain amount of time. " +
|
||||
"First argument is me/here/'channelname'. Second argument is time in a descending order (mo>w>d>h>m) example: 1w5d3h10m. " +
|
||||
"Third argument is a (multiword)message. " +
|
||||
" | `.remind me 1d5h Do something` or `.remind #general Start now!`")
|
||||
$" | `{Prefix}remind me 1d5h Do something` or `{Prefix}remind #general Start now!`")
|
||||
.Parameter("meorchannel", ParameterType.Required)
|
||||
.Parameter("time", ParameterType.Required)
|
||||
.Parameter("message", ParameterType.Unparsed)
|
||||
@ -171,7 +171,7 @@ namespace NadekoBot.Modules.Utility.Commands
|
||||
UserId = (long)e.User.Id,
|
||||
ServerId = (long)e.Server.Id
|
||||
};
|
||||
DbHandler.Instance.InsertData(rem);
|
||||
DbHandler.Instance.Connection.Insert(rem);
|
||||
|
||||
reminders.Add(StartNewReminder(rem));
|
||||
|
||||
@ -180,7 +180,7 @@ namespace NadekoBot.Modules.Utility.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "remindmsg")
|
||||
.Description("Sets message for when the remind is triggered. " +
|
||||
" Available placeholders are %user% - user who ran the command, %message% -" +
|
||||
" Message specified in the remind, %target% - target channel of the remind. **Bot Owner Only!**")
|
||||
$" Message specified in the remind, %target% - target channel of the remind. **Bot Owner Only!** | `{Prefix}remindmsg do something else`")
|
||||
.Parameter("msg", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
|
@ -87,7 +87,7 @@ namespace NadekoBot.Modules.Utility
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "checkmyperms")
|
||||
.Description("Checks your userspecific permissions on this channel.")
|
||||
.Description($"Checks your userspecific permissions on this channel. | `{Prefix}checkmyperms`")
|
||||
.Do(async e =>
|
||||
{
|
||||
var output = "```\n";
|
||||
@ -100,21 +100,21 @@ namespace NadekoBot.Modules.Utility
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "stats")
|
||||
.Description("Shows some basic stats for Nadeko.")
|
||||
.Description($"Shows some basic stats for Nadeko. | `{Prefix}stats`")
|
||||
.Do(async e =>
|
||||
{
|
||||
await e.Channel.SendMessage(await NadekoStats.Instance.GetStats()).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "dysyd")
|
||||
.Description("Shows some basic stats for Nadeko.")
|
||||
.Description($"Shows some basic stats for Nadeko. | `{Prefix}dysyd`")
|
||||
.Do(async e =>
|
||||
{
|
||||
await e.Channel.SendMessage((await NadekoStats.Instance.GetStats()).Matrix().TrimTo(1990)).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "userid").Alias(Prefix + "uid")
|
||||
.Description($"Shows user ID. | `{Prefix}uid` or `{Prefix}uid \"@SomeGuy\"")
|
||||
.Description($"Shows user ID. | `{Prefix}uid` or `{Prefix}uid \"@SomeGuy\"`")
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -117,7 +117,7 @@ namespace NadekoBot
|
||||
Client = new DiscordClient(new DiscordConfigBuilder()
|
||||
{
|
||||
MessageCacheSize = 10,
|
||||
ConnectionTimeout = 120000,
|
||||
ConnectionTimeout = 180000,
|
||||
LogLevel = LogSeverity.Warning,
|
||||
LogHandler = (s, e) =>
|
||||
Console.WriteLine($"Severity: {e.Severity}" +
|
||||
@ -197,7 +197,7 @@ namespace NadekoBot
|
||||
return;
|
||||
}
|
||||
#if NADEKO_RELEASE
|
||||
await Task.Delay(100000).ConfigureAwait(false);
|
||||
await Task.Delay(120000).ConfigureAwait(false);
|
||||
#else
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
#endif
|
||||
|
@ -161,8 +161,23 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>lib\ScaredFingers.UnitsConversion.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SQLite-net, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\sqlite-net-pcl.1.1.2\lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10\SQLite-net.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="SQLitePCL.batteries, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SQLitePCL.bundle_green.0.9.2\lib\net45\SQLitePCL.batteries.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="SQLitePCL.raw, Version=0.9.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SQLitePCL.raw.0.9.2\lib\net45\SQLitePCL.raw.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="SQLitePCLPlugin_esqlite3, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SQLitePCL.plugin.sqlite3.net45.0.9.2\lib\net45\SQLitePCLPlugin_esqlite3.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
@ -202,6 +217,7 @@
|
||||
<Compile Include="Modules\Searches\Commands\OsuCommands.cs" />
|
||||
<Compile Include="Modules\Searches\Commands\PokemonSearchCommands.cs" />
|
||||
<Compile Include="Modules\Utility\UtilityModule.cs" />
|
||||
<Compile Include="_Models\DataModels\TestDataModel.cs" />
|
||||
<Compile Include="_Models\DataModels\Incident.cs" />
|
||||
<Compile Include="_Models\JSONModels\AnimeResult.cs" />
|
||||
<Compile Include="_Models\JSONModels\Configuration.cs" />
|
||||
@ -215,6 +231,7 @@
|
||||
<Compile Include="Modules\Music\Classes\MusicControls.cs" />
|
||||
<Compile Include="Modules\Music\Classes\PoopyBuffer.cs" />
|
||||
<Compile Include="Modules\Music\Classes\Song.cs" />
|
||||
<Compile Include="Modules\Music\Classes\SongBuffer.cs" />
|
||||
<Compile Include="Modules\Music\Classes\SoundCloud.cs" />
|
||||
<Compile Include="Modules\Permissions\Classes\PermissionChecker.cs" />
|
||||
<Compile Include="Modules\Permissions\Classes\PermissionHelper.cs" />
|
||||
@ -264,7 +281,6 @@
|
||||
<Compile Include="Modules\Gambling\DrawCommand.cs" />
|
||||
<Compile Include="Modules\Gambling\FlipCoinCommand.cs" />
|
||||
<Compile Include="Modules\Help\Commands\HelpCommand.cs" />
|
||||
<Compile Include="Modules\Administration\Commands\VoiceNotificationCommand.cs" />
|
||||
<Compile Include="Modules\Administration\Commands\VoicePlusTextCommand.cs" />
|
||||
<Compile Include="Modules\Administration\AdministrationModule.cs" />
|
||||
<Compile Include="Modules\Conversations\Conversations.cs" />
|
||||
@ -296,8 +312,6 @@
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Classes\NadekoStats.cs" />
|
||||
<Compile Include="SQLite.cs" />
|
||||
<Compile Include="SQLiteAsync.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
@ -550,6 +564,13 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\SQLitePCL.native.sqlite3.v110_xp.0.9.2\build\SQLitePCL.native.sqlite3.v110_xp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\SQLitePCL.native.sqlite3.v110_xp.0.9.2\build\SQLitePCL.native.sqlite3.v110_xp.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\SQLitePCL.native.sqlite3.v110_xp.0.9.2\build\SQLitePCL.native.sqlite3.v110_xp.targets" Condition="Exists('..\packages\SQLitePCL.native.sqlite3.v110_xp.0.9.2\build\SQLitePCL.native.sqlite3.v110_xp.targets')" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
3278
NadekoBot/SQLite.cs
3278
NadekoBot/SQLite.cs
File diff suppressed because it is too large
Load Diff
@ -1,503 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2012 Krueger Systems, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
public partial class SQLiteAsyncConnection
|
||||
{
|
||||
SQLiteConnectionString _connectionString;
|
||||
SQLiteOpenFlags _openFlags;
|
||||
|
||||
public SQLiteAsyncConnection(string databasePath, bool storeDateTimeAsTicks = false)
|
||||
: this(databasePath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create, storeDateTimeAsTicks)
|
||||
{
|
||||
}
|
||||
|
||||
public SQLiteAsyncConnection(string databasePath, SQLiteOpenFlags openFlags, bool storeDateTimeAsTicks = false)
|
||||
{
|
||||
_openFlags = openFlags;
|
||||
_connectionString = new SQLiteConnectionString(databasePath, storeDateTimeAsTicks);
|
||||
}
|
||||
|
||||
SQLiteConnectionWithLock GetConnection ()
|
||||
{
|
||||
return SQLiteConnectionPool.Shared.GetConnection (_connectionString, _openFlags);
|
||||
}
|
||||
|
||||
public Task<CreateTablesResult> CreateTableAsync<T> ()
|
||||
where T : new ()
|
||||
{
|
||||
return CreateTablesAsync (typeof (T));
|
||||
}
|
||||
|
||||
public Task<CreateTablesResult> CreateTablesAsync<T, T2> ()
|
||||
where T : new ()
|
||||
where T2 : new ()
|
||||
{
|
||||
return CreateTablesAsync (typeof (T), typeof (T2));
|
||||
}
|
||||
|
||||
public Task<CreateTablesResult> CreateTablesAsync<T, T2, T3> ()
|
||||
where T : new ()
|
||||
where T2 : new ()
|
||||
where T3 : new ()
|
||||
{
|
||||
return CreateTablesAsync (typeof (T), typeof (T2), typeof (T3));
|
||||
}
|
||||
|
||||
public Task<CreateTablesResult> CreateTablesAsync<T, T2, T3, T4> ()
|
||||
where T : new ()
|
||||
where T2 : new ()
|
||||
where T3 : new ()
|
||||
where T4 : new ()
|
||||
{
|
||||
return CreateTablesAsync (typeof (T), typeof (T2), typeof (T3), typeof (T4));
|
||||
}
|
||||
|
||||
public Task<CreateTablesResult> CreateTablesAsync<T, T2, T3, T4, T5> ()
|
||||
where T : new ()
|
||||
where T2 : new ()
|
||||
where T3 : new ()
|
||||
where T4 : new ()
|
||||
where T5 : new ()
|
||||
{
|
||||
return CreateTablesAsync (typeof (T), typeof (T2), typeof (T3), typeof (T4), typeof (T5));
|
||||
}
|
||||
|
||||
public Task<CreateTablesResult> CreateTablesAsync (params Type[] types)
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
CreateTablesResult result = new CreateTablesResult ();
|
||||
var conn = GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
foreach (Type type in types) {
|
||||
int aResult = conn.CreateTable (type);
|
||||
result.Results[type] = aResult;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
public Task<int> DropTableAsync<T> ()
|
||||
where T : new ()
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
var conn = GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
return conn.DropTable<T> ();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<int> InsertAsync (object item)
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
var conn = GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
return conn.Insert (item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<int> UpdateAsync (object item)
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
var conn = GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
return conn.Update (item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<int> DeleteAsync (object item)
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
var conn = GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
return conn.Delete (item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<T> GetAsync<T>(object pk)
|
||||
where T : new()
|
||||
{
|
||||
return Task.Factory.StartNew(() =>
|
||||
{
|
||||
var conn = GetConnection();
|
||||
using (conn.Lock())
|
||||
{
|
||||
return conn.Get<T>(pk);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<T> FindAsync<T> (object pk)
|
||||
where T : new ()
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
var conn = GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
return conn.Find<T> (pk);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<T> GetAsync<T> (Expression<Func<T, bool>> predicate)
|
||||
where T : new()
|
||||
{
|
||||
return Task.Factory.StartNew(() =>
|
||||
{
|
||||
var conn = GetConnection();
|
||||
using (conn.Lock())
|
||||
{
|
||||
return conn.Get<T> (predicate);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<T> FindAsync<T> (Expression<Func<T, bool>> predicate)
|
||||
where T : new ()
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
var conn = GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
return conn.Find<T> (predicate);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<int> ExecuteAsync (string query, params object[] args)
|
||||
{
|
||||
return Task<int>.Factory.StartNew (() => {
|
||||
var conn = GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
return conn.Execute (query, args);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<int> InsertAllAsync (IEnumerable items)
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
var conn = GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
return conn.InsertAll (items);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<int> UpdateAllAsync (IEnumerable items)
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
var conn = GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
return conn.UpdateAll (items);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Obsolete("Will cause a deadlock if any call in action ends up in a different thread. Use RunInTransactionAsync(Action<SQLiteConnection>) instead.")]
|
||||
public Task RunInTransactionAsync (Action<SQLiteAsyncConnection> action)
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
var conn = this.GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
conn.BeginTransaction ();
|
||||
try {
|
||||
action (this);
|
||||
conn.Commit ();
|
||||
}
|
||||
catch (Exception) {
|
||||
conn.Rollback ();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task RunInTransactionAsync(Action<SQLiteConnection> action)
|
||||
{
|
||||
return Task.Factory.StartNew(() =>
|
||||
{
|
||||
var conn = this.GetConnection();
|
||||
using (conn.Lock())
|
||||
{
|
||||
conn.BeginTransaction();
|
||||
try
|
||||
{
|
||||
action(conn);
|
||||
conn.Commit();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
conn.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public AsyncTableQuery<T> Table<T> ()
|
||||
where T : new ()
|
||||
{
|
||||
//
|
||||
// This isn't async as the underlying connection doesn't go out to the database
|
||||
// until the query is performed. The Async methods are on the query iteself.
|
||||
//
|
||||
var conn = GetConnection ();
|
||||
return new AsyncTableQuery<T> (conn.Table<T> ());
|
||||
}
|
||||
|
||||
public Task<T> ExecuteScalarAsync<T> (string sql, params object[] args)
|
||||
{
|
||||
return Task<T>.Factory.StartNew (() => {
|
||||
var conn = GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
var command = conn.CreateCommand (sql, args);
|
||||
return command.ExecuteScalar<T> ();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<List<T>> QueryAsync<T> (string sql, params object[] args)
|
||||
where T : new ()
|
||||
{
|
||||
return Task<List<T>>.Factory.StartNew (() => {
|
||||
var conn = GetConnection ();
|
||||
using (conn.Lock ()) {
|
||||
return conn.Query<T> (sql, args);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Bind to AsyncConnection.GetConnection instead so that delayed
|
||||
// execution can still work after a Pool.Reset.
|
||||
//
|
||||
public class AsyncTableQuery<T>
|
||||
where T : new ()
|
||||
{
|
||||
TableQuery<T> _innerQuery;
|
||||
|
||||
public AsyncTableQuery (TableQuery<T> innerQuery)
|
||||
{
|
||||
_innerQuery = innerQuery;
|
||||
}
|
||||
|
||||
public AsyncTableQuery<T> Where (Expression<Func<T, bool>> predExpr)
|
||||
{
|
||||
return new AsyncTableQuery<T> (_innerQuery.Where (predExpr));
|
||||
}
|
||||
|
||||
public AsyncTableQuery<T> Skip (int n)
|
||||
{
|
||||
return new AsyncTableQuery<T> (_innerQuery.Skip (n));
|
||||
}
|
||||
|
||||
public AsyncTableQuery<T> Take (int n)
|
||||
{
|
||||
return new AsyncTableQuery<T> (_innerQuery.Take (n));
|
||||
}
|
||||
|
||||
public AsyncTableQuery<T> OrderBy<U> (Expression<Func<T, U>> orderExpr)
|
||||
{
|
||||
return new AsyncTableQuery<T> (_innerQuery.OrderBy<U> (orderExpr));
|
||||
}
|
||||
|
||||
public AsyncTableQuery<T> OrderByDescending<U> (Expression<Func<T, U>> orderExpr)
|
||||
{
|
||||
return new AsyncTableQuery<T> (_innerQuery.OrderByDescending<U> (orderExpr));
|
||||
}
|
||||
|
||||
public Task<List<T>> ToListAsync ()
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {
|
||||
return _innerQuery.ToList ();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<int> CountAsync ()
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {
|
||||
return _innerQuery.Count ();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<T> ElementAtAsync (int index)
|
||||
{
|
||||
return Task.Factory.StartNew (() => {
|
||||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {
|
||||
return _innerQuery.ElementAt (index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<T> FirstAsync ()
|
||||
{
|
||||
return Task<T>.Factory.StartNew(() => {
|
||||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {
|
||||
return _innerQuery.First ();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Task<T> FirstOrDefaultAsync ()
|
||||
{
|
||||
return Task<T>.Factory.StartNew(() => {
|
||||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {
|
||||
return _innerQuery.FirstOrDefault ();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class CreateTablesResult
|
||||
{
|
||||
public Dictionary<Type, int> Results { get; private set; }
|
||||
|
||||
internal CreateTablesResult ()
|
||||
{
|
||||
this.Results = new Dictionary<Type, int> ();
|
||||
}
|
||||
}
|
||||
|
||||
class SQLiteConnectionPool
|
||||
{
|
||||
class Entry
|
||||
{
|
||||
public SQLiteConnectionString ConnectionString { get; private set; }
|
||||
public SQLiteConnectionWithLock Connection { get; private set; }
|
||||
|
||||
public Entry (SQLiteConnectionString connectionString, SQLiteOpenFlags openFlags)
|
||||
{
|
||||
ConnectionString = connectionString;
|
||||
Connection = new SQLiteConnectionWithLock (connectionString, openFlags);
|
||||
}
|
||||
|
||||
public void OnApplicationSuspended ()
|
||||
{
|
||||
Connection.Dispose ();
|
||||
Connection = null;
|
||||
}
|
||||
}
|
||||
|
||||
readonly Dictionary<string, Entry> _entries = new Dictionary<string, Entry> ();
|
||||
readonly object _entriesLock = new object ();
|
||||
|
||||
static readonly SQLiteConnectionPool _shared = new SQLiteConnectionPool ();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the singleton instance of the connection tool.
|
||||
/// </summary>
|
||||
public static SQLiteConnectionPool Shared
|
||||
{
|
||||
get
|
||||
{
|
||||
return _shared;
|
||||
}
|
||||
}
|
||||
|
||||
public SQLiteConnectionWithLock GetConnection (SQLiteConnectionString connectionString, SQLiteOpenFlags openFlags)
|
||||
{
|
||||
lock (_entriesLock) {
|
||||
Entry entry;
|
||||
string key = connectionString.ConnectionString;
|
||||
|
||||
if (!_entries.TryGetValue (key, out entry)) {
|
||||
entry = new Entry (connectionString, openFlags);
|
||||
_entries[key] = entry;
|
||||
}
|
||||
|
||||
return entry.Connection;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes all connections managed by this pool.
|
||||
/// </summary>
|
||||
public void Reset ()
|
||||
{
|
||||
lock (_entriesLock) {
|
||||
foreach (var entry in _entries.Values) {
|
||||
entry.OnApplicationSuspended ();
|
||||
}
|
||||
_entries.Clear ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method when the application is suspended.
|
||||
/// </summary>
|
||||
/// <remarks>Behaviour here is to close any open connections.</remarks>
|
||||
public void ApplicationSuspended ()
|
||||
{
|
||||
Reset ();
|
||||
}
|
||||
}
|
||||
|
||||
class SQLiteConnectionWithLock : SQLiteConnection
|
||||
{
|
||||
readonly object _lockPoint = new object ();
|
||||
|
||||
public SQLiteConnectionWithLock (SQLiteConnectionString connectionString, SQLiteOpenFlags openFlags)
|
||||
: base (connectionString.DatabasePath, openFlags, connectionString.StoreDateTimeAsTicks)
|
||||
{
|
||||
}
|
||||
|
||||
public IDisposable Lock ()
|
||||
{
|
||||
return new LockWrapper (_lockPoint);
|
||||
}
|
||||
|
||||
private class LockWrapper : IDisposable
|
||||
{
|
||||
object _lockPoint;
|
||||
|
||||
public LockWrapper (object lockPoint)
|
||||
{
|
||||
_lockPoint = lockPoint;
|
||||
Monitor.Enter (_lockPoint);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Monitor.Exit (_lockPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
8
NadekoBot/_Models/DataModels/TestDataModel.cs
Normal file
8
NadekoBot/_Models/DataModels/TestDataModel.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace NadekoBot.DataModels
|
||||
{
|
||||
internal class TestDataModel : IDataModel
|
||||
{
|
||||
public long TestNumber { get; set; }
|
||||
public string TestString { get; set; }
|
||||
}
|
||||
}
|
Binary file not shown.
BIN
NadekoBot/bin/Debug/x64/esqlite3.dll
Normal file
BIN
NadekoBot/bin/Debug/x64/esqlite3.dll
Normal file
Binary file not shown.
BIN
NadekoBot/bin/Debug/x86/esqlite3.dll
Normal file
BIN
NadekoBot/bin/Debug/x86/esqlite3.dll
Normal file
Binary file not shown.
@ -10,7 +10,12 @@
|
||||
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net46" />
|
||||
<package id="RestSharp" version="105.2.3" targetFramework="net452" />
|
||||
<package id="sqlite-net" version="1.0.8" targetFramework="net452" />
|
||||
<package id="sqlite-net-pcl" version="1.1.2" targetFramework="net452" />
|
||||
<package id="SQLitePCL.bundle_green" version="0.9.2" targetFramework="net452" />
|
||||
<package id="SQLitePCL.native.sqlite3.v110_xp" version="0.9.2" targetFramework="net452" />
|
||||
<package id="SQLitePCL.plugin.sqlite3.net45" version="0.9.2" targetFramework="net452" />
|
||||
<package id="SQLitePCL.raw" version="0.9.2" targetFramework="net452" />
|
||||
<package id="System.Data.SQLite" version="1.0.102.0" targetFramework="net452" />
|
||||
<package id="taglib" version="2.1.0.0" targetFramework="net452" />
|
||||
<package id="VideoLibrary" version="1.3.3" targetFramework="net452" />
|
||||
</packages>
|
229
commandlist.md
229
commandlist.md
@ -1,62 +1,63 @@
|
||||
######For more information and how to setup your own NadekoBot, go to: **http://github.com/Kwoth/NadekoBot/**
|
||||
######You can donate on paypal: `nadekodiscordbot@gmail.com`
|
||||
######You can donate on patreon: `https://patreon.com/nadekobot`
|
||||
######or paypal: `nadekodiscordbot@gmail.com`
|
||||
|
||||
#NadekoBot List Of Commands
|
||||
Version: `NadekoBot v0.9.6051.26856`
|
||||
Version: `NadekoBot v0.9.6054.4837`
|
||||
### Help
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`-h`, `-help`, `@BotName help`, `@BotName h`, `~h` | Either shows a help for a single command, or PMs you help link if no arguments are specified. | '-h !m q' or just '-h'
|
||||
`-hgit` | Generates the commandlist.md file. **Bot Owner Only!**
|
||||
`-readme`, `-guide` | Sends a readme and a guide links to the channel.
|
||||
`-donate`, `~donate` | Instructions for helping the project!
|
||||
`-modules`, `.modules` | List all bot modules.
|
||||
`-commands`, `.commands` | List all of the bot's commands from a certain module.
|
||||
`-h`, `-help`, `@BotName help`, `@BotName h`, `~h` | Either shows a help for a single command, or PMs you help link if no arguments are specified. | `-h !m q` or just `-h`
|
||||
`-hgit` | Generates the commandlist.md file. **Bot Owner Only!** | `-hgit`
|
||||
`-readme`, `-guide` | Sends a readme and a guide links to the channel. | `-readme` or `-guide`
|
||||
`-donate`, `~donate` | Instructions for helping the project! | `{Prefix}donate` or `~donate`
|
||||
`-modules`, `.modules` | List all bot modules. | `{Prefix}modules` or `.modules`
|
||||
`-commands`, `.commands` | List all of the bot's commands from a certain module. | `{Prefix}commands` or `.commands`
|
||||
|
||||
### Administration
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`.grdel` | Toggles automatic deletion of greet and bye messages.
|
||||
`.greet` | Toggles anouncements on the current channel when someone joins the server.
|
||||
`.greetmsg` | Sets a new join announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current greet message. | .greetmsg Welcome to the server, %user%.
|
||||
`.bye` | Toggles anouncements on the current channel when someone leaves the server.
|
||||
`.byemsg` | Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message. | .byemsg %user% has left the server.
|
||||
`.byepm` | Toggles whether the good bye messages will be sent in a PM or in the text channel.
|
||||
`.greetpm` | Toggles whether the greet messages will be sent in a PM or in the text channel.
|
||||
`.spmom` | Toggles whether mentions of other offline users on your server will send a pm to them.
|
||||
`.logserver` | Toggles logging in this channel. Logs every message sent/deleted/edited on the server. **Bot Owner Only!**
|
||||
`.logignore` | Toggles whether the .logserver command ignores this channel. Useful if you have hidden admin channel and public log channel.
|
||||
`.userpresence` | Starts logging to this channel when someone from the server goes online/offline/idle.
|
||||
`.voicepresence` | Toggles logging to this channel whenever someone joins or leaves a voice channel you are in right now.
|
||||
`.repeatinvoke`, `.repinv` | Immediately shows the repeat message and restarts the timer.
|
||||
`.grdel` | Toggles automatic deletion of greet and bye messages. | `.grdel`
|
||||
`.greet` | Toggles anouncements on the current channel when someone joins the server. | `.greet`
|
||||
`.greetmsg` | Sets a new join announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current greet message. | `.greetmsg Welcome to the server, %user%.`
|
||||
`.bye` | Toggles anouncements on the current channel when someone leaves the server. | `.bye`
|
||||
`.byemsg` | Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message. | `.byemsg %user% has left the server.`
|
||||
`.byepm` | Toggles whether the good bye messages will be sent in a PM or in the text channel. | `.byepm`
|
||||
`.greetpm` | Toggles whether the greet messages will be sent in a PM or in the text channel. | `.greetpm`
|
||||
`.spmom` | Toggles whether mentions of other offline users on your server will send a pm to them. | `.spmom`
|
||||
`.logserver` | Toggles logging in this channel. Logs every message sent/deleted/edited on the server. **Bot Owner Only!** | `.logserver`
|
||||
`.logignore` | Toggles whether the .logserver command ignores this channel. Useful if you have hidden admin channel and public log channel. | `.logignore`
|
||||
`.userpresence` | Starts logging to this channel when someone from the server goes online/offline/idle. | `.userpresence`
|
||||
`.voicepresence` | Toggles logging to this channel whenever someone joins or leaves a voice channel you are in right now. | `{Prefix}voicerpresence`
|
||||
`.repeatinvoke`, `.repinv` | Immediately shows the repeat message and restarts the timer. | `{Prefix}repinv`
|
||||
`.repeat` | Repeat a message every X minutes. If no parameters are specified, repeat is disabled. Requires manage messages. | `.repeat 5 Hello there`
|
||||
`.rotateplaying`, `.ropl` | Toggles rotation of playing status of the dynamic strings you specified earlier.
|
||||
`.addplaying`, `.adpl` | Adds a specified string to the list of playing strings to rotate. Supported placeholders: %servers%, %users%, %playing%, %queued%, %trivia%
|
||||
`.listplaying`, `.lipl` | Lists all playing statuses with their corresponding number.
|
||||
`.removeplaying`, `.repl`, `.rmpl` | Removes a playing string on a given number.
|
||||
`.slowmode` | Toggles slow mode. When ON, users will be able to send only 1 message every 5 seconds.
|
||||
`.cleanv+t`, `.cv+t` | Deletes all text channels ending in `-voice` for which voicechannels are not found. **Use at your own risk.**
|
||||
`.voice+text`, `.v+t` | Creates a text channel for each voice channel only users in that voice channel can see.If you are server owner, keep in mind you will see them all the time regardless.
|
||||
`.scsc` | Starts an instance of cross server channel. You will get a token as a DMthat other people will use to tune in to the same instance
|
||||
`.jcsc` | Joins current channel to an instance of cross server channel using the token.
|
||||
`.lcsc` | Leaves Cross server channel instance from this channel
|
||||
`.rotateplaying`, `.ropl` | Toggles rotation of playing status of the dynamic strings you specified earlier. | `.ropl`
|
||||
`.addplaying`, `.adpl` | Adds a specified string to the list of playing strings to rotate. Supported placeholders: %servers%, %users%, %playing%, %queued%, %trivia% | `.adpl`
|
||||
`.listplaying`, `.lipl` | Lists all playing statuses with their corresponding number. | `.lipl`
|
||||
`.removeplaying`, `.repl`, `.rmpl` | Removes a playing string on a given number. | `.rmpl`
|
||||
`.slowmode` | Toggles slow mode. When ON, users will be able to send only 1 message every 5 seconds. | `.slowmode`
|
||||
`.cleanv+t`, `.cv+t` | Deletes all text channels ending in `-voice` for which voicechannels are not found. **Use at your own risk.** | `.cleanv+t`
|
||||
`.voice+text`, `.v+t` | Creates a text channel for each voice channel only users in that voice channel can see.If you are server owner, keep in mind you will see them all the time regardless. | `.voice+text`
|
||||
`.scsc` | Starts an instance of cross server channel. You will get a token as a DM that other people will use to tune in to the same instance. | `.scsc`
|
||||
`.jcsc` | Joins current channel to an instance of cross server channel using the token. | `.jcsc`
|
||||
`.lcsc` | Leaves Cross server channel instance from this channel. | `.lcsc`
|
||||
`.asar` | Adds a role, or list of roles separated by whitespace(use quotations for multiword roles) to the list of self-assignable roles. | .asar Gamer
|
||||
`.rsar` | Removes a specified role from the list of self-assignable roles.
|
||||
`.lsar` | Lists all self-assignable roles.
|
||||
`.togglexclsar`, `.tesar` | toggle whether the self-assigned roles should be exclusive
|
||||
`.rsar` | Removes a specified role from the list of self-assignable roles. | `.rsar`
|
||||
`.lsar` | Lists all self-assignable roles. | `.lsar`
|
||||
`.togglexclsar`, `.tesar` | toggle whether the self-assigned roles should be exclusive | `.tesar`
|
||||
`.iam` | Adds a role to you that you choose. Role must be on a list of self-assignable roles. | .iam Gamer
|
||||
`.iamnot`, `.iamn` | Removes a role to you that you choose. Role must be on a list of self-assignable roles. | .iamn Gamer
|
||||
`.addcustreact`, `.acr` | Add a custom reaction. Guide here: <https://github.com/Kwoth/NadekoBot/wiki/Custom-Reactions> **Bot Owner Only!** | .acr "hello" I love saying hello to %user%
|
||||
`.listcustreact`, `.lcr` | Lists custom reactions (paginated with 30 commands per page). Use 'all' instead of page number to get all custom reactions DM-ed to you. | .lcr 1
|
||||
`.showcustreact`, `.scr` | Shows all possible responses from a single custom reaction. | .scr %mention% bb
|
||||
`.addcustreact`, `.acr` | Add a custom reaction. Guide here: <https://github.com/Kwoth/NadekoBot/wiki/Custom-Reactions> **Bot Owner Only!** | `.acr "hello" I love saying hello to %user%`
|
||||
`.listcustreact`, `.lcr` | Lists custom reactions (paginated with 30 commands per page). Use 'all' instead of page number to get all custom reactions DM-ed to you. | `.lcr 1`
|
||||
`.showcustreact`, `.scr` | Shows all possible responses from a single custom reaction. | `.scr %mention% bb`
|
||||
`.editcustreact`, `.ecr` | Edits a custom reaction, arguments are custom reactions name, index to change, and a (multiword) message **Bot Owner Only** | `.ecr "%mention% disguise" 2 Test 123`
|
||||
`.delcustreact`, `.dcr` | Deletes a custom reaction with given name (and index)
|
||||
`.delcustreact`, `.dcr` | Deletes a custom reaction with given name (and index). | `.dcr index`
|
||||
`.autoassignrole`, `.aar` | Automaticaly assigns a specified role to every user who joins the server. Type `.aar` to disable, `.aar Role Name` to enable
|
||||
`.leave` | Makes Nadeko leave the server. Either name or id required. | `.leave 123123123331`
|
||||
`.listincidents`, `.lin` | List all UNREAD incidents and flags them as read.
|
||||
`.listallincidents`, `.lain` | Sends you a file containing all incidents and flags them as read.
|
||||
`.delmsgoncmd` | Toggles the automatic deletion of user's successful command message to prevent chat flood. Server Manager Only.
|
||||
`.restart` | Restarts the bot. Might not work. **Bot Owner Only**
|
||||
`.listincidents`, `.lin` | List all UNREAD incidents and flags them as read. | `.lin`
|
||||
`.listallincidents`, `.lain` | Sends you a file containing all incidents and flags them as read. | `.lain`
|
||||
`.delmsgoncmd` | Toggles the automatic deletion of user's successful command message to prevent chat flood. Server Manager Only. | `.delmsgoncmd`
|
||||
`.restart` | Restarts the bot. Might not work. **Bot Owner Only** | `.restart`
|
||||
`.setrole`, `.sr` | Sets a role for a given user. | `.sr @User Guest`
|
||||
`.removerole`, `.rr` | Removes a role from a given user. | `.rr @User Admin`
|
||||
`.renamerole`, `.renr` | Renames a role. Role you are renaming must be lower than bot's highest role. | `.renr "First role" SecondRole`
|
||||
@ -76,15 +77,15 @@ Command and aliases | Description | Usage
|
||||
`.creatxtchanl`, `.ctch` | Creates a new text channel with a given name. | `.ctch TextChannelName`
|
||||
`.settopic`, `.st` | Sets a topic on the current channel. | `.st My new topic`
|
||||
`.setchanlname`, `.schn` | Changed the name of the current channel.| `.schn NewName`
|
||||
`.heap` | Shows allocated memory - **Bot Owner Only!**
|
||||
`.heap` | Shows allocated memory - **Bot Owner Only!** | `.heap`
|
||||
`.prune`, `.clr` | `.prune` removes all nadeko's messages in the last 100 messages.`.prune X` removes last X messages from the channel (up to 100)`.prune @Someone` removes all Someone's messages in the last 100 messages.`.prune @Someone X` removes last X 'Someone's' messages in the channel. | `.prune` or `.prune 5` or `.prune @Someone` or `.prune @Someone X`
|
||||
`.die` | Shuts the bot down and notifies users about the restart. **Bot Owner Only!**
|
||||
`.die` | Shuts the bot down and notifies users about the restart. **Bot Owner Only!** | `.die`
|
||||
`.setname`, `.newnm` | Give the bot a new name. **Bot Owner Only!** | .newnm BotName
|
||||
`.newavatar`, `.setavatar` | Sets a new avatar image for the NadekoBot. Argument is a direct link to an image. **Bot Owner Only!** | `.setavatar https://i.ytimg.com/vi/WDudkR1eTMM/maxresdefault.jpg`
|
||||
`.setgame` | Sets the bots game. **Bot Owner Only!** | `.setgame Playing with kwoth`
|
||||
`.send` | Send a message to someone on a different server through the bot. **Bot Owner Only!** | `.send serverid|u:user_id Send this to a user!` or `.send serverid|c:channel_id Send this to a channel!`
|
||||
`.mentionrole`, `.menro` | Mentions every person from the provided role or roles (separated by a ',') on this server. Requires you to have mention everyone permission. | `.menro RoleName`
|
||||
`.unstuck` | Clears the message queue. **Bot Owner Only!**
|
||||
`.unstuck` | Clears the message queue. **Bot Owner Only!** | `.unstuck`
|
||||
`.donators` | List of lovely people who donated to keep this project alive.
|
||||
`.donadd` | Add a donator to the database. | `.donadd Donate Amount`
|
||||
`.announce` | Sends a message to all servers' general channel bot is connected to.**Bot Owner Only!** | `.announce Useless spam`
|
||||
@ -94,16 +95,16 @@ Command and aliases | Description | Usage
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`.remind` | Sends a message to you or a channel after certain amount of time. First argument is me/here/'channelname'. Second argument is time in a descending order (mo>w>d>h>m) example: 1w5d3h10m. Third argument is a (multiword)message. | `.remind me 1d5h Do something` or `.remind #general Start now!`
|
||||
`.remindmsg` | Sets message for when the remind is triggered. Available placeholders are %user% - user who ran the command, %message% - Message specified in the remind, %target% - target channel of the remind. **Bot Owner Only!**
|
||||
`.serverinfo`, `.sinfo` | Shows info about the server the bot is on. If no channel is supplied, it defaults to current one. | .sinfo Some Server
|
||||
`.channelinfo`, `.cinfo` | Shows info about the channel. If no channel is supplied, it defaults to current one. | .cinfo #some-channel
|
||||
`.userinfo`, `.uinfo` | Shows info about the user. If no user is supplied, it defaults a user running the command. | .uinfo @SomeUser
|
||||
`.remindmsg` | Sets message for when the remind is triggered. Available placeholders are %user% - user who ran the command, %message% - Message specified in the remind, %target% - target channel of the remind. **Bot Owner Only!** | `.remindmsg do something else`
|
||||
`.serverinfo`, `.sinfo` | Shows info about the server the bot is on. If no channel is supplied, it defaults to current one. | `.sinfo Some Server`
|
||||
`.channelinfo`, `.cinfo` | Shows info about the channel. If no channel is supplied, it defaults to current one. | `.cinfo #some-channel`
|
||||
`.userinfo`, `.uinfo` | Shows info about the user. If no user is supplied, it defaults a user running the command. | `.uinfo @SomeUser`
|
||||
`.whoplays` | Shows a list of users who are playing the specified game. | `.whoplays Overwatch`
|
||||
`.inrole` | Lists every person from the provided role or roles (separated by a ',') on this server. If the list is too long for 1 message, you must have Manage Messages permission. | `.inrole Role`
|
||||
`.checkmyperms` | Checks your userspecific permissions on this channel.
|
||||
`.stats` | Shows some basic stats for Nadeko.
|
||||
`.dysyd` | Shows some basic stats for Nadeko.
|
||||
`.userid`, `.uid` | Shows user ID. | `.uid` or `.uid "@SomeGuy"
|
||||
`.checkmyperms` | Checks your userspecific permissions on this channel. | `.checkmyperms`
|
||||
`.stats` | Shows some basic stats for Nadeko. | `.stats`
|
||||
`.dysyd` | Shows some basic stats for Nadeko. | `.dysyd`
|
||||
`.userid`, `.uid` | Shows user ID. | `.uid` or `.uid "@SomeGuy"`
|
||||
`.channelid`, `.cid` | Shows current channel ID. | `.cid`
|
||||
`.serverid`, `.sid` | Shows current server ID. | `.sid`
|
||||
`.roles` | List all roles on this server or a single user if specified.
|
||||
@ -119,12 +120,12 @@ Command and aliases | Description | Usage
|
||||
`;rmvfilterword`, `;rfw` | Removes the word from the list of filtered words | ;rw poop
|
||||
`;lstfilterwords`, `;lfw` | Shows a list of filtered words | ;lfw
|
||||
`;srvrfilterwords`, `;sfw` | Enables or disables automatic deleting of messages containing forbidden words on the server. | ;sfw disable
|
||||
`;permrole`, `;pr` | Sets a role which can change permissions. Or supply no parameters to find out the current one. Default one is 'Nadeko'.
|
||||
`;permrole`, `;pr` | Sets a role which can change permissions. Or supply no parameters to find out the current one. Default one is 'Nadeko'. | `;pr role`
|
||||
`;rolepermscopy`, `;rpc` | Copies BOT PERMISSIONS (not discord permissions) from one role to another. | `;rpc Some Role ~ Some other role`
|
||||
`;chnlpermscopy`, `;cpc` | Copies BOT PERMISSIONS (not discord permissions) from one channel to another. | `;cpc Some Channel ~ Some other channel`
|
||||
`;usrpermscopy`, `;upc` | Copies BOT PERMISSIONS (not discord permissions) from one role to another. | `;upc @SomeUser ~ @SomeOtherUser`
|
||||
`;verbose`, `;v` | Sets whether to show when a command/module is blocked. | `;verbose true`
|
||||
`;srvrperms`, `;sp` | Shows banned permissions for this server.
|
||||
`;srvrperms`, `;sp` | Shows banned permissions for this server. | `;sp`
|
||||
`;roleperms`, `;rp` | Shows banned permissions for a certain role. No argument means for everyone. | `;rp AwesomeRole`
|
||||
`;chnlperms`, `;cp` | Shows banned permissions for a certain channel. No argument means for this channel. | `;cp #dev`
|
||||
`;userperms`, `;up` | Shows banned permissions for a certain user. No argument means for yourself. | `;up Kwoth`
|
||||
@ -157,48 +158,48 @@ Command and aliases | Description | Usage
|
||||
`...` | Shows a random quote with a specified name. | `... abc`
|
||||
`..qdel`, `..quotedelete` | Deletes all quotes with the specified keyword. You have to either be bot owner or the creator of the quote to delete it. | `..qdel abc`
|
||||
`@BotName rip` | Shows a grave image of someone with a start year | @NadekoBot rip @Someone 2000
|
||||
`@BotName die` | Works only for the owner. Shuts the bot down.
|
||||
`@BotName do you love me` | Replies with positive answer only to the bot owner.
|
||||
`@BotName how are you`, `@BotName how are you?` | Replies positive only if bot owner is online.
|
||||
`@BotName fire` | Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire. | @NadekoBot fire [x]
|
||||
`@BotName dump` | Dumps all of the invites it can to dump.txt.** Owner Only.**
|
||||
`@BotName ab` | Try to get 'abalabahaha'
|
||||
`@BotName die` | Works only for the owner. Shuts the bot down. | `@NadekoBot die`
|
||||
`@BotName do you love me` | Replies with positive answer only to the bot owner. | `@NadekoBot do you love me`
|
||||
`@BotName how are you`, `@BotName how are you?` | Replies positive only if bot owner is online. | `@NadekoBot how are you`
|
||||
`@BotName fire` | Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire. | `@NadekoBot fire [x]`
|
||||
`@BotName dump` | Dumps all of the invites it can to dump.txt.** Owner Only.** | `@NadekoBot dump`
|
||||
`@BotName ab` | Try to get 'abalabahaha'| `@NadekoBot ab`
|
||||
|
||||
### Gambling
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`$draw` | Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck. | $draw [x]
|
||||
`$shuffle`, `$sh` | Reshuffles all cards back into the deck.
|
||||
`$draw` | Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck. | `$draw [x]`
|
||||
`$shuffle`, `$sh` | Reshuffles all cards back into the deck.|`$shuffle`
|
||||
`$flip` | Flips coin(s) - heads or tails, and shows an image. | `$flip` or `$flip 3`
|
||||
`$betflip`, `$bf` | Bet to guess will the result be heads or tails. Guessing award you double flowers you've bet. | `$bf 5 heads` or `$bf 3 t`
|
||||
`$roll` | Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice. If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | $roll or $roll 7 or $roll 3d5
|
||||
`$rolluo` | Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice (unordered). If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | $roll or $roll 7 or $roll 3d5
|
||||
`$roll` | Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice. If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | `$roll` or `$roll 7` or `$roll 3d5`
|
||||
`$rolluo` | Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice (unordered). If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | `$roll` or `$roll` 7 or `$roll 3d5`
|
||||
`$nroll` | Rolls in a given range. | `$nroll 5` (rolls 0-5) or `$nroll 5-15`
|
||||
`$race` | Starts a new animal race.
|
||||
`$race` | Starts a new animal race. | `$race`
|
||||
`$joinrace`, `$jr` | Joins a new race. You can specify an amount of flowers for betting (optional). You will get YourBet*(participants-1) back if you win. | `$jr` or `$jr 5`
|
||||
`$raffle` | Prints a name and ID of a random user from the online list from the (optional) role. | `$raffle` or `$raffle RoleName
|
||||
`$raffle` | Prints a name and ID of a random user from the online list from the (optional) role. | `$raffle` or `$raffle RoleName`
|
||||
`$$$` | Check how much NadekoFlowers a person has. (Defaults to yourself) | `$$$` or `$$$ @Someone`
|
||||
`$give` | Give someone a certain amount of NadekoFlowers
|
||||
`$give` | Give someone a certain amount of NadekoFlowers|`$give 1 "@SomeGuy"`
|
||||
`$award` | Gives someone a certain amount of flowers. **Bot Owner Only!** | `$award 100 @person`
|
||||
`$take` | Takes a certain amount of flowers from someone. **Bot Owner Only!** | `$take 1 "@someguy"`
|
||||
`$betroll`, `$br` | Bets a certain amount of NadekoFlowers and rolls a dice. Rolling over 66 yields x2 flowers, over 90 - x3 and 100 x10. | $br 5
|
||||
`$leaderboard`, `$lb` |
|
||||
`$betroll`, `$br` | Bets a certain amount of NadekoFlowers and rolls a dice. Rolling over 66 yields x2 flowers, over 90 - x3 and 100 x10. | `$br 5`
|
||||
`$leaderboard`, `$lb` | Displays bot currency leaderboard | $lb
|
||||
|
||||
### Games
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`>t` | Starts a game of trivia. You can add nohint to prevent hints.First player to get to 10 points wins by default. You can specify a different number. 30 seconds per question. | `>t nohint` or `>t 5 nohint`
|
||||
`>tl` | Shows a current trivia leaderboard.
|
||||
`>tq` | Quits current trivia after current question.
|
||||
`>typestart` | Starts a typing contest.
|
||||
`>typestop` | Stops a typing contest on the current channel.
|
||||
`>typeadd` | Adds a new article to the typing contest. Owner only.
|
||||
`>poll` | Creates a poll, only person who has manage server permission can do it. | >poll Question?;Answer1;Answ 2;A_3
|
||||
`>pollend` | Stops active poll on this server and prints the results in this channel.
|
||||
`>pick` | Picks a flower planted in this channel.
|
||||
`>plant` | Spend a flower to plant it in this channel. (If bot is restarted or crashes, flower will be lost)
|
||||
`>tl` | Shows a current trivia leaderboard. | `>tl`
|
||||
`>tq` | Quits current trivia after current question. | `>tq`
|
||||
`>typestart` | Starts a typing contest. | `>typestart`
|
||||
`>typestop` | Stops a typing contest on the current channel. | `>typestop`
|
||||
`>typeadd` | Adds a new article to the typing contest. Owner only. | `>typeadd wordswords`
|
||||
`>poll` | Creates a poll, only person who has manage server permission can do it. | `>poll Question?;Answer1;Answ 2;A_3`
|
||||
`>pollend` | Stops active poll on this server and prints the results in this channel. | `>pollend`
|
||||
`>pick` | Picks a flower planted in this channel. | `>pick`
|
||||
`>plant` | Spend a flower to plant it in this channel. (If bot is restarted or crashes, flower will be lost) | `>plant`
|
||||
`>gencurrency`, `>gc` | Toggles currency generation on this channel. Every posted message will have 2% chance to spawn a NadekoFlower. Optional parameter cooldown time in minutes, 5 minutes by default. Requires Manage Messages permission. | `>gc` or `>gc 60`
|
||||
`>leet` | Converts a text to leetspeak with 6 (1-6) severity levels | >leet 3 Hello
|
||||
`>leet` | Converts a text to leetspeak with 6 (1-6) severity levels | `>leet 3 Hello`
|
||||
`>choose` | Chooses a thing from a list of things | `>choose Get up;Sleep;Sleep more`
|
||||
`>8ball` | Ask the 8ball a yes/no question. | `>8ball should i do something`
|
||||
`>rps` | Play a game of rocket paperclip scissors with Nadeko. | `>rps scissors`
|
||||
@ -237,37 +238,37 @@ Command and aliases | Description | Usage
|
||||
`!!load` | Loads a playlist under a certain name. | `!!load classical-1`
|
||||
`!!playlists`, `!!pls` | Lists all playlists. Paginated. 20 per page. Default page is 0. | `!!pls 1`
|
||||
`!!deleteplaylist`, `!!delpls` | Deletes a saved playlist. Only if you made it or if you are the bot owner. | `!!delpls animu-5`
|
||||
`!!goto` | Goes to a specific time in seconds in a song. | !!goto 30
|
||||
`!!goto` | Goes to a specific time in seconds in a song. | `!!goto 30`
|
||||
`!!getlink`, `!!gl` | Shows a link to the currently playing song.
|
||||
`!!autoplay`, `!!ap` | Toggles autoplay - When the song is finished, automatically queue a related youtube song. (Works only for youtube songs and when queue is empty)
|
||||
|
||||
### Searches
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`~lolchamp` | Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role. | ~lolchamp Riven or ~lolchamp Annie sup
|
||||
`~lolban` | Shows top 6 banned champions ordered by ban rate. Ban these champions and you will be Plat 5 in no time.
|
||||
`~hitbox`, `~hb` | Notifies this channel when a certain user starts streaming. | ~hitbox SomeStreamer
|
||||
`~twitch`, `~tw` | Notifies this channel when a certain user starts streaming. | ~twitch SomeStreamer
|
||||
`~beam`, `~bm` | Notifies this channel when a certain user starts streaming. | ~beam SomeStreamer
|
||||
`~checkhitbox`, `~chhb` | Checks if a certain user is streaming on the hitbox platform. | ~chhb SomeStreamer
|
||||
`~checktwitch`, `~chtw` | Checks if a certain user is streaming on the twitch platform. | ~chtw SomeStreamer
|
||||
`~checkbeam`, `~chbm` | Checks if a certain user is streaming on the beam platform. | ~chbm SomeStreamer
|
||||
`~removestream`, `~rms` | Removes notifications of a certain streamer on this channel. | ~rms SomeGuy
|
||||
`~liststreams`, `~ls` | Lists all streams you are following on this server. | ~ls
|
||||
`~convert` | Convert quantities from>to. Like `~convert m>km 1000`
|
||||
`~lolchamp` | Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role. | `~lolchamp Riven` or `~lolchamp Annie sup`
|
||||
`~lolban` | Shows top 6 banned champions ordered by ban rate. Ban these champions and you will be Plat 5 in no time. | `~lolban`
|
||||
`~hitbox`, `~hb` | Notifies this channel when a certain user starts streaming. | `~hitbox SomeStreamer`
|
||||
`~twitch`, `~tw` | Notifies this channel when a certain user starts streaming. | `~twitch SomeStreamer`
|
||||
`~beam`, `~bm` | Notifies this channel when a certain user starts streaming. | `~beam SomeStreamer`
|
||||
`~checkhitbox`, `~chhb` | Checks if a certain user is streaming on the hitbox platform. | `~chhb SomeStreamer`
|
||||
`~checktwitch`, `~chtw` | Checks if a certain user is streaming on the twitch platform. | `~chtw SomeStreamer`
|
||||
`~checkbeam`, `~chbm` | Checks if a certain user is streaming on the beam platform. | `~chbm SomeStreamer`
|
||||
`~removestream`, `~rms` | Removes notifications of a certain streamer on this channel. | `~rms SomeGuy`
|
||||
`~liststreams`, `~ls` | Lists all streams you are following on this server. | `~ls`
|
||||
`~convert` | Convert quantities from>to. | `~convert m>km 1000`
|
||||
`~convertlist` | List of the convertable dimensions and currencies.
|
||||
`~wowjoke` | Get one of Kwoth's penultimate WoW jokes.
|
||||
`~wowjoke` | Get one of Kwoth's penultimate WoW jokes. | `~wowjoke`
|
||||
`~calculate`, `~calc` | Evaluate a mathematical expression. | ~calc 1+1
|
||||
`~osu` | Shows osu stats for a player. | `~osu Name` or `~osu Name taiko`
|
||||
`~osu b` | Shows information about an osu beatmap. | ~osu b https://osu.ppy.sh/s/127712
|
||||
`~osu b` | Shows information about an osu beatmap. | `~osu b` https://osu.ppy.sh/s/127712`
|
||||
`~osu top5` | Displays a user's top 5 plays. | ~osu top5 Name
|
||||
`~pokemon`, `~poke` | Searches for a pokemon.
|
||||
`~pokemonability`, `~pokeab` | Searches for a pokemon ability.
|
||||
`~memelist` | Pulls a list of memes you can use with `~memegen` from http://memegen.link/templates/
|
||||
`~pokemon`, `~poke` | Searches for a pokemon. | `~poke Sylveon`
|
||||
`~pokemonability`, `~pokeab` | Searches for a pokemon ability. | `~pokeab "water gun"`
|
||||
`~memelist` | Pulls a list of memes you can use with `~memegen` from http://memegen.link/templates/ | `~memelist`
|
||||
`~memegen` | Generates a meme from memelist with top and bottom text. | `~memegen biw "gets iced coffee" "in the winter"`
|
||||
`~we` | Shows weather data for a specified city and a country. BOTH ARE REQUIRED. Use country abbrevations. | `~we Moscow RF`
|
||||
`~yt` | Searches youtubes and shows the first result | `~yt query`
|
||||
`~ani`, `~anime`, `~aq` | Queries anilist for an anime and shows the first result.
|
||||
`~ani`, `~anime`, `~aq` | Queries anilist for an anime and shows the first result. | `~aq aquerion evol`
|
||||
`~imdb` | Queries imdb for movies or series, show first result. | `~imdb query`
|
||||
`~mang`, `~manga`, `~mq` | Queries anilist for a manga and shows the first result. | `~mq query`
|
||||
`~randomcat`, `~meow` | Shows a random cat image.
|
||||
@ -279,13 +280,13 @@ Command and aliases | Description | Usage
|
||||
`~hs` | Searches for a Hearthstone card and shows its image. Takes a while to complete. | `~hs Ysera`
|
||||
`~ud` | Searches Urban Dictionary for a word. | `~ud Pineapple`
|
||||
`~#` | Searches Tagdef.com for a hashtag. | `~# ff`
|
||||
`~quote` | Shows a random quote.
|
||||
`~catfact` | Shows a random catfact from <http://catfacts-api.appspot.com/api/facts>
|
||||
`~yomama`, `~ym` | Shows a random joke from <http://api.yomomma.info/>
|
||||
`~randjoke`, `~rj` | Shows a random joke from <http://tambal.azurewebsites.net/joke/random>
|
||||
`~chucknorris`, `~cn` | Shows a random chucknorris joke from <http://tambal.azurewebsites.net/joke/random>
|
||||
`~magicitem`, `~mi` | Shows a random magicitem from <https://1d4chan.org/wiki/List_of_/tg/%27s_magic_items>
|
||||
`~revav` | Returns a google reverse image search for someone's avatar. | `~revav "@SomeGuy"
|
||||
`~quote` | Shows a random quote. | `~quote`
|
||||
`~catfact` | Shows a random catfact from <http://catfacts-api.appspot.com/api/facts> | `~catfact`
|
||||
`~yomama`, `~ym` | Shows a random joke from <http://api.yomomma.info/> | `~ym`
|
||||
`~randjoke`, `~rj` | Shows a random joke from <http://tambal.azurewebsites.net/joke/random> | `~rj`
|
||||
`~chucknorris`, `~cn` | Shows a random chucknorris joke from <http://tambal.azurewebsites.net/joke/random> | `~cn`
|
||||
`~magicitem`, `~mi` | Shows a random magicitem from <https://1d4chan.org/wiki/List_of_/tg/%27s_magic_items> | `~mi`
|
||||
`~revav` | Returns a google reverse image search for someone's avatar. | `~revav "@SomeGuy"`
|
||||
`~revimg` | Returns a google reverse image search for an image from a link. | `~revav Image link`
|
||||
`~safebooru` | Shows a random image from safebooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +) | `~safebooru yuri+kissing`
|
||||
`~wiki` | Gives you back a wikipedia link | `~wiki query`
|
||||
@ -301,15 +302,15 @@ Command and aliases | Description | Usage
|
||||
`~gelbooru` | Shows a random hentai image from gelbooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +) | `~gelbooru yuri+kissing`
|
||||
`~rule34` | Shows a random image from rule34.xx with a given tag. Tag is optional but preffered. (multiple tags are appended with +) | `~rule34 yuri+kissing`
|
||||
`~e621` | Shows a random hentai image from e621.net with a given tag. Tag is optional but preffered. Use spaces for multiple tags. | `~e621 yuri kissing`
|
||||
`~cp` | We all know where this will lead you to.
|
||||
`~boobs` | Real adult content.
|
||||
`~butts`, `~ass`, `~butt` | Real adult content.
|
||||
`~cp` | We all know where this will lead you to. | `~cp`
|
||||
`~boobs` | Real adult content. | `~boobs`
|
||||
`~butts`, `~ass`, `~butt` | Real adult content. | `~butts` or `~ass`
|
||||
|
||||
### ClashOfClans
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`,createwar`, `,cw` | Creates a new war by specifying a size (>10 and multiple of 5) and enemy clan name. | ,cw 15 The Enemy Clan
|
||||
`,startwar`, `,sw` | Starts a war with a given number. | `,sw 1`
|
||||
`,startwar`, `,sw` | Starts a war with a given number.
|
||||
`,listwar`, `,lw` | Shows the active war claims by a number. Shows all wars in a short way if no number is specified. | ,lw [war_number] or ,lw
|
||||
`,claim`, `,call`, `,c` | Claims a certain base from a certain war. You can supply a name in the third optional argument to claim in someone else's place. | ,call [war_number] [base_number] [optional_other_name]
|
||||
`,claimfinish`, `,cf`, `,cf3`, `,claimfinish3` | Finish your claim with 3 stars if you destroyed a base. Optional second argument finishes for someone else. | ,cf [war_number] [optional_other_name]
|
||||
@ -322,16 +323,16 @@ Command and aliases | Description | Usage
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`>attack` | Attacks a target with the given move. Use `>movelist` to see a list of moves your type can use. | `>attack "vine whip" @someguy`
|
||||
`>movelist`, `>ml` | Lists the moves you are able to use
|
||||
`>heal` | Heals someone. Revives those who fainted. Costs a NadekoFlower | >heal @someone
|
||||
`>type` | Get the poketype of the target. | >type @someone
|
||||
`>settype` | Set your poketype. Costs a NadekoFlower. | >settype fire
|
||||
`>movelist`, `>ml` | Lists the moves you are able to use | `>ml`
|
||||
`>heal` | Heals someone. Revives those who fainted. Costs a NadekoFlower | `>heal @someone`
|
||||
`>type` | Get the poketype of the target. | `>type @someone`
|
||||
`>settype` | Set your poketype. Costs a NadekoFlower. | `>settype fire`
|
||||
|
||||
### Translator
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`~translate`, `~trans` | Translates from>to text. From the given language to the destiation language. | `~trans en>fr Hello`
|
||||
`~translangs` | List the valid languages for translation.
|
||||
`~translangs` | List the valid languages for translation. | `{Prefix}translangs` or `{Prefix}translangs language`
|
||||
|
||||
### Customreactions
|
||||
Command and aliases | Description | Usage
|
||||
|
Loading…
Reference in New Issue
Block a user