Initial commit

This commit is contained in:
Degradin 2023-09-18 12:09:43 +03:00
commit 80a50d8abb
18 changed files with 3953 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

127
.gitignore vendored Normal file
View File

@ -0,0 +1,127 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

15
business.model.js Normal file
View File

@ -0,0 +1,15 @@
const sequelize = require('./db');
const {DataTypes} = require('sequelize');
const Business = sequelize.define('business', {
id: {type: DataTypes.INTEGER, primaryKey: true, unique: true, autoIncrement: true},
name: {type: DataTypes.STRING, defaultValue: "Организация не найдена."},
owner: {type: DataTypes.INTEGER, defaultValue: 0},
balance: {type: DataTypes.INTEGER, defaultValue: 0},
materials: {type: DataTypes.INTEGER, defaultValue: 0},
users: {type: DataTypes.ARRAY(DataTypes.INTEGER)},
checks: {type: DataTypes.INTEGER, defaultValue: 0},
percent: {type: DataTypes.INTEGER, defaultValue: 10}
})
module.exports = Business;

12
db.js Normal file
View File

@ -0,0 +1,12 @@
const {Sequelize} = require('sequelize');
module.exports = new Sequelize(
'campfire',
'bot',
'Ka23ds05!',
{
host: 'localhost',
port: '5432',
dialect: 'postgres'
}
)

52
db/weaponshop.json Normal file
View File

@ -0,0 +1,52 @@
{
"0": {
"name": "AK-47",
"price": 1000,
"type": "weapon"
},
"1": {
"name": "AK-47",
"price": 1000,
"type": "weapon"
},
"2": {
"name": "SCAR-L",
"price": 1000,
"type": "weapon"
},
"3": {
"name": "Five-Seven",
"price": 1000,
"type": "weapon"
},
"4": {
"name": "AK-47",
"price": 1000,
"type": "weapon"
},
"5": {
"name": "Бронежилет M4",
"price": 1000,
"type": "equipment"
},
"6": {
"name": "Бронежилет M6",
"price": 1000,
"type": "equipment"
},
"7": {
"name": "Бронежилет M5",
"price": 1000,
"type": "equipment"
},
"8": {
"name": "Бронежилет M5",
"price": 1000,
"type": "equipment"
},
"9": {
"name": "Бронежилет M3",
"price": 1000,
"type": "equipment"
}
}

810
index.js Normal file
View File

@ -0,0 +1,810 @@
require('dotenv').config()
const { Telegraf, Markup } = require('telegraf')
const { formatDistanceToNowStrict } = require('date-fns');
const fs = require('fs')
const bot = new Telegraf(process.env.BOT_TOKEN)
const weaponshop = require('./db/weaponshop.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 UserModel = require('./user.model');
const WorldModel = require('./world.model');
const JobModel = require('./job.model');
const PropertyModel = require('./property.model');
const BusinessModel = require('./business.model');
const whitelist = [275416286, 1797342681]
const adminList = [275416286]
const expToUp = [0, 10, 15, 22, 35, 50, 70, 85, 100, 125, 200]
const start = async () => {
try {
await sequelize.authenticate()
await sequelize.sync()
} catch (e) {
console.log('Подключение к бд сломалось', e)
}
}
bot.use(async (ctx, next) => {
let id = ctx.from.id
let username = ctx.from.username
let user = await UserModel.findByPk(id);
let property = await PropertyModel.findByPk(id);
if (user === null) {
UserModel.create({
telegram_id: id,
username: username,
})
} else {}
if (property === null) {
PropertyModel.create({
telegram_id: id
})
} else {}
if(id == 1045983457) return ctx.reply(`Резчиков detected...`)
if (whitelist.includes(id) == false) return ctx.reply(`У вас пока нет доступа к боту. Следите за обновлениями в группе: t.me/CampFireGameBotNews`)
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 === null) {
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('Main Menu', Markup
.keyboard([
['😎 Профиль', '💳 Баланс'], // Row1 with 2 buttons
['Работать', 'Бонус'], // Row2 with 2 buttons
['📢 Вакансии', 'Мир', '📞 Пригласить'] // Row3 with 3 buttons
])
.oneTime()
.resize()
)
})
bot.hears('Меню', async (ctx) => {
return await ctx.reply('Main Menu', Markup
.keyboard([
['😎 Профиль', '💳 Баланс'], // Row1 with 2 buttons
['Работать', 'Бонус'], // Row2 with 2 buttons
['📢 Вакансии', 'Мир', '📞 Пригласить'] // Row3 with 3 buttons
])
.oneTime()
.resize()
)
});
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.reply(`
👤 ${user.username} ${adminList.includes(ctx.from.id)? " ✅" : ""}
🆔 ID: ${ctx.from.id}
📶 Уровень: ${user.level} | ${user.exp} / ${expToUp[user.level]}
Повышается за различные действия.
Баланс
¤${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 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 count = rand(2,3)
for(i=0;i<count;i++){
let money = [100, 200, 300, 400, 500, 1000].random();
if(user.level >= 1){
money += money;
}
let r = rand(1,2);
if(r == 1) {
user.money += money;
world.balance -= money
text += `⏩ ¤${money}\n`;
}
if(r == 2){
user.money += money * 2;
world.balance -= money * 2
text += `⏩ ¤${money*2}\n`;
}
}
//uplvl(user);
await user.save();
await world.save();
return ctx.reply(`
Из ежечасного бонуса Вам выпало:
${text}
`)
})
bot.command('pay', async (ctx) => {
ctx.args = ctx.update.message.text.split(' ')
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[1] || !ctx.args[2]) return ctx.reply(`Не указан аргумент.`)
if (!Number(ctx.args[2])) return ctx.reply(`Сумма должна быть числовая.`)
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 = `
Входящий перевод.
Отправитель: ${sender.username}
Идентификатор отправителя: ${sender.telegram_id}
Сумма: ¤${ctx.args[2]}
Ваш баланс: ¤${receiver.money}
`
bot.telegram.sendMessage(receiver.telegram_id, pmToReceiver)
return ctx.reply(`
Операция.
Получатель: ${receiver.username}
Идентификатор получателя: ${receiver.telegram_id}
Сумма: ¤${ctx.args[2]}
Комиссия: ¤${fee}
Ваш баланс: ¤${sender.money}
`)
})
bot.hears('Мир', async (ctx) => {
let world = await WorldModel.findByPk(1)
return ctx.reply(`
Баланс мира: ¤${spaces(world.balance)}
`)
})
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) => {
let user = await UserModel.findByPk(ctx.from.id);
return await ctx.reply('Список работы', Markup
.keyboard([
['Дворник', 'Промоутер'], // Row1 with 2 buttons
['Официант', 'Бармен'], // Row2 with 2 buttons
['Кассир', 'ПВЗ Дикие Ягоды', 'Слесарь'] // Row3 with 3 buttons
])
.oneTime()
.resize()
)
})
bot.hears('Дворник', async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id);
let 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(`Вы уже устроены на другую работу`)
})
bot.hears('Промоутер', async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id);
let 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(`Вы уже устроены на другую работу`)
})
bot.hears('Официант', async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id);
let 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(`Вы уже устроены на другую работу`)
})
bot.hears('Бармен', async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id);
let 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(`Вы уже устроены на другую работу`)
})
bot.hears('Слесарь', async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id);
let 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(`Вы уже устроены на другую работу`)
})
bot.hears('Кассир', async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id);
let 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(`Вы уже устроены на другую работу`)
})
bot.hears('ПВЗ Дикие Ягоды', async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id);
let 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(`Вы уже устроены на другую работу`)
})
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 user = await UserModel.findByPk(ctx.from.id);
if (user.job != 0){
user.job = 0
user.save()
return await ctx.reply(`Теперь вы безработный.`)
}
return await ctx.reply(`Вы итак безработный.`)
})
bot.hears('Топ', async (ctx) => {
let topPlayer = await UserModel.findAll({
attributes: ['username', [sequelize.fn('sum', sequelize.col('money')), 'money']],
group: ['username'],
order: [[sequelize.literal('money'), 'DESC']],
limit: 10
})
if (!topPlayer[9]) {
console.log(topPlayer[0])
return await ctx.reply(`
В данный момент недостаточно игроков для составления топ 10, показывается только топ 1.
Игрок с наибольшим балансом:
1. ${topPlayer[0].username} [¤${topPlayer[0].money}]
`)
} else {
return await ctx.reply(`
Рейтинг игроков:
1. ${topPlayer[0].username}
2. ${topPlayer[1].username}
3. ${topPlayer[2].username}
4. ${topPlayer[3].username}
5. ${topPlayer[4].username}
6. ${topPlayer[5].username}
7. ${topPlayer[6].username}
8. ${topPlayer[7].username}
9. ${topPlayer[8].username}
10. ${topPlayer[9].username}
`)
}
})
bot.hears('Имущество', async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id);
return await ctx.reply(`Тестовое внесение данных `)
})
bot.hears('Жилье', async (ctx) => {
let text = `Вы зашли на сайт с предложениями жилья:\n`
for(i in houses){
text += i + `. ${houses[i].name}${houses[i].price}) [/buy house ${i}]\n`
}
return await ctx.reply(text)
})
bot.hears('Телефоны', async (ctx) => {
let text = `Вы зашли в магазин электроники:\n`
for(i in phones){
text += i + `. ${phones[i].name}${phones[i].price}) [/buy phone ${i}]\n`
}
return await ctx.reply(text)
})
bot.hears('Автосалон', async (ctx) => {
let text = `Автомобили доступные в автосалоне:\n`
for(i in cars){
text += i + `. ${cars[i].name}${cars[i].price}) [/buy car ${i}]\n`
}
return await ctx.reply(text)
})
bot.hears('Поставщик', async (ctx) => {
let text = `Вы подходите к зданию с вывеской "Ништяки Хаткейса".\nВлад Хаткейс: "Вот мой ассортимент на сегодня:"\n`
for(i = 0; i < 10; i++){
text += `${i}. ${weaponshop[i].name}${weaponshop[i].price}) [/buy equipment ${i}]\n`
}
weaponShopUpdate()
return await ctx.reply(text)
})
bot.command('buy', 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] || !ctx.args[2]) return ctx.reply(`Не указан аргумент.`)
if (!Number(ctx.args[2])) return ctx.reply(`Неверно указан параметр.`)
if (ctx.args[1] == "house"){
user.money -= houses[ctx.args[2]].price
world.balance += houses[ctx.args[2]].price
property.house = houses[ctx.args[2]]
await user.save()
await world.save()
await property.save()
return await ctx.reply(`Вы купили ${houses[ctx.args[2]].name}`)
}
if (ctx.args[1] == "car"){
user.money -= cars[ctx.args[2]].price
world.balance += cars[ctx.args[2]].price
property.car = cars[ctx.args[2]]
await user.save()
await world.save()
await property.save()
return await ctx.reply(`Вы купили ${cars[ctx.args[2]].name}`)
}
if (ctx.args[1] == "phone"){
user.money -= phones[ctx.args[2]].price
world.balance += phones[ctx.args[2]].price
property.mobile = phones[ctx.args[2]]
await user.save()
await world.save()
await property.save()
return await ctx.reply(`Вы купили ${phones[ctx.args[2]].name}`)
}
if (ctx.args[1] == "equipment"){
if (ctx.args[1] == weaponshop[ctx.args[2]].type){
user.money -= weaponshop[ctx.args[2]].price
world.balance += weaponshop[ctx.args[2]].price
property.equipment = weaponshop[ctx.args[2]]
await user.save()
await world.save()
await property.save()
return await ctx.reply(`Вы купили ${weaponshop[ctx.args[2]].name}`)
}
user.money -= weaponshop[ctx.args[2]].price
world.balance += weaponshop[ctx.args[2]].price
property.weapon = weaponshop[ctx.args[2]]
await user.save()
await world.save()
await property.save()
return await ctx.reply(`Вы купили ${weaponshop[ctx.args[2]].name}`)
}
return await ctx.reply(`Вы купили.`)
})
bot.hears('Организация', async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id)
let business = await BusinessModel.findOne({owner: ctx.from.id})
if (business === null) return await ctx.reply(`У вас нет организации.`)
console.log(business)
return await ctx.reply(`Ваша организация\n${business.name}\nБаланс: ${business.balance}\nСырье: ${business.materials}\nРабочих: ${business.users.length}`)
})
bot.hears('Отработка', async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id)
let business = await BusinessModel.findOne({owner: ctx.from.id})
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.reply(`📛 Работа в организации будет доступна через ${cooldown.timeLeftInMinutes} минут(у/ы)`);
user.business = {
id: user.business.id,
checks: user.business.checks + 1,
percent: 100
}
business.checks += 1
await user.save()
await business.save()
return await ctx.reply(`Вы отработали час на ${business.name}`)
})
bot.command('payday', async (ctx) => {
let user = null
let business = await BusinessModel.findOne({owner: ctx.from.id})
let world = await WorldModel.findByPk(1)
if (business === null) return await ctx.reply(`У вас нет организации.`)
if (business.checks < 12) return await ctx.reply(`Недостаточно отработок для формирования выплаты.`)
let percentSum = business.percent
let text = ``
let profit = 0
let piece = 0
let businessPercent = 0
let moneyList = rand(500, 2000)
for (i=0; i < business.users.length; i++){ // Summary percent
user = await UserModel.findByPk(business.users[i])
console.log(business.users[i])
percentSum += user.business.percent
text += `${user.username} ${user.business.percent}%\n`
}
if (percentSum > 100) return await ctx.reply(`Общий процент всех сотрудников превышает 100%\nПроцент организации: ${business.percent}%\n${text}`)
for (i=0; i < business.users.length; i++){ // Общая внесенная сумма всеми участниками
user = await UserModel.findByPk(business.users[i])
profit = user.business.checks * moneyList
business.balance += profit
text += `${user.username} нарабатывает ${profit} [${moneyList}*${user.business.checks}] в баланс организации.\n`
}
businessPercent = profit / 100 * business.percent
for (i=0; i < business.users.length; i++){ // Процент выплаты участникам
user = await UserModel.findByPk(business.users[i])
piece = Math.trunc(profit / 100 * user.business.percent)
business.balance -= piece
text += `${user.username} получает ${piece}\n`
}
return await ctx.reply(text)
})
bot.command('business', async (ctx) => {
let user = await UserModel.findByPk(ctx.from.id)
let business = await BusinessModel.findOne({owner: ctx.from.id})
let world = await WorldModel.findByPk(1)
if (business !== null) return await ctx.reply(`У вас уже есть организация.`)
if (!ctx.args[1]) return ctx.reply(`Не указан аргумент.`)
if (user.money < 100000) return await ctx.reply(`Регистрация организации стоит ¤100.000`)
if (user.level < 5) return await ctx.reply(`Регистрация организации доступна с 5 уровня.`)
ctx.args = ctx.update.message.text.split(' ')
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(' ')
let user = await UserModel.findByPk(ctx.from.id)
let invited = await UserModel.findOne({ where: { username: ctx.args[1] } });
await bot.telegram.sendMessage(invited.telegram_id, 'Приглашение', Markup
.inlineKeyboard([
[{text: `Принять ${user.username}`, callback_data: ctx.from.id}, {text: `Отклонить ${user.username}`, callback_data: '0'}]]).oneTime())
return await ctx.reply(`Приглашение отправлено.`)
})
bot.on('callback_query', async ctx => {
const data = ctx.update.callback_query.data;
let user = await UserModel.findByPk(ctx.update.callback_query.from.id)
if (data != 0) {
let business = await BusinessModel.findOne({owner: data})
user.business = {
id: data,
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, `Приглашение принято.`)
} else {
await ctx.telegram.answerCbQuery(ctx.callbackQuery.id, `Приглашение отклонено.`)
}
})
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("");
};
Array.prototype.random = function() {
return this[Math.floor(this.length * Math.random())];
}
function setCooldown(user, seconds, type) {
let cooldown = {}
cooldown.currentTime = Math.trunc(Date.now()/1000)
if(adminList.includes(user.telegram_id)) {
cooldown.endTime = Math.trunc(Date.now()/1000)
}else{
cooldown.endTime = Math.trunc(Date.now()/1000 + seconds)
}
cooldown.timeLeft = cooldown.endTime - cooldown.currentTime
cooldown.timeLeftInMinutes = Math.ceil((type - cooldown.currentTime)/60)
return cooldown
}
function giveExp(user, experience) {
user.exp += experience
if (user.exp >= expToUp[user.level]){
user.level += 1
user.exp = 0
user.save()
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('db/weaponshop.json', JSON.stringify(weaponshop, null, "\t"))
}
setInterval(() => {
var today = new Date();
let hours = today.getHours();
if(hours == "0" || hours == "12" || hours == "23"){
weaponShopUpdate()
}
}, 360000);
weaponShopUpdate()
start()
bot.launch()

11
job.model.js Normal file
View File

@ -0,0 +1,11 @@
const sequelize = require('./db');
const {DataTypes} = require('sequelize');
const Job = sequelize.define('job', {
id: {type: DataTypes.INTEGER, primaryKey: true, unique: true, autoIncrement: true},
level: {type: DataTypes.INTEGER, defaultValue: 1},
salary: {type: DataTypes.INTEGER, defaultValue: 1000},
exp: {type: DataTypes.INTEGER, defaultValue: 1}
})
module.exports = Job;

20
options.js Normal file
View File

@ -0,0 +1,20 @@
module.exports = {
gameOptions: {
reply_markup: JSON.stringify({
inline_keyboard: [
[{text: '1', callback_data: '1'}, {text: '2', callback_data: '2'}, {text: '3', callback_data: '3'}],
[{text: '4', callback_data: '4'}, {text: '5', callback_data: '5'}, {text: '6', callback_data: '6'}],
[{text: '7', callback_data: '7'}, {text: '8', callback_data: '8'}, {text: '9', callback_data: '9'}],
[{text: '0', callback_data: '0'}],
]
})
},
againOptions: {
reply_markup: JSON.stringify({
inline_keyboard: [
[{text: 'Играть еще раз', callback_data: '/again'}],
]
})
}
}

2649
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

24
package.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "telegram-bot-course",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "nodemon index.js",
"start": "node index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"date-fns": "^2.30.0",
"dotenv": "^16.3.1",
"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",
"sequelize": "^6.6.2",
"telegraf": "^4.13.1"
}
}

42
presets/cars.json Normal file
View File

@ -0,0 +1,42 @@
{
"1": {
"name": "Car2",
"price": 0
},
"2": {
"name": "Car3",
"price": 10
},
"3": {
"name": "Car4",
"price": 20
},
"4": {
"name": "Car5",
"price": 30
},
"5": {
"name": "Car6",
"price": 40
},
"6": {
"name": "Car7",
"price": 50
},
"7": {
"name": "Car86",
"price": 60
},
"8": {
"name": "Car8",
"price": 70
},
"9": {
"name": "Car9",
"price": 80
},
"10": {
"name": "Car10",
"price": 90
}
}

52
presets/equipment.json Normal file
View File

@ -0,0 +1,52 @@
{
"1": {
"name": "Наколенники",
"price": 1000,
"type": "equipment"
},
"2": {
"name": "Картонные накладки",
"price": 1000,
"type": "equipment"
},
"3": {
"name": "Шлем танкиста",
"price": 1000,
"type": "equipment"
},
"4": {
"name": "Кольчуга",
"price": 1000,
"type": "equipment"
},
"5": {
"name": "Бронежилет M1",
"price": 1000,
"type": "equipment"
},
"6": {
"name": "Бронежилет M2",
"price": 1000,
"type": "equipment"
},
"7": {
"name": "Бронежилет M3",
"price": 1000,
"type": "equipment"
},
"8": {
"name": "Бронежилет M4",
"price": 1000,
"type": "equipment"
},
"9": {
"name": "Бронежилет M5",
"price": 1000,
"type": "equipment"
},
"10": {
"name": "Бронежилет M6",
"price": 1000,
"type": "equipment"
}
}

42
presets/houses.json Normal file
View File

@ -0,0 +1,42 @@
{
"1": {
"name": "Подвал",
"price": 100
},
"2": {
"name": "Дом",
"price": 100
},
"3": {
"name": ом2",
"price": 100
},
"4": {
"name": ом3",
"price": 100
},
"5": {
"name": ом4",
"price": 100
},
"6": {
"name": ом5",
"price": 100
},
"7": {
"name": ом6",
"price": 100
},
"8": {
"name": ом7",
"price": 100
},
"9": {
"name": ом8",
"price": 100
},
"10": {
"name": ом9",
"price": 100
}
}

1
presets/mobiles.json Normal file
View File

@ -0,0 +1 @@
{}

52
presets/weapons.json Normal file
View File

@ -0,0 +1,52 @@
{
"1": {
"name": "ПМ",
"price": 1000,
"type": "weapon"
},
"2": {
"name": "ТТ",
"price": 1000,
"type": "weapon"
},
"3": {
"name": "Five-Seven",
"price": 1000,
"type": "weapon"
},
"4": {
"name": "Deagle",
"price": 1000,
"type": "weapon"
},
"5": {
"name": "AK-47",
"price": 1000,
"type": "weapon"
},
"6": {
"name": "M4A1",
"price": 1000,
"type": "weapon"
},
"7": {
"name": "SCAR-H",
"price": 1000,
"type": "weapon"
},
"8": {
"name": "MP5",
"price": 1000,
"type": "weapon"
},
"9": {
"name": "SCAR-L",
"price": 1000,
"type": "weapon"
},
"10": {
"name": "Glock",
"price": 1000,
"type": "weapon"
}
}

13
property.model.js Normal file
View File

@ -0,0 +1,13 @@
const sequelize = require('./db');
const {DataTypes} = require('sequelize');
const Property = sequelize.define('property', {
telegram_id: {type: DataTypes.INTEGER, primaryKey: true, unique: true},
house: {type: DataTypes.JSON, defaultValue: 0},
car: {type: DataTypes.JSON, defaultValue: 0},
mobile: {type: DataTypes.JSON, defaultValue: 0},
weapon: {type: DataTypes.JSON, defaultValue: 0},
equipment: {type: DataTypes.JSON, defaultValue: 0}
})
module.exports = Property;

19
user.model.js Normal file
View File

@ -0,0 +1,19 @@
const sequelize = require('./db');
const {DataTypes} = require('sequelize');
const User = sequelize.define('user', {
telegram_id: {type: DataTypes.INTEGER, primaryKey: true, unique: true},
username: {type: DataTypes.STRING},
level: {type: DataTypes.INTEGER, defaultValue: 1},
exp: {type: DataTypes.INTEGER, defaultValue: 0},
money: {type: DataTypes.INTEGER, defaultValue: 0},
bonus: {type: DataTypes.INTEGER, defaultValue: 0},
bonustime: {type: DataTypes.INTEGER, defaultValue: 0},
job: {type: DataTypes.INTEGER, defaultValue: 0},
jobcheck: {type: DataTypes.INTEGER, defaultValue: 0},
jobtime: {type: DataTypes.INTEGER, defaultValue: 0},
business: {type: DataTypes.JSON, defaultValue: 0},
worktime: {type: DataTypes.INTEGER, defaultValue: 0}
})
module.exports = User;

10
world.model.js Normal file
View File

@ -0,0 +1,10 @@
const sequelize = require('./db');
const {DataTypes} = require('sequelize');
const World = sequelize.define('world', {
id: {type: DataTypes.INTEGER, primaryKey: true, unique: true},
balance: {type: DataTypes.INTEGER, defaultValue: 50000000},
transactionfee: {type: DataTypes.INTEGER, defaultValue: 1}
})
module.exports = World;