diff --git a/secret/CREATE-OWO-TABLES.sql b/secret/CREATE-OWO-TABLES.sql index 4cedd2369..48c351231 100644 --- a/secret/CREATE-OWO-TABLES.sql +++ b/secret/CREATE-OWO-TABLES.sql @@ -35,6 +35,7 @@ CREATE TABLE `alter` ( `footer` varchar(256) DEFAULT NULL, `author` varchar(256) DEFAULT NULL, `showAvatar` tinyint(4) NOT NULL DEFAULT '0', + `extra` varchar(1024) DEFAULT NULL, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`uid`,`command`,`type`), CONSTRAINT `alter_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) @@ -156,6 +157,14 @@ DROP TABLE IF EXISTS `animals`; CREATE TABLE `animals` ( `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', `rank` varchar(50) NOT NULL, + `hp` tinyint(4) NOT NULL DEFAULT '0', + `att` tinyint(4) NOT NULL DEFAULT '0', + `pr` tinyint(4) NOT NULL DEFAULT '0', + `wp` tinyint(4) NOT NULL DEFAULT '0', + `mag` tinyint(4) NOT NULL DEFAULT '0', + `mr` tinyint(4) NOT NULL DEFAULT '0', + `description` varchar(2000) NOT NULL, + `alt` varchar(600) NOT NULL, PRIMARY KEY (`name`), KEY `fk_animals__animals_rank__rank` (`rank`), CONSTRAINT `fk_animals__animals_rank__rank` FOREIGN KEY (`rank`) REFERENCES `animals_rank` (`rank`) @@ -1703,4 +1712,4 @@ DELIMITER ; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2024-06-22 15:41:52 +-- Dump completed on 2024-07-20 17:47:59 diff --git a/secret/OWO-TABLE-DATA.sql b/secret/OWO-TABLE-DATA.sql index 9b281fd2f..cc0076a44 100644 --- a/secret/OWO-TABLE-DATA.sql +++ b/secret/OWO-TABLE-DATA.sql @@ -64,7 +64,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2024-06-22 15:41:54 +-- Dump completed on 2024-07-20 17:48:25 -- MySQL dump 10.13 Distrib 5.7.42, for Linux (x86_64) -- -- Host: localhost Database: owo @@ -89,7 +89,7 @@ UNLOCK TABLES; LOCK TABLES `animals` WRITE; /*!40000 ALTER TABLE `animals` DISABLE KEYS */; -INSERT INTO `animals` VALUES (':bee:','common'),(':beetle:','common'),(':bug:','common'),(':butterfly:','common'),(':snail:','common'),(':crocodile:','epic'),(':elephant:','epic'),(':penguin:','epic'),(':tiger2:','epic'),(':whale:','epic'),(':cat2:','rare'),(':cow2:','rare'),(':dog2:','rare'),(':pig2:','rare'),(':sheep:','rare'),(':baby_chick:','uncommon'),(':chipmunk:','uncommon'),(':mouse2:','uncommon'),(':rabbit2:','uncommon'),(':rooster:','uncommon'); +INSERT INTO `animals` VALUES (':bee:','common',1,5,2,3,3,1,'How do bees go to school?\n~ On the school buzz!','bee,wasp'),(':beetle:','common',4,2,2,3,2,2,'Are they all female?','beetle,ladybug'),(':bug:','common',3,2,2,4,2,2,'It\'s a worm.','bug,worm,caterpillar'),(':butterfly:','common',1,1,1,5,5,2,'Why did you throw butter out the window?\n~ To see a butter fly!','butterfly'),(':snail:','common',8,1,2,3,5,1,'The slowest animal, but the toughest in the zoo','snail,slug'),(':crocodile:','epic',3,4,4,2,1,4,'How do you tell the difference between an alligator and an crocodile?\n~ You will see one later and one in a while','crocodile,alligator'),(':elephant:','epic',5,5,3,1,1,3,'They don\'t actually eat peanuts','elephant'),(':penguin:','epic',2,1,2,6,5,2,'The birds that can\'t fly','penguin'),(':tiger2:','epic',4,6,2,1,3,2,'Just a very large kitty','tiger,tiger2,cheetah'),(':whale:','epic',7,1,3,1,2,4,'whale, whale, whale, look what we have here','whale'),(':cat2:','rare',3,1,1,6,3,3,'They shoot lazers.','cat,cat2,kitty,kitten'),(':cow2:','rare',5,4,3,1,1,3,'Some say that they are highly sought-after','cow,cow2'),(':dog2:','rare',4,6,3,1,1,2,'Very loyal and protective','dog,dog2,doggy,puppy,wolf'),(':pig2:','rare',4,2,3,2,2,4,'aka ur mum','pig,pig2'),(':sheep:','rare',5,2,2,3,1,4,'Tastes like cotten candy!','sheep,ram,goat'),(':baby_chick:','uncommon',3,2,3,3,3,2,'chirp chirp! It\'s so cute!','chick,baby_chick'),(':chipmunk:','uncommon',3,5,2,3,2,1,'Don\'t mess with them.','chipmunk,squirrel'),(':mouse2:','uncommon',3,3,2,3,3,2,'~~sqeak~~ squeak!','mouse,mouse2,rat'),(':rabbit2:','uncommon',3,4,2,3,2,2,'There\'s a ton of them.','rabbit,rabbit2,bunny'),(':rooster:','uncommon',3,4,3,2,2,2,'The alarm cluck','chicken,rooster'); /*!40000 ALTER TABLE `animals` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; @@ -102,4 +102,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2024-06-22 15:41:54 +-- Dump completed on 2024-07-20 17:48:25 diff --git a/secret/owo-animals.json b/secret/owo-animals.json deleted file mode 100644 index 9a958287b..000000000 --- a/secret/owo-animals.json +++ /dev/null @@ -1,417 +0,0 @@ -{ - "common": [0.588489, ":bee:", ":bug:", ":snail:", ":beetle:", ":butterfly:"], - "uncommon": [0.888489, ":baby_chick:", ":mouse2:", ":rooster:", ":rabbit2:", ":chipmunk:"], - "rare": [0.988489, ":sheep:", ":pig2:", ":cow2:", ":dog2:", ":cat2:"], - "epic": [0.998489, ":crocodile:", ":tiger2:", ":penguin:", ":elephant:", ":whale:"], - "mythical": [0.999489, ":dragon:", ":unicorn:", ":snowman2:", ":ghost:", ":dove:"], - "legendary": [ - 0.999989, - "", - "", - "", - "", - "" - ], - - "numbers": ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"], - "order": ["common", "uncommon", "rare", "epic", "mythical", "legendary"], - "ranks": { - "common": "<:common:416520037713838081>", - "uncommon": "<:uncommon:416520056269176842>", - "rare": "<:rare:416520066629107712>", - "epic": "<:epic:416520722987614208>", - "mythical": "<:mythic:416520808501084162>", - "legendary": "" - }, - "alias": { - "common": ["c"], - "uncommon": ["u", "uc"], - "rare": ["r"], - "epic": ["e"], - "mythical": ["m", "mythic"], - "legendary": ["l", "legend"] - }, - "rollprice": 5, - "question": "<:question:416100711412137984>", - "price": { - "common": 1, - "uncommon": 3, - "rare": 10, - "epic": 250, - "mythical": 5000, - "legendary": 15000 - }, - "points": { - "common": 1, - "uncommon": 5, - "rare": 20, - "epic": 250, - "mythical": 3000, - "legendary": 10000 - }, - "essence": { - "common": 1, - "uncommon": 5, - "rare": 20, - "epic": 250, - "mythical": 3000, - "legendary": 10000 - }, - "list": { - "bee": { - "value": ":bee:", - "desc": "How do bees go to school?\n~ On the school buzz!", - "uni": "🐝", - "alt": ["wasp"], - "hpr": 1, - "attr": 5, - "wpr": 3, - "magr": 3, - "prr": 2, - "mrr": 1 - }, - "bug": { - "value": ":bug:", - "desc": "It's a worm.", - "uni": "🐛", - "alt": ["worm", "caterpillar"], - "attr": 2, - "hpr": 3, - "wpr": 4, - "magr": 2, - "prr": 2, - "mrr": 2 - }, - "snail": { - "value": ":snail:", - "desc": "The slowest animal, but the toughest in the zoo", - "uni": "🐌", - "alt": ["slug"], - "attr": 1, - "hpr": 8, - "wpr": 3, - "magr": 5, - "prr": 2, - "mrr": 1 - }, - "beetle": { - "value": ":beetle:", - "desc": "Are they all female?", - "uni": "🐞", - "alt": ["ladybug"], - "attr": 2, - "hpr": 4, - "wpr": 3, - "magr": 2, - "prr": 2, - "mrr": 2 - }, - "butterfly": { - "value": ":butterfly:", - "desc": "Why did you throw butter out the window?\n~ To see a butter fly!", - "uni": "🦋", - "alt": [], - "attr": 1, - "hpr": 1, - "wpr": 5, - "magr": 5, - "prr": 1, - "mrr": 2 - }, - "chick": { - "value": ":baby_chick:", - "desc": "chirp chirp! It's so cute!", - "uni": "🐤", - "alt": ["baby_chick"], - "attr": 2, - "hpr": 3, - "wpr": 3, - "magr": 3, - "prr": 3, - "mrr": 2 - }, - "mouse": { - "value": ":mouse2:", - "desc": "~~sqeak~~ squeak!", - "uni": "🐁", - "alt": ["mouse2", "rat"], - "attr": 3, - "hpr": 3, - "wpr": 3, - "magr": 3, - "prr": 2, - "mrr": 2 - }, - "chicken": { - "value": ":rooster:", - "desc": "The alarm cluck", - "uni": "🐓", - "alt": ["rooster"], - "attr": 4, - "hpr": 3, - "wpr": 2, - "magr": 2, - "prr": 3, - "mrr": 2 - }, - "rabbit": { - "value": ":rabbit2:", - "desc": "There's a ton of them.", - "uni": "🐇", - "alt": ["rabbit2", "bunny"], - "attr": 4, - "hpr": 3, - "wpr": 3, - "magr": 2, - "prr": 2, - "mrr": 2 - }, - "chipmunk": { - "value": ":chipmunk:", - "desc": "Don't mess with them.", - "uni": "🐿", - "alt": ["squirrel"], - "attr": 5, - "hpr": 3, - "wpr": 3, - "magr": 2, - "prr": 2, - "mrr": 1 - }, - "sheep": { - "value": ":sheep:", - "desc": "Tastes like cotten candy!", - "uni": "🐑", - "alt": ["ram", "goat"], - "attr": 2, - "hpr": 5, - "wpr": 3, - "magr": 1, - "prr": 2, - "mrr": 4 - }, - "pig": { - "value": ":pig2:", - "desc": "aka ur mum", - "uni": "🐖", - "alt": ["pig2"], - "attr": 2, - "hpr": 4, - "wpr": 2, - "magr": 2, - "prr": 3, - "mrr": 4 - }, - "cow": { - "value": ":cow2:", - "desc": "Some say that they are highly sought-after", - "uni": "🐄", - "alt": ["cow2"], - "attr": 4, - "hpr": 5, - "wpr": 1, - "magr": 1, - "prr": 3, - "mrr": 3 - }, - "dog": { - "value": ":dog2:", - "desc": "Very loyal and protective", - "uni": "🐕", - "alt": ["dog2", "doggy", "puppy", "wolf"], - "attr": 6, - "hpr": 4, - "wpr": 1, - "magr": 1, - "prr": 3, - "mrr": 2 - }, - "cat": { - "value": ":cat2:", - "desc": "They shoot lazers.", - "uni": "🐈", - "alt": ["cat2", "kitty", "kitten"], - "attr": 1, - "hpr": 3, - "wpr": 6, - "magr": 3, - "prr": 1, - "mrr": 3 - }, - "crocodile": { - "value": ":crocodile:", - "desc": "How do you tell the difference between an alligator and an crocodile?\n~ You will see one later and one in a while", - "uni": "🐊", - "alt": ["alligator"], - "attr": 4, - "hpr": 3, - "wpr": 2, - "magr": 1, - "prr": 4, - "mrr": 4 - }, - "tiger": { - "value": ":tiger2:", - "desc": "Just a very large kitty", - "uni": "🐅", - "alt": ["tiger2", "cheetah"], - "attr": 6, - "hpr": 4, - "wpr": 1, - "magr": 3, - "prr": 2, - "mrr": 2 - }, - "penguin": { - "value": ":penguin:", - "desc": "The birds that can't fly", - "uni": "🐧", - "alt": [], - "attr": 1, - "hpr": 2, - "wpr": 6, - "magr": 5, - "prr": 2, - "mrr": 2 - }, - "elephant": { - "value": ":elephant:", - "desc": "They don't actually eat peanuts", - "uni": "🐘", - "alt": [], - "attr": 5, - "hpr": 5, - "wpr": 1, - "magr": 1, - "prr": 3, - "mrr": 3 - }, - "whale": { - "value": ":whale:", - "desc": "whale, whale, whale, look what we have here", - "uni": "🐳", - "alt": [], - "attr": 1, - "hpr": 7, - "wpr": 1, - "magr": 2, - "prr": 3, - "mrr": 4 - }, - "dragon": { - "value": ":dragon:", - "desc": "It's a snake with wings!", - "uni": "🐉", - "alt": [], - "attr": 8, - "hpr": 4, - "wpr": 3, - "magr": 1, - "prr": 1, - "mrr": 2 - }, - "unicorn": { - "value": ":unicorn:", - "desc": "Basically horses with 2x the magic", - "uni": "🦄", - "alt": [], - "attr": 1, - "hpr": 2, - "wpr": 6, - "magr": 6, - "prr": 2, - "mrr": 2 - }, - "snowman": { - "value": ":snowman2:", - "desc": "He comes to life at night!", - "uni": "☃", - "alt": ["snowman2", "snow"], - "attr": 2, - "hpr": 3, - "wpr": 8, - "magr": 3, - "prr": 1, - "mrr": 2 - }, - "ghost": { - "value": ":ghost:", - "desc": "Boo.\nDid I scare you?", - "uni": "👻", - "alt": ["monster"], - "attr": 2, - "hpr": 2, - "wpr": 3, - "magr": 3, - "prr": 8, - "mrr": 1 - }, - "dove": { - "value": ":dove:", - "desc": "Very majestic", - "uni": "🕊", - "alt": ["bird"], - "attr": 4, - "hpr": 4, - "wpr": 2, - "magr": 1, - "prr": 4, - "mrr": 4 - }, - "squid": { - "value": "", - "desc": "Huggable tentacle monster", - "alt": ["gsquid"], - "attr": 1, - "hpr": 3, - "wpr": 6, - "magr": 6, - "prr": 2, - "mrr": 2 - }, - "owl": { - "value": "", - "desc": "Forever petrified in this golden state, the owl is always watching you.", - "alt": ["gowl"], - "attr": 1, - "hpr": 10, - "wpr": 1, - "magr": 2, - "prr": 3, - "mrr": 3 - }, - "lion": { - "value": "", - "desc": "The king of the jungle\nand a vewy good kitty", - "alt": ["glion"], - "attr": 7, - "hpr": 7, - "wpr": 1, - "magr": 1, - "prr": 2, - "mrr": 2 - }, - "fox": { - "value": "", - "desc": "Ring-ding-ding-ding-dingeringeding!\nGering-ding-ding-ding-dingeringeding!\nGering-ding-ding-ding-dingeringeding!", - "alt": ["gfox"], - "attr": 4, - "hpr": 4, - "wpr": 4, - "magr": 2, - "prr": 3, - "mrr": 3 - }, - "deer": { - "value": "", - "desc": "A sparkly magical creature!\nWhat does it do, you might ask.*\n***it sparkles**", - "alt": ["gdeer"], - "attr": 1, - "hpr": 3, - "wpr": 3, - "magr": 11, - "prr": 1, - "mrr": 1 - } - } -} diff --git a/src/commands/command.js b/src/commands/command.js index 98a8a6845..ef96e82ef 100644 --- a/src/commands/command.js +++ b/src/commands/command.js @@ -260,7 +260,7 @@ function initParam(msg, command, args, main, context) { context: context, command: command, client: main.bot, - animals: main.animals, + animalUtil: main.animalUtil, dbl: main.dbl, mysql: main.mysql, con: main.mysql.con, @@ -297,6 +297,7 @@ function initParam(msg, command, args, main, context) { neo4j: main.neo4j, giveaway: main.giveaway, patreonUtil: main.patreonUtil, + cache: main.cache, }; param.setCooldown = function (cooldown) { main.cooldown.setCooldown(param, aliasToCommand[command], cooldown); diff --git a/src/commands/commandList/patreon/alterZoo.js b/src/commands/commandList/patreon/alterZoo.js index 57e11c0b4..79c2e974b 100644 --- a/src/commands/commandList/patreon/alterZoo.js +++ b/src/commands/commandList/patreon/alterZoo.js @@ -77,8 +77,13 @@ async function checkDb(p, info) { commonCount: info.animalCount.common, }; + const extraReplacers = {}; + Object.values(p.animalUtil.getRanks()).forEach((rank) => { + extraReplacers[rank.id] = rank.emoji; + }); + return alterUtils.getAlterCommand('zoo', info.user, type, replacers, null, null, { - extraReplacers: p.animals.ranks, + extraReplacers, }); } diff --git a/src/commands/commandList/patreon/collectibles/pikachu.js b/src/commands/commandList/patreon/collectibles/pikachu.js index 6c0097e16..e686fd168 100644 --- a/src/commands/commandList/patreon/collectibles/pikachu.js +++ b/src/commands/commandList/patreon/collectibles/pikachu.js @@ -14,7 +14,12 @@ class Pikachu extends Collectible { this.key = 'pikachu'; this.alias = ['pikachu', 'chu']; this.emoji = ''; - this.owners = ['768465041489657867','968621197011062804','879313703990870047','969176350621589514']; + this.owners = [ + '768465041489657867', + '968621197011062804', + '879313703990870047', + '969176350621589514', + ]; this.fullControl = true; this.ownerOnly = true; this.giveAmount = 1; diff --git a/src/commands/commandList/zoo/animalUtil.js b/src/commands/commandList/zoo/animalUtil.js index 45948ff00..4296551d7 100644 --- a/src/commands/commandList/zoo/animalUtil.js +++ b/src/commands/commandList/zoo/animalUtil.js @@ -7,18 +7,8 @@ const mysql = require('../../../botHandlers/mysqlHandler.js'); const global = require('../../../utils/global.js'); -let animals; -try { - animals = require('../../../../../tokens/owo-animals.json'); -} catch (err) { - console.error('Could not find owo-animals.json, attempting to use ./secret file...'); - animals = require('../../../../secret/owo-animals.json'); - console.log('Found owo-animals.json file in secret folder!'); -} -const animalRankDict = {}; -for (let i = 0; i <= animals.order.length; i++) { - animalRankDict[animals.order[i]] = i; -} +const animals = require('../../../utils/animalInfoUtil.js'); +const eventUtil = require('../../../utils/eventUtil.js'); let enableDistortedTier = true; setTimeout(() => { @@ -26,234 +16,160 @@ setTimeout(() => { enableDistortedTier = false; }, 21600000); -let specialRatesManual = []; -let specialRatesHuntbot = []; -let specialPercentManual = 0; -let specialPercentHuntbot = 0; -let doubleSpecialRatesManual = []; -let doubleSpecialRatesHuntbot = []; -let doubleSpecialPercentManual = 0; -let doubleSpecialPercentHuntbot = 0; -setSpecialRates(); - -function setSpecialRates() { - specialRatesManual = []; - specialRatesHuntbot = []; - specialPercentManual = 0; - specialPercentHuntbot = 0; - doubleSpecialRatesManual = []; - doubleSpecialRatesHuntbot = []; - doubleSpecialPercentManual = 0; - doubleSpecialPercentHuntbot = 0; - - if (animals.specialRates && animals.specialRates.length) { - for (let i in animals.specialRates) { - const special = animals.specialRates[i]; - const rate = getRate(special); - - if (rate) { - specialRatesManual.push({ - animal: special.animal, - rate: rate, - }); - specialPercentManual += rate; - - specialRatesHuntbot.push({ - animal: special.animal, - rate: rate / 4, - }); - specialPercentHuntbot += rate / 4; - - doubleSpecialRatesManual.push({ - animal: special.animal, - rate: rate * 2, - }); - doubleSpecialPercentManual += rate * 2; - - doubleSpecialRatesHuntbot.push({ - animal: special.animal, - rate: rate / 2, - }); - doubleSpecialPercentHuntbot += rate / 2; - } - } +function randAnimal(opts = {}) { + const event = getEventAnimals(); + opts.event = event; + const rarities = getRarities(opts); + + const rankName = getRandomRank(rarities); + const rank = animals.getRank(rankName); + let animalName; + if (rankName !== 'special') { + animalName = rank.animals[Math.floor(Math.random() * rank.animals.length)]; + } else { + animalName = getRandomEventAnimal(event); } - const d = new Date(); - const h = new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours() + 1, 0, 1, 0); - const diff = h - d; - console.log('Special Rates: ' + JSON.stringify(specialRatesManual, null, 2)); - setTimeout(setSpecialRates, diff); + return animals.getAnimal(animalName); } -function getRate(special) { - const start = new Date(special.startDate).getTime(); - const end = new Date(special.endDate).getTime(); - const diff = end - start; - let rate = special.minRate; - const now = Date.now(); +function getRandomEventAnimal(event) { + const totalRarity = event.reduce((sum, val) => sum + val.rarity, 0); + const rand = Math.random() * totalRarity; - if (end < now || now < start) { - return 0; + let total = 0; + for (let i in event) { + total += event[i].rarity; + if (rand < total) { + return event[i].animal; + } } +} - const percentDiff = (now - start) / diff; - rate += (special.maxRate - special.minRate) * percentDiff; - return rate; +function getRandomRank(rarities) { + const totalRarity = Object.values(rarities).reduce((sum, val) => sum + val, 0); + const rand = Math.random() * totalRarity; + + let total = 0; + for (let rank in rarities) { + total += rarities[rank]; + if (rand < total) { + return rank; + } + } } -/** - * Picks a random animal from secret json file - */ -const randAnimal = (exports.randAnimal = function ({ - patreon, - gem, - lucky, - special, - huntbot, - manual, -} = {}) { - let rand = Math.random(); - let result = []; - - /* Calculate percentage */ - let specialRates, specialPercent; - if (special) { - specialRates = huntbot ? doubleSpecialRatesHuntbot : doubleSpecialRatesManual; - specialPercent = huntbot ? doubleSpecialPercentHuntbot : doubleSpecialPercentManual; - } else { - specialRates = huntbot ? specialRatesHuntbot : specialRatesManual; - specialPercent = huntbot ? specialPercentHuntbot : specialPercentManual; +function getRarities(opts) { + const rarity = {}; + const ranks = animals.getRanks(); + for (let key in ranks) { + const rank = ranks[key]; + if (!rank.conditional) { + rarity[key] = rank.rarity; + } else { + rarity[key] = 0; + } } - // If user has patreon - let patreonPercent = animals.cpatreon[0] + animals.patreon[0]; - if (!patreon) patreonPercent = 0; - // If user is using gems - let gemPercent = animals.gem[0]; - if (!gem) gemPercent = 0; - else if (lucky) gemPercent += gemPercent * lucky.amount; - // If bot has restarted - let distortedPercent = enableDistortedTier && manual ? animals.distorted[0] : 0; - if (distortedPercent) { - distortedPercent += specialPercent + patreonPercent; - if (huntbot) distortedPercent += huntbot; - if (gemPercent) distortedPercent += gemPercent; + + if (opts.patreon) { + const patreon = animals.getRank('patreon'); + rarity[patreon.id] = patreon.rarity; + rarity['common'] -= patreon.rarity; + const cpatreon = animals.getRank('cpatreon'); + rarity[cpatreon.id] = cpatreon.rarity; + rarity['common'] -= cpatreon.rarity; } - if (patreonPercent && rand < patreonPercent) { - if (rand < animals.cpatreon[0]) { - rand = Math.ceil(Math.random() * (animals.cpatreon.length - 1)); - result.push('**patreon** ' + animals.ranks.cpatreon); - result.push(animals.cpatreon[rand]); - result.push('cpatreon'); - result.push(2000); - } else { - rand = Math.ceil(Math.random() * (animals.patreon.length - 1)); - result.push('**patreon** ' + animals.ranks.patreon); - result.push(animals.patreon[rand]); - result.push('patreon'); - result.push(400); + if (opts.gem) { + const gem = animals.getRank('gem'); + let gemRarity = gem.rarity; + if (opts.lucky) { + gemRarity *= opts.lucky.amount; } - } else if (specialPercent && rand < specialPercent + patreonPercent) { - let tempRate = patreonPercent; - let found = false; - for (let i in specialRates) { - tempRate += specialRates[i].rate; - if (!found && rand <= tempRate) { - found = true; - result.push('**special** ' + animals.ranks.special); - result.push(specialRates[i].animal); - result.push('special'); - result.push(500); - } + rarity[gem.id] = gemRarity; + rarity['common'] -= gemRarity; + } + + if (enableDistortedTier && opts.manual) { + const distorted = animals.getRank('distorted'); + rarity[distorted.id] = distorted.rarity; + rarity['common'] -= distorted.rarity; + } + + if (opts.huntbot) { + const bot = animals.getRank('bot'); + rarity[bot.id] = opts.huntbot; + rarity['common'] -= opts.huntbot; + } + + if (opts.event) { + let specialRarity = opts.event.reduce((sum, val) => sum + val.rarity, 0); + if (opts.special) { + specialRarity *= 2; } - } else if (huntbot && rand < huntbot + specialPercent + patreonPercent) { - rand = Math.ceil(Math.random() * (animals.bot.length - 1)); - result.push('**bot** ' + animals.ranks.bot); - result.push(animals.bot[rand]); - result.push('bot'); - result.push(100000); - } else if (gemPercent && rand < gemPercent + specialPercent + patreonPercent) { - rand = Math.ceil(Math.random() * (animals.gem.length - 1)); - result.push('**gem** ' + animals.ranks.gem); - result.push(animals.gem[rand]); - result.push('gem'); - result.push(5000); - } else if (rand < distortedPercent) { - rand = Math.ceil(Math.random() * (animals.distorted.length - 1)); - result.push('**distorted** ' + animals.ranks.distorted); - result.push(animals.distorted[rand]); - result.push('distorted'); - result.push(100000); - } else if (rand < animals.common[0]) { - rand = Math.ceil(Math.random() * (animals.common.length - 1)); - result.push('**common** ' + animals.ranks.common); - result.push(animals.common[rand]); - result.push('common'); - result.push(1); - } else if (rand < animals.uncommon[0]) { - rand = Math.ceil(Math.random() * (animals.uncommon.length - 1)); - result.push('**uncommon** ' + animals.ranks.uncommon); - result.push(animals.uncommon[rand]); - result.push('uncommon'); - result.push(10); - } else if (rand < animals.rare[0]) { - rand = Math.ceil(Math.random() * (animals.rare.length - 1)); - result.push('**rare** ' + animals.ranks.rare); - result.push(animals.rare[rand]); - result.push('rare'); - result.push(20); - } else if (rand < animals.epic[0]) { - rand = Math.ceil(Math.random() * (animals.epic.length - 1)); - result.push('**epic** ' + animals.ranks.epic); - result.push(animals.epic[rand]); - result.push('epic'); - result.push(400); - } else if (rand < animals.mythical[0]) { - rand = Math.ceil(Math.random() * (animals.mythical.length - 1)); - result.push('**mythic** ' + animals.ranks.mythical); - result.push(animals.mythical[rand]); - result.push('mythical'); - result.push(1000); - } else if (rand < animals.legendary[0]) { - rand = Math.ceil(Math.random() * (animals.legendary.length - 1)); - result.push('**legendary** ' + animals.ranks.legendary); - result.push(animals.legendary[rand]); - result.push('legendary'); - result.push(2000); - } else if (rand < animals.fabled[0]) { - rand = Math.ceil(Math.random() * (animals.fabled.length - 1)); - result.push('**fabled** ' + animals.ranks.fabled); - result.push(animals.fabled[rand]); - result.push('fabled'); - result.push(100000); - } else { - rand = Math.ceil(Math.random() * (animals.hidden.length - 1)); - result.push('**hidden** ' + animals.ranks.hidden); - result.push(animals.hidden[rand]); - result.push('hidden'); - result.push(300000); + if (opts.huntbot) { + specialRarity /= 4; + } + const special = animals.getRank('special'); + rarity[special.id] = specialRarity; + rarity['common'] -= specialRarity; + } + + return rarity; +} + +function getEventAnimals() { + const event = eventUtil.getCurrentActive(); + if (!event || !event.animals) { + return []; + } + + const eventAnimals = []; + event.animals.forEach((animal) => { + eventAnimals.push({ + animal: animal.animal, + rarity: getEventRarity(animal, event), + }); + }); + + return eventAnimals; +} + +function getEventRarity(animal, event) { + const start = new Date(event.start).getTime(); + const end = new Date(event.end).getTime(); + const diff = end - start; + let rate = animal.minRate; + const now = Date.now(); + + if (end < now || now < start) { + return 0; } - return result; -}); + + const percentDiff = (now - start) / diff; + rate += (animal.maxRate - animal.minRate) * percentDiff; + return rate; +} exports.getMultipleAnimals = function (count, user, opt) { const total = {}; let xp = 0; for (let i = 0; i < count; i++) { let animal = randAnimal(opt); - xp += animal[3]; - if (total[animal[1]]) { - total[animal[1]].count++; - total[animal[1]].totalXp += animal[3]; + let rank = animals.getRank(animal.rank); + xp += rank.xp; + if (total[animal.value]) { + total[animal.value].count++; + total[animal.value].totalXp += rank.xp; } else { - total[animal[1]] = { + total[animal.value] = { count: 1, - rank: animal[2], - value: animal[1], - text: animal[0], - totalXp: animal[3], - singleXp: animal[3], + rank: rank.id, + value: animal.value, + text: `**${rank.id}** ${rank.emoji}`, + totalXp: rank.xp, + singleXp: rank.xp, + rankSort: rank.order, }; } } @@ -270,16 +186,6 @@ exports.getMultipleAnimals = function (count, user, opt) { }; }; -exports.toSmallNum = function (count, digits) { - let result = ''; - for (let i = 0; i < digits; i++) { - let digit = count % 10; - count = Math.trunc(count / 10); - result = animals.numbers[digit] + result; - } - return result; -}; - exports.zooScore = function (zoo) { let text = ''; if (zoo.hidden > 0) text += 'H-' + zoo.hidden + ', '; @@ -300,7 +206,8 @@ exports.zooScore = function (zoo) { }; exports.hasSpecials = function () { - return specialPercentManual !== 0; + const event = eventUtil.getCurrentActive(); + return !!event?.animals; }; exports.getPid = async function (id, pet) { @@ -330,11 +237,9 @@ function sortAnimals(animals) { animalList.push(animals[value]); } animalList.sort((a, b) => { - const a_rank = animalRankDict[a.rank] || 0; - const b_rank = animalRankDict[b.rank] || 0; - if (a_rank > b_rank) { + if (a.rankSort < b.rankSort) { return -1; - } else if (a_rank < b_rank) { + } else if (a.rankSort > b.rankSort) { return 1; } else if (a.value < b.value) { return -1; diff --git a/src/commands/commandList/zoo/autohunt.js b/src/commands/commandList/zoo/autohunt.js index 7b1821a9d..07d7f1732 100644 --- a/src/commands/commandList/zoo/autohunt.js +++ b/src/commands/commandList/zoo/autohunt.js @@ -90,7 +90,7 @@ async function claim(p, msg, con, query, bot) { let radar = autohuntutil.getLvl(query.radar, 0, 'radar'); let { animals, animalSql } = animalUtil.getMultipleAnimals(query.huntcount, p.msg.author, { patreon: patreon, - huntbot: radar.stat / 100, + huntbot: radar.stat, }); let digits = 0; for (let key in animals) { @@ -110,11 +110,12 @@ async function claim(p, msg, con, query, bot) { let tempText = []; for (let animal in animals) { - let animalString = animal + animalUtil.toSmallNum(animals[animal].count, digits) + ' '; - let animalLoc = p.animals.order.indexOf(animals[animal].rank); + let animalString = animal + p.global.toSmallNum(animals[animal].count, digits) + ' '; + const order = p.animalUtil.getOrder(); + let animalLoc = order.indexOf(animals[animal].rank); if (animalLoc || animalLoc === 0) { if (!tempText[animalLoc]) - tempText[animalLoc] = ' \n' + p.animals.ranks[p.animals.order[animalLoc]] + ' **|**'; + tempText[animalLoc] = ' \n' + p.animalUtil.getRank(order[animalLoc]).emoji + ' **|**'; tempText[animalLoc] += ' ' + animalString; } } diff --git a/src/commands/commandList/zoo/catch.js b/src/commands/commandList/zoo/catch.js index 580f5b0cb..43f19b2c9 100644 --- a/src/commands/commandList/zoo/catch.js +++ b/src/commands/commandList/zoo/catch.js @@ -15,6 +15,7 @@ const alterHunt = require('./../patreon/alterHunt.js'); const patreonUtil = require('./../patreon/utils/patreonUtil.js'); const teamUtil = require('../battle/util/teamUtil.js'); const lootboxChance = 0.05; +const rollPrice = 5; module.exports = new CommandInterface({ alias: ['hunt', 'h', 'catch'], @@ -65,7 +66,7 @@ module.exports = new CommandInterface({ msg.author.id + ' AND activecount > 0;'; let result = await p.query(sql); - if (result[0][0] == undefined || result[0][0].money < this.animals.rollprice) { + if (result[0][0] == undefined || result[0][0].money < rollPrice) { p.errorMsg(", You don't have enough cowoncy!", 3000); } else { //Sort gem benefits diff --git a/src/commands/commandList/zoo/owodex.js b/src/commands/commandList/zoo/owodex.js index 56258dc0a..73fafd9a8 100644 --- a/src/commands/commandList/zoo/owodex.js +++ b/src/commands/commandList/zoo/owodex.js @@ -41,14 +41,13 @@ module.exports = new CommandInterface({ return; } - let sql = - 'SELECT * FROM animal WHERE id = ' + msg.author.id + " AND name = '" + animal.value + "';"; - sql += "SELECT SUM(totalcount) as total FROM animal WHERE name = '" + animal.value + "';"; + let sql = `SELECT * FROM animal WHERE id = ${msg.author.id} AND name = '${animal.value}';`; let result = await p.query(sql); - if (!result[0][0]) { + if (!result[0]) { p.errorMsg(', I could not find that animal in your zoo!', 3000); return; } + const totalAnimals = await this.cache.getAnimalCount(animal.value, 6 * 60 * 60 * 1000); let emoji = animal.uni ? animal.uni : animal.value; let temp; @@ -59,24 +58,24 @@ module.exports = new CommandInterface({ emoji = temp; } else emoji = undefined; - let rankEmoji = p.animals.ranks[animal.rank]; + let rankEmoji = p.animalUtil.getRank(animal.rank).emoji; let points = animal.points; let sell = '???'; - if (result[0][0].sellcount > 0) - sell = animal.price + ' Cowoncy | ' + global.toFancyNum(result[0][0].sellcount) + ' sold'; + if (result[0].sellcount > 0) + sell = animal.price + ' Cowoncy | ' + global.toFancyNum(result[0].sellcount) + ' sold'; let sac = '???'; - if (result[0][0].saccount > 0) - sac = animal.essence + ' Essence | ' + global.toFancyNum(result[0][0].saccount) + ' killed'; + if (result[0].saccount > 0) + sac = animal.essence + ' Essence | ' + global.toFancyNum(result[0].saccount) + ' killed'; let alias = 'None'; - if (animal.alt.length > 0) alias = animal.alt.join(', '); - let phys = `<:hp:531620120410456064> \`${animal.hpr}\` <:att:531616155450998794> \`${animal.attr}\` <:pr:531616156222488606> \`${animal.prr}\` `; - let mag = `<:wp:531620120976687114> \`${animal.wpr}\` <:mag:531616156231139338> \`${animal.magr}\` <:mr:531616156226945024> \`${animal.mrr}\` `; - let rarity = global.toFancyNum(result[1][0].total) + ' total caught'; + if (animal.alt.length > 0) alias = animal.alt.splice(1).join(', '); + let phys = `<:hp:531620120410456064> \`${animal.hp}\` <:att:531616155450998794> \`${animal.att}\` <:pr:531616156222488606> \`${animal.pr}\` `; + let mag = `<:wp:531620120976687114> \`${animal.wp}\` <:mag:531616156231139338> \`${animal.mag}\` <:mr:531616156226945024> \`${animal.mr}\` `; + let rarity = global.toFancyNum(totalAnimals) + ' total caught'; let nickname = ''; - if (result[0][0].nickname) nickname = '**Nickname:** ' + result[0][0].nickname + '\n'; + if (result[0].nickname) nickname = '**Nickname:** ' + result[0].nickname + '\n'; let desc = "*No description created\nHave a fun/creative description?\nUse 'owo feedback'!*"; - if (animal.desc) { - desc = '*' + animal.desc.trim() + '*'; + if (animal.description) { + desc = '*' + animal.description.trim() + '*'; let ids = desc.match(/\?[0-9]+\?/g); for (let i in ids) { let descID = ids[i].match(/[0-9]+/); @@ -139,9 +138,9 @@ module.exports = new CommandInterface({ '\n\n' + nickname + '**Count:** ' + - result[0][0].count + + result[0].count + '/' + - result[0][0].totalcount + + result[0].totalcount + '\n**Rank:** ' + rankEmoji + ' ' + diff --git a/src/commands/commandList/zoo/zoo.js b/src/commands/commandList/zoo/zoo.js index d8498bcaa..b786c7e74 100644 --- a/src/commands/commandList/zoo/zoo.js +++ b/src/commands/commandList/zoo/zoo.js @@ -9,16 +9,7 @@ const CommandInterface = require('../../CommandInterface.js'); const animalUtil = require('./animalUtil.js'); const alterZoo = require('../patreon/alterZoo.js'); -let animals; -try { - animals = require('../../../../../tokens/owo-animals.json'); -} catch (err) { - console.error('Could not find owo-animals.json, attempting to use ./secret file...'); - animals = require('../../../../secret/owo-animals.json'); - console.log('Found owo-animals.json file in secret folder!'); -} -let preBuiltDisplay = {}; -initDisplay(); +const animals = require('../../../utils/animalInfoUtil.js'); module.exports = new CommandInterface({ alias: ['zoo', 'z'], @@ -120,21 +111,25 @@ function createBody(userAnimals, biggest) { animalGrouping[animalRank].push(userAnimal); }); - animals.order.forEach((rank) => { + const preBuiltDisplay = getPreBuiltDisplay(); + animals.getOrder().forEach((rank) => { const rankAnimals = animalGrouping[rank]; - let text = getRankRow.bind(this)(rank, rankAnimals, digits); + let text = getRankRow.bind(this)(rank, rankAnimals, digits, preBuiltDisplay); if (text) { body += '\n' + text; } }); - body = body.replace(/~:[a-zA-Z_0-9]+:/g, animals.question + this.global.toSmallNum(0, digits)); + body = body.replace( + /~:[a-zA-Z_0-9]+:/g, + this.config.emoji.question + this.global.toSmallNum(0, digits) + ); return body.trim(); } /** * Creates row text for a single rank */ -function getRankRow(rank, rankAnimals, digits) { +function getRankRow(rank, rankAnimals, digits, preBuiltDisplay) { let text = ''; if (preBuiltDisplay[rank]) { text += preBuiltDisplay[rank]; @@ -148,7 +143,7 @@ function getRankRow(rank, rankAnimals, digits) { if (!rankAnimals) { return; } - text += `${animals.ranks[rank]} `; + text += `${animals.getRank(rank).emoji} `; for (let i = 0; i < rankAnimals.length; i++) { const animal = rankAnimals[i]; if (i && i % 5 === 0) { @@ -169,7 +164,7 @@ function createFooter(count, paged) { let total = 0; for (let rank in count) { if (!['id', 'total'].includes(rank)) { - total += count[rank] * animals.points[rank]; + total += count[rank] * animals.getRank(rank).points; } } @@ -189,39 +184,20 @@ function createFooter(count, paged) { }; } -function initDisplay() { - let commonDisplay = `${animals.ranks.common} `; - for (let i = 1; i < animals.common.length; i++) { - commonDisplay += `~${animals.common[i]} `; - } - - let uncommonDisplay = `${animals.ranks.uncommon} `; - for (let i = 1; i < animals.uncommon.length; i++) { - uncommonDisplay += `~${animals.uncommon[i]} `; - } - - let rareDisplay = `${animals.ranks.rare} `; - for (let i = 1; i < animals.rare.length; i++) { - rareDisplay += `~${animals.rare[i]} `; - } - - let epicDisplay = `${animals.ranks.epic} `; - for (let i = 1; i < animals.epic.length; i++) { - epicDisplay += `~${animals.epic[i]} `; - } - - let mythicalDisplay = `${animals.ranks.mythical} `; - for (let i = 1; i < animals.mythical.length; i++) { - mythicalDisplay += `~${animals.mythical[i]} `; - } - - preBuiltDisplay = { - common: commonDisplay, - uncommon: uncommonDisplay, - rare: rareDisplay, - epic: epicDisplay, - mythical: mythicalDisplay, - }; +function getPreBuiltDisplay() { + const result = {}; + const ranks = animals.getRanks(); + Object.values(ranks).forEach((rank) => { + const placeholder = rank.placeholder; + if (!placeholder) { + return; + } + result[rank.id] = `${rank.emoji} `; + rank.placeholder.forEach((animal) => { + result[rank.id] += `~${animal} `; + }); + }); + return result; } function toPages(text) { diff --git a/src/data/animal.json b/src/data/animal.json new file mode 100644 index 000000000..2a11ac444 --- /dev/null +++ b/src/data/animal.json @@ -0,0 +1,155 @@ +{ + "ranks": { + "patreon": { + "rarity": 0.5, + "order": 5, + "emoji": "<:patreon:449705754522419222>", + "alias": ["p"], + "price": 1000, + "points": 500, + "essence": 500, + "xp": 400, + "conditional": true + }, + "cpatreon": { + "rarity": 0.01, + "order": 12, + "emoji": "", + "alias": ["cp"], + "price": 50000, + "points": 25000, + "essence": 25000, + "xp": 2000, + "conditional": true + }, + "common": { + "rarity": 58.8489, + "order": 1, + "emoji": "<:common:416520037713838081>", + "alias": ["c"], + "price": 1, + "points": 1, + "essence": 1, + "xp": 1, + "placeholder": [":bee:", ":bug:", ":snail:", ":beetle:", ":butterfly:"] + }, + "uncommon": { + "rarity": 30, + "order": 2, + "emoji": "<:uncommon:416520056269176842>", + "alias": ["u", "uc"], + "price": 3, + "points": 5, + "essence": 5, + "xp": 10, + "placeholder": [":baby_chick:", ":mouse2:", ":rooster:", ":rabbit2:", ":chipmunk:"] + }, + "rare": { + "rarity": 10, + "order": 3, + "emoji": "<:rare:416520066629107712>", + "alias": ["r"], + "price": 10, + "points": 20, + "essence": 20, + "xp": 20, + "placeholder": [":sheep:", ":pig2:", ":cow2:", ":dog2:", ":cat2:"] + }, + "epic": { + "rarity": 1, + "order": 4, + "emoji": "<:epic:416520722987614208>", + "alias": ["e"], + "price": 250, + "points": 250, + "essence": 250, + "xp": 400, + "placeholder": [":crocodile:", ":tiger2:", ":penguin:", ":elephant:", ":whale:"] + }, + "mythical": { + "rarity": 0.1, + "order": 7, + "emoji": "<:mythic:416520808501084162>", + "alias": ["m", "mythic"], + "price": 5000, + "points": 3000, + "essence": 3000, + "xp": 1000, + "placeholder": [":dragon:", ":unicorn:", ":snowman2:", ":ghost:", ":dove:"] + }, + "legendary": { + "rarity": 0.05, + "order": 9, + "emoji": "", + "alias": ["l", "legend"], + "price": 15000, + "points": 10000, + "essence": 10000, + "xp": 2000 + }, + "fabled": { + "rarity": 0.001, + "order": 13, + "emoji": "", + "alias": ["f"], + "price": 250000, + "points": 100000, + "essence": 100000, + "xp": 100000 + }, + "hidden": { + "rarity": 0.0001, + "order": 14, + "emoji": "", + "alias": ["h"], + "price": 1000000, + "points": 500000, + "essence": 500000, + "xp": 300000 + }, + "special": { + "rarity": 0, + "order": 6, + "emoji": "<:special:427935192137859073>", + "alias": ["s"], + "price": 6000, + "points": 500, + "essence": 5000, + "xp": 500, + "conditional": true + }, + "gem": { + "rarity": 0.01, + "order": 8, + "emoji": "", + "alias": ["g"], + "price": 30000, + "points": 20000, + "essence": 20000, + "xp": 5000, + "conditional": true + }, + "bot": { + "rarity": 0, + "order": 10, + "emoji": "", + "alias": ["b"], + "price": 50000, + "points": 30000, + "essence": 10000, + "xp": 100000, + "conditional": true + }, + "distorted": { + "rarity": 0.00025, + "order": 11, + "emoji": "", + "alias": ["d"], + "price": 300000, + "points": 200000, + "essence": 200000, + "xp": 100000, + "conditional": true + } + } +} diff --git a/src/data/config.json b/src/data/config.json index 6bf573f56..c3c42554c 100644 --- a/src/data/config.json +++ b/src/data/config.json @@ -71,7 +71,8 @@ "owo": { "woah": "<:owo_woah:1171297059429691412>", "cry": "" - } + }, + "question": "<:question:416100711412137984>" }, "role": { "admin": ["420112323278143489"], diff --git a/src/data/event.json b/src/data/event.json index 8e4f14e31..c85f85a53 100644 --- a/src/data/event.json +++ b/src/data/event.json @@ -647,6 +647,13 @@ "end": "2024-07-10T00:00:00", "type": "july", "chance": 0.05, + "animals": [ + { + "animal": "2024july_seal", + "minRate": 0.005, + "maxRate": 0.05 + } + ], "rewards": [ { "type": "cowoncy", diff --git a/src/owo.js b/src/owo.js index 2f160eb06..73d705ff9 100644 --- a/src/owo.js +++ b/src/owo.js @@ -62,18 +62,14 @@ class OwO extends Base { this.mysqlhandler = require('./botHandlers/mysqlHandler.js'); this.query = this.mysqlhandler.query; - try { - this.animals = require('./../../tokens/owo-animals.json'); - } catch (err) { - console.error('Could not find owo-animals.json, attempting to use ./secret file...'); - this.animals = require('../secret/owo-animals.json'); - console.log('Found owo-animals.json file in secret folder!'); - } + this.cache = require('./utils/cacheUtil.js'); // Global helper methods this.global = require('./utils/global.js'); this.global.init(this); + this.animalUtil = require('./utils/animalInfoUtil.js'); + this.event = require('./utils/eventUtil.js'); // Message sender helper methods diff --git a/src/utils/alterUtils.js b/src/utils/alterUtils.js index 72389e6db..81d18ed87 100644 --- a/src/utils/alterUtils.js +++ b/src/utils/alterUtils.js @@ -35,7 +35,9 @@ exports.getAlterCommand = async function ( result.text = result.text.replace(extraReplacers[i], extra[i]); } } - } catch (err) {} + } catch (err) { + /* no-op */ + } if (!forceEmbed && !result.isEmbed) { return result.text; } diff --git a/src/utils/animalInfoUtil.js b/src/utils/animalInfoUtil.js new file mode 100644 index 000000000..91fa108c8 --- /dev/null +++ b/src/utils/animalInfoUtil.js @@ -0,0 +1,170 @@ +/* + * OwO Bot for Discord + * Copyright (C) 2024 Christopher Thai + * This software is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International + * For more information, see README.md and LICENSE + */ + +let animalJson = require('../data/animal.json'); +const mysql = require('./../botHandlers/mysqlHandler.js'); + +class AnimalJson { + constructor() { + this.initialize = this.initialize.bind(this); + this.parseAnimal = this.parseAnimal.bind(this); + this.parseRank = this.parseRank.bind(this); + this.getAnimal = this.getAnimal.bind(this); + this.getRank = this.getRank.bind(this); + this.getRanks = this.getRanks.bind(this); + this.getOrder = this.getOrder.bind(this); + + this.initialize(); + } + + async initialize() { + this.animalNameToKey = {}; + this.animals = {}; + this.order = []; + this.ranks = {}; + this.rankNameToKey = {}; + + const result = await mysql.query(`SELECT * FROM animals;`); + + result.forEach(this.parseAnimal); + Object.keys(animalJson.ranks).forEach(this.parseRank); + this.updateAnimalsAndRanks(); + + this.order = Object.keys(animalJson.ranks); + this.order = this.order.sort((a, b) => { + return animalJson.ranks[a].order - animalJson.ranks[b].order; + }); + } + + /** + * Parse animal for db + */ + parseAnimal(rawAnimal) { + const animal = new Animal(rawAnimal); + this.addAnimalKeyMap(animal); + this.animals[animal.value] = animal; + } + + /** + * Parse rank information + */ + parseRank(rankName) { + const rank = new AnimalRank(rankName); + this.addRankKeyMap(rank); + this.ranks[rank.id] = rank; + } + + updateAnimalsAndRanks() { + for (let key in this.animals) { + const animal = this.animals[key]; + const rank = this.getRank(animal.rank); + rank.addAnimal(animal); + } + } + + getRank(rankName) { + rankName = this.rankNameToKey[rankName?.toLowerCase()]; + return this.ranks[rankName]; + } + + getOrder() { + return this.order; + } + + getRanks() { + return this.ranks; + } + + getAnimal(animalName) { + animalName = this.animalNameToKey[animalName?.toLowerCase()]; + return this.animals[animalName]; + } + + /** + * Add animal to animalNameToKey map + * + * Ex: + * [... + * "gsquid": "", + * "squid": "", + * "": "", + * ...] + */ + addAnimalKeyMap(animal) { + animal.alt.forEach((value) => { + this.animalNameToKey[value.toLowerCase()] = animal.value; + }); + this.animalNameToKey[animal.value.toLowerCase()] = animal.value; + } + + /** + * Add rank to rankNameToKey map + * + * Ex: + * [... + * "common": "common", + * "c": "common", + * ...] + */ + addRankKeyMap(rank) { + rank.alias.forEach((value) => { + this.rankNameToKey[value.toLowerCase()] = rank.id; + }); + this.rankNameToKey[rank.id.toLowerCase()] = rank.id; + } +} + +class Animal { + constructor(rawAnimal) { + const alt = rawAnimal.alt.split(','); + this.description = rawAnimal.description; + this.rank = rawAnimal.rank; + this.alt = alt; + this.value = rawAnimal.name; + this.emoji = rawAnimal.name; + this.name = alt[0]; + this.hpr = this.hp = rawAnimal.hp; + this.attr = this.att = rawAnimal.att; + this.prr = this.pr = rawAnimal.pr; + this.wpr = this.wp = rawAnimal.wp; + this.magr = this.mag = rawAnimal.mag; + this.mrr = this.mr = rawAnimal.mr; + } + + setRank(rank) { + this.rank = rank.rank; + this.price = rank.price; + this.points = rank.points; + this.essence = rank.essence; + } +} + +class AnimalRank { + constructor(rank) { + this.id = rank; + this.rank = rank; + this.name = rank; + this.emoji = animalJson.ranks[rank].emoji; + this.alias = [rank, ...animalJson.ranks[rank].alias]; + this.price = animalJson.ranks[rank].price; + this.points = animalJson.ranks[rank].points; + this.essence = animalJson.ranks[rank].essence; + this.animals = []; + this.placeholder = animalJson.ranks[rank].placeholder; + this.conditional = animalJson.ranks[rank].conditional; + this.rarity = animalJson.ranks[rank].rarity; + this.xp = animalJson.ranks[rank].xp; + this.order = animalJson.ranks[rank].order; + } + + addAnimal(animal) { + this.animals.push(animal.value); + animal.setRank(this); + } +} + +module.exports = new AnimalJson(); diff --git a/src/utils/cacheUtil.js b/src/utils/cacheUtil.js new file mode 100644 index 000000000..1c40e5805 --- /dev/null +++ b/src/utils/cacheUtil.js @@ -0,0 +1,35 @@ +/* + * OwO Bot for Discord + * Copyright (C) 2024 Christopher Thai + * This software is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International + * For more information, see README.md and LICENSE + */ +const mysql = require('./../botHandlers/mysqlHandler.js'); + +class CacheUtil { + constructor() { + this.getAnimalCount = this.getAnimalCount.bind(this); + this.animalCount = {}; + } + + async getAnimalCount(animalName, ttl = 1 * 60 * 60 * 1000) { + if (this.animalCount[animalName] !== undefined) { + return this.animalCount[animalName]; + } + + const sql = `SELECT SUM(totalcount) as total FROM animal WHERE name = ?;`; + const result = await mysql.query(sql, animalName); + const total = result[0].total; + + // Only cache if we have over 1000 animals + if (total > 1000) { + this.animalCount[animalName] = total; + setTimeout(() => { + delete this.animalCount[animalName]; + }, ttl); + } + return total; + } +} + +module.exports = new CacheUtil(); diff --git a/src/utils/eventUtil.js b/src/utils/eventUtil.js index 8dde116ec..a0ac8bf50 100644 --- a/src/utils/eventUtil.js +++ b/src/utils/eventUtil.js @@ -187,6 +187,8 @@ function getCurrentActive(override) { } } +exports.getCurrentActive = getCurrentActive; + function getEventByItem(itemName) { return itemToEvents[itemName]; } diff --git a/src/utils/global.js b/src/utils/global.js index b98eeef60..806a6d6e5 100644 --- a/src/utils/global.js +++ b/src/utils/global.js @@ -31,12 +31,9 @@ try { } filter2.removeWords(goodwords); const namor = require('namor'); +const animalInfo = require('./animalInfoUtil.js'); const mysql = require('./../botHandlers/mysqlHandler.js'); -let animalunicode = {}; -let animals = {}; -let ranks = {}; -let rankAlias = {}; -let client, animaljson, main; +let client, main; let totalShards; const uidDict = {}; @@ -91,88 +88,13 @@ exports.parseID = function (id) { exports.init = function (bot) { main = bot; client = bot.bot; - animaljson = bot.animals; - - let animallist = animaljson['list']; - - //Make nickname alias - for (let key in animallist) { - let alt = animallist[key].alt; - animals[animallist[key].value] = key; - animals[animallist[key].value.toLowerCase()] = key; - animals[key] = key; - animals[key.toLowerCase()] = key; - for (let i in alt) { - animals[alt[i]] = key; - animals[alt[i].toLowerCase()] = key; - } - } - - //to unicode - for (let key in animallist) { - if (animallist[key].uni != undefined) - animalunicode[animallist[key].value] = animallist[key].uni; - } - - //other info to animaljson - for (let key in animaljson.ranks) { - ranks[key] = {}; - let animalRank = []; - for (let i = 1; i < animaljson[key].length; i++) { - let name = animals[animaljson[key][i]]; - try { - animalRank.push(animaljson[key][i]); - animaljson.list[name].rank = key; - animaljson.list[name].price = animaljson.price[key]; - animaljson.list[name].points = animaljson.points[key]; - animaljson.list[name].essence = animaljson.essence[key]; - } catch (err) { - console.error(err); - console.error(animaljson[key][i]); - } - } - ranks[key].animals = animalRank; - ranks[key].price = animaljson.price[key]; - ranks[key].points = animaljson.points[key]; - ranks[key].essence = animaljson.essence[key]; - ranks[key].emoji = animaljson.ranks[key]; - ranks[key].rank = key; - } - - for (let key in animaljson.alias) { - rankAlias[key] = key; - for (let i = 0; i < animaljson.alias[key].length; i++) { - rankAlias[animaljson.alias[key][i]] = key; - } - } }; -/** - * Checks if its a valid animal - */ -exports.validAnimal = function (animal) { - if (animal != undefined) animal = animal.toLowerCase(); - let ranimal = animaljson.list[animals[animal]]; - if (ranimal) ranimal['name'] = animals[animal]; - return ranimal; -}; - -exports.validRank = function (rank) { - if (rank) rank.toLowerCase(); - rank = rankAlias[rank]; - return ranks[rank]; -}; - -exports.getAllRanks = function () { - return ranks; -}; - -/** - * Changes animal to unicode - */ -exports.unicodeAnimal = function (animal) { - let unicode = animalunicode[animal]; - return unicode == undefined ? animal : unicode; +exports.validAnimal = animalInfo.getAnimal; +exports.validRank = animalInfo.getRank; +exports.getAllRanks = animalInfo.getRanks; +exports.unicodeAnimal = function (name) { + return name; }; exports.toSmallNum = function (count, digits) {