diff --git a/bot.js b/bot.js new file mode 100644 index 0000000..babc871 --- /dev/null +++ b/bot.js @@ -0,0 +1,407 @@ +require('dotenv').config() +const { + Telegraf, + Scenes, + session, + Stage, + Markup +} = require('telegraf') +const { + weaponshop, + slots, + rarecars, + simplecars, + houses, + cars, + phones, + weapons, + equipment, + UserModel, + WorldModel, + JobModel, + PropertyModel, + BusinessModel, + ReportModel, + BlockModel, + PromocodeModel, + mainChat, + adminList, + expToUp, + topSym +} = require('./config') +const { + profile, + bonus, + pay, + getprofile, + menu, + worldMenu, + referal, + jobs, + chooseJob, + casinoMenu, + work, + top, + propertyList, + propertyMenu, + propertyBuy, + propertySell, + hatkeisList, + organizationMenu, + workoff, + leaveOrg, + leaveOrgAccept, + payday, + orgMessage, + materialsBuy, + percentSet, + invite, + inviteAction, + report, + slotsMenu, + slotsRun, + promocodeActivate, + carContainers, + chooseContainer, + reportAnswer, + fastblock, + createPromo, + genPromo, + organizationCreate +} = require('./commands') +const { + spaces, + spacesWithMarkdown, + escape, + generatePromo, + generateVoucher, + getCurrentTime, + getSlot, + giveExp, + matPriceUpdate, + rand, + random, + setCooldown, + weaponShopUpdate, + stats +} = require('./utils') +const { + handleError + } = require('./handlers') +const crimeScene = require("./scenes/crime"); +const heistScene = require("./scenes/heist"); +const sequelize = require('./db'); +const { Op } = require('sequelize'); +const fs = require('fs'); +const { createCanvas, loadImage } = require('canvas'); +const shortid = require('shortid'); +const voucher_codes = require('voucher-code-generator'); +const bot = new Telegraf(process.env.BOT_TOKEN) +const stage = new Scenes.Stage([crimeScene, heistScene]); + +const start = async () => { + try { + await sequelize.authenticate() + await sequelize.sync() + } catch (e) { + console.log('Подключение к бд сломалось', e) + } +} + +bot.telegram.setMyCommands([{ + command: "pay", + description: "Перевести указанному пользователю сумму." + }, + { + command: "buy", + description: "Приобрести указанное имущество." + }, + { + command: "business", + description: "Создать организацию." + }, + { + command: "invite", + description: "Пригласить пользователя в организацию." + }, + { + command: "percent", + description: "Установить пользователю процент заработка." + }, + { + command: "report", + description: "Создать жалобу/обращение/идею." + } +]) + +bot.use(session({ collectionName: 'sessions' })); +bot.use(stage.middleware()) +bot.use(stats) + +bot.use(async (ctx, next) => { + bot.context.config = require('./ctxconfig.json') + let id = ctx.from.id + let username = ctx.from.username + if(username == null) username = ctx.from.id + switch(ctx.updateType){ + case `message`: + console.log(getCurrentTime() + `: ` + username + `: ` + ctx.update.message.text) + break; + case `callback_query`: + console.log(getCurrentTime() + `: ${username}: ${ctx.update.callback_query.data}`) + break; + default: + console.log(ctx) + } + let user = await UserModel.findByPk(id); + let block = await BlockModel.findByPk(id); + let property = await PropertyModel.findByPk(id); + if (!user) ctx.reply(`❕ Первичная регистрация профиля.`); + if (user === null) { + await UserModel.create({ + telegram_id: id, + username: username, + name: ctx.from.first_name + }) + } else { + user.name = ctx.from.first_name + if(user.username === null) user.username = ctx.from.id + user.save() + } + if (property === null) { + await PropertyModel.create({ + telegram_id: id + }) + } else {} + //if (whitelist.includes(id) == false) return ctx.reply(`У вас пока нет доступа к боту. Следите за обновлениями в группе: t.me/CampFireGameBotNews`) + if (block !== null) { + if (block.isBlocked == true && block.time > Date.now() / 1000) return ctx.reply(`📛 У вас активная блокировка по причине: ${block.reason}.\n⏲️ Оставшееся время: ${Math.trunc((block.time - Date.now()/1000)/60)} мин.`) + block.isBlocked = false + block.save() + } + const start = Date.now() + const timeoutPromise = new Promise((resolve, reject) => { + + setTimeout(() => { + reject(new Error('timeout')) + }, 1000 * 5) + }) + + const nextPromise = next() + .then(() => { + const ms = Date.now() - start + }) + .catch((error) => { + handleError(error, ctx) + }) + + return Promise.race([timeoutPromise, nextPromise]) + .catch((error) => { + if (error.message === 'timeout') { + console.error('timeout', ctx.update) + return false + } + + return true + }) + +}) + +bot.command('start', async (ctx) => { + if (ctx.payload) { + let id = ctx.from.id + let user = await UserModel.findByPk(id); + if (user.level == 1) { + let ref = await UserModel.findByPk(ctx.payload) + let world = await WorldModel.findByPk(1) + world.balance -= 25000 + ref.money += Number(25000) + await ref.save() + await world.save() + bot.telegram.sendMessage(ref.telegram_id, `${ctx.from.username} зарегистрировался по вашей реферальной ссылке. Получено ¤25.000`) + console.log("Transaction to Ref") + } else { + console.log("Exist") + } + } + return await ctx.reply('Главное меню', Markup + .keyboard([ + ['😎 Профиль'], // Row1 with 2 buttons + ['🗄️ Работать', '🌐 Организация', '🎁 Бонус', '🏯 Казино'], // Row2 with 2 buttons + ['📦 Контейнеры'], + ['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'] // Row3 with 3 buttons + ]) + .resize() + ) +}) + +bot.hears('Криминал', async (ctx) => { + await ctx.scene.enter('Crime') +}) + + +bot.hears('промка', async(ctx) => { + generatePromo() +}); + +bot.hears('▶️ Меню', menu); + +bot.hears('Чат', async (ctx) => { + ctx.reply(`${ctx.message.chat.id}`) +}); + +bot.hears('😎 Профиль', profile); + +bot.command('getprofile', getprofile); + +bot.hears('Рандом', async (ctx) => { + let users = await UserModel.findAll(); + let chosenOne = users.random() + return ctx.reply(` + 👤 ${chosenOne.username} + 🆔: ${chosenOne.telegram_id} + `); + +}); + +bot.hears('💳 Баланс', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id); + return ctx.reply(` + ⏩ Аккаунт игрока ${user.username} + 🆔 Игрока: ${user.telegram_id} + + 📶 Уровень: ${user.level} + ⏩ Повышается за различные действия. + + 💰 Баланс: + ¤${user.money} + `); +}) + +bot.hears('🎁 Бонус', bonus) + +bot.command('pay', pay) + +bot.hears('Мир', worldMenu) + +bot.hears('📞 Пригласить', referal) + +bot.hears('📢 Вакансии', jobs) + +bot.action(/job_(1|2|3|4|5|6|7|leave)/, chooseJob) + +bot.hears('🏯 Казино', casinoMenu) + +bot.hears('🗄️ Работать', work) + +bot.hears('Топ', top) + +bot.hears('🔵 Имущество', propertyMenu) + +bot.action('shopmenu', propertyMenu) + +bot.action(/shop_(house|phone|car)/, propertyList) + +bot.action(/{"action": "buy"*/, propertyBuy) + +bot.hears('Поставщик', hatkeisList) + +bot.command('sell', propertySell) + +bot.hears('🌐 Организация', organizationMenu) + +bot.action('workoff', workoff) + +bot.action('покинуть', leaveOrg) + +bot.action('cancel', async (ctx) => { + await ctx.deleteMessage() + await bot.telegram.answerCbQuery(ctx.callbackQuery.id, `Отмена.`) +}) + +bot.action('user_leave_business', leaveOrgAccept) + +bot.action('payday', payday) + +bot.command('orgmessage', orgMessage) + +bot.command('materials', materialsBuy) + +bot.command('percent', percentSet) + +bot.command('business', organizationCreate) + +bot.command('invite', invite) + +bot.action(/{"type": "business_invite_(accept|refuse)"*/, inviteAction) + +bot.command('report', report) + +bot.hears('🎰 Слоты', slotsMenu) + +bot.action(/slots(1000|5000|25000|50000|100000)/, slotsRun) + +bot.hears('Помощь', async (ctx) => { + return await ctx.replyWithMarkdownV2(`• [Функционал](https://telegra.ph/CampFire-Bot-Info-09-25)\n• [Правила](https://telegra.ph/PRAVILA-BOTA-09-25)`, { + disable_web_page_preview: true + }) +}) + +bot.command('promocode', promocodeActivate) + +bot.hears('📦 Контейнеры', carContainers) + +bot.action(/container_(1|2|3|4|5|6|7|8|9|10)/, chooseContainer) + +bot.action(/{"action": "sueta_*/, async (ctx) => { + let data = ctx.update.callback_query.data; + data = JSON.parse(data) + console.log(data.car) + let user = await UserModel.findByPk(ctx.from.id) + let property = await PropertyModel.findByPk(ctx.from.id) + switch(data.action){ + case `sueta_accept`: + user.money += data.carprice + await ctx.editMessageText(`➕ ${data.carprice}`) + break; + case `sueta_refuse`: + user.money += Math.round(property.car.price/2) + property.car = { + name: data.carname, + price: data.carprice + } + await ctx.editMessageText(`➕ ${data.carname}`) + break; + } + user.save() + property.save() +}) +/////////////////////////////////////Admin Commands////////////////////////////////////////////////// + + +bot.command('answer', reportAnswer) + +bot.command('fastblock', fastblock) + +bot.command('createpromocode', createPromo) + +bot.command('genpromo', genPromo) + +///////////////////////////////////////Functions////////////////////////////////////////////////////// + +setInterval(() => { + generatePromo() +}, 18000000); + +setInterval(() => { + var today = new Date(); + let hours = today.getHours(); + if (hours == "0" || hours == "12") { + weaponShopUpdate() + matPriceUpdate() + } +}, 360000); + +start() + +bot.launch() \ No newline at end of file diff --git a/commands/admin/createPromo.js b/commands/admin/createPromo.js new file mode 100644 index 0000000..c357f71 --- /dev/null +++ b/commands/admin/createPromo.js @@ -0,0 +1,29 @@ +const { + UserModel, + PromocodeModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + generateVoucher +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if(user.status != 'admin') return await ctx.reply(`Admin Only.`) + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1] || !ctx.args[2] || !ctx.args[3]) return ctx.reply(`/createpromo [activations] [money] [code]`) + let promocode = await PromocodeModel.findOne({ + where: { + code: ctx.args[3] + } + }) + if(promocode === null){ + await PromocodeModel.create({ + code: ctx.args[3], + activations: ctx.args[1], + money: ctx.args[2] + }) + let voucherImage = await generateVoucher(ctx.args[3], ctx.args[1], ctx.args[2]) + console.log(voucherImage) + return await ctx.sendPhoto({source: voucherImage, caption: `Создан промокод ${ctx.args[3]}` }) +} +} \ No newline at end of file diff --git a/commands/admin/fastblock.js b/commands/admin/fastblock.js new file mode 100644 index 0000000..0612a34 --- /dev/null +++ b/commands/admin/fastblock.js @@ -0,0 +1,23 @@ +const { + Telegraf +} = require('telegraf') +const bot = new Telegraf(process.env.BOT_TOKEN) +const { + UserModel, + BlockModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if(!ctx.message.reply_to_message) return await ctx.reply(`Только на пересланное сообщение.`) + let blocked = ctx.message.reply_to_message.from.id + if(user.status != 'admin') return await ctx.reply(`Admin Only.`) + await BlockModel.create({ + telegram_id: blocked, + isBlocked: true, + reason: `|AutoFastBlock|`, + time: Math.trunc(Date.now() / 1000 + 3600) + }) + await bot.telegram.sendMessage(blocked, `Вы были заблокированы администратором ${user.username}.`) + return await ctx.reply(`Пользователь заблокирован.`) +} \ No newline at end of file diff --git a/commands/admin/genPromo.js b/commands/admin/genPromo.js new file mode 100644 index 0000000..8206e83 --- /dev/null +++ b/commands/admin/genPromo.js @@ -0,0 +1,36 @@ +const voucher_codes = require('voucher-code-generator'); +const { + UserModel, + PromocodeModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + generateVoucher +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if(user.status != 'admin') return await ctx.reply(`Admin Only.`) + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1] || !ctx.args[2]) return ctx.reply(`/genpromo [activations] [money]`) + let code = voucher_codes.generate({ + length: 6, + count: 1, + prefix: "CMP-", + postfix: "-FIRE", + charset: voucher_codes.charset("alphanumeric") + }); + let promocode = await PromocodeModel.findOne({ + where: { + code: code[0] + } + }) + if(promocode === null){ + await PromocodeModel.create({ + code: code[0], + activations: ctx.args[1], + money: ctx.args[2] + }) + let voucherImage = await generateVoucher(code, ctx.args[1], ctx.args[2]) + return await ctx.sendPhoto({source: voucherImage, caption: `Создан промокод ${code[0]}` }) +} +} \ No newline at end of file diff --git a/commands/admin/reportAnswer.js b/commands/admin/reportAnswer.js new file mode 100644 index 0000000..0bfc1fb --- /dev/null +++ b/commands/admin/reportAnswer.js @@ -0,0 +1,26 @@ +const { + Telegraf +} = require('telegraf') +const bot = new Telegraf(process.env.BOT_TOKEN) +const { + UserModel, + ReportModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if(user.status != 'admin') return await ctx.reply(`Admin Only.`) + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1]) return ctx.reply(`Нужен номер обращения`) + let report = await ReportModel.findByPk(ctx.args[1]) + if (report === null) return await ctx.reply(`Нет обращения с таким ID.`) + if (report.status == 0) return await ctx.reply(`Данное обращение уже закрыто.`) + let answer = ctx.args + answer.shift() + answer.shift() + answer = answer.join(' ') + await bot.telegram.sendMessage(report.author, `Ответ на обращение #${report.id}[${report.uid}]\n\n` + answer) + report.status = 0 + report.save() + return await ctx.reply(`Ответ отправлен, обращение закрыто!`) +} \ No newline at end of file diff --git a/commands/bonus.js b/commands/bonus.js new file mode 100644 index 0000000..22fd602 --- /dev/null +++ b/commands/bonus.js @@ -0,0 +1,89 @@ +const { + UserModel, + WorldModel, + BusinessModel +} = require('../config') +const { + rand, + setCooldown +} = require('../utils') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id); + if (!user) return ctx.reply(`Ошибка #1`); + let bonustime = user.bonustime + let cooldown = setCooldown(user, 3600, bonustime) + if (user.bonustime > cooldown.currentTime) return ctx.reply(`📛 Забрать бонус можно будет через ${cooldown.timeLeftInMinutes} минут(у/ы)`); + user.bonus = 1; + user.bonustime = cooldown.endTime + let world = await WorldModel.findByPk(1) + let text = ``; + let money = [100, 200, 300, 400, 500, 1000].random(); + if (user.level >= 5) { + money += money; + } + let r = rand(1, 2); + let x = rand(2, 7); + if (r == 1) { + text += `⏩ ₽${money}\n`; + } + if (r == 2) { + money = money*x + text += `⏩ ₽${money}\n`; + } + switch(user.status){ + case 'bronze': + user.money += 5000 + text += `⭐ Дополнительный бонус за Bronze:\n⏩ ₽5.000\n` + break; + case 'silver': + user.money += 15000 + text += `⭐ Дополнительный бонус за Silver:\n⏩ ₽15.000\n` + break; + case 'gold': + user.money += 30000 + text += `⭐ Дополнительный бонус за Gold:\n⏩ ₽30.000\n` + break; + } + user.money += money; + world.balance -= money + if (user.business.id == 0){ + await user.save(); + await world.save(); + return ctx.reply(` + ⭐ Из ежечасного бонуса Вам выпало: +${text} + `) + } + let business = await BusinessModel.findOne({ + where: { + owner: user.business.id.toString() + } + }) + if(business != null){ + let mats = rand(3, 10) + switch(user.status){ + case 'bronze': + business.materials += 5 + text += `⭐ Дополнительный бонус за Bronze:\n⏩ 5 материалов\n` + break; + case 'silver': + business.materials += 10 + text += `⭐ Дополнительный бонус за Silver:\n⏩ 10 материалов\n` + break; + case 'gold': + business.materials += 20 + text += `⭐ Дополнительный бонус за Gold:\n⏩ 20 материалов\n` + break; + } + text += `⏩ ${mats} материалов в организацию\n` + business.materials += Number(mats) + business.save() + } + await user.save(); + await world.save(); + return ctx.reply(` + ⭐ Из ежечасного бонуса Вам выпало: +${text} + `) +} \ No newline at end of file diff --git a/commands/carcantainers/chooseContainer.js b/commands/carcantainers/chooseContainer.js new file mode 100644 index 0000000..2d2ea73 --- /dev/null +++ b/commands/carcantainers/chooseContainer.js @@ -0,0 +1,32 @@ +const { + rarecars, + simplecars, + UserModel, + PropertyModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + spaces +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') + +module.exports = async (ctx) => { + let data = ctx.update.callback_query.data; + let user = await UserModel.findByPk(ctx.from.id) + let property = await PropertyModel.findByPk(ctx.from.id) + if(user.money < 500000) return ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `Открытие контейнера стоит ₽500.000`, {show_alert: true}) + if(property.car.name) return ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас уже есть автомобиль\nПродайте текущий автомобиль: /sell car`, {show_alert: true}) + user.money -= 500000 + let userWin = null + switch(data){ + case `container_7`: + userWin = rarecars.random() + break; + default: + userWin = simplecars.random() + break; + } + property.car = userWin + user.save() + property.save() + ctx.deleteMessage() + return await ctx.sendPhoto(userWin.image, { caption: `В контейнере была: ${userWin.name} стоимостью ₽${spaces(userWin.price)}`}) +} \ No newline at end of file diff --git a/commands/carcantainers/containersMenu.js b/commands/carcantainers/containersMenu.js new file mode 100644 index 0000000..93d0444 --- /dev/null +++ b/commands/carcantainers/containersMenu.js @@ -0,0 +1,30 @@ +const { + UserModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + let containers = [] + let values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + let oneValue = [] + for(i = 0; i < 10; i++){ + oneValue = values.random() + values = values.filter(value => value != oneValue); + containers.push({name: `📦 Контейнер ${i+1}`, value: oneValue}) + } + let keyboardButtons = containers.map(container => { + return {text: container.name, callback_data: `container_${container.value}`} + }) + let rows = [] + while (keyboardButtons.length > 0) { + rows.push(keyboardButtons.splice(0, 2)) // разбиваем на подмассивы по 5 кнопок + } + console.log(containers) + await ctx.replyWithMarkdownV2('[Sueta Logistic International](https://telegra.ph/OOO-Sueta-Logistic-International-09-27)\nДоступные контейнеры в порту:', + { + reply_markup: { + inline_keyboard: rows + }, + disable_web_page_preview: true + }) +} \ No newline at end of file diff --git a/commands/casino/casinoMenu.js b/commands/casino/casinoMenu.js new file mode 100644 index 0000000..04dfcbf --- /dev/null +++ b/commands/casino/casinoMenu.js @@ -0,0 +1,13 @@ +const { + Markup +} = require('telegraf') + +module.exports = async (ctx) => { + return await ctx.reply('🏯 Добро пожаловать в казино "杜明"\n', Markup + .keyboard([ + ['🎰 Слоты'], + ['▶️ Меню'] + ]) + .resize() +) +} \ No newline at end of file diff --git a/commands/casino/slots.js b/commands/casino/slots.js new file mode 100644 index 0000000..27a45d8 --- /dev/null +++ b/commands/casino/slots.js @@ -0,0 +1,68 @@ +const { + slots, + UserModel, + WorldModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + spaces, + getSlot, + giveExp, + setCooldown +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') + +module.exports = async (ctx) => { + let data = ctx.update.callback_query.data; + let bet = 1000 + switch(data){ + case `slots1000`: + bet = 1000 + break; + case `slots5000`: + bet = 5000 + break; + case `slots25000`: + bet = 25000 + break; + case `slots50000`: + bet = 50000 + break; + case `slots100000`: + bet = 100000 + break; + } + let user = await UserModel.findByPk(ctx.from.id) + let timer = user.slottime + let cooldown = setCooldown(user, 10, timer) + if (user.slottime > cooldown.currentTime) return ctx.reply(`📛 Слоты будут доступны через пару секунд`); + if (user.money < bet) return ctx.reply(`Недостаточно средств.`) + user.slottime = cooldown.endTime + let world = await WorldModel.findByPk(1) + let result = await ctx.replyWithDice({emoji: `🎰`}) + let slot = slots[result.dice.value] + let win = getSlot(result) + console.log(user.username + `: Win: x` + win) + user.money -= bet + world.balance += bet + if(win > 4){ + user.world -= bet*win + user.money += bet*win + user.save() + world.save() + return setTimeout(() => { + ctx.reply(`➕ Вы выиграли ₽${spaces(bet*win)}`) + }, 1700); + } + if(win > 0 && win <= 4){ + await giveExp(user, win*2) + return setTimeout(() => { + ctx.reply(`➕ Вы выиграли ${win*2} опыта.`) + }, 1700); + } + if(win == 0){ + return setTimeout(() => { + world.save() + user.save() + ctx.reply(`➖ Вы проиграли ₽${spaces(bet)}.`) + }, 1700); + } +} \ No newline at end of file diff --git a/commands/casino/slotsMenu.js b/commands/casino/slotsMenu.js new file mode 100644 index 0000000..76e6081 --- /dev/null +++ b/commands/casino/slotsMenu.js @@ -0,0 +1,30 @@ +const { + Markup +} = require('telegraf') +const { + UserModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + ctx.args = ctx.update.message.text.split(' ') + await ctx.reply('Комбинации слотов:\n7️⃣7️⃣7️⃣ - x25\n🍋🍋🍋 - x20\n🍇🍇🍇 - x15\n🔤🔤🔤 - x10', Markup + .inlineKeyboard([ + [{ + text: `1000`, + callback_data: `slots1000` + }, { + text: `5000`, + callback_data: `slots5000` + }, { + text: `25000`, + callback_data: `slots25000` + }, { + text: `50000`, + callback_data: `slots50000` + }, { + text: `100000`, + callback_data: `slots100000` + }] + ])) +} \ No newline at end of file diff --git a/commands/erase.js b/commands/erase.js new file mode 100644 index 0000000..a3e75a7 --- /dev/null +++ b/commands/erase.js @@ -0,0 +1,67 @@ +const { + Telegraf, + Scenes, + session, + Stage, + Markup +} = require('telegraf') +const { + weaponshop, + slots, + rarecars, + simplecars, + houses, + cars, + phones, + weapons, + equipment, + UserModel, + WorldModel, + JobModel, + PropertyModel, + BusinessModel, + ReportModel, + BlockModel, + PromocodeModel, + mainChat, + adminList, + expToUp, + topSym +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + spaces, + spacesWithMarkdown, + escape, + generatePromo, + generateVoucher, + getCurrentTime, + getSlot, + giveExp, + matPriceUpdate, + rand, + random, + setCooldown, + weaponShopUpdate, + stats +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') + +module.exports = async (ctx) => { +// Получаем контекст canvas +const canvas = ctx.update.callback_query.message.photo[0].file_id; +const ctx = new Canvas(cardWidth, cardHeight); + +// Увеличиваем координаты верхнего слоя +topLayerX += 10; +topLayerY += 10; + +// Отправляем обновленную карточку +ctx.replyWithPhoto({ source: canvas.toBuffer() }, Markup.inlineKeyboard([ + Markup.callbackButton('Стереть', 'erase'), +]).extra()); + +// Проверяем, достиг ли верхний слой края карточки +if (topLayerX + cardWidth > cardWidth) { + // Отправляем сообщение с выигрышем + ctx.reply('Поздравляю, вы выиграли!'); +} +} \ No newline at end of file diff --git a/commands/getprofile.js b/commands/getprofile.js new file mode 100644 index 0000000..640e314 --- /dev/null +++ b/commands/getprofile.js @@ -0,0 +1,33 @@ +const { + UserModel, + PropertyModel, + expToUp +} = require('../config') +const { + spacesWithMarkdown, + escape +} = require('../utils') + +module.exports = async (ctx) => { + if(!ctx.message.reply_to_message) return await ctx.reply(`Только на пересланное сообщение.`) + let id = ctx.message.reply_to_message.from.id + let user = await UserModel.findByPk(id); + let property = await PropertyModel.findByPk(id); + return ctx.replyWithMarkdownV2(` + 👤${escape(user.username)} ${user.status == 'bronze' ? `\\[🔺\\]` : ""}${user.status == 'silver' ? `\\[🔹\\]` : ""}${user.status == 'gold' ? `\\[🔸\\]` : ""}${user.status == 'admin' ? "✅" : ""} + 🆔: ${ctx.from.id} + + 📶 Уровень: ${user.level} \\| ${user.exp} / ${expToUp[user.level]} + ⏩ Повышается за различные действия\\. + + 💰 Баланс + ₽${spacesWithMarkdown(user.money)} + + 🔵 Имущество + 🏠 Жилье: ${property.house == 0 ? "Бездомный" : property.house.name} + 🚗 Автомобиль: ${property.car == 0 ? "Пешком" : escape(property.car.name)} + 📱 Телефон: ${property.mobile == 0 ? "Нет" : property.mobile.name} + 🔫 Оружие: ${property.weapon == 0 ? "Безоружный" : property.weapon.name} + 🥼 Экипировка: ${property.equipment == 0 ? "Нет" : property.equipment.name} + `); +} \ No newline at end of file diff --git a/commands/index.js b/commands/index.js new file mode 100644 index 0000000..3bab193 --- /dev/null +++ b/commands/index.js @@ -0,0 +1,40 @@ +module.exports = { + profile: require('./profile'), + bonus: require('./bonus'), + menu: require('./menu'), + getprofile: require('./getprofile'), + pay: require('./pay'), + worldMenu: require('./world'), + referal: require('./invite'), + jobs: require('./jobs/jobs'), + chooseJob: require('./jobs/chooseJob'), + casinoMenu: require('./casino/casinoMenu'), + work: require('./jobs/work'), + top: require('./top'), + propertyMenu: require('./property/propertyMenu'), + propertyList: require('./property/propertyList'), + propertyBuy: require('./property/propertyBuy'), + hatkeisList: require('./property/hatkeisList'), + propertySell: require('./property/propertySell'), + organizationMenu: require('./organization/organizationMenu'), + workoff: require('./organization/workoff'), + leaveOrg: require('./organization/leaveOrg'), + leaveOrgAccept: require('./organization/leaveOrgAccept'), + payday: require('./organization/payday'), + orgMessage: require('./organization/orgMessage'), + materialsBuy: require('./organization/materialsBuy'), + percentSet: require('./organization/percentSet'), + organizationCreate: require('./organization/organizationCreate'), + invite: require('./organization/invite'), + inviteAction: require('./organization/inviteAction'), + report: require('./report'), + slotsMenu: require('./casino/slotsMenu'), + slotsRun: require('./casino/slots'), + promocodeActivate: require('./promocodeActivate'), + carContainers: require('./carcantainers/containersMenu'), + chooseContainer: require('./carcantainers/chooseContainer'), + reportAnswer: require('./admin/reportAnswer'), + fastblock: require('./admin/fastblock'), + createPromo: require('./admin/createPromo'), + genPromo: require('./admin/genPromo') +} \ No newline at end of file diff --git a/commands/invite.js b/commands/invite.js new file mode 100644 index 0000000..d3c88bf --- /dev/null +++ b/commands/invite.js @@ -0,0 +1,49 @@ +const { + weaponshop, + slots, + rarecars, + simplecars, + houses, + cars, + phones, + weapons, + equipment, + UserModel, + WorldModel, + JobModel, + PropertyModel, + BusinessModel, + ReportModel, + BlockModel, + PromocodeModel, + mainChat, + adminList, + expToUp, + topSym +} = require('../config') +const { + spaces, + spacesWithMarkdown, + escape, + generatePromo, + generateVoucher, + getCurrentTime, + getSlot, + giveExp, + matPriceUpdate, + rand, + random, + setCooldown, + weaponShopUpdate, + stats +} = require('../utils') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id); + return ctx.reply(` + ℹ️ Для приглашения друга по реферальной системе, отправьте ему ссылку-приглашение +Как только он перейдет по ней и начнет игру, Вы получите ₽25.000. + +Ваша ссылка: https://t.me/CampFireGameBot?start=${user.telegram_id} + `) +} \ No newline at end of file diff --git a/commands/jobs/chooseJob.js b/commands/jobs/chooseJob.js new file mode 100644 index 0000000..e38459c --- /dev/null +++ b/commands/jobs/chooseJob.js @@ -0,0 +1,96 @@ +const { + UserModel, + JobModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + let data = ctx.update.callback_query.data; + let user = await UserModel.findByPk(ctx.from.id); + let job = null + switch(data){ + case `job_1`: + job = await JobModel.findByPk(1); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 1 + user.save() + return await ctx.reply(`ℹ️ Вы устроились на работу дворником.\nВаш оклад: ₽${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`❕ Вы уже устроены на другую работу`) + case `job_2`: + job = await JobModel.findByPk(2); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 2 + user.save() + return await ctx.reply(`ℹ️ Вы устроились на работу промоутером. \nВаш оклад: ₽${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`❕ Вы уже устроены на другую работу`) + case `job_3`: + job = await JobModel.findByPk(3); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 3 + user.save() + return await ctx.reply(`ℹ️ Вы устроились на работу официантом. \nВаш оклад: ₽${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`❕ Вы уже устроены на другую работу`) + case `job_4`: + job = await JobModel.findByPk(4); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 4 + user.save() + return await ctx.reply(`ℹ️ Вы устроились на работу барменом. \nВаш оклад: ₽${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`❕ Вы уже устроены на другую работу`) + case `job_5`: + job = await JobModel.findByPk(5); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 5 + user.save() + return await ctx.reply(`❕ Вы устроились на работу кассиром. \nВаш оклад: ₽${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`ℹ️ Вы уже устроены на другую работу`) + case `job_6`: + job = await JobModel.findByPk(6); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 6 + user.save() + return await ctx.reply(`ℹ️ Вы устроились на работу в ПВЗ Дикие Ягоды. \nВаш оклад: ₽${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`❕ Вы уже устроены на другую работу`) + case `job_7`: + job = await JobModel.findByPk(7); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 7 + user.save() + return await ctx.reply(`ℹ️ Вы устроились на работу слесарем. \nВаш оклад: ₽${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`❕ Вы уже устроены на другую работу`) + case `job_leave`: + if (user.job != 0) { + user.job = 0 + user.save() + return await ctx.reply(`ℹ️ Теперь вы безработный.`) + } + return await ctx.reply(`❕ Вы итак безработный.`) + } +} \ No newline at end of file diff --git a/commands/jobs/jobs.js b/commands/jobs/jobs.js new file mode 100644 index 0000000..259303b --- /dev/null +++ b/commands/jobs/jobs.js @@ -0,0 +1,36 @@ +const { + Markup +} = require('telegraf') + +module.exports = async (ctx) => { + return await ctx.reply('Список работы', Markup + .inlineKeyboard([ + [{ + text: `Дворник [1 уровень]`, + callback_data: 'job_1' + }, { + text: `Промоутер [1 уровень]`, + callback_data: 'job_2' + }], [{ + text: `Официант [2 уровень]`, + callback_data: 'job_3' + }, { + text: `Бармен [3 уровень]`, + callback_data: 'job_4' + }], [{ + text: `Кассир [4 уровень] `, + callback_data: 'job_5' + }, { + text: `ПВЗ Дикие Ягоды [4 уровень]`, + callback_data: 'job_6' + }], [{ + text: `Слесарь [5 уровень]`, + callback_data: 'job_7' + }], [{ + text: `💤 Уволиться`, + callback_data: 'job_leave' + }] + ]) + .resize() +) +} \ No newline at end of file diff --git a/commands/jobs/work.js b/commands/jobs/work.js new file mode 100644 index 0000000..a9b7d56 --- /dev/null +++ b/commands/jobs/work.js @@ -0,0 +1,191 @@ +const { + UserModel, + WorldModel, + JobModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + giveExp, + setCooldown +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id); + let job = await JobModel.findByPk(user.job); + let world = await WorldModel.findByPk(1) + let timer = user.jobtime + let cooldown = setCooldown(user, 3600, timer) + if (user.jobtime > cooldown.currentTime) return ctx.reply(`📛 Работать можно будет через ${cooldown.timeLeftInMinutes} минут(у/ы)`); + if (user.job == 0) { + return await ctx.reply(`📛 Вы безработный.`) + } + user.jobtime = Number(cooldown.endTime) + let jobExp = job.exp; + user.jobcheck++ + switch (user.job) { + case 1: + if (user.jobcheck >= 4) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + world.balance -= payday + user.money += payday + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену дворника. \n🧾 Расчетный лист: \n⏳ Отработано часов: 4/4 \n💸 Оклад: ₽${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ₽${payday}`) + } else { + user.save() + return ctx.reply(`👔 Вы подмели дворы. \n⏳ Отработано часов: ${user.jobcheck}/4`) + } + break; + case 2: + if (user.jobcheck >= 2) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + world.balance -= payday + user.money += payday + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену промоутера. \n🧾 Расчетный лист: \n⏳ Отработано часов: 2/2 \n💸 Оклад: ₽${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ₽${payday}`) + } else { + user.save() + return ctx.reply(`👔 Вы раздавали листовки целый час. \n⏳ Отработано часов: ${user.jobcheck}/2`) + } + break; + case 3: + if (user.jobcheck >= 4) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + world.balance -= payday + let tips = [50, 100, 200, 500, 1000].random() + user.money += tips + user.money += payday + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену официанта. \n🧾 Расчетный лист: \n⏳ Отработано часов: 4/4 \n💸 Оклад: ₽${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ₽${payday} \n💰 Получено чаевых: ₽${tips}`) + } else { + let tips = [50, 100, 200, 500, 1000].random() + user.money += tips + user.save() + return ctx.reply(`👔 Вы целый час бегали и отрабатывали заказы. \n🧾 Получено чаевых: ₽${tips} \n⏳ Отработано часов: ${user.jobcheck}/4`) + } + break; + case 4: + if (user.jobcheck >= 5) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + world.balance -= payday + let tips = [50, 100, 200, 300, 500, 1000, 2000].random() + world.balance -= tips + user.money += tips + user.money += payday + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену бармена. \n🧾 Расчетный лист: \n⏳ Отработано часов: 5/5 \n💸 Оклад: ₽${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ₽${payday} \n💰 Получено чаевых: ₽${tips}`) + } else { + let tips = [50, 100, 200, 300, 500, 1000, 2000].random() + world.balance -= tips + user.money += tips + user.save() + world.save() + return ctx.reply(`👔 Вы целый час стояли за стойкой и разливали пойло. \n🧾 Получено чаевых: ₽${tips} \n⏳ Отработано часов: ${user.jobcheck}/5`) + } + break; + case 5: + if (user.jobcheck >= 5) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + world.balance -= payday + user.money += payday + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену кассира. \n🧾 Расчетный лист: \n⏳ Отработано часов: 5/5 \n💸 Оклад: ₽${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ₽${payday}`) + } else { + user.save() + return ctx.reply(`👔 Вы целый час обслуживали покупателей и кричали: "Гаааляяя, отмена!". \n⏳ Отработано часов: ${user.jobcheck}/5`) + } + break; + case 6: + if (user.jobcheck >= 6) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + let stealed = [{ + name: "Помада", + price: 200 + }, { + name: "Бюстгалтер", + price: 1300 + }, { + name: "Прокладки", + price: 250 + }, { + name: "Перцовый балончик", + price: 600 + }, { + name: "Гитара", + price: 6500 + }, { + name: "Комбик", + price: 9000 + }, { + name: "Кроссовки", + price: 2000 + }, { + name: "Шампунь", + price: 180 + }, { + name: "Смартфон Texno", + price: 6999 + }, { + name: "TWS Гарнитура", + price: 2800 + }, { + name: "Геймпад GameStation 5", + price: 1400 + }, { + name: "Дилдо", + price: 600 + }, { + name: "Вагиноимитатор", + price: 600 + }].random() + world.balance -= payday + world.balance -= Number(stealed.price) + user.money += payday + user.money += Number(stealed.price) + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену в Диких Ягодах. \n🧾 Расчетный лист: \n⏳ Отработано часов: 6/6 \n💸 Оклад: ₽${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ₽${payday} \n💰 Вы украли и продали со склада: ${stealed.name} (₽${stealed.price})`) + } else { + user.save() + return ctx.reply(`👔 Вы целый час выдавали заказы в Диких Ягодах. \n⏳ Отработано часов: ${user.jobcheck}/6`) + } + break; + case 7: + if (user.jobcheck >= 6) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + world.balance -= payday + user.money += payday + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену слесарем. \n🧾 Расчетный лист: \n⏳ Отработано часов: 6/6 \n💸 Оклад: ₽${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ₽${payday}`) + } else { + user.save() + return ctx.reply(`👔 Вы целый час работали на заводе, вы молодец! \n⏳ Отработано часов: ${user.jobcheck}/6`) + } + break; + } +} \ No newline at end of file diff --git a/commands/menu.js b/commands/menu.js new file mode 100644 index 0000000..f5afcd3 --- /dev/null +++ b/commands/menu.js @@ -0,0 +1,15 @@ +const { + Markup +} = require('telegraf') + +module.exports = async (ctx) => { + return await ctx.reply('Main Menu', Markup + .keyboard([ + ['😎 Профиль'], + ['🗄️ Работать', '🌐 Организация', '🎁 Бонус', '🏯 Казино'], + ['📦 Контейнеры'], + ['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'] + ]) + .resize() + ) +} diff --git a/commands/organization/invite.js b/commands/organization/invite.js new file mode 100644 index 0000000..d1aa160 --- /dev/null +++ b/commands/organization/invite.js @@ -0,0 +1,38 @@ +const { + Telegraf, + Markup +} = require('telegraf') +const bot = new Telegraf(process.env.BOT_TOKEN) +const { + UserModel, + BusinessModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1]) return ctx.reply(`/invite [Nick]`) + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id == 0) return await ctx.reply(`🚫 У вас нет организации в которую можно пригласить игрока.`) + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + if (business.users.length >= 5) return await ctx.reply(`📛 Достигнуто максимальное количество сотрудников в организации.`) + let invited = await UserModel.findOne({ + where: { + username: ctx.args[1] + } + }); + await bot.telegram.sendMessage(invited.telegram_id, '⤵️ Приглашение', Markup + .inlineKeyboard([ + [{ + text: `Принять`, + callback_data: `{"type": "business_invite_accept", "invitor": "${user.telegram_id}"}` + }, { + text: `Отклонить`, + callback_data: `{"type": "business_invite_refuse", "invitor": "${user.telegram_id}"}` + }] + ]).oneTime()) + return await ctx.reply(`Приглашение отправлено.`) +} \ No newline at end of file diff --git a/commands/organization/inviteAction.js b/commands/organization/inviteAction.js new file mode 100644 index 0000000..0b259f2 --- /dev/null +++ b/commands/organization/inviteAction.js @@ -0,0 +1,34 @@ +const sequelize = require('/workspace/degradin/Dev/Telegram/CampFire Play/db'); +const { Op } = require('sequelize'); +const { + UserModel, + BusinessModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + let data = ctx.update.callback_query.data; + data = JSON.parse(data) + let user = await UserModel.findByPk(ctx.update.callback_query.from.id) + if (data.type == 'business_invite_accept') { + if(user.business.id == 0){ + let business = await BusinessModel.findOne({ + where: { + owner: data.invitor + } + }) + user.business = { + id: data.invitor, + checks: 0, + percent: 10 + } + business.users = sequelize.fn('array_append', sequelize.col('users'), ctx.update.callback_query.from.id); + business.save() + user.save() + await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `✔️ Приглашение принято.`, {show_alert: true}) + } + await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `ℹ️ Вы уже в организации.`, {show_alert: true}) + } + if (data.type == 'business_invite_refuse'){ + await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `❌ Приглашение отклонено.`, {show_alert: true}) + } +} \ No newline at end of file diff --git a/commands/organization/leaveOrg.js b/commands/organization/leaveOrg.js new file mode 100644 index 0000000..b3c5ee7 --- /dev/null +++ b/commands/organization/leaveOrg.js @@ -0,0 +1,41 @@ +const { + Telegraf +} = require('telegraf') +const bot = new Telegraf(process.env.BOT_TOKEN) +const { + UserModel, + BusinessModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id == 0) return await ctx.reply(`Вы не состоите в организации.`) + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + if(business === null){ + business = await BusinessModel.findOne({ + where: { + owner: user.business.id + } + }) + await ctx.reply(`Подтвердите в личных сообщениях.`) + return await bot.telegram.sendMessage(ctx.from.id, `🏭 Вы действительно хотите покинуть ${business.name}`, Markup.inlineKeyboard([ + [{ + text: `Да`, + callback_data: "user_leave_business" + }, { + text: `Нет`, + callback_data: "cancel" + }] + ]) + .oneTime() + .resize() + ) + } + if (business.owner == ctx.from.id){ + return await ctx.reply(`Вы не можете покинуть свою организацию.`) + } +} \ No newline at end of file diff --git a/commands/organization/leaveOrgAccept.js b/commands/organization/leaveOrgAccept.js new file mode 100644 index 0000000..cb50ca4 --- /dev/null +++ b/commands/organization/leaveOrgAccept.js @@ -0,0 +1,28 @@ +const { + Telegraf +} = require('telegraf') +const bot = new Telegraf(process.env.BOT_TOKEN) +const { + UserModel, + BusinessModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + let data = ctx.update.callback_query.data; + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id == 0) return await ctx.reply(`Вы не состоите в организации.`) + let business = await BusinessModel.findOne({ + where: { + owner: user.business.id + } + }) + user.business = { + id: 0, + checks: 0, + percent: 0 + } + business.users = business.users.filter(value => value != ctx.from.id); + business.save() + user.save() + return await bot.telegram.sendMessage(ctx.from.id, `🏭 Вы покинули ${business.name}`) +} \ No newline at end of file diff --git a/commands/organization/materialsBuy.js b/commands/organization/materialsBuy.js new file mode 100644 index 0000000..f8c6907 --- /dev/null +++ b/commands/organization/materialsBuy.js @@ -0,0 +1,29 @@ +const { + UserModel, + WorldModel, + BusinessModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + ctx.args = ctx.update.message.text.split(' ') + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id == 0) return await ctx.reply(`🚫 Вы не владеете организацией.`) + let world = await WorldModel.findByPk(1) + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + if (business === null) return await ctx.reply(`🚫 У вас нет организации.`) + if (!ctx.args[1]) return ctx.reply(`🚫 Не указан аргумент.`) + if (!Number(ctx.args[1])) return ctx.reply(`ℹ️ Количество должно быть числом.`) + if (ctx.args[1] < 1) return ctx.reply(`ℹ️ Минимальное количество для покупки - 1`) + if (ctx.args[1]*world.matPrice > business.balance) return ctx.reply(`🚫 Недостаточно средств на балансе организации.`) + if (business.materials >= 700) return ctx.reply(`🚫 Склады полны.`) + if (business.materials + Number(ctx.args[1]) > 700) return ctx.reply(`🚫 Нет столько места на складах.\n Можно закупить еще ${700 - business.materials}`) + let count = Number(ctx.args[1]) + business.balance -= world.matPrice*count + business.materials += count + business.save() + return await ctx.reply(`➕ Закуплено ${ctx.args[1]} материалов для организации на сумму ₽${world.matPrice*count}`) +} \ No newline at end of file diff --git a/commands/organization/orgMessage.js b/commands/organization/orgMessage.js new file mode 100644 index 0000000..a0d1bfa --- /dev/null +++ b/commands/organization/orgMessage.js @@ -0,0 +1,24 @@ +const { + Telegraf +} = require('telegraf') +const bot = new Telegraf(process.env.BOT_TOKEN) +const { + UserModel, + BusinessModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + if (!ctx.args[1]) return ctx.reply(`Не указан аргумент.`) + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + if (business === null) return await ctx.reply(`У вас нет организации.`) + for (i = 0; i < business.users.length; i++) { + user = await UserModel.findByPk(business.users[i]) + await bot.telegram.sendMessage(user.telegram_id, `Директор организации сообщает:\n ${ctx.payload}`) + } + console.log(`Директор организации сообщает:\n ${ctx.payload}`) + return await ctx.reply(`Сообщение отправлено.`) +} \ No newline at end of file diff --git a/commands/organization/organizationCreate.js b/commands/organization/organizationCreate.js new file mode 100644 index 0000000..c3c863e --- /dev/null +++ b/commands/organization/organizationCreate.js @@ -0,0 +1,45 @@ +const { + UserModel, + WorldModel, + BusinessModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id != 0){ + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + } + let business = null + let world = await WorldModel.findByPk(1) + ctx.args = ctx.update.message.text.split(' ') + if (business != null) return await ctx.reply(`У вас уже есть организация.`) + if (!ctx.args[1]) return ctx.reply(`/business [Название организации]`) + if (user.money < 100000) return await ctx.reply(`Регистрация организации стоит ₽100.000`) + if (user.level < 5) return await ctx.reply(`Регистрация организации доступна с 5 уровня.`) + user.money -= 100000 + world.balance += 100000 + let text = `` + for (i = 1; i < ctx.args.length; i++) { + text += `${ctx.args[i]} ` + } + if (business === null) { + BusinessModel.create({ + name: text, + owner: user.telegram_id, + balance: 50000, + users: [user.telegram_id] + }) + user.business = { + id: user.telegram_id, + checks: 0, + percent: 100 + } + } else {} + user.save() + world.save() + return await ctx.reply(`Организация "${text}" успешно создана!\n Регистрация организации в реестре: ₽50.000 \n Капитал: ₽50.000`) +} \ No newline at end of file diff --git a/commands/organization/organizationMenu.js b/commands/organization/organizationMenu.js new file mode 100644 index 0000000..bddf056 --- /dev/null +++ b/commands/organization/organizationMenu.js @@ -0,0 +1,57 @@ +const { + Markup +} = require('telegraf') +const { + UserModel, + BusinessModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + spaces, + escape +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id == 0) return await ctx.reply(`Вы не состоите в организации.`) + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + if(business === null){ + business = await BusinessModel.findOne({ + where: { + owner: user.business.id + } + }) + return await ctx.replyWithMarkdownV2(`🏭 Организация\n_${business.name}_\n💹 Баланс: ₽${escape(spaces(business.balance))}\n🧰 Сырье: ${business.materials}\n👥 Рабочих: ${business.users.length}\n\nВаши отработки: ${user.business.checks}`, Markup.inlineKeyboard([ + [{ + text: `📶 Отработка`, + callback_data: "workoff" + }, { + text: `⬅️ Покинуть`, + callback_data: "покинуть" + }] + ]) + .oneTime() + .resize()) + } + if (business.owner == ctx.from.id){ + let text = `` + for (n = 0; n < business.users.length; n++) { // Процент выплаты участникам + users = await UserModel.findByPk(business.users[n]) + text += `${users.username} - ${users.business.checks} [${users.business.percent}%]\n` + } + return await ctx.replyWithMarkdownV2(`🏭 Ваша организация\n_${business.name}_\n💹 Баланс: ₽${escape(spaces(business.balance))}\n🧰 Сырье: ${business.materials}\n👥 Рабочих: ${business.users.length}\n🔨 Отработок: ${business.checks}\n${escape(text)}\n\nВаши отработки: ${user.business.checks}`, Markup.inlineKeyboard([ + [{ + text: `📶 Отработка`, + callback_data: "workoff" + }, { + text: `💸 Payday`, + callback_data: "payday" + }] + ]) + .oneTime() + .resize()) + } +} \ No newline at end of file diff --git a/commands/organization/payday.js b/commands/organization/payday.js new file mode 100644 index 0000000..73a1a59 --- /dev/null +++ b/commands/organization/payday.js @@ -0,0 +1,70 @@ +const { + Telegraf +} = require('telegraf') +const bot = new Telegraf(process.env.BOT_TOKEN) +const { + UserModel, + WorldModel, + BusinessModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + spaces, + giveExp, + rand +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') + +module.exports = async (ctx) => { + let user = null + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + let world = await WorldModel.findByPk(1) + if (business === null) return await ctx.reply(`У вас нет организации.`) + if (business.checks < 12) return await ctx.reply(`Недостаточно отработок для формирования выплаты.`) + let percentSum = 0 + let text = `` + let percentErrorText = `` + let profit = 0 + let piece = 0 + let moneyList = rand(1000, 3000) + moneyList = moneyList*business.users.length + for (i = 0; i < business.users.length; i++) { // Summary percent + user = await UserModel.findByPk(business.users[i]) + percentSum += Number(user.business.percent) + percentErrorText += `ℹ️ ${user.username} ${user.business.percent}% [/percent ${user.username} [проценты]]\n` + } + if (percentSum > 100) return await ctx.reply(`⚠️ Общий процент всех сотрудников превышает 100%\n ➕ Остаток процентов перенесется в баланс организации.\n\n${percentErrorText}\n`) + for (x = 0; x < business.users.length; x++) { // Общая внесенная сумма всеми участниками + user = await UserModel.findByPk(business.users[x]) + profit += user.business.checks * moneyList * user.level + text += `ℹ️ ${user.username} отработал ${user.business.checks} раз.\n` + user.business = { + id: user.business.id, + checks: 0, + percent: user.business.percent + } + user.save() + } + text += ` 💹 Наработка за текущий период: ${profit}\n` + let profitCheck = profit + for (n = 0; n < business.users.length; n++) { // Процент выплаты участникам + user = await UserModel.findByPk(business.users[n]) + piece = Math.round(profit / 100 * user.business.percent) + profitCheck -= piece + user.money += piece + text += `➕ ${user.username} получает ₽${piece}\n` + await bot.telegram.sendMessage(user.telegram_id, `ℹ️ Директор организации сформировал выплаты.\n➕ На ваш баланс поступило: ₽${spaces(piece)}`) + giveExp(user, business.checks) + user.save() + } + if (profitCheck > 0) { + business.balance += profitCheck + text += `➕ На баланс бизнеса поступило ₽${profitCheck}` + } + business.checks = 0 + business.save() + console.log(`Payday: ${business.name}\n${text}`) + return await ctx.reply(text) +} \ No newline at end of file diff --git a/commands/organization/percentSet.js b/commands/organization/percentSet.js new file mode 100644 index 0000000..6ffdae3 --- /dev/null +++ b/commands/organization/percentSet.js @@ -0,0 +1,34 @@ +const { + UserModel, + BusinessModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + ctx.args = ctx.update.message.text.split(' ') + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id == 0) return await ctx.reply(`Вы не владеете организацией.`) + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + if (business === null) return await ctx.reply(`У вас нет организации.`) + if (!ctx.args[1] || !ctx.args[2]) return ctx.reply(`Не указан аргумент.`) + if (!Number(ctx.args[2])) return ctx.reply(`Процент должен быть числом от 1 до 100.`) + if (ctx.args[2] < 1 || ctx.args[2] > 100) return ctx.reply(`Минимальный процент 1 | Максимальный процент 100.`) + ctx.args[1] = ctx.args[1] + console.log(ctx.args) + let change = await UserModel.findOne({ + where: { + username: ctx.args[1] + } + }) + if (change === null) return await ctx.reply(`Нет такого игрока.`) + change.business = { + id: change.business.id, + checks: change.business.checks, + percent: ctx.args[2] + } + change.save() + return await ctx.reply(`Участнику ${change.username} установлен процент ${ctx.args[2]}`) +} \ No newline at end of file diff --git a/commands/organization/workoff.js b/commands/organization/workoff.js new file mode 100644 index 0000000..e4064ec --- /dev/null +++ b/commands/organization/workoff.js @@ -0,0 +1,71 @@ +const { + UserModel, + BusinessModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + spaces, + escape, + setCooldown +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + let business = await BusinessModel.findOne({ + where: { + owner: user.business.id.toString() + } + }) + if (user.business == null) return await ctx.reply(`Вы не работаете в организации.`) + let timer = user.worktime + let cooldown = setCooldown(user, 3600, timer) + if (user.worktime > cooldown.currentTime) return ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `📛 Работа в организации будет доступна через ${cooldown.timeLeftInMinutes} минут(у/ы)`, {show_alert: true}); + if (business.materials < 10) return ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `📛 В организации недостаточно материалов для отработки.`); + user.worktime = cooldown.endTime + user.business = { + id: user.business.id, + checks: user.business.checks + 1, + percent: user.business.percent + } + business.materials -= 10 + business.checks += 1 + await user.save() + await business.save() + if (business.owner == ctx.from.id){ + let text = `` + for (n = 0; n < business.users.length; n++) { // Процент выплаты участникам + users = await UserModel.findByPk(business.users[n]) + text += `${users.username} - ${users.business.checks} [${users.business.percent}%]\n` + } + return await ctx.editMessageText(`🏭 Ваша организация\n_${business.name}_\n💹 Баланс: ₽${escape(spaces(business.balance))}\n🧰 Сырье: ${business.materials} \n👥 Рабочих: ${business.users.length}\n🔨 Отработок: ${business.checks}\n${escape(text)}\n\nВаши отработки: ${user.business.checks}`, + { + reply_markup: { + inline_keyboard: [ + [{ + text: `📶 Отработка`, + callback_data: "workoff" + }, { + text: `💸 Payday`, + callback_data: "payday" + }] + ]}, + parse_mode: `MarkdownV2` + } + ) + }else{ + return await ctx.editMessageText(`🏭 Организация\n_${business.name}_\n💹 Баланс: ₽${escape(spaces(business.balance))}\n🧰 Сырье: ${business.materials}\n👥 Рабочих: ${business.users.length}\n\nВаши отработки: ${user.business.checks}`, + { + reply_markup: { + inline_keyboard: [ + [{ + text: `📶 Отработка`, + callback_data: "workoff" + }, { + text: `⬅️ Покинуть`, + callback_data: "покинуть" + }] + ]}, + parse_mode: `MarkdownV2` + } + ) + } +} \ No newline at end of file diff --git a/commands/pay.js b/commands/pay.js new file mode 100644 index 0000000..13c2016 --- /dev/null +++ b/commands/pay.js @@ -0,0 +1,35 @@ +const { + Telegraf +} = require('telegraf') +const bot = new Telegraf(process.env.BOT_TOKEN) +const { + UserModel, + WorldModel +} = require('../config') + +module.exports = async (ctx) => { + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1] || !ctx.args[2]) return ctx.reply(`/pay [Никнейм] [Сумма]`) + if (!Number(ctx.args[2])) return ctx.reply(`❕ Сумма должна быть числовая.`) + let sender = await UserModel.findByPk(ctx.from.id); + let receiver = await UserModel.findOne({ + where: { + username: ctx.args[1] + } + }); + let world = await WorldModel.findByPk(1) + let fee = Number(Math.trunc(ctx.args[2] / 100 * world.transactionfee)) + if (ctx.args[2] == 0 || ctx.args[2] < 100) return ctx.reply(`❕ Минимальная сумма перевода ₽100.`) + if (sender.money < ctx.args[2]) return ctx.reply(`❕ Недостаточно средств!`) + if (sender.money < Number(ctx.args[2]) + fee) return ctx.reply(`❕ Недостаточно средств для перевода с комиссией!`) + sender.money -= Number(ctx.args[2]) + sender.money -= Number(fee) + world.balance += Number(fee) + await sender.save(); + await world.save(); + receiver.money += Number(ctx.args[2]) + await receiver.save(); + let pmToReceiver = `🔽 Входящий перевод.\n\n🔼 Отправитель: ${sender.username}\n🆔 Отправителя: ${sender.telegram_id}\n🔢 Сумма: ₽${ctx.args[2]}\n🆕 Ваш баланс: ₽${receiver.money}` + bot.telegram.sendMessage(receiver.telegram_id, pmToReceiver) + return ctx.reply(`🔼 Исходящий перевод.\n\n🔽 Получатель: ${receiver.username}\n🆔 Получателя: ${receiver.telegram_id}\n🔢 Сумма: ₽${ctx.args[2]}\nℹ️ Комиссия: ₽${fee}\n🆕 Ваш баланс: ₽${sender.money}`) +} \ No newline at end of file diff --git a/commands/profile.js b/commands/profile.js new file mode 100644 index 0000000..dac1476 --- /dev/null +++ b/commands/profile.js @@ -0,0 +1,32 @@ +const { + UserModel, + PropertyModel, + expToUp +} = require('../config') +const { + spacesWithMarkdown, + escape +} = require('../utils') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id); + let property = await PropertyModel.findByPk(ctx.from.id); + if (!user) return ctx.reply(`Ошибка #1`); + return ctx.replyWithMarkdownV2(` + 👤${escape(user.username)} ${user.status == 'bronze' ? `\\[🔺\\]` : ""}${user.status == 'silver' ? `\\[🔹\\]` : ""}${user.status == 'gold' ? `\\[🔸\\]` : ""}${user.status == 'admin' ? "✅" : ""} + 🆔: ${ctx.from.id} + + 📶 Уровень: ${user.level} \\| ${user.exp} / ${expToUp[user.level]} + ⏩ Повышается за различные действия\\. + + 💰 Баланс + ₽${spacesWithMarkdown(user.money)} + + 🔵 Имущество + 🏠 Жилье: ${property.house == 0 ? "Бездомный" : property.house.name} + 🚗 Автомобиль: ${property.car == 0 ? "Пешком" : escape(property.car.name)} + 📱 Телефон: ${property.mobile == 0 ? "Нет" : property.mobile.name} + 🔫 Оружие: ${property.weapon == 0 ? "Безоружный" : property.weapon.name} + 🥼 Экипировка: ${property.equipment == 0 ? "Нет" : property.equipment.name} + `); +} \ No newline at end of file diff --git a/commands/promocodeActivate.js b/commands/promocodeActivate.js new file mode 100644 index 0000000..97c8c23 --- /dev/null +++ b/commands/promocodeActivate.js @@ -0,0 +1,34 @@ +const { + Telegraf +} = require('telegraf') +const bot = new Telegraf(process.env.BOT_TOKEN) +const { + UserModel, + PromocodeModel, + adminList +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + spaces +} = require('../utils') +const sequelize = require('../db'); + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1]) return ctx.reply(`/promocode [Code]`) + let promocode = await PromocodeModel.findOne({ + where: { + code: ctx.args[1] + } + }) + if(promocode === null) return await ctx.reply(`➖ Нет такого кода.`) + if(promocode.users.length-1 >= promocode.activations && promocode.users != null) return await ctx.reply(`⚠️ Промокод уже активировали максимальное количество раз.`) + if(promocode.users.includes(ctx.from.id.toString())) return await ctx.reply(`⚠️ Вы уже активировали этот промокод.`) + console.log(promocode.users) + promocode.users = sequelize.fn('array_append', sequelize.col('users'), ctx.from.id.toString()); + user.money += promocode.money + user.save() + promocode.save() + await bot.telegram.sendMessage(adminList[0], `${user.username} активировал промокод на ₽${spaces(promocode.money)}`) + return await ctx.reply(`✅ Вы активировали промокод на ₽${spaces(promocode.money)}`) +} \ No newline at end of file diff --git a/commands/property/hatkeisList.js b/commands/property/hatkeisList.js new file mode 100644 index 0000000..b536b71 --- /dev/null +++ b/commands/property/hatkeisList.js @@ -0,0 +1,18 @@ +const { + weaponshop +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + spaces, + escape, + weaponShopUpdate +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') + +module.exports = async (ctx) => { + let text = `[Hatkeis Gunsmith](https://telegra.ph/Hatkeis-Gunsmith-09-27)` + let shop = `\n Вы подходите к зданию с вывеской "Ништяки Хаткейса".\n Вот ассортимент на сегодня\n` + for (i = 0; i < 10; i++) { + shop += `${i}. ${weaponshop[i].name} (₽${spaces(weaponshop[i].price)})\n` + } + weaponShopUpdate() + return await ctx.replyWithMarkdownV2(text + escape(shop), {disable_web_page_preview: true}) +} \ No newline at end of file diff --git a/commands/property/propertyBuy.js b/commands/property/propertyBuy.js new file mode 100644 index 0000000..24d307a --- /dev/null +++ b/commands/property/propertyBuy.js @@ -0,0 +1,102 @@ +const { + weaponshop, + slots, + rarecars, + simplecars, + houses, + cars, + phones, + weapons, + equipment, + UserModel, + WorldModel, + JobModel, + PropertyModel, + BusinessModel, + ReportModel, + BlockModel, + PromocodeModel, + mainChat, + adminList, + expToUp, + topSym +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + spaces, + spacesWithMarkdown, + escape, + generatePromo, + generateVoucher, + getCurrentTime, + getSlot, + giveExp, + matPriceUpdate, + rand, + random, + setCooldown, + weaponShopUpdate, + stats +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') + +module.exports = async (ctx) => { + let data = ctx.update.callback_query.data; + data = JSON.parse(data) + let user = await UserModel.findByPk(ctx.from.id) + let property = await PropertyModel.findByPk(ctx.from.id); + let world = await WorldModel.findByPk(1) + if (data.type == "house") { + if (user.money < houses[data.value].price) return await ctx.reply(`У вас недостаточно средств!`) + if (property.house.name) return await ctx.reply(`У вас уже есть дом.`) + user.money -= houses[data.value].price + world.balance += houses[data.value].price + property.house = houses[data.value] + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы купили ${houses[data.value].name}`) + } + if (data.type == "car") { + if (user.money < cars[data.value].price) return await ctx.reply(`У вас недостаточно средств!`) + if (property.car.name) return await ctx.reply(`У вас уже есть автомобиль.`) + if (!property.house.name) return await ctx.reply(`Для покупки автомобиля, у Вас должен быть дом.`) + user.money -= cars[data.value].price + world.balance += cars[data.value].price + property.car = cars[data.value] + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы купили ${cars[data.value].name}`) + } + if (data.type == "phone") { + if (user.money < phones[data.value].price) return await ctx.reply(`У вас недостаточно средств!`) + if (property.mobile.name) return await ctx.reply(`У вас уже есть телефон.`) + user.money -= phones[data.value].price + world.balance += phones[data.value].price + property.mobile = phones[data.value] + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы купили ${phones[data.value].name}`) + } + if (data.type == "equipment") { + if (user.money < weaponshop[data.value].price) return await ctx.reply(`У вас недостаточно средств!`) + if (data.type == weaponshop[data.value].type) { + if (property.equipment.name) return await ctx.reply(`У вас уже есть экипировка.`) + user.money -= weaponshop[data.value].price + world.balance += weaponshop[data.value].price + property.equipment = weaponshop[data.value] + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы купили ${weaponshop[data.value].name}`) + } + if (property.weapon.name) return await ctx.reply(`У вас уже есть оружие.`) + user.money -= weaponshop[data.value].price + world.balance += weaponshop[data.value].price + property.weapon = weaponshop[data.value] + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы купили ${weaponshop[data.value].name}`) + } +} \ No newline at end of file diff --git a/commands/property/propertyList.js b/commands/property/propertyList.js new file mode 100644 index 0000000..65fd12a --- /dev/null +++ b/commands/property/propertyList.js @@ -0,0 +1,42 @@ +const { + Markup +} = require('telegraf') +const { + houses, + cars, + phones +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + let data = ctx.update.callback_query.data; + let prodArray = [] + let text = `Доступно к покупке:\n` + switch(data){ + case `shop_house`: + for (i in houses) { + prodArray.push({text: i, callback_data: `{"action": "buy", "type": "house", "value": "${i}"}`}) + text += i + `. ${houses[i].name} (₽${houses[i].price})\n` + } + break; + case `shop_phone`: + for (i in phones) { + prodArray.push({text: i, callback_data: `{"action": "buy", "type": "phone", "value": "${i}"}`}) + text += i + `. ${phones[i].name} (₽${phones[i].price})\n` + } + break; + case `shop_car`: + for (i in cars) { + prodArray.push({text: i, callback_data: `{"action": "buy", "type": "car", "value": "${i}"}`}) + text += i + `. ${cars[i].name} (₽${cars[i].price})\n` + } + break; + } + prodArray.push({text: `Назад`, callback_data: `shopmenu`}) + let rows = [] + while (prodArray.length > 0) { + rows.push(prodArray.splice(0, 5)) // разбиваем на подмассивы по 5 кнопок + } + return await ctx.editMessageText(text, Markup + .inlineKeyboard(rows) + .resize()) +} \ No newline at end of file diff --git a/commands/property/propertyMenu.js b/commands/property/propertyMenu.js new file mode 100644 index 0000000..e123a32 --- /dev/null +++ b/commands/property/propertyMenu.js @@ -0,0 +1,19 @@ +const { + Markup +} = require('telegraf') +const { + UserModel +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id); + return await ctx.reply(`Выберите тип`, Markup + .inlineKeyboard([ + [ + {text: 'Жилье', callback_data: `shop_house`}, + {text: 'Телефоны', callback_data: `shop_phone`}, + {text: 'Автосалон', callback_data: `shop_car`} + ] + ]) + .resize()) +} \ No newline at end of file diff --git a/commands/property/propertySell.js b/commands/property/propertySell.js new file mode 100644 index 0000000..a76c40e --- /dev/null +++ b/commands/property/propertySell.js @@ -0,0 +1,102 @@ +const { + weaponshop, + slots, + rarecars, + simplecars, + houses, + cars, + phones, + weapons, + equipment, + UserModel, + WorldModel, + JobModel, + PropertyModel, + BusinessModel, + ReportModel, + BlockModel, + PromocodeModel, + mainChat, + adminList, + expToUp, + topSym +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + spaces, + spacesWithMarkdown, + escape, + generatePromo, + generateVoucher, + getCurrentTime, + getSlot, + giveExp, + matPriceUpdate, + rand, + random, + setCooldown, + weaponShopUpdate, + stats +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') + +module.exports = async (ctx) => { + ctx.args = ctx.update.message.text.split(' ') + let user = await UserModel.findByPk(ctx.from.id) + let property = await PropertyModel.findByPk(ctx.from.id); + let world = await WorldModel.findByPk(1) + if (!ctx.args[1]) return ctx.reply(`Не указан аргумент.`) + if (ctx.args[1] == "house") { + if (!property.house.name) return await ctx.reply(`У вас нет дома.`) + let name = property.house.name + user.money += Math.round(property.house.price/2) + world.balance -= Math.round(property.house.price/2) + property.house = 0 + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы продали ${name}`) + } + if (ctx.args[1] == "car") { + if (!property.car.name) return await ctx.reply(`У вас нет автомобиля.`) + let name = property.car.name + user.money += Math.round(property.car.price/2) + world.balance -= Math.round(property.car.price/2) + property.car = 0 + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы продали ${name}`) + } + if (ctx.args[1] == "phone") { + if (!property.mobile.name) return await ctx.reply(`У вас нет телефона.`) + let name = property.mobile.name + user.money += Math.round(property.mobile.price/2) + world.balance -= Math.round(property.mobile.price/2) + property.mobile = 0 + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы продали ${name}`) + } + if (ctx.args[1] == "equipment") { + if (!property.equipment.name) return await ctx.reply(`У вас нет экипировки.`) + let name = property.equipment.name + user.money += Math.round(property.equipment.price/2) + world.balance -= Math.round(property.equipment.price/2) + property.equipment = 0 + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы продали ${name}`) + } + if (ctx.args[1] == "weapon") { + if (!property.weapon.name) return await ctx.reply(`У вас нет оружия.`) + let name = property.weapon.name + user.money += Math.round(property.weapon.price/2) + world.balance -= Math.round(property.weapon.price/2) + property.weapon = 0 + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы продали ${name}`) + } +} \ No newline at end of file diff --git a/commands/report.js b/commands/report.js new file mode 100644 index 0000000..9a66601 --- /dev/null +++ b/commands/report.js @@ -0,0 +1,31 @@ +const { + Telegraf, + Markup +} = require('telegraf') +const bot = new Telegraf(process.env.BOT_TOKEN) +const { + UserModel, + ReportModel, + adminList +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const shortid = require('shortid'); + +module.exports = async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1]) return ctx.reply(`/report [Текст обращения]`) + let uID = shortid.generate() + await ReportModel.create({ + uid: uID, + author: user.telegram_id, + text: ctx.payload, + status: 1 + }) + let report = await ReportModel.findOne({ + where: { + uid: uID + } + }) + await bot.telegram.sendMessage(adminList[0], `Обращение от пользователя ${user.username}\nТекст обращения:\n${ctx.payload}\n\nДля ответа /answer ${report.id} [Ответ]`) + return await ctx.reply(`Обращение #${report.id}[${report.uid}] создано.`) +} \ No newline at end of file diff --git a/commands/scratch.js b/commands/scratch.js new file mode 100644 index 0000000..f9e1f6f --- /dev/null +++ b/commands/scratch.js @@ -0,0 +1,7 @@ +const { createCanvas, loadImage } = require('canvas'); +const fs = require('fs'); + +module.exports = async (ctx) => { + + +} \ No newline at end of file diff --git a/commands/top.js b/commands/top.js new file mode 100644 index 0000000..952ae57 --- /dev/null +++ b/commands/top.js @@ -0,0 +1,30 @@ +const { + UserModel, + topSym +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const { + spaces +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/utils') +const sequelize = require('../db'); +const { Op } = require('sequelize'); + +module.exports = async (ctx) => { + let topPlayer = await UserModel.findAll({ + attributes: ['name', [sequelize.fn('sum', sequelize.col('money')), 'money'], 'status'], + group: ['name', 'status'], + where: { + telegram_id: { + [Op.ne]: 275416286 + } + }, + order: [ + [sequelize.literal('money'), 'DESC'] + ], + limit: 10 + }) + let text = `🏆 Топ 10 игроков по балансу.\n\n` + for(i=0; i { + let world = await WorldModel.findByPk(1) + return ctx.reply(`🔰 Баланс мира: ₽${spaces(world.balance)}\nℹ️ Стоимость материалов: ₽${spaces(world.matPrice)} + `) +} \ No newline at end of file diff --git a/config/imports.js b/config/imports.js new file mode 100644 index 0000000..734e28a --- /dev/null +++ b/config/imports.js @@ -0,0 +1,48 @@ + +const testScene = require("../scenes/test"); +const weaponshop = require('../json/weaponshop.json') +const slots = require('../json/slots.json') +const rarecars = require('../json/rarecars.json') +const simplecars = require('../json/simplecars.json') +const houses = require('../presets/houses.json') +const cars = require('../presets/cars.json') +const phones = require('../presets/mobiles.json') +const weapons = require('../presets/weapons.json') +const equipment = require('../presets/equipment.json') +const UserModel = require('../models/user.model'); +const WorldModel = require('../models/world.model'); +const JobModel = require('../models/job.model'); +const PropertyModel = require('../models/property.model'); +const BusinessModel = require('../models/business.model'); +const ReportModel = require('../models/report.model'); +const BlockModel = require('../models/block.model'); +const PromocodeModel = require('../models/promocode.model'); +const mainChat = -1001895132127 +const adminList = [275416286] +const expToUp = [0, 10, 20, 40, 60, 100, 250, 370, 450, 575, 666, 777, 860, 999, 1000, 1177, 1234, 1350, 1488, 1515, 1610] +const topSym = ['🥇', '🥈', '🥉', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟'] + +module.exports = [ + testScene, + weaponshop, + slots, + rarecars, + simplecars, + houses, + cars, + phones, + weapons, + equipment, + UserModel, + WorldModel, + JobModel, + PropertyModel, + BusinessModel, + ReportModel, + BlockModel, + PromocodeModel, + mainChat, + adminList, + expToUp, + topSym +] \ No newline at end of file diff --git a/config/index.js b/config/index.js new file mode 100644 index 0000000..3e8a5e5 --- /dev/null +++ b/config/index.js @@ -0,0 +1,26 @@ +module.exports = { + testScene : require("../scenes/test"), + weaponshop : require('../json/weaponshop.json'), + slots : require('../json/slots.json'), + rarecars : require('../json/rarecars.json'), + simplecars : require('../json/simplecars.json'), + houses : require('../presets/houses.json'), + cars : require('../presets/cars.json'), + phones : require('../presets/mobiles.json'), + weapons : require('../presets/weapons.json'), + equipment : require('../presets/equipment.json'), + UserModel : require('../models/user.model'), + WorldModel : require('../models/world.model'), + JobModel : require('../models/job.model'), + PropertyModel : require('../models/property.model'), + BusinessModel : require('../models/business.model'), + ReportModel : require('../models/report.model'), + BlockModel : require('../models/block.model'), + PromocodeModel : require('../models/promocode.model'), + mainChat : -1001895132127, + adminList : [275416286], + expToUp : [0, 10, 20, 40, 60, 100, 250, 370, 450, 575, 666, 777, 860, 999, 1000, 1177, 1234, 1350, 1488, 1515, 1610], + topSym : ['🥇', '🥈', '🥉', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟'], + promoTopicId: 1807, + gameTopicId: 1808 +} \ No newline at end of file diff --git a/ctxconfig.json b/ctxconfig.json new file mode 100644 index 0000000..4f51ceb --- /dev/null +++ b/ctxconfig.json @@ -0,0 +1,14 @@ +{ + "mainAdminId": 275416286, + "logChatId": -1001948614034, + "stickerLinkPrefix": "t.me/addstickers/", + "emojiLinkPrefix": "t.me/addemoji/", + "charTitleMax": 35, + "premiumCharTitleMax": 64, + "messaging": { + "limit": { + "max": 20, + "duration": 1500 + } + } + } \ No newline at end of file diff --git a/ecosystem.config.js b/ecosystem.config.js new file mode 100644 index 0000000..44ac232 --- /dev/null +++ b/ecosystem.config.js @@ -0,0 +1,15 @@ +module.exports = { + apps: [{ + name: 'CampFireGame', + script: './index.js', + max_memory_restart: '4000M', + watch: true, + cron_restart: '0 */6 * * *', // restart every 6 hours + env: { + NODE_ENV: 'development' + }, + env_production: { + NODE_ENV: 'production' + } + }] + } \ No newline at end of file diff --git a/handlers/catch.js b/handlers/catch.js new file mode 100644 index 0000000..7004ead --- /dev/null +++ b/handlers/catch.js @@ -0,0 +1,54 @@ +const util = require('util') +const exec = util.promisify(require('child_process').exec) +const errorStackParser = require('error-stack-parser') +const { escapeHTML } = require('../utils') + +async function errorLog (error, ctx) { + const errorInfo = errorStackParser.parse(error) + + let gitBlame + + for (const ei of errorInfo) { + if (!gitBlame) gitBlame = await exec(`git blame -L ${ei.lineNumber},${ei.lineNumber} -- ${ei.fileName}`).catch(() => {}) + } + + let errorText = `error for ${ctx.updateType}:` + if (ctx.match) errorText += `\n${ctx.match[0]}` + if (ctx.from && ctx.from.id) errorText += `\n\nuser: ${escapeHTML(ctx.from.first_name)} #user_${ctx.from.id}` + if (ctx?.session?.chainActions && ctx?.session.chainActions.length > 0) errorText += '\n\n🔗 ' + ctx?.session.chainActions.map(v => `${v}`).join(' ➜ ') + + if (gitBlame && !gitBlame.stderr) { + const parsedBlame = gitBlame.stdout.match(/^(?[0-9a-f]+)\s+\((?.+)(?\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [+-]\d{4}\s+)(?\d+)\) ?(?.*)$/m) + + errorText += `\n\n${parsedBlame.groups.USER.trim()}` + errorText += `\ncommit: ${parsedBlame.groups.SHA}` + errorText += `\n\n${parsedBlame.groups.code}` + } + + errorText += `\n\n\n${escapeHTML(error.stack)}` + + if (error.description && error.description.includes('timeout')) return + + if (!ctx.config) return console.error(errorText) + + await ctx.telegram.sendMessage(ctx.config.logChatId, errorText, { + parse_mode: 'HTML' + }).catch((error) => { + console.error('send log error:', error) + }) + + if (ctx?.chat?.type === 'private') { + await ctx.replyWithHTML((` + Произошла неизвестная ошибка. + Вероятно, о ней уже известно администратору, но вы всё равно можете дополнительно сообщить последовательность, которая привела к ошибке => @Degradin. + Пожалуйста, сразу подробно опишите проблему в одном сообщении, можно приложить скрин.`)).catch(() => {}) + } +} + +module.exports = async (error, ctx) => { + console.error(error) + + errorLog(error, ctx).catch(e => { + console.error('errorLog error:', e) + }) +} \ No newline at end of file diff --git a/handlers/index.js b/handlers/index.js new file mode 100644 index 0000000..8bc5213 --- /dev/null +++ b/handlers/index.js @@ -0,0 +1,3 @@ +module.exports = { + handleError: require('./catch') +} \ No newline at end of file diff --git a/index backup.js b/index backup.js new file mode 100644 index 0000000..6748358 --- /dev/null +++ b/index backup.js @@ -0,0 +1,1763 @@ +require('dotenv').config() +const { + Telegraf, + Markup +} = require('telegraf') +const shortid = require('shortid'); +const voucher_codes = require('voucher-code-generator'); +const { createCanvas, loadImage } = require('canvas'); +const fs = require('fs') +const bot = new Telegraf(process.env.BOT_TOKEN) +const weaponshop = require('./json/weaponshop.json') +const slots = require('./json/slots.json') +const rarecars = require('./json/rarecars.json') +const simplecars = require('./json/simplecars.json') +const houses = require('./presets/houses.json') +const cars = require('./presets/cars.json') +const phones = require('./presets/mobiles.json') +const weapons = require('./presets/weapons.json') +const equipment = require('./presets/equipment.json') +const sequelize = require('./db'); +const { Op } = require('sequelize'); +const UserModel = require('./models/user.model'); +const WorldModel = require('./models/world.model'); +const JobModel = require('./models/job.model'); +const PropertyModel = require('./models/property.model'); +const BusinessModel = require('./models/business.model'); +const ReportModel = require('./models/report.model'); +const BlockModel = require('./models/block.model'); +const PromocodeModel = require('./models/promocode.model'); +const mainChat = -1001895132127 +const adminList = [275416286] +const expToUp = [0, 10, 20, 40, 60, 100, 250, 370, 450, 575, 666, 777, 860, 999, 1000, 1177, 1234, 1350, 1488, 1515, 1610] +const topSym = ['🥇', '🥈', '🥉', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟'] + +const start = async () => { + try { + await sequelize.authenticate() + await sequelize.sync() + } catch (e) { + console.log('Подключение к бд сломалось', e) + } +} + +bot.telegram.setMyCommands([{ + command: "pay", + description: "Перевести указанному пользователю сумму." + }, + { + command: "buy", + description: "Приобрести указанное имущество." + }, + { + command: "business", + description: "Создать организацию." + }, + { + command: "invite", + description: "Пригласить пользователя в организацию." + }, + { + command: "percent", + description: "Установить пользователю процент заработка." + }, + { + command: "report", + description: "Создать жалобу/обращение/идею." + } +]) + +bot.use(async (ctx, next) => { + let id = ctx.from.id + let username = ctx.from.username + if(username == null) username = ctx.from.id + try { + console.log(getCurrentTime() + `: ` + username + `: ` + ctx.update.message.text) + } catch (e) { + console.log(getCurrentTime() + `: ${username}: ${ctx.update.callback_query.data}`) + } + let user = await UserModel.findByPk(id); + let block = await BlockModel.findByPk(id); + let property = await PropertyModel.findByPk(id); + if (!user) ctx.reply(`❕ Первичная регистрация профиля.`); + if (user === null) { + await UserModel.create({ + telegram_id: id, + username: username, + name: ctx.from.first_name + }) + } else { + user.name = ctx.from.first_name + if(user.username === null) user.username = ctx.from.id + user.save() + } + if (property === null) { + await PropertyModel.create({ + telegram_id: id + }) + } else {} + //if (whitelist.includes(id) == false) return ctx.reply(`У вас пока нет доступа к боту. Следите за обновлениями в группе: t.me/CampFireGameBotNews`) + if (block !== null) { + if (block.isBlocked == true && block.time > Date.now() / 1000) return ctx.reply(`📛 У вас активная блокировка по причине: ${block.reason}.\n⏲️ Оставшееся время: ${Math.trunc((block.time - Date.now()/1000)/60)} мин.`) + block.isBlocked = false + block.save() + } + const start = Date.now() + return next().then(() => { + const ms = Date.now() - start + console.log('response time %sms', ms) + }) +}) + +bot.command('start', async (ctx) => { + if (ctx.payload) { + let id = ctx.from.id + let user = await UserModel.findByPk(id); + if (user.level == 1) { + let ref = await UserModel.findByPk(ctx.payload) + let world = await WorldModel.findByPk(1) + world.balance -= 25000 + ref.money += Number(25000) + await ref.save() + await world.save() + bot.telegram.sendMessage(ref.telegram_id, `${ctx.from.username} зарегистрировался по вашей реферальной ссылке. Получено ¤25.000`) + console.log("Transaction to Ref") + } else { + console.log("Exist") + } + } + return await ctx.reply('Главное меню', Markup + .keyboard([ + ['😎 Профиль'], // Row1 with 2 buttons + ['🗄️ Работать', '🌐 Организация', '🎁 Бонус', '🏯 Казино'], // Row2 with 2 buttons + ['📦 Контейнеры'], + ['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'] // Row3 with 3 buttons + ]) + .resize() + ) +}) + +bot.hears('▶️ Меню', async (ctx) => { + return await ctx.reply('Main Menu', Markup + .keyboard([ + ['😎 Профиль'], + ['🗄️ Работать', '🌐 Организация', '🎁 Бонус', '🏯 Казино'], + ['📦 Контейнеры'], + ['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'] + ]) + .resize() + ) +}); + +bot.hears('Чат', async (ctx) => { + ctx.telegram.sendMessage(mainChat, `Automatic message`) +}); + +bot.hears('😎 Профиль', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id); + let property = await PropertyModel.findByPk(ctx.from.id); + if (!user) return ctx.reply(`Ошибка #1`); + return ctx.replyWithMarkdownV2(` + 👤${escape(user.username)} ${user.status == 'bronze' ? `\\[🔺\\]` : ""}${user.status == 'silver' ? `\\[🔹\\]` : ""}${user.status == 'gold' ? `\\[🔸\\]` : ""}${user.status == 'admin' ? "✅" : ""} + 🆔: ${ctx.from.id} + + 📶 Уровень: ${user.level} \\| ${user.exp} / ${expToUp[user.level]} + ⏩ Повышается за различные действия\\. + + 💰 Баланс + ¤${spacesWithMarkdown(user.money)} + + 🔵 Имущество + 🏠 Жилье: ${property.house == 0 ? "Бездомный" : property.house.name} + 🚗 Автомобиль: ${property.car == 0 ? "Пешком" : escape(property.car.name)} + 📱 Телефон: ${property.mobile == 0 ? "Нет" : property.mobile.name} + 🔫 Оружие: ${property.weapon == 0 ? "Безоружный" : property.weapon.name} + 🥼 Экипировка: ${property.equipment == 0 ? "Нет" : property.equipment.name} + `); + +}); + +bot.command('getprofile', async (ctx) => { + if(!ctx.message.reply_to_message) return await ctx.reply(`Только на пересланное сообщение.`) + let id = ctx.message.reply_to_message.from.id + let user = await UserModel.findByPk(id); + let property = await PropertyModel.findByPk(id); + return ctx.replyWithMarkdownV2(` + 👤${escape(user.username)} ${user.status == 'bronze' ? `\\[🔺\\]` : ""}${user.status == 'silver' ? `\\[🔹\\]` : ""}${user.status == 'gold' ? `\\[🔸\\]` : ""}${user.status == 'admin' ? "Administrator" : ""} + 🆔: ${ctx.from.id} + + 📶 Уровень: ${user.level} \\| ${user.exp} / ${expToUp[user.level]} + ⏩ Повышается за различные действия\\. + + 💰 Баланс + ¤${spacesWithMarkdown(user.money)} + + 🔵 Имущество + 🏠 Жилье: ${property.house == 0 ? "Бездомный" : property.house.name} + 🚗 Автомобиль: ${property.car == 0 ? "Пешком" : property.car.name} + 📱 Телефон: ${property.mobile == 0 ? "Нет" : property.mobile.name} + 🔫 Оружие: ${property.weapon == 0 ? "Безоружный" : property.weapon.name} + 🥼 Экипировка: ${property.equipment == 0 ? "Нет" : property.equipment.name} + `); + +}); + +bot.hears('Рандом', async (ctx) => { + let users = await UserModel.findAll(); + let chosenOne = users.random() + return ctx.reply(` + 👤 ${chosenOne.username} + 🆔: ${chosenOne.telegram_id} + `); + +}); + +bot.hears('💳 Баланс', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id); + return ctx.reply(` + ⏩ Аккаунт игрока ${user.username} + 🆔 Игрока: ${user.telegram_id} + + 📶 Уровень: ${user.level} + ⏩ Повышается за различные действия. + + 💰 Баланс: + ¤${user.money} + `); +}) + +bot.hears('🎁 Бонус', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id); + if (!user) return ctx.reply(`Ошибка #1`); + let bonustime = user.bonustime + let cooldown = setCooldown(user, 3600, bonustime) + if (user.bonustime > cooldown.currentTime) return ctx.reply(`📛 Забрать бонус можно будет через ${cooldown.timeLeftInMinutes} минут(у/ы)`); + user.bonus = 1; + user.bonustime = cooldown.endTime + let world = await WorldModel.findByPk(1) + let text = ``; + let money = [100, 200, 300, 400, 500, 1000].random(); + if (user.level >= 5) { + money += money; + } + let r = rand(1, 2); + let x = rand(2, 7); + if (r == 1) { + text += `⏩ ¤${money}\n`; + } + if (r == 2) { + money = money*x + text += `⏩ ¤${money}\n`; + } + switch(user.status){ + case 'bronze': + user.money += 5000 + text += `⭐ Дополнительный бонус за Bronze:\n⏩ ¤5.000\n` + break; + case 'silver': + user.money += 15000 + text += `⭐ Дополнительный бонус за Silver:\n⏩ ¤15.000\n` + break; + case 'gold': + user.money += 30000 + text += `⭐ Дополнительный бонус за Gold:\n⏩ ¤30.000\n` + break; + } + user.money += money; + world.balance -= money + if (user.business.id == 0){ + await user.save(); + await world.save(); + return ctx.reply(` + ⭐ Из ежечасного бонуса Вам выпало: +${text} + `) + } + let business = await BusinessModel.findOne({ + where: { + owner: user.business.id + } + }) + if(business != null){ + let mats = rand(3, 10) + switch(user.status){ + case 'bronze': + business.materials += 5 + text += `⭐ Дополнительный бонус за Bronze:\n⏩ 5 материалов\n` + break; + case 'silver': + business.materials += 10 + text += `⭐ Дополнительный бонус за Silver:\n⏩ 10 материалов\n` + break; + case 'gold': + business.materials += 20 + text += `⭐ Дополнительный бонус за Gold:\n⏩ 20 материалов\n` + break; + } + text += `⏩ ${mats} материалов в организацию\n` + business.materials += mats + business.save() + } + await user.save(); + await world.save(); + return ctx.reply(` + ⭐ Из ежечасного бонуса Вам выпало: +${text} + `) +}) + +bot.command('pay', async (ctx) => { + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1] || !ctx.args[2]) return ctx.reply(`/pay [Никнейм] [Сумма]`) + if (!Number(ctx.args[2])) return ctx.reply(`❕ Сумма должна быть числовая.`) + let sender = await UserModel.findByPk(ctx.from.id); + let receiver = await UserModel.findOne({ + where: { + username: ctx.args[1] + } + }); + let world = await WorldModel.findByPk(1) + let fee = Number(Math.trunc(ctx.args[2] / 100 * world.transactionfee)) + if (ctx.args[2] == 0 || ctx.args[2] < 100) return ctx.reply(`❕ Минимальная сумма перевода ¤100.`) + if (sender.money < ctx.args[2]) return ctx.reply(`❕ Недостаточно средств!`) + if (sender.money < Number(ctx.args[2]) + fee) return ctx.reply(`❕ Недостаточно средств для перевода с комиссией!`) + sender.money -= Number(ctx.args[2]) + sender.money -= Number(fee) + world.balance += Number(fee) + await sender.save(); + await world.save(); + receiver.money += Number(ctx.args[2]) + await receiver.save(); + let pmToReceiver = `🔽 Входящий перевод.\n\n🔼 Отправитель: ${sender.username}\n🆔 Отправителя: ${sender.telegram_id}\n🔢 Сумма: ¤${ctx.args[2]}\n🆕 Ваш баланс: ¤${receiver.money} + ` + bot.telegram.sendMessage(receiver.telegram_id, pmToReceiver) + return ctx.reply(`🔼 Исходящий перевод.\n\n🔽 Получатель: ${receiver.username}\n🆔 Получателя: ${receiver.telegram_id}\n🔢 Сумма: ¤${ctx.args[2]}\nℹ️ Комиссия: ¤${fee}\n🆕 Ваш баланс: ¤${sender.money} + `) +}) + +bot.hears('Мир', async (ctx) => { + let world = await WorldModel.findByPk(1) + return ctx.reply(`🔰 Баланс мира: ¤${spaces(world.balance)}\nℹ️ Стоимость материалов: ¤${spaces(world.matPrice)} + `) +}) + +bot.hears('📞 Пригласить', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id); + return ctx.reply(` + ℹ️ Для приглашения друга по реферальной системе, отправьте ему ссылку-приглашение +Как только он перейдет по ней и начнет игру, Вы получите ¤25.000. + +Ваша ссылка: https://t.me/CampFireGameBot?start=${user.telegram_id} + `) +}) + +bot.hears('📢 Вакансии', async (ctx) => { + return await ctx.reply('Список работы', Markup + .inlineKeyboard([ + [{ + text: `Дворник [1 уровень]`, + callback_data: 'job_1' + }, { + text: `Промоутер [1 уровень]`, + callback_data: 'job_2' + }], [{ + text: `Официант [2 уровень]`, + callback_data: 'job_3' + }, { + text: `Бармен [3 уровень]`, + callback_data: 'job_4' + }], [{ + text: `Кассир [4 уровень] `, + callback_data: 'job_5' + }, { + text: `ПВЗ Дикие Ягоды [4 уровень]`, + callback_data: 'job_6' + }], [{ + text: `Слесарь [5 уровень]`, + callback_data: 'job_7' + }], [{ + text: `💤 Уволиться`, + callback_data: 'job_leave' + }] + ]) + .resize() + ) +}) + +bot.action(/job_(1|2|3|4|5|6|7|leave)/, async (ctx) => { + let data = ctx.update.callback_query.data; + let user = await UserModel.findByPk(ctx.from.id); + let job = null + switch(data){ + case `job_1`: + job = await JobModel.findByPk(1); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 1 + user.save() + return await ctx.reply(`ℹ️ Вы устроились на работу дворником.\nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`❕ Вы уже устроены на другую работу`) + case `job_2`: + job = await JobModel.findByPk(2); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 2 + user.save() + return await ctx.reply(`ℹ️ Вы устроились на работу промоутером. \nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`❕ Вы уже устроены на другую работу`) + case `job_3`: + job = await JobModel.findByPk(3); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 3 + user.save() + return await ctx.reply(`ℹ️ Вы устроились на работу официантом. \nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`❕ Вы уже устроены на другую работу`) + case `job_4`: + job = await JobModel.findByPk(4); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 4 + user.save() + return await ctx.reply(`ℹ️ Вы устроились на работу барменом. \nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`❕ Вы уже устроены на другую работу`) + case `job_5`: + job = await JobModel.findByPk(5); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 5 + user.save() + return await ctx.reply(`❕ Вы устроились на работу кассиром. \nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`ℹ️ Вы уже устроены на другую работу`) + case `job_6`: + job = await JobModel.findByPk(6); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 6 + user.save() + return await ctx.reply(`ℹ️ Вы устроились на работу в ПВЗ Дикие Ягоды. \nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`❕ Вы уже устроены на другую работу`) + case `job_7`: + job = await JobModel.findByPk(7); + if (user.level < job.level) { + return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) + } + if (user.job == 0) { + user.job = 7 + user.save() + return await ctx.reply(`ℹ️ Вы устроились на работу слесарем. \nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) + } + return await ctx.reply(`❕ Вы уже устроены на другую работу`) + case `job_leave`: + if (user.job != 0) { + user.job = 0 + user.save() + return await ctx.reply(`ℹ️ Теперь вы безработный.`) + } + return await ctx.reply(`❕ Вы итак безработный.`) + } +}) + +bot.hears('🏯 Казино', async (ctx) => { + return await ctx.reply('🏯 Добро пожаловать в казино "杜明"\n', Markup + .keyboard([ + ['🎰 Слоты'], + ['▶️ Меню'] + ]) + .resize() + ) +}) + +bot.hears('🗄️ Работать', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id); + let job = await JobModel.findByPk(user.job); + let world = await WorldModel.findByPk(1) + let timer = user.jobtime + let cooldown = setCooldown(user, 3600, timer) + if (user.jobtime > cooldown.currentTime) return ctx.reply(`📛 Работать можно будет через ${cooldown.timeLeftInMinutes} минут(у/ы)`); + if (user.job == 0) { + return await ctx.reply(`📛 Вы безработный.`) + } + user.jobtime = Number(cooldown.endTime) + let jobExp = job.exp; + user.jobcheck++ + switch (user.job) { + case 1: + if (user.jobcheck >= 4) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + world.balance -= payday + user.money += payday + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену дворника. \n🧾 Расчетный лист: \n⏳ Отработано часов: 4/4 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday}`) + } else { + user.save() + return ctx.reply(`👔 Вы подмели дворы. \n⏳ Отработано часов: ${user.jobcheck}/4`) + } + break; + case 2: + if (user.jobcheck >= 2) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + world.balance -= payday + user.money += payday + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену промоутера. \n🧾 Расчетный лист: \n⏳ Отработано часов: 2/2 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday}`) + } else { + user.save() + return ctx.reply(`👔 Вы раздавали листовки целый час. \n⏳ Отработано часов: ${user.jobcheck}/2`) + } + break; + case 3: + if (user.jobcheck >= 4) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + world.balance -= payday + let tips = [50, 100, 200, 500, 1000].random() + user.money += tips + user.money += payday + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену официанта. \n🧾 Расчетный лист: \n⏳ Отработано часов: 4/4 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday} \n💰 Получено чаевых: ¤${tips}`) + } else { + let tips = [50, 100, 200, 500, 1000].random() + user.money += tips + user.save() + return ctx.reply(`👔 Вы целый час бегали и отрабатывали заказы. \n🧾 Получено чаевых: ¤${tips} \n⏳ Отработано часов: ${user.jobcheck}/4`) + } + break; + case 4: + if (user.jobcheck >= 5) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + world.balance -= payday + let tips = [50, 100, 200, 300, 500, 1000, 2000].random() + world.balance -= tips + user.money += tips + user.money += payday + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену бармена. \n🧾 Расчетный лист: \n⏳ Отработано часов: 5/5 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday} \n💰 Получено чаевых: ¤${tips}`) + } else { + let tips = [50, 100, 200, 300, 500, 1000, 2000].random() + world.balance -= tips + user.money += tips + user.save() + world.save() + return ctx.reply(`👔 Вы целый час стояли за стойкой и разливали пойло. \n🧾 Получено чаевых: ¤${tips} \n⏳ Отработано часов: ${user.jobcheck}/5`) + } + break; + case 5: + if (user.jobcheck >= 5) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + world.balance -= payday + user.money += payday + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену кассира. \n🧾 Расчетный лист: \n⏳ Отработано часов: 5/5 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday}`) + } else { + user.save() + return ctx.reply(`👔 Вы целый час обслуживали покупателей и кричали: "Гаааляяя, отмена!". \n⏳ Отработано часов: ${user.jobcheck}/5`) + } + break; + case 6: + if (user.jobcheck >= 6) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + let stealed = [{ + name: "Помада", + price: 200 + }, { + name: "Бюстгалтер", + price: 1300 + }, { + name: "Прокладки", + price: 250 + }, { + name: "Перцовый балончик", + price: 600 + }, { + name: "Гитара", + price: 6500 + }, { + name: "Комбик", + price: 9000 + }, { + name: "Кроссовки", + price: 2000 + }, { + name: "Шампунь", + price: 180 + }, { + name: "Смартфон Texno", + price: 6999 + }, { + name: "TWS Гарнитура", + price: 2800 + }, { + name: "Геймпад GameStation 5", + price: 1400 + }, { + name: "Дилдо", + price: 600 + }, { + name: "Вагиноимитатор", + price: 600 + }].random() + world.balance -= payday + world.balance -= Number(stealed.price) + user.money += payday + user.money += Number(stealed.price) + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену в Диких Ягодах. \n🧾 Расчетный лист: \n⏳ Отработано часов: 6/6 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday} \n💰 Вы украли и продали со склада: ${stealed.name} (¤${stealed.price})`) + } else { + user.save() + return ctx.reply(`👔 Вы целый час выдавали заказы в Диких Ягодах. \n⏳ Отработано часов: ${user.jobcheck}/6`) + } + break; + case 7: + if (user.jobcheck >= 6) { + let paydayfee = job.salary / 100 * world.transactionfee + let payday = job.salary - paydayfee + world.balance -= payday + user.money += payday + giveExp(user, jobExp) + user.jobcheck = 0 + user.save() + world.save() + return ctx.reply(`👔 Вы отработали смену слесарем. \n🧾 Расчетный лист: \n⏳ Отработано часов: 6/6 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday}`) + } else { + user.save() + return ctx.reply(`👔 Вы целый час работали на заводе, вы молодец! \n⏳ Отработано часов: ${user.jobcheck}/6`) + } + break; + } +}) + +bot.hears('Топ', async (ctx) => { + let topPlayer = await UserModel.findAll({ + attributes: ['username', [sequelize.fn('sum', sequelize.col('money')), 'money'], 'status'], + group: ['username', 'status'], + where: { + telegram_id: { + [Op.ne]: 275416286 + } + }, + order: [ + [sequelize.literal('money'), 'DESC'] + ], + limit: 10 + }) + let text = `🏆 Топ 10 игроков по балансу.\n\n` + for(i=0; i { + let user = await UserModel.findByPk(ctx.from.id); + return await ctx.reply(`Выберите тип`, Markup + .inlineKeyboard([ + [ + {text: 'Жилье', callback_data: `shop_house`}, + {text: 'Телефоны', callback_data: `shop_phone`}, + {text: 'Автосалон', callback_data: `shop_car`} + ] + ]) + .resize()) +}) + +bot.action('shopmenu', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id); + return await ctx.editMessageText(`Выберите тип`, Markup + .inlineKeyboard([ + [ + {text: 'Жилье', callback_data: `shop_house`}, + {text: 'Телефоны', callback_data: `shop_phone`}, + {text: 'Автосалон', callback_data: `shop_car`} + ] + ]) + .resize()) +}) + +bot.action(/shop_(house|phone|car)/, async (ctx) => { + let data = ctx.update.callback_query.data; + let prodArray = [] + let text = `Доступно к покупке:\n` + switch(data){ + case `shop_house`: + for (i in houses) { + prodArray.push({text: i, callback_data: `{"action": "buy", "type": "house", "value": "${i}"}`}) + text += i + `. ${houses[i].name} (¤${houses[i].price})\n` + } + break; + case `shop_phone`: + for (i in phones) { + prodArray.push({text: i, callback_data: `{"action": "buy", "type": "phone", "value": "${i}"}`}) + text += i + `. ${phones[i].name} (¤${phones[i].price})\n` + } + break; + case `shop_car`: + for (i in cars) { + prodArray.push({text: i, callback_data: `{"action": "buy", "type": "car", "value": "${i}"}`}) + text += i + `. ${cars[i].name} (¤${cars[i].price})\n` + } + break; + } + prodArray.push({text: `Назад`, callback_data: `shopmenu`}) + let rows = [] + while (prodArray.length > 0) { + rows.push(prodArray.splice(0, 5)) // разбиваем на подмассивы по 5 кнопок + } + return await ctx.editMessageText(text, Markup + .inlineKeyboard(rows) + .resize()) +}) + +bot.action(/{"action": "buy"*/, async (ctx) => { + let data = ctx.update.callback_query.data; + data = JSON.parse(data) + let user = await UserModel.findByPk(ctx.from.id) + let property = await PropertyModel.findByPk(ctx.from.id); + let world = await WorldModel.findByPk(1) + if (data.type == "house") { + if (user.money < houses[data.value].price) return await ctx.reply(`У вас недостаточно средств!`) + if (property.house.name) return await ctx.reply(`У вас уже есть дом.`) + user.money -= houses[data.value].price + world.balance += houses[data.value].price + property.house = houses[data.value] + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы купили ${houses[data.value].name}`) + } + if (data.type == "car") { + if (user.money < cars[data.value].price) return await ctx.reply(`У вас недостаточно средств!`) + if (property.car.name) return await ctx.reply(`У вас уже есть автомобиль.`) + if (!property.house.name) return await ctx.reply(`Для покупки автомобиля, у Вас должен быть дом.`) + user.money -= cars[data.value].price + world.balance += cars[data.value].price + property.car = cars[data.value] + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы купили ${cars[data.value].name}`) + } + if (data.type == "phone") { + if (user.money < phones[data.value].price) return await ctx.reply(`У вас недостаточно средств!`) + if (property.mobile.name) return await ctx.reply(`У вас уже есть телефон.`) + user.money -= phones[data.value].price + world.balance += phones[data.value].price + property.mobile = phones[data.value] + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы купили ${phones[data.value].name}`) + } + if (data.type == "equipment") { + if (user.money < weaponshop[data.value].price) return await ctx.reply(`У вас недостаточно средств!`) + if (data.type == weaponshop[data.value].type) { + if (property.equipment.name) return await ctx.reply(`У вас уже есть экипировка.`) + user.money -= weaponshop[data.value].price + world.balance += weaponshop[data.value].price + property.equipment = weaponshop[data.value] + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы купили ${weaponshop[data.value].name}`) + } + if (property.weapon.name) return await ctx.reply(`У вас уже есть оружие.`) + user.money -= weaponshop[data.value].price + world.balance += weaponshop[data.value].price + property.weapon = weaponshop[data.value] + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы купили ${weaponshop[data.value].name}`) + } +}) + +bot.hears('Поставщик', async (ctx) => { + let text = `[Hatkeis Gunsmith](https://telegra.ph/Hatkeis-Gunsmith-09-27)` + let shop = `\n Вы подходите к зданию с вывеской "Ништяки Хаткейса".\n Вот ассортимент на сегодня\n` + for (i = 0; i < 10; i++) { + shop += `${i}. ${weaponshop[i].name} (¤${spaces(weaponshop[i].price)})\n` + } + weaponShopUpdate() + return await ctx.replyWithMarkdownV2(text + escape(shop), {disable_web_page_preview: true}) +}) + +bot.command('sell', async (ctx) => { + ctx.args = ctx.update.message.text.split(' ') + let user = await UserModel.findByPk(ctx.from.id) + let property = await PropertyModel.findByPk(ctx.from.id); + let world = await WorldModel.findByPk(1) + if (!ctx.args[1]) return ctx.reply(`Не указан аргумент.`) + if (ctx.args[1] == "house") { + if (!property.house.name) return await ctx.reply(`У вас нет дома.`) + let name = property.house.name + user.money += Math.round(property.house.price/2) + world.balance -= Math.round(property.house.price/2) + property.house = 0 + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы продали ${name}`) + } + if (ctx.args[1] == "car") { + if (!property.car.name) return await ctx.reply(`У вас нет автомобиля.`) + let name = property.car.name + user.money += Math.round(property.car.price/2) + world.balance -= Math.round(property.car.price/2) + property.car = 0 + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы продали ${name}`) + } + if (ctx.args[1] == "phone") { + if (!property.mobile.name) return await ctx.reply(`У вас нет телефона.`) + let name = property.mobile.name + user.money += Math.round(property.mobile.price/2) + world.balance -= Math.round(property.mobile.price/2) + property.mobile = 0 + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы продали ${name}`) + } + if (ctx.args[1] == "equipment") { + if (!property.equipment.name) return await ctx.reply(`У вас нет экипировки.`) + let name = property.equipment.name + user.money += Math.round(property.equipment.price/2) + world.balance -= Math.round(property.equipment.price/2) + property.equipment = 0 + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы продали ${name}`) + } + if (ctx.args[1] == "weapon") { + if (!property.weapon.name) return await ctx.reply(`У вас нет оружия.`) + let name = property.weapon.name + user.money += Math.round(property.weapon.price/2) + world.balance -= Math.round(property.weapon.price/2) + property.weapon = 0 + await user.save() + await world.save() + await property.save() + return await ctx.reply(`Вы продали ${name}`) + } +}) + +bot.hears('🌐 Организация', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id == 0) return await ctx.reply(`Вы не состоите в организации.`) + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + if(business === null){ + business = await BusinessModel.findOne({ + where: { + owner: user.business.id + } + }) + return await ctx.replyWithMarkdownV2(`🏭 Организация\n_${business.name}_\n💹 Баланс: ¤${escape(spaces(business.balance))}\n🧰 Сырье: ${business.materials}\n👥 Рабочих: ${business.users.length}\n\nВаши отработки: ${user.business.checks}`, Markup.inlineKeyboard([ + [{ + text: `📶 Отработка`, + callback_data: "workoff" + }, { + text: `⬅️ Покинуть`, + callback_data: "покинуть" + }] + ]) + .oneTime() + .resize()) + } + if (business.owner == ctx.from.id){ + return await ctx.replyWithMarkdownV2(`🏭 Ваша организация\n_${business.name}_\n💹 Баланс: ¤${escape(spaces(business.balance))}\n🧰 Сырье: ${business.materials}\n👥 Рабочих: ${business.users.length}\n🔨 Отработок: ${business.checks}\n\nВаши отработки: ${user.business.checks}`, Markup.inlineKeyboard([ + [{ + text: `📶 Отработка`, + callback_data: "workoff" + }, { + text: `💸 Payday`, + callback_data: "payday" + }] + ]) + .oneTime() + .resize()) + } +}) + +bot.action('workoff', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + let business = await BusinessModel.findOne({ + where: { + owner: user.business.id.toString() + } + }) + if (user.business == null) return await ctx.reply(`Вы не работаете в организации.`) + let timer = user.worktime + let cooldown = setCooldown(user, 3600, timer) + if (user.worktime > cooldown.currentTime) return ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `📛 Работа в организации будет доступна через ${cooldown.timeLeftInMinutes} минут(у/ы)`, {show_alert: true}); + if (business.materials < 10) return ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `📛 В организации недостаточно материалов для отработки.`); + user.worktime = cooldown.endTime + user.business = { + id: user.business.id, + checks: user.business.checks + 1, + percent: user.business.percent + } + business.materials -= 10 + business.checks += 1 + await user.save() + await business.save() + if (business.owner == ctx.from.id){ + return await ctx.editMessageText(`🏭 Ваша организация\n_${business.name}_\n💹 Баланс: ¤${escape(spaces(business.balance))}\n🧰 Сырье: ${business.materials} \n👥 Рабочих: ${business.users.length}\n🔨 Отработок: ${business.checks}\n\nВаши отработки: ${user.business.checks}`, + { + reply_markup: { + inline_keyboard: [ + [{ + text: `📶 Отработка`, + callback_data: "workoff" + }, { + text: `💸 Payday`, + callback_data: "payday" + }] + ]}, + parse_mode: `MarkdownV2` + } + ) + }else{ + return await ctx.editMessageText(`🏭 Организация\n_${business.name}_\n💹 Баланс: ¤${escape(spaces(business.balance))}\n🧰 Сырье: ${business.materials}\n👥 Рабочих: ${business.users.length}\n\nВаши отработки: ${user.business.checks}`, + { + reply_markup: { + inline_keyboard: [ + [{ + text: `📶 Отработка`, + callback_data: "workoff" + }, { + text: `⬅️ Покинуть`, + callback_data: "покинуть" + }] + ]}, + parse_mode: `MarkdownV2` + } + ) + } +}) + +bot.action('покинуть', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id == 0) return await ctx.reply(`Вы не состоите в организации.`) + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + if(business === null){ + business = await BusinessModel.findOne({ + where: { + owner: user.business.id + } + }) + await ctx.reply(`Подтвердите в личных сообщениях.`) + return await bot.telegram.sendMessage(ctx.from.id, `🏭 Вы действительно хотите покинуть ${business.name}`, Markup.inlineKeyboard([ + [{ + text: `Да`, + callback_data: "user_leave_business" + }, { + text: `Нет`, + callback_data: "cancel" + }] + ]) + .oneTime() + .resize() + ) + } + if (business.owner == ctx.from.id){ + return await ctx.reply(`Вы не можете покинуть свою организацию.`) + } +}) + +bot.action('cancel', async (ctx) => { + await ctx.deleteMessage() + await bot.telegram.answerCbQuery(ctx.callbackQuery.id, `Отмена.`) +}) + +bot.action('user_leave_business', async (ctx) => { + let data = ctx.update.callback_query.data; + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id == 0) return await ctx.reply(`Вы не состоите в организации.`) + let business = await BusinessModel.findOne({ + where: { + owner: user.business.id + } + }) + user.business = { + id: 0, + checks: 0, + percent: 0 + } + business.users = business.users.filter(value => value != ctx.from.id); + business.save() + user.save() + return await bot.telegram.sendMessage(ctx.from.id, `🏭 Вы покинули ${business.name}`) +}) + +bot.action('payday', async (ctx) => { + let user = null + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + let world = await WorldModel.findByPk(1) + if (business === null) return await ctx.reply(`У вас нет организации.`) + if (business.checks < 12) return await ctx.reply(`Недостаточно отработок для формирования выплаты.`) + let percentSum = 0 + let text = `` + let percentErrorText = `` + let profit = 0 + let piece = 0 + let moneyList = rand(1000, 3000) + moneyList = moneyList*business.users.length + for (i = 0; i < business.users.length; i++) { // Summary percent + user = await UserModel.findByPk(business.users[i]) + percentSum += Number(user.business.percent) + percentErrorText += `ℹ️ ${user.username} ${user.business.percent}% [/percent ${user.username} [проценты]]\n` + } + if (percentSum > 100) return await ctx.reply(`⚠️ Общий процент всех сотрудников превышает 100%\n ➕ Остаток процентов перенесется в баланс организации.\n\n${percentErrorText}\n`) + for (x = 0; x < business.users.length; x++) { // Общая внесенная сумма всеми участниками + user = await UserModel.findByPk(business.users[x]) + profit += user.business.checks * moneyList * user.level + text += `ℹ️ ${user.username} отработал ${user.business.checks} раз.\n` + user.business = { + id: user.business.id, + checks: 0, + percent: user.business.percent + } + user.save() + } + text += ` 💹 Наработка за текущий период: ${profit}\n` + let profitCheck = profit + for (n = 0; n < business.users.length; n++) { // Процент выплаты участникам + user = await UserModel.findByPk(business.users[n]) + piece = Math.round(profit / 100 * user.business.percent) + profitCheck -= piece + user.money += piece + text += `➕ ${user.username} получает ¤${piece}\n` + await bot.telegram.sendMessage(user.telegram_id, `ℹ️ Директор организации сформировал выплаты.\n➕ На ваш баланс поступило: ${spaces(piece)}`) + giveExp(user, business.checks) + user.save() + } + if (profitCheck > 0) { + business.balance += profitCheck + text += `➕ На баланс бизнеса поступило ¤${profitCheck}` + } + business.checks = 0 + business.save() + console.log(`Payday: ${business.name}\n${text}`) + return await ctx.reply(text) +}) + +bot.command('orgmessage', async (ctx) => { + if (!ctx.args[1]) return ctx.reply(`Не указан аргумент.`) + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + if (business === null) return await ctx.reply(`У вас нет организации.`) + for (i = 0; i < business.users.length; i++) { + user = await UserModel.findByPk(business.users[i]) + await bot.telegram.sendMessage(user.telegram_id, `Директор организации сообщает:\n ${ctx.payload}`) + } + console.log(`Директор организации сообщает:\n ${ctx.payload}`) + return await ctx.reply(`Сообщение отправлено.`) +}) + +bot.command('materials', async (ctx) => { + ctx.args = ctx.update.message.text.split(' ') + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id == 0) return await ctx.reply(`🚫 Вы не владеете организацией.`) + let world = await WorldModel.findByPk(1) + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + if (business === null) return await ctx.reply(`🚫 У вас нет организации.`) + if (!ctx.args[1]) return ctx.reply(`🚫 Не указан аргумент.`) + if (!Number(ctx.args[1])) return ctx.reply(`ℹ️ Количество должно быть числом.`) + if (ctx.args[1] < 1) return ctx.reply(`ℹ️ Минимальное количество для покупки - 1`) + if (ctx.args[1]*world.matPrice > business.balance) return ctx.reply(`🚫 Недостаточно средств на балансе организации.`) + if (business.materials >= 700) return ctx.reply(`🚫 Склады полны.`) + if (business.materials + Number(ctx.args[1]) > 700) return ctx.reply(`🚫 Нет столько места на складах.\n Можно закупить еще ${700 - business.materials}`) + let count = Number(ctx.args[1]) + business.balance -= world.matPrice*count + business.materials += count + business.save() + return await ctx.reply(`➕ Закуплено ${ctx.args[1]} материалов для организации на сумму ¤${world.matPrice*count}`) +}) + +bot.command('percent', async (ctx) => { + ctx.args = ctx.update.message.text.split(' ') + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id == 0) return await ctx.reply(`Вы не владеете организацией.`) + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + if (business === null) return await ctx.reply(`У вас нет организации.`) + if (!ctx.args[1] || !ctx.args[2]) return ctx.reply(`Не указан аргумент.`) + if (!Number(ctx.args[2])) return ctx.reply(`Процент должен быть числом от 1 до 100.`) + if (ctx.args[2] < 1 || ctx.args[2] > 100) return ctx.reply(`Минимальный процент 1 | Максимальный процент 100.`) + ctx.args[1] = ctx.args[1] + console.log(ctx.args) + let change = await UserModel.findOne({ + where: { + username: ctx.args[1] + } + }) + if (change === null) return await ctx.reply(`Нет такого игрока.`) + change.business = { + id: change.business.id, + checks: change.business.checks, + percent: ctx.args[2] + } + change.save() + return await ctx.reply(`Участнику ${change.username} установлен процент ${ctx.args[2]}`) +}) + +bot.command('business', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id != 0){ + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + } + let business = null + let world = await WorldModel.findByPk(1) + ctx.args = ctx.update.message.text.split(' ') + if (business != null) return await ctx.reply(`У вас уже есть организация.`) + if (!ctx.args[1]) return ctx.reply(`/business [Название организации]`) + if (user.money < 100000) return await ctx.reply(`Регистрация организации стоит ¤100.000`) + if (user.level < 5) return await ctx.reply(`Регистрация организации доступна с 5 уровня.`) + user.money -= 100000 + world.balance += 100000 + let text = `` + for (i = 1; i < ctx.args.length; i++) { + text += `${ctx.args[i]} ` + } + if (business === null) { + BusinessModel.create({ + name: text, + owner: user.telegram_id, + balance: 50000, + users: [user.telegram_id] + }) + user.business = { + id: user.telegram_id, + checks: 0, + percent: 100 + } + } else {} + user.save() + world.save() + return await ctx.reply(`Организация "${text}" успешно создана!\n Регистрация организации в реестре: ¤50.000 \n Капитал: ¤50.000`) +}) + +bot.command('invite', async (ctx) => { + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1]) return ctx.reply(`/invite [Nick]`) + let user = await UserModel.findByPk(ctx.from.id) + if (user.business.id == 0) return await ctx.reply(`🚫 У вас нет организации в которую можно пригласить игрока.`) + let business = await BusinessModel.findOne({ + where: { + owner: ctx.from.id.toString() + } + }) + if (business.users.length >= 5) return await ctx.reply(`📛 Достигнуто максимальное количество сотрудников в организации.`) + let invited = await UserModel.findOne({ + where: { + username: ctx.args[1] + } + }); + await bot.telegram.sendMessage(invited.telegram_id, '⤵️ Приглашение', Markup + .inlineKeyboard([ + [{ + text: `Принять`, + callback_data: `{"type": "business_invite_accept", "invitor": "${user.telegram_id}"}` + }, { + text: `Отклонить`, + callback_data: `{"type": "business_invite_refuse", "invitor": "${user.telegram_id}"}` + }] + ]).oneTime()) + return await ctx.reply(`Приглашение отправлено.`) +}) + +bot.action(/{"type": "business_invite_(accept|refuse)"*/, async ctx => { + let data = ctx.update.callback_query.data; + data = JSON.parse(data) + let user = await UserModel.findByPk(ctx.update.callback_query.from.id) + if (data.type == 'business_invite_accept') { + if(user.business.id == 0){ + let business = await BusinessModel.findOne({ + where: { + owner: data.invitor + } + }) + user.business = { + id: data.invitor, + checks: 0, + percent: 10 + } + business.users = sequelize.fn('array_append', sequelize.col('users'), ctx.update.callback_query.from.id); + business.save() + user.save() + await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `✔️ Приглашение принято.`, {show_alert: true}) + } + await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `ℹ️ Вы уже в организации.`, {show_alert: true}) + } + if (data.type == 'business_invite_refuse'){ + await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `❌ Приглашение отклонено.`, {show_alert: true}) + } +}) + +bot.command('report', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1]) return ctx.reply(`/report [Текст обращения]`) + let uID = shortid.generate() + await ReportModel.create({ + uid: uID, + author: user.telegram_id, + text: ctx.payload, + status: 1 + }) + let report = await ReportModel.findOne({ + where: { + uid: uID + } + }) + await bot.telegram.sendMessage(adminList[0], `Обращение от пользователя ${user.username}\nТекст обращения:\n${ctx.payload}\n\nДля ответа /answer ${report.id} [Ответ]`) + return await ctx.reply(`Обращение #${report.id}[${report.uid}] создано.`) +}) + +bot.hears('🎰 Слоты', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + ctx.args = ctx.update.message.text.split(' ') + await ctx.reply('Комбинации слотов:\n7️⃣7️⃣7️⃣ - x25\n🍋🍋🍋 - x20\n🍇🍇🍇 - x15\n🔤🔤🔤 - x10', Markup + .inlineKeyboard([ + [{ + text: `1000`, + callback_data: `slots1000` + }, { + text: `5000`, + callback_data: `slots5000` + }, { + text: `25000`, + callback_data: `slots25000` + }, { + text: `50000`, + callback_data: `slots50000` + }, { + text: `100000`, + callback_data: `slots100000` + }] + ])) +}) + +bot.action(/slots(1000|5000|25000|50000|100000)/, async (ctx) => { + let data = ctx.update.callback_query.data; + let bet = 1000 + switch(data){ + case `slots1000`: + bet = 1000 + break; + case `slots5000`: + bet = 5000 + break; + case `slots25000`: + bet = 25000 + break; + case `slots50000`: + bet = 50000 + break; + case `slots100000`: + bet = 100000 + break; + } + let user = await UserModel.findByPk(ctx.from.id) + let timer = user.slottime + let cooldown = setCooldown(user, 10, timer) + if (user.slottime > cooldown.currentTime) return ctx.reply(`📛 Слоты будут доступны через пару секунд`); + if (user.money < bet) return ctx.reply(`Недостаточно средств.`) + user.slottime = cooldown.endTime + let world = await WorldModel.findByPk(1) + let result = await ctx.replyWithDice({emoji: `🎰`}) + let slot = slots[result.dice.value] + let win = getSlot(result) + console.log(user.username + `: Win: x` + win) + user.money -= bet + world.balance += bet + if(win > 4){ + user.world -= bet*win + user.money += bet*win + user.save() + world.save() + return setTimeout(() => { + ctx.reply(`➕ Вы выиграли ¤${spaces(bet*win)}`) + }, 1700); + } + if(win > 0 && win <= 4){ + await giveExp(user, win*2) + return setTimeout(() => { + ctx.reply(`➕ Вы выиграли ${win*2} опыта.`) + }, 1700); + } + if(win == 0){ + return setTimeout(() => { + world.save() + user.save() + ctx.reply(`➖ Вы проиграли ¤${spaces(bet)}.`) + }, 1700); + } + +}) + +bot.hears('Помощь', async (ctx) => { + return await ctx.replyWithMarkdownV2(`• [Функционал](https://telegra.ph/CampFire-Bot-Info-09-25)\n• [Правила](https://telegra.ph/PRAVILA-BOTA-09-25)`, { + disable_web_page_preview: true + }) +}) + +bot.command('promocode', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1]) return ctx.reply(`/promocode [Code]`) + let promocode = await PromocodeModel.findOne({ + where: { + code: ctx.args[1] + } + }) + if(promocode === null) return await ctx.reply(`➖ Нет такого кода.`) + if(promocode.users.length-1 >= promocode.activations && promocode.users != null) return await ctx.reply(`⚠️ Промокод уже активировали максимальное количество раз.`) + if(promocode.users.includes(ctx.from.id.toString())) return await ctx.reply(`⚠️ Вы уже активировали этот промокод.`) + console.log(promocode.users) + promocode.users = sequelize.fn('array_append', sequelize.col('users'), ctx.from.id.toString()); + user.money += promocode.money + user.save() + promocode.save() + await bot.telegram.sendMessage(adminList[0], `${user.username} активировал промокод.`) + return await ctx.reply(`✅ Вы активировали промокод.`) +}) + +bot.hears('📦 Контейнеры', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + let containers = [] + let superWin = rarecars.random() + let values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + let oneValue = [] + for(i = 0; i < 10; i++){ + oneValue = values.random() + values = values.filter(value => value != oneValue); + containers.push({name: `📦 Контейнер ${i+1}`, value: oneValue}) + } + let keyboardButtons = containers.map(container => { + return {text: container.name, callback_data: `container_${container.value}`} + }) + let rows = [] + while (keyboardButtons.length > 0) { + rows.push(keyboardButtons.splice(0, 2)) // разбиваем на подмассивы по 5 кнопок + } + await ctx.replyWithMarkdownV2('[Sueta Logistic International](https://telegra.ph/OOO-Sueta-Logistic-International-09-27)\nДоступные контейнеры в порту:', + { + reply_markup: { + inline_keyboard: rows + }, + disable_web_page_preview: true + }) +}) + + +bot.action(/container_(1|2|3|4|5|6|7|8|9|10)/, async (ctx) => { + let data = ctx.update.callback_query.data; + let user = await UserModel.findByPk(ctx.from.id) + let property = await PropertyModel.findByPk(ctx.from.id) + if(user.money < 500000) return ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `Открытие контейнера стоит ¤500.000`, {show_alert: true}) + if(property.car.name) return ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас уже есть автомобиль\nПродайте текущий автомобиль: /sell car`, {show_alert: true}) + user.money -= 500000 + let userWin = null + switch(data){ + case `container_7`: + userWin = rarecars.random() + break; + default: + userWin = simplecars.random() + break; + } + property.car = userWin + user.save() + property.save() + ctx.deleteMessage() + return await ctx.sendPhoto(userWin.image, { caption: `В контейнере была: ${userWin.name} стоимостью ¤${spaces(userWin.price)}`}) +}) + +bot.action(/{"action": "sueta_*/, async (ctx) => { + let data = ctx.update.callback_query.data; + data = JSON.parse(data) + console.log(data.car) + let user = await UserModel.findByPk(ctx.from.id) + let property = await PropertyModel.findByPk(ctx.from.id) + switch(data.action){ + case `sueta_accept`: + user.money += data.carprice + await ctx.editMessageText(`➕ ${data.carprice}`) + break; + case `sueta_refuse`: + user.money += Math.round(property.car.price/2) + property.car = { + name: data.carname, + price: data.carprice + } + await ctx.editMessageText(`➕ ${data.carname}`) + break; + } + user.save() + property.save() +}) +/////////////////////////////////////Admin Commands////////////////////////////////////////////////// + + +bot.command('answer', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if(user.status != 'admin') return await ctx.reply(`Admin Only.`) + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1]) return ctx.reply(`Нужен номер обращения`) + let report = await ReportModel.findByPk(ctx.args[1]) + if (report === null) return await ctx.reply(`Нет обращения с таким ID.`) + if (report.status == 0) return await ctx.reply(`Данное обращение уже закрыто.`) + let answer = ctx.args + answer.shift() + answer.shift() + answer = answer.join(' ') + await bot.telegram.sendMessage(report.author, `Ответ на обращение #${report.id}[${report.uid}]\n\n` + answer) + report.status = 0 + report.save() + return await ctx.reply(`Ответ отправлен, обращение закрыто!`) +}) + +bot.command('fastblock', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if(!ctx.message.reply_to_message) return await ctx.reply(`Только на пересланное сообщение.`) + let blocked = ctx.message.reply_to_message.from.id + if(user.status != 'admin') return await ctx.reply(`Admin Only.`) + await BlockModel.create({ + telegram_id: blocked, + isBlocked: true, + reason: `|AutoFastBlock|`, + time: Math.trunc(Date.now() / 1000 + 3600) + }) + await bot.telegram.sendMessage(blocked, `Вы были заблокированы администратором ${user.username}.`) + return await ctx.reply(`Пользователь заблокирован.`) +}) + +bot.command('createpromocode', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if(user.status != 'admin') return await ctx.reply(`Admin Only.`) + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1] || !ctx.args[2] || !ctx.args[3]) return ctx.reply(`/createpromo [activations] [money] [code]`) + let promocode = await PromocodeModel.findOne({ + where: { + code: ctx.args[3] + } + }) + if(promocode === null){ + await PromocodeModel.create({ + code: ctx.args[3], + activations: ctx.args[1], + money: ctx.args[2] + }) + let voucherImage = await generateVoucher(ctx.args[3], ctx.args[1], ctx.args[2]) + return await ctx.sendPhoto({source: voucherImage, caption: `Создан промокод ${ctx.args[3]}` }) +} +}) + +bot.command('genpromo', async (ctx) => { + let user = await UserModel.findByPk(ctx.from.id) + if(user.status != 'admin') return await ctx.reply(`Admin Only.`) + ctx.args = ctx.update.message.text.split(' ') + if (!ctx.args[1] || !ctx.args[2]) return ctx.reply(`/genpromo [activations] [money]`) + let code = voucher_codes.generate({ + length: 6, + count: 1, + prefix: "CMP-", + postfix: "-FIRE", + charset: voucher_codes.charset("alphanumeric") + }); + let promocode = await PromocodeModel.findOne({ + where: { + code: code[0] + } + }) + if(promocode === null){ + await PromocodeModel.create({ + code: code[0], + activations: ctx.args[1], + money: ctx.args[2] + }) + let voucherImage = await generateVoucher(code, ctx.args[1], ctx.args[2]) + return await ctx.sendPhoto({source: voucherImage, caption: `Создан промокод ${code[0]}` }) +} +}) + +///////////////////////////////////////Functions////////////////////////////////////////////////////// + +function rand(min, max) { + return Math.round(Math.random() * (max - min)) + min +} +var parserInt = (str) => parseInt(str.replace(/k|к/ig, "000")); + +function spaces(string) { + if (typeof string !== "string") string = string.toString(); + return string.split("").reverse().join("").match(/[0-9]{1,3}/g).join(".").split("").reverse().join(""); +}; +function spacesWithMarkdown(string) { + if (typeof string !== "string") string = string.toString(); + return string.split("").reverse().join("").match(/[0-9]{1,3}/g).join(".\\").split("").reverse().join(""); +}; +function escape(text) { + text = text + .replace(/\_/g, '\\_') + .replace(/\*/g, '\\*') + .replace(/\[/g, '\\[') + .replace(/\]/g, '\\]') + .replace(/\(/g, '\\(') + .replace(/\)/g, '\\)') + .replace(/\~/g, '\\~') + .replace(/\`/g, '\\`') + .replace(/\>/g, '\\>') + .replace(/\#/g, '\\#') + .replace(/\+/g, '\\+') + .replace(/\-/g, '\\-') + .replace(/\=/g, '\\=') + .replace(/\|/g, '\\|') + .replace(/\{/g, '\\{') + .replace(/\}/g, '\\}') + .replace(/\./g, '\\.') + .replace(/\!/g, '\\!'); + return text +}; +Array.prototype.random = function() { + return this[Math.floor(this.length * Math.random())]; +} + +function getCurrentTime() { + const now = new Date(); + const year = now.getFullYear(); + const month = now.getMonth() < 9 ? `0${now.getMonth() + 1}` : now.getMonth() + 1; + const day = now.getDate() < 10 ? `0${now.getDate()}` : now.getDate(); + const hours = now.getHours() < 10 ? `0${now.getHours()}` : now.getHours(); + const minutes = now.getMinutes() < 10 ? `0${now.getMinutes()}` : now.getMinutes(); + const seconds = now.getSeconds() < 10 ? `0${now.getSeconds()}` : now.getSeconds(); + return `${day}.${month}.${year} ${hours}:${minutes}:${seconds}`; +} + +function getSlot(result) { + switch(result.dice.value){ + case 1: + return 10 + case 22: + return 15 + case 43: + return 20 + case 64: + return 25 + case 17: case 33: case 49: + return 1 + case 6: case 38: case 54: + return 2 + case 11: case 27: case 59: + return 3 + case 16: case 32: case 48: + return 4 + default: + return 0 +}} + +function setCooldown(user, seconds, type) { + let cooldown = {} + cooldown.currentTime = Math.trunc(Date.now() / 1000) + + switch(user.status){ + case `user`: + cooldown.endTime = Math.trunc(Date.now() / 1000 + seconds) + break; + case `bronze`: + cooldown.endTime = Math.trunc(Date.now() / 1000 + (seconds/100*85)) + break; + case `silver`: + cooldown.endTime = Math.trunc(Date.now() / 1000 + (seconds/100*75)) + break; + case `gold`: + cooldown.endTime = Math.trunc(Date.now() / 1000 + (seconds/100*50)) + break; + case `admin`: + cooldown.endTime = Math.trunc(Date.now() / 1000) + break; + } + cooldown.timeLeft = cooldown.endTime - cooldown.currentTime + cooldown.timeLeftInMinutes = Math.ceil((type - cooldown.currentTime) / 60) + return cooldown +} + +async function giveExp(user, experience) { + user.exp += experience + for(i in expToUp){ + if (user.exp >= expToUp[user.level]) { + user.exp -= expToUp[user.level] + user.level += 1 + user.save() + await bot.telegram.sendMessage(user.telegram_id, `⤴️ Ваш уровень повысился до ${user.level}!`)} + } + user.save() +} + +function weaponShopUpdate() { + let weaponId = [] + let equipId = [] + let drop = 1 + let counter = 5 + for (i = 0; i < 5; i++) { + drop = weaponId.push(rand(1, 10)) + } + for (i = 0; i < 5; i++) { + drop = equipId.push(rand(1, 10)) + } + for (i = 0; i < 5; i++) { + weaponshop[i] = weapons[weaponId[i]] + } + for (i = 0; i < 5; i++) { + weaponshop[counter] = equipment[equipId[i]] + counter++ + } + fs.writeFileSync('json/weaponshop.json', JSON.stringify(weaponshop, null, "\t")) +} + +async function matPriceUpdate() { + let world = await WorldModel.findByPk(1) + let price = rand(35, 170) + world.matPrice = price + world.save() +} + +setTimeout(() => { + generatePromo() +}, 360000*3); + +setInterval(() => { + var today = new Date(); + let hours = today.getHours(); + if (hours == "0" || hours == "12") { + weaponShopUpdate() + matPriceUpdate() + } +}, 360000); + +async function generatePromo() { + let activs = rand(1, 3) + let give = rand(1000, 10000) + let code = voucher_codes.generate({ + length: 6, + count: 1, + prefix: "CMP-", + postfix: "-FIRE", + charset: voucher_codes.charset("alphanumeric") + }); + let promocode = await PromocodeModel.findOne({ + where: { + code: code[0] + } + }) + if(promocode === null){ + await PromocodeModel.create({ + code: code[0], + activations: activs, + money: give + }) + let voucherImage = await generateVoucher(code[0], activs, give) + return await bot.telegram.sendPhoto(mainChat, {source: voucherImage}) +} +} + +async function generateVoucher(code, activations, money) { + // загружаем изображение фона + const background = await loadImage('./media/imageDefault3.png'); + + // создаем новый canvas + const canvas = createCanvas(background.width, background.height); + const ctx = canvas.getContext('2d'); + + // рисуем фоновое изображение + ctx.drawImage(background, 0, 0); + + // выводим текст на картинку + ctx.font = 'bold 30px Srbija Sans'; + ctx.fillStyle = '#232323'; + ctx.textAlign = 'center'; + ctx.fillText(`${code}`, canvas.width/2, canvas.height/1.90); + + // сохраняем картинку в файл + const out = fs.createWriteStream('./media/image.png'); + const stream = canvas.createPNGStream(); + stream.pipe(out); + + // возвращаем путь к сгенерированной картинке + return './media/image.png'; + } + +start() + +bot.launch() \ No newline at end of file diff --git a/index.js b/index.js index a54b701..a73d4ca 100644 --- a/index.js +++ b/index.js @@ -1,1763 +1,2 @@ require('dotenv').config() -const { - Telegraf, - Markup -} = require('telegraf') -const shortid = require('shortid'); -const voucher_codes = require('voucher-code-generator'); -const { createCanvas, loadImage } = require('canvas'); -const fs = require('fs') -const bot = new Telegraf(process.env.BOT_TOKEN) -const weaponshop = require('./json/weaponshop.json') -const slots = require('./json/slots.json') -const rarecars = require('./json/rarecars.json') -const simplecars = require('./json/simplecars.json') -const houses = require('./presets/houses.json') -const cars = require('./presets/cars.json') -const phones = require('./presets/mobiles.json') -const weapons = require('./presets/weapons.json') -const equipment = require('./presets/equipment.json') -const sequelize = require('./db'); -const { Op } = require('sequelize'); -const UserModel = require('./models/user.model'); -const WorldModel = require('./models/world.model'); -const JobModel = require('./models/job.model'); -const PropertyModel = require('./models/property.model'); -const BusinessModel = require('./models/business.model'); -const ReportModel = require('./models/report.model'); -const BlockModel = require('./models/block.model'); -const PromocodeModel = require('./models/promocode.model'); -const mainChat = -1001895132127 -const adminList = [275416286] -const expToUp = [0, 10, 20, 40, 60, 100, 250, 370, 450, 575, 666, 777, 860, 999, 1000, 1177, 1234, 1350, 1488, 1515, 1610] -const topSym = ['🥇', '🥈', '🥉', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟'] - -const start = async () => { - try { - await sequelize.authenticate() - await sequelize.sync() - } catch (e) { - console.log('Подключение к бд сломалось', e) - } -} - -bot.telegram.setMyCommands([{ - command: "pay", - description: "Перевести указанному пользователю сумму." - }, - { - command: "buy", - description: "Приобрести указанное имущество." - }, - { - command: "business", - description: "Создать организацию." - }, - { - command: "invite", - description: "Пригласить пользователя в организацию." - }, - { - command: "percent", - description: "Установить пользователю процент заработка." - }, - { - command: "report", - description: "Создать жалобу/обращение/идею." - } -]) - -bot.use(async (ctx, next) => { - let id = ctx.from.id - let username = ctx.from.username - if(username == null) username = ctx.from.id - try { - console.log(getCurrentTime() + `: ` + username + `: ` + ctx.update.message.text) - } catch (e) { - console.log(getCurrentTime() + `: ${username}: ${ctx.update.callback_query.data}`) - } - let user = await UserModel.findByPk(id); - let block = await BlockModel.findByPk(id); - let property = await PropertyModel.findByPk(id); - if (!user) ctx.reply(`❕ Первичная регистрация профиля.`); - if (user === null) { - await UserModel.create({ - telegram_id: id, - username: username, - name: ctx.from.first_name - }) - } else { - user.name = ctx.from.first_name - if(user.username === null) user.username = ctx.from.id - user.save() - } - if (property === null) { - await PropertyModel.create({ - telegram_id: id - }) - } else {} - //if (whitelist.includes(id) == false) return ctx.reply(`У вас пока нет доступа к боту. Следите за обновлениями в группе: t.me/CampFireGameBotNews`) - if (block !== null) { - if (block.isBlocked == true && block.time > Date.now() / 1000) return ctx.reply(`📛 У вас активная блокировка по причине: ${block.reason}.\n⏲️ Оставшееся время: ${Math.trunc((block.time - Date.now()/1000)/60)} мин.`) - block.isBlocked = false - block.save() - } - const start = Date.now() - return next().then(() => { - const ms = Date.now() - start - console.log('response time %sms', ms) - }) -}) - -bot.command('start', async (ctx) => { - if (ctx.payload) { - let id = ctx.from.id - let user = await UserModel.findByPk(id); - if (user.level == 1) { - let ref = await UserModel.findByPk(ctx.payload) - let world = await WorldModel.findByPk(1) - world.balance -= 25000 - ref.money += Number(25000) - await ref.save() - await world.save() - bot.telegram.sendMessage(ref.telegram_id, `${ctx.from.username} зарегистрировался по вашей реферальной ссылке. Получено ¤25.000`) - console.log("Transaction to Ref") - } else { - console.log("Exist") - } - } - return await ctx.reply('Главное меню', Markup - .keyboard([ - ['😎 Профиль'], // Row1 with 2 buttons - ['🗄️ Работать', '🌐 Организация', '🎁 Бонус', '🏯 Казино'], // Row2 with 2 buttons - ['📦 Контейнеры'], - ['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'] // Row3 with 3 buttons - ]) - .resize() - ) -}) - -bot.hears('▶️ Меню', async (ctx) => { - return await ctx.reply('Main Menu', Markup - .keyboard([ - ['😎 Профиль'], - ['🗄️ Работать', '🌐 Организация', '🎁 Бонус', '🏯 Казино'], - ['📦 Контейнеры'], - ['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'] - ]) - .resize() - ) -}); - -bot.hears('Чат', async (ctx) => { - ctx.telegram.sendMessage(mainChat, `Automatic message`) -}); - -bot.hears('😎 Профиль', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id); - let property = await PropertyModel.findByPk(ctx.from.id); - if (!user) return ctx.reply(`Ошибка #1`); - return ctx.replyWithMarkdownV2(` - 👤${escape(user.username)} ${user.status == 'bronze' ? `\\[🔺\\]` : ""}${user.status == 'silver' ? `\\[🔹\\]` : ""}${user.status == 'gold' ? `\\[🔸\\]` : ""}${user.status == 'admin' ? "✅" : ""} - 🆔: ${ctx.from.id} - - 📶 Уровень: ${user.level} \\| ${user.exp} / ${expToUp[user.level]} - ⏩ Повышается за различные действия\\. - - 💰 Баланс - ¤${spacesWithMarkdown(user.money)} - - 🔵 Имущество - 🏠 Жилье: ${property.house == 0 ? "Бездомный" : property.house.name} - 🚗 Автомобиль: ${property.car == 0 ? "Пешком" : property.car.name} - 📱 Телефон: ${property.mobile == 0 ? "Нет" : property.mobile.name} - 🔫 Оружие: ${property.weapon == 0 ? "Безоружный" : property.weapon.name} - 🥼 Экипировка: ${property.equipment == 0 ? "Нет" : property.equipment.name} - `); - -}); - -bot.command('getprofile', async (ctx) => { - if(!ctx.message.reply_to_message) return await ctx.reply(`Только на пересланное сообщение.`) - let id = ctx.message.reply_to_message.from.id - let user = await UserModel.findByPk(id); - let property = await PropertyModel.findByPk(id); - return ctx.replyWithMarkdownV2(` - 👤${escape(user.username)} ${user.status == 'bronze' ? `\\[🔺\\]` : ""}${user.status == 'silver' ? `\\[🔹\\]` : ""}${user.status == 'gold' ? `\\[🔸\\]` : ""}${user.status == 'admin' ? "Administrator" : ""} - 🆔: ${ctx.from.id} - - 📶 Уровень: ${user.level} \\| ${user.exp} / ${expToUp[user.level]} - ⏩ Повышается за различные действия\\. - - 💰 Баланс - ¤${spacesWithMarkdown(user.money)} - - 🔵 Имущество - 🏠 Жилье: ${property.house == 0 ? "Бездомный" : property.house.name} - 🚗 Автомобиль: ${property.car == 0 ? "Пешком" : property.car.name} - 📱 Телефон: ${property.mobile == 0 ? "Нет" : property.mobile.name} - 🔫 Оружие: ${property.weapon == 0 ? "Безоружный" : property.weapon.name} - 🥼 Экипировка: ${property.equipment == 0 ? "Нет" : property.equipment.name} - `); - -}); - -bot.hears('Рандом', async (ctx) => { - let users = await UserModel.findAll(); - let chosenOne = users.random() - return ctx.reply(` - 👤 ${chosenOne.username} - 🆔: ${chosenOne.telegram_id} - `); - -}); - -bot.hears('💳 Баланс', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id); - return ctx.reply(` - ⏩ Аккаунт игрока ${user.username} - 🆔 Игрока: ${user.telegram_id} - - 📶 Уровень: ${user.level} - ⏩ Повышается за различные действия. - - 💰 Баланс: - ¤${user.money} - `); -}) - -bot.hears('🎁 Бонус', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id); - if (!user) return ctx.reply(`Ошибка #1`); - let bonustime = user.bonustime - let cooldown = setCooldown(user, 3600, bonustime) - if (user.bonustime > cooldown.currentTime) return ctx.reply(`📛 Забрать бонус можно будет через ${cooldown.timeLeftInMinutes} минут(у/ы)`); - user.bonus = 1; - user.bonustime = cooldown.endTime - let world = await WorldModel.findByPk(1) - let text = ``; - let money = [100, 200, 300, 400, 500, 1000].random(); - if (user.level >= 5) { - money += money; - } - let r = rand(1, 2); - let x = rand(2, 7); - if (r == 1) { - text += `⏩ ¤${money}\n`; - } - if (r == 2) { - money = money*x - text += `⏩ ¤${money}\n`; - } - switch(user.status){ - case 'bronze': - user.money += 5000 - text += `⭐ Дополнительный бонус за Bronze:\n⏩ ¤5.000\n` - break; - case 'silver': - user.money += 15000 - text += `⭐ Дополнительный бонус за Silver:\n⏩ ¤15.000\n` - break; - case 'gold': - user.money += 30000 - text += `⭐ Дополнительный бонус за Gold:\n⏩ ¤30.000\n` - break; - } - user.money += money; - world.balance -= money - if (user.business.id == 0){ - await user.save(); - await world.save(); - return ctx.reply(` - ⭐ Из ежечасного бонуса Вам выпало: -${text} - `) - } - let business = await BusinessModel.findOne({ - where: { - owner: user.business.id - } - }) - if(business != null){ - let mats = rand(3, 10) - switch(user.status){ - case 'bronze': - business.materials += 5 - text += `⭐ Дополнительный бонус за Bronze:\n⏩ 5 материалов\n` - break; - case 'silver': - business.materials += 10 - text += `⭐ Дополнительный бонус за Silver:\n⏩ 10 материалов\n` - break; - case 'gold': - business.materials += 20 - text += `⭐ Дополнительный бонус за Gold:\n⏩ 20 материалов\n` - break; - } - text += `⏩ ${mats} материалов в организацию\n` - business.materials += mats - business.save() - } - await user.save(); - await world.save(); - return ctx.reply(` - ⭐ Из ежечасного бонуса Вам выпало: -${text} - `) -}) - -bot.command('pay', async (ctx) => { - ctx.args = ctx.update.message.text.split(' ') - if (!ctx.args[1] || !ctx.args[2]) return ctx.reply(`/pay [Никнейм] [Сумма]`) - if (!Number(ctx.args[2])) return ctx.reply(`❕ Сумма должна быть числовая.`) - let sender = await UserModel.findByPk(ctx.from.id); - let receiver = await UserModel.findOne({ - where: { - username: ctx.args[1] - } - }); - let world = await WorldModel.findByPk(1) - let fee = Number(Math.trunc(ctx.args[2] / 100 * world.transactionfee)) - if (ctx.args[2] == 0 || ctx.args[2] < 100) return ctx.reply(`❕ Минимальная сумма перевода ¤100.`) - if (sender.money < ctx.args[2]) return ctx.reply(`❕ Недостаточно средств!`) - if (sender.money < Number(ctx.args[2]) + fee) return ctx.reply(`❕ Недостаточно средств для перевода с комиссией!`) - sender.money -= Number(ctx.args[2]) - sender.money -= Number(fee) - world.balance += Number(fee) - await sender.save(); - await world.save(); - receiver.money += Number(ctx.args[2]) - await receiver.save(); - let pmToReceiver = `🔽 Входящий перевод.\n\n🔼 Отправитель: ${sender.username}\n🆔 Отправителя: ${sender.telegram_id}\n🔢 Сумма: ¤${ctx.args[2]}\n🆕 Ваш баланс: ¤${receiver.money} - ` - bot.telegram.sendMessage(receiver.telegram_id, pmToReceiver) - return ctx.reply(`🔼 Исходящий перевод.\n\n🔽 Получатель: ${receiver.username}\n🆔 Получателя: ${receiver.telegram_id}\n🔢 Сумма: ¤${ctx.args[2]}\nℹ️ Комиссия: ¤${fee}\n🆕 Ваш баланс: ¤${sender.money} - `) -}) - -bot.hears('Мир', async (ctx) => { - let world = await WorldModel.findByPk(1) - return ctx.reply(`🔰 Баланс мира: ¤${spaces(world.balance)}\nℹ️ Стоимость материалов: ¤${spaces(world.matPrice)} - `) -}) - -bot.hears('📞 Пригласить', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id); - return ctx.reply(` - ℹ️ Для приглашения друга по реферальной системе, отправьте ему ссылку-приглашение -Как только он перейдет по ней и начнет игру, Вы получите ¤25.000. - -Ваша ссылка: https://t.me/CampFireGameBot?start=${user.telegram_id} - `) -}) - -bot.hears('📢 Вакансии', async (ctx) => { - return await ctx.reply('Список работы', Markup - .inlineKeyboard([ - [{ - text: `Дворник [1 уровень]`, - callback_data: 'job_1' - }, { - text: `Промоутер [1 уровень]`, - callback_data: 'job_2' - }], [{ - text: `Официант [2 уровень]`, - callback_data: 'job_3' - }, { - text: `Бармен [3 уровень]`, - callback_data: 'job_4' - }], [{ - text: `Кассир [4 уровень] `, - callback_data: 'job_5' - }, { - text: `ПВЗ Дикие Ягоды [4 уровень]`, - callback_data: 'job_6' - }], [{ - text: `Слесарь [5 уровень]`, - callback_data: 'job_7' - }], [{ - text: `💤 Уволиться`, - callback_data: 'job_leave' - }] - ]) - .resize() - ) -}) - -bot.action(/job_(1|2|3|4|5|6|7|leave)/, async (ctx) => { - let data = ctx.update.callback_query.data; - let user = await UserModel.findByPk(ctx.from.id); - let job = null - switch(data){ - case `job_1`: - job = await JobModel.findByPk(1); - if (user.level < job.level) { - return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) - } - if (user.job == 0) { - user.job = 1 - user.save() - return await ctx.reply(`ℹ️ Вы устроились на работу дворником.\nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) - } - return await ctx.reply(`❕ Вы уже устроены на другую работу`) - case `job_2`: - job = await JobModel.findByPk(2); - if (user.level < job.level) { - return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) - } - if (user.job == 0) { - user.job = 2 - user.save() - return await ctx.reply(`ℹ️ Вы устроились на работу промоутером. \nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) - } - return await ctx.reply(`❕ Вы уже устроены на другую работу`) - case `job_3`: - job = await JobModel.findByPk(3); - if (user.level < job.level) { - return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) - } - if (user.job == 0) { - user.job = 3 - user.save() - return await ctx.reply(`ℹ️ Вы устроились на работу официантом. \nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) - } - return await ctx.reply(`❕ Вы уже устроены на другую работу`) - case `job_4`: - job = await JobModel.findByPk(4); - if (user.level < job.level) { - return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) - } - if (user.job == 0) { - user.job = 4 - user.save() - return await ctx.reply(`ℹ️ Вы устроились на работу барменом. \nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) - } - return await ctx.reply(`❕ Вы уже устроены на другую работу`) - case `job_5`: - job = await JobModel.findByPk(5); - if (user.level < job.level) { - return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) - } - if (user.job == 0) { - user.job = 5 - user.save() - return await ctx.reply(`❕ Вы устроились на работу кассиром. \nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) - } - return await ctx.reply(`ℹ️ Вы уже устроены на другую работу`) - case `job_6`: - job = await JobModel.findByPk(6); - if (user.level < job.level) { - return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) - } - if (user.job == 0) { - user.job = 6 - user.save() - return await ctx.reply(`ℹ️ Вы устроились на работу в ПВЗ Дикие Ягоды. \nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) - } - return await ctx.reply(`❕ Вы уже устроены на другую работу`) - case `job_7`: - job = await JobModel.findByPk(7); - if (user.level < job.level) { - return await ctx.reply(`❕ У вас не хватает уровня для этой работы.`) - } - if (user.job == 0) { - user.job = 7 - user.save() - return await ctx.reply(`ℹ️ Вы устроились на работу слесарем. \nВаш оклад: ¤${job.salary}\nПриступайте к работе командой "Работать"`) - } - return await ctx.reply(`❕ Вы уже устроены на другую работу`) - case `job_leave`: - if (user.job != 0) { - user.job = 0 - user.save() - return await ctx.reply(`ℹ️ Теперь вы безработный.`) - } - return await ctx.reply(`❕ Вы итак безработный.`) - } -}) - -bot.hears('🏯 Казино', async (ctx) => { - return await ctx.reply('🏯 Добро пожаловать в казино "杜明"\n', Markup - .keyboard([ - ['🎰 Слоты'], - ['▶️ Меню'] - ]) - .resize() - ) -}) - -bot.hears('🗄️ Работать', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id); - let job = await JobModel.findByPk(user.job); - let world = await WorldModel.findByPk(1) - let timer = user.jobtime - let cooldown = setCooldown(user, 3600, timer) - if (user.jobtime > cooldown.currentTime) return ctx.reply(`📛 Работать можно будет через ${cooldown.timeLeftInMinutes} минут(у/ы)`); - if (user.job == 0) { - return await ctx.reply(`📛 Вы безработный.`) - } - user.jobtime = Number(cooldown.endTime) - let jobExp = job.exp; - user.jobcheck++ - switch (user.job) { - case 1: - if (user.jobcheck >= 4) { - let paydayfee = job.salary / 100 * world.transactionfee - let payday = job.salary - paydayfee - world.balance -= payday - user.money += payday - giveExp(user, jobExp) - user.jobcheck = 0 - user.save() - world.save() - return ctx.reply(`👔 Вы отработали смену дворника. \n🧾 Расчетный лист: \n⏳ Отработано часов: 4/4 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday}`) - } else { - user.save() - return ctx.reply(`👔 Вы подмели дворы. \n⏳ Отработано часов: ${user.jobcheck}/4`) - } - break; - case 2: - if (user.jobcheck >= 2) { - let paydayfee = job.salary / 100 * world.transactionfee - let payday = job.salary - paydayfee - world.balance -= payday - user.money += payday - giveExp(user, jobExp) - user.jobcheck = 0 - user.save() - world.save() - return ctx.reply(`👔 Вы отработали смену промоутера. \n🧾 Расчетный лист: \n⏳ Отработано часов: 2/2 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday}`) - } else { - user.save() - return ctx.reply(`👔 Вы раздавали листовки целый час. \n⏳ Отработано часов: ${user.jobcheck}/2`) - } - break; - case 3: - if (user.jobcheck >= 4) { - let paydayfee = job.salary / 100 * world.transactionfee - let payday = job.salary - paydayfee - world.balance -= payday - let tips = [50, 100, 200, 500, 1000].random() - user.money += tips - user.money += payday - giveExp(user, jobExp) - user.jobcheck = 0 - user.save() - world.save() - return ctx.reply(`👔 Вы отработали смену официанта. \n🧾 Расчетный лист: \n⏳ Отработано часов: 4/4 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday} \n💰 Получено чаевых: ¤${tips}`) - } else { - let tips = [50, 100, 200, 500, 1000].random() - user.money += tips - user.save() - return ctx.reply(`👔 Вы целый час бегали и отрабатывали заказы. \n🧾 Получено чаевых: ¤${tips} \n⏳ Отработано часов: ${user.jobcheck}/4`) - } - break; - case 4: - if (user.jobcheck >= 5) { - let paydayfee = job.salary / 100 * world.transactionfee - let payday = job.salary - paydayfee - world.balance -= payday - let tips = [50, 100, 200, 300, 500, 1000, 2000].random() - world.balance -= tips - user.money += tips - user.money += payday - giveExp(user, jobExp) - user.jobcheck = 0 - user.save() - world.save() - return ctx.reply(`👔 Вы отработали смену бармена. \n🧾 Расчетный лист: \n⏳ Отработано часов: 5/5 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday} \n💰 Получено чаевых: ¤${tips}`) - } else { - let tips = [50, 100, 200, 300, 500, 1000, 2000].random() - world.balance -= tips - user.money += tips - user.save() - world.save() - return ctx.reply(`👔 Вы целый час стояли за стойкой и разливали пойло. \n🧾 Получено чаевых: ¤${tips} \n⏳ Отработано часов: ${user.jobcheck}/5`) - } - break; - case 5: - if (user.jobcheck >= 5) { - let paydayfee = job.salary / 100 * world.transactionfee - let payday = job.salary - paydayfee - world.balance -= payday - user.money += payday - giveExp(user, jobExp) - user.jobcheck = 0 - user.save() - world.save() - return ctx.reply(`👔 Вы отработали смену кассира. \n🧾 Расчетный лист: \n⏳ Отработано часов: 5/5 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday}`) - } else { - user.save() - return ctx.reply(`👔 Вы целый час обслуживали покупателей и кричали: "Гаааляяя, отмена!". \n⏳ Отработано часов: ${user.jobcheck}/5`) - } - break; - case 6: - if (user.jobcheck >= 6) { - let paydayfee = job.salary / 100 * world.transactionfee - let payday = job.salary - paydayfee - let stealed = [{ - name: "Помада", - price: 200 - }, { - name: "Бюстгалтер", - price: 1300 - }, { - name: "Прокладки", - price: 250 - }, { - name: "Перцовый балончик", - price: 600 - }, { - name: "Гитара", - price: 6500 - }, { - name: "Комбик", - price: 9000 - }, { - name: "Кроссовки", - price: 2000 - }, { - name: "Шампунь", - price: 180 - }, { - name: "Смартфон Texno", - price: 6999 - }, { - name: "TWS Гарнитура", - price: 2800 - }, { - name: "Геймпад GameStation 5", - price: 1400 - }, { - name: "Дилдо", - price: 600 - }, { - name: "Вагиноимитатор", - price: 600 - }].random() - world.balance -= payday - world.balance -= Number(stealed.price) - user.money += payday - user.money += Number(stealed.price) - giveExp(user, jobExp) - user.jobcheck = 0 - user.save() - world.save() - return ctx.reply(`👔 Вы отработали смену в Диких Ягодах. \n🧾 Расчетный лист: \n⏳ Отработано часов: 6/6 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday} \n💰 Вы украли и продали со склада: ${stealed.name} (¤${stealed.price})`) - } else { - user.save() - return ctx.reply(`👔 Вы целый час выдавали заказы в Диких Ягодах. \n⏳ Отработано часов: ${user.jobcheck}/6`) - } - break; - case 7: - if (user.jobcheck >= 6) { - let paydayfee = job.salary / 100 * world.transactionfee - let payday = job.salary - paydayfee - world.balance -= payday - user.money += payday - giveExp(user, jobExp) - user.jobcheck = 0 - user.save() - world.save() - return ctx.reply(`👔 Вы отработали смену слесарем. \n🧾 Расчетный лист: \n⏳ Отработано часов: 6/6 \n💸 Оклад: ¤${job.salary} \nℹ️ Подоходный налог: ${world.transactionfee}% \n💹 К выплате: ¤${payday}`) - } else { - user.save() - return ctx.reply(`👔 Вы целый час работали на заводе, вы молодец! \n⏳ Отработано часов: ${user.jobcheck}/6`) - } - break; - } -}) - -bot.hears('Топ', async (ctx) => { - let topPlayer = await UserModel.findAll({ - attributes: ['username', [sequelize.fn('sum', sequelize.col('money')), 'money'], 'status'], - group: ['username', 'status'], - where: { - telegram_id: { - [Op.ne]: 275416286 - } - }, - order: [ - [sequelize.literal('money'), 'DESC'] - ], - limit: 10 - }) - let text = `🏆 Топ 10 игроков по балансу.\n\n` - for(i=0; i { - let user = await UserModel.findByPk(ctx.from.id); - return await ctx.reply(`Выберите тип`, Markup - .inlineKeyboard([ - [ - {text: 'Жилье', callback_data: `shop_house`}, - {text: 'Телефоны', callback_data: `shop_phone`}, - {text: 'Автосалон', callback_data: `shop_car`} - ] - ]) - .resize()) -}) - -bot.action('shopmenu', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id); - return await ctx.editMessageText(`Выберите тип`, Markup - .inlineKeyboard([ - [ - {text: 'Жилье', callback_data: `shop_house`}, - {text: 'Телефоны', callback_data: `shop_phone`}, - {text: 'Автосалон', callback_data: `shop_car`} - ] - ]) - .resize()) -}) - -bot.action(/shop_(house|phone|car)/, async (ctx) => { - let data = ctx.update.callback_query.data; - let prodArray = [] - let text = `Доступно к покупке:\n` - switch(data){ - case `shop_house`: - for (i in houses) { - prodArray.push({text: i, callback_data: `{"action": "buy", "type": "house", "value": "${i}"}`}) - text += i + `. ${houses[i].name} (¤${houses[i].price})\n` - } - break; - case `shop_phone`: - for (i in phones) { - prodArray.push({text: i, callback_data: `{"action": "buy", "type": "phone", "value": "${i}"}`}) - text += i + `. ${phones[i].name} (¤${phones[i].price})\n` - } - break; - case `shop_car`: - for (i in cars) { - prodArray.push({text: i, callback_data: `{"action": "buy", "type": "car", "value": "${i}"}`}) - text += i + `. ${cars[i].name} (¤${cars[i].price})\n` - } - break; - } - prodArray.push({text: `Назад`, callback_data: `shopmenu`}) - let rows = [] - while (prodArray.length > 0) { - rows.push(prodArray.splice(0, 5)) // разбиваем на подмассивы по 5 кнопок - } - return await ctx.editMessageText(text, Markup - .inlineKeyboard(rows) - .resize()) -}) - -bot.action(/{"action": "buy"*/, async (ctx) => { - let data = ctx.update.callback_query.data; - data = JSON.parse(data) - let user = await UserModel.findByPk(ctx.from.id) - let property = await PropertyModel.findByPk(ctx.from.id); - let world = await WorldModel.findByPk(1) - if (data.type == "house") { - if (user.money < houses[data.value].price) return await ctx.reply(`У вас недостаточно средств!`) - if (property.house.name) return await ctx.reply(`У вас уже есть дом.`) - user.money -= houses[data.value].price - world.balance += houses[data.value].price - property.house = houses[data.value] - await user.save() - await world.save() - await property.save() - return await ctx.reply(`Вы купили ${houses[data.value].name}`) - } - if (data.type == "car") { - if (user.money < cars[data.value].price) return await ctx.reply(`У вас недостаточно средств!`) - if (property.car.name) return await ctx.reply(`У вас уже есть автомобиль.`) - if (!property.house.name) return await ctx.reply(`Для покупки автомобиля, у Вас должен быть дом.`) - user.money -= cars[data.value].price - world.balance += cars[data.value].price - property.car = cars[data.value] - await user.save() - await world.save() - await property.save() - return await ctx.reply(`Вы купили ${cars[data.value].name}`) - } - if (data.type == "phone") { - if (user.money < phones[data.value].price) return await ctx.reply(`У вас недостаточно средств!`) - if (property.mobile.name) return await ctx.reply(`У вас уже есть телефон.`) - user.money -= phones[data.value].price - world.balance += phones[data.value].price - property.mobile = phones[data.value] - await user.save() - await world.save() - await property.save() - return await ctx.reply(`Вы купили ${phones[data.value].name}`) - } - if (data.type == "equipment") { - if (user.money < weaponshop[data.value].price) return await ctx.reply(`У вас недостаточно средств!`) - if (data.type == weaponshop[data.value].type) { - if (property.equipment.name) return await ctx.reply(`У вас уже есть экипировка.`) - user.money -= weaponshop[data.value].price - world.balance += weaponshop[data.value].price - property.equipment = weaponshop[data.value] - await user.save() - await world.save() - await property.save() - return await ctx.reply(`Вы купили ${weaponshop[data.value].name}`) - } - if (property.weapon.name) return await ctx.reply(`У вас уже есть оружие.`) - user.money -= weaponshop[data.value].price - world.balance += weaponshop[data.value].price - property.weapon = weaponshop[data.value] - await user.save() - await world.save() - await property.save() - return await ctx.reply(`Вы купили ${weaponshop[data.value].name}`) - } -}) - -bot.hears('Поставщик', async (ctx) => { - let text = `[Hatkeis Gunsmith](https://telegra.ph/Hatkeis-Gunsmith-09-27)` - let shop = `\n Вы подходите к зданию с вывеской "Ништяки Хаткейса".\n Вот ассортимент на сегодня\n` - for (i = 0; i < 10; i++) { - shop += `${i}. ${weaponshop[i].name} (¤${spaces(weaponshop[i].price)})\n` - } - weaponShopUpdate() - return await ctx.replyWithMarkdownV2(text + escape(shop), {disable_web_page_preview: true}) -}) - -bot.command('sell', async (ctx) => { - ctx.args = ctx.update.message.text.split(' ') - let user = await UserModel.findByPk(ctx.from.id) - let property = await PropertyModel.findByPk(ctx.from.id); - let world = await WorldModel.findByPk(1) - if (!ctx.args[1]) return ctx.reply(`Не указан аргумент.`) - if (ctx.args[1] == "house") { - if (!property.house.name) return await ctx.reply(`У вас нет дома.`) - let name = property.house.name - user.money += Math.round(property.house.price/2) - world.balance -= Math.round(property.house.price/2) - property.house = 0 - await user.save() - await world.save() - await property.save() - return await ctx.reply(`Вы продали ${name}`) - } - if (ctx.args[1] == "car") { - if (!property.car.name) return await ctx.reply(`У вас нет автомобиля.`) - let name = property.car.name - user.money += Math.round(property.car.price/2) - world.balance -= Math.round(property.car.price/2) - property.car = 0 - await user.save() - await world.save() - await property.save() - return await ctx.reply(`Вы продали ${name}`) - } - if (ctx.args[1] == "phone") { - if (!property.mobile.name) return await ctx.reply(`У вас нет телефона.`) - let name = property.mobile.name - user.money += Math.round(property.mobile.price/2) - world.balance -= Math.round(property.mobile.price/2) - property.mobile = 0 - await user.save() - await world.save() - await property.save() - return await ctx.reply(`Вы продали ${name}`) - } - if (ctx.args[1] == "equipment") { - if (!property.equipment.name) return await ctx.reply(`У вас нет экипировки.`) - let name = property.equipment.name - user.money += Math.round(property.equipment.price/2) - world.balance -= Math.round(property.equipment.price/2) - property.equipment = 0 - await user.save() - await world.save() - await property.save() - return await ctx.reply(`Вы продали ${name}`) - } - if (ctx.args[1] == "weapon") { - if (!property.weapon.name) return await ctx.reply(`У вас нет оружия.`) - let name = property.weapon.name - user.money += Math.round(property.weapon.price/2) - world.balance -= Math.round(property.weapon.price/2) - property.weapon = 0 - await user.save() - await world.save() - await property.save() - return await ctx.reply(`Вы продали ${name}`) - } -}) - -bot.hears('🌐 Организация', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - if (user.business.id == 0) return await ctx.reply(`Вы не состоите в организации.`) - let business = await BusinessModel.findOne({ - where: { - owner: ctx.from.id.toString() - } - }) - if(business === null){ - business = await BusinessModel.findOne({ - where: { - owner: user.business.id - } - }) - return await ctx.replyWithMarkdownV2(`🏭 Организация\n_${business.name}_\n💹 Баланс: ¤${escape(spaces(business.balance))}\n🧰 Сырье: ${business.materials}\n👥 Рабочих: ${business.users.length}\n\nВаши отработки: ${user.business.checks}`, Markup.inlineKeyboard([ - [{ - text: `📶 Отработка`, - callback_data: "workoff" - }, { - text: `⬅️ Покинуть`, - callback_data: "покинуть" - }] - ]) - .oneTime() - .resize()) - } - if (business.owner == ctx.from.id){ - return await ctx.replyWithMarkdownV2(`🏭 Ваша организация\n_${business.name}_\n💹 Баланс: ¤${escape(spaces(business.balance))}\n🧰 Сырье: ${business.materials}\n👥 Рабочих: ${business.users.length}\n🔨 Отработок: ${business.checks}\n\nВаши отработки: ${user.business.checks}`, Markup.inlineKeyboard([ - [{ - text: `📶 Отработка`, - callback_data: "workoff" - }, { - text: `💸 Payday`, - callback_data: "payday" - }] - ]) - .oneTime() - .resize()) - } -}) - -bot.action('workoff', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - let business = await BusinessModel.findOne({ - where: { - owner: user.business.id.toString() - } - }) - if (user.business == null) return await ctx.reply(`Вы не работаете в организации.`) - let timer = user.worktime - let cooldown = setCooldown(user, 3600, timer) - if (user.worktime > cooldown.currentTime) return ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `📛 Работа в организации будет доступна через ${cooldown.timeLeftInMinutes} минут(у/ы)`, {show_alert: true}); - if (business.materials < 10) return ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `📛 В организации недостаточно материалов для отработки.`); - user.worktime = cooldown.endTime - user.business = { - id: user.business.id, - checks: user.business.checks + 1, - percent: user.business.percent - } - business.materials -= 10 - business.checks += 1 - await user.save() - await business.save() - if (business.owner == ctx.from.id){ - return await ctx.editMessageText(`🏭 Ваша организация\n_${business.name}_\n💹 Баланс: ¤${escape(spaces(business.balance))}\n🧰 Сырье: ${business.materials} \n👥 Рабочих: ${business.users.length}\n🔨 Отработок: ${business.checks}\n\nВаши отработки: ${user.business.checks}`, - { - reply_markup: { - inline_keyboard: [ - [{ - text: `📶 Отработка`, - callback_data: "workoff" - }, { - text: `💸 Payday`, - callback_data: "payday" - }] - ]}, - parse_mode: `MarkdownV2` - } - ) - }else{ - return await ctx.editMessageText(`🏭 Организация\n_${business.name}_\n💹 Баланс: ¤${escape(spaces(business.balance))}\n🧰 Сырье: ${business.materials}\n👥 Рабочих: ${business.users.length}\n\nВаши отработки: ${user.business.checks}`, - { - reply_markup: { - inline_keyboard: [ - [{ - text: `📶 Отработка`, - callback_data: "workoff" - }, { - text: `⬅️ Покинуть`, - callback_data: "покинуть" - }] - ]}, - parse_mode: `MarkdownV2` - } - ) - } -}) - -bot.action('покинуть', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - if (user.business.id == 0) return await ctx.reply(`Вы не состоите в организации.`) - let business = await BusinessModel.findOne({ - where: { - owner: ctx.from.id.toString() - } - }) - if(business === null){ - business = await BusinessModel.findOne({ - where: { - owner: user.business.id - } - }) - await ctx.reply(`Подтвердите в личных сообщениях.`) - return await bot.telegram.sendMessage(ctx.from.id, `🏭 Вы действительно хотите покинуть ${business.name}`, Markup.inlineKeyboard([ - [{ - text: `Да`, - callback_data: "user_leave_business" - }, { - text: `Нет`, - callback_data: "cancel" - }] - ]) - .oneTime() - .resize() - ) - } - if (business.owner == ctx.from.id){ - return await ctx.reply(`Вы не можете покинуть свою организацию.`) - } -}) - -bot.action('cancel', async (ctx) => { - await ctx.deleteMessage() - await bot.telegram.answerCbQuery(ctx.callbackQuery.id, `Отмена.`) -}) - -bot.action('user_leave_business', async (ctx) => { - let data = ctx.update.callback_query.data; - let user = await UserModel.findByPk(ctx.from.id) - if (user.business.id == 0) return await ctx.reply(`Вы не состоите в организации.`) - let business = await BusinessModel.findOne({ - where: { - owner: user.business.id - } - }) - user.business = { - id: 0, - checks: 0, - percent: 0 - } - business.users = business.users.filter(value => value != ctx.from.id); - business.save() - user.save() - return await bot.telegram.sendMessage(ctx.from.id, `🏭 Вы покинули ${business.name}`) -}) - -bot.action('payday', async (ctx) => { - let user = null - let business = await BusinessModel.findOne({ - where: { - owner: ctx.from.id.toString() - } - }) - let world = await WorldModel.findByPk(1) - if (business === null) return await ctx.reply(`У вас нет организации.`) - if (business.checks < 12) return await ctx.reply(`Недостаточно отработок для формирования выплаты.`) - let percentSum = 0 - let text = `` - let percentErrorText = `` - let profit = 0 - let piece = 0 - let moneyList = rand(1000, 3000) - moneyList = moneyList*business.users.length - for (i = 0; i < business.users.length; i++) { // Summary percent - user = await UserModel.findByPk(business.users[i]) - percentSum += Number(user.business.percent) - percentErrorText += `ℹ️ ${user.username} ${user.business.percent}% [/percent ${user.username} [проценты]]\n` - } - if (percentSum > 100) return await ctx.reply(`⚠️ Общий процент всех сотрудников превышает 100%\n ➕ Остаток процентов перенесется в баланс организации.\n\n${percentErrorText}\n`) - for (x = 0; x < business.users.length; x++) { // Общая внесенная сумма всеми участниками - user = await UserModel.findByPk(business.users[x]) - profit += user.business.checks * moneyList * user.level - text += `ℹ️ ${user.username} отработал ${user.business.checks} раз.\n` - user.business = { - id: user.business.id, - checks: 0, - percent: user.business.percent - } - user.save() - } - text += ` 💹 Наработка за текущий период: ${profit}\n` - let profitCheck = profit - for (n = 0; n < business.users.length; n++) { // Процент выплаты участникам - user = await UserModel.findByPk(business.users[n]) - piece = Math.round(profit / 100 * user.business.percent) - profitCheck -= piece - user.money += piece - text += `➕ ${user.username} получает ¤${piece}\n` - await bot.telegram.sendMessage(user.telegram_id, `ℹ️ Директор организации сформировал выплаты.\n➕ На ваш баланс поступило: ${spaces(piece)}`) - giveExp(user, business.checks) - user.save() - } - if (profitCheck > 0) { - business.balance += profitCheck - text += `➕ На баланс бизнеса поступило ¤${profitCheck}` - } - business.checks = 0 - business.save() - console.log(`Payday: ${business.name}\n${text}`) - return await ctx.reply(text) -}) - -bot.command('orgmessage', async (ctx) => { - if (!ctx.args[1]) return ctx.reply(`Не указан аргумент.`) - let business = await BusinessModel.findOne({ - where: { - owner: ctx.from.id.toString() - } - }) - if (business === null) return await ctx.reply(`У вас нет организации.`) - for (i = 0; i < business.users.length; i++) { - user = await UserModel.findByPk(business.users[i]) - await bot.telegram.sendMessage(user.telegram_id, `Директор организации сообщает:\n ${ctx.payload}`) - } - console.log(`Директор организации сообщает:\n ${ctx.payload}`) - return await ctx.reply(`Сообщение отправлено.`) -}) - -bot.command('materials', async (ctx) => { - ctx.args = ctx.update.message.text.split(' ') - let user = await UserModel.findByPk(ctx.from.id) - if (user.business.id == 0) return await ctx.reply(`🚫 Вы не владеете организацией.`) - let world = await WorldModel.findByPk(1) - let business = await BusinessModel.findOne({ - where: { - owner: ctx.from.id.toString() - } - }) - if (business === null) return await ctx.reply(`🚫 У вас нет организации.`) - if (!ctx.args[1]) return ctx.reply(`🚫 Не указан аргумент.`) - if (!Number(ctx.args[1])) return ctx.reply(`ℹ️ Количество должно быть числом.`) - if (ctx.args[1] < 1) return ctx.reply(`ℹ️ Минимальное количество для покупки - 1`) - if (ctx.args[1]*world.matPrice > business.balance) return ctx.reply(`🚫 Недостаточно средств на балансе организации.`) - if (business.materials >= 700) return ctx.reply(`🚫 Склады полны.`) - if (business.materials + Number(ctx.args[1]) > 700) return ctx.reply(`🚫 Нет столько места на складах.\n Можно закупить еще ${700 - business.materials}`) - let count = Number(ctx.args[1]) - business.balance -= world.matPrice*count - business.materials += count - business.save() - return await ctx.reply(`➕ Закуплено ${ctx.args[1]} материалов для организации на сумму ¤${world.matPrice*count}`) -}) - -bot.command('percent', async (ctx) => { - ctx.args = ctx.update.message.text.split(' ') - let user = await UserModel.findByPk(ctx.from.id) - if (user.business.id == 0) return await ctx.reply(`Вы не владеете организацией.`) - let business = await BusinessModel.findOne({ - where: { - owner: ctx.from.id.toString() - } - }) - if (business === null) return await ctx.reply(`У вас нет организации.`) - if (!ctx.args[1] || !ctx.args[2]) return ctx.reply(`Не указан аргумент.`) - if (!Number(ctx.args[2])) return ctx.reply(`Процент должен быть числом от 1 до 100.`) - if (ctx.args[2] < 1 || ctx.args[2] > 100) return ctx.reply(`Минимальный процент 1 | Максимальный процент 100.`) - ctx.args[1] = ctx.args[1] - console.log(ctx.args) - let change = await UserModel.findOne({ - where: { - username: ctx.args[1] - } - }) - if (change === null) return await ctx.reply(`Нет такого игрока.`) - change.business = { - id: change.business.id, - checks: change.business.checks, - percent: ctx.args[2] - } - change.save() - return await ctx.reply(`Участнику ${change.username} установлен процент ${ctx.args[2]}`) -}) - -bot.command('business', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - if (user.business.id != 0){ - let business = await BusinessModel.findOne({ - where: { - owner: ctx.from.id.toString() - } - }) - } - let business = null - let world = await WorldModel.findByPk(1) - ctx.args = ctx.update.message.text.split(' ') - if (business != null) return await ctx.reply(`У вас уже есть организация.`) - if (!ctx.args[1]) return ctx.reply(`/business [Название организации]`) - if (user.money < 100000) return await ctx.reply(`Регистрация организации стоит ¤100.000`) - if (user.level < 5) return await ctx.reply(`Регистрация организации доступна с 5 уровня.`) - user.money -= 100000 - world.balance += 100000 - let text = `` - for (i = 1; i < ctx.args.length; i++) { - text += `${ctx.args[i]} ` - } - if (business === null) { - BusinessModel.create({ - name: text, - owner: user.telegram_id, - balance: 50000, - users: [user.telegram_id] - }) - user.business = { - id: user.telegram_id, - checks: 0, - percent: 100 - } - } else {} - user.save() - world.save() - return await ctx.reply(`Организация "${text}" успешно создана!\n Регистрация организации в реестре: ¤50.000 \n Капитал: ¤50.000`) -}) - -bot.command('invite', async (ctx) => { - ctx.args = ctx.update.message.text.split(' ') - if (!ctx.args[1]) return ctx.reply(`/invite [Nick]`) - let user = await UserModel.findByPk(ctx.from.id) - if (user.business.id == 0) return await ctx.reply(`🚫 У вас нет организации в которую можно пригласить игрока.`) - let business = await BusinessModel.findOne({ - where: { - owner: ctx.from.id.toString() - } - }) - if (business.users.length >= 5) return await ctx.reply(`📛 Достигнуто максимальное количество сотрудников в организации.`) - let invited = await UserModel.findOne({ - where: { - username: ctx.args[1] - } - }); - await bot.telegram.sendMessage(invited.telegram_id, '⤵️ Приглашение', Markup - .inlineKeyboard([ - [{ - text: `Принять`, - callback_data: `{"type": "business_invite_accept", "invitor": "${user.telegram_id}"}` - }, { - text: `Отклонить`, - callback_data: `{"type": "business_invite_refuse", "invitor": "${user.telegram_id}"}` - }] - ]).oneTime()) - return await ctx.reply(`Приглашение отправлено.`) -}) - -bot.action(/{"type": "business_invite_(accept|refuse)"*/, async ctx => { - let data = ctx.update.callback_query.data; - data = JSON.parse(data) - let user = await UserModel.findByPk(ctx.update.callback_query.from.id) - if (data.type == 'business_invite_accept') { - if(user.business.id == 0){ - let business = await BusinessModel.findOne({ - where: { - owner: data.invitor - } - }) - user.business = { - id: data.invitor, - checks: 0, - percent: 10 - } - business.users = sequelize.fn('array_append', sequelize.col('users'), ctx.update.callback_query.from.id); - business.save() - user.save() - await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `✔️ Приглашение принято.`, {show_alert: true}) - } - await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `ℹ️ Вы уже в организации.`, {show_alert: true}) - } - if (data.type == 'business_invite_refuse'){ - await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `❌ Приглашение отклонено.`, {show_alert: true}) - } -}) - -bot.command('report', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - ctx.args = ctx.update.message.text.split(' ') - if (!ctx.args[1]) return ctx.reply(`/report [Текст обращения]`) - let uID = shortid.generate() - await ReportModel.create({ - uid: uID, - author: user.telegram_id, - text: ctx.payload, - status: 1 - }) - let report = await ReportModel.findOne({ - where: { - uid: uID - } - }) - await bot.telegram.sendMessage(adminList[0], `Обращение от пользователя ${user.username}\nТекст обращения:\n${ctx.payload}\n\nДля ответа /answer ${report.id} [Ответ]`) - return await ctx.reply(`Обращение #${report.id}[${report.uid}] создано.`) -}) - -bot.hears('🎰 Слоты', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - ctx.args = ctx.update.message.text.split(' ') - await ctx.reply('Комбинации слотов:\n7️⃣7️⃣7️⃣ - x25\n🍋🍋🍋 - x20\n🍇🍇🍇 - x15\n🔤🔤🔤 - x10', Markup - .inlineKeyboard([ - [{ - text: `1000`, - callback_data: `slots1000` - }, { - text: `5000`, - callback_data: `slots5000` - }, { - text: `25000`, - callback_data: `slots25000` - }, { - text: `50000`, - callback_data: `slots50000` - }, { - text: `100000`, - callback_data: `slots100000` - }] - ])) -}) - -bot.action(/slots(1000|5000|25000|50000|100000)/, async (ctx) => { - let data = ctx.update.callback_query.data; - let bet = 1000 - switch(data){ - case `slots1000`: - bet = 1000 - break; - case `slots5000`: - bet = 5000 - break; - case `slots25000`: - bet = 25000 - break; - case `slots50000`: - bet = 50000 - break; - case `slots100000`: - bet = 100000 - break; - } - let user = await UserModel.findByPk(ctx.from.id) - let timer = user.slottime - let cooldown = setCooldown(user, 10, timer) - if (user.slottime > cooldown.currentTime) return ctx.reply(`📛 Слоты будут доступны через пару секунд`); - if (user.money < bet) return ctx.reply(`Недостаточно средств.`) - user.slottime = cooldown.endTime - let world = await WorldModel.findByPk(1) - let result = await ctx.replyWithDice({emoji: `🎰`}) - let slot = slots[result.dice.value] - let win = getSlot(result) - console.log(user.username + `: Win: x` + win) - user.money -= bet - world.balance += bet - if(win > 4){ - user.world -= bet*win - user.money += bet*win - user.save() - world.save() - return setTimeout(() => { - ctx.reply(`➕ Вы выиграли ¤${spaces(bet*win)}`) - }, 1700); - } - if(win > 0 && win <= 4){ - await giveExp(user, win*2) - return setTimeout(() => { - ctx.reply(`➕ Вы выиграли ${win*2} опыта.`) - }, 1700); - } - if(win == 0){ - return setTimeout(() => { - world.save() - user.save() - ctx.reply(`➖ Вы проиграли ¤${spaces(bet)}.`) - }, 1700); - } - -}) - -bot.hears('Помощь', async (ctx) => { - return await ctx.replyWithMarkdownV2(`• [Функционал](https://telegra.ph/CampFire-Bot-Info-09-25)\n• [Правила](https://telegra.ph/PRAVILA-BOTA-09-25)`, { - disable_web_page_preview: true - }) -}) - -bot.command('promocode', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - ctx.args = ctx.update.message.text.split(' ') - if (!ctx.args[1]) return ctx.reply(`/promocode [Code]`) - let promocode = await PromocodeModel.findOne({ - where: { - code: ctx.args[1] - } - }) - if(promocode === null) return await ctx.reply(`➖ Нет такого кода.`) - if(promocode.users.length-1 >= promocode.activations && promocode.users != null) return await ctx.reply(`⚠️ Промокод уже активировали максимальное количество раз.`) - if(promocode.users.includes(ctx.from.id.toString())) return await ctx.reply(`⚠️ Вы уже активировали этот промокод.`) - console.log(promocode.users) - promocode.users = sequelize.fn('array_append', sequelize.col('users'), ctx.from.id.toString()); - user.money += promocode.money - user.save() - promocode.save() - await bot.telegram.sendMessage(adminList[0], `${user.username} активировал промокод.`) - return await ctx.reply(`✅ Вы активировали промокод.`) -}) - -bot.hears('📦 Контейнеры', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - let containers = [] - let superWin = rarecars.random() - let values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - let oneValue = [] - for(i = 0; i < 10; i++){ - oneValue = values.random() - values = values.filter(value => value != oneValue); - containers.push({name: `📦 Контейнер ${i+1}`, value: oneValue}) - } - let keyboardButtons = containers.map(container => { - return {text: container.name, callback_data: `container_${container.value}`} - }) - let rows = [] - while (keyboardButtons.length > 0) { - rows.push(keyboardButtons.splice(0, 2)) // разбиваем на подмассивы по 5 кнопок - } - await ctx.replyWithMarkdownV2('[Sueta Logistic International](https://telegra.ph/OOO-Sueta-Logistic-International-09-27)\nДоступные контейнеры в порту:', - { - reply_markup: { - inline_keyboard: rows - }, - disable_web_page_preview: true - }) -}) - - -bot.action(/container_(1|2|3|4|5|6|7|8|9|10)/, async (ctx) => { - let data = ctx.update.callback_query.data; - let user = await UserModel.findByPk(ctx.from.id) - let property = await PropertyModel.findByPk(ctx.from.id) - if(user.money < 500000) return ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `Открытие контейнера стоит ¤500.000`, {show_alert: true}) - if(property.car.name) return ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас уже есть автомобиль\nПродайте текущий автомобиль: /sell car`, {show_alert: true}) - user.money -= 500000 - let userWin = null - switch(data){ - case `container_7`: - userWin = rarecars.random() - break; - default: - userWin = simplecars.random() - break; - } - property.car = userWin - user.save() - property.save() - ctx.deleteMessage() - return await ctx.sendPhoto(userWin.image, { caption: `В контейнере была: ${userWin.name} стоимостью ¤${spaces(userWin.price)}`}) -}) - -bot.action(/{"action": "sueta_*/, async (ctx) => { - let data = ctx.update.callback_query.data; - data = JSON.parse(data) - console.log(data.car) - let user = await UserModel.findByPk(ctx.from.id) - let property = await PropertyModel.findByPk(ctx.from.id) - switch(data.action){ - case `sueta_accept`: - user.money += data.carprice - await ctx.editMessageText(`➕ ${data.carprice}`) - break; - case `sueta_refuse`: - user.money += Math.round(property.car.price/2) - property.car = { - name: data.carname, - price: data.carprice - } - await ctx.editMessageText(`➕ ${data.carname}`) - break; - } - user.save() - property.save() -}) -/////////////////////////////////////Admin Commands////////////////////////////////////////////////// - - -bot.command('answer', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - if(user.status != 'admin') return await ctx.reply(`Admin Only.`) - ctx.args = ctx.update.message.text.split(' ') - if (!ctx.args[1]) return ctx.reply(`Нужен номер обращения`) - let report = await ReportModel.findByPk(ctx.args[1]) - if (report === null) return await ctx.reply(`Нет обращения с таким ID.`) - if (report.status == 0) return await ctx.reply(`Данное обращение уже закрыто.`) - let answer = ctx.args - answer.shift() - answer.shift() - answer = answer.join(' ') - await bot.telegram.sendMessage(report.author, `Ответ на обращение #${report.id}[${report.uid}]\n\n` + answer) - report.status = 0 - report.save() - return await ctx.reply(`Ответ отправлен, обращение закрыто!`) -}) - -bot.command('fastblock', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - if(!ctx.message.reply_to_message) return await ctx.reply(`Только на пересланное сообщение.`) - let blocked = ctx.message.reply_to_message.from.id - if(user.status != 'admin') return await ctx.reply(`Admin Only.`) - await BlockModel.create({ - telegram_id: blocked, - isBlocked: true, - reason: `|AutoFastBlock|`, - time: Math.trunc(Date.now() / 1000 + 3600) - }) - await bot.telegram.sendMessage(blocked, `Вы были заблокированы администратором ${user.username}.`) - return await ctx.reply(`Пользователь заблокирован.`) -}) - -bot.command('createpromocode', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - if(user.status != 'admin') return await ctx.reply(`Admin Only.`) - ctx.args = ctx.update.message.text.split(' ') - if (!ctx.args[1] || !ctx.args[2] || !ctx.args[3]) return ctx.reply(`/createpromo [activations] [money] [code]`) - let promocode = await PromocodeModel.findOne({ - where: { - code: ctx.args[3] - } - }) - if(promocode === null){ - await PromocodeModel.create({ - code: ctx.args[3], - activations: ctx.args[1], - money: ctx.args[2] - }) - let voucherImage = await generateVoucher(ctx.args[3], ctx.args[1], ctx.args[2]) - return await ctx.sendPhoto({source: voucherImage, caption: `Создан промокод ${ctx.args[3]}` }) -} -}) - -bot.command('genpromo', async (ctx) => { - let user = await UserModel.findByPk(ctx.from.id) - if(user.status != 'admin') return await ctx.reply(`Admin Only.`) - ctx.args = ctx.update.message.text.split(' ') - if (!ctx.args[1] || !ctx.args[2]) return ctx.reply(`/genpromo [activations] [money]`) - let code = voucher_codes.generate({ - length: 6, - count: 1, - prefix: "CMP-", - postfix: "-FIRE", - charset: voucher_codes.charset("alphanumeric") - }); - let promocode = await PromocodeModel.findOne({ - where: { - code: code[0] - } - }) - if(promocode === null){ - await PromocodeModel.create({ - code: code[0], - activations: ctx.args[1], - money: ctx.args[2] - }) - let voucherImage = await generateVoucher(code, ctx.args[1], ctx.args[2]) - return await ctx.sendPhoto({source: voucherImage, caption: `Создан промокод ${code[0]}` }) -} -}) - -///////////////////////////////////////Functions////////////////////////////////////////////////////// - -function rand(min, max) { - return Math.round(Math.random() * (max - min)) + min -} -var parserInt = (str) => parseInt(str.replace(/k|к/ig, "000")); - -function spaces(string) { - if (typeof string !== "string") string = string.toString(); - return string.split("").reverse().join("").match(/[0-9]{1,3}/g).join(".").split("").reverse().join(""); -}; -function spacesWithMarkdown(string) { - if (typeof string !== "string") string = string.toString(); - return string.split("").reverse().join("").match(/[0-9]{1,3}/g).join(".\\").split("").reverse().join(""); -}; -function escape(text) { - text = text - .replace(/\_/g, '\\_') - .replace(/\*/g, '\\*') - .replace(/\[/g, '\\[') - .replace(/\]/g, '\\]') - .replace(/\(/g, '\\(') - .replace(/\)/g, '\\)') - .replace(/\~/g, '\\~') - .replace(/\`/g, '\\`') - .replace(/\>/g, '\\>') - .replace(/\#/g, '\\#') - .replace(/\+/g, '\\+') - .replace(/\-/g, '\\-') - .replace(/\=/g, '\\=') - .replace(/\|/g, '\\|') - .replace(/\{/g, '\\{') - .replace(/\}/g, '\\}') - .replace(/\./g, '\\.') - .replace(/\!/g, '\\!'); - return text -}; -Array.prototype.random = function() { - return this[Math.floor(this.length * Math.random())]; -} - -function getCurrentTime() { - const now = new Date(); - const year = now.getFullYear(); - const month = now.getMonth() < 9 ? `0${now.getMonth() + 1}` : now.getMonth() + 1; - const day = now.getDate() < 10 ? `0${now.getDate()}` : now.getDate(); - const hours = now.getHours() < 10 ? `0${now.getHours()}` : now.getHours(); - const minutes = now.getMinutes() < 10 ? `0${now.getMinutes()}` : now.getMinutes(); - const seconds = now.getSeconds() < 10 ? `0${now.getSeconds()}` : now.getSeconds(); - return `${day}.${month}.${year} ${hours}:${minutes}:${seconds}`; -} - -function getSlot(result) { - switch(result.dice.value){ - case 1: - return 10 - case 22: - return 15 - case 43: - return 20 - case 64: - return 25 - case 17: case 33: case 49: - return 1 - case 6: case 38: case 54: - return 2 - case 11: case 27: case 59: - return 3 - case 16: case 32: case 48: - return 4 - default: - return 0 -}} - -function setCooldown(user, seconds, type) { - let cooldown = {} - cooldown.currentTime = Math.trunc(Date.now() / 1000) - - switch(user.status){ - case `user`: - cooldown.endTime = Math.trunc(Date.now() / 1000 + seconds) - break; - case `bronze`: - cooldown.endTime = Math.trunc(Date.now() / 1000 + (seconds/100*85)) - break; - case `silver`: - cooldown.endTime = Math.trunc(Date.now() / 1000 + (seconds/100*75)) - break; - case `gold`: - cooldown.endTime = Math.trunc(Date.now() / 1000 + (seconds/100*50)) - break; - case `admin`: - cooldown.endTime = Math.trunc(Date.now() / 1000) - break; - } - cooldown.timeLeft = cooldown.endTime - cooldown.currentTime - cooldown.timeLeftInMinutes = Math.ceil((type - cooldown.currentTime) / 60) - return cooldown -} - -async function giveExp(user, experience) { - user.exp += experience - for(i in expToUp){ - if (user.exp >= expToUp[user.level]) { - user.exp -= expToUp[user.level] - user.level += 1 - user.save() - await bot.telegram.sendMessage(user.telegram_id, `⤴️ Ваш уровень повысился до ${user.level}!`)} - } - user.save() -} - -function weaponShopUpdate() { - let weaponId = [] - let equipId = [] - let drop = 1 - let counter = 5 - for (i = 0; i < 5; i++) { - drop = weaponId.push(rand(1, 10)) - } - for (i = 0; i < 5; i++) { - drop = equipId.push(rand(1, 10)) - } - for (i = 0; i < 5; i++) { - weaponshop[i] = weapons[weaponId[i]] - } - for (i = 0; i < 5; i++) { - weaponshop[counter] = equipment[equipId[i]] - counter++ - } - fs.writeFileSync('json/weaponshop.json', JSON.stringify(weaponshop, null, "\t")) -} - -async function matPriceUpdate() { - let world = await WorldModel.findByPk(1) - let price = rand(35, 170) - world.matPrice = price - world.save() -} - -setTimeout(() => { - generatePromo() -}, 360000*3); - -setInterval(() => { - var today = new Date(); - let hours = today.getHours(); - if (hours == "0" || hours == "12") { - weaponShopUpdate() - matPriceUpdate() - } -}, 360000); - -async function generatePromo() { - let activs = rand(1, 3) - let give = rand(1000, 10000) - let code = voucher_codes.generate({ - length: 6, - count: 1, - prefix: "CMP-", - postfix: "-FIRE", - charset: voucher_codes.charset("alphanumeric") - }); - let promocode = await PromocodeModel.findOne({ - where: { - code: code[0] - } - }) - if(promocode === null){ - await PromocodeModel.create({ - code: code[0], - activations: activs, - money: give - }) - let voucherImage = await generateVoucher(code[0], activs, give) - return await bot.telegram.sendPhoto(mainChat, {source: voucherImage}) -} -} - -async function generateVoucher(code, activations, money) { - // загружаем изображение фона - const background = await loadImage('./media/imageDefault3.png'); - - // создаем новый canvas - const canvas = createCanvas(background.width, background.height); - const ctx = canvas.getContext('2d'); - - // рисуем фоновое изображение - ctx.drawImage(background, 0, 0); - - // выводим текст на картинку - ctx.font = 'bold 30px Srbija Sans'; - ctx.fillStyle = '#232323'; - ctx.textAlign = 'center'; - ctx.fillText(`${code}`, canvas.width/2, canvas.height/1.90); - - // сохраняем картинку в файл - const out = fs.createWriteStream('./media/image.png'); - const stream = canvas.createPNGStream(); - stream.pipe(out); - - // возвращаем путь к сгенерированной картинке - return './media/image.png'; - } - -start() - -bot.launch() \ No newline at end of file +require('./bot') \ No newline at end of file diff --git a/json/fastlog.json b/json/fastlog.json new file mode 100644 index 0000000..f550efe --- /dev/null +++ b/json/fastlog.json @@ -0,0 +1,2460 @@ +{ + "update": { + "update_id": 757696514, + "callback_query": { + "id": "7719528038798802037", + "from": { + "id": 1797342681, + "is_bot": false, + "first_name": "Wild", + "last_name": "Developer", + "username": "wild_dev", + "language_code": "ru" + }, + "message": { + "message_id": 23044, + "from": { + "id": 6489664401, + "is_bot": true, + "first_name": "CampFire", + "username": "CampFireGameBot" + }, + "chat": { + "id": 1797342681, + "first_name": "Wild", + "last_name": "Developer", + "username": "wild_dev", + "type": "private" + }, + "date": 1695764308, + "text": "Приглашение", + "reply_markup": { + "inline_keyboard": [ + [ + { + "text": "Принять", + "callback_data": "{type: business_invite_accept, invitor: 275416286}" + }, + { + "text": "Отклонить", + "callback_data": "{type: business_invite_refuse, invitor: 275416286}" + } + ] + ] + } + }, + "chat_instance": "3234091630426335107", + "data": "{type: business_invite_accept, invitor: 275416286}" + } + }, + "telegram": { + "token": "6489664401:AAHTimMFrCzFUXhHGmiMDwWhsAVs6J3rrLs", + "options": { + "apiRoot": "https://api.telegram.org", + "apiMode": "bot", + "webhookReply": true, + "agent": { + "_events": {}, + "_eventsCount": 2, + "defaultPort": 443, + "protocol": "https:", + "options": { + "keepAlive": true, + "keepAliveMsecs": 10000, + "noDelay": true, + "path": null + }, + "requests": {}, + "sockets": {}, + "freeSockets": { + "api.telegram.org:443:::::::::::::::::::::": [ + { + "_tlsOptions": { + "pipe": false, + "secureContext": { + "context": {} + }, + "isServer": false, + "requestCert": true, + "rejectUnauthorized": true + }, + "_secureEstablished": true, + "_securePending": false, + "_newSessionPending": false, + "_controlReleased": true, + "secureConnecting": false, + "_SNICallback": null, + "servername": "api.telegram.org", + "alpnProtocol": false, + "authorized": true, + "authorizationError": null, + "encrypted": true, + "_events": { + "close": [ + null, + null, + null + ] + }, + "_eventsCount": 9, + "connecting": false, + "_hadError": false, + "_parent": null, + "_host": "api.telegram.org", + "_closeAfterHandlingError": false, + "_readableState": { + "objectMode": false, + "highWaterMark": 16384, + "buffer": { + "head": null, + "tail": null, + "length": 0 + }, + "length": 0, + "pipes": [], + "flowing": true, + "ended": false, + "endEmitted": false, + "reading": true, + "constructed": true, + "sync": false, + "needReadable": true, + "emittedReadable": false, + "readableListening": false, + "resumeScheduled": false, + "errorEmitted": false, + "emitClose": false, + "autoDestroy": true, + "destroyed": false, + "errored": null, + "closed": false, + "closeEmitted": false, + "defaultEncoding": "utf8", + "awaitDrainWriters": null, + "multiAwaitDrain": false, + "readingMore": false, + "dataEmitted": true, + "decoder": null, + "encoding": null + }, + "_writableState": { + "objectMode": false, + "highWaterMark": 16384, + "finalCalled": false, + "needDrain": false, + "ending": false, + "ended": false, + "finished": false, + "destroyed": false, + "decodeStrings": false, + "defaultEncoding": "utf8", + "length": 0, + "writing": false, + "corked": 0, + "sync": false, + "bufferProcessing": false, + "writecb": null, + "writelen": 0, + "afterWriteTickInfo": null, + "buffered": [], + "bufferedIndex": 0, + "allBuffers": true, + "allNoop": true, + "pendingcb": 0, + "constructed": true, + "prefinished": false, + "errorEmitted": false, + "emitClose": false, + "autoDestroy": true, + "errored": null, + "closed": false, + "closeEmitted": false + }, + "allowHalfOpen": false, + "_sockname": null, + "_pendingData": null, + "_pendingEncoding": "", + "_server": null, + "ssl": { + "_parent": { + "reading": true, + "onconnection": null + }, + "_secureContext": { + "context": {} + }, + "reading": true + }, + "_requestCert": true, + "_rejectUnauthorized": true, + "parser": null, + "_httpMessage": null, + "timeout": 0 + }, + { + "_tlsOptions": { + "pipe": false, + "secureContext": { + "context": {} + }, + "isServer": false, + "requestCert": true, + "rejectUnauthorized": true + }, + "_secureEstablished": true, + "_securePending": false, + "_newSessionPending": false, + "_controlReleased": true, + "secureConnecting": false, + "_SNICallback": null, + "servername": "api.telegram.org", + "alpnProtocol": false, + "authorized": true, + "authorizationError": null, + "encrypted": true, + "_events": { + "close": [ + null, + null, + null + ] + }, + "_eventsCount": 9, + "connecting": false, + "_hadError": false, + "_parent": null, + "_host": "api.telegram.org", + "_closeAfterHandlingError": false, + "_readableState": { + "objectMode": false, + "highWaterMark": 16384, + "buffer": { + "head": null, + "tail": null, + "length": 0 + }, + "length": 0, + "pipes": [], + "flowing": true, + "ended": false, + "endEmitted": false, + "reading": true, + "constructed": true, + "sync": false, + "needReadable": true, + "emittedReadable": false, + "readableListening": false, + "resumeScheduled": false, + "errorEmitted": false, + "emitClose": false, + "autoDestroy": true, + "destroyed": false, + "errored": null, + "closed": false, + "closeEmitted": false, + "defaultEncoding": "utf8", + "awaitDrainWriters": null, + "multiAwaitDrain": false, + "readingMore": false, + "dataEmitted": true, + "decoder": null, + "encoding": null + }, + "_writableState": { + "objectMode": false, + "highWaterMark": 16384, + "finalCalled": false, + "needDrain": false, + "ending": false, + "ended": false, + "finished": false, + "destroyed": false, + "decodeStrings": false, + "defaultEncoding": "utf8", + "length": 0, + "writing": false, + "corked": 0, + "sync": false, + "bufferProcessing": false, + "writecb": null, + "writelen": 0, + "afterWriteTickInfo": null, + "buffered": [], + "bufferedIndex": 0, + "allBuffers": true, + "allNoop": true, + "pendingcb": 0, + "constructed": true, + "prefinished": false, + "errorEmitted": false, + "emitClose": false, + "autoDestroy": true, + "errored": null, + "closed": false, + "closeEmitted": false + }, + "allowHalfOpen": false, + "_sockname": null, + "_pendingData": null, + "_pendingEncoding": "", + "_server": null, + "ssl": { + "_parent": { + "reading": true, + "onconnection": null + }, + "_secureContext": { + "context": {} + }, + "reading": true + }, + "_requestCert": true, + "_rejectUnauthorized": true, + "parser": null, + "_httpMessage": null, + "timeout": 0 + } + ] + }, + "keepAliveMsecs": 10000, + "keepAlive": true, + "maxSockets": null, + "maxFreeSockets": 256, + "scheduling": "lifo", + "maxTotalSockets": null, + "totalSocketCount": 2, + "maxCachedSessions": 100, + "_sessionCache": { + "map": { + "api.telegram.org:443:::::::::::::::::::::": { + "type": "Buffer", + "data": [ + 48, + 130, + 8, + 51, + 2, + 1, + 1, + 2, + 2, + 3, + 4, + 4, + 2, + 19, + 2, + 4, + 32, + 115, + 64, + 227, + 66, + 58, + 149, + 105, + 85, + 239, + 246, + 207, + 73, + 6, + 113, + 104, + 72, + 91, + 65, + 237, + 145, + 15, + 232, + 0, + 165, + 158, + 207, + 69, + 121, + 37, + 3, + 86, + 23, + 4, + 48, + 116, + 131, + 217, + 130, + 92, + 49, + 241, + 229, + 129, + 139, + 122, + 11, + 222, + 185, + 28, + 198, + 208, + 169, + 44, + 252, + 195, + 102, + 172, + 249, + 165, + 26, + 166, + 242, + 75, + 220, + 13, + 201, + 215, + 127, + 170, + 158, + 158, + 117, + 140, + 40, + 192, + 68, + 187, + 229, + 169, + 161, + 88, + 250, + 161, + 6, + 2, + 4, + 101, + 19, + 79, + 224, + 162, + 4, + 2, + 2, + 28, + 32, + 163, + 130, + 6, + 160, + 48, + 130, + 6, + 156, + 48, + 130, + 5, + 132, + 160, + 3, + 2, + 1, + 2, + 2, + 9, + 0, + 164, + 96, + 110, + 62, + 174, + 68, + 162, + 62, + 48, + 13, + 6, + 9, + 42, + 134, + 72, + 134, + 247, + 13, + 1, + 1, + 11, + 5, + 0, + 48, + 129, + 180, + 49, + 11, + 48, + 9, + 6, + 3, + 85, + 4, + 6, + 19, + 2, + 85, + 83, + 49, + 16, + 48, + 14, + 6, + 3, + 85, + 4, + 8, + 19, + 7, + 65, + 114, + 105, + 122, + 111, + 110, + 97, + 49, + 19, + 48, + 17, + 6, + 3, + 85, + 4, + 7, + 19, + 10, + 83, + 99, + 111, + 116, + 116, + 115, + 100, + 97, + 108, + 101, + 49, + 26, + 48, + 24, + 6, + 3, + 85, + 4, + 10, + 19, + 17, + 71, + 111, + 68, + 97, + 100, + 100, + 121, + 46, + 99, + 111, + 109, + 44, + 32, + 73, + 110, + 99, + 46, + 49, + 45, + 48, + 43, + 6, + 3, + 85, + 4, + 11, + 19, + 36, + 104, + 116, + 116, + 112, + 58, + 47, + 47, + 99, + 101, + 114, + 116, + 115, + 46, + 103, + 111, + 100, + 97, + 100, + 100, + 121, + 46, + 99, + 111, + 109, + 47, + 114, + 101, + 112, + 111, + 115, + 105, + 116, + 111, + 114, + 121, + 47, + 49, + 51, + 48, + 49, + 6, + 3, + 85, + 4, + 3, + 19, + 42, + 71, + 111, + 32, + 68, + 97, + 100, + 100, + 121, + 32, + 83, + 101, + 99, + 117, + 114, + 101, + 32, + 67, + 101, + 114, + 116, + 105, + 102, + 105, + 99, + 97, + 116, + 101, + 32, + 65, + 117, + 116, + 104, + 111, + 114, + 105, + 116, + 121, + 32, + 45, + 32, + 71, + 50, + 48, + 30, + 23, + 13, + 50, + 51, + 48, + 51, + 50, + 54, + 48, + 55, + 51, + 57, + 49, + 56, + 90, + 23, + 13, + 50, + 52, + 48, + 52, + 50, + 54, + 48, + 55, + 51, + 57, + 49, + 56, + 90, + 48, + 27, + 49, + 25, + 48, + 23, + 6, + 3, + 85, + 4, + 3, + 19, + 16, + 97, + 112, + 105, + 46, + 116, + 101, + 108, + 101, + 103, + 114, + 97, + 109, + 46, + 111, + 114, + 103, + 48, + 130, + 1, + 34, + 48, + 13, + 6, + 9, + 42, + 134, + 72, + 134, + 247, + 13, + 1, + 1, + 1, + 5, + 0, + 3, + 130, + 1, + 15, + 0, + 48, + 130, + 1, + 10, + 2, + 130, + 1, + 1, + 0, + 180, + 163, + 22, + 158, + 92, + 87, + 201, + 137, + 101, + 237, + 234, + 120, + 11, + 174, + 138, + 88, + 47, + 174, + 90, + 200, + 110, + 73, + 141, + 252, + 87, + 165, + 152, + 136, + 120, + 46, + 11, + 60, + 64, + 60, + 33, + 46, + 154, + 148, + 152, + 51, + 167, + 227, + 66, + 167, + 133, + 250, + 208, + 115, + 132, + 1, + 28, + 114, + 57, + 55, + 35, + 181, + 86, + 29, + 67, + 165, + 113, + 20, + 8, + 36, + 165, + 57, + 204, + 222, + 88, + 83, + 148, + 142, + 42, + 66, + 167, + 78, + 45, + 7, + 50, + 158, + 186, + 139, + 211, + 42, + 169, + 158, + 192, + 227, + 206, + 154, + 16, + 150, + 69, + 88, + 122, + 199, + 30, + 69, + 20, + 35, + 146, + 187, + 84, + 130, + 136, + 148, + 73, + 182, + 190, + 129, + 33, + 0, + 41, + 109, + 201, + 206, + 139, + 57, + 58, + 220, + 53, + 21, + 217, + 235, + 71, + 156, + 239, + 186, + 9, + 14, + 22, + 228, + 217, + 235, + 114, + 48, + 250, + 73, + 171, + 152, + 49, + 124, + 179, + 172, + 43, + 41, + 145, + 135, + 8, + 65, + 114, + 94, + 53, + 199, + 135, + 4, + 34, + 245, + 72, + 118, + 48, + 109, + 136, + 223, + 242, + 165, + 41, + 19, + 112, + 179, + 135, + 2, + 213, + 107, + 88, + 177, + 232, + 115, + 199, + 228, + 239, + 121, + 134, + 164, + 7, + 95, + 103, + 180, + 121, + 141, + 164, + 37, + 1, + 130, + 140, + 224, + 48, + 23, + 203, + 75, + 92, + 251, + 235, + 76, + 18, + 81, + 185, + 201, + 4, + 31, + 126, + 210, + 248, + 186, + 245, + 53, + 141, + 138, + 28, + 55, + 130, + 240, + 21, + 115, + 0, + 110, + 61, + 28, + 118, + 139, + 1, + 116, + 129, + 61, + 228, + 44, + 167, + 204, + 47, + 102, + 220, + 68, + 168, + 39, + 63, + 234, + 208, + 167, + 168, + 241, + 203, + 234, + 218, + 7, + 56, + 189, + 2, + 3, + 1, + 0, + 1, + 163, + 130, + 3, + 71, + 48, + 130, + 3, + 67, + 48, + 12, + 6, + 3, + 85, + 29, + 19, + 1, + 1, + 255, + 4, + 2, + 48, + 0, + 48, + 29, + 6, + 3, + 85, + 29, + 37, + 4, + 22, + 48, + 20, + 6, + 8, + 43, + 6, + 1, + 5, + 5, + 7, + 3, + 1, + 6, + 8, + 43, + 6, + 1, + 5, + 5, + 7, + 3, + 2, + 48, + 14, + 6, + 3, + 85, + 29, + 15, + 1, + 1, + 255, + 4, + 4, + 3, + 2, + 5, + 160, + 48, + 56, + 6, + 3, + 85, + 29, + 31, + 4, + 49, + 48, + 47, + 48, + 45, + 160, + 43, + 160, + 41, + 134, + 39, + 104, + 116, + 116, + 112, + 58, + 47, + 47, + 99, + 114, + 108, + 46, + 103, + 111, + 100, + 97, + 100, + 100, + 121, + 46, + 99, + 111, + 109, + 47, + 103, + 100, + 105, + 103, + 50, + 115, + 49, + 45, + 53, + 51, + 57, + 53, + 46, + 99, + 114, + 108, + 48, + 93, + 6, + 3, + 85, + 29, + 32, + 4, + 86, + 48, + 84, + 48, + 72, + 6, + 11, + 96, + 134, + 72, + 1, + 134, + 253, + 109, + 1, + 7, + 23, + 1, + 48, + 57, + 48, + 55, + 6, + 8, + 43, + 6, + 1, + 5, + 5, + 7, + 2, + 1, + 22, + 43, + 104, + 116, + 116, + 112, + 58, + 47, + 47, + 99, + 101, + 114, + 116, + 105, + 102, + 105, + 99, + 97, + 116, + 101, + 115, + 46, + 103, + 111, + 100, + 97, + 100, + 100, + 121, + 46, + 99, + 111, + 109, + 47, + 114, + 101, + 112, + 111, + 115, + 105, + 116, + 111, + 114, + 121, + 47, + 48, + 8, + 6, + 6, + 103, + 129, + 12, + 1, + 2, + 1, + 48, + 118, + 6, + 8, + 43, + 6, + 1, + 5, + 5, + 7, + 1, + 1, + 4, + 106, + 48, + 104, + 48, + 36, + 6, + 8, + 43, + 6, + 1, + 5, + 5, + 7, + 48, + 1, + 134, + 24, + 104, + 116, + 116, + 112, + 58, + 47, + 47, + 111, + 99, + 115, + 112, + 46, + 103, + 111, + 100, + 97, + 100, + 100, + 121, + 46, + 99, + 111, + 109, + 47, + 48, + 64, + 6, + 8, + 43, + 6, + 1, + 5, + 5, + 7, + 48, + 2, + 134, + 52, + 104, + 116, + 116, + 112, + 58, + 47, + 47, + 99, + 101, + 114, + 116, + 105, + 102, + 105, + 99, + 97, + 116, + 101, + 115, + 46, + 103, + 111, + 100, + 97, + 100, + 100, + 121, + 46, + 99, + 111, + 109, + 47, + 114, + 101, + 112, + 111, + 115, + 105, + 116, + 111, + 114, + 121, + 47, + 103, + 100, + 105, + 103, + 50, + 46, + 99, + 114, + 116, + 48, + 31, + 6, + 3, + 85, + 29, + 35, + 4, + 24, + 48, + 22, + 128, + 20, + 64, + 194, + 189, + 39, + 142, + 204, + 52, + 131, + 48, + 162, + 51, + 215, + 251, + 108, + 179, + 240, + 180, + 44, + 128, + 206, + 48, + 49, + 6, + 3, + 85, + 29, + 17, + 4, + 42, + 48, + 40, + 130, + 16, + 97, + 112, + 105, + 46, + 116, + 101, + 108, + 101, + 103, + 114, + 97, + 109, + 46, + 111, + 114, + 103, + 130, + 20, + 119, + 119, + 119, + 46, + 97, + 112, + 105, + 46, + 116, + 101, + 108, + 101, + 103, + 114, + 97, + 109, + 46, + 111, + 114, + 103, + 48, + 29, + 6, + 3, + 85, + 29, + 14, + 4, + 22, + 4, + 20, + 5, + 20, + 208, + 192, + 195, + 239, + 14, + 148, + 187, + 33, + 153, + 231, + 163, + 54, + 92, + 40, + 119, + 48, + 150, + 213, + 48, + 130, + 1, + 126, + 6, + 10, + 43, + 6, + 1, + 4, + 1, + 214, + 121, + 2, + 4, + 2, + 4, + 130, + 1, + 110, + 4, + 130, + 1, + 106, + 1, + 104, + 0, + 118, + 0, + 238, + 205, + 208, + 100, + 213, + 219, + 26, + 206, + 197, + 92, + 183, + 157, + 180, + 205, + 19, + 162, + 50, + 135, + 70, + 124, + 188, + 236, + 222, + 195, + 81, + 72, + 89, + 70, + 113, + 31, + 181, + 155, + 0, + 0, + 1, + 135, + 28, + 219, + 122, + 227, + 0, + 0, + 4, + 3, + 0, + 71, + 48, + 69, + 2, + 32, + 50, + 191, + 9, + 112, + 138, + 110, + 88, + 152, + 46, + 199, + 97, + 31, + 100, + 211, + 251, + 20, + 83, + 216, + 13, + 55, + 189, + 104, + 176, + 220, + 79, + 124, + 144, + 73, + 113, + 174, + 150, + 109, + 2, + 33, + 0, + 138, + 223, + 27, + 8, + 53, + 108, + 26, + 182, + 181, + 74, + 159, + 109, + 74, + 137, + 86, + 61, + 40, + 35, + 252, + 193, + 176, + 57, + 212, + 145, + 247, + 139, + 240, + 89, + 61, + 88, + 176, + 211, + 0, + 119, + 0, + 72, + 176, + 227, + 107, + 218, + 166, + 71, + 52, + 15, + 229, + 106, + 2, + 250, + 157, + 48, + 235, + 28, + 82, + 1, + 203, + 86, + 221, + 44, + 129, + 217, + 187, + 191, + 171, + 57, + 216, + 132, + 115, + 0, + 0, + 1, + 135, + 28, + 219, + 123, + 188, + 0, + 0, + 4, + 3, + 0, + 72, + 48, + 70, + 2, + 33, + 0, + 199, + 191, + 203, + 210, + 140, + 109, + 147, + 9, + 6, + 126, + 162, + 136, + 200, + 107, + 63, + 240, + 155, + 133, + 143, + 148, + 9, + 63, + 225, + 230, + 175, + 220, + 20, + 118, + 185, + 214, + 156, + 78, + 2, + 33, + 0, + 162, + 118, + 162, + 21, + 237, + 133, + 249, + 71, + 114, + 217, + 121, + 211, + 17, + 138, + 175, + 119, + 194, + 166, + 168, + 139, + 88, + 219, + 155, + 218, + 72, + 128, + 1, + 80, + 146, + 41, + 134, + 30, + 0, + 117, + 0, + 218, + 182, + 191, + 107, + 63, + 181, + 182, + 34, + 159, + 155, + 194, + 187, + 92, + 107, + 232, + 112, + 145, + 113, + 108, + 187, + 81, + 132, + 133, + 52, + 189, + 164, + 61, + 48, + 72, + 215, + 251, + 171, + 0, + 0, + 1, + 135, + 28, + 219, + 124, + 45, + 0, + 0, + 4, + 3, + 0, + 70, + 48, + 68, + 2, + 32, + 37, + 240, + 252, + 198, + 52, + 50, + 188, + 253, + 37, + 238, + 233, + 249, + 212, + 93, + 25, + 184, + 83, + 191, + 55, + 199, + 96, + 216, + 209, + 71, + 110, + 40, + 164, + 226, + 103, + 70, + 158, + 124, + 2, + 32, + 96, + 253, + 231, + 235, + 124, + 165, + 102, + 237, + 109, + 96, + 186, + 86, + 113, + 81, + 222, + 198, + 203, + 137, + 97, + 143, + 90, + 204, + 179, + 188, + 143, + 94, + 197, + 79, + 86, + 77, + 169, + 225, + 48, + 13, + 6, + 9, + 42, + 134, + 72, + 134, + 247, + 13, + 1, + 1, + 11, + 5, + 0, + 3, + 130, + 1, + 1, + 0, + 34, + 168, + 129, + 97, + 123, + 197, + 117, + 113, + 26, + 200, + 92, + 120, + 44, + 65, + 168, + 60, + 154, + 179, + 244, + 11, + 112, + 79, + 39, + 12, + 185, + 203, + 236, + 10, + 135, + 103, + 232, + 44, + 130, + 236, + 25, + 66, + 168, + 36, + 137, + 230, + 93, + 228, + 203, + 8, + 66, + 156, + 245, + 76, + 83, + 15, + 238, + 168, + 191, + 202, + 217, + 246, + 142, + 63, + 71, + 125, + 82, + 14, + 235, + 200, + 248, + 101, + 49, + 168, + 207, + 126, + 104, + 187, + 40, + 90, + 85, + 88, + 162, + 124, + 146, + 85, + 246, + 112, + 200, + 179, + 106, + 116, + 103, + 5, + 210, + 203, + 76, + 228, + 149, + 33, + 142, + 90, + 242, + 150, + 124, + 142, + 1, + 184, + 73, + 27, + 14, + 245, + 199, + 189, + 34, + 204, + 140, + 33, + 248, + 206, + 73, + 145, + 12, + 71, + 131, + 24, + 110, + 126, + 125, + 212, + 80, + 142, + 44, + 114, + 212, + 27, + 33, + 186, + 223, + 30, + 165, + 78, + 129, + 112, + 240, + 108, + 14, + 249, + 243, + 245, + 17, + 50, + 134, + 28, + 243, + 173, + 31, + 32, + 219, + 37, + 229, + 160, + 174, + 56, + 199, + 37, + 255, + 58, + 254, + 126, + 136, + 60, + 178, + 16, + 115, + 155, + 240, + 194, + 237, + 107, + 57, + 43, + 124, + 1, + 118, + 3, + 109, + 251, + 55, + 5, + 244, + 24, + 172, + 200, + 248, + 225, + 20, + 223, + 243, + 94, + 208, + 209, + 10, + 232, + 230, + 84, + 131, + 122, + 253, + 36, + 4, + 161, + 131, + 183, + 4, + 105, + 195, + 123, + 2, + 27, + 74, + 244, + 109, + 190, + 51, + 191, + 208, + 127, + 192, + 119, + 224, + 199, + 166, + 245, + 12, + 48, + 91, + 245, + 56, + 137, + 152, + 77, + 179, + 68, + 227, + 32, + 160, + 97, + 62, + 30, + 199, + 129, + 123, + 43, + 27, + 31, + 38, + 143, + 179, + 181, + 166, + 122, + 164, + 2, + 4, + 0, + 166, + 18, + 4, + 16, + 97, + 112, + 105, + 46, + 116, + 101, + 108, + 101, + 103, + 114, + 97, + 109, + 46, + 111, + 114, + 103, + 169, + 4, + 2, + 2, + 2, + 88, + 170, + 129, + 243, + 4, + 129, + 240, + 86, + 66, + 161, + 237, + 13, + 127, + 69, + 148, + 53, + 137, + 136, + 30, + 56, + 41, + 120, + 154, + 91, + 238, + 236, + 139, + 172, + 51, + 34, + 252, + 57, + 111, + 157, + 9, + 31, + 137, + 252, + 117, + 23, + 38, + 58, + 224, + 119, + 65, + 191, + 216, + 21, + 0, + 243, + 77, + 104, + 44, + 103, + 154, + 21, + 213, + 60, + 11, + 37, + 142, + 36, + 179, + 78, + 230, + 179, + 233, + 254, + 136, + 160, + 150, + 169, + 54, + 7, + 80, + 42, + 58, + 180, + 99, + 210, + 126, + 24, + 223, + 180, + 107, + 115, + 214, + 238, + 62, + 9, + 55, + 239, + 47, + 163, + 77, + 43, + 191, + 137, + 152, + 199, + 176, + 164, + 98, + 189, + 136, + 78, + 35, + 253, + 163, + 201, + 111, + 47, + 134, + 28, + 253, + 100, + 150, + 214, + 177, + 70, + 166, + 78, + 39, + 128, + 88, + 219, + 231, + 4, + 90, + 62, + 157, + 17, + 58, + 58, + 175, + 170, + 196, + 86, + 1, + 81, + 23, + 194, + 147, + 180, + 39, + 93, + 160, + 89, + 93, + 213, + 16, + 48, + 105, + 133, + 145, + 209, + 194, + 217, + 229, + 103, + 199, + 69, + 48, + 248, + 210, + 199, + 128, + 55, + 118, + 243, + 239, + 161, + 135, + 176, + 157, + 145, + 44, + 101, + 61, + 200, + 81, + 180, + 46, + 39, + 210, + 233, + 37, + 46, + 72, + 56, + 173, + 20, + 103, + 184, + 138, + 62, + 223, + 195, + 7, + 186, + 211, + 191, + 143, + 138, + 10, + 131, + 236, + 57, + 109, + 250, + 53, + 151, + 229, + 181, + 205, + 19, + 151, + 196, + 211, + 114, + 5, + 219, + 201, + 229, + 220, + 176, + 136, + 177, + 15, + 91, + 24, + 211, + 87, + 65, + 218, + 252, + 249, + 15, + 217, + 160, + 47, + 111, + 196, + 94, + 52, + 225, + 167, + 174, + 7, + 2, + 5, + 0, + 218, + 165, + 102, + 102, + 179, + 3, + 2, + 1, + 29 + ] + } + }, + "list": [ + "api.telegram.org:443:::::::::::::::::::::" + ] + } + }, + "testEnv": false + } + }, + "botInfo": { + "id": 6489664401, + "is_bot": true, + "first_name": "CampFire", + "username": "CampFireGameBot", + "can_join_groups": true, + "can_read_all_group_messages": false, + "supports_inline_queries": false + }, + "state": {}, + "match": [ + "{type: business_invite_accept", + "accept" + ] +} \ No newline at end of file diff --git a/json/rarecars.json b/json/rarecars.json index cfa8033..4f2b2b9 100644 --- a/json/rarecars.json +++ b/json/rarecars.json @@ -93,5 +93,10 @@ "name": "Ferrari F8", "price": 34000000, "image": "https://avatars.mds.yandex.net/get-autoru-vos/2037331/cd075cbfc2d10c05bb0450dcc889d351/1200x900n" + }, + { + "name": "Mercedes-Benz AMG GT S, 2017", + "price": 10500000, + "image": "https://avatars.mds.yandex.net/get-autoru-vos/2159790/270111424b42001ae010abc3367bcda9/1200x900n" } ] \ No newline at end of file diff --git a/json/simplecars.json b/json/simplecars.json index cc30e92..a5e8be7 100644 --- a/json/simplecars.json +++ b/json/simplecars.json @@ -53,5 +53,10 @@ "name": "Mazda 3", "price": 500000, "image": "https://a.d-cd.net/da371e4s-1920.jpg" + }, + { + "name": "Hot Wheels Lamborghini Sian FKP 37 Orange Коллекционная", + "price": 1000, + "image": "https://ir.ozone.ru/s3/multimedia-4/wc700/6769855444.jpg" } ] \ No newline at end of file diff --git a/json/weaponshop.json b/json/weaponshop.json index 6200cb1..dea5b33 100644 --- a/json/weaponshop.json +++ b/json/weaponshop.json @@ -1,52 +1,57 @@ { "0": { - "name": "M1911", - "price": 13000, + "name": "HK UMP", + "price": 33999, + "damage": 0.028, "type": "weapon" }, "1": { - "name": "ПМ", - "price": 13000, + "name": "Glock 17", + "price": 7999, + "damage": 0.013, "type": "weapon" }, "2": { - "name": "АКС74У", - "price": 34999, + "name": "HK UMP", + "price": 33999, + "damage": 0.028, "type": "weapon" }, "3": { - "name": "G36C", - "price": 38999, + "name": "АКС74У", + "price": 34999, + "damage": 0.031, "type": "weapon" }, "4": { - "name": "G36C", - "price": 38999, + "name": "M1911", + "price": 13000, + "damage": 0.018, "type": "weapon" }, "5": { - "name": "Бронежилет M1", - "price": 25000, + "name": "Шлем танкиста", + "price": 1000, "type": "equipment" }, "6": { - "name": "Бронежилет M2", - "price": 35000, + "name": "Бронежилет M5", + "price": 1000, "type": "equipment" }, "7": { - "name": "Бронежилет M1", - "price": 25000, + "name": "Бронежилет M4", + "price": 1000, "type": "equipment" }, "8": { - "name": "Бронежилет M2", - "price": 35000, + "name": "Бронежилет M5", + "price": 1000, "type": "equipment" }, "9": { - "name": "Бронежилет M3", - "price": 60000, + "name": "Кольчуга", + "price": 1000, "type": "equipment" } } \ No newline at end of file diff --git a/media/Thumbs.db b/media/Thumbs.db new file mode 100644 index 0000000..db80c43 Binary files /dev/null and b/media/Thumbs.db differ diff --git a/media/image.png b/media/image.png index 4a43875..facd116 100644 Binary files a/media/image.png and b/media/image.png differ diff --git a/package-lock.json b/package-lock.json index 5df0f93..23a0498 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,11 +12,13 @@ "canvas": "^2.11.2", "date-fns": "^2.30.0", "dotenv": "^16.3.1", + "error-stack-parser": "^2.1.4", "fs": "^0.0.1-security", "node-telegram-bot-api": "^0.52.0", "nodemon": "^2.0.7", "pg": "^8.6.0", "pg-hstore": "^2.3.3", + "pm2": "^5.3.0", "prettytable": "^0.3.1", "sequelize": "^6.6.2", "shortid": "^2.2.16", @@ -83,6 +85,272 @@ "node": ">=10" } }, + "node_modules/@opencensus/core": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.9.tgz", + "integrity": "sha512-31Q4VWtbzXpVUd2m9JS6HEaPjlKvNMOiF7lWKNmXF84yUcgfAFL5re7/hjDmdyQbOp32oGc+RFV78jXIldVz6Q==", + "dependencies": { + "continuation-local-storage": "^3.2.1", + "log-driver": "^1.2.7", + "semver": "^5.5.0", + "shimmer": "^1.2.0", + "uuid": "^3.2.1" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/@opencensus/core/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@opencensus/propagation-b3": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@opencensus/propagation-b3/-/propagation-b3-0.0.8.tgz", + "integrity": "sha512-PffXX2AL8Sh0VHQ52jJC4u3T0H6wDK6N/4bg7xh4ngMYOIi13aR1kzVvX1sVDBgfGwDOkMbl4c54Xm3tlPx/+A==", + "dependencies": { + "@opencensus/core": "^0.0.8", + "uuid": "^3.2.1" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/@opencensus/propagation-b3/node_modules/@opencensus/core": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.8.tgz", + "integrity": "sha512-yUFT59SFhGMYQgX0PhoTR0LBff2BEhPrD9io1jWfF/VDbakRfs6Pq60rjv0Z7iaTav5gQlttJCX2+VPxFWCuoQ==", + "dependencies": { + "continuation-local-storage": "^3.2.1", + "log-driver": "^1.2.7", + "semver": "^5.5.0", + "shimmer": "^1.2.0", + "uuid": "^3.2.1" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/@opencensus/propagation-b3/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@pm2/agent": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.3.tgz", + "integrity": "sha512-xkqqCoTf5VsciMqN0vb9jthW7olVAi4KRFNddCc7ZkeJZ3i8QwZANr4NSH2H5DvseRFHq7MiPspRY/EWAFWWTg==", + "dependencies": { + "async": "~3.2.0", + "chalk": "~3.0.0", + "dayjs": "~1.8.24", + "debug": "~4.3.1", + "eventemitter2": "~5.0.1", + "fast-json-patch": "^3.0.0-1", + "fclone": "~1.0.11", + "nssocket": "0.6.0", + "pm2-axon": "~4.0.1", + "pm2-axon-rpc": "~0.7.0", + "proxy-agent": "~6.3.0", + "semver": "~7.5.0", + "ws": "~7.4.0" + } + }, + "node_modules/@pm2/agent/node_modules/dayjs": { + "version": "1.8.36", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", + "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==" + }, + "node_modules/@pm2/agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@pm2/agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@pm2/agent/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@pm2/io": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@pm2/io/-/io-5.0.2.tgz", + "integrity": "sha512-XAvrNoQPKOyO/jJyCu8jPhLzlyp35MEf7w/carHXmWKddPzeNOFSEpSEqMzPDawsvpxbE+i918cNN+MwgVsStA==", + "dependencies": { + "@opencensus/core": "0.0.9", + "@opencensus/propagation-b3": "0.0.8", + "async": "~2.6.1", + "debug": "~4.3.1", + "eventemitter2": "^6.3.1", + "require-in-the-middle": "^5.0.0", + "semver": "~7.5.4", + "shimmer": "^1.2.0", + "signal-exit": "^3.0.3", + "tslib": "1.9.3" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/@pm2/io/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/@pm2/io/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@pm2/io/node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" + }, + "node_modules/@pm2/io/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@pm2/io/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@pm2/js-api": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.6.7.tgz", + "integrity": "sha512-jiJUhbdsK+5C4zhPZNnyA3wRI01dEc6a2GhcQ9qI38DyIk+S+C8iC3fGjcjUbt/viLYKPjlAaE+hcT2/JMQPXw==", + "dependencies": { + "async": "^2.6.3", + "axios": "^0.21.0", + "debug": "~4.3.1", + "eventemitter2": "^6.3.1", + "ws": "^7.0.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@pm2/js-api/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/@pm2/js-api/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@pm2/js-api/node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" + }, + "node_modules/@pm2/js-api/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@pm2/pm2-version-check": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz", + "integrity": "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==", + "dependencies": { + "debug": "^4.3.1" + } + }, + "node_modules/@pm2/pm2-version-check/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@pm2/pm2-version-check/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -107,6 +375,11 @@ "resolved": "https://registry.npmjs.org/@telegraf/types/-/types-6.8.1.tgz", "integrity": "sha512-JCRQuPPDCreYQaAeOwnqIlWrs8pJVvaNEUWBVNvdK3oJoTUKyBV+3TsPrIcnGqLeapptznuTk5s4udTlZPvGTA==" }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==" + }, "node_modules/@types/node": { "version": "14.14.41", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.41.tgz", @@ -175,6 +448,19 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/amp": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz", + "integrity": "sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw==" + }, + "node_modules/amp-message": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz", + "integrity": "sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg==", + "dependencies": { + "amp": "0.3.1" + } + }, "node_modules/ansi-align": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", @@ -196,6 +482,14 @@ "node": ">=6" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", @@ -265,6 +559,19 @@ "node": ">= 6" } }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/argparse/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, "node_modules/array.prototype.findindex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array.prototype.findindex/-/array.prototype.findindex-2.1.0.tgz", @@ -290,6 +597,39 @@ "node": ">=0.8" } }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ast-types/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/async-listener": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", + "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "dependencies": { + "semver": "^5.3.0", + "shimmer": "^1.1.0" + }, + "engines": { + "node": "<=0.11.8 || >0.11.10" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -308,11 +648,27 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/basic-ftp": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.3.tgz", + "integrity": "sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -338,11 +694,27 @@ "safe-buffer": "^5.1.1" } }, + "node_modules/blessed": { + "version": "0.1.81", + "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", + "integrity": "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==", + "bin": { + "blessed": "bin/tput.js" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, + "node_modules/bodec": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz", + "integrity": "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==" + }, "node_modules/boxen": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", @@ -403,6 +775,11 @@ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, "node_modules/buffer-writer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", @@ -529,24 +906,35 @@ "node": ">=8" } }, + "node_modules/charm": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", + "integrity": "sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==" + }, "node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "glob-parent": "~5.1.0", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { - "fsevents": "~2.3.1" + "fsevents": "~2.3.2" } }, "node_modules/chownr": { @@ -573,6 +961,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-tableau": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz", + "integrity": "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==", + "dependencies": { + "chalk": "3.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", @@ -616,6 +1015,11 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -642,11 +1046,25 @@ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, + "node_modules/continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "dependencies": { + "async-listener": "^0.6.0", + "emitter-listener": "^1.1.1" + } + }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "node_modules/croner": { + "version": "4.1.97", + "resolved": "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz", + "integrity": "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==" + }, "node_modules/crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", @@ -660,6 +1078,11 @@ "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.5.0.tgz", "integrity": "sha512-RxruSK3M4XgzcD7Trm2wEN+SJ26ChIb903+IWxNOcB5q4jT2Cs+hFr6QP39J05EohshRFEvyzEBoZ/466S2sbw==" }, + "node_modules/culvert": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz", + "integrity": "sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==" + }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -671,6 +1094,14 @@ "node": ">=0.10" } }, + "node_modules/data-uri-to-buffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-5.0.1.tgz", + "integrity": "sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg==", + "engines": { + "node": ">= 14" + } + }, "node_modules/date-fns": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", @@ -686,6 +1117,11 @@ "url": "https://opencollective.com/date-fns" } }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, "node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -729,6 +1165,19 @@ "node": ">= 0.4" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -799,6 +1248,14 @@ "safer-buffer": "^2.1.0" } }, + "node_modules/emitter-listener": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "dependencies": { + "shimmer": "^1.2.0" + } + }, "node_modules/emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -812,6 +1269,25 @@ "once": "^1.4.0" } }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "dependencies": { + "stackframe": "^1.3.4" + } + }, "node_modules/es-abstract": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", @@ -865,6 +1341,65 @@ "node": ">=8" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -873,6 +1408,11 @@ "node": ">=6" } }, + "node_modules/eventemitter2": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", + "integrity": "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==" + }, "node_modules/eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", @@ -896,11 +1436,21 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "node_modules/fast-json-patch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, + "node_modules/fclone": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", + "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==" + }, "node_modules/file-type": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", @@ -920,6 +1470,25 @@ "node": ">=8" } }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -946,6 +1515,19 @@ "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -1062,6 +1644,41 @@ "once": "^1.3.1" } }, + "node_modules/get-uri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.1.tgz", + "integrity": "sha512-7ZqONUVqaabogsYNWlYj0t3YZaL6dhuEueZXGF+/YVmf6dHmaFg8/6psJKqhx9QykIDKzpGcy2cn4oV4YC7V/Q==", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^5.0.1", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/get-uri/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -1070,6 +1687,16 @@ "assert-plus": "^1.0.0" } }, + "node_modules/git-node-fs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-node-fs/-/git-node-fs-1.0.0.tgz", + "integrity": "sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ==" + }, + "node_modules/git-sha1": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/git-sha1/-/git-sha1-0.1.2.tgz", + "integrity": "sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==" + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -1217,6 +1844,50 @@ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, + "node_modules/http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -1264,6 +1935,17 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", @@ -1312,6 +1994,11 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" }, + "node_modules/ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + }, "node_modules/is-bigint": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", @@ -1367,6 +2054,17 @@ "is-ci": "bin.js" } }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", @@ -1534,6 +2232,17 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "node_modules/js-git": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz", + "integrity": "sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==", + "dependencies": { + "bodec": "^0.1.0", + "culvert": "^0.1.2", + "git-sha1": "^0.1.2", + "pako": "^0.2.5" + } + }, "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -1559,6 +2268,14 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -1592,11 +2309,27 @@ "node": ">=8" } }, + "node_modules/lazy": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", + "integrity": "sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==", + "engines": { + "node": ">=0.2.0" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "engines": { + "node": ">=0.8.6" + } + }, "node_modules/lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -1734,6 +2467,11 @@ "node": ">=10" } }, + "node_modules/module-details-from-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", + "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" + }, "node_modules/moment": { "version": "2.29.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", @@ -1766,6 +2504,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, "node_modules/nan": { "version": "2.18.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", @@ -1776,6 +2519,30 @@ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" }, + "node_modules/needle": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", + "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -1885,6 +2652,23 @@ "set-blocking": "^2.0.0" } }, + "node_modules/nssocket": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.6.0.tgz", + "integrity": "sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==", + "dependencies": { + "eventemitter2": "~0.4.14", + "lazy": "~1.0.11" + }, + "engines": { + "node": ">= 0.10.x" + } + }, + "node_modules/nssocket/node_modules/eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==" + }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -1958,6 +2742,81 @@ "node": ">=10" } }, + "node_modules/pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/pac-resolver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", + "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", + "dependencies": { + "degenerator": "^5.0.0", + "ip": "^1.1.8", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/package-json": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", @@ -1985,6 +2844,11 @@ "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" }, + "node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==" + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1993,6 +2857,11 @@ "node": ">=0.10.0" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -2094,6 +2963,235 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidusage": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-3.0.2.tgz", + "integrity": "sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==", + "dependencies": { + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pm2": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.3.0.tgz", + "integrity": "sha512-xscmQiAAf6ArVmKhjKTeeN8+Td7ZKnuZFFPw1DGkdFPR/0Iyx+m+1+OpCdf9+HQopX3VPc9/wqPQHqVOfHum9w==", + "dependencies": { + "@pm2/agent": "~2.0.0", + "@pm2/io": "~5.0.0", + "@pm2/js-api": "~0.6.7", + "@pm2/pm2-version-check": "latest", + "async": "~3.2.0", + "blessed": "0.1.81", + "chalk": "3.0.0", + "chokidar": "^3.5.3", + "cli-tableau": "^2.0.0", + "commander": "2.15.1", + "croner": "~4.1.92", + "dayjs": "~1.11.5", + "debug": "^4.3.1", + "enquirer": "2.3.6", + "eventemitter2": "5.0.1", + "fclone": "1.0.11", + "mkdirp": "1.0.4", + "needle": "2.4.0", + "pidusage": "~3.0", + "pm2-axon": "~4.0.1", + "pm2-axon-rpc": "~0.7.1", + "pm2-deploy": "~1.0.2", + "pm2-multimeter": "^0.1.2", + "promptly": "^2", + "semver": "^7.2", + "source-map-support": "0.5.21", + "sprintf-js": "1.1.2", + "vizion": "~2.2.1", + "yamljs": "0.3.0" + }, + "bin": { + "pm2": "bin/pm2", + "pm2-dev": "bin/pm2-dev", + "pm2-docker": "bin/pm2-docker", + "pm2-runtime": "bin/pm2-runtime" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "pm2-sysmonit": "^1.2.8" + } + }, + "node_modules/pm2-axon": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pm2-axon/-/pm2-axon-4.0.1.tgz", + "integrity": "sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg==", + "dependencies": { + "amp": "~0.3.1", + "amp-message": "~0.1.1", + "debug": "^4.3.1", + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=5" + } + }, + "node_modules/pm2-axon-rpc": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.7.1.tgz", + "integrity": "sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==", + "dependencies": { + "debug": "^4.3.1" + }, + "engines": { + "node": ">=5" + } + }, + "node_modules/pm2-axon-rpc/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/pm2-axon-rpc/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/pm2-axon/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/pm2-axon/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/pm2-deploy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz", + "integrity": "sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==", + "dependencies": { + "run-series": "^1.1.8", + "tv4": "^1.3.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pm2-multimeter": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz", + "integrity": "sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==", + "dependencies": { + "charm": "~0.1.1" + } + }, + "node_modules/pm2-sysmonit": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/pm2-sysmonit/-/pm2-sysmonit-1.2.8.tgz", + "integrity": "sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==", + "optional": true, + "dependencies": { + "async": "^3.2.0", + "debug": "^4.3.1", + "pidusage": "^2.0.21", + "systeminformation": "^5.7", + "tx2": "~1.0.4" + } + }, + "node_modules/pm2-sysmonit/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "optional": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/pm2-sysmonit/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "optional": true + }, + "node_modules/pm2-sysmonit/node_modules/pidusage": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", + "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", + "optional": true, + "dependencies": { + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pm2/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/pm2/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/pm2/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/postgres-array": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", @@ -2150,6 +3248,89 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "node_modules/promptly": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz", + "integrity": "sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==", + "dependencies": { + "read": "^1.0.4" + } + }, + "node_modules/proxy-agent": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", + "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -2210,6 +3391,17 @@ "rc": "cli.js" } }, + "node_modules/read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -2230,9 +3422,9 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dependencies": { "picomatch": "^2.2.1" }, @@ -2339,6 +3531,56 @@ "uuid": "bin/uuid" } }, + "node_modules/require-in-the-middle": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.2.0.tgz", + "integrity": "sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==", + "dependencies": { + "debug": "^4.1.1", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/require-in-the-middle/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/require-in-the-middle/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/resolve": { + "version": "1.22.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", + "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", @@ -2369,6 +3611,25 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-series": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz", + "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2409,6 +3670,11 @@ "node": ">= 0.10" } }, + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, "node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -2535,6 +3801,11 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, "node_modules/shortid": { "version": "2.2.16", "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz", @@ -2600,6 +3871,95 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", + "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socks-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/socks/node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/split2": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", @@ -2621,6 +3981,11 @@ "node": ">= 6" } }, + "node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" + }, "node_modules/sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -2645,6 +4010,11 @@ "node": ">=0.10.0" } }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + }, "node_modules/stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", @@ -2765,6 +4135,43 @@ "node": ">=4" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/systeminformation": { + "version": "5.21.9", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.21.9.tgz", + "integrity": "sha512-7pI4mu9P/2MGDV0T49B52E7IULBGj+kRVk6JSYUj5qfAk7N7C7aNX15fXziqrbgZntc6/jjYzWeb/x41jhg/eA==", + "optional": true, + "os": [ + "darwin", + "linux", + "win32", + "freebsd", + "openbsd", + "netbsd", + "sunos", + "android" + ], + "bin": { + "systeminformation": "lib/cli.js" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "Buy me a coffee", + "url": "https://www.buymeacoffee.com/systeminfo" + } + }, "node_modules/tar": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", @@ -2886,6 +4293,11 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "node_modules/tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -2897,11 +4309,28 @@ "node": "*" } }, + "node_modules/tv4": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", + "integrity": "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "node_modules/tx2": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tx2/-/tx2-1.0.5.tgz", + "integrity": "sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg==", + "optional": true, + "dependencies": { + "json-stringify-safe": "^5.0.1" + } + }, "node_modules/type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", @@ -2969,6 +4398,14 @@ "node": ">=8" } }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/update-notifier": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", @@ -3052,6 +4489,28 @@ "extsprintf": "^1.2.0" } }, + "node_modules/vizion": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vizion/-/vizion-2.2.1.tgz", + "integrity": "sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==", + "dependencies": { + "async": "^2.6.3", + "git-node-fs": "^1.0.0", + "ini": "^1.3.5", + "js-git": "^0.7.8" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/vizion/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dependencies": { + "lodash": "^4.17.14" + } + }, "node_modules/voucher-code-generator": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/voucher-code-generator/-/voucher-code-generator-1.3.0.tgz", @@ -3129,6 +4588,26 @@ "typedarray-to-buffer": "^3.1.5" } }, + "node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", @@ -3149,6 +4628,19 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yamljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "dependencies": { + "argparse": "^1.0.7", + "glob": "^7.0.5" + }, + "bin": { + "json2yaml": "bin/json2yaml", + "yaml2json": "bin/yaml2json" + } } } } diff --git a/package.json b/package.json index 61fbef4..7d4c867 100644 --- a/package.json +++ b/package.json @@ -14,11 +14,13 @@ "canvas": "^2.11.2", "date-fns": "^2.30.0", "dotenv": "^16.3.1", + "error-stack-parser": "^2.1.4", "fs": "^0.0.1-security", "node-telegram-bot-api": "^0.52.0", "nodemon": "^2.0.7", "pg": "^8.6.0", "pg-hstore": "^2.3.3", + "pm2": "^5.3.0", "prettytable": "^0.3.1", "sequelize": "^6.6.2", "shortid": "^2.2.16", diff --git a/run.ps1 b/run.ps1 new file mode 100644 index 0000000..efba662 --- /dev/null +++ b/run.ps1 @@ -0,0 +1,2 @@ +[System.Console]::Title = 'CampFireGame' +nodemon --ignore json/ .\index.js \ No newline at end of file diff --git a/scenes/crime.js b/scenes/crime.js new file mode 100644 index 0000000..977a720 --- /dev/null +++ b/scenes/crime.js @@ -0,0 +1,56 @@ +const { + Scenes, + Markup +} = require('telegraf') + +const crime = new Scenes.BaseScene('Crime'); + +crime.enter((ctx) => { + ctx.reply('Scene: Выберите ограбление', Markup.inlineKeyboard([ + [ + {text: 'Карманные кражи [SOLO]', callback_data: `POCKET_ACTION`}, + {text: 'Магазин', callback_data: `heist`}, + {text: 'Банкомат', callback_data: `heist`}, + {text: 'Банковское отделение', callback_data: `heist`}, + {text: 'Угон', callback_data: `heist`}, + {text: 'Ювелирка', callback_data: `heist`}, + {text: 'Банк', callback_data: `heist`} + ] + ])) +}); + +crime.action(`POCKET_ACTION`, (ctx) => { + ctx.editMessageText('Scene: Выберите объект', Markup.inlineKeyboard([ + [ + {text: 'Карман', callback_data: `POCKET_TARGET`}, + {text: 'Бумажник', callback_data: `heist`}, + {text: 'Сумка', callback_data: `heist`} + ] +])) +}); + +crime.action(`POCKET_TARGET`, (ctx) => { + if(Math.random() < 0.5) return ctx.editMessageText('Scene: Замечен'); + ctx.editMessageText('Scene: В кармане обнаружено', Markup.inlineKeyboard([ + [ + {text: 'Деньги', callback_data: `MONEY`}, + {text: 'Телефон', callback_data: `PHONE`} + ] +])) +}); + +crime.action(`MONEY`, (ctx) => { + if(Math.random() < 0.5) return ctx.editMessageText('Scene: Замечен'); + return ctx.editMessageText('Scene: Успех MONEY') +}); + +crime.action(`PHONE`, (ctx) => { + if(Math.random() < 0.5) return ctx.editMessageText('Scene: Замечен'); + return ctx.editMessageText('Scene: Успех PHONE') +}); + +crime.leave((ctx) => { + console.log('Завершено'); +}); + +module.exports = crime \ No newline at end of file diff --git a/scenes/heist.js b/scenes/heist.js new file mode 100644 index 0000000..f119105 --- /dev/null +++ b/scenes/heist.js @@ -0,0 +1,56 @@ +const { + Scenes, + Markup +} = require('telegraf') + +const heist = new Scenes.BaseScene('HEIST'); + +heist.enter((ctx) => { + ctx.reply('Scene: Выберите ограбление', Markup.inlineKeyboard([ + [ + {text: 'Карманные кражи', callback_data: `POCKET_ACTION`}, + {text: 'Магазин', callback_data: `heist`}, + {text: 'Банкомат', callback_data: `heist`}, + {text: 'Банковское отделение', callback_data: `heist`}, + {text: 'Угон', callback_data: `heist`}, + {text: 'Ювелирка', callback_data: `heist`}, + {text: 'Банк', callback_data: `heist`} + ] + ])) +}); + +heist.action(`POCKET_ACTION`, (ctx) => { + ctx.editMessageText('Scene: Выберите объект', Markup.inlineKeyboard([ + [ + {text: 'Карман', callback_data: `POCKET_TARGET`}, + {text: 'Бумажник', callback_data: `heist`}, + {text: 'Сумка', callback_data: `heist`} + ] +])) +}); + +heist.action(`POCKET_TARGET`, (ctx) => { + if(Math.random() < 0.5) return ctx.editMessageText('Scene: Замечен'); + ctx.editMessageText('Scene: В кармане обнаружено', Markup.inlineKeyboard([ + [ + {text: 'Деньги', callback_data: `MONEY`}, + {text: 'Телефон', callback_data: `PHONE`} + ] +])) +}); + +heist.action(`MONEY`, (ctx) => { + if(Math.random() < 0.5) return ctx.editMessageText('Scene: Замечен'); + return ctx.editMessageText('Scene: Успех MONEY') +}); + +heist.action(`PHONE`, (ctx) => { + if(Math.random() < 0.5) return ctx.editMessageText('Scene: Замечен'); + return ctx.editMessageText('Scene: Успех PHONE') +}); + +heist.leave((ctx) => { + console.log('Завершено'); +}); + +module.exports = heist \ No newline at end of file diff --git a/scenes/index.js b/scenes/index.js new file mode 100644 index 0000000..0b16fe7 --- /dev/null +++ b/scenes/index.js @@ -0,0 +1,17 @@ +const { + Telegraf, + Scenes, + session, + Stage, + Markup +} = require('telegraf') + +const heistStart = require('./heist') +const testStart = require('./test') + +const stage = new Scenes.Stage( + [heistStart] + ) + + +module.exports = stage \ No newline at end of file diff --git a/scenes/test.js b/scenes/test.js new file mode 100644 index 0000000..984bbcd --- /dev/null +++ b/scenes/test.js @@ -0,0 +1,40 @@ +const { + Telegraf, + Scenes, + Markup +} = require('telegraf') + +const test = new Scenes.BaseScene('TEST'); + +test.enter((ctx) => { +ctx.session.myData = {}; + ctx.reply('Scene: Выберите ограбление', Markup.inlineKeyboard([ + [ + {text: 'Карманные кражи', callback_data: `POCKET_ACTION`}, + {text: 'Магазин', callback_data: `heist`}, + {text: 'Банкомат', callback_data: `heist`}, + {text: 'Банковское отделение', callback_data: `heist`}, + {text: 'Угон', callback_data: `heist`}, + {text: 'Ювелирка', callback_data: `heist`}, + {text: 'Банк', callback_data: `heist`} + ] +])); +}); + +test.action(`POCKET_ACTION`, (ctx) => { +ctx.reply('Выбор'); +ctx.session.myData.preferenceType = 'Pocket'; +return ctx.scene.enter('HEIST'); // switch to some other scene +}); + +test.action(`MOVIE_ACTION`, (ctx) => { +ctx.reply('You choose movie, your loss'); +ctx.session.myData.preferenceType = 'Movie'; +return ctx.scene.leave(); // exit global namespace +}); + +test.leave((ctx) => { +ctx.reply('Thank you for your time!'); +}); + +module.exports = test \ No newline at end of file diff --git a/utils/escape.js b/utils/escape.js new file mode 100644 index 0000000..da5f01c --- /dev/null +++ b/utils/escape.js @@ -0,0 +1,22 @@ +module.exports = (text) => { + text = text + .replace(/\_/g, '\\_') + .replace(/\*/g, '\\*') + .replace(/\[/g, '\\[') + .replace(/\]/g, '\\]') + .replace(/\(/g, '\\(') + .replace(/\)/g, '\\)') + .replace(/\~/g, '\\~') + .replace(/\`/g, '\\`') + .replace(/\>/g, '\\>') + .replace(/\#/g, '\\#') + .replace(/\+/g, '\\+') + .replace(/\-/g, '\\-') + .replace(/\=/g, '\\=') + .replace(/\|/g, '\\|') + .replace(/\{/g, '\\{') + .replace(/\}/g, '\\}') + .replace(/\./g, '\\.') + .replace(/\!/g, '\\!'); + return text +} \ No newline at end of file diff --git a/utils/generatePromo.js b/utils/generatePromo.js new file mode 100644 index 0000000..5bcc5ab --- /dev/null +++ b/utils/generatePromo.js @@ -0,0 +1,37 @@ +const { + Telegraf +} = require('telegraf') +const bot = new Telegraf(process.env.BOT_TOKEN) +const { + PromocodeModel, + mainChat +} = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') +const voucher_codes = require('voucher-code-generator'); +const rand = require('./rand') +const generateVoucher = require('./generateVoucher'); +const { promoTopicId } = require('../config'); +module.exports = async () => { + let activs = rand(1, 3) + let give = rand(1000, 10000) + let code = voucher_codes.generate({ + length: 6, + count: 1, + prefix: "CMP-", + postfix: "-FIRE", + charset: voucher_codes.charset("alphanumeric") + }); + let promocode = await PromocodeModel.findOne({ + where: { + code: code[0] + } + }) + if(promocode === null){ + await PromocodeModel.create({ + code: code[0], + activations: activs, + money: give + }) + let voucherImage = await generateVoucher(code[0], activs, give) + return await bot.telegram.sendPhoto(mainChat, {source: voucherImage}, {reply_to_message_id: promoTopicId}) + } +} \ No newline at end of file diff --git a/utils/generateVoucher.js b/utils/generateVoucher.js new file mode 100644 index 0000000..8def5a7 --- /dev/null +++ b/utils/generateVoucher.js @@ -0,0 +1,28 @@ +const { createCanvas, loadImage } = require('canvas'); +const fs = require('fs'); + +module.exports = async(code, activations, money) => { + // загружаем изображение фона + const background = await loadImage('./media/imageDefault3.png'); + + // создаем новый canvas + const canvas = createCanvas(background.width, background.height); + const ctx = canvas.getContext('2d'); + + // рисуем фоновое изображение + ctx.drawImage(background, 0, 0); + + // выводим текст на картинку + ctx.font = 'bold 30px Srbija Sans'; + ctx.fillStyle = '#232323'; + ctx.textAlign = 'center'; + ctx.fillText(`${code}`, canvas.width/2, canvas.height/1.90); + + // сохраняем картинку в файл + const out = fs.createWriteStream('./media/image.png'); + const stream = canvas.createPNGStream(); + stream.pipe(out); + + // возвращаем путь к сгенерированной картинке + return './media/image.png'; +} \ No newline at end of file diff --git a/utils/getCurrentTime.js b/utils/getCurrentTime.js new file mode 100644 index 0000000..2049195 --- /dev/null +++ b/utils/getCurrentTime.js @@ -0,0 +1,10 @@ +module.exports = () => { + const now = new Date(); + const year = now.getFullYear(); + const month = now.getMonth() < 9 ? `0${now.getMonth() + 1}` : now.getMonth() + 1; + const day = now.getDate() < 10 ? `0${now.getDate()}` : now.getDate(); + const hours = now.getHours() < 10 ? `0${now.getHours()}` : now.getHours(); + const minutes = now.getMinutes() < 10 ? `0${now.getMinutes()}` : now.getMinutes(); + const seconds = now.getSeconds() < 10 ? `0${now.getSeconds()}` : now.getSeconds(); + return `${day}.${month}.${year} ${hours}:${minutes}:${seconds}`; +} \ No newline at end of file diff --git a/utils/getSlot.js b/utils/getSlot.js new file mode 100644 index 0000000..46fbde1 --- /dev/null +++ b/utils/getSlot.js @@ -0,0 +1,22 @@ +module.exports = (result) => { + switch(result.dice.value){ + case 1: + return 10 + case 22: + return 15 + case 43: + return 20 + case 64: + return 25 + case 17: case 33: case 49: + return 1 + case 6: case 38: case 54: + return 2 + case 11: case 27: case 59: + return 3 + case 16: case 32: case 48: + return 4 + default: + return 0 + } +} \ No newline at end of file diff --git a/utils/giveExp.js b/utils/giveExp.js new file mode 100644 index 0000000..d707400 --- /dev/null +++ b/utils/giveExp.js @@ -0,0 +1,20 @@ +const { + Telegraf + } = require('telegraf') +const bot = new Telegraf(process.env.BOT_TOKEN) +const { + expToUp + } = require('/workspace/degradin/Dev/Telegram/CampFire Play Dev/config') + + +module.exports = async (user, experience) => { + user.exp += experience + for(i in expToUp){ + if (user.exp >= expToUp[user.level]) { + user.exp -= expToUp[user.level] + user.level += 1 + user.save() + await bot.telegram.sendMessage(user.telegram_id, `⤴️ Ваш уровень повысился до ${user.level}!`)} + } + user.save() +} \ No newline at end of file diff --git a/utils/html-escape.js b/utils/html-escape.js new file mode 100644 index 0000000..623145b --- /dev/null +++ b/utils/html-escape.js @@ -0,0 +1,10 @@ +module.exports = (str) => str.replace( + /[&<>'"]/g, + (tag) => ({ + '&': '&', + '<': '<', + '>': '>', + "'": ''', + '"': '"' + }[tag] || tag) + ) \ No newline at end of file diff --git a/utils/index.js b/utils/index.js new file mode 100644 index 0000000..92291bb --- /dev/null +++ b/utils/index.js @@ -0,0 +1,33 @@ +const spaces = require('./spaces') +const spacesWithMarkdown = require('./spacesV2') +const escape = require('./escape') +const generatePromo = require('./generatePromo') +const generateVoucher = require('./generateVoucher') +const getCurrentTime = require('./getCurrentTime') +const getSlot = require('./getSlot') +const giveExp = require('./giveExp') +const matPriceUpdate = require('./matPriceUpdate') +const rand = require('./rand') +const random = require('./random') +const setCooldown = require('./setCooldown') +const weaponShopUpdate = require('./weaponShopUpdate') +const stats = require('./stats') +const escapeHTML = require('./html-escape') + +module.exports = { + spaces, + spacesWithMarkdown, + escape, + generatePromo, + generateVoucher, + getCurrentTime, + getSlot, + giveExp, + matPriceUpdate, + rand, + random, + setCooldown, + weaponShopUpdate, + stats, + escapeHTML +} \ No newline at end of file diff --git a/utils/matPriceUpdate.js b/utils/matPriceUpdate.js new file mode 100644 index 0000000..e477e04 --- /dev/null +++ b/utils/matPriceUpdate.js @@ -0,0 +1,11 @@ +const rand = require('./rand') +const { + WorldModel + } = require('/workspace/degradin/Dev/Telegram/CampFire Play/config') + +module.exports = async () => { + let world = await WorldModel.findByPk(1) + let price = rand(35, 170) + world.matPrice = price + world.save() +} \ No newline at end of file diff --git a/utils/rand.js b/utils/rand.js new file mode 100644 index 0000000..1ff15bc --- /dev/null +++ b/utils/rand.js @@ -0,0 +1,3 @@ +module.exports = (min, max) => { + return Math.round(Math.random() * (max - min)) + min +} \ No newline at end of file diff --git a/utils/random.js b/utils/random.js new file mode 100644 index 0000000..befd9ee --- /dev/null +++ b/utils/random.js @@ -0,0 +1,7 @@ +Array.prototype.random = function() { + return this[Math.floor(this.length * Math.random())]; +} + +module.exports = { + randomArray: Array.prototype.random +}; \ No newline at end of file diff --git a/utils/setCooldown.js b/utils/setCooldown.js new file mode 100644 index 0000000..23dd3ac --- /dev/null +++ b/utils/setCooldown.js @@ -0,0 +1,26 @@ +module.exports = (user, seconds, type) => { + let cooldown = {} + cooldown.currentTime = Math.trunc(Date.now() / 1000) + + switch(user.status){ + case `user`: + cooldown.endTime = Math.trunc(Date.now() / 1000 + seconds) + break; + case `bronze`: + cooldown.endTime = Math.trunc(Date.now() / 1000 + (seconds/100*85)) + break; + case `silver`: + cooldown.endTime = Math.trunc(Date.now() / 1000 + (seconds/100*75)) + break; + case `gold`: + cooldown.endTime = Math.trunc(Date.now() / 1000 + (seconds/100*50)) + break; + case `admin`: + cooldown.endTime = Math.trunc(Date.now() / 1000) + break; + } + cooldown.timeLeft = cooldown.endTime - cooldown.currentTime + cooldown.timeLeftInMinutes = Math.ceil((type - cooldown.currentTime) / 60) + return cooldown + +} \ No newline at end of file diff --git a/utils/spaces.js b/utils/spaces.js new file mode 100644 index 0000000..03a320e --- /dev/null +++ b/utils/spaces.js @@ -0,0 +1,4 @@ +module.exports = (string) => { + if (typeof string !== "string") string = string.toString(); + return string.split("").reverse().join("").match(/[0-9]{1,3}/g).join(".").split("").reverse().join(""); +} \ No newline at end of file diff --git a/utils/spacesV2.js b/utils/spacesV2.js new file mode 100644 index 0000000..ecdb455 --- /dev/null +++ b/utils/spacesV2.js @@ -0,0 +1,4 @@ +module.exports = (string) => { + if (typeof string !== "string") string = string.toString(); + return string.split("").reverse().join("").match(/[0-9]{1,3}/g).join(".\\").split("").reverse().join(""); +} \ No newline at end of file diff --git a/utils/stats.js b/utils/stats.js new file mode 100644 index 0000000..9aa70c1 --- /dev/null +++ b/utils/stats.js @@ -0,0 +1,61 @@ +const io = require('@pm2/io') + +const stats = { + rpsAvrg: 0, + responseTimeAvrg: 0, + times: {} +} + +const rtOP = io.metric({ + name: 'response time', + unit: 'ms' +}) + +// const usersCountIO = io.metric({ +// name: 'Users count', +// unit: 'user' +// }) + +setInterval(() => { + if (Object.keys(stats.times).length > 1) { + const time = Object.keys(stats.times).shift() + + const sumResponseTime = stats.times[time].reduce((a, b) => a + b, 0) + const lastResponseTimeAvrg = (sumResponseTime / stats.times[time].length) || 0 + if (stats.responseTimeAvrg > 0) stats.responseTimeAvrg = Math.round((stats.responseTimeAvrg + lastResponseTimeAvrg) / 2) + else stats.responseTimeAvrg = lastResponseTimeAvrg + + console.log('response time avrg total:', stats.responseTimeAvrg) + + rtOP.set(stats.responseTimeAvrg) + + // db.Stats.create({ + // rps, + // responseTime: lastResponseTimeAvrg, + // date: new Date() + // }) + + delete stats.times[time] + } +}, 1000) + +// setInterval(async () => { +// const usersCount = await db.User.count({ +// updatedAt: { +// $gte: new Date(Date.now() - 24 * 60 * 60 * 1000) +// } +// }) + +// usersCountIO.set(usersCount) +// }, 60 * 1000) + +module.exports = async (ctx, next) => { + const startMs = new Date() + + return next().then(() => { + const now = Math.floor(new Date() / 1000) + + if (!stats.times[now]) stats.times[now] = [] + stats.times[now].push(new Date() - startMs) + }) +} \ No newline at end of file diff --git a/utils/weaponShopUpdate.js b/utils/weaponShopUpdate.js new file mode 100644 index 0000000..28bba3d --- /dev/null +++ b/utils/weaponShopUpdate.js @@ -0,0 +1,28 @@ +const rand = require('./rand') +const { + weaponshop, + weapons, + equipment, +} = require('/workspace/degradin/Dev/Telegram/CampFire Play Dev/config') +const fs = require('fs'); + +module.exports = () => { + let weaponId = [] + let equipId = [] + let drop = 1 + let counter = 5 + for (i = 0; i < 5; i++) { + drop = weaponId.push(rand(1, 10)) + } + for (i = 0; i < 5; i++) { + drop = equipId.push(rand(1, 10)) + } + for (i = 0; i < 5; i++) { + weaponshop[i] = weapons[weaponId[i]] + } + for (i = 0; i < 5; i++) { + weaponshop[counter] = equipment[equipId[i]] + counter++ + } + fs.writeFileSync('json/weaponshop.json', JSON.stringify(weaponshop, null, "\t")) +} \ No newline at end of file