CampFirePlay/bot.js
2025-01-06 13:04:36 +03:00

1664 lines
69 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Подключаем необходимые библиотеки
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,
TruckModel,
SaleModel,
ResourcePriceModel,
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.findOne({
where: { telegram_id: id }, // Здесь id — это значение telegram_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) {
const currentTime = Math.trunc(Date.now() / 1000); // Получаем текущее время в секундах
if (block.isBlocked && block.time > currentTime) {
const remainingTime = Math.trunc((block.time - currentTime) / 60); // Рассчитываем оставшееся время
return ctx.reply(
`📛 У вас активная блокировка по причине: ${block.reason}.\n⏲️ Оставшееся время: ${remainingTime} мин.`
);
}
// Если блокировка истекла или отключена
block.isBlocked = false;
await block.save(); // Обязательно используем `await` для сохранения изменений
}
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) => {
try {
const user = await UserModel.findByPk(ctx.from.id);
if (!user) {
console.error('Ошибка: пользователь не найден');
return await ctx.reply('Ошибка: пользователь не найден.');
}
console.log('ID пользователя:', user.telegram_id);
const warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } });
if (!warehouse) {
console.log('Склад не найден для пользователя:', user.telegram_id);
} else {
console.log('Найден склад:', warehouse);
}
const enterprises = await EnterpriseModel.findAll({
where: { playerId: user.telegram_id }
});
if (!enterprises.length) {
console.log('Предприятия не найдены для пользователя:', user.telegram_id);
} else {
console.log('Количество предприятий:', enterprises.length);
}
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: 'buy_warehouse' }]);
}
buttons.push([{ text: '💰 Продать ресурсы', callback_data: 'sell_resources' }]);
return await ctx.reply(message, Markup.inlineKeyboard(buttons).resize());
} catch (error) {
console.error('Ошибка при выполнении команды "🏗️ Предприятия":', error);
return await ctx.reply('Произошла ошибка при выполнении команды. Попробуйте позже.');
}
});
bot.action('enterprise_menu', 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: 'buy_warehouse' }]);
}
buttons.push([{ text: '💰 Продать ресурсы', callback_data: 'sell_resources' }])
// Возвращаем меню с кнопками
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
});
// Функция для преобразования типа ресурса в эмодзи
function getEnterpriseEmoji(resourceType) {
const emojis = {
wood: '🌳',
coal: '⛏️',
oil: '🛢️',
metall: '⚒️',
gold: '💰',
diamond: '💎'
}
return emojis[resourceType] || '🏭'
}
bot.action('my_enterprises', async (ctx) => {
const user = await UserModel.findByPk(ctx.from.id);
const enterprises = await EnterpriseModel.findAll({
where: { playerId: user.telegram_id }
});
if (enterprises.length === 0) {
return await ctx.reply('У вас нет предприятий.');
}
let metallPrice = await ResourcePriceModel.findOne({
where: { resource: "metall" }
});
let message = `🏭 Мои предприятия:\n\n`;
const buttons = [];
for (const enterprise of enterprises) {
const { id, name, level, efficiency, currentResources, resourceType, warehouseCapacity } = enterprise;
const resourcePrice = await ResourcePriceModel.findOne({
where: { resource: resourceType }
});
let price = resourcePrice.price * 1.5 * 10 * 24 * 7 // Стоимость улучшения зависит от уровня
message += `🔹 [ID: ${id}] ${getEnterpriseEmoji(resourceType)} ${name} st. ${level}\n └── ${currentResources}/${warehouseCapacity} [${efficiency} ед/ч]\n └──📈 ${utils.spaces(price)} руб.\n\n`;
const truck = await TruckModel.findOne({ where: { enterpriseId: id } });
const warehouse = await WarehouseModel.findOne({ where: { playerId: user.telegram_id } });
const enterpriseButtons = [
{ text: `ID: 📈 ${id}`, callback_data: `upgrade_${id}` },
];
if (!truck) {
enterpriseButtons.push({ text: `🛻 ID: ${id}`, callback_data: `hire_truck_${id}` });
}else{
enterpriseButtons.push({ text: `🚛 ID: ${id}`, callback_data: `upgrade_truck_${id}` });
}
enterpriseButtons.push({ text: `💰 ID: ${id}`, callback_data: `sell_all_${id}` });
if (warehouse) {
enterpriseButtons.push({ text: `🔄 ID: ${id}`, callback_data: `transfer_from_${id}` });
}
buttons.push(enterpriseButtons);
}
message += `\n\n📈 - Улучшить\n🛻 - Купить грузовик [~${utils.spaces(metallPrice.price*700)} руб.]\n🚛 - Улучшить грузовик\n💰 - Продать ресурсы с предприятия\n🔄 - Перевезти все на склад`
buttons.push([{ text: '⬅️ Назад', callback_data: 'enterprise_menu' }]);
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
});
// Построение предприятия
bot.action('build_enterprise', async (ctx) => {
try {
const user = await UserModel.findByPk(ctx.from.id);
if (!user) {
return await ctx.reply('Пользователь не найден.');
}
const enterprises = await EnterpriseModel.findAll({
where: { playerId: user.telegram_id }
});
if (enterprises.length >= 5) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'Вы достигли максимального числа предприятий.', {show_alert: true});
}
// Получаем текущие цены из базы данных
const resourcePrices = await ResourcePriceModel.findAll();
if (!resourcePrices || resourcePrices.length === 0) {
return await ctx.reply('Цены на ресурсы отсутствуют. Пожалуйста, попробуйте позже.');
}
let message = `🛠️ Постройка предприятия:\n`;
const buttons = [];
for (const resource of resourcePrices) {
const resourceName = getReadableType(resource.resource);
const resourceEmoji = getEnterpriseEmoji(resource.resource);
message += `${resourceEmoji} ${resourceName}: ${utils.spaces(Math.round(resource.price * 1.5 * 10 * 24 * 7))} руб.\n`;
// Генерируем кнопки для каждого ресурса
buttons.push([
{ text: resourceEmoji, callback_data: `build_${resource.resource}` }
]);
}
message += '\nВыберите тип предприятия:';
buttons.push([{ text: '⬅️ Назад', callback_data: 'enterprise_menu' }]);
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
} catch (error) {
console.error('Ошибка в build_enterprise:', error);
return await ctx.reply('Произошла ошибка при обработке запроса. Попробуйте снова.');
}
});
// Построение предприятия по выбранному типу
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]
// Получаем текущие цены из базы данных
const resourcePrice = await ResourcePriceModel.findOne({
where: { resource: type }
});
let price = resourcePrice.price * 1.5 * 10 * 24 * 7
// Проверка, есть ли достаточно денег у пользователя
if (user.money < price) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас недостаточно средств для постройки предприятия. Необходимо ${price} руб.`, {show_alert: true})
}
// Строим предприятие
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.editMessageText(`Предприятие ${enterprise.name} (ID: ${enterprise.id}) построено!`)
})
// Функция для преобразования типа ресурса в читаемое название
function getReadableType(type) {
const names = {
wood: 'Деревообрабатывающее предприятие',
coal: 'Угольное предприятие',
oil: 'Нефтяное предприятие',
metall: 'Металлургическое предприятие',
gold: 'Золотое предприятие',
diamond: 'Алмазное предприятие'
}
return names[type] || type
}
function getReadableResourceType(type) {
const names = {
wood: 'Дерево',
coal: 'Уголь',
oil: 'Нефть',
metall: 'Металл',
gold: 'Золото',
diamond: 'Алмазы'
}
return names[type] || type
}
bot.action('buy_warehouse', async (ctx) => {
try {
// Получаем пользователя
let user = await UserModel.findByPk(ctx.from.id);
if (!user) {
return await ctx.reply('Произошла ошибка. Пользователь не найден.');
}
// Получаем цены на металл и дерево
const woodPrice = await ResourcePriceModel.findOne({ where: { resource: 'wood' } });
const metallPrice = await ResourcePriceModel.findOne({ where: { resource: 'metall' } });
if (!woodPrice || !metallPrice) {
return await ctx.reply('Не удалось получить цены на ресурсы. Попробуйте позже.');
}
// Формируем стоимость склада
const warehouseBaseCost = 10; // Коэффициент для расчёта
const warehouseCost = Math.round(
(woodPrice.price + metallPrice.price) * warehouseBaseCost * 24 * 7
);
// Проверяем, хватает ли денег у пользователя
if (user.money < warehouseCost) {
return await ctx.telegram.answerCbQuery(
ctx.callbackQuery.id,
`У вас недостаточно средств для покупки склада. Необходимо: ${utils.spaces(warehouseCost)} руб.`,
{ show_alert: true }
);
}
// Создаём склад
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 - warehouseCost });
// Уведомление об успешной покупке
return await ctx.reply(
`Вы успешно купили единый склад за ${warehouseCost} руб!`
);
} catch (error) {
console.error('Ошибка при покупке склада:', error);
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' }]
];
buttons.push([{ text: '⬅️ Назад', callback_data: 'enterprise_menu' }]);
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
});
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.telegram.answerCbQuery(ctx.callbackQuery.id,'У вас нет единого склада.');
}
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}` }];
});
buttons.push([{ text: '⬅️ Назад', callback_data: 'enterprise_menu' }]);
return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize());
});
// Перевозка с конкретного предприятия
bot.action(/transfer_from_(\d+)/, async (ctx) => {
const enterpriseId = ctx.match[1];
const enterprise = await EnterpriseModel.findByPk(enterpriseId);
if (!enterprise) {
return await ctx.editMessageText('Предприятие не найдено.');
}
const { currentResources, resourceType, playerId } = enterprise;
if (currentResources === 0) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'На предприятии нет ресурсов для перевода.');
}
const warehouse = await WarehouseModel.findOne({ where: { playerId } });
if (!warehouse) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'У вас нет склада для перевода ресурсов.');
}
const freeCapacity = warehouse.capacity - getWarehouseUsedCapacity(warehouse);
const transferAmount = Math.min(currentResources, freeCapacity);
if (transferAmount === 0) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'Склад заполнен. Перевод невозможен.');
}
// Перевод ресурсов
warehouse[resourceType] = (warehouse[resourceType] || 0) + transferAmount;
enterprise.currentResources -= transferAmount;
await warehouse.save();
await enterprise.save();
return await ctx.reply(
`Успешно переведено ${transferAmount} ед. ${resourceType} с предприятия в склад.`
);
});
bot.command('ent_rename', async (ctx) => {
let args = ctx.message.text.split(' ').slice(1)
if (args.length < 2) {
return await ctx.reply('Использование: /ent_rename <ID> <Новое название>')
}
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_(\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 resourcePrice = await ResourcePriceModel.findOne({
where: { resource: enterprise.resourceType }
});
let upgradeCost = resourcePrice.price * 1.5 * 10 * 24 * 7 // Стоимость улучшения зависит от уровня
if (user.money < upgradeCost) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас недостаточно средств для прокачки предприятия. Необходимо ${upgradeCost} руб.`)
}
// Прокачка: повышение уровня и эффективности
await enterprise.update({
level: enterprise.level + 1,
efficiency: enterprise.efficiency + 10,
warehouseCapacity: enterprise.warehouseCapacity + 110
})
// Снимаем деньги с баланса
await user.update({ money: user.money - upgradeCost })
return await ctx.editMessageText(`Предприятие ${enterprise.name} успешно прокачано! Уровень: ${enterprise.level}, Производительность: ${enterprise.efficiency} ед/ч.`)
})
// Показ списка предприятий
bot.action('sell_resources', async (ctx) => {
const user = await UserModel.findByPk(ctx.from.id);
const enterprises = await EnterpriseModel.findAll({
where: { playerId: user.telegram_id }
});
if (enterprises.length === 0) {
return await ctx.reply('❌ У вас нет предприятий для продажи ресурсов.');
}
let message = `<b>📜 Список ваших предприятий и их ресурсы:</b>\n\n`;
enterprises.forEach((enterprise, index) => {
message += `<b>${index + 1}.</b> ${enterprise.name} (${enterprise.resourceType}): <b>${enterprise.currentResources}</b> единиц\n`;
});
message += `\n<b>📦 Продажа ресурсов:</b>\n`;
message += `• Для продажи ресурсов с предприятия используйте команду:\n<code>/sellres [номер_предприятия] [количество]</code>\n<i>Пример:</i> <code>/sellres 1 50</code>\n\n`;
message += `• Для продажи ресурсов со склада используйте команду:\n<code>/sellstorage [тип_ресурса (wood/coal/oil/metall/gold/diamond)] [количество]</code>\n<i>Пример:</i> <code>/sellstorage wood 10</code>`;
return await ctx.reply(message, {
parse_mode: 'HTML',
reply_markup: {
inline_keyboard: [
[{ text: '↩ Назад', callback_data: 'enterprise_menu' }]
]
}
});
});
// Обработка продажи ресурсов
bot.command('sellres', async (ctx) => {
const user = await UserModel.findByPk(ctx.from.id);
const [enterpriseId, amountToSell] = ctx.message.text.split(' ').slice(1);
if (!enterpriseId || !amountToSell) {
return await ctx.reply('Неверный формат команды. Пример: /sellres 1 50');
}
const enterprise = await EnterpriseModel.findByPk(enterpriseId, {
where: { playerId: user.telegram_id }
});
if (!enterprise) {
return await ctx.reply('Предприятие с таким id не найдено.');
}
const amount = parseInt(amountToSell, 10);
if (isNaN(amount) || amount <= 0) {
return await ctx.reply('Укажите корректное количество для продажи.');
}
if (enterprise.currentResources < amount) {
return await ctx.reply(
`На предприятии ${enterprise.name} недостаточно ресурсов. Доступно: ${enterprise.currentResources} единиц.`
);
}
const resourcePrice = await ResourcePriceModel.findOne({
where: { resource: enterprise.resourceType }
});
if (!resourcePrice) {
return await ctx.reply('Не удалось получить цену ресурса.');
}
const totalSale = Math.floor(amount * resourcePrice.price);
// Обновляем данные
enterprise.currentResources -= amount;
await enterprise.save();
user.money += totalSale;
await user.save();
// Ослабленная инфляция
resourcePrice.price = Math.round(
resourcePrice.price * Math.exp(-resourcePrice.fluctuationRate * (amount / 10)) // Дробное уменьшение инфляции
);
// Гарантируем, что цена не упадет ниже 50% от базовой цены
resourcePrice.price = Math.max(resourcePrice.price, Math.round(resourcePrice.basePrice * 0.5));
await resourcePrice.save();
updateResourcePricesMessage();
return await ctx.reply(
`Вы продали ${amount} единиц ${enterprise.resourceType} с предприятия ${enterprise.name} за ${totalSale} руб.\nТекущая цена за единицу: ${resourcePrice.price.toFixed(0)} руб.`
);
});
const recoverResourcePrices = async () => {
const resources = await ResourcePriceModel.findAll();
for (const resource of resources) {
// Определяем случайное колебание в диапазоне [-maxFluctuation, maxFluctuation]
const maxFluctuation = resource.basePrice * 0.03; // 3% от базовой цены
const priceFluctuation = (Math.random() * 2 - 1) * maxFluctuation;
// Применяем колебание
resource.price = Math.round(resource.price + priceFluctuation);
// Если цена выше базовой, шанс на её снижение
if (resource.price > resource.basePrice) {
const chanceToDrop = 0.6; // 60% шанс на снижение
if (Math.random() < chanceToDrop) {
resource.price -= Math.round(resource.basePrice * 0.01); // Снижение на 1% базовой цены
}
}
// Если цена ниже базовой, восстанавливаем с учётом recoveryRate
if (resource.price < resource.basePrice) {
resource.price = Math.min(
Math.round(resource.price + resource.basePrice * resource.recoveryRate),
resource.basePrice // Не превышать базовую цену
);
}
// Гарантируем, что цена остаётся в диапазоне [50% basePrice, 150% basePrice]
resource.price = Math.max(resource.price, Math.round(resource.basePrice * 0.5)); // Минимум
resource.price = Math.min(resource.price, Math.round(resource.basePrice * 3)); // Максимум
await resource.save(); // Сохраняем после всех корректировок
}
};
bot.action(/sell_all_(\d+)/, async (ctx) => {
const enterpriseId = ctx.match[1];
const enterprise = await EnterpriseModel.findByPk(enterpriseId);
if (!enterprise) {
return await ctx.reply('Предприятие не найдено.');
}
const { currentResources, resourceType, playerId } = enterprise;
const resourcePrice = await ResourcePriceModel.findOne({ where: { resource: resourceType } });
const totalPrice = currentResources * resourcePrice.price;
if (currentResources === 0) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'На предприятии нет ресурсов для продажи.');
}
await ctx.reply(
`Вы уверены, что хотите продать все ${currentResources} ед. ${resourceType} за ${totalPrice} руб.? Это необратимо!\n\nРекомендуем воспользоваться командой /sell для более гибкого управления продажами.`,
Markup.inlineKeyboard([
[
{ text: '✅ Продать всё', callback_data: `confirm_ressell_${enterpriseId}` },
{ text: '❌ Отмена', callback_data: 'cancel' }
]
])
);
});
bot.action(/confirm_ressell_(\d+)/, async (ctx) => {
const enterpriseId = ctx.match[1];
const enterprise = await EnterpriseModel.findByPk(enterpriseId);
if (!enterprise) {
return await ctx.reply('Предприятие не найдено.');
}
const { currentResources, resourceType, playerId } = enterprise;
const resourcePrice = await ResourcePriceModel.findOne({ where: { resource: resourceType } });
const totalPrice = currentResources * resourcePrice.price;
if (currentResources === 0) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'На предприятии нет ресурсов для продажи.');
}
// Обновление баланса игрока
const user = await UserModel.findByPk(playerId);
user.money += totalPrice;
enterprise.currentResources = 0;
await user.save();
await enterprise.save();
console.log(resourcePrice.price * Math.exp(-resourcePrice.fluctuationRate * (currentResources / 10)))
// Ослабленная инфляция
resourcePrice.price = Math.round(
resourcePrice.price * Math.exp(-resourcePrice.fluctuationRate * (currentResources / 10)) // Дробное уменьшение инфляции
);
// Гарантируем, что цена не упадет ниже 50% от базовой цены
resourcePrice.price = Math.max(resourcePrice.price, Math.round(resourcePrice.basePrice * 0.5));
await resourcePrice.save();
updateResourcePricesMessage();
await ctx.editMessageText(`Вы успешно продали ${currentResources} ед. ${getEnterpriseEmoji(resourceType)} за ${totalPrice} руб.`);
});
// Продажа ресурсов со склада
bot.command('sellstorage', async (ctx) => {
const user = await UserModel.findByPk(ctx.from.id);
const [resourceType, amountToSell] = ctx.message.text.split(' ').slice(1);
if (!resourceType || !amountToSell) {
return await ctx.reply('Неверный формат команды. Пример: /sellstorage <тип_ресурса> <количество>');
}
const storage = await WarehouseModel.findOne({
where: { playerId: user.telegram_id }
});
if (!storage || !storage[resourceType]) {
return await ctx.reply(`У вас нет ресурсов типа ${resourceType} на складе.`);
}
const amount = parseInt(amountToSell, 10);
if (isNaN(amount) || amount <= 0) {
return await ctx.reply('Укажите корректное количество для продажи.');
}
if (storage[resourceType] < amount) {
return await ctx.reply(`На складе недостаточно ресурсов типа ${resourceType}. Доступно: ${storage[resourceType]} единиц.`);
}
const resourcePrice = await ResourcePriceModel.findOne({ where: { resource: resourceType } });
if (!resourcePrice) {
return await ctx.reply('Не удалось получить цену ресурса.');
}
const totalSale = Math.floor(amount * resourcePrice.price);
// Обновляем данные
storage[resourceType] -= amount;
await storage.save();
user.money += totalSale;
await user.save();
// Ослабленная инфляция
resourcePrice.price = Math.round(
resourcePrice.price * Math.exp(-resourcePrice.fluctuationRate * (amount / 10)) // Дробное уменьшение инфляции
);
// Гарантируем, что цена не упадет ниже 50% от базовой цены
resourcePrice.price = Math.max(resourcePrice.price, Math.round(resourcePrice.basePrice * 0.5));
await resourcePrice.save();
updateResourcePricesMessage();
return await ctx.reply(
`Вы продали ${amount} ед. ${resourceType} со склада за ${totalSale} руб.\nТекущая цена за единицу: ${resourcePrice.price.toFixed(0)} руб.`
);
});
// Обработка найма грузовика для выбранного предприятия
bot.action(/hire_truck_(\d+)/, async (ctx) => {
const user = await UserModel.findByPk(ctx.from.id);
const enterpriseId = ctx.match[1];
// Находим предприятие
const enterprise = await EnterpriseModel.findByPk(enterpriseId);
if (!enterprise || enterprise.playerId != user.telegram_id) {
return await ctx.reply('Предприятие не найдено или вам не принадлежит.');
}
// Проверяем, есть ли уже грузовик для этого предприятия
const existingTruck = await TruckModel.findOne({
where: { enterpriseId: enterprise.id }
});
if (existingTruck) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас уже есть грузовик для предприятия ${enterprise.name}.`);
}
const resourcePrice = await ResourcePriceModel.findOne({ where: { resource: 'metall' } });
if (!resourcePrice) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, 'Не удалось получить цену ресурса.');
}
if (user.money < resourcePrice.price*700) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `Недостаточно средств. Стоимость грузовика: ${utils.spaces(resourcePrice.price*700)} руб.`);
}
await user.update({ money: user.money - (resourcePrice.price*700) })
// Создаем новый грузовик
const newTruck = await TruckModel.create({
enterpriseId: enterprise.id,
capacity: 10, // Начальная вместимость
efficiency: 1 // Начальная эффективность
});
return await ctx.reply(
`Вы успешно наняли грузовик для предприятия ${enterprise.name}!`
);
});
async function initializePrices() {
const resources = [
{ resource: 'wood', price: 1000, basePrice: 1000, fluctuationRate: 0.002, recoveryRate: 0.15 },
{ resource: 'coal', price: 2000, basePrice: 2000, fluctuationRate: 0.002, recoveryRate: 0.12 },
{ resource: 'oil', price: 5000, basePrice: 5000, fluctuationRate: 0.001, recoveryRate: 0.1 },
{ resource: 'metall', price: 5000, basePrice: 5000, fluctuationRate: 0.001, recoveryRate: 0.1 },
{ resource: 'gold', price: 10000, basePrice: 10000, fluctuationRate: 0.0005, recoveryRate: 0.08 },
{ resource: 'diamond', price: 25000, basePrice: 25000, fluctuationRate: 0.0004, recoveryRate: 0.05 },
];
for (const resource of resources) {
await ResourcePriceModel.findOrCreate({
where: { resource: resource.resource },
defaults: resource,
});
}
}
initializePrices();
// Функция добычи ресурсов
const resourceProduction = async () => {
try {
// Получаем все предприятия
const enterprises = await EnterpriseModel.findAll();
for (const enterprise of enterprises) {
const {
id,
efficiency,
warehouseCapacity,
resourceType,
currentResources,
level,
playerId
} = enterprise;
// Расчёт добытых ресурсов
const producedResources = efficiency * level;
// Проверяем ёмкость склада предприятия
if (currentResources + producedResources <= warehouseCapacity) {
enterprise.currentResources += producedResources;
await enterprise.save();
console.log(
`Предприятие ${id}: добыто ${producedResources} единиц ${resourceType}.`
);
} else {
console.log(`Предприятие ${id}: склад заполнен.`);
}
}
} catch (error) {
console.error('Ошибка добычи ресурсов:', error);
}
};
// Функция транспортировки ресурсов
const resourceTransportation = async () => {
try {
// Получаем все предприятия
const enterprises = await EnterpriseModel.findAll();
for (const enterprise of enterprises) {
const {
id,
resourceType,
currentResources,
playerId
} = enterprise;
if (currentResources > 0) {
// Получаем грузовики, привязанные к предприятию
const trucks = await TruckModel.findAll({
where: { enterpriseId: id }
});
if (trucks.length === 0) {
console.log(
`Предприятие ${id}: нет доступных грузовиков для транспортировки.`
);
continue;
}
// Получаем универсальный склад игрока
const warehouse = await WarehouseModel.findOne({
where: { playerId }
});
if (!warehouse) {
console.log(
`Предприятие ${id}: у игрока ${playerId} нет универсального склада.`
);
continue;
}
// Транспортировка ресурсов
let totalTransported = 0;
for (const truck of trucks) {
const transportableAmount = Math.min(
truck.capacity, // Максимальная вместимость грузовика
currentResources, // Доступные ресурсы на предприятии
warehouse.capacity - getWarehouseUsedCapacity(warehouse) // Свободное место на складе
);
if (transportableAmount > 0) {
// Обновляем данные склада
warehouse[resourceType] =
(warehouse[resourceType] || 0) + transportableAmount;
// Уменьшаем ресурсы на предприятии
enterprise.currentResources -= transportableAmount;
await warehouse.save();
await enterprise.save();
totalTransported += transportableAmount;
console.log(
`Грузовик ${truck.id} перевёз ${transportableAmount} единиц ${resourceType}.`
);
}
// Прекращаем, если ресурсы закончились
if (enterprise.currentResources === 0) break;
}
if (totalTransported === 0) {
console.log(
`Предприятие ${id}: склад заполнен, транспортировка невозможна.`
);
}
} else {
console.log(`Предприятие ${id}: нет ресурсов для транспортировки.`);
}
}
} catch (error) {
console.error('Ошибка транспортировки ресурсов:', error);
}
};
// Расчёт используемой ёмкости склада
const getWarehouseUsedCapacity = (warehouse) => {
const resources = ['wood', 'coal', 'oil', 'metall', 'gold', 'diamond'];
return resources.reduce((sum, resource) => sum + (warehouse[resource] || 0), 0);
};
const CHANNEL_ID = '@CampFireGameBotNews'; // Замените на username вашего канала
let resourceMessageId = 18; // Хранение ID сообщения
const previousPrices = {}; // Объект для хранения предыдущих цен
const getResourcePricesText = async () => {
const resources = await ResourcePriceModel.findAll(); // Получаем данные из базы
let message = '💰 **Актуальные цены на ресурсы:**\n\n';
resources.forEach((resource) => {
const currentPrice = resource.price;
const previousPrice = previousPrices[resource.resource] || currentPrice; // Берем предыдущую цену или текущую, если нет данных
// Определяем эмодзи изменения цены
let trendEmoji = '⚖️'; // По умолчанию стабильность
if (currentPrice > previousPrice) {
trendEmoji = '📈'; // Рост
} else if (currentPrice < previousPrice) {
trendEmoji = '📉'; // Падение
}
// Сохраняем текущую цену как предыдущую для следующего сравнения
previousPrices[resource.resource] = currentPrice;
// Добавляем строку с ценой и эмодзи
message += `${getEnterpriseEmoji(resource.resource)} ${getReadableResourceType(resource.resource)}: ${trendEmoji} ${utils.spaces(currentPrice)} руб/ед.\n`;
});
message += `\n🔁 Последнее обновление цены: ${utils.getCurrentTime()}`;
return message;
};
// Функция для отправки/обновления сообщения
const updateResourcePricesMessage = async () => {
const pricesText = await getResourcePricesText();
try {
if (resourceMessageId) {
// Если сообщение существует, обновляем его
await bot.telegram.editMessageText(CHANNEL_ID, resourceMessageId, null, pricesText, {
parse_mode: 'Markdown',
});
} else {
// Если сообщения нет, отправляем новое
const sentMessage = await bot.telegram.sendMessage(CHANNEL_ID, pricesText, {
parse_mode: 'Markdown',
});
resourceMessageId = sentMessage.message_id; // Сохраняем ID нового сообщения
console.log("ID сообщения с котировками: " + sentMessage.message_id)
}
} catch (error) {
console.error('Ошибка при обновлении сообщения с ценами ресурсов:', error);
}
};
// Запускаем функцию
updateResourcePricesMessage();
// Запускаем процесс восстановления цен каждые 15 минут
setInterval(recoverResourcePrices, 15 * 60 * 1000);
// Запускаем обновление каждые 15 минут
setInterval(updateResourcePricesMessage, 15 * 60 * 1000);
// Запускаем процессы каждый час
setInterval(resourceProduction, 60 * 60 * 1000);
setInterval(resourceTransportation, 60 * 60 * 1000);
bot.command('force_prod', async (ctx) => {
resourceProduction()
return await ctx.reply(`Принудительно добыто.`)
})
bot.command('force_transport', async (ctx) => {
resourceTransportation()
return await ctx.reply(`Принудительно перевезено.`)
})
bot.command('force_hour', async (ctx) => {
resourceProduction()
resourceTransportation()
return await ctx.reply(`Принудительный час.`)
})
bot.command('force_mat', async (ctx) => {
utils.matPriceUpdate()
return await ctx.reply(`Принудительный материал.`)
})
/////////////////////////////////////Enterprise Update end//////////////////////////////////////////////////
/////////////////////////////////////Casino Update//////////////////////////////////////////////////
const spinSlots = async (ctx, bet, user) => {
const slotIcons = ['🔥', '⚡', '⭐', '💀']; // Иконки для слотов
const spinSpeed = 500; // Скорость анимации (мс)
const spinRounds = 8; // Количество вращений
let slotMessage = await ctx.reply('🎰 Слот-машина крутится...');
// Генерация случайного отображения для анимации
const getRandomIcons = () => {
return `${slotIcons[Math.floor(Math.random() * slotIcons.length)]} | ${slotIcons[Math.floor(Math.random() * slotIcons.length)]} | ${slotIcons[Math.floor(Math.random() * slotIcons.length)]}`;
};
// Анимация вращения
for (let i = 0; i < spinRounds; i++) {
await new Promise((resolve) => setTimeout(resolve, spinSpeed));
const uniqueTag = `[${Date.now()}]`; // Уникальный тег для предотвращения ошибок Telegram
await ctx.telegram.editMessageText(ctx.chat.id, slotMessage.message_id, null, `🎰 ${getRandomIcons()} ${uniqueTag}`);
}
// Определяем результат игры
const winMultiplier = determineWin();
const finalIcons = generateVisualResult(winMultiplier, slotIcons);
// Вычисляем выигрыш/проигрыш
let resultMessage = `🎰 Итог:\n${finalIcons.join(' | ')}\n\n`;
if (winMultiplier > 0) {
const winnings = bet * winMultiplier;
user.money += winnings;
await user.save();
resultMessage += `🎉 Вы выиграли ₽${spaces(winnings)}! Множитель: x${winMultiplier}`;
} else {
user.money -= bet;
await user.save();
resultMessage += `💔 Вы проиграли ₽${spaces(bet)}. Попробуйте ещё раз!`;
}
// Финальный результат
await ctx.telegram.editMessageText(ctx.chat.id, slotMessage.message_id, null, resultMessage);
};
// Функция для определения выигрыша
const determineWin = () => {
const probabilities = {
25: 0.01, // 1% шанс на x25
10: 0.03, // 3% шанс на x10
5: 0.06, // 6% шанс на x5
2: 0.1, // 10% шанс на x2
0: 0.8, // 80% шанс на проигрыш
};
const random = Math.random();
let cumulativeProbability = 0;
for (const [multiplier, probability] of Object.entries(probabilities)) {
cumulativeProbability += probability;
if (random < cumulativeProbability) {
return parseInt(multiplier, 10);
}
}
return 0; // По умолчанию проигрыш
};
// Генерация визуального результата на основе выигрыша
const generateVisualResult = (multiplier, slotIcons) => {
if (multiplier === 25) return ['🔥', '🔥', '🔥'];
if (multiplier === 10) return ['⚡', '⚡', '⚡'];
if (multiplier === 5) return ['⭐', '⭐', '⭐'];
if (multiplier === 2) return ['💀', '💀', '💀'];
return [
slotIcons[Math.floor(Math.random() * slotIcons.length)],
slotIcons[Math.floor(Math.random() * slotIcons.length)],
slotIcons[Math.floor(Math.random() * slotIcons.length)],
]; // Проигрыш: случайные иконки
};
// Основная команда слотов
bot.action(/slots\d+/, async (ctx) => {
try {
const data = ctx.update.callback_query.data;
const bet = parseInt(data.replace('slots', ''), 10);
const user = await UserModel.findByPk(ctx.from.id);
// Проверка на текущую игру
if (user.isPlayingCasino) {
return ctx.answerCbQuery('⏳ Ваша ставка уже обрабатывается. Подождите!', { show_alert: true });
}
if (!user || user.money < bet) {
return ctx.answerCbQuery('💸 У вас недостаточно средств для ставки.', { show_alert: true });
}
const timer = user.slottime;
const cooldown = utils.setCooldown(user, 10, timer);
if (user.slottime > cooldown.currentTime) {
return ctx.answerCbQuery('📛 Слоты будут доступны через пару секунд.', { show_alert: true });
}
// Установить флаг игры
user.isPlayingCasino = true;
user.slottime = cooldown.endTime;
await user.save();
// Запуск игры
await spinSlots(ctx, bet, user);
// Сброс флага игры
user.isPlayingCasino = false;
await user.save();
} catch (error) {
console.error('Ошибка при игре в слоты:', error);
return ctx.reply('Произошла ошибка. Попробуйте снова.');
}
});
// Функция для форматирования чисел
const spaces = (number) => {
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
};
bot.hears('🎰 Рулетка', async (ctx) => {
return ctx.reply('Закрыто на ремонт')
const user = await UserModel.findByPk(ctx.from.id);
if (user.money <= 0) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас недостаточно средств для игры.`, { show_alert: true });
}
// Инициализация ставки через ctx.session
if (!ctx.session.betAmount) {
ctx.session.betAmount = 10000; // Начальная ставка
}
// Вспомогательная функция для генерации случайного числа рулетки
const spinRoulette = () => {
// Все нечетные числа (красные)
const redNumbers = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35];
// Все четные числа (черные)
const blackNumbers = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36];
// Рулетка: делаем случайный выбор
const randomIndex = Math.floor(Math.random() * 37); // от 0 до 36
return randomIndex;
};
// Кнопки для выбора ставки
const buttons = [
[{ text: 'Красный', callback_data: 'red' }],
[{ text: 'Черный', callback_data: 'black' }],
[{ text: 'Выбрать номер', callback_data: 'choose_number' }],
[{ text: `Ставка: ₽${ctx.session.betAmount}`, callback_data: 'no_action' }],
[
{ text: '⬆️ Повысить ставку', callback_data: 'increase_bet' },
{ text: '⬇️ Понизить ставку', callback_data: 'decrease_bet' }
]
];
const message = `🎰 Добро пожаловать в рулетку!\nВыберите ставку: Красный, Черный или Номер (0-36).`;
await ctx.reply(message, Markup.inlineKeyboard(buttons));
// Обработчик для изменения ставки
bot.action('increase_bet', async (ctx) => {
if (ctx.session.betAmount < 50000) {
ctx.session.betAmount += 10000; // Увеличиваем ставку на 10000
const buttons = [
[{ text: 'Красный', callback_data: 'red' }],
[{ text: 'Черный', callback_data: 'black' }],
[{ text: 'Выбрать номер', callback_data: 'choose_number' }],
[{ text: `Ставка: ₽${ctx.session.betAmount}`, callback_data: 'no_action' }],
[
{ text: '⬆️ Повысить ставку', callback_data: 'increase_bet' },
{ text: '⬇️ Понизить ставку', callback_data: 'decrease_bet' }
]
];
await ctx.editMessageText(`🎰 Добро пожаловать в рулетку!\nВыберите ставку: Красный, Черный или Номер (0-36).`, Markup.inlineKeyboard(buttons));
} else {
await ctx.reply('Максимальная ставка - ₽50000');
}
});
bot.action('decrease_bet', async (ctx) => {
if (ctx.session.betAmount > 10000) {
ctx.session.betAmount -= 10000; // Уменьшаем ставку на 10000
const buttons = [
[{ text: 'Красный', callback_data: 'red' }],
[{ text: 'Черный', callback_data: 'black' }],
[{ text: 'Выбрать номер', callback_data: 'choose_number' }],
[{ text: `Ставка: ₽${ctx.session.betAmount}`, callback_data: 'no_action' }],
[
{ text: '⬆️ Повысить ставку', callback_data: 'increase_bet' },
{ text: '⬇️ Понизить ставку', callback_data: 'decrease_bet' }
]
];
await ctx.editMessageText(`🎰 Добро пожаловать в рулетку!\nВыберите ставку: Красный, Черный или Номер (0-36).`, Markup.inlineKeyboard(buttons));
} else {
await ctx.reply('Минимальная ставка - ₽10000');
}
});
bot.action(['red', 'black', 'choose_number'], async (ctx) => {
const data = ctx.update.callback_query.data;
if (user.money < ctx.session.betAmount) {
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `У вас недостаточно средств для этой ставки.`, { show_alert: true });
}
let winMultiplier = 0;
let betResult = '';
const spinResult = spinRoulette();
if (data === 'red') {
if ([1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35].includes(spinResult)) {
winMultiplier = 2;
betResult = `Вы выиграли! 🎉 Красный! Множитель: 2x`;
} else {
betResult = `Вы проиграли. Черный номер. 😢`;
}
} else if (data === 'black') {
if ([0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36].includes(spinResult)) {
winMultiplier = 2;
betResult = `Вы выиграли! 🎉 Черный! Множитель: 2x`;
} else {
betResult = `Вы проиграли. Красный номер. 😢`;
}
} else if (data === 'choose_number') {
const number = Math.floor(Math.random() * 37); // Игрок выбирает случайное число
if (spinResult === number) {
winMultiplier = 35; // Огромный выигрыш для точного угадывания
betResult = `Вы угадали номер! 🎉 Номер ${number}! Множитель: 35x`;
} else {
betResult = `Вы не угадали номер. Выпал номер ${spinResult}. 😢`;
}
}
// Считаем выигрыш
let prize = ctx.session.betAmount * winMultiplier;
user.money += prize; // Вычитаем ставку, если выиграли
await user.save();
// Отправляем результат
return await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, betResult, { show_alert: true });
});
});
/////////////////////////////////////Casino Update end//////////////////////////////////////////////////////
/////////////////////////////////////Admin Commands//////////////////////////////////////////////////
bot.command('answer', commands.reportAnswer)
bot.command('fastblock', commands.fastblock)
bot.command('createpromocode', commands.createPromo)
bot.command('genpromo', commands.genPromo)
bot.command('ban', async (ctx) => {
const user = await UserModel.findByPk(ctx.from.id);
// Проверка прав администратора
if (user.status !== 'admin') {
return await ctx.reply(`У вас нет прав для выполнения этой команды.`);
}
// Разбор аргументов команды
const args = ctx.message.text.split(' ').slice(1);
if (args.length < 3) {
return await ctx.reply(`⚠️ Использование: /ban <ID|username> <время в минутах> <причина>.`);
}
const identifier = args[0]; // ID или username пользователя
const blockTimeMinutes = parseInt(args[1], 10); // Время блокировки в минутах
const reason = args.slice(2).join(' '); // Причина блокировки
// Проверка времени блокировки
if (isNaN(blockTimeMinutes) || blockTimeMinutes <= 0) {
return await ctx.reply(`❌ Укажите корректное время блокировки в минутах.`);
}
// Ищем пользователя по Telegram ID или никнейму
let targetUser;
if (identifier.startsWith('@')) {
// Если передан username
targetUser = await UserModel.findOne({ where: { username: identifier.slice(1) } });
} else {
// Если передан Telegram ID
targetUser = await UserModel.findOne({ where: { telegram_id: identifier } });
}
if (!targetUser) {
return await ctx.reply(`❌ Пользователь с идентификатором "${identifier}" не найден.`);
}
// Создаём запись о блокировке
const block = await BlockModel.create({
telegram_id: targetUser.telegram_id,
isBlocked: true,
reason: reason,
time: Math.trunc(Date.now() / 1000 + blockTimeMinutes * 60) // Время блокировки в секундах
});
// Уведомляем заблокированного пользователя
try {
await bot.telegram.sendMessage(
targetUser.telegram_id,
`❌ Вы были заблокированы администратором ${user.username}.\nПричина: ${reason}\nСрок: ${blockTimeMinutes} минут(ы).`
);
} catch (error) {
console.error(`Ошибка отправки уведомления пользователю ${targetUser.telegram_id}:`, error);
}
// Уведомляем администратора
return await ctx.reply(
`✅ Пользователь ${targetUser.username || targetUser.telegram_id} был успешно заблокирован.\nПричина: ${reason}\nСрок: ${blockTimeMinutes} минут(ы).`
);
});
///////////////////////////////////////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()