Merge remote-tracking branch 'refs/remotes/Kwoth/master' into patch-4

# Conflicts:
#	NadekoBot/NadekoBot.cs
#	NadekoBot/NadekoBot.csproj
This commit is contained in:
appelemac
2016-05-02 14:23:17 +02:00
19 changed files with 296 additions and 103 deletions

View File

@ -69,9 +69,9 @@ namespace NadekoBot.Modules.Administration.Commands
if (channel == null) return;
Greeted++;
var toDelete = await channel.SendMessage(msg).ConfigureAwait(false);
if (e.Server.CurrentUser.GetPermissions(channel).ManageMessages)
if (e.Server.CurrentUser.GetPermissions(channel).ManageMessages && controls.DeleteGreetMessages)
{
await Task.Delay(300000).ConfigureAwait(false); // 5 minutes
await Task.Delay(30000).ConfigureAwait(false); // 5 minutes
await toDelete.Delete().ConfigureAwait(false);
}
}
@ -102,9 +102,9 @@ namespace NadekoBot.Modules.Administration.Commands
if (channel == null) return;
Greeted++;
var toDelete = await channel.SendMessage(msg).ConfigureAwait(false);
if (e.Server.CurrentUser.GetPermissions(channel).ManageMessages)
if (e.Server.CurrentUser.GetPermissions(channel).ManageMessages && controls.DeleteGreetMessages)
{
await Task.Delay(300000).ConfigureAwait(false); // 5 minutes
await Task.Delay(30000).ConfigureAwait(false); // 5 minutes
await toDelete.Delete().ConfigureAwait(false);
}
}
@ -160,6 +160,15 @@ namespace NadekoBot.Modules.Administration.Commands
set { _model.ServerId = (long)value; }
}
public bool DeleteGreetMessages {
get {
return _model.DeleteGreetMessages;
}
set {
_model.DeleteGreetMessages = value; Save();
}
}
public AnnounceControls(DataModels.Announcement model)
{
this._model = model;
@ -196,6 +205,8 @@ namespace NadekoBot.Modules.Administration.Commands
return Greet = true;
}
}
internal bool ToggleDelete() => DeleteGreetMessages = !DeleteGreetMessages;
internal bool ToggleGreetPM() => GreetPM = !GreetPM;
internal bool ToggleByePM() => ByePM = !ByePM;
@ -207,18 +218,27 @@ namespace NadekoBot.Modules.Administration.Commands
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "grdel")
.Description("Enables or Disables automatic deletion of greet and bye messages.")
.Do(async e =>
{
if (!e.User.ServerPermissions.ManageServer) return;
var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
if (ann.ToggleDelete())
await e.Channel.SendMessage("`Automatic deletion of greet and bye messages has been enabled.`").ConfigureAwait(false);
else
await e.Channel.SendMessage("`Automatic deletion of greet and bye messages has been disabled.`").ConfigureAwait(false);
});
cgb.CreateCommand(Module.Prefix + "greet")
.Description("Enables or Disables anouncements on the current channel when someone joins the server.")
.Do(async e =>
{
if (!e.User.ServerPermissions.ManageServer) return;
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
var controls = AnnouncementsDictionary[e.Server.Id];
if (controls.ToggleGreet(e.Channel.Id))
if (ann.ToggleGreet(e.Channel.Id))
await e.Channel.SendMessage("Greet announcements enabled on this channel.").ConfigureAwait(false);
else
await e.Channel.SendMessage("Greet announcements disabled.").ConfigureAwait(false);
@ -231,12 +251,11 @@ namespace NadekoBot.Modules.Administration.Commands
{
if (!e.User.ServerPermissions.ManageServer) return;
if (e.GetArg("msg") == null) return;
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
AnnouncementsDictionary[e.Server.Id].GreetText = e.GetArg("msg");
ann.GreetText = e.GetArg("msg");
await e.Channel.SendMessage("New greet message set.").ConfigureAwait(false);
if (!AnnouncementsDictionary[e.Server.Id].Greet)
if (!ann.Greet)
await e.Channel.SendMessage("Enable greet messsages by typing `.greet`").ConfigureAwait(false);
});
@ -245,12 +264,9 @@ namespace NadekoBot.Modules.Administration.Commands
.Do(async e =>
{
if (!e.User.ServerPermissions.ManageServer) return;
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
var controls = AnnouncementsDictionary[e.Server.Id];
if (controls.ToggleBye(e.Channel.Id))
if (ann.ToggleBye(e.Channel.Id))
await e.Channel.SendMessage("Bye announcements enabled on this channel.").ConfigureAwait(false);
else
await e.Channel.SendMessage("Bye announcements disabled.").ConfigureAwait(false);
@ -263,12 +279,11 @@ namespace NadekoBot.Modules.Administration.Commands
{
if (!e.User.ServerPermissions.ManageServer) return;
if (e.GetArg("msg") == null) return;
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
AnnouncementsDictionary[e.Server.Id].ByeText = e.GetArg("msg");
ann.ByeText = e.GetArg("msg");
await e.Channel.SendMessage("New bye message set.").ConfigureAwait(false);
if (!AnnouncementsDictionary[e.Server.Id].Bye)
if (!ann.Bye)
await e.Channel.SendMessage("Enable bye messsages by typing `.bye`.").ConfigureAwait(false);
});
@ -277,15 +292,14 @@ namespace NadekoBot.Modules.Administration.Commands
.Do(async e =>
{
if (!e.User.ServerPermissions.ManageServer) return;
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
AnnouncementsDictionary[e.Server.Id].ToggleByePM();
if (AnnouncementsDictionary[e.Server.Id].ByePM)
if (ann.ToggleByePM())
await e.Channel.SendMessage("Bye messages will be sent in a PM from now on.\n ⚠ Keep in mind this might fail if the user and the bot have no common servers after the user leaves.").ConfigureAwait(false);
else
await e.Channel.SendMessage("Bye messages will be sent in a bound channel from now on.").ConfigureAwait(false);
if (!AnnouncementsDictionary[e.Server.Id].Bye)
if (!ann.Bye)
await e.Channel.SendMessage("Enable bye messsages by typing `.bye`, and set the bye message using `.byemsg`").ConfigureAwait(false);
});
@ -294,15 +308,14 @@ namespace NadekoBot.Modules.Administration.Commands
.Do(async e =>
{
if (!e.User.ServerPermissions.ManageServer) return;
if (!AnnouncementsDictionary.ContainsKey(e.Server.Id))
AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
AnnouncementsDictionary[e.Server.Id].ToggleGreetPM();
if (AnnouncementsDictionary[e.Server.Id].GreetPM)
var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id));
if (ann.ToggleGreetPM())
await e.Channel.SendMessage("Greet messages will be sent in a PM from now on.").ConfigureAwait(false);
else
await e.Channel.SendMessage("Greet messages will be sent in a bound channel from now on.").ConfigureAwait(false);
if (!AnnouncementsDictionary[e.Server.Id].Greet)
if (!ann.Greet)
await e.Channel.SendMessage("Enable greet messsages by typing `.greet`, and set the greet message using `.greetmsg`").ConfigureAwait(false);
});
}

View File

@ -130,7 +130,7 @@ namespace NadekoBot.Modules.Games.Commands.Trivia
await channel.SendMessage($"☑️ {e.User.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**").ConfigureAwait(false);
if (Users[e.User] != WinRequirement) return;
ShouldStopGame = true;
await channel.Send($":exclamation: We have a winner! Its {e.User.Mention}.").ConfigureAwait(false);
await channel.Send($":exclamation: We have a winner! It's {e.User.Mention}.").ConfigureAwait(false);
// add points to the winner
await FlowersHandler.AddFlowersAsync(e.User, "Won Trivia", 2).ConfigureAwait(false);
}

View File

@ -11,47 +11,21 @@ namespace NadekoBot.Classes.Help.Commands
{
internal class HelpCommand : DiscordCommand
{
public Func<CommandEventArgs, Task> DoFunc() => async e =>
public Func<CommandEventArgs, Task> HelpFunc() => async e =>
{
#region OldHelp
/*
string helpstr = "**COMMANDS DO NOT WORK IN PERSONAL MESSAGES**\nOfficial repo: **github.com/Kwoth/NadekoBot/**";
string lastCategory = "";
foreach (var com in client.GetService<CommandService>().AllCommands)
{
if (com.Category != lastCategory)
{
helpstr += "\n`----`**`" + com.Category + "`**`----`\n";
lastCategory = com.Category;
}
helpstr += PrintCommandHelp(com);
}
helpstr += "\nBot Creator's server: https://discord.gg/0ehQwTK2RBhxEi0X";
helpstr = helpstr.Replace(NadekoBot.botMention, "@BotName");
while (helpstr.Length > 2000)
{
var curstr = helpstr.Substring(0, 2000);
await e.User.Send(curstr.Substring(0, curstr.LastIndexOf("\n") + 1)).ConfigureAwait(false);
helpstr = curstr.Substring(curstr.LastIndexOf("\n") + 1) + helpstr.Substring(2000);
await Task.Delay(200).ConfigureAwait(false);
}
*/
#endregion OldHelp
if (string.IsNullOrWhiteSpace(e.GetArg("command")))
var comToFind = e.GetArg("command")?.ToLowerInvariant();
if (string.IsNullOrWhiteSpace(comToFind))
{
await e.User.Send(HelpString).ConfigureAwait(false);
return;
}
await Task.Run(async () =>
{
var comToFind = e.GetArg("command");
var com = NadekoBot.Client.GetService<CommandService>().AllCommands
.FirstOrDefault(c => c.Text.ToLower().Equals(comToFind));
.FirstOrDefault(c => c.Text.ToLowerInvariant().Equals(comToFind) ||
c.Aliases.Select(a => a.ToLowerInvariant()).Contains(comToFind));
if (com != null)
await e.Channel.SendMessage($"`Help for '{com.Text}':` **{com.Description}**").ConfigureAwait(false);
await e.Channel.SendMessage($"`Help for '{com.Text}':` {com.Description}").ConfigureAwait(false);
}).ConfigureAwait(false);
};
public static string HelpString => (NadekoBot.IsBot
@ -102,7 +76,7 @@ Version: `{NadekoStats.Instance.BotVersion}`";
.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' ")
.Parameter("command", ParameterType.Unparsed)
.Do(DoFunc());
.Do(HelpFunc());
cgb.CreateCommand(Module.Prefix + "hgit")
.Description("Generates the commandlist.md file. **Owner Only!**")
.AddCheck(SimpleCheckers.OwnerOnly())

View File

@ -488,16 +488,6 @@ namespace NadekoBot.Modules.Music
});
//cgb.CreateCommand("info")
// .Description("Prints music info (queued/finished/playing) only to this channel")
// .Do(async e =>
// {
// MusicPlayer musicPlayer;
// if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
// return;
// musicPlayer
// });
cgb.CreateCommand("load")
.Description("Loads a playlist under a certain name. \n**Usage**: `!m load classical-1`")
.Parameter("name", ParameterType.Unparsed)
@ -553,6 +543,23 @@ 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`")
.Parameter("num", ParameterType.Optional)
.Do(e =>
{
int num = 0;
int.TryParse(e.GetArg("num"), out num);
if (num < 0)
return;
var result = DbHandler.Instance.GetPlaylistData(num);
if (result.Count == 0)
e.Channel.SendMessage($"`No saved playlists found on page {num}`");
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} ---```");
});
cgb.CreateCommand("goto")
.Description("Goes to a specific time in seconds in a song.")
.Parameter("time")
@ -589,6 +596,20 @@ namespace NadekoBot.Modules.Music
await e.Channel.SendMessage($"`Skipped to {minutes}:{seconds}`").ConfigureAwait(false);
});
cgb.CreateCommand("getlink")
.Alias("gl")
.Description("Shows a link to the currently playing song.")
.Do(async e =>
{
MusicPlayer musicPlayer;
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer))
return;
var curSong = musicPlayer.CurrentSong;
if (curSong == null)
return;
await e.Channel.SendMessage($"🎶`Current song:` <{curSong.SongInfo.Query}>");
});
});
}

View File

@ -48,14 +48,7 @@ namespace NadekoBot.Modules.NSFW
var tag = e.GetArg("tag")?.Trim() ?? "";
await e.Channel.SendMessage(await SearchHelper.GetGelbooruImageLink(tag).ConfigureAwait(false)).ConfigureAwait(false);
});
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")
.Parameter("tag", ParameterType.Unparsed)
.Do(async e =>
{
var tag = e.GetArg("tag")?.Trim() ?? "";
await e.Channel.SendMessage(await SearchHelper.GetSafebooruImageLink(tag).ConfigureAwait(false)).ConfigureAwait(false);
});
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**: ~gelbooru yuri+kissing")
.Parameter("tag", ParameterType.Unparsed)

View File

@ -0,0 +1,92 @@
using Discord;
using Discord.Commands;
using NadekoBot.Classes;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
/// <summary>
/// I have no idea what am i doing
/// </summary>
namespace NadekoBot.Modules.Programming.Commands
{
class HaskellRepl : DiscordCommand
{
ConcurrentQueue<KeyValuePair<string, Channel>> commandQueue = new ConcurrentQueue<KeyValuePair<string, Channel>>();
Thread haskellThread;
public HaskellRepl(DiscordModule module) : base(module)
{
//start haskell interpreter
haskellThread = new Thread(new ThreadStart(() =>
{
var p = Process.Start(new ProcessStartInfo
{
FileName = "stack", //shouldn't use repl, but a Language.Haskell.Interpreter somehow
Arguments = "repl",
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
});
Task.Run(async () =>
{
while (true)
{
while (commandQueue.Count == 0)
await Task.Delay(100);
//read from queue
KeyValuePair<string, Channel> com;
if (!commandQueue.TryDequeue(out com))
{
await Task.Delay(100);
continue;
}
//var bytes = Encoding.ASCII.GetBytes(com.Key);
//send the command to the process
p.StandardInput.WriteLine(com.Key);
//wait 50 ms for execution
await Task.Delay(50);
//read everything from the output
var outBuffer = new byte[1500];
p.StandardOutput.BaseStream.Read(outBuffer, 0, 1500);
var outStr = Encoding.ASCII.GetString(outBuffer);
//send to channel
await com.Value.SendMessage($"```hs\nPrelude> {com.Key}\n" + outStr + "\n```");
}
});
}));
haskellThread.Start();
}
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "hs")
.Description("Executes a haskell express with LAMBDABOT")
.Parameter("command", ParameterType.Unparsed)
.Do(e =>
{
var com = e.GetArg("command")?.Trim();
if (string.IsNullOrWhiteSpace(com))
return;
//send a command and a channel to the queue
commandQueue.Enqueue(new KeyValuePair<string, Channel>(com, e.Channel));
});
}
}
}

View File

@ -0,0 +1,26 @@
using Discord.Modules;
using NadekoBot.Extensions;
using NadekoBot.Modules.Permissions.Classes;
using NadekoBot.Modules.Programming.Commands;
namespace NadekoBot.Modules.Programming
{
class ProgrammingModule : DiscordModule
{
public override string Prefix => NadekoBot.Config.CommandPrefixes.Programming;
public ProgrammingModule()
{
commands.Add(new HaskellRepl(this));
}
public override void Install(ModuleManager manager)
{
manager.CreateCommands("", cgb =>
{
cgb.AddCheck(PermissionChecker.Instance);
commands.ForEach(c => c.Init(cgb));
});
}
}
}

View File

@ -92,6 +92,8 @@ namespace NadekoBot.Modules.Searches.Commands
}
else
{
CultureInfo ci = new CultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = ci;
reInitCurrencyConverterTable();
Unit inUnit = currTable.CreateUnit(quantity, from.ToUpperInvariant());
Unit outUnit = inUnit.Convert(currTable.CurrencyCode(to.ToUpperInvariant()));
@ -109,9 +111,16 @@ namespace NadekoBot.Modules.Searches.Commands
{
if (lastChanged == null || lastChanged.DayOfYear != DateTime.Now.DayOfYear)
{
exchangeRateProvider = new WebExchangeRatesProvider();
currTable = new CurrencyExchangeTable(exchangeRateProvider);
lastChanged = DateTime.Now;
try
{
exchangeRateProvider = new WebExchangeRatesProvider();
currTable = new CurrencyExchangeTable(exchangeRateProvider);
lastChanged = DateTime.Now;
}
catch
{
Console.WriteLine("Error with the currency download.");
}
}
}

View File

@ -409,6 +409,27 @@ $@"🌍 **Weather for** 【{obj["target"]}】
return;
await e.Channel.SendMessage($"https://images.google.com/searchbyimage?image_url={usr.AvatarUrl}").ConfigureAwait(false);
});
cgb.CreateCommand(Prefix + "revimg")
.Description("Returns a google reverse image search for an image from a link.")
.Parameter("image", ParameterType.Unparsed)
.Do(async e =>
{
var imgLink = e.GetArg("image")?.Trim();
if (string.IsNullOrWhiteSpace(imgLink))
return;
await e.Channel.SendMessage($"https://images.google.com/searchbyimage?image_url={imgLink}").ConfigureAwait(false);
});
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")
.Parameter("tag", ParameterType.Unparsed)
.Do(async e =>
{
var tag = e.GetArg("tag")?.Trim() ?? "";
await e.Channel.SendMessage(await SearchHelper.GetSafebooruImageLink(tag).ConfigureAwait(false)).ConfigureAwait(false);
});
});
}
}