// Подключаем необходимые библиотеки const { Telegraf, Scenes, session, Markup, Stage } = require('telegraf'); const { Op } = require('sequelize'); const sequelize = require('./db'); // Подключение базы данных // Подключаем обработчики const commands = require('./commands'); const utils = require('./utils'); const handlers = require('./handlers'); const { UserModel, WorldModel, JobModel, PropertyModel, AFKPropertyModel, BusinessModel, ReportModel, BlockModel, PromocodeModel, EnterpriseModel, WarehouseModel, SaleModel, SkillsModel, } = global.config const bot = new Telegraf(process.env.BOT_TOKEN) const crime = require('./scenes/crime') const pocketsteal = require('./scenes/pocketsteal') const shop = require('./scenes/shop') const pve = require('./scenes/pve') const newpve = require('./scenes/newpve') const stage = new Scenes.Stage([crime, pocketsteal, shop, pve, newpve]); const start = async () => { try { // Подключаемся к базе данных await sequelize.authenticate(); console.log('Подключение к базе данных успешно!'); // Синхронизация моделей, если нужно await sequelize.sync({ alter: true }); console.log('Синхронизация моделей завершена.'); // Запуск бота console.log('Бот успешно запущен!'); } catch (error) { console.error('Ошибка при запуске приложения:', error); } } bot.telegram.setMyCommands([{ command: "pay", description: "Перевести указанному пользователю сумму." }, { command: "buy", description: "Приобрести указанное имущество." }, { command: "business", description: "Создать организацию." }, { command: "invite", description: "Пригласить пользователя в организацию." }, { command: "percent", description: "Установить пользователю процент заработка." }, { command: "report", description: "Создать жалобу/обращение/идею." } ]) bot.use(stage.middleware()) bot.use( session({ getSessionKey: (ctx) => { if ((ctx.from && ctx.chat && ctx.chat.id === ctx.from.id) || (!ctx.chat && ctx.from)) { return `user:${ctx.from.id}` } else if (ctx.from && ctx.chat) { return `${ctx.from.id}:${ctx.chat.id}` } return ctx.update.update_id } }) ) bot.use(stage) bot.use(utils.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(utils.getCurrentTime() + `: ` + username + `: ` + ctx.update.message.text) break; case `callback_query`: console.log(utils.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); let skill = await SkillsModel.findByPk(ctx.from.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 }) } if (skill === null) { await SkillsModel.create({ telegram_id: id, stealing: { level: 1, exp: 0 } }) } //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.reply(`Closed`) /*await ctx.scene.enter('Crime')*/ }) bot.hears('промка', async(ctx) => { generatePromo() }); bot.hears('▶️ Меню', commands.menu); bot.hears('Чат', async (ctx) => { ctx.reply(`${ctx.message.chat.id}`) }); bot.hears('😎 Профиль', commands.profile); bot.command('getprofile', commands.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('🎁 Бонус', commands.bonus) bot.hears('Гараж', commands.garage) bot.hears('Гонка', commands.race) bot.command('pay', commands.pay) bot.hears('Мир', commands.worldMenu) bot.hears('📞 Пригласить', commands.referal) bot.hears('📢 Вакансии', commands.jobs) bot.action(/job_(1|2|3|4|5|6|7|leave)/, commands.chooseJob) bot.hears('🏯 Казино', commands.casinoMenu) bot.hears('🗄️ Работать', commands.work) bot.hears('Топ', commands.top) bot.hears('🔵 Имущество', commands.propertyMenu) bot.action('shopmenu', commands.propertyMenu) bot.action(/shop_(house|phone|car)/, commands.propertyList) bot.action(/{"action": "buy"*/, commands.propertyBuy) bot.hears('Поставщик', commands.hatkeisList) bot.command('sell', commands.propertySell) bot.hears('🌐 Организация', commands.organizationMenu) bot.action('workoff', commands.workoff) bot.action('покинуть', commands.leaveOrg) bot.action('cancel', async (ctx) => { await ctx.deleteMessage() await bot.telegram.answerCbQuery(ctx.callbackQuery.id, `Отмена.`) }) bot.action('user_leave_business', commands.leaveOrgAccept) bot.action('payday', commands.payday) bot.command('orgmessage', commands.orgMessage) bot.command('materials', commands.materialsBuy) bot.command('percent', commands.percentSet) bot.command('business', commands.organizationCreate) bot.command('invite', commands.invite) bot.action(/{"type": "business_invite_(accept|refuse)"*/, commands.inviteAction) bot.command('report', commands.report) bot.hears('🎰 Слоты', commands.slotsMenu) bot.action(/slots(1000|5000|25000|50000|100000)/, commands.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', commands.promocodeActivate) bot.hears('📦 Контейнеры', commands.carContainers) bot.action(/container_(1|2|3|4|5|6|7|8|9|10)/, commands.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() }) /////////////////////////////////////Enterprise Update 20.12.2024////////////////////////////////////////////////// // Обновление меню "Предприятия" bot.hears('🏗️ Предприятия', async (ctx) => { const user = await UserModel.findByPk(ctx.from.id); const warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } }); const enterprises = await EnterpriseModel.findAll({ where: { playerId: user.telegram_id } }); let message = `🏗️ Меню предприятий:\n`; message += `У вас: ${enterprises.length} предприятий.\n`; message += warehouse ? `🗄️ Единый склад: Доступен (Ёмкость: ${warehouse.capacity} ед.)\n` : `🗄️ Единый склад: Не построен.\n`; const buttons = []; // Добавляем кнопки для предприятий buttons.push([{ text: '🏭 Мои предприятия', callback_data: 'my_enterprises' }]); buttons.push([{ text: '🛠️ Построить предприятие', callback_data: 'build_enterprise' }]); // Кнопка для управления или постройки склада if (warehouse) { buttons.push([{ text: '🚛 Управление складом', callback_data: 'manage_warehouse' }]); } else { buttons.push([{ text: '🗄️ Построить склад', callback_data: 'open_warehouse' }]); } // Возвращаем меню с кнопками return await ctx.reply(message, Markup.inlineKeyboard(buttons).resize()); }); // Функция для преобразования типа ресурса в эмодзи function getEnterpriseEmoji(resourceType) { const emojis = { wood: '🌳', coal: '⛏️', oil: '🛢️', metall: '⚒️', gold: '💰', diamond: '💎' } return emojis[resourceType] || '🏭' } // Построение предприятия bot.action('build_enterprise', async (ctx) => { const user = await UserModel.findByPk(ctx.from.id); const enterprises = await EnterpriseModel.findAll({ where: { playerId: user.telegram_id } }); if (enterprises.length >= 5) { return await ctx.reply('Вы достигли максимального числа предприятий.'); } const resourcePrices = { wood: 10000, coal: 20000, oil: 50000, metall: 100000, gold: 300000, diamond: 500000 }; let message = `🛠️ Постройка предприятия:\n`; for (const [resource, price] of Object.entries(resourcePrices)) { const resourceName = getResourceName(resource); message += `${resourceName}: ${price} монет\n`; } message += '\nВыберите тип предприятия:'; const buttons = [ [ { text: '🌲', callback_data: 'build_wood' }, { text: '⛏️', callback_data: 'build_coal' } ], [ { text: '🛢️', callback_data: 'build_oil' }, { text: '⚙️', callback_data: 'build_metall' } ], [ { text: '🥇', callback_data: 'build_gold' }, { text: '💎', callback_data: 'build_diamond' } ] ]; return await ctx.reply(message, Markup.inlineKeyboard(buttons).resize()); }); // Построение предприятия по выбранному типу bot.action(/build_(wood|coal|oil|metall|gold|diamond)/, async (ctx) => { let user = await UserModel.findByPk(ctx.from.id) let data = ctx.update.callback_query.data let type = data.split('_')[1] let price = getEnterprisePrice(type) // Проверка, есть ли достаточно денег у пользователя if (user.balance < price) { return await ctx.reply(`У вас недостаточно средств для постройки предприятия. Необходимо ${price} руб.`) } // Строим предприятие let enterpriseName = `${user.username}'s ${getReadableType(type)}` // Название предприятия let enterprise = await EnterpriseModel.create({ name: enterpriseName, resourceType: type, playerId: user.telegram_id, level: 1, efficiency: 10, warehouseCapacity: 100 }) // Снимаем деньги с баланса await user.update({ money: user.money - price }) return await ctx.reply(`Предприятие ${enterprise.name} (ID: ${enterprise.id}) построено!`) }) // Функция для расчета стоимости предприятия function getEnterprisePrice(resourceType) { const prices = { wood: 5000, coal: 10000, oil: 20000, metall: 50000, gold: 150000, diamond: 250000 } return prices[resourceType] || 0 } // Функция для преобразования типа ресурса в читаемое название function getReadableType(type) { const names = { wood: 'Деревообрабатывающее предприятие', coal: 'Угольное предприятие', oil: 'Нефтяное предприятие', metall: 'Металлургическое предприятие', gold: 'Золотое предприятие', diamond: 'Алмазное предприятие' } return names[type] || type } bot.action('buy_warehouse', async (ctx) => { let user = await UserModel.findByPk(ctx.from.id) if (user.money < 500000) { return await ctx.reply(`У вас недостаточно средств для покупки склада.`) } await WarehouseModel.create({ playerId: user.telegram_id, capacity: 1000, // Начальная ёмкость wood: 0, coal: 0, oil: 0, metall: 0, gold: 0, diamond: 0 }) await user.update({ money: user.money - 500000 }) return await ctx.reply(`Вы успешно купили единый склад!`) }) // Управление складом bot.action('manage_warehouse', async (ctx) => { const user = await UserModel.findByPk(ctx.from.id); const warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } }); if (!warehouse) { return await ctx.reply('У вас нет склада для управления.'); } let message = `🚛 Управление складом:\n`; message += `Общая ёмкость: ${warehouse.capacity} ед.\n`; message += `Хранимые ресурсы:\n`; message += `🌲 Дерево: ${warehouse.wood || 0}\n`; message += `⛏️ Уголь: ${warehouse.coal || 0}\n`; message += `🛢️ Нефть: ${warehouse.oil || 0}\n`; message += `⚙️ Металл: ${warehouse.metall || 0}\n`; message += `🥇 Золото: ${warehouse.gold || 0}\n`; message += `💎 Алмазы: ${warehouse.diamond || 0}\n`; const buttons = [ [{ text: '➕ Перевести ресурсы', callback_data: 'transfer_resources' }], [{ text: '📤 Продать со склада', callback_data: 'sell_from_warehouse' }], [{ text: '🚚 Купить транспорт', callback_data: 'buy_truck' }] ]; return await ctx.reply(message, Markup.inlineKeyboard(buttons).resize()); }); bot.action('warehouse_management', async (ctx) => { let user = await UserModel.findByPk(ctx.from.id) let warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } }) if (!warehouse) { return await ctx.reply(`У вас нет склада. Вы можете купить его за 500,000 руб.`, Markup.inlineKeyboard([ [{ text: 'Купить склад', callback_data: 'buy_warehouse' }] ]).resize()) } let message = ` 🏗️ Единый склад Емкость: ${warehouse.capacity} ед. Ресурсы: 🌲 Дерево: ${warehouse.wood || 0} ⛏️ Уголь: ${warehouse.coal || 0} 🛢️ Нефть: ${warehouse.oil || 0} 🛠️ Металл: ${warehouse.metall || 0} 💰 Золото: ${warehouse.gold || 0} 💎 Алмазы: ${warehouse.diamond || 0} ` return await ctx.reply(message, Markup.inlineKeyboard([ [{ text: 'Управление транспортом', callback_data: 'manage_trucks' }], [{ text: 'Продать ресурсы', callback_data: 'sell_from_warehouse' }] ]).resize()) }) // Управление предприятием bot.action(/manage_(\d+)/, async (ctx) => { let enterpriseId = ctx.match[1] let enterprise = await EnterpriseModel.findByPk(enterpriseId) if (!enterprise) return await ctx.reply(`Предприятие не найдено.`) // Логика управления предприятием (например, прокачка или продажа ресурсов) return await ctx.reply(`Вы управляете предприятием ${enterprise.name} (ID: ${enterprise.id}).`) }) bot.action('transfer_resources', async (ctx) => { const user = await UserModel.findByPk(ctx.from.id); const warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } }); if (!warehouse) { return await ctx.reply('У вас нет единого склада.'); } const enterprises = await EnterpriseModel.findAll({ where: { playerId: user.telegram_id } }); let message = `➕ Перевозка ресурсов:\n`; message += `Общая ёмкость склада: ${warehouse.capacity} ед.\n`; message += `Выберите предприятие для перевозки ресурсов:`; const buttons = enterprises.map(ent => { return [{ text: `🏭 ${ent.name}`, callback_data: `transfer_from_${ent.id}` }]; }); return await ctx.reply(message, Markup.inlineKeyboard(buttons).resize()); }); // Перевозка с конкретного предприятия bot.action(/transfer_from_(\d+)/, async (ctx) => { const enterpriseId = ctx.match[1]; const user = await UserModel.findByPk(ctx.from.id); const warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } }); const enterprise = await EnterpriseModel.findByPk(enterpriseId); if (!enterprise) { return await ctx.reply('Предприятие не найдено.'); } let message = `🚛 Перевозка с предприятия ${enterprise.name}:\n`; message += `🌲 Дерево: ${enterprise.wood || 0}\n`; message += `⛏️ Уголь: ${enterprise.coal || 0}\n`; message += `🛢️ Нефть: ${enterprise.oil || 0}\n`; message += `⚙️ Металл: ${enterprise.metall || 0}\n`; message += `🥇 Золото: ${enterprise.gold || 0}\n`; message += `💎 Алмазы: ${enterprise.diamond || 0}\n`; message += `\nВведите количество ресурса для перевозки.`; return await ctx.reply(message); }); bot.command('ent_rename', async (ctx) => { let args = ctx.message.text.split(' ').slice(1) if (args.length < 2) { return await ctx.reply('Использование: /ent_rename <Новое название>') } let enterpriseId = parseInt(args[0]) let newName = args.slice(1).join(' ') let enterprise = await EnterpriseModel.findByPk(enterpriseId) if (!enterprise) { return await ctx.reply(`Предприятие с ID ${enterpriseId} не найдено.`) } // Переименовываем предприятие await enterprise.update({ name: newName }) return await ctx.reply(`Предприятие (ID: ${enterprise.id}) переименовано в "${newName}".`) }) bot.action('upgrade_enterprise', async (ctx) => { let user = await UserModel.findByPk(ctx.from.id) let enterprises = await EnterpriseModel.findAll({ where: { playerId: user.telegram_id } }) if (enterprises.length === 0) return await ctx.reply(`У вас нет предприятий для прокачки.`) let buttons = [] enterprises.forEach(enterprise => { buttons.push({ text: `Прокачать ${enterprise.name}`, callback_data: `upgrade_${enterprise.id}` }) }) return await ctx.reply(`Выберите предприятие для прокачки:`, Markup.inlineKeyboard(buttons).resize()) }) bot.action(/upgrade_(\d+)/, async (ctx) => { let user = await UserModel.findByPk(ctx.from.id) let enterpriseId = ctx.match[1] let enterprise = await EnterpriseModel.findByPk(enterpriseId) if (!enterprise) return await ctx.reply(`Предприятие не найдено.`) let upgradeCost = enterprise.level * 100 // Стоимость улучшения зависит от уровня if (user.balance < upgradeCost) { return await ctx.reply(`У вас недостаточно средств для прокачки предприятия. Необходимо ${upgradeCost} монет.`) } // Прокачка: повышение уровня и эффективности await enterprise.update({ level: enterprise.level + 1, efficiency: enterprise.efficiency + 10 }) // Снимаем деньги с баланса await user.update({ balance: user.balance - upgradeCost }) return await ctx.reply(`Предприятие ${enterprise.name} успешно прокачано! Уровень: ${enterprise.level}, Производительность: ${enterprise.efficiency} ед/ч.`) }) bot.action('sell_resources', async (ctx) => { let user = await UserModel.findByPk(ctx.from.id) let enterprises = await EnterpriseModel.findAll({ where: { playerId: user.telegram_id } }) if (enterprises.length === 0) return await ctx.reply(`У вас нет предприятий для продажи ресурсов.`) let buttons = [] enterprises.forEach(enterprise => { buttons.push({ text: `Продать ресурсы с ${enterprise.name}`, callback_data: `sell_${enterprise.id}` }) }) return await ctx.reply(`Выберите предприятие для продажи ресурсов:`, Markup.inlineKeyboard(buttons).resize()) }) bot.action(/sell_(\d+)/, async (ctx) => { let user = await UserModel.findByPk(ctx.from.id) let enterpriseId = ctx.match[1] let enterprise = await EnterpriseModel.findByPk(enterpriseId) if (!enterprise) return await ctx.reply(`Предприятие не найдено.`) // Логика продажи ресурсов с предприятия const resourceQuantity = await ResourceModel.findOne({ where: { playerId: user.telegram_id, type: enterprise.resourceType } }) if (!resourceQuantity || resourceQuantity.quantity <= 0) { return await ctx.reply(`У вас нет ресурсов для продажи на предприятии ${enterprise.name}.`) } const salePrice = getResourcePrice(enterprise.resourceType) // Цена за единицу ресурса const totalSale = salePrice * resourceQuantity.quantity // Обновляем количество ресурсов await ResourceModel.update( { quantity: 0 }, // Все ресурсы продаются { where: { playerId: user.telegram_id, type: enterprise.resourceType } } ) // Добавляем деньги пользователю await user.update({ balance: user.balance + totalSale }) return await ctx.reply(`Вы продали все ресурсы с ${enterprise.name} за ${totalSale} монет.`) }) bot.action('hire_truck', async (ctx) => { let user = await UserModel.findByPk(ctx.from.id) let warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } }) if (!warehouse) return await ctx.reply(`У вас нет склада для найма грузовиков.`) // Логика найма грузовика let truck = await TruckModel.create({ warehouseId: warehouse.id, capacity: 10, // Начальная вместимость efficiency: 1 // Начальная эффективность }) return await ctx.reply(`Вы наняли грузовик для транспортировки ресурсов!`) }) async function initializeResourcePrices() { const resources = [ { resourceType: 'wood', basePrice: 100, recoveryRate: 1 }, { resourceType: 'coal', basePrice: 200, recoveryRate: 2 }, { resourceType: 'oil', basePrice: 500, recoveryRate: 5 }, { resourceType: 'metall', basePrice: 1000, recoveryRate: 10 }, { resourceType: 'gold', basePrice: 3000, recoveryRate: 15 }, { resourceType: 'diamond', basePrice: 5000, recoveryRate: 20 } ] for (let resource of resources) { await ResourcePriceModel.findOrCreate({ where: { resourceType: resource.resourceType }, defaults: { currentPrice: resource.basePrice, basePrice: resource.basePrice, recoveryRate: resource.recoveryRate } }) } } initializeResourcePrices() setInterval(async () => { const resources = await ResourcePriceModel.findAll() for (let resource of resources) { if (resource.currentPrice < resource.basePrice) { resource.currentPrice += resource.recoveryRate if (resource.currentPrice > resource.basePrice) { resource.currentPrice = resource.basePrice } await resource.save() } } }, 60000) // Обновляем цены каждые 60 секунд /////////////////////////////////////Enterprise Update end////////////////////////////////////////////////// /////////////////////////////////////Admin Commands////////////////////////////////////////////////// bot.command('answer', commands.reportAnswer) bot.command('fastblock', commands.fastblock) bot.command('createpromocode', commands.createPromo) bot.command('genpromo', commands.genPromo) ///////////////////////////////////////Functions////////////////////////////////////////////////////// setInterval(() => { var today = new Date(); let hours = today.getHours(); if (hours == "0" || hours == "12") { weaponShopUpdate() matPriceUpdate() } /*if (hours == "9" || hours == "18" || hours == "12") { generatePromo() }*/ }, 3600000); start() bot.launch()