diff --git a/DockerGuide.md b/DockerGuide.md
index 4b6ec756..5a87bc22 100644
--- a/DockerGuide.md
+++ b/DockerGuide.md
@@ -43,6 +43,7 @@ Open putty and type ip adress **you got in your email** with port 22
- Type `nano /nadeko/credentials.json` and type in your `credentials`
- CTRL+X then CTRL+Y to save
- Type `docker start nadeko`
+- Type `docker logs -f nadeko` to see the console output
**Your bot is running, enjoy! o/**
diff --git a/LinuxSetup.md b/LinuxSetup.md
index 784e1253..0272affc 100644
--- a/LinuxSetup.md
+++ b/LinuxSetup.md
@@ -153,7 +153,7 @@ TMUX
`certmgr -ssl https://discordapp.com`
**14)**
-`certmgr --ssl https://gateway.discord.gg`
+`certmgr -ssl https://gateway.discord.gg`
Type `yes` and hit Enter **(three times - as it will ask for three times)**
diff --git a/NadekoBot/Modules/Administration/AdministrationModule.cs b/NadekoBot/Modules/Administration/AdministrationModule.cs
index 2ea33354..23402c81 100644
--- a/NadekoBot/Modules/Administration/AdministrationModule.cs
+++ b/NadekoBot/Modules/Administration/AdministrationModule.cs
@@ -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. | `{Prefix}delmsgoncmd`")
+ .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 =>
{
@@ -90,7 +90,7 @@ namespace NadekoBot.Modules.Administration
});
cgb.CreateCommand(Prefix + "setrole").Alias(Prefix + "sr")
- .Description($"Sets a role for a given user. | `{Prefix}sr @User Guest`")
+ .Description($"Sets a role for a given user. **Needs Manage Roles Permissions.**| `{Prefix}sr @User Guest`")
.Parameter("user_name", ParameterType.Required)
.Parameter("role_name", ParameterType.Unparsed)
.AddCheck(SimpleCheckers.CanManageRoles)
@@ -133,7 +133,7 @@ namespace NadekoBot.Modules.Administration
});
cgb.CreateCommand(Prefix + "removerole").Alias(Prefix + "rr")
- .Description($"Removes a role from a given user. | `{Prefix}rr @User Admin`")
+ .Description($"Removes a role from a given user. **Needs Manage Roles Permissions.**| `{Prefix}rr @User Admin`")
.Parameter("user_name", ParameterType.Required)
.Parameter("role_name", ParameterType.Unparsed)
.AddCheck(SimpleCheckers.CanManageRoles)
@@ -171,7 +171,7 @@ namespace NadekoBot.Modules.Administration
cgb.CreateCommand(Prefix + "renamerole")
.Alias(Prefix + "renr")
- .Description($"Renames a role. Role you are renaming must be lower than bot's highest role. | `{Prefix}renr \"First role\" SecondRole`")
+ .Description($"Renames a role. Roles you are renaming must be lower than bot's highest role. **Manage Roles Permissions.** | `{Prefix}renr \"First role\" SecondRole`")
.Parameter("r1", ParameterType.Required)
.Parameter("r2", ParameterType.Required)
.AddCheck(new SimpleCheckers.ManageRoles())
@@ -204,7 +204,7 @@ namespace NadekoBot.Modules.Administration
});
cgb.CreateCommand(Prefix + "removeallroles").Alias(Prefix + "rar")
- .Description($"Removes all roles from a mentioned user. | `{Prefix}rar @User`")
+ .Description($"Removes all roles from a mentioned user. **Needs Manage Roles Permissions.**| `{Prefix}rar @User`")
.Parameter("user_name", ParameterType.Unparsed)
.AddCheck(SimpleCheckers.CanManageRoles)
.Do(async e =>
@@ -230,7 +230,7 @@ namespace NadekoBot.Modules.Administration
});
cgb.CreateCommand(Prefix + "createrole").Alias(Prefix + "cr")
- .Description($"Creates a role with a given name. | `{Prefix}cr Awesome Role`")
+ .Description($"Creates a role with a given name. **Needs Manage Roles Permissions.**| `{Prefix}cr Awesome Role`")
.Parameter("role_name", ParameterType.Unparsed)
.AddCheck(SimpleCheckers.CanManageRoles)
.Do(async e =>
@@ -253,7 +253,7 @@ namespace NadekoBot.Modules.Administration
.Parameter("r", ParameterType.Optional)
.Parameter("g", ParameterType.Optional)
.Parameter("b", ParameterType.Optional)
- .Description($"Set a role's color to the hex or 0-255 rgb color value provided. | `{Prefix}rc Admin 255 200 100` or `{Prefix}rc Admin ffba55`")
+ .Description($"Set a role's color to the hex or 0-255 rgb color value provided. **Needs Manage Roles Permissions.** | `{Prefix}rc Admin 255 200 100` or `{Prefix}rc Admin ffba55`")
.Do(async e =>
{
if (!e.User.ServerPermissions.ManageRoles)
@@ -298,7 +298,7 @@ namespace NadekoBot.Modules.Administration
cgb.CreateCommand(Prefix + "ban").Alias(Prefix + "b")
.Parameter("user", ParameterType.Required)
.Parameter("msg", ParameterType.Unparsed)
- .Description($"Bans a user by id or name with an optional message. | `{Prefix}b \"@some Guy\" Your behaviour is toxic.`")
+ .Description($"Bans a user by id or name with an optional message. **Needs Ban Permissions.**| `{Prefix}b \"@some Guy\" Your behaviour is toxic.`")
.Do(async e =>
{
var msg = e.GetArg("msg");
@@ -333,7 +333,7 @@ namespace NadekoBot.Modules.Administration
cgb.CreateCommand(Prefix + "softban").Alias(Prefix + "sb")
.Parameter("user", ParameterType.Required)
.Parameter("msg", ParameterType.Unparsed)
- .Description($"Bans and then unbans a user by id or name with an optional message. | `{Prefix}sb \"@some Guy\" Your behaviour is toxic.`")
+ .Description($"Bans and then unbans a user by id or name with an optional message. **Needs Ban Permissions.**| `{Prefix}sb \"@some Guy\" Your behaviour is toxic.`")
.Do(async e =>
{
var msg = e.GetArg("msg");
@@ -369,7 +369,7 @@ namespace NadekoBot.Modules.Administration
cgb.CreateCommand(Prefix + "kick").Alias(Prefix + "k")
.Parameter("user")
.Parameter("msg", ParameterType.Unparsed)
- .Description($"Kicks a mentioned user. | `{Prefix}k \"@some Guy\" Your behaviour is toxic.`")
+ .Description($"Kicks a mentioned user. **Needs Kick Permissions.**| `{Prefix}k \"@some Guy\" Your behaviour is toxic.`")
.Do(async e =>
{
var msg = e.GetArg("msg");
@@ -400,7 +400,7 @@ namespace NadekoBot.Modules.Administration
}
});
cgb.CreateCommand(Prefix + "mute")
- .Description($"Mutes mentioned user or users. | `{Prefix}mute \"@Someguy\"` or `{Prefix}mute \"@Someguy\" \"@Someguy\"`")
+ .Description($"Mutes mentioned user or users. **Needs Mute Permissions.**| `{Prefix}mute \"@Someguy\"` or `{Prefix}mute \"@Someguy\" \"@Someguy\"`")
.Parameter("throwaway", ParameterType.Unparsed)
.Do(async e =>
{
@@ -426,7 +426,7 @@ namespace NadekoBot.Modules.Administration
});
cgb.CreateCommand(Prefix + "unmute")
- .Description($"Unmutes mentioned user or users. | `{Prefix}unmute \"@Someguy\"` or `{Prefix}unmute \"@Someguy\" \"@Someguy\"`")
+ .Description($"Unmutes mentioned user or users. **Needs Mute Permissions.**| `{Prefix}unmute \"@Someguy\"` or `{Prefix}unmute \"@Someguy\" \"@Someguy\"`")
.Parameter("throwaway", ParameterType.Unparsed)
.Do(async e =>
{
@@ -453,7 +453,7 @@ namespace NadekoBot.Modules.Administration
cgb.CreateCommand(Prefix + "deafen")
.Alias(Prefix + "deaf")
- .Description($"Deafens mentioned user or users | `{Prefix}deaf \"@Someguy\"` or `{Prefix}deaf \"@Someguy\" \"@Someguy\"`")
+ .Description($"Deafens mentioned user or users. **Needs Deafen Permissions.**| `{Prefix}deaf \"@Someguy\"` or `{Prefix}deaf \"@Someguy\" \"@Someguy\"`")
.Parameter("throwaway", ParameterType.Unparsed)
.Do(async e =>
{
@@ -480,7 +480,7 @@ namespace NadekoBot.Modules.Administration
cgb.CreateCommand(Prefix + "undeafen")
.Alias(Prefix + "undef")
- .Description($"Undeafens mentioned user or users | `{Prefix}undef \"@Someguy\"` or `{Prefix}undef \"@Someguy\" \"@Someguy\"`")
+ .Description($"Undeafens mentioned user or users. **Needs Deafen Permissions.** | `{Prefix}undef \"@Someguy\"` or `{Prefix}undef \"@Someguy\" \"@Someguy\"`")
.Parameter("throwaway", ParameterType.Unparsed)
.Do(async e =>
{
@@ -507,7 +507,7 @@ namespace NadekoBot.Modules.Administration
cgb.CreateCommand(Prefix + "delvoichanl")
.Alias(Prefix + "dvch")
- .Description($"Deletes a voice channel with a given name. | `{Prefix}dvch VoiceChannelName`")
+ .Description($"Deletes a voice channel with a given name. **Needs Manage Channel Permissions.**| `{Prefix}dvch VoiceChannelName`")
.Parameter("channel_name", ParameterType.Required)
.Do(async e =>
{
@@ -530,7 +530,7 @@ namespace NadekoBot.Modules.Administration
cgb.CreateCommand(Prefix + "creatvoichanl")
.Alias(Prefix + "cvch")
- .Description($"Creates a new voice channel with a given name. | `{Prefix}cvch VoiceChannelName`")
+ .Description($"Creates a new voice channel with a given name. **Needs Manage Channel Permissions.** | `{Prefix}cvch VoiceChannelName`")
.Parameter("channel_name", ParameterType.Required)
.Do(async e =>
{
@@ -550,7 +550,7 @@ namespace NadekoBot.Modules.Administration
cgb.CreateCommand(Prefix + "deltxtchanl")
.Alias(Prefix + "dtch")
- .Description($"Deletes a text channel with a given name. | `{Prefix}dtch TextChannelName`")
+ .Description($"Deletes a text channel with a given name. **Needs Manage Channel Permissions.** | `{Prefix}dtch TextChannelName`")
.Parameter("channel_name", ParameterType.Required)
.Do(async e =>
{
@@ -572,7 +572,7 @@ namespace NadekoBot.Modules.Administration
cgb.CreateCommand(Prefix + "creatxtchanl")
.Alias(Prefix + "ctch")
- .Description($"Creates a new text channel with a given name. | `{Prefix}ctch TextChannelName`")
+ .Description($"Creates a new text channel with a given name. **Needs Manage Channel Permissions.** | `{Prefix}ctch TextChannelName`")
.Parameter("channel_name", ParameterType.Required)
.Do(async e =>
{
@@ -592,7 +592,7 @@ namespace NadekoBot.Modules.Administration
cgb.CreateCommand(Prefix + "settopic")
.Alias(Prefix + "st")
- .Description($"Sets a topic on the current channel. | `{Prefix}st My new topic`")
+ .Description($"Sets a topic on the current channel. **Needs Manage Channel Permissions.** | `{Prefix}st My new topic`")
.AddCheck(SimpleCheckers.ManageChannels())
.Parameter("topic", ParameterType.Unparsed)
.Do(async e =>
@@ -604,7 +604,7 @@ namespace NadekoBot.Modules.Administration
cgb.CreateCommand(Prefix + "setchanlname")
.Alias(Prefix + "schn")
- .Description($"Changed the name of the current channel.| `{Prefix}schn NewName`")
+ .Description($"Changed the name of the current channel. **Needs Manage Channel Permissions.**| `{Prefix}schn NewName`")
.AddCheck(SimpleCheckers.ManageChannels())
.Parameter("name", ParameterType.Unparsed)
.Do(async e =>
@@ -815,7 +815,7 @@ namespace NadekoBot.Modules.Administration
});
cgb.CreateCommand(Prefix + "donators")
- .Description("List of lovely people who donated to keep this project alive. | `{Prefix}donators`")
+ .Description($"List of lovely people who donated to keep this project alive. | `{Prefix}donators`")
.Do(async e =>
{
await Task.Run(async () =>
@@ -829,7 +829,7 @@ namespace NadekoBot.Modules.Administration
});
cgb.CreateCommand(Prefix + "donadd")
- .Description($"Add a donator to the database. | `{Prefix}donadd Donate Amount`")
+ .Description($"Add a donator to the database. **Kwoth Only** | `{Prefix}donadd Donate Amount`")
.Parameter("donator")
.Parameter("amount")
.AddCheck(SimpleCheckers.OwnerOnly())
diff --git a/NadekoBot/Modules/Administration/Commands/AutoAssignRole.cs b/NadekoBot/Modules/Administration/Commands/AutoAssignRole.cs
index 7ccd0e0e..38084dfa 100644
--- a/NadekoBot/Modules/Administration/Commands/AutoAssignRole.cs
+++ b/NadekoBot/Modules/Administration/Commands/AutoAssignRole.cs
@@ -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. |`{Prefix}aar` to disable, `{Prefix}aar Role Name` to enable")
+ .Description($"Automaticaly assigns a specified role to every user who joins the server. **Needs Manage Roles Permissions.** |`{Prefix}aar` to disable, `{Prefix}aar Role Name` to enable")
.Parameter("role", ParameterType.Unparsed)
.AddCheck(new SimpleCheckers.ManageRoles())
.Do(async e =>
diff --git a/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs b/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs
index f8dc2133..c08c34ef 100644
--- a/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs
+++ b/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs
@@ -65,7 +65,7 @@ namespace NadekoBot.Modules.Administration.Commands
{
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. | `{Prefix}scsc`")
+ $"that other people will use to tune in to the same instance. **Bot Owner Only.** | `{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. | `{Prefix}jcsc`")
+ .Description($"Joins current channel to an instance of cross server channel using the token. **Needs Manage Server Permissions.**| `{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. | `{Prefix}lcsc`")
+ .Description($"Leaves Cross server channel instance from this channel. **Needs Manage Server Permissions.**| `{Prefix}lcsc`")
.AddCheck(SimpleCheckers.ManageServer())
.Do(async e =>
{
diff --git a/NadekoBot/Modules/Administration/Commands/CustomReactionsCommands.cs b/NadekoBot/Modules/Administration/Commands/CustomReactionsCommands.cs
index 5105863f..2725e196 100644
--- a/NadekoBot/Modules/Administration/Commands/CustomReactionsCommands.cs
+++ b/NadekoBot/Modules/Administration/Commands/CustomReactionsCommands.cs
@@ -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). | `{Prefix}dcr index`")
+ .Description($"Deletes a custom reaction with given name (and index). **Bot Owner Only.**| `{Prefix}dcr index`")
.Parameter("name", ParameterType.Required)
.Parameter("index", ParameterType.Optional)
.AddCheck(SimpleCheckers.OwnerOnly())
diff --git a/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs b/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs
index d7915bb2..ab93693a 100644
--- a/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs
+++ b/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs
@@ -14,7 +14,7 @@ namespace NadekoBot.Modules.Administration.Commands
{
cgb.CreateCommand(Module.Prefix + "listincidents")
.Alias(Prefix + "lin")
- .Description($"List all UNREAD incidents and flags them as read. | `{Prefix}lin`")
+ .Description($"List all UNREAD incidents and flags them as read. **Needs Manage Server Permissions.**| `{Prefix}lin`")
.AddCheck(SimpleCheckers.ManageServer())
.Do(async e =>
{
@@ -27,7 +27,7 @@ namespace NadekoBot.Modules.Administration.Commands
cgb.CreateCommand(Module.Prefix + "listallincidents")
.Alias(Prefix + "lain")
- .Description($"Sends you a file containing all incidents and flags them as read. | `{Prefix}lain`")
+ .Description($"Sends you a file containing all incidents and flags them as read. **Needs Manage Server Permissions.**| `{Prefix}lain`")
.AddCheck(SimpleCheckers.ManageServer())
.Do(async e =>
{
diff --git a/NadekoBot/Modules/Administration/Commands/LogCommand.cs b/NadekoBot/Modules/Administration/Commands/LogCommand.cs
index db693ae3..b5f19eb1 100644
--- a/NadekoBot/Modules/Administration/Commands/LogCommand.cs
+++ b/NadekoBot/Modules/Administration/Commands/LogCommand.cs
@@ -375,7 +375,7 @@ namespace NadekoBot.Modules.Administration.Commands
{
cgb.CreateCommand(Module.Prefix + "spmom")
- .Description($"Toggles whether mentions of other offline users on your server will send a pm to them. | `{Prefix}spmom`")
+ .Description($"Toggles whether mentions of other offline users on your server will send a pm to them. **Needs Manage Server Permissions.**| `{Prefix}spmom`")
.AddCheck(SimpleCheckers.ManageServer())
.Do(async e =>
{
@@ -413,7 +413,7 @@ namespace NadekoBot.Modules.Administration.Commands
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. | `{Prefix}logignore`")
+ .Description($"Toggles whether the {Prefix}logserver command ignores this channel. Useful if you have hidden admin channel and public log channel. **Bot Owner Only!**| `{Prefix}logignore`")
.AddCheck(SimpleCheckers.OwnerOnly())
.AddCheck(SimpleCheckers.ManageServer())
.Do(async e =>
@@ -431,7 +431,7 @@ namespace NadekoBot.Modules.Administration.Commands
});
cgb.CreateCommand(Module.Prefix + "userpresence")
- .Description($"Starts logging to this channel when someone from the server goes online/offline/idle. | `{Prefix}userpresence`")
+ .Description($"Starts logging to this channel when someone from the server goes online/offline/idle. **Needs Manage Server Permissions.**| `{Prefix}userpresence`")
.AddCheck(SimpleCheckers.ManageServer())
.Do(async e =>
{
@@ -447,7 +447,7 @@ namespace NadekoBot.Modules.Administration.Commands
});
cgb.CreateCommand(Module.Prefix + "voicepresence")
- .Description("Toggles logging to this channel whenever someone joins or leaves a voice channel you are in right now. | `{Prefix}voicerpresence`")
+ .Description($"Toggles logging to this channel whenever someone joins or leaves a voice channel you are in right now. **Needs Manage Server Permissions.**| `{Prefix}voicerpresence`")
.Parameter("all", ParameterType.Optional)
.AddCheck(SimpleCheckers.ManageServer())
.Do(async e =>
diff --git a/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs b/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs
index 2ea4346d..e87f5555 100644
--- a/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs
+++ b/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs
@@ -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. | `{Prefix}repinv`")
+ .Description($"Immediately shows the repeat message and restarts the timer. **Needs Manage Messages Permissions.**| `{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. |`{Prefix}repeat 5 Hello there`")
+ $"repeat is disabled. **Needs Manage Messages Permissions.** |`{Prefix}repeat 5 Hello there`")
.Parameter("minutes", ParameterType.Optional)
.Parameter("msg", ParameterType.Unparsed)
.AddCheck(SimpleCheckers.ManageMessages())
diff --git a/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs b/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs
index 4978dbe3..c1caa0bc 100644
--- a/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs
+++ b/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs
@@ -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. | `{Prefix}ropl`")
+ .Description($"Toggles rotation of playing status of the dynamic strings you specified earlier. **Bot Owner Only!** | `{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)+ $" | `{Prefix}adpl`")
+ "Supported placeholders: " + string.Join(", ", PlayingPlaceholders.Keys)+ $" **Bot Owner Only!**| `{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. | `{Prefix}lipl`")
+ .Description($"Lists all playing statuses with their corresponding number. **Bot Owner Only!**| `{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. | `{Prefix}rmpl`")
+ .Description($"Removes a playing string on a given number. **Bot Owner Only!**| `{Prefix}rmpl`")
.Parameter("number", ParameterType.Required)
.AddCheck(SimpleCheckers.OwnerOnly())
.Do(async e =>
diff --git a/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs b/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs
index c9efe84e..d1f62bd9 100644
--- a/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs
+++ b/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs
@@ -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. | `{Prefix}slowmode`")
+ .Description($"Toggles slow mode. When ON, users will be able to send only 1 message every 5 seconds. **Needs Manage Messages Permissions.**| `{Prefix}slowmode`")
.AddCheck(SimpleCheckers.ManageMessages())
.Do(async e =>
{
diff --git a/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs b/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs
index f88957bd..8e5e54fb 100644
--- a/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs
+++ b/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs
@@ -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. | `{Prefix}asar Gamer`")
+ $"(use quotations for multiword roles) to the list of self-assignable roles. **Needs Manage Roles Permissions.**| `{Prefix}asar Gamer`")
.Parameter("roles", ParameterType.Multiple)
.AddCheck(SimpleCheckers.CanManageRoles)
.Do(async e =>
diff --git a/NadekoBot/Modules/Administration/Commands/SelfCommands.cs b/NadekoBot/Modules/Administration/Commands/SelfCommands.cs
index 23322e07..f8019ac9 100644
--- a/NadekoBot/Modules/Administration/Commands/SelfCommands.cs
+++ b/NadekoBot/Modules/Administration/Commands/SelfCommands.cs
@@ -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. | `{Prefix}leave 123123123331`")
+ .Description($"Makes Nadeko leave the server. Either name or id required. **Bot Owner Only!**| `{Prefix}leave 123123123331`")
.Parameter("arg", ParameterType.Required)
.AddCheck(SimpleCheckers.OwnerOnly())
.Do(async e =>
diff --git a/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs b/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs
index 5281f9df..b2cdf3b4 100644
--- a/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs
+++ b/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs
@@ -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. | `{Prefix}grdel`")
+ .Description($"Toggles automatic deletion of greet and bye messages. **Needs Manage Server Permissions.**| `{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. | `{Prefix}greet`")
+ .Description($"Toggles anouncements on the current channel when someone joins the server. **Needs Manage Server Permissions.**| `{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. | `{Prefix}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. **Needs Manage Server Permissions.**| `{Prefix}greetmsg Welcome to the server, %user%.`")
.Parameter("msg", ParameterType.Unparsed)
.Do(async e =>
{
@@ -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. | `{Prefix}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. **Needs Manage Server Permissions.**| `{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. | `{Prefix}byepm`")
+ .Description($"Toggles whether the good bye messages will be sent in a PM or in the text channel. **Needs Manage Server Permissions.**| `{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. | `{Prefix}greetpm`")
+ .Description($"Toggles whether the greet messages will be sent in a PM or in the text channel. **Needs Manage Server Permissions.**| `{Prefix}greetpm`")
.Do(async e =>
{
if (!e.User.ServerPermissions.ManageServer) return;
diff --git a/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommand.cs b/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommand.cs
index bf5e2a73..4c6a948c 100644
--- a/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommand.cs
+++ b/NadekoBot/Modules/Administration/Commands/VoicePlusTextCommand.cs
@@ -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.** | `{Prefix}cleanv+t`")
+ .Description($"Deletes all text channels ending in `-voice` for which voicechannels are not found. **Use at your own risk.\nNeeds Manage Roles and Manage Channels Permissions.** | `{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. | `{Prefix}voice+text`")
+ $"If you are server owner, keep in mind you will see them all the time regardless. **Needs Manage Roles and Manage Channels Permissions.**| `{Prefix}voice+text`")
.AddCheck(SimpleCheckers.ManageChannels())
.AddCheck(SimpleCheckers.CanManageRoles)
.Do(async e =>
diff --git a/NadekoBot/Modules/ClashOfClans/ClashOfClansModule.cs b/NadekoBot/Modules/ClashOfClans/ClashOfClansModule.cs
index 449c4da6..e14e48b4 100644
--- a/NadekoBot/Modules/ClashOfClans/ClashOfClansModule.cs
+++ b/NadekoBot/Modules/ClashOfClans/ClashOfClansModule.cs
@@ -186,7 +186,7 @@ namespace NadekoBot.Modules.ClashOfClans
cgb.CreateCommand(Prefix + "startwar")
.Alias(Prefix + "sw")
- .Description("Starts a war with a given number. | `{Prefix}sw 15`")
+ .Description($"Starts a war with a given number. | `{Prefix}sw 15`")
.Parameter("number", ParameterType.Required)
.Do(async e =>
{
diff --git a/NadekoBot/Modules/Music/MusicModule.cs b/NadekoBot/Modules/Music/MusicModule.cs
index e0045ab9..3c4aa351 100644
--- a/NadekoBot/Modules/Music/MusicModule.cs
+++ b/NadekoBot/Modules/Music/MusicModule.cs
@@ -756,7 +756,7 @@ namespace NadekoBot.Modules.Music
cgb.CreateCommand(Prefix + "getlink")
.Alias(Prefix + "gl")
- .Description("Shows a link to the song in the queue by index, or the currently playing song by default. | `{Prefix}gl`")
+ .Description($"Shows a link to the song in the queue by index, or the currently playing song by default. | `{Prefix}gl`")
.Parameter("index", ParameterType.Optional)
.Do(async e =>
{
@@ -791,7 +791,7 @@ namespace NadekoBot.Modules.Music
cgb.CreateCommand(Prefix + "autoplay")
.Alias(Prefix + "ap")
- .Description("Toggles autoplay - When the song is finished, automatically queue a related youtube song. (Works only for youtube songs and when queue is empty) | `{Prefix}ap`")
+ .Description($"Toggles autoplay - When the song is finished, automatically queue a related youtube song. (Works only for youtube songs and when queue is empty) | `{Prefix}ap`")
.Do(async e =>
{
diff --git a/NadekoBot/Modules/Permissions/Classes/PermissionChecker.cs b/NadekoBot/Modules/Permissions/Classes/PermissionChecker.cs
index 412ce69a..0c6aa79b 100644
--- a/NadekoBot/Modules/Permissions/Classes/PermissionChecker.cs
+++ b/NadekoBot/Modules/Permissions/Classes/PermissionChecker.cs
@@ -49,7 +49,6 @@ namespace NadekoBot.Modules.Permissions.Classes
{
return false;
}
-
if (timeBlackList.Contains(user.Id))
return false;
@@ -64,9 +63,9 @@ namespace NadekoBot.Modules.Permissions.Classes
PermissionsHandler.PermissionsDict.TryGetValue(user.Server.Id, out perms);
AddUserCooldown(user.Server.Id, user.Id, command.Text.ToLower());
- if (commandCooldowns.Keys.Contains(user.Server.Id+":"+command.Text.ToLower()))
+ if (commandCooldowns.Keys.Contains(user.Server.Id + ":" + command.Text.ToLower()))
{
- if(perms?.Verbose == true)
+ if (perms?.Verbose == true)
error = $"{user.Mention} You have a cooldown on that command.";
return false;
}
@@ -150,7 +149,8 @@ namespace NadekoBot.Modules.Permissions.Classes
}
}
- public void AddUserCooldown(ulong serverId, ulong userId, string commandName) {
+ public void AddUserCooldown(ulong serverId, ulong userId, string commandName)
+ {
commandCooldowns.TryAdd(commandName, userId);
var tosave = serverId + ":" + commandName;
Task.Run(async () =>
@@ -158,7 +158,8 @@ namespace NadekoBot.Modules.Permissions.Classes
ServerPermissions perms;
PermissionsHandler.PermissionsDict.TryGetValue(serverId, out perms);
int cd;
- if (!perms.CommandCooldowns.TryGetValue(commandName,out cd)) {
+ if (!perms.CommandCooldowns.TryGetValue(commandName, out cd))
+ {
return;
}
if (commandCooldowns.TryAdd(tosave, userId))
diff --git a/NadekoBot/Modules/Permissions/PermissionsModule.cs b/NadekoBot/Modules/Permissions/PermissionsModule.cs
index d2bc1840..a024341f 100644
--- a/NadekoBot/Modules/Permissions/PermissionsModule.cs
+++ b/NadekoBot/Modules/Permissions/PermissionsModule.cs
@@ -813,7 +813,7 @@ namespace NadekoBot.Modules.Permissions
cgb.CreateCommand(Prefix + "allcmdcooldowns")
.Alias(Prefix + "acmdcds")
- .Description("Shows a list of all commands and their respective cooldowns. | `{Prefix}acmdcds`")
+ .Description($"Shows a list of all commands and their respective cooldowns. | `{Prefix}acmdcds`")
.Do(async e =>
{
ServerPermissions perms;
diff --git a/NadekoBot/Modules/Searches/Commands/EvalCommand.cs b/NadekoBot/Modules/Searches/Commands/EvalCommand.cs
index 0d0108e0..4dd5a9fe 100644
--- a/NadekoBot/Modules/Searches/Commands/EvalCommand.cs
+++ b/NadekoBot/Modules/Searches/Commands/EvalCommand.cs
@@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Searches.Commands
{
cgb.CreateCommand(Module.Prefix + "calculate")
.Alias(Module.Prefix + "calc")
- .Description($"Evaluate a mathematical expression. | {Prefix}calc 1+1")
+ .Description($"Evaluate a mathematical expression. | `{Prefix}calc 1+1`")
.Parameter("expression", ParameterType.Unparsed)
.Do(EvalFunc());
}
diff --git a/NadekoBot/Modules/Searches/Commands/OsuCommands.cs b/NadekoBot/Modules/Searches/Commands/OsuCommands.cs
index bda99f48..8ead137d 100644
--- a/NadekoBot/Modules/Searches/Commands/OsuCommands.cs
+++ b/NadekoBot/Modules/Searches/Commands/OsuCommands.cs
@@ -56,7 +56,7 @@ namespace NadekoBot.Modules.Searches.Commands
});
cgb.CreateCommand(Module.Prefix + "osu b")
- .Description($"Shows information about an osu beatmap. |`{Prefix}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. |{Prefix}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 =>
diff --git a/NadekoBot/Modules/Searches/SearchesModule.cs b/NadekoBot/Modules/Searches/SearchesModule.cs
index c484fabf..2662107a 100644
--- a/NadekoBot/Modules/Searches/SearchesModule.cs
+++ b/NadekoBot/Modules/Searches/SearchesModule.cs
@@ -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. | `{Prefix}aq aquerion evol`")
+ .Description($"Queries anilist for an anime and shows the first result. | `{Prefix}aq aquarion evol`")
.Do(async e =>
{
if (!(await SearchHelper.ValidateQuery(e.Channel, e.GetArg("query")).ConfigureAwait(false))) return;
@@ -106,7 +106,7 @@ $@"š **Weather for** ć{obj["target"]}ć
cgb.CreateCommand(Prefix + "imdb")
.Parameter("query", ParameterType.Unparsed)
- .Description($"Queries imdb for movies or series, show first result. | `{Prefix}imdb query`")
+ .Description($"Queries imdb for movies or series, show first result. | `{Prefix}imdb Batman vs Superman`")
.Do(async e =>
{
if (!(await SearchHelper.ValidateQuery(e.Channel, e.GetArg("query")).ConfigureAwait(false))) return;
@@ -130,7 +130,7 @@ $@"š **Weather for** ć{obj["target"]}ć
cgb.CreateCommand(Prefix + "mang")
.Alias(Prefix + "manga").Alias(Prefix + "mq")
.Parameter("query", ParameterType.Unparsed)
- .Description($"Queries anilist for a manga and shows the first result. | `{Prefix}mq query`")
+ .Description($"Queries anilist for a manga and shows the first result. | `{Prefix}mq Shingeki no kyojin`")
.Do(async e =>
{
if (!(await SearchHelper.ValidateQuery(e.Channel, e.GetArg("query")).ConfigureAwait(false))) return;
@@ -149,7 +149,7 @@ $@"š **Weather for** ć{obj["target"]}ć
cgb.CreateCommand(Prefix + "randomcat")
.Alias(Prefix + "meow")
- .Description("Shows a random cat image. | `{Prefix}meow`")
+ .Description($"Shows a random cat image. | `{Prefix}meow`")
.Do(async e =>
{
await e.Channel.SendMessage(JObject.Parse(
@@ -159,7 +159,7 @@ $@"š **Weather for** ć{obj["target"]}ć
cgb.CreateCommand(Prefix + "randomdog")
.Alias(Prefix + "woof")
- .Description("Shows a random dog image. | `{Prefix}woof`")
+ .Description($"Shows a random dog image. | `{Prefix}woof`")
.Do(async e =>
{
await e.Channel.SendMessage("http://random.dog/" + await SearchHelper.GetResponseStringAsync("http://random.dog/woof").ConfigureAwait(false)).ConfigureAwait(false);
@@ -502,7 +502,7 @@ $@"š **Weather for** ć{obj["target"]}ć
cgb.CreateCommand(Prefix + "av")
.Alias(Prefix + "avatar")
.Parameter("mention", ParameterType.Required)
- .Description($"Shows a mentioned person's avatar. | `{Prefix}av @X`")
+ .Description($"Shows a mentioned person's avatar. | `{Prefix}av \"@SomeGuy\"`")
.Do(async e =>
{
var usr = e.Channel.FindUsers(e.GetArg("mention")).FirstOrDefault();
diff --git a/NadekoBot/Modules/Trello/TrelloModule.cs b/NadekoBot/Modules/Trello/TrelloModule.cs
index 527a2ed5..176ca2b8 100644
--- a/NadekoBot/Modules/Trello/TrelloModule.cs
+++ b/NadekoBot/Modules/Trello/TrelloModule.cs
@@ -71,7 +71,7 @@ namespace NadekoBot.Modules.Trello
cgb.CreateCommand(Prefix + "bind")
.Description("Bind a trello bot to a single channel. " +
"You will receive notifications from your board when something is added or edited." +
- $" | `{Prefix}bind [board_id]`")
+ $" **Bot Owner Only!**| `{Prefix}bind [board_id]`")
.Parameter("board_id", Discord.Commands.ParameterType.Required)
.Do(async e =>
{
@@ -92,7 +92,7 @@ namespace NadekoBot.Modules.Trello
});
cgb.CreateCommand(Prefix + "unbind")
- .Description($"Unbinds a bot from the channel and board. | `{Prefix}unbind`")
+ .Description($"Unbinds a bot from the channel and board. **Bot Owner Only!**| `{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 ;) | `{Prefix}list`")
+ .Description($"Lists all lists, yo ;) **Bot Owner Only!**| `{Prefix}list`")
.Do(async e =>
{
if (!NadekoBot.IsOwner(e.User.Id)) return;
@@ -116,7 +116,7 @@ namespace NadekoBot.Modules.Trello
});
cgb.CreateCommand(Prefix + "cards")
- .Description($"Lists all cards from the supplied list. You can supply either a name or an index. | `{Prefix}cards index`")
+ .Description($"Lists all cards from the supplied list. You can supply either a name or an index. **Bot Owner Only!**| `{Prefix}cards index`")
.Parameter("list_name", Discord.Commands.ParameterType.Unparsed)
.Do(async e =>
{
diff --git a/NadekoBot/Modules/Utility/UtilityModule.cs b/NadekoBot/Modules/Utility/UtilityModule.cs
index 6fd8db53..218ccbae 100644
--- a/NadekoBot/Modules/Utility/UtilityModule.cs
+++ b/NadekoBot/Modules/Utility/UtilityModule.cs
@@ -48,7 +48,7 @@ namespace NadekoBot.Modules.Utility
if (arr.Length == 0)
await e.Channel.SendMessage("Nobody. (not 100% sure)").ConfigureAwait(false);
else
- await e.Channel.SendMessage("```xl\n" + string.Join("\n", arr.GroupBy(item => (i++) / 3).Select(ig => string.Concat(ig.Select(el => $" {el,-35}")))) + "\n```").ConfigureAwait(false);
+ await e.Channel.SendMessage("```xl\n" + string.Join("\n", arr.GroupBy(item => (i++) / 3).Select(ig => string.Concat(ig.Select(el => $"ā¢ {el,-35}")))) + "\n```").ConfigureAwait(false);
});
cgb.CreateCommand(Prefix + "inrole")
@@ -134,7 +134,7 @@ namespace NadekoBot.Modules.Utility
.Do(async e => await e.Channel.SendMessage("This server's ID is " + e.Server.Id).ConfigureAwait(false));
cgb.CreateCommand(Prefix + "roles")
- .Description("List all roles on this server or a single user if specified.")
+ .Description($"List all roles on this server or a single user if specified. | `{Prefix}roles`")
.Parameter("user", ParameterType.Unparsed)
.Do(async e =>
{
@@ -143,10 +143,10 @@ namespace NadekoBot.Modules.Utility
var usr = e.Server.FindUsers(e.GetArg("user")).FirstOrDefault();
if (usr == null) return;
- await e.Channel.SendMessage($"`List of roles for **{usr.Name}**:` \n " + string.Join("\n ", usr.Roles)).ConfigureAwait(false);
+ await e.Channel.SendMessage($"`List of roles for **{usr.Name}**:` \nā¢ " + string.Join("\nā¢ ", usr.Roles)).ConfigureAwait(false);
return;
}
- await e.Channel.SendMessage("`List of roles:` \n " + string.Join("\n ", e.Server.Roles)).ConfigureAwait(false);
+ await e.Channel.SendMessage("`List of roles:` \nā¢ " + string.Join("\nā¢ ", e.Server.Roles)).ConfigureAwait(false);
});
diff --git a/NadekoBot/NadekoBot.cs b/NadekoBot/NadekoBot.cs
index a1299d97..b706b95d 100644
--- a/NadekoBot/NadekoBot.cs
+++ b/NadekoBot/NadekoBot.cs
@@ -121,8 +121,8 @@ namespace NadekoBot
LogLevel = LogSeverity.Warning,
LogHandler = (s, e) =>
Console.WriteLine($"Severity: {e.Severity}" +
- $"Message: {e.Message}" +
- $"ExceptionMessage: {e.Exception?.Message ?? "-"}"),
+ $"ExceptionMessage: {e.Exception?.Message ?? "-"}" +
+ $"Message: {e.Message}"),
});
//create a command service
@@ -197,7 +197,7 @@ namespace NadekoBot
return;
}
#if NADEKO_RELEASE
- await Task.Delay(120000).ConfigureAwait(false);
+ await Task.Delay(150000).ConfigureAwait(false);
#else
await Task.Delay(1000).ConfigureAwait(false);
#endif
diff --git a/NadekoBot/NadekoBot.csproj b/NadekoBot/NadekoBot.csproj
index d332dad2..341f1850 100644
--- a/NadekoBot/NadekoBot.csproj
+++ b/NadekoBot/NadekoBot.csproj
@@ -161,22 +161,6 @@
Falselib\ScaredFingers.UnitsConversion.dll
-
- ..\packages\sqlite-net-pcl.1.1.2\lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10\SQLite-net.dll
- True
-
-
- ..\packages\SQLitePCL.bundle_green.0.9.2\lib\net45\SQLitePCL.batteries.dll
- True
-
-
- ..\packages\SQLitePCL.raw.0.9.2\lib\net45\SQLitePCL.raw.dll
- True
-
-
- ..\packages\SQLitePCL.plugin.sqlite3.net45.0.9.2\lib\net45\SQLitePCLPlugin_esqlite3.dll
- True
-
@@ -217,6 +201,7 @@
+
@@ -231,7 +216,7 @@
-
+
diff --git a/NadekoBot/SQLite.cs b/NadekoBot/SQLite.cs
new file mode 100644
index 00000000..e74447f6
--- /dev/null
+++ b/NadekoBot/SQLite.cs
@@ -0,0 +1,3278 @@
+//
+// Copyright (c) 2009-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.
+//
+#if WINDOWS_PHONE && !USE_WP8_NATIVE_SQLITE
+#define USE_CSHARP_SQLITE
+#endif
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Threading;
+
+#if USE_CSHARP_SQLITE
+using Sqlite3 = Community.CsharpSqlite.Sqlite3;
+using Sqlite3DatabaseHandle = Community.CsharpSqlite.Sqlite3.sqlite3;
+using Sqlite3Statement = Community.CsharpSqlite.Sqlite3.Vdbe;
+#elif USE_WP8_NATIVE_SQLITE
+using Sqlite3 = Sqlite.Sqlite3;
+using Sqlite3DatabaseHandle = Sqlite.Database;
+using Sqlite3Statement = Sqlite.Statement;
+#else
+using Sqlite3DatabaseHandle = System.IntPtr;
+using Sqlite3Statement = System.IntPtr;
+#endif
+
+namespace SQLite
+{
+ public class SQLiteException : Exception
+ {
+ public SQLite3.Result Result { get; private set; }
+
+ protected SQLiteException (SQLite3.Result r,string message) : base(message)
+ {
+ Result = r;
+ }
+
+ public static SQLiteException New (SQLite3.Result r, string message)
+ {
+ return new SQLiteException (r, message);
+ }
+ }
+
+ public class NotNullConstraintViolationException : SQLiteException
+ {
+ public IEnumerable Columns { get; protected set; }
+
+ protected NotNullConstraintViolationException (SQLite3.Result r, string message)
+ : this (r, message, null, null)
+ {
+
+ }
+
+ protected NotNullConstraintViolationException (SQLite3.Result r, string message, TableMapping mapping, object obj)
+ : base (r, message)
+ {
+ if (mapping != null && obj != null) {
+ this.Columns = from c in mapping.Columns
+ where c.IsNullable == false && c.GetValue (obj) == null
+ select c;
+ }
+ }
+
+ public static new NotNullConstraintViolationException New (SQLite3.Result r, string message)
+ {
+ return new NotNullConstraintViolationException (r, message);
+ }
+
+ public static NotNullConstraintViolationException New (SQLite3.Result r, string message, TableMapping mapping, object obj)
+ {
+ return new NotNullConstraintViolationException (r, message, mapping, obj);
+ }
+
+ public static NotNullConstraintViolationException New (SQLiteException exception, TableMapping mapping, object obj)
+ {
+ return new NotNullConstraintViolationException (exception.Result, exception.Message, mapping, obj);
+ }
+ }
+
+ [Flags]
+ public enum SQLiteOpenFlags {
+ ReadOnly = 1, ReadWrite = 2, Create = 4,
+ NoMutex = 0x8000, FullMutex = 0x10000,
+ SharedCache = 0x20000, PrivateCache = 0x40000,
+ ProtectionComplete = 0x00100000,
+ ProtectionCompleteUnlessOpen = 0x00200000,
+ ProtectionCompleteUntilFirstUserAuthentication = 0x00300000,
+ ProtectionNone = 0x00400000
+ }
+
+ [Flags]
+ public enum CreateFlags
+ {
+ None = 0,
+ ImplicitPK = 1, // create a primary key for field called 'Id' (Orm.ImplicitPkName)
+ ImplicitIndex = 2, // create an index for fields ending in 'Id' (Orm.ImplicitIndexSuffix)
+ AllImplicit = 3, // do both above
+
+ AutoIncPK = 4 // force PK field to be auto inc
+ }
+
+ ///
+ /// Represents an open connection to a SQLite database.
+ ///
+ public partial class SQLiteConnection : IDisposable
+ {
+ private bool _open;
+ private TimeSpan _busyTimeout;
+ private Dictionary _mappings = null;
+ private Dictionary _tables = null;
+ private System.Diagnostics.Stopwatch _sw;
+ private long _elapsedMilliseconds = 0;
+
+ private int _transactionDepth = 0;
+ private Random _rand = new Random ();
+
+ public Sqlite3DatabaseHandle Handle { get; private set; }
+ internal static readonly Sqlite3DatabaseHandle NullHandle = default(Sqlite3DatabaseHandle);
+
+ public string DatabasePath { get; private set; }
+
+ public bool TimeExecution { get; set; }
+
+ public bool Trace { get; set; }
+
+ public bool StoreDateTimeAsTicks { get; private set; }
+
+ ///
+ /// Constructs a new SQLiteConnection and opens a SQLite database specified by databasePath.
+ ///
+ ///
+ /// Specifies the path to the database file.
+ ///
+ ///
+ /// Specifies whether to store DateTime properties as ticks (true) or strings (false). You
+ /// absolutely do want to store them as Ticks in all new projects. The default of false is
+ /// only here for backwards compatibility. There is a *significant* speed advantage, with no
+ /// down sides, when setting storeDateTimeAsTicks = true.
+ ///
+ public SQLiteConnection (string databasePath, bool storeDateTimeAsTicks = false)
+ : this (databasePath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create, storeDateTimeAsTicks)
+ {
+ }
+
+ ///
+ /// Constructs a new SQLiteConnection and opens a SQLite database specified by databasePath.
+ ///
+ ///
+ /// Specifies the path to the database file.
+ ///
+ ///
+ /// Specifies whether to store DateTime properties as ticks (true) or strings (false). You
+ /// absolutely do want to store them as Ticks in all new projects. The default of false is
+ /// only here for backwards compatibility. There is a *significant* speed advantage, with no
+ /// down sides, when setting storeDateTimeAsTicks = true.
+ ///
+ public SQLiteConnection (string databasePath, SQLiteOpenFlags openFlags, bool storeDateTimeAsTicks = false)
+ {
+ if (string.IsNullOrEmpty (databasePath))
+ throw new ArgumentException ("Must be specified", "databasePath");
+
+ DatabasePath = databasePath;
+
+#if NETFX_CORE
+ SQLite3.SetDirectory(/*temp directory type*/2, Windows.Storage.ApplicationData.Current.TemporaryFolder.Path);
+#endif
+
+ Sqlite3DatabaseHandle handle;
+
+#if SILVERLIGHT || USE_CSHARP_SQLITE
+ var r = SQLite3.Open (databasePath, out handle, (int)openFlags, IntPtr.Zero);
+#else
+ // open using the byte[]
+ // in the case where the path may include Unicode
+ // force open to using UTF-8 using sqlite3_open_v2
+ var databasePathAsBytes = GetNullTerminatedUtf8 (DatabasePath);
+ var r = SQLite3.Open (databasePathAsBytes, out handle, (int) openFlags, IntPtr.Zero);
+#endif
+
+ Handle = handle;
+ if (r != SQLite3.Result.OK) {
+ throw SQLiteException.New (r, String.Format ("Could not open database file: {0} ({1})", DatabasePath, r));
+ }
+ _open = true;
+
+ StoreDateTimeAsTicks = storeDateTimeAsTicks;
+
+ BusyTimeout = TimeSpan.FromSeconds (0.1);
+ }
+
+ static SQLiteConnection ()
+ {
+ if (_preserveDuringLinkMagic) {
+ var ti = new ColumnInfo ();
+ ti.Name = "magic";
+ }
+ }
+
+ public void EnableLoadExtension(int onoff)
+ {
+ SQLite3.Result r = SQLite3.EnableLoadExtension(Handle, onoff);
+ if (r != SQLite3.Result.OK) {
+ string msg = SQLite3.GetErrmsg (Handle);
+ throw SQLiteException.New (r, msg);
+ }
+ }
+
+ static byte[] GetNullTerminatedUtf8 (string s)
+ {
+ var utf8Length = System.Text.Encoding.UTF8.GetByteCount (s);
+ var bytes = new byte [utf8Length + 1];
+ utf8Length = System.Text.Encoding.UTF8.GetBytes(s, 0, s.Length, bytes, 0);
+ return bytes;
+ }
+
+ ///
+ /// Used to list some code that we want the MonoTouch linker
+ /// to see, but that we never want to actually execute.
+ ///
+ static bool _preserveDuringLinkMagic;
+
+ ///
+ /// Sets a busy handler to sleep the specified amount of time when a table is locked.
+ /// The handler will sleep multiple times until a total time of has accumulated.
+ ///
+ public TimeSpan BusyTimeout {
+ get { return _busyTimeout; }
+ set {
+ _busyTimeout = value;
+ if (Handle != NullHandle) {
+ SQLite3.BusyTimeout (Handle, (int)_busyTimeout.TotalMilliseconds);
+ }
+ }
+ }
+
+ ///
+ /// Returns the mappings from types to tables that the connection
+ /// currently understands.
+ ///
+ public IEnumerable TableMappings {
+ get {
+ return _tables != null ? _tables.Values : Enumerable.Empty ();
+ }
+ }
+
+ ///
+ /// Retrieves the mapping that is automatically generated for the given type.
+ ///
+ ///
+ /// The type whose mapping to the database is returned.
+ ///
+ ///
+ /// Optional flags allowing implicit PK and indexes based on naming conventions
+ ///
+ ///
+ /// The mapping represents the schema of the columns of the database and contains
+ /// methods to set and get properties of objects.
+ ///
+ public TableMapping GetMapping(Type type, CreateFlags createFlags = CreateFlags.None)
+ {
+ if (_mappings == null) {
+ _mappings = new Dictionary ();
+ }
+ TableMapping map;
+ if (!_mappings.TryGetValue (type.FullName, out map)) {
+ map = new TableMapping (type, createFlags);
+ _mappings [type.FullName] = map;
+ }
+ return map;
+ }
+
+ ///
+ /// Retrieves the mapping that is automatically generated for the given type.
+ ///
+ ///
+ /// The mapping represents the schema of the columns of the database and contains
+ /// methods to set and get properties of objects.
+ ///
+ public TableMapping GetMapping ()
+ {
+ return GetMapping (typeof (T));
+ }
+
+ private struct IndexedColumn
+ {
+ public int Order;
+ public string ColumnName;
+ }
+
+ private struct IndexInfo
+ {
+ public string IndexName;
+ public string TableName;
+ public bool Unique;
+ public List Columns;
+ }
+
+ ///
+ /// Executes a "drop table" on the database. This is non-recoverable.
+ ///
+ public int DropTable()
+ {
+ var map = GetMapping (typeof (T));
+
+ var query = string.Format("drop table if exists \"{0}\"", map.TableName);
+
+ return Execute (query);
+ }
+
+ ///
+ /// Executes a "create table if not exists" on the database. It also
+ /// creates any specified indexes on the columns of the table. It uses
+ /// a schema automatically generated from the specified type. You can
+ /// later access this schema by calling GetMapping.
+ ///
+ ///
+ /// The number of entries added to the database schema.
+ ///
+ public int CreateTable(CreateFlags createFlags = CreateFlags.None)
+ {
+ return CreateTable(typeof (T), createFlags);
+ }
+
+ ///
+ /// Executes a "create table if not exists" on the database. It also
+ /// creates any specified indexes on the columns of the table. It uses
+ /// a schema automatically generated from the specified type. You can
+ /// later access this schema by calling GetMapping.
+ ///
+ /// Type to reflect to a database table.
+ /// Optional flags allowing implicit PK and indexes based on naming conventions.
+ ///
+ /// The number of entries added to the database schema.
+ ///
+ public int CreateTable(Type ty, CreateFlags createFlags = CreateFlags.None)
+ {
+ if (_tables == null) {
+ _tables = new Dictionary ();
+ }
+ TableMapping map;
+ if (!_tables.TryGetValue (ty.FullName, out map)) {
+ map = GetMapping (ty, createFlags);
+ _tables.Add (ty.FullName, map);
+ }
+ var query = "create table if not exists \"" + map.TableName + "\"(\n";
+
+ var decls = map.Columns.Select (p => Orm.SqlDecl (p, StoreDateTimeAsTicks));
+ var decl = string.Join (",\n", decls.ToArray ());
+ query += decl;
+ query += ")";
+
+ var count = Execute (query);
+
+ if (count == 0) { //Possible bug: This always seems to return 0?
+ // Table already exists, migrate it
+ MigrateTable (map);
+ }
+
+ var indexes = new Dictionary ();
+ foreach (var c in map.Columns) {
+ foreach (var i in c.Indices) {
+ var iname = i.Name ?? map.TableName + "_" + c.Name;
+ IndexInfo iinfo;
+ if (!indexes.TryGetValue (iname, out iinfo)) {
+ iinfo = new IndexInfo {
+ IndexName = iname,
+ TableName = map.TableName,
+ Unique = i.Unique,
+ Columns = new List ()
+ };
+ indexes.Add (iname, iinfo);
+ }
+
+ if (i.Unique != iinfo.Unique)
+ throw new Exception ("All the columns in an index must have the same value for their Unique property");
+
+ iinfo.Columns.Add (new IndexedColumn {
+ Order = i.Order,
+ ColumnName = c.Name
+ });
+ }
+ }
+
+ foreach (var indexName in indexes.Keys) {
+ var index = indexes[indexName];
+ var columns = index.Columns.OrderBy(i => i.Order).Select(i => i.ColumnName).ToArray();
+ count += CreateIndex(indexName, index.TableName, columns, index.Unique);
+ }
+
+ return count;
+ }
+
+ ///
+ /// Creates an index for the specified table and columns.
+ ///
+ /// Name of the index to create
+ /// Name of the database table
+ /// An array of column names to index
+ /// Whether the index should be unique
+ public int CreateIndex(string indexName, string tableName, string[] columnNames, bool unique = false)
+ {
+ const string sqlFormat = "create {2} index if not exists \"{3}\" on \"{0}\"(\"{1}\")";
+ var sql = String.Format(sqlFormat, tableName, string.Join ("\", \"", columnNames), unique ? "unique" : "", indexName);
+ return Execute(sql);
+ }
+
+ ///
+ /// Creates an index for the specified table and column.
+ ///
+ /// Name of the index to create
+ /// Name of the database table
+ /// Name of the column to index
+ /// Whether the index should be unique
+ public int CreateIndex(string indexName, string tableName, string columnName, bool unique = false)
+ {
+ return CreateIndex(indexName, tableName, new string[] { columnName }, unique);
+ }
+
+ ///
+ /// Creates an index for the specified table and column.
+ ///
+ /// Name of the database table
+ /// Name of the column to index
+ /// Whether the index should be unique
+ public int CreateIndex(string tableName, string columnName, bool unique = false)
+ {
+ return CreateIndex(tableName + "_" + columnName, tableName, columnName, unique);
+ }
+
+ ///
+ /// Creates an index for the specified table and columns.
+ ///
+ /// Name of the database table
+ /// An array of column names to index
+ /// Whether the index should be unique
+ public int CreateIndex(string tableName, string[] columnNames, bool unique = false)
+ {
+ return CreateIndex(tableName + "_" + string.Join ("_", columnNames), tableName, columnNames, unique);
+ }
+
+ ///
+ /// Creates an index for the specified object property.
+ /// e.g. CreateIndex(c => c.Name);
+ ///
+ /// Type to reflect to a database table.
+ /// Property to index
+ /// Whether the index should be unique
+ public void CreateIndex(Expression> property, bool unique = false)
+ {
+ MemberExpression mx;
+ if (property.Body.NodeType == ExpressionType.Convert)
+ {
+ mx = ((UnaryExpression)property.Body).Operand as MemberExpression;
+ }
+ else
+ {
+ mx= (property.Body as MemberExpression);
+ }
+ var propertyInfo = mx.Member as PropertyInfo;
+ if (propertyInfo == null)
+ {
+ throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
+ }
+
+ var propName = propertyInfo.Name;
+
+ var map = GetMapping();
+ var colName = map.FindColumnWithPropertyName(propName).Name;
+
+ CreateIndex(map.TableName, colName, unique);
+ }
+
+ public class ColumnInfo
+ {
+// public int cid { get; set; }
+
+ [Column ("name")]
+ public string Name { get; set; }
+
+// [Column ("type")]
+// public string ColumnType { get; set; }
+
+ public int notnull { get; set; }
+
+// public string dflt_value { get; set; }
+
+// public int pk { get; set; }
+
+ public override string ToString ()
+ {
+ return Name;
+ }
+ }
+
+ public List GetTableInfo (string tableName)
+ {
+ var query = "pragma table_info(\"" + tableName + "\")";
+ return Query (query);
+ }
+
+ void MigrateTable (TableMapping map)
+ {
+ var existingCols = GetTableInfo (map.TableName);
+
+ var toBeAdded = new List ();
+
+ foreach (var p in map.Columns) {
+ var found = false;
+ foreach (var c in existingCols) {
+ found = (string.Compare (p.Name, c.Name, StringComparison.OrdinalIgnoreCase) == 0);
+ if (found)
+ break;
+ }
+ if (!found) {
+ toBeAdded.Add (p);
+ }
+ }
+
+ foreach (var p in toBeAdded) {
+ var addCol = "alter table \"" + map.TableName + "\" add column " + Orm.SqlDecl (p, StoreDateTimeAsTicks);
+ Execute (addCol);
+ }
+ }
+
+ ///
+ /// Creates a new SQLiteCommand. Can be overridden to provide a sub-class.
+ ///
+ ///
+ protected virtual SQLiteCommand NewCommand ()
+ {
+ return new SQLiteCommand (this);
+ }
+
+ ///
+ /// Creates a new SQLiteCommand given the command text with arguments. Place a '?'
+ /// in the command text for each of the arguments.
+ ///
+ ///
+ /// The fully escaped SQL.
+ ///
+ ///
+ /// Arguments to substitute for the occurences of '?' in the command text.
+ ///
+ ///
+ /// A
+ ///
+ public SQLiteCommand CreateCommand (string cmdText, params object[] ps)
+ {
+ if (!_open)
+ throw SQLiteException.New (SQLite3.Result.Error, "Cannot create commands from unopened database");
+
+ var cmd = NewCommand ();
+ cmd.CommandText = cmdText;
+ foreach (var o in ps) {
+ cmd.Bind (o);
+ }
+ return cmd;
+ }
+
+ ///
+ /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'
+ /// in the command text for each of the arguments and then executes that command.
+ /// Use this method instead of Query when you don't expect rows back. Such cases include
+ /// INSERTs, UPDATEs, and DELETEs.
+ /// You can set the Trace or TimeExecution properties of the connection
+ /// to profile execution.
+ ///
+ ///
+ /// The fully escaped SQL.
+ ///
+ ///
+ /// Arguments to substitute for the occurences of '?' in the query.
+ ///
+ ///
+ /// The number of rows modified in the database as a result of this execution.
+ ///
+ public int Execute (string query, params object[] args)
+ {
+ var cmd = CreateCommand (query, args);
+
+ if (TimeExecution) {
+ if (_sw == null) {
+ _sw = new Stopwatch ();
+ }
+ _sw.Reset ();
+ _sw.Start ();
+ }
+
+ var r = cmd.ExecuteNonQuery ();
+
+ if (TimeExecution) {
+ _sw.Stop ();
+ _elapsedMilliseconds += _sw.ElapsedMilliseconds;
+ Debug.WriteLine (string.Format ("Finished in {0} ms ({1:0.0} s total)", _sw.ElapsedMilliseconds, _elapsedMilliseconds / 1000.0));
+ }
+
+ return r;
+ }
+
+ public T ExecuteScalar (string query, params object[] args)
+ {
+ var cmd = CreateCommand (query, args);
+
+ if (TimeExecution) {
+ if (_sw == null) {
+ _sw = new Stopwatch ();
+ }
+ _sw.Reset ();
+ _sw.Start ();
+ }
+
+ var r = cmd.ExecuteScalar ();
+
+ if (TimeExecution) {
+ _sw.Stop ();
+ _elapsedMilliseconds += _sw.ElapsedMilliseconds;
+ Debug.WriteLine (string.Format ("Finished in {0} ms ({1:0.0} s total)", _sw.ElapsedMilliseconds, _elapsedMilliseconds / 1000.0));
+ }
+
+ return r;
+ }
+
+ ///
+ /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'
+ /// in the command text for each of the arguments and then executes that command.
+ /// It returns each row of the result using the mapping automatically generated for
+ /// the given type.
+ ///
+ ///
+ /// The fully escaped SQL.
+ ///
+ ///
+ /// Arguments to substitute for the occurences of '?' in the query.
+ ///
+ ///
+ /// An enumerable with one result for each row returned by the query.
+ ///
+ public List Query (string query, params object[] args) where T : new()
+ {
+ var cmd = CreateCommand (query, args);
+ return cmd.ExecuteQuery ();
+ }
+
+ ///
+ /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'
+ /// in the command text for each of the arguments and then executes that command.
+ /// It returns each row of the result using the mapping automatically generated for
+ /// the given type.
+ ///
+ ///
+ /// The fully escaped SQL.
+ ///
+ ///
+ /// Arguments to substitute for the occurences of '?' in the query.
+ ///
+ ///
+ /// An enumerable with one result for each row returned by the query.
+ /// The enumerator will call sqlite3_step on each call to MoveNext, so the database
+ /// connection must remain open for the lifetime of the enumerator.
+ ///
+ public IEnumerable DeferredQuery(string query, params object[] args) where T : new()
+ {
+ var cmd = CreateCommand(query, args);
+ return cmd.ExecuteDeferredQuery();
+ }
+
+ ///
+ /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'
+ /// in the command text for each of the arguments and then executes that command.
+ /// It returns each row of the result using the specified mapping. This function is
+ /// only used by libraries in order to query the database via introspection. It is
+ /// normally not used.
+ ///
+ ///
+ /// A to use to convert the resulting rows
+ /// into objects.
+ ///
+ ///
+ /// The fully escaped SQL.
+ ///
+ ///
+ /// Arguments to substitute for the occurences of '?' in the query.
+ ///
+ ///
+ /// An enumerable with one result for each row returned by the query.
+ ///
+ public List