trivia, help module converted

This commit is contained in:
Kwoth 2016-08-16 16:53:38 +02:00
parent 915153cd0a
commit dcddd5bbe8
46 changed files with 346 additions and 1920 deletions

15
.gitignore vendored
View File

@ -10,21 +10,6 @@
obj/
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
**/Bin/Release/
**/Bin/PRIVATE/
!**/Bin/Debug/opus.dll
!**/Bin/Debug/libsodium.dll
!**/Bin/Debug/Nito.AsyncEx.Enlightenment.dll
!**/Bin/Debug/Nito.AsyncEx.dll
!**/Bin/Debug/WebSocket4Net.dll
!**/Bin/Debug/sqlite3.dll
!**/Bin/Debug/credentials_example.json
NadekoBot/bin/debug/*.*
NadekoBot/bin/debug/data/permissions
NadekoBot/bin/debug/data/incidents
NadekoBot/bin/debug/data/musicdata
NadekoBot/bin/NadekoRelease/*.*
!NadekoBot/bin/Debug/data/currency_images/*
Tests/bin
# NuGet Packages

View File

@ -1,10 +1,6 @@
using Discord.Commands;
using NadekoBot.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace NadekoBot.Attributes
{

View File

@ -1,10 +1,6 @@
using Discord.Commands;
using NadekoBot.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace NadekoBot.Attributes
{

View File

@ -1,10 +1,6 @@
using Discord.Commands;
using NadekoBot.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace NadekoBot.Attributes
{

View File

@ -1,10 +1,6 @@
using Discord;
using Discord.Commands;
using NadekoBot.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Modules
{

View File

@ -1,7 +1,6 @@
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Classes;
using NadekoBot.Extensions;
using System.Text;
using System.Threading.Tasks;

View File

@ -1,7 +1,6 @@
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Classes;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;

View File

@ -1,6 +1,4 @@
using Discord;
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Extensions;
using System.Collections.Concurrent;
using System.Collections.Generic;

View File

@ -1,7 +1,6 @@
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Classes;
using NadekoBot.Modules.Games.Commands.Trivia;
using System;
using System.Collections.Concurrent;

View File

@ -0,0 +1,140 @@
using Discord.Commands;
using NadekoBot.Extensions;
using System.Linq;
using Discord;
using NadekoBot.Services;
using System.Threading.Tasks;
using NadekoBot.Attributes;
using System;
using System.IO;
using System.Text;
namespace NadekoBot.Modules.Help
{
[Module("-", AppendSpace = false)]
public partial class HelpModule : DiscordModule
{
public string HelpString {
get {
var str = "To add me to your server, use this link -> <https://discordapp.com/oauth2/authorize?client_id={0}&scope=bot&permissions=66186303>\n";
return str + String.Format(str, NadekoBot.Credentials.ClientId);
}
}
public HelpModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client)
{
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Modules(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
await imsg.Channel.SendMessageAsync("`List of modules:` \n• " + string.Join("\n• ", _commands.Modules.Select(m => m.Name)) + $"\n`Type \"-commands module_name\" to get a list of commands in that module.`")
.ConfigureAwait(false);
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Commands(IMessage imsg, [Remainder] string module)
{
var channel = imsg.Channel as IGuildChannel;
module = module?.Trim().ToUpperInvariant();
if (string.IsNullOrWhiteSpace(module))
return;
var cmds = _commands.Commands.Where(c => c.Module.Name.ToUpperInvariant() == module)
.OrderBy(c => c.Text)
.AsEnumerable();
var cmdsArray = cmds as Command[] ?? cmds.ToArray();
if (!cmdsArray.Any())
{
await imsg.Channel.SendMessageAsync("That module does not exist.").ConfigureAwait(false);
return;
}
if (module != "customreactions" && module != "conversations")
{
//todo aliases
await imsg.Channel.SendTableAsync("`List Of Commands:`\n", cmdsArray, el => $"{el.Text,-15}").ConfigureAwait(false);
}
else
{
await imsg.Channel.SendMessageAsync("`List Of Commands:`\n• " + string.Join("\n• ", cmdsArray.Select(c => $"{c.Text}")));
}
await imsg.Channel.SendMessageAsync($"`You can type \"-h command_name\" to see the help about that specific command.`").ConfigureAwait(false);
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Help(IMessage imsg, [Remainder] string comToFind)
{
var channel = imsg.Channel as IGuildChannel;
comToFind = comToFind?.ToLowerInvariant();
if (string.IsNullOrWhiteSpace(comToFind))
{
await (await (imsg.Author as IGuildUser).CreateDMChannelAsync()).SendMessageAsync(HelpString).ConfigureAwait(false);
return;
}
var com = _commands.Commands.FirstOrDefault(c => c.Text.ToLowerInvariant() == comToFind);
//todo aliases
if (com != null)
await imsg.Channel.SendMessageAsync($@"**__Help for:__ `{com.Text}`**
**Desc:** {com.Description}
**Usage:** {com.Summary}").ConfigureAwait(false);
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Hgit(IMessage imsg)
{
var helpstr = new StringBuilder();
var lastModule = "";
foreach (var com in _commands.Commands)
{
if (com.Module.Name != lastModule)
{
helpstr.AppendLine("\n### " + com.Module.Name + " ");
helpstr.AppendLine("Command and aliases | Description | Usage");
helpstr.AppendLine("----------------|--------------|-------");
lastModule = com.Module.Name;
}
//todo aliases
helpstr.AppendLine($"`{com.Text}` | {com.Description} | {com.Summary}");
}
helpstr = helpstr.Replace((await NadekoBot.Client.GetCurrentUserAsync()).Username , "@BotName");
#if DEBUG
File.WriteAllText("../../../docs/Commands List.md", helpstr.ToString());
#else
File.WriteAllText("commandlist.md", helpstr.ToString());
#endif
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Guide(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
await imsg.Channel.SendMessageAsync(
@"**LIST OF COMMANDS**: <http://nadekobot.readthedocs.io/en/latest/Commands%20List/>
**Hosting Guides and docs can be found here**: <http://nadekobot.rtfd.io>").ConfigureAwait(false);
}
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Donate(IMessage imsg)
{
var channel = imsg.Channel as IGuildChannel;
await imsg.Channel.SendMessageAsync(
$@"You can support the project on patreon. <https://patreon.com/nadekobot> or
You can send donations to `nadekodiscordbot@gmail.com`
Don't forget to leave your discord name or id in the message.
**Thank you** ").ConfigureAwait(false);
}
}
}

View File

@ -8,7 +8,6 @@ using System.Threading.Tasks;
using NadekoBot.Services;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Xml.Linq;
namespace NadekoBot.Modules.NSFW
@ -16,9 +15,6 @@ namespace NadekoBot.Modules.NSFW
[Module("~", AppendSpace = false)]
public class NSFWModule : DiscordModule
{
private readonly Random rng = new Random();
public NSFWModule(ILocalization loc, CommandService cmds, IBotConfiguration config, IDiscordClient client) : base(loc, cmds, config, client)
{
}
@ -117,7 +113,7 @@ namespace NadekoBot.Modules.NSFW
JToken obj;
using (var http = new HttpClient())
{
obj = JArray.Parse(await http.GetStringAsync($"http://api.oboobs.ru/boobs/{rng.Next(0, 9380)}").ConfigureAwait(false))[0];
obj = JArray.Parse(await http.GetStringAsync($"http://api.oboobs.ru/boobs/{ new Random().Next(0, 9880) }").ConfigureAwait(false))[0];
}
await imsg.Channel.SendMessageAsync($"http://media.oboobs.ru/{ obj["preview"].ToString() }").ConfigureAwait(false);
}
@ -138,7 +134,7 @@ namespace NadekoBot.Modules.NSFW
JToken obj;
using (var http = new HttpClient())
{
obj = JArray.Parse(await http.GetStringAsync($"http://api.obutts.ru/butts/{rng.Next(0, 3373)}").ConfigureAwait(false))[0];
obj = JArray.Parse(await http.GetStringAsync($"http://api.obutts.ru/butts/{ new Random().Next(0, 3873) }").ConfigureAwait(false))[0];
}
await imsg.Channel.SendMessageAsync($"http://media.obutts.ru/{ obj["preview"].ToString() }").ConfigureAwait(false);
}

View File

@ -1,12 +1,8 @@
using NadekoBot.Modules.Searches.Commands.Models;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

View File

@ -1,5 +1,4 @@
using Discord.Commands;
using NadekoBot.Classes;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace NadekoBot.Modules.Searches.Commands.Models
{

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches.Commands.Models
namespace NadekoBot.Modules.Searches.Commands.Models
{
public class WikipediaApiModel
{

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches.Commands.Models
namespace NadekoBot.Modules.Searches.Commands.Models
{
public class WoWJoke
{

View File

@ -4,19 +4,15 @@ using NadekoBot.Modules.Searches.Commands.IMDB;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using NadekoBot.Services;
using System.Threading.Tasks;
using NadekoBot.Attributes;
using NadekoBot.Extensions;
using Discord.API;
using System.Text.RegularExpressions;
using System.Net;
using NadekoBot.Modules.Searches.Commands.Models;
using Google.Apis.YouTube.v3;
namespace NadekoBot.Modules.Searches
{
@ -355,7 +351,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
if (string.IsNullOrWhiteSpace(usrStr))
return;
var usr = (await channel.Guild.GetUsersAsync()).Where(u=>u.Username.ToUpperInvariant() == usrStr).FirstOrDefault();
var usr = (await channel.Guild.GetUsersAsync()).Where(u => u.Username.ToUpperInvariant() == usrStr).FirstOrDefault();
if (usr == null || string.IsNullOrWhiteSpace(usr.AvatarUrl))
return;
@ -496,4 +492,3 @@ $@"🌍 **Weather for** 【{obj["target"]}】
}
}
}

View File

@ -0,0 +1,145 @@
//using Discord.Modules;
//using Manatee.Trello;
//using Manatee.Trello.ManateeJson;
//using NadekoBot.Extensions;
//using NadekoBot.Modules.Permissions.Classes;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Timers;
//using Action = Manatee.Trello.Action;
////todo rewrite
//namespace NadekoBot.Modules.Trello
//{
// internal class TrelloModule : DiscordModule
// {
// private readonly Timer t = new Timer { Interval = 2000 };
// public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Trello;
// public override void Install(ModuleManager manager)
// {
// var client = manager.Client;
// var serializer = new ManateeSerializer();
// TrelloConfiguration.Serializer = serializer;
// TrelloConfiguration.Deserializer = serializer;
// TrelloConfiguration.JsonFactory = new ManateeFactory();
// TrelloConfiguration.RestClientProvider = new Manatee.Trello.WebApi.WebApiClientProvider();
// TrelloAuthorization.Default.AppKey = NadekoBot.Creds.TrelloAppKey;
// //TrelloAuthorization.Default.UserToken = "[your user token]";
// Discord.Channel bound = null;
// Board board = null;
// List<string> last5ActionIDs = null;
// t.Elapsed += async (s, e) =>
// {
// try
// {
// if (board == null || bound == null)
// return; //do nothing if there is no bound board
// board.Refresh();
// var cur5Actions = board.Actions.Take(board.Actions.Count() < 5 ? board.Actions.Count() : 5);
// var cur5ActionsArray = cur5Actions as Action[] ?? cur5Actions.ToArray();
// if (last5ActionIDs == null)
// {
// last5ActionIDs = cur5ActionsArray.Select(a => a.Id).ToList();
// return;
// }
// foreach (var a in cur5ActionsArray.Where(ca => !last5ActionIDs.Contains(ca.Id)))
// {
// await bound.Send("**--TRELLO NOTIFICATION--**\n" + a.ToString()).ConfigureAwait(false);
// }
// last5ActionIDs.Clear();
// last5ActionIDs.AddRange(cur5ActionsArray.Select(a => a.Id));
// }
// catch (Exception ex)
// {
// Console.WriteLine("Timer failed " + ex.ToString());
// }
// };
// manager.CreateCommands("", cgb =>
// {
// cgb.AddCheck(PermissionChecker.Instance);
// cgb.CreateCommand(Prefix + "bind")
// .Description("Bind a trello bot to a single channel. " +
// "You will receive notifications from your board when something is added or edited." +
// $" **Bot Owner Only!**| `{Prefix}bind [board_id]`")
// .Parameter("board_id", Discord.Commands.ParameterType.Required)
// .Do(async e =>
// {
// if (!NadekoBot.IsOwner(e.User.Id)) return;
// if (bound != null) return;
// try
// {
// bound = e.Channel;
// board = new Board(e.GetArg("board_id").Trim());
// board.Refresh();
// await imsg.Channel.SendMessageAsync("Successfully bound to this channel and board " + board.Name);
// t.Start();
// }
// catch (Exception ex)
// {
// Console.WriteLine("Failed to join the board. " + ex.ToString());
// }
// });
// cgb.CreateCommand(Prefix + "unbind")
// .Description($"Unbinds a bot from the channel and board. **Bot Owner Only!**| `{Prefix}unbind`")
// .Do(async e =>
// {
// if (!NadekoBot.IsOwner(e.User.Id)) return;
// if (bound == null || bound != e.Channel) return;
// t.Stop();
// bound = null;
// board = null;
// await imsg.Channel.SendMessageAsync("Successfully unbound trello from this channel.").ConfigureAwait(false);
// });
// cgb.CreateCommand(Prefix + "lists")
// .Alias(Prefix + "list")
// .Description($"Lists all lists, yo ;) **Bot Owner Only!**| `{Prefix}list`")
// .Do(async e =>
// {
// if (!NadekoBot.IsOwner(e.User.Id)) return;
// if (bound == null || board == null || bound != e.Channel) return;
// await imsg.Channel.SendMessageAsync("Lists for a board '" + board.Name + "'\n" + string.Join("\n", board.Lists.Select(l => "**• " + l.ToString() + "**")))
// .ConfigureAwait(false);
// });
// cgb.CreateCommand(Prefix + "cards")
// .Description($"Lists all cards from the supplied list. You can supply either a name or an index. **Bot Owner Only!**| `{Prefix}cards index`")
// .Parameter("list_name", Discord.Commands.ParameterType.Unparsed)
// .Do(async e =>
// {
// if (!NadekoBot.IsOwner(e.User.Id)) return;
// if (bound == null || board == null || bound != e.Channel || e.GetArg("list_name") == null) return;
// int num;
// var success = int.TryParse(e.GetArg("list_name"), out num);
// List list = null;
// if (success && num <= board.Lists.Count() && num > 0)
// list = board.Lists[num - 1];
// else
// list = board.Lists.FirstOrDefault(l => l.Name == e.GetArg("list_name"));
// if (list != null)
// await imsg.Channel.SendMessageAsync("There are " + list.Cards.Count() + " cards in a **" + list.Name + "** list\n" + string.Join("\n", list.Cards.Select(c => "**• " + c.ToString() + "**")))
// .ConfigureAwait(false);
// else
// await imsg.Channel.SendMessageAsync("No such list.")
// .ConfigureAwait(false);
// });
// });
// }
// }
//}

View File

@ -1,11 +1,9 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using NadekoBot.Modules.Utility;
using NadekoBot.Services;
using NadekoBot.Services.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

View File

@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following

View File

@ -2759,6 +2759,33 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Sends a readme and a guide links to the channel..
/// </summary>
public static string guide_desc {
get {
return ResourceManager.GetString("guide_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `-readme` or `-guide`.
/// </summary>
public static string guide_summary {
get {
return ResourceManager.GetString("guide_summary", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to readme.
/// </summary>
public static string guide_text {
get {
return ResourceManager.GetString("guide_text", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Either shows a help for a single command, or PMs you help link if no arguments are specified..
/// </summary>
@ -4892,33 +4919,6 @@ namespace NadekoBot.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Sends a readme and a guide links to the channel..
/// </summary>
public static string readme_desc {
get {
return ResourceManager.GetString("readme_desc", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to `-readme` or `-guide`.
/// </summary>
public static string readme_summary {
get {
return ResourceManager.GetString("readme_summary", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to readme.
/// </summary>
public static string readme_text {
get {
return ResourceManager.GetString("readme_text", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sends a message to you or a channel after certain amount of time. First argument is me/here/&apos;channelname&apos;. Second argument is time in a descending order (mo&gt;w&gt;d&gt;h&gt;m) example: 1w5d3h10m. Third argument is a (multiword)message..
/// </summary>

View File

@ -135,15 +135,6 @@
<data name="hgit_summary" xml:space="preserve">
<value>`-hgit`</value>
</data>
<data name="readme_text" xml:space="preserve">
<value>readme</value>
</data>
<data name="readme_desc" xml:space="preserve">
<value>Sends a readme and a guide links to the channel.</value>
</data>
<data name="readme_summary" xml:space="preserve">
<value>`-readme` or `-guide`</value>
</data>
<data name="donate_text" xml:space="preserve">
<value>donate</value>
</data>
@ -2619,4 +2610,13 @@
<data name="cards_summary" xml:space="preserve">
<value>`trello cards index`</value>
</data>
<data name="guide_desc" xml:space="preserve">
<value>Sends a readme and a guide links to the channel.</value>
</data>
<data name="guide_summary" xml:space="preserve">
<value>`-readme` or `-guide`</value>
</data>
<data name="guide_text" xml:space="preserve">
<value>readme</value>
</data>
</root>

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace NadekoBot.Services
{

View File

@ -1,14 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Services
namespace NadekoBot.Services
{
public interface IBotCredentials
{
string ClientId { get; }
string Token { get; }
string GoogleApiKey { get; }
}
}

View File

@ -1,10 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Services
namespace NadekoBot.Services
{
public interface ILocalization
{

View File

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace NadekoBot.Services

View File

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace NadekoBot.Services.Impl

View File

@ -1,20 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NadekoBot.Services.Impl
{
public class BotCredentials : IBotCredentials
{
public string ClientId { get; }
public string GoogleApiKey {
get {
throw new NotImplementedException();
}
}
public IEnumerable<string> MashapeKey { get; internal set; }
public IEnumerable<string> MashapeKey { get; }
public string Token {
get {

View File

@ -1,9 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Resources;
namespace NadekoBot.Services
{

View File

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Google.Apis.YouTube.v3;
using Google.Apis.Services;

View File

@ -50,15 +50,20 @@ namespace NadekoBot.Extensions
return list.ToArray();
}
public static Task<IMessage> SendTableAsync<T>(this IMessageChannel ch, IEnumerable<T> items, Func<T, string> howToPrint, int columns = 3)
public static Task<IMessage> SendTableAsync<T>(this IMessageChannel ch, string seed, IEnumerable<T> items, Func<T, string> howToPrint, int columns = 3)
{
var i = 0;
return ch.SendMessageAsync($@"```xl
return ch.SendMessageAsync($@"{seed}```xl
{string.Join("\n", items.GroupBy(item => (i++) / columns)
.Select(ig => string.Concat(ig.Select(el => howToPrint(el)))))}
```");
}
public static Task<IMessage> SendTableAsync<T>(this IMessageChannel ch, IEnumerable<T> items, Func<T, string> howToPrint, int columns = 3)
{
return ch.SendTableAsync("", items, howToPrint, columns);
}
public static async Task<string> ShortenUrl(this string url)
{
if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.GoogleApiKey)) return url;

View File

@ -1,127 +0,0 @@
using Discord.Commands;
using NadekoBot.Extensions;
using NadekoBot.Modules;
using NadekoBot.Modules.Permissions.Classes;
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace NadekoBot.Classes.Help.Commands
{
internal class HelpCommand : DiscordCommand
{
public Func<CommandEventArgs, Task> HelpFunc() => async e =>
{
var comToFind = e.GetArg("command")?.ToLowerInvariant();
if (string.IsNullOrWhiteSpace(comToFind))
{
await e.User.Send(HelpString).ConfigureAwait(false);
return;
}
await Task.Run(async () =>
{
var com = NadekoBot.Client.GetService<CommandService>().AllCommands
.FirstOrDefault(c => c.Text.ToLowerInvariant().Equals(comToFind) ||
c.Aliases.Select(a => a.ToLowerInvariant()).Contains(comToFind));
var str = "";
var alias = com.Aliases.FirstOrDefault();
if (alias != null)
str = $" / `{ com.Aliases.FirstOrDefault()}`";
if (com != null)
await imsg.Channel.SendMessageAsync($@"**__Help for:__ `{com.Text}`**" + str + $"\n**Desc:** {new Regex(@"\|").Replace(com.Description, "\n**Usage:**", 1)}").ConfigureAwait(false);
}).ConfigureAwait(false);
};
public static string HelpString {
get {
var str = !string.IsNullOrWhiteSpace(NadekoBot.Creds.ClientId) && !NadekoBot.Config.DontJoinServers
? String.Format("To add me to your server, use this link -> <https://discordapp.com/oauth2/authorize?client_id={0}&scope=bot&permissions=66186303>\n", NadekoBot.Creds.ClientId)
: "";
return str + String.Format(NadekoBot.Config.HelpString, NadekoBot.Config.CommandPrefixes.Help);
}
}
public static string DMHelpString => NadekoBot.Config.DMHelpString;
public Action<CommandEventArgs> DoGitFunc() => e =>
{
string helpstr =
$@"######For more information and how to setup your own NadekoBot, go to: <http://github.com/Kwoth/NadekoBot/wiki>
######You can donate on patreon: <https://patreon.com/nadekobot>
######or paypal: `nadekodiscordbot@gmail.com`
#NadekoBot List Of Commands ";
string lastCategory = "";
foreach (var com in NadekoBot.Client.GetService<CommandService>().AllCommands)
{
if (com.Category != lastCategory)
{
helpstr += "\n### " + com.Category + " \n";
helpstr += "Command and aliases | Description | Usage\n";
helpstr += "----------------|--------------|-------\n";
lastCategory = com.Category;
}
helpstr += PrintCommandHelp(com);
}
helpstr = helpstr.Replace(NadekoBot.BotMention, "@BotName");
helpstr = helpstr.Replace(" |", " | ").Replace("**Usage**:", " | ").Replace("**Description:**", " | ").Replace("\n|", " | \n");
#if DEBUG
File.WriteAllText("../../../commandlist.md", helpstr);
#else
File.WriteAllText("commandlist.md", helpstr);
#endif
};
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "h")
.Alias(Module.Prefix + "help", NadekoBot.BotMention + " help", NadekoBot.BotMention + " h", "~h")
.Description($"Either shows a help for a single command, or PMs you help link if no arguments are specified. | `{Prefix}h !m q` or just `{Prefix}h` ")
.Parameter("command", ParameterType.Unparsed)
.Do(HelpFunc());
cgb.CreateCommand(Module.Prefix + "hgit")
.Description($"Generates the commandlist.md file. **Bot Owner Only!** | `{Prefix}hgit`")
.AddCheck(SimpleCheckers.OwnerOnly())
.Do(DoGitFunc());
cgb.CreateCommand(Module.Prefix + "readme")
.Alias(Module.Prefix + "guide")
.Description($"Sends a readme and a guide links to the channel. | `{Prefix}readme` or `{Prefix}guide`")
.Do(async e =>
await imsg.Channel.SendMessageAsync(
@"**Wiki with all info**: <https://github.com/Kwoth/NadekoBot/wiki>
**WINDOWS SETUP GUIDE**: <https://github.com/Kwoth/NadekoBot/blob/master/ComprehensiveGuide.md>
**LINUX SETUP GUIDE**: <https://github.com/Kwoth/NadekoBot/blob/master/LinuxSetup.md>
**LIST OF COMMANDS**: <https://github.com/Kwoth/NadekoBot/blob/master/commandlist.md>").ConfigureAwait(false));
cgb.CreateCommand(Module.Prefix + "donate")
.Alias("~donate")
.Description($"Instructions for helping the project! | `{Prefix}donate` or `~donate`")
.Do(async e =>
{
await imsg.Channel.SendMessageAsync(
$@"You can support the project on patreon. <https://patreon.com/nadekobot> or
You can send donations to `nadekodiscordbot@gmail.com`
Don't forget to leave your discord name or id in the message.
**Thank you** ").ConfigureAwait(false);
});
}
private static string PrintCommandHelp(Command com)
{
var str = "`" + com.Text + "`";
str = com.Aliases.Aggregate(str, (current, a) => current + (", `" + a + "`"));
str += " **Description:** " + com.Description + "\n";
return str;
}
public HelpCommand(DiscordModule module) : base(module) { }
}
}

View File

@ -1,73 +0,0 @@
using Discord.Commands;
using Discord.Modules;
using NadekoBot.Classes;
using NadekoBot.Classes.Help.Commands;
using NadekoBot.Extensions;
using NadekoBot.Modules.Permissions.Classes;
using System.Linq;
namespace NadekoBot.Modules.Help
{
internal class HelpModule : DiscordModule
{
public HelpModule()
{
commands.Add(new HelpCommand(this));
}
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Help;
public override void Install(ModuleManager manager)
{
manager.CreateCommands("", cgb =>
{
cgb.AddCheck(PermissionChecker.Instance);
commands.ForEach(com => com.Init(cgb));
cgb.CreateCommand(Prefix + "modules")
.Alias(".modules")
.Description($"List all bot modules. | `{Prefix}modules` or `.modules`")
.Do(async e =>
{
await imsg.Channel.SendMessageAsync("`List of modules:` \n• " + string.Join("\n• ", NadekoBot.Client.GetService<ModuleService>().Modules.Select(m => m.Name)) + $"\n`Type \"{Prefix}commands module_name\" to get a list of commands in that module.`")
.ConfigureAwait(false);
});
cgb.CreateCommand(Prefix + "commands")
.Alias(".commands")
.Description($"List all of the bot's commands from a certain module. | `{Prefix}commands` or `.commands`")
.Parameter("module", ParameterType.Unparsed)
.Do(async e =>
{
var module = e.GetArg("module")?.Trim().ToLower();
if (string.IsNullOrWhiteSpace(module))
return;
var cmds = NadekoBot.Client.GetService<CommandService>().AllCommands
.Where(c => c.Category.ToLower() == module)
.OrderBy(c=>c.Text)
.AsEnumerable();
var cmdsArray = cmds as Command[] ?? cmds.ToArray();
if (!cmdsArray.Any())
{
await imsg.Channel.SendMessageAsync("That module does not exist.").ConfigureAwait(false);
return;
}
if (module != "customreactions" && module != "conversations")
{
await imsg.Channel.SendMessageAsync("`List Of Commands:`\n" + SearchHelper.ShowInPrettyCode<Command>(cmdsArray,
el => $"{el.Text,-15}{"[" + el.Aliases.FirstOrDefault() + "]",-8}"))
.ConfigureAwait(false);
}
else
{
await imsg.Channel.SendMessageAsync("`List Of Commands:`\n• " + string.Join("\n• ", cmdsArray.Select(c => $"{c.Text}")));
}
await imsg.Channel.SendMessageAsync($"`You can type \"{Prefix}h command_name\" to see the help about that specific command.`").ConfigureAwait(false);
});
});
}
}
}

View File

@ -1,145 +0,0 @@
using Discord.Modules;
using Manatee.Trello;
using Manatee.Trello.ManateeJson;
using NadekoBot.Extensions;
using NadekoBot.Modules.Permissions.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Timers;
using Action = Manatee.Trello.Action;
namespace NadekoBot.Modules.Trello
{
internal class TrelloModule : DiscordModule
{
private readonly Timer t = new Timer { Interval = 2000 };
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Trello;
public override void Install(ModuleManager manager)
{
var client = manager.Client;
var serializer = new ManateeSerializer();
TrelloConfiguration.Serializer = serializer;
TrelloConfiguration.Deserializer = serializer;
TrelloConfiguration.JsonFactory = new ManateeFactory();
TrelloConfiguration.RestClientProvider = new Manatee.Trello.WebApi.WebApiClientProvider();
TrelloAuthorization.Default.AppKey = NadekoBot.Creds.TrelloAppKey;
//TrelloAuthorization.Default.UserToken = "[your user token]";
Discord.Channel bound = null;
Board board = null;
List<string> last5ActionIDs = null;
t.Elapsed += async (s, e) =>
{
try
{
if (board == null || bound == null)
return; //do nothing if there is no bound board
board.Refresh();
var cur5Actions = board.Actions.Take(board.Actions.Count() < 5 ? board.Actions.Count() : 5);
var cur5ActionsArray = cur5Actions as Action[] ?? cur5Actions.ToArray();
if (last5ActionIDs == null)
{
last5ActionIDs = cur5ActionsArray.Select(a => a.Id).ToList();
return;
}
foreach (var a in cur5ActionsArray.Where(ca => !last5ActionIDs.Contains(ca.Id)))
{
await bound.Send("**--TRELLO NOTIFICATION--**\n" + a.ToString()).ConfigureAwait(false);
}
last5ActionIDs.Clear();
last5ActionIDs.AddRange(cur5ActionsArray.Select(a => a.Id));
}
catch (Exception ex)
{
Console.WriteLine("Timer failed " + ex.ToString());
}
};
manager.CreateCommands("", cgb =>
{
cgb.AddCheck(PermissionChecker.Instance);
cgb.CreateCommand(Prefix + "bind")
.Description("Bind a trello bot to a single channel. " +
"You will receive notifications from your board when something is added or edited." +
$" **Bot Owner Only!**| `{Prefix}bind [board_id]`")
.Parameter("board_id", Discord.Commands.ParameterType.Required)
.Do(async e =>
{
if (!NadekoBot.IsOwner(e.User.Id)) return;
if (bound != null) return;
try
{
bound = e.Channel;
board = new Board(e.GetArg("board_id").Trim());
board.Refresh();
await imsg.Channel.SendMessageAsync("Successfully bound to this channel and board " + board.Name);
t.Start();
}
catch (Exception ex)
{
Console.WriteLine("Failed to join the board. " + ex.ToString());
}
});
cgb.CreateCommand(Prefix + "unbind")
.Description($"Unbinds a bot from the channel and board. **Bot Owner Only!**| `{Prefix}unbind`")
.Do(async e =>
{
if (!NadekoBot.IsOwner(e.User.Id)) return;
if (bound == null || bound != e.Channel) return;
t.Stop();
bound = null;
board = null;
await imsg.Channel.SendMessageAsync("Successfully unbound trello from this channel.").ConfigureAwait(false);
});
cgb.CreateCommand(Prefix + "lists")
.Alias(Prefix + "list")
.Description($"Lists all lists, yo ;) **Bot Owner Only!**| `{Prefix}list`")
.Do(async e =>
{
if (!NadekoBot.IsOwner(e.User.Id)) return;
if (bound == null || board == null || bound != e.Channel) return;
await imsg.Channel.SendMessageAsync("Lists for a board '" + board.Name + "'\n" + string.Join("\n", board.Lists.Select(l => "**• " + l.ToString() + "**")))
.ConfigureAwait(false);
});
cgb.CreateCommand(Prefix + "cards")
.Description($"Lists all cards from the supplied list. You can supply either a name or an index. **Bot Owner Only!**| `{Prefix}cards index`")
.Parameter("list_name", Discord.Commands.ParameterType.Unparsed)
.Do(async e =>
{
if (!NadekoBot.IsOwner(e.User.Id)) return;
if (bound == null || board == null || bound != e.Channel || e.GetArg("list_name") == null) return;
int num;
var success = int.TryParse(e.GetArg("list_name"), out num);
List list = null;
if (success && num <= board.Lists.Count() && num > 0)
list = board.Lists[num - 1];
else
list = board.Lists.FirstOrDefault(l => l.Name == e.GetArg("list_name"));
if (list != null)
await imsg.Channel.SendMessageAsync("There are " + list.Cards.Count() + " cards in a **" + list.Name + "** list\n" + string.Join("\n", list.Cards.Select(c => "**• " + c.ToString() + "**")))
.ConfigureAwait(false);
else
await imsg.Channel.SendMessageAsync("No such list.")
.ConfigureAwait(false);
});
});
}
}
}

View File

@ -1,8 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>Discord.Net.Commands</name>
</assembly>
<members>
</members>
</doc>

File diff suppressed because it is too large Load Diff

View File

@ -1,163 +0,0 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v1.0",
"signature": "52eb77cc5a8d5f8cf4a40bc5cbf2392e380f956a"
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v1.0": {
"NadekoBot/1.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0",
"Microsoft.Extensions.PlatformAbstractions": "1.0.0",
"Newtonsoft.Json": "9.0.1",
"Microsoft.Extensions.DependencyInjection": "1.0.0",
"Discord.Net": "1.0.0-dev",
"Discord.Net.Commands": "1.0.0-dev",
"System.Resources.ResourceWriter": "4.0.0-beta-22816"
},
"runtime": {
"NadekoBot.dll": {}
}
},
"Microsoft.Extensions.DependencyInjection/1.0.0": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0"
},
"runtime": {
"lib/netstandard1.1/Microsoft.Extensions.DependencyInjection.dll": {}
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions/1.0.0": {
"runtime": {
"lib/netstandard1.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {}
}
},
"Microsoft.Extensions.PlatformAbstractions/1.0.0": {
"runtime": {
"lib/netstandard1.3/Microsoft.Extensions.PlatformAbstractions.dll": {}
}
},
"Microsoft.NETCore.Platforms/1.0.2-beta-24410-01": {},
"Newtonsoft.Json/9.0.1": {
"dependencies": {
"System.Runtime.Serialization.Primitives": "4.1.1"
},
"runtime": {
"lib/netstandard1.0/Newtonsoft.Json.dll": {}
}
},
"System.Net.WebSockets/4.0.0": {
"runtime": {
"lib/netstandard1.3/System.Net.WebSockets.dll": {}
}
},
"System.Net.WebSockets.Client/4.0.1-beta-24410-01": {
"dependencies": {
"Microsoft.NETCore.Platforms": "1.0.2-beta-24410-01",
"System.Net.WebSockets": "4.0.0"
},
"runtimeTargets": {
"runtimes/unix/lib/netstandard1.3/System.Net.WebSockets.Client.dll": {
"rid": "unix",
"assetType": "runtime"
},
"runtimes/win/lib/netstandard1.3/System.Net.WebSockets.Client.dll": {
"rid": "win",
"assetType": "runtime"
}
}
},
"System.Resources.ResourceWriter/4.0.0-beta-22816": {
"runtime": {
"lib/aspnetcore50/System.Resources.ResourceWriter.dll": {}
}
},
"System.Runtime.Serialization.Primitives/4.1.1": {
"runtime": {
"lib/netstandard1.3/System.Runtime.Serialization.Primitives.dll": {}
}
},
"Discord.Net/1.0.0-dev": {
"dependencies": {
"Newtonsoft.Json": "9.0.1",
"System.Net.WebSockets.Client": "4.0.1-beta-24410-01",
"System.Runtime.Serialization.Primitives": "4.1.1"
},
"runtime": {
"Discord.Net.dll": {}
}
},
"Discord.Net.Commands/1.0.0-dev": {
"dependencies": {
"Discord.Net": "1.0.0-dev"
},
"runtime": {
"Discord.Net.Commands.dll": {}
}
}
}
},
"libraries": {
"NadekoBot/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Microsoft.Extensions.DependencyInjection/1.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-zdtkiZNV6LB8xtpmfyUjP/9N9ZCL/ydQ+0bfjun38fbrk+MDEm9M2yeLzRdq+OIt5xExw/KU04wFaVwJ1bhQPg=="
},
"Microsoft.Extensions.DependencyInjection.Abstractions/1.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-+XwaNo3o9RhLQhUnnOBCaukeRi1X9yYc0Fzye9RlErSflKZdw0VgHtn6rvKo0FTionsW0x8QVULhKH+nkqVjQA=="
},
"Microsoft.Extensions.PlatformAbstractions/1.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-zyjUzrOmuevOAJpIo3Mt5GmpALVYCVdLZ99keMbmCxxgQH7oxzU58kGHzE6hAgYEiWsdfMJLjVR7r+vSmaJmtg=="
},
"Microsoft.NETCore.Platforms/1.0.2-beta-24410-01": {
"type": "package",
"serviceable": true,
"sha512": "sha512-uc/pGYdE4sVy3OovFF8hg79MvCxptzICxn0jdA6WusGWZa7VieqFoZYc+a6bHUVhMI0s/7SfBriux0RUq+PpbA=="
},
"Newtonsoft.Json/9.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-U82mHQSKaIk+lpSVCbWYKNavmNH1i5xrExDEquU1i6I5pV6UMOqRnJRSlKO3cMPfcpp0RgDY+8jUXHdQ4IfXvw=="
},
"System.Net.WebSockets/4.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-2KJo8hir6Edi9jnMDAMhiJoI691xRBmKcbNpwjrvpIMOCTYOtBpSsSEGBxBDV7PKbasJNaFp1+PZz1D7xS41Hg=="
},
"System.Net.WebSockets.Client/4.0.1-beta-24410-01": {
"type": "package",
"serviceable": true,
"sha512": "sha512-IOqAcR7k+3LwNI6aL7qN61HcCOA9X4MM9LbrZhDeNbeB/IeWTk7zpeb7kh3d7H678s7ndIqN6a7okO8dAAfcYQ=="
},
"System.Resources.ResourceWriter/4.0.0-beta-22816": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Q6wpzkZjop1J+WJXl9H0OgXQvxDQxMkqA43AVENNW4SlTzIT8rFW7tum54xYZy3QCMKK8gIfOnVqA6VbgXRq1Q=="
},
"System.Runtime.Serialization.Primitives/4.1.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-HZ6Du5QrTG8MNJbf4e4qMO3JRAkIboGT5Fk804uZtg3Gq516S7hAqTm2UZKUHa7/6HUGdVy3AqMQKbns06G/cg=="
},
"Discord.Net/1.0.0-dev": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Discord.Net.Commands/1.0.0-dev": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@ -1,7 +0,0 @@
{
"runtimeOptions": {
"additionalProbingPaths": [
"C:\\Users\\Kwoth\\.nuget\\packages"
]
}
}

View File

@ -1,8 +0,0 @@
{
"runtimeOptions": {
"framework": {
"name": "Microsoft.NETCore.App",
"version": "1.0.0"
}
}
}

View File

@ -1,128 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="String1" xml:space="preserve">
<value>1</value>
<comment>1</comment>
</data>
<data name="String2" xml:space="preserve">
<value>2</value>
<comment>3</comment>
</data>
</root>