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'); // Подключение базы данных
|
||||
|
||||
@ -10,4 +10,3 @@ global.utils = require('./utils');
|
||||
|
||||
// Инициализация бота
|
||||
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;
|
||||
}
|
||||
.container {
|
||||
max-width: 700px;
|
||||
margin: 30px auto;
|
||||
max-width: 600px;
|
||||
margin: 20px auto;
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 15px;
|
||||
@ -26,7 +26,7 @@
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
color: #4e7dd1;
|
||||
color: #e26f22;
|
||||
}
|
||||
.section {
|
||||
margin-bottom: 20px;
|
||||
@ -34,7 +34,7 @@
|
||||
.section h2 {
|
||||
font-size: 20px;
|
||||
margin-bottom: 10px;
|
||||
color: #4e7dd1;
|
||||
color: #e26f22;
|
||||
}
|
||||
.section p {
|
||||
margin: 5px 0;
|
||||
@ -44,7 +44,7 @@
|
||||
}
|
||||
.button {
|
||||
display: inline-block;
|
||||
background-color: #4e7dd1;
|
||||
background-color: #e26f22;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
text-decoration: none;
|
||||
@ -52,7 +52,7 @@
|
||||
font-size: 16px;
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
width: 50%;
|
||||
}
|
||||
.emoji {
|
||||
font-size: 1.3em;
|
||||
@ -67,6 +67,159 @@
|
||||
margin-top: 10px;
|
||||
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>
|
||||
<script src="https://telegram.org/js/telegram-web-app.js"></script>
|
||||
</head>
|
||||
@ -74,12 +227,52 @@
|
||||
<div class="container">
|
||||
<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">
|
||||
<h2>👤 Личные данные</h2>
|
||||
<p>Имя: <span id="name">—</span></p>
|
||||
<p>Уровень: <span id="level">—</span></p>
|
||||
<p>Опыт: <span id="exp">—</span></p>
|
||||
<p>Здоровье: <span id="hp">—</span> / <span id="max_hp">—</span></p>
|
||||
<p>Telegram ID: <span id="telegramID">—</span></p>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>👤 Профиль</h2>
|
||||
<p>Деньги: ₽<span id="money">—</span></p>
|
||||
<p>Грязные деньги: ₽<span id="dirtymoney">—</span></p>
|
||||
</div>
|
||||
@ -98,7 +291,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="https://t.me/yourbot" class="button">🏠 Перейти в чат бота</a>
|
||||
|
||||
|
||||
<a href="https://t.me/CampFireGameBot" class="button">🏠 Перейти в чат бота</a>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@ -112,13 +307,50 @@
|
||||
|
||||
// Личные данные
|
||||
document.getElementById("name").textContent = user.name || user.username;
|
||||
document.getElementById("level").textContent = user.level;
|
||||
document.getElementById("exp").textContent = user.exp;
|
||||
document.getElementById("hp").textContent = user.hp;
|
||||
document.getElementById("max_hp").textContent = user.max_hp;
|
||||
document.getElementById("telegramID").textContent = user.telegramID;
|
||||
|
||||
// Профиль
|
||||
document.getElementById("money").textContent = user.money;
|
||||
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-balance").textContent = business.balance;
|
||||
@ -133,7 +365,7 @@
|
||||
div.classList.add("enterprise");
|
||||
div.innerHTML = `
|
||||
<strong>${ent.name}</strong><br>
|
||||
Тип ресурса: ${getResourceIcon(ent.resourceType)} ${ent.resourceType}<br>
|
||||
Тип ресурса: ${getResourceIcon(ent.resourceType)} ${getResourceName(ent.resourceType)}<br>
|
||||
Уровень: ${ent.level}<br>
|
||||
Эффективность: ${ent.efficiency}/час<br>
|
||||
Заполненность склада: ${ent.currentResources}/${ent.warehouseCapacity}
|
||||
@ -146,18 +378,29 @@
|
||||
console.error("Ошибка загрузки данных:", err);
|
||||
});
|
||||
|
||||
// Функция для конвертации типов ресурсов в эмодзи
|
||||
function getResourceIcon(resource) {
|
||||
switch (resource.toLowerCase()) {
|
||||
case 'дерево': return '🌳';
|
||||
case 'металл': return '🛠️';
|
||||
case 'нефть': return '🛢️';
|
||||
case 'уголь': return '⛏️';
|
||||
case 'золото': return '💰';
|
||||
case 'алмазы': return '💎';
|
||||
case 'wood': return '🌳';
|
||||
case 'metall': return '🛠️';
|
||||
case 'oil': return '🛢️';
|
||||
case 'coal': return '⛏️';
|
||||
case 'gold': return '💰';
|
||||
case 'diamond': 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>
|
||||
</body>
|
||||
</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 { UserModel, CharacterModel, BusinessModel, EnterpriseModel } = global.config;
|
||||
const app = express();
|
||||
@ -9,10 +18,9 @@ app.get('/player/:id', async (req, res) => {
|
||||
const playerId = req.params.id;
|
||||
|
||||
try {
|
||||
console.log(playerId)
|
||||
const user = await UserModel.findOne({ where: { telegram_id: req.params.id } });
|
||||
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){
|
||||
business = await BusinessModel.findOne( {where: { owner: user.business.id} } )
|
||||
}
|
||||
@ -25,13 +33,25 @@ app.get('/player/:id', async (req, res) => {
|
||||
res.json({
|
||||
user: {
|
||||
username: user.username,
|
||||
telegramID: user.telegram_id,
|
||||
name: user.name,
|
||||
level: user.level,
|
||||
exp: user.exp,
|
||||
status: user.status,
|
||||
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,
|
||||
max_hp: character.max_hp,
|
||||
money: user.money,
|
||||
dirtymoney: character.dirtymoney,
|
||||
maxHp: character.max_hp,
|
||||
stamina: character.stamina,
|
||||
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: [] },
|
||||
enterprises: enterprises || [],
|
||||
|
Loading…
Reference in New Issue
Block a user