├── src ├── globals │ ├── messages.js │ └── constants.js ├── util │ ├── commandManager.js │ └── common.js ├── commands │ ├── info.js │ ├── help.js │ └── mvp.js └── index.js ├── img ├── add.PNG ├── info.PNG ├── list.PNG └── remind.PNG ├── .flowconfig ├── .prettierrc ├── .babelrc ├── .gitignore ├── LICENSE ├── README.md ├── .eslintrc.js ├── package.json └── data └── bossList.json /src/globals/messages.js: -------------------------------------------------------------------------------- 1 | export const messages = {}; 2 | -------------------------------------------------------------------------------- /img/add.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RagnaWay/Sprinkles/HEAD/img/add.PNG -------------------------------------------------------------------------------- /img/info.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RagnaWay/Sprinkles/HEAD/img/info.PNG -------------------------------------------------------------------------------- /img/list.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RagnaWay/Sprinkles/HEAD/img/list.PNG -------------------------------------------------------------------------------- /img/remind.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RagnaWay/Sprinkles/HEAD/img/remind.PNG -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | [include] 4 | 5 | [libs] 6 | 7 | [lints] 8 | 9 | [options] 10 | module.file_ext=.js 11 | 12 | [strict] 13 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all", 8 | "endOfLine": "auto" 9 | } 10 | -------------------------------------------------------------------------------- /src/globals/constants.js: -------------------------------------------------------------------------------- 1 | export const events = { 2 | READY: 'ready', 3 | MESSAGE: 'message', 4 | }; 5 | export const BOT_NAME = 'Sprinkles'; 6 | export const DEFAULT_COMMAND_PREFIX = '$'; 7 | 8 | export const COMMANDS_DIRECTORY = './src/commands'; 9 | export const BOSS_DATA_DIRECTORY = './data/bossList.json'; 10 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-flow"], 3 | "plugins": [ 4 | "@babel/plugin-syntax-dynamic-import", 5 | "@babel/plugin-transform-modules-commonjs", 6 | "@babel/plugin-proposal-class-properties", 7 | "dynamic-import-node", 8 | "@babel/plugin-proposal-optional-chaining", 9 | "inline-dotenv" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | 26 | .idea 27 | -------------------------------------------------------------------------------- /src/util/commandManager.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import Discord from 'discord.js'; 3 | import { COMMANDS_DIRECTORY } from '../globals/constants'; 4 | 5 | const commandFiles = fs.readdirSync(COMMANDS_DIRECTORY) 6 | .filter((fileName) => fileName.endsWith('.js')); 7 | 8 | export const loadCommands = async (discordClient) => { 9 | discordClient.commands = new Discord.Collection(); 10 | console.log("Loading commands..."); 11 | for (const fileName of commandFiles) { 12 | const command = await import(`../commands/${fileName}`); 13 | discordClient.commands.set(command.name, command); 14 | } 15 | console.log("Loaded all commands..."); 16 | }; 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Janelle Unabia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sprinkles 2 | Sprinkles is a Discord bot that aims to be a MVP helper for Ragnarok Online. 3 | 4 | ## Features 5 | - Show boss information (RMS-based) 6 | - Creates a list of bosses currently being held by the player 7 | - Creates a reminder when the respawn time for a boss is starting 8 | 9 | ## Commands 10 | ``` 11 | $help 12 | $info 13 | $mvp add 14 | $mvp list 15 | $mvp clear 16 | ``` 17 | 18 | ### $help 19 | To view all the available bot commands. 20 | 21 | ### $info "bossname" 22 | ![info](img/info.PNG) 23 | 24 | 25 | To view the information of a specific boss. 26 | 27 | ### $mvp add "bossname" 28 | ![info](img/add.PNG) 29 | 30 | 31 | To add a boss into the MVP list. 32 | 33 | 34 | ![info](img/remind.PNG) 35 | 36 | 37 | This will also set a reminder on the boss' scheduled respawn time. 38 | 39 | ### $mvp list 40 | ![info](img/list.PNG) 41 | 42 | 43 | To view the list of the current MVPs with a respawn time schedule. 44 | 45 | #### $mvp clear 46 | To clear all contents in the MVP list. 47 | This command should **ONLY** be used when there is a server restart 48 | 49 | > Sprinkles is developed by 🌺 Xaikyu 🌺#3108 and Jeee#0016 -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | const prettierOptions = JSON.parse(fs.readFileSync(path.resolve(__dirname, '.prettierrc'), 'utf8')); 5 | 6 | module.exports = { 7 | parser: 'babel-eslint', 8 | extends: ['prettier'], 9 | plugins: ['prettier'], 10 | env: { 11 | jest: true, 12 | browser: true, 13 | node: true, 14 | es6: true, 15 | }, 16 | parserOptions: { 17 | ecmaVersion: 6, 18 | sourceType: 'module', 19 | }, 20 | rules: { 21 | 'prettier/prettier': ['error', prettierOptions], 22 | 'arrow-body-style': [2, 'as-needed'], 23 | 'class-methods-use-this': 0, 24 | 'import/imports-first': 0, 25 | 'import/newline-after-import': 0, 26 | 'import/no-dynamic-require': 0, 27 | 'import/no-extraneous-dependencies': 0, 28 | 'import/no-named-as-default': 0, 29 | 'import/prefer-default-export': 0, 30 | indent: [ 31 | 2, 32 | 2, 33 | { 34 | SwitchCase: 1, 35 | }, 36 | ], 37 | 'max-len': 0, 38 | 'newline-per-chained-call': 0, 39 | 'no-confusing-arrow': 0, 40 | 'no-unused-vars': 2, 41 | 'no-use-before-define': 0, 42 | 'prefer-template': 2, 43 | 'require-yield': 0, 44 | }, 45 | }; 46 | -------------------------------------------------------------------------------- /src/commands/info.js: -------------------------------------------------------------------------------- 1 | import { checkAlias, checkInput, sendBossInfoEmbed } from '../util/common'; 2 | 3 | export const name = 'info'; 4 | export const description = 'To check boss information'; 5 | 6 | export const execute = (message, args, bossList) => { 7 | let input = args.join(' '); 8 | let isFound = false; 9 | let isValidInput = false; 10 | let isValidAlias = true; 11 | 12 | isValidAlias = checkAlias(input); 13 | isValidInput = checkInput(input, isValidAlias); 14 | 15 | if (isValidInput) { 16 | for (let i = 0; i < bossList.bosses.length; i++) { 17 | if ( 18 | bossList.bosses[i].bossName.toLowerCase().includes(input.toLowerCase().trim()) && 19 | !isValidAlias 20 | ) { 21 | isFound = sendBossInfoEmbed(message, bossList.bosses[i], isFound); 22 | } else if (isValidAlias) { 23 | for (let j = 0; j < bossList.bosses[i].alias.length; j++) { 24 | if (bossList.bosses[i].alias[j].toLowerCase() === input.toLowerCase().trim()) { 25 | isFound = sendBossInfoEmbed(message, bossList.bosses[i], isFound); 26 | } 27 | } 28 | } 29 | } 30 | } else { 31 | message.channel.send('Please enter at least **3 characters** or the correct **boss alias**'); 32 | } 33 | 34 | if (!isFound && isValidInput) { 35 | message.channel.send('Boss not found! Please try again.'); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spinkles-bot", 3 | "version": "1.0.0", 4 | "description": "A discord bot", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon --exec babel-node -- src/index.js", 8 | "flow": "flow" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "axios": "^0.19.2", 15 | "discord.js": "^12.3.1", 16 | "moment": "^2.29.1", 17 | "nodemon": "^2.0.7" 18 | }, 19 | "devDependencies": { 20 | "@babel/cli": "^7.10.1", 21 | "@babel/core": "^7.10.2", 22 | "@babel/node": "^7.10.1", 23 | "@babel/plugin-proposal-class-properties": "^7.10.1", 24 | "@babel/plugin-proposal-optional-chaining": "^7.10.1", 25 | "@babel/plugin-syntax-dynamic-import": "^7.8.3", 26 | "@babel/plugin-transform-modules-commonjs": "^7.10.1", 27 | "@babel/preset-env": "^7.10.2", 28 | "@babel/preset-flow": "^7.10.1", 29 | "babel-eslint": "^10.1.0", 30 | "babel-loader": "^8.1.0", 31 | "babel-plugin-dynamic-import-node": "^2.3.3", 32 | "babel-plugin-inline-dotenv": "^1.5.0", 33 | "cross-env": "^7.0.2", 34 | "dotenv": "^8.2.0", 35 | "eslint": "^7.2.0", 36 | "eslint-config-prettier": "^6.11.0", 37 | "eslint-plugin-prettier": "^3.1.4", 38 | "flow-bin": "^0.127.0", 39 | "nodeman": "^1.1.2", 40 | "prettier": "^2.0.5" 41 | }, 42 | "nodemonConfig": { 43 | "ignore": [ 44 | "data/*" 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/commands/help.js: -------------------------------------------------------------------------------- 1 | export const name = 'help'; 2 | export const description = 'To check the available bot commands'; 3 | 4 | export const execute = (message, args) => { 5 | if (args.length === 0) { 6 | message.channel.send({ embed: helpEmbed }); 7 | } else { 8 | message.channel.send( 9 | 'Command **does not exist**! Please enter `$help` for the list of bot commands.', 10 | ); 11 | } 12 | }; 13 | 14 | const helpEmbed = { 15 | color: 0xd8bfdd, 16 | title: 'Sprinkles Bot Commands', 17 | thumbnail: { 18 | url: 'https://pm1.narvii.com/6809/215fde5d4d73b9012c311b096e54a5567bde7befv2_hq.jpg', 19 | }, 20 | fields: [ 21 | { 22 | name: '$help', 23 | value: 'To view all the available bot commands', 24 | }, 25 | { 26 | name: '$info ', 27 | value: 'To view the information of a specific boss', 28 | }, 29 | { 30 | name: '$mvp add ', 31 | value: 32 | "To add a boss into the MVP list \nThis will also set a reminder on the boss' scheduled respawn time", 33 | }, 34 | { 35 | name: '$mvp list', 36 | value: 'To view the list of the current MVPs with a respawn time schedule', 37 | }, 38 | { 39 | name: '$mvp clear', 40 | value: 41 | 'To clear all contents in the MVP list. \nUse this **ONLY** when there is a server restart', 42 | }, 43 | ], 44 | footer: { 45 | text: 'Sprinkles is developed by 🌺 Xaikyu 🌺#3108 and Jeee#0016', 46 | }, 47 | }; 48 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Discord from 'discord.js'; 2 | import { BOSS_DATA_DIRECTORY, BOT_NAME, DEFAULT_COMMAND_PREFIX, events } from './globals/constants'; 3 | import * as commandManager from './util/commandManager'; 4 | import { 5 | convertToTimestamp, 6 | convertUnixTimeToCalendarFormat, 7 | getCurrentTime, 8 | getCurrentTimeInHMAFormat, 9 | readFile, 10 | writeFile, 11 | } from './util/common'; 12 | 13 | const discordClient = new Discord.Client(); 14 | let reminderChannels = []; 15 | const bossList = readFile(BOSS_DATA_DIRECTORY); 16 | const onReady = () => { 17 | commandManager.loadCommands(discordClient).then(onLoad); 18 | }; 19 | 20 | const onLoad = () => { 21 | console.log(`${BOT_NAME} is online!`); 22 | checkMvpRespawnTimers(); 23 | }; 24 | 25 | const checkMvpRespawnTimers = () => { 26 | setInterval(() => { 27 | let currentTime = convertToTimestamp(getCurrentTime()); 28 | for (let i = 0; i < bossList.bosses.length; i++) { 29 | if (bossList.bosses[i].deathTime && currentTime >= bossList.bosses[i].minRespawnTime) { 30 | const remindEmbed = new Discord.MessageEmbed() 31 | .setColor('#0x43a047') 32 | .setTitle(`${bossList.bosses[i].bossName} respawn schedule is now **UP!** `) 33 | .setThumbnail(bossList.bosses[i].imageUrl) 34 | .addFields( 35 | { 36 | name: 'Min. Respawn', 37 | value: convertUnixTimeToCalendarFormat(bossList.bosses[i].minRespawnTime) || '--', 38 | inline: true, 39 | }, 40 | { 41 | name: 'Max. Respawn', 42 | value: convertUnixTimeToCalendarFormat(bossList.bosses[i].maxRespawnTime) || '--', 43 | inline: true, 44 | }, 45 | ) 46 | .setFooter( 47 | `Current Time: ${getCurrentTimeInHMAFormat()}`, 48 | 'https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/microsoft/209/alarm-clock_23f0.png', 49 | ); 50 | reminderChannels.forEach((channel) => { 51 | channel.send(remindEmbed); 52 | }); 53 | bossList.bosses[i].deathTime = null; 54 | bossList.bosses[i].minRespawnTime = null; 55 | bossList.bosses[i].maxRespawnTime = null; 56 | } 57 | } 58 | }, 1000); 59 | 60 | setInterval(function () { 61 | writeFile(BOSS_DATA_DIRECTORY, bossList); 62 | }, 30000); 63 | }; 64 | 65 | const onMessageReceived = (message) => { 66 | if (!message.content.startsWith(DEFAULT_COMMAND_PREFIX) || message.author.bot) return; 67 | 68 | const args = message.content.slice(DEFAULT_COMMAND_PREFIX.length).split(/ +/); 69 | const command = args.shift().toLowerCase(); 70 | 71 | if (command == 'mvp') { 72 | discordClient.commands.get('mvp').execute(message, args, bossList); 73 | } else if (command == 'help') { 74 | discordClient.commands.get('help').execute(message, args); 75 | } else if (command == 'info') { 76 | discordClient.commands.get('info').execute(message, args, bossList); 77 | } else if (command == 'set-reminder-channel') { 78 | if (reminderChannels.filter((channel) => channel.id === message.channel.id).length > 0) { 79 | message.channel.send('[FAILED] MVP reminders are already being sent in this channel'); 80 | } else { 81 | reminderChannels.push(message.channel); 82 | message.channel.send('[SUCCESS] MVP reminders are now sent in this channel'); 83 | } 84 | } else { 85 | message.channel.send( 86 | 'Command **does not exist**! Please enter `$help` for the list of bot commands.', 87 | ); 88 | } 89 | }; 90 | 91 | discordClient.once(events.READY, onReady); 92 | discordClient.on(events.MESSAGE, onMessageReceived); 93 | discordClient.login(`${process.env.TOKEN}`); 94 | -------------------------------------------------------------------------------- /src/commands/mvp.js: -------------------------------------------------------------------------------- 1 | import { 2 | addTimeInSecondsToCalendarFormat, 3 | addTimeInSecondsToUnixFormat, 4 | checkAlias, 5 | checkInput, 6 | getCurrentTime, 7 | convertToTimestamp, 8 | convertUnixTimeToHMAFormat, 9 | sendBossAddedEmbed, 10 | sortArray, 11 | } from '../util/common'; 12 | export const name = 'mvp'; 13 | export const description = 'Ragnarok Online MVP helper'; 14 | 15 | export const execute = (message, args, bossList) => { 16 | let input = ''; 17 | let isFound = false; 18 | let isValidInput = false; 19 | let isValidAlias = true; 20 | let currentMVPList = []; 21 | let currentTimeInUnix = convertToTimestamp(getCurrentTime()); 22 | let minRespawnTime; 23 | let maxRespawnTime; 24 | 25 | if (args[0] === 'add') { 26 | for (let i = 1; i < args.length; i++) { 27 | input += args[i] + ' '; 28 | } 29 | 30 | isValidAlias = checkAlias(input); 31 | isValidInput = checkInput(input, isValidAlias); 32 | 33 | if (isValidInput) { 34 | for (let i = 0; i < bossList.bosses.length; i++) { 35 | if ( 36 | bossList.bosses[i].bossName.toLowerCase().includes(input.toLowerCase().trim()) && 37 | !isValidAlias 38 | ) { 39 | isFound = setupBossAddedEmbed( 40 | bossList.bosses[i], 41 | bossList.bosses[i].minRespawnTimeScheduleInSeconds, 42 | bossList.bosses[i].maxRespawnTimeScheduleInSeconds, 43 | isFound, 44 | message, 45 | ); 46 | 47 | // change deathTime, minRespawn and maxRespawn in bossList file 48 | 49 | minRespawnTime = addTimeInSecondsToUnixFormat( 50 | bossList.bosses[i].minRespawnTimeScheduleInSeconds, 51 | ); 52 | maxRespawnTime = addTimeInSecondsToUnixFormat( 53 | bossList.bosses[i].maxRespawnTimeScheduleInSeconds, 54 | ); 55 | 56 | bossList.bosses[i].deathTime = currentTimeInUnix; 57 | bossList.bosses[i].minRespawnTime = minRespawnTime; 58 | bossList.bosses[i].maxRespawnTime = maxRespawnTime; 59 | break; 60 | } else if (isValidAlias) { 61 | for (let j = 0; j < bossList.bosses[i].alias.length; j++) { 62 | if (bossList.bosses[i].alias[j].toLowerCase() === input.toLowerCase().trim()) { 63 | isFound = setupBossAddedEmbed( 64 | bossList.bosses[i], 65 | bossList.bosses[i].minRespawnTimeScheduleInSeconds, 66 | bossList.bosses[i].maxRespawnTimeScheduleInSeconds, 67 | isFound, 68 | message, 69 | ); 70 | // change deathTime, minRespawn and maxRespawn in bossList file 71 | 72 | minRespawnTime = addTimeInSecondsToUnixFormat( 73 | bossList.bosses[i].minRespawnTimeScheduleInSeconds, 74 | ); 75 | maxRespawnTime = addTimeInSecondsToUnixFormat( 76 | bossList.bosses[i].maxRespawnTimeScheduleInSeconds, 77 | ); 78 | 79 | bossList.bosses[i].deathTime = currentTimeInUnix; 80 | bossList.bosses[i].minRespawnTime = minRespawnTime; 81 | bossList.bosses[i].maxRespawnTime = maxRespawnTime; 82 | } 83 | } 84 | } 85 | } 86 | } else { 87 | message.channel.send('Please enter at least **3 characters** or the correct **boss alias**'); 88 | } 89 | if (!isFound && isValidInput) { 90 | message.channel.send( 91 | 'Boss not found! Please try again with the correct **boss name** or **alias**.', 92 | ); 93 | } 94 | } else if (args[0] === 'list') { 95 | let txt = ''; 96 | let minTime; 97 | let maxTime; 98 | 99 | for (let i = 0; i < bossList.bosses.length; i++) { 100 | if (bossList.bosses[i].deathTime && bossList.bosses[i].minRespawnTime > currentTimeInUnix) { 101 | currentMVPList.push(bossList.bosses[i]); 102 | } 103 | } 104 | currentMVPList = sortArray(currentMVPList); 105 | 106 | if (currentMVPList.length > 0) { 107 | for (let i = 0; i < currentMVPList.length; i++) { 108 | minTime = convertUnixTimeToHMAFormat(currentMVPList[i].minRespawnTime); 109 | maxTime = convertUnixTimeToHMAFormat(currentMVPList[i].maxRespawnTime); 110 | txt += `🔹 **${currentMVPList[i].bossName}** | ${minTime} - ${maxTime}\n`; 111 | } 112 | message.channel.send(txt); 113 | } else { 114 | message.channel.send( 115 | '⚠️ There is **no** MVP list! Enter `$mvp add ` to add a MVP into the list', 116 | ); 117 | } 118 | } else if (args[0] === 'clear') { 119 | for (let i = 0; i < bossList.bosses.length; i++) { 120 | if (bossList.bosses[i].deathTime) { 121 | bossList.bosses[i].minRespawnTime = null; 122 | bossList.bosses[i].maxRespawnTime = null; 123 | bossList.bosses[i].deathTime = null; 124 | } 125 | } 126 | currentMVPList = null; 127 | message.channel.send('✅ MVP List has been cleared **successfully**!'); 128 | } else { 129 | message.channel.send( 130 | '⚠️ Command **does not exist**! Please enter `$help` for the list of bot commands.', 131 | ); 132 | } 133 | }; 134 | 135 | // * parameter = boss data 136 | // * returns isFound result 137 | const setupBossAddedEmbed = ( 138 | bossList, 139 | minRespawnTimeScheduleInSeconds, 140 | maxRespawnTimeScheduleInSeconds, 141 | isFound, 142 | message, 143 | ) => { 144 | let minRespawnTimeInCalendar; 145 | let maxRespawnTimeInCalendar; 146 | 147 | minRespawnTimeInCalendar = addTimeInSecondsToCalendarFormat(minRespawnTimeScheduleInSeconds); 148 | maxRespawnTimeInCalendar = addTimeInSecondsToCalendarFormat(maxRespawnTimeScheduleInSeconds); 149 | 150 | isFound = sendBossAddedEmbed( 151 | message, 152 | bossList, 153 | minRespawnTimeInCalendar, 154 | maxRespawnTimeInCalendar, 155 | isFound, 156 | ); 157 | 158 | return isFound; 159 | }; 160 | -------------------------------------------------------------------------------- /src/util/common.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import Discord from 'discord.js'; 3 | import { BOSS_DATA_DIRECTORY } from '../globals/constants'; 4 | import moment from 'moment'; 5 | 6 | // * parameters = time 7 | // * returns a number separated with commas 8 | export const addNumberWithCommas = (x) => x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); 9 | 10 | // * parameters = time 11 | // * returns the converted seconds into minutes or hours 12 | export const convertSecondstoHMS = (time) => { 13 | time = Number(time); 14 | var h = Math.floor(time / 3600); 15 | var m = Math.floor((time % 3600) / 60); 16 | var s = Math.floor((time % 3600) % 60); 17 | 18 | var hDisplay = h > 0 ? h + (h == 1 ? ' hour ' : ' hours ') : ''; 19 | var mDisplay = m > 0 ? m + (m == 1 ? ' minute ' : ' minutes ') : ''; 20 | var sDisplay = s > 0 ? s + (s == 1 ? ' second' : ' seconds') : ''; 21 | return hDisplay + mDisplay + sDisplay; 22 | }; 23 | 24 | export const removePrefix = (input, prefix) => input.replace(prefix, '').trim(); 25 | export const tokenizeInput = (input, prefix) => removePrefix(input, prefix).split(' '); 26 | 27 | // * parameter = file name 28 | // * returns parsed data 29 | export const readFile = (filename) => { 30 | const data = fs.readFileSync(filename); 31 | const result = JSON.parse(data); 32 | return result; 33 | }; 34 | 35 | // * parameters = user input 36 | // * returns TRUE if boss alias is found in the db 37 | export const checkAlias = (input) => { 38 | let isFound = false; 39 | let bossList = readFile(BOSS_DATA_DIRECTORY); 40 | 41 | for (let i = 0; i < bossList.bosses.length; i++) { 42 | for (let j = 0; j < bossList.bosses[i].alias.length; j++) { 43 | if (bossList.bosses[i].alias[j].toLowerCase() === input.toLowerCase().trim()) { 44 | isFound = true; 45 | } 46 | } 47 | } 48 | return isFound; 49 | }; 50 | 51 | // * parameters = user input and its result checked by checkAlias() 52 | // * returns TRUE if input is correct 53 | export const checkInput = (input, checkAliasResult) => { 54 | let isValidInput = true; 55 | 56 | if (input.length < 3 && !checkAliasResult) { 57 | isValidInput = false; 58 | } 59 | return isValidInput; 60 | }; 61 | 62 | // * parameters = boss info 63 | // * returns embed with boss info 64 | export const createBossInfoEmbed = ({ 65 | bossName, 66 | HP, 67 | race, 68 | property, 69 | location, 70 | minRespawnTimeScheduleInSeconds, 71 | maxRespawnTimeScheduleInSeconds, 72 | imageUrl, 73 | alias, 74 | }) => { 75 | const bossInfoEmbed = new Discord.MessageEmbed() 76 | .setColor('#0xD8BFDD') 77 | .setTitle(bossName) 78 | .setDescription(`**Alias:** ${alias.join(', ')}`) 79 | .setThumbnail(imageUrl) 80 | .addFields( 81 | { name: 'HP', value: addNumberWithCommas(HP) || '--' }, 82 | { name: 'Location', value: location || '--' }, 83 | { name: 'Race', value: race || '--', inline: true }, 84 | { name: '\u200B', value: '\u200B', inline: true }, 85 | { name: 'Property', value: property || '--', inline: true }, 86 | { 87 | name: 'Min. Respawn', 88 | value: convertSecondstoHMS(minRespawnTimeScheduleInSeconds) || '--', 89 | inline: true, 90 | }, 91 | { name: '\u200B', value: '\u200B', inline: true }, 92 | { 93 | name: 'Max. Respawn', 94 | value: convertSecondstoHMS(maxRespawnTimeScheduleInSeconds) || '--', 95 | inline: true, 96 | }, 97 | ); 98 | return bossInfoEmbed; 99 | }; 100 | 101 | // * parameters = message, boss data, isFound 102 | // * returns isFound result and sends boss info embed 103 | export const sendBossInfoEmbed = (message, data, isFound) => { 104 | message.channel.send(createBossInfoEmbed(data)); 105 | isFound = true; 106 | return isFound; 107 | }; 108 | 109 | // * parameters = boss info 110 | // * returns embed with boss info and its respawn times 111 | export const createBossAddedEmbed = ( 112 | { bossName, location, imageUrl }, 113 | minRespawnTimeCalendarFormat, 114 | maxRespawnTimeCalendarFormat, 115 | ) => { 116 | const bossAddedEmbed = new Discord.MessageEmbed() 117 | .setColor('#0xf44336') 118 | .setTitle(bossName) 119 | .setThumbnail(imageUrl) 120 | .addFields( 121 | { name: 'Location', value: location || '--' }, 122 | { name: 'Min. Respawn', value: minRespawnTimeCalendarFormat || '--', inline: true }, 123 | { name: '\u200B', value: '\u200B', inline: true }, 124 | { name: 'Max. Respawn', value: maxRespawnTimeCalendarFormat || '--', inline: true }, 125 | ) 126 | .setFooter( 127 | `Time of Death: ${getCurrentTimeInHMAFormat()}`, 128 | 'https://emoji.gg/assets/emoji/9468_ghostplus.gif', 129 | ); 130 | return bossAddedEmbed; 131 | }; 132 | 133 | // * parameters = message, boss data, min respawn time, max respawn time, isFound 134 | // * returns isFound result and sends boss info embed 135 | export const sendBossAddedEmbed = ( 136 | message, 137 | data, 138 | minRespawnTimeCalendarFormat, 139 | maxRespawnTimeCalendarFormat, 140 | isFound, 141 | ) => { 142 | message.channel.send( 143 | createBossAddedEmbed(data, minRespawnTimeCalendarFormat, maxRespawnTimeCalendarFormat), 144 | ); 145 | message.channel.send( 146 | `MVP added successfully!\nI will remind you in **${convertSecondstoHMS( 147 | data.minRespawnTimeScheduleInSeconds, 148 | )}**!`, 149 | ); 150 | isFound = true; 151 | return isFound; 152 | }; 153 | 154 | // * returns current time in hh:mm A format 155 | export const getCurrentTimeInHMAFormat = () => { 156 | let currentTime = moment(); 157 | return moment(currentTime).format('hh:mm A'); 158 | }; 159 | 160 | // * returns current time in default format 161 | export const getCurrentTime = () => { 162 | let currentTime = moment(); 163 | return moment(currentTime); 164 | }; 165 | 166 | // * returns time in unix format 167 | export const convertToTimestamp = (time) => moment(time).unix(); 168 | 169 | // * parameters = time in unix 170 | // * returns time in calendar format 171 | export const convertUnixTimeToCalendarFormat = (time) => moment.unix(time).calendar(); 172 | 173 | // * parameters = time in unix 174 | // * returns time in HMA format 175 | export const convertUnixTimeToHMAFormat = (time) => moment.unix(time).format('hh:mm A'); 176 | 177 | // * parameters = time in seconds 178 | // * returns = added time in calendar format 179 | export const addTimeInSecondsToCalendarFormat = (time) => moment().add(time, 'seconds').calendar(); 180 | 181 | // * parameters = time in seconds 182 | // * returns = added time in unix format 183 | export const addTimeInSecondsToUnixFormat = (time) => moment().add(time, 'seconds').unix(); 184 | 185 | // * parameters = time in seconds 186 | // * returns time in milliseconds 187 | export const convertSecondsToMS = (seconds) => seconds * 1000; 188 | 189 | // * parameters = file to be written, and data to be written 190 | export const writeFile = (filename, data) => { 191 | let jsonString = JSON.stringify(data); 192 | fs.writeFile(filename, jsonString, (err) => { 193 | if (err) { 194 | console.log('Error in writing file!', err); 195 | } else { 196 | console.log(`Successfully wrote the file in ${filename}`); 197 | } 198 | }); 199 | }; 200 | 201 | // * parameters = boss data, message 202 | // * sends the boss list with scheduled respawn times 203 | export const createBossList = ({ bossName }, min, max, message) => { 204 | message.channel.send(`${bossName} | **Min** ${min} | **Max** ${max} \n`); 205 | }; 206 | 207 | // * parameter = array 208 | // * sends a sorted array 209 | export const sortArray = (arr) => 210 | arr.sort((a, b) => (a.minRespawnTime > b.minRespawnTime ? 1 : -1)); 211 | -------------------------------------------------------------------------------- /data/bossList.json: -------------------------------------------------------------------------------- 1 | {"bosses":[{"ID":1511,"bossName":"Amon Ra","HP":1214138,"race":"Demi-Human","property":"Fire 3","location":"moc_pryd06","minRespawnTimeScheduleInSeconds":3600,"maxRespawnTimeScheduleInSeconds":4200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1511.gif","alias":["AR"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1647,"bossName":"Assassin Cross Eremes","HP":1411230,"race":"Demi-Human","property":"Poison 4","location":"lhz_dun03","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1647.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1630,"bossName":"Bacsojin","HP":253221,"race":"Demi-Human","property":"Wind 3","location":"lou_dun03","minRespawnTimeScheduleInSeconds":7020,"maxRespawnTimeScheduleInSeconds":7620,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1630.gif","alias":["White Lady"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1039,"bossName":"Baphomet","HP":668000,"race":"Demon","property":"Shadow 3","location":"prt_maze03","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1039.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2068,"bossName":"Boitata","HP":1283990,"race":"Formless","property":"Fire 3","location":"bra_dun02","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2068.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2238,"bossName":"Champion Chen","HP":4249350,"race":"Demon","property":"Water 4","location":"lhz_dun04","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2238.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2240,"bossName":"Clown Alphoccio","HP":3894278,"race":"Demi-Human","property":"Wind 4","location":"lhz_dun04","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2240.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2236,"bossName":"Creator Flamel","HP":4230000,"race":"Demi-Human","property":"Fire 4","location":"lhz_dun04","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2236.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2253,"bossName":"Daehyon","HP":2500148,"race":"Demi-Human","property":"Earth 4","location":"gld2_pay","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2253.gif","alias":["General Daehyun"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1272,"bossName":"Dark Lord","HP":720000,"race":"Demon","property":"Undead 4","location":"gl_chyard","minRespawnTimeScheduleInSeconds":3600,"maxRespawnTimeScheduleInSeconds":4200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1272.gif","alias":["DL"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1719,"bossName":"Detale","HP":960000,"race":"Dragon","property":"Shadow 4","location":"abyss_03","minRespawnTimeScheduleInSeconds":10800,"maxRespawnTimeScheduleInSeconds":11400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1719.gif","alias":["Detarderous"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1046,"bossName":"Doppelganger","HP":249000,"race":"Demon","property":"Shadow 3","location":"gef_dun02","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1046.gif","alias":["Dopel"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1389,"bossName":"Dracula","HP":320096,"race":"Demon","property":"Shadow 4","location":"gef_dun01","minRespawnTimeScheduleInSeconds":3600,"maxRespawnTimeScheduleInSeconds":4200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1389.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1112,"bossName":"Drake","HP":326666,"race":"Undead","property":"Undead 1","location":"treasure02","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1112.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1115,"bossName":"Eddga","HP":152000,"race":"Brute","property":"Fire 1","location":"pay_fild11","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1115.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1418,"bossName":"Evil Snake Lord","HP":254993,"race":"Brute","property":"Ghost 3","location":"gon_dun03","minRespawnTimeScheduleInSeconds":5640,"maxRespawnTimeScheduleInSeconds":6240,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1418.gif","alias":["ESL"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1871,"bossName":"Fallen Bishop","HP":3333333,"race":"Demon","property":"Shadow 2","location":"abbey02","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1871.gif","alias":["Fallen Bishop Hibram"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1252,"bossName":"Garm","HP":197000,"race":"Brute","property":"Water 4","location":"xmas_fild01","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1252.gif","alias":["Hatii"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2251,"bossName":"Gioia","HP":2507989,"race":"Formless","property":"Wind 4","location":"gld2_ald","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2251.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1768,"bossName":"Gloom Under Night","HP":2298000,"race":"Formless","property":"Ghost 3","location":"ra_san05","minRespawnTimeScheduleInSeconds":18000,"maxRespawnTimeScheduleInSeconds":18600,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1768.gif","alias":["GOM"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2165,"bossName":"Gold Queen Scaraba","HP":6441600,"race":"Insect","property":"Earth 3","location":"dic_dun03","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2165.gif","alias":["GQS"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1086,"bossName":"Golden Thief Bug","HP":126000,"race":"Insect","property":"Fire 3","location":"prt_sewb4","minRespawnTimeScheduleInSeconds":3600,"maxRespawnTimeScheduleInSeconds":4200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1086.gif","alias":["GTB"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1885,"bossName":"Gopinich","HP":299321,"race":"Brute","property":"Earth 3","location":"mosk_dun03","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1885.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2241,"bossName":"Gypsy Trentini","HP":3894278,"race":"Demi-Human","property":"Wind 4","location":"lhz_dun04","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2241.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1649,"bossName":"High Priest Magaleta","HP":1092910,"race":"Demi-Human","property":"Holy 4","location":"lhz_dun03","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1649.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1651,"bossName":"High Wizard Katrinn","HP":1069920,"race":"Demi-Human","property":"Ghost 3","location":"lhz_dun03","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1651.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1832,"bossName":"Ifrit","HP":7700000,"race":"Formless","property":"Fire 4","location":"thor_v03","minRespawnTimeScheduleInSeconds":39600,"maxRespawnTimeScheduleInSeconds":40200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1832.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1492,"bossName":"Incantation Samurai","HP":218652,"race":"Demi-Human","property":"Shadow 3","location":"ama_dun03","minRespawnTimeScheduleInSeconds":5460,"maxRespawnTimeScheduleInSeconds":6060,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1492.gif","alias":["Samurai Specter","IS"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2255,"bossName":"Kades","HP":2505000,"race":"Formless","property":"Shadow 3","location":"gld2_gef","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2255.gif","alias":["Dark Guardian Kades"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1734,"bossName":"Kiel D-01","HP":1523000,"race":"Formless","property":"Shadow 2","location":"kh_dun02","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":10800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1734.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1251,"bossName":"Stormy Knight","HP":240000,"race":"Formless","property":"Wind 4","location":"kh_dun02","minRespawnTimeScheduleInSeconds":3600,"maxRespawnTimeScheduleInSeconds":4200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1251.gif","alias":["SK","Knight of Windstorm"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2202,"bossName":"Kraken","HP":5602800,"race":"Fish","property":"Water 4","location":"iz_dun05","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":9000,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2202.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1688,"bossName":"Lady Tanee","HP":493000,"race":"Plant","property":"Wind 3","location":"ayo_dun02","minRespawnTimeScheduleInSeconds":25200,"maxRespawnTimeScheduleInSeconds":25800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1688.gif","alias":["LT"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2156,"bossName":"Leak","HP":1266000,"race":"Demon","property":"Shadow 2","location":"dew_dun01","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2156.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1646,"bossName":"Lord Knight Seyren","HP":1647590,"race":"Demi-Human","property":"Fire 4","location":"lhz_dun03","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1646.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1373,"bossName":"Lord of Death","HP":603383,"race":"Demon","property":"Shadow 3","location":"niflheim","minRespawnTimeScheduleInSeconds":7980,"maxRespawnTimeScheduleInSeconds":7980,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1373.gif","alias":["LOD","Lord of the Dead"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1147,"bossName":"Maya","HP":169000,"race":"Insect","property":"Earth 4","location":"anthell02","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1147.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1059,"bossName":"Mistress","HP":212000,"race":"Insect","property":"Wind 4","location":"mjolnir_04","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1059.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1150,"bossName":"Moonlight Flower","HP":120000,"race":"Demon","property":"Fire 3","location":"pay_dun04","minRespawnTimeScheduleInSeconds":3600,"maxRespawnTimeScheduleInSeconds":4200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1150.gif","alias":["ML","MF"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1087,"bossName":"Orc Hero","HP":585700,"race":"Demi-Human","property":"Earth 2","location":"gef_fild14","minRespawnTimeScheduleInSeconds":3600,"maxRespawnTimeScheduleInSeconds":4200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1087.gif","alias":["OH"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1087,"bossName":"Orc Hero - 24 Hrs","HP":585700,"race":"Demi-Human","property":"Earth 2","location":"gef_fild02","minRespawnTimeScheduleInSeconds":86400,"maxRespawnTimeScheduleInSeconds":87000,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1087.gif","alias":["OH24"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1190,"bossName":"Orc Lord","HP":783000,"race":"Demi-Human","property":"Earth 4","location":"gef_fild10","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1190.gif","alias":["OL"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1038,"bossName":"Osiris","HP":415400,"race":"Undead","property":"Undead 4","location":"moc_pryd04","minRespawnTimeScheduleInSeconds":3600,"maxRespawnTimeScheduleInSeconds":4200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1038.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2235,"bossName":"Paladin Randel","HP":6870000,"race":"Demi-Human","property":"Holy 4","location":"lhz_dun04","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2235.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1157,"bossName":"Pharaoh","HP":445997,"race":"Demi-Human","property":"Shadow 3","location":"in_sphinx5","minRespawnTimeScheduleInSeconds":3600,"maxRespawnTimeScheduleInSeconds":4200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1157.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1159,"bossName":"Phreeoni","HP":188000,"race":"Brute","property":"Neutral 3","location":"moc_fild17","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1159.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2237,"bossName":"Professor Celia","HP":3847804,"race":"Demi-Human","property":"Ghost 4","location":"moc_fild17","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2237.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2249,"bossName":"Pyuriel","HP":2205000,"race":"Demi-Human","property":"Fire 4","location":"gld2_prt","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2249.gif","alias":["Angry Student Pyuriel"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2087,"bossName":"Queen Scaraba","HP":2441600,"race":"Insect","property":"Earth 3","location":"dic_dun02","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2087.gif","alias":["Scaraba Queen","QS"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1623,"bossName":"RSX 0806","HP":560733,"race":"Formless","property":"Neutral 3","location":"ein_dun02","minRespawnTimeScheduleInSeconds":7500,"maxRespawnTimeScheduleInSeconds":8100,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1623.gif","alias":["RSX-0806"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1650,"bossName":"Sniper Shecil","HP":1349000,"race":"Demi-Human","property":"Wind 4","location":"lhz_dun03","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1650.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2239,"bossName":"Stalker Gertie","HP":4057279,"race":"Demon","property":"Poison 4","location":"lhz_dun04","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2239.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1583,"bossName":"Tao Gunka","HP":193000,"race":"Demon","property":"Neutral 3","location":"beach_dun","minRespawnTimeScheduleInSeconds":18000,"maxRespawnTimeScheduleInSeconds":18600,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1583.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1312,"bossName":"Turtle General","HP":320700,"race":"Brute","property":"Earth 2","location":"tur_dun04","minRespawnTimeScheduleInSeconds":3600,"maxRespawnTimeScheduleInSeconds":4200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1312.gif","alias":["TG"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1751,"bossName":"Valkyrie Randgris","HP":3567200,"race":"Angel","property":"Holy 4","location":"odin_tem03","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1751.gif","alias":["VR"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1685,"bossName":"Vesper","HP":640700,"race":"Brute","property":"Holy 2","location":"jupe_core","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1685.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1648,"bossName":"Whitesmith Harword","HP":1460000,"race":"Demi-Human","property":"Earth 4","location":"lhz_dun03","minRespawnTimeScheduleInSeconds":6000,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1648.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1917,"bossName":"Wounded Morroc","HP":8388607,"race":"Demon","property":"Shadow 4","location":"moc_fild22","minRespawnTimeScheduleInSeconds":43200,"maxRespawnTimeScheduleInSeconds":46800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1917.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1658,"bossName":"Ygnizem","HP":214200,"race":"Demi-Human","property":"Fire 2","location":"lhz_dun02","minRespawnTimeScheduleInSeconds":7200,"maxRespawnTimeScheduleInSeconds":7800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1658.gif","alias":["Egnigem Cenia"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2476,"bossName":"Amdarias","HP":3283990,"race":"Brute","property":"Fire 3","location":"2@gl_k","minRespawnTimeScheduleInSeconds":null,"maxRespawnTimeScheduleInSeconds":null,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2476.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1873,"bossName":"Beelzebub","HP":6666666,"race":"Demon","property":"Ghost 4","location":"abbey03","minRespawnTimeScheduleInSeconds":43200,"maxRespawnTimeScheduleInSeconds":43800,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1873.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2319,"bossName":"Buwaya","HP":4090365,"race":"Dragon","property":"Water 4","location":"1@ma_c","minRespawnTimeScheduleInSeconds":null,"maxRespawnTimeScheduleInSeconds":null,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2319.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1779,"bossName":"Ktullanux","HP":4417000,"race":"Brute","property":"Water 4","location":"ice_dun03","minRespawnTimeScheduleInSeconds":null,"maxRespawnTimeScheduleInSeconds":null,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1779.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1980,"bossName":"Kubkin","HP":1176000,"race":"Demi-Human","property":"Earth 1","location":null,"minRespawnTimeScheduleInSeconds":null,"maxRespawnTimeScheduleInSeconds":null,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1980.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2131,"bossName":"Lost Dragon","HP":608920,"race":"Dragon","property":"Shadow 3","location":"1@mist","minRespawnTimeScheduleInSeconds":null,"maxRespawnTimeScheduleInSeconds":null,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2131.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2022,"bossName":"Nidhoggr's Shadow","HP":3450000,"race":"Dragon","property":"Shadow 4","location":"2@nyd","minRespawnTimeScheduleInSeconds":null,"maxRespawnTimeScheduleInSeconds":null,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2022.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2362,"bossName":"Nightmare Amon Ra","HP":2515784,"race":"Demi-Human","property":"Earth 3","location":"moc_prydn2","minRespawnTimeScheduleInSeconds":null,"maxRespawnTimeScheduleInSeconds":null,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2362.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2475,"bossName":"Root of Corruption","HP":3190000,"race":"Demi-Human","property":"Earth 3","location":"1@gl_k","minRespawnTimeScheduleInSeconds":null,"maxRespawnTimeScheduleInSeconds":null,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2475.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":2341,"bossName":"RWC Boss","HP":3205000,"race":"Angel","property":"Holy 4","location":null,"minRespawnTimeScheduleInSeconds":null,"maxRespawnTimeScheduleInSeconds":null,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/2341.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1708,"bossName":"Thanatos","HP":445660,"race":"Demon","property":"Ghost 4","location":"thana_boss","minRespawnTimeScheduleInSeconds":null,"maxRespawnTimeScheduleInSeconds":null,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1708.gif","alias":["Memory of Thanatos"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1785,"bossName":"Atroce - ra_fild02","HP":1008420,"race":"Brute","property":"Shadow 3","location":"ra_fild02","minRespawnTimeScheduleInSeconds":14400,"maxRespawnTimeScheduleInSeconds":15000,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1785.gif","alias":["atr_rf02"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1785,"bossName":"Atroce - ra_fild03","HP":1008420,"race":"Brute","property":"Shadow 3","location":"ra_fild03","minRespawnTimeScheduleInSeconds":10800,"maxRespawnTimeScheduleInSeconds":11400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1785.gif","alias":["atr_rf03"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1785,"bossName":"Atroce - ra_fild04","HP":1008420,"race":"Brute","property":"Shadow 3","location":"ra_fild04","minRespawnTimeScheduleInSeconds":18000,"maxRespawnTimeScheduleInSeconds":18600,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1785.gif","alias":["atr_rf04"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1785,"bossName":"Atroce - ve_fild01","HP":1008420,"race":"Brute","property":"Shadow 3","location":"ve_fild01","minRespawnTimeScheduleInSeconds":10800,"maxRespawnTimeScheduleInSeconds":11400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1785.gif","alias":["atr_vf01"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1785,"bossName":"Atroce - ve_fild02","HP":1008420,"race":"Brute","property":"Shadow 3","location":"ve_fild02","minRespawnTimeScheduleInSeconds":21600,"maxRespawnTimeScheduleInSeconds":22200,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1785.gif","alias":["atr_vf02"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1785,"bossName":"Atroce - Guild","HP":1008420,"race":"Brute","property":"Shadow 3","location":"gld_dun03_2","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1785.gif","alias":["Atroce Guild"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1272,"bossName":"Dark Lord - Guild","HP":720000,"race":"Demon","property":"Undead 4","location":"gld_dun04","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1272.gif","alias":["Dark Lord Guild","DL Guild"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1272,"bossName":"Dark Lord - Guild2","HP":720000,"race":"Demon","property":"Undead 4","location":"gld_dun04_2","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1272.gif","alias":["Dark Lord Guild2","DL Guild2"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1046,"bossName":"Doppelganger - Guild","HP":249000,"race":"Demon","property":"Shadow 3","location":"gld_dun02","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1046.gif","alias":["Doppel Guild","Dopel Guild"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1115,"bossName":"Eddga - Guild","HP":152000,"race":"Brute","property":"Fire 1","location":"gld_dun01","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1115.gif","alias":["Eddga Guild"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1115,"bossName":"Eddga - Guild2","HP":152000,"race":"Brute","property":"Fire 1","location":"gld_dun01_2","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1115.gif","alias":["Eddga Guild2"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1147,"bossName":"Maya - Guild","HP":169000,"race":"Insect","property":"Earth 4","location":"gld_dun02_2","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1147.gif","alias":["Maya Guild"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1147,"bossName":"Maya - Guild2","HP":169000,"race":"Insect","property":"Earth 4","location":"gld_dun03","minRespawnTimeScheduleInSeconds":28800,"maxRespawnTimeScheduleInSeconds":29400,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1147.gif","alias":["Maya Guild2"],"minRespawnTime":null,"maxRespawnTime":null},{"ID":1388,"bossName":"Archangeling","HP":79523,"race":"Angel","property":"Holy 3","location":"yuno_fild05","minRespawnTimeScheduleInSeconds":3600,"maxRespawnTimeScheduleInSeconds":3780,"deathTime":1612603786,"imageUrl":"https://file5s.ratemyserver.net/mobs/1388.gif","alias":["AA"],"minRespawnTime":1612607386,"maxRespawnTime":1612607566},{"ID":123,"bossName":"Jaii","HP":123456,"race":"Angel","property":"Fire 4","location":"prt_fild08","minRespawnTimeScheduleInSeconds":50,"maxRespawnTimeScheduleInSeconds":60,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1002.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null},{"ID":124,"bossName":"Jee","HP":123456,"race":"Demon","property":"Earth 4","location":"prt_fild08","minRespawnTimeScheduleInSeconds":50,"maxRespawnTimeScheduleInSeconds":60,"deathTime":null,"imageUrl":"https://file5s.ratemyserver.net/mobs/1127.gif","alias":[],"minRespawnTime":null,"maxRespawnTime":null}]} --------------------------------------------------------------------------------