Add autocomplete manager + context menu bugfixes
This commit is contained in:
@@ -78,6 +78,8 @@ export class ODClientManager {
|
|||||||
textCommands: ODTextCommandManager
|
textCommands: ODTextCommandManager
|
||||||
/**The context menu manager is responsible for all context menus & their events inside the bot. */
|
/**The context menu manager is responsible for all context menus & their events inside the bot. */
|
||||||
contextMenus: ODContextMenuManager
|
contextMenus: ODContextMenuManager
|
||||||
|
/**The autocomplete manager is responsible for all autocomplete events inside the bot. */
|
||||||
|
autocompletes: ODAutocompleteManager
|
||||||
|
|
||||||
constructor(debug:ODDebugger){
|
constructor(debug:ODDebugger){
|
||||||
this.#debug = debug
|
this.#debug = debug
|
||||||
@@ -85,6 +87,7 @@ export class ODClientManager {
|
|||||||
this.slashCommands = new ODSlashCommandManager(this.#debug,this)
|
this.slashCommands = new ODSlashCommandManager(this.#debug,this)
|
||||||
this.textCommands = new ODTextCommandManager(this.#debug,this)
|
this.textCommands = new ODTextCommandManager(this.#debug,this)
|
||||||
this.contextMenus = new ODContextMenuManager(this.#debug,this)
|
this.contextMenus = new ODContextMenuManager(this.#debug,this)
|
||||||
|
this.autocompletes = new ODAutocompleteManager(this.#debug,this)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Initiate the `client` variable & add the intents & partials to the bot. */
|
/**Initiate the `client` variable & add the intents & partials to the bot. */
|
||||||
@@ -152,6 +155,7 @@ export class ODClientManager {
|
|||||||
if (!this.client.application) throw new ODSystemError("Couldn't get client application for slashCommand & contextMenu managers!")
|
if (!this.client.application) throw new ODSystemError("Couldn't get client application for slashCommand & contextMenu managers!")
|
||||||
this.slashCommands.commandManager = this.client.application.commands
|
this.slashCommands.commandManager = this.client.application.commands
|
||||||
this.contextMenus.commandManager = this.client.application.commands
|
this.contextMenus.commandManager = this.client.application.commands
|
||||||
|
this.autocompletes.commandManager = this.client.application.commands
|
||||||
|
|
||||||
if (this.readyListener) await this.readyListener()
|
if (this.readyListener) await this.readyListener()
|
||||||
resolve(true)
|
resolve(true)
|
||||||
@@ -1920,7 +1924,7 @@ export class ODContextMenuComparator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**## ODContextMenuInteractionCallback `type`
|
/**## ODContextMenuInteractionCallback `type`
|
||||||
* Callback for the message context menu interaction listener.
|
* Callback for the context menu interaction listener.
|
||||||
*/
|
*/
|
||||||
export type ODContextMenuInteractionCallback = (interaction:discord.ContextMenuCommandInteraction,cmd:ODContextMenu) => void
|
export type ODContextMenuInteractionCallback = (interaction:discord.ContextMenuCommandInteraction,cmd:ODContextMenu) => void
|
||||||
|
|
||||||
@@ -1928,29 +1932,29 @@ export type ODContextMenuInteractionCallback = (interaction:discord.ContextMenuC
|
|||||||
* The result which will be returned when getting all (un)registered user context menu's from the manager.
|
* The result which will be returned when getting all (un)registered user context menu's from the manager.
|
||||||
*/
|
*/
|
||||||
export type ODContextMenuRegisteredResult = {
|
export type ODContextMenuRegisteredResult = {
|
||||||
/**A list of all registered message context menus. */
|
/**A list of all registered context menus. */
|
||||||
registered:{
|
registered:{
|
||||||
/**The instance (`ODContextMenu`) from this message context menu. */
|
/**The instance (`ODContextMenu`) from this context menu. */
|
||||||
instance:ODContextMenu,
|
instance:ODContextMenu,
|
||||||
/**The universal object/template/builder of this message context menu. */
|
/**The universal object/template/builder of this context menu. */
|
||||||
menu:ODContextMenuUniversalMenu,
|
menu:ODContextMenuUniversalMenu,
|
||||||
/**Does this message context menu require an update? */
|
/**Does this context menu require an update? */
|
||||||
requiresUpdate:boolean
|
requiresUpdate:boolean
|
||||||
}[],
|
}[],
|
||||||
/**A list of all unregistered message context menus. */
|
/**A list of all unregistered context menus. */
|
||||||
unregistered:{
|
unregistered:{
|
||||||
/**The instance (`ODContextMenu`) from this message context menu. */
|
/**The instance (`ODContextMenu`) from this context menu. */
|
||||||
instance:ODContextMenu,
|
instance:ODContextMenu,
|
||||||
/**The universal object/template/builder of this message context menu. */
|
/**The universal object/template/builder of this context menu. */
|
||||||
menu:null,
|
menu:null,
|
||||||
/**Does this message context menu require an update? */
|
/**Does this context menu require an update? */
|
||||||
requiresUpdate:true
|
requiresUpdate:true
|
||||||
}[],
|
}[],
|
||||||
/**A list of all unused message context menus (not found in `ODContextMenuManager`). */
|
/**A list of all unused context menus (not found in `ODContextMenuManager`). */
|
||||||
unused:{
|
unused:{
|
||||||
/**The instance (`ODContextMenu`) from this message context menu. */
|
/**The instance (`ODContextMenu`) from this context menu. */
|
||||||
instance:null,
|
instance:null,
|
||||||
/**The universal object/template/builder of this message context menu. */
|
/**The universal object/template/builder of this context menu. */
|
||||||
menu:ODContextMenuUniversalMenu,
|
menu:ODContextMenuUniversalMenu,
|
||||||
/**Does this context menu require an update? */
|
/**Does this context menu require an update? */
|
||||||
requiresUpdate:false
|
requiresUpdate:false
|
||||||
@@ -1958,11 +1962,11 @@ export type ODContextMenuRegisteredResult = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**## ODContextMenuManager `class`
|
/**## ODContextMenuManager `class`
|
||||||
* This is an Open Ticket client message context menu manager.
|
* This is an Open Ticket client context menu manager.
|
||||||
*
|
*
|
||||||
* It's responsible for managing all the message context interactions from the client.
|
* It's responsible for managing all the context interactions from the client.
|
||||||
*
|
*
|
||||||
* Here, you can add & remove message context interactions & the bot will do the (de)registering.
|
* Here, you can add & remove context interactions & the bot will do the (de)registering.
|
||||||
*/
|
*/
|
||||||
export class ODContextMenuManager extends ODManager<ODContextMenu> {
|
export class ODContextMenuManager extends ODManager<ODContextMenu> {
|
||||||
/**Alias to Open Ticket debugger. */
|
/**Alias to Open Ticket debugger. */
|
||||||
@@ -2175,4 +2179,66 @@ export class ODContextMenu extends ODManagerData {
|
|||||||
set name(name:string){
|
set name(name:string){
|
||||||
this.builder.name = name
|
this.builder.name = name
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**## ODAutocompleteInteractionCallback `type`
|
||||||
|
* Callback for the autocomplete interaction listener.
|
||||||
|
*/
|
||||||
|
export type ODAutocompleteInteractionCallback = (interaction:discord.AutocompleteInteraction) => void
|
||||||
|
|
||||||
|
/**## ODAutocompleteManager `class`
|
||||||
|
* This is an Open Ticket client autocomplete interaction manager.
|
||||||
|
*
|
||||||
|
* It's responsible for managing all the autocomplete interactions from the client.
|
||||||
|
*/
|
||||||
|
export class ODAutocompleteManager {
|
||||||
|
/**Alias to Open Ticket debugger. */
|
||||||
|
#debug: ODDebugger
|
||||||
|
|
||||||
|
/**Refrerence to discord.js client. */
|
||||||
|
manager: ODClientManager
|
||||||
|
/**Discord.js application commands manager. */
|
||||||
|
commandManager: discord.ApplicationCommandManager|null
|
||||||
|
/**Collection of all interaction listeners. */
|
||||||
|
#interactionListeners: {cmdName:string|RegExp, optName:string|RegExp, callback:ODAutocompleteInteractionCallback}[] = []
|
||||||
|
/**Set the soft limit for maximum amount of listeners. A warning will be shown when there are more listeners than this limit. */
|
||||||
|
listenerLimit: number = 100
|
||||||
|
|
||||||
|
constructor(debug:ODDebugger, manager:ODClientManager){
|
||||||
|
this.#debug = debug
|
||||||
|
this.manager = manager
|
||||||
|
this.commandManager = (manager.client.application) ? manager.client.application.commands : null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Start listening to the discord.js client `interactionCreate` event. */
|
||||||
|
startListeningToInteractions(){
|
||||||
|
this.manager.client.on("interactionCreate",(interaction) => {
|
||||||
|
//return when not in main server or DM
|
||||||
|
if (!this.manager.mainServer || (interaction.guild && interaction.guild.id != this.manager.mainServer.id)) return
|
||||||
|
|
||||||
|
if (!interaction.isAutocomplete()) return
|
||||||
|
this.#interactionListeners.forEach((listener) => {
|
||||||
|
|
||||||
|
if (typeof listener.cmdName == "string" && (interaction.commandName != listener.cmdName)) return
|
||||||
|
else if (listener.cmdName instanceof RegExp && !listener.cmdName.test(interaction.commandName)) return
|
||||||
|
if (typeof listener.optName == "string" && (interaction.options.getFocused(true).name != listener.optName)) return
|
||||||
|
else if (listener.optName instanceof RegExp && !listener.optName.test(interaction.options.getFocused(true).name)) return
|
||||||
|
|
||||||
|
//this is a valid listener
|
||||||
|
listener.callback(interaction)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/**Callback on interaction from one or multiple autocompletes. */
|
||||||
|
onInteraction(cmdName:string|RegExp,optName:string|RegExp,callback:ODAutocompleteInteractionCallback){
|
||||||
|
this.#interactionListeners.push({
|
||||||
|
cmdName,optName,callback
|
||||||
|
})
|
||||||
|
|
||||||
|
if (this.#interactionListeners.length > this.listenerLimit){
|
||||||
|
this.#debug.console.log("Possible autocomplete interaction memory leak detected!","warning",[
|
||||||
|
{key:"listeners",value:this.#interactionListeners.length.toString()}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,10 @@ export const loadVersionMigrationSystem = async () => {
|
|||||||
if (opendiscord.flags.exists("opendiscord:no-plugins") && opendiscord.flags.get("opendiscord:no-plugins").value) opendiscord.defaults.setDefault("pluginLoading",false)
|
if (opendiscord.flags.exists("opendiscord:no-plugins") && opendiscord.flags.get("opendiscord:no-plugins").value) opendiscord.defaults.setDefault("pluginLoading",false)
|
||||||
if (opendiscord.flags.exists("opendiscord:soft-plugins") && opendiscord.flags.get("opendiscord:soft-plugins").value) opendiscord.defaults.setDefault("softPluginLoading",true)
|
if (opendiscord.flags.exists("opendiscord:soft-plugins") && opendiscord.flags.get("opendiscord:soft-plugins").value) opendiscord.defaults.setDefault("softPluginLoading",true)
|
||||||
if (opendiscord.flags.exists("opendiscord:crash") && opendiscord.flags.get("opendiscord:crash").value) opendiscord.defaults.setDefault("crashOnError",true)
|
if (opendiscord.flags.exists("opendiscord:crash") && opendiscord.flags.get("opendiscord:crash").value) opendiscord.defaults.setDefault("crashOnError",true)
|
||||||
if (opendiscord.flags.exists("opendiscord:force-slash-update") && opendiscord.flags.get("opendiscord:force-slash-update").value) opendiscord.defaults.setDefault("forceSlashCommandRegistration",true)
|
if (opendiscord.flags.exists("opendiscord:force-slash-update") && opendiscord.flags.get("opendiscord:force-slash-update").value){
|
||||||
|
opendiscord.defaults.setDefault("forceSlashCommandRegistration",true)
|
||||||
|
opendiscord.defaults.setDefault("forceContextMenuRegistration",true)
|
||||||
|
}
|
||||||
if (opendiscord.flags.exists("opendiscord:silent") && opendiscord.flags.get("opendiscord:silent").value) opendiscord.console.silent = true
|
if (opendiscord.flags.exists("opendiscord:silent") && opendiscord.flags.get("opendiscord:silent").value) opendiscord.console.silent = true
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ export const loadStartListeningInteractionsCode = async () => {
|
|||||||
opendiscord.code.add(new api.ODCode("opendiscord:start-listening-interactions",13,() => {
|
opendiscord.code.add(new api.ODCode("opendiscord:start-listening-interactions",13,() => {
|
||||||
opendiscord.client.slashCommands.startListeningToInteractions()
|
opendiscord.client.slashCommands.startListeningToInteractions()
|
||||||
opendiscord.client.textCommands.startListeningToInteractions()
|
opendiscord.client.textCommands.startListeningToInteractions()
|
||||||
|
opendiscord.client.contextMenus.startListeningToInteractions()
|
||||||
|
opendiscord.client.autocompletes.startListeningToInteractions()
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -384,7 +384,7 @@ const main = async () => {
|
|||||||
if (!mainServer || !client.checkBotInGuild(mainServer)){
|
if (!mainServer || !client.checkBotInGuild(mainServer)){
|
||||||
console.log("\n")
|
console.log("\n")
|
||||||
opendiscord.log("The bot isn't a member of the server provided in the config!","error")
|
opendiscord.log("The bot isn't a member of the server provided in the config!","error")
|
||||||
opendiscord.log("Please invite your bot to the server!","info")
|
opendiscord.log("Please invite your bot to this server!","info")
|
||||||
console.log("\n")
|
console.log("\n")
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
@@ -399,8 +399,8 @@ const main = async () => {
|
|||||||
if (opendiscord.defaults.getDefault("clientMultiGuildWarning")){
|
if (opendiscord.defaults.getDefault("clientMultiGuildWarning")){
|
||||||
//warn if bot is in multiple servers
|
//warn if bot is in multiple servers
|
||||||
if (botServers.length > 1){
|
if (botServers.length > 1){
|
||||||
opendiscord.log("This bot is part of multiple servers, but Open Ticket doesn't have support for it!","warning")
|
opendiscord.log("This bot is part of multiple servers, but Open Ticket doesn't provide support for this!","warning")
|
||||||
opendiscord.log("It may result in the bot crashing & glitching when used in these servers!","info")
|
opendiscord.log("As a result, the bot may crash & glitch when used in the additional servers!","info")
|
||||||
}
|
}
|
||||||
botServers.forEach((server) => {
|
botServers.forEach((server) => {
|
||||||
//warn if bot doesn't have permissions in multiple servers
|
//warn if bot doesn't have permissions in multiple servers
|
||||||
|
|||||||
Reference in New Issue
Block a user