Merge pull request #33 from Kwoth/dev

ups
This commit is contained in:
samvaio 2016-12-09 16:56:34 +05:30 committed by GitHub
commit 1d8c1265b8
58 changed files with 516 additions and 838 deletions

@ -1 +1 @@
Subproject commit 57fc8290666dba35b2385c97e3a51c493b40a425 Subproject commit 63cc61d8db062fcbd577dc5f9e764a61f283689b

View File

@ -10,6 +10,7 @@ You can support the project on patreon: <https://patreon.com/nadekobot> or paypa
- [Music](#music) - [Music](#music)
- [NSFW](#nsfw) - [NSFW](#nsfw)
- [Permissions](#permissions) - [Permissions](#permissions)
- [Pokemon](#pokemon)
- [Searches](#searches) - [Searches](#searches)
- [Utility](#utility) - [Utility](#utility)
@ -268,6 +269,17 @@ Command and aliases | Description | Usage
###### [Back to TOC](#table-of-contents) ###### [Back to TOC](#table-of-contents)
### Pokemon
Command and aliases | Description | Usage
----------------|--------------|-------
`>attack` | Attacks a target with the given move. Use `>movelist` to see a list of moves your type can use. | `>attack "vine whip" @someguy`
`>movelist` `>ml` | Lists the moves you are able to use | `>ml`
`>heal` | Heals someone. Revives those who fainted. Costs a NadekoFlower | `>heal @someone`
`>type` | Get the poketype of the target. | `>type @someone`
`>settype` | Set your poketype. Costs a NadekoFlower. Provide no arguments to see a list of available types. | `>settype fire` or `>settype`
###### [Back to TOC](#table-of-contents)
### Searches ### Searches
Command and aliases | Description | Usage Command and aliases | Description | Usage
----------------|--------------|------- ----------------|--------------|-------
@ -283,6 +295,7 @@ Command and aliases | Description | Usage
`~google` `~g` | Get a google search link for some terms. | `~google query` `~google` `~g` | Get a google search link for some terms. | `~google query`
`~magicthegathering` `~mtg` | Searches for a Magic The Gathering card. | `~magicthegathering about face` or `~mtg about face` `~magicthegathering` `~mtg` | Searches for a Magic The Gathering card. | `~magicthegathering about face` or `~mtg about face`
`~hearthstone` `~hs` | Searches for a Hearthstone card and shows its image. Takes a while to complete. | `~hs Ysera` `~hearthstone` `~hs` | Searches for a Hearthstone card and shows its image. Takes a while to complete. | `~hs Ysera`
`~yodify` `~yoda` | Translates your normal sentences into Yoda styled sentences! | ~yodify I was once an adventurer like you` or `~yoda my feelings hurt`
`~urbandict` `~ud` | Searches Urban Dictionary for a word. | `~ud Pineapple` `~urbandict` `~ud` | Searches Urban Dictionary for a word. | `~ud Pineapple`
`~#` | Searches Tagdef.com for a hashtag. | `~# ff` `~#` | Searches Tagdef.com for a hashtag. | `~# ff`
`~catfact` | Shows a random catfact from <http://catfacts-api.appspot.com/api/facts> | `~catfact` `~catfact` | Shows a random catfact from <http://catfacts-api.appspot.com/api/facts> | `~catfact`
@ -293,8 +306,6 @@ Command and aliases | Description | Usage
`~color` `~clr` | Shows you what color corresponds to that hex. | `~clr 00ff00` `~color` `~clr` | Shows you what color corresponds to that hex. | `~clr 00ff00`
`~videocall` | Creates a private <http://www.appear.in> video call link for you and other mentioned people. The link is sent to mentioned people via a private message. | `~videocall "@SomeGuy"` `~videocall` | Creates a private <http://www.appear.in> video call link for you and other mentioned people. The link is sent to mentioned people via a private message. | `~videocall "@SomeGuy"`
`~avatar` `~av` | Shows a mentioned person's avatar. | `~av "@SomeGuy"` `~avatar` `~av` | Shows a mentioned person's avatar. | `~av "@SomeGuy"`
`~bfonline` `~bfo` | Gives you online players for BF3 and BF4 | `~bfo bf3` or `~bfo bf4`
`~bfuser` `~bfu` | Gives you back a battlefield user's stats. | `~bfu platform game user`
`~wikia` | Gives you back a wikia link | `~wikia mtg Vigilance` or `~wikia mlp Dashy` `~wikia` | Gives you back a wikia link | `~wikia mtg Vigilance` or `~wikia mlp Dashy`
`~minecraftping` `~mcping` | Pings a minecraft server. | `~mcping 127.0.0.1:25565` `~minecraftping` `~mcping` | Pings a minecraft server. | `~mcping 127.0.0.1:25565`
`~minecraftquery` `~mcq` | Finds information about a minecraft server. | `~mcq server:ip` `~minecraftquery` `~mcq` | Finds information about a minecraft server. | `~mcq server:ip`
@ -319,7 +330,7 @@ Command and aliases | Description | Usage
`~twitch` `~tw` | Notifies this channel when a certain user starts streaming. **Requires ManageMessages server permission.** | `~twitch SomeStreamer` `~twitch` `~tw` | Notifies this channel when a certain user starts streaming. **Requires ManageMessages server permission.** | `~twitch SomeStreamer`
`~beam` `~bm` | Notifies this channel when a certain user starts streaming. **Requires ManageMessages server permission.** | `~beam SomeStreamer` `~beam` `~bm` | Notifies this channel when a certain user starts streaming. **Requires ManageMessages server permission.** | `~beam SomeStreamer`
`~liststreams` `~ls` | Lists all streams you are following on this server. | `~ls` `~liststreams` `~ls` | Lists all streams you are following on this server. | `~ls`
`~removestream` `~rms` | Removes notifications of a certain streamer on this channel. **Requires ManageMessages server permission.** | `~rms SomeGuy` `~removestream` `~rms` | Removes notifications of a certain streamer from a certain platform on this channel. **Requires ManageMessages server permission.** | `~rms Twitch SomeGuy` or `~rms Beam SomeOtherGuy`
`~checkstream` `~cs` | Checks if a user is online on a certain streaming platform. | `~cs twitch MyFavStreamer` `~checkstream` `~cs` | Checks if a user is online on a certain streaming platform. | `~cs twitch MyFavStreamer`
`~translate` `~trans` | Translates from>to text. From the given language to the destination language. | `~trans en>fr Hello` `~translate` `~trans` | Translates from>to text. From the given language to the destination language. | `~trans en>fr Hello`
`~autotrans` `~at` | Starts automatic translation of all messages by users who set their `~atl` in this channel. You can set "del" argument to automatically delete all translated user messages. **Requires Administrator server permission.** **Bot Owner only.** | `~at` or `~at del` `~autotrans` `~at` | Starts automatic translation of all messages by users who set their `~atl` in this channel. You can set "del" argument to automatically delete all translated user messages. **Requires Administrator server permission.** **Bot Owner only.** | `~at` or `~at del`
@ -345,7 +356,6 @@ Command and aliases | Description | Usage
`.listservers` | Lists servers the bot is on with some basic info. 15 per page. **Bot Owner only.** | `.listservers 3` `.listservers` | Lists servers the bot is on with some basic info. 15 per page. **Bot Owner only.** | `.listservers 3`
`.calculate` `.calc` | Evaluate a mathematical expression. | `.calc 1+1` `.calculate` `.calc` | Evaluate a mathematical expression. | `.calc 1+1`
`.calcops` | Shows all available operations in .calc command | `.calcops` `.calcops` | Shows all available operations in .calc command | `.calcops`
`.togethertube` `.totube` | Creates a new room on <https://togethertube.com> and shows the link in the chat. | `.totube`
`.serverinfo` `.sinfo` | Shows info about the server the bot is on. If no channel is supplied, it defaults to current one. | `.sinfo Some Server` `.serverinfo` `.sinfo` | Shows info about the server the bot is on. If no channel is supplied, it defaults to current one. | `.sinfo Some Server`
`.channelinfo` `.cinfo` | Shows info about the channel. If no channel is supplied, it defaults to current one. | `.cinfo #some-channel` `.channelinfo` `.cinfo` | Shows info about the channel. If no channel is supplied, it defaults to current one. | `.cinfo #some-channel`
`.userinfo` `.uinfo` | Shows info about the user. If no user is supplied, it defaults a user running the command. | `.uinfo @SomeUser` `.userinfo` `.uinfo` | Shows info about the user. If no user is supplied, it defaults a user running the command. | `.uinfo @SomeUser`

View File

@ -15,6 +15,7 @@ using System.Net.Http;
using System.IO; using System.IO;
using static NadekoBot.Modules.Permissions.Permissions; using static NadekoBot.Modules.Permissions.Permissions;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using NLog;
namespace NadekoBot.Modules.Administration namespace NadekoBot.Modules.Administration
{ {
@ -24,13 +25,17 @@ namespace NadekoBot.Modules.Administration
private static ConcurrentDictionary<ulong, string> GuildMuteRoles { get; } = new ConcurrentDictionary<ulong, string>(); private static ConcurrentDictionary<ulong, string> GuildMuteRoles { get; } = new ConcurrentDictionary<ulong, string>();
public Administration(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) private static Logger _log { get; }
public Administration() : base()
{ {
NadekoBot.CommandHandler.CommandExecuted += DelMsgOnCmd_Handler;
} }
static Administration() static Administration()
{ {
_log = LogManager.GetCurrentClassLogger();
NadekoBot.CommandHandler.CommandExecuted += DelMsgOnCmd_Handler;
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
var configs = NadekoBot.AllGuildConfigs; var configs = NadekoBot.AllGuildConfigs;
@ -40,11 +45,11 @@ namespace NadekoBot.Modules.Administration
} }
} }
private async void DelMsgOnCmd_Handler(object sender, CommandExecutedEventArgs e) private static async Task DelMsgOnCmd_Handler(IUserMessage msg, Command cmd)
{ {
try try
{ {
var channel = e.Message.Channel as ITextChannel; var channel = msg.Channel as ITextChannel;
if (channel == null) if (channel == null)
return; return;
@ -56,7 +61,7 @@ namespace NadekoBot.Modules.Administration
} }
if (shouldDelete) if (shouldDelete)
await e.Message.DeleteAsync().ConfigureAwait(false); await msg.DeleteAsync().ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -802,7 +807,7 @@ namespace NadekoBot.Modules.Administration
{ {
var channel = (ITextChannel)umsg.Channel; var channel = (ITextChannel)umsg.Channel;
var channels = await Task.WhenAll(_client.GetGuilds().Select(g => var channels = await Task.WhenAll(NadekoBot.Client.GetGuilds().Select(g =>
g.GetDefaultChannelAsync() g.GetDefaultChannelAsync()
)).ConfigureAwait(false); )).ConfigureAwait(false);

View File

@ -74,13 +74,13 @@ namespace NadekoBot.Modules.Administration
private static ConcurrentDictionary<ulong, AntiSpamSetting> antiSpamGuilds = private static ConcurrentDictionary<ulong, AntiSpamSetting> antiSpamGuilds =
new ConcurrentDictionary<ulong, AntiSpamSetting>(); new ConcurrentDictionary<ulong, AntiSpamSetting>();
private Logger _log { get; } private static Logger _log { get; }
public AntiRaidCommands(ShardedDiscordClient client) static AntiRaidCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
client.MessageReceived += (imsg) => NadekoBot.Client.MessageReceived += (imsg) =>
{ {
var msg = imsg as IUserMessage; var msg = imsg as IUserMessage;
if (msg == null || msg.Author.IsBot) if (msg == null || msg.Author.IsBot)
@ -115,7 +115,7 @@ namespace NadekoBot.Modules.Administration
return Task.CompletedTask; return Task.CompletedTask;
}; };
client.UserJoined += (usr) => NadekoBot.Client.UserJoined += (usr) =>
{ {
if (usr.IsBot) if (usr.IsBot)
return Task.CompletedTask; return Task.CompletedTask;
@ -148,7 +148,7 @@ namespace NadekoBot.Modules.Administration
}; };
} }
private async Task PunishUsers(PunishmentAction action, IRole muteRole, ProtectionType pt, params IGuildUser[] gus) private static async Task PunishUsers(PunishmentAction action, IRole muteRole, ProtectionType pt, params IGuildUser[] gus)
{ {
foreach (var gu in gus) foreach (var gu in gus)
{ {

View File

@ -15,13 +15,12 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class AutoAssignRoleCommands public class AutoAssignRoleCommands
{ {
private Logger _log { get; } private static Logger _log { get; }
public AutoAssignRoleCommands() static AutoAssignRoleCommands()
{ {
var _client = NadekoBot.Client; _log = LogManager.GetCurrentClassLogger();
this._log = LogManager.GetCurrentClassLogger(); NadekoBot.Client.UserJoined += (user) =>
_client.UserJoined += (user) =>
{ {
var t = Task.Run(async () => var t = Task.Run(async () =>
{ {

View File

@ -16,7 +16,7 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class CrossServerTextChannel public class CrossServerTextChannel
{ {
public CrossServerTextChannel() static CrossServerTextChannel()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
NadekoBot.Client.MessageReceived += (imsg) => NadekoBot.Client.MessageReceived += (imsg) =>
@ -50,11 +50,11 @@ namespace NadekoBot.Modules.Administration
}; };
} }
private string GetText(IGuild server, ITextChannel channel, IGuildUser user, IUserMessage message) => private static string GetText(IGuild server, ITextChannel channel, IGuildUser user, IUserMessage message) =>
$"**{server.Name} | {channel.Name}** `{user.Username}`: " + message.Content; $"**{server.Name} | {channel.Name}** `{user.Username}`: " + message.Content;
public static readonly ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>> Subscribers = new ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>>(); public static readonly ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>> Subscribers = new ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>>();
private Logger _log { get; } private static Logger _log { get; }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]

View File

@ -63,7 +63,7 @@ namespace NadekoBot.Modules.Administration
}, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10)); }, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));
} }
public LogCommands(ShardedDiscordClient client) public LogCommands()
{ {
//_client.MessageReceived += _client_MessageReceived; //_client.MessageReceived += _client_MessageReceived;
_client.MessageUpdated += _client_MessageUpdated; _client.MessageUpdated += _client_MessageUpdated;

View File

@ -18,7 +18,7 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class RepeatCommands public class RepeatCommands
{ {
public ConcurrentDictionary<ulong, RepeatRunner> repeaters; public static ConcurrentDictionary<ulong, RepeatRunner> repeaters { get; }
public class RepeatRunner public class RepeatRunner
{ {
@ -70,7 +70,7 @@ namespace NadekoBot.Modules.Administration
} }
} }
public RepeatCommands() static RepeatCommands()
{ {
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {

View File

@ -18,7 +18,7 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class PlayingRotateCommands public class PlayingRotateCommands
{ {
private Logger _log { get; } private static Logger _log { get; }
public static List<PlayingStatus> RotatingStatusMessages { get; } public static List<PlayingStatus> RotatingStatusMessages { get; }
public static bool RotatingStatuses { get; private set; } = false; public static bool RotatingStatuses { get; private set; } = false;
@ -30,12 +30,9 @@ namespace NadekoBot.Modules.Administration
RotatingStatusMessages = conf.RotatingStatusMessages; RotatingStatusMessages = conf.RotatingStatusMessages;
RotatingStatuses = conf.RotatingStatuses; RotatingStatuses = conf.RotatingStatuses;
} }
}
public PlayingRotateCommands()
{
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
Task.Run(async () => var t = Task.Run(async () =>
{ {
var index = 0; var index = 0;
do do

View File

@ -16,9 +16,7 @@ namespace NadekoBot.Modules.Administration
public class RatelimitCommand public class RatelimitCommand
{ {
public static ConcurrentDictionary<ulong, Ratelimiter> RatelimitingChannels = new ConcurrentDictionary<ulong, Ratelimiter>(); public static ConcurrentDictionary<ulong, Ratelimiter> RatelimitingChannels = new ConcurrentDictionary<ulong, Ratelimiter>();
private Logger _log { get; } private static Logger _log { get; }
private ShardedDiscordClient _client { get; }
public class Ratelimiter public class Ratelimiter
{ {
@ -61,12 +59,11 @@ namespace NadekoBot.Modules.Administration
} }
} }
public RatelimitCommand() static RatelimitCommand()
{ {
this._client = NadekoBot.Client; _log = LogManager.GetCurrentClassLogger();
this._log = LogManager.GetCurrentClassLogger();
_client.MessageReceived += (umsg) => NadekoBot.Client.MessageReceived += (umsg) =>
{ {
var t = Task.Run(async () => var t = Task.Run(async () =>
{ {

View File

@ -13,9 +13,9 @@ namespace NadekoBot.Modules.Administration
{ {
private ShardedDiscordClient _client; private ShardedDiscordClient _client;
public SelfCommands(ShardedDiscordClient client) public SelfCommands()
{ {
this._client = client; this._client = NadekoBot.Client;
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]

View File

@ -17,17 +17,16 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class ServerGreetCommands public class ServerGreetCommands
{ {
public static long Greeted = 0; private static Logger _log { get; }
private Logger _log;
public ServerGreetCommands() static ServerGreetCommands()
{ {
NadekoBot.Client.UserJoined += UserJoined; NadekoBot.Client.UserJoined += UserJoined;
NadekoBot.Client.UserLeft += UserLeft; NadekoBot.Client.UserLeft += UserLeft;
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
} }
private Task UserLeft(IGuildUser user) private static Task UserLeft(IGuildUser user)
{ {
var leftTask = Task.Run(async () => var leftTask = Task.Run(async () =>
{ {
@ -67,7 +66,7 @@ namespace NadekoBot.Modules.Administration
return Task.CompletedTask; return Task.CompletedTask;
} }
private Task UserJoined(IGuildUser user) private static Task UserJoined(IGuildUser user)
{ {
var joinedTask = Task.Run(async () => var joinedTask = Task.Run(async () =>
{ {

View File

@ -17,10 +17,10 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class VoicePlusTextCommands public class VoicePlusTextCommands
{ {
Regex channelNameRegex = new Regex(@"[^a-zA-Z0-9 -]", RegexOptions.Compiled); private static Regex channelNameRegex = new Regex(@"[^a-zA-Z0-9 -]", RegexOptions.Compiled);
private ConcurrentHashSet<ulong> voicePlusTextCache; private static ConcurrentHashSet<ulong> voicePlusTextCache { get; }
public VoicePlusTextCommands() static VoicePlusTextCommands()
{ {
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
@ -29,7 +29,7 @@ namespace NadekoBot.Modules.Administration
NadekoBot.Client.UserVoiceStateUpdated += UserUpdatedEventHandler; NadekoBot.Client.UserVoiceStateUpdated += UserUpdatedEventHandler;
} }
private Task UserUpdatedEventHandler(IUser iuser, IVoiceState before, IVoiceState after) private static Task UserUpdatedEventHandler(IUser iuser, IVoiceState before, IVoiceState after)
{ {
var user = (iuser as IGuildUser); var user = (iuser as IGuildUser);
var guild = user?.Guild; var guild = user?.Guild;
@ -101,7 +101,7 @@ namespace NadekoBot.Modules.Administration
return Task.CompletedTask; return Task.CompletedTask;
} }
private string GetChannelName(string voiceName) => private static string GetChannelName(string voiceName) =>
channelNameRegex.Replace(voiceName, "").Trim().Replace(" ", "-").TrimTo(90, true) + "-voice"; channelNameRegex.Replace(voiceName, "").Trim().Replace(" ", "-").TrimTo(90, true) + "-voice";
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]

View File

@ -36,7 +36,7 @@ namespace NadekoBot.Modules.ClashOfClans
.ToDictionary(g => g.Key, g => g.ToList())); .ToDictionary(g => g.Key, g => g.ToList()));
} }
} }
public ClashOfClans(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public ClashOfClans() : base()
{ {
} }

View File

@ -25,7 +25,7 @@ namespace NadekoBot.Modules.CustomReactions
GlobalReactions = new ConcurrentHashSet<CustomReaction>(items.Where(g => g.GuildId == null || g.GuildId == 0)); GlobalReactions = new ConcurrentHashSet<CustomReaction>(items.Where(g => g.GuildId == null || g.GuildId == 0));
} }
} }
public CustomReactions(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public CustomReactions() : base()
{ {
} }

View File

@ -6,13 +6,10 @@ namespace NadekoBot.Modules
{ {
public class DiscordModule public class DiscordModule
{ {
protected ILocalization _l { get; }
protected CommandService _commands { get; }
protected ShardedDiscordClient _client { get; }
protected Logger _log { get; } protected Logger _log { get; }
protected string _prefix { get; } protected string _prefix { get; }
public DiscordModule(ILocalization loc, CommandService cmds, ShardedDiscordClient client) public DiscordModule()
{ {
string prefix; string prefix;
if (NadekoBot.ModulePrefixes.TryGetValue(this.GetType().Name, out prefix)) if (NadekoBot.ModulePrefixes.TryGetValue(this.GetType().Name, out prefix))
@ -20,9 +17,6 @@ namespace NadekoBot.Modules
else else
_prefix = "?missing_prefix?"; _prefix = "?missing_prefix?";
_l = loc;
_commands = cmds;
_client = client;
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
} }
} }

View File

@ -18,11 +18,7 @@ namespace NadekoBot.Modules.Gambling
[Group] [Group]
public class AnimalRacing public class AnimalRacing
{ {
public static ConcurrentDictionary<ulong, AnimalRace> AnimalRaces { get; } = new ConcurrentDictionary<ulong, AnimalRace>();
public AnimalRacing()
{
}
public static ConcurrentDictionary<ulong, AnimalRace> AnimalRaces = new ConcurrentDictionary<ulong, AnimalRace>();
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
@ -119,7 +115,7 @@ namespace NadekoBot.Modules.Gambling
await Task.Run(StartRace); await Task.Run(StartRace);
End(); End();
} }
catch { } catch { try { End(); } catch { } }
}); });
} }

View File

@ -15,10 +15,9 @@ namespace NadekoBot.Modules.Gambling
[Group] [Group]
public class FlipCoinCommands public class FlipCoinCommands
{ {
NadekoRandom rng { get; } = new NadekoRandom(); private static NadekoRandom rng { get; } = new NadekoRandom();
private const string headsPath = "data/images/coins/heads.png"; private const string headsPath = "data/images/coins/heads.png";
private const string tailsPath = "data/images/coins/tails.png"; private const string tailsPath = "data/images/coins/tails.png";
public FlipCoinCommands() { }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]

View File

@ -20,7 +20,7 @@ namespace NadekoBot.Modules.Gambling
public static string CurrencyPluralName { get; set; } public static string CurrencyPluralName { get; set; }
public static string CurrencySign { get; set; } public static string CurrencySign { get; set; }
public Gambling(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public Gambling() : base()
{ {
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {

View File

@ -31,23 +31,20 @@ namespace NadekoBot.Modules.Games
[Group] [Group]
public class PlantPickCommands public class PlantPickCommands
{ {
private Random rng; private static ConcurrentHashSet<ulong> generationChannels { get; } = new ConcurrentHashSet<ulong>();
private ConcurrentHashSet<ulong> generationChannels = new ConcurrentHashSet<ulong>();
//channelid/message //channelid/message
private ConcurrentDictionary<ulong, List<IUserMessage>> plantedFlowers = new ConcurrentDictionary<ulong, List<IUserMessage>>(); private static ConcurrentDictionary<ulong, List<IUserMessage>> plantedFlowers { get; } = new ConcurrentDictionary<ulong, List<IUserMessage>>();
//channelId/last generation //channelId/last generation
private ConcurrentDictionary<ulong, DateTime> lastGenerations = new ConcurrentDictionary<ulong, DateTime>(); private static ConcurrentDictionary<ulong, DateTime> lastGenerations { get; } = new ConcurrentDictionary<ulong, DateTime>();
private float chance; private static float chance { get; }
private int cooldown; private static int cooldown { get; }
private Logger _log { get; } private static Logger _log { get; }
public PlantPickCommands() static PlantPickCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
NadekoBot.Client.MessageReceived += PotentialFlowerGeneration; NadekoBot.Client.MessageReceived += PotentialFlowerGeneration;
rng = new NadekoRandom();
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
@ -60,7 +57,7 @@ namespace NadekoBot.Modules.Games
} }
} }
private Task PotentialFlowerGeneration(IMessage imsg) private static Task PotentialFlowerGeneration(IMessage imsg)
{ {
var msg = imsg as IUserMessage; var msg = imsg as IUserMessage;
if (msg == null || msg.IsAuthor() || msg.Author.IsBot) if (msg == null || msg.IsAuthor() || msg.Author.IsBot)
@ -76,6 +73,7 @@ namespace NadekoBot.Modules.Games
var t = Task.Run(async () => var t = Task.Run(async () =>
{ {
var lastGeneration = lastGenerations.GetOrAdd(channel.Id, DateTime.MinValue); var lastGeneration = lastGenerations.GetOrAdd(channel.Id, DateTime.MinValue);
var rng = new NadekoRandom();
if (DateTime.Now - TimeSpan.FromSeconds(cooldown) < lastGeneration) //recently generated in this channel, don't generate again if (DateTime.Now - TimeSpan.FromSeconds(cooldown) < lastGeneration) //recently generated in this channel, don't generate again
return; return;
@ -194,8 +192,11 @@ namespace NadekoBot.Modules.Games
} }
} }
private string GetRandomCurrencyImagePath() => private static string GetRandomCurrencyImagePath()
Directory.GetFiles("data/currency_images").OrderBy(s => rng.Next()).FirstOrDefault(); {
var rng = new NadekoRandom();
return Directory.GetFiles("data/currency_images").OrderBy(s => rng.Next()).FirstOrDefault();
}
int GetRandomNumber() int GetRandomNumber()
{ {

View File

@ -21,7 +21,7 @@ namespace NadekoBot.Modules.Games
} }
} }
} }
public Games(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public Games() : base()
{ {
} }

View File

@ -30,7 +30,7 @@ namespace NadekoBot.Modules.Help
} }
} }
public Help(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public Help() : base()
{ {
} }
@ -38,7 +38,7 @@ namespace NadekoBot.Modules.Help
public async Task Modules(IUserMessage umsg) public async Task Modules(IUserMessage umsg)
{ {
await umsg.Channel.SendMessageAsync("📜 **List of modules:** ```css\n• " + string.Join("\n• ", _commands.Modules.Select(m => m.Name)) + $"\n``` **Type** `-commands module_name` **to get a list of commands in that module.** ***e.g.*** `-commands games`") await umsg.Channel.SendMessageAsync("📜 **List of modules:** ```css\n• " + string.Join("\n• ", NadekoBot.CommandService.Modules.Select(m => m.Name)) + $"\n``` **Type** `-commands module_name` **to get a list of commands in that module.** ***e.g.*** `-commands games`")
.ConfigureAwait(false); .ConfigureAwait(false);
} }
@ -50,7 +50,7 @@ namespace NadekoBot.Modules.Help
module = module?.Trim().ToUpperInvariant(); module = module?.Trim().ToUpperInvariant();
if (string.IsNullOrWhiteSpace(module)) if (string.IsNullOrWhiteSpace(module))
return; return;
var cmds = _commands.Commands.Where(c => c.Module.Name.ToUpperInvariant().StartsWith(module)) var cmds = NadekoBot.CommandService.Commands.Where(c => c.Module.Name.ToUpperInvariant().StartsWith(module))
.OrderBy(c => c.Text) .OrderBy(c => c.Text)
.Distinct(new CommandTextEqualityComparer()) .Distinct(new CommandTextEqualityComparer())
.AsEnumerable(); .AsEnumerable();
@ -84,7 +84,7 @@ namespace NadekoBot.Modules.Help
await ch.SendMessageAsync(HelpString).ConfigureAwait(false); await ch.SendMessageAsync(HelpString).ConfigureAwait(false);
return; return;
} }
var com = _commands.Commands.FirstOrDefault(c => c.Text.ToLowerInvariant() == comToFind || c.Aliases.Select(a=>a.ToLowerInvariant()).Contains(comToFind)); var com = NadekoBot.CommandService.Commands.FirstOrDefault(c => c.Text.ToLowerInvariant() == comToFind || c.Aliases.Select(a=>a.ToLowerInvariant()).Contains(comToFind));
if (com == null) if (com == null)
{ {
@ -129,7 +129,7 @@ namespace NadekoBot.Modules.Help
helpstr.AppendLine(string.Join("\n", NadekoBot.CommandService.Modules.Where(m => m.Name.ToLowerInvariant() != "help").OrderBy(m => m.Name).Prepend(NadekoBot.CommandService.Modules.FirstOrDefault(m=>m.Name.ToLowerInvariant()=="help")).Select(m => $"- [{m.Name}](#{m.Name.ToLowerInvariant()})"))); helpstr.AppendLine(string.Join("\n", NadekoBot.CommandService.Modules.Where(m => m.Name.ToLowerInvariant() != "help").OrderBy(m => m.Name).Prepend(NadekoBot.CommandService.Modules.FirstOrDefault(m=>m.Name.ToLowerInvariant()=="help")).Select(m => $"- [{m.Name}](#{m.Name.ToLowerInvariant()})")));
helpstr.AppendLine(); helpstr.AppendLine();
string lastModule = null; string lastModule = null;
foreach (var com in _commands.Commands.OrderBy(com=>com.Module.Name).GroupBy(c=>c.Text).Select(g=>g.First())) foreach (var com in NadekoBot.CommandService.Commands.OrderBy(com=>com.Module.Name).GroupBy(c=>c.Text).Select(g=>g.First()))
{ {
if (com.Module.Name != lastModule) if (com.Module.Name != lastModule)
{ {

View File

@ -20,19 +20,16 @@ namespace NadekoBot.Modules.Music
[NadekoModule("Music", "!!", AutoLoad = false)] [NadekoModule("Music", "!!", AutoLoad = false)]
public partial class Music : DiscordModule public partial class Music : DiscordModule
{ {
public static ConcurrentDictionary<ulong, MusicPlayer> MusicPlayers = new ConcurrentDictionary<ulong, MusicPlayer>(); public static ConcurrentDictionary<ulong, MusicPlayer> MusicPlayers { get; } = new ConcurrentDictionary<ulong, MusicPlayer>();
public const string MusicDataPath = "data/musicdata"; public const string MusicDataPath = "data/musicdata";
private IGoogleApiService _google;
public Music(ILocalization loc, CommandService cmds, ShardedDiscordClient client, IGoogleApiService google) : base(loc, cmds, client) public Music() : base()
{ {
//it can fail if its currenctly opened or doesn't exist. Either way i don't care //it can fail if its currenctly opened or doesn't exist. Either way i don't care
try { Directory.Delete(MusicDataPath, true); } catch { } try { Directory.Delete(MusicDataPath, true); } catch { }
Directory.CreateDirectory(MusicDataPath); Directory.CreateDirectory(MusicDataPath);
_google = google;
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -259,13 +256,13 @@ namespace NadekoBot.Modules.Music
await channel.SendMessageAsync("💢 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); await channel.SendMessageAsync("💢 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; return;
} }
var plId = (await _google.GetPlaylistIdsByKeywordsAsync(arg).ConfigureAwait(false)).FirstOrDefault(); var plId = (await NadekoBot.Google.GetPlaylistIdsByKeywordsAsync(arg).ConfigureAwait(false)).FirstOrDefault();
if (plId == null) if (plId == null)
{ {
await channel.SendMessageAsync("No search results for that query."); await channel.SendMessageAsync("No search results for that query.");
return; return;
} }
var ids = await _google.GetPlaylistTracksAsync(plId, 500).ConfigureAwait(false); var ids = await NadekoBot.Google.GetPlaylistTracksAsync(plId, 500).ConfigureAwait(false);
if (!ids.Any()) if (!ids.Any())
{ {
await channel.SendMessageAsync($"🎵 `Failed to find any songs.`").ConfigureAwait(false); await channel.SendMessageAsync($"🎵 `Failed to find any songs.`").ConfigureAwait(false);

View File

@ -16,7 +16,7 @@ namespace NadekoBot.Modules.NSFW
[NadekoModule("NSFW", "~")] [NadekoModule("NSFW", "~")]
public class NSFW : DiscordModule public class NSFW : DiscordModule
{ {
public NSFW(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public NSFW() : base()
{ {
} }

View File

@ -24,7 +24,7 @@ namespace NadekoBot.Modules.Permissions
public class CmdCdsCommands public class CmdCdsCommands
{ {
public static ConcurrentDictionary<ulong, ConcurrentHashSet<CommandCooldown>> commandCooldowns { get; } public static ConcurrentDictionary<ulong, ConcurrentHashSet<CommandCooldown>> commandCooldowns { get; }
private static ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>> activeCooldowns = new ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>>(); private static ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>> activeCooldowns { get; } = new ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>>();
static CmdCdsCommands() static CmdCdsCommands()
{ {

View File

@ -14,14 +14,14 @@ namespace NadekoBot.Modules.Permissions
[Group] [Group]
public class FilterCommands public class FilterCommands
{ {
public static ConcurrentHashSet<ulong> InviteFilteringChannels { get; set; } public static ConcurrentHashSet<ulong> InviteFilteringChannels { get; }
public static ConcurrentHashSet<ulong> InviteFilteringServers { get; set; } public static ConcurrentHashSet<ulong> InviteFilteringServers { get; }
//serverid, filteredwords //serverid, filteredwords
private static ConcurrentDictionary<ulong, ConcurrentHashSet<string>> ServerFilteredWords { get; set; } private static ConcurrentDictionary<ulong, ConcurrentHashSet<string>> ServerFilteredWords { get; }
public static ConcurrentHashSet<ulong> WordFilteringChannels { get; set; } public static ConcurrentHashSet<ulong> WordFilteringChannels { get; }
public static ConcurrentHashSet<ulong> WordFilteringServers { get; set; } public static ConcurrentHashSet<ulong> WordFilteringServers { get; }
public static ConcurrentHashSet<string> FilteredWordsForChannel(ulong channelId, ulong guildId) public static ConcurrentHashSet<string> FilteredWordsForChannel(ulong channelId, ulong guildId)
{ {

View File

@ -21,7 +21,7 @@ namespace NadekoBot.Modules.Permissions
} }
//guildid, root permission //guildid, root permission
public static ConcurrentDictionary<ulong, PermissionCache> Cache; public static ConcurrentDictionary<ulong, PermissionCache> Cache { get; }
static Permissions() static Permissions()
{ {
@ -39,7 +39,7 @@ namespace NadekoBot.Modules.Permissions
} }
} }
public Permissions(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public Permissions() : base()
{ {
} }

View File

@ -27,7 +27,7 @@ namespace NadekoBot.Modules.Pokemon
private Logger _pokelog { get; } private Logger _pokelog { get; }
public Pokemon(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public Pokemon() : base()
{ {
_pokelog = LogManager.GetCurrentClassLogger(); _pokelog = LogManager.GetCurrentClassLogger();
if (File.Exists(PokemonTypesFile)) if (File.Exists(PokemonTypesFile))

View File

@ -10,6 +10,7 @@ using NLog;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches namespace NadekoBot.Modules.Searches
@ -19,14 +20,36 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class AnimeSearchCommands public class AnimeSearchCommands
{ {
private Logger _log; private static Timer anilistTokenRefresher { get; }
private static Logger _log { get; }
private static string anilistToken { get; set; }
private string anilistToken { get; set; } static AnimeSearchCommands()
private DateTime lastRefresh { get; set; }
public AnimeSearchCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
anilistTokenRefresher = new Timer(async (state) =>
{
try
{
var headers = new Dictionary<string, string> {
{"grant_type", "client_credentials"},
{"client_id", "kwoth-w0ki9"},
{"client_secret", "Qd6j4FIAi1ZK6Pc7N7V4Z"},
};
using (var http = new HttpClient())
{
http.AddFakeHeaders();
var formContent = new FormUrlEncodedContent(headers);
var response = await http.PostAsync("http://anilist.co/api/auth/access_token", formContent).ConfigureAwait(false);
var stringContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
anilistToken = JObject.Parse(stringContent)["access_token"].ToString();
}
}
catch (Exception ex) {
_log.Error(ex);
}
}, null, TimeSpan.FromSeconds(0), TimeSpan.FromMinutes(29));
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -40,6 +63,12 @@ namespace NadekoBot.Modules.Searches
var animeData = await GetAnimeData(query).ConfigureAwait(false); var animeData = await GetAnimeData(query).ConfigureAwait(false);
if (animeData == null)
{
await umsg.Channel.SendErrorAsync("Failed finding that animu.").ConfigureAwait(false);
return;
}
var embed = new Discord.API.Embed() var embed = new Discord.API.Embed()
{ {
Description = animeData.Synopsis, Description = animeData.Synopsis,
@ -79,32 +108,38 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(query)) if (string.IsNullOrWhiteSpace(query))
return; return;
var animeData = await GetMangaData(query).ConfigureAwait(false); var mangaData = await GetMangaData(query).ConfigureAwait(false);
if (mangaData == null)
{
await umsg.Channel.SendErrorAsync("Failed finding that mango.").ConfigureAwait(false);
return;
}
var embed = new Discord.API.Embed() var embed = new Discord.API.Embed()
{ {
Description = animeData.Synopsis, Description = mangaData.Synopsis,
Title = animeData.title_english, Title = mangaData.title_english,
Url = animeData.Link, Url = mangaData.Link,
Image = new Discord.API.EmbedImage() Image = new Discord.API.EmbedImage()
{ {
Url = animeData.image_url_lge Url = mangaData.image_url_lge
}, },
Fields = new[] { Fields = new[] {
new Discord.API.EmbedField() { new Discord.API.EmbedField() {
Inline = true, Inline = true,
Name = "Chapters", Name = "Chapters",
Value = animeData.total_chapters.ToString() Value = mangaData.total_chapters.ToString()
}, },
new Discord.API.EmbedField() { new Discord.API.EmbedField() {
Inline = true, Inline = true,
Name = "Status", Name = "Status",
Value = animeData.publishing_status.ToString() Value = mangaData.publishing_status.ToString()
}, },
new Discord.API.EmbedField() { new Discord.API.EmbedField() {
Inline = true, Inline = true,
Name = "Genres", Name = "Genres",
Value = String.Join(", ", animeData.Genres) Value = String.Join(", ", mangaData.Genres)
} }
}, },
Color = NadekoBot.OkColor Color = NadekoBot.OkColor
@ -119,7 +154,6 @@ namespace NadekoBot.Modules.Searches
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
try try
{ {
await RefreshAnilistToken().ConfigureAwait(false);
var link = "http://anilist.co/api/anime/search/" + Uri.EscapeUriString(query); var link = "http://anilist.co/api/anime/search/" + Uri.EscapeUriString(query);
using (var http = new HttpClient()) using (var http = new HttpClient())
@ -137,37 +171,12 @@ namespace NadekoBot.Modules.Searches
} }
} }
private async Task RefreshAnilistToken()
{
if (DateTime.Now - lastRefresh > TimeSpan.FromMinutes(29))
lastRefresh = DateTime.Now;
else
{
return;
}
var headers = new Dictionary<string, string> {
{"grant_type", "client_credentials"},
{"client_id", "kwoth-w0ki9"},
{"client_secret", "Qd6j4FIAi1ZK6Pc7N7V4Z"},
};
using (var http = new HttpClient())
{
http.AddFakeHeaders();
var formContent = new FormUrlEncodedContent(headers);
var response = await http.PostAsync("http://anilist.co/api/auth/access_token", formContent).ConfigureAwait(false);
var stringContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
anilistToken = JObject.Parse(stringContent)["access_token"].ToString();
}
}
private async Task<MangaResult> GetMangaData(string query) private async Task<MangaResult> GetMangaData(string query)
{ {
if (string.IsNullOrWhiteSpace(query)) if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
try try
{ {
await RefreshAnilistToken().ConfigureAwait(false);
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
var res = await http.GetStringAsync("http://anilist.co/api/manga/search/" + Uri.EscapeUriString(query) + $"?access_token={anilistToken}").ConfigureAwait(false); var res = await http.GetStringAsync("http://anilist.co/api/manga/search/" + Uri.EscapeUriString(query) + $"?access_token={anilistToken}").ConfigureAwait(false);

View File

@ -1,6 +1,7 @@
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Modules.Searches.Models; using NadekoBot.Modules.Searches.Models;
using NadekoBot.Services; using NadekoBot.Services;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -19,11 +20,11 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class JokeCommands public class JokeCommands
{ {
private List<WoWJoke> wowJokes = new List<WoWJoke>(); private static List<WoWJoke> wowJokes { get; } = new List<WoWJoke>();
private List<MagicItem> magicItems; private static List<MagicItem> magicItems { get; } = new List<MagicItem>();
private Logger _log; private static Logger _log { get; }
public JokeCommands() static JokeCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
if (File.Exists("data/wowjokes.json")) if (File.Exists("data/wowjokes.json"))
@ -43,61 +44,62 @@ namespace NadekoBot.Modules.Searches
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task Yomama(IUserMessage umsg) public async Task Yomama(IUserMessage msg)
{ {
var channel = (ITextChannel)umsg.Channel;
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
var response = await http.GetStringAsync("http://api.yomomma.info/").ConfigureAwait(false); var response = await http.GetStringAsync("http://api.yomomma.info/").ConfigureAwait(false);
await channel.SendMessageAsync("`" + JObject.Parse(response)["joke"].ToString() + "` 😆").ConfigureAwait(false); await msg.Channel.SendConfirmAsync(JObject.Parse(response)["joke"].ToString() + " 😆").ConfigureAwait(false);
} }
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task Randjoke(IUserMessage umsg) public async Task Randjoke(IUserMessage msg)
{ {
var channel = (ITextChannel)umsg.Channel;
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
var response = await http.GetStringAsync("http://tambal.azurewebsites.net/joke/random").ConfigureAwait(false); var response = await http.GetStringAsync("http://tambal.azurewebsites.net/joke/random").ConfigureAwait(false);
await channel.SendMessageAsync("`" + JObject.Parse(response)["joke"].ToString() + "` 😆").ConfigureAwait(false); await msg.Channel.SendConfirmAsync(JObject.Parse(response)["joke"].ToString() + " 😆").ConfigureAwait(false);
} }
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task ChuckNorris(IUserMessage umsg) public async Task ChuckNorris(IUserMessage msg)
{ {
var channel = (ITextChannel)umsg.Channel;
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
var response = await http.GetStringAsync("http://api.icndb.com/jokes/random/").ConfigureAwait(false); var response = await http.GetStringAsync("http://api.icndb.com/jokes/random/").ConfigureAwait(false);
await channel.SendMessageAsync("`" + JObject.Parse(response)["value"]["joke"].ToString() + "` 😆").ConfigureAwait(false); await msg.Channel.SendConfirmAsync(JObject.Parse(response)["value"]["joke"].ToString() + " 😆").ConfigureAwait(false);
} }
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task WowJoke(IUserMessage umsg) public async Task WowJoke(IUserMessage msg)
{ {
var channel = (ITextChannel)umsg.Channel;
if (!wowJokes.Any()) if (!wowJokes.Any())
{ {
await msg.Channel.SendErrorAsync("Jokes not loaded.").ConfigureAwait(false);
return;
} }
await channel.SendMessageAsync(wowJokes[new NadekoRandom().Next(0, wowJokes.Count)].ToString()); var joke = wowJokes[new NadekoRandom().Next(0, wowJokes.Count)];
await msg.Channel.SendConfirmAsync(joke.Question, joke.Answer).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task MagicItem(IUserMessage umsg) public async Task MagicItem(IUserMessage msg)
{ {
var channel = (ITextChannel)umsg.Channel; if (!wowJokes.Any())
var rng = new NadekoRandom(); {
var item = magicItems[rng.Next(0, magicItems.Count)].ToString(); await msg.Channel.SendErrorAsync("MagicItems not loaded.").ConfigureAwait(false);
return;
}
var item = magicItems[new NadekoRandom().Next(0, magicItems.Count)];
await channel.SendMessageAsync(item).ConfigureAwait(false); await msg.Channel.SendConfirmAsync("✨" + item.Name, item.Description).ConfigureAwait(false);
} }
} }
} }

View File

@ -1,6 +1,7 @@
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services; using NadekoBot.Services;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System; using System;
@ -23,7 +24,7 @@ namespace NadekoBot.Modules.Searches
obj["name"].GetHashCode(); obj["name"].GetHashCode();
} }
private string[] trashTalk { get; } = { "Better ban your counters. You are going to carry the game anyway.", private static string[] trashTalk { get; } = { "Better ban your counters. You are going to carry the game anyway.",
"Go with the flow. Don't think. Just ban one of these.", "Go with the flow. Don't think. Just ban one of these.",
"DONT READ BELOW! Ban Urgot mid OP 100%. Im smurf Diamond 1.", "DONT READ BELOW! Ban Urgot mid OP 100%. Im smurf Diamond 1.",
"Ask your teammates what would they like to play, and ban that.", "Ask your teammates what would they like to play, and ban that.",
@ -50,23 +51,19 @@ namespace NadekoBot.Modules.Searches
$"limit={showCount}") $"limit={showCount}")
.ConfigureAwait(false))["data"] as JArray; .ConfigureAwait(false))["data"] as JArray;
var dataList = data.Distinct(new ChampionNameComparer()).Take(showCount).ToList(); var dataList = data.Distinct(new ChampionNameComparer()).Take(showCount).ToList();
var sb = new StringBuilder(); var eb = new EmbedBuilder().WithColor(NadekoBot.OkColor).WithTitle(Format.Underline($"{dataList.Count} most banned champions"));
sb.AppendLine($"**Showing {dataList.Count} top banned champions.**");
sb.AppendLine($"`{trashTalk[new NadekoRandom().Next(0, trashTalk.Length)]}`");
for (var i = 0; i < dataList.Count; i++) for (var i = 0; i < dataList.Count; i++)
{ {
if (i % 2 == 0 && i != 0) var champ = dataList[i];
sb.AppendLine(); eb.AddField(efb => efb.WithName(champ["name"].ToString()).WithValue(champ["general"]["banRate"] + "%").WithIsInline(true));
sb.Append($"`{i + 1}.` **{dataList[i]["name"]}** {dataList[i]["general"]["banRate"]}% ");
//sb.AppendLine($" ({dataList[i]["general"]["banRate"]}%)");
} }
await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false); await channel.EmbedAsync(eb.Build(), Format.Italics(trashTalk[new NadekoRandom().Next(0, trashTalk.Length)])).ConfigureAwait(false);
} }
} }
catch (Exception) catch (Exception)
{ {
await channel.SendMessageAsync($":anger: `Something went wrong.`").ConfigureAwait(false); await channel.SendMessageAsync("Something went wrong.").ConfigureAwait(false);
} }
} }
} }

View File

@ -25,20 +25,11 @@ namespace NadekoBot.Modules.Searches
using (var http = new HttpClient(handler)) using (var http = new HttpClient(handler))
{ {
http.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); var rawJson = await http.GetStringAsync("https://memegen.link/api/templates/").ConfigureAwait(false);
string rawJson = "";
try
{
rawJson = await http.GetStringAsync("https://memegen.link/api/templates/").ConfigureAwait(false);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawJson) var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawJson)
.Select(kvp => Path.GetFileName(kvp.Value)); .Select(kvp => Path.GetFileName(kvp.Value));
await channel.SendTableAsync(data, x => $"{x,-17}", 3); await channel.SendTableAsync(data, x => $"{x,-17}", 3).ConfigureAwait(false);
} }
} }
@ -50,7 +41,8 @@ namespace NadekoBot.Modules.Searches
var top = Uri.EscapeDataString(topText.Replace(' ', '-')); var top = Uri.EscapeDataString(topText.Replace(' ', '-'));
var bot = Uri.EscapeDataString(botText.Replace(' ', '-')); var bot = Uri.EscapeDataString(botText.Replace(' ', '-'));
await channel.SendMessageAsync($"http://memegen.link/{meme}/{top}/{bot}.jpg"); await channel.SendMessageAsync($"http://memegen.link/{meme}/{top}/{bot}.jpg")
.ConfigureAwait(false);
} }
} }
} }

View File

@ -4,7 +4,5 @@
{ {
public string Name { get; set; } public string Name { get; set; }
public string Description { get; set; } public string Description { get; set; }
public override string ToString() =>
$"✨`{Name}`\n\t*{Description}*";
} }
} }

View File

@ -18,9 +18,8 @@ namespace NadekoBot.Modules.Searches.Models
public int SPD { get; set; } public int SPD { get; set; }
public int SPE { get; set; } public int SPE { get; set; }
public override string ToString() => $@" public override string ToString() => $@"**HP:** {HP,-4} **ATK:** {ATK,-4} **DEF:** {DEF,-4}
**HP:** {HP,-4} **ATK:** {ATK,-4} **DEF:** {DEF,-4} **SPA:** {SPA,-4} **SPD:** {SPD,-4} **SPE:** {SPE,-4}";
**SPA:** {SPA,-4} **SPD:** {SPD,-4} **SPE:** {SPE,-4}";
} }
public int Id { get; set; } public int Id { get; set; }
public string Species { get; set; } public string Species { get; set; }

View File

@ -1,4 +1,6 @@
using Newtonsoft.Json; using Discord;
using Discord.API;
using Newtonsoft.Json;
using System; using System;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -32,6 +34,17 @@ namespace NadekoBot.Modules.Searches.Commands.OMDB
public string Plot { get; set; } public string Plot { get; set; }
public string Poster { get; set; } public string Poster { get; set; }
public Embed GetEmbed() =>
new EmbedBuilder().WithColor(NadekoBot.OkColor)
.WithTitle(Title)
.WithUrl($"http://www.imdb.com/title/{ImdbId}/")
.WithDescription(Plot)
.AddField(efb => efb.WithName("Rating").WithValue(ImdbRating).WithIsInline(true))
.AddField(efb => efb.WithName("Genre").WithValue(Genre).WithIsInline(true))
.AddField(efb => efb.WithName("Year").WithValue(Year).WithIsInline(true))
.WithImage(eib => eib.WithUrl(Poster))
.Build();
public override string ToString() => public override string ToString() =>
$@"`Title:` {Title} $@"`Title:` {Title}
`Year:` {Year} `Year:` {Year}

View File

@ -18,9 +18,9 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class OsuCommands public class OsuCommands
{ {
private Logger _log; private static Logger _log { get; }
public OsuCommands() static OsuCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
} }
@ -52,7 +52,7 @@ namespace NadekoBot.Modules.Searches
} }
catch (Exception ex) catch (Exception ex)
{ {
await channel.SendMessageAsync("💢 Failed retrieving osu signature :\\").ConfigureAwait(false); await channel.SendErrorAsync("Failed retrieving osu signature.").ConfigureAwait(false);
_log.Warn(ex, "Osu command failed"); _log.Warn(ex, "Osu command failed");
} }
} }
@ -66,7 +66,7 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey)) if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey))
{ {
await channel.SendMessageAsync("💢 An osu! API key is required.").ConfigureAwait(false); await channel.SendErrorAsync("An osu! API key is required.").ConfigureAwait(false);
return; return;
} }
@ -90,7 +90,7 @@ namespace NadekoBot.Modules.Searches
} }
catch (Exception ex) catch (Exception ex)
{ {
await channel.SendMessageAsync("Something went wrong."); await channel.SendErrorAsync("Something went wrong.");
_log.Warn(ex, "Osub command failed"); _log.Warn(ex, "Osub command failed");
} }
} }
@ -102,13 +102,13 @@ namespace NadekoBot.Modules.Searches
var channel = (ITextChannel)umsg.Channel; var channel = (ITextChannel)umsg.Channel;
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey)) if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey))
{ {
await channel.SendMessageAsync("💢 An osu! API key is required.").ConfigureAwait(false); await channel.SendErrorAsync("An osu! API key is required.").ConfigureAwait(false);
return; return;
} }
if (string.IsNullOrWhiteSpace(user)) if (string.IsNullOrWhiteSpace(user))
{ {
await channel.SendMessageAsync("💢 Please provide a username.").ConfigureAwait(false); await channel.SendErrorAsync("Please provide a username.").ConfigureAwait(false);
return; return;
} }
using (var http = new HttpClient()) using (var http = new HttpClient())
@ -141,7 +141,7 @@ namespace NadekoBot.Modules.Searches
} }
catch (Exception ex) catch (Exception ex)
{ {
await channel.SendMessageAsync("Something went wrong."); await channel.SendErrorAsync("Something went wrong.");
_log.Warn(ex, "Osu5 command failed"); _log.Warn(ex, "Osu5 command failed");
} }

View File

@ -1,6 +1,7 @@
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services; using NadekoBot.Services;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -36,7 +37,7 @@ namespace NadekoBot.Modules.Searches
{ {
var channel = (ITextChannel)imsg.Channel; var channel = (ITextChannel)imsg.Channel;
await channel.SendMessageAsync(typesStr) await channel.SendConfirmAsync(typesStr)
.ConfigureAwait(false); .ConfigureAwait(false);
} }

View File

@ -1,11 +1,13 @@
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Modules.Searches.Models; using NadekoBot.Modules.Searches.Models;
using Newtonsoft.Json; using Newtonsoft.Json;
using NLog; using NLog;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches namespace NadekoBot.Modules.Searches
@ -15,15 +17,15 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class PokemonSearchCommands public class PokemonSearchCommands
{ {
private static Dictionary<string, SearchPokemon> pokemons = new Dictionary<string, SearchPokemon>(); private static Dictionary<string, SearchPokemon> pokemons { get; } = new Dictionary<string, SearchPokemon>();
private static Dictionary<string, SearchPokemonAbility> pokemonAbilities = new Dictionary<string, SearchPokemonAbility>(); private static Dictionary<string, SearchPokemonAbility> pokemonAbilities { get; } = new Dictionary<string, SearchPokemonAbility>();
public const string PokemonAbilitiesFile = "data/pokemon/pokemon_abilities.json"; public const string PokemonAbilitiesFile = "data/pokemon/pokemon_abilities.json";
public const string PokemonListFile = "data/pokemon/pokemon_list.json"; public const string PokemonListFile = "data/pokemon/pokemon_list.json";
private Logger _log; private static Logger _log { get; }
public PokemonSearchCommands() static PokemonSearchCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
if (File.Exists(PokemonListFile)) if (File.Exists(PokemonListFile))
@ -52,11 +54,18 @@ namespace NadekoBot.Modules.Searches
{ {
if (kvp.Key.ToUpperInvariant() == pokemon.ToUpperInvariant()) if (kvp.Key.ToUpperInvariant() == pokemon.ToUpperInvariant())
{ {
await channel.SendMessageAsync($"`Stats for \"{kvp.Key}\" pokemon:`\n{kvp.Value}"); var p = kvp.Value;
await channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor)
.WithTitle(kvp.Key.ToTitleCase())
.WithDescription(p.BaseStats.ToString())
.AddField(efb => efb.WithName("Types").WithValue(string.Join(",\n", p.Types)).WithIsInline(true))
.AddField(efb => efb.WithName("Height/Weight").WithValue($"{p.HeightM}m/{p.WeightKg}kg").WithIsInline(true))
.AddField(efb => efb.WithName("Abilitities").WithValue(string.Join(",\n", p.Abilities.Select(a => a.Value))).WithIsInline(true))
.Build());
return; return;
} }
} }
await channel.SendMessageAsync("`No pokemon found.`"); await channel.SendErrorAsync("No pokemon found.");
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -72,11 +81,15 @@ namespace NadekoBot.Modules.Searches
{ {
if (kvp.Key.ToUpperInvariant() == ability) if (kvp.Key.ToUpperInvariant() == ability)
{ {
await channel.SendMessageAsync($"`Info for \"{kvp.Key}\" ability:`\n{kvp.Value}"); await channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor)
.WithTitle(kvp.Value.Name)
.WithDescription(kvp.Value.Desc)
.AddField(efb => efb.WithName("Rating").WithValue(kvp.Value.Rating.ToString()).WithIsInline(true))
.Build()).ConfigureAwait(false);
return; return;
} }
} }
await channel.SendMessageAsync("`No ability found.`"); await channel.SendErrorAsync("No ability found.");
} }
} }
} }

View File

@ -69,14 +69,14 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class StreamNotificationCommands public class StreamNotificationCommands
{ {
private Timer checkTimer { get; } private static Timer checkTimer { get; }
private ConcurrentDictionary<string, StreamStatus> oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>(); private static ConcurrentDictionary<string, StreamStatus> oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private ConcurrentDictionary<string, StreamStatus> cachedStatuses = new ConcurrentDictionary<string, StreamStatus>(); private static ConcurrentDictionary<string, StreamStatus> cachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private Logger _log { get; } private static Logger _log { get; }
private bool FirstPass { get; set; } = true; private static bool FirstPass { get; set; } = true;
public StreamNotificationCommands() static StreamNotificationCommands()
{ {
_log = NLog.LogManager.GetCurrentClassLogger(); _log = NLog.LogManager.GetCurrentClassLogger();
@ -111,17 +111,14 @@ namespace NadekoBot.Modules.Searches
try { await channel.EmbedAsync(fs.GetEmbed(newStatus).Build()).ConfigureAwait(false); } catch { } try { await channel.EmbedAsync(fs.GetEmbed(newStatus).Build()).ConfigureAwait(false); } catch { }
} }
} }
catch (Exception ex) catch { }
{
}
})); }));
FirstPass = false; FirstPass = false;
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(60)); }, null, TimeSpan.Zero, TimeSpan.FromSeconds(60));
} }
private async Task<StreamStatus> GetStreamStatus(FollowedStream stream, bool checkCache = true) private static async Task<StreamStatus> GetStreamStatus(FollowedStream stream, bool checkCache = true)
{ {
string response; string response;
StreamStatus result; StreamStatus result;
@ -193,40 +190,6 @@ namespace NadekoBot.Modules.Searches
return null; return null;
} }
//[NadekoCommand, Usage, Description, Aliases]
//[RequireContext(ContextType.Guild)]
//public async Task Test(IUserMessage imsg)
//{
// var channel = (ITextChannel)imsg.Channel;
// await channel.EmbedAsync(new Discord.API.Embed()
// {
// Title = "Imqtpie",
// Url = "https://twitch.tv/masterkwoth",
// Fields = new[] {
// new Discord.API.EmbedField()
// {
// Name = "Status",
// Value = "Online",
// Inline = true,
// },
// new Discord.API.EmbedField()
// {
// Name = "Viewers",
// Value = "123123",
// Inline = true
// },
// new Discord.API.EmbedField()
// {
// Name = "Platform",
// Value = "Twitch",
// Inline = true
// },
// },
// Color = NadekoBot.OkColor
// });
//}
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
[RequirePermission(GuildPermission.ManageMessages)] [RequirePermission(GuildPermission.ManageMessages)]
@ -265,7 +228,7 @@ namespace NadekoBot.Modules.Searches
if (!streams.Any()) if (!streams.Any())
{ {
await channel.SendMessageAsync("You are not following any streams on this server.").ConfigureAwait(false); await channel.SendConfirmAsync("You are not following any streams on this server.").ConfigureAwait(false);
return; return;
} }
@ -274,7 +237,7 @@ namespace NadekoBot.Modules.Searches
return $"`{snc.Username}`'s stream on **{channel.Guild.GetTextChannel(snc.ChannelId)?.Name}** channel. 【`{snc.Type.ToString()}`】"; return $"`{snc.Username}`'s stream on **{channel.Guild.GetTextChannel(snc.ChannelId)?.Name}** channel. 【`{snc.Type.ToString()}`】";
})); }));
await channel.SendMessageAsync($"You are following **{streams.Count()}** streams on this server.\n\n" + text).ConfigureAwait(false); await channel.SendConfirmAsync($"You are following **{streams.Count()}** streams on this server.\n\n" + text).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -303,10 +266,10 @@ namespace NadekoBot.Modules.Searches
} }
if (!removed) if (!removed)
{ {
await channel.SendMessageAsync("❎ No such stream.").ConfigureAwait(false); await channel.SendErrorAsync("No such stream.").ConfigureAwait(false);
return; return;
} }
await channel.SendMessageAsync($"🗑 Removed `{username}`'s stream ({type}) from notifications.").ConfigureAwait(false); await channel.SendConfirmAsync($"Removed `{username}`'s stream ({type}) from notifications.").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -327,22 +290,22 @@ namespace NadekoBot.Modules.Searches
})); }));
if (streamStatus.IsLive) if (streamStatus.IsLive)
{ {
await channel.SendMessageAsync($"`Streamer {username} is online with {streamStatus.Views} viewers.`"); await channel.SendConfirmAsync($"Streamer {username} is online with {streamStatus.Views} viewers.");
} }
else else
{ {
await channel.SendMessageAsync($"`Streamer {username} is offline.`"); await channel.SendConfirmAsync($"Streamer {username} is offline.");
} }
} }
catch catch
{ {
await channel.SendMessageAsync("No channel found."); await channel.SendErrorAsync("No channel found.");
} }
} }
private async Task TrackStream(ITextChannel channel, string username, FollowedStream.FollowedStreamType type) private async Task TrackStream(ITextChannel channel, string username, FollowedStream.FollowedStreamType type)
{ {
username = username.Trim(); username = username.ToLowerInvariant().Trim();
var fs = new FollowedStream var fs = new FollowedStream
{ {
GuildId = channel.Guild.Id, GuildId = channel.Guild.Id,
@ -358,7 +321,7 @@ namespace NadekoBot.Modules.Searches
} }
catch catch
{ {
await channel.SendMessageAsync("💢 Stream probably doesn't exist.").ConfigureAwait(false); await channel.SendErrorAsync("Stream probably doesn't exist.").ConfigureAwait(false);
return; return;
} }
@ -369,9 +332,7 @@ namespace NadekoBot.Modules.Searches
.Add(fs); .Add(fs);
await uow.CompleteAsync().ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false);
} }
await channel.EmbedAsync(fs.GetEmbed(status).Build(), $"🆗 I will notify this channel when status changes.").ConfigureAwait(false);
var msg = $"🆗 I will notify this channel when status changes.";
await channel.EmbedAsync(fs.GetEmbed(status).Build(), msg).ConfigureAwait(false);
} }
} }
} }

View File

@ -75,12 +75,12 @@ namespace NadekoBot.Modules.Searches
{ {
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
var translation = await TranslateInternal(umsg, langs, text); var translation = await TranslateInternal(umsg, langs, text);
await channel.SendMessageAsync(translation).ConfigureAwait(false); await channel.SendConfirmAsync(translation).ConfigureAwait(false);
} }
catch catch
{ {
await channel.SendMessageAsync("Bad input format, or something went wrong...").ConfigureAwait(false); await channel.SendErrorAsync("Bad input format, or something went wrong...").ConfigureAwait(false);
} }
} }
@ -114,19 +114,19 @@ namespace NadekoBot.Modules.Searches
if (autoDelete == AutoDeleteAutoTranslate.Del) if (autoDelete == AutoDeleteAutoTranslate.Del)
{ {
TranslatedChannels.AddOrUpdate(channel.Id, true, (key, val) => true); TranslatedChannels.AddOrUpdate(channel.Id, true, (key, val) => true);
try { await channel.SendMessageAsync("`Started automatic translation of messages on this channel. User messages will be auto-deleted.`").ConfigureAwait(false); } catch { } try { await channel.SendConfirmAsync("Started automatic translation of messages on this channel. User messages will be auto-deleted.").ConfigureAwait(false); } catch { }
return; return;
} }
bool throwaway; bool throwaway;
if (TranslatedChannels.TryRemove(channel.Id, out throwaway)) if (TranslatedChannels.TryRemove(channel.Id, out throwaway))
{ {
try { await channel.SendMessageAsync("`Stopped automatic translation of messages on this channel.`").ConfigureAwait(false); } catch { } try { await channel.SendConfirmAsync("Stopped automatic translation of messages on this channel.").ConfigureAwait(false); } catch { }
return; return;
} }
else if (TranslatedChannels.TryAdd(channel.Id, autoDelete == AutoDeleteAutoTranslate.Del)) else if (TranslatedChannels.TryAdd(channel.Id, autoDelete == AutoDeleteAutoTranslate.Del))
{ {
try { await channel.SendMessageAsync("`Started automatic translation of messages on this channel.`").ConfigureAwait(false); } catch { } try { await channel.SendConfirmAsync("Started automatic translation of messages on this channel.").ConfigureAwait(false); } catch { }
} }
} }
@ -145,7 +145,7 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(langs)) if (string.IsNullOrWhiteSpace(langs))
{ {
if (UserLanguages.TryRemove(ucp, out langs)) if (UserLanguages.TryRemove(ucp, out langs))
await channel.SendMessageAsync($"{msg.Author.Mention}'s auto-translate language has been removed.").ConfigureAwait(false); await channel.SendConfirmAsync($"{msg.Author.Mention}'s auto-translate language has been removed.").ConfigureAwait(false);
return; return;
} }
@ -157,13 +157,13 @@ namespace NadekoBot.Modules.Searches
if (!GoogleTranslator.Instance.Languages.Contains(from) || !GoogleTranslator.Instance.Languages.Contains(to)) if (!GoogleTranslator.Instance.Languages.Contains(from) || !GoogleTranslator.Instance.Languages.Contains(to))
{ {
try { await channel.SendMessageAsync("`Invalid source and/or target Language.`").ConfigureAwait(false); } catch { } try { await channel.SendErrorAsync("Invalid source and/or target language.").ConfigureAwait(false); } catch { }
return; return;
} }
UserLanguages.AddOrUpdate(ucp, langs, (key, val) => langs); UserLanguages.AddOrUpdate(ucp, langs, (key, val) => langs);
await channel.SendMessageAsync(":ok:").ConfigureAwait(false); await channel.SendConfirmAsync($"Your auto-translate language has been set to {from}>{to}").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]

View File

@ -1,6 +1,7 @@
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions;
using NadekoBot.Services; using NadekoBot.Services;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Net.Http; using System.Net.Http;
@ -55,12 +56,17 @@ namespace NadekoBot.Modules.Searches
var res = await http.GetStringAsync($"{xkcdUrl}/{num}/info.0.json").ConfigureAwait(false); var res = await http.GetStringAsync($"{xkcdUrl}/{num}/info.0.json").ConfigureAwait(false);
var comic = JsonConvert.DeserializeObject<XkcdComic>(res); var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
var sent = await channel.SendMessageAsync($"{msg.Author.Mention} " + comic.ToString()) var embed = new EmbedBuilder().WithColor(NadekoBot.OkColor)
.WithImage(eib => eib.WithUrl(comic.ImageLink))
.WithAuthor(eab => eab.WithName(comic.Title).WithUrl($"{xkcdUrl}/{num}").WithIconUrl("http://xkcd.com/s/919f27.ico"))
.AddField(efb => efb.WithName("Comic#").WithValue(comic.Num.ToString()).WithIsInline(true))
.AddField(efb => efb.WithName("Date").WithValue($"{comic.Month}/{comic.Year}").WithIsInline(true));
var sent = await channel.EmbedAsync(embed.Build())
.ConfigureAwait(false); .ConfigureAwait(false);
await Task.Delay(10000).ConfigureAwait(false); await Task.Delay(10000).ConfigureAwait(false);
await sent.ModifyAsync(m => m.Content = sent.Content + $"\n`Alt:` {comic.Alt}"); await sent.ModifyAsync(m => m.Embed = embed.AddField(efb => efb.WithName("Alt").WithValue(comic.Alt.ToString()).WithIsInline(false)).Build());
} }
} }
} }

View File

@ -23,13 +23,6 @@ namespace NadekoBot.Modules.Searches
[NadekoModule("Searches", "~")] [NadekoModule("Searches", "~")]
public partial class Searches : DiscordModule public partial class Searches : DiscordModule
{ {
private IGoogleApiService _google { get; }
public Searches(ILocalization loc, CommandService cmds, ShardedDiscordClient client, IGoogleApiService youtube) : base(loc, cmds, client)
{
_google = youtube;
}
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task Weather(IUserMessage umsg, string city, string country) public async Task Weather(IUserMessage umsg, string city, string country)
@ -63,13 +56,16 @@ namespace NadekoBot.Modules.Searches
{ {
var channel = (ITextChannel)umsg.Channel; var channel = (ITextChannel)umsg.Channel;
if (!(await ValidateQuery(channel, query).ConfigureAwait(false))) return; if (!(await ValidateQuery(channel, query).ConfigureAwait(false))) return;
var result = (await _google.GetVideosByKeywordsAsync(query, 1)).FirstOrDefault(); var result = (await NadekoBot.Google.GetVideosByKeywordsAsync(query, 1)).FirstOrDefault();
if (string.IsNullOrWhiteSpace(result)) if (string.IsNullOrWhiteSpace(result))
{ {
await channel.SendMessageAsync("No results found for that query."); await channel.SendErrorAsync("No results found for that query.").ConfigureAwait(false);
return; return;
} }
await channel.SendMessageAsync(result).ConfigureAwait(false); await channel.SendMessageAsync(result).ConfigureAwait(false);
//await channel.EmbedAsync(new Discord.API.Embed() { Video = new Discord.API.EmbedVideo() { Url = result.Replace("watch?v=", "embed/") }, Color = NadekoBot.OkColor }).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -84,10 +80,10 @@ namespace NadekoBot.Modules.Searches
var movie = await OmdbProvider.FindMovie(query); var movie = await OmdbProvider.FindMovie(query);
if (movie == null) if (movie == null)
{ {
await channel.SendMessageAsync("Failed to find that movie.").ConfigureAwait(false); await channel.SendErrorAsync("Failed to find that movie.").ConfigureAwait(false);
return; return;
} }
await channel.SendMessageAsync(movie.ToString()).ConfigureAwait(false); await channel.EmbedAsync(movie.GetEmbed()).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -97,9 +93,8 @@ namespace NadekoBot.Modules.Searches
var channel = (ITextChannel)umsg.Channel; var channel = (ITextChannel)umsg.Channel;
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
await channel.SendMessageAsync(JObject.Parse( var res = JObject.Parse(await http.GetStringAsync("http://www.random.cat/meow").ConfigureAwait(false));
await http.GetStringAsync("http://www.random.cat/meow").ConfigureAwait(false))["file"].ToString()) await channel.SendMessageAsync(res["file"].ToString()).ConfigureAwait(false);
.ConfigureAwait(false);
} }
} }
@ -110,7 +105,8 @@ namespace NadekoBot.Modules.Searches
var channel = (ITextChannel)umsg.Channel; var channel = (ITextChannel)umsg.Channel;
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
await channel.SendMessageAsync("http://random.dog/" + await http.GetStringAsync("http://random.dog/woof").ConfigureAwait(false)).ConfigureAwait(false); await channel.SendMessageAsync("http://random.dog/" + await http.GetStringAsync("http://random.dog/woof")
.ConfigureAwait(false)).ConfigureAwait(false);
} }
} }
@ -135,11 +131,12 @@ namespace NadekoBot.Modules.Searches
{ {
if (exception.Message.Contains("403 (Forbidden)")) if (exception.Message.Contains("403 (Forbidden)"))
{ {
await channel.SendMessageAsync("Daily limit reached!"); await channel.SendErrorAsync("Daily limit reached!");
} }
else else
{ {
await channel.SendMessageAsync("Something went wrong."); await channel.SendErrorAsync("Something went wrong.");
_log.Error(exception);
} }
} }
} }
@ -167,11 +164,12 @@ namespace NadekoBot.Modules.Searches
{ {
if (exception.Message.Contains("403 (Forbidden)")) if (exception.Message.Contains("403 (Forbidden)"))
{ {
await channel.SendMessageAsync("Daily limit reached!"); await channel.SendErrorAsync("Daily limit reached!");
} }
else else
{ {
await channel.SendMessageAsync("Something went wrong."); await channel.SendErrorAsync("Something went wrong.");
_log.Error(exception);
} }
} }
} }
@ -186,7 +184,7 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(ffs)) if (string.IsNullOrWhiteSpace(ffs))
return; return;
await channel.SendMessageAsync(await _google.ShortenUrl($"<http://lmgtfy.com/?q={ Uri.EscapeUriString(ffs) }>")) await channel.SendConfirmAsync(await NadekoBot.Google.ShortenUrl($"<http://lmgtfy.com/?q={ Uri.EscapeUriString(ffs) }>"))
.ConfigureAwait(false); .ConfigureAwait(false);
} }
@ -197,7 +195,20 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(arg)) if (string.IsNullOrWhiteSpace(arg))
return; return;
await msg.Channel.SendMessageAsync(await NadekoBot.Google.ShortenUrl(arg).ConfigureAwait(false)); var shortened = await NadekoBot.Google.ShortenUrl(arg).ConfigureAwait(false);
if (shortened == arg)
{
await msg.Channel.SendErrorAsync("Failed to shorten that url.").ConfigureAwait(false);
}
await msg.Channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor)
.AddField(efb => efb.WithName("Original Url")
.WithValue($"<{arg}>"))
.AddField(efb => efb.WithName("Short Url")
.WithValue($"<{shortened}>"))
.Build())
.ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -206,11 +217,11 @@ namespace NadekoBot.Modules.Searches
{ {
var channel = (ITextChannel)umsg.Channel; var channel = (ITextChannel)umsg.Channel;
terms = terms?.Trim(); terms = terms?.Trim();
if (string.IsNullOrWhiteSpace(terms)) if (string.IsNullOrWhiteSpace(terms))
return; return;
await channel.SendMessageAsync($"https://google.com/search?q={ WebUtility.UrlEncode(terms).Replace(' ', '+') }")
await channel.SendConfirmAsync($"https://google.com/search?q={ WebUtility.UrlEncode(terms).Replace(' ', '+') }")
.ConfigureAwait(false); .ConfigureAwait(false);
} }
@ -222,7 +233,7 @@ namespace NadekoBot.Modules.Searches
var arg = name; var arg = name;
if (string.IsNullOrWhiteSpace(arg)) if (string.IsNullOrWhiteSpace(arg))
{ {
await channel.SendMessageAsync("💢 `Please enter a card name to search for.`").ConfigureAwait(false); await channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false);
return; return;
} }
@ -238,18 +249,26 @@ namespace NadekoBot.Modules.Searches
var items = JArray.Parse(response).Shuffle().ToList(); var items = JArray.Parse(response).Shuffle().ToList();
if (items == null) if (items == null)
throw new KeyNotFoundException("Cannot find a card by that name"); throw new KeyNotFoundException("Cannot find a card by that name");
var msg = $@"```css var item = items[0];
[☕ Magic The Gathering]: {items[0]["name"].ToString()} var storeUrl = await NadekoBot.Google.ShortenUrl(item["store_url"].ToString());
[Store URL]: {await _google.ShortenUrl(items[0]["store_url"].ToString())} var cost = item["cost"].ToString();
[Cost]: {items[0]["cost"].ToString()} var desc = item["text"].ToString();
[Description]: {items[0]["text"].ToString()} var types = String.Join(",\n", item["types"].ToObject<string[]>());
``` var img = item["editions"][0]["image_url"].ToString();
{items[0]["editions"][0]["image_url"].ToString()}"; var embed = new EmbedBuilder().WithColor(NadekoBot.OkColor)
await channel.SendMessageAsync(msg).ConfigureAwait(false); .WithTitle(item["name"].ToString())
.WithDescription(desc)
.WithImage(eib => eib.WithUrl(img))
.AddField(efb => efb.WithName("Store Url").WithValue(storeUrl).WithIsInline(true))
.AddField(efb => efb.WithName("Cost").WithValue(cost).WithIsInline(true))
.AddField(efb => efb.WithName("Types").WithValue(types).WithIsInline(true));
//.AddField(efb => efb.WithName("Store Url").WithValue(await NadekoBot.Google.ShortenUrl(items[0]["store_url"].ToString())).WithIsInline(true));
await channel.EmbedAsync(embed.Build()).ConfigureAwait(false);
} }
catch catch
{ {
await channel.SendMessageAsync($"💢 Error could not find the card {arg}").ConfigureAwait(false); await channel.SendErrorAsync($"Error could not find the card '{arg}'.").ConfigureAwait(false);
} }
} }
} }
@ -262,13 +281,13 @@ namespace NadekoBot.Modules.Searches
var arg = name; var arg = name;
if (string.IsNullOrWhiteSpace(arg)) if (string.IsNullOrWhiteSpace(arg))
{ {
await channel.SendMessageAsync("💢 `Please enter a card name to search for.`").ConfigureAwait(false); await channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false);
return; return;
} }
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey)) if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
{ {
await channel.SendMessageAsync("💢 `Bot owner didn't specify MashapeApiKey. You can't use this functionality.`").ConfigureAwait(false); await channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false);
return; return;
} }
@ -308,7 +327,8 @@ namespace NadekoBot.Modules.Searches
} }
catch (Exception ex) catch (Exception ex)
{ {
await channel.SendMessageAsync($"💢 Error {ex.Message}").ConfigureAwait(false); await channel.SendErrorAsync($"Error occured.").ConfigureAwait(false);
_log.Error(ex);
} }
} }
} }
@ -321,14 +341,14 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey)) if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
{ {
await channel.SendMessageAsync("💢 `Bot owner didn't specify MashapeApiKey. You can't use this functionality.`").ConfigureAwait(false); await channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false);
return; return;
} }
var arg = query; var arg = query;
if (string.IsNullOrWhiteSpace(arg)) if (string.IsNullOrWhiteSpace(arg))
{ {
await channel.SendMessageAsync("💢 `Please enter a sentence.`").ConfigureAwait(false); await channel.SendErrorAsync("Please enter a sentence.").ConfigureAwait(false);
return; return;
} }
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
@ -341,18 +361,15 @@ namespace NadekoBot.Modules.Searches
try try
{ {
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.WithTitle("Young Padawan")
.WithUrl("http://www.yodaspeak.co.uk/") .WithUrl("http://www.yodaspeak.co.uk/")
.WithAuthor(au => au.WithName("Yoda").WithIconUrl("http://www.yodaspeak.co.uk/yoda-small1.gif")) .WithAuthor(au => au.WithName("Yoda").WithIconUrl("http://www.yodaspeak.co.uk/yoda-small1.gif"))
.WithDescription("Seek advice, you must!") .WithDescription(res)
.WithThumbnail(th => th.WithUrl("http://i.imgur.com/62Uh4u6.jpg"))
.AddField(fb => fb.WithName($"🌍 **{umsg.Author.Username}**").WithValue($"{res.ToString()}").WithIsInline(false))
.WithColor(NadekoBot.OkColor); .WithColor(NadekoBot.OkColor);
await channel.EmbedAsync(embed.Build()).ConfigureAwait(false); await channel.EmbedAsync(embed.Build()).ConfigureAwait(false);
} }
catch catch
{ {
await channel.SendMessageAsync("💢 Failed to yodify your sentence.").ConfigureAwait(false); await channel.SendErrorAsync("Failed to yodify your sentence.").ConfigureAwait(false);
} }
} }
} }
@ -365,34 +382,38 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey)) if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
{ {
await channel.SendMessageAsync("💢 `Bot owner didn't specify MashapeApiKey. You can't use this functionality.`").ConfigureAwait(false); await channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false);
return; return;
} }
var arg = query; var arg = query;
if (string.IsNullOrWhiteSpace(arg)) if (string.IsNullOrWhiteSpace(arg))
{ {
await channel.SendMessageAsync("💢 `Please enter a search term.`").ConfigureAwait(false); await channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false);
return; return;
} }
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
http.DefaultRequestHeaders.Clear(); http.DefaultRequestHeaders.Clear();
http.DefaultRequestHeaders.Add("X-Mashape-Key", NadekoBot.Credentials.MashapeKey); http.DefaultRequestHeaders.Add("Accept", "application/json");
var res = await http.GetStringAsync($"https://mashape-community-urban-dictionary.p.mashape.com/define?term={Uri.EscapeUriString(arg)}").ConfigureAwait(false); var res = await http.GetStringAsync($"http://api.urbandictionary.com/v0/define?term={Uri.EscapeUriString(arg)}").ConfigureAwait(false);
try try
{ {
var items = JObject.Parse(res); var items = JObject.Parse(res);
var sb = new StringBuilder(); var item = items["list"][0];
sb.AppendLine($"`Term:` {items["list"][0]["word"].ToString()}"); var word = item["word"].ToString();
sb.AppendLine($"`Definition:` {items["list"][0]["definition"].ToString()}"); var def = item["definition"].ToString();
sb.Append($"`Link:` <{await _google.ShortenUrl(items["list"][0]["permalink"].ToString()).ConfigureAwait(false)}>"); var link = item["permalink"].ToString();
await channel.SendMessageAsync(sb.ToString()); var embed = new EmbedBuilder().WithColor(NadekoBot.OkColor)
.WithUrl(link)
.WithAuthor(eab => eab.WithIconUrl("http://i.imgur.com/nwERwQE.jpg").WithName(word))
.WithDescription(def);
await channel.EmbedAsync(embed.Build()).ConfigureAwait(false);
} }
catch catch
{ {
await channel.SendMessageAsync("💢 Failed finding a definition for that term.").ConfigureAwait(false); await channel.SendErrorAsync("Failed finding a definition for that term.").ConfigureAwait(false);
} }
} }
} }
@ -406,12 +427,12 @@ namespace NadekoBot.Modules.Searches
var arg = query; var arg = query;
if (string.IsNullOrWhiteSpace(arg)) if (string.IsNullOrWhiteSpace(arg))
{ {
await channel.SendMessageAsync("💢 `Please enter a search term.`").ConfigureAwait(false); await channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false);
return; return;
} }
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey)) if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
{ {
await channel.SendMessageAsync("💢 `Bot owner didn't specify MashapeApiKey. You can't use this functionality.`").ConfigureAwait(false); await channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false);
return; return;
} }
@ -427,14 +448,20 @@ namespace NadekoBot.Modules.Searches
try try
{ {
var items = JObject.Parse(res); var items = JObject.Parse(res);
var str = $@"`Hashtag:` {items["defs"]["def"]["hashtag"].ToString()} var item = items["defs"]["def"];
`Definition:` {items["defs"]["def"]["text"].ToString()} var hashtag = item["hashtag"].ToString();
`Link:` <{await _google.ShortenUrl(items["defs"]["def"]["uri"].ToString()).ConfigureAwait(false)}>"; var link = item["uri"].ToString();
await channel.SendMessageAsync(str); var desc = item["text"].ToString();
await channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor)
.WithAuthor(eab => eab.WithUrl(link)
.WithIconUrl("http://res.cloudinary.com/urbandictionary/image/upload/a_exif,c_fit,h_200,w_200/v1394975045/b8oszuu3tbq7ebyo7vo1.jpg")
.WithName(query))
.WithDescription(desc)
.Build());
} }
catch catch
{ {
await channel.SendMessageAsync("💢 Failed finding a definition for that tag.").ConfigureAwait(false); await channel.SendErrorAsync("Failed finding a definition for that tag.").ConfigureAwait(false);
} }
} }
@ -448,7 +475,9 @@ namespace NadekoBot.Modules.Searches
var response = await http.GetStringAsync("http://catfacts-api.appspot.com/api/facts").ConfigureAwait(false); var response = await http.GetStringAsync("http://catfacts-api.appspot.com/api/facts").ConfigureAwait(false);
if (response == null) if (response == null)
return; return;
await channel.SendMessageAsync($"🐈 `{JObject.Parse(response)["facts"][0].ToString()}`").ConfigureAwait(false);
var fact = JObject.Parse(response)["facts"][0].ToString();
await channel.SendConfirmAsync("🐈fact", fact).ConfigureAwait(false);
} }
} }
@ -460,7 +489,7 @@ namespace NadekoBot.Modules.Searches
if (usr == null) if (usr == null)
usr = umsg.Author; usr = umsg.Author;
await channel.SendMessageAsync($"https://images.google.com/searchbyimage?image_url={usr.AvatarUrl}").ConfigureAwait(false); await channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={usr.AvatarUrl}").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -472,7 +501,7 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(imageLink)) if (string.IsNullOrWhiteSpace(imageLink))
return; return;
await channel.SendMessageAsync($"https://images.google.com/searchbyimage?image_url={imageLink}").ConfigureAwait(false); await channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={imageLink}").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -484,7 +513,7 @@ namespace NadekoBot.Modules.Searches
tag = tag?.Trim() ?? ""; tag = tag?.Trim() ?? "";
var link = await GetSafebooruImageLink(tag).ConfigureAwait(false); var link = await GetSafebooruImageLink(tag).ConfigureAwait(false);
if (link == null) if (link == null)
await channel.SendMessageAsync("`No results.`"); await channel.SendErrorAsync("No results.");
else else
await channel.SendMessageAsync(link).ConfigureAwait(false); await channel.SendMessageAsync(link).ConfigureAwait(false);
} }
@ -503,7 +532,7 @@ namespace NadekoBot.Modules.Searches
var result = await http.GetStringAsync("https://en.wikipedia.org//w/api.php?action=query&format=json&prop=info&redirects=1&formatversion=2&inprop=url&titles=" + Uri.EscapeDataString(query)); var result = await http.GetStringAsync("https://en.wikipedia.org//w/api.php?action=query&format=json&prop=info&redirects=1&formatversion=2&inprop=url&titles=" + Uri.EscapeDataString(query));
var data = JsonConvert.DeserializeObject<WikipediaApiModel>(result); var data = JsonConvert.DeserializeObject<WikipediaApiModel>(result);
if (data.Query.Pages[0].Missing) if (data.Query.Pages[0].Missing)
await channel.SendMessageAsync("`That page could not be found.`"); await channel.SendErrorAsync("That page could not be found.");
else else
await channel.SendMessageAsync(data.Query.Pages[0].FullUrl); await channel.SendMessageAsync(data.Query.Pages[0].FullUrl);
} }
@ -543,12 +572,12 @@ namespace NadekoBot.Modules.Searches
str += new NadekoRandom().Next(); str += new NadekoRandom().Next();
foreach (var usr in allUsrsArray) foreach (var usr in allUsrsArray)
{ {
await (await (usr as IGuildUser).CreateDMChannelAsync()).SendMessageAsync(str).ConfigureAwait(false); await (await (usr as IGuildUser).CreateDMChannelAsync()).SendConfirmAsync(str).ConfigureAwait(false);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex); _log.Error(ex);
} }
} }
@ -561,10 +590,10 @@ namespace NadekoBot.Modules.Searches
var usr = umsg.MentionedUsers.FirstOrDefault(); var usr = umsg.MentionedUsers.FirstOrDefault();
if (usr == null) if (usr == null)
{ {
await channel.SendMessageAsync("Invalid user specified.").ConfigureAwait(false); await channel.SendErrorAsync("Invalid user specified.").ConfigureAwait(false);
return; return;
} }
await channel.SendMessageAsync(await _google.ShortenUrl(usr.AvatarUrl).ConfigureAwait(false)).ConfigureAwait(false); await channel.SendMessageAsync(await NadekoBot.Google.ShortenUrl(usr.AvatarUrl).ConfigureAwait(false)).ConfigureAwait(false);
} }
public static async Task<string> GetSafebooruImageLink(string tag) public static async Task<string> GetSafebooruImageLink(string tag)
@ -583,160 +612,6 @@ namespace NadekoBot.Modules.Searches
} }
} }
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task BFO(IUserMessage umsg, [Remainder] string game = null)
{
var channel = (ITextChannel)umsg.Channel;
if (string.IsNullOrWhiteSpace(game))
{
await channel.SendMessageAsync("💢 Please enter a game `(bf3, bf4)`").ConfigureAwait(false);
return;
}
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
try
{
if (game.Equals("bf3", StringComparison.OrdinalIgnoreCase))
{
var res = await http.GetStringAsync($"http://api.bf3stats.com/global/onlinestats/").ConfigureAwait(false);
var items = JObject.Parse(res);
var sb = new StringBuilder();
var status = items["status"];
var x360 = items["360"];
var ps3 = items["ps3"];
var pc = items["pc"];
var response = $@"```css
[☕ BF3 Status: {status.ToString().ToUpper()}]
XBOX360: [{x360.ToString()}]
PS3: [{ps3.ToString()}]
PC: [{pc.ToString()}]
```";
await channel.SendMessageAsync(response);
}
else if (game.Equals("bf4", StringComparison.OrdinalIgnoreCase))
{
var res = await http.GetStringAsync($"http://api.bf4stats.com/api/onlinePlayers?output=json").ConfigureAwait(false);
var items = JObject.Parse(res);
var sb = new StringBuilder();
var status = !string.IsNullOrEmpty(items.ToString()) ? "OK" : "BAD";
var pc = items["pc"];
var ps3 = items["ps3"];
var ps4 = items["ps4"];
var xbox = items["xbox"];
var xone = items["xone"];
sb.AppendLine("```css");
sb.AppendLine($"[☕ BF4 Status: {status}]");
foreach (var i in items) {
var plat = items[i.Key];
sb.AppendLine($"{plat["label"]}: ✔[{plat["count"]}] / ↑[{plat["peak24"]}]");
}
sb.Append("```");
await channel.SendMessageAsync(sb.ToString());
}
} catch
{
await channel.SendMessageAsync($"💢 BF3/BF4 API is most likely not working at the moment or could not find {game}.").ConfigureAwait(false);
}
}
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task BFU(IUserMessage umsg, string platform, string game, [Remainder] string query = null)
{
var channel = (ITextChannel)umsg.Channel;
if (string.IsNullOrWhiteSpace(platform) || string.IsNullOrWhiteSpace(game) || string.IsNullOrWhiteSpace(query))
{
await channel.SendMessageAsync("💢 Please enter a platform `(pc, xbox, ps3, xone, ps4)`, game `(bf3, bf4)`, followed by a search query.").ConfigureAwait(false);
return;
}
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Clear();
try
{
if (game.Equals("bf3", StringComparison.OrdinalIgnoreCase))
{
var res = await http.GetStringAsync($"http://api.bf3stats.com/{Uri.EscapeUriString(platform)}/playerlist/players={Uri.EscapeUriString(query)}?output=json").ConfigureAwait(false);
var items = JObject.Parse(res);
var sb = new StringBuilder();
var playerName = items["list"][query];
var playerTag = playerName["tag"];
var playerCountryName = playerName["country_name"];
var playerStats = playerName["stats"];
var playerRank = playerStats["rank"];
var playerRank_name = playerRank["name"];
var playerGlobal_Kills = playerStats["global"]["kills"];
var playerGlobal_Deaths = playerStats["global"]["deaths"];
var playerGlobal_KD = Math.Round(Double.Parse(playerGlobal_Kills.ToString()) / Double.Parse(playerGlobal_Deaths.ToString()), 2);
var playerGlobal_Wins = playerStats["global"]["wins"];
var playerGlobal_Losses = playerStats["global"]["losses"];
var playerGlobal_WL = Math.Round(Double.Parse(playerGlobal_Wins.ToString()) / Double.Parse(playerGlobal_Losses.ToString()), 2);
var playerGlobal_Shots = playerStats["global"]["shots"];
var playerGlobal_Hits = playerStats["global"]["hits"];
var playerGlobal_Accuracy = Math.Round(Double.Parse(playerGlobal_Hits.ToString()) / Double.Parse(playerGlobal_Shots.ToString()), 2);
var playerGlobal_ELO = playerStats["global"]["elo"];
var response = $@"```css
[☕ BF3 Player: {query}]
Platform: [{platform.ToUpper()}]
Tag: [{playerTag.ToString()}]
K/D: [{playerGlobal_KD.ToString()}]
W/L: [{playerGlobal_WL.ToString()}]
Accuracy: %[{playerGlobal_Accuracy.ToString()}]
ELO: [{playerGlobal_ELO.ToString()}]
```";
await channel.SendMessageAsync(response);
} else if (game.Equals("bf4", StringComparison.OrdinalIgnoreCase))
{
var res = await http.GetStringAsync($"http://api.bf4stats.com/api/playerInfo?plat={Uri.EscapeUriString(platform)}&name={Uri.EscapeUriString(query)}&output=json").ConfigureAwait(false);
var items = JObject.Parse(res);
var sb = new StringBuilder();
var player = items["player"];
var playerStats = items["stats"];
var playerName = player["name"];
var playerTag = player["tag"];
var playerPlatform = player["plat"];
var playerKills = playerStats["kills"];
var playerDeaths = playerStats["deaths"];
var player_KD = Math.Round(Double.Parse(playerKills.ToString()) / Double.Parse(playerDeaths.ToString()), 2);
var playerWins = playerStats["numWins"];
var playerRounds = playerStats["numRounds"];
var player_WL = Math.Round(Double.Parse(playerWins.ToString()) / Double.Parse(playerRounds.ToString()), 2);
var shotsFired = playerStats["shotsFired"];
var shotsHit = playerStats["shotsHit"];
var accuracy = Math.Round(Double.Parse(shotsHit.ToString()) / Double.Parse(shotsFired.ToString()), 2);
var playerELO = playerStats["elo"];
var response = $@"```css
[☕ BF4 Player: {playerName.ToString()}]
Platform: [{playerPlatform.ToString().ToUpper()}]
Tag: [{playerTag.ToString()}]
K/D: [{player_KD.ToString()}]
W/L: [{player_WL.ToString()}]
Accuracy: %[{accuracy.ToString()}]
ELO: [{playerELO.ToString()}]
```";
await channel.SendMessageAsync(response);
}
}
catch
{
await channel.SendMessageAsync($"💢 BF3/BF4 API is most likely not working at the moment or could not find {query}.").ConfigureAwait(false);
}
}
}
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task Wikia(IUserMessage umsg, string target, [Remainder] string query = null) public async Task Wikia(IUserMessage umsg, string target, [Remainder] string query = null)
@ -744,7 +619,7 @@ ELO: [{playerELO.ToString()}]
var channel = (ITextChannel)umsg.Channel; var channel = (ITextChannel)umsg.Channel;
if (string.IsNullOrWhiteSpace(target) || string.IsNullOrWhiteSpace(query)) if (string.IsNullOrWhiteSpace(target) || string.IsNullOrWhiteSpace(query))
{ {
await channel.SendMessageAsync("💢 Please enter a target wikia, followed by search query.").ConfigureAwait(false); await channel.SendErrorAsync("Please enter a target wikia, followed by search query.").ConfigureAwait(false);
return; return;
} }
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
@ -763,7 +638,7 @@ ELO: [{playerELO.ToString()}]
} }
catch catch
{ {
await channel.SendMessageAsync($"💢 Failed finding `{query}`.").ConfigureAwait(false); await channel.SendErrorAsync($"Failed finding `{query}`.").ConfigureAwait(false);
} }
} }
} }
@ -776,7 +651,7 @@ ELO: [{playerELO.ToString()}]
var arg = query; var arg = query;
if (string.IsNullOrWhiteSpace(arg)) if (string.IsNullOrWhiteSpace(arg))
{ {
await channel.SendMessageAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false); await channel.SendErrorAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false);
return; return;
} }
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
@ -800,7 +675,7 @@ ELO: [{playerELO.ToString()}]
} }
catch catch
{ {
await channel.SendMessageAsync($"💢 Failed finding `{arg}`.").ConfigureAwait(false); await channel.SendErrorAsync($"Failed finding `{arg}`.").ConfigureAwait(false);
} }
} }
} }
@ -813,7 +688,7 @@ ELO: [{playerELO.ToString()}]
var arg = query; var arg = query;
if (string.IsNullOrWhiteSpace(arg)) if (string.IsNullOrWhiteSpace(arg))
{ {
await channel.SendMessageAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false); await channel.SendErrorAsync("Please enter `ip:port`.").ConfigureAwait(false);
return; return;
} }
await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false);
@ -840,7 +715,7 @@ ELO: [{playerELO.ToString()}]
} }
catch catch
{ {
await channel.SendMessageAsync($"💢 Failed finding server `{arg}`.").ConfigureAwait(false); await channel.SendErrorAsync($"Failed finding server `{arg}`.").ConfigureAwait(false);
} }
} }
} }
@ -848,7 +723,7 @@ ELO: [{playerELO.ToString()}]
public static async Task<bool> ValidateQuery(ITextChannel ch, string query) public static async Task<bool> ValidateQuery(ITextChannel ch, string query)
{ {
if (!string.IsNullOrEmpty(query.Trim())) return true; if (!string.IsNullOrEmpty(query.Trim())) return true;
await ch.SendMessageAsync("Please specify search parameters.").ConfigureAwait(false); await ch.SendErrorAsync("Please specify search parameters.").ConfigureAwait(false);
return false; return false;
} }
} }

View File

@ -3,6 +3,8 @@ using Discord.Commands;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using System; using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
@ -10,24 +12,19 @@ using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility namespace NadekoBot.Modules.Utility
{ {
[Group]
public partial class Utility public partial class Utility
{ {
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public static async Task Calculate(IUserMessage msg, [Remainder] string expression) public static async Task Calculate(IUserMessage msg, [Remainder] string expression)
{
try
{ {
var expr = new NCalc.Expression(expression, NCalc.EvaluateOptions.IgnoreCase); var expr = new NCalc.Expression(expression, NCalc.EvaluateOptions.IgnoreCase);
expr.EvaluateParameter += Expr_EvaluateParameter; expr.EvaluateParameter += Expr_EvaluateParameter;
var result = expr.Evaluate(); var result = expr.Evaluate();
await msg.Reply(string.Format("⚙ `{0}`", expr.Error ?? result)); if (expr.Error == null)
} await msg.Channel.SendConfirmAsync("Result", $"{result}");
catch (Exception e) else
{ await msg.Channel.SendErrorAsync($"⚙ Error", expr.Error);
await msg.Reply($"Failed to evaluate: {e.Message} ");
}
} }
private static void Expr_EvaluateParameter(string name, NCalc.ParameterArgs args) private static void Expr_EvaluateParameter(string name, NCalc.ParameterArgs args)
@ -44,20 +41,25 @@ namespace NadekoBot.Modules.Utility
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task CalcOps(IUserMessage msg) public async Task CalcOps(IUserMessage msg)
{ {
StringBuilder builder = new StringBuilder(); var selection = typeof(Math).GetTypeInfo().GetMethods().Except(typeof(object).GetTypeInfo().GetMethods()).Distinct(new MethodInfoEqualityComparer()).Select(x =>
var selection = typeof(Math).GetTypeInfo().GetMethods().Except(typeof(object).GetTypeInfo().GetMethods()).Select(x =>
{ {
var name = x.Name; return x.Name;
if (x.GetParameters().Any()) })
.Except(new[] { "ToString",
"Equals",
"GetHashCode",
"GetType"});
await msg.Channel.SendConfirmAsync(string.Join(", ",selection));
}
}
class MethodInfoEqualityComparer : IEqualityComparer<MethodInfo>
{ {
name += " (" + string.Join(", ", x.GetParameters().Select(y => y.IsOptional ? $"[{y.ParameterType.Name + " " + y.Name }]" : y.ParameterType.Name + " " + y.Name)) + ")"; public bool Equals(MethodInfo x, MethodInfo y) => x.Name == y.Name;
}
return name; public int GetHashCode(MethodInfo obj) => obj.Name.GetHashCode();
});
foreach (var method in selection) builder.AppendLine(method);
await msg.ReplyLong(builder.ToString());
}
} }
class ExpressionContext class ExpressionContext
{ {
public double Pi { get; set; } = Math.PI; public double Pi { get; set; } = Math.PI;

View File

@ -10,25 +10,8 @@ using System.Threading.Tasks;
namespace NadekoBot.Modules.Utility namespace NadekoBot.Modules.Utility
{ {
partial class Utility : DiscordModule public partial class Utility
{ {
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task TogetherTube(IUserMessage imsg)
{
var channel = (ITextChannel)imsg.Channel;
Uri target;
using (var http = new HttpClient())
{
var res = await http.GetAsync("https://togethertube.com/room/create").ConfigureAwait(false);
target = res.RequestMessage.RequestUri;
}
await channel.SendMessageAsync($"🎞 {imsg.Author.Mention}, **Your new video room created. Join and invite to watch videos together with friends:** {target}")
.ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task ServerInfo(IUserMessage msg, string guild = null) public async Task ServerInfo(IUserMessage msg, string guild = null)
@ -39,7 +22,7 @@ namespace NadekoBot.Modules.Utility
if (guild == null) if (guild == null)
server = channel.Guild; server = channel.Guild;
else else
server = _client.GetGuilds().Where(g => g.Name.ToUpperInvariant() == guild.ToUpperInvariant()).FirstOrDefault(); server = NadekoBot.Client.GetGuilds().Where(g => g.Name.ToUpperInvariant() == guild.ToUpperInvariant()).FirstOrDefault();
if (server == null) if (server == null)
return; return;
@ -61,7 +44,7 @@ __`Created At:`__ **{createdAt.ToString("dd.MM.yyyy HH:mm")}**
sb.AppendLine($"__`Features:`__ **{string.Join(", ", server.Features)}**"); sb.AppendLine($"__`Features:`__ **{string.Join(", ", server.Features)}**");
if (!string.IsNullOrWhiteSpace(server.SplashUrl)) if (!string.IsNullOrWhiteSpace(server.SplashUrl))
sb.AppendLine($"__`Region:`__ **{server.VoiceRegionId}**"); sb.AppendLine($"__`Region:`__ **{server.VoiceRegionId}**");
await msg.Reply(sb.ToString()).ConfigureAwait(false); await channel.SendConfirmAsync(sb.ToString()).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -77,7 +60,7 @@ __`ID:`__ **{ch.Id}**
__`Created At:`__ **{createdAt.ToString("dd.MM.yyyy HH:mm")}** __`Created At:`__ **{createdAt.ToString("dd.MM.yyyy HH:mm")}**
__`Topic:`__ {ch.Topic} __`Topic:`__ {ch.Topic}
__`Users:`__ **{(await ch.GetUsersAsync()).Count()}**"; __`Users:`__ **{(await ch.GetUsersAsync()).Count()}**";
await msg.Reply(toReturn).ConfigureAwait(false); await msg.Channel.SendConfirmAsync(toReturn).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -99,7 +82,7 @@ __`Users:`__ **{(await ch.GetUsersAsync()).Count()}**";
if (!string.IsNullOrWhiteSpace(user.AvatarUrl)) if (!string.IsNullOrWhiteSpace(user.AvatarUrl))
toReturn += $@" toReturn += $@"
📷 __`Avatar URL:`__ **{await NadekoBot.Google.ShortenUrl(user.AvatarUrl).ConfigureAwait(false)}**"; 📷 __`Avatar URL:`__ **{await NadekoBot.Google.ShortenUrl(user.AvatarUrl).ConfigureAwait(false)}**";
await msg.Reply(toReturn).ConfigureAwait(false); await msg.Channel.SendConfirmAsync(toReturn).ConfigureAwait(false);
} }
} }
} }

View File

@ -31,10 +31,10 @@ namespace NadekoBot.Modules.Utility
} }
if (quotes.Any()) if (quotes.Any())
await channel.SendMessageAsync($"💬 **Page {page + 1} of quotes:**\n```xl\n" + String.Join("\n", quotes.Select((q) => $"{q.Keyword,-20} by {q.AuthorName}")) + "\n```") await channel.SendConfirmAsync($"💬 **Page {page + 1} of quotes:**\n```xl\n" + String.Join("\n", quotes.Select((q) => $"{q.Keyword,-20} by {q.AuthorName}")) + "\n```")
.ConfigureAwait(false); .ConfigureAwait(false);
else else
await channel.SendMessageAsync(" **No quotes on this page.**").ConfigureAwait(false); await channel.SendErrorAsync("No quotes on this page.").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -57,7 +57,7 @@ namespace NadekoBot.Modules.Utility
if (quote == null) if (quote == null)
return; return;
await channel.SendMessageAsync("📣 " + quote.Text.SanitizeMentions()); await channel.SendConfirmAsync("📣 " + quote.Text.SanitizeMentions());
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -83,7 +83,7 @@ namespace NadekoBot.Modules.Utility
}); });
await uow.CompleteAsync().ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false);
} }
await channel.SendMessageAsync("✅ **Quote added.**").ConfigureAwait(false); await channel.SendConfirmAsync("✅ Quote added.").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -105,7 +105,7 @@ namespace NadekoBot.Modules.Utility
if (qs==null || !qs.Any()) if (qs==null || !qs.Any())
{ {
response = " **No quotes found.**"; await channel.SendErrorAsync("No quotes found.");
return; return;
} }
@ -115,7 +115,7 @@ namespace NadekoBot.Modules.Utility
await uow.CompleteAsync().ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false);
response = "🗑 **Deleted a random quote.**"; response = "🗑 **Deleted a random quote.**";
} }
await channel.SendMessageAsync(response); await channel.SendConfirmAsync(response);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -139,7 +139,7 @@ namespace NadekoBot.Modules.Utility
await uow.CompleteAsync(); await uow.CompleteAsync();
} }
await channel.SendMessageAsync($"🗑 **Deleted all quotes** with **{keyword}** keyword."); await channel.SendConfirmAsync($"🗑 **Deleted all quotes** with **{keyword}** keyword.");
} }
} }
} }

View File

@ -74,7 +74,7 @@ namespace NadekoBot.Modules.Utility
if (ch == null) if (ch == null)
return; return;
await ch.SendMessageAsync( await ch.SendConfirmAsync(
replacements.Aggregate(RemindMessageFormat, replacements.Aggregate(RemindMessageFormat,
(cur, replace) => cur.Replace(replace.Key, replace.Value(r))) (cur, replace) => cur.Replace(replace.Key, replace.Value(r)))
.SanitizeMentions() .SanitizeMentions()
@ -124,7 +124,7 @@ namespace NadekoBot.Modules.Utility
if (ch == null) if (ch == null)
{ {
await channel.SendMessageAsync($"⚠️ {umsg.Author.Mention} Something went wrong (channel cannot be found) ;(").ConfigureAwait(false); await channel.SendErrorAsync($"{umsg.Author.Mention} Something went wrong (channel cannot be found) ;(").ConfigureAwait(false);
return; return;
} }
@ -132,7 +132,7 @@ namespace NadekoBot.Modules.Utility
if (m.Length == 0) if (m.Length == 0)
{ {
await channel.SendMessageAsync("❎ **Not a valid time format.** type `-h .remind`").ConfigureAwait(false); await channel.SendErrorAsync("Not a valid time format. Type `-h .remind`").ConfigureAwait(false);
return; return;
} }
@ -157,7 +157,7 @@ namespace NadekoBot.Modules.Utility
(groupName == "hours" && value > 23) || (groupName == "hours" && value > 23) ||
(groupName == "minutes" && value > 59)) (groupName == "minutes" && value > 59))
{ {
await channel.SendMessageAsync($"⚠️ Invalid {groupName} value.").ConfigureAwait(false); await channel.SendErrorAsync($"Invalid {groupName} value.").ConfigureAwait(false);
return; return;
} }
else else
@ -187,7 +187,7 @@ namespace NadekoBot.Modules.Utility
await uow.CompleteAsync(); await uow.CompleteAsync();
} }
try { await channel.SendMessageAsync($"⏰ I will remind **\"{(ch is ITextChannel ? ((ITextChannel)ch).Name : umsg.Author.Username)}\"** to **\"{message.SanitizeMentions()}\"** in **{output}** `({time:d.M.yyyy.} at {time:HH:mm})`").ConfigureAwait(false); } catch { } try { await channel.SendConfirmAsync($"⏰ I will remind **\"{(ch is ITextChannel ? ((ITextChannel)ch).Name : umsg.Author.Username)}\"** to **\"{message.SanitizeMentions()}\"** in **{output}** `({time:d.M.yyyy.} at {time:HH:mm})`").ConfigureAwait(false); } catch { }
await StartReminder(rem); await StartReminder(rem);
} }
@ -206,7 +206,7 @@ namespace NadekoBot.Modules.Utility
uow.BotConfig.GetOrCreate().RemindMessageFormat = arg.Trim(); uow.BotConfig.GetOrCreate().RemindMessageFormat = arg.Trim();
await uow.CompleteAsync().ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false);
} }
await channel.SendMessageAsync("🆗 New remind template set."); await channel.SendConfirmAsync("🆗 New remind template set.");
} }
} }
} }

View File

@ -25,7 +25,7 @@ namespace NadekoBot.Modules.Utility
{ {
public static List<ConvertUnit> Units { get; set; } = new List<ConvertUnit>(); public static List<ConvertUnit> Units { get; set; } = new List<ConvertUnit>();
private static Logger _log; private static Logger _log { get; }
private static Timer _timer; private static Timer _timer;
private static TimeSpan updateInterval = new TimeSpan(12, 0, 0); private static TimeSpan updateInterval = new TimeSpan(12, 0, 0);
@ -104,15 +104,14 @@ namespace NadekoBot.Modules.Utility
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task ConvertList(IUserMessage msg) public async Task ConvertList(IUserMessage msg)
{ {
var sb = new StringBuilder("Units that can be used by the converter: \n"); var res = Units.GroupBy(x => x.UnitType)
var res = Units.GroupBy(x => x.UnitType); .Aggregate(new EmbedBuilder().WithTitle("__Units which can be used by the converter__")
foreach (var group in res) .WithColor(NadekoBot.OkColor),
{ (embed, g) => embed.AddField(efb =>
sb.AppendLine($"{group.Key}: ```xl"); efb.WithName(g.Key.ToTitleCase())
sb.AppendLine(string.Join(",", group.Select(x => x.Triggers.FirstOrDefault()).OrderBy(x => x))); .WithValue(String.Join(", ", g.Select(x => x.Triggers.FirstOrDefault())
sb.AppendLine("```"); .OrderBy(x => x)))));
} await msg.Channel.EmbedAsync(res.Build());
await msg.ReplyLong(sb.ToString(), breakOn: new[] { "```xl\n", "\n" });
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Convert(IUserMessage msg, string origin, string target, decimal value) public async Task Convert(IUserMessage msg, string origin, string target, decimal value)
@ -121,12 +120,12 @@ namespace NadekoBot.Modules.Utility
var targetUnit = Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(target.ToLowerInvariant())); var targetUnit = Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(target.ToLowerInvariant()));
if (originUnit == null || targetUnit == null) if (originUnit == null || targetUnit == null)
{ {
await msg.Reply(string.Format("Cannot convert {0} to {1}: units not found", origin, target)); await msg.Channel.SendErrorAsync(string.Format("Cannot convert {0} to {1}: units not found", origin, target));
return; return;
} }
if (originUnit.UnitType != targetUnit.UnitType) if (originUnit.UnitType != targetUnit.UnitType)
{ {
await msg.Reply(string.Format("Cannot convert {0} to {1}: types of unit are not equal", originUnit.Triggers.First(), targetUnit.Triggers.First())); await msg.Channel.SendErrorAsync(string.Format("Cannot convert {0} to {1}: types of unit are not equal", originUnit.Triggers.First(), targetUnit.Triggers.First()));
return; return;
} }
decimal res; decimal res;
@ -170,7 +169,7 @@ namespace NadekoBot.Modules.Utility
} }
res = Math.Round(res, 4); res = Math.Round(res, 4);
await msg.Reply(string.Format("{0} {1} is equal to {2} {3}", value, (originUnit.Triggers.First() + "s").SnPl(value.IsInteger() ? (int)value : 2), res, (targetUnit.Triggers.First() + "s").SnPl(res.IsInteger() ? (int)res : 2))); await msg.Channel.SendConfirmAsync(string.Format("{0} {1} is equal to {2} {3}", value, (originUnit.Triggers.First() + "s").SnPl(value.IsInteger() ? (int)value : 2), res, (targetUnit.Triggers.First() + "s").SnPl(res.IsInteger() ? (int)res : 2)));
} }
} }

View File

@ -22,7 +22,7 @@ namespace NadekoBot.Modules.Utility
[NadekoModule("Utility", ".")] [NadekoModule("Utility", ".")]
public partial class Utility : DiscordModule public partial class Utility : DiscordModule
{ {
public Utility(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public Utility() : base()
{ {
} }
@ -44,7 +44,9 @@ namespace NadekoBot.Modules.Utility
if (!arr.Any()) if (!arr.Any())
await channel.SendErrorAsync("Nobody is playing that game.").ConfigureAwait(false); await channel.SendErrorAsync("Nobody is playing that game.").ConfigureAwait(false);
else else
await channel.SendMessageAsync("```css\n" + string.Join("\n", arr.GroupBy(item => (i++) / 3).Select(ig => string.Concat(ig.Select(el => $"• {el,-35}")))) + "\n```").ConfigureAwait(false); await channel.SendConfirmAsync("```css\n" + string.Join("\n", arr.GroupBy(item => (i++) / 2)
.Select(ig => string.Concat(ig.Select(el => $"• {el,-27}")))) + "\n```")
.ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -55,7 +57,7 @@ namespace NadekoBot.Modules.Utility
return; return;
var channel = (ITextChannel)umsg.Channel; var channel = (ITextChannel)umsg.Channel;
var arg = roles.Split(',').Select(r => r.Trim().ToUpperInvariant()); var arg = roles.Split(',').Select(r => r.Trim().ToUpperInvariant());
string send = _l[" **Here is a list of users in a specfic role:**"]; string send = " **Here is a list of users in those roles:**";
foreach (var roleStr in arg.Where(str => !string.IsNullOrWhiteSpace(str) && str != "@EVERYONE" && str != "EVERYONE")) foreach (var roleStr in arg.Where(str => !string.IsNullOrWhiteSpace(str) && str != "@EVERYONE" && str != "EVERYONE"))
{ {
var role = channel.Guild.Roles.Where(r => r.Name.ToUpperInvariant() == roleStr).FirstOrDefault(); var role = channel.Guild.Roles.Where(r => r.Name.ToUpperInvariant() == roleStr).FirstOrDefault();
@ -69,16 +71,16 @@ namespace NadekoBot.Modules.Utility
{ {
if (!usr.GetPermissions(channel).ManageMessages) if (!usr.GetPermissions(channel).ManageMessages)
{ {
await channel.SendMessageAsync($"⚠️ {usr.Mention} **you are not allowed to use this command on roles with a lot of users in them to prevent abuse.**").ConfigureAwait(false); await channel.SendErrorAsync($"⚠️ {usr.Mention} **you are not allowed to use this command on roles with a lot of users in them to prevent abuse.**").ConfigureAwait(false);
return; return;
} }
var curstr = send.Substring(0, 2000); var curstr = send.Substring(0, 2000);
await channel.SendMessageAsync(curstr.Substring(0, await channel.SendConfirmAsync(curstr.Substring(0,
curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1)).ConfigureAwait(false); curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1)).ConfigureAwait(false);
send = curstr.Substring(curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1) + send = curstr.Substring(curstr.LastIndexOf(", ", StringComparison.Ordinal) + 1) +
send.Substring(2000); send.Substring(2000);
} }
await channel.SendMessageAsync(send).ConfigureAwait(false); await channel.SendConfirmAsync(send).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -95,7 +97,7 @@ namespace NadekoBot.Modules.Utility
} }
builder.Append("```"); builder.Append("```");
await msg.Reply(builder.ToString()); await msg.Channel.SendConfirmAsync(builder.ToString());
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -103,20 +105,20 @@ namespace NadekoBot.Modules.Utility
public async Task UserId(IUserMessage msg, IGuildUser target = null) public async Task UserId(IUserMessage msg, IGuildUser target = null)
{ {
var usr = target ?? msg.Author; var usr = target ?? msg.Author;
await msg.Reply($"🆔 of the user **{ usr.Username }** is `{ usr.Id }`").ConfigureAwait(false); await msg.Channel.SendConfirmAsync($"🆔 of the user **{ usr.Username }** is `{ usr.Id }`").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task ChannelId(IUserMessage msg) public async Task ChannelId(IUserMessage msg)
{ {
await msg.Reply($" This **Channel's ID** is `{msg.Channel.Id}`").ConfigureAwait(false); await msg.Channel.SendConfirmAsync($"🆔 of this channel is `{msg.Channel.Id}`").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task ServerId(IUserMessage msg) public async Task ServerId(IUserMessage msg)
{ {
await msg.Reply($" This **Server's ID** is `{((ITextChannel)msg.Channel).Guild.Id}`").ConfigureAwait(false); await msg.Channel.SendConfirmAsync($"🆔 of this server is `{((ITextChannel)msg.Channel).Guild.Id}`").ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -132,11 +134,11 @@ namespace NadekoBot.Modules.Utility
return; return;
if (target != null) if (target != null)
{ {
await msg.Reply($"⚔ **Page #{page} of roles for {target.Username}:** ```css\n• " + string.Join("\n• ", target.Roles.Except(new[] { guild.EveryoneRole }).OrderBy(r => r.Position).Skip((page - 1) * RolesPerPage).Take(RolesPerPage)).SanitizeMentions() + "\n```"); await channel.SendConfirmAsync($"⚔ **Page #{page} of roles for {target.Username}**", $"```css\n• " + string.Join("\n• ", target.Roles.Except(new[] { guild.EveryoneRole }).OrderBy(r => -r.Position).Skip((page - 1) * RolesPerPage).Take(RolesPerPage)).SanitizeMentions() + "\n```");
} }
else else
{ {
await msg.Reply($"⚔ **Page #{page} of all roles on this server:** ```css\n• " + string.Join("\n• ", guild.Roles.Except(new[] { guild.EveryoneRole }).OrderBy(r => r.Position).Skip((page - 1) * RolesPerPage).Take(RolesPerPage)).SanitizeMentions() + "\n```"); await channel.SendConfirmAsync($"⚔ **Page #{page} of all roles on this server:**", $"```css\n• " + string.Join("\n• ", guild.Roles.Except(new[] { guild.EveryoneRole }).OrderBy(r => -r.Position).Skip((page - 1) * RolesPerPage).Take(RolesPerPage)).SanitizeMentions() + "\n```");
} }
} }
@ -153,9 +155,9 @@ namespace NadekoBot.Modules.Utility
var topic = channel.Topic; var topic = channel.Topic;
if (string.IsNullOrWhiteSpace(topic)) if (string.IsNullOrWhiteSpace(topic))
await channel.SendMessageAsync("❎ **No topic set.**"); await channel.SendErrorAsync("No topic set.");
else else
await channel.SendMessageAsync(" **Topic:** " + topic); await channel.SendConfirmAsync("Channel topic", topic);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -235,6 +237,9 @@ namespace NadekoBot.Modules.Utility
var result = string.Join("\n", matches.Cast<Match>() var result = string.Join("\n", matches.Cast<Match>()
.Select(m => $"**Name:** {m.Groups["name"]} **Link:** http://discordapp.com/api/emojis/{m.Groups["id"]}.png")); .Select(m => $"**Name:** {m.Groups["name"]} **Link:** http://discordapp.com/api/emojis/{m.Groups["id"]}.png"));
if (string.IsNullOrWhiteSpace(result))
await msg.Channel.SendErrorAsync("No special emojis found.");
else
await msg.Channel.SendMessageAsync(result).ConfigureAwait(false); await msg.Channel.SendMessageAsync(result).ConfigureAwait(false);
} }
@ -254,42 +259,16 @@ namespace NadekoBot.Modules.Utility
if (!guilds.Any()) if (!guilds.Any())
{ {
await channel.SendMessageAsync("❎ No servers found on that page.").ConfigureAwait(false); await channel.SendErrorAsync("No servers found on that page.").ConfigureAwait(false);
return; return;
} }
await channel.SendMessageAsync(String.Join("\n", guilds.Select(g => $"```css\nName: {g.Name} ID:{g.Id} Members:#{g.GetUsers().Count} OwnerID: {g.OwnerId} ```"))).ConfigureAwait(false); await channel.EmbedAsync(guilds.Aggregate(new EmbedBuilder().WithColor(NadekoBot.OkColor),
(embed, g) => embed.AddField(efb => efb.WithName(g.Name)
.WithValue($"```css\nID: {g.Id}\nMembers: {g.GetUsers().Count}\nOwnerID: {g.OwnerId} ```")
.WithIsInline(false)))
.Build())
.ConfigureAwait(false);
} }
//[NadekoCommand, Usage, Description, Aliases]
//[RequireContext(ContextType.Guild)]
//public async Task TextToImage(IUserMessage msg, [Remainder] string arg)
//{
// var channel = (ITextChannel)msg.Channel;
// const string bgName = "xbiy3";
// if (string.IsNullOrWhiteSpace(arg))
// return;
// using (var http = new HttpClient())
// {
// http.AddFakeHeaders();
// http.DefaultRequestHeaders.Add("Host", "www.tagsmaker.com");
// http.DefaultRequestHeaders.Add("Referer", "http://www.tagsmaker.com/");
// http.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
// http.DefaultRequestHeaders.Add("Alt-Used", "www.tagsmaker.com:443");
// var res = await http.GetAsync($"http://www.tagsmaker.com/tagsmaker.php?background_name=0011&tag_text={arg}&font_name=applejuiced&text_color=white&text_size=48&text_alignment=middle").ConfigureAwait(false);
// var img = res.RequestMessage.RequestUri.Segments[1].Replace("image-", "").Replace("tag-", "");
// var imgStream = await http.GetStreamAsync($"http://www.tagsmaker.com/upload/www.tagsmaker.com_{ img.ToString() }.png");
// var ms = new MemoryStream();
// await imgStream.CopyToAsync(ms).ConfigureAwait(false);
// ms.Position = 0;
// await channel.SendFileAsync(ms, arg+".png", "Provided by www.tagsmaker.com").ConfigureAwait(false);
// }
//}
} }
} }

View File

@ -30,7 +30,6 @@ namespace NadekoBot
public static CommandService CommandService { get; private set; } public static CommandService CommandService { get; private set; }
public static CommandHandler CommandHandler { get; private set; } public static CommandHandler CommandHandler { get; private set; }
public static ShardedDiscordClient Client { get; private set; } public static ShardedDiscordClient Client { get; private set; }
public static Localization Localizer { get; private set; }
public static BotCredentials Credentials { get; private set; } public static BotCredentials Credentials { get; private set; }
public static GoogleApiService Google { get; private set; } public static GoogleApiService Google { get; private set; }
@ -70,17 +69,16 @@ namespace NadekoBot
//initialize Services //initialize Services
CommandService = new CommandService(); CommandService = new CommandService();
Localizer = new Localization();
Google = new GoogleApiService(); Google = new GoogleApiService();
CommandHandler = new CommandHandler(Client, CommandService); CommandHandler = new CommandHandler(Client, CommandService);
Stats = new StatsService(Client, CommandHandler); Stats = new StatsService(Client, CommandHandler);
//setup DI ////setup DI
var depMap = new DependencyMap(); //var depMap = new DependencyMap();
depMap.Add<ILocalization>(Localizer); //depMap.Add<ILocalization>(Localizer);
depMap.Add<ShardedDiscordClient>(Client); //depMap.Add<ShardedDiscordClient>(Client);
depMap.Add<CommandService>(CommandService); //depMap.Add<CommandService>(CommandService);
depMap.Add<IGoogleApiService>(Google); //depMap.Add<IGoogleApiService>(Google);
//setup typereaders //setup typereaders
@ -104,9 +102,9 @@ namespace NadekoBot
// start handling messages received in commandhandler // start handling messages received in commandhandler
await CommandHandler.StartHandling().ConfigureAwait(false); await CommandHandler.StartHandling().ConfigureAwait(false);
await CommandService.LoadAssembly(this.GetType().GetTypeInfo().Assembly, depMap).ConfigureAwait(false); await CommandService.LoadAssembly(this.GetType().GetTypeInfo().Assembly).ConfigureAwait(false);
#if !GLOBAL_NADEKO #if !GLOBAL_NADEKO
await CommandService.Load(new Music(Localizer, CommandService, Client, Google)).ConfigureAwait(false); await CommandService.Load(new Music()).ConfigureAwait(false);
#endif #endif
Ready = true; Ready = true;
Console.WriteLine(await Stats.Print().ConfigureAwait(false)); Console.WriteLine(await Stats.Print().ConfigureAwait(false));

View File

@ -788,60 +788,6 @@ namespace NadekoBot.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to bfonline bfo.
/// </summary>
public static string bfo_cmd {
get {
return ResourceManager.GetString("bfo_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Gives you online players for BF3 and BF4.
/// </summary>
public static string bfo_desc {
get {
return ResourceManager.GetString("bfo_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}bfo bf3` or `{0}bfo bf4`.
/// </summary>
public static string bfo_usage {
get {
return ResourceManager.GetString("bfo_usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to bfuser bfu.
/// </summary>
public static string bfu_cmd {
get {
return ResourceManager.GetString("bfu_cmd", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Gives you back a battlefield user&apos;s stats..
/// </summary>
public static string bfu_desc {
get {
return ResourceManager.GetString("bfu_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `{0}bfu platform game user`.
/// </summary>
public static string bfu_usage {
get {
return ResourceManager.GetString("bfu_usage", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to boobs. /// Looks up a localized string similar to boobs.
/// </summary> /// </summary>

View File

@ -2673,24 +2673,6 @@
<data name="wikia_usage" xml:space="preserve"> <data name="wikia_usage" xml:space="preserve">
<value>`{0}wikia mtg Vigilance` or `{0}wikia mlp Dashy`</value> <value>`{0}wikia mtg Vigilance` or `{0}wikia mlp Dashy`</value>
</data> </data>
<data name="bfo_cmd" xml:space="preserve">
<value>bfonline bfo</value>
</data>
<data name="bfo_desc" xml:space="preserve">
<value>Gives you online players for BF3 and BF4</value>
</data>
<data name="bfo_usage" xml:space="preserve">
<value>`{0}bfo bf3` or `{0}bfo bf4`</value>
</data>
<data name="bfu_cmd" xml:space="preserve">
<value>bfuser bfu</value>
</data>
<data name="bfu_desc" xml:space="preserve">
<value>Gives you back a battlefield user's stats.</value>
</data>
<data name="bfu_usage" xml:space="preserve">
<value>`{0}bfu platform game user`</value>
</data>
<data name="yandere_cmd" xml:space="preserve"> <data name="yandere_cmd" xml:space="preserve">
<value>yandere</value> <value>yandere</value>
</data> </data>

View File

@ -39,7 +39,7 @@ namespace NadekoBot.Services
private List<IDMChannel> ownerChannels { get; set; } private List<IDMChannel> ownerChannels { get; set; }
public event EventHandler<CommandExecutedEventArgs> CommandExecuted = delegate { }; public event Func<IUserMessage,Command, Task> CommandExecuted = delegate { return Task.CompletedTask; };
public CommandHandler(ShardedDiscordClient client, CommandService commandService) public CommandHandler(ShardedDiscordClient client, CommandService commandService)
{ {
@ -154,7 +154,7 @@ namespace NadekoBot.Services
var channel = (usrMsg.Channel as ITextChannel); var channel = (usrMsg.Channel as ITextChannel);
if (result.IsSuccess) if (result.IsSuccess)
{ {
CommandExecuted(this, new CommandExecutedEventArgs(usrMsg, command)); await CommandExecuted(usrMsg, command);
_log.Info("Command Executed after {4}s\n\t" + _log.Info("Command Executed after {4}s\n\t" +
"User: {0}\n\t" + "User: {0}\n\t" +
"Server: {1}\n\t" + "Server: {1}\n\t" +

View File

@ -1,7 +0,0 @@
namespace NadekoBot.Services
{
public interface ILocalization
{
string this[string key] { get; }
}
}

View File

@ -1,6 +1,6 @@
namespace NadekoBot.Services namespace NadekoBot.Services
{ {
public class Localization : ILocalization public class Localization
{ {
public string this[string key] => LoadCommandString(key); public string this[string key] => LoadCommandString(key);

View File

@ -38,7 +38,7 @@ namespace NadekoBot.Services.Impl
Reset(); Reset();
this.client.MessageReceived += _ => Task.FromResult(MessageCounter++); this.client.MessageReceived += _ => Task.FromResult(MessageCounter++);
cmdHandler.CommandExecuted += (_, e) => CommandsRan++; cmdHandler.CommandExecuted += (_, e) => Task.FromResult(CommandsRan++);
this.client.Disconnected += _ => Reset(); this.client.Disconnected += _ => Reset();

View File

@ -13,20 +13,20 @@ namespace NadekoBot
private DiscordSocketConfig discordSocketConfig; private DiscordSocketConfig discordSocketConfig;
private Logger _log { get; } private Logger _log { get; }
public Func<IGuildUser, Task> UserJoined { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<IGuildUser, Task> UserJoined = delegate { return Task.CompletedTask; };
public Func<IMessage, Task> MessageReceived { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<IMessage, Task> MessageReceived = delegate { return Task.CompletedTask; };
public Func<IGuildUser, Task> UserLeft { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<IGuildUser, Task> UserLeft = delegate { return Task.CompletedTask; };
public Func<IGuildUser, IGuildUser, Task> UserUpdated { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<IGuildUser, IGuildUser, Task> UserUpdated = delegate { return Task.CompletedTask; };
public Func<Optional<IMessage>, IMessage, Task> MessageUpdated { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<Optional<IMessage>, IMessage, Task> MessageUpdated = delegate { return Task.CompletedTask; };
public Func<ulong, Optional<IMessage>, Task> MessageDeleted { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<ulong, Optional<IMessage>, Task> MessageDeleted = delegate { return Task.CompletedTask; };
public Func<IUser, IGuild, Task> UserBanned { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<IUser, IGuild, Task> UserBanned = delegate { return Task.CompletedTask; };
public Func<IUser, IGuild, Task> UserUnbanned { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<IUser, IGuild, Task> UserUnbanned = delegate { return Task.CompletedTask; };
public Func<IGuildUser, IPresence, IPresence, Task> UserPresenceUpdated { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<IGuildUser, IPresence, IPresence, Task> UserPresenceUpdated = delegate { return Task.CompletedTask; };
public Func<IUser, IVoiceState, IVoiceState, Task> UserVoiceStateUpdated { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<IUser, IVoiceState, IVoiceState, Task> UserVoiceStateUpdated = delegate { return Task.CompletedTask; };
public Func<IChannel, Task> ChannelCreated { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<IChannel, Task> ChannelCreated = delegate { return Task.CompletedTask; };
public Func<IChannel, Task> ChannelDestroyed { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<IChannel, Task> ChannelDestroyed = delegate { return Task.CompletedTask; };
public Func<IChannel, IChannel, Task> ChannelUpdated { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<IChannel, IChannel, Task> ChannelUpdated = delegate { return Task.CompletedTask; };
public Func<Exception, Task> Disconnected { get; internal set; } = delegate { return Task.CompletedTask; }; public event Func<Exception, Task> Disconnected = delegate { return Task.CompletedTask; };
private IReadOnlyList<DiscordSocketClient> Clients { get; } private IReadOnlyList<DiscordSocketClient> Clients { get; }

View File

@ -74,94 +74,27 @@ namespace NadekoBot.Extensions
public static async Task<IUserMessage> SendFileAsync(this IGuildUser user, Stream fileStream, string fileName, string caption = null, bool isTTS = false) => public static async Task<IUserMessage> SendFileAsync(this IGuildUser user, Stream fileStream, string fileName, string caption = null, bool isTTS = false) =>
await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(fileStream, fileName, caption, isTTS).ConfigureAwait(false); await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(fileStream, fileName, caption, isTTS).ConfigureAwait(false);
public static async Task<IUserMessage> Reply(this IUserMessage msg, string content) =>
await msg.Channel.SendMessageAsync(content).ConfigureAwait(false);
public static bool IsAuthor(this IUserMessage msg) => public static bool IsAuthor(this IUserMessage msg) =>
NadekoBot.Client.GetCurrentUser().Id == msg.Author.Id; NadekoBot.Client.GetCurrentUser().Id == msg.Author.Id;
public static IEnumerable<IUser> Members(this IRole role) => public static IEnumerable<IUser> Members(this IRole role) =>
NadekoBot.Client.GetGuild(role.GuildId)?.GetUsers().Where(u => u.Roles.Contains(role)) ?? Enumerable.Empty<IUser>(); NadekoBot.Client.GetGuild(role.GuildId)?.GetUsers().Where(u => u.Roles.Contains(role)) ?? Enumerable.Empty<IUser>();
public static async Task<IUserMessage[]> ReplyLong(this IUserMessage msg, string content, string[] breakOn = null, string addToPartialEnd = "", string addToPartialStart = "")
{
if (content.Length == 0) return null;
var characterLimit = 1750;
if (content.Length < characterLimit) return new[] { await msg.Channel.SendMessageAsync(content).ConfigureAwait(false) };
if (breakOn == null) breakOn = new[] { "\n", " ", " " };
var list = new List<IUserMessage>();
var splitItems = new List<string>();
foreach (var breaker in breakOn)
{
if (splitItems.Count == 0)
{
splitItems = Regex.Split(content, $"(?={breaker})").Where(s => !string.IsNullOrWhiteSpace(s)).ToList();
}
else
{
for (int i = 0; i < splitItems.Count; i++)
{
var temp = splitItems[i];
if (temp.Length > characterLimit)
{
var splitDeep = Regex.Split(temp, $"(?={breaker})").Where(s => !string.IsNullOrWhiteSpace(s));
splitItems.RemoveAt(i);
splitItems.InsertRange(i, splitDeep);
}
}
}
if (splitItems.All(s => s.Length < characterLimit)) break;
}
//We remove any entries that are larger than 2000 chars
if (splitItems.Any(s => s.Length >= characterLimit))
{
splitItems = splitItems.Where(s => s.Length < characterLimit).ToList();
}
//ensured every item can be sent (if individually)
var firstItem = true;
Queue<string> buildItems = new Queue<string>(splitItems);
StringBuilder builder = new StringBuilder();
while (buildItems.Count > 0)
{
if (builder.Length == 0)
{
//first item to add
if (!firstItem)
builder.Append(addToPartialStart);
else
firstItem = false;
builder.Append(buildItems.Dequeue());
}
else
{
builder.Append(buildItems.Dequeue());
}
if (buildItems.Count == 0)
{
list.Add(await msg.Channel.SendMessageAsync(builder.ToString()));
builder.Clear();
}
else
{
var peeked = buildItems.Peek();
if (builder.Length + peeked.Length + addToPartialEnd.Length > characterLimit)
{
builder.Append(addToPartialEnd);
list.Add(await msg.Channel.SendMessageAsync(builder.ToString()));
builder.Clear();
}
}
}
return list.ToArray();
}
public static Task<IUserMessage> EmbedAsync(this IMessageChannel ch, Discord.API.Embed embed, string msg = "") public static Task<IUserMessage> EmbedAsync(this IMessageChannel ch, Discord.API.Embed embed, string msg = "")
=> ch.SendMessageAsync(msg, embed: embed); => ch.SendMessageAsync(msg, embed: embed);
public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string error, string title = null, string url = null) public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string title, string error, string url = null)
=> ch.SendMessageAsync("", embed: new Embed() { Description = error, Title = title, Url = url, Color = NadekoBot.ErrorColor }); => ch.SendMessageAsync("", embed: new Embed() { Description = error, Title = title, Url = url, Color = NadekoBot.ErrorColor });
public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string error)
=> ch.SendMessageAsync("", embed: new Embed() { Description = error, Color = NadekoBot.ErrorColor });
public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, string title, string text, string url = null)
=> ch.SendMessageAsync("", embed: new Embed() { Description = text, Title = title, Url = url, Color = NadekoBot.OkColor });
public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, string text)
=> ch.SendMessageAsync("", embed: new Embed() { Description = text, Color = NadekoBot.OkColor });
public static Task<IUserMessage> SendTableAsync<T>(this IMessageChannel ch, string seed, IEnumerable<T> items, Func<T, string> howToPrint, int columns = 3) public static Task<IUserMessage> SendTableAsync<T>(this IMessageChannel ch, string seed, IEnumerable<T> items, Func<T, string> howToPrint, int columns = 3)
{ {
var i = 0; var i = 0;

View File

@ -60,8 +60,11 @@
}, },
"configurations": { "configurations": {
"GlobalNadeko": { "GlobalNadeko": {
"buildOptions": { "define": [ "GLOBAL_NADEKO" ] }, "buildOptions": {
"compilationOptions": { "optimize": true } "define": [ "GLOBAL_NADEKO" ],
"nowarn": [ "CS1573", "CS1591" ],
"optimize": true
}
} }
} }
} }