Merge remote-tracking branch 'refs/remotes/Kwoth/master' into selfassignedtoggle
merging branch
This commit is contained in:
@ -6,8 +6,11 @@ using NadekoBot.DataModels;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Administration.Commands;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Administration
|
||||
@ -76,7 +79,7 @@ namespace NadekoBot.Modules.Administration
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "restart")
|
||||
.Description("Restarts the bot. Might not work.")
|
||||
.Description("Restarts the bot. Might not work. **Bot Owner Only**")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -902,6 +905,33 @@ namespace NadekoBot.Modules.Administration
|
||||
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)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
var cntstr = e.GetArg("cnt")?.Trim();
|
||||
int cnt;
|
||||
if (!int.TryParse(cntstr, out cnt))
|
||||
return;
|
||||
ulong? lastmsgId = null;
|
||||
var sb = new StringBuilder();
|
||||
var msgs = new List<Message>(cnt);
|
||||
while (cnt > 0)
|
||||
{
|
||||
var dlcnt = cnt < 100 ? cnt : 100;
|
||||
|
||||
var dledMsgs = await e.Channel.DownloadMessages(dlcnt, lastmsgId);
|
||||
if (!dledMsgs.Any())
|
||||
break;
|
||||
msgs.AddRange(dledMsgs);
|
||||
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());
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -45,14 +46,88 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
|
||||
cgb.CreateCommand(Prefix + "listcustreact")
|
||||
.Alias(Prefix + "lcr")
|
||||
.Description($"Lists all current custom reactions (paginated with 5 commands per page).\n**Usage**:{Prefix}lcr 1")
|
||||
.Description($"Lists all current custom reactions (paginated with 30 commands per page).\n**Usage**:{Prefix}lcr 1")
|
||||
.Parameter("num", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
int num;
|
||||
if (!int.TryParse(e.GetArg("num"), out num) || num <= 0) return;
|
||||
string result = GetCustomsOnPage(num - 1); //People prefer starting with 1
|
||||
await e.Channel.SendMessage(result).ConfigureAwait(false);
|
||||
if (!int.TryParse(e.GetArg("num"), out num) || num <= 0) num = 1;
|
||||
var cmds = GetCustomsOnPage(num - 1);
|
||||
if (!cmds.Any())
|
||||
{
|
||||
await e.Channel.SendMessage("");
|
||||
}
|
||||
else
|
||||
{
|
||||
string result = SearchHelper.ShowInPrettyCode<string>(cmds, s => $"{s,-25}"); //People prefer starting with 1
|
||||
await e.Channel.SendMessage($"`Showing page {num}:`\n" + result).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "showcustreact")
|
||||
.Alias(Prefix + "scr")
|
||||
.Description($"Shows all possible responses from a single custom reaction.\n**Usage**:{Prefix}scr %mention% bb")
|
||||
.Parameter("name", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var name = e.GetArg("name")?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
return;
|
||||
if (!NadekoBot.Config.CustomReactions.ContainsKey(name))
|
||||
{
|
||||
await e.Channel.SendMessage("`Can't find that custom reaction.`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
var items = NadekoBot.Config.CustomReactions[name];
|
||||
var message = new StringBuilder($"Responses for {Format.Bold(name)}:\n");
|
||||
var last = items.Last();
|
||||
|
||||
int i = 1;
|
||||
foreach (var reaction in items)
|
||||
{
|
||||
message.AppendLine($"[{i++}] " + Format.Code(reaction));
|
||||
}
|
||||
await e.Channel.SendMessage(message.ToString());
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "editcustreact")
|
||||
.Alias(Prefix + "ecr")
|
||||
.Description("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`")
|
||||
.Parameter("name", ParameterType.Required)
|
||||
.Parameter("index", ParameterType.Required)
|
||||
.Parameter("message", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.Do(async e =>
|
||||
{
|
||||
var name = e.GetArg("name")?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
return;
|
||||
var indexstr = e.GetArg("index")?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(indexstr))
|
||||
return;
|
||||
var msg = e.GetArg("message")?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(msg))
|
||||
return;
|
||||
|
||||
|
||||
|
||||
if (!NadekoBot.Config.CustomReactions.ContainsKey(name))
|
||||
{
|
||||
await e.Channel.SendMessage("`Could not find given commandname`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
int index;
|
||||
if (!int.TryParse(indexstr, out index) || index < 1 || index > NadekoBot.Config.CustomReactions[name].Count)
|
||||
{
|
||||
await e.Channel.SendMessage("`Invalid index.`").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
index = index - 1;
|
||||
NadekoBot.Config.CustomReactions[name][index] = msg;
|
||||
|
||||
await Task.Run(() => Classes.JSONModels.ConfigHandler.SaveConfig()).ConfigureAwait(false);
|
||||
await e.Channel.SendMessage($"Edited response #{index + 1} from `{name}`").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "delcustreact")
|
||||
@ -99,19 +174,21 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
});
|
||||
}
|
||||
|
||||
private readonly int ItemsPerPage = 5;
|
||||
private readonly int ItemsPerPage = 30;
|
||||
|
||||
private string GetCustomsOnPage(int page)
|
||||
private IEnumerable<string> GetCustomsOnPage(int page)
|
||||
{
|
||||
var items = NadekoBot.Config.CustomReactions.Skip(page * ItemsPerPage).Take(ItemsPerPage);
|
||||
if (!items.Any())
|
||||
{
|
||||
return $"No items on page {page + 1}.";
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
return items.Select(kvp => kvp.Key);
|
||||
/*
|
||||
var message = new StringBuilder($"--- Custom reactions - page {page + 1} ---\n");
|
||||
foreach (var cr in items)
|
||||
{
|
||||
message.Append($"{ Format.Code(cr.Key)}\n");
|
||||
message.Append($"{Format.Code(cr.Key)}\n");
|
||||
int i = 1;
|
||||
var last = cr.Value.Last();
|
||||
foreach (var reaction in cr.Value)
|
||||
@ -123,6 +200,7 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
}
|
||||
}
|
||||
return message.ToString() + "\n";
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,19 +4,12 @@ using NadekoBot.Classes;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
internal class LogCommand : DiscordCommand
|
||||
{
|
||||
|
||||
private readonly ConcurrentDictionary<Server, Channel> logs = new ConcurrentDictionary<Server, Channel>();
|
||||
private readonly ConcurrentDictionary<Server, Channel> loggingPresences = new ConcurrentDictionary<Server, Channel>();
|
||||
private readonly ConcurrentDictionary<Channel, Channel> voiceChannelLog = new ConcurrentDictionary<Channel, Channel>();
|
||||
|
||||
private string prettyCurrentTime => $"【{DateTime.Now:HH:mm:ss}】";
|
||||
|
||||
public LogCommand(DiscordModule module) : base(module)
|
||||
@ -58,8 +51,11 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
try
|
||||
{
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null)
|
||||
return;
|
||||
Channel ch;
|
||||
if (!logs.TryGetValue(e.Server, out ch))
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
if (e.Before.Name != e.After.Name)
|
||||
await ch.SendMessage($@"`{prettyCurrentTime}` **Channel Name Changed** `#{e.Before.Name}` (*{e.After.Id}*)
|
||||
@ -76,8 +72,11 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
try
|
||||
{
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null)
|
||||
return;
|
||||
Channel ch;
|
||||
if (!logs.TryGetValue(e.Server, out ch))
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
await ch.SendMessage($"❗`{prettyCurrentTime}`❗`Channel Deleted:` #{e.Channel.Name} (*{e.Channel.Id}*)").ConfigureAwait(false);
|
||||
}
|
||||
@ -88,8 +87,11 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
try
|
||||
{
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null)
|
||||
return;
|
||||
Channel ch;
|
||||
if (!logs.TryGetValue(e.Server, out ch))
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
await ch.SendMessage($"`{prettyCurrentTime}`🆕`Channel Created:` #{e.Channel.Mention} (*{e.Channel.Id}*)").ConfigureAwait(false);
|
||||
}
|
||||
@ -100,8 +102,11 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
try
|
||||
{
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null)
|
||||
return;
|
||||
Channel ch;
|
||||
if (!logs.TryGetValue(e.Server, out ch))
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
await ch.SendMessage($"`{prettyCurrentTime}`♻`User was unbanned:` **{e.User.Name}** ({e.User.Id})").ConfigureAwait(false);
|
||||
}
|
||||
@ -112,8 +117,11 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
try
|
||||
{
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null)
|
||||
return;
|
||||
Channel ch;
|
||||
if (!logs.TryGetValue(e.Server, out ch))
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
await ch.SendMessage($"`{prettyCurrentTime}`✅`User joined:` **{e.User.Name}** ({e.User.Id})").ConfigureAwait(false);
|
||||
}
|
||||
@ -124,8 +132,11 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
try
|
||||
{
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null)
|
||||
return;
|
||||
Channel ch;
|
||||
if (!logs.TryGetValue(e.Server, out ch))
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
await ch.SendMessage($"`{prettyCurrentTime}`❗`User left:` **{e.User.Name}** ({e.User.Id})").ConfigureAwait(false);
|
||||
}
|
||||
@ -136,35 +147,28 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
try
|
||||
{
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null)
|
||||
return;
|
||||
Channel ch;
|
||||
if (!logs.TryGetValue(e.Server, out ch))
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
await ch.SendMessage($"❗`{prettyCurrentTime}`❌`User banned:` **{e.User.Name}** ({e.User.Id})").ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public Func<CommandEventArgs, Task> DoFunc() => async e =>
|
||||
{
|
||||
Channel ch;
|
||||
if (!logs.TryRemove(e.Server, out ch))
|
||||
{
|
||||
logs.TryAdd(e.Server, e.Channel);
|
||||
await e.Channel.SendMessage($"❗**I WILL BEGIN LOGGING SERVER ACTIVITY IN THIS CHANNEL**❗").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await e.Channel.SendMessage($"❗**NO LONGER LOGGING IN {ch.Mention} CHANNEL**❗").ConfigureAwait(false);
|
||||
};
|
||||
|
||||
private async void MsgRecivd(object sender, MessageEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
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)
|
||||
return;
|
||||
Channel ch;
|
||||
if (!logs.TryGetValue(e.Server, out ch) || e.Channel == ch)
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
if (!string.IsNullOrWhiteSpace(e.Message.Text))
|
||||
{
|
||||
@ -188,8 +192,11 @@ 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)
|
||||
return;
|
||||
Channel ch;
|
||||
if (!logs.TryGetValue(e.Server, out ch) || e.Channel == ch)
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
if (!string.IsNullOrWhiteSpace(e.Message.Text))
|
||||
{
|
||||
@ -212,8 +219,11 @@ 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)
|
||||
return;
|
||||
Channel ch;
|
||||
if (!logs.TryGetValue(e.Server, out ch) || e.Channel == ch)
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
await ch.SendMessage(
|
||||
$@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
@ -225,19 +235,28 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
}
|
||||
private async void UsrUpdtd(object sender, UserUpdatedEventArgs e)
|
||||
{
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
try
|
||||
{
|
||||
Channel ch;
|
||||
if (loggingPresences.TryGetValue(e.Server, out ch))
|
||||
if (e.Before.Status != e.After.Status)
|
||||
var chId = config.LogPresenceChannel;
|
||||
if (chId != null)
|
||||
{
|
||||
Channel ch;
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) != null)
|
||||
{
|
||||
await ch.SendMessage($"`{prettyCurrentTime}`**{e.Before.Name}** is now **{e.After.Status}**.").ConfigureAwait(false);
|
||||
if (e.Before.Status != e.After.Status)
|
||||
{
|
||||
await ch.SendMessage($"`{prettyCurrentTime}`**{e.Before.Name}** is now **{e.After.Status}**.").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
ulong notifyChBeforeId;
|
||||
ulong notifyChAfterId;
|
||||
Channel notifyChBefore = null;
|
||||
Channel notifyChAfter = null;
|
||||
var beforeVch = e.Before.VoiceChannel;
|
||||
@ -246,11 +265,11 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
var notifyJoin = false;
|
||||
if ((beforeVch != null || afterVch != null) && (beforeVch != afterVch)) // this means we need to notify for sure.
|
||||
{
|
||||
if (beforeVch != null && voiceChannelLog.TryGetValue(beforeVch, out notifyChBefore))
|
||||
if (beforeVch != null && config.VoiceChannelLog.TryGetValue(beforeVch.Id, out notifyChBeforeId) && (notifyChBefore = e.Before.Server.TextChannels.FirstOrDefault(tc => tc.Id == notifyChBeforeId)) != null)
|
||||
{
|
||||
notifyLeave = true;
|
||||
}
|
||||
if (afterVch != null && voiceChannelLog.TryGetValue(afterVch, out notifyChAfter))
|
||||
if (afterVch != null && config.VoiceChannelLog.TryGetValue(afterVch.Id, out notifyChAfterId) && (notifyChAfter = e.After.Server.TextChannels.FirstOrDefault(tc => tc.Id == notifyChAfterId)) != null)
|
||||
{
|
||||
notifyJoin = true;
|
||||
}
|
||||
@ -272,8 +291,11 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
|
||||
try
|
||||
{
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null)
|
||||
return;
|
||||
Channel ch;
|
||||
if (!logs.TryGetValue(e.Server, out ch))
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
string str = $"🕔`{prettyCurrentTime}`";
|
||||
if (e.Before.Name != e.After.Name)
|
||||
@ -331,21 +353,36 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
.Description("Toggles logging in this channel. Logs every message sent/deleted/edited on the server. **Bot Owner Only!**")
|
||||
.AddCheck(SimpleCheckers.OwnerOnly())
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(DoFunc());
|
||||
.Do(async e =>
|
||||
{
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel;
|
||||
if (chId == null)
|
||||
{
|
||||
SpecificConfigurations.Default.Of(e.Server.Id).LogServerChannel = e.Channel.Id;
|
||||
await e.Channel.SendMessage($"❗**I WILL BEGIN LOGGING SERVER ACTIVITY IN THIS CHANNEL**❗").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
Channel ch;
|
||||
if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null)
|
||||
return;
|
||||
|
||||
SpecificConfigurations.Default.Of (e.Server.Id).LogServerChannel = null;
|
||||
await e.Channel.SendMessage($"❗**NO LONGER LOGGING IN {ch.Mention} CHANNEL**❗").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "userpresence")
|
||||
.Description("Starts logging to this channel when someone from the server goes online/offline/idle.")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
{
|
||||
Channel ch;
|
||||
if (!loggingPresences.TryRemove(e.Server, out ch))
|
||||
var chId = SpecificConfigurations.Default.Of(e.Server.Id).LogPresenceChannel;
|
||||
if (chId == null)
|
||||
{
|
||||
loggingPresences.TryAdd(e.Server, e.Channel);
|
||||
SpecificConfigurations.Default.Of(e.Server.Id).LogPresenceChannel = e.Channel.Id;
|
||||
await e.Channel.SendMessage($"**User presence notifications enabled.**").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
SpecificConfigurations.Default.Of(e.Server.Id).LogPresenceChannel = null;
|
||||
await e.Channel.SendMessage($"**User presence notifications disabled.**").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
@ -356,11 +393,12 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
.Do(async e =>
|
||||
{
|
||||
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
if (e.GetArg("all")?.ToLower() == "all")
|
||||
{
|
||||
foreach (var voiceChannel in e.Server.VoiceChannels)
|
||||
{
|
||||
voiceChannelLog.TryAdd(voiceChannel, e.Channel);
|
||||
config.VoiceChannelLog.TryAdd(voiceChannel.Id, e.Channel.Id);
|
||||
}
|
||||
await e.Channel.SendMessage("Started logging user presence for **ALL** voice channels!").ConfigureAwait(false);
|
||||
return;
|
||||
@ -371,10 +409,10 @@ $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}`
|
||||
await e.Channel.SendMessage("💢 You are not in a voice channel right now. If you are, please rejoin it.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
Channel throwaway;
|
||||
if (!voiceChannelLog.TryRemove(e.User.VoiceChannel, out throwaway))
|
||||
ulong throwaway;
|
||||
if (!config.VoiceChannelLog.TryRemove(e.User.VoiceChannel.Id, out throwaway))
|
||||
{
|
||||
voiceChannelLog.TryAdd(e.User.VoiceChannel, e.Channel);
|
||||
config.VoiceChannelLog.TryAdd(e.User.VoiceChannel.Id, e.Channel.Id);
|
||||
await e.Channel.SendMessage($"`Logging user updates for` {e.User.VoiceChannel.Mention} `voice channel.`").ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
|
@ -51,11 +51,9 @@ namespace NadekoBot.Modules.Administration.Commands
|
||||
{
|
||||
if (PlayingPlaceholders.Count == 0
|
||||
|| NadekoBot.Config.RotatingStatuses.Count == 0
|
||||
|| i >= PlayingPlaceholders.Count
|
||||
|| i >= NadekoBot.Config.RotatingStatuses.Count)
|
||||
{
|
||||
i = -1;
|
||||
return;
|
||||
i = 0;
|
||||
}
|
||||
status = NadekoBot.Config.RotatingStatuses[i];
|
||||
status = PlayingPlaceholders.Aggregate(status,
|
||||
|
@ -1,62 +0,0 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Modules;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Classes.Conversations.Commands
|
||||
{
|
||||
internal class CopyCommand : DiscordCommand
|
||||
{
|
||||
private readonly HashSet<ulong> CopiedUsers = new HashSet<ulong>();
|
||||
|
||||
public CopyCommand(DiscordModule module) : base(module)
|
||||
{
|
||||
NadekoBot.Client.MessageReceived += Client_MessageReceived;
|
||||
}
|
||||
|
||||
private async void Client_MessageReceived(object sender, Discord.MessageEventArgs e)
|
||||
{
|
||||
if (e.User.Id == NadekoBot.Client.CurrentUser.Id) return;
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.Message.Text))
|
||||
return;
|
||||
if (CopiedUsers.Contains(e.User.Id))
|
||||
{
|
||||
await e.Channel.SendMessage(e.Message.Text).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public Func<CommandEventArgs, Task> DoFunc() => async e =>
|
||||
{
|
||||
if (CopiedUsers.Contains(e.User.Id)) return;
|
||||
|
||||
CopiedUsers.Add(e.User.Id);
|
||||
await e.Channel.SendMessage(" I'll start copying you now.").ConfigureAwait(false);
|
||||
};
|
||||
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand("copyme")
|
||||
.Alias("cm")
|
||||
.Description("Nadeko starts copying everything you say. Disable with cs")
|
||||
.Do(DoFunc());
|
||||
|
||||
cgb.CreateCommand("cs")
|
||||
.Alias("copystop")
|
||||
.Description("Nadeko stops copying you")
|
||||
.Do(StopCopy());
|
||||
}
|
||||
|
||||
private Func<CommandEventArgs, Task> StopCopy() => async e =>
|
||||
{
|
||||
if (!CopiedUsers.Contains(e.User.Id)) return;
|
||||
|
||||
CopiedUsers.Remove(e.User.Id);
|
||||
await e.Channel.SendMessage(" I wont copy anymore.").ConfigureAwait(false);
|
||||
};
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.Modules;
|
||||
using NadekoBot.Classes.Conversations.Commands;
|
||||
using NadekoBot.DataModels;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Conversations.Commands;
|
||||
@ -19,7 +18,6 @@ namespace NadekoBot.Modules.Conversations
|
||||
private const string firestr = "🔥 ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้ 🔥";
|
||||
public Conversations()
|
||||
{
|
||||
commands.Add(new CopyCommand(this));
|
||||
commands.Add(new RipCommand(this));
|
||||
}
|
||||
|
||||
@ -255,21 +253,6 @@ namespace NadekoBot.Modules.Conversations
|
||||
await e.Channel.SendMessage(construct).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand("av")
|
||||
.Alias("avatar")
|
||||
.Parameter("mention", ParameterType.Required)
|
||||
.Description("Shows a mentioned person's avatar.\n**Usage**: ~av @X")
|
||||
.Do(async e =>
|
||||
{
|
||||
var usr = e.Channel.FindUsers(e.GetArg("mention")).FirstOrDefault();
|
||||
if (usr == null)
|
||||
{
|
||||
await e.Channel.SendMessage("Invalid user specified.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
await e.Channel.SendMessage(await usr.AvatarUrl.ShortenUrl()).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
await e.Channel.SendFile(images.Count + " cards.jpg", bitmap.ToStream()).ConfigureAwait(false);
|
||||
if (cardObjects.Count == 5)
|
||||
{
|
||||
await e.Channel.SendMessage(Cards.GetHandValue(cardObjects)).ConfigureAwait(false);
|
||||
await e.Channel.SendMessage($"{e.User.Mention} `{Cards.GetHandValue(cardObjects)}`").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -1,10 +1,12 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Games.Commands
|
||||
@ -18,11 +20,31 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
/// </summary>
|
||||
class PlantPick : DiscordCommand
|
||||
{
|
||||
|
||||
private Random rng;
|
||||
public PlantPick(DiscordModule module) : base(module)
|
||||
{
|
||||
|
||||
NadekoBot.Client.MessageReceived += PotentialFlowerGeneration;
|
||||
rng = new Random();
|
||||
}
|
||||
|
||||
|
||||
private async void PotentialFlowerGeneration(object sender, Discord.MessageEventArgs e)
|
||||
{
|
||||
if (e.Server == null || e.Channel.IsPrivate)
|
||||
return;
|
||||
var config = Classes.SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
if (config.GenerateCurrencyChannels.Contains(e.Channel.Id))
|
||||
{
|
||||
var rnd = Math.Abs(GetRandomNumber());
|
||||
if ((rnd % 50) == 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; });
|
||||
}
|
||||
}
|
||||
}
|
||||
//channelid/messageid pair
|
||||
ConcurrentDictionary<ulong, Message> plantedFlowerChannels = new ConcurrentDictionary<ulong, Message>();
|
||||
|
||||
@ -65,8 +87,7 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
return;
|
||||
}
|
||||
|
||||
var rng = new Random();
|
||||
var file = Directory.GetFiles("data/currency_images").OrderBy(s => rng.Next()).FirstOrDefault();
|
||||
var file = GetRandomCurrencyImagePath();
|
||||
Message msg;
|
||||
//todo send message after, not in lock
|
||||
if (file == null)
|
||||
@ -80,6 +101,38 @@ namespace NadekoBot.Modules.Games.Commands
|
||||
await Task.Delay(20000).ConfigureAwait(false);
|
||||
await msg2.Delete().ConfigureAwait(false);
|
||||
});
|
||||
|
||||
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`")
|
||||
.AddCheck(SimpleCheckers.ManageMessages())
|
||||
.Do(async e =>
|
||||
{
|
||||
var config = SpecificConfigurations.Default.Of(e.Server.Id);
|
||||
if (config.GenerateCurrencyChannels.Remove(e.Channel.Id))
|
||||
{
|
||||
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.`");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private string GetRandomCurrencyImagePath() =>
|
||||
Directory.GetFiles("data/currency_images").OrderBy(s => rng.Next()).FirstOrDefault();
|
||||
|
||||
int GetRandomNumber()
|
||||
{
|
||||
using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider())
|
||||
{
|
||||
byte[] rno = new byte[4];
|
||||
rg.GetBytes(rno);
|
||||
int randomvalue = BitConverter.ToInt32(rno, 0);
|
||||
return randomvalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ Version: `{NadekoStats.Instance.BotVersion}`";
|
||||
.Description("Sends a readme and a guide links to the channel.")
|
||||
.Do(async e =>
|
||||
await e.Channel.SendMessage(
|
||||
@"**FULL README**: <https://github.com/Kwoth/NadekoBot/blob/master/README.md>
|
||||
@"**Wiki with all info**: <https://github.com/Kwoth/NadekoBot/wiki>
|
||||
|
||||
**WINDOWS SETUP GUIDE**: <https://github.com/Kwoth/NadekoBot/blob/master/ComprehensiveGuide.md>
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Discord.Commands;
|
||||
using Discord.Modules;
|
||||
using NadekoBot.Classes;
|
||||
using NadekoBot.Classes.Help.Commands;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
@ -54,10 +55,8 @@ namespace NadekoBot.Modules.Help
|
||||
}
|
||||
var i = 0;
|
||||
if (module != "customreactions" && module != "conversations")
|
||||
await e.Channel.SendMessage("`List Of Commands:`\n```xl\n" +
|
||||
string.Join("\n", cmdsArray.GroupBy(item => (i++) / 3)
|
||||
.Select(ig => string.Join("", ig.Select(el => $"{el.Text,-15}" + $"{"[" + el.Aliases.FirstOrDefault() + "]",-8}"))))
|
||||
+ $"\n```")
|
||||
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}")));
|
||||
|
@ -50,7 +50,7 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
private bool Destroyed { get; set; } = false;
|
||||
public bool RepeatSong { get; private set; } = false;
|
||||
public bool RepeatPlaylist { get; private set; } = false;
|
||||
public bool Autoplay { get; private set; } = false;
|
||||
public bool Autoplay { get; set; } = false;
|
||||
|
||||
public MusicPlayer(Channel startingVoiceChannel, float? defaultVolume)
|
||||
{
|
||||
@ -174,6 +174,7 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
throw new ArgumentNullException(nameof(s));
|
||||
lock (playlistLock)
|
||||
{
|
||||
s.MusicPlayer = this;
|
||||
playlist.Add(s);
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
}
|
||||
}
|
||||
|
||||
private Song(SongInfo songInfo)
|
||||
public Song(SongInfo songInfo)
|
||||
{
|
||||
this.SongInfo = songInfo;
|
||||
}
|
||||
@ -67,6 +67,12 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
return s;
|
||||
}
|
||||
|
||||
public Song SetMusicPlayer(MusicPlayer mp)
|
||||
{
|
||||
this.MusicPlayer = mp;
|
||||
return this;
|
||||
}
|
||||
|
||||
private Task BufferSong(CancellationToken cancelToken) =>
|
||||
Task.Factory.StartNew(async () =>
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
using NadekoBot.Classes;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -34,18 +35,22 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
|
||||
public class SoundCloudVideo
|
||||
{
|
||||
public string Kind = "";
|
||||
public long Id = 0;
|
||||
public SoundCloudUser User = new SoundCloudUser();
|
||||
public string Title = "";
|
||||
public string Kind { get; set; } = "";
|
||||
public long Id { get; set; } = 0;
|
||||
public SoundCloudUser User { get; set; } = new SoundCloudUser();
|
||||
public string Title { get; set; } = "";
|
||||
[JsonIgnore]
|
||||
public string FullName => User.Name + " - " + Title;
|
||||
public bool Streamable = false;
|
||||
public bool Streamable { get; set; } = false;
|
||||
[JsonProperty("permalink_url")]
|
||||
public string TrackLink { get; set; } = "";
|
||||
[JsonIgnore]
|
||||
public string StreamLink => $"https://api.soundcloud.com/tracks/{Id}/stream?client_id={NadekoBot.Creds.SoundCloudClientID}";
|
||||
}
|
||||
public class SoundCloudUser
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("username")]
|
||||
public string Name;
|
||||
public string Name { get; set; }
|
||||
}
|
||||
/*
|
||||
{"kind":"track",
|
||||
|
@ -6,6 +6,7 @@ using NadekoBot.DataModels;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Modules.Music.Classes;
|
||||
using NadekoBot.Modules.Permissions.Classes;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
@ -52,30 +53,27 @@ namespace NadekoBot.Modules.Music
|
||||
cgb.CreateCommand("stop")
|
||||
.Alias("s")
|
||||
.Description("Stops the music and clears the playlist. Stays in the channel.\n**Usage**: `!m s`")
|
||||
.Do(async e =>
|
||||
.Do(e =>
|
||||
{
|
||||
await Task.Run(() =>
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer)) return;
|
||||
if (e.User.VoiceChannel == musicPlayer.PlaybackVoiceChannel)
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer)) return;
|
||||
if (e.User.VoiceChannel == musicPlayer.PlaybackVoiceChannel)
|
||||
musicPlayer.Stop();
|
||||
}).ConfigureAwait(false);
|
||||
musicPlayer.Autoplay = false;
|
||||
musicPlayer.Stop();
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("destroy")
|
||||
.Alias("d")
|
||||
.Description("Completely stops the music and unbinds the bot from the channel. " +
|
||||
"(may cause weird behaviour)\n**Usage**: `!m d`")
|
||||
.Do(async e =>
|
||||
.Do(e =>
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryRemove(e.Server, out musicPlayer)) return;
|
||||
if (e.User.VoiceChannel == musicPlayer.PlaybackVoiceChannel)
|
||||
musicPlayer.Destroy();
|
||||
}).ConfigureAwait(false);
|
||||
MusicPlayer musicPlayer;
|
||||
if (!MusicPlayers.TryRemove(e.Server, out musicPlayer)) return;
|
||||
if (e.User.VoiceChannel == musicPlayer.PlaybackVoiceChannel)
|
||||
musicPlayer.Destroy();
|
||||
});
|
||||
|
||||
cgb.CreateCommand("pause")
|
||||
@ -110,6 +108,21 @@ 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("listqueue")
|
||||
.Alias("lq")
|
||||
.Description("Lists 15 currently queued songs per page. Default page is 1.\n**Usage**: `!m lq` or `!m lq 2`")
|
||||
@ -188,7 +201,7 @@ namespace NadekoBot.Modules.Music
|
||||
cgb.CreateCommand("defvol")
|
||||
.Alias("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.\n**Usage**: `!m dv 80`")
|
||||
.Parameter("val", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
@ -302,6 +315,37 @@ namespace NadekoBot.Modules.Music
|
||||
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`")
|
||||
.Parameter("pl", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var pl = e.GetArg("pl")?.Trim();
|
||||
|
||||
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);
|
||||
|
||||
MusicPlayer mp;
|
||||
if (!MusicPlayers.TryGetValue(e.Server, out mp))
|
||||
return;
|
||||
|
||||
foreach (var svideo in scvids.Skip(1))
|
||||
{
|
||||
mp.AddSong(new Song(new Classes.SongInfo
|
||||
{
|
||||
Title = svideo.FullName,
|
||||
Provider = "SoundCloud",
|
||||
Uri = svideo.StreamLink,
|
||||
ProviderType = MusicType.Normal,
|
||||
Query = svideo.TrackLink,
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand("localplaylst")
|
||||
.Alias("lopl")
|
||||
.Description("Queues all songs from a directory. **Bot Owner Only!**\n**Usage**: `!m lopl C:/music/classical`")
|
||||
@ -757,8 +801,6 @@ namespace NadekoBot.Modules.Music
|
||||
return mp;
|
||||
});
|
||||
var resolvedSong = await Song.ResolveSong(query, musicType).ConfigureAwait(false);
|
||||
resolvedSong.MusicPlayer = musicPlayer;
|
||||
|
||||
musicPlayer.AddSong(resolvedSong);
|
||||
if (!silent)
|
||||
{
|
||||
|
46
NadekoBot/Modules/Searches/Commands/MemegenCommands.cs
Normal file
46
NadekoBot/Modules/Searches/Commands/MemegenCommands.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Classes;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace NadekoBot.Modules.Searches.Commands
|
||||
{
|
||||
class MemegenCommands : DiscordCommand
|
||||
{
|
||||
public MemegenCommands(DiscordModule module) : base(module)
|
||||
{
|
||||
}
|
||||
|
||||
internal override void Init(CommandGroupBuilder cgb)
|
||||
{
|
||||
cgb.CreateCommand(Prefix + "memelist")
|
||||
.Description("Pulls a list of memes you can use with `~memegen` from http://memegen.link/templates/")
|
||||
.Do(async e =>
|
||||
{
|
||||
int i = 0;
|
||||
await e.Channel.SendMessage("`List Of Commands:`\n```xl\n" +
|
||||
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}"))))
|
||||
+ $"\n```").ConfigureAwait(false);
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "memegen")
|
||||
.Description("Generates a meme from memelist with top and bottom text. | `~memegen biw \"gets iced coffee\" \"in the winter\"`")
|
||||
.Parameter("meme", ParameterType.Required)
|
||||
.Parameter("toptext", ParameterType.Required)
|
||||
.Parameter("bottext", ParameterType.Required)
|
||||
.Do(async e =>
|
||||
{
|
||||
var meme = e.GetArg("meme");
|
||||
var top = Uri.EscapeDataString(e.GetArg("toptext").Replace(' ', '-'));
|
||||
var bot = Uri.EscapeDataString(e.GetArg("bottext").Replace(' ', '-'));
|
||||
await e.Channel.SendMessage($"http://memegen.link/{meme}/{top}/{bot}.jpg");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -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 `")
|
||||
.Description("Shows osu stats for a player.\n**Usage**: `~osu Name` or `~osu Name taiko`")
|
||||
.Parameter("usr", ParameterType.Required)
|
||||
.Parameter("mode", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
|
@ -73,7 +73,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
checkTimer.Start();
|
||||
}
|
||||
|
||||
private async Task<Tuple<bool, string>> GetStreamStatus(StreamNotificationConfig stream)
|
||||
private async Task<Tuple<bool, string>> GetStreamStatus(StreamNotificationConfig stream, bool checkCache = true)
|
||||
{
|
||||
bool isLive;
|
||||
string response;
|
||||
@ -83,7 +83,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
{
|
||||
case StreamNotificationConfig.StreamType.Hitbox:
|
||||
var hitboxUrl = $"https://api.hitbox.tv/media/status/{stream.Username}";
|
||||
if (cachedStatuses.TryGetValue(hitboxUrl, out result))
|
||||
if (checkCache && cachedStatuses.TryGetValue(hitboxUrl, out result))
|
||||
return result;
|
||||
response = await SearchHelper.GetResponseStringAsync(hitboxUrl).ConfigureAwait(false);
|
||||
data = JObject.Parse(response);
|
||||
@ -93,7 +93,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
return result;
|
||||
case StreamNotificationConfig.StreamType.Twitch:
|
||||
var twitchUrl = $"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username)}";
|
||||
if (cachedStatuses.TryGetValue(twitchUrl, out result))
|
||||
if (checkCache && cachedStatuses.TryGetValue(twitchUrl, out result))
|
||||
return result;
|
||||
response = await SearchHelper.GetResponseStringAsync(twitchUrl).ConfigureAwait(false);
|
||||
data = JObject.Parse(response);
|
||||
@ -103,7 +103,7 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
return result;
|
||||
case StreamNotificationConfig.StreamType.Beam:
|
||||
var beamUrl = $"https://beam.pro/api/v1/channels/{stream.Username}";
|
||||
if (cachedStatuses.TryGetValue(beamUrl, out result))
|
||||
if (checkCache && cachedStatuses.TryGetValue(beamUrl, out result))
|
||||
return result;
|
||||
response = await SearchHelper.GetResponseStringAsync(beamUrl).ConfigureAwait(false);
|
||||
data = JObject.Parse(response);
|
||||
@ -143,6 +143,93 @@ namespace NadekoBot.Modules.Searches.Commands
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(TrackStream(StreamNotificationConfig.StreamType.Beam));
|
||||
|
||||
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")
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Do(async e =>
|
||||
{
|
||||
var stream = e.GetArg("username")?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(stream))
|
||||
return;
|
||||
try
|
||||
{
|
||||
var streamStatus = (await GetStreamStatus(new StreamNotificationConfig
|
||||
{
|
||||
Username = stream,
|
||||
Type = StreamNotificationConfig.StreamType.Hitbox
|
||||
}));
|
||||
if (streamStatus.Item1)
|
||||
{
|
||||
await e.Channel.SendMessage($"`Streamer {streamStatus.Item2} is online.`");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
await e.Channel.SendMessage("No channel found.");
|
||||
}
|
||||
});
|
||||
|
||||
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")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var stream = e.GetArg("username")?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(stream))
|
||||
return;
|
||||
try
|
||||
{
|
||||
var streamStatus = (await GetStreamStatus(new StreamNotificationConfig
|
||||
{
|
||||
Username = stream,
|
||||
Type = StreamNotificationConfig.StreamType.Twitch
|
||||
}));
|
||||
if (streamStatus.Item1)
|
||||
{
|
||||
await e.Channel.SendMessage($"`Streamer {streamStatus.Item2} is online.`");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
await e.Channel.SendMessage("No channel found.");
|
||||
}
|
||||
});
|
||||
|
||||
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")
|
||||
.AddCheck(SimpleCheckers.ManageServer())
|
||||
.Parameter("username", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
var stream = e.GetArg("username")?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(stream))
|
||||
return;
|
||||
try
|
||||
{
|
||||
var streamStatus = (await GetStreamStatus(new StreamNotificationConfig
|
||||
{
|
||||
Username = stream,
|
||||
Type = StreamNotificationConfig.StreamType.Beam
|
||||
}));
|
||||
if (streamStatus.Item1)
|
||||
{
|
||||
await e.Channel.SendMessage($"`Streamer {streamStatus.Item2} is online.`");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
await e.Channel.SendMessage("No channel found.");
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Module.Prefix + "removestream")
|
||||
.Alias(Module.Prefix + "rms")
|
||||
.Description("Removes notifications of a certain streamer on this channel." +
|
||||
|
@ -31,6 +31,7 @@ namespace NadekoBot.Modules.Searches
|
||||
commands.Add(new CalcCommand(this));
|
||||
commands.Add(new OsuCommands(this));
|
||||
commands.Add(new PokemonSearchCommands(this));
|
||||
commands.Add(new MemegenCommands(this));
|
||||
rng = new Random();
|
||||
}
|
||||
|
||||
@ -184,29 +185,30 @@ $@"🌍 **Weather for** 【{obj["target"]}】
|
||||
cgb.CreateCommand(Prefix + "ir")
|
||||
.Description("Pulls a random image using a search parameter.\n**Usage**: ~ir cute kitten")
|
||||
.Parameter("query", ParameterType.Unparsed)
|
||||
.Do(async e =>
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.GetArg("query")))
|
||||
return;
|
||||
try
|
||||
{
|
||||
var reqString = $"https://www.googleapis.com/customsearch/v1?q={Uri.EscapeDataString(e.GetArg("query"))}&cx=018084019232060951019%3Ahs5piey28-e&num=50&searchType=image&start={ rng.Next(1, 50) }&fields=items%2Flink&key={NadekoBot.Creds.GoogleAPIKey}";
|
||||
var obj = JObject.Parse(await SearchHelper.GetResponseStringAsync(reqString).ConfigureAwait(false));
|
||||
var items = obj["items"] as JArray;
|
||||
await e.Channel.SendMessage(items[rng.Next(0, items.Count)]["link"].ToString()).ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpRequestException exception)
|
||||
{
|
||||
if (exception.Message.Contains("403 (Forbidden)"))
|
||||
{
|
||||
await e.Channel.SendMessage("Daily limit reached!");
|
||||
}
|
||||
else
|
||||
{
|
||||
await e.Channel.SendMessage("Something went wrong.");
|
||||
}
|
||||
}
|
||||
});
|
||||
.Do(async e =>
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.GetArg("query")))
|
||||
return;
|
||||
try
|
||||
{
|
||||
var reqString = $"https://www.googleapis.com/customsearch/v1?q={Uri.EscapeDataString(e.GetArg("query"))}&cx=018084019232060951019%3Ahs5piey28-e&num=1&searchType=image&start={ rng.Next(1, 50) }&fields=items%2Flink&key={NadekoBot.Creds.GoogleAPIKey}";
|
||||
var obj = JObject.Parse(await SearchHelper.GetResponseStringAsync(reqString).ConfigureAwait(false));
|
||||
var items = obj["items"] as JArray;
|
||||
await e.Channel.SendMessage(items[0]["link"].ToString()).ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpRequestException exception)
|
||||
{
|
||||
if (exception.Message.Contains("403 (Forbidden)"))
|
||||
{
|
||||
await e.Channel.SendMessage("Daily limit reached!");
|
||||
}
|
||||
else
|
||||
{
|
||||
await e.Channel.SendMessage("Something went wrong.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cgb.CreateCommand(Prefix + "lmgtfy")
|
||||
.Description("Google something for an idiot.")
|
||||
.Parameter("ffs", ParameterType.Unparsed)
|
||||
@ -475,6 +477,21 @@ $@"🌍 **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")
|
||||
.Do(async e =>
|
||||
{
|
||||
var usr = e.Channel.FindUsers(e.GetArg("mention")).FirstOrDefault();
|
||||
if (usr == null)
|
||||
{
|
||||
await e.Channel.SendMessage("Invalid user specified.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
await e.Channel.SendMessage(await usr.AvatarUrl.ShortenUrl()).ConfigureAwait(false);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,12 @@
|
||||
// License: Code Project Open License
|
||||
// http://www.codeproject.com/info/cpol10.aspx
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace NadekoBot.Modules.Translator.Helpers
|
||||
@ -26,32 +28,6 @@ namespace NadekoBot.Modules.Translator.Helpers
|
||||
return GoogleTranslator._languageModeMap.Keys.OrderBy(p => p);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time taken to perform the translation.
|
||||
/// </summary>
|
||||
public TimeSpan TranslationTime {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the url used to speak the translation.
|
||||
/// </summary>
|
||||
/// <value>The url used to speak the translation.</value>
|
||||
public string TranslationSpeechUrl {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the error.
|
||||
/// </summary>
|
||||
public Exception Error {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
@ -63,92 +39,28 @@ namespace NadekoBot.Modules.Translator.Helpers
|
||||
/// <param name="sourceLanguage">The source language.</param>
|
||||
/// <param name="targetLanguage">The target language.</param>
|
||||
/// <returns>The translation.</returns>
|
||||
public string Translate
|
||||
public async Task<string> Translate
|
||||
(string sourceText,
|
||||
string sourceLanguage,
|
||||
string targetLanguage)
|
||||
{
|
||||
// Initialize
|
||||
this.Error = null;
|
||||
this.TranslationSpeechUrl = null;
|
||||
this.TranslationTime = TimeSpan.Zero;
|
||||
DateTime tmStart = DateTime.Now;
|
||||
string translation = string.Empty;
|
||||
string text = string.Empty;
|
||||
|
||||
try
|
||||
|
||||
// Download translation
|
||||
string url = string.Format("https://translate.googleapis.com/translate_a/single?client=gtx&sl={0}&tl={1}&dt=t&q={2}",
|
||||
GoogleTranslator.LanguageEnumToIdentifier(sourceLanguage),
|
||||
GoogleTranslator.LanguageEnumToIdentifier(targetLanguage),
|
||||
HttpUtility.UrlEncode(sourceText));
|
||||
using (HttpClient http = new HttpClient())
|
||||
{
|
||||
// Download translation
|
||||
string url = string.Format("https://translate.googleapis.com/translate_a/single?client=gtx&sl={0}&tl={1}&dt=t&q={2}",
|
||||
GoogleTranslator.LanguageEnumToIdentifier(sourceLanguage),
|
||||
GoogleTranslator.LanguageEnumToIdentifier(targetLanguage),
|
||||
HttpUtility.UrlEncode(sourceText));
|
||||
using (WebClient wc = new WebClient())
|
||||
{
|
||||
wc.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
|
||||
text = wc.DownloadString(url);
|
||||
}
|
||||
|
||||
// Get translated text
|
||||
// Get phrase collection
|
||||
// string text = File.ReadAllText(outputFile);
|
||||
int index = text.IndexOf(string.Format(",,\"{0}\"", GoogleTranslator.LanguageEnumToIdentifier(sourceLanguage)));
|
||||
if (index == -1)
|
||||
{
|
||||
// Translation of single word
|
||||
int startQuote = text.IndexOf('\"');
|
||||
if (startQuote != -1)
|
||||
{
|
||||
int endQuote = text.IndexOf('\"', startQuote + 1);
|
||||
if (endQuote != -1)
|
||||
{
|
||||
translation = text.Substring(startQuote + 1, endQuote - startQuote - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Translation of phrase
|
||||
text = text.Substring(0, index);
|
||||
text = text.Replace("],[", ",");
|
||||
text = text.Replace("]", string.Empty);
|
||||
text = text.Replace("[", string.Empty);
|
||||
text = text.Replace("\",\"", "\"");
|
||||
|
||||
// Get translated phrases
|
||||
string[] phrases = text.Split(new[] { '\"' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int i = 0; (i < phrases.Count()); i += 2)
|
||||
{
|
||||
string translatedPhrase = phrases[i];
|
||||
if (translatedPhrase.StartsWith(",,"))
|
||||
{
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
translation += translatedPhrase + " ";
|
||||
}
|
||||
}
|
||||
|
||||
// Fix up translation
|
||||
translation = translation.Trim();
|
||||
translation = translation.Replace(" ?", "?");
|
||||
translation = translation.Replace(" !", "!");
|
||||
translation = translation.Replace(" ,", ",");
|
||||
translation = translation.Replace(" .", ".");
|
||||
translation = translation.Replace(" ;", ";");
|
||||
|
||||
// And translation speech URL
|
||||
this.TranslationSpeechUrl = string.Format("https://translate.googleapis.com/translate_tts?ie=UTF-8&q={0}&tl={1}&total=1&idx=0&textlen={2}&client=gtx",
|
||||
HttpUtility.UrlEncode(translation), GoogleTranslator.LanguageEnumToIdentifier(targetLanguage), translation.Length);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Error = ex;
|
||||
http.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
|
||||
text = await http.GetStringAsync(url).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// Return result
|
||||
this.TranslationTime = DateTime.Now - tmStart;
|
||||
return translation;
|
||||
return JArray.Parse(text)[0][0][0].ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -27,13 +27,17 @@ namespace NadekoBot.Modules.Translator
|
||||
await e.Channel.SendIsTyping().ConfigureAwait(false);
|
||||
string from = e.GetArg("langs").ToLowerInvariant().Split('>')[0];
|
||||
string to = e.GetArg("langs").ToLowerInvariant().Split('>')[1];
|
||||
var text = e.GetArg("text")?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return;
|
||||
|
||||
string translation = t.Translate(e.GetArg("text"), from, to);
|
||||
string translation = await t.Translate(text, from, to).ConfigureAwait(false);
|
||||
await e.Channel.SendMessage(translation).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
await e.Channel.SendMessage("Bad input format, or sth went wrong...").ConfigureAwait(false);
|
||||
Console.WriteLine(ex);
|
||||
await e.Channel.SendMessage("Bad input format, or something went wrong...").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
};
|
||||
|
Reference in New Issue
Block a user