diff --git a/.gitignore b/.gitignore index a45912f..b57bba5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ devConfig5.json openticketdebug.txt developerChangelog.md storage/dynamicDB/ +storage/slashcmdEnabled.txt storage/.DS_Store .vscode/ livestatus.json diff --git a/core/dynamicdatabase/dynamicfiles/database.js b/core/dynamicdatabase/dynamicfiles/database.js new file mode 100644 index 0000000..f89955e --- /dev/null +++ b/core/dynamicdatabase/dynamicfiles/database.js @@ -0,0 +1,66 @@ +const fs = require("fs") +const location = "./storage/database.json" + + +/**@returns {[{category:String, key:String, value:String}]}*/ +function getData(){ + return JSON.parse(fs.readFileSync(location).toString()) +} +/**@param {[{category:String, key:String, value:String}]} data*/ +function setData(data){ + fs.writeFileSync(location,JSON.stringify(data,null,"\t")) +} + +exports.set = (category,key,value) => { + const currentData = getData() + const exists = currentData.find((d) => (d.category == category) && (d.key == key)) ? true : false + var newData = [] + if (exists){ + currentData.forEach((d,i) => { + if (d.category == category && d.key == key){ + newData.push({category,key,value}) + }else{ + newData.push(d) + } + }) + }else{ + currentData.push({category,key,value}) + newData = currentData + } + + setData(newData) + return exists +} +/** + * @param {String} category + * @param {String} key + * @returns {String|false} + */ +exports.get = (category,key) => { + const currentData = getData() + const tempresult = currentData.find((d) => (d.category == category) && (d.key == key)) + const result = tempresult ? tempresult.value : false + return result +} +/** + * @param {String} category + * @param {String} key + * @param {String} value + */ +exports.delete = (category,key) => { + const currentData = getData() + const exists = currentData.find((d) => (d.category == category) && (d.key == key)) ? true : false + var newData = [] + if (exists){ + currentData.forEach((d,i) => { + if (!(d.category == category && d.key == key)){ + newData.push(d) + } + }) + }else{ + newData = currentData + } + + setData(newData) + return exists +} \ No newline at end of file diff --git a/core/dynamicdatabase/dynamicfiles/local.js b/core/dynamicdatabase/dynamicfiles/local.js index fec0b6c..4ee9d79 100644 --- a/core/dynamicdatabase/dynamicfiles/local.js +++ b/core/dynamicdatabase/dynamicfiles/local.js @@ -36,4 +36,8 @@ exports.get = (category,id) => { exports.delete = (category,id) => { ls.removeItem(category+"--"+id) return true -} \ No newline at end of file +} + +this.set("category","key","value") +this.get("category","key",) +this.delete("category","key") \ No newline at end of file diff --git a/core/dynamicdatabase/storage.js b/core/dynamicdatabase/storage.js index 80ad75d..dcc4060 100644 --- a/core/dynamicdatabase/storage.js +++ b/core/dynamicdatabase/storage.js @@ -1,11 +1,7 @@ -//Do not change this without knowing what you are doing!! -const databaseFile = "local" -//Do not change this without knowing what you are doing!! - - try { - var db = require("./dynamicfiles/local") -}catch{ + var db = require("./dynamicfiles/database") +}catch(err){ + console.log(err) console.log("I couldn't find the database file! (location: ./core/dynamicdatabase/storage.js:2)") process.exit(1) } diff --git a/core/interactionHandlers/handlers/accepted/closing.js b/core/interactionHandlers/handlers/accepted/closing.js index 27dc578..17776aa 100644 --- a/core/interactionHandlers/handlers/accepted/closing.js +++ b/core/interactionHandlers/handlers/accepted/closing.js @@ -22,7 +22,9 @@ module.exports = () => { if (!interaction.isButton()) return if (interaction.customId != "OTcloseTicketTrue") return - interaction.deferUpdate() + try { + interaction.deferUpdate() + } catch{} if (closeTicketButtonChecker == true) return closeTicketButtonChecker = true diff --git a/core/interactionHandlers/handlers/sendTranscript.js b/core/interactionHandlers/handlers/sendTranscript.js index c1f1c65..6ac442c 100644 --- a/core/interactionHandlers/handlers/sendTranscript.js +++ b/core/interactionHandlers/handlers/sendTranscript.js @@ -20,7 +20,9 @@ module.exports = () => { if (!interaction.isButton()) return if (interaction.customId != "OTsendTranscript") return - interaction.deferUpdate() + try { + interaction.deferUpdate() + } catch{} const tsmsg = await interaction.channel.send({embeds:[bot.embeds.commands.sendTranscriptEmbed(false,interaction.channel,interaction.user)]}) const channelmessages = await interaction.channel.messages.fetch() diff --git a/core/interactionHandlers/handlers/verifyBars.js b/core/interactionHandlers/handlers/verifyBars.js index a365bcd..bb2ae74 100644 --- a/core/interactionHandlers/handlers/verifyBars.js +++ b/core/interactionHandlers/handlers/verifyBars.js @@ -20,7 +20,9 @@ module.exports = () => { if (!interaction.isButton()) return if (interaction.customId != "OTcloseTicket") return - interaction.deferUpdate() + try { + interaction.deferUpdate() + } catch{} interaction.message.edit({components:[bot.buttons.verifybars.closeVerifyBar]}) }) @@ -28,7 +30,9 @@ module.exports = () => { if (!interaction.isButton()) return if (interaction.customId != "OTcloseTicketFalse") return - interaction.deferUpdate() + try { + interaction.deferUpdate() + } catch{} interaction.message.edit({components:[bot.buttons.close.openRowNormal]}) }) @@ -37,7 +41,9 @@ module.exports = () => { if (!interaction.isButton()) return if (interaction.customId != "OTdeleteTicket") return - interaction.deferUpdate() + try { + interaction.deferUpdate() + } catch{} interaction.message.edit({components:[bot.buttons.verifybars.deleteVerifyBar]}) }) @@ -45,7 +51,9 @@ module.exports = () => { if (!interaction.isButton()) return if (interaction.customId != "OTdeleteTicketFalse") return - interaction.deferUpdate() + try { + interaction.deferUpdate() + } catch{} interaction.message.edit({components:[bot.buttons.close.openRowNormal]}) }) @@ -54,7 +62,9 @@ module.exports = () => { if (!interaction.isButton()) return if (interaction.customId != "OTdeleteTicket1") return - interaction.deferUpdate() + try { + interaction.deferUpdate() + } catch{} interaction.message.edit({components:[bot.buttons.verifybars.delete1VerifyBar]}) }) @@ -62,7 +72,9 @@ module.exports = () => { if (!interaction.isButton()) return if (interaction.customId != "OTdeleteTicketFalse1") return - interaction.deferUpdate() + try { + interaction.deferUpdate() + } catch{} interaction.message.edit({components:[bot.buttons.close.closeCommandRow]}) }) } \ No newline at end of file diff --git a/core/reactionRoles.js b/core/reactionRoles.js index de34b8f..fc8317a 100644 --- a/core/reactionRoles.js +++ b/core/reactionRoles.js @@ -16,14 +16,20 @@ module.exports = async () => { if (interaction.isButton() && !interaction.customId.startsWith("newR")) return if (interaction.isStringSelectMenu() && !(interaction.customId == "OTdropdownMenu")) return - interaction.deferUpdate() + + const optionidRaw = interaction.isStringSelectMenu() ? interaction.values[0] : interaction.customId + if (!optionidRaw.includes("newR")) return const optionid = optionidRaw.split("newR")[1] if (!optionid){ interaction.reply({embeds:[bot.errorLog.serverError(l.errors.roleDoesntExist)]}) return + }else{ + try { + interaction.deferUpdate() + } catch{} } try { @@ -53,14 +59,14 @@ module.exports = async () => { }else if (mode == "add&remove"){ option.roles.forEach((role) => { - if (interaction.guild.members.cache.find(u => u.id == user.id).roles.cache.has(role)){ - interaction.guild.members.cache.find(u => u.id == user.id).roles.remove(role) + if (!interaction.guild.members.cache.find(u => u.id == user.id).roles.cache.has(role)){ + interaction.guild.members.cache.find(u => u.id == user.id).roles.add(role) log("system","added role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}]) const apirole = interaction.guild.roles.cache.find(r => r.id == role) APIEvents.onReactionRole("add","add&remove",apirole,interaction.user,interaction.channel,interaction.guild,new Date()) }else { - interaction.guild.members.cache.find(u => u.id == user.id).roles.add(role) + interaction.guild.members.cache.find(u => u.id == user.id).roles.remove(role) log("system","removed role (reaction roles)",[{key:"user",value:interaction.user.tag},{key:"role",value:role}]) const apirole = interaction.guild.roles.cache.find(r => r.id == role) diff --git a/core/slashSystem/autoSlashUpdate.js b/core/slashSystem/autoSlashUpdate.js new file mode 100644 index 0000000..3ef73c6 --- /dev/null +++ b/core/slashSystem/autoSlashUpdate.js @@ -0,0 +1,88 @@ +const discord = require("discord.js") +const bot = require("../../index") +const client = require("../../index").client +const config = bot.config +const configParser = require("../utils/configParser") + +const act = discord.ApplicationCommandType +const acot = discord.ApplicationCommandOptionType + +module.exports = async () => { + bot.errorLog.log("info","auto-updating slash commands...") + const sid = config.server_id + + const ids = configParser.getTicketValuesArray("id") + /**@type {[{name:String,value:String}]} */ + var choices = [] + ids.forEach((id) => { + const option = configParser.getTicketById(id) + if (option){ + choices.push({name:option.name,value:option.id}) + } + }) + + /**@type {[{name:String,value:String}]} */ + var msgchoices = [] + config.messages.forEach((msg) => { + msgchoices.push({name:msg.id,value:msg.id}) + }) + + //slashtranslation + const ST = require("../../language/slashcmds/slash.json").data + + //create a ticket (/new or /ticket) + client.application.commands.create({ + name:"ticket", + description:"Create a ticket!", + descriptionLocalizations:ST.newticket, + defaultPermission:true, + type:act.ChatInput, + options:[ + { + type:acot.String, + name:"type", + description:"The type of ticket.", + required:true, + choices:choices + } + ] + },sid) + + client.application.commands.create({ + name:"new", + description:"Create a ticket!", + defaultPermission:true, + type:act.ChatInput, + descriptionLocalizations:ST.newticket, + options:[ + { + type:acot.String, + name:"type", + description:"The type of ticket.", + required:true, + choices:choices + + } + ] + },sid) + + //msg + client.application.commands.create({ + name:"message", + description:"Create a ticket message.", + defaultPermission:true, + descriptionLocalizations:ST.message, + type:act.ChatInput, + options:[ + { + type:acot.String, + name:"id", + description:"The message id.", + required:true, + choices:msgchoices, + max_length:30 + + } + ] + },sid) +} \ No newline at end of file diff --git a/core/slashSystem/slashEnable.js b/core/slashSystem/slashEnable.js index cc39c23..299b5e7 100644 --- a/core/slashSystem/slashEnable.js +++ b/core/slashSystem/slashEnable.js @@ -34,6 +34,8 @@ module.exports = async () => { process.stdout.cursorTo(0) process.stdout.write("[status] there are "+chalk.blue(readystats+" out of 12")+" commands ready! (this can take up to 40 seconds)") if (readystats >= 12){ + const fs = require("fs") + fs.writeFileSync("./storage/slashcmdEnabled.txt","true") console.log(chalk.green("\nready!")) console.log(chalk.blue("you can now start the bot with "+chalk.bgBlue("'npm start'")+"!")) process.exit(1) diff --git a/core/ticketActions/ticketOpener.js b/core/ticketActions/ticketOpener.js index 1221ad2..3ff877b 100755 --- a/core/ticketActions/ticketOpener.js +++ b/core/ticketActions/ticketOpener.js @@ -13,7 +13,9 @@ module.exports = () => { client.on("interactionCreate",(interaction) => { if (!interaction.isStringSelectMenu()) return if (interaction.customId != "OTdropdownMenu") return - if (interaction.values.includes("OTChooseTicket")) interaction.deferUpdate() + if (interaction.values.includes("OTChooseTicket")){ + interaction.deferUpdate() + } }) @@ -50,11 +52,15 @@ module.exports = () => { if (currentTicketOptions == false) return interaction.reply({embeds:[bot.errorLog.serverError(l.errors.anotherOption)]}) if (interaction.isButton()){ - interaction.deferUpdate() + try { + interaction.deferUpdate() + } catch{} }else if (interaction.isChatInputCommand()){ interaction.reply({embeds:[bot.errorLog.success(l.messages.createdTitle,l.messages.createdDescription)]}) }else if (interaction.isStringSelectMenu()){ - await interaction.deferUpdate() + try { + interaction.deferUpdate() + } catch{} } if (storage.get("ticketStorage",interaction.member.id) == null || storage.get("ticketStorage",interaction.member.id) == "false"|| Number(storage.get("ticketStorage",interaction.member.id)) < config.system.max_allowed_tickets){ diff --git a/index.js b/index.js index e529ec6..94ce9d2 100644 --- a/index.js +++ b/index.js @@ -124,6 +124,12 @@ client.on('ready',async () => { setStatus(config.status.type,config.status.text) } + if (fs.existsSync("./storage/slashcmdEnabled.txt")){ + /**@type {"true"|"false"} */ + const data = fs.readFileSync("./storage/slashcmdEnabled.txt").toString() + if (data === "true"){require("./core/slashSystem/autoSlashUpdate")()} + }else{fs.writeFileSync("./storage/slashcmdEnabled.txt","false")} + log("system","bot logged in!") try { @@ -150,10 +156,19 @@ client.on('ready',async () => { if (config.status.enabled){ setStatus(config.status.type,config.status.text) } + if (fs.existsSync("./storage/slashcmdEnabled.txt")){ + /**@type {"true"|"false"} */ + const data = fs.readFileSync("./storage/slashcmdEnabled.txt").toString() + if (data === "true"){require("./core/slashSystem/autoSlashUpdate")()} + }else{fs.writeFileSync("./storage/slashcmdEnabled.txt","false")} log("system","bot logged in!") - await client.guilds.cache.find((g) => g.id == config.server_id).members.fetch() + try { + await client.guilds.cache.find((g) => g.id == config.server_id).members.fetch() + }catch{ + this.errorLog.log("info","tried to cache user information, failed!") + } }else{ console.log(chalk.red("STARTING IN ")+chalk.blue("SLASH MODE")+chalk.red("...")) this.errorLog.log("debug","slashmode activated") diff --git a/language/german.json b/language/german.json index 3a31cda..a555b6c 100644 --- a/language/german.json +++ b/language/german.json @@ -75,6 +75,9 @@ "chooseCategory":"Wähle eine Kategorie:", + "none":"keiner", + "reason":"Grund", + "deletedby":"Gelöscht von", "closedby":"Geschlossen von", "modalreason":"Was ist der Grund?", diff --git a/storage/database.json b/storage/database.json new file mode 100644 index 0000000..719dbd2 --- /dev/null +++ b/storage/database.json @@ -0,0 +1,12 @@ +[ + { + "category": "ticketStorage", + "key": "779742674932072469", + "value": 1 + }, + { + "category": "userTicketStorage", + "key": "1057318979082919936", + "value": "779742674932072469" + } +] \ No newline at end of file