Restructure documentation layout

This commit is contained in:
Christopher F
2017-04-03 16:36:26 -04:00
parent b4c3427ed1
commit 5ade1e387b
41 changed files with 22 additions and 33 deletions

View File

@@ -0,0 +1,56 @@
using System.Threading.Tasks;
using System.Reflection;
using Discord;
using Discord.WebSocket;
using Discord.Commands;
public class Program
{
private CommandService commands;
private DiscordSocketClient client;
private DependencyMap map;
static void Main(string[] args) => new Program().Start().GetAwaiter().GetResult();
public async Task Start()
{
client = new DiscordSocketClient();
commands = new CommandService();
string token = "bot token here";
map = new DependencyMap();
await InstallCommands();
await client.LoginAsync(TokenType.Bot, token);
await client.ConnectAsync();
await Task.Delay(-1);
}
public async Task InstallCommands()
{
// Hook the MessageReceived Event into our Command Handler
client.MessageReceived += HandleCommand;
// Discover all of the commands in this assembly and load them.
await commands.AddModulesAsync(Assembly.GetEntryAssembly());
}
public async Task HandleCommand(SocketMessage messageParam)
{
// Don't process the command if it was a System Message
var message = messageParam as SocketUserMessage;
if (message == null) return;
// Create a number to track where the prefix ends and the command begins
int argPos = 0;
// Determine if the message is a command, based on if it starts with '!' or a mention prefix
if (!(message.HasCharPrefix('!', ref argPos) || message.HasMentionPrefix(client.CurrentUser, ref argPos))) return;
// Create a Command Context
var context = new CommandContext(client, message);
// Execute the command. (result does not indicate a return value,
// rather an object stating if the command executed succesfully)
var result = await commands.ExecuteAsync(context, argPos, map);
if (!result.IsSuccess)
await context.Channel.SendMessageAsync(result.ErrorReason);
}
}

View File

@@ -0,0 +1,19 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using foxboat.Services;
public class Commands
{
public async Task Install(DiscordSocketClient client)
{
// Here, we will inject the Dependency Map with
// all of the services our client will use.
_map.Add(client);
_map.Add(commands);
_map.Add(new NotificationService(_map));
_map.Add(new DatabaseService(_map));
// ...
await _commands.AddModulesAsync(Assembly.GetEntryAssembly());
}
}

View File

@@ -0,0 +1,40 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;
public class ModuleA : ModuleBase
{
private readonly DatabaseService _database;
// Dependencies can be injected via the constructor
public ModuleA(DatabaseService database)
{
_database = database;
}
public async Task ReadFromDb()
{
var x = _database.getX();
await ReplyAsync(x);
}
}
public class ModuleB
{
// Public settable properties will be injected
public AnnounceService { get; set; }
// Public properties without setters will not
public CommandService Commands { get; }
// Public properties annotated with [DontInject] will not
[DontInject]
public NotificationService { get; set; }
public ModuleB(CommandService commands)
{
Commands = commands;
}
}

View File

@@ -0,0 +1,6 @@
using Discord.Commands;
public class InfoModule : ModuleBase
{
}

View File

@@ -0,0 +1,18 @@
[Group("admin")]
public class AdminModule : ModuleBase
{
[Group("clean")]
public class CleanModule : ModuleBase
{
// ~admin clean 15
[Command]
public async Task Default(int count = 10) => Messages(count);
// ~admin clean messages 15
[Command("messages")]
public async Task Messages(int count = 10) { }
}
// ~admin ban foxbot#0282
[Command("ban")]
public async Task Ban(IGuildUser user) { }
}

View File

@@ -0,0 +1,42 @@
using Discord;
using Discord.Commands;
using Discord.WebSocket;
// Create a module with no prefix
public class Info : ModuleBase
{
// ~say hello -> hello
[Command("say"), Summary("Echos a message.")]
public async Task Say([Remainder, Summary("The text to echo")] string echo)
{
// ReplyAsync is a method on ModuleBase
await ReplyAsync(echo);
}
}
// Create a module with the 'sample' prefix
[Group("sample")]
public class Sample : ModuleBase
{
// ~sample square 20 -> 400
[Command("square"), Summary("Squares a number.")]
public async Task Square([Summary("The number to square.")] int num)
{
// We can also access the channel from the Command Context.
await Context.Channel.SendMessageAsync($"{num}^2 = {Math.Pow(num, 2)}");
}
// ~sample userinfo --> foxbot#0282
// ~sample userinfo @Khionu --> Khionu#8708
// ~sample userinfo Khionu#8708 --> Khionu#8708
// ~sample userinfo Khionu --> Khionu#8708
// ~sample userinfo 96642168176807936 --> Khionu#8708
// ~sample whois 96642168176807936 --> Khionu#8708
[Command("userinfo"), Summary("Returns info about the current user, or the user parameter, if one passed.")]
[Alias("user", "whois")]
public async Task UserInfo([Summary("The (optional) user to get info for")] IUser user = null)
{
var userInfo = user ?? Context.Client.CurrentUser;
await ReplyAsync($"{userInfo.Username}#{userInfo.Discriminator}");
}
}

View File

@@ -0,0 +1,22 @@
// (Note: This precondition is obsolete, it is recommended to use the RequireOwnerAttribute that is bundled with Discord.Commands)
using Discord.Commands;
using Discord.WebSocket;
using System.Threading.Tasks;
// Inherit from PreconditionAttribute
public class RequireOwnerAttribute : PreconditionAttribute
{
// Override the CheckPermissions method
public async override Task<PreconditionResult> CheckPermissions(ICommandContext context, CommandInfo command, IDependencyMap map)
{
// Get the ID of the bot's owner
var ownerId = (await map.Get<DiscordSocketClient>().GetApplicationInfoAsync()).Owner.Id;
// If this command was executed by that user, return a success
if (context.User.Id == ownerId)
return PreconditionResult.FromSuccess();
// Since it wasn't, fail
else
return PreconditionResult.FromError("You must be the owner of the bot to run this command.");
}
}

View File

@@ -0,0 +1,15 @@
// Note: This example is obsolete, a boolean type reader is bundled with Discord.Commands
using Discord;
using Discord.Commands;
public class BooleanTypeReader : TypeReader
{
public override Task<TypeReaderResult> Read(CommandContext context, string input)
{
bool result;
if (bool.TryParse(input, out result))
return Task.FromResult(TypeReaderResult.FromSuccess(result));
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Input could not be parsed as a boolean."))
}
}