Build overrides are a way for library developers to override the default behavior of the library on the fly. Adding them to your code is really simple.
## Installing the package
The build override package can be installed on nuget [here](TODO) or by using the package manager
Overrides are normally built for specific problems, for example if someone is having an issue and we think we might have a fix then we can create a build override for them to test out the fix.
## Security and Transparency
Overrides can only be created and updated by library developers, you should only apply an override if a library developer askes you to.
Code for the overrides server and the overrides themselves can be found [here](https://github.com/discord-net/Discord.Net.BuildOverrides).
var result = await client.PostAsync($"{ApiUrl}/override/{id}/dependency", new StringContent($"{{ \"info\": \"{name}\"}}", Encoding.UTF8, "application/json"));
if (!result.IsSuccessStatusCode)
throw new Exception("Failed to get dependency");
using(var ms = new MemoryStream())
{
var innerStream = await result.Content.ReadAsStreamAsync();
// If a Slash Command execution fails it is most likely that the original interaction acknowledgement will persist. It is a good idea to delete the original
// response, or at least let the user know that something went wrong during the command execution.
// Create an execution context that matches the generic type parameter of your InteractionModuleBase<T> modules.
var context = new SocketInteractionContext(_client, interaction);
// Execute the incoming command.
var result = await _handler.ExecuteCommandAsync(context, _services);
if (!result.IsSuccess)
switch (result.Error)
{
case InteractionCommandError.UnmetPrecondition:
// implement
break;
default:
break;
}
}
catch
{
// If Slash Command execution fails it is most likely that the original interaction acknowledgement will persist. It is a good idea to delete the original
// response, or at least let the user know that something went wrong during the command execution.
if (interaction.Type is InteractionType.ApplicationCommand)
// Interation modules must be public and inherit from an IInterationModuleBase
// Interation modules must be public and inherit from an IInterationModuleBase
public class GeneralModule : InteractionModuleBase<SocketInteractionContext>
public class ExampleModule : InteractionModuleBase<SocketInteractionContext>
{
{
// Dependencies can be accessed through Property injection, public properties with public setters will be set by the service provider
// Dependencies can be accessed through Property injection, public properties with public setters will be set by the service provider
public InteractionService Commands { get; set; }
public InteractionService Commands { get; set; }
private CommandHandler _handler;
private InteractionHandler _handler;
// Constructor injection is also a valid way to access the dependecies
// Constructor injection is also a valid way to access the dependecies
public GeneralModule(CommandHandler handler)
public ExampleModule(InteractionHandler handler)
{
{
_handler = handler;
_handler = handler;
}
}
// Slash Commands are declared using the [SlashCommand], you need to provide a name and a description, both following the Discord guidelines
[SlashCommand("ping", "Recieve a pong")]
// By setting the DefaultPermission to false, you can disable the command by default. No one can use the command until you give them permission
[DefaultPermission(false)]
public async Task Ping ( )
{
await RespondAsync("pong");
}
// You can use a number of parameter types in you Slash Command handlers (string, int, double, bool, IUser, IChannel, IMentionable, IRole, Enums) by default. Optionally,
// You can use a number of parameter types in you Slash Command handlers (string, int, double, bool, IUser, IChannel, IMentionable, IRole, Enums) by default. Optionally,
// you can implement your own TypeConverters to support a wider range of parameter types. For more information, refer to the library documentation.
// you can implement your own TypeConverters to support a wider range of parameter types. For more information, refer to the library documentation.
// Optional method parameters(parameters with a default value) also will be displayed as optional on Discord.
// Optional method parameters(parameters with a default value) also will be displayed as optional on Discord.
// Select Menu interactions, contain ids of the menu options that were selected by the user. You can access the option ids from the method parameters.
// Select Menu interactions, contain ids of the menu options that were selected by the user. You can access the option ids from the method parameters.
// You can also use the wild card pattern with Select Menus, in that case, the wild card captures will be passed on to the method first, followed by the option ids.
// You can also use the wild card pattern with Select Menus, in that case, the wild card captures will be passed on to the method first, followed by the option ids.
[ComponentInteraction("roleSelect")]
[ComponentInteraction("roleSelect")]
public async Task RoleSelect(params string[] selections)
public async Task RoleSelect(string[] selections)
{
throw new NotImplementedException();
}
// With the Attribute DoUserCheck you can make sure that only the user this button targets can click it. This is defined by the first wildcard: *.
// See Attributes/DoUserCheckAttribute.cs for elaboration.
// Dependency injection is a key part of the Interactions framework but it needs to be disposed at the end of the app's lifetime.
using var services = ConfigureServices(configuration);
static void Main(string[] args)
=> new Program().RunAsync()
.GetAwaiter()
.GetResult();
var client = services.GetRequiredService<DiscordSocketClient>();
var commands = services.GetRequiredService<InteractionService>();
public async Task RunAsync()
{
var client = _services.GetRequiredService<DiscordSocketClient>();
client.Log += LogAsync;
client.Log += LogAsync;
commands.Log += LogAsync;
// Slash Commands and Context Commands are can be automatically registered, but this process needs to happen after the client enters the READY state.
// Since Global Commands take around 1 hour to register, we should use a test guild to instantly update and test our commands. To determine the method we should
// register the commands with, we can check whether we are in a DEBUG environment and if we are, we can register the commands to a predetermined test guild.
client.Ready += async ( ) =>
{
if (IsDebug())
// Id of the test guild can be provided from the Configuration object
/// Removes a type reader from the list of type readers.
/// </summary>
/// <remarks>
/// Removing a <see cref="TypeReader"/> from the <see cref="CommandService"/> will not dereference the <see cref="TypeReader"/> from the loaded module/command instances.
/// You need to reload the modules for the changes to take effect.
/// </remarks>
/// <param name="type">The type to remove the readers from.</param>
/// <param name="isDefaultTypeReader"><see langword="true"/> if the default readers for <paramref name="type"/> should be removed; otherwise <see langword="false"/>.</param>
/// <param name="readers">The removed collection of type readers.</param>
/// <returns><see langword="true"/> if the remove operation was successful; otherwise <see langword="false"/>.</returns>
public bool TryRemoveTypeReader(Type type, bool isDefaultTypeReader, out IDictionary<Type, TypeReader> readers)
{
readers = new Dictionary<Type, TypeReader>();
if (isDefaultTypeReader)
{
var isSuccess = _defaultTypeReaders.TryRemove(type, out var result);
if (isSuccess)
readers.Add(result?.GetType(), result);
return isSuccess;
}
else
{
var isSuccess = _typeReaders.TryRemove(type, out var result);
throw new ArgumentException($"{typeof(T).FullName} isn't referenced by any registered Modal Interaction Command and doesn't have a cached {typeof(ModalInfo)}");
var modal = modalInfo.ToModal(customId, modifyModal);
/// Removes a type reader for the type <typeparamref name="T"/>.
/// </summary>
/// <typeparam name="T">The type to remove the readers from.</typeparam>
/// <param name="reader">The reader if the resulting remove operation was successful.</param>
/// <returns><see langword="true"/> if the remove operation was successful; otherwise <see langword="false"/>.</returns>
public bool TryRemoveTypeReader<T>(out TypeReader reader)
=> TryRemoveTypeReader(typeof(T), out reader);
/// <summary>
/// Removes a type reader for the given type.
/// </summary>
/// <remarks>
/// Removing a <see cref="TypeReader"/> from the <see cref="CommandService"/> will not dereference the <see cref="TypeReader"/> from the loaded module/command instances.
/// You need to reload the modules for the changes to take effect.
/// </remarks>
/// <param name="type">The type to remove the reader from.</param>
/// <param name="reader">The reader if the resulting remove operation was successful.</param>
/// <returns><see langword="true"/> if the remove operation was successful; otherwise <see langword="false"/>.</returns>
public bool TryRemoveTypeReader(Type type, out TypeReader reader)
=> _typeReaderMap.TryRemoveConcrete(type, out reader);
/// <summary>
/// Removes a generic type reader from the type <typeparamref name="T"/>.
/// </summary>
/// <remarks>
/// Removing a <see cref="TypeReader"/> from the <see cref="CommandService"/> will not dereference the <see cref="TypeReader"/> from the loaded module/command instances.
/// You need to reload the modules for the changes to take effect.
/// </remarks>
/// <typeparam name="T">The type to remove the readers from.</typeparam>
/// <returns><see langword="true"/> if the remove operation was successful; otherwise <see langword="false"/>.</returns>
public bool TryRemoveGenericTypeReader<T>(out Type readerType)
=> TryRemoveGenericTypeReader(typeof(T), out readerType);
/// <summary>
/// Removes a generic type reader from the given type.
/// </summary>
/// <remarks>
/// Removing a <see cref="TypeReader"/> from the <see cref="CommandService"/> will not dereference the <see cref="TypeReader"/> from the loaded module/command instances.
/// You need to reload the modules for the changes to take effect.
/// </remarks>
/// <param name="type">The type to remove the reader from.</param>
/// <param name="readerType">The readers type if the remove operation was successful.</param>
/// <returns><see langword="true"/> if the remove operation was successful; otherwise <see langword="false"/>.</returns>
public bool TryRemoveGenericTypeReader(Type type, out Type readerType)
=> _typeReaderMap.TryRemoveGeneric(type, out readerType);
/// <summary>
/// <summary>
/// Serialize an object using a <see cref="TypeReader"/> into a <see cref="string"/> to be placed in a Component CustomId.
/// Serialize an object using a <see cref="TypeReader"/> into a <see cref="string"/> to be placed in a Component CustomId.
/// </summary>
/// </summary>
/// <remarks>
/// Removing a <see cref="TypeReader"/> from the <see cref="CommandService"/> will not dereference the <see cref="TypeReader"/> from the loaded module/command instances.
/// You need to reload the modules for the changes to take effect.
/// </remarks>
/// <typeparam name="T">Type of the object to be serialized.</typeparam>
/// <typeparam name="T">Type of the object to be serialized.</typeparam>
/// <param name="obj">Object to be serialized.</param>
/// <param name="obj">Object to be serialized.</param>
/// <param name="services">Services that will be passed on to the <see cref="TypeReader"/>.</param>
/// <param name="services">Services that will be passed on to the <see cref="TypeReader"/>.</param>
if (Context.Interaction is not RestInteraction restInteraction)
throw new InvalidOperationException($"Invalid interaction type. Interaction must be a type of {nameof(RestInteraction)} in order to execute this method");
var payload = restInteraction.RespondWithModal(modal, options);
if (Context is IRestInteractionContext restContext && restContext.InteractionResponseCallback != null)
if (Context.Interaction is not RestInteraction restInteraction)
throw new InvalidOperationException($"Invalid interaction type. Interaction must be a type of {nameof(RestInteraction)} in order to execute this method");
var payload = restInteraction.RespondWithModal<T>(customId, options);
if (Context is IRestInteractionContext restContext && restContext.InteractionResponseCallback != null)
internal new static SocketThreadChannel Create(SocketGuild guild, ClientState state, Model model)
internal new static SocketThreadChannel Create(SocketGuild guild, ClientState state, Model model)
{
{
var parent = guild.GetChannel(model.CategoryId.Value);
var parent = guild.GetChannel(model.CategoryId.Value);
var entity = new SocketThreadChannel(guild.Discord, guild, model.Id, parent, model.ThreadMetadata.GetValueOrDefault()?.CreatedAt.ToNullable());
var entity = new SocketThreadChannel(guild.Discord, guild, model.Id, parent, model.ThreadMetadata.GetValueOrDefault()?.CreatedAt.GetValueOrDefault(null));
Thank you for your continuous support to the Openl Qizhi Community AI Collaboration Platform. In order to protect your usage rights and ensure network security, we updated the Openl Qizhi Community AI Collaboration Platform Usage Agreement in January 2024. The updated agreement specifies that users are prohibited from using intranet penetration tools. After you click "Agree and continue", you can continue to use our services. Thank you for your cooperation and understanding.