diff --git a/ADAM/adam.js b/ADAM/adam.js index 3edf616..55418b0 100644 --- a/ADAM/adam.js +++ b/ADAM/adam.js @@ -9,13 +9,13 @@ let cron = require('node-cron'); // Bot Modules let npcSettings = require('./npcSettings'); let shared = require("../shared/shared"); +let core = require("../shared/core/core"); let dataRequest = require('../modules/dataRequest'); -let calcRandom = require('../modules/calcRandom'); //dialog system let dialog = shared.GenerateDialogFunction(require("./dialog.json")); -//dialog decorator +//ADAM dialog decorator dialog = function(baseDialog) { return function(key, ...data) { if ( (key === "help" || key === "lore") && typeof(data[0]) !== "undefined") { @@ -49,7 +49,7 @@ client.on('ready', async () => { // You can set status to 'online', 'invisible', 'away', or 'dnd' (do not disturb) client.user.setStatus('online'); - + // Sets your "Playing" if (npcSettings.activity) { client.user.setActivity(npcSettings.activity, { type: npcSettings.type }) @@ -89,7 +89,7 @@ client.on('message', async message => { return; } - if (processBasicCommands(message)) { + if (processBasicCommands(client, message)) { return; } @@ -99,7 +99,7 @@ client.on('message', async message => { } //TODO: remove this from ADAM - if (processGameplayCommands(message)) { + if (core.ProcessGameplayCommands(client, message, dialog)) { return; } }); @@ -135,7 +135,7 @@ function processGateCommands(message) { return false; //TODO: set to true once the faction change commands have been assigned to other bots } -function processBasicCommands(message) { +function processBasicCommands(client, message) { // "This is the best way to define args. Trust me." // - Some tutorial dude on the internet let args = message.content.slice(process.env.PREFIX.length).trim().split(/ +/g); @@ -149,13 +149,13 @@ function processBasicCommands(message) { return true; case "obsidian": //TODO: move this to the other bots - return processFactionChangeAttempt(client, message, process.env.GROUP_A_ROLE, "Obsidian"); + return core.ProcessFactionChangeAttempt(client, message, process.env.GROUP_A_ROLE, dialog, "Obsidian"); case "genesis": //TODO: move this to the other bots - return processFactionChangeAttempt(client, message, process.env.GROUP_B_ROLE, "Genesis"); + return core.ProcessFactionChangeAttempt(client, message, process.env.GROUP_B_ROLE, dialog, "Genesis"); case "hand": //TODO: move this to the other bots - return processFactionChangeAttempt(client, message, process.env.GROUP_C_ROLE, "Hand"); + return core.ProcessFactionChangeAttempt(client, message, process.env.GROUP_C_ROLE, dialog, "Hand"); //ADAM and the faction leaders print the intros in the gate //TODO: prune the unneeded intros from each bot @@ -199,7 +199,8 @@ function processBasicCommands(message) { shared.SendPublicMessage(client, message.author, message.channel, dialog(command, args[0])); return true; - case "xp": + //DEBUGGING + case "debugxp": shared.AddXP(client, message.author, args[0]); return true; } @@ -207,151 +208,3 @@ function processBasicCommands(message) { return false; } -function processGameplayCommands(message) { - // "This is the best way to define args. Trust me." - // - Some tutorial dude on the internet - let args = message.content.slice(process.env.PREFIX.length).trim().split(/ +/g); - let command = args.shift().toLowerCase(); - - switch (command) { - case "checkin": - let checkinAmount = calcRandom.random(4, 9); - let checkInResponse = String(dataRequest.sendServerData("checkin", checkinAmount, message.author.id)); - if (checkInResponse === "available") { - shared.SendPublicMessage(client, message.author, message.channel, dialog("checkin", checkinAmount)); - shared.AddXP(client, message.author, 1); //1XP - } else { - shared.SendPublicMessage(client, message.channel, dialog("checkinLocked", message.author.id, checkInResponse)); - } - return true; - - case "give": //TODO: fold this code into a function - let amount = Math.floor(args[0]); - - //not enough - if (amount <= 0) { - shared.SendPublicMessage(client, message.channel, dialog("giveNotAboveZero", message.author.id)); - return true; - } - - //didn't mention anyone - if (message.mentions.members.size == 0) { - shared.SendPublicMessage(client, message.channel, dialog("giveInvalidUser", message.author.id)); - return true; - } - - let targetMember = message.mentions.members.first(); - - //can't give to yourself - if (targetMember.id === message.author.id) { - shared.SendPublicMessage(client, message.channel, dialog("giveInvalidUserSelf", message.author.id)); - return true; - } - - let accountBalance = dataRequest.loadServerData("account",message.author.id); - - //not enough money in account - if (accountBalance < amount) { - shared.SendPublicMessage(client, message.channel, dialog("giveNotEnoughInAccount", message.author.id)); - return true; - } - - //try to send the money - if (dataRequest.sendServerData("transfer", targetMember.id, message.author.id, amount) != "success") { - shared.SendPublicMessage(client, message.channel, dialog("giveFailed", message.author.id)); - return true; - } - - //print the success message - shared.SendPublicMessage(client, message.author, message.channel, dialog("giveSuccessful", targetMember.id, amount)); - return true; - - case "stats": //TODO: fold this code into a function - // Sees if the user is supposed to level up - let levelUp = shared.LevelUp(client, message.member); //TODO: process automatically - - // Grabs all parameters from server - //TODO: improve this once the server-side has been updated - let attacker = String(dataRequest.loadServerData("userStats",message.author.id)).split(","); - - if (attacker[0] == "failure") { - shared.SendPublicMessage(client, message.author, message.channel, "The server returned an error."); - return true; - } - - let attackerStrength = parseFloat(attacker[1]); //TODO: constants representing the player structure instead of [0] - let attackerSpeed = parseFloat(attacker[2]); - let attackerStamina = parseFloat(attacker[3]); - let attackerHealth = parseFloat(attacker[4]); - let attackerMaxStamina = parseFloat(attacker[5]); - let attackerMaxHealth = parseFloat(attacker[6]); - let attackerWallet = parseFloat(attacker[7]); - let attackerXP = parseFloat(attacker[8]); - let attackerLVL = Math.floor(parseFloat(attacker[9])); - let attackerLvlPercent = parseFloat(attacker[10]); - let attackerStatPoints = parseFloat(attacker[11]); - - // Forms stats into a string - var levelText = `:level: **${attackerLVL}**`; //NOTE: I don't like backticks - var levelProgress = `(${attackerLvlPercent}%)`; - var crystalText = `:crystals: **${attackerWallet}**`; - var cannisterText = `:cannister: **${attackerStatPoints}**`; - var userStats = "```" + `STR: ${attackerStrength} | SPD: ${attackerSpeed} | STAM: ${attackerStamina}/${attackerMaxStamina} | HP: ${attackerHealth}/${attackerMaxHealth}` + "```"; - - // Says level is maxed out if it is LVL 30+ - if (attackerLVL >= process.env.RANK_3_THRESHOLD) { - levelProgress = "(MAX)"; - } - - // Creates embed & sends it - const embed = new Discord.RichEmbed() - .setAuthor(`${message.member.displayName}`, message.author.avatarURL) - .setColor(message.member.displayColor) - .setDescription(`${levelText} ${levelProgress} | ${crystalText} | ${cannisterText}`) - .addField("Stats", userStats) - .setFooter("Commands: !help | !lore | !checkin | !give"); - - message.channel.send(embed); - - //handle levelling up - if (levelUp === "levelUp" || levelUp === "RankUp") { - if (attackerLVL >= process.env.RANK_3_THRESHOLD) { - shared.SendPublicMessage(client, message.author, message.channel, dialog("levelUpCap", dialog("levelUpCapRemark"), attackerLVL)); - } else { - shared.SendPublicMessage(client, message.author, message.channel, dialog("LevelUp", dialog("levelUpRemark"), attackerLVL, attackerStatPoints)); - } - } - - return true; - } - - //didn't process it - return false; -} - -//tailor this for each faction leader -function processFactionChangeAttempt(client, message, factionRole, factionShorthand) { - shared.ChangeFaction(client, factionRole, message.channel, message.member) - .then(result => { - switch (result) { - case "alreadyJoined": - shared.SendPublicMessage(client, message.channel, dialog("alreadyJoined" + factionShorthand, message.author.id)); - break; - case "hasConvertedToday": - shared.SendPublicMessage(client, message.channel, dialog("conversionLocked", message.author.id)); - break; - case "createdUser": - shared.SendPublicMessage(client, message.author, shared.GetFactionChannel(factionRole), dialog("newUserPublicMessage", shared.GetFactionName(factionRole), shared.GetFactionChannel(factionRole))); - shared.SendPrivateMessage(client, message.author, dialog("newUserPrivateMessage", dialog("newUserPrivateMessageRemark" + factionShorthand))); - break; - case "joined": - shared.SendPublicMessage(client, message.author, message.channel, dialog("join" + factionShorthand)); - break; - default: - //DEBUGGING - console.log("processFactionChangeAttempt failed:" + result); - } - }) - .catch(console.error); - return true; -} \ No newline at end of file diff --git a/Shared/Core/core.js b/Shared/Core/core.js new file mode 100644 index 0000000..5917370 --- /dev/null +++ b/Shared/Core/core.js @@ -0,0 +1,163 @@ +exports = module.exports = {}; + +let shared = require("../shared"); +let calcRandom = require('../../modules/calcRandom'); + +//ProcessGameplayCommands +//client - discord.js client +//message - discord.js message +//dialog - the dialog function +exports.ProcessGameplayCommands = function(client, message, dialog) { + // "This is the best way to define args. Trust me." + // - Some tutorial dude on the internet + let args = message.content.slice(process.env.PREFIX.length).trim().split(/ +/g); + let command = args.shift().toLowerCase(); + + switch (command) { + case "checkin": + let checkinAmount = calcRandom.random(4, 9); + let checkInResponse = String(dataRequest.sendServerData("checkin", checkinAmount, message.author.id)); + if (checkInResponse === "available") { + shared.SendPublicMessage(client, message.author, message.channel, dialog("checkin", checkinAmount)); + shared.AddXP(client, message.author, 1); //1XP + } else { + shared.SendPublicMessage(client, message.channel, dialog("checkinLocked", message.author.id, checkInResponse)); + } + return true; + + case "give": //TODO: fold this code into a function + let amount = Math.floor(args[0]); + + //not enough + if (amount <= 0) { + shared.SendPublicMessage(client, message.channel, dialog("giveNotAboveZero", message.author.id)); + return true; + } + + //didn't mention anyone + if (message.mentions.members.size == 0) { + shared.SendPublicMessage(client, message.channel, dialog("giveInvalidUser", message.author.id)); + return true; + } + + let targetMember = message.mentions.members.first(); + + //can't give to yourself + if (targetMember.id === message.author.id) { + shared.SendPublicMessage(client, message.channel, dialog("giveInvalidUserSelf", message.author.id)); + return true; + } + + let accountBalance = dataRequest.loadServerData("account",message.author.id); + + //not enough money in account + if (accountBalance < amount) { + shared.SendPublicMessage(client, message.channel, dialog("giveNotEnoughInAccount", message.author.id)); + return true; + } + + //try to send the money + if (dataRequest.sendServerData("transfer", targetMember.id, message.author.id, amount) != "success") { + shared.SendPublicMessage(client, message.channel, dialog("giveFailed", message.author.id)); + return true; + } + + //print the success message + shared.SendPublicMessage(client, message.author, message.channel, dialog("giveSuccessful", targetMember.id, amount)); + return true; + + case "stats": //TODO: fold this code into a function + // Sees if the user is supposed to level up + let levelUp = shared.LevelUp(client, message.member); //TODO: process automatically + + // Grabs all parameters from server + //TODO: improve this once the server-side has been updated + let attacker = String(dataRequest.loadServerData("userStats",message.author.id)).split(","); + + if (attacker[0] == "failure") { + shared.SendPublicMessage(client, message.author, message.channel, "The server returned an error."); + return true; + } + + let attackerStrength = parseFloat(attacker[1]); //TODO: constants representing the player structure instead of [0] + let attackerSpeed = parseFloat(attacker[2]); + let attackerStamina = parseFloat(attacker[3]); + let attackerHealth = parseFloat(attacker[4]); + let attackerMaxStamina = parseFloat(attacker[5]); + let attackerMaxHealth = parseFloat(attacker[6]); + let attackerWallet = parseFloat(attacker[7]); + let attackerXP = parseFloat(attacker[8]); + let attackerLVL = Math.floor(parseFloat(attacker[9])); + let attackerLvlPercent = parseFloat(attacker[10]); + let attackerStatPoints = parseFloat(attacker[11]); + + // Forms stats into a string + var levelText = `:level: **${attackerLVL}**`; //NOTE: I don't like backticks + var levelProgress = `(${attackerLvlPercent}%)`; + var crystalText = `:crystals: **${attackerWallet}**`; + var cannisterText = `:cannister: **${attackerStatPoints}**`; + var userStats = "```" + `STR: ${attackerStrength} | SPD: ${attackerSpeed} | STAM: ${attackerStamina}/${attackerMaxStamina} | HP: ${attackerHealth}/${attackerMaxHealth}` + "```"; + + // Says level is maxed out if it is LVL 30+ + if (attackerLVL >= process.env.RANK_3_THRESHOLD) { + levelProgress = "(MAX)"; + } + + // Creates embed & sends it + const embed = new Discord.RichEmbed() + .setAuthor(`${message.member.displayName}`, message.author.avatarURL) + .setColor(message.member.displayColor) + .setDescription(`${levelText} ${levelProgress} | ${crystalText} | ${cannisterText}`) + .addField("Stats", userStats) + .setFooter("Commands: !help | !lore | !checkin | !give"); + + message.channel.send(embed); + + //handle levelling up + if (levelUp === "levelUp" || levelUp === "RankUp") { + if (attackerLVL >= process.env.RANK_3_THRESHOLD) { + shared.SendPublicMessage(client, message.author, message.channel, dialog("levelUpCap", dialog("levelUpCapRemark"), attackerLVL)); + } else { + shared.SendPublicMessage(client, message.author, message.channel, dialog("LevelUp", dialog("levelUpRemark"), attackerLVL, attackerStatPoints)); + } + } + + return true; + } + + //didn't process it + return false; +} + +//ProcessFactionChangeAttempt +//client - discord.js client +//message - discord.js message +//factionRole - the new faction's role +//dialog - the dialog function +//factionShorthand - the shorthand name of the new faction (TEMPORARY) +exports.ProcessFactionChangeAttempt = function(client, message, factionRole, dialog, factionShorthand) { + //tailor this for each faction leader? + shared.ChangeFaction(client, factionRole, message.channel, message.member) + .then(result => { + switch (result) { + case "alreadyJoined": + shared.SendPublicMessage(client, message.channel, dialog("alreadyJoined" + factionShorthand, message.author.id)); + break; + case "hasConvertedToday": + shared.SendPublicMessage(client, message.channel, dialog("conversionLocked", message.author.id)); + break; + case "createdUser": + shared.SendPublicMessage(client, message.author, shared.GetFactionChannel(factionRole), dialog("newUserPublicMessage", shared.GetFactionName(factionRole), shared.GetFactionChannel(factionRole))); + shared.SendPrivateMessage(client, message.author, dialog("newUserPrivateMessage", dialog("newUserPrivateMessageRemark" + factionShorthand))); + break; + case "joined": + shared.SendPublicMessage(client, message.author, message.channel, dialog("join" + factionShorthand)); + break; + default: + //DEBUGGING + console.log("processFactionChangeAttempt failed:" + result); + } + }) + .catch(console.error); + return true; +} \ No newline at end of file diff --git a/Shared/testbot.js b/Shared/testbot.js deleted file mode 100644 index baf89cc..0000000 --- a/Shared/testbot.js +++ /dev/null @@ -1,70 +0,0 @@ -// .env Variables -require('dotenv').config({path: '../.env'}); - -let shared = require("./shared.js"); - -let Discord = require("discord.js"); -let client = new Discord.Client(); - -//message handler -client.on("ready", function() { - console.log("Logged in as " + client.user.tag); -}); - -client.on("reconnecting", function() { - console.log("Reconnecting..."); -}); - -client.on("disconnect", function() { - console.log("Disconnected"); -}); - -client.on("message", function(msg) { - //only react to commands - if (msg.content.slice(0, 1) !== process.env.PREFIX) { - return; - } - - //get the command - let command = msg.content.slice(1).split(" ")[0]; - let args = msg.content.slice(1 + command.length).trim(); - - //handle command - switch(command) { - //used for debugging - case "create": - shared.ChangeFaction(client, process.env.GROUP_A_ROLE, "bot-spam", msg.member); - break; - - case "xp": - shared.AddXP(client, msg.author, parseInt(args)); - break; - - case "levelup": - shared.LevelUp(client, msg.member); - break; - - case "rankup": - shared.RankUp(client, msg.member, parseInt(args)); - break; - } -}); - -//DEBUGGING: eventually be require("./dialog.json") -let dialogJson = { - "hello": [ - "Hi there {1} {2} {3}!", - "Howdy {1} {3}, of the {3} clan!" - ], - "goodbye": "See ya!" -} - -let dialog = shared.GenerateDialogFunction(dialogJson); -console.log(dialog("hello", "Kayne", "Matthew", "Ruse")); - -//actually log in -client.login(process.env.DEVELOPER_TOKEN); - -//TODO: change usernames to tags throughout the shared library -//FIXME: The server currently queries chest count, which is not in the database. -