You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
5.0 KiB
148 lines
5.0 KiB
4 years ago
|
using System;
|
||
|
using System.Linq;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Collections.Immutable;
|
||
|
using Discord.Commands.Builders;
|
||
|
|
||
|
namespace Discord.Commands
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Provides the information of a module.
|
||
|
/// </summary>
|
||
|
public class ModuleInfo
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Gets the command service associated with this module.
|
||
|
/// </summary>
|
||
|
public CommandService Service { get; }
|
||
|
/// <summary>
|
||
|
/// Gets the name of this module.
|
||
|
/// </summary>
|
||
|
public string Name { get; }
|
||
|
/// <summary>
|
||
|
/// Gets the summary of this module.
|
||
|
/// </summary>
|
||
|
public string Summary { get; }
|
||
|
/// <summary>
|
||
|
/// Gets the remarks of this module.
|
||
|
/// </summary>
|
||
|
public string Remarks { get; }
|
||
|
/// <summary>
|
||
|
/// Gets the group name (main prefix) of this module.
|
||
|
/// </summary>
|
||
|
public string Group { get; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets a read-only list of aliases associated with this module.
|
||
|
/// </summary>
|
||
|
public IReadOnlyList<string> Aliases { get; }
|
||
|
/// <summary>
|
||
|
/// Gets a read-only list of commands associated with this module.
|
||
|
/// </summary>
|
||
|
public IReadOnlyList<CommandInfo> Commands { get; }
|
||
|
/// <summary>
|
||
|
/// Gets a read-only list of preconditions that apply to this module.
|
||
|
/// </summary>
|
||
|
public IReadOnlyList<PreconditionAttribute> Preconditions { get; }
|
||
|
/// <summary>
|
||
|
/// Gets a read-only list of attributes that apply to this module.
|
||
|
/// </summary>
|
||
|
public IReadOnlyList<Attribute> Attributes { get; }
|
||
|
/// <summary>
|
||
|
/// Gets a read-only list of submodules associated with this module.
|
||
|
/// </summary>
|
||
|
public IReadOnlyList<ModuleInfo> Submodules { get; }
|
||
|
/// <summary>
|
||
|
/// Gets the parent module of this submodule if applicable.
|
||
|
/// </summary>
|
||
|
public ModuleInfo Parent { get; }
|
||
|
/// <summary>
|
||
|
/// Gets a value that indicates whether this module is a submodule or not.
|
||
|
/// </summary>
|
||
|
public bool IsSubmodule => Parent != null;
|
||
|
|
||
|
internal ModuleInfo(ModuleBuilder builder, CommandService service, IServiceProvider services, ModuleInfo parent = null)
|
||
|
{
|
||
|
Service = service;
|
||
|
|
||
|
Name = builder.Name;
|
||
|
Summary = builder.Summary;
|
||
|
Remarks = builder.Remarks;
|
||
|
Group = builder.Group;
|
||
|
Parent = parent;
|
||
|
|
||
|
Aliases = BuildAliases(builder, service).ToImmutableArray();
|
||
|
Commands = builder.Commands.Select(x => x.Build(this, service)).ToImmutableArray();
|
||
|
Preconditions = BuildPreconditions(builder).ToImmutableArray();
|
||
|
Attributes = BuildAttributes(builder).ToImmutableArray();
|
||
|
|
||
|
Submodules = BuildSubmodules(builder, service, services).ToImmutableArray();
|
||
|
}
|
||
|
|
||
|
private static IEnumerable<string> BuildAliases(ModuleBuilder builder, CommandService service)
|
||
|
{
|
||
|
var result = builder.Aliases.ToList();
|
||
|
var builderQueue = new Queue<ModuleBuilder>();
|
||
|
|
||
|
var parent = builder;
|
||
|
while ((parent = parent.Parent) != null)
|
||
|
builderQueue.Enqueue(parent);
|
||
|
|
||
|
while (builderQueue.Count > 0)
|
||
|
{
|
||
|
var level = builderQueue.Dequeue();
|
||
|
// permute in reverse because we want to *prefix* our aliases
|
||
|
result = level.Aliases.Permutate(result, (first, second) =>
|
||
|
{
|
||
|
if (first == "")
|
||
|
return second;
|
||
|
else if (second == "")
|
||
|
return first;
|
||
|
else
|
||
|
return first + service._separatorChar + second;
|
||
|
}).ToList();
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
private List<ModuleInfo> BuildSubmodules(ModuleBuilder parent, CommandService service, IServiceProvider services)
|
||
|
{
|
||
|
var result = new List<ModuleInfo>();
|
||
|
|
||
|
foreach (var submodule in parent.Modules)
|
||
|
result.Add(submodule.Build(service, services, this));
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
private static List<PreconditionAttribute> BuildPreconditions(ModuleBuilder builder)
|
||
|
{
|
||
|
var result = new List<PreconditionAttribute>();
|
||
|
|
||
|
ModuleBuilder parent = builder;
|
||
|
while (parent != null)
|
||
|
{
|
||
|
result.AddRange(parent.Preconditions);
|
||
|
parent = parent.Parent;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
private static List<Attribute> BuildAttributes(ModuleBuilder builder)
|
||
|
{
|
||
|
var result = new List<Attribute>();
|
||
|
|
||
|
ModuleBuilder parent = builder;
|
||
|
while (parent != null)
|
||
|
{
|
||
|
result.AddRange(parent.Attributes);
|
||
|
parent = parent.Parent;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
}
|