commit
6bf17e49b2
1
.gitignore
vendored
1
.gitignore
vendored
@ -41,3 +41,4 @@ NadekoBot.sln.iml
|
||||
.idea/workspace.xml
|
||||
.idea/vcs.xml
|
||||
.idea/modules.xml
|
||||
NadekoBot/bin/Debug/data/config_xnaas.json
|
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -1,3 +1,3 @@
|
||||
[submodule "discord.net"]
|
||||
path = discord.net
|
||||
url = git://github.com/rogueexception/discord.net.git
|
||||
url = git://github.com/kwoth/discord.net.git
|
||||
|
@ -36,8 +36,11 @@ ________________________________________________________________________________
|
||||
###### Setting up `ffmpeg` with installer:
|
||||
1) Google Account
|
||||
2) Soundcloud Account (if you want soundcloud support)
|
||||
|
||||
3) Download installer here: http://luxcaeli.de/owncloud/s/fIxSgh4Nde3Td6e/download
|
||||
|
||||
4) Run the installer
|
||||
|
||||
5) Follow these steps on how to setup API keys:
|
||||
- Go to https://console.developers.google.com and log in.
|
||||
- Create a new project (name does not matter). Once the project is created, go into "Enable and manage APIs."
|
||||
|
@ -53,6 +53,15 @@ Note if the command is not be initiated, hit **Enter**
|
||||
<pre><code class="language-bash">echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | sudo tee -a /etc/apt/sources.list.d/mono-xamarin.list
|
||||
</code></pre>
|
||||
|
||||
**2.6)**
|
||||
*ONLY CentOS 7, Fedora 19 (and later)*
|
||||
<pre><code class="language-bash">yum install yum-util
|
||||
</code></pre>
|
||||
<pre><code class="language-bash">rpm --import "http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF"
|
||||
</code></pre>
|
||||
<pre><code class="language-bash">yum-config-manager --add-repo http://download.mono-project.com/repo/centos/
|
||||
</code></pre>
|
||||
|
||||
**3)**
|
||||
<pre><code class="language-bash">apt-get install mono-devel
|
||||
</code></pre>
|
||||
@ -68,6 +77,18 @@ Note if the command is not be initiated, hit **Enter**
|
||||
<pre><code class="language-bash">sudo apt-get install libopus-dev
|
||||
</code></pre>
|
||||
|
||||
**In case you are having issues with Mono where you get a random string and the bot won't run, do this:**
|
||||
|
||||
<pre><code class="language-bash">sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
|
||||
</code></pre>
|
||||
<pre><code class="language-bash">echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
|
||||
</code></pre>
|
||||
<pre><code class="language-bash">apt-get install ca-certificates-mono
|
||||
</code></pre>
|
||||
<pre><code class="language-bash">mozroots --import --sync
|
||||
</code></pre>
|
||||
|
||||
|
||||
######FFMPEG
|
||||
|
||||
**6)**
|
||||
@ -87,6 +108,20 @@ Note if the command is not be initiated, hit **Enter**
|
||||
|
||||
*Before executing* `sudo apt-get install ffmpeg`
|
||||
|
||||
*If you are running Debian 8 Jessie, please, follow these steps:*
|
||||
|
||||
`wget http://luxcaeli.de/installer.sh && sudo bash installer.sh` (Thanks to Eleria<3)
|
||||
|
||||
In case you are not able to install it with installer ^up there, follow these steps:
|
||||
|
||||
`sudo apt-get update`
|
||||
|
||||
`echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/debian-backports.list`
|
||||
|
||||
`sudo apt-get update`
|
||||
|
||||
`sudo apt-get install ffmpeg -y`
|
||||
|
||||
######Uncomplicated Firewall UFW
|
||||
|
||||
**7)**
|
||||
@ -121,12 +156,10 @@ Note if the command is not be initiated, hit **Enter**
|
||||
|
||||
######NOW WE NEED TO IMPORT SOME DISCORD CERTS
|
||||
**13)**
|
||||
<pre><code class="language-bash">mozroots --import --ask-remove --machine
|
||||
</code></pre>
|
||||
`certmgr -ssl https://discordapp.com`
|
||||
|
||||
**14)**
|
||||
<pre><code class="language-bash">certmgr --ssl https://gateway.discord.gg
|
||||
</code></pre>
|
||||
`certmgr --ssl https://gateway.discord.gg`
|
||||
|
||||
Type `yes` and hit Enter **(three times - as it will ask for three times)**
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NadekoBot", "NadekoBot\NadekoBot.csproj", "{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}"
|
||||
EndProject
|
||||
@ -13,70 +13,104 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Modules", "disc
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Net.Commands", "discord.net\src\Discord.Net.Commands.Net45\Discord.Net.Commands.csproj", "{1B5603B4-6F8F-4289-B945-7BAAE523D740}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{45B2545D-C612-4919-B34C-D65EA1371C51}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
discord.net\src\Discord.Net.Shared\Discord.Net.Shared.projitems*{7bfef748-b934-4621-9b11-6302e3a9f6b3}*SharedItemsImports = 4
|
||||
discord.net\src\Discord.Net.Shared\Discord.Net.Shared.projitems*{1b5603b4-6f8f-4289-b945-7baae523d740}*SharedItemsImports = 4
|
||||
discord.net\src\Discord.Net.Shared\Discord.Net.Shared.projitems*{3091164f-66ae-4543-a63d-167c1116241d}*SharedItemsImports = 4
|
||||
discord.net\src\Discord.Net.Shared\Discord.Net.Shared.projitems*{7bfef748-b934-4621-9b11-6302e3a9f6b3}*SharedItemsImports = 4
|
||||
discord.net\src\Discord.Net.Shared\Discord.Net.Shared.projitems*{8d71a857-879a-4a10-859e-5ff824ed6688}*SharedItemsImports = 4
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
FullDebug|Any CPU = FullDebug|Any CPU
|
||||
FullDebug|x64 = FullDebug|x64
|
||||
NadekoRelease|Any CPU = NadekoRelease|Any CPU
|
||||
NadekoRelease|x64 = NadekoRelease|x64
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Debug|x64.Build.0 = Debug|x64
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.FullDebug|x64.ActiveCfg = Debug|x64
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.FullDebug|x64.Build.0 = Debug|x64
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.NadekoRelease|Any CPU.ActiveCfg = NadekoRelease|Any CPU
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.NadekoRelease|Any CPU.Build.0 = NadekoRelease|Any CPU
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.NadekoRelease|x64.ActiveCfg = NadekoRelease|x64
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.NadekoRelease|x64.Build.0 = NadekoRelease|x64
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Release|x64.ActiveCfg = Release|x64
|
||||
{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}.Release|x64.Build.0 = Release|x64
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Debug|x64.Build.0 = Debug|x64
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.FullDebug|x64.ActiveCfg = Debug|x64
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.FullDebug|x64.Build.0 = Debug|x64
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.NadekoRelease|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.NadekoRelease|Any CPU.Build.0 = Release|Any CPU
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.NadekoRelease|x64.ActiveCfg = Release|x64
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.NadekoRelease|x64.Build.0 = Release|x64
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Release|x64.ActiveCfg = Release|x64
|
||||
{7BFEF748-B934-4621-9B11-6302E3A9F6B3}.Release|x64.Build.0 = Release|x64
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.Debug|x64.Build.0 = Debug|x64
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.FullDebug|x64.ActiveCfg = Debug|x64
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.FullDebug|x64.Build.0 = Debug|x64
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.NadekoRelease|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.NadekoRelease|Any CPU.Build.0 = Release|Any CPU
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.NadekoRelease|x64.ActiveCfg = Release|x64
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.NadekoRelease|x64.Build.0 = Release|x64
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.Release|x64.ActiveCfg = Release|x64
|
||||
{8D71A857-879A-4A10-859E-5FF824ED6688}.Release|x64.Build.0 = Release|x64
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.Debug|x64.Build.0 = Debug|x64
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.FullDebug|x64.ActiveCfg = Debug|x64
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.FullDebug|x64.Build.0 = Debug|x64
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.NadekoRelease|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.NadekoRelease|Any CPU.Build.0 = Release|Any CPU
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.NadekoRelease|x64.ActiveCfg = Release|x64
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.NadekoRelease|x64.Build.0 = Release|x64
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.Release|x64.ActiveCfg = Release|x64
|
||||
{3091164F-66AE-4543-A63D-167C1116241D}.Release|x64.Build.0 = Release|x64
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Debug|x64.Build.0 = Debug|x64
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.FullDebug|x64.ActiveCfg = Debug|x64
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.FullDebug|x64.Build.0 = Debug|x64
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.NadekoRelease|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.NadekoRelease|Any CPU.Build.0 = Release|Any CPU
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.NadekoRelease|x64.ActiveCfg = Release|x64
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.NadekoRelease|x64.Build.0 = Release|x64
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{45B2545D-C612-4919-B34C-D65EA1371C51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{45B2545D-C612-4919-B34C-D65EA1371C51}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{45B2545D-C612-4919-B34C-D65EA1371C51}.FullDebug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{45B2545D-C612-4919-B34C-D65EA1371C51}.FullDebug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{45B2545D-C612-4919-B34C-D65EA1371C51}.NadekoRelease|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{45B2545D-C612-4919-B34C-D65EA1371C51}.NadekoRelease|Any CPU.Build.0 = Release|Any CPU
|
||||
{45B2545D-C612-4919-B34C-D65EA1371C51}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{45B2545D-C612-4919-B34C-D65EA1371C51}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|x64.ActiveCfg = Release|x64
|
||||
{1B5603B4-6F8F-4289-B945-7BAAE523D740}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -161,9 +161,7 @@ namespace NadekoBot.Classes
|
||||
using (var conn = new SQLiteConnection(FilePath))
|
||||
{
|
||||
foreach (var o in ocol)
|
||||
{
|
||||
conn.InsertOrReplace(o, typeof(T));
|
||||
}
|
||||
conn.InsertOrReplace(o);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,10 +46,10 @@ namespace NadekoBot.Extensions
|
||||
if (num == 0)
|
||||
return string.Empty;
|
||||
if (num <= 3)
|
||||
return string.Join("", str.Select(c => '.'));
|
||||
return string.Concat(str.Select(c => '.'));
|
||||
if (str.Length < num)
|
||||
return str;
|
||||
return string.Join("", str.Take(num - 3)) + (hideDots ? "" : "...");
|
||||
return string.Concat(str.Take(num - 3)) + (hideDots ? "" : "...");
|
||||
}
|
||||
/// <summary>
|
||||
/// Removes trailing S or ES (if specified) on the given string if the num is 1
|
||||
@ -237,7 +237,7 @@ namespace NadekoBot.Extensions
|
||||
|
||||
public static string Matrix(this string s)
|
||||
=>
|
||||
string.Join("", s.Select(c => c.ToString() + " ̵̢̬̜͉̞̭̖̰͋̉̎ͬ̔̇̌̀".TrimTo(rng.Next(0, 12), true)));
|
||||
string.Concat(s.Select(c => c.ToString() + " ̵̢̬̜͉̞̭̖̰͋̉̎ͬ̔̇̌̀".TrimTo(rng.Next(0, 12), true)));
|
||||
//.Replace("`", "");
|
||||
|
||||
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
|
||||
|
@ -26,7 +26,7 @@ namespace NadekoBot.Classes
|
||||
await u.SendMessage("👑Congratulations!👑\nYou received: " + flows).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static bool RemoveFlowers(Discord.User u, string reason, int amount)
|
||||
public static async Task<bool> RemoveFlowers(Discord.User u, string reason, int amount, bool silent=false, string message="👎`Bot owner has taken {0}{1} from you.`")
|
||||
{
|
||||
if (amount <= 0)
|
||||
return false;
|
||||
@ -42,6 +42,11 @@ namespace NadekoBot.Classes
|
||||
UserId = (long)u.Id,
|
||||
Value = -amount,
|
||||
});
|
||||
|
||||
if (silent)
|
||||
return true;
|
||||
|
||||
await u.SendMessage(string.Format(message,amount,NadekoBot.Config.CurrencySign)).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -145,8 +145,6 @@ namespace NadekoBot.Classes
|
||||
|
||||
public static async Task<string> FindYoutubeUrlByKeywords(string keywords)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Creds.GoogleAPIKey))
|
||||
throw new InvalidCredentialException("Google API Key is missing.");
|
||||
if (string.IsNullOrWhiteSpace(keywords))
|
||||
throw new ArgumentNullException(nameof(keywords), "Query not specified.");
|
||||
if (keywords.Length > 150)
|
||||
@ -158,6 +156,10 @@ namespace NadekoBot.Classes
|
||||
{
|
||||
return $"https://www.youtube.com/watch?v={match.Groups["id"].Value}";
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Creds.GoogleAPIKey))
|
||||
throw new InvalidCredentialException("Google API Key is missing.");
|
||||
|
||||
var response = await GetResponseStringAsync(
|
||||
$"https://www.googleapis.com/youtube/v3/search?" +
|
||||
$"part=snippet&maxResults=1" +
|
||||
@ -357,7 +359,7 @@ namespace NadekoBot.Classes
|
||||
|
||||
using (var streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false)))
|
||||
{
|
||||
var json = "{\"longUrl\":\"" + url + "\"}";
|
||||
var json = "{\"longUrl\":\"" + Uri.EscapeDataString(url) + "\"}";
|
||||
streamWriter.Write(json);
|
||||
}
|
||||
|
||||
@ -382,7 +384,7 @@ namespace NadekoBot.Classes
|
||||
{
|
||||
var i = 0;
|
||||
return "```xl\n" + string.Join("\n", items.GroupBy(item => (i++) / cols)
|
||||
.Select(ig => string.Join("", ig.Select(el => howToPrint(el)))))
|
||||
.Select(ig => string.Concat(ig.Select(el => howToPrint(el)))))
|
||||
+ $"\n```";
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,13 @@ namespace NadekoBot.Classes
|
||||
{
|
||||
configs = JsonConvert
|
||||
.DeserializeObject<ConcurrentDictionary<ulong, ServerSpecificConfig>>(
|
||||
File.ReadAllText(filePath));
|
||||
File.ReadAllText(filePath), new JsonSerializerSettings() {
|
||||
Error = (s,e) => {
|
||||
if (e.ErrorContext.Member.ToString() == "GenerateCurrencyChannels") {
|
||||
e.ErrorContext.Handled = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -94,6 +100,21 @@ namespace NadekoBot.Classes
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
private ObservableCollection<ulong> logserverIgnoreChannels;
|
||||
public ObservableCollection<ulong> LogserverIgnoreChannels {
|
||||
get { return logserverIgnoreChannels; }
|
||||
set {
|
||||
logserverIgnoreChannels = value;
|
||||
if (value != null)
|
||||
logserverIgnoreChannels.CollectionChanged += (s, e) =>
|
||||
{
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("LogPresenceChannel")]
|
||||
private ulong? logPresenceChannel = null;
|
||||
[JsonIgnore]
|
||||
@ -136,6 +157,8 @@ namespace NadekoBot.Classes
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[JsonIgnore]
|
||||
private ulong autoAssignedRole = 0;
|
||||
public ulong AutoAssignedRole {
|
||||
@ -148,8 +171,8 @@ namespace NadekoBot.Classes
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
private ObservableCollection<ulong> generateCurrencyChannels;
|
||||
public ObservableCollection<ulong> GenerateCurrencyChannels {
|
||||
private ObservableConcurrentDictionary<ulong, int> generateCurrencyChannels;
|
||||
public ObservableConcurrentDictionary<ulong, int> GenerateCurrencyChannels {
|
||||
get { return generateCurrencyChannels; }
|
||||
set {
|
||||
generateCurrencyChannels = value;
|
||||
@ -173,6 +196,19 @@ namespace NadekoBot.Classes
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
private bool exclusiveSelfAssignedRoles = false;
|
||||
public bool ExclusiveSelfAssignedRoles
|
||||
{
|
||||
get { return exclusiveSelfAssignedRoles; }
|
||||
set
|
||||
{
|
||||
exclusiveSelfAssignedRoles = value;
|
||||
if (!SpecificConfigurations.Instantiated) return;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[JsonIgnore]
|
||||
private ObservableCollection<StreamNotificationConfig> observingStreams;
|
||||
@ -204,8 +240,9 @@ namespace NadekoBot.Classes
|
||||
{
|
||||
ListOfSelfAssignableRoles = new ObservableCollection<ulong>();
|
||||
ObservingStreams = new ObservableCollection<StreamNotificationConfig>();
|
||||
GenerateCurrencyChannels = new ObservableCollection<ulong>();
|
||||
GenerateCurrencyChannels = new ObservableConcurrentDictionary<ulong, int>();
|
||||
VoiceChannelLog = new ObservableConcurrentDictionary<ulong, ulong>();
|
||||
LogserverIgnoreChannels = new ObservableCollection<ulong>();
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged = delegate { SpecificConfigurations.Default.Save(); };
|
||||
@ -239,7 +276,7 @@ namespace NadekoBot.Classes
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (int)((int)ServerId + Username.Length + (int)Type);
|
||||
return (int)ServerId + Username.Length + (int)Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ namespace NadekoBot.Modules.Administration
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "setrole").Alias(Prefix + "sr")
|
||||
.Description("Sets a role for a given user.\n**Usage**: .sr @User Guest")
|
||||
.Description("Sets a role for a given user. | .sr @User Guest")
|
||||
.Parameter("user_name", ParameterType.Required)
|
||||
.Parameter("role_name", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||
@ -133,7 +133,7 @@ namespace NadekoBot.Modules.Administration
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "removerole").Alias(Prefix + "rr")
|
||||
.Description("Removes a role from a given user.\n**Usage**: .rr @User Admin")
|
||||
.Description("Removes a role from a given user. | .rr @User Admin")
|
||||
.Parameter("user_name", ParameterType.Required)
|
||||
.Parameter("role_name", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||
@ -171,7 +171,7 @@ namespace NadekoBot.Modules.Administration
|
||||
|
||||
cgb.CreateCommand(Prefix + "renamerole")
|
||||
.Alias(Prefix + "renr")
|
||||
.Description($"Renames a role. Role you are renaming must be lower than bot's highest role.\n**Usage**: `{Prefix}renr \"First role\" SecondRole`")
|
||||
.Description($"Renames a role. Role you are renaming must be lower than bot's highest role. | `{Prefix}renr \"First role\" SecondRole`")
|
||||
.Parameter("r1", ParameterType.Required)
|
||||
.Parameter("r2", ParameterType.Required)
|
||||
.AddCheck(new SimpleCheckers.ManageRoles())
|
||||
@ -204,7 +204,7 @@ namespace NadekoBot.Modules.Administration
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "removeallroles").Alias(Prefix + "rar")
|
||||
.Description("Removes all roles from a mentioned user.\n**Usage**: .rar @User")
|
||||
.Description("Removes all roles from a mentioned user. | .rar @User")
|
||||
.Parameter("user_name", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||
.Do(async e =>
|
||||
@ -253,7 +253,7 @@ namespace NadekoBot.Modules.Administration
|
||||
.Parameter("r", ParameterType.Optional)
|
||||
.Parameter("g", ParameterType.Optional)
|
||||
.Parameter("b", ParameterType.Optional)
|
||||
.Description("Set a role's color to the hex or 0-255 rgb color value provided.\n**Usage**: `.color Admin 255 200 100` or `.color Admin ffba55`")
|
||||
.Description("Set a role's color to the hex or 0-255 rgb color value provided. | `.color Admin 255 200 100` or `.color Admin ffba55`")
|
||||
.Do(async e =>
|
||||
{
|
||||
if (!e.User.ServerPermissions.ManageRoles)
|
||||
@ -298,7 +298,7 @@ namespace NadekoBot.Modules.Administration
|
||||
cgb.CreateCommand(Prefix + "ban").Alias(Prefix + "b")
|
||||
.Parameter("user", ParameterType.Required)
|
||||
.Parameter("msg", ParameterType.Unparsed)
|
||||
.Description("Bans a user by id or name with an optional message.\n**Usage**: .b \"@some Guy\" Your behaviour is toxic.")
|
||||
.Description("Bans a user by id or name with an optional message. | .b \"@some Guy\" Your behaviour is toxic.")
|
||||
.Do(async e =>
|
||||
{
|
||||
var msg = e.GetArg("msg");
|
||||
@ -333,7 +333,7 @@ namespace NadekoBot.Modules.Administration
|
||||
cgb.CreateCommand(Prefix + "softban").Alias(Prefix + "sb")
|
||||
.Parameter("user", ParameterType.Required)
|
||||
.Parameter("msg", ParameterType.Unparsed)
|
||||
.Description("Bans and then unbans a user by id or name with an optional message.\n**Usage**: .sb \"@some Guy\" Your behaviour is toxic.")
|
||||
.Description("Bans and then unbans a user by id or name with an optional message. | .sb \"@some Guy\" Your behaviour is toxic.")
|
||||
.Do(async e =>
|
||||
{
|
||||
var msg = e.GetArg("msg");
|
||||
@ -592,7 +592,7 @@ namespace NadekoBot.Modules.Administration
|
||||
|
||||
cgb.CreateCommand(Prefix + "settopic")
|
||||
.Alias(Prefix + "st")
|
||||
.Description($"Sets a topic on the current channel.\n**Usage**: `{Prefix}st My new topic`")
|
||||
.Description($"Sets a topic on the current channel. | `{Prefix}st My new topic`")
|
||||
.AddCheck(SimpleCheckers.ManageChannels())
|
||||
.Parameter("topic", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -628,27 +628,18 @@ namespace NadekoBot.Modules.Administration
|
||||
cgb.CreateCommand(Prefix + "prune")
|
||||
.Alias(Prefix + "clr")
|
||||
.Description(
|
||||
"`.prune` removes all nadeko's messages in the last 100 messages.`.prune X` removes last X messages from the channel (up to 100)`.prune @Someone` removes all Someone's messages in the last 100 messages.`.prune @Someone X` removes last X 'Someone's' messages in the channel.\n**Usage**: `.prune` or `.prune 5` or `.prune @Someone` or `.prune @Someone X`")
|
||||
"`.prune` removes all nadeko's messages in the last 100 messages.`.prune X` removes last X messages from the channel (up to 100)`.prune @Someone` removes all Someone's messages in the last 100 messages.`.prune @Someone X` removes last X 'Someone's' messages in the channel. | `.prune` or `.prune 5` or `.prune @Someone` or `.prune @Someone X`")
|
||||
.Parameter("user_or_num", ParameterType.Optional)
|
||||
.Parameter("num", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
Message[] msgs;
|
||||
if (string.IsNullOrWhiteSpace(e.GetArg("user_or_num"))) // if nothing is set, clear nadeko's messages, no permissions required
|
||||
{
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
var msgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false)).Where(m => m.User.Id == e.Server.CurrentUser.Id);
|
||||
foreach (var m in msgs)
|
||||
{
|
||||
try
|
||||
{
|
||||
await m.Delete().ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
msgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false)).Where(m => m.User.Id == e.Server.CurrentUser.Id).ToArray();
|
||||
if (!msgs.Any())
|
||||
return;
|
||||
await e.Channel.DeleteMessages(msgs).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
if (!e.User.GetPermissions(e.Channel).ManageMessages)
|
||||
@ -665,11 +656,7 @@ namespace NadekoBot.Modules.Administration
|
||||
if (val <= 0)
|
||||
return;
|
||||
val++;
|
||||
foreach (var msg in await e.Channel.DownloadMessages(val).ConfigureAwait(false))
|
||||
{
|
||||
await msg.Delete().ConfigureAwait(false);
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
}
|
||||
await e.Channel.DeleteMessages((await e.Channel.DownloadMessages(val).ConfigureAwait(false)).ToArray()).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
//else if first argument is user
|
||||
@ -679,20 +666,10 @@ namespace NadekoBot.Modules.Administration
|
||||
val = 100;
|
||||
if (!int.TryParse(e.GetArg("num"), out val))
|
||||
val = 100;
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
var msgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false)).Where(m => m.User.Id == usr.Id).Take(val);
|
||||
foreach (var m in msgs)
|
||||
{
|
||||
try
|
||||
{
|
||||
await m.Delete().ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
msgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false)).Where(m => m.User.Id == usr.Id).Take(val).ToArray();
|
||||
if (!msgs.Any())
|
||||
return;
|
||||
await e.Channel.DeleteMessages(msgs).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "die")
|
||||
@ -719,7 +696,7 @@ namespace NadekoBot.Modules.Administration
|
||||
|
||||
cgb.CreateCommand(Prefix + "newavatar")
|
||||
.Alias(Prefix + "setavatar")
|
||||
.Description("Sets a new avatar image for the NadekoBot. Argument is a direct link to an image. **Bot Owner Only!**\n**Usage**: `.setavatar https://i.ytimg.com/vi/WDudkR1eTMM/maxresdefault.jpg`")
|
||||
.Description("Sets a new avatar image for the NadekoBot. Argument is a direct link to an image. **Bot Owner Only!** | `.setavatar https://i.ytimg.com/vi/WDudkR1eTMM/maxresdefault.jpg`")
|
||||
.Parameter("img", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
@ -750,7 +727,7 @@ namespace NadekoBot.Modules.Administration
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "send")
|
||||
.Description("Send a message to someone on a different server through the bot. **Bot Owner Only!**\n**Usage**: `.send serverid|u:user_id Send this to a user!` or `.send serverid|c:channel_id Send this to a channel!`")
|
||||
.Description("Send a message to someone on a different server through the bot. **Bot Owner Only!** | `.send serverid|u:user_id Send this to a user!` or `.send serverid|c:channel_id Send this to a channel!`")
|
||||
.Parameter("ids", ParameterType.Required)
|
||||
.Parameter("msg", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
@ -761,7 +738,7 @@ namespace NadekoBot.Modules.Administration
|
||||
if (string.IsNullOrWhiteSpace(msg))
|
||||
return;
|
||||
|
||||
var ids = e.GetArg("ids").Split('-');
|
||||
var ids = e.GetArg("ids").Split('|');
|
||||
if (ids.Length != 2)
|
||||
return;
|
||||
var sid = ulong.Parse(ids[0]);
|
||||
@ -877,7 +854,7 @@ namespace NadekoBot.Modules.Administration
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "announce")
|
||||
.Description($"Sends a message to all servers' general channel bot is connected to.**Bot Owner Only!**\n**Usage**: {Prefix}announce Useless spam")
|
||||
.Description($"Sends a message to all servers' general channel bot is connected to.**Bot Owner Only!** | {Prefix}announce Useless spam")
|
||||
.Parameter("msg", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
@ -890,21 +867,6 @@ namespace NadekoBot.Modules.Administration
|
||||
await e.Channel.SendMessage(":ok:").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "leave")
|
||||
.Description("Leaves a server with a supplied ID.\n**Usage**: `.leave 493243292839`")
|
||||
.Parameter("num", ParameterType.Required)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
var srvr = NadekoBot.Client.Servers.Where(s => s.Id.ToString() == e.GetArg("num").Trim()).FirstOrDefault();
|
||||
if (srvr == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await srvr.Leave().ConfigureAwait(false);
|
||||
await e.Channel.SendMessage("`Done.`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "savechat")
|
||||
.Description("Saves a number of messages to a text file and sends it to you. **Bot Owner Only** | `.chatsave 150`")
|
||||
.Parameter("cnt", ParameterType.Required)
|
||||
@ -929,7 +891,7 @@ namespace NadekoBot.Modules.Administration
|
||||
lastmsgId = msgs[msgs.Count - 1].Id;
|
||||
cnt -= 100;
|
||||
}
|
||||
await e.User.SendFile($"Chatlog-{e.Server.Name}/#{e.Channel.Name}-{DateTime.Now}.txt", JsonConvert.SerializeObject(new { Messages = msgs.Select(s => s.ToString()) }, Formatting.Indented).ToStream());
|
||||
await e.User.SendFile($"Chatlog-{e.Server.Name}/#{e.Channel.Name}-{DateTime.Now}.txt", JsonConvert.SerializeObject(new { Messages = msgs.Select(s => s.ToString()) }, Formatting.Indented).ToStream()).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -2,6 +2,7 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -22,7 +23,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Prefix + "addcustreact")
|
||||
.Alias(Prefix + "acr")
|
||||
.Description($"Add a custom reaction. Guide here: <https://github.com/Kwoth/NadekoBot/wiki/Custom-Reactions> **Bot Owner Only!** \n**Usage**: {Prefix}acr \"hello\" I love saying hello to %user%")
|
||||
.Description($"Add a custom reaction. Guide here: <https://github.com/Kwoth/NadekoBot/wiki/Custom-Reactions> **Bot Owner Only!** | {Prefix}acr \"hello\" I love saying hello to %user%")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Parameter("name", ParameterType.Required)
|
||||
.Parameter("message", ParameterType.Unparsed)
|
||||
@ -46,16 +47,29 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Prefix + "listcustreact")
|
||||
.Alias(Prefix + "lcr")
|
||||
.Description($"Lists all current custom reactions (paginated with 30 commands per page).\n**Usage**:{Prefix}lcr 1")
|
||||
.Description($"Lists custom reactions (paginated with 30 commands per page). Use 'all' instead of page number to get all custom reactions DM-ed to you. |{Prefix}lcr 1")
|
||||
.Parameter("num", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
var numStr = e.GetArg("num");
|
||||
|
||||
if (numStr.ToUpperInvariant() == "ALL")
|
||||
{
|
||||
var fullstr = String.Join("\n", NadekoBot.Config.CustomReactions.Select(kvp => kvp.Key));
|
||||
do
|
||||
{
|
||||
var str = string.Concat(fullstr.Take(1900));
|
||||
fullstr = new string(fullstr.Skip(1900).ToArray());
|
||||
await e.User.SendMessage("```xl\n" + str + "```");
|
||||
} while (fullstr.Length != 0);
|
||||
return;
|
||||
}
|
||||
int num;
|
||||
if (!int.TryParse(e.GetArg("num"), out num) || num <= 0) num = 1;
|
||||
if (!int.TryParse(numStr, out num) || num <= 0) num = 1;
|
||||
var cmds = GetCustomsOnPage(num - 1);
|
||||
if (!cmds.Any())
|
||||
{
|
||||
await e.Channel.SendMessage("");
|
||||
await e.Channel.SendMessage("`There are no custom reactions.`");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -66,7 +80,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Prefix + "showcustreact")
|
||||
.Alias(Prefix + "scr")
|
||||
.Description($"Shows all possible responses from a single custom reaction.\n**Usage**:{Prefix}scr %mention% bb")
|
||||
.Description($"Shows all possible responses from a single custom reaction. |{Prefix}scr %mention% bb")
|
||||
.Parameter("name", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -85,7 +99,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
int i = 1;
|
||||
foreach (var reaction in items)
|
||||
{
|
||||
message.AppendLine($"[{i++}] " + Format.Code(reaction));
|
||||
message.AppendLine($"[{i++}] " + Format.Code(Format.Escape(reaction)));
|
||||
}
|
||||
await e.Channel.SendMessage(message.ToString());
|
||||
});
|
||||
|
@ -51,8 +51,9 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
try
|
||||
{
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null)
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
var chId = config.LogServerChannel;
|
||||
if (chId == null || config.LogserverIgnoreChannels.Contains(e.After.Id))
|
||||
return;
|
||||
Channel ch;
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
@ -72,8 +73,9 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
try
|
||||
{
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null)
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
var chId = config.LogServerChannel;
|
||||
if (chId == null || config.LogserverIgnoreChannels.Contains(e.Channel.Id))
|
||||
return;
|
||||
Channel ch;
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
@ -87,8 +89,9 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
try
|
||||
{
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null)
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
var chId = config.LogServerChannel;
|
||||
if (chId == null || config.LogserverIgnoreChannels.Contains(e.Channel.Id))
|
||||
return;
|
||||
Channel ch;
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
@ -164,8 +167,9 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
if (e.Server == null || e.Channel.IsPrivate || e.User.Id == NadekoBot.Client.CurrentUser.Id)
|
||||
return;
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null || e.Channel.Id == chId)
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
var chId = config.LogServerChannel;
|
||||
if (chId == null || e.Channel.Id == chId || config.LogserverIgnoreChannels.Contains(e.Channel.Id))
|
||||
return;
|
||||
Channel ch;
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
@ -192,8 +196,9 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
if (e.Server == null || e.Channel.IsPrivate || e.User?.Id == NadekoBot.Client.CurrentUser.Id)
|
||||
return;
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null || e.Channel.Id == chId)
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
var chId = config.LogServerChannel;
|
||||
if (chId == null || e.Channel.Id == chId || config.LogserverIgnoreChannels.Contains(e.Channel.Id))
|
||||
return;
|
||||
Channel ch;
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
@ -219,8 +224,9 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
if (e.Server == null || e.Channel.IsPrivate || e.User?.Id == NadekoBot.Client.CurrentUser.Id)
|
||||
return;
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null || e.Channel.Id == chId)
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
var chId = config.LogServerChannel;
|
||||
if (chId == null || e.Channel.Id == chId || config.LogserverIgnoreChannels.Contains(e.Channel.Id))
|
||||
return;
|
||||
Channel ch;
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
@ -370,6 +376,25 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
await e.Channel.SendMessage($"❗**NO LONGER LOGGING IN {ch.Mention} CHANNEL**❗").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
|
||||
cgb.CreateCommand(Prefix + "logignore")
|
||||
.Description($"Toggles whether the {Prefix}logserver command ignores this channel. Useful if you have hidden admin channel and public log channel.")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
{
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
if (config.LogserverIgnoreChannels.Remove(e.Channel.Id))
|
||||
{
|
||||
await e.Channel.SendMessage($"`{Prefix}logserver will stop ignoring this channel.`");
|
||||
}
|
||||
else
|
||||
{
|
||||
config.LogserverIgnoreChannels.Add(e.Channel.Id);
|
||||
await e.Channel.SendMessage($"`{Prefix}logserver will ignore this channel.`");
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "userpresence")
|
||||
.Description("Starts logging to this channel when someone from the server goes online/offline/idle.")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
|
@ -73,7 +73,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "repeat")
|
||||
.Description("Repeat a message every X minutes. If no parameters are specified, " +
|
||||
"repeat is disabled. Requires manage messages.\n**Usage**:`.repeat 5 Hello there`")
|
||||
"repeat is disabled. Requires manage messages. |`.repeat 5 Hello there`")
|
||||
.Parameter("minutes", ParameterType.Optional)
|
||||
.Parameter("msg", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.ManageMessages())
|
||||
|
@ -1,6 +1,8 @@
|
||||
using Discord.Commands;
|
||||
using Discord.Net;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -15,7 +17,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "asar")
|
||||
.Description("Adds a role, or list of roles separated by whitespace" +
|
||||
"(use quotations for multiword roles) to the list of self-assignable roles.\n**Usage**: .asar Gamer")
|
||||
"(use quotations for multiword roles) to the list of self-assignable roles. | .asar Gamer")
|
||||
.Parameter("roles", ParameterType.Multiple)
|
||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||
.Do(async e =>
|
||||
@ -74,7 +76,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
var msg = new StringBuilder($"There are `{config.ListOfSelfAssignableRoles.Count}` self assignable roles:\n");
|
||||
var toRemove = new HashSet<ulong>();
|
||||
foreach (var roleId in config.ListOfSelfAssignableRoles)
|
||||
foreach (var roleId in config.ListOfSelfAssignableRoles.OrderBy(r=>r.ToString()))
|
||||
{
|
||||
var role = e.Server.GetRole(roleId);
|
||||
if (role == null)
|
||||
@ -94,10 +96,23 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
await e.Channel.SendMessage(msg.ToString()).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "togglexclsar").Alias(Module.Prefix +"tesar")
|
||||
.Description("toggle whether the self-assigned roles should be exclusive")
|
||||
.AddCheck(SimpleCheckers.CanManageRoles)
|
||||
.Do(async e =>
|
||||
{
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
config.ExclusiveSelfAssignedRoles = !config.ExclusiveSelfAssignedRoles;
|
||||
string exl = config.ExclusiveSelfAssignedRoles ? "exclusive" : "not exclusive";
|
||||
await e.Channel.SendMessage("Self assigned roles are now " + exl);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "iam")
|
||||
.Description("Adds a role to you that you choose. " +
|
||||
"Role must be on a list of self-assignable roles." +
|
||||
"\n**Usage**: .iam Gamer")
|
||||
" | .iam Gamer")
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -121,17 +136,26 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
await e.Channel.SendMessage($":anger:You already have {role.Name} role.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var sameRoles = e.User.Roles.Where(r => config.ListOfSelfAssignableRoles.Contains(r.Id));
|
||||
if (config.ExclusiveSelfAssignedRoles && sameRoles.Any())
|
||||
{
|
||||
await e.Channel.SendMessage($":anger:You already have {sameRoles.FirstOrDefault().Name} role.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
await e.User.AddRoles(role).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
catch(HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.InternalServerError)
|
||||
{
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
await e.Channel.SendMessage($":anger:`I am unable to add that role to you. I can't add roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false);
|
||||
}
|
||||
var msg = await e.Channel.SendMessage($":ok:You now have {role.Name} role.").ConfigureAwait(false);
|
||||
await Task.Delay(3000);
|
||||
await msg.Delete();
|
||||
await Task.Delay(3000).ConfigureAwait(false);
|
||||
await msg.Delete().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await e.Message.Delete().ConfigureAwait(false);
|
||||
@ -143,7 +167,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
.Alias(Module.Prefix + "iamn")
|
||||
.Description("Removes a role to you that you choose. " +
|
||||
"Role must be on a list of self-assignable roles." +
|
||||
"\n**Usage**: .iamn Gamer")
|
||||
" | .iamn Gamer")
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -168,7 +192,14 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
return;
|
||||
}
|
||||
await e.User.RemoveRoles(role).ConfigureAwait(false);
|
||||
await e.Channel.SendMessage($":ok:Successfuly removed {role.Name} role from you.").ConfigureAwait(false);
|
||||
var msg = await e.Channel.SendMessage($":ok:Successfuly removed {role.Name} role from you.").ConfigureAwait(false);
|
||||
await Task.Delay(3000).ConfigureAwait(false);
|
||||
await msg.Delete().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await e.Message.Delete().ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "leave")
|
||||
.Description("Makes Nadeko leave the server. Either name or id required.\n**Usage**: `.leave 123123123331`")
|
||||
.Description("Makes Nadeko leave the server. Either name or id required. | `.leave 123123123331`")
|
||||
.Parameter("arg", ParameterType.Required)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
|
@ -245,7 +245,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "greetmsg")
|
||||
.Description("Sets a new join announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current greet message.\n**Usage**: .greetmsg Welcome to the server, %user%.")
|
||||
.Description("Sets a new join announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current greet message. | .greetmsg Welcome to the server, %user%.")
|
||||
.Parameter("msg", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -278,7 +278,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "byemsg")
|
||||
.Description("Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message.\n**Usage**: .byemsg %user% has left the server.")
|
||||
.Description("Sets a new leave announcement message. Type %user% if you want to mention the new member. Using it with no message will show the current bye message. | .byemsg %user% has left the server.")
|
||||
.Parameter("msg", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "voicenotif")
|
||||
.Description("Enables notifications on who joined/left the voice channel.\n**Usage**:.voicenotif Karaoke club")
|
||||
.Description("Enables notifications on who joined/left the voice channel. |.voicenotif Karaoke club")
|
||||
.Parameter("voice_name", ParameterType.Unparsed)
|
||||
.Do(DoFunc());
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
sendMessages: PermValue.Deny)).ConfigureAwait(false);
|
||||
}
|
||||
var afterVch = e.After.VoiceChannel;
|
||||
if (afterVch != null)
|
||||
if (afterVch != null && e.Server.AFKChannel != afterVch)
|
||||
{
|
||||
var textChannel = e.Server.FindChannels(
|
||||
GetChannelName(afterVch.Name),
|
||||
|
@ -7,6 +7,10 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Classes.ClashOfClans
|
||||
{
|
||||
public enum DestroyStars
|
||||
{
|
||||
One, Two, Three
|
||||
}
|
||||
internal class Caller
|
||||
{
|
||||
public string CallUser { get; }
|
||||
@ -15,6 +19,9 @@ namespace NadekoBot.Classes.ClashOfClans
|
||||
|
||||
public bool BaseDestroyed { get; internal set; }
|
||||
|
||||
public int Stars { get; set; } = 3;
|
||||
|
||||
|
||||
public Caller(string callUser, DateTime timeAdded, bool baseDestroyed)
|
||||
{
|
||||
CallUser = callUser;
|
||||
@ -148,7 +155,7 @@ namespace NadekoBot.Classes.ClashOfClans
|
||||
{
|
||||
if (bases[i].BaseDestroyed)
|
||||
{
|
||||
sb.AppendLine($"`{i + 1}.` ✅ `{bases[i].CallUser}` ⭐ ⭐ ⭐");
|
||||
sb.AppendLine($"`{i + 1}.` ✅ `{bases[i].CallUser}` {new string('⭐', bases[i].Stars)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -161,13 +168,14 @@ namespace NadekoBot.Classes.ClashOfClans
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
internal int FinishClaim(string user)
|
||||
internal int FinishClaim(string user, int stars = 3)
|
||||
{
|
||||
user = user.Trim();
|
||||
for (var i = 0; i < bases.Length; i++)
|
||||
{
|
||||
if (bases[i]?.BaseDestroyed != false || bases[i]?.CallUser != user) continue;
|
||||
bases[i].BaseDestroyed = true;
|
||||
bases[i].Stars = stars;
|
||||
return i;
|
||||
}
|
||||
throw new InvalidOperationException($"@{user} You are either not participating in that war, or you already destroyed a base.");
|
||||
|
@ -5,6 +5,8 @@ using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
|
||||
namespace NadekoBot.Modules.ClashOfClans
|
||||
{
|
||||
@ -21,10 +23,11 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
manager.CreateCommands("", cgb =>
|
||||
{
|
||||
|
||||
cgb.AddCheck(PermissionChecker.Instance);
|
||||
|
||||
cgb.CreateCommand(Prefix + "createwar")
|
||||
.Alias(Prefix + "cw")
|
||||
.Description(
|
||||
$"Creates a new war by specifying a size (>10 and multiple of 5) and enemy clan name.\n**Usage**:{Prefix}cw 15 The Enemy Clan")
|
||||
.Description($"Creates a new war by specifying a size (>10 and multiple of 5) and enemy clan name. |{Prefix}cw 15 The Enemy Clan")
|
||||
.Parameter("size")
|
||||
.Parameter("enemy_clan", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -102,7 +105,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
|
||||
cgb.CreateCommand(Prefix + "listwar")
|
||||
.Alias(Prefix + "lw")
|
||||
.Description($"Shows the active war claims by a number. Shows all wars in a short way if no number is specified.\n**Usage**: {Prefix}lw [war_number] or {Prefix}lw")
|
||||
.Description($"Shows the active war claims by a number. Shows all wars in a short way if no number is specified. | {Prefix}lw [war_number] or {Prefix}lw")
|
||||
.Parameter("number", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -143,7 +146,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
cgb.CreateCommand(Prefix + "claim")
|
||||
.Alias(Prefix + "call")
|
||||
.Alias(Prefix + "c")
|
||||
.Description($"Claims a certain base from a certain war. You can supply a name in the third optional argument to claim in someone else's place. \n**Usage**: {Prefix}call [war_number] [base_number] [optional_other_name]")
|
||||
.Description($"Claims a certain base from a certain war. You can supply a name in the third optional argument to claim in someone else's place. | {Prefix}call [war_number] [base_number] [optional_other_name]")
|
||||
.Parameter("number")
|
||||
.Parameter("baseNumber")
|
||||
.Parameter("other_name", ParameterType.Unparsed)
|
||||
@ -179,38 +182,31 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
|
||||
cgb.CreateCommand(Prefix + "claimfinish")
|
||||
.Alias(Prefix + "cf")
|
||||
.Description($"Finish your claim if you destroyed a base. Optional second argument finishes for someone else.\n**Usage**: {Prefix}cf [war_number] [optional_other_name]")
|
||||
.Alias(Prefix + "cf3")
|
||||
.Alias(Prefix + "claimfinish3")
|
||||
.Description($"Finish your claim with 3 stars if you destroyed a base. Optional second argument finishes for someone else. | {Prefix}cf [war_number] [optional_other_name]")
|
||||
.Parameter("number", ParameterType.Required)
|
||||
.Parameter("other_name", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var warInfo = GetInfo(e);
|
||||
if (warInfo == null || warInfo.Item1.Count == 0)
|
||||
{
|
||||
await e.Channel.SendMessage("💢🔰 **That war does not exist.**").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var usr =
|
||||
string.IsNullOrWhiteSpace(e.GetArg("other_name")) ?
|
||||
e.User.Name :
|
||||
e.GetArg("other_name");
|
||||
.Do(e => FinishClaim(e));
|
||||
|
||||
var war = warInfo.Item1[warInfo.Item2];
|
||||
try
|
||||
{
|
||||
var baseNum = war.FinishClaim(usr);
|
||||
await e.Channel.SendMessage($"❗🔰{e.User.Mention} **DESTROYED** a base #{baseNum + 1} in a war against {war.ShortPrint()}").ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await e.Channel.SendMessage($"💢🔰 {ex.Message}").ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
cgb.CreateCommand(Prefix + "claimfinish2")
|
||||
.Alias(Prefix + "cf2")
|
||||
.Description($"Finish your claim with 2 stars if you destroyed a base. Optional second argument finishes for someone else. | {Prefix}cf [war_number] [optional_other_name]")
|
||||
.Parameter("number", ParameterType.Required)
|
||||
.Parameter("other_name", ParameterType.Unparsed)
|
||||
.Do(e => FinishClaim(e, 2));
|
||||
|
||||
cgb.CreateCommand(Prefix + "claimfinish1")
|
||||
.Alias(Prefix + "cf1")
|
||||
.Description($"Finish your claim with 1 stars if you destroyed a base. Optional second argument finishes for someone else. | {Prefix}cf [war_number] [optional_other_name]")
|
||||
.Parameter("number", ParameterType.Required)
|
||||
.Parameter("other_name", ParameterType.Unparsed)
|
||||
.Do(e => FinishClaim(e, 1));
|
||||
|
||||
cgb.CreateCommand(Prefix + "unclaim")
|
||||
.Alias(Prefix + "uncall")
|
||||
.Alias(Prefix + "uc")
|
||||
.Description($"Removes your claim from a certain war. Optional second argument denotes a person in whos place to unclaim\n**Usage**: {Prefix}uc [war_number] [optional_other_name]")
|
||||
.Description($"Removes your claim from a certain war. Optional second argument denotes a person in whos place to unclaim | {Prefix}uc [war_number] [optional_other_name]")
|
||||
.Parameter("number", ParameterType.Required)
|
||||
.Parameter("other_name", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -239,7 +235,7 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
|
||||
cgb.CreateCommand(Prefix + "endwar")
|
||||
.Alias(Prefix + "ew")
|
||||
.Description($"Ends the war with a given index.\n**Usage**:{Prefix}ew [war_number]")
|
||||
.Description($"Ends the war with a given index. |{Prefix}ew [war_number]")
|
||||
.Parameter("number")
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -257,6 +253,31 @@ namespace NadekoBot.Modules.ClashOfClans
|
||||
});
|
||||
}
|
||||
|
||||
private async Task FinishClaim(CommandEventArgs e, int stars = 3)
|
||||
{
|
||||
var warInfo = GetInfo(e);
|
||||
if (warInfo == null || warInfo.Item1.Count == 0)
|
||||
{
|
||||
await e.Channel.SendMessage("💢🔰 **That war does not exist.**").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var usr =
|
||||
string.IsNullOrWhiteSpace(e.GetArg("other_name")) ?
|
||||
e.User.Name :
|
||||
e.GetArg("other_name");
|
||||
|
||||
var war = warInfo.Item1[warInfo.Item2];
|
||||
try
|
||||
{
|
||||
var baseNum = war.FinishClaim(usr, stars);
|
||||
await e.Channel.SendMessage($"❗🔰{e.User.Mention} **DESTROYED** a base #{baseNum + 1} in a war against {war.ShortPrint()}").ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await e.Channel.SendMessage($"💢🔰 {ex.Message}").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static Tuple<List<ClashWar>, int> GetInfo(CommandEventArgs e)
|
||||
{
|
||||
//check if there are any wars
|
||||
|
@ -23,7 +23,7 @@ namespace NadekoBot.Modules.Conversations.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand("rip")
|
||||
.Description("Shows a grave image of someone with a start year\n**Usage**: @NadekoBot rip @Someone 2000")
|
||||
.Description("Shows a grave image of someone with a start year | @NadekoBot rip @Someone 2000")
|
||||
.Parameter("user", ParameterType.Required)
|
||||
.Parameter("year", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
|
@ -9,13 +9,14 @@ using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Conversations
|
||||
{
|
||||
internal class Conversations : DiscordModule
|
||||
{
|
||||
private const string firestr = "🔥 ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้ 🔥";
|
||||
private const string firestr = "🔥 ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้ 🔥";
|
||||
public Conversations()
|
||||
{
|
||||
commands.Add(new RipCommand(this));
|
||||
@ -32,7 +33,7 @@ namespace NadekoBot.Modules.Conversations
|
||||
cgb.AddCheck(PermissionChecker.Instance);
|
||||
|
||||
cgb.CreateCommand("..")
|
||||
.Description("Adds a new quote with the specified name (single word) and message (no limit).\n**Usage**: .. abc My message")
|
||||
.Description("Adds a new quote with the specified name (single word) and message (no limit). | .. abc My message")
|
||||
.Parameter("keyword", ParameterType.Required)
|
||||
.Parameter("text", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -53,7 +54,7 @@ namespace NadekoBot.Modules.Conversations
|
||||
});
|
||||
|
||||
cgb.CreateCommand("...")
|
||||
.Description("Shows a random quote with a specified name.\n**Usage**: .. abc")
|
||||
.Description("Shows a random quote with a specified name. | .. abc")
|
||||
.Parameter("keyword", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -73,7 +74,7 @@ namespace NadekoBot.Modules.Conversations
|
||||
|
||||
cgb.CreateCommand("..qdel")
|
||||
.Alias("..quotedelete")
|
||||
.Description("Deletes all quotes with the specified keyword. You have to either be bot owner or the creator of the quote to delete it.\n**Usage**: `..qdel abc`")
|
||||
.Description("Deletes all quotes with the specified keyword. You have to either be bot owner or the creator of the quote to delete it. | `..qdel abc`")
|
||||
.Parameter("quote", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -100,15 +101,6 @@ namespace NadekoBot.Modules.Conversations
|
||||
|
||||
commands.ForEach(cmd => cmd.Init(cgb));
|
||||
|
||||
cgb.CreateCommand("uptime")
|
||||
.Description("Shows how long Nadeko has been running for.")
|
||||
.Do(async e =>
|
||||
{
|
||||
var time = (DateTime.Now - Process.GetCurrentProcess().StartTime);
|
||||
var str = string.Format("I have been running for {0} days, {1} hours, and {2} minutes.", time.Days, time.Hours, time.Minutes);
|
||||
await e.Channel.SendMessage(str).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("die")
|
||||
.Description("Works only for the owner. Shuts the bot down.")
|
||||
.Do(async e =>
|
||||
@ -158,58 +150,27 @@ namespace NadekoBot.Modules.Conversations
|
||||
});
|
||||
|
||||
cgb.CreateCommand("fire")
|
||||
.Description("Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire.\n**Usage**: @NadekoBot fire [x]")
|
||||
.Description("Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire. | @NadekoBot fire [x]")
|
||||
.Parameter("times", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
var count = 1;
|
||||
int.TryParse(e.Args[0], out count);
|
||||
if (count == 0)
|
||||
int count;
|
||||
if (string.IsNullOrWhiteSpace(e.Args[0]))
|
||||
count = 1;
|
||||
else
|
||||
int.TryParse(e.Args[0], out count);
|
||||
if (count < 1 || count > 12)
|
||||
{
|
||||
await e.Channel.SendMessage("Number must be between 0 and 12").ConfigureAwait(false);
|
||||
await e.Channel.SendMessage("Number must be between 1 and 12").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var str = "";
|
||||
var str = new StringBuilder();
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
str += firestr;
|
||||
str.Append(firestr);
|
||||
}
|
||||
await e.Channel.SendMessage(str).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("slm")
|
||||
.Description("Shows the message where you were last mentioned in this channel (checks last 10k messages)")
|
||||
.Do(async e =>
|
||||
{
|
||||
|
||||
Message msg = null;
|
||||
var msgs = (await e.Channel.DownloadMessages(100).ConfigureAwait(false))
|
||||
.Where(m => m.MentionedUsers.Contains(e.User))
|
||||
.OrderByDescending(m => m.Timestamp);
|
||||
if (msgs.Any())
|
||||
msg = msgs.First();
|
||||
else
|
||||
{
|
||||
var attempt = 0;
|
||||
Message lastMessage = null;
|
||||
while (msg == null && attempt++ < 5)
|
||||
{
|
||||
var msgsarr = await e.Channel.DownloadMessages(100, lastMessage?.Id).ConfigureAwait(false);
|
||||
msg = msgsarr
|
||||
.Where(m => m.MentionedUsers.Contains(e.User))
|
||||
.OrderByDescending(m => m.Timestamp)
|
||||
.FirstOrDefault();
|
||||
lastMessage = msgsarr.OrderBy(m => m.Timestamp).First();
|
||||
}
|
||||
}
|
||||
if (msg != null)
|
||||
await e.Channel.SendMessage($"Last message mentioning you was at {msg.Timestamp}\n**Message from {msg.User.Name}:** {msg.RawText}")
|
||||
.ConfigureAwait(false);
|
||||
else
|
||||
await e.Channel.SendMessage("I can't find a message mentioning you.").ConfigureAwait(false);
|
||||
await e.Channel.SendMessage(str.ToString()).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("dump")
|
||||
|
@ -50,7 +50,7 @@ namespace NadekoBot.Modules.CustomReactions
|
||||
var c = cgb.CreateCommand(commandName);
|
||||
if (commandName.Contains(NadekoBot.BotMention))
|
||||
c.Alias(commandName.Replace("<@", "<@!"));
|
||||
c.Description($"Custom reaction.\n**Usage**:{command.Key}")
|
||||
c.Description($"Custom reaction. |{command.Key}")
|
||||
.Parameter("args", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -7,7 +7,7 @@ namespace NadekoBot.Classes
|
||||
/// Base DiscordCommand Class.
|
||||
/// Inherit this class to create your own command.
|
||||
/// </summary>
|
||||
internal abstract class DiscordCommand
|
||||
public abstract class DiscordCommand
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using NadekoBot.Classes;
|
||||
|
||||
namespace NadekoBot.Modules {
|
||||
internal abstract class DiscordModule : IModule {
|
||||
public abstract class DiscordModule : IModule {
|
||||
protected readonly HashSet<DiscordCommand> commands = new HashSet<DiscordCommand>();
|
||||
|
||||
public abstract string Prefix { get; }
|
||||
|
@ -21,11 +21,18 @@ namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "roll")
|
||||
.Description("Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice." +
|
||||
" If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y.\n**Usage**: $roll or $roll 7 or $roll 3d5")
|
||||
" If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | $roll or $roll 7 or $roll 3d5")
|
||||
.Parameter("num", ParameterType.Optional)
|
||||
.Do(RollFunc());
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "rolluo")
|
||||
.Description("Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice (unordered)." +
|
||||
" If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | $roll or $roll 7 or $roll 3d5")
|
||||
.Parameter("num", ParameterType.Optional)
|
||||
.Do(RollFunc(false));
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "nroll")
|
||||
.Description("Rolls in a given range.\n**Usage**: `$nroll 5` (rolls 0-5) or `$nroll 5-15`")
|
||||
.Description("Rolls in a given range. | `$nroll 5` (rolls 0-5) or `$nroll 5-15`")
|
||||
.Parameter("range", ParameterType.Required)
|
||||
.Do(NRollFunc());
|
||||
}
|
||||
@ -40,7 +47,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
|
||||
|
||||
Regex dndRegex = new Regex(@"(?<n1>\d+)d(?<n2>\d+)", RegexOptions.Compiled);
|
||||
private Func<CommandEventArgs, Task> RollFunc()
|
||||
private Func<CommandEventArgs, Task> RollFunc(bool ordered = true)
|
||||
{
|
||||
var r = new Random();
|
||||
return async e =>
|
||||
@ -73,7 +80,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
arr[i] = r.Next(1, n2 + 1);
|
||||
}
|
||||
var elemCnt = 0;
|
||||
await e.Channel.SendMessage($"`Rolled {n1} {(n1 == 1 ? "die" : "dice")} 1-{n2}.`\n`Result:` " + string.Join(", ", arr.OrderBy(x => x).Select(x => elemCnt++ % 2 == 0 ? $"**{x}**" : x.ToString()))).ConfigureAwait(false);
|
||||
await e.Channel.SendMessage($"`Rolled {n1} {(n1 == 1 ? "die" : "dice")} 1-{n2}.`\n`Result:` " + string.Join(", ", (ordered ? arr.OrderBy(x => x).AsEnumerable() : arr).Select(x => elemCnt++ % 2 == 0 ? $"**{x}**" : x.ToString()))).ConfigureAwait(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -92,6 +99,8 @@ namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
var randomNumber = r.Next(1, 7);
|
||||
var toInsert = dices.Count;
|
||||
if (ordered)
|
||||
{
|
||||
if (randomNumber == 6 || dices.Count == 0)
|
||||
toInsert = 0;
|
||||
else if (randomNumber != 1)
|
||||
@ -103,6 +112,10 @@ namespace NadekoBot.Modules.Gambling
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
toInsert = dices.Count;
|
||||
}
|
||||
dices.Insert(toInsert, GetDice(randomNumber));
|
||||
values.Insert(toInsert, randomNumber);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "draw")
|
||||
.Description("Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck.\n**Usage**: $draw [x]")
|
||||
.Description("Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck. | $draw [x]")
|
||||
.Parameter("count", ParameterType.Optional)
|
||||
.Do(DrawCardFunc());
|
||||
|
||||
|
@ -15,14 +15,68 @@ namespace NadekoBot.Modules.Gambling
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "flip")
|
||||
.Description("Flips coin(s) - heads or tails, and shows an image.\n**Usage**: `$flip` or `$flip 3`")
|
||||
.Description("Flips coin(s) - heads or tails, and shows an image. | `$flip` or `$flip 3`")
|
||||
.Parameter("count", ParameterType.Optional)
|
||||
.Do(FlipCoinFunc());
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "betflip")
|
||||
.Alias(Prefix+"bf")
|
||||
.Description($"Bet to guess will the result be heads or tails. Guessing award you double flowers you've bet. | `{Prefix}bf 5 heads` or `{Prefix}bf 3 t`")
|
||||
.Parameter("amount", ParameterType.Required)
|
||||
.Parameter("guess", ParameterType.Required)
|
||||
.Do(BetFlipCoinFunc());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private readonly Random rng = new Random();
|
||||
public Func<CommandEventArgs, Task> BetFlipCoinFunc() => async e =>
|
||||
{
|
||||
|
||||
var amountstr = e.GetArg("amount").Trim();
|
||||
|
||||
var guessStr = e.GetArg("guess").Trim().ToUpperInvariant();
|
||||
if (guessStr != "H" && guessStr != "T" && guessStr != "HEADS" && guessStr != "TAILS")
|
||||
return;
|
||||
|
||||
int amount;
|
||||
if (!int.TryParse(amountstr, out amount) || amount < 1)
|
||||
return;
|
||||
|
||||
var userFlowers = GamblingModule.GetUserFlowers(e.User.Id);
|
||||
|
||||
if (userFlowers < amount)
|
||||
{
|
||||
await e.Channel.SendMessage($"{e.User.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await FlowersHandler.RemoveFlowers(e.User, "Betflip Gamble", (int)amount, true).ConfigureAwait(false);
|
||||
//heads = true
|
||||
//tails = false
|
||||
|
||||
var guess = guessStr == "HEADS" || guessStr == "H";
|
||||
bool result = false;
|
||||
if (rng.Next(0, 2) == 1) {
|
||||
await e.Channel.SendFile("heads.png", Properties.Resources.heads.ToStream(System.Drawing.Imaging.ImageFormat.Png)).ConfigureAwait(false);
|
||||
result = true;
|
||||
}
|
||||
else {
|
||||
await e.Channel.SendFile("tails.png", Properties.Resources.tails.ToStream(System.Drawing.Imaging.ImageFormat.Png)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
string str;
|
||||
if (guess == result)
|
||||
{
|
||||
str = $"{e.User.Mention}`You guessed it!` You won {amount * 2}{NadekoBot.Config.CurrencySign}";
|
||||
await FlowersHandler.AddFlowersAsync(e.User, "Betflip Gamble", amount * 2, true).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
else
|
||||
str = $"{e.User.Mention}`More luck next time.`";
|
||||
|
||||
await e.Channel.SendMessage(str).ConfigureAwait(false);
|
||||
};
|
||||
|
||||
public Func<CommandEventArgs, Task> FlipCoinFunc() => async e =>
|
||||
{
|
||||
|
@ -13,7 +13,6 @@ namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
internal class GamblingModule : DiscordModule
|
||||
{
|
||||
|
||||
public GamblingModule()
|
||||
{
|
||||
commands.Add(new DrawCommand(this));
|
||||
@ -50,7 +49,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "$$")
|
||||
.Description(string.Format("Check how much {0}s a person has. (Defaults to yourself)\n**Usage**:`{1}$$` or `{1}$$ @Someone`",
|
||||
.Description(string.Format("Check how much {0}s a person has. (Defaults to yourself) |`{1}$$` or `{1}$$ @Someone`",
|
||||
NadekoBot.Config.CurrencyName, Prefix))
|
||||
.Parameter("all", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -69,7 +68,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
var amountStr = e.GetArg("amount")?.Trim();
|
||||
long amount;
|
||||
if (!long.TryParse(amountStr, out amount) || amount < 0)
|
||||
if (!long.TryParse(amountStr, out amount) || amount <= 0)
|
||||
return;
|
||||
|
||||
var mentionedUser = e.Message.MentionedUsers.FirstOrDefault(u =>
|
||||
@ -82,11 +81,11 @@ namespace NadekoBot.Modules.Gambling
|
||||
|
||||
if (userFlowers < amount)
|
||||
{
|
||||
await e.Channel.SendMessage($"{e.User.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You have only {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false);
|
||||
await e.Channel.SendMessage($"{e.User.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
FlowersHandler.RemoveFlowers(e.User, "Gift", (int)amount);
|
||||
await FlowersHandler.RemoveFlowers(e.User, "Gift", (int)amount, true).ConfigureAwait(false);
|
||||
await FlowersHandler.AddFlowersAsync(mentionedUser, "Gift", (int)amount).ConfigureAwait(false);
|
||||
|
||||
await e.Channel.SendMessage($"{e.User.Mention} successfully sent {amount} {NadekoBot.Config.CurrencyName}s to {mentionedUser.Mention}!").ConfigureAwait(false);
|
||||
@ -94,7 +93,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "award")
|
||||
.Description("Gives someone a certain amount of flowers. **Bot Owner Only!**\n**Usage**: `$award 100 @person`")
|
||||
.Description("Gives someone a certain amount of flowers. **Bot Owner Only!** | `$award 100 @person`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Parameter("amount", ParameterType.Required)
|
||||
.Parameter("receiver", ParameterType.Unparsed)
|
||||
@ -132,11 +131,58 @@ namespace NadekoBot.Modules.Gambling
|
||||
if (mentionedUser == null)
|
||||
return;
|
||||
|
||||
FlowersHandler.RemoveFlowers(mentionedUser, $"Taken by bot owner.({e.User.Name}/{e.User.Id})", (int)amount);
|
||||
await FlowersHandler.RemoveFlowers(mentionedUser, $"Taken by bot owner.({e.User.Name}/{e.User.Id})", (int)amount).ConfigureAwait(false);
|
||||
|
||||
await e.Channel.SendMessage($"{e.User.Mention} successfully took {amount} {NadekoBot.Config.CurrencyName}s from {mentionedUser.Mention}!").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "betroll")
|
||||
.Alias(Prefix + "br")
|
||||
.Description($"Bets a certain amount of {NadekoBot.Config.CurrencyName}s and rolls a dice. Rolling over 66 yields x2 flowers, over 90 - x3 and 100 x10. | {Prefix}br 5")
|
||||
.Parameter("amount",ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
var amountstr = e.GetArg("amount").Trim();
|
||||
int amount;
|
||||
|
||||
if (!int.TryParse(amountstr, out amount) || amount < 1)
|
||||
return;
|
||||
|
||||
var userFlowers = GetUserFlowers(e.User.Id);
|
||||
|
||||
if (userFlowers < amount)
|
||||
{
|
||||
await e.Channel.SendMessage($"{e.User.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await FlowersHandler.RemoveFlowers(e.User, "Betroll Gamble", (int)amount, true).ConfigureAwait(false);
|
||||
|
||||
var rng = new Random().Next(0, 101);
|
||||
var str = $"{e.User.Mention} `You rolled {rng}.` ";
|
||||
if (rng < 67)
|
||||
{
|
||||
str += "Better luck next time.";
|
||||
}
|
||||
else if (rng < 90)
|
||||
{
|
||||
str += $"Congratulations! You won {amount * 2}{NadekoBot.Config.CurrencySign} for rolling above 66";
|
||||
await FlowersHandler.AddFlowersAsync(e.User, "Betroll Gamble", amount * 2, true).ConfigureAwait(false);
|
||||
}
|
||||
else if (rng < 100)
|
||||
{
|
||||
str += $"Congratulations! You won {amount * 3}{NadekoBot.Config.CurrencySign} for rolling above 90.";
|
||||
await FlowersHandler.AddFlowersAsync(e.User, "Betroll Gamble", amount * 3, true).ConfigureAwait(false);
|
||||
}
|
||||
else {
|
||||
str += $"👑 Congratulations! You won {amount * 10}{NadekoBot.Config.CurrencySign} for rolling **100**. 👑";
|
||||
await FlowersHandler.AddFlowersAsync(e.User, "Betroll Gamble", amount * 10, true).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await e.Channel.SendMessage(str).ConfigureAwait(false);
|
||||
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "leaderboard")
|
||||
.Alias(Prefix + "lb")
|
||||
.Do(async e =>
|
||||
@ -148,18 +194,18 @@ namespace NadekoBot.Modules.Gambling
|
||||
await e.Channel.SendMessage(
|
||||
richest.Aggregate(new StringBuilder(
|
||||
$@"```xl
|
||||
┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
|
||||
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
|
||||
┃ Id ┃ $$$ ┃
|
||||
"),
|
||||
(cur, cs) => cur.AppendLine(
|
||||
$@"┣━━━━━━━━━━━━━━━━━━━╋━━━━━━━┫
|
||||
┃{cs.UserId,-18} ┃ {cs.Value,5} ┃")
|
||||
).ToString() + "┗━━━━━━━━━━━━━━━━━━━┻━━━━━━━┛```");
|
||||
$@"┣━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━┫
|
||||
┃{(e.Server.Users.Where(u => u.Id == (ulong)cs.UserId).FirstOrDefault()?.Name.TrimTo(18, true) ?? cs.UserId.ToString()),-20} ┃ {cs.Value,5} ┃")
|
||||
).ToString() + "┗━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━┛```").ConfigureAwait(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static long GetUserFlowers(ulong userId) =>
|
||||
public static long GetUserFlowers(ulong userId) =>
|
||||
Classes.DbHandler.Instance.GetStateByUserId((long)userId)?.Value ?? 0;
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ namespace NadekoBot.Modules.Gambling.Helpers
|
||||
var orderedPool = cardPool.OrderBy(x => r.Next());
|
||||
cardPool = cardPool as List<Card> ?? orderedPool.ToList();
|
||||
}
|
||||
public override string ToString() => string.Join("", cardPool.Select(c => c.ToString())) + Environment.NewLine;
|
||||
public override string ToString() => string.Concat(cardPool.Select(c => c.ToString())) + Environment.NewLine;
|
||||
|
||||
private static void InitHandValues()
|
||||
{
|
||||
@ -226,7 +226,7 @@ namespace NadekoBot.Modules.Gambling.Helpers
|
||||
{
|
||||
return kvp.Key;
|
||||
}
|
||||
return "High card " + cards.Max().GetName();
|
||||
return "High card " + (cards.FirstOrDefault(c => c.Number == 1)?.GetName() ?? cards.Max().GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "leet")
|
||||
.Description($"Converts a text to leetspeak with 6 (1-6) severity levels\n**Usage**: {Module.Prefix}leet 3 Hello")
|
||||
.Description($"Converts a text to leetspeak with 6 (1-6) severity levels | {Module.Prefix}leet 3 Hello")
|
||||
.Parameter("level", ParameterType.Required)
|
||||
.Parameter("text", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
|
@ -1,9 +1,11 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
@ -28,25 +30,34 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
rng = new Random();
|
||||
}
|
||||
|
||||
private static readonly ConcurrentDictionary<ulong, DateTime> plantpickCooldowns = new ConcurrentDictionary<ulong, DateTime>();
|
||||
|
||||
private async void PotentialFlowerGeneration(object sender, Discord.MessageEventArgs e)
|
||||
{
|
||||
if (e.Server == null || e.Channel.IsPrivate)
|
||||
try
|
||||
{
|
||||
if (e.Server == null || e.Channel.IsPrivate || e.Message.IsAuthor)
|
||||
return;
|
||||
var config = Classes.SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
if (config.GenerateCurrencyChannels.Contains(e.Channel.Id))
|
||||
var now = DateTime.Now;
|
||||
int cd;
|
||||
DateTime lastSpawned;
|
||||
if (config.GenerateCurrencyChannels.TryGetValue(e.Channel.Id, out cd))
|
||||
if (!plantpickCooldowns.TryGetValue(e.Channel.Id, out lastSpawned) || (lastSpawned + new TimeSpan(0, cd, 0)) < now)
|
||||
{
|
||||
var rnd = Math.Abs(GetRandomNumber());
|
||||
if ((rnd % 50) == 0)
|
||||
var rnd = Math.Abs(rng.Next(0,101));
|
||||
if (rnd == 0)
|
||||
{
|
||||
var msg = await e.Channel.SendFile(GetRandomCurrencyImagePath());
|
||||
await e.Channel.SendMessage($"❗ A random {NadekoBot.Config.CurrencyName} appeared! Pick it up by typing `>pick`");
|
||||
plantedFlowerChannels.AddOrUpdate(e.Channel.Id, msg, (u, m) => { m.Delete().GetAwaiter().GetResult(); return msg; });
|
||||
var msgs = new[] { await e.Channel.SendFile(GetRandomCurrencyImagePath()), await e.Channel.SendMessage($"❗ A random {NadekoBot.Config.CurrencyName} appeared! Pick it up by typing `>pick`") };
|
||||
plantedFlowerChannels.AddOrUpdate(e.Channel.Id, msgs, (u, m) => { m.ForEach(async msgToDelete => { try { await msgToDelete.Delete(); } catch { } }); return msgs; });
|
||||
plantpickCooldowns.AddOrUpdate(e.Channel.Id, now, (i, d) => now);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
//channelid/messageid pair
|
||||
ConcurrentDictionary<ulong, Message> plantedFlowerChannels = new ConcurrentDictionary<ulong, Message>();
|
||||
ConcurrentDictionary<ulong, IEnumerable<Message>> plantedFlowerChannels = new ConcurrentDictionary<ulong, IEnumerable<Message>>();
|
||||
|
||||
private object locker = new object();
|
||||
|
||||
@ -56,22 +67,24 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
.Description("Picks a flower planted in this channel.")
|
||||
.Do(async e =>
|
||||
{
|
||||
Message msg;
|
||||
IEnumerable<Message> msgs;
|
||||
|
||||
await e.Message.Delete().ConfigureAwait(false);
|
||||
if (!plantedFlowerChannels.TryRemove(e.Channel.Id, out msg))
|
||||
if (!plantedFlowerChannels.TryRemove(e.Channel.Id, out msgs))
|
||||
return;
|
||||
|
||||
await msg.Delete().ConfigureAwait(false);
|
||||
foreach(var msgToDelete in msgs)
|
||||
await msgToDelete.Delete().ConfigureAwait(false);
|
||||
|
||||
await FlowersHandler.AddFlowersAsync(e.User, "Picked a flower.", 1, true).ConfigureAwait(false);
|
||||
msg = await e.Channel.SendMessage($"**{e.User.Name}** picked a {NadekoBot.Config.CurrencyName}!").ConfigureAwait(false);
|
||||
var msg = await e.Channel.SendMessage($"**{e.User.Name}** picked a {NadekoBot.Config.CurrencyName}!").ConfigureAwait(false);
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await msg.Delete().ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "plant")
|
||||
.Description("Spend a flower to plant it in this channel. (If bot is restarted or crashes, flower will be lost)")
|
||||
.Do(async e =>
|
||||
.Do(e =>
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
@ -80,7 +93,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
e.Channel.SendMessage($"There is already a {NadekoBot.Config.CurrencyName} in this channel.");
|
||||
return;
|
||||
}
|
||||
var removed = FlowersHandler.RemoveFlowers(e.User, "Planted a flower.", 1);
|
||||
var removed = FlowersHandler.RemoveFlowers(e.User, "Planted a flower.", 1, true).GetAwaiter().GetResult();
|
||||
if (!removed)
|
||||
{
|
||||
e.Channel.SendMessage($"You don't have any {NadekoBot.Config.CurrencyName}s.").Wait();
|
||||
@ -89,34 +102,39 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
|
||||
var file = GetRandomCurrencyImagePath();
|
||||
Message msg;
|
||||
//todo send message after, not in lock
|
||||
if (file == null)
|
||||
msg = e.Channel.SendMessage(NadekoBot.Config.CurrencySign).GetAwaiter().GetResult();
|
||||
else
|
||||
msg = e.Channel.SendFile(file).GetAwaiter().GetResult();
|
||||
plantedFlowerChannels.TryAdd(e.Channel.Id, msg);
|
||||
}
|
||||
var vowelFirst = new[] { 'a', 'e', 'i', 'o', 'u' }.Contains(NadekoBot.Config.CurrencyName[0]);
|
||||
var msg2 = await e.Channel.SendMessage($"Oh how Nice! **{e.User.Name}** planted {(vowelFirst ? "an" : "a")} {NadekoBot.Config.CurrencyName}. Pick it using {Module.Prefix}pick");
|
||||
await Task.Delay(20000).ConfigureAwait(false);
|
||||
await msg2.Delete().ConfigureAwait(false);
|
||||
var msg2 = e.Channel.SendMessage($"Oh how Nice! **{e.User.Name}** planted {(vowelFirst ? "an" : "a")} {NadekoBot.Config.CurrencyName}. Pick it using {Module.Prefix}pick").GetAwaiter().GetResult();
|
||||
plantedFlowerChannels.TryAdd(e.Channel.Id, new[] { msg, msg2 });
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "gencurrency")
|
||||
.Alias(Prefix + "gc")
|
||||
.Description($"Toggles currency generation on this channel. Every posted message will have 2% chance to spawn a {NadekoBot.Config.CurrencyName}. Requires Manage Messages permission. | `>gc`")
|
||||
.Description($"Toggles currency generation on this channel. Every posted message will have 2% chance to spawn a {NadekoBot.Config.CurrencyName}. Optional parameter cooldown time in minutes, 5 minutes by default. Requires Manage Messages permission. | `>gc` or `>gc 60`")
|
||||
.AddCheck(SimpleCheckers.ManageMessages())
|
||||
.Parameter("cd", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var cdStr = e.GetArg("cd");
|
||||
int cd = 2;
|
||||
if (!int.TryParse(cdStr, out cd) || cd < 0)
|
||||
{
|
||||
cd = 2;
|
||||
}
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
if (config.GenerateCurrencyChannels.Remove(e.Channel.Id))
|
||||
int throwaway;
|
||||
if (config.GenerateCurrencyChannels.TryRemove(e.Channel.Id, out throwaway))
|
||||
{
|
||||
await e.Channel.SendMessage("`Currency generation disabled on this channel.`");
|
||||
}
|
||||
else
|
||||
{
|
||||
config.GenerateCurrencyChannels.Add(e.Channel.Id);
|
||||
await e.Channel.SendMessage("`Currency generation enabled on this channel.`");
|
||||
if (config.GenerateCurrencyChannels.TryAdd(e.Channel.Id, cd))
|
||||
await e.Channel.SendMessage($"`Currency generation enabled on this channel. Cooldown is {cd} minutes.`");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "poll")
|
||||
.Description("Creates a poll, only person who has manage server permission can do it.\n**Usage**: >poll Question?;Answer1;Answ 2;A_3")
|
||||
.Description("Creates a poll, only person who has manage server permission can do it. | >poll Question?;Answer1;Answ 2;A_3")
|
||||
.Parameter("allargs", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -190,8 +190,6 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
|
||||
await e.Channel.SendMessage("Added new article for typing game.").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
//todo add user submissions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "t")
|
||||
.Description($"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." +
|
||||
$"\n**Usage**:`{Module.Prefix}t nohint` or `{Module.Prefix}t 5 nohint`")
|
||||
$" |`{Module.Prefix}t nohint` or `{Module.Prefix}t 5 nohint`")
|
||||
.Parameter("args", ParameterType.Multiple)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ namespace NadekoBot.Modules.Games
|
||||
commands.ForEach(cmd => cmd.Init(cgb));
|
||||
|
||||
cgb.CreateCommand(Prefix + "choose")
|
||||
.Description("Chooses a thing from a list of things\n**Usage**: >choose Get up;Sleep;Sleep more")
|
||||
.Description("Chooses a thing from a list of things | >choose Get up;Sleep;Sleep more")
|
||||
.Parameter("list", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -67,7 +67,7 @@ namespace NadekoBot.Modules.Games
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "rps")
|
||||
.Description("Play a game of rocket paperclip scissors with Nadeko.\n**Usage**: >rps scissors")
|
||||
.Description("Play a game of rocket paperclip scissors with Nadeko. | >rps scissors")
|
||||
.Parameter("input", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -107,7 +107,7 @@ namespace NadekoBot.Modules.Games
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "linux")
|
||||
.Description($"Prints a customizable Linux interjection\n**Usage**: `{Prefix}linux Spyware Windows`")
|
||||
.Description($"Prints a customizable Linux interjection | `{Prefix}linux Spyware Windows`")
|
||||
.Parameter("gnu", ParameterType.Required)
|
||||
.Parameter("linux", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
|
@ -5,6 +5,7 @@ using NadekoBot.Modules.Permissions.Classes;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Classes.Help.Commands
|
||||
@ -24,8 +25,13 @@ namespace NadekoBot.Classes.Help.Commands
|
||||
var com = NadekoBot.Client.GetService<CommandService>().AllCommands
|
||||
.FirstOrDefault(c => c.Text.ToLowerInvariant().Equals(comToFind) ||
|
||||
c.Aliases.Select(a => a.ToLowerInvariant()).Contains(comToFind));
|
||||
|
||||
var str = "";
|
||||
var alias = com.Aliases.FirstOrDefault();
|
||||
if (alias != null)
|
||||
str = $" / `{ com.Aliases.FirstOrDefault()}`";
|
||||
if (com != null)
|
||||
await e.Channel.SendMessage($"`Help for '{com.Text}':` {com.Description}").ConfigureAwait(false);
|
||||
await e.Channel.SendMessage($@"**__Help for:__ `{com.Text}`**" + str + $"\n**Desc:** {new Regex(@"\|").Replace(com.Description, "\n**Usage:**",1)}").ConfigureAwait(false);
|
||||
}).ConfigureAwait(false);
|
||||
};
|
||||
public static string HelpString {
|
||||
@ -43,7 +49,7 @@ namespace NadekoBot.Classes.Help.Commands
|
||||
{
|
||||
string helpstr =
|
||||
$@"######For more information and how to setup your own NadekoBot, go to: **http://github.com/Kwoth/NadekoBot/**
|
||||
######You can donate on paypal: `nadekodiscordbot@gmail.com` or Bitcoin `17MZz1JAqME39akMLrVT4XBPffQJ2n1EPa`
|
||||
######You can donate on paypal: `nadekodiscordbot@gmail.com`
|
||||
|
||||
#NadekoBot List Of Commands
|
||||
Version: `{NadekoStats.Instance.BotVersion}`";
|
||||
@ -62,7 +68,7 @@ Version: `{NadekoStats.Instance.BotVersion}`";
|
||||
helpstr += PrintCommandHelp(com);
|
||||
}
|
||||
helpstr = helpstr.Replace(NadekoBot.BotMention, "@BotName");
|
||||
helpstr = helpstr.Replace("\n**Usage**:", " | ").Replace("**Usage**:", " | ").Replace("**Description:**", " | ").Replace("\n|", " | \n");
|
||||
helpstr = helpstr.Replace(" |", " | ").Replace("**Usage**:", " | ").Replace("**Description:**", " | ").Replace("\n|", " | \n");
|
||||
#if DEBUG
|
||||
File.WriteAllText("../../../commandlist.md", helpstr);
|
||||
#else
|
||||
@ -74,7 +80,7 @@ Version: `{NadekoStats.Instance.BotVersion}`";
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "h")
|
||||
.Alias(Module.Prefix + "help", NadekoBot.BotMention + " help", NadekoBot.BotMention + " h", "~h")
|
||||
.Description("Either shows a help for a single command, or PMs you help link if no arguments are specified.\n**Usage**: '-h !m q' or just '-h' ")
|
||||
.Description("Either shows a help for a single command, or PMs you help link if no arguments are specified. | '-h !m q' or just '-h' ")
|
||||
.Parameter("command", ParameterType.Unparsed)
|
||||
.Do(HelpFunc());
|
||||
cgb.CreateCommand(Module.Prefix + "hgit")
|
||||
|
@ -46,20 +46,25 @@ namespace NadekoBot.Modules.Help
|
||||
if (string.IsNullOrWhiteSpace(module))
|
||||
return;
|
||||
var cmds = NadekoBot.Client.GetService<CommandService>().AllCommands
|
||||
.Where(c => c.Category.ToLower() == module);
|
||||
.Where(c => c.Category.ToLower() == module)
|
||||
.OrderBy(c=>c.Text)
|
||||
.AsEnumerable();
|
||||
var cmdsArray = cmds as Command[] ?? cmds.ToArray();
|
||||
if (!cmdsArray.Any())
|
||||
{
|
||||
await e.Channel.SendMessage("That module does not exist.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var i = 0;
|
||||
if (module != "customreactions" && module != "conversations")
|
||||
{
|
||||
await e.Channel.SendMessage("`List Of Commands:`\n" + SearchHelper.ShowInPrettyCode<Command>(cmdsArray,
|
||||
el => $"{el.Text,-15}{"[" + el.Aliases.FirstOrDefault() + "]",-8}"))
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await e.Channel.SendMessage("`List Of Commands:`\n• " + string.Join("\n• ", cmdsArray.Select(c => $"{c.Text}")));
|
||||
}
|
||||
await e.Channel.SendMessage($"`You can type \"{Prefix}h command_name\" to see the help about that specific command.`").ConfigureAwait(false);
|
||||
});
|
||||
});
|
||||
|
@ -2,7 +2,9 @@
|
||||
using Discord.Audio;
|
||||
using NadekoBot.Extensions;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
namespace NadekoBot.Modules.Music.Classes
|
||||
@ -12,29 +14,26 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
{
|
||||
Radio,
|
||||
Normal,
|
||||
Local
|
||||
Local,
|
||||
Soundcloud
|
||||
}
|
||||
|
||||
public enum StreamState
|
||||
{
|
||||
Resolving,
|
||||
Queued,
|
||||
Buffering, //not using it atm
|
||||
Playing,
|
||||
Completed
|
||||
}
|
||||
|
||||
public class MusicPlayer
|
||||
{
|
||||
public static int MaximumPlaylistSize => 50;
|
||||
|
||||
private IAudioClient audioClient { get; set; }
|
||||
|
||||
private readonly List<Song> playlist = new List<Song>();
|
||||
public IReadOnlyCollection<Song> Playlist => playlist;
|
||||
private readonly object playlistLock = new object();
|
||||
|
||||
public Song CurrentSong { get; set; } = default(Song);
|
||||
public Song CurrentSong { get; private set; }
|
||||
private CancellationTokenSource SongCancelSource { get; set; }
|
||||
private CancellationToken cancelToken { get; set; }
|
||||
|
||||
@ -51,6 +50,9 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
public bool RepeatSong { get; private set; } = false;
|
||||
public bool RepeatPlaylist { get; private set; } = false;
|
||||
public bool Autoplay { get; set; } = false;
|
||||
public uint MaxQueueSize { get; set; } = 0;
|
||||
|
||||
private ConcurrentQueue<Action> actionQueue { get; set; } = new ConcurrentQueue<Action>();
|
||||
|
||||
public MusicPlayer(Channel startingVoiceChannel, float? defaultVolume)
|
||||
{
|
||||
@ -65,86 +67,111 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
cancelToken = SongCancelSource.Token;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!Destroyed)
|
||||
{
|
||||
try
|
||||
{
|
||||
Action action;
|
||||
if (actionQueue.TryDequeue(out action))
|
||||
{
|
||||
action();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Action queue crashed");
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
var t = new Thread(new ThreadStart(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!Destroyed)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (audioClient?.State != ConnectionState.Connected)
|
||||
audioClient = await PlaybackVoiceChannel.JoinAudio().ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
audioClient = await PlaybackVoiceChannel.JoinAudio();
|
||||
continue;
|
||||
}
|
||||
|
||||
CurrentSong = GetNextSong();
|
||||
var curSong = CurrentSong;
|
||||
if (curSong != null)
|
||||
{
|
||||
RemoveSongAt(0);
|
||||
|
||||
if (CurrentSong == null)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
OnStarted(this, curSong);
|
||||
await curSong.Play(audioClient, cancelToken).ConfigureAwait(false);
|
||||
OnStarted(this, CurrentSong);
|
||||
await CurrentSong.Play(audioClient, cancelToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Console.WriteLine("Song canceled");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Exception in PlaySong: {ex}");
|
||||
}
|
||||
OnCompleted(this, curSong);
|
||||
curSong = CurrentSong; //to check if its null now
|
||||
if (curSong != null)
|
||||
if (RepeatSong)
|
||||
playlist.Insert(0, curSong);
|
||||
else if (RepeatPlaylist)
|
||||
playlist.Insert(playlist.Count, curSong);
|
||||
SongCancelSource = new CancellationTokenSource();
|
||||
cancelToken = SongCancelSource.Token;
|
||||
}
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
OnCompleted(this, CurrentSong);
|
||||
|
||||
if (RepeatPlaylist)
|
||||
AddSong(CurrentSong, CurrentSong.QueuerName);
|
||||
|
||||
if (RepeatSong)
|
||||
AddSong(CurrentSong, 0);
|
||||
|
||||
}
|
||||
});
|
||||
finally
|
||||
{
|
||||
await Task.Delay(300).ConfigureAwait(false);
|
||||
CurrentSong = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Console.WriteLine("Music thread crashed.");
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
}));
|
||||
|
||||
t.Start();
|
||||
}
|
||||
|
||||
public void Next()
|
||||
{
|
||||
lock (playlistLock)
|
||||
{
|
||||
if (!SongCancelSource.IsCancellationRequested)
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
Paused = false;
|
||||
SongCancelSource.Cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
lock (playlistLock)
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
playlist.Clear();
|
||||
CurrentSong = null;
|
||||
RepeatPlaylist = false;
|
||||
RepeatSong = false;
|
||||
playlist.Clear();
|
||||
if (!SongCancelSource.IsCancellationRequested)
|
||||
SongCancelSource.Cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void TogglePause() => Paused = !Paused;
|
||||
|
||||
public void Shuffle()
|
||||
{
|
||||
lock (playlistLock)
|
||||
{
|
||||
playlist.Shuffle();
|
||||
}
|
||||
}
|
||||
|
||||
public int SetVolume(int volume)
|
||||
{
|
||||
if (volume < 0)
|
||||
@ -156,57 +183,80 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
return volume;
|
||||
}
|
||||
|
||||
private Song GetNextSong()
|
||||
private Song GetNextSong() =>
|
||||
playlist.FirstOrDefault();
|
||||
|
||||
public void Shuffle()
|
||||
{
|
||||
lock (playlistLock)
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
if (playlist.Count == 0)
|
||||
return null;
|
||||
var toReturn = playlist[0];
|
||||
playlist.RemoveAt(0);
|
||||
return toReturn;
|
||||
}
|
||||
playlist.Shuffle();
|
||||
});
|
||||
}
|
||||
|
||||
public void AddSong(Song s)
|
||||
public void AddSong(Song s, string username)
|
||||
{
|
||||
if (s == null)
|
||||
throw new ArgumentNullException(nameof(s));
|
||||
lock (playlistLock)
|
||||
ThrowIfQueueFull();
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
s.MusicPlayer = this;
|
||||
s.QueuerName = username.TrimTo(10);
|
||||
playlist.Add(s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void AddSong(Song s, int index)
|
||||
{
|
||||
if (s == null)
|
||||
throw new ArgumentNullException(nameof(s));
|
||||
lock (playlistLock)
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
playlist.Insert(index, s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void RemoveSong(Song s)
|
||||
{
|
||||
if (s == null)
|
||||
throw new ArgumentNullException(nameof(s));
|
||||
lock (playlistLock)
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
playlist.Remove(s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void RemoveSongAt(int index)
|
||||
{
|
||||
lock (playlistLock)
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
if (index < 0 || index >= playlist.Count)
|
||||
throw new ArgumentException("Invalid index");
|
||||
return;
|
||||
playlist.RemoveAt(index);
|
||||
});
|
||||
}
|
||||
|
||||
internal void ClearQueue()
|
||||
{
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
playlist.Clear();
|
||||
});
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
actionQueue.Enqueue(() =>
|
||||
{
|
||||
RepeatPlaylist = false;
|
||||
RepeatSong = false;
|
||||
Destroyed = true;
|
||||
playlist.Clear();
|
||||
if (!SongCancelSource.IsCancellationRequested)
|
||||
SongCancelSource.Cancel();
|
||||
audioClient.Disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
internal Task MoveToVoiceChannel(Channel voiceChannel)
|
||||
@ -217,31 +267,18 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
return PlaybackVoiceChannel.JoinAudio();
|
||||
}
|
||||
|
||||
internal void ClearQueue()
|
||||
{
|
||||
lock (playlistLock)
|
||||
{
|
||||
playlist.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
lock (playlistLock)
|
||||
{
|
||||
playlist.Clear();
|
||||
Destroyed = true;
|
||||
CurrentSong = null;
|
||||
if (!SongCancelSource.IsCancellationRequested)
|
||||
SongCancelSource.Cancel();
|
||||
audioClient.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
internal bool ToggleRepeatSong() => this.RepeatSong = !this.RepeatSong;
|
||||
|
||||
internal bool ToggleRepeatPlaylist() => this.RepeatPlaylist = !this.RepeatPlaylist;
|
||||
|
||||
internal bool ToggleAutoplay() => this.Autoplay = !this.Autoplay;
|
||||
|
||||
internal void ThrowIfQueueFull()
|
||||
{
|
||||
if (MaxQueueSize == 0)
|
||||
return;
|
||||
if (playlist.Count >= MaxQueueSize)
|
||||
throw new PlaylistFullException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
NadekoBot/Modules/Music/Classes/PlaylistFullException.cs
Normal file
12
NadekoBot/Modules/Music/Classes/PlaylistFullException.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace NadekoBot.Modules.Music.Classes
|
||||
{
|
||||
class PlaylistFullException : Exception
|
||||
{
|
||||
public PlaylistFullException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
public PlaylistFullException() : base("Queue is full.") { }
|
||||
}
|
||||
}
|
@ -27,10 +27,11 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
{
|
||||
public StreamState State { get; internal set; }
|
||||
public string PrettyName =>
|
||||
$"**【 {SongInfo.Title.TrimTo(55)} 】**`{(SongInfo.Provider ?? "-")}`";
|
||||
$"**【 {SongInfo.Title.TrimTo(55)} 】**`{(SongInfo.Provider ?? "-")}` `by {QueuerName}`";
|
||||
public SongInfo SongInfo { get; }
|
||||
public string QueuerName { get; set; }
|
||||
|
||||
private PoopyBuffer songBuffer { get; } = new PoopyBuffer(NadekoBot.Config.BufferSize);
|
||||
private PoopyBuffer songBuffer { get; set; }
|
||||
|
||||
private bool prebufferingComplete { get; set; } = false;
|
||||
public MusicPlayer MusicPlayer { get; set; }
|
||||
@ -136,6 +137,9 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
|
||||
internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken)
|
||||
{
|
||||
// initialize the buffer here because if this song was playing before (requeued), we must delete old buffer data
|
||||
songBuffer = new PoopyBuffer(NadekoBot.Config.BufferSize);
|
||||
|
||||
var bufferTask = BufferSong(cancelToken).ConfigureAwait(false);
|
||||
var bufferAttempts = 0;
|
||||
const int waitPerAttempt = 500;
|
||||
@ -144,7 +148,6 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
{
|
||||
await Task.Delay(waitPerAttempt, cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
cancelToken.ThrowIfCancellationRequested();
|
||||
Console.WriteLine($"Prebuffering done? in {waitPerAttempt * bufferAttempts}");
|
||||
const int blockSize = 3840;
|
||||
var attempt = 0;
|
||||
@ -244,16 +247,30 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
}
|
||||
if (SoundCloud.Default.IsSoundCloudLink(query))
|
||||
{
|
||||
var svideo = await SoundCloud.Default.GetVideoAsync(query).ConfigureAwait(false);
|
||||
var svideo = await SoundCloud.Default.ResolveVideoAsync(query).ConfigureAwait(false);
|
||||
return new Song(new SongInfo
|
||||
{
|
||||
Title = svideo.FullName,
|
||||
Provider = "SoundCloud",
|
||||
Uri = svideo.StreamLink,
|
||||
ProviderType = musicType,
|
||||
Query = query,
|
||||
Query = svideo.TrackLink,
|
||||
});
|
||||
}
|
||||
|
||||
if (musicType == MusicType.Soundcloud)
|
||||
{
|
||||
var svideo = await SoundCloud.Default.GetVideoByQueryAsync(query).ConfigureAwait(false);
|
||||
return new Song(new SongInfo
|
||||
{
|
||||
Title = svideo.FullName,
|
||||
Provider = "SoundCloud",
|
||||
Uri = svideo.StreamLink,
|
||||
ProviderType = MusicType.Normal,
|
||||
Query = svideo.TrackLink,
|
||||
});
|
||||
}
|
||||
|
||||
var link = await SearchHelper.FindYoutubeUrlByKeywords(query).ConfigureAwait(false);
|
||||
if (string.IsNullOrWhiteSpace(link))
|
||||
throw new OperationCanceledException("Not a valid youtube query.");
|
||||
|
@ -1,6 +1,7 @@
|
||||
using NadekoBot.Classes;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Music.Classes
|
||||
@ -13,7 +14,7 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
static SoundCloud() { }
|
||||
public SoundCloud() { }
|
||||
|
||||
public async Task<SoundCloudVideo> GetVideoAsync(string url)
|
||||
public async Task<SoundCloudVideo> ResolveVideoAsync(string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
throw new ArgumentNullException(nameof(url));
|
||||
@ -31,6 +32,22 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
|
||||
public bool IsSoundCloudLink(string url) =>
|
||||
System.Text.RegularExpressions.Regex.IsMatch(url, "(.*)(soundcloud.com|snd.sc)(.*)");
|
||||
|
||||
internal async Task<SoundCloudVideo> GetVideoByQueryAsync(string query)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(query))
|
||||
throw new ArgumentNullException(nameof(query));
|
||||
if (string.IsNullOrWhiteSpace(NadekoBot.Creds.SoundCloudClientID))
|
||||
throw new ArgumentNullException(nameof(NadekoBot.Creds.SoundCloudClientID));
|
||||
|
||||
var response = await SearchHelper.GetResponseStringAsync($"http://api.soundcloud.com/tracks?q={Uri.EscapeDataString(query)}&client_id={NadekoBot.Creds.SoundCloudClientID}").ConfigureAwait(false);
|
||||
|
||||
var responseObj = JsonConvert.DeserializeObject<SoundCloudVideo[]>(response).Where(s => s.Streamable).FirstOrDefault();
|
||||
if (responseObj?.Kind != "track")
|
||||
throw new InvalidOperationException("Query yielded no results.");
|
||||
|
||||
return responseObj;
|
||||
}
|
||||
}
|
||||
|
||||
public class SoundCloudVideo
|
||||
|
@ -31,17 +31,17 @@ namespace NadekoBot.Modules.Music
|
||||
{
|
||||
var client = NadekoBot.Client;
|
||||
|
||||
manager.CreateCommands(Prefix, cgb =>
|
||||
manager.CreateCommands("", cgb =>
|
||||
{
|
||||
|
||||
cgb.AddCheck(PermissionChecker.Instance);
|
||||
|
||||
commands.ForEach(cmd => cmd.Init(cgb));
|
||||
|
||||
cgb.CreateCommand("next")
|
||||
.Alias("n")
|
||||
.Alias("skip")
|
||||
.Description("Goes to the next song in the queue. You have to be in the same voice channel as the bot.\n**Usage**: `!m n`")
|
||||
cgb.CreateCommand(Prefix + "next")
|
||||
.Alias(Prefix + "n")
|
||||
.Alias(Prefix + "skip")
|
||||
.Description($"Goes to the next song in the queue. You have to be in the same voice channel as the bot. | `{Prefix}n`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
@ -50,9 +50,9 @@ namespace NadekoBot.Modules.Music
|
||||
musicPlayer.Next();
|
||||
});
|
||||
|
||||
cgb.CreateCommand("stop")
|
||||
.Alias("s")
|
||||
.Description("Stops the music and clears the playlist. Stays in the channel.\n**Usage**: `!m s`")
|
||||
cgb.CreateCommand(Prefix + "stop")
|
||||
.Alias(Prefix + "s")
|
||||
.Description($"Stops the music and clears the playlist. Stays in the channel. | `{Prefix}s`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
@ -64,10 +64,10 @@ namespace NadekoBot.Modules.Music
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("destroy")
|
||||
.Alias("d")
|
||||
cgb.CreateCommand(Prefix + "destroy")
|
||||
.Alias(Prefix + "d")
|
||||
.Description("Completely stops the music and unbinds the bot from the channel. " +
|
||||
"(may cause weird behaviour)\n**Usage**: `!m d`")
|
||||
$"(may cause weird behaviour) | `{Prefix}d`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
@ -76,9 +76,9 @@ namespace NadekoBot.Modules.Music
|
||||
musicPlayer.Destroy();
|
||||
});
|
||||
|
||||
cgb.CreateCommand("pause")
|
||||
.Alias("p")
|
||||
.Description("Pauses or Unpauses the song.\n**Usage**: `!m p`")
|
||||
cgb.CreateCommand(Prefix + "pause")
|
||||
.Alias(Prefix + "p")
|
||||
.Description($"Pauses or Unpauses the song. | `{Prefix}p`")
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
@ -92,15 +92,15 @@ namespace NadekoBot.Modules.Music
|
||||
await e.Channel.SendMessage("🎵`Music Player unpaused.`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("queue")
|
||||
.Alias("q")
|
||||
.Alias("yq")
|
||||
cgb.CreateCommand(Prefix + "queue")
|
||||
.Alias(Prefix + "q")
|
||||
.Alias(Prefix + "yq")
|
||||
.Description("Queue a song using keywords or a link. Bot will join your voice channel." +
|
||||
"**You must be in a voice channel**.\n**Usage**: `!m q Dream Of Venice`")
|
||||
$"**You must be in a voice channel**. | `{Prefix}q Dream Of Venice`")
|
||||
.Parameter("query", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
await QueueSong(e.Channel, e.User.VoiceChannel, e.GetArg("query")).ConfigureAwait(false);
|
||||
await QueueSong(e.User, e.Channel, e.User.VoiceChannel, e.GetArg("query")).ConfigureAwait(false);
|
||||
if (e.Server.CurrentUser.GetPermissions(e.Channel).ManageMessages)
|
||||
{
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
@ -108,24 +108,24 @@ namespace NadekoBot.Modules.Music
|
||||
}
|
||||
});
|
||||
|
||||
//cgb.CreateCommand("soundcloudqueue")
|
||||
// .Alias("sq")
|
||||
// .Description("Queue a soundcloud song using keywords. Bot will join your voice channel." +
|
||||
// "**You must be in a voice channel**.\n**Usage**: `!m sq Dream Of Venice`")
|
||||
// .Parameter("query", ParameterType.Unparsed)
|
||||
// .Do(async e =>
|
||||
// {
|
||||
// await QueueSong(e.Channel, e.User.VoiceChannel, e.GetArg("query")).ConfigureAwait(false);
|
||||
// if (e.Server.CurrentUser.GetPermissions(e.Channel).ManageMessages)
|
||||
// {
|
||||
// await Task.Delay(10000).ConfigureAwait(false);
|
||||
// await e.Message.Delete().ConfigureAwait(false);
|
||||
// }
|
||||
// });
|
||||
cgb.CreateCommand(Prefix + "soundcloudqueue")
|
||||
.Alias(Prefix + "sq")
|
||||
.Description("Queue a soundcloud song using keywords. Bot will join your voice channel." +
|
||||
$"**You must be in a voice channel**. | `{Prefix}sq Dream Of Venice`")
|
||||
.Parameter("query", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
await QueueSong(e.User, e.Channel, e.User.VoiceChannel, e.GetArg("query"), musicType: MusicType.Soundcloud).ConfigureAwait(false);
|
||||
if (e.Server.CurrentUser.GetPermissions(e.Channel).ManageMessages)
|
||||
{
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await e.Message.Delete().ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("listqueue")
|
||||
.Alias("lq")
|
||||
.Description("Lists 15 currently queued songs per page. Default page is 1.\n**Usage**: `!m lq` or `!m lq 2`")
|
||||
cgb.CreateCommand(Prefix + "listqueue")
|
||||
.Alias(Prefix + "lq")
|
||||
.Description($"Lists 15 currently queued songs per page. Default page is 1. | `{Prefix}lq` or `{Prefix}lq 2`")
|
||||
.Parameter("page", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -151,7 +151,7 @@ namespace NadekoBot.Modules.Music
|
||||
else if (musicPlayer.RepeatPlaylist)
|
||||
toSend += "🔁";
|
||||
toSend += $" **{musicPlayer.Playlist.Count}** `tracks currently queued. Showing page {page}` ";
|
||||
if (musicPlayer.Playlist.Count >= MusicPlayer.MaximumPlaylistSize)
|
||||
if (musicPlayer.MaxQueueSize != 0 && musicPlayer.Playlist.Count >= musicPlayer.MaxQueueSize)
|
||||
toSend += "**Song queue is full!**\n";
|
||||
else
|
||||
toSend += "\n";
|
||||
@ -161,9 +161,9 @@ namespace NadekoBot.Modules.Music
|
||||
await e.Channel.SendMessage(toSend + string.Join("\n", musicPlayer.Playlist.Skip(startAt).Take(15).Select(v => $"`{number++}.` {v.PrettyName}"))).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("nowplaying")
|
||||
.Alias("np")
|
||||
.Description("Shows the song currently playing.\n**Usage**: `!m np`")
|
||||
cgb.CreateCommand(Prefix + "nowplaying")
|
||||
.Alias(Prefix + "np")
|
||||
.Description($"Shows the song currently playing. | `{Prefix}np`")
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
@ -176,9 +176,9 @@ namespace NadekoBot.Modules.Music
|
||||
$"{currentSong.PrettyCurrentTime()}").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("volume")
|
||||
.Alias("vol")
|
||||
.Description("Sets the music volume 0-100%\n**Usage**: `!m vol 50`")
|
||||
cgb.CreateCommand(Prefix + "volume")
|
||||
.Alias(Prefix + "vol")
|
||||
.Description($"Sets the music volume 0-100% | `{Prefix}vol 50`")
|
||||
.Parameter("val", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -198,10 +198,10 @@ namespace NadekoBot.Modules.Music
|
||||
await e.Channel.SendMessage($"🎵 `Volume set to {volume}%`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("defvol")
|
||||
.Alias("dv")
|
||||
cgb.CreateCommand(Prefix + "defvol")
|
||||
.Alias(Prefix + "dv")
|
||||
.Description("Sets the default music volume when music playback is started (0-100)." +
|
||||
" Does not persist through restarts.\n**Usage**: `!m dv 80`")
|
||||
$" Persists through restarts. | `{Prefix}dv 80`")
|
||||
.Parameter("val", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -217,8 +217,9 @@ namespace NadekoBot.Modules.Music
|
||||
await e.Channel.SendMessage($"🎵 `Default volume set to {volume}%`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("mute").Alias("min")
|
||||
.Description("Sets the music volume to 0%\n**Usage**: `!m min`")
|
||||
cgb.CreateCommand(Prefix + "mute")
|
||||
.Alias(Prefix + "min")
|
||||
.Description($"Sets the music volume to 0% | `{Prefix}min`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
@ -229,8 +230,8 @@ namespace NadekoBot.Modules.Music
|
||||
musicPlayer.SetVolume(0);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("max")
|
||||
.Description("Sets the music volume to 100% (real max is actually 150%).\n**Usage**: `!m max`")
|
||||
cgb.CreateCommand(Prefix + "max")
|
||||
.Description($"Sets the music volume to 100%. | `{Prefix}max`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
@ -241,8 +242,8 @@ namespace NadekoBot.Modules.Music
|
||||
musicPlayer.SetVolume(100);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("half")
|
||||
.Description("Sets the music volume to 50%.\n**Usage**: `!m half`")
|
||||
cgb.CreateCommand(Prefix + "half")
|
||||
.Description($"Sets the music volume to 50%. | `{Prefix}half`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
@ -253,9 +254,9 @@ namespace NadekoBot.Modules.Music
|
||||
musicPlayer.SetVolume(50);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("shuffle")
|
||||
.Alias("sh")
|
||||
.Description("Shuffles the current playlist.\n**Usage**: `!m sh`")
|
||||
cgb.CreateCommand(Prefix + "shuffle")
|
||||
.Alias(Prefix + "sh")
|
||||
.Description($"Shuffles the current playlist. | `{Prefix}sh`")
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
@ -273,9 +274,9 @@ namespace NadekoBot.Modules.Music
|
||||
await e.Channel.SendMessage("🎵 `Songs shuffled.`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("playlist")
|
||||
.Alias("pl")
|
||||
.Description("Queues up to 50 songs from a youtube playlist specified by a link, or keywords.\n**Usage**: `!m pl playlist link or name`")
|
||||
cgb.CreateCommand(Prefix + "playlist")
|
||||
.Alias(Prefix + "pl")
|
||||
.Description($"Queues up to 500 songs from a youtube playlist specified by a link, or keywords. | `{Prefix}pl playlist link or name`")
|
||||
.Parameter("playlist", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -296,10 +297,9 @@ namespace NadekoBot.Modules.Music
|
||||
var ids = await SearchHelper.GetVideoIDs(plId, 500).ConfigureAwait(false);
|
||||
if (ids == null || ids.Count == 0)
|
||||
{
|
||||
await e.Channel.SendMessage($"🎵`Failed to find any songs.`");
|
||||
await e.Channel.SendMessage($"🎵 `Failed to find any songs.`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
//todo TEMPORARY SOLUTION, USE RESOLVE QUEUE IN THE FUTURE
|
||||
var idArray = ids as string[] ?? ids.ToArray();
|
||||
var count = idArray.Length;
|
||||
var msg =
|
||||
@ -308,16 +308,18 @@ namespace NadekoBot.Modules.Music
|
||||
{
|
||||
try
|
||||
{
|
||||
await QueueSong(e.Channel, e.User.VoiceChannel, id, true).ConfigureAwait(false);
|
||||
await QueueSong(e.User, e.Channel, e.User.VoiceChannel, id, true).ConfigureAwait(false);
|
||||
}
|
||||
catch (PlaylistFullException)
|
||||
{ break; }
|
||||
catch { }
|
||||
}
|
||||
await msg.Edit("🎵 `Playlist queue complete.`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("soundcloudpl")
|
||||
.Alias("scpl")
|
||||
.Description("Queue a soundcloud playlist using a link. | `!m scpl https://soundcloud.com/saratology/sets/symphony`")
|
||||
cgb.CreateCommand(Prefix + "soundcloudpl")
|
||||
.Alias(Prefix + "scpl")
|
||||
.Description($"Queue a soundcloud playlist using a link. | `{Prefix}scpl https://soundcloud.com/saratology/sets/symphony`")
|
||||
.Parameter("pl", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -326,14 +328,16 @@ namespace NadekoBot.Modules.Music
|
||||
if (string.IsNullOrWhiteSpace(pl))
|
||||
return;
|
||||
|
||||
var scvids = JObject.Parse(await SearchHelper.GetResponseStringAsync($"http://api.soundcloud.com/resolve?url={pl}&client_id={NadekoBot.Creds.SoundCloudClientID}"))["tracks"].ToObject<SoundCloudVideo[]>();
|
||||
await QueueSong(e.Channel, e.User.VoiceChannel, scvids[0].TrackLink);
|
||||
var scvids = JObject.Parse(await SearchHelper.GetResponseStringAsync($"http://api.soundcloud.com/resolve?url={pl}&client_id={NadekoBot.Creds.SoundCloudClientID}").ConfigureAwait(false))["tracks"].ToObject<SoundCloudVideo[]>();
|
||||
await QueueSong(e.User, e.Channel, e.User.VoiceChannel, scvids[0].TrackLink).ConfigureAwait(false);
|
||||
|
||||
MusicPlayer mp;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out mp))
|
||||
return;
|
||||
|
||||
foreach (var svideo in scvids.Skip(1))
|
||||
{
|
||||
try
|
||||
{
|
||||
mp.AddSong(new Song(new Classes.SongInfo
|
||||
{
|
||||
@ -342,13 +346,15 @@ namespace NadekoBot.Modules.Music
|
||||
Uri = svideo.StreamLink,
|
||||
ProviderType = MusicType.Normal,
|
||||
Query = svideo.TrackLink,
|
||||
}));
|
||||
}), e.User.Name);
|
||||
}
|
||||
catch (PlaylistFullException) { break; }
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("localplaylst")
|
||||
.Alias("lopl")
|
||||
.Description("Queues all songs from a directory. **Bot Owner Only!**\n**Usage**: `!m lopl C:/music/classical`")
|
||||
cgb.CreateCommand(Prefix + "localplaylst")
|
||||
.Alias(Prefix + "lopl")
|
||||
.Description($"Queues all songs from a directory. **Bot Owner Only!** | `{Prefix}lopl C:/music/classical`")
|
||||
.Parameter("directory", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
@ -362,15 +368,23 @@ namespace NadekoBot.Modules.Music
|
||||
.Where(x => !x.Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System));
|
||||
foreach (var file in fileEnum)
|
||||
{
|
||||
await QueueSong(e.Channel, e.User.VoiceChannel, file.FullName, true, MusicType.Local).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await QueueSong(e.User, e.Channel, e.User.VoiceChannel, file.FullName, true, MusicType.Local).ConfigureAwait(false);
|
||||
}
|
||||
catch (PlaylistFullException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
await e.Channel.SendMessage("🎵 `Directory queue complete.`").ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
|
||||
cgb.CreateCommand("radio").Alias("ra")
|
||||
.Description("Queues a radio stream from a link. It can be a direct mp3 radio stream, .m3u, .pls .asx or .xspf\n**Usage**: `!m ra radio link here`")
|
||||
cgb.CreateCommand(Prefix + "radio").Alias(Prefix + "ra")
|
||||
.Description($"Queues a radio stream from a link. It can be a direct mp3 radio stream, .m3u, .pls .asx or .xspf (Usage Video: <https://streamable.com/al54>) | `{Prefix}ra radio link here`")
|
||||
.Parameter("radio_link", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -379,7 +393,7 @@ namespace NadekoBot.Modules.Music
|
||||
await e.Channel.SendMessage("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
await QueueSong(e.Channel, e.User.VoiceChannel, e.GetArg("radio_link"), musicType: MusicType.Radio).ConfigureAwait(false);
|
||||
await QueueSong(e.User, e.Channel, e.User.VoiceChannel, e.GetArg("radio_link"), musicType: MusicType.Radio).ConfigureAwait(false);
|
||||
if (e.Server.CurrentUser.GetPermissions(e.Channel).ManageMessages)
|
||||
{
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
@ -387,9 +401,9 @@ namespace NadekoBot.Modules.Music
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("local")
|
||||
.Alias("lo")
|
||||
.Description("Queues a local file by specifying a full path. **Bot Owner Only!**\n**Usage**: `!m lo C:/music/mysong.mp3`")
|
||||
cgb.CreateCommand(Prefix + "local")
|
||||
.Alias(Prefix + "lo")
|
||||
.Description($"Queues a local file by specifying a full path. **Bot Owner Only!** | `{Prefix}lo C:/music/mysong.mp3`")
|
||||
.Parameter("path", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
@ -397,12 +411,12 @@ namespace NadekoBot.Modules.Music
|
||||
var arg = e.GetArg("path");
|
||||
if (string.IsNullOrWhiteSpace(arg))
|
||||
return;
|
||||
await QueueSong(e.Channel, e.User.VoiceChannel, e.GetArg("path"), musicType: MusicType.Local).ConfigureAwait(false);
|
||||
await QueueSong(e.User, e.Channel, e.User.VoiceChannel, e.GetArg("path"), musicType: MusicType.Local).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("move")
|
||||
.Alias("mv")
|
||||
.Description("Moves the bot to your voice channel. (works only if music is already playing)\n**Usage**: `!m mv`")
|
||||
cgb.CreateCommand(Prefix + "move")
|
||||
.Alias(Prefix + "mv")
|
||||
.Description($"Moves the bot to your voice channel. (works only if music is already playing) | `{Prefix}mv`")
|
||||
.Do(e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
@ -412,9 +426,9 @@ namespace NadekoBot.Modules.Music
|
||||
musicPlayer.MoveToVoiceChannel(voiceChannel);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("remove")
|
||||
.Alias("rm")
|
||||
.Description("Remove a song by its # in the queue, or 'all' to remove whole queue.\n**Usage**: `!m rm 5`")
|
||||
cgb.CreateCommand(Prefix + "remove")
|
||||
.Alias(Prefix + "rm")
|
||||
.Description($"Remove a song by its # in the queue, or 'all' to remove whole queue. | `{Prefix}rm 5`")
|
||||
.Parameter("num", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -445,9 +459,9 @@ namespace NadekoBot.Modules.Music
|
||||
});
|
||||
|
||||
//var msRegex = new Regex(@"(?<n1>\d+)>(?<n2>\d+)", RegexOptions.Compiled);
|
||||
cgb.CreateCommand("movesong")
|
||||
.Alias("ms")
|
||||
.Description($"Moves a song from one position to another.\n**Usage**: `{Prefix} ms` 5>3")
|
||||
cgb.CreateCommand(Prefix + "movesong")
|
||||
.Alias(Prefix + "ms")
|
||||
.Description($"Moves a song from one position to another. | `{Prefix} ms` 5>3")
|
||||
.Parameter("fromto")
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -468,7 +482,7 @@ namespace NadekoBot.Modules.Music
|
||||
!int.TryParse(fromtoArr[1], out n2) || n1 < 1 || n2 < 1 || n1 == n2 ||
|
||||
n1 > playlist.Count || n2 > playlist.Count)
|
||||
{
|
||||
await e.Channel.SendMessage("`Invalid input.`");
|
||||
await e.Channel.SendMessage("`Invalid input.`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -477,12 +491,35 @@ namespace NadekoBot.Modules.Music
|
||||
var nn1 = n2 < n1 ? n1 : n1 - 1;
|
||||
playlist.RemoveAt(nn1);
|
||||
|
||||
await e.Channel.SendMessage($"🎵`Moved` {s.PrettyName} `from #{n1} to #{n2}`");
|
||||
await e.Channel.SendMessage($"🎵`Moved` {s.PrettyName} `from #{n1} to #{n2}`").ConfigureAwait(false);
|
||||
|
||||
});
|
||||
|
||||
cgb.CreateCommand("cleanup")
|
||||
.Description("Cleans up hanging voice connections. **Bot Owner Only!**\n**Usage**: `!m cleanup`")
|
||||
cgb.CreateCommand(Prefix + "setmaxqueue")
|
||||
.Alias(Prefix + "smq")
|
||||
.Description($"Sets a maximum queue size. Supply 0 or no argument to have no limit. | `{Prefix}smq` 50 or `{Prefix}smq`")
|
||||
.Parameter("size", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sizeStr = e.GetArg("size")?.Trim();
|
||||
uint size = 0;
|
||||
if (string.IsNullOrWhiteSpace(sizeStr) || !uint.TryParse(sizeStr, out size))
|
||||
{
|
||||
size = 0;
|
||||
}
|
||||
|
||||
musicPlayer.MaxQueueSize = size;
|
||||
await e.Channel.SendMessage($"🎵 `Max queue set to {(size == 0 ? ("unlimited") : size + " tracks")}`");
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "cleanup")
|
||||
.Description($"Cleans up hanging voice connections. **Bot Owner Only!** | `{Prefix}cleanup`")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(e =>
|
||||
{
|
||||
@ -499,9 +536,9 @@ namespace NadekoBot.Modules.Music
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("reptcursong")
|
||||
.Alias("rcs")
|
||||
.Description("Toggles repeat of current song.\n**Usage**: `!m rcs`")
|
||||
cgb.CreateCommand(Prefix + "reptcursong")
|
||||
.Alias(Prefix + "rcs")
|
||||
.Description($"Toggles repeat of current song. | `{Prefix}rcs`")
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
@ -517,9 +554,9 @@ namespace NadekoBot.Modules.Music
|
||||
.ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("rpeatplaylst")
|
||||
.Alias("rpl")
|
||||
.Description("Toggles repeat of all songs in the queue (every song that finishes is added to the end of the queue).\n**Usage**: `!m rpl`")
|
||||
cgb.CreateCommand(Prefix + "rpeatplaylst")
|
||||
.Alias(Prefix + "rpl")
|
||||
.Description($"Toggles repeat of all songs in the queue (every song that finishes is added to the end of the queue). | `{Prefix}rpl`")
|
||||
.Do(async e =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
@ -529,8 +566,8 @@ namespace NadekoBot.Modules.Music
|
||||
await e.Channel.SendMessage($"🎵🔁`Repeat playlist {(currentValue ? "enabled" : "disabled")}`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("save")
|
||||
.Description("Saves a playlist under a certain name. Name must be no longer than 20 characters and mustn't contain dashes.\n**Usage**: `!m save classical1`")
|
||||
cgb.CreateCommand(Prefix + "save")
|
||||
.Description($"Saves a playlist under a certain name. Name must be no longer than 20 characters and mustn't contain dashes. | `{Prefix}save classical1`")
|
||||
.Parameter("name", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -582,8 +619,8 @@ namespace NadekoBot.Modules.Music
|
||||
|
||||
});
|
||||
|
||||
cgb.CreateCommand("load")
|
||||
.Description("Loads a playlist under a certain name. \n**Usage**: `!m load classical-1`")
|
||||
cgb.CreateCommand(Prefix + "load")
|
||||
.Description($"Loads a playlist under a certain name. | `{Prefix}load classical-1`")
|
||||
.Parameter("name", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -628,7 +665,11 @@ namespace NadekoBot.Modules.Music
|
||||
{
|
||||
try
|
||||
{
|
||||
await QueueSong(textCh, voiceCh, si.Query, true, (MusicType)si.ProviderType).ConfigureAwait(false);
|
||||
await QueueSong(e.User, textCh, voiceCh, si.Query, true, (MusicType)si.ProviderType).ConfigureAwait(false);
|
||||
}
|
||||
catch (PlaylistFullException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -637,9 +678,9 @@ namespace NadekoBot.Modules.Music
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("playlists")
|
||||
.Alias("pls")
|
||||
.Description("Lists all playlists. Paginated. 20 per page. Default page is 0.\n**Usage**:`!m pls 1`")
|
||||
cgb.CreateCommand(Prefix + "playlists")
|
||||
.Alias(Prefix + "pls")
|
||||
.Description($"Lists all playlists. Paginated. 20 per page. Default page is 0. |`{Prefix}pls 1`")
|
||||
.Parameter("num", ParameterType.Optional)
|
||||
.Do(e =>
|
||||
{
|
||||
@ -649,14 +690,14 @@ namespace NadekoBot.Modules.Music
|
||||
return;
|
||||
var result = DbHandler.Instance.GetPlaylistData(num);
|
||||
if (result.Count == 0)
|
||||
e.Channel.SendMessage($"`No saved playlists found on page {num}`");
|
||||
e.Channel.SendMessage($"`No saved playlists found on page {num}`").ConfigureAwait(false);
|
||||
else
|
||||
e.Channel.SendMessage($"```js\n--- List of saved playlists ---\n\n" + string.Join("\n", result.Select(r => $"'{r.Name}-{r.Id}' by {r.Creator} ({r.SongCnt} songs)")) + $"\n\n --- Page {num} ---```");
|
||||
e.Channel.SendMessage($"```js\n--- List of saved playlists ---\n\n" + string.Join("\n", result.Select(r => $"'{r.Name}-{r.Id}' by {r.Creator} ({r.SongCnt} songs)")) + $"\n\n --- Page {num} ---```").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("deleteplaylist")
|
||||
.Alias("delpls")
|
||||
.Description("Deletes a saved playlist. Only if you made it or if you are the bot owner. | `!m delpls animu-5`")
|
||||
cgb.CreateCommand(Prefix + "deleteplaylist")
|
||||
.Alias(Prefix + "delpls")
|
||||
.Description($"Deletes a saved playlist. Only if you made it or if you are the bot owner. | `{Prefix}delpls animu-5`")
|
||||
.Parameter("pl", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -668,10 +709,10 @@ namespace NadekoBot.Modules.Music
|
||||
DbHandler.Instance.Delete<MusicPlaylist>(plnum);
|
||||
else
|
||||
DbHandler.Instance.DeleteWhere<MusicPlaylist>(mp => mp.Id == plnum && (long)e.User.Id == mp.CreatorId);
|
||||
await e.Channel.SendMessage("`Ok.` :ok:");
|
||||
await e.Channel.SendMessage("`Ok.` :ok:").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("goto")
|
||||
cgb.CreateCommand(Prefix + "goto")
|
||||
.Description("Goes to a specific time in seconds in a song.")
|
||||
.Parameter("time")
|
||||
.Do(async e =>
|
||||
@ -708,8 +749,8 @@ namespace NadekoBot.Modules.Music
|
||||
await e.Channel.SendMessage($"`Skipped to {minutes}:{seconds}`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("getlink")
|
||||
.Alias("gl")
|
||||
cgb.CreateCommand(Prefix + "getlink")
|
||||
.Alias(Prefix + "gl")
|
||||
.Description("Shows a link to the currently playing song.")
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -719,11 +760,11 @@ namespace NadekoBot.Modules.Music
|
||||
var curSong = musicPlayer.CurrentSong;
|
||||
if (curSong == null)
|
||||
return;
|
||||
await e.Channel.SendMessage($"🎶`Current song:` <{curSong.SongInfo.Query}>");
|
||||
await e.Channel.SendMessage($"🎶`Current song:` <{curSong.SongInfo.Query}>").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("autoplay")
|
||||
.Alias("ap")
|
||||
cgb.CreateCommand(Prefix + "autoplay")
|
||||
.Alias(Prefix + "ap")
|
||||
.Description("Toggles autoplay - When the song is finished, automatically queue a related youtube song. (Works only for youtube songs and when queue is empty)")
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -733,14 +774,14 @@ namespace NadekoBot.Modules.Music
|
||||
return;
|
||||
|
||||
if (!musicPlayer.ToggleAutoplay())
|
||||
await e.Channel.SendMessage("🎶`Autoplay disabled.`");
|
||||
await e.Channel.SendMessage("🎶`Autoplay disabled.`").ConfigureAwait(false);
|
||||
else
|
||||
await e.Channel.SendMessage("🎶`Autoplay enabled.`");
|
||||
await e.Channel.SendMessage("🎶`Autoplay enabled.`").ConfigureAwait(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static async Task QueueSong(Channel textCh, Channel voiceCh, string query, bool silent = false, MusicType musicType = MusicType.Normal)
|
||||
public static async Task QueueSong(User queuer, Channel textCh, Channel voiceCh, string query, bool silent = false, MusicType musicType = MusicType.Normal)
|
||||
{
|
||||
if (voiceCh == null || voiceCh.Server != textCh.Server)
|
||||
{
|
||||
@ -772,7 +813,7 @@ namespace NadekoBot.Modules.Music
|
||||
lastFinishedMessage = await textCh.SendMessage($"🎵`Finished`{song.PrettyName}").ConfigureAwait(false);
|
||||
if (mp.Autoplay && mp.Playlist.Count == 0 && song.SongInfo.Provider == "YouTube")
|
||||
{
|
||||
await QueueSong(textCh, voiceCh, await SearchHelper.GetRelatedVideoId(song.SongInfo.Query), silent, musicType).ConfigureAwait(false);
|
||||
await QueueSong(queuer, textCh, voiceCh, await SearchHelper.GetRelatedVideoId(song.SongInfo.Query), silent, musicType).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -800,8 +841,19 @@ namespace NadekoBot.Modules.Music
|
||||
};
|
||||
return mp;
|
||||
});
|
||||
var resolvedSong = await Song.ResolveSong(query, musicType).ConfigureAwait(false);
|
||||
musicPlayer.AddSong(resolvedSong);
|
||||
Song resolvedSong;
|
||||
try
|
||||
{
|
||||
musicPlayer.ThrowIfQueueFull();
|
||||
resolvedSong = await Song.ResolveSong(query, musicType).ConfigureAwait(false);
|
||||
|
||||
musicPlayer.AddSong(resolvedSong, queuer.Name);
|
||||
}
|
||||
catch (PlaylistFullException)
|
||||
{
|
||||
await textCh.SendMessage($"🎵 `Queue is full at {musicPlayer.MaxQueueSize}/{musicPlayer.MaxQueueSize}.` ");
|
||||
throw;
|
||||
}
|
||||
if (!silent)
|
||||
{
|
||||
var queuedMessage = await textCh.SendMessage($"🎵`Queued`{resolvedSong.PrettyName} **at** `#{musicPlayer.Playlist.Count}`").ConfigureAwait(false);
|
||||
|
@ -22,7 +22,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
cgb.AddCheck(PermissionChecker.Instance);
|
||||
|
||||
cgb.CreateCommand(Prefix + "hentai")
|
||||
.Description("Shows a random NSFW hentai image from gelbooru and danbooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +)\n**Usage**: ~hentai yuri+kissing")
|
||||
.Description("Shows a random NSFW hentai image from gelbooru and danbooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +) | ~hentai yuri+kissing")
|
||||
.Parameter("tag", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -39,7 +39,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
await e.Channel.SendMessage("`No results.`");
|
||||
});
|
||||
cgb.CreateCommand(Prefix + "danbooru")
|
||||
.Description("Shows a random hentai image from danbooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +)\n**Usage**: ~danbooru yuri+kissing")
|
||||
.Description("Shows a random hentai image from danbooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +) | ~danbooru yuri+kissing")
|
||||
.Parameter("tag", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -51,7 +51,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
await e.Channel.SendMessage(link).ConfigureAwait(false);
|
||||
});
|
||||
cgb.CreateCommand(Prefix + "gelbooru")
|
||||
.Description("Shows a random hentai image from gelbooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +)\n**Usage**: ~gelbooru yuri+kissing")
|
||||
.Description("Shows a random hentai image from gelbooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +) | ~gelbooru yuri+kissing")
|
||||
.Parameter("tag", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -64,7 +64,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "rule34")
|
||||
.Description("Shows a random image from rule34.xx with a given tag. Tag is optional but preffered. (multiple tags are appended with +)\n**Usage**: ~rule34 yuri+kissing")
|
||||
.Description("Shows a random image from rule34.xx with a given tag. Tag is optional but preffered. (multiple tags are appended with +) | ~rule34 yuri+kissing")
|
||||
.Parameter("tag", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -76,7 +76,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
await e.Channel.SendMessage(link).ConfigureAwait(false);
|
||||
});
|
||||
cgb.CreateCommand(Prefix + "e621")
|
||||
.Description("Shows a random hentai image from e621.net with a given tag. Tag is optional but preffered. Use spaces for multiple tags.\n**Usage**: ~e621 yuri kissing")
|
||||
.Description("Shows a random hentai image from e621.net with a given tag. Tag is optional but preffered. Use spaces for multiple tags. | ~e621 yuri kissing")
|
||||
.Parameter("tag", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ using Discord.Commands.Permissions;
|
||||
using NadekoBot.Classes.JSONModels;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions.Classes
|
||||
@ -13,7 +14,10 @@ namespace NadekoBot.Modules.Permissions.Classes
|
||||
{
|
||||
public static PermissionChecker Instance { get; } = new PermissionChecker();
|
||||
|
||||
private ConcurrentDictionary<User, DateTime> timeBlackList { get; } = new ConcurrentDictionary<User, DateTime>();
|
||||
//key - sid:command
|
||||
//value - userid
|
||||
private ConcurrentDictionary<string, ulong> commandCooldowns = new ConcurrentDictionary<string, ulong>();
|
||||
private HashSet<ulong> timeBlackList { get; } = new HashSet<ulong>();
|
||||
|
||||
static PermissionChecker() { }
|
||||
private PermissionChecker()
|
||||
@ -22,8 +26,8 @@ namespace NadekoBot.Modules.Permissions.Classes
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
//blacklist is cleared every 1.75 seconds. That is the most time anyone will be blocked
|
||||
await Task.Delay(1750).ConfigureAwait(false);
|
||||
//blacklist is cleared every 1.00 seconds. That is the most time anyone will be blocked
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
timeBlackList.Clear();
|
||||
}
|
||||
});
|
||||
@ -46,18 +50,26 @@ namespace NadekoBot.Modules.Permissions.Classes
|
||||
return false;
|
||||
}
|
||||
|
||||
if (timeBlackList.ContainsKey(user))
|
||||
if (timeBlackList.Contains(user.Id))
|
||||
return false;
|
||||
|
||||
timeBlackList.TryAdd(user, DateTime.Now);
|
||||
|
||||
if (!channel.IsPrivate && !channel.Server.CurrentUser.GetPermissions(channel).SendMessages)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//{
|
||||
// user.SendMessage($"I ignored your command in {channel.Server.Name}/#{channel.Name} because i don't have permissions to write to it. Please use `;acm channel_name 0` in that server instead of muting me.").GetAwaiter().GetResult();
|
||||
//}
|
||||
|
||||
timeBlackList.Add(user.Id);
|
||||
|
||||
ServerPermissions perms;
|
||||
PermissionsHandler.PermissionsDict.TryGetValue(user.Server.Id, out perms);
|
||||
|
||||
AddUserCooldown(user.Server.Id, user.Id, command.Text.ToLower());
|
||||
if (commandCooldowns.Keys.Contains(user.Server.Id+":"+command.Text.ToLower()))
|
||||
{
|
||||
if(perms?.Verbose == true)
|
||||
error = $"{user.Mention} You have a cooldown on that command.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@ -75,8 +87,6 @@ namespace NadekoBot.Modules.Permissions.Classes
|
||||
catch { }
|
||||
if (user.Server.Owner.Id == user.Id || (role != null && user.HasRole(role)))
|
||||
return true;
|
||||
ServerPermissions perms;
|
||||
PermissionsHandler.PermissionsDict.TryGetValue(user.Server.Id, out perms);
|
||||
throw new Exception($"You don't have the necessary role (**{(perms?.PermissionsControllerRole ?? "Nadeko")}**) to change permissions.");
|
||||
}
|
||||
|
||||
@ -128,8 +138,7 @@ namespace NadekoBot.Modules.Permissions.Classes
|
||||
Console.WriteLine($"Exception in canrun: {ex}");
|
||||
try
|
||||
{
|
||||
ServerPermissions perms;
|
||||
if (PermissionsHandler.PermissionsDict.TryGetValue(user.Server.Id, out perms) && perms.Verbose)
|
||||
if (perms != null && perms.Verbose)
|
||||
//if verbose - print errors
|
||||
error = ex.Message;
|
||||
}
|
||||
@ -140,5 +149,26 @@ namespace NadekoBot.Modules.Permissions.Classes
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddUserCooldown(ulong serverId, ulong userId, string commandName) {
|
||||
commandCooldowns.TryAdd(commandName, userId);
|
||||
var tosave = serverId + ":" + commandName;
|
||||
Task.Run(async () =>
|
||||
{
|
||||
ServerPermissions perms;
|
||||
PermissionsHandler.PermissionsDict.TryGetValue(serverId, out perms);
|
||||
int cd;
|
||||
if (!perms.CommandCooldowns.TryGetValue(commandName,out cd)) {
|
||||
return;
|
||||
}
|
||||
if (commandCooldowns.TryAdd(tosave, userId))
|
||||
{
|
||||
await Task.Delay(cd * 1000);
|
||||
ulong throwaway;
|
||||
commandCooldowns.TryRemove(tosave, out throwaway);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,9 +55,11 @@ namespace NadekoBot.Modules.Permissions.Classes
|
||||
if (string.IsNullOrWhiteSpace(commandText))
|
||||
throw new ArgumentNullException(nameof(commandText));
|
||||
|
||||
var normalizedCmdTxt = commandText.Trim().ToUpperInvariant();
|
||||
|
||||
foreach (var com in NadekoBot.Client.GetService<CommandService>().AllCommands)
|
||||
{
|
||||
if (com.Text.ToLower().Equals(commandText.Trim().ToLower()))
|
||||
if (com.Text.ToUpperInvariant().Equals(normalizedCmdTxt) || com.Aliases.Select(c=>c.ToUpperInvariant()).Contains(normalizedCmdTxt))
|
||||
return com.Text;
|
||||
}
|
||||
throw new NullReferenceException("That command does not exist.");
|
||||
|
@ -424,6 +424,21 @@ namespace NadekoBot.Modules.Permissions.Classes
|
||||
Task.Run(() => WriteServerToJson(serverPerms));
|
||||
}
|
||||
|
||||
public static void SetCommandCooldown(Server server, string commandName, int value)
|
||||
{
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
new ServerPermissions(server.Id, server.Name));
|
||||
if (value == 0) {
|
||||
int throwaway;
|
||||
serverPerms.CommandCooldowns.TryRemove(commandName, out throwaway);
|
||||
}
|
||||
else {
|
||||
serverPerms.CommandCooldowns.AddOrUpdate(commandName, value, (str, v) => value);
|
||||
}
|
||||
|
||||
Task.Run(() => WriteServerToJson(serverPerms));
|
||||
}
|
||||
|
||||
public static void AddFilteredWord(Server server, string word)
|
||||
{
|
||||
var serverPerms = PermissionsDict.GetOrAdd(server.Id,
|
||||
@ -537,6 +552,10 @@ namespace NadekoBot.Modules.Permissions.Classes
|
||||
public Dictionary<ulong, Permissions> UserPermissions { get; set; }
|
||||
public Dictionary<ulong, Permissions> ChannelPermissions { get; set; }
|
||||
public Dictionary<ulong, Permissions> RolePermissions { get; set; }
|
||||
/// <summary>
|
||||
/// Dictionary of command names with their respective cooldowns
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<string, int> CommandCooldowns { get; set; }
|
||||
|
||||
public ServerPermissions(ulong id, string name)
|
||||
{
|
||||
@ -549,6 +568,7 @@ namespace NadekoBot.Modules.Permissions.Classes
|
||||
UserPermissions = new Dictionary<ulong, Permissions>();
|
||||
ChannelPermissions = new Dictionary<ulong, Permissions>();
|
||||
RolePermissions = new Dictionary<ulong, Permissions>();
|
||||
CommandCooldowns = new ConcurrentDictionary<string, int>();
|
||||
Words = new HashSet<string>();
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
.Alias(Module.Prefix + "cfi")
|
||||
.Description("Enables or disables automatic deleting of invites on the channel." +
|
||||
"If no channel supplied, it will default to current one. Use ALL to apply to all existing channels at once." +
|
||||
"\n**Usage**: ;cfi enable #general-chat")
|
||||
" | ;cfi enable #general-chat")
|
||||
.Parameter("bool")
|
||||
.Parameter("channel", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
@ -95,7 +95,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "srvrfilterinv")
|
||||
.Alias(Module.Prefix + "sfi")
|
||||
.Description("Enables or disables automatic deleting of invites on the server.\n**Usage**: ;sfi disable")
|
||||
.Description("Enables or disables automatic deleting of invites on the server. | ;sfi disable")
|
||||
.Parameter("bool")
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
.Alias(Module.Prefix + "cfw")
|
||||
.Description("Enables or disables automatic deleting of messages containing banned words on the channel." +
|
||||
"If no channel supplied, it will default to current one. Use ALL to apply to all existing channels at once." +
|
||||
"\n**Usage**: ;cfw enable #general-chat")
|
||||
" | ;cfw enable #general-chat")
|
||||
.Parameter("bool")
|
||||
.Parameter("channel", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
@ -89,7 +89,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "addfilterword")
|
||||
.Alias(Module.Prefix + "afw")
|
||||
.Description("Adds a new word to the list of filtered words" +
|
||||
"\n**Usage**: ;afw poop")
|
||||
" | ;afw poop")
|
||||
.Parameter("word", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -111,7 +111,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "rmvfilterword")
|
||||
.Alias(Module.Prefix + "rfw")
|
||||
.Description("Removes the word from the list of filtered words" +
|
||||
"\n**Usage**: ;rw poop")
|
||||
" | ;rw poop")
|
||||
.Parameter("word", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -133,7 +133,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "lstfilterwords")
|
||||
.Alias(Module.Prefix + "lfw")
|
||||
.Description("Shows a list of filtered words" +
|
||||
"\n**Usage**: ;lfw")
|
||||
" | ;lfw")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -152,7 +152,7 @@ namespace NadekoBot.Modules.Permissions.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "srvrfilterwords")
|
||||
.Alias(Module.Prefix + "sfw")
|
||||
.Description("Enables or disables automatic deleting of messages containing forbidden words on the server.\n**Usage**: ;sfw disable")
|
||||
.Description("Enables or disables automatic deleting of messages containing forbidden words on the server. | ;sfw disable")
|
||||
.Parameter("bool")
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Discord.Commands;
|
||||
using Discord.Modules;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Classes.JSONModels;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Games.Commands;
|
||||
@ -60,7 +61,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
|
||||
cgb.CreateCommand(Prefix + "rolepermscopy")
|
||||
.Alias(Prefix + "rpc")
|
||||
.Description($"Copies BOT PERMISSIONS (not discord permissions) from one role to another.\n**Usage**:`{Prefix}rpc Some Role ~ Some other role`")
|
||||
.Description($"Copies BOT PERMISSIONS (not discord permissions) from one role to another. |`{Prefix}rpc Some Role ~ Some other role`")
|
||||
.Parameter("from_to", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -88,7 +89,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
});
|
||||
cgb.CreateCommand(Prefix + "chnlpermscopy")
|
||||
.Alias(Prefix + "cpc")
|
||||
.Description($"Copies BOT PERMISSIONS (not discord permissions) from one channel to another.\n**Usage**:`{Prefix}cpc Some Channel ~ Some other channel`")
|
||||
.Description($"Copies BOT PERMISSIONS (not discord permissions) from one channel to another. |`{Prefix}cpc Some Channel ~ Some other channel`")
|
||||
.Parameter("from_to", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -116,7 +117,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
});
|
||||
cgb.CreateCommand(Prefix + "usrpermscopy")
|
||||
.Alias(Prefix + "upc")
|
||||
.Description($"Copies BOT PERMISSIONS (not discord permissions) from one role to another.\n**Usage**:`{Prefix}upc @SomeUser ~ @SomeOtherUser`")
|
||||
.Description($"Copies BOT PERMISSIONS (not discord permissions) from one role to another. |`{Prefix}upc @SomeUser ~ @SomeOtherUser`")
|
||||
.Parameter("from_to", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -145,7 +146,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
|
||||
cgb.CreateCommand(Prefix + "verbose")
|
||||
.Alias(Prefix + "v")
|
||||
.Description("Sets whether to show when a command/module is blocked.\n**Usage**: ;verbose true")
|
||||
.Description("Sets whether to show when a command/module is blocked. | ;verbose true")
|
||||
.Parameter("arg", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -168,7 +169,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
|
||||
cgb.CreateCommand(Prefix + "roleperms")
|
||||
.Alias(Prefix + "rp")
|
||||
.Description("Shows banned permissions for a certain role. No argument means for everyone.\n**Usage**: ;rp AwesomeRole")
|
||||
.Description("Shows banned permissions for a certain role. No argument means for everyone. | ;rp AwesomeRole")
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -194,7 +195,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
|
||||
cgb.CreateCommand(Prefix + "chnlperms")
|
||||
.Alias(Prefix + "cp")
|
||||
.Description("Shows banned permissions for a certain channel. No argument means for this channel.\n**Usage**: ;cp #dev")
|
||||
.Description("Shows banned permissions for a certain channel. No argument means for this channel. | ;cp #dev")
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -219,7 +220,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
|
||||
cgb.CreateCommand(Prefix + "userperms")
|
||||
.Alias(Prefix + "up")
|
||||
.Description("Shows banned permissions for a certain user. No argument means for yourself.\n**Usage**: ;up Kwoth")
|
||||
.Description("Shows banned permissions for a certain user. No argument means for yourself. | ;up Kwoth")
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -245,7 +246,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Alias(Prefix + "sm")
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Description("Sets a module's permission at the server level.\n**Usage**: ;sm [module_name] enable")
|
||||
.Description("Sets a module's permission at the server level. | ;sm \"module name\" enable")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -269,7 +270,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
cgb.CreateCommand(Prefix + "srvrcmd").Alias(Prefix + "sc")
|
||||
.Parameter("command", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Description("Sets a command's permission at the server level.\n**Usage**: ;sc [command_name] disable")
|
||||
.Description("Sets a command's permission at the server level. | ;sc \"command name\" disable")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -294,7 +295,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Description("Sets a module's permission at the role level.\n**Usage**: ;rm [module_name] enable [role_name]")
|
||||
.Description("Sets a module's permission at the role level. | ;rm \"module name\" enable MyRole")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -332,7 +333,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("command", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Description("Sets a command's permission at the role level.\n**Usage**: ;rc [command_name] disable [role_name]")
|
||||
.Description("Sets a command's permission at the role level. | ;rc \"command name\" disable MyRole")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -370,7 +371,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Description("Sets a module's permission at the channel level.\n**Usage**: ;cm [module_name] enable [channel_name]")
|
||||
.Description("Sets a module's permission at the channel level. | ;cm \"module name\" enable SomeChannel")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -413,7 +414,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("command", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Description("Sets a command's permission at the channel level.\n**Usage**: ;cc [command_name] enable [channel_name]")
|
||||
.Description("Sets a command's permission at the channel level. | ;cc \"command name\" enable SomeChannel")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -451,7 +452,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
.Description("Sets a module's permission at the user level.\n**Usage**: ;um [module_name] enable [user_name]")
|
||||
.Description("Sets a module's permission at the user level. | ;um \"module name\" enable SomeUsername")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -477,7 +478,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("command", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
.Description("Sets a command's permission at the user level.\n**Usage**: ;uc [command_name] enable [user_name]")
|
||||
.Description("Sets a command's permission at the user level. | ;uc \"command name\" enable SomeUsername")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -501,7 +502,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
|
||||
cgb.CreateCommand(Prefix + "allsrvrmdls").Alias(Prefix + "asm")
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Description("Sets permissions for all modules at the server level.\n**Usage**: ;asm [enable/disable]")
|
||||
.Description("Sets permissions for all modules at the server level. | ;asm [enable/disable]")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -527,7 +528,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
cgb.CreateCommand(Prefix + "allsrvrcmds").Alias(Prefix + "asc")
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Description("Sets permissions for all commands from a certain module at the server level.\n**Usage**: ;asc [module_name] [enable/disable]")
|
||||
.Description("Sets permissions for all commands from a certain module at the server level. | ;asc \"module name\" [enable/disable]")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -554,7 +555,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
cgb.CreateCommand(Prefix + "allchnlmdls").Alias(Prefix + "acm")
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Description("Sets permissions for all modules at the channel level.\n**Usage**: ;acm [enable/disable] [channel_name]")
|
||||
.Description("Sets permissions for all modules at the channel level. | ;acm [enable/disable] SomeChannel")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -583,7 +584,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Description("Sets permissions for all commands from a certain module at the channel level.\n**Usage**: ;acc [module_name] [enable/disable] [channel_name]")
|
||||
.Description("Sets permissions for all commands from a certain module at the channel level. | ;acc \"module name\" [enable/disable] SomeChannel")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -610,7 +611,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
cgb.CreateCommand(Prefix + "allrolemdls").Alias(Prefix + "arm")
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Description("Sets permissions for all modules at the role level.\n**Usage**: ;arm [enable/disable] [role_name]")
|
||||
.Description("Sets permissions for all modules at the role level. | ;arm [enable/disable] MyRole")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -638,7 +639,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
.Parameter("module", ParameterType.Required)
|
||||
.Parameter("bool", ParameterType.Required)
|
||||
.Parameter("role", ParameterType.Unparsed)
|
||||
.Description("Sets permissions for all commands from a certain module at the role level.\n**Usage**: ;arc [module_name] [enable/disable] [role_name]")
|
||||
.Description("Sets permissions for all commands from a certain module at the role level. | ;arc \"module name\" [enable/disable] MyRole")
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
@ -678,7 +679,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "ubl")
|
||||
.Description("Blacklists a mentioned user.\n**Usage**: ;ubl [user_mention]")
|
||||
.Description("Blacklists a mentioned user. | ;ubl [user_mention]")
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
@ -694,7 +695,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "uubl")
|
||||
.Description($"Unblacklists a mentioned user.\n**Usage**: {Prefix}uubl [user_mention]")
|
||||
.Description($"Unblacklists a mentioned user. | {Prefix}uubl [user_mention]")
|
||||
.Parameter("user", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
@ -717,7 +718,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "cbl")
|
||||
.Description("Blacklists a mentioned channel (#general for example).\n**Usage**: ;cbl [channel_mention]")
|
||||
.Description("Blacklists a mentioned channel (#general for example). | ;cbl #some_channel")
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -732,7 +733,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "cubl")
|
||||
.Description("Unblacklists a mentioned channel (#general for example).\n**Usage**: ;cubl [channel_mention]")
|
||||
.Description("Unblacklists a mentioned channel (#general for example). | ;cubl #some_channel")
|
||||
.Parameter("channel", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -747,7 +748,7 @@ namespace NadekoBot.Modules.Permissions
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "sbl")
|
||||
.Description("Blacklists a server by a name or id (#general for example). **BOT OWNER ONLY**\n**Usage**: ;sbl [servername/serverid]")
|
||||
.Description("Blacklists a server by a name or id (#general for example). **BOT OWNER ONLY** | ;sbl [servername/serverid]")
|
||||
.Parameter("server", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
@ -776,6 +777,57 @@ namespace NadekoBot.Modules.Permissions
|
||||
await e.Channel.SendMessage($"`Sucessfully blacklisted server {server.Name}`").ConfigureAwait(false);
|
||||
}).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "cmdcooldown")
|
||||
.Alias(Prefix+ "cmdcd")
|
||||
.Description($"Sets a cooldown per user for a command. Set 0 to clear. | `{Prefix}cmdcd \"some cmd\" 5`")
|
||||
.Parameter("command", ParameterType.Required)
|
||||
.Parameter("secs",ParameterType.Required)
|
||||
.AddCheck(SimpleCheckers.ManageMessages())
|
||||
.Do(async e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var command = PermissionHelper.ValidateCommand(e.GetArg("command"));
|
||||
var secsStr = e.GetArg("secs").Trim();
|
||||
int secs;
|
||||
if (!int.TryParse(secsStr, out secs) || secs < 0 || secs > 3600)
|
||||
throw new ArgumentOutOfRangeException("secs", "Invalid second parameter. (Must be a number between 0 and 3600)");
|
||||
|
||||
|
||||
PermissionsHandler.SetCommandCooldown(e.Server, command, secs);
|
||||
if(secs == 0)
|
||||
await e.Channel.SendMessage($"Command **{command}** has no coooldown now.").ConfigureAwait(false);
|
||||
else
|
||||
await e.Channel.SendMessage($"Command **{command}** now has a **{secs} {(secs==1 ? "second" : "seconds")}** cooldown.").ConfigureAwait(false);
|
||||
}
|
||||
catch (ArgumentException exArg)
|
||||
{
|
||||
await e.Channel.SendMessage(exArg.Message).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await e.Channel.SendMessage("Something went terribly wrong - " + ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "allcmdcooldowns")
|
||||
.Alias(Prefix + "acmdcds")
|
||||
.Description("Shows a list of all commands and their respective cooldowns.")
|
||||
.Do(async e =>
|
||||
{
|
||||
ServerPermissions perms;
|
||||
PermissionsHandler.PermissionsDict.TryGetValue(e.Server.Id, out perms);
|
||||
if (perms == null)
|
||||
return;
|
||||
|
||||
if (!perms.CommandCooldowns.Any())
|
||||
{
|
||||
await e.Channel.SendMessage("`No command cooldowns set.`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
await e.Channel.SendMessage(SearchHelper.ShowInPrettyCode(perms.CommandCooldowns.Select(c=>c.Key+ ": "+c.Value+" secs"),s=>$"{s,-30}",2)).ConfigureAwait(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ namespace NadekoBot.Modules.Pokemon
|
||||
commands.ForEach(cmd => cmd.Init(cgb));
|
||||
|
||||
cgb.CreateCommand(Prefix + "attack")
|
||||
.Description("Attacks a target with the given move")
|
||||
.Description($"Attacks a target with the given move. Use `{Prefix}movelist` to see a list of moves your type can use. | `{Prefix}attack \"vine whip\" @someguy`")
|
||||
.Parameter("move", ParameterType.Required)
|
||||
.Parameter("target", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -210,7 +210,7 @@ namespace NadekoBot.Modules.Pokemon
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "heal")
|
||||
.Description($"Heals someone. Revives those that fainted. Costs a {NadekoBot.Config.CurrencyName} \n**Usage**:{Prefix}revive @someone")
|
||||
.Description($"Heals someone. Revives those who fainted. Costs a {NadekoBot.Config.CurrencyName} | {Prefix}heal @someone")
|
||||
.Parameter("target", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -242,7 +242,7 @@ namespace NadekoBot.Modules.Pokemon
|
||||
return;
|
||||
}
|
||||
var target = (usr.Id == e.User.Id) ? "yourself" : usr.Name;
|
||||
FlowersHandler.RemoveFlowers(e.User, $"Poke-Heal {target}", amount);
|
||||
await FlowersHandler.RemoveFlowers(e.User, $"Poke-Heal {target}", amount).ConfigureAwait(false);
|
||||
//healing
|
||||
targetStats.Hp = targetStats.MaxHp;
|
||||
if (HP < 0)
|
||||
@ -263,7 +263,7 @@ namespace NadekoBot.Modules.Pokemon
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "type")
|
||||
.Description($"Get the poketype of the target.\n**Usage**: {Prefix}type @someone")
|
||||
.Description($"Get the poketype of the target. | {Prefix}type @someone")
|
||||
.Parameter("target", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -282,7 +282,7 @@ namespace NadekoBot.Modules.Pokemon
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "settype")
|
||||
.Description($"Set your poketype. Costs a {NadekoBot.Config.CurrencyName}.\n**Usage**: {Prefix}settype fire")
|
||||
.Description($"Set your poketype. Costs a {NadekoBot.Config.CurrencyName}. | {Prefix}settype fire")
|
||||
.Parameter("targetType", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -309,7 +309,7 @@ namespace NadekoBot.Modules.Pokemon
|
||||
await e.Channel.SendMessage($"{e.User.Mention} you don't have enough {NadekoBot.Config.CurrencyName}s! \nYou still need {amount - pts} {NadekoBot.Config.CurrencySign} to be able to do this!").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
FlowersHandler.RemoveFlowers(e.User, $"set usertype to {targetTypeStr}", amount);
|
||||
await FlowersHandler.RemoveFlowers(e.User, $"set usertype to {targetTypeStr}", amount).ConfigureAwait(false);
|
||||
//Actually changing the type here
|
||||
var preTypes = DbHandler.Instance.GetAllRows<UserPokeTypes>();
|
||||
Dictionary<long, int> Dict = preTypes.ToDictionary(x => x.UserId, y => y.Id.Value);
|
||||
|
@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "calculate")
|
||||
.Alias(Module.Prefix + "calc")
|
||||
.Description("Evaluate a mathematical expression.\n**Usage**: ~calc 1+1")
|
||||
.Description("Evaluate a mathematical expression. | ~calc 1+1")
|
||||
.Parameter("expression", ParameterType.Unparsed)
|
||||
.Do(EvalFunc());
|
||||
}
|
||||
@ -49,11 +49,11 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
string result = parser.Parse(expression).ToString();
|
||||
return result;
|
||||
}
|
||||
catch (OverflowException e)
|
||||
catch (OverflowException)
|
||||
{
|
||||
return $"Overflow error on {expression}";
|
||||
}
|
||||
catch (FormatException e)
|
||||
catch (FormatException)
|
||||
{
|
||||
return $"\"{expression}\" was not formatted correctly";
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "lolchamp")
|
||||
.Description("Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role.\n**Usage**:~lolchamp Riven or ~lolchamp Annie sup")
|
||||
.Description("Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role. |~lolchamp Riven or ~lolchamp Annie sup")
|
||||
.Parameter("champ", ParameterType.Required)
|
||||
.Parameter("position", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
|
@ -25,7 +25,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
string.Join("\n", JsonConvert.DeserializeObject<Dictionary<string, string>>(await SearchHelper.GetResponseStringAsync("http://memegen.link/templates/"))
|
||||
.Select(kvp => Path.GetFileName(kvp.Value))
|
||||
.GroupBy(item => (i++) / 4)
|
||||
.Select(ig => string.Join("", ig.Select(el => $"{el,-17}"))))
|
||||
.Select(ig => string.Concat(ig.Select(el => $"{el,-17}"))))
|
||||
+ $"\n```").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
|
@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "osu")
|
||||
.Description("Shows osu stats for a player.\n**Usage**: `~osu Name` or `~osu Name taiko`")
|
||||
.Description("Shows osu stats for a player. | `~osu Name` or `~osu Name taiko`")
|
||||
.Parameter("usr", ParameterType.Required)
|
||||
.Parameter("mode", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -56,7 +56,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "osu b")
|
||||
.Description("Shows information about an osu beatmap.\n**Usage**:~osu b https://osu.ppy.sh/s/127712")
|
||||
.Description("Shows information about an osu beatmap. |~osu b https://osu.ppy.sh/s/127712")
|
||||
.Parameter("map", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "osu top5")
|
||||
.Description("Displays a user's top 5 plays. \n**Usage**:~osu top5 Name")
|
||||
.Description("Displays a user's top 5 plays. |~osu top5 Name")
|
||||
.Parameter("usr", ParameterType.Required)
|
||||
.Parameter("mode", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
|
@ -42,12 +42,12 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "pokemonability")
|
||||
.Alias(Prefix + "pokab")
|
||||
.Alias(Prefix + "pokeab")
|
||||
.Description("Searches for a pokemon ability.")
|
||||
.Parameter("abil", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var ab = e.GetArg("abil")?.Trim().ToUpperInvariant();
|
||||
var ab = e.GetArg("abil")?.Trim().ToUpperInvariant().Replace(" ", "");
|
||||
if (string.IsNullOrWhiteSpace(ab))
|
||||
return;
|
||||
foreach (var kvp in pokemonAbilities)
|
||||
|
@ -122,7 +122,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "hitbox")
|
||||
.Alias(Module.Prefix + "hb")
|
||||
.Description("Notifies this channel when a certain user starts streaming." +
|
||||
"\n**Usage**: ~hitbox SomeStreamer")
|
||||
" | ~hitbox SomeStreamer")
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(TrackStream(StreamNotificationConfig.StreamType.Hitbox));
|
||||
@ -130,7 +130,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "twitch")
|
||||
.Alias(Module.Prefix + "tw")
|
||||
.Description("Notifies this channel when a certain user starts streaming." +
|
||||
"\n**Usage**: ~twitch SomeStreamer")
|
||||
" | ~twitch SomeStreamer")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(TrackStream(StreamNotificationConfig.StreamType.Twitch));
|
||||
@ -138,7 +138,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "beam")
|
||||
.Alias(Module.Prefix + "bm")
|
||||
.Description("Notifies this channel when a certain user starts streaming." +
|
||||
"\n**Usage**: ~beam SomeStreamer")
|
||||
" | ~beam SomeStreamer")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(TrackStream(StreamNotificationConfig.StreamType.Beam));
|
||||
@ -146,7 +146,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "checkhitbox")
|
||||
.Alias(Module.Prefix + "chhb")
|
||||
.Description("Checks if a certain user is streaming on the hitbox platform." +
|
||||
"\n**Usage**: ~chhb SomeStreamer")
|
||||
" | ~chhb SomeStreamer")
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
@ -175,7 +175,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "checktwitch")
|
||||
.Alias(Module.Prefix + "chtw")
|
||||
.Description("Checks if a certain user is streaming on the twitch platform." +
|
||||
"\n**Usage**: ~chtw SomeStreamer")
|
||||
" | ~chtw SomeStreamer")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -204,7 +204,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "checkbeam")
|
||||
.Alias(Module.Prefix + "chbm")
|
||||
.Description("Checks if a certain user is streaming on the beam platform." +
|
||||
"\n**Usage**: ~chbm SomeStreamer")
|
||||
" | ~chbm SomeStreamer")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -233,7 +233,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "removestream")
|
||||
.Alias(Module.Prefix + "rms")
|
||||
.Description("Removes notifications of a certain streamer on this channel." +
|
||||
"\n**Usage**: ~rms SomeGuy")
|
||||
" | ~rms SomeGuy")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
@ -261,7 +261,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
cgb.CreateCommand(Module.Prefix + "liststreams")
|
||||
.Alias(Module.Prefix + "ls")
|
||||
.Description("Lists all streams you are following on this server." +
|
||||
"\n**Usage**: ~ls")
|
||||
" | ~ls")
|
||||
.Do(async e =>
|
||||
{
|
||||
|
||||
|
@ -15,6 +15,7 @@ using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Web;
|
||||
|
||||
namespace NadekoBot.Modules.Searches
|
||||
{
|
||||
@ -47,7 +48,7 @@ namespace NadekoBot.Modules.Searches
|
||||
commands.ForEach(cmd => cmd.Init(cgb));
|
||||
|
||||
cgb.CreateCommand(Prefix + "we")
|
||||
.Description($"Shows weather data for a specified city and a country. BOTH ARE REQUIRED. Use country abbrevations.\n**Usage**: {Prefix}we Moscow RF")
|
||||
.Description($"Shows weather data for a specified city and a country. BOTH ARE REQUIRED. Use country abbrevations. | {Prefix}we Moscow RF")
|
||||
.Parameter("city", ParameterType.Required)
|
||||
.Parameter("country", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
@ -157,7 +158,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "i")
|
||||
.Description("Pulls the first image found using a search parameter. Use ~ir for different results.\n**Usage**: ~i cute kitten")
|
||||
.Description("Pulls the first image found using a search parameter. Use ~ir for different results. | ~i cute kitten")
|
||||
.Parameter("query", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -183,7 +184,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "ir")
|
||||
.Description("Pulls a random image using a search parameter.\n**Usage**: ~ir cute kitten")
|
||||
.Description("Pulls a random image using a search parameter. | ~ir cute kitten")
|
||||
.Parameter("query", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -219,8 +220,21 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
.ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "google")
|
||||
.Alias(Prefix + "g")
|
||||
.Description("Get a google search link for some terms.")
|
||||
.Parameter("terms", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var terms = e.GetArg("terms")?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(terms))
|
||||
return;
|
||||
await e.Channel.SendMessage($"https://google.com/search?q={ HttpUtility.UrlEncode(terms).Replace(' ', '+') }")
|
||||
.ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "hs")
|
||||
.Description("Searches for a Hearthstone card and shows its image. Takes a while to complete.\n**Usage**:~hs Ysera")
|
||||
.Description("Searches for a Hearthstone card and shows its image. Takes a while to complete. |~hs Ysera")
|
||||
.Parameter("name", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -261,7 +275,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "ud")
|
||||
.Description("Searches Urban Dictionary for a word.\n**Usage**:~ud Pineapple")
|
||||
.Description("Searches Urban Dictionary for a word. |~ud Pineapple")
|
||||
.Parameter("query", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -290,7 +304,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
});
|
||||
// thanks to Blaubeerwald
|
||||
cgb.CreateCommand(Prefix + "#")
|
||||
.Description("Searches Tagdef.com for a hashtag.\n**Usage**:~# ff")
|
||||
.Description("Searches Tagdef.com for a hashtag. |~# ff")
|
||||
.Parameter("query", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -404,7 +418,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "safebooru")
|
||||
.Description("Shows a random image from safebooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +)\n**Usage**: ~safebooru yuri+kissing")
|
||||
.Description("Shows a random image from safebooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +) | ~safebooru yuri+kissing")
|
||||
.Parameter("tag", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -431,7 +445,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "clr")
|
||||
.Description("Shows you what color corresponds to that hex.\n**Usage**: `~clr 00ff00`")
|
||||
.Description("Shows you what color corresponds to that hex. | `~clr 00ff00`")
|
||||
.Parameter("color", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -480,7 +494,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
cgb.CreateCommand(Prefix + "av")
|
||||
.Alias(Prefix + "avatar")
|
||||
.Parameter("mention", ParameterType.Required)
|
||||
.Description("Shows a mentioned person's avatar.\n**Usage**: ~av @X")
|
||||
.Description("Shows a mentioned person's avatar. | ~av @X")
|
||||
.Do(async e =>
|
||||
{
|
||||
var usr = e.Channel.FindUsers(e.GetArg("mention")).FirstOrDefault();
|
||||
|
@ -60,7 +60,7 @@ namespace NadekoBot.Modules.Translator.Helpers
|
||||
text = await http.GetStringAsync(url).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return JArray.Parse(text)[0][0][0].ToString();
|
||||
return (string.Concat(JArray.Parse(text)[0].Select(x => x[0])));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -14,7 +14,7 @@ namespace NadekoBot.Modules.Translator
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "translate")
|
||||
.Alias(Module.Prefix + "trans")
|
||||
.Description($"Translates from>to text. From the given language to the destiation language.\n**Usage**: {Module.Prefix}trans en>fr Hello")
|
||||
.Description($"Translates from>to text. From the given language to the destiation language. | {Module.Prefix}trans en>fr Hello")
|
||||
.Parameter("langs", ParameterType.Required)
|
||||
.Parameter("text", ParameterType.Unparsed)
|
||||
.Do(TranslateFunc());
|
||||
|
@ -71,7 +71,7 @@ namespace NadekoBot.Modules.Trello
|
||||
cgb.CreateCommand(Prefix + "bind")
|
||||
.Description("Bind a trello bot to a single channel. " +
|
||||
"You will receive notifications from your board when something is added or edited." +
|
||||
"\n**Usage**: bind [board_id]")
|
||||
" | bind [board_id]")
|
||||
.Parameter("board_id", Discord.Commands.ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ namespace NadekoBot.Modules.Utility.Commands
|
||||
{
|
||||
cgb.CreateCommand(Module.Prefix + "serverinfo")
|
||||
.Alias(Module.Prefix + "sinfo")
|
||||
.Description($"Shows info about the server the bot is on. If no channel is supplied, it defaults to current one.\n**Usage**:{Module.Prefix}sinfo Some Server")
|
||||
.Description($"Shows info about the server the bot is on. If no channel is supplied, it defaults to current one. |{Module.Prefix}sinfo Some Server")
|
||||
.Parameter("server", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -49,7 +49,7 @@ namespace NadekoBot.Modules.Utility.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "channelinfo")
|
||||
.Alias(Module.Prefix + "cinfo")
|
||||
.Description($"Shows info about the channel. If no channel is supplied, it defaults to current one.\n**Usage**:{Module.Prefix}cinfo #some-channel")
|
||||
.Description($"Shows info about the channel. If no channel is supplied, it defaults to current one. |{Module.Prefix}cinfo #some-channel")
|
||||
.Parameter("channel", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -71,7 +71,7 @@ namespace NadekoBot.Modules.Utility.Commands
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "userinfo")
|
||||
.Alias(Module.Prefix + "uinfo")
|
||||
.Description($"Shows info about the user. If no user is supplied, it defaults a user running the command.\n**Usage**:{Module.Prefix}uinfo @SomeUser")
|
||||
.Description($"Shows info about the user. If no user is supplied, it defaults a user running the command. |{Module.Prefix}uinfo @SomeUser")
|
||||
.Parameter("user", ParameterType.Optional)
|
||||
.Do(async e =>
|
||||
{
|
||||
|
@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Utility.Commands
|
||||
.Description("Sends a message to you or a channel after certain amount of time. " +
|
||||
"First argument is me/here/'channelname'. Second argument is time in a descending order (mo>w>d>h>m) example: 1w5d3h10m. " +
|
||||
"Third argument is a (multiword)message. " +
|
||||
"\n**Usage**: `.remind me 1d5h Do something` or `.remind #general Start now!`")
|
||||
" | `.remind me 1d5h Do something` or `.remind #general Start now!`")
|
||||
.Parameter("meorchannel", ParameterType.Required)
|
||||
.Parameter("time", ParameterType.Required)
|
||||
.Parameter("message", ParameterType.Unparsed)
|
||||
|
@ -48,7 +48,7 @@ namespace NadekoBot.Modules.Utility
|
||||
if (arr.Length == 0)
|
||||
await e.Channel.SendMessage("Nobody. (not 100% sure)").ConfigureAwait(false);
|
||||
else
|
||||
await e.Channel.SendMessage("```xl\n" + string.Join("\n", arr.GroupBy(item => (i++) / 3).Select(ig => string.Join("", ig.Select(el => $"• {el,-35}")))) + "\n```").ConfigureAwait(false);
|
||||
await e.Channel.SendMessage("```xl\n" + string.Join("\n", arr.GroupBy(item => (i++) / 3).Select(ig => string.Concat(ig.Select(el => $"• {el,-35}")))) + "\n```").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "inrole")
|
||||
@ -99,7 +99,7 @@ namespace NadekoBot.Modules.Utility
|
||||
.Description("Shows some basic stats for Nadeko.")
|
||||
.Do(async e =>
|
||||
{
|
||||
await e.Channel.SendMessage(await NadekoStats.Instance.GetStats());
|
||||
await e.Channel.SendMessage(await NadekoStats.Instance.GetStats()).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "dysyd")
|
||||
|
@ -41,8 +41,9 @@ namespace NadekoBot
|
||||
public static LocalizedStrings Locale { get; set; } = new LocalizedStrings();
|
||||
public static string BotMention { get; set; } = "";
|
||||
public static bool Ready { get; set; } = false;
|
||||
public static Action OnReady { get; set; } = delegate { };
|
||||
|
||||
private static Channel OwnerPrivateChannel { get; set; }
|
||||
private static List<Channel> OwnerPrivateChannels { get; set; }
|
||||
|
||||
private static void Main()
|
||||
{
|
||||
@ -196,7 +197,7 @@ namespace NadekoBot
|
||||
return;
|
||||
}
|
||||
#if NADEKO_RELEASE
|
||||
await Task.Delay(100000).ConfigureAwait(false);
|
||||
await Task.Delay(90000).ConfigureAwait(false);
|
||||
#else
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
#endif
|
||||
@ -205,15 +206,19 @@ namespace NadekoBot
|
||||
Console.WriteLine(await NadekoStats.Instance.GetStats().ConfigureAwait(false));
|
||||
Console.WriteLine("-----------------");
|
||||
|
||||
|
||||
OwnerPrivateChannels = new List<Channel>(Creds.OwnerIds.Length);
|
||||
foreach (var id in Creds.OwnerIds)
|
||||
{
|
||||
try
|
||||
{
|
||||
OwnerPrivateChannel = await Client.CreatePrivateChannel(Creds.OwnerIds[0]).ConfigureAwait(false);
|
||||
OwnerPrivateChannels.Add(await Client.CreatePrivateChannel(id).ConfigureAwait(false));
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Failed creating private channel with the first owner listed in credentials.json");
|
||||
Console.WriteLine($"Failed creating private channel with the owner {id} listed in credentials.json");
|
||||
}
|
||||
}
|
||||
|
||||
Client.ClientAPI.SendingRequest += (s, e) =>
|
||||
{
|
||||
var request = e.Request as Discord.API.Client.Rest.SendMessageRequest;
|
||||
@ -225,6 +230,7 @@ namespace NadekoBot
|
||||
};
|
||||
PermissionsHandler.Initialize();
|
||||
NadekoBot.Ready = true;
|
||||
NadekoBot.OnReady();
|
||||
});
|
||||
Console.WriteLine("Exiting...");
|
||||
Console.ReadKey();
|
||||
@ -234,8 +240,18 @@ namespace NadekoBot
|
||||
|
||||
public static async Task SendMessageToOwner(string message)
|
||||
{
|
||||
if (Config.ForwardMessages && OwnerPrivateChannel != null)
|
||||
await OwnerPrivateChannel.SendMessage(message).ConfigureAwait(false);
|
||||
if (Config.ForwardMessages && OwnerPrivateChannels.Any())
|
||||
if (Config.ForwardToAllOwners)
|
||||
OwnerPrivateChannels.ForEach(async c =>
|
||||
{
|
||||
try { await c.SendMessage(message).ConfigureAwait(false); } catch { }
|
||||
});
|
||||
else
|
||||
{
|
||||
var c = OwnerPrivateChannels.FirstOrDefault();
|
||||
if (c != null)
|
||||
await c.SendMessage(message).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool repliedRecently = false;
|
||||
@ -248,8 +264,8 @@ namespace NadekoBot
|
||||
if (ConfigHandler.IsBlackListed(e))
|
||||
return;
|
||||
|
||||
if (Config.ForwardMessages && !NadekoBot.Creds.OwnerIds.Contains(e.User.Id) && OwnerPrivateChannel != null)
|
||||
await OwnerPrivateChannel.SendMessage(e.User + ": ```\n" + e.Message.Text + "\n```").ConfigureAwait(false);
|
||||
if (Config.ForwardMessages && !NadekoBot.Creds.OwnerIds.Contains(e.User.Id) && OwnerPrivateChannels.Any())
|
||||
await SendMessageToOwner(e.User + ": ```\n" + e.Message.Text + "\n```").ConfigureAwait(false);
|
||||
|
||||
if (repliedRecently) return;
|
||||
|
||||
@ -263,5 +279,3 @@ namespace NadekoBot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//95520984584429568 meany
|
||||
|
@ -40,10 +40,12 @@
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;__DEMO__,__DEMO_EXPERIMENTAL__</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@ -74,6 +76,46 @@
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'PRIVATE|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\PRIVATE\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'NadekoRelease|x64'">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NADEKO_RELEASE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="libvideo, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\VideoLibrary.1.3.3\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\libvideo.dll</HintPath>
|
||||
@ -144,6 +186,7 @@
|
||||
<Compile Include="Classes\FlowersHandler.cs" />
|
||||
<Compile Include="Modules\Conversations\Commands\RipCommand.cs" />
|
||||
<Compile Include="Modules\CustomReactions\CustomReactions.cs" />
|
||||
<Compile Include="Modules\Music\Classes\PlaylistFullException.cs" />
|
||||
<Compile Include="Modules\Programming\Commands\HaskellRepl.cs" />
|
||||
<Compile Include="Modules\Programming\ProgrammingModule.cs" />
|
||||
<Compile Include="Modules\Searches\Commands\EvalCommand.cs" />
|
||||
|
@ -3,25 +3,14 @@ using NadekoBot.Extensions;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace NadekoBot.Classes.JSONModels
|
||||
{
|
||||
public class Configuration
|
||||
{
|
||||
public bool DontJoinServers { get; set; } = false;
|
||||
public bool ForwardMessages { get; set; } = true;
|
||||
public bool IsRotatingStatus { get; set; } = false;
|
||||
public int BufferSize { get; set; } = 4.MiB();
|
||||
|
||||
[JsonIgnore]
|
||||
public List<Quote> Quotes { get; set; } = new List<Quote>();
|
||||
|
||||
[JsonIgnore]
|
||||
public List<PokemonType> PokemonTypes { get; set; } = new List<PokemonType>();
|
||||
|
||||
public string RemindMessageFormat { get; set; } = "❗⏰**I've been told to remind you to '%message%' now by %user%.**⏰❗";
|
||||
|
||||
public Dictionary<string, List<string>> CustomReactions { get; set; } = new Dictionary<string, List<string>>()
|
||||
public static readonly Dictionary<string, List<string>> DefaultCustomReactions = new Dictionary<string, List<string>>
|
||||
{
|
||||
{@"\o\", new List<string>()
|
||||
{ "/o/" } },
|
||||
@ -93,6 +82,22 @@ namespace NadekoBot.Classes.JSONModels
|
||||
} }
|
||||
};
|
||||
|
||||
public bool DontJoinServers { get; set; } = false;
|
||||
public bool ForwardMessages { get; set; } = true;
|
||||
public bool ForwardToAllOwners { get; set; } = false;
|
||||
public bool IsRotatingStatus { get; set; } = false;
|
||||
public int BufferSize { get; set; } = 4.MiB();
|
||||
|
||||
public List<Quote> Quotes { get; set; } = new List<Quote>();
|
||||
|
||||
[JsonIgnore]
|
||||
public List<PokemonType> PokemonTypes { get; set; } = new List<PokemonType>();
|
||||
|
||||
public string RemindMessageFormat { get; set; } = "❗⏰**I've been told to remind you to '%message%' now by %user%.**⏰❗";
|
||||
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public Dictionary<string, List<string>> CustomReactions { get; set; }
|
||||
|
||||
public List<string> RotatingStatuses { get; set; } = new List<string>();
|
||||
public CommandPrefixesModel CommandPrefixes { get; set; } = new CommandPrefixesModel();
|
||||
public HashSet<ulong> ServerBlacklist { get; set; } = new HashSet<ulong>();
|
||||
@ -104,6 +109,22 @@ namespace NadekoBot.Classes.JSONModels
|
||||
143515953525817344
|
||||
};
|
||||
|
||||
[OnDeserialized]
|
||||
internal void OnDeserialized(StreamingContext context)
|
||||
{
|
||||
if (CustomReactions == null)
|
||||
{
|
||||
CustomReactions = DefaultCustomReactions;
|
||||
}
|
||||
}
|
||||
[OnSerializing]
|
||||
internal void OnSerializing(StreamingContext context)
|
||||
{
|
||||
if (CustomReactions == null)
|
||||
{
|
||||
CustomReactions = DefaultCustomReactions;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] _8BallResponses { get; set; } =
|
||||
{
|
||||
@ -154,7 +175,7 @@ Nadeko Support Server: <https://discord.gg/0ehQwTK2RBjAxzEY>";
|
||||
public string Conversations { get; set; } = "<@{0}>";
|
||||
public string ClashOfClans { get; set; } = ",";
|
||||
public string Help { get; set; } = "-";
|
||||
public string Music { get; set; } = "!m";
|
||||
public string Music { get; set; } = "!!";
|
||||
public string Trello { get; set; } = "trello ";
|
||||
public string Games { get; set; } = ">";
|
||||
public string Gambling { get; set; } = "$";
|
||||
|
@ -7,7 +7,7 @@ namespace NadekoBot.Classes.JSONModels
|
||||
public class Credentials
|
||||
{
|
||||
public string Token { get; set; } = "";
|
||||
public string ClientId { get; set; } = "116275390695079945";
|
||||
public string ClientId { get; set; } = "170254782546575360";
|
||||
public ulong BotId { get; set; } = 1231231231231;
|
||||
public ulong[] OwnerIds { get; set; } = { 123123123123, 5675675679845 };
|
||||
public string GoogleAPIKey { get; set; } = "";
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"Token": "",
|
||||
"ClientId": "116275390695079945",
|
||||
"ClientId": "170254782546575360",
|
||||
"BotId": 1231231231231,
|
||||
"OwnerIds": [
|
||||
123123123123,
|
||||
|
@ -1,8 +1,10 @@
|
||||
{
|
||||
"DontJoinServers": false,
|
||||
"ForwardMessages": true,
|
||||
"ForwardToAllOwners": false,
|
||||
"IsRotatingStatus": false,
|
||||
"BufferSize": 4194304,
|
||||
"Quotes": [],
|
||||
"RemindMessageFormat": "❗⏰**I've been told to remind you to '%message%' now by %user%.**⏰❗",
|
||||
"CustomReactions": {
|
||||
"\\o\\": [
|
||||
@ -81,7 +83,7 @@
|
||||
"Conversations": "<@{0}>",
|
||||
"ClashOfClans": ",",
|
||||
"Help": "-",
|
||||
"Music": "!m",
|
||||
"Music": "!!",
|
||||
"Trello": "trello ",
|
||||
"Games": ">",
|
||||
"Gambling": "$",
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 11 KiB |
Binary file not shown.
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 11 KiB |
@ -1,4 +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)
|
||||
# NadekoBot
|
||||
|
||||
## [Click here to invite nadeko to your discord server](https://discordapp.com/oauth2/authorize?client_id=170254782546575360&scope=bot&permissions=66186303)
|
||||
|
@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Tests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Tests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("45b2545d-c612-4919-b34c-d65ea1371c51")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
@ -1,45 +0,0 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System.Collections.Generic;
|
||||
using static NadekoBot.Modules.Gambling.Helpers.Cards;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class TestCards
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestHandValues()
|
||||
{
|
||||
var setting1 = new List<Card> {
|
||||
new Card(CardSuit.Clubs,10),
|
||||
new Card(CardSuit.Clubs,10),
|
||||
new Card(CardSuit.Clubs,10),
|
||||
new Card(CardSuit.Clubs,11),
|
||||
new Card(CardSuit.Diamonds,12),
|
||||
};
|
||||
var result1 = "Three Of A Kind";
|
||||
|
||||
var setting2 = new List<Card> {
|
||||
new Card(CardSuit.Clubs,1),
|
||||
new Card(CardSuit.Hearts,2),
|
||||
new Card(CardSuit.Clubs,3),
|
||||
new Card(CardSuit.Spades,4),
|
||||
new Card(CardSuit.Diamonds,5),
|
||||
};
|
||||
var result2 = "Straight";
|
||||
|
||||
var setting3 = new List<Card> {
|
||||
new Card(CardSuit.Diamonds,10),
|
||||
new Card(CardSuit.Diamonds,11),
|
||||
new Card(CardSuit.Diamonds,12),
|
||||
new Card(CardSuit.Diamonds,13),
|
||||
new Card(CardSuit.Diamonds,1),
|
||||
};
|
||||
var result3 = "Royal Flush";
|
||||
|
||||
Assert.AreEqual(GetHandValue(setting1), result1);
|
||||
Assert.AreEqual(GetHandValue(setting2), result2);
|
||||
Assert.AreEqual(GetHandValue(setting3), result3);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{45B2545D-C612-4919-B34C-D65EA1371C51}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Tests</RootNamespace>
|
||||
<AssemblyName>Tests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||
<IsCodedUITest>False</IsCodedUITest>
|
||||
<TestProjectType>UnitTest</TestProjectType>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<Choose>
|
||||
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
</ItemGroup>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
|
||||
</ItemGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<ItemGroup>
|
||||
<Compile Include="TestCards.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NadekoBot\NadekoBot.csproj">
|
||||
<Project>{27a886f5-cdda-4f4a-81ee-6dafcce9de46}</Project>
|
||||
<Name>NadekoBot</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Choose>
|
||||
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
144
commandlist.md
144
commandlist.md
@ -1,8 +1,8 @@
|
||||
######For more information and how to setup your own NadekoBot, go to: **http://github.com/Kwoth/NadekoBot/**
|
||||
######You can donate on paypal: `nadekodiscordbot@gmail.com` or Bitcoin `17MZz1JAqME39akMLrVT4XBPffQJ2n1EPa`
|
||||
######You can donate on paypal: `nadekodiscordbot@gmail.com`
|
||||
|
||||
#NadekoBot List Of Commands
|
||||
Version: `NadekoBot v0.9.6029.36463`
|
||||
Version: `NadekoBot v0.9.6048.2992`
|
||||
### Help
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
@ -25,6 +25,7 @@ Command and aliases | Description | Usage
|
||||
`.greetpm` | Toggles whether the greet messages will be sent in a PM or in the text channel.
|
||||
`.spmom` | Toggles whether mentions of other offline users on your server will send a pm to them.
|
||||
`.logserver` | Toggles logging in this channel. Logs every message sent/deleted/edited on the server. **Bot Owner Only!**
|
||||
`.logignore` | Toggles whether the .logserver command ignores this channel. Useful if you have hidden admin channel and public log channel.
|
||||
`.userpresence` | Starts logging to this channel when someone from the server goes online/offline/idle.
|
||||
`.voicepresence` | Toggles logging to this channel whenever someone joins or leaves a voice channel you are in right now.
|
||||
`.repeatinvoke`, `.repinv` | Immediately shows the repeat message and restarts the timer.
|
||||
@ -42,10 +43,11 @@ Command and aliases | Description | Usage
|
||||
`.asar` | Adds a role, or list of roles separated by whitespace(use quotations for multiword roles) to the list of self-assignable roles. | .asar Gamer
|
||||
`.rsar` | Removes a specified role from the list of self-assignable roles.
|
||||
`.lsar` | Lists all self-assignable roles.
|
||||
`.togglexclsar`, `.tesar` | toggle whether the self-assigned roles should be exclusive
|
||||
`.iam` | Adds a role to you that you choose. Role must be on a list of self-assignable roles. | .iam Gamer
|
||||
`.iamnot`, `.iamn` | Removes a role to you that you choose. Role must be on a list of self-assignable roles. | .iamn Gamer
|
||||
`.addcustreact`, `.acr` | Add a custom reaction. Guide here: <https://github.com/Kwoth/NadekoBot/wiki/Custom-Reactions> **Bot Owner Only!** | .acr "hello" I love saying hello to %user%
|
||||
`.listcustreact`, `.lcr` | Lists all current custom reactions (paginated with 30 commands per page). | .lcr 1
|
||||
`.listcustreact`, `.lcr` | Lists custom reactions (paginated with 30 commands per page). Use 'all' instead of page number to get all custom reactions DM-ed to you. | .lcr 1
|
||||
`.showcustreact`, `.scr` | Shows all possible responses from a single custom reaction. | .scr %mention% bb
|
||||
`.editcustreact`, `.ecr` | Edits a custom reaction, arguments are custom reactions name, index to change, and a (multiword) message **Bot Owner Only** | `.ecr "%mention% disguise" 2 Test 123`
|
||||
`.delcustreact`, `.dcr` | Deletes a custom reaction with given name (and index)
|
||||
@ -86,7 +88,6 @@ Command and aliases | Description | Usage
|
||||
`.donators` | List of lovely people who donated to keep this project alive.
|
||||
`.donadd` | Add a donator to the database.
|
||||
`.announce` | Sends a message to all servers' general channel bot is connected to.**Bot Owner Only!** | .announce Useless spam
|
||||
`.leave` | Leaves a server with a supplied ID. | `.leave 493243292839`
|
||||
`.savechat` | Saves a number of messages to a text file and sends it to you. **Bot Owner Only** | `.chatsave 150`
|
||||
|
||||
### Utility
|
||||
@ -126,25 +127,27 @@ Command and aliases | Description | Usage
|
||||
`;roleperms`, `;rp` | Shows banned permissions for a certain role. No argument means for everyone. | ;rp AwesomeRole
|
||||
`;chnlperms`, `;cp` | Shows banned permissions for a certain channel. No argument means for this channel. | ;cp #dev
|
||||
`;userperms`, `;up` | Shows banned permissions for a certain user. No argument means for yourself. | ;up Kwoth
|
||||
`;srvrmdl`, `;sm` | Sets a module's permission at the server level. | ;sm [module_name] enable
|
||||
`;srvrcmd`, `;sc` | Sets a command's permission at the server level. | ;sc [command_name] disable
|
||||
`;rolemdl`, `;rm` | Sets a module's permission at the role level. | ;rm [module_name] enable [role_name]
|
||||
`;rolecmd`, `;rc` | Sets a command's permission at the role level. | ;rc [command_name] disable [role_name]
|
||||
`;chnlmdl`, `;cm` | Sets a module's permission at the channel level. | ;cm [module_name] enable [channel_name]
|
||||
`;chnlcmd`, `;cc` | Sets a command's permission at the channel level. | ;cc [command_name] enable [channel_name]
|
||||
`;usrmdl`, `;um` | Sets a module's permission at the user level. | ;um [module_name] enable [user_name]
|
||||
`;usrcmd`, `;uc` | Sets a command's permission at the user level. | ;uc [command_name] enable [user_name]
|
||||
`;srvrmdl`, `;sm` | Sets a module's permission at the server level. | ;sm "module name" enable
|
||||
`;srvrcmd`, `;sc` | Sets a command's permission at the server level. | ;sc "command name" disable
|
||||
`;rolemdl`, `;rm` | Sets a module's permission at the role level. | ;rm "module name" enable MyRole
|
||||
`;rolecmd`, `;rc` | Sets a command's permission at the role level. | ;rc "command name" disable MyRole
|
||||
`;chnlmdl`, `;cm` | Sets a module's permission at the channel level. | ;cm "module name" enable SomeChannel
|
||||
`;chnlcmd`, `;cc` | Sets a command's permission at the channel level. | ;cc "command name" enable SomeChannel
|
||||
`;usrmdl`, `;um` | Sets a module's permission at the user level. | ;um "module name" enable SomeUsername
|
||||
`;usrcmd`, `;uc` | Sets a command's permission at the user level. | ;uc "command name" enable SomeUsername
|
||||
`;allsrvrmdls`, `;asm` | Sets permissions for all modules at the server level. | ;asm [enable/disable]
|
||||
`;allsrvrcmds`, `;asc` | Sets permissions for all commands from a certain module at the server level. | ;asc [module_name] [enable/disable]
|
||||
`;allchnlmdls`, `;acm` | Sets permissions for all modules at the channel level. | ;acm [enable/disable] [channel_name]
|
||||
`;allchnlcmds`, `;acc` | Sets permissions for all commands from a certain module at the channel level. | ;acc [module_name] [enable/disable] [channel_name]
|
||||
`;allrolemdls`, `;arm` | Sets permissions for all modules at the role level. | ;arm [enable/disable] [role_name]
|
||||
`;allrolecmds`, `;arc` | Sets permissions for all commands from a certain module at the role level. | ;arc [module_name] [enable/disable] [role_name]
|
||||
`;allsrvrcmds`, `;asc` | Sets permissions for all commands from a certain module at the server level. | ;asc "module name" [enable/disable]
|
||||
`;allchnlmdls`, `;acm` | Sets permissions for all modules at the channel level. | ;acm [enable/disable] SomeChannel
|
||||
`;allchnlcmds`, `;acc` | Sets permissions for all commands from a certain module at the channel level. | ;acc "module name" [enable/disable] SomeChannel
|
||||
`;allrolemdls`, `;arm` | Sets permissions for all modules at the role level. | ;arm [enable/disable] MyRole
|
||||
`;allrolecmds`, `;arc` | Sets permissions for all commands from a certain module at the role level. | ;arc "module name" [enable/disable] MyRole
|
||||
`;ubl` | Blacklists a mentioned user. | ;ubl [user_mention]
|
||||
`;uubl` | Unblacklists a mentioned user. | ;uubl [user_mention]
|
||||
`;cbl` | Blacklists a mentioned channel (#general for example). | ;cbl [channel_mention]
|
||||
`;cubl` | Unblacklists a mentioned channel (#general for example). | ;cubl [channel_mention]
|
||||
`;cbl` | Blacklists a mentioned channel (#general for example). | ;cbl #some_channel
|
||||
`;cubl` | Unblacklists a mentioned channel (#general for example). | ;cubl #some_channel
|
||||
`;sbl` | Blacklists a server by a name or id (#general for example). **BOT OWNER ONLY** | ;sbl [servername/serverid]
|
||||
`;cmdcooldown`, `;cmdcd` | Sets a cooldown per user for a command. Set 0 to clear. | `;cmdcd "some cmd" 5`
|
||||
`;allcmdcooldowns`, `;acmdcds` | Shows a list of all commands and their respective cooldowns.
|
||||
|
||||
### Conversations
|
||||
Command and aliases | Description | Usage
|
||||
@ -153,12 +156,10 @@ Command and aliases | Description | Usage
|
||||
`...` | Shows a random quote with a specified name. | .. abc
|
||||
`..qdel`, `..quotedelete` | Deletes all quotes with the specified keyword. You have to either be bot owner or the creator of the quote to delete it. | `..qdel abc`
|
||||
`@BotName rip` | Shows a grave image of someone with a start year | @NadekoBot rip @Someone 2000
|
||||
`@BotName uptime` | Shows how long Nadeko has been running for.
|
||||
`@BotName die` | Works only for the owner. Shuts the bot down.
|
||||
`@BotName do you love me` | Replies with positive answer only to the bot owner.
|
||||
`@BotName how are you`, `@BotName how are you?` | Replies positive only if bot owner is online.
|
||||
`@BotName fire` | Shows a unicode fire message. Optional parameter [x] tells her how many times to repeat the fire. | @NadekoBot fire [x]
|
||||
`@BotName slm` | Shows the message where you were last mentioned in this channel (checks last 10k messages)
|
||||
`@BotName dump` | Dumps all of the invites it can to dump.txt.** Owner Only.**
|
||||
`@BotName ab` | Try to get 'abalabahaha'
|
||||
|
||||
@ -168,13 +169,16 @@ Command and aliases | Description | Usage
|
||||
`$draw` | Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck. | $draw [x]
|
||||
`$shuffle`, `$sh` | Reshuffles all cards back into the deck.
|
||||
`$flip` | Flips coin(s) - heads or tails, and shows an image. | `$flip` or `$flip 3`
|
||||
`$betflip`, `$bf` | Bet to guess will the result be heads or tails. Guessing award you double flowers you've bet. | `$bf 5 heads` or `$bf 3 t`
|
||||
`$roll` | Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice. If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | $roll or $roll 7 or $roll 3d5
|
||||
`$rolluo` | Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice (unordered). If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | $roll or $roll 7 or $roll 3d5
|
||||
`$nroll` | Rolls in a given range. | `$nroll 5` (rolls 0-5) or `$nroll 5-15`
|
||||
`$raffle` | Prints a name and ID of a random user from the online list from the (optional) role.
|
||||
`$$$` | Check how much NadekoFlowers a person has. (Defaults to yourself) | `$$$` or `$$$ @Someone`
|
||||
`$give` | Give someone a certain amount of NadekoFlowers
|
||||
`$award` | Gives someone a certain amount of flowers. **Bot Owner Only!** | `$award 100 @person`
|
||||
`$take` | Takes a certain amount of flowers from someone. **Bot Owner Only!**
|
||||
`$betroll`, `$br` | Bets a certain amount of NadekoFlowers and rolls a dice. Rolling over 66 yields x2 flowers, over 90 - x3 and 100 x10. | $br 5
|
||||
`$leaderboard`, `$lb` |
|
||||
|
||||
### Games
|
||||
@ -190,7 +194,7 @@ Command and aliases | Description | Usage
|
||||
`>pollend` | Stops active poll on this server and prints the results in this channel.
|
||||
`>pick` | Picks a flower planted in this channel.
|
||||
`>plant` | Spend a flower to plant it in this channel. (If bot is restarted or crashes, flower will be lost)
|
||||
`>gencurrency`, `>gc` | Toggles currency generation on this channel. Every posted message will have 2% chance to spawn a NadekoFlower. Requires Manage Messages permission. | `>gc`
|
||||
`>gencurrency`, `>gc` | Toggles currency generation on this channel. Every posted message will have 2% chance to spawn a NadekoFlower. Optional parameter cooldown time in minutes, 5 minutes by default. Requires Manage Messages permission. | `>gc` or `>gc 60`
|
||||
`>leet` | Converts a text to leetspeak with 6 (1-6) severity levels | >leet 3 Hello
|
||||
`>choose` | Chooses a thing from a list of things | >choose Get up;Sleep;Sleep more
|
||||
`>8ball` | Ask the 8ball a yes/no question.
|
||||
@ -200,37 +204,39 @@ Command and aliases | Description | Usage
|
||||
### Music
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`!m next`, `!m n`, `!m skip` | Goes to the next song in the queue. You have to be in the same voice channel as the bot. | `!m n`
|
||||
`!m stop`, `!m s` | Stops the music and clears the playlist. Stays in the channel. | `!m s`
|
||||
`!m destroy`, `!m d` | Completely stops the music and unbinds the bot from the channel. (may cause weird behaviour) | `!m d`
|
||||
`!m pause`, `!m p` | Pauses or Unpauses the song. | `!m p`
|
||||
`!m queue`, `!m q`, `!m yq` | Queue a song using keywords or a link. Bot will join your voice channel.**You must be in a voice channel**. | `!m q Dream Of Venice`
|
||||
`!m listqueue`, `!m lq` | Lists 15 currently queued songs per page. Default page is 1. | `!m lq` or `!m lq 2`
|
||||
`!m nowplaying`, `!m np` | Shows the song currently playing. | `!m np`
|
||||
`!m volume`, `!m vol` | Sets the music volume 0-100% | `!m vol 50`
|
||||
`!m defvol`, `!m dv` | Sets the default music volume when music playback is started (0-100). Does not persist through restarts. | `!m dv 80`
|
||||
`!m mute`, `!m min` | Sets the music volume to 0% | `!m min`
|
||||
`!m max` | Sets the music volume to 100% (real max is actually 150%). | `!m max`
|
||||
`!m half` | Sets the music volume to 50%. | `!m half`
|
||||
`!m shuffle`, `!m sh` | Shuffles the current playlist. | `!m sh`
|
||||
`!m playlist`, `!m pl` | Queues up to 50 songs from a youtube playlist specified by a link, or keywords. | `!m pl playlist link or name`
|
||||
`!m soundcloudpl`, `!m scpl` | Queue a soundcloud playlist using a link. | `!m scpl https://soundcloud.com/saratology/sets/symphony`
|
||||
`!m localplaylst`, `!m lopl` | Queues all songs from a directory. **Bot Owner Only!** | `!m lopl C:/music/classical`
|
||||
`!m radio`, `!m ra` | Queues a radio stream from a link. It can be a direct mp3 radio stream, .m3u, .pls .asx or .xspf | `!m ra radio link here`
|
||||
`!m local`, `!m lo` | Queues a local file by specifying a full path. **Bot Owner Only!** | `!m lo C:/music/mysong.mp3`
|
||||
`!m move`, `!m mv` | Moves the bot to your voice channel. (works only if music is already playing) | `!m mv`
|
||||
`!m remove`, `!m rm` | Remove a song by its # in the queue, or 'all' to remove whole queue. | `!m rm 5`
|
||||
`!m movesong`, `!m ms` | Moves a song from one position to another. | `!m ms` 5>3
|
||||
`!m cleanup` | Cleans up hanging voice connections. **Bot Owner Only!** | `!m cleanup`
|
||||
`!m reptcursong`, `!m rcs` | Toggles repeat of current song. | `!m rcs`
|
||||
`!m rpeatplaylst`, `!m rpl` | Toggles repeat of all songs in the queue (every song that finishes is added to the end of the queue). | `!m rpl`
|
||||
`!m save` | Saves a playlist under a certain name. Name must be no longer than 20 characters and mustn't contain dashes. | `!m save classical1`
|
||||
`!m load` | Loads a playlist under a certain name. | `!m load classical-1`
|
||||
`!m playlists`, `!m pls` | Lists all playlists. Paginated. 20 per page. Default page is 0. | `!m pls 1`
|
||||
`!m deleteplaylist`, `!m delpls` | Deletes a saved playlist. Only if you made it or if you are the bot owner. | `!m delpls animu-5`
|
||||
`!m goto` | Goes to a specific time in seconds in a song.
|
||||
`!m getlink`, `!m gl` | Shows a link to the currently playing song.
|
||||
`!m autoplay`, `!m ap` | Toggles autoplay - When the song is finished, automatically queue a related youtube song. (Works only for youtube songs and when queue is empty)
|
||||
`!!next`, `!!n`, `!!skip` | Goes to the next song in the queue. You have to be in the same voice channel as the bot. | `!!n`
|
||||
`!!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`
|
||||
`!!queue`, `!!q`, `!!yq` | Queue a song using keywords or a link. Bot will join your voice channel.**You must be in a voice channel**. | `!!q Dream Of Venice`
|
||||
`!!soundcloudqueue`, `!!sq` | Queue a soundcloud song using keywords. Bot will join your voice channel.**You must be in a voice channel**. | `!!sq Dream Of Venice`
|
||||
`!!listqueue`, `!!lq` | Lists 15 currently queued songs per page. Default page is 1. | `!!lq` or `!!lq 2`
|
||||
`!!nowplaying`, `!!np` | Shows the song currently playing. | `!!np`
|
||||
`!!volume`, `!!vol` | Sets the music volume 0-100% | `!!vol 50`
|
||||
`!!defvol`, `!!dv` | Sets the default music volume when music playback is started (0-100). Persists through restarts. | `!!dv 80`
|
||||
`!!mute`, `!!min` | Sets the music volume to 0% | `!!min`
|
||||
`!!max` | Sets the music volume to 100%. | `!!max`
|
||||
`!!half` | Sets the music volume to 50%. | `!!half`
|
||||
`!!shuffle`, `!!sh` | Shuffles the current playlist. | `!!sh`
|
||||
`!!playlist`, `!!pl` | Queues up to 500 songs from a youtube playlist specified by a link, or keywords. | `!!pl playlist link or name`
|
||||
`!!soundcloudpl`, `!!scpl` | Queue a soundcloud playlist using a link. | `!!scpl https://soundcloud.com/saratology/sets/symphony`
|
||||
`!!localplaylst`, `!!lopl` | Queues all songs from a directory. **Bot Owner Only!** | `!!lopl C:/music/classical`
|
||||
`!!radio`, `!!ra` | Queues a radio stream from a link. It can be a direct mp3 radio stream, .m3u, .pls .asx or .xspf (Usage Video: <https://streamable.com/al54>) | `!!ra radio link here`
|
||||
`!!local`, `!!lo` | Queues a local file by specifying a full path. **Bot Owner Only!** | `!!lo C:/music/mysong.mp3`
|
||||
`!!move`, `!!mv` | Moves the bot to your voice channel. (works only if music is already playing) | `!!mv`
|
||||
`!!remove`, `!!rm` | Remove a song by its # in the queue, or 'all' to remove whole queue. | `!!rm 5`
|
||||
`!!movesong`, `!!ms` | Moves a song from one position to another. | `!! ms` 5>3
|
||||
`!!setmaxqueue`, `!!smq` | Sets a maximum queue size. Supply 0 or no argument to have no limit. | `!!smq` 50 or `!!smq`
|
||||
`!!cleanup` | Cleans up hanging voice connections. **Bot Owner Only!** | `!!cleanup`
|
||||
`!!reptcursong`, `!!rcs` | Toggles repeat of current song. | `!!rcs`
|
||||
`!!rpeatplaylst`, `!!rpl` | Toggles repeat of all songs in the queue (every song that finishes is added to the end of the queue). | `!!rpl`
|
||||
`!!save` | Saves a playlist under a certain name. Name must be no longer than 20 characters and mustn't contain dashes. | `!!save classical1`
|
||||
`!!load` | Loads a playlist under a certain name. | `!!load classical-1`
|
||||
`!!playlists`, `!!pls` | Lists all playlists. Paginated. 20 per page. Default page is 0. | `!!pls 1`
|
||||
`!!deleteplaylist`, `!!delpls` | Deletes a saved playlist. Only if you made it or if you are the bot owner. | `!!delpls animu-5`
|
||||
`!!goto` | Goes to a specific time in seconds in a song.
|
||||
`!!getlink`, `!!gl` | Shows a link to the currently playing song.
|
||||
`!!autoplay`, `!!ap` | Toggles autoplay - When the song is finished, automatically queue a related youtube song. (Works only for youtube songs and when queue is empty)
|
||||
|
||||
### Searches
|
||||
Command and aliases | Description | Usage
|
||||
@ -253,7 +259,7 @@ Command and aliases | Description | Usage
|
||||
`~osu b` | Shows information about an osu beatmap. | ~osu b https://osu.ppy.sh/s/127712
|
||||
`~osu top5` | Displays a user's top 5 plays. | ~osu top5 Name
|
||||
`~pokemon`, `~poke` | Searches for a pokemon.
|
||||
`~pokemonability`, `~pokab` | Searches for a pokemon ability.
|
||||
`~pokemonability`, `~pokeab` | Searches for a pokemon ability.
|
||||
`~memelist` | Pulls a list of memes you can use with `~memegen` from http://memegen.link/templates/
|
||||
`~memegen` | Generates a meme from memelist with top and bottom text. | `~memegen biw "gets iced coffee" "in the winter"`
|
||||
`~we` | Shows weather data for a specified city and a country. BOTH ARE REQUIRED. Use country abbrevations. | ~we Moscow RF
|
||||
@ -265,6 +271,7 @@ Command and aliases | Description | Usage
|
||||
`~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.
|
||||
`~google`, `~g` | Get a google search link for some terms.
|
||||
`~hs` | Searches for a Hearthstone card and shows its image. Takes a while to complete. | ~hs Ysera
|
||||
`~ud` | Searches Urban Dictionary for a word. | ~ud Pineapple
|
||||
`~#` | Searches Tagdef.com for a hashtag. | ~# ff
|
||||
@ -301,16 +308,18 @@ Command and aliases | Description | Usage
|
||||
`,startwar`, `,sw` | Starts a war with a given number.
|
||||
`,listwar`, `,lw` | Shows the active war claims by a number. Shows all wars in a short way if no number is specified. | ,lw [war_number] or ,lw
|
||||
`,claim`, `,call`, `,c` | Claims a certain base from a certain war. You can supply a name in the third optional argument to claim in someone else's place. | ,call [war_number] [base_number] [optional_other_name]
|
||||
`,claimfinish`, `,cf` | Finish your claim if you destroyed a base. Optional second argument finishes for someone else. | ,cf [war_number] [optional_other_name]
|
||||
`,claimfinish`, `,cf`, `,cf3`, `,claimfinish3` | Finish your claim with 3 stars if you destroyed a base. Optional second argument finishes for someone else. | ,cf [war_number] [optional_other_name]
|
||||
`,claimfinish2`, `,cf2` | Finish your claim with 2 stars if you destroyed a base. Optional second argument finishes for someone else. | ,cf [war_number] [optional_other_name]
|
||||
`,claimfinish1`, `,cf1` | Finish your claim with 1 stars if you destroyed a base. Optional second argument finishes for someone else. | ,cf [war_number] [optional_other_name]
|
||||
`,unclaim`, `,uncall`, `,uc` | Removes your claim from a certain war. Optional second argument denotes a person in whos place to unclaim | ,uc [war_number] [optional_other_name]
|
||||
`,endwar`, `,ew` | Ends the war with a given index. | ,ew [war_number]
|
||||
|
||||
### Pokegame
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`>attack` | Attacks a target with the given move
|
||||
`>attack` | Attacks a target with the given move. Use `>movelist` to see a list of moves your type can use. | `>attack "vine whip" @someguy`
|
||||
`>movelist`, `>ml` | Lists the moves you are able to use
|
||||
`>heal` | Heals someone. Revives those that fainted. Costs a NadekoFlower | >revive @someone
|
||||
`>heal` | Heals someone. Revives those who fainted. Costs a NadekoFlower | >heal @someone
|
||||
`>type` | Get the poketype of the target. | >type @someone
|
||||
`>settype` | Set your poketype. Costs a NadekoFlower. | >settype fire
|
||||
|
||||
@ -328,16 +337,17 @@ Command and aliases | Description | Usage
|
||||
`moveto` | Custom reaction. | moveto
|
||||
`comeatmebro` | Custom reaction. | comeatmebro
|
||||
`e` | Custom reaction. | e
|
||||
`@BotName insult`, `<@!119777021319577610> insult` | Custom reaction. | %mention% insult
|
||||
`@BotName praise`, `<@!119777021319577610> praise` | Custom reaction. | %mention% praise
|
||||
`@BotName pat`, `<@!119777021319577610> pat` | Custom reaction. | %mention% pat
|
||||
`@BotName cry`, `<@!119777021319577610> cry` | Custom reaction. | %mention% cry
|
||||
`@BotName are you real?`, `<@!119777021319577610> are you real?` | Custom reaction. | %mention% are you real?
|
||||
`@BotName are you there?`, `<@!119777021319577610> are you there?` | Custom reaction. | %mention% are you there?
|
||||
`@BotName draw`, `<@!119777021319577610> draw` | Custom reaction. | %mention% draw
|
||||
`@BotName bb`, `<@!119777021319577610> bb` | Custom reaction. | %mention% bb
|
||||
`@BotName call`, `<@!119777021319577610> call` | Custom reaction. | %mention% call
|
||||
`@BotName disguise`, `<@!119777021319577610> disguise` | Custom reaction. | %mention% disguise
|
||||
`@BotName insult`, `<@!116275390695079945> insult` | Custom reaction. | %mention% insult
|
||||
`@BotName praise`, `<@!116275390695079945> praise` | Custom reaction. | %mention% praise
|
||||
`@BotName pat`, `<@!116275390695079945> pat` | Custom reaction. | %mention% pat
|
||||
`@BotName cry`, `<@!116275390695079945> cry` | Custom reaction. | %mention% cry
|
||||
`@BotName are you real?`, `<@!116275390695079945> are you real?` | Custom reaction. | %mention% are you real?
|
||||
`@BotName are you there?`, `<@!116275390695079945> are you there?` | Custom reaction. | %mention% are you there?
|
||||
`@BotName draw`, `<@!116275390695079945> draw` | Custom reaction. | %mention% draw
|
||||
`@BotName bb`, `<@!116275390695079945> bb` | Custom reaction. | %mention% bb
|
||||
`@BotName call`, `<@!116275390695079945> call` | Custom reaction. | %mention% call
|
||||
`@BotName disguise`, `<@!116275390695079945> disguise` | Custom reaction. | %mention% disguise
|
||||
`~hentai` | Custom reaction. | ~hentai
|
||||
|
||||
### Trello
|
||||
Command and aliases | Description | Usage
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 80f9d6f2de25355a245bf93d4019d16e3fd033ca
|
||||
Subproject commit 3e519b5e0b33175e5a5ca247322b7082de484e15
|
Loading…
Reference in New Issue
Block a user