From 6c51d4107b5ed9861923e7b0910d298b98e89f1a Mon Sep 17 00:00:00 2001 From: ION606 Date: Tue, 24 May 2022 08:55:57 +0300 Subject: [PATCH] Re-structured the file structure, finished the 'help' command. Started the 'game' command (not operational) --- commands/db/battle.js | 37 ++++++++ commands/{misc => db}/econ.js | 161 ++++++++++++++++++++++------------ commands/db/game.js | 123 ++++++++++++++++++++++++++ commands/game/game.js | 12 --- commands/misc/EC.js | 2 +- commands/misc/commandhelp.js | 17 ---- commands/misc/help.js | 36 ++++++++ commands/misc/react.js | 2 +- main.js | 38 ++++++-- 9 files changed, 331 insertions(+), 97 deletions(-) create mode 100644 commands/db/battle.js rename commands/{misc => db}/econ.js (67%) create mode 100644 commands/db/game.js delete mode 100644 commands/game/game.js delete mode 100644 commands/misc/commandhelp.js create mode 100644 commands/misc/help.js diff --git a/commands/db/battle.js b/commands/db/battle.js new file mode 100644 index 0000000..24580d4 --- /dev/null +++ b/commands/db/battle.js @@ -0,0 +1,37 @@ +//@ts-check + + +function hpmp(message, command, dbo) { + if (command == 'hp') { + dbo.find({"hp": {$exists: true}}).toArray(function(err, doc) { + return message.reply(`You have ${String(doc[0].hp)} hp left!`); + }); + } else if (command == 'mp') { + dbo.find({"mp": {$exists: true}}).toArray(function(err, doc) { + return message.reply(`You have ${String(doc[0].hp)} mp left!`); + }); + } +} + + + + +//#region Exports +function verifyAndInitiate() { + +} + +function handle(user_dbo, other_dbo, bot, message, args, command, Discord, mongouri, items, xp_collection) { + if (command == 'hp' || command == 'mp') { + hpmp(message, command, user_dbo); + } else if (command == 'initiate') { + + } + // initiate(user_dbo, other_dbo, command, message); +} + + +//#endregion + + +module.exports = { handle } \ No newline at end of file diff --git a/commands/misc/econ.js b/commands/db/econ.js similarity index 67% rename from commands/misc/econ.js rename to commands/db/econ.js index e5fe9d8..bb4aa5e 100644 --- a/commands/misc/econ.js +++ b/commands/db/econ.js @@ -2,8 +2,19 @@ const { MongoClient, ServerApiVersion } = require('mongodb'); // const { update } = require('apt'); const { Collection, Client, Formatters, Intents } = require('discord.js'); const { CLIENT_ODBC } = require('mysql/lib/protocol/constants/client'); -const BASE_PAY = 5; -const BASE_LVL_XP = 35; + +//Declair an "enum" to help with BASE calculations +const BASE = { + PAY: 5, + HP: 5, + MP: 10 +} + +const STATE = { + IDLE: 0, + FIGHTING: 1, + PRONE: 2 +} //Note that leveling up to the next level takes 10% more xp than the previous one @@ -14,6 +25,25 @@ function isNum(arg) { }; +function CreateNewCollection(message, client, server, id, opponent = null, game = null) { + client.connect(err => { + const db = client.db(String(server) + "[ECON]"); + const dbo = db.collection(id); + if (err) { return console.log(err); } + db.listCollections({name: id}) + .next(function(err, collinfo) { + if (err) { return console.log(err); } + if (!collinfo) { + message.reply("You didn't have a place in my databases, so I created one for you!\nPlease try your command again!") + dbo.insertOne({balance: 10, rank: 1, lastdayworked: 0, xp: 0, hp: BASE.HP, mp: BASE.MP, game: game, opponent: opponent, state: STATE.IDLE}); + } + }); + }); + + client.close(); +} + + function addxp(message, dbo, amt, xp_list) { if (!isNum(amt)) { return console.log("This isn't a number...."); } @@ -21,8 +51,8 @@ function addxp(message, dbo, amt, xp_list) { if (!String(doc)) { return console.log("ERROR!\nThis account does not exist!"); } temp = doc[0]; - let rank = temp.rank + 1; - const txp = temp.xp + amt; + let rank = temp.rank + 1; //The table starts at rank 0, the user starts at rank 1 + const txp = amt; /*temp.xp + amt; // This part was used before the xp check was made in the 'work' function */ //If the rank is less than 100, you can still advance if (rank < 101) { let needed = xp_list.get(rank); @@ -165,15 +195,18 @@ function work(dbo, message, xp_list) { let date = fulldate.getDate(); dbo.find({"lastdayworked": {$exists: true}}).toArray(function(err, doc) { if (!String(doc)) { return message.reply("Your account doesn't exist, please contact the mods for support"); } - if (doc[0].lastdayworked == date) { + if (doc[0].lastdayworked == 111111) {//date message.reply("You've already worked today, try again tomorrow!"); } else { //Amount to be paid let amt = 0; - amt = BASE_PAY * doc[0].rank; - dbo.updateOne({balance: doc[0].balance, rank: doc[0].rank}, { $set: { balance: amt, lastdayworked: date }}); - addxp(message, dbo, Math.ceil(amt*1.5), xp_list); - message.channel.send('<@' + message.author.id + '> worked and earned $' + amt +' and ' + Math.ceil(amt*1.5) + ' xp!'); + amt = (BASE.PAY * doc[0].rank); + let xp_earned = doc[0].xp + Math.ceil(amt*1.5); + + //Update the amount to the new TOTAL balance + dbo.updateOne({"balance": {$exists: true}}, { $set: { balance: doc[0].balance + amt, lastdayworked: date }}); + addxp(message, dbo, xp_earned, xp_list); + message.channel.send('<@' + message.author.id + '> worked and earned $' + amt +' and ' + String(xp_earned) + ' xp!'); } }); } @@ -193,12 +226,12 @@ function printInventory(dbo, message) { } -function getShop(message, args, items) { +function getShop(message, args, items, bot) { if (args.length == 0) { let temp = Formatters.codeBlock(items.map(i => `${i.sect}`).join(' ')); temp = [...new Set(temp.split(' '))]; - return message.reply("Please use the format /shop [type] [page number]\nTypes are: " + temp); + return message.reply(`Please use the format ${bot.prefix}shop [type] [page number]\nTypes are: ${temp}`); } let ind = 1; @@ -218,17 +251,23 @@ function getShop(message, args, items) { .filter(f => f.sect = args[0]).join('\n')); if (noinp) { - newText += "(Use /shop [type] [page number] to access other pages)"; + newText += `(Use ${bot.prefix}shop [type] [page number] to access other pages)`; } return message.reply(newText); } + +function econHelp() { + let l = ["buy", 'shop', 'work', 'rank', 'inventory', 'balance', 'sell'] + + return l.join(", "); +} //#endregion //Main Code module.exports = { - name: 'ECON', + name: 'econ', description: 'ECON', async execute(bot, message, args, command, Discord, mongouri, items, xp_list) { //Set Discord vars @@ -236,60 +275,68 @@ module.exports = { const server = message.guild.id; const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 }); - if (client.writeConcern || client.writeConcern) { return client.close(); } + if (client.writeConcern || client.writeConcern) { + client.close(); + return message.reply("Something went wrong with the database, please try again later and contact support if this problem persists!"); + } + //Initialize if necessary + CreateNewCollection(message, client, server, id); + client.connect(err => { const db = client.db(String(server) + "[ECON]"); const dbo = db.collection(id); if (err) { return console.log(err); } - //Initialize if necessary - db.listCollections({name: id}) - .next(function(err, collinfo) { - if (!collinfo) { - message.reply("You didn't have a place in my databases, so I created one for you!\nPlease try your command again!") - dbo.insertOne({balance: 100, rank: 1, lastdayworked: 0, xp: 0}); - return; - } - //test area - if (command == 'xp' || command == 'adbal') { - //Selmer Dev only command - if (message.member.roles.cache.has('944048889038774302')) { - if (command == 'xp') { - return addxp(message, dbo, Number(args[0]), xp_list); - } + //test area + if (command == 'xp' || command == 'adbal') { + //Selmer Dev only command + if (message.member.roles.cache.has('944048889038774302')) { + if (command == 'xp') { + return addxp(message, dbo, Number(args[0]), xp_list); } } + } - //Command Area - if(command == 'init') { - //Add security check here - // init.execute(bot, message, args, command, dbo, Discord, connect); - return; - } else if (command == 'checkinv') { - const req = dbo.findOne({ id: message.guild.id }); - if (!req) { return message.reply("Doc doesn't exist!"); } - } else if (command == 'buy') { - buy(id, message, args, dbo, items, xp_list); - } else if (command == 'shop') { - getShop(message, args, items); - } else if (command == 'work') { - work(dbo, message, xp_list); - } else if (command == 'rank') { - rank(dbo, message, xp_list); - } else if (command == 'inventory') { - printInventory(dbo, message); - } else if (command == 'balance') { - getBalance(dbo, message); - } else if (command == 'sell') { - sell(id, message, args, dbo, items, xp_list); - } else { - message.channel.send("'" + message.content + "' is not a command!"); - } + //Command Area + if(command == 'init') { + //Add security check here + // init.execute(bot, message, args, command, dbo, Discord, connect); + return; + } else if (command == 'buy') { + buy(id, message, args, dbo, items, xp_list); + } else if (command == 'shop') { + getShop(message, args, items, bot); + } else if (command == 'work') { + work(dbo, message, xp_list); + } else if (command == 'rank') { + rank(dbo, message, xp_list); + } else if (command == 'inventory') { + printInventory(dbo, message); + } else if (command == 'balance') { + getBalance(dbo, message); + } else if (command == 'sell') { + sell(id, message, args, dbo, items, xp_list); + } else { + message.channel.send("'" + message.content + "' is not a command!"); + } - }); }); //Close the database client.close(); - } -} \ No newline at end of file + }, + + //Battle Updating stuff + addxp, checkAndUpdateBal, CreateNewCollection, econHelp, BASE, STATE +} + + + +/* +?????????????? What did I need this for? +else if (command == 'checkinv') { + const req = dbo.findOne({ id: message.guild.id }); + if (!req) { return message.reply("Doc doesn't exist!"); } + } + +*/ \ No newline at end of file diff --git a/commands/db/game.js b/commands/db/game.js new file mode 100644 index 0000000..3e3e98a --- /dev/null +++ b/commands/db/game.js @@ -0,0 +1,123 @@ +const { MongoClient, ServerApiVersion } = require('mongodb'); +let ecoimport = require("./econ.js"); +let battle = require("./battle.js"); +const STATE = ecoimport.STATE; + +//Has a list of all games (used to change player state) +const allGames = ['battle']; +// const { NULL } = require('mysql/lib/protocol/constants/types'); + + +//#region functions (NOT GAME SPECIFIC) + +/** Adds the game type tag to the user(s) so the system can tell what game they're playing + * @param other_dbo optional, include if the game has two players +*/ +function Initialize(user_dbo, command, message, other_dbo = null) { + user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs){ + let doc = docs[0]; + if (allGames.indexOf(command) != -1) { + if (other_dbo != null) { + user_dbo.updateOne(doc, { $set: { game: command, opponent: other_dbo.s.namespace.collection }}); + } else { + user_dbo.updateOne(doc, { $set: { game: command }}); + } + } + }); +} + + +function resetPlayer(user_dbo) { + user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs){ + let doc = docs[0]; + user_dbo.updateOne(doc, { $set: { game: null, opponent: null, state: STATE.IDLE }}); + }); +} + + +function gameHelp() { + let l = ['']; + + return l.join(', '); +} + +//#endregion + + + + +module.exports ={ + name: "game", + description: "Play a game using Selmer Bot!", + async execute(bot, message, args, command, Discord, mongouri, items, xp_collection) { + + return message.reply("This command is currently in development!"); + + const id = message.author.id; + const server = message.guild.id; + + const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 }); + if (client.writeConcern || client.writeConcern) { + client.close(); + return message.reply("Something went wrong with the database, please try again later and contact support if this problem persists!"); + } + + //Initialize if necessary + ecoimport.CreateNewCollection(message, client, server, id); + command = args[0]; + + //Check for a second person and create a second database entry if neccessary + if (message.mentions.users.first() != undefined) { + ecoimport.CreateNewCollection(message, client, server, message.mentions.users.first().id); + } + + client.connect(err => { + const db = client.db(String(server) + "[ECON]"); + const dbo = db.collection(id); + if (err) { return console.log(err); } + + //Check if the client is currently in a game and act accordingly + //#region Check Game + dbo.find({"game": {$exists: true}}).toArray(async function(err, docs){ + if (err) { return console.log(error); } + let doc = docs[0]; + let game = doc.game; + //#endregion + + if (command == 'accept') { + //Handle the messages + if (message.reference == null) { return message.reply("Please reply to a valid battle request message!"); } + let mid = message.reference.messageId; + let msg = await message.channel.messages.fetch(mid); + + //Check if the person actually challenged you + let mentioned = msg.mentions.users.keys(); + const other_discord = mentioned.next().value; + + //Get the opponent + const other = db.collection(other_discord); + Initialize(dbo, command, message); + battle.handle(dbo, other, bot, message, args, command, Discord, mongouri, items, xp_collection); + } else { + if (game == 'battle' || command == 'battle') { + //Handle sending the request and making sure the user exists here + let other_discord = message.mentions.users.first(); + if (other_discord == undefined) { + return message.reply(`${args[1]} is not a valid user!`); + } + + message.channel.send(`<@${other_discord}>, <@${message.author.id}> has invited you to battle, to accept, please reply to this message with !accept`); + } + + //Catch statement (invalid command) + else { + message.reply(`'!game ${command}' is not a command!`); + } + } + + }); + }); + + client.close(); + } +} \ No newline at end of file diff --git a/commands/game/game.js b/commands/game/game.js deleted file mode 100644 index ceadf3c..0000000 --- a/commands/game/game.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports ={ - name: "game", - description: "Play a game using Selmer Bot!", - execute(message, args, Discord, Client, bot) { - let temp = "Selmer Bot Commands:\n"; - var keys = bot.commands.keys(); - for (let i = 0; i < keys.length; i ++) { - temp += keys[i].toLowerCase(); - temp += ` - ${bot.commands.get(keys[i]).description}\n`; - } - } -} \ No newline at end of file diff --git a/commands/misc/EC.js b/commands/misc/EC.js index 6ab7dbb..71837bf 100644 --- a/commands/misc/EC.js +++ b/commands/misc/EC.js @@ -19,7 +19,7 @@ module.exports = { case 3: dm = 'The AI is coming for you! Buy my book to find out how to stop them!'; break; - case 4: dm = 'Did you know I proved P=NP. The proof is on my password-encrypted tablet.\nPretty safe there I reckon'; + case 4: dm = 'Did you know I proved P=NP? The proof is on my password-encrypted tablet.\nPretty safe there I reckon'; break; case 5: dm = 'I hate informal logic, but there\'s nothing informal about you!'; diff --git a/commands/misc/commandhelp.js b/commands/misc/commandhelp.js deleted file mode 100644 index 79fc86c..0000000 --- a/commands/misc/commandhelp.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports ={ - name: "help", - description: "Gets help for all of Selmer Bot's commands", - execute(message, args, Discord, Client, bot) { - let temp = "***Selmer Bot Commands:***\n"; - - bot.commands.sort((a, b) => a.name[0] < b.name[0]); - - bot.commands.forEach((comm) => { - if (comm.name != 'verify') { - temp += `${comm.name.toLowerCase()} - ${comm.description}\n`; - } - }); - - message.channel.send(temp); - } -} \ No newline at end of file diff --git a/commands/misc/help.js b/commands/misc/help.js new file mode 100644 index 0000000..0f7fb55 --- /dev/null +++ b/commands/misc/help.js @@ -0,0 +1,36 @@ +module.exports ={ + name: "help", + description: "Gets help for all of Selmer Bot's commands", + execute(message, args, Discord, Client, bot) { + + if (args[0] == 'econ') { + let temp = "***Selmer Bot Commands (Econ):***\n"; + temp += bot.commands.get('econ').econHelp(); + temp += `\n\n(remember to use '${bot.prefix}' before the command!)`; + return message.channel.send(temp); + } else if (args[0] == 'game') { + let temp = "***Selmer Bot Commands (Games):***\n"; + temp += bot.commands.get('game').gameHelp(); + temp += `\n\n(remember to use '${bot.prefix}' before the command!)`; + return message.channel.send(temp); } + + let temp = "***Selmer Bot Commands:***\n"; + + bot.commands.sort((a, b) => {a.name[0] < b.name[0]}); + + bot.commands.forEach((comm) => { + if (comm.name != 'verify') { + if (comm.name == 'econ') { + temp += `econ - use _!help econ_\n`; + } else if (comm.name == 'game') { + temp += `game - use _!help game_\n`; + }else { + temp += `${comm.name.toLowerCase()} - _${comm.description}_\n`; + } + } + }); + + temp += `\n_(remember to use '${bot.prefix}' before the command!)_`; + message.channel.send(temp); + } +} \ No newline at end of file diff --git a/commands/misc/react.js b/commands/misc/react.js index 632bbef..6989a46 100644 --- a/commands/misc/react.js +++ b/commands/misc/react.js @@ -12,7 +12,7 @@ module.exports = { console.log("IMPLEMENT THIS"); let emoji = [...new Set(args[0])]; - if (emoji.length > 15 || message.IndexOf(":") != -1) { return message.reply("Please enter less than 15 emojis"); } + if (emoji.length > 15 /*|| message.IndexOf(":") != -1*/) { return message.reply("Please enter less than 15 emojis"); } let notused = new Array(15); let counter = 0; diff --git a/main.js b/main.js index f4955c0..23615a9 100644 --- a/main.js +++ b/main.js @@ -78,14 +78,23 @@ const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith( bot.commands = new Discord.Collection(); fs.readdirSync('./commands') .forEach(dir => { - fs.readdirSync(`./commands/${dir}`) - .filter(file => file.endsWith('.js')) - .forEach(file => { - const command = require(`./commands/${dir}/${file}`); - bot.commands.set(command.name, command); - }); + if (dir != 'db') { + fs.readdirSync(`./commands/${dir}`) + .filter(file => file.endsWith('.js')) + .forEach(file => { + const command = require(`./commands/${dir}/${file}`); + bot.commands.set(command.name, command); + }); + } }); + + //Set these two manually because all the seperate games can't be included in the command list (all managed by the 'game' file) + let temp_command = require("./commands/db/econ.js"); + bot.commands.set('econ', temp_command); + temp_command = require('./commands/db/game.js'); + bot.commands.set('game', temp_command); + // const econFiles = fs.readdirSync('./commands/inventory').filter(file => file.endsWith('.js'));; // const currency = new Discord.Collection(); // const { Users } = require('./commands/currency/dbObjects.js'); @@ -107,7 +116,10 @@ bot.on('ready', async () => { client.close(); }); - + + //Srt status and Activity (idle and listening to !help) + bot.user.setActivity(`${bot.prefix}help`, { type: "LISTENING" }); + // bot.user.setStatus('idle'); }); //Note the xp numbers are a little wonky on levels 6, 8 and 13 (why though?) @@ -141,9 +153,17 @@ bot.on('messageCreate', (message) => { //Admin section if (command == 'reactionrole') { bot.commands.get(command).execute(message, args, Discord, bot); } - else if(bot.commands.has(command)) { bot.commands.get(command).execute(message, args, Discord, Client, bot); } + else if(bot.commands.has(command) && command != 'ECON') { + //Database access is required, change the inputs + if (command == 'game' || command == 'accept') { + bot.commands.get(command).execute(bot, message, args, command, Discord, mongouri, items, xp_collection) + } else { + bot.commands.get(command).execute(message, args, Discord, Client, bot); + } + } - else { bot.commands.get('ECON').execute(bot, message, args, command, Discord, mongouri, items, xp_collection); } + //Catch + else { bot.commands.get('econ').execute(bot, message, args, command, Discord, mongouri, items, xp_collection); } }) //Look into integrating MySQL into SelmerBot instead of SQLite