├── LICENSE ├── README.md ├── db.js ├── index.js ├── package.json └── shop.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Assistants 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 | # discord-bot-eco 2 | Very customizable economy framework for your Discord Bot 3 | 4 | ## How does it work? 5 | Easy and fast. Data is saved to a MongoDB database. 6 | Economics is divided into wallet and bank balance, so you have more room to act! 7 | 8 | ## Need Help? 9 | Join our [Discord Server](https://discord.gg/EdJFwNvNS9). 10 | 11 | ## Simple Economy System 12 | discord-bot-eco supports activities such as buy, daily, deposit, get, getItems, giveItem, leaderboard, monthly, reset, rob, sell, take, takeItem, weekly, withdraw, and work! 13 | 14 | ## Introduction 15 | To start using **discord-bot-eco**, you will first need to initialise the configuration as shown below. 16 | ```js 17 | const economy = require('discord-bot-eco') 18 | client.on('ready', async() => { 19 | economy.setConfig({ 20 | mongoURL: "", 21 | currency: "$", 22 | allowBankruptcy: false, 23 | limits: { 24 | defaultBankLimit: 3000, 25 | enabled: true 26 | }, 27 | shopEnabled: true, 28 | shop: [ 29 | /* 30 | Item properties can be modified but the following below must be kept as they are used in the module! 31 | The entire item is returned when using it with functions, go crazy! 32 | */ 33 | { 34 | itemName: "Example Item", 35 | itemBuyPrice: 1000, 36 | itemSellPrice: 900, 37 | itemBuyable: true, 38 | itemSellable: false 39 | } 40 | ] 41 | }); 42 | }); 43 | ``` 44 | 45 | ## Wallet & Bank Functions 46 | |*Function* |Wallet|Bank| 47 | |-------------|---------------|------------------| 48 | |give|`economy.give(userID, amount, "wallet")`|`economy.give(userID, amount, "bank")`| 49 | |take|`economy.take(userID, amount, "wallet")`|`economy.take(userID, amount, "bank")`| 50 | |set|`economy.set(userID, amount, "wallet")`|`economy.set(userID, amount, "bank")`| 51 | |reset|`economy.reset(userID, "wallet")`|`economy.reset(userID, "bank")`| 52 | |get|`economy.get(userID, "wallet")`|`economy.get(userID, "bank")`| 53 | |leaderboard|`economy.leaderboard("wallet")`|`economy.leaderboard("bank")`| 54 | 55 | ## Shop Functions 56 | |*Function* |Usage| 57 | |-------------|-----------------| 58 | |getShop|`economy.getShop(optionalGuildID)`| 59 | |setShop|`economy.setShop(guildID, newShop)`| 60 | |buy|`economy.buy(userID, itemName)`| 61 | |sell|`economy.sell(userID, itemName)`| 62 | |giveItem|`economy.giveItem(userID, itemName)`| 63 | |takeItem|`economy.takeItem(userID, itemName)`| 64 | |hasItem|`economy.hasItem(userID, itemName)`| 65 | |getItems|`economy.getItems(userID)`| 66 | 67 | ## Other Functions 68 | |*Function* |Usage| 69 | |-------------|---------------| 70 | |withdraw|`economy.withdraw(userID, amount)`| 71 | |deposit|`economy.deposit(userID, amount)`| 72 | |work|`economy.work(userID, minEarn, maxEarn)`| 73 | |rob|`economy.rob(userID, robUserID, minEarn, maxEarn, failChance)`| 74 | |daily|`economy.daily(userID, amount)`| 75 | |weekly|`economy.weekly(userID, amount)`| 76 | |monthly|`economy.monthly(userID, amount)`| 77 | |format|`economy.format(amount)`| 78 | |getTimeout|`economy.getTimeout(userID, timeout)`| 79 | |getBankLimit|`economy.getBankLimit(userID)`| 80 | |setBankLimit|`economy.setBankLimit(userID, amount)`| 81 | |getRandom|`economy.getRandom(from, to)`| 82 | |getStreak|`economy.getStreak(userID, type)`| 83 | 84 | ## Handling 85 | All error handling is built into the package! User tries buying a package and it's not real? It'll return an error! 86 | User cannot afford an item? That will also return an error, more details and examples below! 87 | - All functions that save data can return **false** if it failed to save. 88 | ### Buy 89 | ```js 90 | await economy.buy(userID, itemName); 91 | ``` 92 | - **not_real:** The item the user is attempting to buy is not real. 93 | - **not_for_sale:** The item the user is attempting to buy is not for sale. 94 | - **cannot_afford:** The user does not have enough money in their wallet to afford the item. 95 | - The balance will be returned upon success. 96 | 97 | ### Sell 98 | ```js 99 | await economy.sell(userID, itemName); 100 | ``` 101 | - **not_real:** The item the user is attempting to sell is not real. 102 | - **not_sellable:** The item the user is attempting to sell is not sellable. 103 | - **not_owned:** The user does not own the item. 104 | - The balance will be returned upon success. 105 | 106 | ### Daily, Weekly and Monthly 107 | ```js 108 | await economy.daily(userID, amount); 109 | await economy.weekly(userID, amount); 110 | await economy.monthly(userID, amount); 111 | ``` 112 | - **false:** The timeout has not yet expired. 113 | - The balance and the users streak will be returned upon success. 114 | 115 | ### Deposit 116 | ```js 117 | await economy.deposit(userID, amount); 118 | ``` 119 | - **false:** The user does not have enough money. 120 | - **bank_limit:** The users bank limit will exceed. 121 | - The balance will be returned upon success. 122 | 123 | ### Withdraw 124 | ```js 125 | await economy.withdraw(userID, amount); 126 | ``` 127 | - **false:** The user does not have enough money in the bank. 128 | - The balance will be returned upon success. 129 | 130 | ### Leaderboard 131 | ```js 132 | await economy.leaderboard(type); 133 | ``` 134 | - Type can be: **wallet**, **bank** or **both**. 135 | - **false:** The leaderboard is empty. 136 | - The leaderboard sorted from highest to lowest will be returned upon success. 137 | 138 | ### Rob 139 | ```js 140 | await economy.rob(userID, robUserID, minEarn, maxEarn, failChance); 141 | ``` 142 | - failChance is the percentage of the rob failing (10%=10) 143 | - **false:** The rob failed from failChance. 144 | - The amount earned and your current balance will be returned upon success. 145 | 146 | ### Give 147 | ```js 148 | await economy.give(userID, amount, type); 149 | ``` 150 | - Type can be: **wallet**, **bank** or **both**. 151 | - **bank_limit:** The users bank limit will be exceeded if money is given. 152 | - The balance will be returned upon success. 153 | 154 | ### Take 155 | ```js 156 | await economy.take(userID, amount, type); 157 | ``` 158 | - Type can be: **wallet**, **bank** or **both**. 159 | - **false:** The user will go bankrupt if money is taken. 160 | - The balance will be returned upon success. 161 | 162 | ### Get 163 | ```js 164 | await economy.get(userID, type); 165 | ``` 166 | - If type is not provided, both balances will be returned. 167 | 168 | ### GetBankLimit 169 | ```js 170 | await economy.getBankLimit(userID); 171 | ``` 172 | - **false:** Bank limit is not enabled 173 | - The limit will be returned upon success. 174 | 175 | ### SetBankLimit 176 | ```js 177 | await economy.setBankLimit(userID, amount); 178 | ``` 179 | - **false:** Bank limit is not enabled 180 | - The bank limit will be returned upon success. 181 | 182 | ### GetTimeout 183 | ```js 184 | await economy.getTimeout(userID, timeout); 185 | ``` 186 | - Timeout can be: **daily**, **weekly** or **monthly**. 187 | - Returns the *milliseconds* until the next reward is ready. 188 | 189 | ### GetStreak 190 | ```js 191 | await economy.getStreak(userID, type); 192 | ``` 193 | - Type can be: **daily**, **weekly** or **monthly**. 194 | - Returns the streak for the type. 195 | 196 | -------------------------------------------------------------------------------- /db.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require("mongoose"); 2 | 3 | const ecoSchema = new Schema({ 4 | userID: { type: String }, 5 | bankLimit: { type: Number }, 6 | itemsOwned: { type: Array, default: [] }, 7 | dailyTimeout: { type: Number, default: 0 }, 8 | dailyStreak: { type: Number, default: 0 }, 9 | weeklyTimeout: { type: Number, default: 0 }, 10 | weeklyStreak: { type: Number, default: 0 }, 11 | monthlyTimeout: { type: Number, default: 0 }, 12 | monthlyStreak: { type: Number, default: 0 }, 13 | balance: { 14 | wallet: { type: Number, default: 0 }, 15 | bank: { type: Number, default: 0 } 16 | } 17 | }); 18 | 19 | module.exports = model("economy", ecoSchema); -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const ecoSchema = require('./db'); 3 | const shopSchema = require('./shop'); 4 | 5 | var config; 6 | 7 | class Economy { 8 | 9 | /** 10 | * @param {string} [userID] - Get raw data for a user 11 | */ 12 | static async getUser(userID) { 13 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 14 | var storedSettings = await ecoSchema.findOne({ 15 | userID 16 | }); 17 | 18 | if (!storedSettings) { 19 | // If there are no settings stored for this guild, we create them and try to retrive them again. 20 | const newSettings = new ecoSchema({ 21 | userID, 22 | bankLimit: config.limits.defaultBankLimit || 3000 23 | }); 24 | await newSettings.save().catch(() => {}); 25 | var storedSettings = await ecoSchema.findOne({ 26 | userID 27 | }); 28 | } 29 | return storedSettings; 30 | } 31 | 32 | 33 | /** 34 | * @param {object} [conf] - Module configuration 35 | */ 36 | static async setConfig(conf) { 37 | if (!conf) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 38 | config = conf; 39 | 40 | mongoose.connect(config.mongoURL, { 41 | useNewUrlParser: true, 42 | useUnifiedTopology: true 43 | }); 44 | return config; 45 | } 46 | 47 | 48 | /** 49 | * @param {string} [userID] - Discord User ID 50 | * @param {string} [iName] - Item Name 51 | */ 52 | static async buy(userID, iName) { 53 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 54 | if (!userID || !iName) throw new Error("Missing variables."); 55 | 56 | const data = await Economy.getUser(userID); 57 | 58 | const shop = config.shop; 59 | let item = shop.find(o => o.itemName === iName); 60 | 61 | if (!item) return ("not_real"); 62 | if (!item.itemBuyable) return ("not_for_sale"); 63 | if (data.balance.wallet < item.itemBuyPrice) return ("cannot_afford"); 64 | 65 | data.balance.wallet = data.balance.wallet - item.itemBuyPrice; 66 | 67 | let failed1 = 0; 68 | try { 69 | await data.save(); 70 | } catch (e) { 71 | failed1++; 72 | } 73 | if (failed1 !== 0) return false; 74 | else { 75 | Economy.giveItem(userID, item.itemName); 76 | return data.balance; 77 | } 78 | } 79 | 80 | /** 81 | * @param {string} [userID] - Discord User ID 82 | * @param {number} [amount] - Amount of money to give 83 | */ 84 | static async daily(userID, amount) { 85 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 86 | 87 | if (!userID || !amount) throw new Error("Missing variables."); 88 | const data = await Economy.getUser(userID); 89 | 90 | if (Date.now() < (data.dailyTimeout + 86400000)) return false; // If it has been less than 24 hours, return. 91 | 92 | 93 | if (Date.now() > (data.dailyTimeout + (86400000 * 2))) data.dailyStreak = 0 94 | else data.dailyStreak = data.dailyStreak + 1 95 | 96 | data.dailyTimeout = Date.now(); 97 | data.balance.wallet = data.balance.wallet + amount; 98 | 99 | let failed2 = 0; 100 | try { 101 | await data.save(); 102 | } catch (e) { 103 | failed2++; 104 | } 105 | if (failed2 !== 0) return false; 106 | else return { 107 | wallet: data.balance.wallet, 108 | bank: data.balance.bank, 109 | streak: data.dailyStreak 110 | }; 111 | } 112 | 113 | /** 114 | * @param {string} [userID] - Discord User ID 115 | * @param {number} [amount] - Item Name 116 | */ 117 | static async deposit(userID, amount) { 118 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 119 | 120 | if (!userID || !amount) throw new Error("Missing variables."); 121 | const data = await Economy.getUser(userID); 122 | 123 | if ((data.balance.wallet - amount) < 0 && !config.allowBankruptcy) return false; 124 | if ((data.balance.bank + amount) > data.bankLimit && config.limits.enabled) return ("bank_limit"); 125 | data.balance.wallet = data.balance.wallet - amount; 126 | data.balance.bank = data.balance.bank + amount; 127 | let failed3 = 0; 128 | try { 129 | await data.save(); 130 | } catch (e) { 131 | failed3++; 132 | } 133 | if (failed3 !== 0) return false; 134 | else return data.balance; 135 | } 136 | 137 | /** 138 | * @param {number} [money] - Number to format 139 | */ 140 | static async format(money) { 141 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 142 | var formatter = new Intl.NumberFormat('en-US', { 143 | style: 'currency', 144 | currency: 'USD' 145 | }); 146 | 147 | if (!money && money !== 0) throw new Error("Missing variables."); 148 | const convert = formatter.format(money); 149 | return (convert.replace('$', config.currency).replace('.00', '')); 150 | } 151 | 152 | /** 153 | * @param {string} [userID] - Discord User ID 154 | * @param {string} [type] - Wallet, Bank 155 | */ 156 | static async get(userID, type) { 157 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 158 | 159 | if (!userID) throw new Error("Missing variables."); 160 | const data = await Economy.getUser(userID); 161 | if (!type) return data.balance; 162 | if (type === "wallet") return data.balance.wallet; 163 | if (type === "bank") return data.balance.bank; 164 | return data.balance; 165 | } 166 | 167 | /** 168 | * @param {string} [userID] - Discord User ID 169 | */ 170 | static async getBankLimit(userID) { 171 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 172 | 173 | if (!userID) throw new Error("Missing variables."); 174 | const data = await Economy.getUser(userID); 175 | if (!config.limits.enabled) return false; 176 | 177 | return data.bankLimit; 178 | } 179 | 180 | /** 181 | * @param {string} [userID] - Discord User ID 182 | * @param {integer} [amount] - Amount 183 | */ 184 | static async setBankLimit(userID, amount) { 185 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 186 | 187 | if (!userID || !amount) throw new Error("Missing variables."); 188 | const data = await Economy.getUser(userID); 189 | if (!config.limits.enabled) return false; 190 | 191 | data.bankLimit = amount; 192 | await data.save(); 193 | return data.bankLimit; 194 | } 195 | 196 | 197 | /** 198 | * @param {string} [userID] - Discord User ID 199 | */ 200 | static async getItems(userID) { 201 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 202 | 203 | if (!userID) throw new Error("Missing variables."); 204 | 205 | const data = await Economy.getUser(userID); 206 | 207 | return data.itemsOwned; 208 | } 209 | 210 | /** 211 | * @param {string} [userID] - Discord User ID 212 | * @param {string} [item] - Item Name 213 | */ 214 | static async hasItem(userID, item) { 215 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 216 | 217 | if (!userID || !item) throw new Error("Missing variables."); 218 | 219 | const data = await Economy.getItems(userID); 220 | if (!data.find(i => i.item.itemName.toLowerCase() === item.toLowerCase())) return false 221 | 222 | return true; 223 | } 224 | 225 | 226 | /** 227 | * @param {number} [from] - Min 228 | * @param {number} [to] - Max 229 | */ 230 | static async getRandom(from, to) { 231 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 232 | 233 | if (!from || !to) throw new Error("Missing variables."); 234 | 235 | return Math.floor(Math.random() * (to - from + 1) + from) 236 | } 237 | 238 | /** 239 | * @param {string} [userID] - Discord User ID 240 | * @param {string} [timeout] - Daily, Weekly, Monthly 241 | */ 242 | static async getTimeout(userID, timeout) { 243 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 244 | 245 | if (!userID || !timeout) throw new Error("Missing variables."); 246 | 247 | const data = await Economy.getUser(userID); 248 | 249 | if (timeout === "daily") return timeoutMsg('daily', data); 250 | if (timeout === "weekly") return timeoutMsg('weekly', data); 251 | if (timeout === "monthly") return timeoutMsg('monthly', data); 252 | } 253 | 254 | /** 255 | * @param {string} [userID] - Discord User ID 256 | * @param {number} [amount] - Amount of money to give 257 | * @param {string} [type] - Wallet, Bank 258 | */ 259 | static async give(userID, amount, type) { 260 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 261 | 262 | if (!userID || !amount) throw new Error("Missing variables."); 263 | const data = await Economy.getUser(userID); 264 | if (!type) data.balance.wallet = data.balance.wallet + amount; 265 | else if (type === "wallet") data.balance.wallet = data.balance.wallet + amount; 266 | else if (type === "bank") { 267 | if (data.balance.bank + amount > data.bankLimit && config.limits.enabled) return ("bank_limit"); 268 | else data.balance.bank = data.balance.bank + amount; 269 | } 270 | let failed4 = 0; 271 | try { 272 | await data.save(); 273 | } catch (e) { 274 | failed4++; 275 | } 276 | if (failed4 !== 0) return false; 277 | else return data.balance; 278 | } 279 | 280 | /** 281 | * @param {string} [userID] - Discord User ID 282 | * @param {string} [iName] - Item Name to give 283 | */ 284 | static async giveItem(userID, iName) { 285 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 286 | 287 | if (!userID || !iName) throw new Error("Missing variables."); 288 | 289 | const data = await Economy.getUser(userID); 290 | 291 | const shop = config.shop; 292 | let item = shop.find(o => o.itemName === iName); 293 | 294 | if (!item) return false; 295 | const objIndex = await data.itemsOwned.findIndex((obj => obj.item.itemName === iName)); 296 | let iowned; 297 | if (objIndex === -1) { 298 | data.itemsOwned.push({ 299 | item, 300 | amount: 1 301 | }); 302 | } else { 303 | data.itemsOwned[objIndex].amount = data.itemsOwned[objIndex].amount + 1; 304 | iowned = data.itemsOwned[objIndex]; 305 | } 306 | 307 | if (iowned) data.itemsOwned[objIndex] = iowned; 308 | 309 | let failed5 = 0; 310 | try { 311 | await data.save(); 312 | } catch (e) { 313 | failed5++; 314 | } 315 | if (failed5 !== 0) return false; 316 | else return data.balance; 317 | } 318 | 319 | /** 320 | * @param {string} [type] - Wallet, Bank, Both 321 | */ 322 | static async leaderboard(type) { 323 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 324 | 325 | if (!type || type === "both") { 326 | const d2 = await require('./db.js').find({}); 327 | if (!d2) return; 328 | d2.sort((a, b) => { 329 | return parseFloat(b.balance.bank + b.balance.wallet) - parseFloat(a.balance.bank + a.balance.wallet) 330 | }); 331 | 332 | if (!d2[0] || (d2[0].balance.bank + d2[0].balance.wallet) === 0) return false; 333 | 334 | return d2; 335 | } 336 | if (type === "wallet") { 337 | const d2 = await require('./db.js').find({}); 338 | if (!d2) return; 339 | d2.sort((a, b) => { 340 | return parseFloat(b.balance.wallet) - parseFloat(a.balance.wallet) 341 | }); 342 | 343 | if (!d2[0] || d2[0].balance.wallet === 0) return false; 344 | return d2; 345 | } 346 | if (type === "bank") { 347 | const d2 = await require('./db.js').find({}); 348 | if (!d2) return; 349 | d2.sort((a, b) => { 350 | return parseFloat(b.balance.bank) - parseFloat(a.balance.bank) 351 | }); 352 | 353 | if (!d2[0] || d2[0].balance.bank === 0) return false; 354 | return d2; 355 | } 356 | } 357 | 358 | /** 359 | * @param {string} [userID] - Discord User ID 360 | * @param {number} [amount] - Amount of money to give 361 | */ 362 | static async monthly(userID, amount) { 363 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 364 | 365 | if (!userID || !amount) throw new Error("Missing variables."); 366 | const data = await Economy.getUser(userID); 367 | 368 | if (Date.now() < (data.monthlyTimeout + 2592000000)) return false; // If it has been less than 24 hours, return. 369 | 370 | if (Date.now() > (data.monthlyTimeout + (2592000000 * 2))) data.monthlyStreak = 0 371 | else data.monthlyStreak = data.monthlyStreak + 1 372 | 373 | data.monthlyTimeout = Date.now(); 374 | data.balance.wallet = data.balance.wallet + amount; 375 | 376 | let failed6 = 0; 377 | try { 378 | await data.save(); 379 | } catch (e) { 380 | failed6++; 381 | } 382 | if (failed6 !== 0) return false; 383 | else return { 384 | wallet: data.balance.wallet, 385 | bank: data.balance.bank, 386 | streak: data.monthlyStreak 387 | }; 388 | } 389 | 390 | /** 391 | * @param {string} [userID] - Discord User ID 392 | * @param {string} [type] - Wallet, Bank 393 | */ 394 | static async reset(userID, type) { 395 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 396 | 397 | if (!userID) throw new Error("Missing variables."); 398 | const data = await Economy.getUser(userID); 399 | if (!type) { 400 | data.balance.wallet = 0; 401 | data.balance.bank = 0; 402 | } else if (type === "wallet") data.balance.wallet = 0; 403 | else if (type === "bank") data.balance.bank = 0; 404 | 405 | let failed7 = 0; 406 | try { 407 | await data.save(); 408 | } catch (e) { 409 | failed7++; 410 | } 411 | if (failed7 !== 0) return false; 412 | else return data.balance; 413 | } 414 | 415 | /** 416 | * @param {string} [userID] - Discord User ID 417 | * @param {string} [robUserID] - User ID to rob 418 | * @param {number} [minEarn] - Minimum money to earn 419 | * @param {number} [maxEarn] - Maximum money to earn 420 | * @param {number} [failChance] - Fail chance out of 100 421 | */ 422 | static async rob(userID, robUserID, minEarn, maxEarn, failChance) { 423 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 424 | 425 | if (!userID || !robUserID || !maxEarn || !failChance) throw new Error("Missing variables."); 426 | if (!minEarn) minEarn = 0; 427 | const data = await Economy.getUser(userID); 428 | const data2 = await Economy.getUser(robUserID); 429 | 430 | const failed8 = Math.random() < (failChance / 10); 431 | if (failed8) return false; 432 | 433 | let amount = Math.floor(Math.random() * (maxEarn - minEarn + 1) + minEarn); 434 | if (amount < 0 || amount === 0) Math.floor(Math.random() * (maxEarn - minEarn + 1) + minEarn); 435 | if (amount < 0 || amount === 0) return false; 436 | if (data2.balance.wallet - amount < amount - (amount * .4) && (amount / 2) > data2.balance.wallet) return false; // Let them keep 4% 437 | data.balance.wallet = data.balance.wallet + amount; 438 | data2.balance.wallet = data2.balance.wallet - amount; 439 | 440 | let failed9 = 0; 441 | try { 442 | await data.save(); 443 | await data2.save(); 444 | } catch (e) { 445 | failed9++; 446 | } 447 | if (failed9 !== 0) return false; 448 | else return { 449 | earned: amount, 450 | balance: data.balance 451 | }; 452 | } 453 | 454 | /** 455 | * @param {string} [userID] - Discord User ID 456 | * @param {string} [iName] - Item Name 457 | */ 458 | static async sell(userID, iName) { 459 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 460 | 461 | if (!userID || !iName) throw new Error("Missing variables."); 462 | 463 | const data = await Economy.getUser(userID); 464 | 465 | const shop = config.shop; 466 | let item = shop.find(o => o.itemName === iName); 467 | 468 | if (!item) return ("not_real"); 469 | if (!item.itemSellable) return ("not_sellable"); 470 | if (data.itemsOwned.findIndex((obj => obj.item.itemName == item.name)) === -1) return ("not_owned"); 471 | data.balance.wallet = data.balance.wallet + item.itemSellPrice; 472 | 473 | let failed10 = 0; 474 | try { 475 | await data.save(); 476 | } catch (e) { 477 | failed10++; 478 | } 479 | if (failed10 !== 0) return false; 480 | else { 481 | require('../index').takeItem(userID, item.itemName); 482 | return data.balance; 483 | } 484 | } 485 | 486 | /** 487 | * @param {string} [userID] - Discord User ID 488 | * @param {number} [amount] - Amount of money to set 489 | * @param {string} [type] - Wallet, Bank 490 | */ 491 | static async set(userID, amount, type) { 492 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 493 | 494 | if (!userID || !amount) throw new Error("Missing variables."); 495 | const data = await Economy.getUser(userID); 496 | if (!type) data.balance.wallet = amount; 497 | else if (type === "wallet") data.balance.wallet = amount; 498 | else if (type === "bank") data.balance.bank = amount; 499 | 500 | let failed11 = 0; 501 | try { 502 | await data.save(); 503 | } catch (e) { 504 | failed11++; 505 | } 506 | if (failed11 !== 0) return false; 507 | else return data.balance; 508 | } 509 | 510 | /** 511 | * @param {string} [userID] - Discord User ID 512 | * @param {number} [amount] - Amount of money to take 513 | * @param {string} [type] - Wallet, Bank 514 | */ 515 | static async take(userID, amount, type) { 516 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 517 | 518 | if (!userID || !amount) throw new Error("Missing variables."); 519 | const data = await Economy.getUser(userID); 520 | if (!type) { 521 | if (data.balance.wallet - amount < 0 && !config.allowBankruptcy) return false; 522 | data.balance.wallet = data.balance.wallet - amount; 523 | } else if (type === "wallet") { 524 | if (data.balance.wallet - amount < 0 && !config.allowBankruptcy) return false; 525 | data.balance.wallet = data.balance.wallet - amount; 526 | } else if (type === "bank") { 527 | if (data.balance.wallet - amount < 0 && !config.allowBankruptcy) return false; 528 | data.balance.bank = data.balance.bank - amount; 529 | } 530 | 531 | let failed12 = 0; 532 | try { 533 | await data.save(); 534 | } catch (e) { 535 | failed12++; 536 | } 537 | if (failed12 !== 0) return false; 538 | else return data.balance; 539 | } 540 | 541 | /** 542 | * @param {string} [userID] - Discord User ID 543 | * @param {string} [iName] - Item Name to take 544 | */ 545 | static async takeItem(userID, iName) { 546 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 547 | 548 | if (!userID || !iName) throw new Error("Missing variables."); 549 | 550 | const data = await Economy.getUser(userID); 551 | 552 | const shop = config.shop; 553 | let item = shop.find(o => o.itemName === iName); 554 | 555 | if (!item) return false; 556 | let objIndex = data.itemsOwned.findIndex((obj => obj.item.itemName == item.itemName)); 557 | if (objIndex === -1) return ("not_owned"); 558 | 559 | if (data.itemsOwned[objIndex].amount === 1) data.itemsOwned = data.itemsOwned.filter(obj => { 560 | return obj.item.itemName !== data.itemsOwned[objIndex].item.itemName; 561 | }); 562 | else data.itemsOwned[objIndex].amount--; 563 | 564 | let failed13 = 0; 565 | try { 566 | await data.save(); 567 | } catch (e) { 568 | failed13++; 569 | } 570 | if (failed13 !== 0) return false; 571 | else return data.balance; 572 | } 573 | 574 | /** 575 | * @param {string} [userID] - Discord User ID 576 | * @param {number} [amount] - Amount of money to give 577 | */ 578 | static async weekly(userID, amount) { 579 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 580 | 581 | if (!userID || !amount) throw new Error("Missing variables."); 582 | const data = await Economy.getUser(userID); 583 | 584 | if (Date.now() < (data.weeklyTimeout + (604800000))) return false; // If it has been less than 24 hours, return. 585 | 586 | if (Date.now() > (data.weeklyTimeout + (604800000 * 2))) data.weeklyStreak = 0 587 | else data.weeklyStreak = data.weeklyStreak + 1 588 | 589 | data.weeklyTimeout = Date.now(); 590 | data.balance.wallet = data.balance.wallet + amount; 591 | 592 | let failed14 = 0; 593 | try { 594 | await data.save(); 595 | } catch (e) { 596 | failed14++; 597 | } 598 | if (failed14 !== 0) return false; 599 | else return { 600 | wallet: data.balance.wallet, 601 | bank: data.balance.bank, 602 | streak: data.weeklyStreak 603 | }; //? 604 | } 605 | 606 | /** 607 | * @param {string} [userID] - Discord User ID 608 | * @param {number} [amount] - Item Name 609 | */ 610 | static async withdraw(userID, amount) { 611 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 612 | 613 | if (!userID || !amount) throw new Error("Missing variables."); 614 | const data = await Economy.getUser(userID); 615 | 616 | if ((data.balance.bank - amount) < 0 && !config.allowBankruptcy) return false; 617 | data.balance.wallet = data.balance.wallet + amount; 618 | data.balance.bank = data.balance.bank - amount; 619 | let failed15 = 0; 620 | try { 621 | await data.save(); 622 | } catch (e) { 623 | failed15++; 624 | } 625 | if (failed15 !== 0) return false; 626 | else return data.balance; 627 | } 628 | 629 | /** 630 | * @param {string} [userID] - Discord User ID 631 | * @param {number} [minEarn] - Min money they can get 632 | * @param {number} [maxEarn] - Max money they can get 633 | * @param {number} [failChance] - Chance they get nothing 634 | */ 635 | static async work(userID, minEarn, maxEarn, failChance) { 636 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 637 | 638 | if (!userID || !maxEarn) throw new Error("Missing variables."); 639 | if (!minEarn) minEarn = 0; 640 | const data = await Economy.getUser(userID); 641 | 642 | const failed16 = Math.random() < (failChance / 10); 643 | if (failed16) return false; 644 | 645 | let amount = Math.floor(Math.random() * (maxEarn - minEarn + 1) + minEarn); 646 | 647 | data.balance.wallet = data.balance.wallet + amount; 648 | let failed17 = 0; 649 | try { 650 | await data.save(); 651 | } catch (e) { 652 | failed17++; 653 | } 654 | if (failed17 !== 0) return false; 655 | else return { 656 | earned: amount, 657 | balance: data.balance 658 | }; 659 | } 660 | 661 | /** 662 | * @param {string} [userID] - Discord User ID 663 | * @param {string} [streak] - Daily, Weekly, Monthly 664 | */ 665 | 666 | static async getStreak(userID, streak) { 667 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 668 | 669 | if (!userID || !streak) throw new Error("Missing variables."); 670 | 671 | const data = await Economy.getUser(userID); 672 | 673 | if (streak === "daily") { 674 | if (Date.now() > (data.dailyTimeout + (86400000 * 2))) { 675 | data.dailyStreak = 0 676 | await data.save(); 677 | } 678 | return data.dailyStreak 679 | } 680 | if (streak === "weekly") { 681 | if (Date.now() > (data.weeklyTimeout + (604800000 * 2))) { 682 | data.weeklyStreak = 0; 683 | await data.save(); 684 | } 685 | return data.weeklyStreak; 686 | } 687 | if (streak === "monthly") { 688 | if (Date.now() > (data.monthlyTimeout + (2592000000 * 2))) { 689 | data.monthlyStreak = 0; 690 | await data.save(); 691 | } 692 | return data.monthlyStreak; 693 | } 694 | } 695 | 696 | /** 697 | * @param {string} [guildID] - Optional Guild ID 698 | */ 699 | static async getShop(guildID) { 700 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 701 | if (!guildID) return config.shop; 702 | const shop = await shopSchema.findOne({ 703 | guildID 704 | }); 705 | if (!shop || !shop.shop) return false; 706 | return shop.shop; 707 | } 708 | 709 | /** 710 | * @param {string} [guildID] - Guild ID 711 | * @param {object} [shop] - Shop Array 712 | */ 713 | static async setShop(guildID, jsonShop) { 714 | if (!config) throw new Error("You have not setup the module, please join the discord for support. https://discord.gg/DRxfU8wtu8"); 715 | if (!guildID || !jsonShop) throw new Error("Missing variables."); 716 | let shop = await shopSchema.findOne({ 717 | guildID 718 | }); 719 | if (!shop) { 720 | shop = new shopSchema({ 721 | guildID 722 | }); 723 | } 724 | shop.shop = jsonShop; 725 | await shop.save(); 726 | return true; 727 | } 728 | } 729 | async function timeoutMsg(type, data) { 730 | if (type === 'daily') return (new Date(data.dailyTimeout).setDate(new Date(data.dailyTimeout).getDate() + 1)) - Date.now(); 731 | if (type === 'weekly') return (new Date(data.weeklyTimeout).setDate(new Date(data.weeklyTimeout).getDate() + 7)) - Date.now(); 732 | if (type === 'monthly') return (new Date(data.monthlyTimeout).setDate(new Date(data.monthlyTimeout).getDate() + 30)) - Date.now(); 733 | return false; 734 | } 735 | module.exports = Economy; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "discord-bot-eco", 3 | "version": "1.4.1", 4 | "description": "Very customizable economy framework for your Discord Bot", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/PlainDevelopment/discord-bot-eco.git" 12 | }, 13 | "keywords": [ 14 | "discord", 15 | "economy", 16 | "discord-eco", 17 | "discord-economy", 18 | "bot", 19 | "mongo", 20 | "mongoose", 21 | "discordjs", 22 | "discord.js", 23 | "djs", 24 | "shop", 25 | "work", 26 | "rob", 27 | "leaderboard" 28 | ], 29 | "author": "PlainDevelopment", 30 | "license": "MIT", 31 | "dependencies": { 32 | "mongoose": "^6.1.1", 33 | "pretty-ms": "^7.0.1" 34 | }, 35 | "bugs": { 36 | "url": "https://github.com/PlainDevelopment/discord-bot-eco/issues" 37 | }, 38 | "homepage": "https://github.com/PlainDevelopment/discord-bot-eco#readme" 39 | } 40 | -------------------------------------------------------------------------------- /shop.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require("mongoose"); 2 | 3 | const ecoSchema = new Schema({ 4 | guildID: { type: String }, 5 | shop: { type: Object } 6 | }); 7 | 8 | module.exports = model("economyshop", ecoSchema); --------------------------------------------------------------------------------