From 2aa514168b5123465ac5337531a0c67797e9ed9f Mon Sep 17 00:00:00 2001 From: Dalton Date: Tue, 19 Mar 2019 12:06:46 -0700 Subject: [PATCH] Initial Commit Not a working build, but I wanted to get this on my github. --- .gitignore | 1 + LICENSE | 2 +- data/enums/playerdata.js | 3 + data/enums/playerdata.ts | 11 ++ main.js | 220 ++++++++++++++++++++++++++++++++++++ main.ts | 233 +++++++++++++++++++++++++++++++++++++++ yarn.lock | 82 ++++++++++++++ 7 files changed, 551 insertions(+), 1 deletion(-) create mode 100644 data/enums/playerdata.js create mode 100644 data/enums/playerdata.ts create mode 100644 main.js create mode 100644 main.ts create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore index e1da6ae..1252713 100644 --- a/.gitignore +++ b/.gitignore @@ -74,3 +74,4 @@ typings/ # FuseBox cache .fusebox/ +*.json diff --git a/LICENSE b/LICENSE index 5d9c338..27d652a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Dalton +Copyright (c) 2019 Dalton Lange Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/data/enums/playerdata.js b/data/enums/playerdata.js new file mode 100644 index 0000000..06fad7f --- /dev/null +++ b/data/enums/playerdata.js @@ -0,0 +1,3 @@ +"use strict"; +// Generated by https://quicktype.io +exports.__esModule = true; diff --git a/data/enums/playerdata.ts b/data/enums/playerdata.ts new file mode 100644 index 0000000..c7d757f --- /dev/null +++ b/data/enums/playerdata.ts @@ -0,0 +1,11 @@ +// Generated by https://quicktype.io + +export interface player { + name: string; + race: string; + class: string; + level: number; + nuts: number; + dm: boolean; + dm_points: number; +} diff --git a/main.js b/main.js new file mode 100644 index 0000000..85d80de --- /dev/null +++ b/main.js @@ -0,0 +1,220 @@ +"use strict"; +// Created by Dalton Lange +exports.__esModule = true; +var fs = require('fs'); +var Discord = require('discord.js'); +var client = new Discord.Client(); +var info = JSON.parse(fs.readFileSync("./data/info.json")); +var races = ["tree", "ground", "chipmunk"]; +var classes = ["rogue", "berserker", "knight", "ranger", "huntsman", "priest"]; +var lastNames = ["Nutcrack", "Seedsower", "McScuiri", "Rodentia", "Arbora", "Patagi"]; +var newPlayerTemplate = { + "name": "", + "race": "", + "class": "", + "level": 1, + "nuts": 0, + "dm": false, + "dm_points": 0 +}; +var processes = { + "!read": { + title: "read", + description: "Read a description of your character", + run: function (msg, data) { return read(msg, data); } + }, + "!create": { + title: "create", + description: "Create a character, can only be used once.", + run: function (msg, args) { return create(msg, args); } + } +}; +var authorId; +var playerFile; +var rawPlayerData; +var command; +var messageContent; +var args = [""]; +var encounterInProgress; +var playerData; +client.on('ready', function () { + console.log("Logged in as " + client.user.tag + "!"); + var encounterChannel = client.channels.find(function (ch) { return ch.name === 'the-wild'; }); + var preparingChannel = client.channels.find(function (ch) { return ch.name === 'preparing-for-expedition'; }); + // const preparingCollector = new Discord.MessageCollector(preparingChannel); + // preparingCollector.on('collect', msg => { + // console.log(msg.content); + // }); + // setInterval( function() { encounter(encounterChannel); }, 300000 ); + // encounter(encounterChannel); +}); +client.on('message', function (msg) { + if (msg.channel.type === "dm") + return; + messageContent = msg.content.split(" "); + command = messageContent[0]; + if (messageContent.length > 1) + args = messageContent.slice(1); + if (!command.startsWith(info.prefix)) + return; + authorId = msg.author.id; + playerFile = "./data/playerdata/" + authorId + ".json"; + if (fs.existsSync(playerFile)) { + rawPlayerData = fs.readFileSync(playerFile); + playerData = JSON.parse(rawPlayerData); + processes.forEach(function (process) { + if (command === "!" + process.title) { + process.run(); + } + }); + if (command === "!read") { + read(msg, playerData); + } + else if (command === "!create") { + msg.reply("You already have a squirrel silly."); + } + else if (command === "!namechange") { + nameChange(msg, playerData, playerFile); + } + else if (command === "!races") { + printRaces(msg); + } + else if (command === "!classes") { + printClasses(msg); + } + } + else if (command === "!create") { + console.log("Attempting to make a squirrel for " + authorId); + if (create(msg, args)) + console.log("Squirrel made succesfully for " + authorId); + else + console.log("Failed to create quirrel for " + authorId); + } +}); +client.login(info.key); +function encounter(encounterChannel) { + if (!encounterInProgress) { // randomInt(1,60) === 60 && + console.log("Starting Encounter"); + encounterInProgress = true; + encounterChannel.send("An encounter is beginning!"); + encounterChannel.send("`\u25A0\u25A0\u25A0 \u25A0\u25A0\u25A0 \u25A0\u25A0\u25A0 \u25A0\u25A0\u25A0`\n`\u25A0\u25A0\u25A0 \u25A0\u25A0\u25A0 \u25A0\u25A0\u25A0 \u25A0\u25A0\u25A0`\n`\u25A0\u25A0\u25A0 \u25A0\u25A0\u25A0 \u25A0\u25A0\u25A0 \u25A0\u25A0\u25A0`").then(function (msg) { + console.log("Encounter finished"); + encounterInProgress = false; + }); + } +} +function randomInt(low, high) { + return Math.floor(Math.random() * (high - low + 1) + low); +} +function raceText(race) { + if (race === races[2]) + return capitalize(race); + else if (race === races[0] || race === races[1]) + return capitalize(race) + " Squirrel"; + else { + console.log("Error " + race + " is not a valid race"); + return ""; + } +} +function capitalize(toCaps) { + return toCaps.charAt(0).toUpperCase() + toCaps.slice(1).toLowerCase(); +} +// Commands: +function read(msg, data) { + var embed = new Discord.RichEmbed() + .setTitle(msg.author.username) + .setDescription("Squirrel Info") + .setColor("#E81B47") + .setThumbnail(msg.author.avatarURL) + .addField("Name", data.name) + .addField("Race", raceText(data.race)) + .addField("Class", capitalize(data["class"])) + .addField("Nuts", data.nuts) + .addField("Level", data.level); + if (data.dm === true) + embed.addField("DM Points", data.dm_points); + msg.channel.send(embed); +} +function create(msg, args) { + if (args.length === 3) { + var newSquirrel_1 = msg.content.split(' '); + var newPlayer = newPlayerTemplate; + var incorrect_1 = ""; + incorrect_1 = " race"; + races.some(function (type) { + if (newSquirrel_1[2].toLowerCase() == type) { + incorrect_1 = ""; + return true; + } + }); + if (incorrect_1 == "") + incorrect_1 = " class"; + else + incorrect_1 += ", and class"; + classes.some(function (type) { + if (newSquirrel_1[3].toLowerCase() == type) { + if (incorrect_1 == " race, and class") + incorrect_1 = " race"; + else + incorrect_1 = ""; + return true; + } + }); + if (incorrect_1 === "") { + newPlayer.name = newSquirrel_1[1] + " " + lastNames[randomInt(0, lastNames.length - 1)]; + newPlayer.race = newSquirrel_1[2]; + newPlayer["class"] = newSquirrel_1[3]; + fs.writeFileSync(playerFile, JSON.stringify(newPlayer)); + msg.reply("Squirrel " + newPlayer.name + " has been created"); + return true; + } + else { + msg.reply("Some parameters were entered incorrectly. Remember the format is \"create name race class\". Your name can be whatever you want, but you have to choose from !race, and !class. You incorrectly entered your:" + incorrect_1 + "."); + return false; + } + } + else { + msg.reply("Too many or too few parameters were entered. The format is \"create name race class\". You only get to choose your first name, don't write a last name."); + return false; + } +} +function nameChange(msg, data, file) { + if (data.level == 1) { + if (msg.content.split(' ').length >= 2) { + var newName = msg.content.split(' ')[1]; + data.name = capitalize(newName) + " " + data.name.split(' ')[1]; + fs.writeFileSync(file, JSON.stringify(data)); + msg.reply("Name changed to " + data.name); + } + else { + msg.reply("Please provide a name"); + } + } + else { + msg.reply("Sorry, you have to be level 1 to change your name. You're stuck with " + data.name); + } +} +function printRaces(msg) { + var print = "The races are: "; + for (var i = 0; i < races.length; i++) { + if (i === races.length - 1) { + print += "& " + raceText(races[i]) + "s"; + } + else { + print += raceText(races[i]) + "s, "; + } + } + msg.reply(print); +} +function printClasses(msg) { + var print = "The classes are: "; + for (var i = 0; i < classes.length; i++) { + if (i === classes.length - 1) { + print += "& " + capitalize(classes[i]) + "s"; + } + else { + print += capitalize(classes[i]) + "s, "; + } + } + msg.reply(print); +} diff --git a/main.ts b/main.ts new file mode 100644 index 0000000..3b30cbd --- /dev/null +++ b/main.ts @@ -0,0 +1,233 @@ +// Created by Dalton Lange + +const fs = require('fs'); +const Discord = require('discord.js'); +const client = new Discord.Client(); +const info = JSON.parse(fs.readFileSync(`./data/info.json`)); +import { player } from "./data/enums/playerdata"; + +const races: Array = ["tree", "ground", "chipmunk"]; +const classes: Array = ["rogue", "berserker", "knight", "ranger", "huntsman", "priest"]; +const lastNames: Array = ["Nutcrack", "Seedsower", "McScuiri", "Rodentia", "Arbora", "Patagi"]; +const newPlayerTemplate: player = { + "name": "", + "race": "", + "class": "", + "level": 1, + "nuts": 0, + "dm": false, + "dm_points": 0 +} +const processes: any = { + "!read": { + title: "read", + description: "Read a description of your character", + run: (msg, data) => read(msg, data) + }, + "!create": { + title: "create", + description: "Create a character, can only be used once.", + run: (msg, args) => create(msg, args) + } +} + +let authorId: number; +let playerFile: string; +let rawPlayerData: string; +let command: string; +let messageContent: Array; +let args: Array = [""]; +let encounterInProgress: boolean; +let playerData: player; + +client.on('ready', () => { + console.log(`Logged in as ${client.user.tag}!`); + const encounterChannel = client.channels.find(ch => ch.name === 'the-wild'); + const preparingChannel = client.channels.find(ch => ch.name === 'preparing-for-expedition'); + // const preparingCollector = new Discord.MessageCollector(preparingChannel); + // preparingCollector.on('collect', msg => { + // console.log(msg.content); + // }); + // setInterval( function() { encounter(encounterChannel); }, 300000 ); + // encounter(encounterChannel); +}); + +client.on('message', msg => { + if (msg.channel.type === "dm") return; + + messageContent = msg.content.split(" "); + command = messageContent[0]; + if (messageContent.length > 1) args = messageContent.slice(1); + + if (!command.startsWith(info.prefix)) return; + + authorId = msg.author.id; + playerFile = `./data/playerdata/${authorId}.json`; + + if (fs.existsSync(playerFile)) { + + rawPlayerData = fs.readFileSync(playerFile); + playerData = JSON.parse(rawPlayerData); + + processes.forEach(process => { + if(command === `!${process.title}`){ + process.run() + } + }); + if (command === `!read`) { + read(msg, playerData); + } else if (command === `!create`) { + msg.reply(`You already have a squirrel silly.`); + } else if (command === `!namechange`) { + nameChange(msg, playerData, playerFile); + } else if (command === `!races`) { + printRaces(msg); + } else if (command === `!classes`) { + printClasses(msg); + } + + } else if (command === `!create`) { + console.log(`Attempting to make a squirrel for ${authorId}`); + if (create(msg, args)) + console.log(`Squirrel made succesfully for ${authorId}`); + else + console.log(`Failed to create quirrel for ${authorId}`); + } +}); + +client.login(info.key); + +function encounter(encounterChannel: any): void { + if (!encounterInProgress) { // randomInt(1,60) === 60 && + console.log("Starting Encounter"); + encounterInProgress = true; + encounterChannel.send("An encounter is beginning!"); + + encounterChannel.send(`\`■■■ ■■■ ■■■ ■■■\`\n\`■■■ ■■■ ■■■ ■■■\`\n\`■■■ ■■■ ■■■ ■■■\``).then(msg => { + + + + console.log("Encounter finished"); + encounterInProgress = false; + }); + } +} +function randomInt(low: number, high: number): number { + return Math.floor(Math.random() * (high - low + 1) + low) +} + +function raceText(race: string): string { + if (race === races[2]) return capitalize(race); + else if (race === races[0] || race === races[1]) return `${capitalize(race)} Squirrel`; + else { + console.log(`Error ${race} is not a valid race`); + return ""; + } +} + +function capitalize(toCaps: string): string { + return toCaps.charAt(0).toUpperCase() + toCaps.slice(1).toLowerCase(); +} + +// Commands: + +function read(msg: any, data: player): void { + let embed = new Discord.RichEmbed() + .setTitle(msg.author.username) + .setDescription("Squirrel Info") + .setColor("#E81B47") + .setThumbnail(msg.author.avatarURL) + .addField("Name", data.name) + .addField("Race", raceText(data.race)) + .addField("Class", capitalize(data.class)) + .addField("Nuts", data.nuts) + .addField("Level", data.level); + if (data.dm === true) + embed.addField("DM Points", data.dm_points); + + msg.channel.send(embed); +} + +function create(msg: any, args: Array): boolean { + if (args.length === 3) { + let newSquirrel: Array = msg.content.split(' '); + let newPlayer: player = newPlayerTemplate; + let incorrect: string = ""; + + incorrect = " race"; + races.some(type => { + if (newSquirrel[2].toLowerCase() == type) { + incorrect = ""; + return true; + } + }); + + if (incorrect == "") + incorrect = " class"; + else + incorrect += ", and class"; + classes.some(type => { + if (newSquirrel[3].toLowerCase() == type) { + if (incorrect == " race, and class") + incorrect = " race"; + else + incorrect = ""; + return true; + } + }); + + if (incorrect === "") { + newPlayer.name = newSquirrel[1] + " " + lastNames[randomInt(0, lastNames.length - 1)]; + newPlayer.race = newSquirrel[2]; + newPlayer.class = newSquirrel[3]; + fs.writeFileSync(playerFile, JSON.stringify(newPlayer)); + msg.reply(`Squirrel ${newPlayer.name} has been created`); + return true; + } else { + msg.reply(`Some parameters were entered incorrectly. Remember the format is "create name race class". Your name can be whatever you want, but you have to choose from !race, and !class. You incorrectly entered your:${incorrect}.`); + return false; + } + } else { + msg.reply(`Too many or too few parameters were entered. The format is "create name race class". You only get to choose your first name, don't write a last name.`); + return false; + } +} + +function nameChange(msg: any, data: player, file: any): void { + if (data.level == 1) { + if (msg.content.split(' ').length >= 2) { + let newName: string = msg.content.split(' ')[1]; + data.name = capitalize(newName) + " " + data.name.split(' ')[1]; + fs.writeFileSync(file, JSON.stringify(data)); + msg.reply(`Name changed to ${data.name}`); + } else { + msg.reply(`Please provide a name`); + } + } else { + msg.reply(`Sorry, you have to be level 1 to change your name. You're stuck with ${data.name}`); + } +} + +function printRaces(msg: any): void { + let print = "The races are: "; + for (let i = 0; i < races.length; i++) { + if (i === races.length - 1) { + print += `& ${raceText(races[i])}s`; + } else { + print += `${raceText(races[i])}s, `; + } + } + msg.reply(print); +} + +function printClasses(msg: any): void { + let print = "The classes are: "; + for (let i = 0; i < classes.length; i++) { + if (i === classes.length - 1) { + print += `& ${capitalize(classes[i])}s`; + } else { + print += `${capitalize(classes[i])}s, `; + } + } + msg.reply(print); +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..4afcebe --- /dev/null +++ b/yarn.lock @@ -0,0 +1,82 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/node@^11.9.3": + version "11.9.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.9.3.tgz#14adbb5ab8cd563f549fbae8dbe92e0b7d6e76cc" + integrity sha512-DMiqG51GwES/c4ScBY0u5bDlH44+oY8AeYHjY1SGCWidD7h08o1dfHue/TGK7REmif2KiJzaUskO+Q0eaeZ2fQ== + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + +discord.js@^11.4.2: + version "11.4.2" + resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-11.4.2.tgz#54586981926521572051f2a30b984aad2b49786e" + integrity sha512-MDwpu0lMFTjqomijDl1Ed9miMQe6kB4ifKdP28QZllmLv/HVOJXhatRgjS8urp/wBlOfx+qAYSXcdI5cKGYsfg== + dependencies: + long "^4.0.0" + prism-media "^0.0.3" + snekfetch "^3.6.4" + tweetnacl "^1.0.0" + ws "^4.0.0" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= + +global@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + +prism-media@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-0.0.3.tgz#8842d4fae804f099d3b48a9a38e3c2bab6f4855b" + integrity sha512-c9KkNifSMU/iXT8FFTaBwBMr+rdVcN+H/uNv1o+CuFeTThNZNTOrQ+RgXA1yL/DeLk098duAeRPP3QNPNbhxYQ== + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= + +safe-buffer@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +snekfetch@^3.6.4: + version "3.6.4" + resolved "https://registry.yarnpkg.com/snekfetch/-/snekfetch-3.6.4.tgz#d13e80a616d892f3d38daae4289f4d258a645120" + integrity sha512-NjxjITIj04Ffqid5lqr7XdgwM7X61c/Dns073Ly170bPQHLm6jkmelye/eglS++1nfTWktpP6Y2bFXjdPlQqdw== + +tweetnacl@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.1.tgz#2594d42da73cd036bd0d2a54683dd35a6b55ca17" + integrity sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A== + +ws@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" + integrity sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0"