diff --git a/Discord.Net b/Discord.Net
index b9f76733..d2229228 160000
--- a/Discord.Net
+++ b/Discord.Net
@@ -1 +1 @@
-Subproject commit b9f767337d2b7c07ed76eb83c3bc5030109d5238
+Subproject commit d2229228b92117899d65cd549a1f2853057b255b
diff --git a/NuGet.Config b/NuGet.Config
index d40268d3..e482807c 100644
--- a/NuGet.Config
+++ b/NuGet.Config
@@ -2,5 +2,6 @@
+
diff --git a/README.md b/README.md
index c0df0727..ae4aa579 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,12 @@
![img](https://ci.appveyor.com/api/projects/status/gmu6b3ltc80hr3k9?svg=true)
-[![Discord](https://discordapp.com/api/guilds/117523346618318850/widget.png)](https://discord.gg/0ehQwTK2RBjAxzEY)
+[![Discord](https://discordapp.com/api/guilds/117523346618318850/widget.png)](https://discord.gg/nadekobot)
[![Documentation Status](https://readthedocs.org/projects/nadekobot/badge/?version=latest)](http://nadekobot.readthedocs.io/en/latest/?badge=latest)
-# NadekoBot
-[![nadeko1](https://cdn.discordapp.com/attachments/155726317222887425/252095170676391936/A1.jpg)](https://discordapp.com/oauth2/authorize?client_id=170254782546575360&scope=bot&permissions=66186303)
-[![nadeko2](https://cdn.discordapp.com/attachments/155726317222887425/252095207514832896/A2.jpg)](http://nadekobot.readthedocs.io/en/latest/Commands%20List/)
-
-##For Update, Help and Guidlines
-
-`Follow me on twitter for updates. | Join my Discord server if you need help. | Read the Docs for hosting guides.`
-
-[![twitter](https://cdn.discordapp.com/attachments/155726317222887425/252192520094613504/twiter_banner.JPG)](https://twitter.com/TheNadekoBot) [![discord](https://cdn.discordapp.com/attachments/155726317222887425/252192415673221122/discord_banner.JPG)](https://discord.gg/0ehQwTK2RBjAxzEY) [![Wiki](https://cdn.discordapp.com/attachments/155726317222887425/252192472849973250/read_the_docs_banner.JPG)](http://nadekobot.readthedocs.io/en/latest/)
+[![nadeko0](https://cdn.discordapp.com/attachments/266240393639755778/281920716809699328/part1.png)](http://nadekobot.xyz)
+[![nadeko1](https://cdn.discordapp.com/attachments/266240393639755778/281920134967328768/part2.png)](https://discordapp.com/oauth2/authorize?client_id=170254782546575360&scope=bot&permissions=66186303)
+[![nadeko2](https://cdn.discordapp.com/attachments/266240393639755778/281920161311883264/part3.png)](http://nadekobot.readthedocs.io/en/latest/Commands%20List/)
+## For Updates, Help and Guidelines
+| [![twitter](https://cdn.discordapp.com/attachments/155726317222887425/252192520094613504/twiter_banner.JPG)](https://twitter.com/TheNadekoBot) | [![discord](https://cdn.discordapp.com/attachments/266240393639755778/281920766490968064/discord.png)](https://discord.gg/nadekobot) | [![Wiki](https://cdn.discordapp.com/attachments/266240393639755778/281920793330581506/datcord.png)](http://nadekobot.readthedocs.io/en/latest/)
+| --- | --- | --- |
+| **Follow me on Twitter.** | **Join my Discord server for help.** | **Read the Docs for self-hosting.** |
diff --git a/docs/Commands List.md b/docs/Commands List.md
index f435ab6d..6c47c7ed 100644
--- a/docs/Commands List.md
+++ b/docs/Commands List.md
@@ -1,6 +1,6 @@
-You can support the project on patreon: or paypal:
+You can support the project on patreon: or paypal:
-##Table Of Contents
+##Table of contents
- [Help](#help)
- [Administration](#administration)
- [ClashOfClans](#clashofclans)
@@ -16,71 +16,18 @@ You can support the project on patreon: or paypa
### Administration
-Command and aliases | Description | Usage
+Commands and aliases | Description | Usage
----------------|--------------|-------
-`.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. **Requires ManageRoles server permission.** **Requires ManageChannels server permission.** | `.voice+text`
-`.cleanvplust` `.cv+t` | Deletes all text channels ending in `-voice` for which voicechannels are not found. Use at your own risk. **Requires ManageChannels server permission.** **Requires ManageRoles server permission.** | `.cleanv+t`
-`.greetdel` `.grdel` | Sets the time it takes (in seconds) for greet messages to be auto-deleted. Set 0 to disable automatic deletion. **Requires ManageServer server permission.** | `.greetdel 0` or `.greetdel 30`
-`.greet` | Toggles anouncements on the current channel when someone joins the server. **Requires ManageServer server permission.** | `.greet`
-`.greetmsg` | Sets a new join announcement message which will be shown in the server's channel. Type %user% if you want to mention the new member. Using it with no message will show the current greet message. **Requires ManageServer server permission.** | `.greetmsg Welcome, %user%.`
-`.greetdm` | Toggles whether the greet messages will be sent in a DM (This is separate from greet - you can have both, any or neither enabled). **Requires ManageServer server permission.** | `.greetdm`
-`.greetdmmsg` | Sets a new join announcement message which will be sent to the user who joined. Type %user% if you want to mention the new member. Using it with no message will show the current DM greet message. **Requires ManageServer server permission.** | `.greetdmmsg Welcome to the server, %user%`.
-`.bye` | Toggles anouncements on the current channel when someone leaves the server. **Requires ManageServer server permission.** | `.bye`
-`.byemsg` | Sets a new leave announcement message. Type %user% if you want to show the name the user who left. Type %id% to show id. Using this command with no message will show the current bye message. **Requires ManageServer server permission.** | `.byemsg %user% has left.`
-`.byedel` | Sets the time it takes (in seconds) for bye messages to be auto-deleted. Set 0 to disable automatic deletion. **Requires ManageServer server permission.** | `.byedel 0` or `.byedel 30`
-`.leave` | Makes Nadeko leave the server. Either name or id required. **Bot Owner only.** | `.leave 123123123331`
-`.die` | Shuts the bot down. **Bot Owner only.** | `.die`
-`.setname` `.newnm` | Gives the bot a new name. **Bot Owner only.** | `.newnm BotName`
-`.setavatar` `.setav` | Sets a new avatar image for the NadekoBot. Argument is a direct link to an image. **Bot Owner only.** | `.setav http://i.imgur.com/xTG3a1I.jpg`
-`.setgame` | Sets the bots game. **Bot Owner only.** | `.setgame with snakes`
-`.setstream` | Sets the bots stream. First argument is the twitch link, second argument is stream name. **Bot Owner only.** | `.setstream TWITCHLINK Hello`
-`.send` | Sends a message to someone on a different server through the bot. Separate server and channel/user ids with `|` and prepend channel id with `c:` and user id with `u:`. **Bot Owner only.** | `.send serverid|c:channelid message` or `.send serverid|u:userid message`
-`.announce` | Sends a message to all servers' general channel bot is connected to. **Bot Owner only.** | `.announce Useless spam`
-`.adsarm` | Toggles the automatic deletion of confirmations for .iam and .iamn commands. **Requires ManageMessages server permission.** | `.adsarm`
-`.asar` | Adds a role to the list of self-assignable roles. **Requires ManageRoles server permission.** | `.asar Gamer`
-`.rsar` | Removes a specified role from the list of self-assignable roles. **Requires ManageRoles server permission.** | `.rsar`
-`.lsar` | Lists all self-assignable roles. | `.lsar`
-`.togglexclsar` `.tesar` | Toggles whether the self-assigned roles are exclusive. (So that any person can have only one of the self assignable roles) **Requires ManageRoles server permission.** | `.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`
-`.slowmode` | Toggles slowmode. Disable by specifying no parameters. To enable, specify a number of messages each user can send, and an interval in seconds. For example 1 message every 5 seconds. **Requires ManageMessages server permission.** | `.slowmode 1 5` or `.slowmode`
-`.rotateplaying` `.ropl` | Toggles rotation of playing status of the dynamic strings you previously specified. **Bot Owner only.** | `.ropl`
-`.addplaying` `.adpl` | Adds a specified string to the list of playing strings to rotate. Supported placeholders: %servers%, %users%, %playing%, %queued% **Bot Owner only.** | `.adpl`
-`.listplaying` `.lipl` | Lists all playing statuses with their corresponding number. **Bot Owner only.** | `.lipl`
-`.removeplaying` `.rmpl` `.repl` | Removes a playing string on a given number. **Bot Owner only.** | `.rmpl`
-`.setmuterole` | Sets a name of the role which will be assigned to people who should be muted. Default is nadeko-mute. **Requires ManageRoles server permission.** | `.setmuterole Silenced`
-`.mute` | Mutes a mentioned user both from speaking and chatting. **Requires ManageRoles server permission.** **Requires MuteMembers server permission.** | `.mute @Someone`
-`.unmute` | Unmutes a mentioned user previously muted with `.mute` command. **Requires ManageRoles server permission.** **Requires MuteMembers server permission.** | `.unmute @Someone`
-`.chatmute` | Prevents a mentioned user from chatting in text channels. **Requires ManageRoles server permission.** | `.chatmute @Someone`
-`.chatunmute` | Removes a mute role previously set on a mentioned user with `.chatmute` which prevented him from chatting in text channels. **Requires ManageRoles server permission.** | `.chatunmute @Someone`
-`.voicemute` | Prevents a mentioned user from speaking in voice channels. **Requires MuteMembers server permission.** | `.voicemute @Someone`
-`.voiceunmute` | Gives a previously voice-muted user a permission to speak. **Requires MuteMembers server permission.** | `.voiceunmute @Someguy`
-`.migratedata` | Migrate data from old bot configuration **Bot Owner only.** | `.migratedata`
-`.repeatinvoke` `.repinv` | Immediately shows the repeat message and restarts the timer. **Requires ManageMessages server permission.** | `.repinv`
-`.repeat` | Repeat a message every X minutes. If no parameters are specified, repeat is disabled. **Requires ManageMessages server permission.** | `.repeat 5 Hello there`
-`.logserver` | Enables or Disables ALL log events. If enabled, all log events will log to this channel. **Requires Administrator server permission.** **Bot Owner only.** | `.logserver enable` or `.logserver disable`
-`.logignore` | Toggles whether the .logserver command ignores this channel. Useful if you have hidden admin channel and public log channel. **Requires Administrator server permission.** **Bot Owner only.** | `.logignore`
-`.logevents` | Shows a list of all events you can subscribe to with `.log` **Requires Administrator server permission.** **Bot Owner only.** | `.logevents`
-`.log` | Toggles logging event. Disables it if it's active anywhere on the server. Enables if it's not active. Use `.logevents` to see a list of all events you can subscribe to. **Requires Administrator server permission.** **Bot Owner only.** | `.log userpresence` or `.log userbanned`
-`.fwmsgs` | Toggles forwarding of non-command messages sent to bot's DM to the bot owners **Bot Owner only.** | `.fwmsgs`
-`.fwtoall` | Toggles whether messages will be forwarded to all bot owners or only to the first one specified in the credentials.json **Bot Owner only.** | `.fwtoall`
-`.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. **Bot Owner only.** | `.scsc`
-`.jcsc` | Joins current channel to an instance of cross server channel using the token. **Requires ManageServer server permission.** | `.jcsc TokenHere`
-`.lcsc` | Leaves Cross server channel instance from this channel. **Requires ManageServer server permission.** | `.lcsc`
-`.autoassignrole` `.aar` | Automaticaly assigns a specified role to every user who joins the server. **Requires ManageRoles server permission.** | `.aar` to disable, `.aar Role Name` to enable
-`.antiraid` | Sets an anti-raid protection on the server. First argument is number of people which will trigger the protection. Second one is a time interval in which that number of people needs to join in order to trigger the protection, and third argument is punishment for those people (Kick, Ban, Mute) **Requires Administrator server permission.** | `.antiraid 5 20 Kick`
-`.antispam` | Stops people from repeating same message X times in a row. You can specify to either mute, kick or ban the offenders. **Requires Administrator server permission.** | `.antispam 3 Mute` or `.antispam 4 Kick` or `.antispam 6 Ban`
-`.resetperms` | Resets BOT's permissions module on this server to the default value. **Requires Administrator server permission.** | `.resetperms`
-`.delmsgoncmd` | Toggles the automatic deletion of user's successful command message to prevent chat flood. **Requires Administrator server permission.** | `.delmsgoncmd`
+`.resetperms` | Resets the bot's permissions module on this server to the default value. **Requires Administrator server permission.** | `.resetperms`
+`.resetglobalperms` | Resets global permissions set by bot owner. **Bot owner only** | `.resetglobalperms`
+`.delmsgoncmd` | Toggles the automatic deletion of the user's successful command message to prevent chat flood. **Requires Administrator server permission.** | `.delmsgoncmd`
`.setrole` `.sr` | Sets a role for a given user. **Requires ManageRoles server permission.** | `.sr @User Guest`
`.removerole` `.rr` | Removes a role from a given user. **Requires ManageRoles server permission.** | `.rr @User Admin`
-`.renamerole` `.renr` | Renames a role. Roles you are renaming must be lower than bot's highest role. **Requires ManageRoles server permission.** | `.renr "First role" SecondRole`
+`.renamerole` `.renr` | Renames a role. The role you are renaming must be lower than bot's highest role. **Requires ManageRoles server permission.** | `.renr "First role" SecondRole`
`.removeallroles` `.rar` | Removes all roles from a mentioned user. **Requires ManageRoles server permission.** | `.rar @User`
`.createrole` `.cr` | Creates a role with a given name. **Requires ManageRoles server permission.** | `.cr Awesome Role`
+`.rolehoist` `.rh` | Toggles if this role is displayed in the sidebar or not **Requires ManageRoles server permission.** | `.rh Guests true` or `.rh "Space Wizards" true
`.rolecolor` `.rc` | Set a role's color to the hex or 0-255 rgb color value provided. **Requires ManageRoles server permission.** | `.rc Admin 255 200 100` or `.rc Admin ffba55`
-`.ban` `.b` | Bans a user by ID or name with an optional message. **Requires BanMembers server permission.** | `.b "@some Guy" Your behaviour is toxic.`
-`.softban` `.sb` | Bans and then unbans a user by ID or name with an optional message. **Requires KickMembers server permission.** **Requires ManageMessages server permission.** | `.sb "@some Guy" Your behaviour is toxic.`
-`.kick` `.k` | Kicks a mentioned user. **Requires KickMembers server permission.** | `.k "@some Guy" Your behaviour is toxic.`
`.deafen` `.deaf` | Deafens mentioned user or users. **Requires DeafenMembers server permission.** | `.deaf "@Someguy"` or `.deaf "@Someguy" "@Someguy"`
`.undeafen` `.undef` | Undeafens mentioned user or users. **Requires DeafenMembers server permission.** | `.undef "@Someguy"` or `.undef "@Someguy" "@Someguy"`
`.delvoichanl` `.dvch` | Deletes a voice channel with a given name. **Requires ManageChannels server permission.** | `.dvch VoiceChannelName`
@@ -89,20 +36,92 @@ Command and aliases | Description | Usage
`.creatxtchanl` `.ctch` | Creates a new text channel with a given name. **Requires ManageChannels server permission.** | `.ctch TextChannelName`
`.settopic` `.st` | Sets a topic on the current channel. **Requires ManageChannels server permission.** | `.st My new topic`
`.setchanlname` `.schn` | Changes the name of the current channel. **Requires ManageChannels server permission.** | `.schn NewName`
-`.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`
-`.savechat` | Saves a number of messages to a text file and sends it to you. **Bot Owner only.** | `.savechat 150`
-`.mentionrole` `.menro` | Mentions every person from the provided role or roles (separated by a ',') on this server. Requires you to have mention everyone permission. **Requires MentionEveryone server permission.** | `.menro RoleName`
-`.donators` | List of lovely people who donated to keep this project alive. | `.donators`
-`.donadd` | Add a donator to the database. **Bot Owner only.** | `.donadd Donate Amount`
+`.prune` `.clr` | `.prune` removes all Nadeko's messages in the last 100 messages. `.prune X` removes last `X` number of 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` number of 'Someone's' messages in the channel. | `.prune` or `.prune 5` or `.prune @Someone` or `.prune @Someone X`
+`.mentionrole` `.menro` | Mentions every person from the provided role or roles (separated by a ',') on this server. **Requires MentionEveryone server permission.** | `.menro RoleName`
+`.donators` | List of the lovely people who donated to keep this project alive. | `.donators`
+`.donadd` | Add a donator to the database. **Bot owner only** | `.donadd Donate Amount`
+`.autoassignrole` `.aar` | Automaticaly assigns a specified role to every user who joins the server. **Requires ManageRoles server permission.** | `.aar` to disable, `.aar Role Name` to enable
+`.gvc` | Toggles game voice channel feature in the voice channel you're currently in. Users who join the game voice channel will get automatically redirected to the voice channel with the name of their current game, if it exists. Can't move users to channels that the bot has no connect permission for. One per server. **Requires Administrator server permission.** | `.gvc`
+`.languageset` `.langset` | Sets this server's response language. If bot's response strings have been translated to that language, bot will use that language in this server. Reset by using `default` as the locale name. Provide no arguments to see currently set language. | `.langset de-DE ` or `.langset default`
+`.langsetdefault` `.langsetd` | Sets the bot's default response language. All servers which use a default locale will use this one. Setting to `default` will use the host's current culture. Provide no arguments to see currently set language. | `.langsetd en-US` or `.langsetd default`
+`.languageslist` `.langli` | List of languages for which translation (or part of it) exist atm. | `.langli`
+`.logserver` | Enables or Disables ALL log events. If enabled, all log events will log to this channel. **Requires Administrator server permission.** **Bot owner only** | `.logserver enable` or `.logserver disable`
+`.logignore` | Toggles whether the `.logserver` command ignores this channel. Useful if you have hidden admin channel and public log channel. **Requires Administrator server permission.** **Bot owner only** | `.logignore`
+`.logevents` | Shows a list of all events you can subscribe to with `.log` **Requires Administrator server permission.** **Bot owner only** | `.logevents`
+`.log` | Toggles logging event. Disables it if it is active anywhere on the server. Enables if it isn't active. Use `.logevents` to see a list of all events you can subscribe to. **Requires Administrator server permission.** **Bot owner only** | `.log userpresence` or `.log userbanned`
+`.migratedata` | Migrate data from old bot configuration **Bot owner only** | `.migratedata`
+`.setmuterole` | Sets a name of the role which will be assigned to people who should be muted. Default is nadeko-mute. **Requires ManageRoles server permission.** | `.setmuterole Silenced`
+`.mute` | Mutes a mentioned user both from speaking and chatting. You can also specify time in minutes (up to 1440) for how long the user should be muted. **Requires ManageRoles server permission.** **Requires MuteMembers server permission.** | `.mute @Someone` or `.mute 30 @Someone`
+`.unmute` | Unmutes a mentioned user previously muted with `.mute` command. **Requires ManageRoles server permission.** **Requires MuteMembers server permission.** | `.unmute @Someone`
+`.chatmute` | Prevents a mentioned user from chatting in text channels. **Requires ManageRoles server permission.** | `.chatmute @Someone`
+`.chatunmute` | Removes a mute role previously set on a mentioned user with `.chatmute` which prevented him from chatting in text channels. **Requires ManageRoles server permission.** | `.chatunmute @Someone`
+`.voicemute` | Prevents a mentioned user from speaking in voice channels. **Requires MuteMembers server permission.** | `.voicemute @Someone`
+`.voiceunmute` | Gives a previously voice-muted user a permission to speak. **Requires MuteMembers server permission.** | `.voiceunmute @Someguy`
+`.rotateplaying` `.ropl` | Toggles rotation of playing status of the dynamic strings you previously specified. **Bot owner only** | `.ropl`
+`.addplaying` `.adpl` | Adds a specified string to the list of playing strings to rotate. Supported placeholders: `%servers%`, `%users%`, `%playing%`, `%queued%`, `%time%`, `%shardid%`, `%shardcount%`, `%shardguilds%`. **Bot owner only** | `.adpl`
+`.listplaying` `.lipl` | Lists all playing statuses with their corresponding number. **Bot owner only** | `.lipl`
+`.removeplaying` `.rmpl` `.repl` | Removes a playing string on a given number. **Bot owner only** | `.rmpl`
+`.antiraid` | Sets an anti-raid protection on the server. First argument is number of people which will trigger the protection. Second one is a time interval in which that number of people needs to join in order to trigger the protection, and third argument is punishment for those people (Kick, Ban, Mute) **Requires Administrator server permission.** | `.antiraid 5 20 Kick`
+`.antispam` | Stops people from repeating same message X times in a row. You can specify to either mute, kick or ban the offenders. Max message count is 10. **Requires Administrator server permission.** | `.antispam 3 Mute` or `.antispam 4 Kick` or `.antispam 6 Ban`
+`.antispamignore` | Toggles whether antispam ignores current channel. Antispam must be enabled. | `.antispamignore`
+`.antilist` `.antilst` | Shows currently enabled protection features. | `.antilist`
+`.slowmode` | Toggles slowmode. Disable by specifying no parameters. To enable, specify a number of messages each user can send, and an interval in seconds. For example 1 message every 5 seconds. **Requires ManageMessages server permission.** | `.slowmode 1 5` or `.slowmode`
+`.slowmodewl` | Ignores a role or a user from the slowmode feature. **Requires ManageMessages server permission.** | `.slowmodewl SomeRole` or `.slowmodewl AdminDude`
+`.adsarm` | Toggles the automatic deletion of confirmations for `.iam` and `.iamn` commands. **Requires ManageMessages server permission.** | `.adsarm`
+`.asar` | Adds a role to the list of self-assignable roles. **Requires ManageRoles server permission.** | `.asar Gamer`
+`.rsar` | Removes a specified role from the list of self-assignable roles. **Requires ManageRoles server permission.** | `.rsar`
+`.lsar` | Lists all self-assignable roles. | `.lsar`
+`.togglexclsar` `.tesar` | Toggles whether the self-assigned roles are exclusive. (So that any person can have only one of the self assignable roles) **Requires ManageRoles server permission.** | `.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`
+`.scadd` | Adds a command to the list of commands which will be executed automatically in the current channel, in the order they were added in, by the bot when it startups up. **Bot owner only** | `.scadd .stats`
+`.sclist` | Lists all startup commands in the order they will be executed in. **Bot owner only** | `.sclist`
+`.wait` | Used only as a startup command. Waits a certain number of miliseconds before continuing the execution of the following startup commands. **Bot owner only** | `.wait 3000`
+`.scrm` | Removes a startup command with the provided command text. **Bot owner only** | `.scrm .stats`
+`.scclr` | Removes all startup commands. **Bot owner only** | `.scclr`
+`.fwmsgs` | Toggles forwarding of non-command messages sent to bot's DM to the bot owners **Bot owner only** | `.fwmsgs`
+`.fwtoall` | Toggles whether messages will be forwarded to all bot owners or only to the first one specified in the credentials.json file **Bot owner only** | `.fwtoall`
+`.connectshard` | Try (re)connecting a shard with a certain shardid when it dies. No one knows will it work. Keep an eye on the console for errors. **Bot owner only** | `.connectshard 2`
+`.leave` | Makes Nadeko leave the server. Either server name or server ID is required. **Bot owner only** | `.leave 123123123331`
+`.die` | Shuts the bot down. **Bot owner only** | `.die`
+`.setname` `.newnm` | Gives the bot a new name. **Bot owner only** | `.newnm BotName`
+`.setstatus` | Sets the bot's status. (Online/Idle/Dnd/Invisible) **Bot owner only** | `.setstatus Idle`
+`.setavatar` `.setav` | Sets a new avatar image for the NadekoBot. Argument is a direct link to an image. **Bot owner only** | `.setav http://i.imgur.com/xTG3a1I.jpg`
+`.setgame` | Sets the bots game. **Bot owner only** | `.setgame with snakes`
+`.setstream` | Sets the bots stream. First argument is the twitch link, second argument is stream name. **Bot owner only** | `.setstream TWITCHLINK Hello`
+`.send` | Sends a message to someone on a different server through the bot. Separate server and channel/user ids with `|` and prefix the channel id with `c:` and the user id with `u:`. **Bot owner only** | `.send serverid|c:channelid message` or `.send serverid|u:userid message`
+`.announce` | Sends a message to all servers' default channel that bot is connected to. **Bot owner only** | `.announce Useless spam`
+`.reloadimages` | Reloads images bot is using. Safe to use even when bot is being used heavily. **Bot owner only** | `.reloadimages`
+`.greetdel` `.grdel` | Sets the time it takes (in seconds) for greet messages to be auto-deleted. Set it to 0 to disable automatic deletion. **Requires ManageServer server permission.** | `.greetdel 0` or `.greetdel 30`
+`.greet` | Toggles anouncements on the current channel when someone joins the server. **Requires ManageServer server permission.** | `.greet`
+`.greetmsg` | Sets a new join announcement message which will be shown in the server's channel. Type `%user%` if you want to mention the new member. Using it with no message will show the current greet message. You can use embed json from instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.greetmsg Welcome, %user%.`
+`.greetdm` | Toggles whether the greet messages will be sent in a DM (This is separate from greet - you can have both, any or neither enabled). **Requires ManageServer server permission.** | `.greetdm`
+`.greetdmmsg` | Sets a new join announcement message which will be sent to the user who joined. Type `%user%` if you want to mention the new member. Using it with no message will show the current DM greet message. You can use embed json from instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.greetdmmsg Welcome to the server, %user%`.
+`.bye` | Toggles anouncements on the current channel when someone leaves the server. **Requires ManageServer server permission.** | `.bye`
+`.byemsg` | Sets a new leave announcement message. Type `%user%` if you want to show the name the user who left. Type `%id%` to show id. Using this command with no message will show the current bye message. You can use embed json from instead of a regular text, if you want the message to be embedded. **Requires ManageServer server permission.** | `.byemsg %user% has left.`
+`.byedel` | Sets the time it takes (in seconds) for bye messages to be auto-deleted. Set it to `0` to disable automatic deletion. **Requires ManageServer server permission.** | `.byedel 0` or `.byedel 30`
+`.warn` | Warns a user. **Requires BanMembers server permission.** | `.warn @b1nzy Very rude person`
+`.warnlog` | See a list of warnings of a certain user. **Requires BanMembers server permission.** | `.warnlog @b1nzy`
+`.warnclear` `.warnc` | Clears all warnings from a certain user. **Requires BanMembers server permission.** | `.warnclear @PoorDude`
+`.warnpunish` `.warnp` | Sets a punishment for a certain number of warnings. Provide no punishment to remove. **Requires BanMembers server permission.** | `.warnpunish 5 Ban` or `.warnpunish 3`
+`.warnpunishlist` `.warnpl` | Lists punishments for warnings. | `.warnpunishlist`
+`.ban` `.b` | Bans a user by ID or name with an optional message. **Requires BanMembers server permission.** | `.b "@some Guy" Your behaviour is toxic.`
+`.unban` | Unbans a user with the provided user#discrim or id. **Requires BanMembers server permission.** | `.unban kwoth#1234` or `.unban 123123123`
+`.softban` `.sb` | Bans and then unbans a user by ID or name with an optional message. **Requires KickMembers server permission.** **Requires ManageMessages server permission.** | `.sb "@some Guy" Your behaviour is toxic.`
+`.kick` `.k` | Kicks a mentioned user. **Requires KickMembers server permission.** | `.k "@some Guy" Your behaviour is toxic.`
+`.vcrole` | Sets or resets a role which will be given to users who join the voice channel you're in when you run this command. Provide no role name to disable. You must be in a voice channel to run this command. **Requires ManageRoles server permission.** **Requires ManageChannels server permission.** | `.vcrole SomeRole` or `.vcrole`
+`.vcrolelist` | Shows a list of currently set voice channel roles. | `.vcrolelist`
+`.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. **Requires ManageRoles server permission.** **Requires ManageChannels server permission.** | `.v+t`
+`.cleanvplust` `.cv+t` | Deletes all text channels ending in `-voice` for which voicechannels are not found. Use at your own risk. **Requires ManageChannels server permission.** **Requires ManageRoles server permission.** | `.cleanv+t`
-###### [Back to TOC](#table-of-contents)
+###### [Back to ToC](#table-of-contents)
### ClashOfClans
-Command and aliases | Description | Usage
+Commands 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`
+`,createwar` `,cw` | Creates a new war by specifying a size (>10 and multiple of 5) and enemy clan name. **Requires ManageMessages server permission.** | `,cw 15 The Enemy Clan`
`,startwar` `,sw` | Starts a war with a given number. | `,sw 15`
-`,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`
+`,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]`
`,claimfinish1` `,cf1` | Finish your claim with 1 star if you destroyed a base. First argument is the war number, optional second argument is a base number if you want to finish for someone else. | `,cf1 1` or `,cf1 1 5`
`,claimfinish2` `,cf2` | Finish your claim with 2 stars if you destroyed a base. First argument is the war number, optional second argument is a base number if you want to finish for someone else. | `,cf2 1` or `,cf2 1 5`
@@ -110,157 +129,165 @@ Command and aliases | Description | Usage
`,endwar` `,ew` | Ends the war with a given index. | `,ew [war_number]`
`,unclaim` `,ucall` `,uc` | Removes your claim from a certain war. Optional second argument denotes a person in whose place to unclaim | `,uc [war_number] [optional_other_name]`
-###### [Back to TOC](#table-of-contents)
+###### [Back to ToC](#table-of-contents)
### CustomReactions
-Command and aliases | Description | Usage
+Commands and aliases | Description | Usage
----------------|--------------|-------
-`.addcustreact` `.acr` | Add a custom reaction with a trigger and a response. Running this command in server requires Administration permission. Running this command in DM is Bot Owner only and adds a new global custom reaction. Guide here: | `.acr "hello" Hi there %user%`
+`.addcustreact` `.acr` | Add a custom reaction with a trigger and a response. Running this command in server requires the Administration permission. Running this command in DM is Bot Owner only and adds a new global custom reaction. Guide here: | `.acr "hello" Hi there %user%`
`.listcustreact` `.lcr` | Lists global or server custom reactions (20 commands per page). Running the command in DM will list global custom reactions, while running it in server will list that server's custom reactions. Specifying `all` argument instead of the number will DM you a text file with a list of all custom reactions. | `.lcr 1` or `.lcr all`
`.listcustreactg` `.lcrg` | Lists global or server custom reactions (20 commands per page) grouped by trigger, and show a number of responses for each. Running the command in DM will list global custom reactions, while running it in server will list that server's custom reactions. | `.lcrg 1`
`.showcustreact` `.scr` | Shows a custom reaction's response on a given ID. | `.scr 1`
-`.delcustreact` `.dcr` | Deletes a custom reaction on a specific index. If ran in DM, it is bot owner only and deletes a global custom reaction. If ran in a server, it requires Administration priviledges and removes server custom reaction. | `.dcr 5`
-`.crstatsclear` | Resets the counters on `.crstats`. You can specify a trigger to clear stats only for that trigger. **Bot Owner only.** | `.crstatsclear` or `.crstatsclear rng`
+`.delcustreact` `.dcr` | Deletes a custom reaction on a specific index. If ran in DM, it is bot owner only and deletes a global custom reaction. If ran in a server, it requires Administration privileges and removes server custom reaction. | `.dcr 5`
+`.crdm` | Toggles whether the response message of the custom reaction will be sent as a direct message. | `.crdm 44`
+`.crad` | Toggles whether the message triggering the custom reaction will be automatically deleted. | `.crad 59`
+`.crstatsclear` | Resets the counters on `.crstats`. You can specify a trigger to clear stats only for that trigger. **Bot owner only** | `.crstatsclear` or `.crstatsclear rng`
`.crstats` | Shows a list of custom reactions and the number of times they have been executed. Paginated with 10 per page. Use `.crstatsclear` to reset the counters. | `.crstats` or `.crstats 3`
-###### [Back to TOC](#table-of-contents)
+###### [Back to ToC](#table-of-contents)
### Gambling
-Command and aliases | Description | Usage
+Commands and aliases | Description | Usage
----------------|--------------|-------
-`$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 awards you 1.8x the currency you've bet. | `$bf 5 heads` or `$bf 3 t`
-`$draw` | Draws a card from the deck.If you supply number X, she draws up to 5 cards from the deck. | `$draw` or `$draw 5`
-`$shuffle` `$sh` | Reshuffles all cards back into the deck. | `$sh`
-`$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. Y can be a letter 'F' if you want to roll fate dice instead of dnd. | `$roll` or `$roll 7` or `$roll 3d5` or `$roll 5dF`
-`$rolluo` | Rolls X normal dice (up to 30) unordered. If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | `$rolluo` or `$rolluo 7` or `$rolluo 3d5`
-`$nroll` | Rolls in a given range. | `$nroll 5` (rolls 0-5) or `$nroll 5-15`
-`$race` | Starts a new animal race. | `$race`
-`$joinrace` `$jr` | Joins a new race. You can specify an amount of currency 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`
`$cash` `$$$` | Check how much currency a person has. (Defaults to yourself) | `$$$` or `$$$ @SomeGuy`
`$give` | Give someone a certain amount of currency. | `$give 1 "@SomeGuy"`
-`$award` | Awards someone a certain amount of currency. You can also specify a role name to award currency to all users in a role. **Bot Owner only.** | `$award 100 @person` or `$award 5 Role Of Gamblers`
-`$take` | Takes a certain amount of currency from someone. **Bot Owner only.** | `$take 1 "@someguy"`
-`$betroll` `$br` | Bets a certain amount of currency and rolls a dice. Rolling over 66 yields x2 of your currency, over 90 - x3 and 100 x10. | `$br 5`
-`$leaderboard` `$lb` | Displays bot currency leaderboard. | `$lb`
+`$award` | Awards someone a certain amount of currency. You can also specify a role name to award currency to all users in a role. **Bot owner only** | `$award 100 @person` or `$award 5 Role Of Gamblers`
+`$take` | Takes a certain amount of currency from someone. **Bot owner only** | `$take 1 "@someguy"`
+`$betroll` `$br` | Bets a certain amount of currency and rolls a dice. Rolling over 66 yields x2 of your currency, over 90 - x4 and 100 x10. | `$br 5`
+`$leaderboard` `$lb` | Displays the bot's currency leaderboard. | `$lb`
+`$race` | Starts a new animal race. | `$race`
+`$joinrace` `$jr` | Joins a new race. You can specify an amount of currency for betting (optional). You will get YourBet*(participants-1) back if you win. | `$jr` or `$jr 5`
+`$startevent` | Starts one of the events seen on public nadeko. **Bot owner only** | `$startevent flowerreaction`
+`$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`. `Y` can be a letter 'F' if you want to roll fate dice instead of dnd. | `$roll` or `$roll 7` or `$roll 3d5` or `$roll 5dF`
+`$rolluo` | Rolls `X` normal dice (up to 30) unordered. If you split 2 numbers with letter `d` (`xdy`) it will roll `X` dice from 1 to `y`. | `$rolluo` or `$rolluo 7` or `$rolluo 3d5`
+`$nroll` | Rolls in a given range. | `$nroll 5` (rolls 0-5) or `$nroll 5-15`
+`$draw` | Draws a card from the deck.If you supply number X, she draws up to 5 cards from the deck. | `$draw` or `$draw 5`
+`$shuffle` `$sh` | Reshuffles all cards back into the deck. | `$sh`
+`$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 awards you 1.95x the currency you've bet (rounded up). Multiplier can be changed by the bot owner. | `$bf 5 heads` or `$bf 3 t`
+`$shop` | Lists this server's administrators' shop. Paginated. | `$shop` or `$shop 2`
+`$buy` | Buys an item from the shop on a given index. If buying items, make sure that the bot can DM you. | `$buy 2`
+`$shopadd` | Adds an item to the shop by specifying type price and name. Available types are role and list. **Requires Administrator server permission.** | `$shopadd role 1000 Rich`
+`$shoplistadd` | Adds an item to the list of items for sale in the shop entry given the index. You usually want to run this command in the secret channel, so that the unique items are not leaked. **Requires Administrator server permission.** | `$shoplistadd 1 Uni-que-Steam-Key`
+`$shoprem` `$shoprm` | Removes an item from the shop by its color. **Requires Administrator server permission.** | `$shoprm 1`
+`$slotstats` | Shows the total stats of the slot command for this bot's session. **Bot owner only** | `$slotstats`
+`$slottest` | Tests to see how much slots payout for X number of plays. **Bot owner only** | `$slottest 1000`
+`$slot` | Play Nadeko slots. Max bet is 9999. 1.5 second cooldown per user. | `$slot 5`
+`$claimwaifu` `$claim` | Claim a waifu for yourself by spending currency. You must spend at least 10% more than her current value unless she set `$affinity` towards you. | `$claim 50 @Himesama`
+`$divorce` | Releases your claim on a specific waifu. You will get some of the money you've spent back unless that waifu has an affinity towards you. 6 hours cooldown. | `$divorce @CheatingSloot`
+`$affinity` | Sets your affinity towards someone you want to be claimed by. Setting affinity will reduce their `$claim` on you by 20%. You can leave second argument empty to clear your affinity. 30 minutes cooldown. | `$affinity @MyHusband` or `$affinity`
+`$waifus` `$waifulb` | Shows top 9 waifus. | `$waifus`
+`$waifuinfo` `$waifustats` | Shows waifu stats for a target person. Defaults to you if no user is provided. | `$waifuinfo @MyCrush` or `$waifuinfo`
-###### [Back to TOC](#table-of-contents)
+###### [Back to ToC](#table-of-contents)
### Games
-Command and aliases | Description | Usage
+Commands and aliases | Description | Usage
----------------|--------------|-------
-`>trivia` `>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` or `>t 5 nohint`
-`>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. **Bot Owner only.** | `>typeadd wordswords`
-`>typelist` | Lists added typing articles with their IDs. 15 per page. | `>typelist` or `>typelist 3`
-`>typedel` | Deletes a typing article given the ID. **Bot Owner only.** | `>typedel 3`
-`>poll` | Creates a poll which requires users to send the number of the voting option to the bot. **Requires ManageMessages server permission.** | `>poll Question?;Answer1;Answ 2;A_3`
-`>publicpoll` `>ppoll` | Creates a public poll which requires users to type a number of the voting option in the channel command is ran in. **Requires ManageMessages server permission.** | `>ppoll Question?;Answer1;Answ 2;A_3`
-`>pollend` | Stops active poll on this server and prints the results in this channel. **Requires ManageMessages server permission.** | `>pollend`
-`>pick` | Picks the currency planted in this channel. 60 seconds cooldown. | `>pick`
-`>plant` | Spend a unit of currency to plant it in this channel. (If bot is restarted or crashes, the currency will be lost) | `>plant`
-`>gencurrency` `>gc` | Toggles currency generation on this channel. Every posted message will have chance to spawn currency. Chance is specified by the Bot Owner. (default is 2%) **Requires ManageMessages server permission.** | `>gc`
-`>hangmanlist` | Shows a list of hangman term types. | `> hangmanlist`
-`>hangman` | Starts a game of hangman in the channel. Use `>hangmanlist` to see a list of available term types. Defaults to 'all'. | `>hangman` or `>hangman movies`
-`>cleverbot` | Toggles cleverbot session. When enabled, the bot will reply to messages starting with bot mention in the server. Custom reactions starting with %mention% won't work if cleverbot is enabled. **Requires ManageMessages channel permission.** | `>cleverbot`
-`>acrophobia` `>acro` | Starts an Acrophobia game. Second argment is optional round length in seconds. (default is 60) | `>acro` or `>acro 30`
`>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`
+`>rps` | Play a game of Rocket-Paperclip-Scissors with Nadeko. | `>rps scissors`
+`>rategirl` | Use the universal hot-crazy wife zone matrix to determine the girl's worth. It is everything young men need to know about women. At any moment in time, any woman you have previously located on this chart can vanish from that location and appear anywhere else on the chart. | `>rategirl @SomeGurl`
`>linux` | Prints a customizable Linux interjection | `>linux Spyware Windows`
`>leet` | Converts a text to leetspeak with 6 (1-6) severity levels | `>leet 3 Hello`
+`>acrophobia` `>acro` | Starts an Acrophobia game. Second argument is optional round length in seconds. (default is 60) | `>acro` or `>acro 30`
+`>cleverbot` | Toggles cleverbot session. When enabled, the bot will reply to messages starting with bot mention in the server. Custom reactions starting with %mention% won't work if cleverbot is enabled. **Requires ManageMessages server permission.** | `>cleverbot`
+`>hangmanlist` | Shows a list of hangman term types. | `> hangmanlist`
+`>hangman` | Starts a game of hangman in the channel. Use `>hangmanlist` to see a list of available term types. Defaults to 'all'. | `>hangman` or `>hangman movies`
+`>pick` | Picks the currency planted in this channel. 60 seconds cooldown. | `>pick`
+`>plant` | Spend an amount of currency to plant it in this channel. Default is 1. (If bot is restarted or crashes, the currency will be lost) | `>plant` or `>plant 5`
+`>gencurrency` `>gc` | Toggles currency generation on this channel. Every posted message will have chance to spawn currency. Chance is specified by the Bot Owner. (default is 2%) **Requires ManageMessages server permission.** | `>gc`
+`>poll` | Creates a poll which requires users to send the number of the voting option to the bot. **Requires ManageMessages server permission.** | `>poll Question?;Answer1;Answ 2;A_3`
+`>publicpoll` `>ppoll` | Creates a public poll which requires users to type a number of the voting option in the channel command is ran in. **Requires ManageMessages server permission.** | `>ppoll Question?;Answer1;Answ 2;A_3`
+`>pollstats` | Shows the poll results without stopping the poll on this server. **Requires ManageMessages server permission.** | `>pollstats`
+`>pollend` | Stops active poll on this server and prints the results in this channel. **Requires ManageMessages server permission.** | `>pollend`
+`>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. **Bot owner only** | `>typeadd wordswords`
+`>typelist` | Lists added typing articles with their IDs. 15 per page. | `>typelist` or `>typelist 3`
+`>typedel` | Deletes a typing article given the ID. **Bot owner only** | `>typedel 3`
+`>tictactoe` `>ttt` | Starts a game of tic tac toe. Another user must run the command in the same channel in order to accept the challenge. Use numbers 1-9 to play. 15 seconds per move. | >ttt
+`>trivia` `>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` or `>t 5 nohint`
+`>tl` | Shows a current trivia leaderboard. | `>tl`
+`>tq` | Quits current trivia after current question. | `>tq`
-###### [Back to TOC](#table-of-contents)
+###### [Back to ToC](#table-of-contents)
### Help
-Command and aliases | Description | Usage
+Commands and aliases | Description | Usage
----------------|--------------|-------
`-modules` `-mdls` | Lists all bot modules. | `-modules`
-`-commands` `-cmds` | List all of the bot's commands from a certain module. You can either specify full, or only first few letters of the module name. | `-commands Administration` or `-cmds Admin`
-`-help` `-h` | Either shows a help for a single command, or DMs you help link if no arguments are specified. | `-h !!q` or `-h`
-`-hgit` | Generates the commandlist.md file. **Bot Owner only.** | `-hgit`
+`-commands` `-cmds` | List all of the bot's commands from a certain module. You can either specify the full name or only the first few letters of the module name. | `-commands Administration` or `-cmds Admin`
+`-help` `-h` | Either shows a help for a single command, or DMs you help link if no arguments are specified. | `-h -cmds` or `-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` | Instructions for helping the project financially. | `-donate`
-###### [Back to TOC](#table-of-contents)
+###### [Back to ToC](#table-of-contents)
### Music
-Command and aliases | Description | Usage
+Commands and aliases | Description | Usage
----------------|--------------|-------
`!!next` `!!n` | Goes to the next song in the queue. You have to be in the same voice channel as the bot. You can skip multiple songs, but in that case songs will not be requeued if !!rcs or !!rpl is enabled. | `!!n` or `!!n 5`
`!!stop` `!!s` | Stops the music and clears the playlist. Stays in the channel. | `!!s`
`!!destroy` `!!d` | Completely stops the music and unbinds the bot from the channel. (may cause weird behaviour) | `!!d`
`!!pause` `!!p` | Pauses or Unpauses the song. | `!!p`
-`!!fairplay` `!!fp` | Toggles fairplay. While enabled, music player will prioritize songs from users who didn't have their song recently played instead of the song's position in the queue. | `!!fp`
-`!!queue` `!!q` `!!yq` | Queue a song using keywords or a link. Bot will join your voice channel.**You must be in a voice channel**. | `!!q Dream Of Venice`
-`!!soundcloudqueue` `!!sq` | Queue a soundcloud song using keywords. Bot will join your voice channel.**You must be in a voice channel**. | `!!sq Dream Of Venice`
+`!!fairplay` `!!fp` | Toggles fairplay. While enabled, the bot will prioritize songs from users who didn't have their song recently played instead of the song's position in the queue. | `!!fp`
+`!!queue` `!!q` `!!yq` | Queue a song using keywords or a link. Bot will join your voice channel. **You must be in a voice channel**. | `!!q Dream Of Venice`
+`!!soundcloudqueue` `!!sq` | Queue a soundcloud song using keywords. Bot will join your voice channel. **You must be in a voice channel**. | `!!sq Dream Of Venice`
`!!listqueue` `!!lq` | Lists 15 currently queued songs per page. Default page is 1. | `!!lq` or `!!lq 2`
-`!!nowplaying` `!!np` | Shows the song currently playing. | `!!np`
-`!!volume` `!!vol` | Sets the music volume 0-100% | `!!vol 50`
+`!!nowplaying` `!!np` | Shows the song that the bot is currently playing. | `!!np`
+`!!volume` `!!vol` | Sets the music playback volume (0-100%) | `!!vol 50`
`!!defvol` `!!dv` | Sets the default music volume when music playback is started (0-100). Persists through restarts. | `!!dv 80`
`!!shuffle` `!!sh` | Shuffles the current playlist. | `!!sh`
`!!playlist` `!!pl` | Queues up to 500 songs from a youtube playlist specified by a link, or keywords. | `!!pl playlist link or name`
-`!!soundcloudpl` `!!scpl` | Queue a soundcloud playlist using a link. | `!!scpl soundcloudseturl`
-`!!localplaylst` `!!lopl` | Queues all songs from a directory. **Bot Owner only.** | `!!lopl C:/music/classical`
+`!!soundcloudpl` `!!scpl` | Queue a Soundcloud playlist using a link. | `!!scpl soundcloudseturl`
+`!!localplaylst` `!!lopl` | Queues all songs from a directory. **Bot owner only** | `!!lopl C:/music/classical`
`!!radio` `!!ra` | Queues a radio stream from a link. It can be a direct mp3 radio stream, .m3u, .pls .asx or .xspf (Usage Video: ) | `!!ra radio link here`
-`!!local` `!!lo` | Queues a local file by specifying a full path. **Bot Owner only.** | `!!lo C:/music/mysong.mp3`
-`!!move` `!!mv` | Moves the bot to your voice channel. (works only if music is already playing) | `!!mv`
+`!!local` `!!lo` | Queues a local file by specifying a full path. **Bot owner only** | `!!lo C:/music/mysong.mp3`
`!!remove` `!!rm` | Remove a song by its # in the queue, or 'all' to remove whole queue. | `!!rm 5`
`!!movesong` `!!ms` | Moves a song from one position to another. | `!!ms 5>3`
`!!setmaxqueue` `!!smq` | Sets a maximum queue size. Supply 0 or no argument to have no limit. | `!!smq 50` or `!!smq`
`!!setmaxplaytime` `!!smp` | Sets a maximum number of seconds (>14) a song can run before being skipped automatically. Set 0 to have no limit. | `!!smp 0` or `!!smp 270`
`!!reptcursong` `!!rcs` | Toggles repeat of current song. | `!!rcs`
`!!rpeatplaylst` `!!rpl` | Toggles repeat of all songs in the queue (every song that finishes is added to the end of the queue). | `!!rpl`
-`!!save` | Saves a playlist under a certain name. Name must be no longer than 20 characters and mustn't contain dashes. | `!!save classical1`
-`!!load` | Loads a saved playlist using it's ID. Use `!!pls` to list all saved playlists and !!save to save new ones. | `!!load 5`
-`!!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`
+`!!save` | Saves a playlist under a certain name. Playlist name must be no longer than 20 characters and must not contain dashes. | `!!save classical1`
+`!!load` | Loads a saved playlist using its ID. Use `!!pls` to list all saved playlists and `!!save` to save new ones. | `!!load 5`
+`!!playlists` `!!pls` | Lists all playlists. Paginated, 20 per page. Default page is 0. | `!!pls 1`
+`!!deleteplaylist` `!!delpls` | Deletes a saved playlist. Works 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`
-`!!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) | `!!ap`
+`!!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) | `!!ap`
+`!!setmusicchannel` `!!smch` | Sets the current channel as the default music output channel. This will output playing, finished, paused and removed songs to that channel instead of the channel where the first song was queued in. **Requires ManageMessages server permission.** | `!!smch`
-###### [Back to TOC](#table-of-contents)
+###### [Back to ToC](#table-of-contents)
### NSFW
-Command and aliases | Description | Usage
+Commands and aliases | Description | Usage
----------------|--------------|-------
`~hentai` | Shows a hentai image from a random website (gelbooru or danbooru or konachan or atfbooru or yandere) with a given tag. Tag is optional but preferred. Only 1 tag allowed. | `~hentai yuri`
-`~autohentai` | Posts a hentai every X seconds with a random tag from the provided tags. Use `|` to separate tags. 20 seconds minimum. Provide no arguments to disable. | `~autohentai 30 yuri|tail|long_hair` or `~autohentai`
+`~autohentai` | Posts a hentai every X seconds with a random tag from the provided tags. Use `|` to separate tags. 20 seconds minimum. Provide no arguments to disable. **Requires ManageMessages channel permission.** | `~autohentai 30 yuri|tail|long_hair` or `~autohentai`
`~hentaibomb` | Shows a total 5 images (from gelbooru, danbooru, konachan, yandere and atfbooru). Tag is optional but preferred. | `~hentaibomb yuri`
-`~danbooru` | Shows a random hentai image from danbooru with a given tag. Tag is optional but preferred. (multiple tags are appended with +) | `~danbooru yuri+kissing`
`~yandere` | Shows a random image from yandere with a given tag. Tag is optional but preferred. (multiple tags are appended with +) | `~yandere tag1+tag2`
`~konachan` | Shows a random hentai image from konachan with a given tag. Tag is optional but preferred. | `~konachan yuri`
-`~gelbooru` | Shows a random hentai image from gelbooru with a given tag. Tag is optional but preferred. (multiple tags are appended with +) | `~gelbooru yuri+kissing`
-`~rule34` | Shows a random image from rule34.xx with a given tag. Tag is optional but preferred. (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 preferred. Use spaces for multiple tags. | `~e621 yuri kissing`
+`~rule34` | Shows a random image from rule34.xx with a given tag. Tag is optional but preferred. (multiple tags are appended with +) | `~rule34 yuri+kissing`
+`~danbooru` | Shows a random hentai image from danbooru with a given tag. Tag is optional but preferred. (multiple tags are appended with +) | `~danbooru yuri+kissing`
+`~gelbooru` | Shows a random hentai image from gelbooru with a given tag. Tag is optional but preferred. (multiple tags are appended with +) | `~gelbooru yuri+kissing`
`~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`
-###### [Back to TOC](#table-of-contents)
+###### [Back to ToC](#table-of-contents)
### Permissions
-Command and aliases | Description | Usage
+Commands and aliases | Description | Usage
----------------|--------------|-------
-`;srvrfilterinv` `;sfi` | Toggles automatic deleting of invites posted in the server. Does not affect Bot Owner. | `;sfi`
-`;chnlfilterinv` `;cfi` | Toggles automatic deleting of invites posted in the channel. Does not negate the ;srvrfilterinv enabled setting. Does not affect Bot Owner. | `;cfi`
-`;srvrfilterwords` `;sfw` | Toggles automatic deleting of messages containing forbidden words on the server. Does not affect Bot Owner. | `;sfw`
-`;chnlfilterwords` `;cfw` | Toggles automatic deleting of messages containing banned words on the channel. Does not negate the ;srvrfilterwords enabled setting. Does not affect bot owner. | `;cfw`
-`;fw` | Adds or removes (if it exists) a word from the list of filtered words. Use`;sfw` or `;cfw` to toggle filtering. | `;fw poop`
-`;lstfilterwords` `;lfw` | Shows a list of filtered words. | `;lfw`
-`;cmdcooldown` `;cmdcd` | Sets a cooldown per user for a command. Set to 0 to remove the cooldown. | `;cmdcd "some cmd" 5`
-`;allcmdcooldowns` `;acmdcds` | Shows a list of all commands and their respective cooldowns. | `;acmdcds`
-`;ubl` | Either [add]s or [rem]oves a user specified by a mention or ID from a blacklist. **Bot Owner only.** | `;ubl add @SomeUser` or `;ubl rem 12312312313`
-`;cbl` | Either [add]s or [rem]oves a channel specified by an ID from a blacklist. **Bot Owner only.** | `;cbl rem 12312312312`
-`;sbl` | Either [add]s or [rem]oves a server specified by a Name or ID from a blacklist. **Bot Owner only.** | `;sbl add 12312321312` or `;sbl rem SomeTrashServer`
`;verbose` `;v` | Sets whether to show when a command/module is blocked. | `;verbose true`
-`;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`
+`;permrole` `;pr` | Sets a role which can change permissions. Supply no parameters to see the current one. Default is 'Nadeko'. | `;pr role`
`;listperms` `;lp` | Lists whole permission chain with their indexes. You can specify an optional page number if there are a lot of permissions. | `;lp` or `;lp 3`
-`;removeperm` `;rp` | Removes a permission from a given position in Permissions list. | `;rp 1`
-`;moveperm` `;mp` | Moves permission from one position to another in Permissions list. | `;mp 2 4`
+`;removeperm` `;rp` | Removes a permission from a given position in the Permissions list. | `;rp 1`
+`;moveperm` `;mp` | Moves permission from one position to another in the Permissions list. | `;mp 2 4`
`;srvrcmd` `;sc` | Sets a command's permission at the server level. | `;sc "command name" disable`
`;srvrmdl` `;sm` | Sets a module's permission at the server level. | `;sm ModuleName enable`
`;usrcmd` `;uc` | Sets a command's permission at the user level. | `;uc "command name" enable SomeUsername`
@@ -273,109 +300,142 @@ Command and aliases | Description | Usage
`;allrolemdls` `;arm` | Enable or disable all modules for a specific role. | `;arm [enable/disable] MyRole`
`;allusrmdls` `;aum` | Enable or disable all modules for a specific user. | `;aum enable @someone`
`;allsrvrmdls` `;asm` | Enable or disable all modules for your server. | `;asm [enable/disable]`
+`;ubl` | Either [add]s or [rem]oves a user specified by a Mention or an ID from a blacklist. **Bot owner only** | `;ubl add @SomeUser` or `;ubl rem 12312312313`
+`;cbl` | Either [add]s or [rem]oves a channel specified by an ID from a blacklist. **Bot owner only** | `;cbl rem 12312312312`
+`;sbl` | Either [add]s or [rem]oves a server specified by a Name or an ID from a blacklist. **Bot owner only** | `;sbl add 12312321312` or `;sbl rem SomeTrashServer`
+`;cmdcooldown` `;cmdcd` | Sets a cooldown per user for a command. Set it to 0 to remove the cooldown. | `;cmdcd "some cmd" 5`
+`;allcmdcooldowns` `;acmdcds` | Shows a list of all commands and their respective cooldowns. | `;acmdcds`
+`;srvrfilterinv` `;sfi` | Toggles automatic deletion of invites posted in the server. Does not affect the Bot Owner. | `;sfi`
+`;chnlfilterinv` `;cfi` | Toggles automatic deletion of invites posted in the channel. Does not negate the `;srvrfilterinv` enabled setting. Does not affect the Bot Owner. | `;cfi`
+`;srvrfilterwords` `;sfw` | Toggles automatic deletion of messages containing filtered words on the server. Does not affect the Bot Owner. | `;sfw`
+`;chnlfilterwords` `;cfw` | Toggles automatic deletion of messages containing filtered words on the channel. Does not negate the `;srvrfilterwords` enabled setting. Does not affect the Bot Owner. | `;cfw`
+`;fw` | Adds or removes (if it exists) a word from the list of filtered words. Use`;sfw` or `;cfw` to toggle filtering. | `;fw poop`
+`;lstfilterwords` `;lfw` | Shows a list of filtered words. | `;lfw`
+`;listglobalperms` `;lgp` | Lists global permissions set by the bot owner. **Bot owner only** | `;lgp`
+`;globalmodule` `;gmod` | Enable or disable a module from use on all servers. **Bot owner only** | `;gmod nsfw disable`
+`;globalcommand` `;gcmd` | Enables or disables a command from use on all servers. **Bot owner only** | `;gcmd `
-###### [Back to TOC](#table-of-contents)
+###### [Back to ToC](#table-of-contents)
### Pokemon
-Command and aliases | Description | Usage
+Commands 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 | `>ml`
-`>heal` | Heals someone. Revives those who fainted. Costs a NadekoFlower | `>heal @someone`
+`>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. Provide no arguments to see a list of available types. | `>settype fire` or `>settype`
-###### [Back to TOC](#table-of-contents)
+###### [Back to ToC](#table-of-contents)
### Searches
-Command and aliases | Description | Usage
+Commands and aliases | Description | Usage
----------------|--------------|-------
-`~xkcd` | Shows a XKCD comic. No arguments will retrieve random one. Number argument will retrieve a specific comic, and "latest" will get the latest one. | `~xkcd` or `~xkcd 1400` or `~xkcd latest`
-`~translate` `~trans` | Translates from>to text. From the given language to the destination language. | `~trans en>fr Hello`
-`~autotrans` `~at` | Starts automatic translation of all messages by users who set their `~atl` in this channel. You can set "del" argument to automatically delete all translated user messages. **Requires Administrator server permission.** **Bot Owner only.** | `~at` or `~at del`
-`~autotranslang` `~atl` | `~atl en>fr` | Sets your source and target language to be used with `~at`. Specify no arguments to remove previously set value.
-`~translangs` | Lists the valid languages for translation. | `~translangs`
-`~hitbox` `~hb` | Notifies this channel when a certain user starts streaming. **Requires ManageMessages server permission.** | `~hitbox SomeStreamer`
-`~twitch` `~tw` | Notifies this channel when a certain user starts streaming. **Requires ManageMessages server permission.** | `~twitch SomeStreamer`
-`~beam` `~bm` | Notifies this channel when a certain user starts streaming. **Requires ManageMessages server permission.** | `~beam SomeStreamer`
-`~liststreams` `~ls` | Lists all streams you are following on this server. | `~ls`
-`~removestream` `~rms` | Removes notifications of a certain streamer from a certain platform on this channel. **Requires ManageMessages server permission.** | `~rms Twitch SomeGuy` or `~rms Beam SomeOtherGuy`
-`~checkstream` `~cs` | Checks if a user is online on a certain streaming platform. | `~cs twitch MyFavStreamer`
-`~pokemon` `~poke` | Searches for a pokemon. | `~poke Sylveon`
-`~pokemonability` `~pokeab` | Searches for a pokemon ability. | `~pokeab overgrow`
-`~placelist` | Shows the list of available tags for the `~place` command. | `~placelist`
-`~place` | Shows a placeholder image of a given tag. Use `~placelist` to see all available tags. You can specify the width and height of the image as the last two optional arguments. | `~place Cage` or `~place steven 500 400`
-`~overwatch` `~ow` | Show's basic stats on a player (competitive rank, playtime, level etc) Region codes are: `eu` `us` `cn` `kr` | `~ow us Battletag#1337` or `~overwatch eu Battletag#2016`
-`~osu` | Shows osu stats for a player. | `~osu Name` or `~osu Name taiko`
-`~osub` | Shows information about an osu beatmap. | `~osub https://osu.ppy.sh/s/127712`
-`~osu5` | Displays a user's top 5 plays. | `~osu5 Name`
-`~yomama` `~ym` | Shows a random joke from | `~ym`
-`~randjoke` `~rj` | Shows a random joke from | `~rj`
-`~chucknorris` `~cn` | Shows a random chucknorris joke from | `~cn`
-`~wowjoke` | Get one of Kwoth's penultimate WoW jokes. | `~wowjoke`
-`~magicitem` `~mi` | Shows a random magicitem from | `~mi`
-`~anime` `~ani` `~aq` | Queries anilist for an anime and shows the first result. | `~ani aquarion evol`
-`~manga` `~mang` `~mq` | Queries anilist for a manga and shows the first result. | `~mq Shingeki no kyojin`
`~weather` `~we` | Shows weather data for a specified city. You can also specify a country after a comma. | `~we Moscow, RU`
+`~time` | Shows the current time and timezone in the specified location. | `~time London, UK`
`~youtube` `~yt` | Searches youtubes and shows the first result | `~yt query`
`~imdb` `~omdb` | Queries omdb for movies or series, show first result. | `~imdb Batman vs Superman`
`~randomcat` `~meow` | Shows a random cat image. | `~meow`
`~randomdog` `~woof` | Shows a random dog image. | `~woof`
-`~image` `~img` | Pulls the first image found using a search parameter. Use ~rimg for different results. | `~img cute kitten`
+`~image` `~img` | Pulls the first image found using a search parameter. Use `~rimg` for different results. | `~img cute kitten`
`~randomimage` `~rimg` | Pulls a random image using a search parameter. | `~rimg cute kitten`
`~lmgtfy` | Google something for an idiot. | `~lmgtfy query`
`~shorten` | Attempts to shorten an URL, if it fails, returns the input URL. | `~shorten https://google.com`
-`~google` `~g` | Get a google search link for some terms. | `~google query`
+`~google` `~g` | Get a Google search link for some terms. | `~google query`
`~magicthegathering` `~mtg` | Searches for a Magic The Gathering card. | `~magicthegathering about face` or `~mtg about face`
`~hearthstone` `~hs` | Searches for a Hearthstone card and shows its image. Takes a while to complete. | `~hs Ysera`
-`~yodify` `~yoda` | Translates your normal sentences into Yoda styled sentences! | ~yodify I was once an adventurer like you` or `~yoda my feelings hurt`
+`~yodify` `~yoda` | Translates your normal sentences into Yoda styled sentences! | `~yoda my feelings hurt`
`~urbandict` `~ud` | Searches Urban Dictionary for a word. | `~ud Pineapple`
`~define` `~def` | Finds a definition of a word. | `~def heresy`
`~#` | Searches Tagdef.com for a hashtag. | `~# ff`
`~catfact` | Shows a random catfact from | `~catfact`
-`~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. | `~revimg Image link`
+`~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. | `~revimg Image link`
`~safebooru` | Shows a random image from safebooru with a given tag. Tag is optional but preferred. (multiple tags are appended with +) | `~safebooru yuri+kissing`
`~wikipedia` `~wiki` | Gives you back a wikipedia link | `~wiki query`
`~color` `~clr` | Shows you what color corresponds to that hex. | `~clr 00ff00`
`~videocall` | Creates a private video call link for you and other mentioned people. The link is sent to mentioned people via a private message. | `~videocall "@SomeGuy"`
`~avatar` `~av` | Shows a mentioned person's avatar. | `~av "@SomeGuy"`
`~wikia` | Gives you back a wikia link | `~wikia mtg Vigilance` or `~wikia mlp Dashy`
-`~minecraftping` `~mcping` | Pings a minecraft server. | `~mcping 127.0.0.1:25565`
-`~minecraftquery` `~mcq` | Finds information about a minecraft server. | `~mcq server:ip`
`~lolban` | Shows top banned champions ordered by ban rate. | `~lolban`
+`~mal` | Shows basic info from a MyAnimeList profile. | `~mal straysocks`
+`~anime` `~ani` `~aq` | Queries anilist for an anime and shows the first result. | `~ani aquarion evol`
+`~manga` `~mang` `~mq` | Queries anilist for a manga and shows the first result. | `~mq Shingeki no kyojin`
+`~yomama` `~ym` | Shows a random joke from | `~ym`
+`~randjoke` `~rj` | Shows a random joke from | `~rj`
+`~chucknorris` `~cn` | Shows a random Chuck Norris joke from | `~cn`
+`~wowjoke` | Get one of Kwoth's penultimate WoW jokes. | `~wowjoke`
+`~magicitem` `~mi` | Shows a random magic item from | `~mi`
`~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"`
+`~osu` | Shows osu stats for a player. | `~osu Name` or `~osu Name taiko`
+`~osub` | Shows information about an osu beatmap. | `~osub https://osu.ppy.sh/s/127712`
+`~osu5` | Displays a user's top 5 plays. | `~osu5 Name`
+`~overwatch` `~ow` | Show's basic stats on a player (competitive rank, playtime, level etc) Region codes are: `eu` `us` `cn` `kr` | `~ow us Battletag#1337` or `~overwatch eu Battletag#2016`
+`~placelist` | Shows the list of available tags for the `~place` command. | `~placelist`
+`~place` | Shows a placeholder image of a given tag. Use `~placelist` to see all available tags. You can specify the width and height of the image as the last two optional arguments. | `~place Cage` or `~place steven 500 400`
+`~pokemon` `~poke` | Searches for a pokemon. | `~poke Sylveon`
+`~pokemonability` `~pokeab` | Searches for a pokemon ability. | `~pokeab overgrow`
+`~hitbox` `~hb` | Notifies this channel when a certain user starts streaming. **Requires ManageMessages server permission.** | `~hitbox SomeStreamer`
+`~twitch` `~tw` | Notifies this channel when a certain user starts streaming. **Requires ManageMessages server permission.** | `~twitch SomeStreamer`
+`~beam` `~bm` | Notifies this channel when a certain user starts streaming. **Requires ManageMessages server permission.** | `~beam SomeStreamer`
+`~liststreams` `~ls` | Lists all streams you are following on this server. | `~ls`
+`~removestream` `~rms` | Removes notifications of a certain streamer from a certain platform on this channel. **Requires ManageMessages server permission.** | `~rms Twitch SomeGuy` or `~rms Beam SomeOtherGuy`
+`~checkstream` `~cs` | Checks if a user is online on a certain streaming platform. | `~cs twitch MyFavStreamer`
+`~translate` `~trans` | Translates from>to text. From the given language to the destination language. | `~trans en>fr Hello`
+`~autotrans` `~at` | Starts automatic translation of all messages by users who set their `~atl` in this channel. You can set "del" argument to automatically delete all translated user messages. **Requires Administrator server permission.** **Bot owner only** | `~at` or `~at del`
+`~autotranslang` `~atl` | Sets your source and target language to be used with `~at`. Specify no arguments to remove previously set value. | `~atl en>fr`
+`~translangs` | Lists the valid languages for translation. | `~translangs`
+`~xkcd` | Shows a XKCD comic. No arguments will retrieve random one. Number argument will retrieve a specific comic, and "latest" will get the latest one. | `~xkcd` or `~xkcd 1400` or `~xkcd latest`
-###### [Back to TOC](#table-of-contents)
+###### [Back to ToC](#table-of-contents)
### Utility
-Command and aliases | Description | Usage
+Commands and aliases | Description | Usage
----------------|--------------|-------
-`.convertlist` | List of the convertible dimensions and currencies. | `.convertlist`
-`.convert` | Convert quantities. Use `.convertlist` to see supported dimensions and currencies. | `.convert m km 1000`
-`.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 1m Start now!`
-`.remindtemplate` | 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.** | `.remindtemplate %user%, do %message%!`
-`.listquotes` `.liqu` | `.liqu` or `.liqu 3` | Lists all quotes on the server ordered alphabetically. 15 Per page.
-`...` | Shows a random quote with a specified name. | `... abc`
-`..` | Adds a new quote with the specified name and message. | `.. sayhi Hi`
-`.deletequote` `.delq` | Deletes a random quote with the specified keyword. You have to either be server Administrator or the creator of the quote to delete it. | `.delq abc`
-`.delallq` `.daq` | Deletes all quotes on a specified keyword. **Requires Administrator server permission.** | `.delallq kek`
-`.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`
-`.calculate` `.calc` | Evaluate a mathematical expression. | `.calc 1+1`
-`.calcops` | Shows all available operations in .calc command | `.calcops`
+`.rotaterolecolor` `.rrc` | Rotates a roles color on an interval with a list of supplied colors. First argument is interval in seconds (Minimum 60). Second argument is a role, followed by a space-separated list of colors in hex. Provide a rolename with a 0 interval to disable. **Requires ManageRoles server permission.** **Bot owner only** | `.rrc 60 MyLsdRole #ff0000 #00ff00 #0000ff` or `.rrc 0 MyLsdRole`
`.togethertube` `.totube` | Creates a new room on and shows the link in the chat. | `.totube`
`.whosplaying` `.whpl` | Shows a list of users who are playing the specified game. | `.whpl 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`
+`.inrole` | Lists every person from the specified role on this server. You can use role ID, role name. | `.inrole Some Role`
`.checkmyperms` | Checks your user-specific permissions on this channel. | `.checkmyperms`
`.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 roles on this server or a roles of a specific user if specified. Paginated. 20 roles per page. | `.roles 2` or `.roles @Someone`
+`.roles` | List roles on this server or a roles of a specific user if specified. Paginated, 20 roles per page. | `.roles 2` or `.roles @Someone`
`.channeltopic` `.ct` | Sends current channel's topic as a message. | `.ct`
+`.createinvite` `.crinv` | Creates a new invite which has infinite max uses and never expires. **Requires CreateInstantInvite channel permission.** | `.crinv`
+`.shardstats` | Stats for shards. Paginated with 25 shards per page. | `.shardstats` or `.shardstats 2`
+`.shardid` | Shows which shard is a certain guild on, by guildid. | `.shardid 117523346618318850`
`.stats` | Shows some basic stats for Nadeko. | `.stats`
`.showemojis` `.se` | Shows a name and a link to every SPECIAL emoji in the message. | `.se A message full of SPECIAL emojis`
-`.listservers` | Lists servers the bot is on with some basic info. 15 per page. **Bot Owner only.** | `.listservers 3`
-`.activity` | Checks for spammers. **Bot Owner only.** | `.activity`
+`.listservers` | Lists servers the bot is on with some basic info. 15 per page. **Bot owner only** | `.listservers 3`
+`.savechat` | Saves a number of messages to a text file and sends it to you. **Bot owner only** | `.savechat 150`
+`.ping` | Ping the bot to see if there are latency issues. | `.ping`
+`.activity` | Checks for spammers. **Bot owner only** | `.activity`
+`.calculate` `.calc` | Evaluate a mathematical expression. | `.calc 1+1`
+`.calcops` | Shows all available operations in the `.calc` command | `.calcops`
+`.alias` `.cmdmap` | Create a custom alias for a certain Nadeko command. Provide no alias to remove the existing one. **Requires Administrator server permission.** | `.alias allin $bf 100 h` or `.alias "linux thingy" >loonix Spyware Windows`
+`.aliaslist` `.cmdmaplist` `.aliases` | Shows the list of currently set aliases. Paginated. | `.aliaslist` or `.aliaslist 3`
+`.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. **Bot owner only** | `.scsc`
+`.jcsc` | Joins current channel to an instance of cross server channel using the token. **Requires ManageServer server permission.** | `.jcsc TokenHere`
+`.lcsc` | Leaves a cross server channel instance from this channel. **Requires ManageServer server permission.** | `.lcsc`
+`.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`
+`.repeatinvoke` `.repinv` | Immediately shows the repeat message on a certain index and restarts its timer. **Requires ManageMessages server permission.** | `.repinv 1`
+`.repeatremove` `.reprm` | Removes a repeating message on a specified index. Use `.repeatlist` to see indexes. **Requires ManageMessages server permission.** | `.reprm 2`
+`.repeat` | Repeat a message every `X` minutes in the current channel. You can have up to 5 repeating messages on the server in total. **Requires ManageMessages server permission.** | `.repeat 5 Hello there`
+`.repeatlist` `.replst` | Shows currently repeating messages and their indexes. **Requires ManageMessages server permission.** | `.repeatlist`
+`.parewrel` | Forces the update of the list of patrons who are eligible for the reward. **Bot owner only** | `.parewrel`
+`.clparew` | Claim patreon rewards. If you're subscribed to bot owner's patreon you can use this command to claim your rewards - assuming bot owner did setup has their patreon key. | `.clparew`
+`.listquotes` `.liqu` | Lists all quotes on the server ordered alphabetically. 15 Per page. | `.liqu` or `.liqu 3`
+`...` | Shows a random quote with a specified name. | `... abc`
+`.qsearch` | Shows a random quote for a keyword that contains any text specified in the search. | `.qsearch keyword text`
+`.quoteid` `.qid` | Displays the quote with the specified ID number. Quote ID numbers can be found by typing `.liqu [num]` where `[num]` is a number of a page which contains 15 quotes. | `.qid 123456`
+`..` | Adds a new quote with the specified name and message. | `.. sayhi Hi`
+`.deletequote` `.delq` | Deletes a quote with the specified ID. You have to be either server Administrator or the creator of the quote to delete it. | `.delq 123456`
+`.delallq` `.daq` | Deletes all quotes on a specified keyword. **Requires Administrator server permission.** | `.delallq kek`
+`.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 1m Start now!`
+`.remindtemplate` | 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** | `.remindtemplate %user%, do %message%!`
+`.convertlist` | List of the convertible dimensions and currencies. | `.convertlist`
+`.convert` | Convert quantities. Use `.convertlist` to see supported dimensions and currencies. | `.convert m km 1000`
diff --git a/docs/Frequently Asked Questions.md b/docs/Frequently Asked Questions.md
index 32d7a6e9..09eaafd7 100644
--- a/docs/Frequently Asked Questions.md
+++ b/docs/Frequently Asked Questions.md
@@ -19,7 +19,7 @@
###Question 5: I have an issue/bug/suggestion, where do I put it so it gets noticed?
-----------
-**Answer:** First, check [issues](https://github.com/Kwoth/NadekoBot/issues "GitHub NadekoBot Issues"), then check the `#suggestions` channel in the Nadeko [help server](https://discord.gg/0ehQwTK2RBjAxzEY).
+**Answer:** First, check [issues](https://github.com/Kwoth/NadekoBot/issues "GitHub NadekoBot Issues"), then check the `#suggestions` channel in the Nadeko [help server](https://discord.gg/nadekobot).
If your problem or suggestion is not there, feel free to request/notify us about it either in the Issues section of GitHub for issues or in the `#suggestions` channel on the Nadeko help server for suggestions.
diff --git a/docs/guides/Docker Guide.md b/docs/guides/Docker Guide.md
index 9908a477..474337d6 100644
--- a/docs/guides/Docker Guide.md
+++ b/docs/guides/Docker Guide.md
@@ -1,34 +1,58 @@
# NadekoBot a Discord bot
-Nadeko is written in C# and Discord.net for more information visit https://github.com/Kwoth/NadekoBot
+Nadeko is written in C# and Discord.net for more information visit
## Install Docker
-Follow the respective guide for your operating system found here https://docs.docker.com/engine/installation/
+Follow the respective guide for your operating system found here [Docker Engine Install Guide](https://docs.docker.com/engine/installation/)
## Nadeko Setup Guide
For this guide we will be using the folder /nadeko as our config root folder.
-```
-docker create --name=nadeko -v /nadeko/data:/opt/NadekoBot/src/NadekoBot/bin/Release/netcoreapp1.0/data -v /nadeko/credentials.json:/opt/NadekoBot/src/NadekoBot/credentials.json kwoth/nadeko:dev
+```bash
+docker create --name=nadeko -v /nadeko/data:/opt/NadekoBot/src/NadekoBot/bin/Release/netcoreapp1.0/data -v /nadeko/credentials.json:/opt/NadekoBot/src/NadekoBot/credentials.json uirel/nadeko
```
-If you are coming from a previous version of nadeko (the old docker) make sure your crednetials.json has been copied into this directory and is the only thing in this folder.
--If you are making a fresh install, create your credentials.json from the following guide and palce it in the /nadeko folder
-http://nadekobot.readthedocs.io/en/latest/JSON%20Explanations/
+-If you are making a fresh install, create your credentials.json from the following guide and palce it in the /nadeko folder [Nadeko JSON Guide](http://nadekobot.readthedocs.io/en/latest/JSON%20Explanations/)
Next start the docker up with
-```docker start nadeko; docker logs -f nadeko```
+`docker start nadeko; docker logs -f nadeko`
The docker will start and the log file will start scrolling past. Depending on hardware the bot start can take up to 5 minutes on a small DigitalOcean droplet.
Once the log ends with "NadekoBot | Starting NadekoBot v1.0-rc2" the bot is ready and can be invited to your server. Ctrl+C at this point to stop viewing the logs.
After a few moments you should be able to invite Nadeko to your server. If you cannot check the log file for errors
-## Updates / Monitoring
+## Monitoring
-* Upgrade to the latest version of Nadeko simply `docker restart nadeko`.
* Monitor the logs of the container in realtime `docker logs -f nadeko`.
+## Updates
+
+# Manual
+Updates are handled by pulling the new layer of the Docker Container which contains a pre compiled update to Nadeko.
+The following commands are required for the default options
+
+`docker pull uirel/nadeko:latest`
+
+`docker stop nadeko; docker rm nadeko`
+
+`docker create --name=nadeko -v /nadeko/data:/opt/NadekoBot/src/NadekoBot/bin/Release/netcoreapp1.0/data -v /nadeko/credentials.json:/opt/NadekoBot/src/NadekoBot/credentials.json uirel/nadeko`
+
+`docker start nadeko`
+
+
+# Automatic Updates
+Automatic update are now handled by watchertower [WatchTower GitHub](https://github.com/CenturyLinkLabs/watchtower)
+To setup watchtower to keep Nadeko up-to-date for you with the default settings use the following command
+
+```bash
+docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock centurylink/watchtower --cleanup nadeko
+```
+
+This will check for updates to the docker every 5 minutes and update immediately. Alternatively using the `--interval X` command to change the interval, where X is the amount of time in seconds to wait. eg 21600 for 6 hours.
+
+
If you have any issues with the docker setup, please ask in #help but indicate you are using the docker.
-For information about configuring your bot or its functionality, please check the http://nadekobot.readthedocs.io/en/latest guides.
+For information about configuring your bot or its functionality, please check the guides.
diff --git a/docs/guides/Linux Guide.md b/docs/guides/Linux Guide.md
index c2e7e797..4e168cf4 100644
--- a/docs/guides/Linux Guide.md
+++ b/docs/guides/Linux Guide.md
@@ -8,11 +8,11 @@ Assuming you have followed the link above to setup an account and Droplet with 6
**Go through this whole guide before setting up Nadeko**
-#### Prerequisites
+####Prerequisites
- Download [PuTTY](http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html)
-- Download [CyberDuck](https://cyberduck.io) or [WinSCP](https://winscp.net/eng/download.php)
+- Download [WinSCP](https://winscp.net/eng/download.php) *(optional)*
-#### Follow these steps
+####Starting up
- **Open PuTTY.exe** that you downloaded before, and paste or enter your `IP address` and then click **Open**.
If you entered your Droplets IP address correctly, it should show **login as:** in a newly opened window.
@@ -24,46 +24,254 @@ If you entered your Droplets IP address correctly, it should show **login as:**
**NOTE:** Copy the commands, and just paste them using **mouse single right-click.**
-####Installing Git
+####Creating and Inviting bot
+
+- Read here how to [create a DiscordBot application](http://nadekobot.readthedocs.io/en/latest/guides/Windows%20Guide/#creating-discordbot-application)
+- [Visual Invite Guide](http://discord.kongslien.net/guide.html) **(Note: Client ID is your Bot ID)**
+- Copy your `Client ID` from your [applications page](https://discordapp.com/developers/applications/me).
+- Replace the **12345678** in this link:
+`https://discordapp.com/oauth2/authorize?client_id=`12345678`&scope=bot&permissions=66186303`
+ with your `Client ID`
+- The link should now look like this:
+`https://discordapp.com/oauth2/authorize?client_id=`**YOUR_CLENT_ID_HERE**`&scope=bot&permissions=66186303`
+- Go to the newly created link and pick the server we created, and click `Authorize`
+- The bot should have been added to your server.
+
+####Getting NadekoBot
+#####Part I
+Use the following command to get and run `linuxAIO.sh`
+(Remember **Do Not** rename the file **linuxAIO.sh**)
+
+`cd ~ && wget -N https://github.com/Kwoth/NadekoBot-BashScript/raw/master/linuxAIO.sh && bash linuxAIO.sh`
+
+You should see these following options after using the above command:
+
+```
+1. Download Dev Build (Latest)
+2. Download Stable Build
+3. Run Nadeko (Normally)
+4. Run Nadeko with Auto Restart (Run Nadeko normally before using this.)
+5. Auto-Install Prerequisites (for Ubuntu, Debian and CentOS)
+6. Set up credentials.json (if you have downloaded the bot already)
+7. To exit
+```
+#####Part II (Optional)
+**If** you are running NadekoBot for the first time on your system and never had any *prerequisites* installed and have Ubuntu, Debian or CentOS, Press `5` and `enter` key, then `y` when you see the following:
+```
+Welcome to NadekoBot Auto Prerequisites Installer.
+Would you like to continue?
+```
+That will install all the prerequisites your system need to run NadekoBot.
+
+If you prefer to install them [manually](http://nadekobot.readthedocs.io/en/latest/guides/Linux%20Guide/#installing-manually-optional), click on the link. *(Optional)*
+
+Once *prerequisites* finish installing.
+#####Part III
+Choose either
+`1` to get the **most updated build of NadekoBot**
+or
+`2` to get the **previously stable build of NadekoBot**
+and then press `enter` key.
+
+Once Installation is completed you should see the options again.
+
+Next, check out:
+#####Part IV (Optional)
+If you prefer to skip this step and want to do it [manually](http://nadekobot.readthedocs.io/en/latest/guides/Linux%20Guide/#setting-up-sftp) or already have the `credentials.json` file, click on the link. *(Optional)*
+
+- [1. Setting up credentials.json](http://nadekobot.readthedocs.io/en/latest/guides/Linux%20Guide/#setting-up-credentialsjson)
+- [2. To Get the Google API](http://nadekobot.readthedocs.io/en/latest/guides/Windows%20Guide/#setting-up-nadekobot-for-music)
+- [3. JSON Explanations for other APIs](http://nadekobot.readthedocs.io/en/latest/JSON%20Explanations/)
+
+You will need the following for the next step:
+![botimg](https://cdn.discordapp.com/attachments/251504306010849280/276455844223123457/Capture.PNG)
+
+- **Bot's Client ID** and **Bot's ID** (both are same) [(*required)](http://nadekobot.readthedocs.io/en/latest/guides/Windows%20Guide/#setting-up-credentialsjson-file)
+- **Bot's Token** (not client secret) [(*required)](http://nadekobot.readthedocs.io/en/latest/guides/Windows%20Guide/#setting-up-credentialsjson-file)
+- Your **Discord userID** [(*required)](http://nadekobot.readthedocs.io/en/latest/guides/Windows%20Guide/#setting-up-credentialsjson-file)
+- **Google Api Key** [(optional)](http://nadekobot.readthedocs.io/en/latest/guides/Windows%20Guide/#setting-up-nadekobot-for-music)
+- **LoL Api Key** [(optional)](http://nadekobot.readthedocs.io/en/latest/JSON%20Explanations/)
+- **Mashape Key** [(optional)](http://nadekobot.readthedocs.io/en/latest/JSON%20Explanations/)
+- **Osu Api Key** [(optional)](http://nadekobot.readthedocs.io/en/latest/JSON%20Explanations/)
+- **Sound Cloud Client Id** [(optional)](http://nadekobot.readthedocs.io/en/latest/JSON%20Explanations/)
+
+Once you have acquired them, press `6` to **Set up credentials.json**
+
+You will be asked to enter the required informations, just follow the on-screen instructions and enter the required information.
+*i.e* If you are asked **Bot's Token**, then just copy and paste or type the **Bot's Token** and press `enter` key.
+
+(If you want to skip any optional infos, just press `enter` key without typing/pasting anything.)
+Once done,
+#####Part V
+You should see the options again.
+Next, press `3` to **Run Nadeko (Normally)**
+Check in your discord server if your new bot is working properly.
+#####Part VI
+If your bot is working properly in your server, type `.die` to **shut down the bot**, then press `7` to **exit**.
+Next, [Run your bot again with **tmux**.](http://nadekobot.readthedocs.io/en/latest/guides/Linux%20Guide/#running-nadekobot)
+
+[Check this when you need to **restart** your **NadekoBot** anytime later along with tmux session.](http://nadekobot.readthedocs.io/en/latest/guides/Linux%20Guide/#restarting-nadeko)
+
+####Running NadekoBot
+
+**Create a new Session:**
+
+- `tmux new -s nadeko`
+
+The above command will create a new session named **nadeko** *(you can replace “nadeko” with anything you prefer and remember its your session name)* so you can run the bot in background without having to keep the PuTTY running.
+
+**Next, we need to run `linuxAIO.sh` in order to get the latest running scripts with patches:**
+
+- `cd ~ && bash linuxAIO.sh`
+
+**From the options,**
+
+Choose `3` to **Run NadekoBot normally.**
+**NOTE:** With option `3` (Running Normally), if you use `.die` [command](http://nadekobot.readthedocs.io/en/latest/Commands%20List/#administration) in discord. The bot will shut down and will stay offline until you manually run it again. (best if you want to check the bot.)
+
+Choose `4` to **Run NadekoBot with Auto Restart.**
+It will show you more options:
+```
+1. Run Auto Restart normally without Updating.
+2. Auto Restart and Update with Dev Build (latest)
+3. Auto Restart and Update with Stable Build
+4. Exit
+```
+**NOTE:** With option `4` (Running with Auto Restart), bot will auto run if you use `.die` [command](http://nadekobot.readthedocs.io/en/latest/Commands%20List/#administration) making the command `.die` to function as restart.
+
+See how that happens:
+
+![img9](https://cdn.discordapp.com/attachments/251504306010849280/251506312893038592/die_explaination.gif)
+
+**Remember** that, while running with Auto Restart, you will need to [close the tmux session](http://nadekobot.readthedocs.io/en/latest/guides/Linux%20Guide/#restarting-nadeko) to stop the bot completely.
+
+**Now check your Discord, the bot should be online**
+
+Next to **move the bot to background** and to do that, press **CTRL+B+D** (that will detach the nadeko session using TMUX) and you can finally close **PuTTY** if you want.
+
+####Restarting Nadeko
+
+**Restarting NadekoBot:**
+
+**If** you have chosen option `4` to **Run Nadeko with Auto Restart** from Nadeko's `linuxAIO.sh` *[(you got it from this step)](http://nadekobot.readthedocs.io/en/latest/guides/Linux%20Guide/#getting-nadekobot)*
+You can simply type `.die` in the server you have your NadekoBot to make her restart.
+
+**Restarting Nadeko with the Server:**
+
+Open **PuTTY** and login as you have before, type `reboot` and hit Enter.
+
+**Restarting Manually:**
+
+- Kill your previous session, check with `tmux ls`
+- `tmux kill-session -t nadeko` (don't forget to replace "nadeko" to what ever you named your bot's session)
+- [Run the bot again.](http://nadekobot.readthedocs.io/en/latest/guides/Linux%20Guide/#running-nadekobot)
+
+####Updating Nadeko
+
+- Connect to the terminal through **PuTTY**.
+- `tmux kill-session -t nadeko` (don't forget to replace **nadeko** in the command with the name of your bot's session)
+- Make sure the bot is **not** running.
+- `tmux new -s nadeko` (**nadeko** is the name of the session)
+- `cd ~ && bash linuxAIO.sh`
+- Choose either `1` or `2` to update the bot with **latest build** or **stable build** respectively.
+- Choose either `3` or `4` to run the bot again with **normally** or **auto restart** respectively.
+- Done. You can close **PuTTY** now.
+
+####Installing Manually (Optional)
+
+#####Installing Git
![img1](https://cdn.discordapp.com/attachments/251504306010849280/251504416019054592/git.gif)
+Ubuntu:
+
`sudo apt-get install git -y`
+CentOS:
+
+`yum -y install git`
+
**NOTE:** If the command is not being initiated, hit **Enter**
-####Installing .NET Core SDK
+#####Installing .NET Core SDK
![img2](https://cdn.discordapp.com/attachments/251504306010849280/251504746987388938/dotnet.gif)
-Go to [this link](https://www.microsoft.com/net/core#ubuntu) provided by microsoft for instructions on how to get the most up to date version of the dotnet core sdk!
-Make sure that you're on the correct page for your distribution of linux as the guides are different for the various distributions
+Go to [this link](https://www.microsoft.com/net/core#ubuntu) (for Ubuntu) or to [this link](https://www.microsoft.com/net/core#linuxcentos) (for CentOS) provided by microsoft for instructions on how to get the most up to date version of the dotnet core sdk!
+Make sure that you're on the correct page for your distribution of linux as the guides are different for the various distributions.
+Install the **currently supported version** `1.0.0-preview2-1-003177`.
+You can find it [here](https://github.com/dotnet/core/blob/master/release-notes/download-archives/1.1-preview2.1-download.md) if you prefer manual installing `dpkg` files.
-We'll go over the steps here for Ubuntu 16.04 anyway (these will **only** work on Ubuntu 16.04), accurate as of 25/11/2016
+We'll go over the steps here for few linux distributions, accurate as of March 08, 2017:
+**NOTE:** .NET CORE SDK only supports 64-bit Linux Operating Systems (Raspberry Pis are not supported because of this)
+**Ubuntu x64 17.04 & 16.10**
+```sh
+sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ yakkety main" > /etc/apt/sources.list.d/dotnetdev.list'
+sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893
+sudo apt-get update && sudo apt-get install dotnet-dev-1.0.0-preview2.1-003177 -y
```
+
+**Ubuntu x64 16.04**
+```sh
sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" > /etc/apt/sources.list.d/dotnetdev.list'
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893
sudo apt-get update && sudo apt-get install dotnet-dev-1.0.0-preview2.1-003177 -y
```
-**NOTE:** .NET CORE SDK only supports 64-bit Linux Operating Systems (Raspberry Pis are not supported because of this)
+**Ubuntu x64 14.04**
+```sh
+sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'
+sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893
+sudo apt-get update && sudo apt-get install dotnet-dev-1.0.0-preview2.1-003177 -y
+```
-####Installing Opus Voice Codec and libsodium
+**Debian 8 x64**
+```sh
+sudo apt-get install curl libunwind8 gettext -y
+curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=835021
+sudo mkdir -p /opt/dotnet && sudo tar zxf dotnet.tar.gz -C /opt/dotnet
+sudo ln -s /opt/dotnet/dotnet /usr/local/bin
+```
+
+**CentOS 7 x64**
+```sh
+sudo yum install libunwind libicu -y
+curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=835019
+sudo mkdir -p /opt/dotnet && sudo tar zxf dotnet.tar.gz -C /opt/dotnet
+sudo ln -s /opt/dotnet/dotnet /usr/local/bin
+```
+
+#####Installing Opus Voice Codec and libsodium
![img3](https://cdn.discordapp.com/attachments/251504306010849280/251505294654308353/libopus.gif)
+Ubuntu:
+
`sudo apt-get install libopus0 opus-tools libopus-dev libsodium-dev -y`
-####Installing FFMPEG
+CentOS:
+
+`yum -y install opus opus-devel`
+
+#####Installing FFMPEG
![img4](https://cdn.discordapp.com/attachments/251504306010849280/251505443111829505/ffmpeg.gif)
+Ubuntu:
+
`apt-get install ffmpeg -y`
+Centos:
+
+```sh
+yum -y install http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm epel-release
+yum -y install ffmpeg
+```
+
**NOTE:** If you are running **UBUNTU 14.04**, you must run these first:
-```
+```sh
sudo add-apt-repository ppa:mc3man/trusty-media
sudo apt-get update
sudo apt-get dist-upgrade
@@ -74,49 +282,25 @@ sudo apt-get dist-upgrade
**NOTE:** If you are running **Debian 8 Jessie**, please, follow these steps:
-`wget http://luxcaeli.de/installer.sh && sudo bash installer.sh` *Thanks to Eleria <3*
-
-In case you are not able to install it with **installer**, follow these steps:
-
-```
+```sh
sudo apt-get update
echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/debian-backports.list
sudo apt-get update && sudo apt-get install ffmpeg -y
```
-####Installing TMUX
+#####Installing TMUX
![img5](https://cdn.discordapp.com/attachments/251504306010849280/251505519758409728/tmux.gif)
+Ubuntu:
+
`sudo apt-get install tmux -y`
-####Getting NadekoBot
+Centos:
-Use the following command to get and run `linuxAIO.sh`:
-(Remember **DO NOT** rename the file `linuxAIO.sh`)
+`yum -y install tmux`
-`cd ~ && wget -N https://github.com/Kwoth/NadekoBot-BashScript/raw/master/linuxAIO.sh && bash linuxAIO.sh`
-
-Follow the on screen instructions:
-
-1. To Get the latest build. (most recent updates)
-2. To Get the stable build.
-
-Choose either `1` or `2` then press `enter` key.
-Once Installation is completed you should see the options again.
-Next, choose `5` to exit.
-
-####Creating and Inviting bot
-
-- Read here how to [create a DiscordBot application](http://nadekobot.readthedocs.io/en/latest/guides/Windows%20Guide/#creating-discordbot-application)
-- [Visual Invite Guide](http://discord.kongslien.net/guide.html) *NOTE: Client ID is your Bot ID*
-- Copy your `Client ID` from your [applications page](https://discordapp.com/developers/applications/me).
-- Replace the `12345678` in this link `https://discordapp.com/oauth2/authorize?client_id=12345678&scope=bot&permissions=66186303` with your `Client ID`.
-- The link should now look like this: `https://discordapp.com/oauth2/authorize?client_id=**YOUR_CLENT_ID_HERE**&scope=bot&permissions=66186303`.
-- Go to the newly created link and pick the server we created, and click `Authorize`.
-- The bot should have been added to your server.
-
-####Guide for Advance Users
+####Guide for Advance Users (Optional)
**Skip this step if you are a Regular User or New to Linux.**
@@ -135,23 +319,23 @@ Next, choose `5` to exit.
####Setting up SFTP
-- Open **CyberDuck**
-- Click on **Open Connection** (top-left corner), a new window should appear.
-- You should see **FTP (File Transfer Protocol)** in drop-down.
-- Change it to **SFTP (SSH File Transfer Protocol)**
-- Now, in **Server:** paste or type in your `Digital Ocean Droplets IP address`, leave `Port: 22` (no need to change it)
+- Open **WinSCP**
+- Click on **New Site** (top-left corner).
+- On the right-hand side, you should see **File Protocol** above a drop-down selection menu.
+- Select **SFTP** *(SSH File Transfer Protocol)* if its not already selected.
+- Now, in **Host name:** paste or type in your `Digital Ocean Droplets IP address` and leave `Port: 22` (no need to change it).
- In **Username:** type `root`
- In **Password:** type `the new root password (you changed at the start)`
-- Click on **Connect**
-- It should show you the NadekoBot folder which was created by git earlier
+- Click on **Login**, it should connect.
+- It should show you the NadekoBot folder which was created by git earlier on the right-hand side window.
- Open that folder, then open the `src` folder, followed by another `NadekoBot` folder and you should see `credentials.json` there.
####Setting up credentials.json
- Copy the `credentials.json` to desktop
- EDIT it as it is guided here: [Setting up credentials.json](http://nadekobot.readthedocs.io/en/latest/guides/Windows%20Guide/#setting-up-credentialsjson-file)
-- Paste/put it back in the folder once done. `(Using CyberDuck/WinSCP)`
-- **If** you already have Nadeko 1.0 setup and have `credentials.json` and `NadekoBot.db`, you can just copy and paste the `credentials.json` to `NadekoBot/src/NadekoBot` and `NadekoBot.db` to `NadekoBot/src/NadekoBot/bin/Release/netcoreapp1.0/data` using CyberDuck.
+- Paste/put it back in the folder once done. `(Using WinSCP)`
+- **If** you already have Nadeko 1.0 setup and have `credentials.json` and `NadekoBot.db`, you can just copy and paste the `credentials.json` to `NadekoBot/src/NadekoBot` and `NadekoBot.db` to `NadekoBot/src/NadekoBot/bin/Release/netcoreapp1.0/data` using WinSCP.
- **If** you have Nadeko 0.9x follow the [Upgrading Guide](http://nadekobot.readthedocs.io/en/latest/guides/Upgrading%20Guide/)
####Setting up Music
@@ -160,94 +344,32 @@ To set up Nadeko for music and Google API Keys, follow [Setting up NadekoBot for
Once done, go back to **PuTTY**
-####Running NadekoBot
+####Some more Info
-**Create a new Session:**
-
-- `tmux new -s nadeko`
-
-The above command will create a new session named **nadeko** *(you can replace “nadeko” with anything you prefer and remember its your session name)* so you can run the bot in background without having to keep the PuTTY running.
-
-**Next, we need to run `linuxAIO.sh` in order to get the latest running scripts with patches:**
-
-- `cd ~ && bash linuxAIO.sh`
-
-From the options,
-
-Choose `3` To Run the bot normally.
-**NOTE:** With option `3` (Running Normally), if you use `.die` [command](http://nadekobot.readthedocs.io/en/latest/Commands%20List/#administration) in discord. The bot will shut down and will stay offline until you manually run it again. (best if you want to check the bot.)
-
-Choose `4` To Run the bot with Auto Restart.
-**NOTE:** With option `4` (Running with Auto Restart), bot will auto run if you use `.die` [command](http://nadekobot.readthedocs.io/en/latest/Commands%20List/#administration) making the command `.die` to function as restart.
-
-See how that happens:
-
-![img9](https://cdn.discordapp.com/attachments/251504306010849280/251506312893038592/die_explaination.gif)
-
-**Remember** that, while running with Auto Restart, you will need to [close the tmux session](http://nadekobot.readthedocs.io/en/latest/guides/Linux%20Guide/#restarting-nadeko) to stop the bot completely.
-
-**Now check your Discord, the bot should be online**
-
-Next to **move the bot to background** and to do that, press **CTRL+B+D** (this will detach the nadeko session using TMUX), and you can finally close PuTTY now.
-
-####Some more Info (just in case)
-
-**Info about tmux:**
+#####Info about tmux
- If you want to **see the sessions** after logging back again, type `tmux ls`, and that will give you the list of sessions running.
- If you want to **switch to/ see that session**, type `tmux a -t nadeko` (**nadeko** is the name of the session we created before so, replace **“nadeko”** with the session name you created.)
- If you want to **kill** NadekoBot **session**, type `tmux kill-session -t nadeko`
-**If you are running Ubuntu 16.10, and having trouble installing .NET Core:**
-
-- Go to [Download Page for libicu55_55.1-7_amd64.deb](http://packages.ubuntu.com/en/xenial/amd64/libicu55/download)
-- Copy the link with a download option closest to you
-- `wget ` *e.g.* `wget http://mirrors.kernel.org/ubuntu/pool/main/i/icu/libicu55_55.1-7_amd64.deb` (make sure it is downloaded)
-- Install with: `dpkg –i libicu55_55.1-7_amd64.deb`
-- Now go back and install the .NET Core
-
-####Restarting Nadeko
-
-**Restarting Nadeko with the Server:**
-
-Open **PuTTY** and login as you have before, type `reboot` and hit Enter.
-
-**Restarting Manually:**
-
-- Kill your previous session, check with `tmux ls`
-- `tmux kill-session -t nadeko` (don't forget to replace "nadeko" to what ever you named your bot's session)
-- [Run the bot again.](http://nadekobot.readthedocs.io/en/latest/guides/Linux%20Guide/#running-nadekobot)
-
-####Updating Nadeko
-
-- Connect to the terminal through PuTTY.
-- `tmux kill-session -t nadeko` (don't forget to replace **nadeko** in the command with the name of your bot's session)
-- Make sure the bot is **not** running.
-- `tmux new -s nadeko` (**nadeko** is the name of the session)
-- `cd ~ && bash linuxAIO.sh`
-- Choose either `1` or `2` to update the bot with **latest build** or **stable build** respectively.
-- Choose either `3` or `4` to run the bot again with **normally** or **auto restart** respectively.
-- Done. You can close PuTTY now.
-
-####Alternative way to Install
+#####Alternative way to Install
If the [Nadeko installer](http://nadekobot.readthedocs.io/en/latest/guides/Linux%20Guide/#getting-nadekobot) shows any kind error, check if you have the `linuxAIO.sh` file and make sure its not renamed or if you want to manually install the bot. Use the following command(s):
-
![img6](https://cdn.discordapp.com/attachments/251504306010849280/251505587089571850/getting_nadeko.gif)
`cd ~ && curl -L https://github.com/Kwoth/NadekoBot-BashScript/raw/master/nadeko_installer.sh | sh`
**OR**
-```
-cd ~ && git clone -b 1.0 --recursive --depth 1 https://github.com/Kwoth/NadekoBot.git
+```sh
+cd ~ && git clone -b dev --recursive --depth 1 https://github.com/Kwoth/NadekoBot.git
cd ~/NadekoBot/discord.net/src/Discord.Net && dotnet restore && cd ../Discord.Net.Commands && dotnet restore && cd ../../../src/NadekoBot/ && dotnet restore && dotnet build --configuration Release
```
If you are getting error using the above steps try:
-```
+```sh
cd ~/NadekoBot/discord.net && dotnet restore -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json && dotnet restore
cd ~/NadekoBot/src/NadekoBot/ && dotnet restore && dotnet build --configuration Release
```
diff --git a/docs/guides/OSX Guide.md b/docs/guides/OSX Guide.md
index 7475a911..366a5319 100644
--- a/docs/guides/OSX Guide.md
+++ b/docs/guides/OSX Guide.md
@@ -30,7 +30,7 @@ brew install tmux
- `ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/`
- `ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/`
-- Download the [.NET Core SDK](https://www.microsoft.com/net/core#macos), found [here.](https://go.microsoft.com/fwlink/?LinkID=835011)
+- Download the [.NET Core SDK][.NET Core SDK]
- Open the `.pkg` file you downloaded and install it.
- `ln -s /usr/local/share/dotnet/dotnet /usr/local/bin`
@@ -166,6 +166,7 @@ If you used Screen press CTRL+A+D (this will detach the nadeko screen)
- `dotnet build --configuration Release`
[Homebrew]: http://brew.sh/
+[.NET Core SDK]: https://github.com/dotnet/core/blob/master/release-notes/download-archives/1.1-preview2.1-download.md
[DiscordApp]: https://discordapp.com/developers/applications/me
[Atom]: https://atom.io/
[Invite Guide]: http://discord.kongslien.net/guide.html
diff --git a/docs/guides/Windows Guide.md b/docs/guides/Windows Guide.md
index 04554aa2..0f141fad 100644
--- a/docs/guides/Windows Guide.md
+++ b/docs/guides/Windows Guide.md
@@ -7,18 +7,17 @@ ________________________________________________________________________________
#### Prerequisites
- 1) [.NET Core SDK][.NET Core SDK]
- 2) [Git][Git]
-- 3) [FFMPEG][FFMPEG]
-- 4) Google Account
-- 5) Soundcloud Account (if you want soundcloud support)
-- 6) [7zip][7zip] (or whatever you are using, WinRar)
-- 7) [Notepad++][Notepad++]
-- 8) Windows 8 or later
+- 3) Google Account
+- 4) Soundcloud Account (if you want soundcloud support)
+- 5) [7zip][7zip] (or whatever you are using, WinRar)
+- 6) [Notepad++][Notepad++]
+- 7) Windows 8 or later
####Guide
- Make sure you have installed both [Git][Git] and the [.NET Core SDK][.NET Core SDK].
- Create a **new folder** anywhere you like and name it `Nadeko`.
-- Next, [Right-Click on this link](https://github.com/Kwoth/NadekoBotInstallerWin/raw/master/NadekoInstaller.bat) and select **Save link as** and save the file `NadekoInstaller.bat` inside the `Nadeko` folder that we created earlier. (**DO NOT** rename the file `NadekoInstaller.bat`)
-- Once that's done, double-click on `NadekoInstaller.bat` to run it.
+- Next, [Right-Click on this link](https://github.com/Kwoth/NadekoBotInstallerWin/raw/master/NadekoInstaller.bat) and select **Save link as** and save the file `NadekoInstaller.bat` inside the `Nadeko` folder that we created earlier. (Please **DO NOT** rename the file `NadekoInstaller.bat`.)
+- Once that's done, right-click on `NadekoInstaller.bat` to run it as Administrator.
- From the options,
- Choose `1` to get the **most recent build**.
- Choose `2` to get the **stable build**.
@@ -46,7 +45,7 @@ ________________________________________________________________________________
- Again, copy the same `Client ID` and replace the `null` part of the `BotId` line with it.
- Go to a server on discord and attempt to mention yourself, but put a backslash at the start like shown below
- So the message `\@fearnlj01#3535` will appears as `<@145521851676884992>` after you send the message (to make it slightly easier, add the backslash after you type the mention out)
-- The message will appear as a mention if done correctly, copy the numbers from the message you sent (`145521851676884992`) and replace the `0` on the `OwnerIds` section with your user ID shown earlier.
+- The message will appear as a mention if done correctly, copy the numbers from the message you sent (`145521851676884992`) and replace the ID (By default, the ID is `105635576866156544`) on the `OwnerIds` section with your user ID shown earlier.
- Save `credentials.json` (make sure you aren't saving it as `credentials.json.txt`)
- If done correctly, you are now the bot owner. You can add multiple owners by seperating each owner ID with a comma within the square brackets.
@@ -59,7 +58,7 @@ ________________________________________________________________________________
- The bot should have been added to your server.
####Starting the bot
-- Go to the `Nadeko` folder that we have created earlier, and run the `NadekoInstaller.bat` file.
+- Go to the `Nadeko` folder that we have created earlier, and run the `NadekoInstaller.bat` file as Administrator.
- From the options,
- Choose `3` to **run the bot normally**.
(with normal-run the bot will shutdown and will stay offline if it disconnects by the use of `.die` command until you manually run it again. Useful if you want to test the bot.)
@@ -80,11 +79,30 @@ ________________________________________________________________________________
- You've updated and are running again, easy as that!
________________________________________________________________________________
-#### Setting Up NadekoBot For Music
-##### Prerequisites
-- 1) [FFMPEG][FFMPEG] installed.
-- 2) Setting up API keys.
+### Setting Up NadekoBot For Music
+In order to have a functioning music module, you need to install ffmpeg and setup api keys.
+
+#### Setting up `ffmpeg` using NadekoBot Client!
+- Go to the `Nadeko` folder that we have created earlier, and run the `NadekoInstaller.bat` file as Administrator.
+- From the options select `6` Install ffmpeg (for music)
+- Next, **Press Any Key** if you are running as Administrator or just close and relaunch it as Administrator using mouse right-click.
+- Wait for it to finish installing and backing up existing.
+- Once done, you should see "ffmpeg Installation complete!".
+- Next, **Press Any Key** to go back to NadekoBot Client.
+- Press `3` to run the bot normally just to test music. (optional)
+- `ffmpeg` installation for Music is now complete.
+
+#### Manual `ffmpeg` setup
+- Create a folder named `ffmpeg` in your main Windows directory. We will use **C:\ffmpeg** (for our guide)
+- Download FFMPEG through the link https://ffmpeg.zeranoe.com/builds/ (download static build)
+- EXTRACT it using `7zip` and place the FOLDER `ffmpeg-xxxxx-git-xxxxx-xxxx-static` inside **C:\ffmpeg**
+- Before proceeding, check out this gif to set up `ffmpeg` PATH correctly ![LINK TO gif](http://i.imgur.com/aR5l1Hn.gif) *(thanks to PooPeePants#7135)*
+- Go to My Computer, right click and select Properties. On the left tab, select Advanced System Settings. Under the Advanced tab, select Environmental Variables near the bottom. One of the variables should be called "Path". Add a semi-colon (;) to the end followed by your FFMPEG's **bin** install location (**for example C:\ffmpeg\ffmpeg-xxxxx-git-xxxxx-xxxx-static\bin**). Save and close.
+- Setup your API keys as explained above.
+- **Restart your computer**
+
+#### Api keys setup
- Follow these steps on how to setup Google API keys:
- Go to [Google Console][Google Console] and log in.
- Create a new project (name does not matter). Once the project is created, go into "Enable and manage APIs."
@@ -98,22 +116,12 @@ ________________________________________________________________________________
- Enter a name for the app and create it.
- You will need to fill out an application form to request access to the Soundcloud API.
- All requests for an API key must go through the review process, where applications will be reviewed on a case by case basis, in line with Soundcloud API Terms of Use. If your application is successful, you will receive an API key.
-- **Restart your computer**.
+- **Restart your computer**
-####Manual `ffmpeg` setup
-**Do this step in case you were not able to install `ffmpeg` with the installer.**
-- Create a folder named `ffmpeg` in your main Windows directory. We will use **C:\ffmpeg** (for our guide)
-- Download FFMPEG through the link https://ffmpeg.zeranoe.com/builds/ (download static build)
-- Extract it using `7zip` and place the folder `ffmpeg-xxxxx-git-xxxxx-xxxx-static` inside **C:\ffmpeg**
-- Before proceeding, check out this gif to set up `ffmpeg` PATH correctly ![LINK TO gif](http://i.imgur.com/aR5l1Hn.gif) *(thanks to PooPeePants#7135)*
-- Go to My Computer, right click and select Properties. On the left tab, select Advanced System Settings. Under the Advanced tab, select Environmental Variables near the bottom. One of the variables should be called "Path". Add a semi-colon (;) to the end followed by your FFMPEG's **bin** install location (**for example C:\ffmpeg\ffmpeg-xxxxx-git-xxxxx-xxxx-static\bin**). Save and close.
-- Setup your API keys as explained above.
-- Restart your computer.
-[.NET Core SDK]: https://www.microsoft.com/net/core#windowscmd
+[.NET Core SDK]: https://github.com/dotnet/core/blob/master/release-notes/download-archives/1.1-preview2.1-download.md
[Git]: https://git-scm.com/download/win
-[FFMPEG]: https://github.com/Soundofdarkness/FFMPEG-Inst/releases
[7zip]: http://www.7-zip.org/download.html
[DiscordApp]: https://discordapp.com/developers/applications/me
[Notepad++]: https://notepad-plus-plus.org/
diff --git a/docs/guides/mii-chan.md b/docs/guides/mii-chan.md
deleted file mode 100644
index 76be958b..00000000
--- a/docs/guides/mii-chan.md
+++ /dev/null
@@ -1,2 +0,0 @@
-Docs are in the air.
-Kwoth is magic.
diff --git a/docs/index.md b/docs/index.md
index c2dbfa0a..50909579 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -33,7 +33,7 @@ If you want to contribute, be sure to PR on the **[dev][dev]** branch.
- [Donate](Donate.md)
[img]: https://cdn.discordapp.com/attachments/202743183774318593/210580315381563392/discord.png
-[NadekoBot Server]: https://discord.gg/0ehQwTK2RBjAxzEY
+[NadekoBot Server]: https://discord.gg/nadekobot
[GitHub]: https://github.com/Kwoth/NadekoBot
[Issues]: https://github.com/Kwoth/NadekoBot/issues
[dev]: https://github.com/Kwoth/NadekoBot/tree/dev
diff --git a/global.json b/global.json
index ae345495..2c5832ca 100644
--- a/global.json
+++ b/global.json
@@ -1,3 +1,6 @@
{
- "projects": [ "Discord.Net/src", "src" ]
+ "projects": [ "Discord.Net/src", "src" ],
+ "sdk": {
+ "version": "1.0.0-preview2-1-003177"
+ }
}
diff --git a/scripts/Latest.bat b/scripts/Latest.bat
index f551c732..13248a96 100644
--- a/scripts/Latest.bat
+++ b/scripts/Latest.bat
@@ -1,79 +1,93 @@
@ECHO off
-TITLE Downloading NadekoBot, please wait
+TITLE Downloading Latest Build of NadekoBot...
::Setting convenient to read variables which don't delete the windows temp folder
-SET root=%~dp0
-CD /D %root%
-SET rootdir=%cd%
-SET build1=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.Core\
-SET build2=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.Rest\
-SET build3=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.WebSocket\
-SET build4=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.Commands\
-SET build5=%root%NadekoInstall_Temp\NadekoBot\src\NadekoBot\
-SET installtemp=%root%NadekoInstall_Temp\
+SET "root=%~dp0"
+CD /D "%root%"
+SET "rootdir=%cd%"
+SET "build1=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.Core\"
+SET "build2=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.Rest\"
+SET "build3=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.WebSocket\"
+SET "build4=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.Commands\"
+SET "build5=%root%NadekoInstall_Temp\NadekoBot\src\NadekoBot\"
+SET "installtemp=%root%NadekoInstall_Temp\"
::Deleting traces of last setup for the sake of clean folders, if by some miracle it still exists
-IF EXIST %installtemp% ( RMDIR %installtemp% /S /Q >nul 2>&1)
+IF EXIST "%installtemp%" ( RMDIR "%installtemp%" /S /Q >nul 2>&1)
+timeout /t 5
::Checks that both git and dotnet are installed
dotnet --version >nul 2>&1 || GOTO :dotnet
git --version >nul 2>&1 || GOTO :git
::Creates the install directory to work in and get the current directory because spaces ruins everything otherwise
:start
-MKDIR NadekoInstall_Temp
-CD /D %installtemp%
+MKDIR "%root%NadekoInstall_Temp"
+CD /D "%installtemp%"
::Downloads the latest version of Nadeko
ECHO Downloading Nadeko...
ECHO.
git clone -b dev --recursive --depth 1 --progress https://github.com/Kwoth/NadekoBot.git >nul
IF %ERRORLEVEL% EQU 128 (GOTO :giterror)
-TITLE Installing NadekoBot, please wait
+TITLE Installing NadekoBot, please wait...
ECHO.
-ECHO Installing...
+ECHO Installing Discord.Net(1/4)...
::Building Nadeko
-CD /D %build1%
+CD /D "%build1%"
dotnet restore >nul 2>&1
-CD /D %build2%
+ECHO Installing Discord.Net(2/4)...
+CD /D "%build2%"
dotnet restore >nul 2>&1
-CD /D %build3%
+ECHO Installing Discord.Net(3/4)...
+CD /D "%build3%"
dotnet restore >nul 2>&1
-CD /D %build4%
+ECHO Installing Discord.Net(4/4)...
+CD /D "%build4%"
dotnet restore >nul 2>&1
-CD /D %build5%
+ECHO.
+ECHO Discord.Net installation completed successfully...
+ECHO.
+ECHO Installing NadekoBot...
+CD /D "%build5%"
dotnet restore >nul 2>&1
dotnet build --configuration Release >nul 2>&1
+ECHO.
+ECHO NadekoBot installation completed successfully...
::Attempts to backup old files if they currently exist in the same folder as the batch file
-IF EXIST "%root%NadekoBot\" (GOTO :backupinstall)
+IF EXIST "%root%NadekoBot\" (GOTO :backupinstall) ELSE (GOTO :freshinstall)
:freshinstall
::Moves the NadekoBot folder to keep things tidy
+ ECHO.
+ ECHO Moving files, Please wait...
ROBOCOPY "%root%NadekoInstall_Temp" "%rootdir%" /E /MOVE >nul 2>&1
IF %ERRORLEVEL% GEQ 8 (GOTO :copyerror)
- GOTO :end
+ IF EXIST "%PROGRAMFILES(X86)%" (GOTO 64BIT) ELSE (GOTO 32BIT)
:backupinstall
- TITLE Backing up old files
+ TITLE Backing up old files...
ECHO.
- ECHO Make sure to close any files such as NadekoBot.db before PRESSing ANY KEY TO CONTINUE to prevent data loss
- PAUSE >nul 2>&1
+ ECHO Moving and Backing up old files...
::Recursively copies all files and folders from NadekoBot to NadekoBot_Old
ROBOCOPY "%root%NadekoBot" "%root%NadekoBot_Old" /MIR >nul 2>&1
IF %ERRORLEVEL% GEQ 8 (GOTO :copyerror)
ECHO.
- ECHO Old files backed up to NadekoBot_Old
+ ECHO Old files backed up to NadekoBot_Old...
::Copies the credentials and database from the backed up data to the new folder
COPY "%root%NadekoBot_Old\src\NadekoBot\credentials.json" "%installtemp%NadekoBot\src\NadekoBot\credentials.json" >nul 2>&1
IF %ERRORLEVEL% GEQ 8 (GOTO :copyerror)
ECHO.
- ECHO credentials.json copied to new folder
+ ECHO credentials.json copied...
ROBOCOPY "%root%NadekoBot_Old\src\NadekoBot\bin" "%installtemp%NadekoBot\src\NadekoBot\bin" /E >nul 2>&1
IF %ERRORLEVEL% GEQ 8 (GOTO :copyerror)
ECHO.
- ECHO Old bin folder copied to new folder
+ ECHO bin folder copied...
+ RD /S /Q "%root%NadekoBot_Old\src\NadekoBot\data\musicdata"
+ ECHO.
+ ECHO music cache cleared...
ROBOCOPY "%root%NadekoBot_Old\src\NadekoBot\data" "%installtemp%NadekoBot\src\NadekoBot\data" /E >nul 2>&1
IF %ERRORLEVEL% GEQ 8 (GOTO :copyerror)
ECHO.
- ECHO Old data folder copied to new folder
+ ECHO Old data folder copied...
::Moves the setup Nadeko folder
RMDIR "%root%NadekoBot\" /S /Q >nul 2>&1
ROBOCOPY "%root%NadekoInstall_Temp" "%rootdir%" /E /MOVE >nul 2>&1
IF %ERRORLEVEL% GEQ 8 (GOTO :copyerror)
- GOTO :end
+ IF EXIST "%PROGRAMFILES(X86)%" (GOTO 64BIT) ELSE (GOTO 32BIT)
:dotnet
::Terminates the batch script if it can't run dotnet --version
TITLE Error!
@@ -93,7 +107,7 @@ IF EXIST "%root%NadekoBot\" (GOTO :backupinstall)
:giterror
ECHO.
ECHO Git clone failed, trying again
- RMDIR %installtemp% /S /Q >nul 2>&1
+ RMDIR "%installtemp%" /S /Q >nul 2>&1
GOTO :start
:copyerror
::If at any point a copy error is encountered
@@ -105,12 +119,48 @@ IF EXIST "%root%NadekoBot\" (GOTO :backupinstall)
PAUSE >nul 2>&1
CD /D "%root%"
GOTO :EOF
+:64BIT
+ECHO.
+ECHO Your System Architecture is 64bit...
+GOTO end
+:32BIT
+ECHO.
+ECHO Your System Architecture is 32bit...
+timeout /t 5
+ECHO.
+ECHO Getting 32bit libsodium.dll and opus.dll...
+IF EXIST "%root%NadekoBot\src\NadekoBot\_libs\32\libsodium.dll" (GOTO copysodium) ELSE (GOTO downloadsodium)
+:copysodium
+del "%root%NadekoBot\src\NadekoBot\libsodium.dll"
+copy "%root%NadekoBot\src\NadekoBot\_libs\32\libsodium.dll" "%root%NadekoBot\src\NadekoBot\libsodium.dll"
+ECHO libsodium.dll copied.
+ECHO.
+timeout /t 5
+IF EXIST "%root%NadekoBot\src\NadekoBot\_libs\32\opus.dll" (GOTO copyopus) ELSE (GOTO downloadopus)
+:downloadsodium
+SET "FILENAME=%~dp0\NadekoBot\src\NadekoBot\libsodium.dll"
+powershell -Command "Invoke-WebRequest https://github.com/Kwoth/NadekoBot/raw/dev/src/NadekoBot/_libs/32/libsodium.dll -OutFile '%FILENAME%'"
+ECHO libsodium.dll downloaded.
+ECHO.
+timeout /t 5
+IF EXIST "%root%NadekoBot\src\NadekoBot\_libs\32\opus.dll" (GOTO copyopus) ELSE (GOTO downloadopus)
+:copyopus
+del "%root%NadekoBot\src\NadekoBot\opus.dll"
+copy "%root%NadekoBot\src\NadekoBot\_libs\32\opus.dll" "%root%NadekoBot\src\NadekoBot\opus.dll"
+ECHO opus.dll copied.
+GOTO end
+:downloadopus
+SET "FILENAME=%~dp0\NadekoBot\src\NadekoBot\opus.dll"
+powershell -Command "Invoke-WebRequest https://github.com/Kwoth/NadekoBot/raw/dev/src/NadekoBot/_libs/32/opus.dll -OutFile '%FILENAME%'"
+ECHO opus.dll downloaded.
+GOTO end
:end
::Normal execution of end of script
- TITLE Installation complete!
+ TITLE NadekoBot Installation complete!
CD /D "%root%"
RMDIR /S /Q "%installtemp%" >nul 2>&1
ECHO.
- ECHO Installation complete, press any key to close this window!
- PAUSE >nul 2>&1
- del Latest.bat
+ ECHO Installation complete!
+ ECHO.
+ PAUSE
+ del Latest.bat
\ No newline at end of file
diff --git a/scripts/NadekoAutoRun.bat b/scripts/NadekoAutoRun.bat
index 90d88f4a..4441e25b 100644
--- a/scripts/NadekoAutoRun.bat
+++ b/scripts/NadekoAutoRun.bat
@@ -2,8 +2,8 @@
@TITLE NadekoBot
-SET root=%~dp0
-CD /D %root%
+SET "root=%~dp0"
+CD /D "%root%"
CLS
ECHO Welcome to NadekoBot Auto Restart and Update!
@@ -25,32 +25,28 @@ IF ERRORLEVEL 1 GOTO latestar
:latestar
ECHO Auto Restart and Update with Dev Build (latest)
ECHO Bot will auto update on every restart!
-timeout /t 3
-CD /D %~dp0NadekoBot\src\NadekoBot
+CD /D "%~dp0NadekoBot\src\NadekoBot"
dotnet run --configuration Release
ECHO Updating...
-timeout /t 3
SET "FILENAME=%~dp0\Latest.bat"
-bitsadmin.exe /transfer "Downloading Nadeko (Latest)" /priority high https://github.com/Kwoth/NadekoBot/raw/master/scripts/Latest.bat "%FILENAME%"
+powershell -Command "Invoke-WebRequest https://github.com/Kwoth/NadekoBot/raw/dev/scripts/Latest.bat -OutFile '%FILENAME%'"
ECHO NadekoBot Dev Build (latest) downloaded.
-SET root=%~dp0
-CD /D %root%
+SET "root=%~dp0"
+CD /D "%root%"
CALL Latest.bat
GOTO latestar
:stablear
ECHO Auto Restart and Update with Stable Build
ECHO Bot will auto update on every restart!
-timeout /t 3
-CD /D %~dp0NadekoBot\src\NadekoBot
+CD /D "%~dp0NadekoBot\src\NadekoBot"
dotnet run --configuration Release
ECHO Updating...
-timeout /t 3
SET "FILENAME=%~dp0\Stable.bat"
-bitsadmin.exe /transfer "Downloading Nadeko (Stable)" /priority high https://github.com/Kwoth/NadekoBot/raw/master/scripts/Stable.bat "%FILENAME%"
+powershell -Command "Invoke-WebRequest https://github.com/Kwoth/NadekoBot/raw/dev/scripts/Stable.bat -OutFile '%FILENAME%'"
ECHO NadekoBot Stable build downloaded.
-SET root=%~dp0
-CD /D %root%
+SET "root=%~dp0"
+CD /D "%root%"
CALL Stable.bat
GOTO stablear
@@ -58,12 +54,12 @@ GOTO stablear
ECHO Normal Auto Restart
ECHO Bot will not auto update on every restart!
timeout /t 3
-CD /D %~dp0NadekoBot\src\NadekoBot
+CD /D "%~dp0NadekoBot\src\NadekoBot"
dotnet run --configuration Release
goto autorun
:Exit
-SET root=%~dp0
-CD /D %root%
+SET "root=%~dp0"
+CD /D "%root%"
del NadekoAutoRun.bat
CALL NadekoInstaller.bat
diff --git a/scripts/NadekoRun.bat b/scripts/NadekoRun.bat
index 207fb278..73c66b17 100644
--- a/scripts/NadekoRun.bat
+++ b/scripts/NadekoRun.bat
@@ -1,9 +1,9 @@
@ECHO off
@TITLE NadekoBot
-CD /D %~dp0NadekoBot\src\NadekoBot
+CD /D "%~dp0NadekoBot\src\NadekoBot"
dotnet run --configuration Release
ECHO NadekoBot has been succesfully stopped, press any key to close this window.
TITLE NadekoBot - Stopped
-CD /D %~dp0
+CD /D "%~dp0"
PAUSE >nul 2>&1
del NadekoRunNormal.bat
diff --git a/scripts/Stable.bat b/scripts/Stable.bat
index f1e11147..a3ffb6f4 100644
--- a/scripts/Stable.bat
+++ b/scripts/Stable.bat
@@ -1,79 +1,93 @@
@ECHO off
-TITLE Downloading NadekoBot, please wait
+TITLE Downloading Stable Build of NadekoBot...
::Setting convenient to read variables which don't delete the windows temp folder
-SET root=%~dp0
-CD /D %root%
-SET rootdir=%cd%
-SET build1=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.Core\
-SET build2=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.Rest\
-SET build3=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.WebSocket\
-SET build4=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.Commands\
-SET build5=%root%NadekoInstall_Temp\NadekoBot\src\NadekoBot\
-SET installtemp=%root%NadekoInstall_Temp\
+SET "root=%~dp0"
+CD /D "%root%"
+SET "rootdir=%cd%"
+SET "build1=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.Core\"
+SET "build2=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.Rest\"
+SET "build3=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.WebSocket\"
+SET "build4=%root%NadekoInstall_Temp\NadekoBot\Discord.Net\src\Discord.Net.Commands\"
+SET "build5=%root%NadekoInstall_Temp\NadekoBot\src\NadekoBot\"
+SET "installtemp=%root%NadekoInstall_Temp\"
::Deleting traces of last setup for the sake of clean folders, if by some miracle it still exists
-IF EXIST %installtemp% ( RMDIR %installtemp% /S /Q >nul 2>&1)
+IF EXIST "%installtemp%" ( RMDIR "%installtemp%" /S /Q >nul 2>&1)
+timeout /t 5
::Checks that both git and dotnet are installed
dotnet --version >nul 2>&1 || GOTO :dotnet
git --version >nul 2>&1 || GOTO :git
::Creates the install directory to work in and get the current directory because spaces ruins everything otherwise
:start
-MKDIR NadekoInstall_Temp
-CD /D %installtemp%
+MKDIR "%root%NadekoInstall_Temp"
+CD /D "%installtemp%"
::Downloads the latest version of Nadeko
ECHO Downloading Nadeko...
ECHO.
git clone -b master --recursive --depth 1 --progress https://github.com/Kwoth/NadekoBot.git >nul
IF %ERRORLEVEL% EQU 128 (GOTO :giterror)
-TITLE Installing NadekoBot, please wait
+TITLE Installing NadekoBot, please wait...
ECHO.
-ECHO Installing...
+ECHO Installing Discord.Net(1/4)...
::Building Nadeko
-CD /D %build1%
+CD /D "%build1%"
dotnet restore >nul 2>&1
-CD /D %build2%
+ECHO Installing Discord.Net(2/4)...
+CD /D "%build2%"
dotnet restore >nul 2>&1
-CD /D %build3%
+ECHO Installing Discord.Net(3/4)...
+CD /D "%build3%"
dotnet restore >nul 2>&1
-CD /D %build4%
+ECHO Installing Discord.Net(4/4)...
+CD /D "%build4%"
dotnet restore >nul 2>&1
-CD /D %build5%
+ECHO.
+ECHO Discord.Net installation completed successfully...
+ECHO.
+ECHO Installing NadekoBot...
+CD /D "%build5%"
dotnet restore >nul 2>&1
dotnet build --configuration Release >nul 2>&1
+ECHO.
+ECHO NadekoBot installation completed successfully...
::Attempts to backup old files if they currently exist in the same folder as the batch file
-IF EXIST "%root%NadekoBot\" (GOTO :backupinstall)
+IF EXIST "%root%NadekoBot\" (GOTO :backupinstall) ELSE (GOTO :freshinstall)
:freshinstall
::Moves the NadekoBot folder to keep things tidy
+ ECHO.
+ ECHO Moving files, Please wait...
ROBOCOPY "%root%NadekoInstall_Temp" "%rootdir%" /E /MOVE >nul 2>&1
IF %ERRORLEVEL% GEQ 8 (GOTO :copyerror)
- GOTO :end
+ IF EXIST "%PROGRAMFILES(X86)%" (GOTO 64BIT) ELSE (GOTO 32BIT)
:backupinstall
- TITLE Backing up old files
+ TITLE Backing up old files...
ECHO.
- ECHO Make sure to close any files such as NadekoBot.db before PRESSing ANY KEY TO CONTINUE to prevent data loss
- PAUSE >nul 2>&1
+ ECHO Moving and Backing up old files...
::Recursively copies all files and folders from NadekoBot to NadekoBot_Old
ROBOCOPY "%root%NadekoBot" "%root%NadekoBot_Old" /MIR >nul 2>&1
IF %ERRORLEVEL% GEQ 8 (GOTO :copyerror)
ECHO.
- ECHO Old files backed up to NadekoBot_Old
+ ECHO Old files backed up to NadekoBot_Old...
::Copies the credentials and database from the backed up data to the new folder
COPY "%root%NadekoBot_Old\src\NadekoBot\credentials.json" "%installtemp%NadekoBot\src\NadekoBot\credentials.json" >nul 2>&1
IF %ERRORLEVEL% GEQ 8 (GOTO :copyerror)
ECHO.
- ECHO credentials.json copied to new folder
+ ECHO credentials.json copied...
ROBOCOPY "%root%NadekoBot_Old\src\NadekoBot\bin" "%installtemp%NadekoBot\src\NadekoBot\bin" /E >nul 2>&1
IF %ERRORLEVEL% GEQ 8 (GOTO :copyerror)
ECHO.
- ECHO Old bin folder copied to new folder
+ ECHO bin folder copied...
+ RD /S /Q "%root%NadekoBot_Old\src\NadekoBot\data\musicdata"
+ ECHO.
+ ECHO music cache cleared...
ROBOCOPY "%root%NadekoBot_Old\src\NadekoBot\data" "%installtemp%NadekoBot\src\NadekoBot\data" /E >nul 2>&1
IF %ERRORLEVEL% GEQ 8 (GOTO :copyerror)
ECHO.
- ECHO Old data folder copied to new folder
+ ECHO Old data folder copied...
::Moves the setup Nadeko folder
RMDIR "%root%NadekoBot\" /S /Q >nul 2>&1
ROBOCOPY "%root%NadekoInstall_Temp" "%rootdir%" /E /MOVE >nul 2>&1
IF %ERRORLEVEL% GEQ 8 (GOTO :copyerror)
- GOTO :end
+ IF EXIST "%PROGRAMFILES(X86)%" (GOTO 64BIT) ELSE (GOTO 32BIT)
:dotnet
::Terminates the batch script if it can't run dotnet --version
TITLE Error!
@@ -93,7 +107,7 @@ IF EXIST "%root%NadekoBot\" (GOTO :backupinstall)
:giterror
ECHO.
ECHO Git clone failed, trying again
- RMDIR %installtemp% /S /Q >nul 2>&1
+ RMDIR "%installtemp%" /S /Q >nul 2>&1
GOTO :start
:copyerror
::If at any point a copy error is encountered
@@ -105,12 +119,48 @@ IF EXIST "%root%NadekoBot\" (GOTO :backupinstall)
PAUSE >nul 2>&1
CD /D "%root%"
GOTO :EOF
+:64BIT
+ECHO.
+ECHO Your System Architecture is 64bit...
+GOTO end
+:32BIT
+ECHO.
+ECHO Your System Architecture is 32bit...
+timeout /t 5
+ECHO.
+ECHO Getting 32bit libsodium.dll and opus.dll...
+IF EXIST "%root%NadekoBot\src\NadekoBot\_libs\32\libsodium.dll" (GOTO copysodium) ELSE (GOTO downloadsodium)
+:copysodium
+del "%root%NadekoBot\src\NadekoBot\libsodium.dll"
+copy "%root%NadekoBot\src\NadekoBot\_libs\32\libsodium.dll" "%root%NadekoBot\src\NadekoBot\libsodium.dll"
+ECHO libsodium.dll copied.
+ECHO.
+timeout /t 5
+IF EXIST "%root%NadekoBot\src\NadekoBot\_libs\32\opus.dll" (GOTO copyopus) ELSE (GOTO downloadopus)
+:downloadsodium
+SET "FILENAME=%~dp0\NadekoBot\src\NadekoBot\libsodium.dll"
+powershell -Command "Invoke-WebRequest https://github.com/Kwoth/NadekoBot/raw/dev/src/NadekoBot/_libs/32/libsodium.dll -OutFile '%FILENAME%'"
+ECHO libsodium.dll downloaded.
+ECHO.
+timeout /t 5
+IF EXIST "%root%NadekoBot\src\NadekoBot\_libs\32\opus.dll" (GOTO copyopus) ELSE (GOTO downloadopus)
+:copyopus
+del "%root%NadekoBot\src\NadekoBot\opus.dll"
+copy "%root%NadekoBot\src\NadekoBot\_libs\32\opus.dll" "%root%NadekoBot\src\NadekoBot\opus.dll"
+ECHO opus.dll copied.
+GOTO end
+:downloadopus
+SET "FILENAME=%~dp0\NadekoBot\src\NadekoBot\opus.dll"
+powershell -Command "Invoke-WebRequest https://github.com/Kwoth/NadekoBot/raw/dev/src/NadekoBot/_libs/32/opus.dll -OutFile '%FILENAME%'"
+ECHO opus.dll downloaded.
+GOTO end
:end
::Normal execution of end of script
- TITLE Installation complete!
+ TITLE NadekoBot Installation complete!
CD /D "%root%"
RMDIR /S /Q "%installtemp%" >nul 2>&1
ECHO.
- ECHO Installation complete, press any key to close this window!
- PAUSE >nul 2>&1
- del Stable.bat
+ ECHO Installation complete!
+ ECHO.
+ PAUSE
+ del Stable.bat
\ No newline at end of file
diff --git a/src/NadekoBot/Attributes/NadekoModule.cs b/src/NadekoBot/Attributes/NadekoModuleAttribute.cs
similarity index 100%
rename from src/NadekoBot/Attributes/NadekoModule.cs
rename to src/NadekoBot/Attributes/NadekoModuleAttribute.cs
diff --git a/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs b/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs
index 410a24af..eefc489c 100644
--- a/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs
+++ b/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs
@@ -6,6 +6,6 @@ namespace NadekoBot.Attributes
public class OwnerOnlyAttribute : PreconditionAttribute
{
public override Task CheckPermissions(ICommandContext context, CommandInfo executingCommand,IDependencyMap depMap) =>
- Task.FromResult((NadekoBot.Credentials.IsOwner(context.User) ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner")));
+ Task.FromResult((NadekoBot.Credentials.IsOwner(context.User) || NadekoBot.Client.CurrentUser.Id == context.User.Id ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner")));
}
}
\ No newline at end of file
diff --git a/src/NadekoBot/DataStructures/AsyncLazy.cs b/src/NadekoBot/DataStructures/AsyncLazy.cs
new file mode 100644
index 00000000..40800755
--- /dev/null
+++ b/src/NadekoBot/DataStructures/AsyncLazy.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NadekoBot.DataStructures
+{
+ public class AsyncLazy : Lazy>
+ {
+ public AsyncLazy(Func valueFactory) :
+ base(() => Task.Factory.StartNew(valueFactory))
+ { }
+
+ public AsyncLazy(Func> taskFactory) :
+ base(() => Task.Factory.StartNew(taskFactory).Unwrap())
+ { }
+
+ public TaskAwaiter GetAwaiter() { return Value.GetAwaiter(); }
+ }
+
+}
diff --git a/src/NadekoBot/DataStructures/CREmbed.cs b/src/NadekoBot/DataStructures/CREmbed.cs
new file mode 100644
index 00000000..cb67503b
--- /dev/null
+++ b/src/NadekoBot/DataStructures/CREmbed.cs
@@ -0,0 +1,91 @@
+using Discord;
+using Newtonsoft.Json;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NadekoBot.DataStructures
+{
+ public class CREmbed
+ {
+ private static readonly Logger _log;
+ public string PlainText { get; set; }
+ public string Title { get; set; }
+ public string Description { get; set; }
+ public CREmbedFooter Footer { get; set; }
+ public string Thumbnail { get; set; }
+ public string Image { get; set; }
+ public CREmbedField[] Fields { get; set; }
+ public uint Color { get; set; } = 7458112;
+
+ static CREmbed()
+ {
+ _log = LogManager.GetCurrentClassLogger();
+ }
+
+ public bool IsValid =>
+ !string.IsNullOrWhiteSpace(Title) ||
+ !string.IsNullOrWhiteSpace(Description) ||
+ !string.IsNullOrWhiteSpace(Thumbnail) ||
+ !string.IsNullOrWhiteSpace(Image) ||
+ (Footer != null && (!string.IsNullOrWhiteSpace(Footer.Text) || !string.IsNullOrWhiteSpace(Footer.IconUrl))) ||
+ (Fields != null && Fields.Length > 0);
+
+ public EmbedBuilder ToEmbed()
+ {
+ var embed = new EmbedBuilder()
+ .WithTitle(Title)
+ .WithDescription(Description)
+ .WithColor(new Discord.Color(Color));
+ if (Footer != null)
+ embed.WithFooter(efb => efb.WithIconUrl(Footer.IconUrl).WithText(Footer.Text));
+ embed.WithThumbnailUrl(Thumbnail)
+ .WithImageUrl(Image);
+
+ if (Fields != null)
+ foreach (var f in Fields)
+ {
+ embed.AddField(efb => efb.WithName(f.Name).WithValue(f.Value).WithIsInline(f.Inline));
+ }
+
+ return embed;
+ }
+
+ public static bool TryParse(string input, out CREmbed embed)
+ {
+ embed = null;
+ if (string.IsNullOrWhiteSpace(input))
+ return false;
+
+ try
+ {
+ var crembed = JsonConvert.DeserializeObject(input);
+
+ if (!crembed.IsValid)
+ return false;
+
+ embed = crembed;
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ }
+
+ public class CREmbedField
+ {
+ public string Name { get; set; }
+ public string Value { get; set; }
+ public bool Inline { get; set; }
+ }
+
+ public class CREmbedFooter {
+ public string Text { get; set; }
+ public string IconUrl { get; set; }
+ }
+}
diff --git a/src/NadekoBot/DataStructures/DisposableImutableList.cs b/src/NadekoBot/DataStructures/DisposableImutableList.cs
new file mode 100644
index 00000000..71bda6de
--- /dev/null
+++ b/src/NadekoBot/DataStructures/DisposableImutableList.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NadekoBot.DataStructures
+{
+
+ public static class DisposableReadOnlyListExtensions
+ {
+ public static IDisposableReadOnlyList AsDisposable(this IReadOnlyList arr) where T : IDisposable
+ => new DisposableReadOnlyList(arr);
+
+ public static IDisposableReadOnlyList> AsDisposable(this IReadOnlyList> arr) where TValue : IDisposable
+ => new DisposableReadOnlyList(arr);
+ }
+
+ public interface IDisposableReadOnlyList : IReadOnlyList, IDisposable
+ {
+ }
+
+ public class DisposableReadOnlyList : IDisposableReadOnlyList
+ where T : IDisposable
+ {
+ private readonly IReadOnlyList _arr;
+
+ public int Count => _arr.Count;
+
+ public T this[int index] => _arr[index];
+
+ public DisposableReadOnlyList(IReadOnlyList arr)
+ {
+ this._arr = arr;
+ }
+
+ public IEnumerator GetEnumerator()
+ => _arr.GetEnumerator();
+
+ IEnumerator IEnumerable.GetEnumerator()
+ => _arr.GetEnumerator();
+
+ public void Dispose()
+ {
+ foreach (var item in _arr)
+ {
+ item.Dispose();
+ }
+ }
+ }
+
+ public class DisposableReadOnlyList : IDisposableReadOnlyList>
+ where U : IDisposable
+ {
+ private readonly IReadOnlyList> _arr;
+
+ public int Count => _arr.Count;
+
+ KeyValuePair IReadOnlyList>.this[int index] => _arr[index];
+
+ public DisposableReadOnlyList(IReadOnlyList> arr)
+ {
+ this._arr = arr;
+ }
+
+ public IEnumerator> GetEnumerator() =>
+ _arr.GetEnumerator();
+
+ IEnumerator IEnumerable.GetEnumerator() =>
+ _arr.GetEnumerator();
+
+ public void Dispose()
+ {
+ foreach (var item in _arr)
+ {
+ item.Value.Dispose();
+ }
+ }
+ }
+}
diff --git a/src/NadekoBot/DataStructures/IndexedCollection.cs b/src/NadekoBot/DataStructures/IndexedCollection.cs
new file mode 100644
index 00000000..72b4f343
--- /dev/null
+++ b/src/NadekoBot/DataStructures/IndexedCollection.cs
@@ -0,0 +1,128 @@
+using NadekoBot.Services.Database.Models;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace NadekoBot.DataStructures
+{
+ public class IndexedCollection : IList where T : IIndexed
+ {
+ public List Source { get; }
+ private readonly object _locker = new object();
+
+ public IndexedCollection(IEnumerable source)
+ {
+ lock (_locker)
+ {
+ Source = source.OrderBy(x => x.Index).ToList();
+ for (var i = 0; i < Source.Count; i++)
+ {
+ if (Source[i].Index != i)
+ Source[i].Index = i;
+ }
+ }
+ }
+
+ public static implicit operator List(IndexedCollection x) =>
+ x.Source;
+
+ public IEnumerator GetEnumerator() =>
+ Source.GetEnumerator();
+
+ IEnumerator IEnumerable.GetEnumerator() =>
+ Source.GetEnumerator();
+
+ public void Add(T item)
+ {
+ lock (_locker)
+ {
+ item.Index = Source.Count;
+ Source.Add(item);
+ }
+ }
+
+ public virtual void Clear()
+ {
+ lock (_locker)
+ {
+ Source.Clear();
+ }
+ }
+
+ public bool Contains(T item)
+ {
+ lock (_locker)
+ {
+ return Source.Contains(item);
+ }
+ }
+
+ public void CopyTo(T[] array, int arrayIndex)
+ {
+ lock (_locker)
+ {
+ Source.CopyTo(array, arrayIndex);
+ }
+ }
+
+ public virtual bool Remove(T item)
+ {
+ bool removed;
+ lock (_locker)
+ {
+ if (removed = Source.Remove(item))
+ {
+ for (int i = 0; i < Source.Count; i++)
+ {
+ // hm, no idea how ef works, so I don't want to set if it's not changed,
+ // maybe it will try to update db?
+ // But most likely it just compares old to new values, meh.
+ if (Source[i].Index != i)
+ Source[i].Index = i;
+ }
+ }
+ }
+ return removed;
+ }
+
+ public int Count => Source.Count;
+ public bool IsReadOnly => false;
+ public int IndexOf(T item) => item.Index;
+
+ public virtual void Insert(int index, T item)
+ {
+ lock (_locker)
+ {
+ Source.Insert(index, item);
+ for (int i = index; i < Source.Count; i++)
+ {
+ Source[i].Index = i;
+ }
+ }
+ }
+
+ public virtual void RemoveAt(int index)
+ {
+ lock (_locker)
+ {
+ Source.RemoveAt(index);
+ for (int i = index; i < Source.Count; i++)
+ {
+ Source[i].Index = i;
+ }
+ }
+ }
+
+ public virtual T this[int index] {
+ get { return Source[index]; }
+ set {
+ lock (_locker)
+ {
+ value.Index = index;
+ Source[index] = value;
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/NadekoBot/DataStructures/PermissionsCollection.cs b/src/NadekoBot/DataStructures/PermissionsCollection.cs
new file mode 100644
index 00000000..484c4f9d
--- /dev/null
+++ b/src/NadekoBot/DataStructures/PermissionsCollection.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using NadekoBot.Services.Database.Models;
+
+namespace NadekoBot.DataStructures
+{
+ public class PermissionsCollection : IndexedCollection where T : IIndexed
+ {
+ private readonly object _localLocker = new object();
+ public PermissionsCollection(IEnumerable source) : base(source)
+ {
+ }
+
+ public static implicit operator List(PermissionsCollection x) =>
+ x.Source;
+
+ public override void Clear()
+ {
+ lock (_localLocker)
+ {
+ var first = Source[0];
+ base.Clear();
+ Source[0] = first;
+ }
+ }
+
+ public override bool Remove(T item)
+ {
+ bool removed;
+ lock (_localLocker)
+ {
+ if(Source.IndexOf(item) == 0)
+ throw new ArgumentException("You can't remove first permsission (allow all)");
+ removed = base.Remove(item);
+ }
+ return removed;
+ }
+
+ public override void Insert(int index, T item)
+ {
+ lock (_localLocker)
+ {
+ if(index == 0) // can't insert on first place. Last item is always allow all.
+ throw new IndexOutOfRangeException(nameof(index));
+ base.Insert(index, item);
+ }
+ }
+
+ public override void RemoveAt(int index)
+ {
+ lock (_localLocker)
+ {
+ if(index == 0) // you can't remove first permission (allow all)
+ throw new IndexOutOfRangeException(nameof(index));
+
+ base.RemoveAt(index);
+ }
+ }
+
+ public override T this[int index] {
+ get { return Source[index]; }
+ set {
+ lock (_localLocker)
+ {
+ if(index == 0) // can't set first element. It's always allow all
+ throw new IndexOutOfRangeException(nameof(index));
+ base[index] = value;
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/NadekoBot/Migrations/20170110111159_repeater-drop.Designer.cs b/src/NadekoBot/Migrations/20170110111159_repeater-drop.Designer.cs
new file mode 100644
index 00000000..db95f728
--- /dev/null
+++ b/src/NadekoBot/Migrations/20170110111159_repeater-drop.Designer.cs
@@ -0,0 +1,834 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using NadekoBot.Services.Database;
+using NadekoBot.Services.Database.Models;
+using NadekoBot.Modules.Music.Classes;
+
+namespace NadekoBot.Migrations
+{
+ [DbContext(typeof(NadekoContext))]
+ [Migration("20170110111159_repeater-drop")]
+ partial class repeaterdrop
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+ modelBuilder
+ .HasAnnotation("ProductVersion", "1.1.0-rtm-22752");
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("BotConfigId");
+
+ b.Property("ItemId");
+
+ b.Property("Type");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BotConfigId");
+
+ b.ToTable("BlacklistItem");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.BotConfig", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("BufferSize");
+
+ b.Property("CurrencyGenerationChance");
+
+ b.Property("CurrencyGenerationCooldown");
+
+ b.Property("CurrencyName");
+
+ b.Property("CurrencyPluralName");
+
+ b.Property("CurrencySign");
+
+ b.Property("DMHelpString");
+
+ b.Property("ForwardMessages");
+
+ b.Property("ForwardToAllOwners");
+
+ b.Property("HelpString");
+
+ b.Property("MigrationVersion");
+
+ b.Property("RemindMessageFormat");
+
+ b.Property("RotatingStatuses");
+
+ b.HasKey("Id");
+
+ b.ToTable("BotConfig");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("BaseDestroyed");
+
+ b.Property("CallUser");
+
+ b.Property("ClashWarId");
+
+ b.Property("SequenceNumber");
+
+ b.Property("Stars");
+
+ b.Property("TimeAdded");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ClashWarId");
+
+ b.ToTable("ClashCallers");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashWar", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ChannelId");
+
+ b.Property("EnemyClan");
+
+ b.Property("GuildId");
+
+ b.Property("Size");
+
+ b.Property("StartedAt");
+
+ b.Property("WarState");
+
+ b.HasKey("Id");
+
+ b.ToTable("ClashOfClans");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("CommandName");
+
+ b.Property("GuildConfigId");
+
+ b.Property("Seconds");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GuildConfigId");
+
+ b.ToTable("CommandCooldown");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.ConvertUnit", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("InternalTrigger");
+
+ b.Property("Modifier");
+
+ b.Property("UnitType");
+
+ b.HasKey("Id");
+
+ b.ToTable("ConversionUnits");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.Currency", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Amount");
+
+ b.Property("UserId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("Currency");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Amount");
+
+ b.Property("Reason");
+
+ b.Property("UserId");
+
+ b.HasKey("Id");
+
+ b.ToTable("CurrencyTransactions");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.CustomReaction", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("GuildId");
+
+ b.Property("IsRegex");
+
+ b.Property("OwnerOnly");
+
+ b.Property("Response");
+
+ b.Property("Trigger");
+
+ b.HasKey("Id");
+
+ b.ToTable("CustomReactions");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Amount");
+
+ b.Property("Name");
+
+ b.Property("UserId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("Donators");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("BotConfigId");
+
+ b.Property("Text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BotConfigId");
+
+ b.ToTable("EightBallResponses");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ChannelId");
+
+ b.Property("GuildConfigId");
+
+ b.Property("GuildConfigId1");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GuildConfigId");
+
+ b.HasIndex("GuildConfigId1");
+
+ b.ToTable("FilterChannelId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("GuildConfigId");
+
+ b.Property("Word");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GuildConfigId");
+
+ b.ToTable("FilteredWord");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ChannelId");
+
+ b.Property("GuildConfigId");
+
+ b.Property("GuildId");
+
+ b.Property("Type");
+
+ b.Property("Username");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GuildConfigId");
+
+ b.ToTable("FollowedStream");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ChannelId");
+
+ b.Property("GuildConfigId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GuildConfigId");
+
+ b.ToTable("GCChannelId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AutoAssignRoleId");
+
+ b.Property("AutoDeleteByeMessages");
+
+ b.Property("AutoDeleteByeMessagesTimer");
+
+ b.Property("AutoDeleteGreetMessages");
+
+ b.Property("AutoDeleteGreetMessagesTimer");
+
+ b.Property("AutoDeleteSelfAssignedRoleMessages");
+
+ b.Property("ByeMessageChannelId");
+
+ b.Property("ChannelByeMessageText");
+
+ b.Property("ChannelGreetMessageText");
+
+ b.Property("CleverbotEnabled");
+
+ b.Property("DefaultMusicVolume");
+
+ b.Property("DeleteMessageOnCommand");
+
+ b.Property("DmGreetMessageText");
+
+ b.Property("ExclusiveSelfAssignedRoles");
+
+ b.Property("FilterInvites");
+
+ b.Property("FilterWords");
+
+ b.Property("GreetMessageChannelId");
+
+ b.Property("GuildId");
+
+ b.Property("LogSettingId");
+
+ b.Property("MuteRoleName");
+
+ b.Property("PermissionRole");
+
+ b.Property("RootPermissionId");
+
+ b.Property("SendChannelByeMessage");
+
+ b.Property("SendChannelGreetMessage");
+
+ b.Property("SendDmGreetMessage");
+
+ b.Property("VerbosePermissions");
+
+ b.Property("VoicePlusTextEnabled");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GuildId")
+ .IsUnique();
+
+ b.HasIndex("LogSettingId");
+
+ b.HasIndex("RootPermissionId");
+
+ b.ToTable("GuildConfigs");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ChannelId");
+
+ b.Property("LogSettingId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("LogSettingId");
+
+ b.ToTable("IgnoredLogChannels");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ChannelId");
+
+ b.Property("LogSettingId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("LogSettingId");
+
+ b.ToTable("IgnoredVoicePresenceCHannels");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ChannelCreated");
+
+ b.Property("ChannelCreatedId");
+
+ b.Property("ChannelDestroyed");
+
+ b.Property("ChannelDestroyedId");
+
+ b.Property("ChannelId");
+
+ b.Property("ChannelUpdated");
+
+ b.Property("ChannelUpdatedId");
+
+ b.Property("IsLogging");
+
+ b.Property("LogOtherId");
+
+ b.Property("LogUserPresence");
+
+ b.Property("LogUserPresenceId");
+
+ b.Property("LogVoicePresence");
+
+ b.Property("LogVoicePresenceId");
+
+ b.Property("LogVoicePresenceTTSId");
+
+ b.Property("MessageDeleted");
+
+ b.Property("MessageDeletedId");
+
+ b.Property("MessageUpdated");
+
+ b.Property("MessageUpdatedId");
+
+ b.Property("UserBanned");
+
+ b.Property("UserBannedId");
+
+ b.Property("UserJoined");
+
+ b.Property("UserJoinedId");
+
+ b.Property("UserLeft");
+
+ b.Property("UserLeftId");
+
+ b.Property("UserMutedId");
+
+ b.Property("UserPresenceChannelId");
+
+ b.Property("UserUnbanned");
+
+ b.Property("UserUnbannedId");
+
+ b.Property("UserUpdated");
+
+ b.Property("UserUpdatedId");
+
+ b.Property("VoicePresenceChannelId");
+
+ b.HasKey("Id");
+
+ b.ToTable("LogSettings");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("BotConfigId");
+
+ b.Property("ModuleName");
+
+ b.Property("Prefix");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BotConfigId");
+
+ b.ToTable("ModulePrefixes");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Author");
+
+ b.Property("AuthorId");
+
+ b.Property("Name");
+
+ b.HasKey("Id");
+
+ b.ToTable("MusicPlaylists");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("GuildConfigId");
+
+ b.Property("UserId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GuildConfigId");
+
+ b.ToTable("MutedUserId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("NextId");
+
+ b.Property("PrimaryTarget");
+
+ b.Property("PrimaryTargetId");
+
+ b.Property("SecondaryTarget");
+
+ b.Property("SecondaryTargetName");
+
+ b.Property("State");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NextId")
+ .IsUnique();
+
+ b.ToTable("Permission");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("BotConfigId");
+
+ b.Property("Status");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BotConfigId");
+
+ b.ToTable("PlayingStatus");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("MusicPlaylistId");
+
+ b.Property("Provider");
+
+ b.Property("ProviderType");
+
+ b.Property("Query");
+
+ b.Property("Title");
+
+ b.Property("Uri");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MusicPlaylistId");
+
+ b.ToTable("PlaylistSong");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AuthorId");
+
+ b.Property("AuthorName")
+ .IsRequired();
+
+ b.Property("GuildId");
+
+ b.Property("Keyword")
+ .IsRequired();
+
+ b.Property("Text")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.ToTable("Quotes");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("BotConfigId");
+
+ b.Property("Icon");
+
+ b.Property("Name");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BotConfigId");
+
+ b.ToTable("RaceAnimals");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ChannelId");
+
+ b.Property("IsPrivate");
+
+ b.Property("Message");
+
+ b.Property("ServerId");
+
+ b.Property("UserId");
+
+ b.Property("When");
+
+ b.HasKey("Id");
+
+ b.ToTable("Reminders");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("GuildId");
+
+ b.Property("RoleId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GuildId", "RoleId")
+ .IsUnique();
+
+ b.ToTable("SelfAssignableRoles");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.UserPokeTypes", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("UserId");
+
+ b.Property("type");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("PokeGame");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
+ .WithMany("Blacklist")
+ .HasForeignKey("BotConfigId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar")
+ .WithMany("Bases")
+ .HasForeignKey("ClashWarId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
+ .WithMany("CommandCooldowns")
+ .HasForeignKey("GuildConfigId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
+ .WithMany("EightBallResponses")
+ .HasForeignKey("BotConfigId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
+ .WithMany("FilterInvitesChannelIds")
+ .HasForeignKey("GuildConfigId");
+
+ b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
+ .WithMany("FilterWordsChannelIds")
+ .HasForeignKey("GuildConfigId1");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
+ .WithMany("FilteredWords")
+ .HasForeignKey("GuildConfigId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
+ .WithMany("FollowedStreams")
+ .HasForeignKey("GuildConfigId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
+ .WithMany("GenerateCurrencyChannelIds")
+ .HasForeignKey("GuildConfigId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting")
+ .WithMany()
+ .HasForeignKey("LogSettingId");
+
+ b.HasOne("NadekoBot.Services.Database.Models.Permission", "RootPermission")
+ .WithMany()
+ .HasForeignKey("RootPermissionId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting")
+ .WithMany("IgnoredChannels")
+ .HasForeignKey("LogSettingId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting")
+ .WithMany("IgnoredVoicePresenceChannelIds")
+ .HasForeignKey("LogSettingId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
+ .WithMany("ModulePrefixes")
+ .HasForeignKey("BotConfigId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
+ .WithMany("MutedUsers")
+ .HasForeignKey("GuildConfigId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.Permission", "Next")
+ .WithOne("Previous")
+ .HasForeignKey("NadekoBot.Services.Database.Models.Permission", "NextId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
+ .WithMany("RotatingStatusMessages")
+ .HasForeignKey("BotConfigId");
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.MusicPlaylist")
+ .WithMany("Songs")
+ .HasForeignKey("MusicPlaylistId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b =>
+ {
+ b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
+ .WithMany("RaceAnimals")
+ .HasForeignKey("BotConfigId");
+ });
+ }
+ }
+}
diff --git a/src/NadekoBot/Migrations/20170110111159_repeater-drop.cs b/src/NadekoBot/Migrations/20170110111159_repeater-drop.cs
new file mode 100644
index 00000000..d05e6672
--- /dev/null
+++ b/src/NadekoBot/Migrations/20170110111159_repeater-drop.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace NadekoBot.Migrations
+{
+ public partial class repeaterdrop : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "Repeaters");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "Repeaters",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ ChannelId = table.Column(nullable: false),
+ GuildId = table.Column