Merge remote-tracking branch 'refs/remotes/Kwoth/1.0' into 1.0-fearnlj01

This commit is contained in:
Jordan Fearnley 2016-11-10 23:14:14 +00:00
commit 8c39c33eba
54 changed files with 2863 additions and 415 deletions

2
.gitignore vendored
View File

@ -2,7 +2,7 @@
src/NadekoBot/credentials.json
src/NadekoBot/data/NadekoBot.db
src/NadekoBot/musicdata
src/NadekoBot/data/musicdata
# Created by https://www.gitignore.io/api/visualstudio,visualstudiocode,windows,linux,macos

View File

@ -1,5 +1,5 @@
![img](https://ci.appveyor.com/api/projects/status/gmu6b3ltc80hr3k9?svg=true)
[![Discord](https://discordapp.com/api/servers/117523346618318850/widget.png)](https://discord.gg/0ehQwTK2RBjAxzEY)
[![Discord](https://discordapp.com/api/guilds/117523346618318850/widget.png)](https://discord.gg/0ehQwTK2RBjAxzEY)
[![Documentation Status](https://readthedocs.org/projects/nadekobot/badge/?version=latest)](http://nadekobot.readthedocs.io/en/1.0/?badge=latest)
# NadekoBot

View File

@ -1,40 +1,54 @@
For more information and how to setup your own NadekoBot, go to: <http://github.com/Kwoth/NadekoBot/wiki>
You can support the project on patreon: <https://patreon.com/nadekobot> or paypal: `nadekodiscordbot@gmail.com`
##Table Of Contents
- [Help](#help)
- [Administration](#administration)
- [ClashOfClans](#clashofclans)
- [CustomReactions](#customreactions)
- [Gambling](#gambling)
- [Games](#games)
- [Music](#music)
- [NSFW](#nsfw)
- [Permissions](#permissions)
- [Searches](#searches)
- [Utility](#utility)
### Administration
Command and aliases | Description | Usage
----------------|--------------|-------
`.resetperms` | Resets BOT's permissions module on this server to the default value. **Requires Administrator server permission.** | `.resetperms`
`.restart` | Restarts the bot. Might not work. **Bot owner only.** | `.restart`
`.delmsgoncmd` | Toggles the automatic deletion of 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`
`.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`
`.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`
`.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`
`.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`
`.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 BanMembers 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.`
`.setmuterole` | Sets a name of the role which will be assigned to people who should be muted. Default is nadeko-mute. After specifying this role, restart commands which use mute as punishment. **Requires ManageRoles server permission.** | `.setmuterole Silenced`
`.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.`
`.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`
`.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`
`.creatvoichanl` `.cvch` | Creates a new voice channel with a given name. **Requires ManageChannels server permission.** | `.cvch VoiceChannelName`
`.deltxtchanl` `.dtch` | Deletes a text channel with a given name. **Requires ManageChannels server permission.** | `.dtch TextChannelName`
`.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`
`.voiceunmute` | Gives a previously voice-muted user a permission to speak. **Requires MuteMembers server permission.** | `.voiceunmute @Someguy`
`.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`
`.creatvoichanl` `.cvch` | Creates a new voice channel with a given name. **Requires ManageChannels server permission.** | `.cvch VoiceChannelName`
`.deltxtchanl` `.dtch` | Deletes a text channel with a given name. **Requires ManageChannels server permission.** | `.dtch TextChannelName`
`.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`
`.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 https://www.twitch.tv/masterkwoth Developing Nakedo`
`.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` or `.send serverid|u:userid`
`.announce` | Sends a message to all servers' general channel bot is connected to. **Bot owner only.** | `.announce Useless spam`
`.savechat` | Saves a number of messages to a text file and sends it to you. **Bot owner only.** | `.savechat 150`
@ -43,23 +57,23 @@ Command and aliases | Description | Usage
`.donadd` | Add a donator to the database. **Bot owner only.** | `.donadd Donate Amount`
`.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`
`.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
`.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
`.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`
`.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`
`.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`
`.logserver` | Logs server activity in this channel. **Requires Administrator server permission.** **Bot owner only.** | `.logserver`
`.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`
`.userpresence` | Starts logging to this channel when someone from the server goes online/offline/idle. **Requires Administrator server permission.** | `.userpresence`
`.voicepresence` | Toggles logging to this channel whenever someone joins or leaves a voice channel you are currently in. **Requires Administrator server permission.** | `.voicepresence`
`.repeatinvoke` `.repinv` | Immediately shows the repeat message and restarts the timer. **Requires ManageMessages server permission.** | `.repinv`
`.userpresence` | Starts logging to this channel when someone from the server goes online/offline/idle. **Requires Administrator server permission.** | `.userpresence`
`.voicepresence` | Toggles logging to this channel whenever someone joins or leaves a voice channel you are currently in. **Requires Administrator server permission.** | `.voicepresence`
`.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. | `.repeat 5 Hello there`
`.migratedata` | Migrate data from old bot configuration **Bot owner only.** | `.migratedata`
`.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`
`.removeplaying` `.rmpl` `.repl` | Removes a playing string on a given number. **Bot owner only.** | `.rmpl`
`.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`
`.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`
@ -68,18 +82,20 @@ Command and aliases | Description | Usage
`.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`
`.leave` | Makes Nadeko leave the server. Either name or id required. **Bot owner only.** | `.leave 123123123331`
`.greetdel` `.grdel` | Toggles automatic deletion of greet messages. **Requires ManageServer server permission.** | `.greetdel`
`.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%`.
`.leave` | Makes Nadeko leave the server. Either name or id required. **Bot owner only.** | `.leave 123123123331`
`.greetdel` `.grdel` | Toggles automatic deletion of greet messages. **Requires ManageServer server permission.** | `.greetdel`
`.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 mention the new member. Using it with no message will show the current bye message. **Requires ManageServer server permission.** | `.byemsg %user% has left.`
`.byedel` | Toggles automatic deletion of bye messages. **Requires ManageServer server permission.** | `.byedel`
`.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`
`.byemsg` | Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message. **Requires ManageServer server permission.** | `.byemsg %user% has left.`
`.byedel` | Toggles automatic deletion of bye messages. **Requires ManageServer server permission.** | `.byedel`
`.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`
###### [Back to TOC](#table-of-contents)
### ClashOfClans
Command and aliases | Description | Usage
----------------|--------------|-------
@ -93,6 +109,8 @@ 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)
### CustomReactions
Command and aliases | Description | Usage
----------------|--------------|-------
@ -101,6 +119,8 @@ Command and aliases | Description | Usage
`.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`
###### [Back to TOC](#table-of-contents)
### Gambling
Command and aliases | Description | Usage
----------------|--------------|-------
@ -108,7 +128,7 @@ Command and aliases | Description | Usage
`$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"`
`$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`
`$race` | Starts a new animal race. | `$race`
@ -121,6 +141,8 @@ Command 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`
###### [Back to TOC](#table-of-contents)
### Games
Command and aliases | Description | Usage
----------------|--------------|-------
@ -132,16 +154,21 @@ Command and aliases | Description | Usage
`>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`
`>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`
`>pick` | Picks the currency planted in this channel. | `>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`
`>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`
`>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)
### Help
Command and aliases | Description | Usage
----------------|--------------|-------
@ -152,10 +179,12 @@ Command and aliases | Description | Usage
`-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)
### Music
Command 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. | `!!n`
`!!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`
@ -185,12 +214,16 @@ Command and aliases | Description | Usage
`!!getlink` `!!gl` | Shows a link to the song in the queue by index, or the currently playing song by default. | `!!gl`
`!!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`
###### [Back to TOC](#table-of-contents)
### NSFW
Command and aliases | Description | Usage
----------------|--------------|-------
`~hentai` | Shows a 2 random images (from gelbooru and danbooru) with a given tag. Tag is optional but preferred. Only 1 tag allowed. | `~hentai yuri`
`~hentai` | Shows a hentai image from a random website (gelbooru or danbooru or konachan or atfbooru) with a given tag. Tag is optional but preferred. Only 1 tag allowed. | `~hentai yuri`
`~hentaibomb` | Shows a total 4 images (from gelbooru, danbooru, konachan and atfbooru). Tag is optional but preferred. | `~hentaibomb yuri`
`~atfbooru` `~atf` | Shows a random hentai image from atfbooru with a given tag. Tag is optional but preferred. | `~atfbooru 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`
`~konachan` | Shows a random hentai image from konachan with a given tag. Tag is optional but preferred. (multiple tags are appended with +) | `~konachan yuri`
`~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`
@ -198,6 +231,8 @@ Command and aliases | Description | Usage
`~boobs` | Real adult content. | `~boobs`
`~butts` `~ass` `~butt` | Real adult content. | `~butts` or `~ass`
###### [Back to TOC](#table-of-contents)
### Permissions
Command and aliases | Description | Usage
----------------|--------------|-------
@ -230,6 +265,8 @@ Command and aliases | Description | Usage
`;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`
###### [Back to TOC](#table-of-contents)
### Searches
Command and aliases | Description | Usage
----------------|--------------|-------
@ -241,6 +278,7 @@ Command and aliases | Description | Usage
`~img` `~i` | Pulls the first image found using a search parameter. Use ~ir for different results. | `~i cute kitten`
`~ir` | Pulls a random image using a search parameter. | `~ir 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`
`~hearthstone` `~hs` | Searches for a Hearthstone card and shows its image. Takes a while to complete. | `~hs Ysera`
`~urbandict` `~ud` | Searches Urban Dictionary for a word. | `~ud Pineapple`
@ -252,12 +290,10 @@ Command and aliases | Description | Usage
`~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 <http://www.appear.in> video call link for you and other mentioned people. The link is sent to mentioned people via a private message. | `~videocall "@SomeGuy"`
`~av` `~avatar` | Shows a mentioned person's avatar. | `~av "@SomeGuy"`
`~avatar` `~av` | Shows a mentioned person's avatar. | `~av "@SomeGuy"`
`~lolban` | Shows top banned champions ordered by ban rate. | `~lolban`
`~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"`
`~translate` `~trans` | Translates from>to text. From the given language to the destination language. | `~trans en>fr Hello`
`~translangs` | Lists the valid languages for translation. | `~translangs`
`~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 <http://api.yomomma.info/> | `~ym`
@ -278,8 +314,14 @@ Command and aliases | Description | Usage
`~liststreams` `~ls` | Lists all streams you are following on this server. | `~ls`
`~removestream` `~rms` | Removes notifications of a certain streamer on this channel. **Requires ManageMessages server permission.** | `~rms SomeGuy`
`~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` | `~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`
`~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)
### Utility
Command and aliases | Description | Usage
----------------|--------------|-------
@ -293,17 +335,19 @@ Command and aliases | Description | Usage
`.channeltopic` `.ct` | Sends current channel's topic as a message. | `.ct`
`.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`
`.calculate` `.calc` | Evaluate a mathematical expression. | `.calc 1+1`
`.calcops` | Shows all available operations in .calc command | `.calcops`
`.togethertube` `.totube` | Creates a new room on <https://togethertube.com> and shows the link in the chat. | `.totube`
`.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`
`.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`
`.remind` | Sends a message to you or a channel after certain amount of time. First argument is me/here/'channelname'. Second argument is time in a descending order (mo>w>d>h>m) example: 1w5d3h10m. Third argument is a (multiword)message. | `.remind me 1d5h Do something` or `.remind #general Start now!`
`.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%, you gotta do %message%!`
`.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`

View File

@ -34,25 +34,25 @@ Setting up your API keys
====================
####This part is completely optional, **However it is necessary for music to work properly**
- **GoogleAPIKey** - Required for Youtube Song Search, Playlist queuing, and URL Shortener. `~i` and `~img`.
- You can get this api Key [here](https://console.developers.google.com/apis)
You can get this api Key [here](https://console.developers.google.com/apis)
- **SoundCloudClientID** - Required to queue soundloud songs from sc links.
- You will need to create a new app [here](http://soundcloud.com/you/apps). **Please note you must be logged into SoundCloud**
You will need to create a new app [here](http://soundcloud.com/you/apps). **Please note you must be logged into SoundCloud**
- Simply click Register a new application and enter a name.
- Copy the Client ID and click "save app" then paste the Client Id it into your `credentials.json`
- **MashapeKey** - Required for Urban Disctionary, Hashtag search, and Hearthstone cards.
- You need to create an account on their [api marketplace](https://market.mashape.com/), after that go to `market.mashape.com/YOURNAMEHERE/applications/default-application` and press **Get the keys** in the top right corner.
You need to create an account on their [api marketplace](https://market.mashape.com/), after that go to `market.mashape.com/YOURNAMEHERE/applications/default-application` and press **Get the keys** in the top right corner.
- Copy the key and paste it into `credentials.json`
- **LOLAPIKey** - Required for all League of Legends commands.
- You can get this key [here](http://api.champion.gg/)
You can get this key [here](http://api.champion.gg/)
- **OsuAPIKey** - Required for Osu commands
- You can get this key [here](https://osu.ppy.sh/p/api) **You will need to log in and like the soundcloud it may take a few tries**
You can get this key [here](https://osu.ppy.sh/p/api) **You will need to log in and like the soundcloud it may take a few tries**
- **CarbonKey** -This key is for Carobnitex.net stats.
- Most likely unnecessary **Needed only if your bot is listed on Carbonitex.net**
Most likely unnecessary **Needed only if your bot is listed on Carbonitex.net**
Additional options
====================
- **TotalShards** - Required if the bot will be connected to more than 2500 servers
- Most likely unnecessary to change until your bot is added to more than 2000 servers
Most likely unnecessary to change until your bot is added to more than 2000 servers
[//]: # (- **Db** - Allows for advanced database configuration )
[//]: # ( - Leave this with the `null` value for standard operation - change this to `examples` to [This is only a comment so doesn't need proper detail])
@ -63,3 +63,5 @@ In the folder where `NadekoBot.exe` is located you should also see a `Data` fold
`config.json` contains user specific commands, such as: if DM's sent to the bot are forwarded to you, Blacklisted Ids, Servers, and channels...etc.
**If you do not see** `config.json` **you need to rename** `config_example.json` **to** `config.json`
[CleverBot APIs]: https://cleverbot.io/keys

View File

@ -1,54 +1,3 @@
# Docker Guide with DigitalOcean
#####Prerequisites
- Digital ocean account (you can use my [reflink][reflink] to support the project and get 10$ after you register)
- [PuTTY][PuTTY]
- A bot account - follow this [guide][guide]
- $5
- Common sense
#####Guide
- Click on the create droplet button
![img](http://i.imgur.com/g2ayOcC.png)
- Pick one click apps and select docker on 14.04
![img](http://imgur.com/065Xkme.png)
- Pick any droplet size you want (5$ will work ok-ish on a few servers)
- Pick location closest to your discord server's location
- Pick a hostname
![img](http://imgur.com/ifPKB6p.png)
- Click create
You will get an email from DigitalOcean with your credentials now.
Open putty and type ip adress **you got in your email** with port 22
![img](http://imgur.com/Mh5ehsh.png)
- Console will open and you will be prompted for a username, type `root`.
- Type in the password you got in the email.
- Confirm the password you just typed in.
- Type in the new password.
- Confirm new password.
- When you are successfully logged in, type
`docker run --name nadeko -v /nadeko:/config uirel/nadeko`
- Wait for it to download and at one point it is going to start throwing errors due to `credentials.json` being empty
- CTRL+C to exit that
- Type `docker stop nadeko`
- Type `nano /nadeko/credentials.json` and type in your `credentials`
- CTRL+X then CTRL+Y to save
- Type `docker start nadeko`
- Type `docker logs -f nadeko` to see the console output
**Your bot is running, enjoy! o/**
*When you want to update the bot, just type `docker restart nadeko` as it always downloads latest prerelease*
[reflink]: http://m.do.co/c/46b4d3d44795/
[PuTTY]: http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
[guide]: http://discord.kongslien.net/guide.html
## There is no docker image for 1.0 nadeko right now. Soon.

View File

@ -0,0 +1,781 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using NadekoBot.Services.Database.Impl;
namespace NadekoBot.Migrations
{
[DbContext(typeof(NadekoSqliteContext))]
[Migration("20161107213222_Cleverbot")]
partial class Cleverbot
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
modelBuilder
.HasAnnotation("ProductVersion", "1.0.0-rtm-21431");
modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<ulong>("ItemId");
b.Property<int>("Type");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("BlacklistItem");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.BotConfig", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("BufferSize");
b.Property<float>("CurrencyGenerationChance");
b.Property<int>("CurrencyGenerationCooldown");
b.Property<string>("CurrencyName");
b.Property<string>("CurrencyPluralName");
b.Property<string>("CurrencySign");
b.Property<string>("DMHelpString");
b.Property<bool>("ForwardMessages");
b.Property<bool>("ForwardToAllOwners");
b.Property<string>("HelpString");
b.Property<int>("MigrationVersion");
b.Property<string>("RemindMessageFormat");
b.Property<bool>("RotatingStatuses");
b.HasKey("Id");
b.ToTable("BotConfig");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("BaseDestroyed");
b.Property<string>("CallUser");
b.Property<int>("ClashWarId");
b.Property<int?>("SequenceNumber");
b.Property<int>("Stars");
b.Property<DateTime>("TimeAdded");
b.HasKey("Id");
b.HasIndex("ClashWarId");
b.ToTable("ClashCallers");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashWar", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<string>("EnemyClan");
b.Property<ulong>("GuildId");
b.Property<int>("Size");
b.Property<DateTime>("StartedAt");
b.Property<int>("WarState");
b.HasKey("Id");
b.ToTable("ClashOfClans");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("CommandName");
b.Property<int?>("GuildConfigId");
b.Property<int>("Seconds");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("CommandCooldown");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ConvertUnit", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("InternalTrigger");
b.Property<decimal>("Modifier");
b.Property<string>("UnitType");
b.HasKey("Id");
b.ToTable("ConversionUnits");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Currency", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<long>("Amount");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.HasIndex("UserId")
.IsUnique();
b.ToTable("Currency");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<long>("Amount");
b.Property<string>("Reason");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.ToTable("CurrencyTransactions");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.CustomReaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong?>("GuildId");
b.Property<bool>("IsRegex");
b.Property<bool>("OwnerOnly");
b.Property<string>("Response");
b.Property<string>("Trigger");
b.HasKey("Id");
b.ToTable("CustomReactions");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Amount");
b.Property<string>("Name");
b.Property<ulong>("UserId");
b.HasKey("Id");
b.HasIndex("UserId")
.IsUnique();
b.ToTable("Donators");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("Text");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("EightBallResponses");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("GuildConfigId");
b.Property<int?>("GuildConfigId1");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.HasIndex("GuildConfigId1");
b.ToTable("FilterChannelId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("GuildConfigId");
b.Property<string>("Word");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("FilteredWord");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("GuildConfigId");
b.Property<ulong>("GuildId");
b.Property<int>("Type");
b.Property<string>("Username");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("FollowedStream");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("GuildConfigId");
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.ToTable("GCChannelId");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("AutoAssignRoleId");
b.Property<bool>("AutoDeleteByeMessages");
b.Property<bool>("AutoDeleteGreetMessages");
b.Property<int>("AutoDeleteGreetMessagesTimer");
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages");
b.Property<ulong>("ByeMessageChannelId");
b.Property<string>("ChannelByeMessageText");
b.Property<string>("ChannelGreetMessageText");
b.Property<bool>("CleverbotEnabled");
b.Property<float>("DefaultMusicVolume");
b.Property<bool>("DeleteMessageOnCommand");
b.Property<string>("DmGreetMessageText");
b.Property<bool>("ExclusiveSelfAssignedRoles");
b.Property<bool>("FilterInvites");
b.Property<bool>("FilterWords");
b.Property<ulong>("GreetMessageChannelId");
b.Property<ulong>("GuildId");
b.Property<int?>("LogSettingId");
b.Property<string>("MuteRoleName");
b.Property<string>("PermissionRole");
b.Property<int?>("RootPermissionId");
b.Property<bool>("SendChannelByeMessage");
b.Property<bool>("SendChannelGreetMessage");
b.Property<bool>("SendDmGreetMessage");
b.Property<bool>("VerbosePermissions");
b.Property<bool>("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<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("LogSettingId");
b.HasKey("Id");
b.HasIndex("LogSettingId");
b.ToTable("IgnoredLogChannels");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<int?>("LogSettingId");
b.HasKey("Id");
b.HasIndex("LogSettingId");
b.ToTable("IgnoredVoicePresenceCHannels");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("ChannelCreated");
b.Property<bool>("ChannelDestroyed");
b.Property<ulong>("ChannelId");
b.Property<bool>("ChannelUpdated");
b.Property<bool>("IsLogging");
b.Property<bool>("LogUserPresence");
b.Property<bool>("LogVoicePresence");
b.Property<bool>("MessageDeleted");
b.Property<bool>("MessageUpdated");
b.Property<bool>("UserBanned");
b.Property<bool>("UserJoined");
b.Property<bool>("UserLeft");
b.Property<ulong>("UserPresenceChannelId");
b.Property<bool>("UserUnbanned");
b.Property<bool>("UserUpdated");
b.Property<ulong>("VoicePresenceChannelId");
b.HasKey("Id");
b.ToTable("LogSettings");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("ModuleName");
b.Property<string>("Prefix");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("ModulePrefixes");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Author");
b.Property<ulong>("AuthorId");
b.Property<string>("Name");
b.HasKey("Id");
b.ToTable("MusicPlaylists");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("NextId");
b.Property<int>("PrimaryTarget");
b.Property<ulong>("PrimaryTargetId");
b.Property<int>("SecondaryTarget");
b.Property<string>("SecondaryTargetName");
b.Property<bool>("State");
b.HasKey("Id");
b.HasIndex("NextId")
.IsUnique();
b.ToTable("Permission");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("Status");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("PlayingStatus");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("MusicPlaylistId");
b.Property<string>("Provider");
b.Property<int>("ProviderType");
b.Property<string>("Query");
b.Property<string>("Title");
b.Property<string>("Uri");
b.HasKey("Id");
b.HasIndex("MusicPlaylistId");
b.ToTable("PlaylistSong");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("AuthorId");
b.Property<string>("AuthorName")
.IsRequired();
b.Property<ulong>("GuildId");
b.Property<string>("Keyword")
.IsRequired();
b.Property<string>("Text")
.IsRequired();
b.HasKey("Id");
b.ToTable("Quotes");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("BotConfigId");
b.Property<string>("Icon");
b.Property<string>("Name");
b.HasKey("Id");
b.HasIndex("BotConfigId");
b.ToTable("RaceAnimals");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<bool>("IsPrivate");
b.Property<string>("Message");
b.Property<ulong>("ServerId");
b.Property<ulong>("UserId");
b.Property<DateTime>("When");
b.HasKey("Id");
b.ToTable("Reminders");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("ChannelId");
b.Property<ulong>("GuildId");
b.Property<TimeSpan>("Interval");
b.Property<string>("Message");
b.HasKey("Id");
b.HasIndex("ChannelId")
.IsUnique();
b.ToTable("Repeaters");
});
modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<ulong>("GuildId");
b.Property<ulong>("RoleId");
b.HasKey("Id");
b.HasIndex("GuildId", "RoleId")
.IsUnique();
b.ToTable("SelfAssignableRoles");
});
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.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");
});
}
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace NadekoBot.Migrations
{
public partial class Cleverbot : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "CleverbotEnabled",
table: "GuildConfigs",
nullable: false,
defaultValue: false);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "CleverbotEnabled",
table: "GuildConfigs");
}
}
}

View File

@ -332,6 +332,8 @@ namespace NadekoBot.Migrations
b.Property<string>("ChannelGreetMessageText");
b.Property<bool>("CleverbotEnabled");
b.Property<float>("DefaultMusicVolume");
b.Property<bool>("DeleteMessageOnCommand");

View File

@ -36,7 +36,7 @@ namespace NadekoBot.Modules.Administration
{
using (var uow = DbHandler.UnitOfWork())
{
var configs = uow.GuildConfigs.GetAll();
var configs = NadekoBot.AllGuildConfigs;
GuildMuteRoles = new ConcurrentDictionary<ulong, string>(configs
.Where(c=>!string.IsNullOrWhiteSpace(c.MuteRoleName))
.ToDictionary(c => c.GuildId, c => c.MuteRoleName));
@ -88,8 +88,12 @@ namespace NadekoBot.Modules.Administration
foreach (var toOverwrite in guild.GetTextChannels())
{
await toOverwrite.AddPermissionOverwriteAsync(muteRole, new OverwritePermissions(sendMessages: PermValue.Deny, attachFiles: PermValue.Deny))
.ConfigureAwait(false);
try
{
await toOverwrite.AddPermissionOverwriteAsync(muteRole, new OverwritePermissions(sendMessages: PermValue.Deny, attachFiles: PermValue.Deny))
.ConfigureAwait(false);
}
catch { }
await Task.Delay(200).ConfigureAwait(false);
}
}
@ -311,7 +315,8 @@ namespace NadekoBot.Modules.Administration
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequirePermission(GuildPermission.BanMembers)]
[RequirePermission(GuildPermission.KickMembers)]
[RequirePermission(GuildPermission.ManageMessages)]
public async Task Softban(IUserMessage umsg, IGuildUser user, [Remainder] string msg = null)
{
var channel = (ITextChannel)umsg.Channel;

View File

@ -36,7 +36,6 @@ namespace NadekoBot.Modules.Administration
public int UserThreshold { get; set; }
public int Seconds { get; set; }
public PunishmentAction Action { get; set; }
public IRole MuteRole { get; set; }
public int UsersCount { get; set; }
public ConcurrentHashSet<IGuildUser> RaidUsers { get; set; } = new ConcurrentHashSet<IGuildUser>();
}
@ -45,7 +44,6 @@ namespace NadekoBot.Modules.Administration
{
public PunishmentAction Action { get; set; }
public int MessageThreshold { get; set; } = 3;
public IRole MuteRole { get; set; }
public ConcurrentDictionary<ulong, UserSpamStats> UserStats { get; set; }
= new ConcurrentDictionary<ulong, UserSpamStats>();
}
@ -114,9 +112,9 @@ namespace NadekoBot.Modules.Administration
{
if (spamSettings.UserStats.TryRemove(msg.Author.Id, out stats))
{
var log = await PunishUser((IGuildUser)msg.Author, spamSettings.Action, spamSettings.MuteRole, ProtectionType.Spamming)
await PunishUsers(spamSettings.Action, await GetMuteRole(channel.Guild), ProtectionType.Spamming, (IGuildUser)msg.Author)
.ConfigureAwait(false);
await channel.Guild.SendMessageToOwnerAsync(log).ConfigureAwait(false); }
}
}
}
catch { }
@ -142,16 +140,11 @@ namespace NadekoBot.Modules.Administration
if (settings.UsersCount >= settings.UserThreshold)
{
var users = settings.RaidUsers.ToList();
var users = settings.RaidUsers.ToArray();
settings.RaidUsers.Clear();
string msg = "";
foreach (var gu in users)
{
msg += await PunishUser(gu, settings.Action, settings.MuteRole, ProtectionType.Raiding).ConfigureAwait(false);
}
try { await usr.Guild.SendMessageToOwnerAsync(msg).ConfigureAwait(false); } catch { }
}
await PunishUsers(settings.Action, await GetMuteRole(usr.Guild), ProtectionType.Raiding, users).ConfigureAwait(false);
}
await Task.Delay(1000 * settings.Seconds).ConfigureAwait(false);
settings.RaidUsers.TryRemove(usr);
@ -162,49 +155,48 @@ namespace NadekoBot.Modules.Administration
};
}
private async Task<string> PunishUser(IGuildUser gu, PunishmentAction action, IRole muteRole, ProtectionType pt)
private async Task PunishUsers(PunishmentAction action, IRole muteRole, ProtectionType pt, params IGuildUser[] gus)
{
switch (action)
foreach (var gu in gus)
{
case PunishmentAction.Mute:
try
{
await gu.AddRolesAsync(muteRole);
return $"{Format.Bold(gu.ToString())} was **MUTED** due to `{pt}` protection on **{gu.Guild.Name}** server.\n";
}
catch (Exception ex) { _log.Warn(ex, "I can't apply punishement"); }
break;
case PunishmentAction.Kick:
try
{
await gu.Guild.AddBanAsync(gu, 7);
switch (action)
{
case PunishmentAction.Mute:
try
{
await gu.Guild.RemoveBanAsync(gu);
await gu.AddRolesAsync(muteRole);
}
catch
catch (Exception ex) { _log.Warn(ex, "I can't apply punishement"); }
break;
case PunishmentAction.Kick:
try
{
await gu.Guild.RemoveBanAsync(gu);
// try it twice, really don't want to ban user if
// only kick has been specified as the punishement
await gu.Guild.AddBanAsync(gu, 7);
try
{
await gu.Guild.RemoveBanAsync(gu);
}
catch
{
await gu.Guild.RemoveBanAsync(gu);
// try it twice, really don't want to ban user if
// only kick has been specified as the punishement
}
}
return $"{Format.Bold(gu.ToString())} was **KICKED** due to `{pt}` protection on **{gu.Guild.Name}** server.\n";
}
catch (Exception ex) { _log.Warn(ex, "I can't apply punishment"); }
break;
case PunishmentAction.Ban:
try
{
await gu.Guild.AddBanAsync(gu, 7);
return $"{Format.Bold(gu.ToString())} was **BANNED** due to `{pt}` protection on **{gu.Guild.Name}** server.\n";
}
catch (Exception ex) { _log.Warn(ex, "I can't apply punishment"); }
break;
default:
break;
catch (Exception ex) { _log.Warn(ex, "I can't apply punishment"); }
break;
case PunishmentAction.Ban:
try
{
await gu.Guild.AddBanAsync(gu, 7);
}
catch (Exception ex) { _log.Warn(ex, "I can't apply punishment"); }
break;
default:
break;
}
}
return String.Empty;
await LogCommands.TriggeredAntiProtection(gus, action, pt).ConfigureAwait(false);
}
@ -227,10 +219,9 @@ namespace NadekoBot.Modules.Administration
return;
}
IRole muteRole;
try
{
muteRole = await GetMuteRole(channel.Guild).ConfigureAwait(false);
await GetMuteRole(channel.Guild).ConfigureAwait(false);
}
catch (Exception ex)
{
@ -246,7 +237,6 @@ namespace NadekoBot.Modules.Administration
Action = action,
Seconds = seconds,
UserThreshold = userThreshold,
MuteRole = muteRole,
};
antiRaidGuilds.AddOrUpdate(channel.Guild.Id, setting, (id, old) => setting);
@ -271,10 +261,22 @@ namespace NadekoBot.Modules.Administration
}
else
{
try
{
await GetMuteRole(channel.Guild).ConfigureAwait(false);
}
catch (Exception ex)
{
await channel.SendMessageAsync("Failed creating a mute role. Give me ManageRoles permission" +
"or create 'nadeko-mute' role with disabled SendMessages and try again.")
.ConfigureAwait(false);
_log.Warn(ex);
return;
}
if (antiSpamGuilds.TryAdd(channel.Guild.Id, new AntiSpamSetting()
{
Action = action,
MuteRole = await GetMuteRole(channel.Guild).ConfigureAwait(false),
MessageThreshold = messageCount,
}))
await channel.SendMessageAsync("`Anti-Spam feature enabled on this server.`").ConfigureAwait(false);

View File

@ -80,7 +80,7 @@ namespace NadekoBot.Modules.Administration
{
var firstOwnerChannel = ownerChannels.First();
if (firstOwnerChannel.Recipient.Id != msg.Author.Id)
try { await firstOwnerChannel.SendMessageAsync(msg.Content).ConfigureAwait(false); } catch { }
try { await firstOwnerChannel.SendMessageAsync(toSend).ConfigureAwait(false); } catch { }
}
}
}

View File

@ -22,31 +22,29 @@ namespace NadekoBot.Modules.Administration
[Group]
public class LogCommands
{
private ShardedDiscordClient _client { get; }
private Logger _log { get; }
private static ShardedDiscordClient _client { get; }
private static Logger _log { get; }
private string prettyCurrentTime => $"【{DateTime.Now:HH:mm:ss}】";
private static string prettyCurrentTime => $"【{DateTime.Now:HH:mm:ss}】";
public ConcurrentDictionary<ulong, LogSetting> GuildLogSettings { get; }
public static ConcurrentDictionary<ulong, LogSetting> GuildLogSettings { get; }
private ConcurrentDictionary<ITextChannel, List<string>> UserPresenceUpdates { get; } = new ConcurrentDictionary<ITextChannel, List<string>>();
private Timer t;
private static ConcurrentDictionary<ITextChannel, List<string>> UserPresenceUpdates { get; } = new ConcurrentDictionary<ITextChannel, List<string>>();
private static Timer timerReference { get; }
private IGoogleApiService _google { get; }
public LogCommands(ShardedDiscordClient client, IGoogleApiService google)
static LogCommands()
{
_client = client;
_google = google;
_client = NadekoBot.Client;
_log = LogManager.GetCurrentClassLogger();
using (var uow = DbHandler.UnitOfWork())
{
GuildLogSettings = new ConcurrentDictionary<ulong, LogSetting>(uow.GuildConfigs
.GetAll()
GuildLogSettings = new ConcurrentDictionary<ulong, LogSetting>(NadekoBot.AllGuildConfigs
.ToDictionary(g => g.GuildId, g => g.LogSetting));
}
t = new Timer(async (state) =>
timerReference = new Timer(async (state) =>
{
try
{
@ -64,8 +62,10 @@ namespace NadekoBot.Modules.Administration
_log.Warn(ex);
}
}, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));
}
public LogCommands(ShardedDiscordClient client)
{
//_client.MessageReceived += _client_MessageReceived;
_client.MessageUpdated += _client_MessageUpdated;
_client.MessageDeleted += _client_MessageDeleted;
@ -82,6 +82,36 @@ namespace NadekoBot.Modules.Administration
_client.ChannelUpdated += _client_ChannelUpdated;
}
public static async Task TriggeredAntiProtection(IGuildUser[] users, PunishmentAction action, ProtectionType protection)
{
if (users.Length == 0)
return;
LogSetting logSetting;
if (!GuildLogSettings.TryGetValue(users.First().Guild.Id, out logSetting)
|| !logSetting.IsLogging)
return;
ITextChannel logChannel;
if ((logChannel = TryGetLogChannel(users.First().Guild, logSetting)) == null)
return;
var punishment = "";
if (action == PunishmentAction.Mute)
{
punishment = "MUTED";
}
else if (action == PunishmentAction.Kick)
{
punishment = "KICKED";
}
else if (action == PunishmentAction.Ban)
{
punishment = "BANNED";
}
await logChannel.SendMessageAsync(String.Join("\n",users.Select(user=>$"{Format.Bold(user.ToString())} was **{punishment}** due to `{protection}` protection on **{user.Guild.Name}** server.")))
.ConfigureAwait(false);
}
private Task _client_UserUpdated(IGuildUser before, IGuildUser after)
{
LogSetting logSetting;
@ -385,7 +415,7 @@ namespace NadekoBot.Modules.Administration
👤`{msg.Author.Username}`: {msg.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator)}";
if (msg.Attachments.Any())
str += $"{Environment.NewLine}`Attachements`: {string.Join(", ", msg.Attachments.Select(a => a.ProxyUrl))}";
await logChannel.SendMessageAsync(str).ConfigureAwait(false);
await logChannel.SendMessageAsync(str.SanitizeMentions()).ConfigureAwait(false);
}
catch (Exception ex) { _log.Warn(ex); }
});
@ -422,8 +452,8 @@ namespace NadekoBot.Modules.Administration
{
try { await logChannel.SendMessageAsync($@"🕔`{prettyCurrentTime}` **Message** 📝 `#{channel.Name}`
👤`{before.Author.Username}`
`Old:` {before.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator)}
`New:` {after.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator)}").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
`Old:` {before.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator).SanitizeMentions()}
`New:` {after.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator).SanitizeMentions()}").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
});
return Task.CompletedTask;
@ -462,7 +492,7 @@ namespace NadekoBot.Modules.Administration
// }
private enum LogChannelType { Text, Voice, UserPresence };
private ITextChannel TryGetLogChannel(IGuild guild, LogSetting logSetting, LogChannelType logChannelType = LogChannelType.Text)
private static ITextChannel TryGetLogChannel(IGuild guild, LogSetting logSetting, LogChannelType logChannelType = LogChannelType.Text)
{
ulong id = 0;
switch (logChannelType)

View File

@ -159,7 +159,7 @@ namespace NadekoBot.Modules.Administration
return old;
});
await channel.SendMessageAsync($"Repeating \"{rep.Repeater.Message}\" every {rep.Repeater.Interval} minutes").ConfigureAwait(false);
await channel.SendMessageAsync($"Repeating \"{rep.Repeater.Message}\" every {rep.Repeater.Interval.Days} days, {rep.Repeater.Interval.Hours} hours and {rep.Repeater.Interval.Minutes} minutes.").ConfigureAwait(false);
}
}
}

View File

@ -75,9 +75,9 @@ namespace NadekoBot.Modules.Administration
MigrateDb0_9(uow);
//NOW save it
botConfig.MigrationVersion = 1;
_log.Warn("Writing to disc");
uow.Complete();
botConfig.MigrationVersion = 1;
}
}
@ -128,18 +128,19 @@ namespace NadekoBot.Modules.Administration
}
var com2 = db.CreateCommand();
com.CommandText = "SELECT * FROM CurrencyState";
com.CommandText = "SELECT * FROM CurrencyState GROUP BY UserId";
i = 0;
var reader2 = com.ExecuteReader();
while (reader2.Read())
{
_log.Info(++i);
uow.Currency.Add(new Currency()
var curr = new Currency()
{
Amount = (long)reader2["Value"],
UserId = (ulong)(long)reader2["UserId"]
});
};
uow.Currency.Add(curr);
}
db.Close();
try { File.Move("data/nadekobot.sqlite", "data/DELETE_ME_nadekobot.sqlite"); } catch { }

View File

@ -67,7 +67,7 @@ namespace NadekoBot.Modules.Administration
}
finally
{
await Task.Delay(15000);
await Task.Delay(TimeSpan.FromMinutes(1));
}
} while (true);
});

View File

@ -25,7 +25,7 @@ namespace NadekoBot.Modules.Administration
{
using (var uow = DbHandler.UnitOfWork())
{
voicePlusTextCache = new ConcurrentHashSet<ulong>(uow.GuildConfigs.GetAll().Where(g => g.VoicePlusTextEnabled).Select(g => g.GuildId));
voicePlusTextCache = new ConcurrentHashSet<ulong>(NadekoBot.AllGuildConfigs.Where(g => g.VoicePlusTextEnabled).Select(g => g.GuildId));
}
NadekoBot.Client.UserVoiceStateUpdated += UserUpdatedEventHandler;
}
@ -114,7 +114,7 @@ namespace NadekoBot.Modules.Administration
var channel = (ITextChannel)msg.Channel;
var guild = channel.Guild;
var botUser = guild.GetCurrentUser();
var botUser = await guild.GetCurrentUserAsync().ConfigureAwait(false);
if (!botUser.GuildPermissions.ManageRoles || !botUser.GuildPermissions.ManageChannels)
{
await channel.SendMessageAsync(":anger: `I require atleast manage roles and manage channels permissions to enable this feature (preffered Administration permission).`");
@ -166,7 +166,8 @@ namespace NadekoBot.Modules.Administration
{
var channel = (ITextChannel)msg.Channel;
var guild = channel.Guild;
if (!guild.GetCurrentUser().GuildPermissions.Administrator)
var botUser = await guild.GetCurrentUserAsync().ConfigureAwait(false);
if (!botUser.GuildPermissions.Administrator)
{
await channel.SendMessageAsync("`I need Administrator permission to do that.`").ConfigureAwait(false);
return;

View File

@ -19,6 +19,7 @@ namespace NadekoBot.Modules.CustomReactions
{
public static ConcurrentHashSet<CustomReaction> GlobalReactions { get; } = new ConcurrentHashSet<CustomReaction>();
public static ConcurrentDictionary<ulong, ConcurrentHashSet<CustomReaction>> GuildReactions { get; } = new ConcurrentDictionary<ulong, ConcurrentHashSet<CustomReaction>>();
static CustomReactions()
{
using (var uow = DbHandler.UnitOfWork())
@ -30,49 +31,43 @@ namespace NadekoBot.Modules.CustomReactions
}
public CustomReactions(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client)
{
client.MessageReceived += (imsg) =>
}
public static async Task<bool> TryExecuteCustomReaction(IUserMessage umsg)
{
var channel = umsg.Channel as ITextChannel;
if (channel == null)
return false;
var content = umsg.Content.Trim().ToLowerInvariant();
ConcurrentHashSet<CustomReaction> reactions;
GuildReactions.TryGetValue(channel.Guild.Id, out reactions);
if (reactions != null && reactions.Any())
{
var umsg = imsg as IUserMessage;
if (umsg == null || imsg.Author.IsBot)
return Task.CompletedTask;
var channel = umsg.Channel as ITextChannel;
if (channel == null)
return Task.CompletedTask;
var t = Task.Run(async () =>
var reaction = reactions.Where(cr => {
var hasTarget = cr.Response.ToLowerInvariant().Contains("%target%");
var trigger = cr.TriggerWithContext(umsg).Trim().ToLowerInvariant();
return ((hasTarget && content.StartsWith(trigger + " ")) || content == trigger);
}).Shuffle().FirstOrDefault();
if (reaction != null)
{
var content = umsg.Content.Trim().ToLowerInvariant();
ConcurrentHashSet<CustomReaction> reactions;
GuildReactions.TryGetValue(channel.Guild.Id, out reactions);
if (reactions != null && reactions.Any())
{
var reaction = reactions.Where(cr => {
var hasTarget = cr.Response.ToLowerInvariant().Contains("%target%");
var trigger = cr.TriggerWithContext(umsg).Trim().ToLowerInvariant();
return ((hasTarget && content.StartsWith(trigger + " ")) || content == trigger);
}).Shuffle().FirstOrDefault();
if (reaction != null)
{
try { await channel.SendMessageAsync(reaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { }
return;
}
}
var greaction = GlobalReactions.Where(cr =>
{
var hasTarget = cr.Response.ToLowerInvariant().Contains("%target%");
var trigger = cr.TriggerWithContext(umsg).Trim().ToLowerInvariant();
return ((hasTarget && content.StartsWith(trigger + " ")) || content == trigger);
}).Shuffle().FirstOrDefault();
try { await channel.SendMessageAsync(reaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { }
return true;
}
}
var greaction = GlobalReactions.Where(cr =>
{
var hasTarget = cr.Response.ToLowerInvariant().Contains("%target%");
var trigger = cr.TriggerWithContext(umsg).Trim().ToLowerInvariant();
return ((hasTarget && content.StartsWith(trigger + " ")) || content == trigger);
}).Shuffle().FirstOrDefault();
if (greaction != null)
{
try { await channel.SendMessageAsync(greaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { }
return;
}
});
return Task.CompletedTask;
};
if (greaction != null)
{
try { await channel.SendMessageAsync(greaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { }
return true;
}
return false;
}
[NadekoCommand, Usage, Description, Aliases]
@ -115,7 +110,7 @@ namespace NadekoBot.Modules.CustomReactions
reactions.Add(cr);
}
await imsg.Channel.SendMessageAsync($"`Added new custom reaction:`\n\t`Trigger:` {key}\n\t`Response:` {message}").ConfigureAwait(false);
await imsg.Channel.SendMessageAsync($"`Added new custom reaction {cr.Id}:`\n\t`Trigger:` {key}\n\t`Response:` {message}").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]

View File

@ -46,13 +46,6 @@ namespace NadekoBot.Modules.Gambling
if (amount < 0)
amount = 0;
if (amount > 0)
if (!await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)umsg.Author, "BetRace", amount, true).ConfigureAwait(false))
{
try { await channel.SendMessageAsync($"{umsg.Author.Mention} You don't have enough {Gambling.CurrencyName}s.").ConfigureAwait(false); } catch { }
return;
}
AnimalRace ar;
if (!AnimalRaces.TryGetValue(channel.Guild.Id, out ar))
@ -225,28 +218,33 @@ namespace NadekoBot.Modules.Gambling
}
}
public async Task<bool> JoinRace(IGuildUser u, int amount = 0)
public async Task JoinRace(IGuildUser u, int amount = 0)
{
var animal = "";
if (!animals.TryDequeue(out animal))
{
await raceChannel.SendMessageAsync($"{u.Mention} `There is no running race on this server.`");
return false;
return;
}
var p = new Participant(u, animal, amount);
if (participants.Contains(p))
{
await raceChannel.SendMessageAsync($"{u.Mention} `You already joined this race.`");
return false;
return;
}
if (Started)
{
await raceChannel.SendMessageAsync($"{u.Mention} `Race is already started`");
return false;
return;
}
if (amount > 0)
if (!await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)u, "BetRace", amount, true).ConfigureAwait(false))
{
try { await raceChannel.SendMessageAsync($"{u.Mention} You don't have enough {Gambling.CurrencyName}s.").ConfigureAwait(false); } catch { }
return;
}
participants.Add(p);
await raceChannel.SendMessageAsync($"{u.Mention} **joined the race as a {p.Animal}" + (amount > 0 ? $" and bet {amount} {(amount == 1? CurrencyName : CurrencyPluralName)}!**" : "**"));
return true;
await raceChannel.SendMessageAsync($"{u.Mention} **joined the race as a {p.Animal}" + (amount > 0 ? $" and bet {amount} {CurrencySign}!**" : "**"));
}
}

View File

@ -0,0 +1,125 @@
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Services;
using NadekoBot.Services.Database;
using Newtonsoft.Json;
using NLog;
using Services.CleverBotApi;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Games
{
public partial class Games
{
[Group]
public class CleverBotCommands
{
private static Logger _log { get; }
class CleverAnswer {
public string Status { get; set; }
public string Response { get; set; }
}
//user#discrim is the key
public static ConcurrentHashSet<string> ChannelsInConversation { get; } = new ConcurrentHashSet<string>();
public static ConcurrentDictionary<ulong, ChatterBotSession> CleverbotGuilds { get; } = new ConcurrentDictionary<ulong, ChatterBotSession>();
static CleverBotCommands()
{
_log = LogManager.GetCurrentClassLogger();
using (var uow = DbHandler.UnitOfWork())
{
var bot = ChatterBotFactory.Create(ChatterBotType.CLEVERBOT);
CleverbotGuilds = new ConcurrentDictionary<ulong, ChatterBotSession>(
uow.GuildConfigs.GetAll()
.Where(gc => gc.CleverbotEnabled)
.ToDictionary(gc => gc.GuildId, gc => bot.CreateSession()));
}
}
public static async Task<bool> TryAsk(IUserMessage msg) {
var channel = msg.Channel as ITextChannel;
if (channel == null)
return false;
ChatterBotSession cleverbot;
if (!CleverbotGuilds.TryGetValue(channel.Guild.Id, out cleverbot))
return false;
var nadekoId = NadekoBot.Client.GetCurrentUser().Id;
var normalMention = $"<@{nadekoId}> ";
var nickMention = $"<@!{nadekoId}> ";
string message;
if (msg.Content.StartsWith(normalMention))
{
message = msg.Content.Substring(normalMention.Length).Trim();
}
else if (msg.Content.StartsWith(nickMention))
{
message = msg.Content.Substring(nickMention.Length).Trim();
}
else
{
return false;
}
await msg.Channel.TriggerTypingAsync().ConfigureAwait(false);
var response = await cleverbot.Think(message).ConfigureAwait(false);
try
{
await msg.Channel.SendMessageAsync(response).ConfigureAwait(false);
}
catch (Exception ex)
{
_log.Warn(ex, "Eror sending response");
await msg.Channel.SendMessageAsync(msg.Author.Mention+" "+response).ConfigureAwait(false); // try twice :\
}
return true;
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequirePermission(ChannelPermission.ManageMessages)]
public async Task Cleverbot(IUserMessage imsg)
{
var channel = (ITextChannel)imsg.Channel;
ChatterBotSession throwaway;
if (CleverbotGuilds.TryRemove(channel.Guild.Id, out throwaway))
{
using (var uow = DbHandler.UnitOfWork())
{
uow.GuildConfigs.SetCleverbotEnabled(channel.Guild.Id, false);
await uow.CompleteAsync().ConfigureAwait(false);
}
await channel.SendMessageAsync($"{imsg.Author.Mention} `Disabled cleverbot on this server.`").ConfigureAwait(false);
return;
}
var cleverbot = ChatterBotFactory.Create(ChatterBotType.CLEVERBOT);
var session = cleverbot.CreateSession();
CleverbotGuilds.TryAdd(channel.Guild.Id, session);
using (var uow = DbHandler.UnitOfWork())
{
uow.GuildConfigs.SetCleverbotEnabled(channel.Guild.Id, true);
await uow.CompleteAsync().ConfigureAwait(false);
}
await channel.SendMessageAsync($"{imsg.Author.Mention} `Enabled cleverbot on this server.`").ConfigureAwait(false);
}
}
}
}

View File

@ -54,7 +54,7 @@ namespace NadekoBot.Modules.Games
{
var conf = uow.BotConfig.GetOrCreate();
var x =
generationChannels = new ConcurrentHashSet<ulong>(uow.GuildConfigs.GetAll()
generationChannels = new ConcurrentHashSet<ulong>(NadekoBot.AllGuildConfigs
.SelectMany(c => c.GenerateCurrencyChannelIds.Select(obj=>obj.ChannelId)));
chance = conf.CurrencyGenerationChance;
cooldown = conf.CurrencyGenerationCooldown;

View File

@ -218,6 +218,47 @@ namespace NadekoBot.Modules.Games
await channel.SendMessageAsync("Added new article for typing game.").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Typelist(IUserMessage imsg, int page = 1)
{
var channel = (ITextChannel)imsg.Channel;
if (page < 1)
return;
var articles = TypingArticles.Skip((page - 1) * 15).Take(15);
if (!articles.Any())
{
await channel.SendMessageAsync($"{imsg.Author.Mention} `No articles found on that page.`").ConfigureAwait(false);
return;
}
var i = (page - 1) * 15;
await channel.SendMessageAsync(String.Join("\n", articles.Select(a => $"`#{++i}` - {a.Text.TrimTo(50)}")))
.ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[OwnerOnly]
public async Task Typedel(IUserMessage imsg, int index)
{
var channel = (ITextChannel)imsg.Channel;
index -= 1;
if (index < 0 || index >= TypingArticles.Count)
return;
var removed = TypingArticles[index];
TypingArticles.RemoveAt(index);
File.WriteAllText(typingArticlesPath, JsonConvert.SerializeObject(TypingArticles));
await channel.SendMessageAsync($"`Removed typing article:` #{index + 1} - {removed.Text.TrimTo(50)}")
.ConfigureAwait(false);
}
}
}
}

View File

@ -125,13 +125,23 @@ namespace NadekoBot.Modules.Help
public Task Hgit(IUserMessage umsg)
{
var helpstr = new StringBuilder();
var lastModule = "";
helpstr.AppendLine(@"For more information and how to setup your own NadekoBot, go to: <http://github.com/Kwoth/NadekoBot/wiki>
You can support the project on patreon: <https://patreon.com/nadekobot> or paypal: `nadekodiscordbot@gmail.com`");
helpstr.AppendLine("##Table Of Contents");
helpstr.AppendLine(string.Join("\n", NadekoBot.CommandService.Modules.Where(m => m.Name.ToLowerInvariant() != "help").OrderBy(m => m.Name).Prepend(NadekoBot.CommandService.Modules.FirstOrDefault(m=>m.Name.ToLowerInvariant()=="help")).Select(m => $"- [{m.Name}](#{m.Name.ToLowerInvariant()})")));
helpstr.AppendLine();
string lastModule = null;
foreach (var com in _commands.Commands.OrderBy(com=>com.Module.Name).GroupBy(c=>c.Text).Select(g=>g.First()))
{
if (com.Module.Name != lastModule)
{
helpstr.AppendLine("\n### " + com.Module.Name + " ");
if (lastModule != null)
{
helpstr.AppendLine();
helpstr.AppendLine("###### [Back to TOC](#table-of-contents)");
}
helpstr.AppendLine();
helpstr.AppendLine("### " + com.Module.Name + " ");
helpstr.AppendLine("Command and aliases | Description | Usage");
helpstr.AppendLine("----------------|--------------|-------");
lastModule = com.Module.Name;

View File

@ -38,14 +38,23 @@ namespace NadekoBot.Modules.Music
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public Task Next(IUserMessage umsg)
public Task Next(IUserMessage umsg, int skipCount = 1)
{
var channel = (ITextChannel)umsg.Channel;
if (skipCount < 1)
return Task.CompletedTask;
MusicPlayer musicPlayer;
if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return Task.CompletedTask;
if (musicPlayer.PlaybackVoiceChannel == ((IGuildUser)umsg.Author).VoiceChannel)
{
while (--skipCount > 0)
{
musicPlayer.RemoveSongAt(0);
}
musicPlayer.Next();
}
return Task.CompletedTask;
}

View File

@ -30,17 +30,71 @@ namespace NadekoBot.Modules.NSFW
tag = tag?.Trim() ?? "";
var links = await Task.WhenAll(GetGelbooruImageLink("rating%3Aexplicit+" + tag), GetDanbooruImageLink("rating%3Aexplicit+" + tag)).ConfigureAwait(false);
tag = "rating%3Aexplicit+" + tag;
var rng = new NadekoRandom();
Task<string> provider = Task.FromResult("");
switch (rng.Next(0,4))
{
case 0:
provider = GetDanbooruImageLink(tag);
break;
case 1:
provider = GetGelbooruImageLink(tag);
break;
case 2:
provider = GetATFbooruImageLink(tag);
break;
case 3:
provider = GetKonachanImageLink(tag);
break;
default:
break;
}
var link = await provider.ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(link))
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task HentaiBomb(IUserMessage umsg, [Remainder] string tag = null)
{
var channel = (ITextChannel)umsg.Channel;
tag = tag?.Trim() ?? "";
tag = "rating%3Aexplicit+" + tag;
var links = await Task.WhenAll(GetGelbooruImageLink(tag),
GetDanbooruImageLink(tag),
GetKonachanImageLink(tag),
GetATFbooruImageLink(tag)).ConfigureAwait(false);
if (links.All(l => l == null))
{
await channel.SendMessageAsync("`No results.`");
await channel.SendMessageAsync("`No results.`").ConfigureAwait(false);
return;
}
await channel.SendMessageAsync(String.Join("\n\n", links)).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task ATFbooru(IUserMessage umsg, [Remainder] string tag = null)
{
var channel = (ITextChannel)umsg.Channel;
tag = tag?.Trim() ?? "";
var link = await GetATFbooruImageLink(tag).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(link))
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Danbooru(IUserMessage umsg, [Remainder] string tag = null)
@ -50,7 +104,7 @@ namespace NadekoBot.Modules.NSFW
tag = tag?.Trim() ?? "";
var link = await GetDanbooruImageLink(tag).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(link))
await channel.SendMessageAsync("Search yielded no results ;(");
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
@ -64,7 +118,7 @@ namespace NadekoBot.Modules.NSFW
tag = tag?.Trim() ?? "";
var link = await GetKonachanImageLink(tag).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(link))
await channel.SendMessageAsync("Search yielded no results ;(");
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
@ -78,7 +132,7 @@ namespace NadekoBot.Modules.NSFW
tag = tag?.Trim() ?? "";
var link = await GetGelbooruImageLink(tag).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(link))
await channel.SendMessageAsync("Search yielded no results ;(");
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
@ -92,7 +146,7 @@ namespace NadekoBot.Modules.NSFW
tag = tag?.Trim() ?? "";
var link = await GetRule34ImageLink(tag).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(link))
await channel.SendMessageAsync("Search yielded no results ;(");
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
@ -106,7 +160,7 @@ namespace NadekoBot.Modules.NSFW
tag = tag?.Trim() ?? "";
var link = await GetE621ImageLink(tag).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(link))
await channel.SendMessageAsync("Search yielded no results ;(");
await channel.SendMessageAsync("Search yielded no results ;(").ConfigureAwait(false);
else
await channel.SendMessageAsync(link).ConfigureAwait(false);
}
@ -176,7 +230,7 @@ namespace NadekoBot.Modules.NSFW
if (matches.Count == 0)
return null;
return await NadekoBot.Google.ShortenUrl(matches[rng.Next(0, matches.Count)].Groups["ll"].Value).ConfigureAwait(false);
return matches[rng.Next(0, matches.Count)].Groups["ll"].Value;
}
}
@ -255,5 +309,25 @@ namespace NadekoBot.Modules.NSFW
return "Error, do you have too many tags?";
}
}
public static async Task<string> GetATFbooruImageLink(string tag)
{
var rng = new NadekoRandom();
var link = $"https://atfbooru.ninja/posts?" +
$"limit=100";
if (!string.IsNullOrWhiteSpace(tag))
link += $"&tags={tag.Replace(" ", "+")}";
using (var http = new HttpClient())
{
var webpage = await http.GetStringAsync(link).ConfigureAwait(false);
var matches = Regex.Matches(webpage, "data-file-url=\"(?<id>.*?)\"");
if (matches.Count == 0)
return null;
return $"https://atfbooru.ninja" +
$"{matches[rng.Next(0, matches.Count)].Groups["id"].Value}";
}
}
}
}

View File

@ -80,7 +80,7 @@ namespace NadekoBot.Modules.Permissions
}
await uow.CompleteAsync().ConfigureAwait(false);
}
if (action == AddRemove.Rem)
if (action == AddRemove.Add)
{
TriviaGame tg;
switch (type)

View File

@ -33,7 +33,7 @@ namespace NadekoBot.Modules.Permissions
{
using (var uow = DbHandler.UnitOfWork())
{
var configs = uow.GuildConfigs.GetAll();
var configs = NadekoBot.AllGuildConfigs;
commandCooldowns = new ConcurrentDictionary<ulong, ConcurrentHashSet<CommandCooldown>>(configs.ToDictionary(k => k.GuildId, v => new ConcurrentHashSet<CommandCooldown>(v.CommandCooldowns)));
}
}

View File

@ -46,7 +46,7 @@ namespace NadekoBot.Modules.Permissions
{
using (var uow = DbHandler.UnitOfWork())
{
var guildConfigs = uow.GuildConfigs.GetAll();
var guildConfigs = NadekoBot.AllGuildConfigs;
InviteFilteringServers = new ConcurrentHashSet<ulong>(guildConfigs.Where(gc => gc.FilterInvites).Select(gc => gc.GuildId));
InviteFilteringChannels = new ConcurrentHashSet<ulong>(guildConfigs.SelectMany(gc => gc.FilterInvitesChannelIds.Select(fci => fci.ChannelId)));

View File

@ -58,7 +58,7 @@ namespace NadekoBot.Modules.Searches
{
if (i % 2 == 0 && i != 0)
sb.AppendLine();
sb.Append($"`{i + 1}.` **{dataList[i]["name"]}** ");
sb.Append($"`{i + 1}.` **{dataList[i]["name"]}** {dataList[i]["general"]["banRate"]}% ");
//sb.AppendLine($" ({dataList[i]["general"]["banRate"]}%)");
}
@ -67,7 +67,7 @@ namespace NadekoBot.Modules.Searches
}
catch (Exception)
{
await channel.SendMessageAsync($":anger: Fail: Champion.gg didsabled ban data until next patch. Sorry for the inconvenience.").ConfigureAwait(false);
await channel.SendMessageAsync($":anger: `Something went wrong.`").ConfigureAwait(false);
}
}
}

View File

@ -6,47 +6,178 @@ using System;
using System.Threading.Tasks;
using NadekoBot.Services;
using Discord.WebSocket;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
namespace NadekoBot.Modules.Searches
{
public partial class Searches
{
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Translate(IUserMessage umsg, string langs, [Remainder] string text = null)
public struct UserChannelPair
{
var channel = (ITextChannel)umsg.Channel;
public ulong UserId { get; set; }
public ulong ChannelId { get; set; }
}
try
[Group]
public class TranslateCommands
{
private static ConcurrentDictionary<ulong, bool> TranslatedChannels { get; }
private static ConcurrentDictionary<UserChannelPair, string> UserLanguages { get; }
static TranslateCommands()
{
TranslatedChannels = new ConcurrentDictionary<ulong, bool>();
UserLanguages = new ConcurrentDictionary<UserChannelPair, string>();
NadekoBot.Client.MessageReceived += (msg) =>
{
var umsg = msg as IUserMessage;
if(umsg == null)
return Task.CompletedTask;
bool autoDelete;
if (!TranslatedChannels.TryGetValue(umsg.Channel.Id, out autoDelete))
return Task.CompletedTask;
var t = Task.Run(async () =>
{
var key = new UserChannelPair()
{
UserId = umsg.Author.Id,
ChannelId = umsg.Channel.Id,
};
string langs;
if (!UserLanguages.TryGetValue(key, out langs))
return;
try
{
var text = await TranslateInternal(umsg, langs, umsg.Resolve(UserMentionHandling.Ignore), true)
.ConfigureAwait(false);
if (autoDelete)
try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { }
await umsg.Channel.SendMessageAsync($"{umsg.Author.Mention} `:` "+text.Replace("<@ ", "<@").Replace("<@! ", "<@!")).ConfigureAwait(false);
}
catch { }
});
return Task.CompletedTask;
};
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Translate(IUserMessage umsg, string langs, [Remainder] string text = null)
{
var channel = (ITextChannel)umsg.Channel;
try
{
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
var translation = await TranslateInternal(umsg, langs, text);
await channel.SendMessageAsync(translation).ConfigureAwait(false);
}
catch
{
await channel.SendMessageAsync("Bad input format, or something went wrong...").ConfigureAwait(false);
}
}
private static async Task<string> TranslateInternal(IUserMessage umsg, string langs, [Remainder] string text = null, bool silent = false)
{
var langarr = langs.ToLowerInvariant().Split('>');
if (langarr.Length != 2)
return;
throw new ArgumentException();
string from = langarr[0];
string to = langarr[1];
text = text?.Trim();
if (string.IsNullOrWhiteSpace(text))
return;
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
string translation = await GoogleTranslator.Instance.Translate(text, from, to).ConfigureAwait(false);
await channel.SendMessageAsync(translation).ConfigureAwait(false);
throw new ArgumentException();
return await GoogleTranslator.Instance.Translate(text, from, to).ConfigureAwait(false);
}
catch (Exception ex)
public enum AutoDeleteAutoTranslate
{
Console.WriteLine(ex);
await channel.SendMessageAsync("Bad input format, or something went wrong...").ConfigureAwait(false);
Del,
Nodel
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequirePermission(GuildPermission.Administrator)]
[OwnerOnly]
public async Task AutoTranslate(IUserMessage msg, AutoDeleteAutoTranslate autoDelete = AutoDeleteAutoTranslate.Nodel)
{
var channel = (ITextChannel)msg.Channel;
if (autoDelete == AutoDeleteAutoTranslate.Del)
{
TranslatedChannels.AddOrUpdate(channel.Id, true, (key, val) => true);
try { await channel.SendMessageAsync("`Started automatic translation of messages on this channel. User messages will be auto-deleted.`").ConfigureAwait(false); } catch { }
return;
}
bool throwaway;
if (TranslatedChannels.TryRemove(channel.Id, out throwaway))
{
try { await channel.SendMessageAsync("`Stopped automatic translation of messages on this channel.`").ConfigureAwait(false); } catch { }
return;
}
else if (TranslatedChannels.TryAdd(channel.Id, autoDelete == AutoDeleteAutoTranslate.Del))
{
try { await channel.SendMessageAsync("`Started automatic translation of messages on this channel.`").ConfigureAwait(false); } catch { }
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task AutoTransLang(IUserMessage msg, [Remainder] string langs = null)
{
var channel = (ITextChannel)msg.Channel;
var ucp = new UserChannelPair
{
UserId = msg.Author.Id,
ChannelId = msg.Channel.Id,
};
if (string.IsNullOrWhiteSpace(langs))
{
if (UserLanguages.TryRemove(ucp, out langs))
await channel.SendMessageAsync($"{msg.Author.Mention}'s auto-translate language has been removed.").ConfigureAwait(false);
return;
}
var langarr = langs.ToLowerInvariant().Split('>');
if (langarr.Length != 2)
return;
var from = langarr[0];
var to = langarr[1];
if (!GoogleTranslator.Instance.Languages.Contains(from) || !GoogleTranslator.Instance.Languages.Contains(to))
{
try { await channel.SendMessageAsync("`Invalid source and/or target Language.`").ConfigureAwait(false); } catch { }
return;
}
UserLanguages.AddOrUpdate(ucp, langs, (key, val) => langs);
await channel.SendMessageAsync(":ok:").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Translangs(IUserMessage umsg)
{
var channel = (ITextChannel)umsg.Channel;
await channel.SendTableAsync(GoogleTranslator.Instance.Languages, str => $"{str,-15}", columns: 3);
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Translangs(IUserMessage umsg)
{
var channel = (ITextChannel)umsg.Channel;
await channel.SendTableAsync(GoogleTranslator.Instance.Languages, str => $"{str,-15}", columns: 3);
}
}
}

View File

@ -4,6 +4,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Text;
using System.Net.Http;
using NadekoBot.Services;
using System.Threading.Tasks;
@ -184,6 +185,16 @@ $@"🌍 **Weather for** 【{obj["target"]}】
.ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Shorten(IUserMessage msg, [Remainder] string arg)
{
if (string.IsNullOrWhiteSpace(arg))
return;
await msg.Channel.SendMessageAsync(await NadekoBot.Google.ShortenUrl(arg).ConfigureAwait(false));
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Google(IUserMessage umsg, [Remainder] string terms = null)
@ -206,9 +217,16 @@ $@"🌍 **Weather for** 【{obj["target"]}】
var arg = name;
if (string.IsNullOrWhiteSpace(arg))
{
await channel.SendMessageAsync("💢 Please enter a card name to search for.").ConfigureAwait(false);
await channel.SendMessageAsync("💢 `Please enter a card name to search for.`").ConfigureAwait(false);
return;
}
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
{
await channel.SendMessageAsync("💢 `Bot owner didn't specify MashapeApiKey. You can't use this functionality.`").ConfigureAwait(false);
return;
}
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
string response = "";
using (var http = new HttpClient())
@ -225,7 +243,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
throw new KeyNotFoundException("Cannot find a card by that name");
foreach (var item in items.Where(item => item.HasValues && item["img"] != null).Take(4))
{
using (var sr =await http.GetStreamAsync(item["img"].ToString()))
using (var sr = await http.GetStreamAsync(item["img"].ToString()))
{
var imgStream = new MemoryStream();
await sr.CopyToAsync(imgStream);
@ -256,10 +274,16 @@ $@"🌍 **Weather for** 【{obj["target"]}】
{
var channel = (ITextChannel)umsg.Channel;
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
{
await channel.SendMessageAsync("💢 `Bot owner didn't specify MashapeApiKey. You can't use this functionality.`").ConfigureAwait(false);
return;
}
var arg = query;
if (string.IsNullOrWhiteSpace(arg))
{
await channel.SendMessageAsync("💢 Please enter a search term.").ConfigureAwait(false);
await channel.SendMessageAsync("💢 `Please enter a search term.`").ConfigureAwait(false);
return;
}
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
@ -271,7 +295,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
try
{
var items = JObject.Parse(res);
var sb = new System.Text.StringBuilder();
var sb = new StringBuilder();
sb.AppendLine($"`Term:` {items["list"][0]["word"].ToString()}");
sb.AppendLine($"`Definition:` {items["list"][0]["definition"].ToString()}");
sb.Append($"`Link:` <{await _google.ShortenUrl(items["list"][0]["permalink"].ToString()).ConfigureAwait(false)}>");
@ -293,9 +317,15 @@ $@"🌍 **Weather for** 【{obj["target"]}】
var arg = query;
if (string.IsNullOrWhiteSpace(arg))
{
await channel.SendMessageAsync("💢 Please enter a search term.").ConfigureAwait(false);
await channel.SendMessageAsync("💢 `Please enter a search term.`").ConfigureAwait(false);
return;
}
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
{
await channel.SendMessageAsync("💢 `Bot owner didn't specify MashapeApiKey. You can't use this functionality.`").ConfigureAwait(false);
return;
}
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
string res = "";
using (var http = new HttpClient())
@ -464,6 +494,114 @@ $@"🌍 **Weather for** 【{obj["target"]}】
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task Wikia(IUserMessage umsg, string target, [Remainder] string query = null)
{
var channel = (ITextChannel)umsg.Channel;
if (string.IsNullOrWhiteSpace(target) || string.IsNullOrWhiteSpace(query))
{
await channel.SendMessageAsync("💢 Please enter a target wikia, followed by search query.").ConfigureAwait(false);
return;
}
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
try
{
var res = await http.GetStringAsync($"http://www.{Uri.EscapeUriString(target)}.wikia.com/api/v1/Search/List?query={Uri.EscapeUriString(query)}&limit=25&minArticleQuality=10&batch=1&namespaces=0%2C14").ConfigureAwait(false);
var items = JObject.Parse(res);
var found = items["items"][0];
var response = $@"`Title:` {found["title"].ToString()}
`Quality:` {found["quality"]}
`URL:` {await NadekoBot.Google.ShortenUrl(found["url"].ToString()).ConfigureAwait(false)}";
await channel.SendMessageAsync(response);
}
catch
{
await channel.SendMessageAsync($"💢 Failed finding `{query}`.").ConfigureAwait(false);
}
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task MCPing(IUserMessage umsg, [Remainder] string query = null)
{
var channel = (ITextChannel)umsg.Channel;
var arg = query;
if (string.IsNullOrWhiteSpace(arg))
{
await channel.SendMessageAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false);
return;
}
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
string ip = arg.Split(':')[0];
string port = arg.Split(':')[1];
var res = await http.GetStringAsync($"https://api.minetools.eu/ping/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false);
try
{
var items = JObject.Parse(res);
var sb = new StringBuilder();
int ping = (int)Math.Ceiling(Double.Parse(items["latency"].ToString()));
sb.AppendLine($"`Server:` {arg}");
sb.AppendLine($"`Version:` {items["version"]["name"].ToString()} / Protocol {items["version"]["protocol"].ToString()}");
sb.AppendLine($"`Description:` {items["description"].ToString()}");
sb.AppendLine($"`Online Players:` {items["players"]["online"].ToString()}/{items["players"]["max"].ToString()}");
sb.Append($"`Latency:` {ping}");
await channel.SendMessageAsync(sb.ToString());
}
catch
{
await channel.SendMessageAsync($"💢 Failed finding `{arg}`.").ConfigureAwait(false);
}
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task MCQ(IUserMessage umsg, [Remainder] string query = null)
{
var channel = (ITextChannel)umsg.Channel;
var arg = query;
if (string.IsNullOrWhiteSpace(arg))
{
await channel.SendMessageAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false);
return;
}
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
try
{
string ip = arg.Split(':')[0];
string port = arg.Split(':')[1];
var res = await http.GetStringAsync($"https://api.minetools.eu/query/{Uri.EscapeUriString(ip)}/{Uri.EscapeUriString(port)}").ConfigureAwait(false);
var items = JObject.Parse(res);
var sb = new StringBuilder();
sb.AppendLine($"`Server:` {arg.ToString()} 〘Status: {items["status"]}〙");
sb.AppendLine($"`Player List (First 5):`");
foreach (var item in items["Playerlist"].Take(5))
{
sb.AppendLine($":rosette: {item}");
}
sb.AppendLine($"`Online Players:` {items["Players"]} / {items["MaxPlayers"]}");
sb.AppendLine($"`Plugins:` {items["Plugins"]}");
sb.Append($"`Version:` {items["Version"]}");
await channel.SendMessageAsync(sb.ToString());
}
catch
{
await channel.SendMessageAsync($"💢 Failed finding server `{arg}`.").ConfigureAwait(false);
}
}
}
public static async Task<bool> ValidateQuery(ITextChannel ch, string query)
{
if (!string.IsNullOrEmpty(query.Trim())) return true;

View File

@ -15,6 +15,30 @@ namespace NadekoBot.Modules.Utility
{
public partial class Utility
{
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task ListQuotes(IUserMessage imsg, int page = 1)
{
var channel = (ITextChannel)imsg.Channel;
page -= 1;
if (page < 0)
return;
IEnumerable<Quote> quotes;
using (var uow = DbHandler.UnitOfWork())
{
quotes = uow.Quotes.GetGroup(page * 16, 16);
}
if (quotes.Any())
await channel.SendMessageAsync($"`Page {page + 1} of quotes:`\n```xl\n" + String.Join("\n", quotes.Select((q) => $"{q.Keyword,-20} by {q.AuthorName}")) + "\n```")
.ConfigureAwait(false);
else
await channel.SendMessageAsync("`No quotes on this page.`").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task ShowQuote(IUserMessage umsg, [Remainder] string keyword)

View File

@ -11,6 +11,8 @@ using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Reflection;
using Discord.WebSocket;
using System.Net.Http;
using System.IO;
namespace NadekoBot.Modules.Utility
{
@ -167,13 +169,65 @@ namespace NadekoBot.Modules.Utility
{
var matches = emojiFinder.Matches(emojis);
var result = string.Join("\n", matches.Cast<Match>()
.Select(m => $"`Name:` {m.Groups["name"]} `Link:` http://discordapp.com/api/emojis/{m.Groups["id"]}.png"));
await msg.Channel.SendMessageAsync(result).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[OwnerOnly]
public async Task ListServers(IUserMessage imsg, int page = 1)
{
var channel = (ITextChannel)imsg.Channel;
page -= 1;
if (page < 0)
return;
var guilds = NadekoBot.Client.GetGuilds().OrderBy(g => g.Name).Skip((page - 1) * 15).Take(15);
if (!guilds.Any())
{
await channel.SendMessageAsync("`No servers found on that page.`").ConfigureAwait(false);
return;
}
await channel.SendMessageAsync(String.Join("\n", guilds.Select(g => $"`Name:` {g.Name} `Id:` {g.Id} `Members:` {g.GetUsers().Count} `OwnerId:`{g.OwnerId}"))).ConfigureAwait(false);
}
//[NadekoCommand, Usage, Description, Aliases]
//[RequireContext(ContextType.Guild)]
//public async Task TextToImage(IUserMessage msg, [Remainder] string arg)
//{
// var channel = (ITextChannel)msg.Channel;
// const string bgName = "xbiy3";
// if (string.IsNullOrWhiteSpace(arg))
// return;
// using (var http = new HttpClient())
// {
// http.AddFakeHeaders();
// http.DefaultRequestHeaders.Add("Host", "www.tagsmaker.com");
// http.DefaultRequestHeaders.Add("Referer", "http://www.tagsmaker.com/");
// http.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
// http.DefaultRequestHeaders.Add("Alt-Used", "www.tagsmaker.com:443");
// var res = await http.GetAsync($"http://www.tagsmaker.com/tagsmaker.php?background_name=0011&tag_text={arg}&font_name=applejuiced&text_color=white&text_size=48&text_alignment=middle").ConfigureAwait(false);
// var img = res.RequestMessage.RequestUri.Segments[1].Replace("image-", "").Replace("tag-", "");
// var imgStream = await http.GetStreamAsync($"http://www.tagsmaker.com/upload/www.tagsmaker.com_{ img.ToString() }.png");
// var ms = new MemoryStream();
// await imgStream.CopyToAsync(ms).ConfigureAwait(false);
// ms.Position = 0;
// await channel.SendFileAsync(ms, arg+".png", "Provided by www.tagsmaker.com").ConfigureAwait(false);
// }
//}
}
}

View File

@ -19,6 +19,7 @@ using Module = Discord.Commands.Module;
using NadekoBot.TypeReaders;
using System.Collections.Concurrent;
using NadekoBot.Modules.Music;
using NadekoBot.Services.Database.Models;
namespace NadekoBot
{
@ -38,6 +39,16 @@ namespace NadekoBot
public static ConcurrentDictionary<string, string> ModulePrefixes { get; private set; }
public static bool Ready { get; private set; }
public static IEnumerable<GuildConfig> AllGuildConfigs { get; }
static NadekoBot()
{
using (var uow = DbHandler.UnitOfWork())
{
AllGuildConfigs = uow.GuildConfigs.GetAll();
}
}
public async Task RunAsync(string[] args)
{
SetupLogger();

View File

@ -464,6 +464,33 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to atfbooru atf.
/// </summary>
public static string atfbooru_cmd {
get {
return ResourceManager.GetString("atfbooru_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Shows a random hentai image from atfbooru with a given tag. Tag is optional but preferred..
/// </summary>
public static string atfbooru_desc {
get {
return ResourceManager.GetString("atfbooru_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}atfbooru yuri+kissing`.
/// </summary>
public static string atfbooru_usage {
get {
return ResourceManager.GetString("atfbooru_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to autoassignrole aar.
/// </summary>
@ -474,7 +501,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Automaticaly assigns a specified role to every user who joins the server. .
/// Looks up a localized string similar to Automaticaly assigns a specified role to every user who joins the server..
/// </summary>
public static string autoassignrole_desc {
get {
@ -519,7 +546,61 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to av avatar.
/// Looks up a localized string similar to autotranslang atl.
/// </summary>
public static string autotranslang_cmd {
get {
return ResourceManager.GetString("autotranslang_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}atl en&gt;fr`.
/// </summary>
public static string autotranslang_desc {
get {
return ResourceManager.GetString("autotranslang_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sets your source and target language to be used with `{0}at`. Specify no arguments to remove previously set value..
/// </summary>
public static string autotranslang_usage {
get {
return ResourceManager.GetString("autotranslang_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to autotrans at.
/// </summary>
public static string autotranslate_cmd {
get {
return ResourceManager.GetString("autotranslate_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Starts automatic translation of all messages by users who set their `{0}atl` in this channel. You can set &quot;del&quot; argument to automatically delete all translated user messages..
/// </summary>
public static string autotranslate_desc {
get {
return ResourceManager.GetString("autotranslate_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}at` or `{0}at del`.
/// </summary>
public static string autotranslate_usage {
get {
return ResourceManager.GetString("autotranslate_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to avatar av.
/// </summary>
public static string avatar_cmd {
get {
@ -771,7 +852,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Toggles automatic deletion of bye messages. .
/// Looks up a localized string similar to Toggles automatic deletion of bye messages..
/// </summary>
public static string byedel_desc {
get {
@ -798,7 +879,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message. .
/// Looks up a localized string similar to Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message..
/// </summary>
public static string byemsg_desc {
get {
@ -1419,7 +1500,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Cleans up hanging voice connections. .
/// Looks up a localized string similar to Cleans up hanging voice connections..
/// </summary>
public static string cleanup_desc {
get {
@ -1463,6 +1544,33 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to cleverbot.
/// </summary>
public static string cleverbot_cmd {
get {
return ResourceManager.GetString("cleverbot_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Toggles cleverbot session. When enabled, the bot will reply to messages starting with bot mention in the server. Custom reactions starting with %mention% won&apos;t work if cleverbot is enabled..
/// </summary>
public static string cleverbot_desc {
get {
return ResourceManager.GetString("cleverbot_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}cleverbot`.
/// </summary>
public static string cleverbot_usage {
get {
return ResourceManager.GetString("cleverbot_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to cmdcooldown cmdcd.
/// </summary>
@ -1635,7 +1743,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Creates a role with a given name. .
/// Looks up a localized string similar to Creates a role with a given name..
/// </summary>
public static string createrole_desc {
get {
@ -1689,7 +1797,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Creates a new voice channel with a given name. .
/// Looks up a localized string similar to Creates a new voice channel with a given name..
/// </summary>
public static string creatvoichanl_desc {
get {
@ -1716,7 +1824,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Creates a new text channel with a given name. .
/// Looks up a localized string similar to Creates a new text channel with a given name..
/// </summary>
public static string creatxtchanl_desc {
get {
@ -1770,7 +1878,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Deafens mentioned user or users. .
/// Looks up a localized string similar to Deafens mentioned user or users..
/// </summary>
public static string deafen_desc {
get {
@ -1959,7 +2067,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Deletes a text channel with a given name. .
/// Looks up a localized string similar to Deletes a text channel with a given name..
/// </summary>
public static string deltxtchanl_desc {
get {
@ -1986,7 +2094,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Deletes a voice channel with a given name. .
/// Looks up a localized string similar to Deletes a voice channel with a given name..
/// </summary>
public static string delvoichanl_desc {
get {
@ -2499,7 +2607,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Toggles anouncements on the current channel when someone joins the server. .
/// Looks up a localized string similar to Toggles anouncements on the current channel when someone joins the server..
/// </summary>
public static string greet_desc {
get {
@ -2526,7 +2634,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Toggles automatic deletion of greet messages. .
/// Looks up a localized string similar to Toggles automatic deletion of greet messages..
/// </summary>
public static string greetdel_desc {
get {
@ -2553,7 +2661,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Toggles whether the greet messages will be sent in a DM (This is separate from greet - you can have both, any or neither enabled). .
/// Looks up a localized string similar to Toggles whether the greet messages will be sent in a DM (This is separate from greet - you can have both, any or neither enabled)..
/// </summary>
public static string greetdm_desc {
get {
@ -2580,7 +2688,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to 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. .
/// Looks up a localized string similar to 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..
/// </summary>
public static string greetdmmsg_desc {
get {
@ -2607,7 +2715,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Sets a new join announcement message which will be shown in the server&apos;s channel. Type %user% if you want to mention the new member. Using it with no message will show the current greet message. .
/// Looks up a localized string similar to Sets a new join announcement message which will be shown in the server&apos;s channel. Type %user% if you want to mention the new member. Using it with no message will show the current greet message..
/// </summary>
public static string greetmsg_desc {
get {
@ -2769,7 +2877,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Shows a 2 random images (from gelbooru and danbooru) with a given tag. Tag is optional but preferred. Only 1 tag allowed..
/// Looks up a localized string similar to Shows a hentai image from a random website (gelbooru or danbooru or konachan or atfbooru) with a given tag. Tag is optional but preferred. Only 1 tag allowed..
/// </summary>
public static string hentai_desc {
get {
@ -2786,6 +2894,33 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to hentaibomb.
/// </summary>
public static string hentaibomb_cmd {
get {
return ResourceManager.GetString("hentaibomb_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Shows a total 4 images (from gelbooru, danbooru, konachan and atfbooru). Tag is optional but preferred..
/// </summary>
public static string hentaibomb_desc {
get {
return ResourceManager.GetString("hentaibomb_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}hentaibomb yuri`.
/// </summary>
public static string hentaibomb_usage {
get {
return ResourceManager.GetString("hentaibomb_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to hgit.
/// </summary>
@ -3012,7 +3147,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Joins current channel to an instance of cross server channel using the token. .
/// Looks up a localized string similar to Joins current channel to an instance of cross server channel using the token..
/// </summary>
public static string jcsc_desc {
get {
@ -3066,7 +3201,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Kicks a mentioned user. .
/// Looks up a localized string similar to Kicks a mentioned user..
/// </summary>
public static string kick_desc {
get {
@ -3093,7 +3228,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Shows a random hentai image from konachan with a given tag. Tag is optional but preferred. (multiple tags are appended with +).
/// Looks up a localized string similar to Shows a random hentai image from konachan with a given tag. Tag is optional but preferred..
/// </summary>
public static string konachan_desc {
get {
@ -3120,7 +3255,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Leaves Cross server channel instance from this channel. .
/// Looks up a localized string similar to Leaves Cross server channel instance from this channel..
/// </summary>
public static string lcsc_desc {
get {
@ -3174,7 +3309,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Makes Nadeko leave the server. Either name or id required. .
/// Looks up a localized string similar to Makes Nadeko leave the server. Either name or id required..
/// </summary>
public static string leave_desc {
get {
@ -3353,6 +3488,60 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to listquotes liqu.
/// </summary>
public static string listquotes_cmd {
get {
return ResourceManager.GetString("listquotes_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}liqu` or `{0}liqu 3`.
/// </summary>
public static string listquotes_desc {
get {
return ResourceManager.GetString("listquotes_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Lists all quotes on the server ordered alphabetically. 15 Per page..
/// </summary>
public static string listquotes_usage {
get {
return ResourceManager.GetString("listquotes_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to listservers.
/// </summary>
public static string listservers_cmd {
get {
return ResourceManager.GetString("listservers_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Lists servers the bot is on with some basic info. 15 per page..
/// </summary>
public static string listservers_desc {
get {
return ResourceManager.GetString("listservers_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}listservers 3`.
/// </summary>
public static string listservers_usage {
get {
return ResourceManager.GetString("listservers_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to liststreams ls.
/// </summary>
@ -3758,6 +3947,60 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to minecraftping mcping.
/// </summary>
public static string mcping_cmd {
get {
return ResourceManager.GetString("mcping_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Pings a minecraft server..
/// </summary>
public static string mcping_desc {
get {
return ResourceManager.GetString("mcping_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}mcping 127.0.0.1:25565`.
/// </summary>
public static string mcping_usage {
get {
return ResourceManager.GetString("mcping_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to minecraftquery mcq.
/// </summary>
public static string mcq_cmd {
get {
return ResourceManager.GetString("mcq_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Finds information about a minecraft server..
/// </summary>
public static string mcq_desc {
get {
return ResourceManager.GetString("mcq_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}mcq server:ip`.
/// </summary>
public static string mcq_usage {
get {
return ResourceManager.GetString("mcq_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to memegen.
/// </summary>
@ -4011,7 +4254,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Goes to the next song in the queue. You have to be in the same voice channel as the bot..
/// Looks up a localized string similar to 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 {0}rcs or {0}rpl is enabled..
/// </summary>
public static string next_desc {
get {
@ -4020,7 +4263,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to `{0}n`.
/// Looks up a localized string similar to `{0}n` or `{0}n 5`.
/// </summary>
public static string next_usage {
get {
@ -4497,7 +4740,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to `{0}prune` removes all nadeko&apos;s messages in the last 100 messages.`{0}prune X` removes last X messages from the channel (up to 100)`{0}prune @Someone` removes all Someone&apos;s messages in the last 100 messages.`{0}prune @Someone X` removes last X &apos;Someone&apos;s&apos; messages in the channel. .
/// Looks up a localized string similar to `{0}prune` removes all nadeko&apos;s messages in the last 100 messages.`{0}prune X` removes last X messages from the channel (up to 100)`{0}prune @Someone` removes all Someone&apos;s messages in the last 100 messages.`{0}prune @Someone X` removes last X &apos;Someone&apos;s&apos; messages in the channel..
/// </summary>
public static string prune_desc {
get {
@ -4767,7 +5010,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to 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. .
/// Looks up a localized string similar to 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..
/// </summary>
public static string remindtemplate_desc {
get {
@ -4776,7 +5019,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to `{0}remindtemplate %user%, you gotta do %message%!`.
/// Looks up a localized string similar to `{0}remindtemplate %user%, do %message%!`.
/// </summary>
public static string remindtemplate_usage {
get {
@ -4821,7 +5064,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Removes all roles from a mentioned user. .
/// Looks up a localized string similar to Removes all roles from a mentioned user..
/// </summary>
public static string removeallroles_desc {
get {
@ -4875,7 +5118,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Removes a playing string on a given number. .
/// Looks up a localized string similar to Removes a playing string on a given number..
/// </summary>
public static string removeplaying_desc {
get {
@ -4902,7 +5145,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Removes a role from a given user. .
/// Looks up a localized string similar to Removes a role from a given user..
/// </summary>
public static string removerole_desc {
get {
@ -5010,7 +5253,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Immediately shows the repeat message and restarts the timer. .
/// Looks up a localized string similar to Immediately shows the repeat message and restarts the timer..
/// </summary>
public static string repeatinvoke_desc {
get {
@ -5226,7 +5469,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Set a role&apos;s color to the hex or 0-255 rgb color value provided. .
/// Looks up a localized string similar to Set a role&apos;s color to the hex or 0-255 rgb color value provided..
/// </summary>
public static string rolecolor_desc {
get {
@ -5685,7 +5928,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Sets a new avatar image for the NadekoBot. Argument is a direct link to an image. .
/// Looks up a localized string similar to Sets a new avatar image for the NadekoBot. Argument is a direct link to an image..
/// </summary>
public static string setavatar_desc {
get {
@ -5712,7 +5955,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Changes the name of the current channel. .
/// Looks up a localized string similar to Changes the name of the current channel..
/// </summary>
public static string setchanlname_desc {
get {
@ -5739,7 +5982,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Sets the bots game. .
/// Looks up a localized string similar to Sets the bots game..
/// </summary>
public static string setgame_desc {
get {
@ -5793,7 +6036,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Sets a name of the role which will be assigned to people who should be muted. Default is nadeko-mute. After specifying this role, restart commands which use mute as punishment..
/// Looks up a localized string similar to Sets a name of the role which will be assigned to people who should be muted. Default is nadeko-mute..
/// </summary>
public static string setmuterole_desc {
get {
@ -5820,7 +6063,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Gives the bot a new name. .
/// Looks up a localized string similar to Gives the bot a new name..
/// </summary>
public static string setname_desc {
get {
@ -5847,7 +6090,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Sets a role for a given user. .
/// Looks up a localized string similar to Sets a role for a given user..
/// </summary>
public static string setrole_desc {
get {
@ -5883,7 +6126,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to `{0}setstream https://www.twitch.tv/masterkwoth Developing Nakedo`.
/// Looks up a localized string similar to `{0}setstream TWITCHLINK Hello`.
/// </summary>
public static string setstream_usage {
get {
@ -5901,7 +6144,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Sets a topic on the current channel. .
/// Looks up a localized string similar to Sets a topic on the current channel..
/// </summary>
public static string settopic_desc {
get {
@ -5918,6 +6161,33 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to shorten.
/// </summary>
public static string shorten_cmd {
get {
return ResourceManager.GetString("shorten_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Attempts to shorten an URL, if it fails, returns the input URL..
/// </summary>
public static string shorten_desc {
get {
return ResourceManager.GetString("shorten_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}shorten https://google.com`.
/// </summary>
public static string shorten_usage {
get {
return ResourceManager.GetString("shorten_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to showcustreact scr.
/// </summary>
@ -6090,7 +6360,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Bans and then unbans a user by ID or name with an optional message. .
/// Looks up a localized string similar to Bans and then unbans a user by ID or name with an optional message..
/// </summary>
public static string softban_desc {
get {
@ -6360,7 +6630,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Takes a certain amount of currency from someone. .
/// Looks up a localized string similar to Takes a certain amount of currency from someone..
/// </summary>
public static string take_desc {
get {
@ -6620,6 +6890,60 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to typedel.
/// </summary>
public static string typedel_cmd {
get {
return ResourceManager.GetString("typedel_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Deletes a typing article given the ID..
/// </summary>
public static string typedel_desc {
get {
return ResourceManager.GetString("typedel_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}typedel 3`.
/// </summary>
public static string typedel_usage {
get {
return ResourceManager.GetString("typedel_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to typelist.
/// </summary>
public static string typelist_cmd {
get {
return ResourceManager.GetString("typelist_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Lists added typing articles with their IDs. 15 per page..
/// </summary>
public static string typelist_desc {
get {
return ResourceManager.GetString("typelist_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}typelist` or `{0}typelist 3`.
/// </summary>
public static string typelist_usage {
get {
return ResourceManager.GetString("typelist_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to typestart.
/// </summary>
@ -6711,7 +7035,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Undeafens mentioned user or users. .
/// Looks up a localized string similar to Undeafens mentioned user or users..
/// </summary>
public static string undeafen_desc {
get {
@ -6765,7 +7089,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Clears the message queue. .
/// Looks up a localized string similar to Clears the message queue..
/// </summary>
public static string unstuck_desc {
get {
@ -6900,7 +7224,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Starts logging to this channel when someone from the server goes online/offline/idle. .
/// Looks up a localized string similar to Starts logging to this channel when someone from the server goes online/offline/idle..
/// </summary>
public static string userpresence_desc {
get {
@ -7062,7 +7386,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to 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. .
/// Looks up a localized string similar to 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..
/// </summary>
public static string voiceplustext_desc {
get {
@ -7089,7 +7413,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Toggles logging to this channel whenever someone joins or leaves a voice channel you are currently in. .
/// Looks up a localized string similar to Toggles logging to this channel whenever someone joins or leaves a voice channel you are currently in..
/// </summary>
public static string voicepresence_desc {
get {
@ -7116,7 +7440,7 @@ namespace NadekoBot.Resources {
}
/// <summary>
/// Looks up a localized string similar to Gives a previously voice-muted user a permission to speak. .
/// Looks up a localized string similar to Gives a previously voice-muted user a permission to speak..
/// </summary>
public static string voiceunmute_desc {
get {
@ -7241,6 +7565,33 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to wikia.
/// </summary>
public static string wikia_cmd {
get {
return ResourceManager.GetString("wikia_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Gives you back a wikia link.
/// </summary>
public static string wikia_desc {
get {
return ResourceManager.GetString("wikia_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}wikia mtg Vigilance` or `{0}wikia mlp Dashy`.
/// </summary>
public static string wikia_usage {
get {
return ResourceManager.GetString("wikia_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to wowjoke.
/// </summary>

View File

@ -166,7 +166,7 @@
<value>greetdel grdel</value>
</data>
<data name="greetdel_desc" xml:space="preserve">
<value>Toggles automatic deletion of greet messages. </value>
<value>Toggles automatic deletion of greet messages.</value>
</data>
<data name="greetdel_usage" xml:space="preserve">
<value>`{0}greetdel`</value>
@ -175,7 +175,7 @@
<value>greet</value>
</data>
<data name="greet_desc" xml:space="preserve">
<value>Toggles anouncements on the current channel when someone joins the server. </value>
<value>Toggles anouncements on the current channel when someone joins the server.</value>
</data>
<data name="greet_usage" xml:space="preserve">
<value>`{0}greet`</value>
@ -184,7 +184,7 @@
<value>greetmsg</value>
</data>
<data name="greetmsg_desc" xml:space="preserve">
<value>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. </value>
<value>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.</value>
</data>
<data name="greetmsg_usage" xml:space="preserve">
<value>`{0}greetmsg Welcome, %user%.`</value>
@ -202,7 +202,7 @@
<value>byemsg</value>
</data>
<data name="byemsg_desc" xml:space="preserve">
<value>Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message. </value>
<value>Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message.</value>
</data>
<data name="byemsg_usage" xml:space="preserve">
<value>`{0}byemsg %user% has left.`</value>
@ -211,7 +211,7 @@
<value>byedel</value>
</data>
<data name="byedel_desc" xml:space="preserve">
<value>Toggles automatic deletion of bye messages. </value>
<value>Toggles automatic deletion of bye messages.</value>
</data>
<data name="byedel_usage" xml:space="preserve">
<value>`{0}byedel`</value>
@ -220,7 +220,7 @@
<value>greetdm</value>
</data>
<data name="greetdm_desc" xml:space="preserve">
<value>Toggles whether the greet messages will be sent in a DM (This is separate from greet - you can have both, any or neither enabled). </value>
<value>Toggles whether the greet messages will be sent in a DM (This is separate from greet - you can have both, any or neither enabled).</value>
</data>
<data name="greetdm_usage" xml:space="preserve">
<value>`{0}greetdm`</value>
@ -247,7 +247,7 @@
<value>userpresence</value>
</data>
<data name="userpresence_desc" xml:space="preserve">
<value>Starts logging to this channel when someone from the server goes online/offline/idle. </value>
<value>Starts logging to this channel when someone from the server goes online/offline/idle.</value>
</data>
<data name="userpresence_usage" xml:space="preserve">
<value>`{0}userpresence`</value>
@ -256,7 +256,7 @@
<value>voicepresence</value>
</data>
<data name="voicepresence_desc" xml:space="preserve">
<value>Toggles logging to this channel whenever someone joins or leaves a voice channel you are currently in. </value>
<value>Toggles logging to this channel whenever someone joins or leaves a voice channel you are currently in.</value>
</data>
<data name="voicepresence_usage" xml:space="preserve">
<value>`{0}voicepresence`</value>
@ -265,7 +265,7 @@
<value>repeatinvoke repinv</value>
</data>
<data name="repeatinvoke_desc" xml:space="preserve">
<value>Immediately shows the repeat message and restarts the timer. </value>
<value>Immediately shows the repeat message and restarts the timer.</value>
</data>
<data name="repeatinvoke_usage" xml:space="preserve">
<value>`{0}repinv`</value>
@ -310,7 +310,7 @@
<value>removeplaying rmpl repl</value>
</data>
<data name="removeplaying_desc" xml:space="preserve">
<value>Removes a playing string on a given number. </value>
<value>Removes a playing string on a given number.</value>
</data>
<data name="removeplaying_usage" xml:space="preserve">
<value>`{0}rmpl`</value>
@ -337,7 +337,7 @@
<value>voice+text v+t</value>
</data>
<data name="voiceplustext_desc" xml:space="preserve">
<value>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. </value>
<value>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.</value>
</data>
<data name="voiceplustext_usage" xml:space="preserve">
<value>`{0}voice+text`</value>
@ -355,7 +355,7 @@
<value>jcsc</value>
</data>
<data name="jcsc_desc" xml:space="preserve">
<value>Joins current channel to an instance of cross server channel using the token. </value>
<value>Joins current channel to an instance of cross server channel using the token.</value>
</data>
<data name="jcsc_usage" xml:space="preserve">
<value>`{0}jcsc TokenHere`</value>
@ -364,7 +364,7 @@
<value>lcsc</value>
</data>
<data name="lcsc_desc" xml:space="preserve">
<value>Leaves Cross server channel instance from this channel. </value>
<value>Leaves Cross server channel instance from this channel.</value>
</data>
<data name="lcsc_usage" xml:space="preserve">
<value>`{0}lcsc`</value>
@ -463,7 +463,7 @@
<value>autoassignrole aar</value>
</data>
<data name="autoassignrole_desc" xml:space="preserve">
<value>Automaticaly assigns a specified role to every user who joins the server. </value>
<value>Automaticaly assigns a specified role to every user who joins the server.</value>
</data>
<data name="autoassignrole_usage" xml:space="preserve">
<value>`{0}aar` to disable, `{0}aar Role Name` to enable</value>
@ -472,7 +472,7 @@
<value>leave</value>
</data>
<data name="leave_desc" xml:space="preserve">
<value>Makes Nadeko leave the server. Either name or id required. </value>
<value>Makes Nadeko leave the server. Either name or id required.</value>
</data>
<data name="leave_usage" xml:space="preserve">
<value>`{0}leave 123123123331`</value>
@ -499,7 +499,7 @@
<value>setrole sr</value>
</data>
<data name="setrole_desc" xml:space="preserve">
<value>Sets a role for a given user. </value>
<value>Sets a role for a given user.</value>
</data>
<data name="setrole_usage" xml:space="preserve">
<value>`{0}sr @User Guest`</value>
@ -508,7 +508,7 @@
<value>removerole rr</value>
</data>
<data name="removerole_desc" xml:space="preserve">
<value>Removes a role from a given user. </value>
<value>Removes a role from a given user.</value>
</data>
<data name="removerole_usage" xml:space="preserve">
<value>`{0}rr @User Admin`</value>
@ -526,7 +526,7 @@
<value>removeallroles rar</value>
</data>
<data name="removeallroles_desc" xml:space="preserve">
<value>Removes all roles from a mentioned user. </value>
<value>Removes all roles from a mentioned user.</value>
</data>
<data name="removeallroles_usage" xml:space="preserve">
<value>`{0}rar @User`</value>
@ -535,7 +535,7 @@
<value>createrole cr</value>
</data>
<data name="createrole_desc" xml:space="preserve">
<value>Creates a role with a given name. </value>
<value>Creates a role with a given name.</value>
</data>
<data name="createrole_usage" xml:space="preserve">
<value>`{0}cr Awesome Role`</value>
@ -544,7 +544,7 @@
<value>rolecolor rc</value>
</data>
<data name="rolecolor_desc" xml:space="preserve">
<value>Set a role's color to the hex or 0-255 rgb color value provided. </value>
<value>Set a role's color to the hex or 0-255 rgb color value provided.</value>
</data>
<data name="rolecolor_usage" xml:space="preserve">
<value>`{0}rc Admin 255 200 100` or `{0}rc Admin ffba55`</value>
@ -562,7 +562,7 @@
<value>softban sb</value>
</data>
<data name="softban_desc" xml:space="preserve">
<value>Bans and then unbans a user by ID or name with an optional message. </value>
<value>Bans and then unbans a user by ID or name with an optional message.</value>
</data>
<data name="softban_usage" xml:space="preserve">
<value>`{0}sb "@some Guy" Your behaviour is toxic.`</value>
@ -571,7 +571,7 @@
<value>kick k</value>
</data>
<data name="kick_desc" xml:space="preserve">
<value>Kicks a mentioned user. </value>
<value>Kicks a mentioned user.</value>
</data>
<data name="kick_usage" xml:space="preserve">
<value>`{0}k "@some Guy" Your behaviour is toxic.`</value>
@ -589,7 +589,7 @@
<value>voiceunmute</value>
</data>
<data name="voiceunmute_desc" xml:space="preserve">
<value>Gives a previously voice-muted user a permission to speak. </value>
<value>Gives a previously voice-muted user a permission to speak.</value>
</data>
<data name="voiceunmute_usage" xml:space="preserve">
<value>`{0}voiceunmute @Someguy`</value>
@ -598,7 +598,7 @@
<value>deafen deaf</value>
</data>
<data name="deafen_desc" xml:space="preserve">
<value>Deafens mentioned user or users. </value>
<value>Deafens mentioned user or users.</value>
</data>
<data name="deafen_usage" xml:space="preserve">
<value>`{0}deaf "@Someguy"` or `{0}deaf "@Someguy" "@Someguy"`</value>
@ -607,7 +607,7 @@
<value>undeafen undef</value>
</data>
<data name="undeafen_desc" xml:space="preserve">
<value>Undeafens mentioned user or users. </value>
<value>Undeafens mentioned user or users.</value>
</data>
<data name="undeafen_usage" xml:space="preserve">
<value>`{0}undef "@Someguy"` or `{0}undef "@Someguy" "@Someguy"`</value>
@ -616,7 +616,7 @@
<value>delvoichanl dvch</value>
</data>
<data name="delvoichanl_desc" xml:space="preserve">
<value>Deletes a voice channel with a given name. </value>
<value>Deletes a voice channel with a given name.</value>
</data>
<data name="delvoichanl_usage" xml:space="preserve">
<value>`{0}dvch VoiceChannelName`</value>
@ -625,7 +625,7 @@
<value>creatvoichanl cvch</value>
</data>
<data name="creatvoichanl_desc" xml:space="preserve">
<value>Creates a new voice channel with a given name. </value>
<value>Creates a new voice channel with a given name.</value>
</data>
<data name="creatvoichanl_usage" xml:space="preserve">
<value>`{0}cvch VoiceChannelName`</value>
@ -634,7 +634,7 @@
<value>deltxtchanl dtch</value>
</data>
<data name="deltxtchanl_desc" xml:space="preserve">
<value>Deletes a text channel with a given name. </value>
<value>Deletes a text channel with a given name.</value>
</data>
<data name="deltxtchanl_usage" xml:space="preserve">
<value>`{0}dtch TextChannelName`</value>
@ -643,7 +643,7 @@
<value>creatxtchanl ctch</value>
</data>
<data name="creatxtchanl_desc" xml:space="preserve">
<value>Creates a new text channel with a given name. </value>
<value>Creates a new text channel with a given name.</value>
</data>
<data name="creatxtchanl_usage" xml:space="preserve">
<value>`{0}ctch TextChannelName`</value>
@ -652,7 +652,7 @@
<value>settopic st</value>
</data>
<data name="settopic_desc" xml:space="preserve">
<value>Sets a topic on the current channel. </value>
<value>Sets a topic on the current channel.</value>
</data>
<data name="settopic_usage" xml:space="preserve">
<value>`{0}st My new topic`</value>
@ -661,7 +661,7 @@
<value>setchanlname schn</value>
</data>
<data name="setchanlname_desc" xml:space="preserve">
<value>Changes the name of the current channel. </value>
<value>Changes the name of the current channel.</value>
</data>
<data name="setchanlname_usage" xml:space="preserve">
<value>`{0}schn NewName`</value>
@ -670,7 +670,7 @@
<value>prune clr</value>
</data>
<data name="prune_desc" xml:space="preserve">
<value>`{0}prune` removes all nadeko's messages in the last 100 messages.`{0}prune X` removes last X messages from the channel (up to 100)`{0}prune @Someone` removes all Someone's messages in the last 100 messages.`{0}prune @Someone X` removes last X 'Someone's' messages in the channel. </value>
<value>`{0}prune` removes all nadeko's messages in the last 100 messages.`{0}prune X` removes last X messages from the channel (up to 100)`{0}prune @Someone` removes all Someone's messages in the last 100 messages.`{0}prune @Someone X` removes last X 'Someone's' messages in the channel.</value>
</data>
<data name="prune_usage" xml:space="preserve">
<value>`{0}prune` or `{0}prune 5` or `{0}prune @Someone` or `{0}prune @Someone X`</value>
@ -688,7 +688,7 @@
<value>setname newnm</value>
</data>
<data name="setname_desc" xml:space="preserve">
<value>Gives the bot a new name. </value>
<value>Gives the bot a new name.</value>
</data>
<data name="setname_usage" xml:space="preserve">
<value>`{0}newnm BotName`</value>
@ -697,7 +697,7 @@
<value>setavatar setav</value>
</data>
<data name="setavatar_desc" xml:space="preserve">
<value>Sets a new avatar image for the NadekoBot. Argument is a direct link to an image. </value>
<value>Sets a new avatar image for the NadekoBot. Argument is a direct link to an image.</value>
</data>
<data name="setavatar_usage" xml:space="preserve">
<value>`{0}setav http://i.imgur.com/xTG3a1I.jpg`</value>
@ -706,7 +706,7 @@
<value>setgame</value>
</data>
<data name="setgame_desc" xml:space="preserve">
<value>Sets the bots game. </value>
<value>Sets the bots game.</value>
</data>
<data name="setgame_usage" xml:space="preserve">
<value>`{0}setgame with snakes`</value>
@ -733,7 +733,7 @@
<value>unstuck</value>
</data>
<data name="unstuck_desc" xml:space="preserve">
<value>Clears the message queue. </value>
<value>Clears the message queue.</value>
</data>
<data name="unstuck_usage" xml:space="preserve">
<value>`{0}unstuck`</value>
@ -787,10 +787,10 @@
<value>remindtemplate</value>
</data>
<data name="remindtemplate_desc" xml:space="preserve">
<value>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. </value>
<value>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.</value>
</data>
<data name="remindtemplate_usage" xml:space="preserve">
<value>`{0}remindtemplate %user%, you gotta do %message%!`</value>
<value>`{0}remindtemplate %user%, do %message%!`</value>
</data>
<data name="serverinfo_cmd" xml:space="preserve">
<value>serverinfo sinfo</value>
@ -1255,7 +1255,7 @@
<value>take</value>
</data>
<data name="take_desc" xml:space="preserve">
<value>Takes a certain amount of currency from someone. </value>
<value>Takes a certain amount of currency from someone.</value>
</data>
<data name="take_usage" xml:space="preserve">
<value>`{0}take 1 "@someguy"`</value>
@ -1426,10 +1426,10 @@
<value>next n</value>
</data>
<data name="next_desc" xml:space="preserve">
<value>Goes to the next song in the queue. You have to be in the same voice channel as the bot.</value>
<value>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 {0}rcs or {0}rpl is enabled.</value>
</data>
<data name="next_usage" xml:space="preserve">
<value>`{0}n`</value>
<value>`{0}n` or `{0}n 5`</value>
</data>
<data name="stop_cmd" xml:space="preserve">
<value>stop s</value>
@ -1615,7 +1615,7 @@
<value>cleanup</value>
</data>
<data name="cleanup_desc" xml:space="preserve">
<value>Cleans up hanging voice connections. </value>
<value>Cleans up hanging voice connections.</value>
</data>
<data name="cleanup_usage" xml:space="preserve">
<value>`{0}cleanup`</value>
@ -2089,7 +2089,7 @@
<value>`{0}videocall "@SomeGuy"`</value>
</data>
<data name="avatar_cmd" xml:space="preserve">
<value>av avatar</value>
<value>avatar av</value>
</data>
<data name="avatar_desc" xml:space="preserve">
<value>Shows a mentioned person's avatar.</value>
@ -2101,7 +2101,7 @@
<value>hentai</value>
</data>
<data name="hentai_desc" xml:space="preserve">
<value>Shows a 2 random images (from gelbooru and danbooru) with a given tag. Tag is optional but preferred. Only 1 tag allowed.</value>
<value>Shows a hentai image from a random website (gelbooru or danbooru or konachan or atfbooru) with a given tag. Tag is optional but preferred. Only 1 tag allowed.</value>
</data>
<data name="hentai_usage" xml:space="preserve">
<value>`{0}hentai yuri`</value>
@ -2115,6 +2115,15 @@
<data name="danbooru_usage" xml:space="preserve">
<value>`{0}danbooru yuri+kissing`</value>
</data>
<data name="atfbooru_cmd" xml:space="preserve">
<value>atfbooru atf</value>
</data>
<data name="atfbooru_desc" xml:space="preserve">
<value>Shows a random hentai image from atfbooru with a given tag. Tag is optional but preferred.</value>
</data>
<data name="atfbooru_usage" xml:space="preserve">
<value>`{0}atfbooru yuri+kissing`</value>
</data>
<data name="gelbooru_cmd" xml:space="preserve">
<value>gelbooru</value>
</data>
@ -2302,7 +2311,7 @@
<value>`{0}greetdmmsg Welcome to the server, %user%`.</value>
</data>
<data name="greetdmmsg_desc" xml:space="preserve">
<value>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. </value>
<value>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.</value>
</data>
<data name="cash_desc" xml:space="preserve">
<value>Check how much currency a person has. (Defaults to yourself)</value>
@ -2452,7 +2461,7 @@
<value>konachan</value>
</data>
<data name="konachan_desc" xml:space="preserve">
<value>Shows a random hentai image from konachan with a given tag. Tag is optional but preferred. (multiple tags are appended with +)</value>
<value>Shows a random hentai image from konachan with a given tag. Tag is optional but preferred.</value>
</data>
<data name="konachan_usage" xml:space="preserve">
<value>`{0}konachan yuri`</value>
@ -2461,7 +2470,7 @@
<value>setmuterole</value>
</data>
<data name="setmuterole_desc" xml:space="preserve">
<value>Sets a name of the role which will be assigned to people who should be muted. Default is nadeko-mute. After specifying this role, restart commands which use mute as punishment.</value>
<value>Sets a name of the role which will be assigned to people who should be muted. Default is nadeko-mute.</value>
</data>
<data name="setmuterole_usage" xml:space="preserve">
<value>`{0}setmuterole Silenced`</value>
@ -2482,7 +2491,7 @@
<value>Sets the bots stream. First argument is the twitch link, second argument is stream name.</value>
</data>
<data name="setstream_usage" xml:space="preserve">
<value>`{0}setstream https://www.twitch.tv/masterkwoth Developing Nakedo`</value>
<value>`{0}setstream TWITCHLINK Hello`</value>
</data>
<data name="chatunmute_cmd" xml:space="preserve">
<value>chatunmute</value>
@ -2547,4 +2556,112 @@
<data name="publicpoll_usage" xml:space="preserve">
<value>`{0}ppoll Question?;Answer1;Answ 2;A_3`</value>
</data>
<data name="autotranslang_cmd" xml:space="preserve">
<value>autotranslang atl</value>
</data>
<data name="autotranslang_desc" xml:space="preserve">
<value>`{0}atl en&gt;fr`</value>
</data>
<data name="autotranslang_usage" xml:space="preserve">
<value>Sets your source and target language to be used with `{0}at`. Specify no arguments to remove previously set value.</value>
</data>
<data name="autotranslate_cmd" xml:space="preserve">
<value>autotrans at</value>
</data>
<data name="autotranslate_desc" xml:space="preserve">
<value>Starts automatic translation of all messages by users who set their `{0}atl` in this channel. You can set "del" argument to automatically delete all translated user messages.</value>
</data>
<data name="autotranslate_usage" xml:space="preserve">
<value>`{0}at` or `{0}at del`</value>
</data>
<data name="listquotes_cmd" xml:space="preserve">
<value>listquotes liqu</value>
</data>
<data name="listquotes_desc" xml:space="preserve">
<value>`{0}liqu` or `{0}liqu 3`</value>
</data>
<data name="listquotes_usage" xml:space="preserve">
<value>Lists all quotes on the server ordered alphabetically. 15 Per page.</value>
</data>
<data name="typedel_cmd" xml:space="preserve">
<value>typedel</value>
</data>
<data name="typedel_desc" xml:space="preserve">
<value>Deletes a typing article given the ID.</value>
</data>
<data name="typedel_usage" xml:space="preserve">
<value>`{0}typedel 3`</value>
</data>
<data name="typelist_cmd" xml:space="preserve">
<value>typelist</value>
</data>
<data name="typelist_desc" xml:space="preserve">
<value>Lists added typing articles with their IDs. 15 per page.</value>
</data>
<data name="typelist_usage" xml:space="preserve">
<value>`{0}typelist` or `{0}typelist 3`</value>
</data>
<data name="listservers_cmd" xml:space="preserve">
<value>listservers</value>
</data>
<data name="listservers_desc" xml:space="preserve">
<value>Lists servers the bot is on with some basic info. 15 per page.</value>
</data>
<data name="listservers_usage" xml:space="preserve">
<value>`{0}listservers 3`</value>
</data>
<data name="hentaibomb_cmd" xml:space="preserve">
<value>hentaibomb</value>
</data>
<data name="hentaibomb_desc" xml:space="preserve">
<value>Shows a total 4 images (from gelbooru, danbooru, konachan and atfbooru). Tag is optional but preferred.</value>
</data>
<data name="hentaibomb_usage" xml:space="preserve">
<value>`{0}hentaibomb yuri`</value>
</data>
<data name="cleverbot_cmd" xml:space="preserve">
<value>cleverbot</value>
</data>
<data name="cleverbot_desc" xml:space="preserve">
<value>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.</value>
</data>
<data name="cleverbot_usage" xml:space="preserve">
<value>`{0}cleverbot`</value>
</data>
<data name="shorten_cmd" xml:space="preserve">
<value>shorten</value>
</data>
<data name="shorten_desc" xml:space="preserve">
<value>Attempts to shorten an URL, if it fails, returns the input URL.</value>
</data>
<data name="shorten_usage" xml:space="preserve">
<value>`{0}shorten https://google.com`</value>
</data>
<data name="mcping_cmd" xml:space="preserve">
<value>minecraftping mcping</value>
</data>
<data name="mcping_desc" xml:space="preserve">
<value>Pings a minecraft server.</value>
</data>
<data name="mcping_usage" xml:space="preserve">
<value>`{0}mcping 127.0.0.1:25565`</value>
</data>
<data name="mcq_cmd" xml:space="preserve">
<value>minecraftquery mcq</value>
</data>
<data name="mcq_desc" xml:space="preserve">
<value>Finds information about a minecraft server.</value>
</data>
<data name="mcq_usage" xml:space="preserve">
<value>`{0}mcq server:ip`</value>
</data>
<data name="wikia_cmd" xml:space="preserve">
<value>wikia</value>
</data>
<data name="wikia_desc" xml:space="preserve">
<value>Gives you back a wikia link</value>
</data>
<data name="wikia_usage" xml:space="preserve">
<value>`{0}wikia mtg Vigilance` or `{0}wikia mlp Dashy`</value>
</data>
</root>

View File

@ -0,0 +1,25 @@
/*
ChatterBotAPI
Copyright (C) 2011 pierredavidbelanger@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Services.CleverBotApi
{
public interface ChatterBot
{
ChatterBotSession CreateSession();
}
}

View File

@ -0,0 +1,45 @@
using System;
/*
ChatterBotAPI
Copyright (C) 2011 pierredavidbelanger@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Services.CleverBotApi
{
public class ChatterBotFactory
{
public static ChatterBot Create(ChatterBotType type)
{
return Create(type, null);
}
public static ChatterBot Create(ChatterBotType type, object arg)
{
switch (type)
{
case ChatterBotType.CLEVERBOT:
return new Cleverbot("http://www.cleverbot.com/", "http://www.cleverbot.com/webservicemin?uc=165", 26);
case ChatterBotType.JABBERWACKY:
return new Cleverbot("http://jabberwacky.com", "http://jabberwacky.com/webservicemin", 20);
case ChatterBotType.PANDORABOTS:
if (arg == null) throw new ArgumentException("PANDORABOTS needs a botid arg", nameof(arg));
return new Pandorabots(arg.ToString());
}
return null;
}
}
}

View File

@ -0,0 +1,28 @@
/*
ChatterBotAPI
Copyright (C) 2011 pierredavidbelanger@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Threading.Tasks;
namespace Services.CleverBotApi
{
public interface ChatterBotSession
{
Task<ChatterBotThought> Think(ChatterBotThought thought);
Task<string> Think(string text);
}
}

View File

@ -0,0 +1,26 @@
/*
ChatterBotAPI
Copyright (C) 2011 pierredavidbelanger@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Services.CleverBotApi
{
public class ChatterBotThought
{
public string[] Emotions { get; set; }
public string Text { get; set; }
}
}

View File

@ -0,0 +1,27 @@
/*
ChatterBotAPI
Copyright (C) 2011 pierredavidbelanger@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Services.CleverBotApi
{
public enum ChatterBotType
{
CLEVERBOT,
JABBERWACKY,
PANDORABOTS
}
}

View File

@ -0,0 +1,116 @@
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
/*
ChatterBotAPI
Copyright (C) 2011 pierredavidbelanger@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Services.CleverBotApi
{
internal class Cleverbot : ChatterBot
{
private readonly int endIndex;
private readonly string baseUrl;
private readonly string url;
public Cleverbot(string baseUrl, string url, int endIndex)
{
this.baseUrl = baseUrl;
this.url = url;
this.endIndex = endIndex;
}
public ChatterBotSession CreateSession()
{
return new CleverbotSession(baseUrl, url, endIndex);
}
}
internal class CleverbotSession : ChatterBotSession
{
private readonly int endIndex;
private readonly string url;
private readonly IDictionary<string, string> vars;
private readonly CookieCollection cookies;
public CleverbotSession(string baseUrl, string url, int endIndex)
{
this.url = url;
this.endIndex = endIndex;
vars = new Dictionary<string, string>();
//vars["start"] = "y";
vars["stimulus"] = "";
vars["islearning"] = "1";
vars["icognoid"] = "wsf";
//vars["fno"] = "0";
//vars["sub"] = "Say";
//vars["cleanslate"] = "false";
cookies = Utils.GetCookies(baseUrl);
}
public async Task<ChatterBotThought> Think(ChatterBotThought thought)
{
vars["stimulus"] = thought.Text;
var formData = Utils.ParametersToWWWFormURLEncoded(vars);
var formDataToDigest = formData.Substring(9, endIndex);
var formDataDigest = Utils.MD5(formDataToDigest);
vars["icognocheck"] = formDataDigest;
var response = await Utils.Post(url, vars, cookies).ConfigureAwait(false);
var responseValues = response.Split('\r');
//vars[""] = Utils.StringAtIndex(responseValues, 0); ??
vars["sessionid"] = Utils.StringAtIndex(responseValues, 1);
vars["logurl"] = Utils.StringAtIndex(responseValues, 2);
vars["vText8"] = Utils.StringAtIndex(responseValues, 3);
vars["vText7"] = Utils.StringAtIndex(responseValues, 4);
vars["vText6"] = Utils.StringAtIndex(responseValues, 5);
vars["vText5"] = Utils.StringAtIndex(responseValues, 6);
vars["vText4"] = Utils.StringAtIndex(responseValues, 7);
vars["vText3"] = Utils.StringAtIndex(responseValues, 8);
vars["vText2"] = Utils.StringAtIndex(responseValues, 9);
vars["prevref"] = Utils.StringAtIndex(responseValues, 10);
//vars[""] = Utils.StringAtIndex(responseValues, 11); ??
// vars["emotionalhistory"] = Utils.StringAtIndex(responseValues, 12);
// vars["ttsLocMP3"] = Utils.StringAtIndex(responseValues, 13);
// vars["ttsLocTXT"] = Utils.StringAtIndex(responseValues, 14);
// vars["ttsLocTXT3"] = Utils.StringAtIndex(responseValues, 15);
// vars["ttsText"] = Utils.StringAtIndex(responseValues, 16);
// vars["lineRef"] = Utils.StringAtIndex(responseValues, 17);
// vars["lineURL"] = Utils.StringAtIndex(responseValues, 18);
// vars["linePOST"] = Utils.StringAtIndex(responseValues, 19);
// vars["lineChoices"] = Utils.StringAtIndex(responseValues, 20);
// vars["lineChoicesAbbrev"] = Utils.StringAtIndex(responseValues, 21);
// vars["typingData"] = Utils.StringAtIndex(responseValues, 22);
// vars["divert"] = Utils.StringAtIndex(responseValues, 23);
var responseThought = new ChatterBotThought();
responseThought.Text = Utils.StringAtIndex(responseValues, 0);
return responseThought;
}
public async Task<string> Think(string text)
{
return (await Think(new ChatterBotThought {Text = text}).ConfigureAwait(false)).Text;
}
}
}

View File

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
/*
ChatterBotAPI
Copyright (C) 2011 pierredavidbelanger@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Services.CleverBotApi
{
internal class Pandorabots : ChatterBot
{
private readonly string botid;
public Pandorabots(string botid)
{
this.botid = botid;
}
public ChatterBotSession CreateSession()
{
return new PandorabotsSession(botid);
}
}
internal class PandorabotsSession : ChatterBotSession
{
private readonly IDictionary<string, string> vars;
public PandorabotsSession(string botid)
{
vars = new Dictionary<string, string>();
vars["botid"] = botid;
vars["custid"] = Guid.NewGuid().ToString();
}
public async Task<ChatterBotThought> Think(ChatterBotThought thought)
{
vars["input"] = thought.Text;
var response = await Utils.Post("http://www.pandorabots.com/pandora/talk-xml", vars, null).ConfigureAwait(false);
var responseThought = new ChatterBotThought();
responseThought.Text = Utils.XPathSearch(response, "//result/that/text()");
return responseThought;
}
public async Task<string> Think(string text)
{
return (await Think(new ChatterBotThought {Text = text}).ConfigureAwait(false)).Text;
}
}
}

View File

@ -0,0 +1,148 @@
using NadekoBot.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Xml.XPath;
/*
ChatterBotAPI
Copyright (C) 2011 pierredavidbelanger@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Services.CleverBotApi
{
internal static class Utils
{
public static string ParametersToWWWFormURLEncoded(IDictionary<string, string> parameters)
{
string wwwFormUrlEncoded = null;
foreach (var parameterKey in parameters.Keys)
{
var parameterValue = parameters[parameterKey];
var parameter = string.Format("{0}={1}", System.Uri.EscapeDataString(parameterKey), System.Uri.EscapeDataString(parameterValue));
if (wwwFormUrlEncoded == null)
{
wwwFormUrlEncoded = parameter;
}
else
{
wwwFormUrlEncoded = string.Format("{0}&{1}", wwwFormUrlEncoded, parameter);
}
}
return wwwFormUrlEncoded;
}
public static string MD5(string input)
{
// step 1, calculate MD5 hash from input
var md5 = System.Security.Cryptography.MD5.Create();
var inputBytes = Encoding.ASCII.GetBytes(input);
var hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
var sb = new StringBuilder();
for (var i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
public static CookieCollection GetCookies(string url)
{
CookieContainer container = new CookieContainer();
HttpResponseMessage res;
using (var handler = new HttpClientHandler() { CookieContainer = container })
using (var http = new HttpClient(handler))
{
http.AddFakeHeaders();
http.DefaultRequestHeaders.Add("ContentType", "text/html");
res = http.GetAsync(url).GetAwaiter().GetResult();
}
var response = res.Content.ReadAsStringAsync().GetAwaiter().GetResult();
return container.GetCookies(res.RequestMessage.RequestUri);
}
public static async Task<string> Post(string url, IDictionary<string, string> parameters, CookieCollection cookies)
{
var postData = ParametersToWWWFormURLEncoded(parameters);
var postDataBytes = Encoding.ASCII.GetBytes(postData);
var request = (HttpWebRequest)WebRequest.Create(url);
if (cookies != null)
{
var container = new CookieContainer();
container.Add(new Uri(url), cookies);
request.CookieContainer = container;
}
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
using (var outputStream = await request.GetRequestStreamAsync())
{
outputStream.Write(postDataBytes, 0, postDataBytes.Length);
outputStream.Flush();
var response = (HttpWebResponse)await request.GetResponseAsync();
using (var responseStreamReader = new StreamReader(response.GetResponseStream()))
{
return responseStreamReader.ReadToEnd().Trim();
}
}
//HttpClientHandler handler;
//var uri = new Uri(url);
//if (cookies == null)
// handler = new HttpClientHandler();
//else
//{
// var cookieContainer = new CookieContainer();
// cookieContainer.Add(uri, cookies);
// handler = new HttpClientHandler() { CookieContainer = cookieContainer };
//}
//using (handler)
//using (var http = new HttpClient(handler))
//{
// var res = await http.PostAsync(url, new FormUrlEncodedContent(parameters)).ConfigureAwait(false);
// return await res.Content.ReadAsStringAsync().ConfigureAwait(false);
//}
}
public static string XPathSearch(string input, string expression)
{
var document = new XPathDocument(new MemoryStream(Encoding.ASCII.GetBytes(input)));
var navigator = document.CreateNavigator();
return navigator.SelectSingleNode(expression).Value.Trim();
}
public static string StringAtIndex(string[] strings, int index)
{
if (index >= strings.Length) return "";
return strings[index];
}
}
}

View File

@ -18,6 +18,8 @@ using static NadekoBot.Modules.Permissions.Permissions;
using System.Collections.Concurrent;
using NadekoBot.Modules.Help;
using static NadekoBot.Modules.Administration.Administration;
using NadekoBot.Modules.CustomReactions;
using NadekoBot.Modules.Games;
namespace NadekoBot.Services
{
@ -110,16 +112,37 @@ namespace NadekoBot.Services
_log.Warn("I do not have permission to filter words in channel with id " + usrMsg.Channel.Id, ex);
}
}
BlacklistItem blacklistedItem;
if ((blacklistedItem = Permissions.BlacklistCommands.BlacklistedItems.FirstOrDefault(bi =>
(bi.Type == BlacklistItem.BlacklistType.Server && bi.ItemId == guild?.Id) ||
(bi.Type == BlacklistItem.BlacklistType.Channel && bi.ItemId == msg.Channel.Id) ||
(bi.Type == BlacklistItem.BlacklistType.User && bi.ItemId == usrMsg.Author.Id))) != null)
{
return;
}
}
BlacklistItem blacklistedItem;
if ((blacklistedItem = Permissions.BlacklistCommands.BlacklistedItems.FirstOrDefault(bi =>
(bi.Type == BlacklistItem.BlacklistType.Server && bi.ItemId == guild?.Id) ||
(bi.Type == BlacklistItem.BlacklistType.Channel && bi.ItemId == msg.Channel.Id) ||
(bi.Type == BlacklistItem.BlacklistType.User && bi.ItemId == usrMsg.Author.Id))) != null)
{
return;
}
try
{
var cleverbotExecuted = await Games.CleverBotCommands.TryAsk(usrMsg);
if (cleverbotExecuted)
return;
}
catch (Exception ex) { _log.Warn(ex, "Error in cleverbot"); }
try
{
// maybe this message is a custom reaction
var crExecuted = await CustomReactions.TryExecuteCustomReaction(usrMsg).ConfigureAwait(false);
//if it was, don't execute the command
if (crExecuted)
return;
}
catch { }
var throwaway = Task.Run(async () =>
{
var sw = new Stopwatch();

View File

@ -59,6 +59,7 @@ namespace NadekoBot.Services.Database.Models
public HashSet<FilterChannelId> FilterWordsChannelIds { get; set; } = new HashSet<FilterChannelId>();
public string MuteRoleName { get; set; }
public bool CleverbotEnabled { get; set; }
}
public class FilterChannelId :DbEntity

View File

@ -15,5 +15,6 @@ namespace NadekoBot.Services.Database.Repositories
IEnumerable<GuildConfig> PermissionsForAll();
GuildConfig SetNewRootPermission(ulong guildId, Permission p);
IEnumerable<FollowedStream> GetAllFollowedStreams();
void SetCleverbotEnabled(ulong id, bool cleverbotEnabled);
}
}

View File

@ -11,5 +11,6 @@ namespace NadekoBot.Services.Database.Repositories
{
IEnumerable<Quote> GetAllQuotesByKeyword(ulong guildId, string keyword);
Task<Quote> GetRandomQuoteByKeywordAsync(ulong guildId, string keyword);
IEnumerable<Quote> GetGroup(int skip, int take);
}
}

View File

@ -121,5 +121,15 @@ namespace NadekoBot.Services.Database.Repositories.Impl
data.RootPermission = p;
return data;
}
public void SetCleverbotEnabled(ulong id, bool cleverbotEnabled)
{
var conf = _set.FirstOrDefault(gc => gc.GuildId == id);
if (conf == null)
return;
conf.CleverbotEnabled = cleverbotEnabled;
}
}
}

View File

@ -18,6 +18,9 @@ namespace NadekoBot.Services.Database.Repositories.Impl
public IEnumerable<Quote> GetAllQuotesByKeyword(ulong guildId, string keyword) =>
_set.Where(q => q.GuildId == guildId && q.Keyword == keyword);
public IEnumerable<Quote> GetGroup(int skip, int take) =>
_set.OrderBy(q => q.Keyword).Skip(skip).Take(take).ToList();
public Task<Quote> GetRandomQuoteByKeywordAsync(ulong guildId, string keyword)
{
var rng = new NadekoRandom();

View File

@ -19,18 +19,19 @@ namespace NadekoBot.Services
static DbHandler() { }
private DbHandler() {
switch (NadekoBot.Credentials.Db.Type.ToUpperInvariant())
{
case "SQLITE":
dbType = typeof(NadekoSqliteContext);
break;
//case "SQLSERVER":
// dbType = typeof(NadekoSqlServerContext);
// break;
default:
break;
dbType = typeof(NadekoSqliteContext);
//switch (NadekoBot.Credentials.Db.Type.ToUpperInvariant())
//{
// case "SQLITE":
// dbType = typeof(NadekoSqliteContext);
// break;
// //case "SQLSERVER":
// // dbType = typeof(NadekoSqlServerContext);
// // break;
// default:
// break;
}
//}
}
public NadekoContext GetDbContext() =>

View File

@ -91,6 +91,10 @@ namespace NadekoBot.Services.Impl
{
if (string.IsNullOrWhiteSpace(url))
throw new ArgumentNullException(nameof(url));
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.GoogleApiKey))
return url;
try
{
var response = await sh.Url.Insert(new Url { LongUrl = url }).ExecuteAsync();

View File

@ -19,7 +19,7 @@ namespace NadekoBot.Services.Impl
private DateTime started;
private int commandsRan = 0;
public const string BotVersion = "1.0-rc1";
public const string BotVersion = "1.0-rc2";
public string Heap => Math.Round((double)GC.GetTotalMemory(false) / 1.MiB(), 2).ToString();

View File

@ -11533,7 +11533,7 @@
},
{
"Question": "What is the capital of the Canadian province of British Columbia",
"Answer": "victor1a"
"Answer": "victoria"
},
{
"Question": "What is the capital of the US state of Delaware",

View File

@ -7,7 +7,7 @@
"emitEntryPoint": true,
"allowUnsafe": true,
"compile": {
"exclude": [ "data" ]
"exclude": [ "data", "credentials.json", "credentials_example.json" ]
},
"copyToOutput": {
"include": [ "data" ],
@ -41,7 +41,8 @@
},
"Discord.Net": {
"target": "project"
}
},
"System.Xml.XPath": "4.0.1"
},
"tools": {
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"