diff --git a/actions/action_anchor.js b/actions/action_anchor.js new file mode 100644 index 0000000..0e31564 --- /dev/null +++ b/actions/action_anchor.js @@ -0,0 +1,135 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "Action Anchor", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "Other Stuff", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + return data.description + ? `${data.description}` + : `Create ${ + data.anchor_id + ? `the "${data.anchorName}" anchor at the current position!` + : 'an anchor!' + }`; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/action_anchor.js" }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding IDs in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: ["anchorName", "color", "description"], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ` +Anchor Name
+ +
+ Anchor Color:
+
+
+
+
+ Description:
+ +
+
`; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + action(cache) { + this.callNextAction(cache); + }, + + //--------------------------------------------------------------------- + // Action Bot Mod Init + // + // An optional function for action mods. Upon the bot's initialization, + // each command/event's actions are iterated through. This is to + // initialize responses to interactions created within actions + // (e.g. buttons and select menus for Send Message). + // + // If an action provides inputs for more actions within, be sure + // to call the `this.prepareActions` function to ensure all actions are + // recursively iterated through. + //--------------------------------------------------------------------- + + modInit(data, customData, index) { + if (!customData.anchors) { + customData.anchors = {}; + } + customData.anchors[data.anchorName] = index; + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; diff --git a/actions/action_container_color_comment_MOD.js b/actions/action_container_color_comment_MOD.js new file mode 100644 index 0000000..7ac332f --- /dev/null +++ b/actions/action_container_color_comment_MOD.js @@ -0,0 +1,132 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "Action Container", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "Other Stuff", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + return `${data.comment}`; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/action_container_color_comment_MOD.js" }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding Ids in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: ["comment", "actions", "color"], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + // + // The "data" parameter stores constants for select elements to use. + // Each is an array: index 0 for commands, index 1 for events. + // The names are: sendTargets, members, roles, channels, + // messages, servers, variables + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ` +
+ Text Color:
+
+ Comment
+ + + +

+ +`; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + action(cache) { + const data = cache.actions[cache.index]; + const actions = data.actions; + this.executeSubActionsThenNextAction(actions, cache); + }, + + //--------------------------------------------------------------------- + // Action Bot Mod Init + // + // An optional function for action mods. Upon the bot's initialization, + // each command/event's actions are iterated through. This is to + // initialize responses to interactions created within actions + // (e.g. buttons and select menus for Send Message). + // + // If an action provides inputs for more actions within, be sure + // to call the `this.prepareActions` function to ensure all actions are + // recursively iterated through. + //--------------------------------------------------------------------- + + modInit(data) { + this.prepareActions(data.actions); + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; diff --git a/actions/anchor_create_MOD.js b/actions/anchor_create_MOD.js new file mode 100644 index 0000000..7ee43cf --- /dev/null +++ b/actions/anchor_create_MOD.js @@ -0,0 +1,96 @@ +module.exports = { + name: 'Create Anchor', + section: 'Other Stuff', + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/anchor_create_MOD.js" }, + + subtitle(data) { + return data.description + ? `${data.description}` + : `Create ${ + data.anchorName + ? `the "${data.anchorName}" anchor at the current position!` + : 'an anchor!' + }`; + }, + + fields: ['anchorName', 'color', 'description'], + + html() { + return ` +
+

+ Mod Info:
+ This mod creates an anchor point for you to jump to without
+ having to edit other jumps or skips. +

+

+
+ Anchor Name:
+
+
+
+ Anchor Color:
+
+
+
+
+ Description:
+ +
+
`; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + action(cache) { + this.callNextAction(cache); + }, + + //--------------------------------------------------------------------- + // Action Bot Mod Init + // + // An optional function for action mods. Upon the bot's initialization, + // each command/event's actions are iterated through. This is to + // initialize responses to interactions created within actions + // (e.g. buttons and select menus for Send Message). + // + // If an action provides inputs for more actions within, be sure + // to call the `this.prepareActions` function to ensure all actions are + // recursively iterated through. + //--------------------------------------------------------------------- + + modInit(data, customData, index) { + if (!customData.anchors) { + customData.anchors = {}; + } + customData.anchors[data.anchorName] = index; + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; diff --git a/actions/anchor_jump_MOD.js b/actions/anchor_jump_MOD.js new file mode 100644 index 0000000..6f239d6 --- /dev/null +++ b/actions/anchor_jump_MOD.js @@ -0,0 +1,68 @@ +module.exports = { + name: 'Jump to Anchor', + section: 'Other Stuff', + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/anchor_jump_MOD.js" }, + + subtitle(data) { + return data.description + ? `${data.description}` + : `Jump to ${ + data.jump_to_anchor + ? `the "${data.anchorName}" anchor in your command if it exists!` + : 'an anchor!' + }`; + }, + + fields: ['description', 'anchorName', 'color'], + + html() { + return ` +
+

+ Mod Info:
+ This mod will jump to the specified anchor point
+ without requiring you to edit any other skips or jumps.
+ This is sensitive and must be exactly the same as your anchor name. +

+

+
+ Jump to Anchor Name:
+
+
+
+ Anchor Color:
+
+
+
+ Description:
+
+
`; + }, + + init() {}, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + action(cache) { + const data = cache.actions[cache.index]; + const anchorName = this.evalMessage(data.anchorName, cache); + cache.goToAnchor(anchorName); + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; diff --git a/actions/await_interaction_MOD.js b/actions/await_interaction_MOD.js new file mode 100644 index 0000000..80931ea --- /dev/null +++ b/actions/await_interaction_MOD.js @@ -0,0 +1,313 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "Await Interaction", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "DBM-Enhanced", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + if (data.time >= 1) { + return `Await Interaction For ${data.time/1000} Seconds`; + } else { + return `Await Interaction For 60 Seconds (Default)` + } + }, + + //--------------------------------------------------------------------- + // Action Storage Function + // + // Stores the relevant variable info for the editor. + //--------------------------------------------------------------------- + + variableStorage(data, varType) { + const type = parseInt(data.storage, 10); + if (type !== varType) return; + return [data.varName, "Unknown Type"]; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/await_interaction_MOD.js" }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding IDs in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: ["type", "msgvar","msgvarname", "time", "code", "timeout", "storage", "varName"], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + // + // The "data" parameter stores constants for select elements to use. + // Each is an array: index 0 for commands, index 1 for events. + // The names are: sendTargets, members, roles, channels, + // messages, servers, variables + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ` + + + +
+

+

How To Use:

+ ● Put This Action After Your Send Message.
+ ● If Await Time Runs Out, Result Will Be timeout by "Default" +

+ +
+ Interaction Type
+ +
+
+ Source Message (ID ONLY)
+ +
+


+
+ Await Time (Miliseconds)
+ +
+
+ Await Timeout Value
+ +
+
+ +


+ + + +



+ A DBM-E Modification | Install DBM-E`; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + async action(cache) { + + const data = cache.actions[cache.index]; + + const type = this.evalMessage(data.type, cache) || 0 + const msgvar = this.evalMessage(data.msgvar, cache) || 0; { + if (isNaN(msgvar)) { + console.log(`------------ DBME ERROR ------------\n-> \"${msgvar}\" Is not a Message's ID!\n--------- Await Interaction --------\n`); + return + } + } + var time = this.evalMessage(data.time, cache) || 60000 + const timeout = this.evalMessage(data.timeout, cache) || "timeout" + const varName = this.evalMessage(data.varName, cache); + const storage = parseInt(data.storage, 10); + + if (msgvar === 0) { + var path = `last-interaction` + } else { + var path = `${msgvar}-interaction` + } + + const member = await this.getMemberFromData(1, undefined, cache); + (async () => { + const sleep = require('sleep-promise') + member.setData(path, undefined) + LABEL: do { + await sleep(500); + time = time - 500 + if (time < 500) { + this.storeValue(timeout, storage, varName, cache); + break LABEL + } + var result = member.data(path); + if (!!result) { + member.setData(path, undefined) + if (msgvar !== 0) { + var path2 = member.data(`message-interaction`) + if (!!path2) member.setData(path2, undefined) + } + this.storeValue(result, storage, varName, cache); + break LABEL + } else { + continue LABEL + } + } while (1) + this.callNextAction(cache); + })(); + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; diff --git a/actions/check_custom_data.js b/actions/check_custom_data.js new file mode 100644 index 0000000..b7e46bd --- /dev/null +++ b/actions/check_custom_data.js @@ -0,0 +1,152 @@ +module.exports = { + name: 'Check Custom Data', + section: 'Data', + fields: [ + 'filePath', + 'value', + 'branch', + 'jsonPath', + 'comparison', + 'varName', + 'storage', + ], + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/check_custom_data.js" }, + + subtitle(data, presets) { + return `${presets.getConditionsText(data)}`; + }, + + html() { + return ` +
+
+ Path
+ +
+ +
+ Data
+ +
+



+ +
+
+ Comparison Type
+ +
+ +
+ Value to Compare to
+ +
+



+ + +
+ + +`; + }, + + preInit(data, formatters) { + return formatters.compatibility_2_0_0_iftruefalse_to_branch(data); + }, + + init() {}, + + async action(cache) { + const data = cache.actions[cache.index]; + const Mods = this.getMods(); + const fs = Mods.require('fs-extra'); + const path = Mods.require('path') + const filepath = data.filePath; + const fpath = this.evalMessage(filepath, cache); + const compare = parseInt(data.comparison, 10); + let fileformat = path.extname(filepath) + let file = ''; + let json = '' + let val1 = ''; + let val2 = this.evalMessage(data.value, cache); + + let result = ''; + + if (fileformat == '.json') { + try { + + file = fs.readFileSync(fpath, 'utf8') + json = JSON.parse(file) + + let jsonPath = this.evalMessage(data.jsonPath, cache) + let split = jsonPath.split('/') + + for (let tt = 1; tt <= split.length - 1; tt++) { + jsonPath = jsonPath.replace('/', '"]["') + } + + jsonPath = jsonPath != '' ? `json["${jsonPath}"]` : 'json'; + + try { + + if (fileformat === '.json') { + file = fs.readFileSync(fpath, 'utf8') + let json = JSON.parse(file) + eval(`val1 = ${jsonPath}`) + + } else { + console.error(`the file format should be .json!`) + } + + } catch (e) { + console.error(e) + } + + } catch (err) { + val1 = undefined; + } + } + + switch (compare) { + case 0: + result = val1 !== undefined; + break; + case 1: + result = val1 == val2; + break; + case 2: + result = val1 === val2; + break; + case 3: + result = val1 < val2; + break; + case 4: + result = val1 > val2; + break; + case 5: + if (typeof val1.includes === "function") { + result = val1.includes(val2); + } + break; + case 6: + result = Boolean(val1.match(new RegExp(`^${val2}$`, "i"))); + break; + } + this.executeResults(result, data?.branch ?? data, cache); + }, + + modInit(data) { + this.prepareActions(data.branch?.iftrueActions); + this.prepareActions(data.branch?.iffalseActions); + }, + + mod() {}, +}; \ No newline at end of file diff --git a/actions/check_variable.js b/actions/check_variable.js new file mode 100644 index 0000000..4a1f39f --- /dev/null +++ b/actions/check_variable.js @@ -0,0 +1,270 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "Check Variable", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "Conditions", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + const comparisons = ['Exists', 'Equals', 'Equals Exactly', 'Less Than', 'Greater Than', 'Includes', 'Matches Regex', 'Length is Bigger Than', 'Length is Smaller Than', 'Length is Equals', 'Starts With', 'Ends With', 'Matches Full Regex', 'Less Than or Equal to', 'Greater Than or Equal to'] + const results = ['Continue Actions', 'Stop Action Sequence', 'Jump To Action', 'Jump Forward Actions', 'Jump to Anchor'] + return `${presets.getConditionsText(data)}`; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/check_variable.js" }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding IDs in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: ["storage", "varName", "comparison", "value", "branch", "iftrue", "iftrueVal", "iffalse", "iffalseVal"], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ` + + +


+ +
+
+ Comparison Type
+ +
+
+ Value to Compare to
+ +
+
+ +



+ +
+ +
+ +`; + }, + + //--------------------------------------------------------------------- + // Action Editor Pre-Init Code + // + // Before the fields from existing data in this action are applied + // to the user interface, this function is called if it exists. + // The existing data is provided, and a modified version can be + // returned. The returned version will be used if provided. + // This is to help provide compatibility with older versions of the action. + // + // The "formatters" argument contains built-in functions for formatting + // the data required for official DBM action compatibility. + //--------------------------------------------------------------------- + + preInit(data, formatters) { + return formatters.compatibility_2_0_0_iftruefalse_to_branch(data); + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() { + const { glob, document } = this; + + glob.onComparisonChanged = function (event) { + if (event.value === "0") { + document.getElementById("directValue").style.display = "none"; + } else { + document.getElementById("directValue").style.display = null; + } + switch (parseInt(event.value)) { + case 6: + document.getElementById('value').placeholder = "('My'|'Regex')" + break + case 12: + document.getElementById('value').placeholder = "/('My'|'Regex')\\w+/igm" + break + default: + document.getElementById('value').placeholder = '' + } + }; + + const option = document.createElement('OPTION') + option.value = '7' + option.text = 'Jump to Anchor' + const iffalse = document.getElementById('iffalse') + if (iffalse.length === 7) iffalse.add(option) + + const option2 = document.createElement('OPTION') + option2.value = '7' + option2.text = 'Jump to Anchor' + const iftrue = document.getElementById('iftrue') + if (iftrue.length === 7) iftrue.add(option2) + + glob.onComparisonChanged(document.getElementById("comparison")); + }, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + action(cache) { + const data = cache.actions[cache.index]; + const type = parseInt(data.storage, 10); + const varName = this.evalMessage(data.varName, cache); + const variable = this.getVariable(type, varName, cache); + let result = false; + + const val1 = variable; + const compare = parseInt(data.comparison, 10); + let val2 = data.value; + if (compare !== 6) val2 = this.evalIfPossible(val2, cache); + switch (compare) { + case 0: + result = val1 !== undefined; + break; + case 1: + result = val1 == val2; + break; + case 2: + result = val1 === val2; + break; + case 3: + result = val1 < val2; + break; + case 4: + result = val1 > val2; + break; + case 5: + if (typeof val1?.includes === "function") { + result = val1.includes(val2); + } + break; + case 6: + if (typeof val1?.match === "function") { + result = Boolean(val1.match(new RegExp("^" + val2 + "$", "i"))); + } + break; + case 7: + result = val1.length > val2 + break; + case 8: + result = val1.length < val2 + break; + case 9: + result = val1.length === val2 + break; + case 10: + result = val1.startsWith(val2) + break; + case 11: + result = val1.endsWith(val2) + break; + case 12: + result = Boolean(val1.match(new RegExp(val2))) + break; + case 13: + result = val1 <= val2 + break; + case 14: + result = val1 >= val2 + break; + default: + break; + } + + this.executeResults(result, data?.branch ?? data, cache); + }, + + //--------------------------------------------------------------------- + // Action Bot Mod Init + // + // An optional function for action mods. Upon the bot's initialization, + // each command/event's actions are iterated through. This is to + // initialize responses to interactions created within actions + // (e.g. buttons and select menus for Send Message). + // + // If an action provides inputs for more actions within, be sure + // to call the `this.prepareActions` function to ensure all actions are + // recursively iterated through. + //--------------------------------------------------------------------- + + modInit(data) { + this.prepareActions(data.branch?.iftrueActions); + this.prepareActions(data.branch?.iffalseActions); + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; diff --git a/actions/control_custom_data.js b/actions/control_custom_data.js new file mode 100644 index 0000000..b6c4c5a --- /dev/null +++ b/actions/control_custom_data.js @@ -0,0 +1,224 @@ +module.exports = { + name: 'Control Custom Data', + section: 'Data', + fields: [ + 'filePath', + 'task', + 'type', + 'valueName', + 'value', + 'jsonPath', + 'varName', + 'storage', + ], + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/control_custom_data.js" }, + + + subtitle(data) { + let task = '' + let type2 = '' + let filename = data.filePath !== '' ? data.filePath.split('/')[data.filePath.match(/[\/]/g).length] : ''; + let valuename = data.valueName + let nam = data.jsonPath ? data.jsonPath.split('/')[data.jsonPath.split('/').length - 1] : ''; + let val = data.type === "value" ? ` to ${data.value}` : ''; + let valName = data.task !== "add" ? valuename : nam; + + if (data.type === 'array') { + type2 = 'n array' + } else if (data.type === 'object') { + type2 = 'n object' + } else type2 = ' value' + + if (data.task === 'create') { + task = "Create / Edit a" + } else if (data.task === 'delete') { + task = "Delete a" + } else task = `Add ${data.valueName} to a`; + + if (filename === '') { + return `The file path is empty (Error!)` + } + + if (data.valueName === '') { + return `The value name is empty (Error!)` + } + + if (filename !== '' && data.valueName !== '') { + return `${task}${type2} ${valName}${val} in ${filename}` + } + + return `Ignore this message :3` + }, + + variableStorage(data, varType) { + if (parseInt(data.storage, 10) !== varType) return; + return [data.varName, 'Custom Data JSON']; + }, + + html() { + return ` +
+
+ Path
+ +
+ +
+ JSON path
+ +

+


+ +
+
+ Task
+ +
+ +
+ Type
+ +



+ +
+
+ Name
+ +
+ +
+ Value
+ +
+
+ +



+ +`; + }, + + init() { + const { glob, document } = this; + + glob.onArray = function (event) { + if (event.value === 'array' || 'object') { + document.getElementById('divalue').style.display = 'none'; + document.getElementById('divname').style.width = '100%'; + } else { + document.getElementById('divalue').style.display = null; + document.getElementById('divname').style.width = '50%'; + } + }; + + glob.onArray(document.getElementById('type')); + + glob.onDelete = function (event) { + if (event.value === 'delete') { + document.getElementById('divalue').style.display = 'none'; + document.getElementById('divname').style.width = '100%'; + } else { + document.getElementById('divalue').style.display = null; + document.getElementById('divname').style.width = '50%'; + } + }; + + glob.onDelete(document.getElementById('task')); + }, + + async action(cache) { + // DBM + const data = cache.actions[cache.index]; + const Mods = this.getMods(); + // Modules + const fs = Mods.require('fs-extra'); + const path = Mods.require('path'); + // Datas + const fpath = this.evalMessage(data.filePath, cache); + const valueName = this.evalMessage(data.valueName, cache); + const task = data.task; + const type = data.type; + const value = this.evalMessage(data.value, cache) ? this.evalMessage(data.value, cache) : false; + let jsonPath = this.evalMessage(data.jsonPath, cache) + // Other + let fileformat = path.extname(fpath) + let split = jsonPath.split('/') + let file = '' // + let json = '' // + + for (let tt = 1; tt <= split.length - 1; tt++) { + jsonPath = jsonPath.replace('/', '"]["') + } + + jsonPath = jsonPath != '' ? `json["${jsonPath}"]` : 'json'; + + + + // Script + if (fileformat == '.json') { // Checking for file format + + try { // Executing the script safely + + // Reading the file + file = fs.readFileSync(fpath, 'utf8') + json = JSON.parse(file) + + // Create Value + if (task == 'create' && type == 'value') { + eval(`${jsonPath}["${valueName}"] = ${value}`) + fs.writeFileSync(fpath, JSON.stringify(json, undefined, 4)) + } + + // Create Object + if (task == 'create' && type == 'object') { + eval(`${jsonPath}["${valueName}"] = {}`) + fs.writeFileSync(fpath, JSON.stringify(json, undefined, 4)) + } + + // Create Array + if (task == 'create' && type == 'array') { + eval(`${jsonPath}["${valueName}"] = []`) + fs.writeFileSync(fpath, JSON.stringify(json, undefined, 4)) + } + + // Add Array + if (task == 'add' && type == 'array') { + eval(`${jsonPath}.push("${valueName}")`) + fs.writeFileSync(fpath, JSON.stringify(json, undefined, 4)) + } + + // Delete All + if (task == 'delete') { + eval(`delete ${jsonPath}["${valueName}"]`) + fs.writeFileSync(fpath, JSON.stringify(json, undefined, 4)) + } + + } catch (err) { // Error! + if (err.message.includes('no such file or directory')) { + console.log(`Error: no such file or directory, open '${fpath}'`) + } else { + console.log(err) + } + } + + } else { // If the format is different, output an error + console.log(`The file format should be JSON Not ${fileformat !== '' ? `'${fileformat}'` : 'empty'}!!!`) + } + + const varName = this.evalMessage(data.varName, cache); + const storage = parseInt(data.storage, 10); + this.storeValue(json, storage, varName, cache); + + this.callNextAction(cache); + }, + + mod() {}, +}; \ No newline at end of file diff --git a/actions/create_custom_data.js b/actions/create_custom_data.js new file mode 100644 index 0000000..148d5cf --- /dev/null +++ b/actions/create_custom_data.js @@ -0,0 +1,66 @@ +module.exports = { + name: 'Create Custom Data File', + section: 'Data', + fields: [ + 'filePath', + 'fileName', + 'varName', + 'storage' + ], + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/create_custom_data.js" }, + + subtitle(data) { + if (data.filePath && data.fileName) { + return `Create ${data.filePath}${data.fileName}.json`; + } else { + return `Nothing to create (error)`; + } + }, + + variableStorage(data, varType) { + if (data.filePath && data.fileName) { + if (parseInt(data.storage, 10) !== varType) return; + return [data.varName, 'Data Path']; + } + }, + + html() { + return ` +
+
+ Path
+ +
+
+ Name
+ +
+



+ + + `; + }, + + init() {}, + + async action(cache) { + const data = cache.actions[cache.index]; + const Mods = this.getMods(); + const fs = Mods.require('fs-extra'); + + const result = data.filePath && data.fileName ? `${data.filePath}${data.fileName}.json` : `Nothing to create (error)`; + const varName = this.evalMessage(data.varName, cache); + const storage = parseInt(data.storage, 10); + let fileExists = false + this.storeValue(result, storage, varName, cache); + + if (data.filePath && data.fileName) { + fs.pathExistsSync(`${data.filePath}/${data.fileName}.json`) ? console.log('File already exists!') : fs.writeFileSync(`${data.filePath}/${data.fileName}.json`, '{}') + } + + this.callNextAction(cache); + }, + + mod() {}, +}; \ No newline at end of file diff --git a/actions/disconnect_user_MOD.js b/actions/disconnect_user_MOD.js new file mode 100644 index 0000000..9e10736 --- /dev/null +++ b/actions/disconnect_user_MOD.js @@ -0,0 +1,129 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "Disconnect Member", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "Mods", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + return `${presets.getMemberText(data.member, data.varName)}`; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/disconnect_user_MOD.js" }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding IDs in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: ["member", "varName", "reason"], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + // + // The "data" parameter stores constants for select elements to use. + // Each is an array: index 0 for commands, index 1 for events. + // The names are: sendTargets, members, roles, channels, + // messages, servers, variables + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ` + + +


+ +
+ Reason
+ +
`; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + action(cache) { + const data = cache.actions[cache.index]; + const type = parseInt(data.member, 10); + const varName = this.evalMessage(data.varName, cache); + const member = this.getMember(type, varName, cache); + const reason = this.evalMessage(data.reason, cache); + if (Array.isArray(member)) { + this.callListFunc( + member.map((m) => m.voice), + "disconnect", + [reason], + ).then(() => this.callNextAction(cache)); + } else if (member?.voice.disconnect) { + member + .voice.disconnect(reason) + .then(() => this.callNextAction(cache)) + .catch((err) => this.displayError(data, cache, err)); + } else { + this.callNextAction(cache); + } + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; diff --git a/actions/end_action_container.js b/actions/end_action_container.js new file mode 100644 index 0000000..cf0ecd7 --- /dev/null +++ b/actions/end_action_container.js @@ -0,0 +1,106 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "End Actions Within Container", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "DBM-Enhanced", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + return ""; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/end_action_container.js" }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding Ids in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: [], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + // + // The "data" parameter stores constants for select elements to use. + // Each is an array: index 0 for commands, index 1 for events. + // The names are: sendTargets, members, roles, channels, + // messages, servers, variables + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ""; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + async action(cache) { + const member = await this.getMemberFromData(1, undefined, cache); + member.setData('end-action-sequence' , 1); + member.setData('end-stop-master' , 1); + this.endActions(cache); + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; diff --git a/actions/end_action_sequence.js b/actions/end_action_sequence.js new file mode 100644 index 0000000..ab07bff --- /dev/null +++ b/actions/end_action_sequence.js @@ -0,0 +1,103 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "End Action Sequence", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "DBM-Enhanced", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + return ""; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/end_action_sequence.js" }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding Ids in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: [], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + // + // The "data" parameter stores constants for select elements to use. + // Each is an array: index 0 for commands, index 1 for events. + // The names are: sendTargets, members, roles, channels, + // messages, servers, variables + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ""; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + action(cache) { + this.endActions(cache); + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; diff --git a/actions/end_if_ended.js b/actions/end_if_ended.js new file mode 100644 index 0000000..ba83f7d --- /dev/null +++ b/actions/end_if_ended.js @@ -0,0 +1,146 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "End If Ended", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "DBM-Enhanced", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + return ""; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/end_if_ended.js" }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding Ids in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: ["type", "type2"], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + // + // The "data" parameter stores constants for select elements to use. + // Each is an array: index 0 for commands, index 1 for events. + // The names are: sendTargets, members, roles, channels, + // messages, servers, variables + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ` +
+ Behavior Type
+

+
+
+ Branch Behavior
+ +
`; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + async action(cache) { + const member = await this.getMemberFromData(1, undefined, cache); + const data = cache.actions[cache.index]; + if (member.data('end-action-sequence', 0) === 1) { + if (parseInt(data.type) === 0) { + member.setData('end-action-sequence', 0); + if (member.data('end-stop-master') === 1) {member.setData('end-stop-master', 0); this.endActions(cache);} else {this.callNextAction(cache)} + } else { + if (parseInt(data.type2) === 0) { + member.setData('end-stop-master', 1); + this.endActions(cache) + } else { + member.setData('end-stop-master', 0); + this.endActions(cache); + } + + } + } else { + if (parseInt(data.type) === 0) { + if (member.data('end-stop-master') === 1) { + member.setData('end-stop-master', 0); + this.endActions(cache); + } else { + this.callNextAction(cache) + } + } else { + this.callNextAction(cache); + } +; + } + + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; diff --git a/actions/go_to_anchor.js b/actions/go_to_anchor.js new file mode 100644 index 0000000..e155f6b --- /dev/null +++ b/actions/go_to_anchor.js @@ -0,0 +1,116 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "Go To Action Anchor", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "Other Stuff", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + return data.anchorName + ? `${data.description}` + : `Jump to ${ + data.jump_to_anchor + ? `the "${data.anchorName}" anchor in your command if it exists!` + : 'an anchor!' + }`; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/go_to_anchor.js" }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding IDs in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: ["description", "anchorName", "color"], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ` +Action Anchor Name + +
+
+ Anchor Color:
+
+
+
+ Description:
+
+
`; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + action(cache) { + const data = cache.actions[cache.index]; + const anchorName = this.evalMessage(data.anchorName, cache); + cache.goToAnchor(anchorName); + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; diff --git a/actions/run_script_colorable_MOD.js b/actions/run_script_colorable_MOD.js new file mode 100644 index 0000000..2b8cb77 --- /dev/null +++ b/actions/run_script_colorable_MOD.js @@ -0,0 +1,158 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "Run Script Colorable", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "Other Stuff", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + return `${data.code}`; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/run_script_colorable_MOD.js" }, + + //--------------------------------------------------------------------- + // Action Storage Function + // + // Stores the relevant variable info for the editor. + //--------------------------------------------------------------------- + + variableStorage(data, varType) { + const type = parseInt(data.storage, 10); + if (type !== varType) return; + return [data.varName, "Unknown Type"]; + }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding Ids in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: ["behavior", "interpretation", "code", "storage", "varName", "color"], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + // + // The "data" parameter stores constants for select elements to use. + // Each is an array: index 0 for commands, index 1 for events. + // The names are: sendTargets, members, roles, channels, + // messages, servers, variables + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ` +
+
+ Text Color:
+
+
+ End Behavior
+ +
+
+ Interpretation Style
+ +
+
+ +


+ +
+ Custom Code
+ +
+ +
+ +`; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + action(cache) { + const data = cache.actions[cache.index]; + let code; + if (data.interpretation === "0") { + code = this.evalMessage(data.code, cache); + } else { + code = data.code; + } + const result = this.eval(code, cache); + const varName = this.evalMessage(data.varName, cache); + const storage = parseInt(data.storage, 10); + this.storeValue(result, storage, varName, cache); + if (data.behavior === "0") { + this.callNextAction(cache); + } + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; diff --git a/actions/send_message.js b/actions/send_message.js new file mode 100644 index 0000000..70678af --- /dev/null +++ b/actions/send_message.js @@ -0,0 +1,993 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "Send Message", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "Messaging", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + let text = ""; + if (data.message) { + text = `"${data.message.replace(/[\n\r]+/, " ↲ ")}"`; + } else if (data.embeds?.length > 0) { + text = `${data.embeds.length} Embeds`; + } else if (data.attachments?.length > 0) { + text = `${data.attachments.length} Attachments`; + } else if (data.buttons?.length > 0 || data.selectMenus?.length > 0) { + text = `${data.buttons.length} Buttons and ${data.selectMenus.length} Select Menus`; + } else if (data.editMessage && data.editMessage !== "0") { + text = `Message Options - ${presets.getVariableText(data.editMessage, data.editMessageVarName)}`; + } else { + text = `Nothing (might cause error)`; + } + if (data.dontSend) { + return `Store Data: ${text}`; + } + return `${presets.getSendReplyTargetText(data.channel, data.varName)}: ${text}`; + }, + + //--------------------------------------------------------------------- + // Action Storage Function + // + // Stores the relevant variable info for the editor. + //--------------------------------------------------------------------- + + variableStorage(data, varType) { + const type = parseInt(data.storage, 10); + if (type !== varType) return; + return [data.varName2, data.dontSend ? "Message Options" : "Message"]; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/send_message.js" }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding IDs in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: [ + "channel", + "varName", + "message", + "buttons", + "selectMenus", + "attachments", + "embeds", + "reply", + "nointeraction", + "ephemeral", + "tts", + "overwrite", + "dontSend", + "editMessage", + "editMessageVarName", + "storage", + "varName2", + ], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ` + + +


+ + + + + +
+ +
+
+ + + +
+ + +
+ + + + +
+
+ Title
+ + +
+ + Color
+ +
+ +
+ URL
+ + +
+ + Use Timestamp
+ +
+ +






+ +
+ +
+ + Image URL
+ + +
+ + Thumbnail URL
+ +
+
+ + +
+ +
+
+ + +
+ +
+
+ Field Name
+ +
+ +
+ Inline?
+ +
+ +



+ + Field Value
+ + +
+
+
+
+ + +
+ Author Text
+ + +
+ + Author URL
+ + +
+ + Author Icon URL
+ +
+
+ + +
+ Footer Icon URL
+ + +
+ + Footer Text
+ +
+
+ +
+ +
+
+ +
+
+ + + +
+ + +
+
+ Name + + +
+ + Type
+ + +
+ + Link URL + + +
+ + + Action Response Mode + +
+ + +
+ + Appear Options + + + +
+ + Color Options + + + +
+
+ Unique ID + + +
+ + Action Row (1 - 5) + + +
+ + Emoji + + +
+ + Temporary Time-Limit (Miliseconds) + + +
+ + Disable Options + + +
+ +



















+ + + +
+
+ +
+
+ + + +
+ + +
+
+ Placeholder + + +
+ + Temp Variable Name + + +
+ + Minimum Select Number + + +
+ + + Action Response Mode + +
+ +
+
+ Unique ID + + +
+ + Action Row (1 - 5) + + +
+ + Maximum Select Number + + +
+ + Temporary Time-Limit (Miliseconds) + +
+
+ + +
+ Name + + +
+ + Description + + +
+ + Value + + +
+ + Emoji + + +
+ + Default Selected
+ +
+
+ +
+ +















+ + + + + +
+
+ +
+
+ + + +
+ + +
+ Attachment Local/Web URL + + +
+ + Attachment Name + + +
+ +
+ +
+
+
+
+
+ + + +
+ + + + + + +

+ +
+ + + + + +
+ +
+ +
+ +
+ +
+ + + +
+ +


+ +
+ +
+ +

+ +
+
+
+
`; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Editor On Save + // + // When the data for the action is saved, this function is called. + // It provides the ability to modify the final data associated with + // the action by retrieving it as an argument and returning a modified + // version through the return value. This can be used to verify the + // data and fill required entries the user did not. + // + // Its inclusion within action mods is optional. + //--------------------------------------------------------------------- + + onSave(data, helpers) { + // generate unique ids if not provided by user since they are important + if (Array.isArray(data?.buttons)) { + for (let i = 0; i < data.buttons.length; i++) { + if (!data.buttons[i].id) { + data.buttons[i].id = "msg-button-" + helpers.generateUUID().substring(0, 7); + } + } + } + if (Array.isArray(data?.selectMenus)) { + for (let i = 0; i < data.selectMenus.length; i++) { + if (!data.selectMenus[i].id) { + data.selectMenus[i].id = "msg-select-" + helpers.generateUUID().substring(0, 7); + } + } + } + return data; + }, + + //--------------------------------------------------------------------- + // Action Editor On Paste + // + // When the data for the action is pasted, this function is called. + // It provides the ability to modify the final data associated with + // the action by retrieving it as an argument and returning a modified + // version through the return value. + // + // Its inclusion within action mods is optional. + //--------------------------------------------------------------------- + + onPaste(data, helpers) { + if (Array.isArray(data?.buttons)) { + for (let i = 0; i < data.buttons.length; i++) { + const id = data.buttons[i].id; + if (!id || id.startsWith("msg-button-")) { + data.buttons[i].id = "msg-button-" + helpers.generateUUID().substring(0, 7); + } + } + } + if (Array.isArray(data?.selectMenus)) { + for (let i = 0; i < data.selectMenus.length; i++) { + const id = data.selectMenus[i].id; + if (!id || id.startsWith("msg-select-")) { + data.selectMenus[i].id = "msg-select-" + helpers.generateUUID().substring(0, 7); + } + } + } + return data; + }, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + async action(cache) { + const data = cache.actions[cache.index]; + + const channel = parseInt(data.channel, 10); + const message = data.message; + if (data.channel === undefined || message === undefined) { + return; + } + + let target = await this.getSendReplyTarget(channel, this.evalMessage(data.varName, cache), cache); + + let messageOptions = {}; + + const overwrite = data.overwrite; + + let isEdit = 0; + if(data.editMessage === "intUpdate") { + isEdit = 2; + } else { + const editMessage = parseInt(data.editMessage, 10); + if (typeof editMessage === "number" && editMessage >= 0) { + const editVarName = this.evalMessage(data.editMessageVarName, cache); + const editObject = this.getVariable(editMessage, editVarName, cache); + const { Message } = this.getDBM().DiscordJS; + if (editObject) { + if (editObject instanceof Message) { + target = editObject; + isEdit = 1; + } else { + messageOptions = editObject; + } + } + } + } + + + const content = this.evalMessage(message, cache); + if (content) { + if (messageOptions.content && !overwrite) { + messageOptions.content += content; + } else { + messageOptions.content = content; + } + } + + if (data.embeds?.length > 0) { + const { MessageEmbed } = this.getDBM().DiscordJS; + + if (!Array.isArray(messageOptions.embeds) || overwrite) { + messageOptions.embeds = []; + } + + const embedDatas = data.embeds; + for (let i = 0; i < embedDatas.length; i++) { + const embedData = embedDatas[i]; + const embed = new MessageEmbed(); + + if (embedData.title) embed.setTitle(this.evalMessage(embedData.title, cache)); + if (embedData.url) embed.setURL(this.evalMessage(embedData.url, cache)); + if (embedData.color) embed.setColor(this.evalMessage(embedData.color, cache)); + if (embedData.timestamp === "true") embed.setTimestamp(); + if (embedData.imageUrl) embed.setImage(this.evalMessage(embedData.imageUrl, cache)); + if (embedData.thumbUrl) embed.setThumbnail(this.evalMessage(embedData.thumbUrl, cache)); + + if (embedData.description) embed.setDescription(this.evalMessage(embedData.description, cache)); + + if (embedData.fields?.length > 0) { + const fields = embedData.fields; + for (let i = 0; i < fields.length; i++) { + const f = fields[i]; + embed.addField(this.evalMessage(f.name, cache), this.evalMessage(f.value, cache), f.inline === "true"); + } + } + + if (embedData.author) { + embed.setAuthor({ + name: this.evalMessage(embedData.author, cache), + iconURL: embedData.authorIcon ? this.evalMessage(embedData.authorIcon, cache) : null, + url: embedData.authorUrl ? this.evalMessage(embedData.authorUrl, cache) : null, + }); + } + + if (embedData.footerText) { + embed.setFooter({ + text: this.evalMessage(embedData.footerText, cache), + iconURL: embedData.footerIconUrl ? this.evalMessage(embedData.footerIconUrl, cache) : null, + }); + } + + messageOptions.embeds.push(embed); + } + } + + let componentsArr = []; + let awaitResponses = []; + + if (!overwrite && messageOptions.components?.length > 0) { + componentsArr = messageOptions.components.map(function (comps) { + return comps.components; + }); + } + + const defaultTime = 60000; + + if (Array.isArray(data.buttons)) { + for (let i = 0; i < data.buttons.length; i++) { + const button = data.buttons[i]; + var buttonData = this.generateButton(button, cache); + var btn_appear_or_not = this.evalMessage(button["appear_or_not"],cache) + var btn_disabled_or_not = this.evalMessage(button["disabled_or_not"],cache) + var btn_color_overwrite = this.evalMessage(button["color_overwrite"],cache) + + if (btn_appear_or_not) { + if (btn_appear_or_not.toString() !== '1' || btn_appear_or_not.toString().toLowerCase() !== 'yes' || btn_appear_or_not.toString().toLowerCase() !== 'true') continue + } + + if (btn_disabled_or_not) { + if (btn_disabled_or_not.toString() === '1' || btn_disabled_or_not.toString().toLowerCase() === 'yes' || btn_disabled_or_not.toString().toLowerCase() === 'true') { + finalstep(1) + } else { + finalstep(0) + } + } else if (!btn_disabled_or_not) { + if (button.id.includes("disabled") === true) { + finalstep(1) + } else { + finalstep(0) + } + } + + function finalstep(string) { + if (btn_color_overwrite) { + if (Number(btn_color_overwrite) > 0 && Number(btn_color_overwrite) < 6) { + switch (Number(btn_color_overwrite)) { + case 1: + buttonData.style = 'PRIMARY' + break; + case 2: + buttonData.style = 'SECONDARY' + break; + case 3: + buttonData.style = 'SUCCESS' + break; + case 4: + buttonData.style = 'DANGER' + break; + case 5: + buttonData.style = 'LINK' + break; + } + } + } + if (string) { + if (Number(string) === 1) { + buttonData.disabled = true + } + } + } + + if (buttonData) { + if (!buttonData["custom_id"] && buttonData.style !== 'LINK') { + buttonData.custom_id = button.id + delete buttonData.url + } else if (buttonData.style === 'LINK') { + delete buttonData.custom_id + if (!buttonData.url) { + button.actions = '[Object object]' + var showbtn = {} + console.error(`-------------------------------------------`, `\n[DBME] SEND MESSAGE ERROR: URL Missing On Button!\n\nButton: `, button); + return + } + } + } + this.addButtonToActionRowArray(componentsArr, this.evalMessage(button.row, cache), buttonData, cache); + + if (button.mode !== "PERSISTENT") { + awaitResponses.push({ + type: "BUTTON", + time: button.time ? parseInt(this.evalMessage(button.time, cache)) || defaultTime : defaultTime, + id: this.evalMessage(button.id, cache), + user: button.mode.endsWith("PERSONAL") ? cache.getUser()?.id : null, + multi: button.mode.startsWith("MULTI"), + data: button, + }); + } + } + } + + if (Array.isArray(data.selectMenus)) { + for (let i = 0; i < data.selectMenus.length; i++) { + const select = data.selectMenus[i]; + const selectData = this.generateSelectMenu(select, cache); + this.addSelectToActionRowArray(componentsArr, this.evalMessage(select.row, cache), selectData, cache); + + if (select.mode !== "PERSISTENT") { + awaitResponses.push({ + type: "SELECT", + time: select.time ? parseInt(this.evalMessage(select.time, cache)) || defaultTime : defaultTime, + id: this.evalMessage(select.id, cache), + user: select.mode.endsWith("PERSONAL") ? cache.getUser()?.id : null, + multi: select.mode.startsWith("MULTI"), + data: select, + }); + } + } + } + + if (messageOptions._awaitResponses?.length > 0) { + if (overwrite && awaitResponses.length > 0) { + messageOptions._awaitResponses = []; + } else { + awaitResponses = messageOptions._awaitResponses.concat(awaitResponses); + } + } + + if (componentsArr.length > 0) { + const newComponents = componentsArr + .filter((comps) => comps.length > 0) + .map(function (comps) { + return { + type: "ACTION_ROW", + components: comps, + }; + }); + + messageOptions.components = newComponents; + } + + if (data.tts) { + messageOptions.tts = true; + } + + if (data.attachments?.length > 0) { + const { Util, MessageAttachment } = this.getDBM().DiscordJS; + if (!Array.isArray(messageOptions.files) || overwrite) { + messageOptions.files = []; + } + for (let i = 0; i < data.attachments.length; i++) { + const attachment = data.attachments[i]; + const url = this.evalMessage(attachment?.url, cache); + if (url) { + const spoiler = !!attachment?.spoiler; + const name = attachment?.name || (spoiler ? Util.basename(url) : undefined); + const msgAttachment = new MessageAttachment(url, name); + if (spoiler) { + msgAttachment.setSpoiler(true); + } + messageOptions.files.push(msgAttachment); + } + } + } + + let defaultResultMsg = null; + const onComplete = (resultMsg) => { + if (defaultResultMsg) { + resultMsg ??= defaultResultMsg; + } + + if (resultMsg) { + const varName2 = this.evalMessage(data.varName2, cache); + const storage = parseInt(data.storage, 10); + this.storeValue(resultMsg, storage, varName2, cache); + this.callNextAction(cache); + + for (let i = 0; i < awaitResponses.length; i++) { + const response = awaitResponses[i]; + const originalInteraction = cache.interaction?.__originalInteraction ?? cache.interaction; + const tempVariables = cache.temp || {}; + this.registerTemporaryInteraction(resultMsg.id, response.time, response.id, response.user, response.multi, (interaction) => { + if (response.data) { + interaction.__originalInteraction = originalInteraction; + if (response.type === "BUTTON") { + this.preformActionsFromInteraction(interaction, response.data, cache.meta, tempVariables); + } else { + this.preformActionsFromSelectInteraction(interaction, response.data, cache.meta, tempVariables); + } + } + }); + } + } else { + this.callNextAction(cache); + } + }; + + const isMessageTarget = target instanceof this.getDBM().DiscordJS.Message; + + const sameId = target?.id?.length > 0 && (target?.id ?? "") === cache?.interaction?.channel?.id; + const sameChannel = channel === 0 || sameId; + const canReply = !isMessageTarget && cache?.interaction?.replied === false && sameChannel; + + if (data.dontSend) { + const varName2 = this.evalMessage(data.varName2, cache); + const storage = parseInt(data.storage, 10); + messageOptions._awaitResponses = awaitResponses; + this.storeValue(messageOptions, storage, varName2, cache); + this.callNextAction(cache); + } + + else if (Array.isArray(target)) { + this.callListFunc(target, "send", [messageOptions]).then(onComplete); + } + + else if (isEdit === 2 && cache?.interaction?.update) { + let promise = null; + + defaultResultMsg = cache.interaction?.message; + + if (cache.interaction?.replied && cache.interaction?.editReply) { + promise = cache.interaction.editReply(messageOptions); + } else { + promise = cache.interaction.update(messageOptions); + } + + if (promise) { + promise + .then(onComplete) + .catch((err) => this.displayError(data, cache, err)); + } + } + + else if (isEdit === 1 && target?.edit) { + if (data.nointeraction === true) { + messageOptions["components"] = []; + } + target + .edit(messageOptions) + .then(onComplete) + .catch((err) => this.displayError(data, cache, err)); + } + + else if (isMessageTarget && target?.reply) { + target + .reply(messageOptions) + .then(onComplete) + .catch((err) => this.displayError(data, cache, err)); + } + + else if (data.reply === true && canReply) { + messageOptions.fetchReply = true; + if (data.ephemeral === true) { + messageOptions.ephemeral = true; + } + let promise = null; + if (cache.interaction.deferred) { + promise = cache.interaction.editReply(messageOptions); + } else { + promise = cache.interaction.reply(messageOptions); + } + promise.then(onComplete).catch((err) => this.displayError(data, cache, err)); + } + + else if (target?.send) { + target + .send(messageOptions) + .then(onComplete) + .catch((err) => this.displayError(data, cache, err)); + } + + else { + this.callNextAction(cache); + } + }, + + //--------------------------------------------------------------------- + // Action Bot Mod Init + // + // An optional function for action mods. Upon the bot's initialization, + // each command/event's actions are iterated through. This is to + // initialize responses to interactions created within actions + // (e.g. buttons and select menus for Send Message). + // + // If an action provides inputs for more actions within, be sure + // to call the `this.prepareActions` function to ensure all actions are + // recursively iterated through. + //--------------------------------------------------------------------- + + modInit(data) { + if (Array.isArray(data?.buttons)) { + for (let i = 0; i < data.buttons.length; i++) { + const button = data.buttons[i]; + if (button.mode === "PERSISTENT") { + this.registerButtonInteraction(button.id, button); + } + this.prepareActions(button.actions); + } + } + if (Array.isArray(data?.selectMenus)) { + for (let i = 0; i < data.selectMenus.length; i++) { + const select = data.selectMenus[i]; + if (select.mode === "PERSISTENT") { + this.registerSelectMenuInteraction(select.id, select); + } + this.prepareActions(select.actions); + } + } + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; + diff --git a/actions/show_modal.js b/actions/show_modal.js new file mode 100644 index 0000000..7fc663f --- /dev/null +++ b/actions/show_modal.js @@ -0,0 +1,337 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "Show Modal Window", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "Messaging", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + if(!data.uniq || data.inputs.length == 0 || !data.title) { + return "You have not filled in the required fields!" + } else { + let title = data.title + let inputs = data.inputs.length + return `Open a modal window "${title}" with ${inputs} fields` + } + }, + + //--------------------------------------------------------------------- + // Action Storage Function + // + // Stores the relevant variable info for the editor. + //--------------------------------------------------------------------- + + variableStorage(data, varType, cache) { + if(varType !== 1) return + return [data.uniq.replace("msg-", "modal-"), "Input Text"]; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/show_modal.js" }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding IDs in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: [ + "inputs", + "title", + "uniq", + ], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ` + +
+ Window Title
+ +
+
+ Unique ID
+ +



+ +
+
+ Label
+ +
+
+ Unique ID
+ +



+
+ Type
+ +
+
+ + Text Length
+ + +
+
+ Start Value
+ +



+
+ Placeholder
+ +
+
+ Set Required
+ +




+ +
+ Text from this field will be saved in + +
+
+

+ +
+ Modal windows can only be opened with a slash command or a button or select menu +

+
+ Attention!
+ Modal windows are an event they don't support "reply" and "ephemeral" messages
+ but it support buttons and select menus
+
+ `; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Editor On Save + // + // When the data for the action is saved, this function is called. + // It provides the ability to modify the final data associated with + // the action by retrieving it as an argument and returning a modified + // version through the return value. This can be used to verify the + // data and fill required entries the user did not. + // + // Its inclusion within action mods is optional. + //--------------------------------------------------------------------- + + onSave(data, helpers, cache) { + for(let i = 0; i < data.inputs.length; i++) { + data.inputs[i].ssd = `\$\{tempVars("${data.uniq.replace("msg-", "modal-")}")[${i}]}` + if(data.inputs[i].uniqID == '') { + data.inputs[i].uniqID = `msg-modal-${helpers.generateUUID().substring(0, 7)}` + } + } + return data; + }, + + //--------------------------------------------------------------------- + // Action Editor On Paste + // + // When the data for the action is pasted, this function is called. + // It provides the ability to modify the final data associated with + // the action by retrieving it as an argument and returning a modified + // version through the return value. + // + // Its inclusion within action mods is optional. + //--------------------------------------------------------------------- + + onPaste(data, helpers) { + if(data.uniq == '') { + data.uniq = `msg-${helpers.generateUUID().substring(0, 7)}` + } + + for(let i = 0; i < data.inputs.length; i++) { + data.inputs[i].ssd = `\$\{tempVars("${data.uniq.replace("msg-", "modal-")}")[${i}]}` + if(data.inputs[i].uniqID == '') { + data.inputs[i].uniqID = `msg-modal-${helpers.generateUUID().substring(0, 7)}` + } + } + return data; + }, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + async action(cache) { + const data = cache.actions[cache.index]; + const { Modal, TextInputComponent, showModal } = require('discord-modals') // Now we extract the showModal method + const discordModals = require('discord-modals') + const title = this.evalMessage(data.title, cache) + const CustomId = this.evalMessage(data.uniq, cache) + let components = [] + + const Bot = this.getDBM().Bot + const client = Bot.bot + discordModals(client); + + for(let i = 0; i < data.inputs.length; i++) { + const uniqueId = this.evalMessage(data.inputs[i].uniqID, cache) + const label = this.evalMessage(data.inputs[i].label, cache) + const min = this.evalMessage(data.inputs[i].min, cache) + const max = this.evalMessage(data.inputs[i].max, cache) + const placeholder = this.evalMessage(data.inputs[i].plholder, cache) + + components.push( + new TextInputComponent() // We create a Text Input Component + .setCustomId(uniqueId) + .setLabel(label) + .setStyle(data.inputs[i].type) //IMPORTANT: Text Input Component Style can be 'SHORT' or 'LONG' + .setMinLength(min) + .setMaxLength(max) + .setPlaceholder(placeholder) + .setRequired(data.inputs[i].req) // If it's required or not + ) + } + + let resultd = [] + const modal = new Modal() + .setTitle(title) + .setCustomId(CustomId) + .addComponents(components) + showModal(modal, { + client: client, // Client to show the Modal through the Discord API. + interaction: cache.interaction // Show the modal with interaction data. + }) + + Bot.bot.on('modalSubmit', async (modal) => { + if(modal.customId === CustomId){ + for(let i = 0; i < data.inputs.length; i++) { + resultd.push(modal.getTextInputValue(data.inputs[i].uniqID)) + } + await modal.reply({ ephemeral: true }).catch(e => console.log("")) + await modal.deleteReply().catch(e => console.log("")) + await this.storeValue(resultd, 1, CustomId.replace("msg-", "modal-"), cache); + await this.callNextAction(cache) + } + }); + + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +}; \ No newline at end of file diff --git a/actions/store_custom_data.js b/actions/store_custom_data.js new file mode 100644 index 0000000..02f7be4 --- /dev/null +++ b/actions/store_custom_data.js @@ -0,0 +1,104 @@ +module.exports = { + name: 'Store Custom Data', + section: 'Data', + fields: [ + 'filePath', + 'valueName', + 'jsonPath', + 'varName', + 'storage', + ], + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/store_custom_data.js" }, + + subtitle(data) { + let filepath = data.filePath; + let filename = filepath !== '' ? filepath.split('/')[filepath.match(/[\/]/g).length] : ''; + let match = data.jsonPath.split('/')[data.jsonPath.split('.').length - 1] + if (data.filePath !== '' && data.jsonPath !== '' && data.varName !== '') { + return `Store ${match} from ${filename} to ${data.varName}` + } + + if (data.filePath !== '' && data.dataField !== '' && data.varName == '') { + return `Store ${match} from ${filename} but not to a variable` + } + + if (data.filePath == '') { + return `File path is empty ( Error! )` + } + + if (data.dataField == '') { + return `Data field is empty ( Error! )` + } + }, + + variableStorage(data, varType) { + if (parseInt(data.storage, 10) !== varType) return; + return [data.varName, 'Custom Data']; + }, + + html() { + return ` +
+
+ Path
+ +
+ +
+ JSON path
+ +
+



+ +
+ +`; + }, + + init() {}, + + async action(cache) { + // DBM + const data = cache.actions[cache.index]; + const Mods = this.getMods(); + let result = ''; + // Modules + const fs = Mods.require('fs-extra'); + const path = Mods.require('path') + // Datas + const fpath = this.evalMessage(data.filePath, cache) + let jsonPath = this.evalMessage(data.jsonPath, cache) + let fileformat = path.extname(fpath); + let split = jsonPath.split('/') + + for (let tt = 1; tt <= split.length - 1; tt++) { + jsonPath = jsonPath.replace('/', '"]["') + } + + jsonPath = jsonPath != '' ? `json["${jsonPath}"]` : 'json'; + // Script + try { + + if (fileformat === '.json') { + file = fs.readFileSync(fpath, 'utf8') + let json = JSON.parse(file) + eval(`result = ${jsonPath}`) + + } else { + console.error(`the file format should be .json!`) + } + + } catch (e) { + console.error(e) + } + + const varName = this.evalMessage(data.varName, cache); + const storage = parseInt(data.storage, 10); + this.storeValue(result, storage, varName, cache); + + this.callNextAction(cache); + }, + + mod() {}, +}; \ No newline at end of file diff --git a/actions/store_voice_channel_info_MOD.js b/actions/store_voice_channel_info_MOD.js new file mode 100644 index 0000000..24b4466 --- /dev/null +++ b/actions/store_voice_channel_info_MOD.js @@ -0,0 +1,202 @@ +module.exports = { + //--------------------------------------------------------------------- + // Action Name + // + // This is the name of the action displayed in the editor. + //--------------------------------------------------------------------- + + name: "Store Voice Channel Info V2", + + //--------------------------------------------------------------------- + // Action Section + // + // This is the section the action will fall into. + //--------------------------------------------------------------------- + + section: "Mods", + + //--------------------------------------------------------------------- + // Action Subtitle + // + // This function generates the subtitle displayed next to the name. + //--------------------------------------------------------------------- + + subtitle(data, presets) { + const info = [ + "Voice Channel Object", + "Voice Channel ID", + "Voice Channel Name", + "Voice Channel Position", + "Voice Channel User Limit", + "Voice Channel Bitrate", + "Voice Channel Connected Users" + ]; + return `${presets.getVoiceChannelText(data.channel, data.varName)} - ${info[parseInt(data.info, 10)]}`; + }, + + //--------------------------------------------------------------------- + // Action Meta Data + // + // Helps check for updates and provides info if a custom mod. + // If this is a third-party mod, please set "author" and "authorUrl". + // + // It's highly recommended "preciseCheck" is set to false for third-party mods. + // This will make it so the patch version (0.0.X) is not checked. + //--------------------------------------------------------------------- + + + meta: { version: "2.1.2", preciseCheck: true, author: "DBM Extended", authorUrl: "https://github.com/DBM-Extended/mods", downloadURL: "https://github.com/DBM-Extended/mods/tree/main/actions/store_voice_channel_info_MOD.js" }, + + //--------------------------------------------------------------------- + // Action Storage Function + // + // Stores the relevant variable info for the editor. + //--------------------------------------------------------------------- + + variableStorage(data, varType) { + const type = parseInt(data.storage, 10); + if (type !== varType) return; + const info = parseInt(data.info, 10); + let dataType = "Unknown Type"; + switch (info) { + case 0: + dataType = "Voice Channel"; + break; + case 1: + dataType = "Voice Channel ID"; + break; + case 2: + dataType = "Text"; + break; + case 3: + case 4: + case 5: + dataType = "Number"; + break; + } + return [data.varName2, dataType]; + }, + + //--------------------------------------------------------------------- + // Action Fields + // + // These are the fields for the action. These fields are customized + // by creating elements with corresponding IDs in the HTML. These + // are also the names of the fields stored in the action's JSON data. + //--------------------------------------------------------------------- + + fields: ["channel", "varName", "info", "storage", "varName2"], + + //--------------------------------------------------------------------- + // Command HTML + // + // This function returns a string containing the HTML used for + // editing actions. + // + // The "isEvent" parameter will be true if this action is being used + // for an event. Due to their nature, events lack certain information, + // so edit the HTML to reflect this. + // + // The "data" parameter stores constants for select elements to use. + // Each is an array: index 0 for commands, index 1 for events. + // The names are: sendTargets, members, roles, channels, + // messages, servers, variables + //--------------------------------------------------------------------- + + html(isEvent, data) { + return ` + + +


+ +
+ Source Info
+ +
+ +
+ +`; + }, + + //--------------------------------------------------------------------- + // Action Editor Init Code + // + // When the HTML is first applied to the action editor, this code + // is also run. This helps add modifications or setup reactionary + // functions for the DOM elements. + //--------------------------------------------------------------------- + + init() {}, + + //--------------------------------------------------------------------- + // Action Bot Function + // + // This is the function for the action within the Bot's Action class. + // Keep in mind event calls won't have access to the "msg" parameter, + // so be sure to provide checks for variable existence. + //--------------------------------------------------------------------- + + action(cache) { + const data = cache.actions[cache.index]; + const channel = parseInt(data.channel, 10); + const varName = this.evalMessage(data.varName, cache); + const info = parseInt(data.info, 10); + const targetChannel = this.getVoiceChannel(channel, varName, cache); + if (!targetChannel) { + this.callNextAction(cache); + return; + } + let result; + switch (info) { + case 0: + result = targetChannel; + break; + case 1: + result = targetChannel.id; + break; + case 2: + result = targetChannel.name; + break; + case 3: + result = targetChannel.position; + break; + case 4: + result = targetChannel.userLimit; + break; + case 5: + result = targetChannel.bitrate; + break; + case 6: + result = targetChannel.members.map(user => user); + break; + default: + break; + } + if (result !== undefined) { + const storage = parseInt(data.storage, 10); + const varName2 = this.evalMessage(data.varName2, cache); + this.storeValue(result, storage, varName2, cache); + } + this.callNextAction(cache); + }, + + //--------------------------------------------------------------------- + // Action Bot Mod + // + // Upon initialization of the bot, this code is run. Using the bot's + // DBM namespace, one can add/modify existing functions if necessary. + // In order to reduce conflicts between mods, be sure to alias + // functions you wish to overwrite. + //--------------------------------------------------------------------- + + mod() {}, +};