diff --git a/base/Member.js b/base/Member.js index 27c486e1..f00d73ad 100644 --- a/base/Member.js +++ b/base/Member.js @@ -11,6 +11,7 @@ module.exports = mongoose.model("Member", new mongoose.Schema({ bankSold: { type: Number, default: 0 }, // Bank sold of the user exp: { type: Number, default: 0 }, // Exp points of the user level: { type: Number, default: 0 }, // Level of the user + transactions: { type: Array, default: [] }, // Transactions of the user /* STATS */ registeredAt: { type: Number, default: Date.now() }, // Registered date of the member diff --git a/commands/Economy/deposit.js b/commands/Economy/deposit.js index dafec604..485cff9e 100644 --- a/commands/Economy/deposit.js +++ b/commands/Economy/deposit.js @@ -30,6 +30,15 @@ class Deposit extends Command { if (data.memberData.money < amount) return message.error("economy/deposit:NOT_ENOUGH_CREDIT", { money: `**${amount}** ${message.getNoun(amount, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}` }); + const info = { + user: message.translate("economy/transactions:BANK"), + amount: amount, + date: Date.now(), + type: "send" + }; + + data.memberData.transactions.push(info); + data.memberData.money = data.memberData.money - amount; data.memberData.bankSold = data.memberData.bankSold + amount; data.memberData.save(); diff --git a/commands/Economy/money.js b/commands/Economy/money.js index db88c74f..50a5c00e 100644 --- a/commands/Economy/money.js +++ b/commands/Economy/money.js @@ -1,11 +1,11 @@ const Command = require("../../base/Command.js"), Discord = require("discord.js"); -const asyncForEach = async (array, callback) => { - for (let index = 0; index < array.length; index++) { - await callback(array[index], index, array); - }; -}; +// const asyncForEach = async (array, callback) => { +// for (let index = 0; index < array.size; index++) { +// await callback(index, array); +// }; +// }; class Credits extends Command { constructor(client) { @@ -36,15 +36,16 @@ class Credits extends Command { }); const commonsGuilds = this.client.guilds.cache.filter((g) => g.members.cache.get(user.id)); - let globalMoney = 0; - await asyncForEach(commonsGuilds, async (guild) => { - const memberData = await this.client.findOrCreateMember({ - id: user.id, - guildID: guild.id - }); - globalMoney += memberData.money; - globalMoney += memberData.bankSold; - }); + const globalMoney = memberData.money + memberData.bankSold; + // let globalMoney = 0; + // await asyncForEach(commonsGuilds, async (guild) => { + // const memberData = await this.client.findOrCreateMember({ + // id: user.id, + // guildID: guild.id + // }); + // globalMoney += memberData.money; + // globalMoney += memberData.bankSold; + // }); const embed = new Discord.MessageEmbed() .setAuthor({ diff --git a/commands/Economy/pay.js b/commands/Economy/pay.js index 74c4ae59..c3f83453 100644 --- a/commands/Economy/pay.js +++ b/commands/Economy/pay.js @@ -35,6 +35,14 @@ class Pay extends Command { guildID: message.guild.id }); + const info = { + user: member.user.tag, + amount: parseInt(amount, 10), + date: Date.now(), + type: "send" + }; + + data.memberData.transactions.push(info); data.memberData.money = data.memberData.money - parseInt(amount, 10); data.memberData.save(); diff --git a/commands/Economy/profile.js b/commands/Economy/profile.js index dd6ae721..a3bcb358 100644 --- a/commands/Economy/profile.js +++ b/commands/Economy/profile.js @@ -1,11 +1,11 @@ const Command = require("../../base/Command.js"), Discord = require("discord.js"); -const asyncForEach = async (array, callback) => { - for (let index = 0; index < array.length; index++) { - await callback(array[index], index, array); - }; -}; +// const asyncForEach = async (array, callback) => { +// for (let index = 0; index < array.size; index++) { +// await callback(index, array); +// }; +// }; class Profile extends Command { constructor(client) { @@ -41,15 +41,16 @@ class Profile extends Command { if (userData.lover && !this.client.users.cache.get(userData.lover)) await this.client.users.fetch(userData.lover, true); const commonsGuilds = client.guilds.cache.filter((g) => g.members.cache.get(member.id)); - let globalMoney = 0; - await asyncForEach(commonsGuilds, async (guild) => { - const memberData = await client.findOrCreateMember({ - id: member.id, - guildID: guild.id - }); - globalMoney += memberData.money; - globalMoney += memberData.bankSold; - }); + const globalMoney = memberData.money + memberData.bankSold; + // let globalMoney = 0; + // await asyncForEach(commonsGuilds, async (guild) => { + // const memberData = await client.findOrCreateMember({ + // id: member.id, + // guildID: guild.id + // }); + // globalMoney += memberData.money; + // globalMoney += memberData.bankSold; + // }); const profileEmbed = new Discord.MessageEmbed() .setAuthor({ diff --git a/commands/Economy/slots.js b/commands/Economy/slots.js index 73b4ab6f..c9890197 100644 --- a/commands/Economy/slots.js +++ b/commands/Economy/slots.js @@ -82,7 +82,18 @@ class Slots extends Command { username: message.author.username }) }); + const toAdd = credits - amount; + + const info = { + user: message.translate("economy/slots:DESCRIPTION"), + amount: toAdd, + date: Date.now(), + type: "got" + }; + + data.memberData.transactions.push(info); + data.memberData.money = data.memberData.money + toAdd; if (!data.userData.achievements.slots.achieved) { data.userData.achievements.slots.progress.now += 1; @@ -114,6 +125,16 @@ class Slots extends Command { }) }); const toAdd = credits - amount; + + const info = { + user: message.translate("economy/slots:DESCRIPTION"), + amount: toAdd, + date: Date.now(), + type: "got" + }; + + data.memberData.transactions.push(info); + data.memberData.money = data.memberData.money + toAdd; if (!data.userData.achievements.slots.achieved) { data.userData.achievements.slots.progress.now += 1; @@ -140,6 +161,16 @@ class Slots extends Command { username: message.author.username }) }); + + const info = { + user: message.translate("economy/slots:DESCRIPTION"), + amount: amount, + date: Date.now(), + type: "send" + }; + + data.memberData.transactions.push(info); + data.memberData.money = data.memberData.money - amount; if (!data.userData.achievements.slots.achieved) { data.userData.achievements.slots.progress.now = 0; diff --git a/commands/Economy/transactions.js b/commands/Economy/transactions.js new file mode 100644 index 00000000..438d0cc4 --- /dev/null +++ b/commands/Economy/transactions.js @@ -0,0 +1,66 @@ +const Command = require("../../base/Command.js"), + Discord = require("discord.js"); + +class Transactions extends Command { + constructor(client) { + super(client, { + name: "transactions", + dirname: __dirname, + enabled: true, + guildOnly: true, + aliases: ["tr"], + memberPermissions: [], + botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"], + nsfw: false, + ownerOnly: false, + cooldown: 2000 + }); + } + + async run(message, args, data) { + const timestamp = Date.now() + (30 * 24 * 60 * 60 * 1000); // day hour min sec msec / 1 month + const transactions = data.memberData.transactions; + for (const t of transactions) { + if (t.date > timestamp) { + const index = transactions.indexOf(t); + transactions.splice(index, 1); + }; + }; + + const embed = new Discord.MessageEmbed() + .setAuthor({ + name: message.translate("economy/transactions:EMBED_TRANSACTIONS"), + iconURL: message.author.displayAvatarURL({ + size: 512, + dynamic: true, + format: "png" + }) + }) + .setColor(data.config.embed.color) + .setFooter({ + text: data.config.embed.footer + }); + + const sortedTransactions = [ [], [] ]; + + transactions.slice(-20).forEach((t) => { + const array = t.type === "got" ? sortedTransactions[0] : sortedTransactions[1]; + array.push(`${message.translate("economy/transactions:T_USER_" + t.type.toUpperCase())}: ${t.user}\n${message.translate("economy/transactions:T_AMOUNT")}: ${t.amount}\n${message.translate("economy/transactions:T_DATE")}: ${message.printDate(t.date, "Do MMMM YYYY, HH:mm")}\n`); + }); + + if (transactions.length < 1) { + embed.setDescription(message.translate("economy/transactions:NO_TRANSACTIONS")); + return message.channel.send({ + embeds: [embed] + }); + } else { + embed.addField(message.translate("economy/transactions:T_GOT"), sortedTransactions[0].join("\n"), true) + embed.addField(message.translate("economy/transactions:T_SEND"), sortedTransactions[1].join("\n"), true) + }; + message.channel.send({ + embeds: [embed] + }); + } +}; + +module.exports = Transactions; \ No newline at end of file diff --git a/commands/Economy/withdraw.js b/commands/Economy/withdraw.js index 77560414..c1d4b84c 100644 --- a/commands/Economy/withdraw.js +++ b/commands/Economy/withdraw.js @@ -30,6 +30,15 @@ class Withdraw extends Command { if (data.memberData.bankSold < amount) return message.error("economy/withdraw:NOT_ENOUGH", { money: `**${amount}** ${message.getNoun(amount, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}` }); + const info = { + user: message.translate("economy/transactions:BANK"), + amount: amount, + date: Date.now(), + type: "got" + }; + + data.memberData.transactions.push(info); + data.memberData.money = data.memberData.money + amount; data.memberData.bankSold = data.memberData.bankSold - amount; data.memberData.save(); diff --git a/commands/Economy/work.js b/commands/Economy/work.js index 9a9b7220..86e5b2fd 100644 --- a/commands/Economy/work.js +++ b/commands/Economy/work.js @@ -74,11 +74,19 @@ class Work extends Command { }; }; embed.addField(message.translate("economy/work:SALARY"), message.translate("economy/work:SALARY_CONTENT", { - won: `${won} ${message.getNoun(won, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}` + won: `**${won}** ${message.getNoun(won, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}` })) .addField(message.translate("economy/work:STREAK"), award.join("")); }; + const info = { + user: message.translate("economy/work:SALARY"), + amount: won, + date: Date.now(), + type: "got" + }; + + data.memberData.transactions.push(info); data.memberData.money = data.memberData.money + won; data.memberData.save(); diff --git a/commands/Fun/choice.js b/commands/Fun/choice.js index 28cac91e..ba8ccd6b 100644 --- a/commands/Fun/choice.js +++ b/commands/Fun/choice.js @@ -7,7 +7,7 @@ class Choice extends Command { dirname: __dirname, enabled: true, guildOnly: false, - aliases: ["random"], + aliases: ["cho", "ra"], memberPermissions: [], botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"], nsfw: false, diff --git a/commands/Fun/findwords.js b/commands/Fun/findwords.js index 6915d568..821c07aa 100644 --- a/commands/Fun/findwords.js +++ b/commands/Fun/findwords.js @@ -33,7 +33,7 @@ class FindWords extends Command { const participants = [], winners = [], words = [], - nbGames = 4; + nbGames = this.client.functions.randomNum(4, 10); // Store the date wich the game has started const createdAt = Date.now(); // 20929038303 @@ -70,6 +70,7 @@ class FindWords extends Command { collector.on("collect", (msg) => { if (this.client.functions.getPrefix(msg, data)) return; if (!participants.includes(msg.author.id)) participants.push(msg.author.id); + if (msg.content === "STOP") return collector.stop("force"); if (msg.content.toLowerCase().indexOf(word) >= 0 && wordList.map((word) => word.toLowerCase()).indexOf(msg.content.toLowerCase()) >= 0) { collector.stop(msg.author.id); // Stop the collector } else msg.error("fun/findwords:INVALID_WORD", { member: msg.author.toString() }); @@ -78,12 +79,17 @@ class FindWords extends Command { collector.on("end", async (collected, reason) => { if (reason === "time") { message.error("fun/findwords:NO_WINNER"); + } else if (reason === "force") { + return message.error("misc:FORCE_STOP", { + user: message.author.toString() + }); } else { message.success("fun/findwords:WORD_FOUND", { winner: `<@${reason}>` }); winners.push(reason); - } + }; + if (i < nbGames - 1) { i++; generateGame.call(this, words[i]); @@ -112,6 +118,16 @@ class FindWords extends Command { id: user.id, guildID: message.guild.id }); + + const info = { + user: message.translate("economy/transactions:WORDS"), + amount: won, + date: Date.now(), + type: "got" + }; + + data.memberData.transactions.push(info); + userdata.money = userdata.money + won; userdata.save(); }; diff --git a/commands/Fun/joke.js b/commands/Fun/joke.js index b2ca3017..56ac5b0e 100644 --- a/commands/Fun/joke.js +++ b/commands/Fun/joke.js @@ -8,7 +8,7 @@ class Joke extends Command { dirname: __dirname, enabled: true, guildOnly: false, - aliases: [], + aliases: ["jo"], memberPermissions: [], botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"], nsfw: false, diff --git a/commands/Fun/number.js b/commands/Fun/number.js index 2263478e..71e28a53 100644 --- a/commands/Fun/number.js +++ b/commands/Fun/number.js @@ -23,7 +23,7 @@ class Number extends Command { if (currentGames[message.guild.id]) return message.error("fun/number:GAME_RUNNING"); const participants = [], - number = Math.floor(this.client.functions.randomNum(100, 10000)); + number = Math.floor(this.client.functions.randomNum(1000, 10000)); await message.sendT("fun/number:GAME_START"); @@ -40,6 +40,7 @@ class Number extends Command { collector.on("collect", async msg => { if (this.client.functions.getPrefix(msg, data)) return; if (!participants.includes(msg.author.id)) participants.push(msg.author.id); + if (msg.content === "STOP") return collector.stop("force"); if (isNaN(msg.content)) return; const parsedNumber = parseInt(msg.content, 10); @@ -66,20 +67,24 @@ class Number extends Command { id: msg.author.id, guildID: message.guild.id }); + + const info = { + user: message.translate("economy/transactions:NUMBERS"), + amount: won, + date: Date.now(), + type: "got" + }; + + data.memberData.transactions.push(info); + userdata.money = userdata.money + won; userdata.save(); }; collector.stop(); }; - if (parseInt(msg.content) < number) message.error("fun/number:BIG", { - user: msg.author.toString(), - number: parsedNumber - }); - if (parseInt(msg.content) > number) message.error("fun/number:SMALL", { - user: msg.author.toString(), - number: parsedNumber - }); + if (parseInt(msg.content) < number) message.error("fun/number:BIG", { user: msg.author.toString(), number: parsedNumber }); + if (parseInt(msg.content) > number) message.error("fun/number:SMALL", { user: msg.author.toString(), number: parsedNumber }); }); collector.on("end", (_collected, reason) => { @@ -88,6 +93,10 @@ class Number extends Command { return message.error("fun/number:DEFEAT", { number }); + } else if (reason === "force") { + return message.error("misc:FORCE_STOP", { + user: message.author.toString() + }); }; }); } diff --git a/commands/Fun/tictactoe.js b/commands/Fun/tictactoe.js index f394ee9f..f244faaf 100644 --- a/commands/Fun/tictactoe.js +++ b/commands/Fun/tictactoe.js @@ -33,6 +33,15 @@ class TicTacToe extends Command { guildID: message.guild.id }); + const info = { + user: message.translate("economy/tictactoe:DESCRIPTION"), + amount: 100, + date: Date.now(), + type: "got" + }; + + data.memberData.transactions.push(info); + userdata.money = userdata.money + 100; userdata.save(); }); diff --git a/commands/General/ping.js b/commands/General/ping.js index 560996d5..b605fa24 100644 --- a/commands/General/ping.js +++ b/commands/General/ping.js @@ -7,7 +7,7 @@ class Ping extends Command { dirname: __dirname, enabled: true, guildOnly: false, - aliases: ["pong", "latency"], + aliases: ["pi"], memberPermissions: [], botPermissions: ["SEND_MESSAGES"], nsfw: false, diff --git a/commands/General/report.js b/commands/General/report.js index 91fff91c..82376ba9 100644 --- a/commands/General/report.js +++ b/commands/General/report.js @@ -8,7 +8,7 @@ class Report extends Command { dirname: __dirname, enabled: true, guildOnly: true, - aliases: [], + aliases: ["repo"], memberPermissions: [], botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"], nsfw: false, diff --git a/commands/General/staff.js b/commands/General/staff.js index 6d223034..d41c864c 100644 --- a/commands/General/staff.js +++ b/commands/General/staff.js @@ -8,7 +8,7 @@ class Staff extends Command { dirname: __dirname, enabled: true, guildOnly: true, - aliases: ["stafflist"], + aliases: ["staf"], memberPermissions: [], botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"], nsfw: false, diff --git a/commands/General/stats.js b/commands/General/stats.js index 9d073fea..e0d0d0f9 100644 --- a/commands/General/stats.js +++ b/commands/General/stats.js @@ -8,7 +8,7 @@ class Stats extends Command { dirname: __dirname, enabled: true, guildOnly: false, - aliases: [], + aliases: ["stat"], memberPermissions: [], botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"], nsfw: false, @@ -44,7 +44,7 @@ class Stats extends Command { count: `${this.client.player.voices.collection.size} ${message.getNoun(this.client.player.voices.collection.size, message.translate("misc:NOUNS:SERVERS:1"), message.translate("misc:NOUNS:SERVERS:2"), message.translate("misc:NOUNS:SERVERS:5"))}` })) .addField(message.translate("general/stats:CREDITS_TITLE"), message.translate("general/stats:CREDITS_CONTENT", { - donators: ["**`Добрый Спецназ#8801`** - Тестер"].join("\n"), + donators: ["**`Добрый Спецназ#8801`** - Тестер, генератор идей"].join("\n"), translators: ["**`Jonny_Bro#4226`** (:flag_ru:)"].join("\n") })); diff --git a/commands/General/translate.js b/commands/General/translate.js index 14741661..f06a9a52 100644 --- a/commands/General/translate.js +++ b/commands/General/translate.js @@ -11,7 +11,7 @@ class Translate extends Command { dirname: __dirname, enabled: true, guildOnly: false, - aliases: ["tr"], + aliases: ["tran"], memberPermissions: [], botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"], nsfw: false, diff --git a/commands/Images/challenger.js b/commands/Images/challenger.js index 39897a7b..e2108af5 100644 --- a/commands/Images/challenger.js +++ b/commands/Images/challenger.js @@ -8,7 +8,7 @@ class Challenger extends Command { dirname: __dirname, enabled: true, guildOnly: false, - aliases: [], + aliases: ["cha"], memberPermissions: [], botPermissions: ["SEND_MESSAGES", "EMBED_LINKS", "ATTACH_FILES"], nsfw: false, diff --git a/commands/Images/jail.js b/commands/Images/jail.js index 9dda89d6..c5e5a1b0 100644 --- a/commands/Images/jail.js +++ b/commands/Images/jail.js @@ -8,7 +8,7 @@ class Jail extends Command { dirname: __dirname, enabled: true, guildOnly: false, - aliases: [], + aliases: ["ja"], memberPermissions: [], botPermissions: ["SEND_MESSAGES", "EMBED_LINKS", "ATTACH_FILES"], nsfw: false, diff --git a/commands/Moderation/clear.js b/commands/Moderation/clear.js index 15d41cda..03887b43 100644 --- a/commands/Moderation/clear.js +++ b/commands/Moderation/clear.js @@ -7,7 +7,7 @@ class Clear extends Command { dirname: __dirname, enabled: true, guildOnly: true, - aliases: ["clear", "bulkdelete", "purge"], + aliases: ["cl", "purge"], memberPermissions: ["MANAGE_MESSAGES"], botPermissions: ["SEND_MESSAGES", "EMBED_LINKS", "MANAGE_MESSAGES"], nsfw: false, diff --git a/commands/Moderation/clearsanctions.js b/commands/Moderation/clearsanctions.js index 591ddd6f..4fdc8711 100644 --- a/commands/Moderation/clearsanctions.js +++ b/commands/Moderation/clearsanctions.js @@ -1,13 +1,13 @@ const Command = require("../../base/Command.js"); -class Clearsanctions extends Command { +class Clearwarns extends Command { constructor(client) { super(client, { - name: "clearsanctions", + name: "clearwarns", dirname: __dirname, enabled: true, guildOnly: true, - aliases: ["clearwarns"], + aliases: ["clearw", "clw"], memberPermissions: ["MANAGE_MESSAGES"], botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"], nsfw: false, @@ -18,7 +18,7 @@ class Clearsanctions extends Command { async run(message, args) { const member = await this.client.resolveMember(args[0], message.guild); - if (!member) return message.error("moderation/clearsanctions:MISSING_MEMBER"); + if (!member) return message.error("moderation/clearwarns:MISSING_MEMBER"); const memberData = await this.client.findOrCreateMember({ id: member.id, @@ -26,10 +26,10 @@ class Clearsanctions extends Command { }); memberData.sanctions = []; memberData.save(); - message.success("moderation/clearsanctions:SUCCESS", { + message.success("moderation/clearwarns:SUCCESS", { username: member.user.tag }); } }; -module.exports = Clearsanctions; \ No newline at end of file +module.exports = Clearwarns; \ No newline at end of file diff --git a/commands/Moderation/poll.js b/commands/Moderation/poll.js index 327454ac..232818b3 100644 --- a/commands/Moderation/poll.js +++ b/commands/Moderation/poll.js @@ -8,7 +8,7 @@ class Poll extends Command { dirname: __dirname, enabled: true, guildOnly: true, - aliases: [], + aliases: ["po"], memberPermissions: ["MANAGE_MESSAGES"], botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"], nsfw: false, diff --git a/commands/Moderation/setwarns.js b/commands/Moderation/setwarns.js index af301cfe..306f0438 100644 --- a/commands/Moderation/setwarns.js +++ b/commands/Moderation/setwarns.js @@ -7,7 +7,7 @@ class Setwarns extends Command { dirname: __dirname, enabled: true, guildOnly: true, - aliases: [], + aliases: ["setw"], memberPermissions: ["MANAGE_GUILD"], botPermissions: ["SEND_MESSAGES", "EMBED_LINKS", "BAN_MEMBERS", "KICK_MEMBERS"], nsfw: false, diff --git a/dashboard/views/docs.ejs b/dashboard/views/docs.ejs index c3bc3f75..9894b100 100644 --- a/dashboard/views/docs.ejs +++ b/dashboard/views/docs.ejs @@ -193,6 +193,21 @@
+									-----------------------------------------------------------------------------------------
+									JaBa v3.2.2
+									-----------------------------------------------------------------------------------------
+
+									Добавлено
+										- transactions (tr) - отслеживание транзакций на вашем счёте.
+										- Принудительная остановка findwords и number.
+										Необходимо написать STOP (без префикса, капсом, никак больше) во время игры.
+										- Больше сокращений для команд.
+
+									Исправления
+										- Кредиты на всех серверах в profile и money заменены на кредиты на текущем сервере.
+										(Я не смог совладать с ошибкой из за discord.js 13, возможно верну позже).
+
+									Спасибо Добрый Спецназ#8801 за идеи.
 									-----------------------------------------------------------------------------------------
 									JaBa v3.2.1
 									-----------------------------------------------------------------------------------------
diff --git a/languages/ru-RU/economy/profile.json b/languages/ru-RU/economy/profile.json
index 5a52d365..5608bfcb 100644
--- a/languages/ru-RU/economy/profile.json
+++ b/languages/ru-RU/economy/profile.json
@@ -9,7 +9,7 @@
 	"NO_BIO": "Биография отсутствует",
 	"CASH": "💵 Кредиты",
 	"BANK": "💳 Банк",
-	"GLOBAL": "🌍 Всего кредитов на всех серверах",
+	"GLOBAL": "🌍 Всего кредитов на текущем сервере",
 	"REPUTATION": "🎩 Репутация",
 	"LEVEL": "📊 Уровень",
 	"EXP": "🔮 Опыт",
diff --git a/languages/ru-RU/economy/transactions.json b/languages/ru-RU/economy/transactions.json
new file mode 100644
index 00000000..d77186cd
--- /dev/null
+++ b/languages/ru-RU/economy/transactions.json
@@ -0,0 +1,16 @@
+{
+	"DESCRIPTION": "Посмотреть историю транзакций!",
+	"USAGE": "{{prefix}}transactions",
+	"EXAMPLES": "{{prefix}}transactions",
+	"NO_TRANSACTIONS": "У вас нет транзакций.",
+	"EMBED_TRANSACTIONS": "Ваши транзакции",
+	"BANK": "Банк",
+	"WORDS": "Угадай слово",
+	"NUMBERS": "Угадай число",
+	"T_GOT": "Пополнение",
+	"T_SEND": "Списание",
+	"T_USER_GOT": "Источник",
+	"T_USER_SEND": "Получатель",
+	"T_AMOUNT": "Сумма",
+	"T_DATE": "Дата"
+}
\ No newline at end of file
diff --git a/languages/ru-RU/misc.json b/languages/ru-RU/misc.json
index 24342ada..230867a6 100644
--- a/languages/ru-RU/misc.json
+++ b/languages/ru-RU/misc.json
@@ -9,6 +9,7 @@
 	"INVALID_TIME": "Укажите действительное время! Доступные единицы: `s`, `m`, `h` или `d`",
 	"INVALID_NUMBER": "Укажите число!",
 	"INVALID_NUMBER_RANGE": "Укажите число от **{{min}}** до **{{max}}**!",
+	"FORCE_STOP": "Игра принудительно окончена {{user}}, никто не победил!",
 	"STATS_FOOTER": "● [Панель управления]({{dashboardLink}})\n● [Документация]({{docsLink}})\n● [Поддержать]({{donateLink}}) (для других способов пишите в ЛС <@{{owner}}>)",
 	"BOT_USER": "Этот пользователь - бот!",
 	"NO_PERMS": "Вы должны быть администратором или модератором для выполнения данного действия!",
diff --git a/languages/ru-RU/moderation/clearsanctions.json b/languages/ru-RU/moderation/clearwarns.json
similarity index 69%
rename from languages/ru-RU/moderation/clearsanctions.json
rename to languages/ru-RU/moderation/clearwarns.json
index fc9fe05a..22cd6777 100644
--- a/languages/ru-RU/moderation/clearsanctions.json
+++ b/languages/ru-RU/moderation/clearwarns.json
@@ -1,7 +1,7 @@
 {
 	"DESCRIPTION": "Снять все предупреждения с пользователя!",
-	"USAGE": "{{prefix}}clearsanctions [@пользователь]",
-	"EXAMPLES": "{{prefix}}clearsanctions @Jonny_Bro#4226",
+	"USAGE": "{{prefix}}clearwarns [@пользователь]",
+	"EXAMPLES": "{{prefix}}clearwarns @Jonny_Bro#4226",
 	"MISSING_MEMBER": "Вы должны упомянуть пользователя!",
 	"SUCCESS": "Предупреждения пользователя **{{username}}** удалены!"
 }
\ No newline at end of file
diff --git a/package.json b/package.json
index 73e0b6f5..334da67b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
     "name": "jaba",
-    "version": "3.2.1",
+    "version": "3.2.2",
     "description": "A very complete Discord bot (more than 100 commands) that uses the Discord.js",
     "main": "index.js",
     "private": true,
@@ -52,7 +52,7 @@
         "mathjs": "^9.0.0",
         "md5": "^2.2.1",
         "moment": "^2.26.0",
-        "mongoose": "^5.9.25",
+        "mongoose": "^5.13.14",
         "ms": "^2.1.3",
         "string-sanitizer": "^1.1.1"
     },