v5.9.3
MiniApp updates
This commit is contained in:
parent
d9e5eb0d79
commit
b8debe8fc4
3
index.js
3
index.js
@ -1,4 +1,4 @@
|
|||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
|
|
||||||
const sequelize = require('./db'); // Подключение базы данных
|
const sequelize = require('./db'); // Подключение базы данных
|
||||||
|
|
||||||
@ -10,4 +10,3 @@ global.utils = require('./utils');
|
|||||||
|
|
||||||
// Инициализация бота
|
// Инициализация бота
|
||||||
require('./bot')
|
require('./bot')
|
||||||
require('./server'); // Подключение модуля API
|
|
4544
json/logs.json
4544
json/logs.json
File diff suppressed because it is too large
Load Diff
@ -13,8 +13,8 @@
|
|||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
max-width: 700px;
|
max-width: 600px;
|
||||||
margin: 30px auto;
|
margin: 20px auto;
|
||||||
background: white;
|
background: white;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
@ -26,7 +26,7 @@
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
color: #4e7dd1;
|
color: #e26f22;
|
||||||
}
|
}
|
||||||
.section {
|
.section {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
@ -34,7 +34,7 @@
|
|||||||
.section h2 {
|
.section h2 {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
color: #4e7dd1;
|
color: #e26f22;
|
||||||
}
|
}
|
||||||
.section p {
|
.section p {
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
@ -44,7 +44,7 @@
|
|||||||
}
|
}
|
||||||
.button {
|
.button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-color: #4e7dd1;
|
background-color: #e26f22;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@ -52,7 +52,7 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
.emoji {
|
.emoji {
|
||||||
font-size: 1.3em;
|
font-size: 1.3em;
|
||||||
@ -67,6 +67,159 @@
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
.profile-container {
|
||||||
|
position: relative;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-img {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-ring {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
circle {
|
||||||
|
transition: stroke-dashoffset 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-ring {
|
||||||
|
stroke-width: 10;
|
||||||
|
fill: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-level-ring {
|
||||||
|
stroke: #e26f22;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-level-ring {
|
||||||
|
stroke: #4e9f3d;
|
||||||
|
}
|
||||||
|
|
||||||
|
#progress-ring {
|
||||||
|
stroke-dasharray: 283;
|
||||||
|
stroke-dashoffset: 283;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-circle {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -7px;
|
||||||
|
right: 10px;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: #e26f22;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar {
|
||||||
|
margin-top: 15px;
|
||||||
|
background-color: #ddd;
|
||||||
|
border-radius: 10px;
|
||||||
|
height: 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-hp {
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #e26f22;
|
||||||
|
transition: width 0.5s ease;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-stamina {
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #4ba100;
|
||||||
|
transition: width 0.5s ease;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fire-stats {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fire-stats .stat {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fire-stats .stat span {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.circle {
|
||||||
|
stroke-width: 10;
|
||||||
|
fill: transparent;
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-level-ring {
|
||||||
|
stroke: #e26f22;
|
||||||
|
stroke-dasharray: 283;
|
||||||
|
stroke-dashoffset: 283;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-level-ring {
|
||||||
|
stroke: #4e9f3d;
|
||||||
|
stroke-dasharray: 283;
|
||||||
|
stroke-dashoffset: 283;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Для создания полукругов */
|
||||||
|
.circle {
|
||||||
|
transform-origin: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-level-ring {
|
||||||
|
stroke-dasharray: 141.5; /* половина окружности */
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-level-ring {
|
||||||
|
stroke-dasharray: 141.5; /* половина окружности */
|
||||||
|
transform: rotate(180deg); /* Поворот правого полукруга */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<script src="https://telegram.org/js/telegram-web-app.js"></script>
|
<script src="https://telegram.org/js/telegram-web-app.js"></script>
|
||||||
</head>
|
</head>
|
||||||
@ -74,12 +227,52 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="title">📜 Меню игрока</div>
|
<div class="title">📜 Меню игрока</div>
|
||||||
|
|
||||||
|
<div class="profile-container">
|
||||||
|
<div id="profile-img" class="profile-img"></div>
|
||||||
|
<div class="progress-ring">
|
||||||
|
<svg width="100" height="100">
|
||||||
|
<circle class="profile-level-ring circle" cx="50%" cy="50%" r="45%"/>
|
||||||
|
<circle class="character-level-ring circle" cx="50%" cy="50%" r="45%"/>
|
||||||
|
</svg>
|
||||||
|
<div id="level-circle" class="level-circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="progress-bar">
|
||||||
|
<div class="progress-hp" id="hp-bar"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="progress-bar">
|
||||||
|
<div class="progress-stamina" id="stamina-bar"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fire-stats">
|
||||||
|
<div class="stat">
|
||||||
|
<p>Сила</p>
|
||||||
|
<span id="force">—</span>
|
||||||
|
</div>
|
||||||
|
<div class="stat">
|
||||||
|
<p>Интеллект</p>
|
||||||
|
<span id="intelligence">—</span>
|
||||||
|
</div>
|
||||||
|
<div class="stat">
|
||||||
|
<p>Выносливость</p>
|
||||||
|
<span id="endurance">—</span>
|
||||||
|
</div>
|
||||||
|
<div class="stat">
|
||||||
|
<p>Стойкость</p>
|
||||||
|
<span id="resilience">—</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h2>👤 Личные данные</h2>
|
<h2>👤 Личные данные</h2>
|
||||||
<p>Имя: <span id="name">—</span></p>
|
<p>Имя: <span id="name">—</span></p>
|
||||||
<p>Уровень: <span id="level">—</span></p>
|
<p>Telegram ID: <span id="telegramID">—</span></p>
|
||||||
<p>Опыт: <span id="exp">—</span></p>
|
</div>
|
||||||
<p>Здоровье: <span id="hp">—</span> / <span id="max_hp">—</span></p>
|
|
||||||
|
<div class="section">
|
||||||
|
<h2>👤 Профиль</h2>
|
||||||
<p>Деньги: ₽<span id="money">—</span></p>
|
<p>Деньги: ₽<span id="money">—</span></p>
|
||||||
<p>Грязные деньги: ₽<span id="dirtymoney">—</span></p>
|
<p>Грязные деньги: ₽<span id="dirtymoney">—</span></p>
|
||||||
</div>
|
</div>
|
||||||
@ -98,7 +291,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="https://t.me/yourbot" class="button">🏠 Перейти в чат бота</a>
|
|
||||||
|
|
||||||
|
<a href="https://t.me/CampFireGameBot" class="button">🏠 Перейти в чат бота</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -112,13 +307,50 @@
|
|||||||
|
|
||||||
// Личные данные
|
// Личные данные
|
||||||
document.getElementById("name").textContent = user.name || user.username;
|
document.getElementById("name").textContent = user.name || user.username;
|
||||||
document.getElementById("level").textContent = user.level;
|
document.getElementById("telegramID").textContent = user.telegramID;
|
||||||
document.getElementById("exp").textContent = user.exp;
|
|
||||||
document.getElementById("hp").textContent = user.hp;
|
// Профиль
|
||||||
document.getElementById("max_hp").textContent = user.max_hp;
|
|
||||||
document.getElementById("money").textContent = user.money;
|
document.getElementById("money").textContent = user.money;
|
||||||
document.getElementById("dirtymoney").textContent = user.dirtymoney;
|
document.getElementById("dirtymoney").textContent = user.dirtymoney;
|
||||||
|
|
||||||
|
// Устанавливаем картинку профиля
|
||||||
|
const profileImg = document.getElementById("profile-img");
|
||||||
|
const profilePhotoUrl = tg.initDataUnsafe.user.photo_url;
|
||||||
|
|
||||||
|
if (profilePhotoUrl) {
|
||||||
|
profileImg.style.backgroundImage = `url(${profilePhotoUrl})`;
|
||||||
|
} else {
|
||||||
|
profileImg.style.backgroundImage = `url('https://via.placeholder.com/100')`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Полоса опыта (прогресс бар вокруг аватарки)
|
||||||
|
const progressRing = document.querySelectorAll("circle");
|
||||||
|
const expProgress = (user.profileExp / user.profileExpToUp) * 100;
|
||||||
|
const offset = 283 - (283 * expProgress) / 100;
|
||||||
|
progressRing[0].style.strokeDashoffset = offset; // Левый полукруг для уровня профиля
|
||||||
|
|
||||||
|
const characterProgress = (user.characterLevel / user.characterExpToUp) * 100;
|
||||||
|
const characterOffset = 283 - (283 * characterProgress) / 100;
|
||||||
|
progressRing[1].style.strokeDashoffset = characterOffset; // Правый полукруг для уровня персонажа
|
||||||
|
|
||||||
|
// Уровень в кружке
|
||||||
|
document.getElementById("level-circle").textContent = user.profileLevel;
|
||||||
|
|
||||||
|
// Установка прогресса HP и Стамины
|
||||||
|
const hpProgress = (user.hp / user.maxHp) * 100;
|
||||||
|
const staminaProgress = (user.stamina / user.maxStamina) * 100;
|
||||||
|
|
||||||
|
document.getElementById("hp-bar").textContent = `${hpProgress}%`;
|
||||||
|
document.getElementById('hp-bar').style.width = `${hpProgress}%`;
|
||||||
|
document.getElementById("stamina-bar").textContent = `${staminaProgress}%`;
|
||||||
|
document.getElementById('stamina-bar').style.width = `${staminaProgress}%`;
|
||||||
|
|
||||||
|
// Характеристики FIRE
|
||||||
|
document.getElementById("force").textContent = user.force;
|
||||||
|
document.getElementById("intelligence").textContent = user.intelligence;
|
||||||
|
document.getElementById("endurance").textContent = user.endurance;
|
||||||
|
document.getElementById("resilience").textContent = user.resilience;
|
||||||
|
|
||||||
// Организация
|
// Организация
|
||||||
document.getElementById("business-name").textContent = business.name;
|
document.getElementById("business-name").textContent = business.name;
|
||||||
document.getElementById("business-balance").textContent = business.balance;
|
document.getElementById("business-balance").textContent = business.balance;
|
||||||
@ -133,7 +365,7 @@
|
|||||||
div.classList.add("enterprise");
|
div.classList.add("enterprise");
|
||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<strong>${ent.name}</strong><br>
|
<strong>${ent.name}</strong><br>
|
||||||
Тип ресурса: ${getResourceIcon(ent.resourceType)} ${ent.resourceType}<br>
|
Тип ресурса: ${getResourceIcon(ent.resourceType)} ${getResourceName(ent.resourceType)}<br>
|
||||||
Уровень: ${ent.level}<br>
|
Уровень: ${ent.level}<br>
|
||||||
Эффективность: ${ent.efficiency}/час<br>
|
Эффективность: ${ent.efficiency}/час<br>
|
||||||
Заполненность склада: ${ent.currentResources}/${ent.warehouseCapacity}
|
Заполненность склада: ${ent.currentResources}/${ent.warehouseCapacity}
|
||||||
@ -146,18 +378,29 @@
|
|||||||
console.error("Ошибка загрузки данных:", err);
|
console.error("Ошибка загрузки данных:", err);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Функция для конвертации типов ресурсов в эмодзи
|
|
||||||
function getResourceIcon(resource) {
|
function getResourceIcon(resource) {
|
||||||
switch (resource.toLowerCase()) {
|
switch (resource.toLowerCase()) {
|
||||||
case 'дерево': return '🌳';
|
case 'wood': return '🌳';
|
||||||
case 'металл': return '🛠️';
|
case 'metall': return '🛠️';
|
||||||
case 'нефть': return '🛢️';
|
case 'oil': return '🛢️';
|
||||||
case 'уголь': return '⛏️';
|
case 'coal': return '⛏️';
|
||||||
case 'золото': return '💰';
|
case 'gold': return '💰';
|
||||||
case 'алмазы': return '💎';
|
case 'diamond': return '💎';
|
||||||
default: return '⚙️';
|
default: return '⚙️';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getResourceName(resource) {
|
||||||
|
switch (resource.toLowerCase()) {
|
||||||
|
case 'wood': return 'Дерево';
|
||||||
|
case 'metall': return 'Металл';
|
||||||
|
case 'oil': return 'Нефть';
|
||||||
|
case 'coal': return 'Уголь';
|
||||||
|
case 'gold': return 'Золото';
|
||||||
|
case 'diamond': return 'Алмазы';
|
||||||
|
default: return 'Ресурс';
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
2
server.bat
Normal file
2
server.bat
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
nodemon --ignore json/ .\server.js
|
||||||
|
pause
|
34
server.js
34
server.js
@ -1,3 +1,12 @@
|
|||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
|
const sequelize = require('./db'); // Подключение базы данных
|
||||||
|
|
||||||
|
// Настраиваем глобальные переменные (опционально)
|
||||||
|
global.path = require('path');
|
||||||
|
global.config = require('./config'); // Конфигурация
|
||||||
|
global.database = sequelize; // База данных
|
||||||
|
global.utils = require('./utils');
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { UserModel, CharacterModel, BusinessModel, EnterpriseModel } = global.config;
|
const { UserModel, CharacterModel, BusinessModel, EnterpriseModel } = global.config;
|
||||||
const app = express();
|
const app = express();
|
||||||
@ -9,10 +18,9 @@ app.get('/player/:id', async (req, res) => {
|
|||||||
const playerId = req.params.id;
|
const playerId = req.params.id;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log(playerId)
|
|
||||||
const user = await UserModel.findOne({ where: { telegram_id: req.params.id } });
|
const user = await UserModel.findOne({ where: { telegram_id: req.params.id } });
|
||||||
const character = await CharacterModel.findOne({ where: { telegram_id: playerId } });
|
const character = await CharacterModel.findOne({ where: { telegram_id: playerId } });
|
||||||
let business = await BusinessModel.findOne({ where: { owner: playerId.toString() } })
|
let business = await BusinessModel.findOne({ where: { owner: playerId } })
|
||||||
if(business === null){
|
if(business === null){
|
||||||
business = await BusinessModel.findOne( {where: { owner: user.business.id} } )
|
business = await BusinessModel.findOne( {where: { owner: user.business.id} } )
|
||||||
}
|
}
|
||||||
@ -25,13 +33,25 @@ app.get('/player/:id', async (req, res) => {
|
|||||||
res.json({
|
res.json({
|
||||||
user: {
|
user: {
|
||||||
username: user.username,
|
username: user.username,
|
||||||
|
telegramID: user.telegram_id,
|
||||||
name: user.name,
|
name: user.name,
|
||||||
level: user.level,
|
status: user.status,
|
||||||
exp: user.exp,
|
profileLevel: user.level,
|
||||||
|
characterLevel: character.level,
|
||||||
|
profileExp: user.exp,
|
||||||
|
characterExp: character.exp,
|
||||||
|
profileExpToUp: global.config.expToUp[user.level],
|
||||||
|
characterExpToUp: global.config.expToUp[character.level],
|
||||||
hp: character.hp,
|
hp: character.hp,
|
||||||
max_hp: character.max_hp,
|
maxHp: character.max_hp,
|
||||||
money: user.money,
|
stamina: character.stamina,
|
||||||
dirtymoney: character.dirtymoney,
|
maxStamina: character.max_stamina,
|
||||||
|
force: character.force,
|
||||||
|
intelligence: character.intelligence,
|
||||||
|
resilience: character.resilience,
|
||||||
|
endurance: character.endurance,
|
||||||
|
money: global.utils.spaces(user.money),
|
||||||
|
dirtymoney: global.utils.spaces(character.dirtymoney),
|
||||||
},
|
},
|
||||||
business: business || { name: "Отсутствует", balance: 0, materials: 0, users: [] },
|
business: business || { name: "Отсутствует", balance: 0, materials: 0, users: [] },
|
||||||
enterprises: enterprises || [],
|
enterprises: enterprises || [],
|
||||||
|
Loading…
Reference in New Issue
Block a user