From a31b383dae3796b069c7c8ed85df286b10a04529 Mon Sep 17 00:00:00 2001 From: Degradin Date: Thu, 23 Jan 2025 21:59:59 +0300 Subject: [PATCH] v6.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Новое меню организации --- bot.js | 310 +++++++++++++++++++--- commands/organization/organizationMenu.js | 4 + config/index.js | 1 + models/invite.model.js | 16 ++ models/user.model.js | 13 +- rpg.js | 2 +- 6 files changed, 303 insertions(+), 43 deletions(-) create mode 100644 models/invite.model.js diff --git a/bot.js b/bot.js index 972757b..7ea2cfe 100644 --- a/bot.js +++ b/bot.js @@ -24,6 +24,7 @@ const { ResourcePriceModel, SkillsModel, DailyModel, + InviteModel, logMiddleware, logs } = global.config @@ -166,15 +167,6 @@ bot.use(async (ctx, next) => { 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); // Получаем текущее время в секундах @@ -220,35 +212,112 @@ bot.use(async (ctx, next) => { }) 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") + try { + if (ctx.payload) { // Система обработки приглашений в зависимости от payload + const invite = await InviteModel.findOne({ where: { uid: ctx.payload } }); + + if (invite) { + const user = await UserModel.findByPk(ctx.from.id); + if (!user) { + return await ctx.reply('Ваш профиль не найден.'); + } + + switch (invite.type) { + case 'organization': { + const business = await BusinessModel.findByPk(invite.value); + + if (business) { + // Проверка, состоит ли пользователь уже в организации + if (user.business.id != 0) { + return await ctx.reply('Вы уже состоите в организации.'); + } + + user.business = { + id: business.owner, + checks: 0, + percent: 0 + }; + await user.save({ fields: ['business'] }); + + // Добавляем пользователя в список организации + business.users = sequelize.fn('array_append', sequelize.col('users'), ctx.from.id); + + await business.save(); + + return await ctx.reply(`Вы вступили в организацию "${business.name}".`); + } else { + return await ctx.reply('Организация не найдена.'); + } + } + + case 'referral': { + const inviter = await UserModel.findByPk(invite.author); + + if (ctx.from.id === invite.author) { + return await ctx.reply('Вы не можете пригласить самого себя.'); + } + + if (user.referated) { + return await ctx.reply('Вы уже воспользовались приглашением.'); + } + + if (inviter) { + inviter.money += 250000; + await inviter.save(); + + user.money += 250000; + user.referated = true; + + // Управление статусами + if (user.status === 'bronze') { + user.statustime += 60 * 60 * 24 * 3; // +3 дня + await ctx.reply('Ваш статус "Bronze" продлен на 3 дня.'); + } else if (user.status === 'user') { + user.status = 'bronze'; + user.statustime = Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 3; + await ctx.reply('Вам выдан статус "Bronze" на 3 дня.'); + } + + await user.save(); + + // Обновление данных приглашения + invite.users.push(ctx.from.id); + invite.value++; + await invite.save(); + + await ctx.reply(`Вы получили бонус от пользователя ${inviter.username}.`); + await ctx.reply(`Пользователь ${inviter.username} получил статус "Bronze" на 3 дня.`); + } + break; + } + + default: + return await ctx.reply('Неверный тип приглашения.'); + } } else { - console.log("Exist") + return await ctx.reply('Приглашение не найдено.'); } + } + + // Главное меню + return await ctx.reply( + 'Главное меню', + Markup.keyboard([ + ['😎 Профиль'], // Row1 + ['🗄️ Работать', '🌐 Организация', '🏗️ Предприятия', '🏯 Казино'], // Row2 + ['CampFireGG.Crime'], // Row3 + ['🎁 Бонус'], // Row4 + ['📦 Контейнеры'], // Row5 + ['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'], // Row6 + ['🛡️ Test'], // Row7 + ]).resize() + ); + } catch (error) { + console.error('Ошибка в команде start:', error); + await ctx.reply('Произошла ошибка. Пожалуйста, попробуйте позже.'); } - return await ctx.reply('Главное меню', Markup - .keyboard([ - ['😎 Профиль'], // Row1 with 2 buttons - ['🗄️ Работать', '🌐 Организация', '🏗️ Предприятия', '🏯 Казино'], // Row2 with 2 buttons - ['CampFireGG.Crime'], - ['🎁 Бонус'], - ['📦 Контейнеры'], - ['📢 Вакансии', '🔵 Имущество', '📞 Пригласить'], - ['🛡️ Test'], - ]) - .resize() - ) -}) + }); + bot.hears('🛡️ Test', async (ctx) => { const buttons = [ @@ -538,6 +607,177 @@ bot.command('daily', async (ctx) => { } }); +bot.action('manage_organization', async (ctx) => { + try { + const user = await UserModel.findByPk(ctx.from.id); + if (user.business.id === 0) { + return await ctx.reply('Вы не состоите в организации.'); + } + + const business = await BusinessModel.findOne({ where: { owner: ctx.from.id.toString() } }); + if (!business) { + return await ctx.reply('Организация не найдена.'); + } + if (business.owner != ctx.from.id) { + return await ctx.reply('Вы не являетесь владельцем организации.'); + } + + const buttons = [ + [{ text: '👥 Участники', callback_data: 'org_members' }], + [{ text: '📞 Пригласить', callback_data: 'org_invite' }], + [{ text: '🔧 Настройки', callback_data: 'org_settings' }], + [{ text: '🚫 Расформировать', callback_data: `dissolve_organization_${business.id}` }], + [{ text: '⬅️ Назад', callback_data: 'organization_menu' }] + ]; + + return await ctx.editMessageText(`🏭 Управление организацией "${business.name}":`, Markup.inlineKeyboard(buttons).resize()); + } catch (error) { + console.error('Ошибка при открытии меню управления организацией:', error); + return await ctx.reply('Произошла ошибка. Попробуйте снова.'); + } +}); + +bot.action('org_members', async (ctx) => { + try { + const user = await UserModel.findByPk(ctx.from.id); + if (user.business.id === 0) { + return await ctx.reply('Вы не состоите в организации.'); + } + + const business = await BusinessModel.findOne({ where: { owner: ctx.from.id.toString() } }); + if (!business) { + return await ctx.reply('Организация не найдена.'); + } + + if (business.owner != ctx.from.id) { + return await ctx.reply('Вы не являетесь владельцем организации.'); + } + const buttons = []; + let message = `👥 Участники организации "${business.name}":\n\n`; + for (const member of business.users) { + const user = await UserModel.findByPk(member); + buttons.push([{ text: `👤 ${user.username}`, callback_data: `org_view_member_${user.telegram_id}` }]); + } + + buttons.push([{ text: '🔧 Назад', callback_data: 'manage_organization' }]); + + return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize()); + } catch (error) { + console.error('Ошибка при просмотре участников организации:', error); + return await ctx.reply('Произошла ошибка. Попробуйте снова.'); + } +}); + +bot.action(/org_view_member_(\d+)/, async (ctx) => { + try { + const userId = parseInt(ctx.match[1], 10); + const user = await UserModel.findByPk(userId); + if (!user) { + return await ctx.reply('Пользователь не найден.'); + } + + const business = await BusinessModel.findOne({ where: { owner: ctx.from.id } }); + if (!business) { + return await ctx.reply('Вы не являетесь владельцем организации.'); + } + + if (user.business.id != business.owner) { + return await ctx.reply('Пользователь не состоит в вашей организации.'); + } + + const buttons = [ + [{ text: '📉 Уволить', callback_data: `fireuser_${user.telegram_id}` }], + [{ text: '🔧 Назад', callback_data: 'org_members' }] + ]; + + // Рассчитываем эффективность пользователя + const userChecks = user.business.checks; + const businessChecks = business.checks; + const userEfficiency = userChecks > 0 ? Math.floor((userChecks / businessChecks) * 100) : 0; + + const message = `👤 Профиль участника "${user.username}":\n\n` + + `📶 Отработки: ${user.business.checks}\n` + + `💰 Процент: ${user.business.percent}%\n` + + `🔥 Эффективность: ${userEfficiency}%\n`; + + return await ctx.editMessageText(message, Markup.inlineKeyboard(buttons).resize()); + } catch (error) { + console.error('Ошибка при просмотре участника организации:', error); + return await ctx.reply('Произошла ошибка. Попробуйте снова.'); + } +}); + +// Команда для увольнения сотрудника из организации +bot.action(/fireuser_(\d+)/, async (ctx) => { + try { + const userId = parseInt(ctx.match[1], 10); + const user = await UserModel.findByPk(userId); + if (!user) { + return await ctx.reply('Пользователь не найден.'); + } + + const business = await BusinessModel.findOne({ where: { owner: ctx.from.id } }); + if (!business) { + return await ctx.reply('Вы не являетесь владельцем организации.'); + } + + if (user.business.id != business.owner) { + return await ctx.reply('Пользователь не состоит в вашей организации.'); + } + + if (user.telegram_id == business.owner) { + return await ctx.reply('Вы не можете уволить себя.'); + } + + // Удаляем пользователя из массива участников\ + business.users = business.users.filter((id) => id !== user.telegram_id); + await business.save(); + + user.business = { id: 0, checks: 0, percent: 0 }; + await user.save(); + + return await ctx.reply(`Пользователь ${user.username} уволен из организации.`); + } catch (error) { + console.error('Ошибка при увольнении сотрудника:', error); + return await ctx.reply('Произошла ошибка. Попробуйте снова.'); + } +}); + +bot.action('org_invite', async (ctx) => { + try { + const user = await UserModel.findByPk(ctx.from.id); + if (user.business.id === 0) { + return await ctx.reply('Вы не состоите в организации.'); + } + + const business = await BusinessModel.findOne({ where: { owner: ctx.from.id.toString() } }); + if (!business) { + return await ctx.reply('Организация не найдена.'); + } + + if (business.owner != ctx.from.id) { + return await ctx.reply('Вы не являетесь владельцем организации.'); + } + + // Создаем приглашение + const invites = await InviteModel.findAll({ where: { type: 'organization', author: ctx.from.id } }); + if (invites.length > 0) { + const invite = invites[0]; + const inviteLink = `https://t.me/${process.env.BOT_USERNAME}?start=${invite.uid}`; + return await ctx.reply(`📞 Приглашение для организации "${business.name}":\n\n${inviteLink}`); + } + const invite = await InviteModel.create({ type: 'organization', uid: `${user.username}_org_invite` , author: ctx.from.id, value: business.id }); + const inviteLink = `https://t.me/${process.env.BOT_USERNAME}?start=${invite.uid}`; + + return await ctx.reply(`📞 Приглашение для организации "${business.name}":\n\n${inviteLink}`); + } catch (error) { + console.error('Ошибка при создании приглашения в организацию:', error); + return await ctx.reply('Произошла ошибка. Попробуйте снова.'); + } +}); + + + /////////////////////////////////////Enterprise Update 20.12.2024////////////////////////////////////////////////// diff --git a/commands/organization/organizationMenu.js b/commands/organization/organizationMenu.js index b569081..8ac89a7 100644 --- a/commands/organization/organizationMenu.js +++ b/commands/organization/organizationMenu.js @@ -50,6 +50,10 @@ module.exports = async (ctx) => { text: `💸 Payday`, callback_data: "payday" }, + { + text: `🔧 Управление`, + callback_data: "manage_organization" + }, { text: '❌ Ликвидировать организацию', callback_data: `dissolve_organization_${business.id}` }] diff --git a/config/index.js b/config/index.js index 34a807e..ced77c8 100644 --- a/config/index.js +++ b/config/index.js @@ -39,6 +39,7 @@ module.exports = { ResourcePriceModel: require('../models/resourceprice.model'), SaleModel: require('../models/sales.model'), DailyModel: require('../models/daily.model'), + InviteModel: require('../models/invite.model'), mainChat : -1001895132127, adminList : [275416286], promoTopicId: 1807, diff --git a/models/invite.model.js b/models/invite.model.js new file mode 100644 index 0000000..af8dd26 --- /dev/null +++ b/models/invite.model.js @@ -0,0 +1,16 @@ +const sequelize = require('../db'); +const {DataTypes} = require('sequelize'); + +// Модель Invite, хранит идентификаторы приглашений, приглашение может быть как для регистрации нового пользователя, так и для вступления в организацию или активации какой-либо команды + +const Invite = sequelize.define('invite', { + id: {type: DataTypes.INTEGER, primaryKey: true, unique: true, autoIncrement: true}, + author: {type: DataTypes.BIGINT, defaultValue: 0}, + uid: {type: DataTypes.STRING, unique: true}, + type: {type: DataTypes.STRING, defaultValue: 0}, + value: {type: DataTypes.STRING, defaultValue: 0}, + status: {type: DataTypes.INTEGER, defaultValue: 1}, + users: {type: DataTypes.ARRAY(DataTypes.BIGINT), defaultValue: []} +}) + +module.exports = Invite; diff --git a/models/user.model.js b/models/user.model.js index 7d3d9a3..06b17d2 100644 --- a/models/user.model.js +++ b/models/user.model.js @@ -6,13 +6,10 @@ const User = sequelize.define('user', { username: {type: DataTypes.STRING}, name: {type: DataTypes.STRING}, status: {type: DataTypes.STRING, defaultValue: 'user'}, + statustime: {type: DataTypes.INTEGER, defaultValue: 0}, level: {type: DataTypes.INTEGER, defaultValue: 1}, - hp: {type: DataTypes.INTEGER, defaultValue: 100}, - armor: {type: DataTypes.INTEGER, defaultValue: 0}, exp: {type: DataTypes.INTEGER, defaultValue: 0}, money: {type: DataTypes.INTEGER, defaultValue: 0}, - dirtymoney: {type: DataTypes.INTEGER, defaultValue: 0}, - stealedcards: {type: DataTypes.INTEGER, defaultValue: 0}, bonus: {type: DataTypes.INTEGER, defaultValue: 0}, bonustime: {type: DataTypes.INTEGER, defaultValue: 0}, job: {type: DataTypes.INTEGER, defaultValue: 0}, @@ -26,8 +23,6 @@ const User = sequelize.define('user', { }, worktime: {type: DataTypes.INTEGER, defaultValue: 0}, slottime: {type: DataTypes.INTEGER, defaultValue: 0}, - shoprobcd: {type: DataTypes.INTEGER, defaultValue: 0}, - pocketstealcd: {type: DataTypes.INTEGER, defaultValue: 0}, isPlayingCasino: {type: DataTypes.BOOLEAN, defaultValue: false}, lastLogin: { type: DataTypes.DATE, @@ -36,7 +31,11 @@ const User = sequelize.define('user', { loginStreak: { type: DataTypes.INTEGER, defaultValue: 0, - } + }, + referated: { + type: DataTypes.BOOLEAN, + defaultValue: false, + }, }) module.exports = User; diff --git a/rpg.js b/rpg.js index bdf02c6..54bedf4 100644 --- a/rpg.js +++ b/rpg.js @@ -2517,7 +2517,7 @@ async function addBattleLog(battle, logMessage) { if (!battle.logs) battle.logs = []; // Инициализация массива, если он пустой // Добавляем перед сообщением дату и время до миллисекунды logMessage = `[${new Date().toISOString()}] ${logMessage}`; - battle.logs.push(logMessage); + battle.logs = [...battle.logs, logMessage]; // Добавляем сообщение в массив логов await battle.save({ fields: ["logs"] }); // Сохранение изменений return battle.logs; // Возвращаем обновленный массив логов }