add: if player online when display marketplace in TopBar

This commit is contained in:
2025-07-19 02:07:34 +05:00
parent 56da7c7543
commit c39a8bc43c
5 changed files with 192 additions and 5 deletions

View File

@ -16,6 +16,7 @@ import { Notifier } from './components/Notifier';
import { VersionsExplorer } from './pages/VersionsExplorer';
import Profile from './pages/Profile';
import Shop from './pages/Shop';
import Marketplace from './pages/Marketplace';
const AuthCheck = ({ children }: { children: ReactNode }) => {
const [isAuthenticated, setIsAuthenticated] = useState<boolean | null>(null);
@ -158,6 +159,14 @@ const App = () => {
</AuthCheck>
}
/>
<Route
path="/marketplace"
element={
<AuthCheck>
<Marketplace />
</AuthCheck>
}
/>
</Routes>
</Box>
</Router>

View File

@ -45,6 +45,56 @@ export interface ApiError {
details?: string;
}
export interface Server {
id: string;
name: string;
ip: string;
port: number;
description: string;
online_players: number;
max_players: number;
last_activity: string;
}
export interface ActiveServersResponse {
servers: Server[];
}
// Исправьте тип возвращаемого значения
export async function fetchActiveServers(): Promise<Server[]> {
const response = await fetch(`${API_BASE_URL}/api/pranks/servers`);
if (!response.ok) {
throw new Error('Не удалось получить активные сервера');
}
return await response.json();
}
export interface OnlinePlayersResponse {
server: {
id: string;
name: string;
};
online_players: {
// Это массив объектов, а не один объект
username: string;
uuid: string;
online_since: string;
}[]; // Добавьте [] здесь чтобы указать, что это массив
count: number;
}
export async function fetchOnlinePlayers(
server_id: string,
): Promise<OnlinePlayersResponse> {
const response = await fetch(
`${API_BASE_URL}/api/pranks/servers/${server_id}/players`,
);
if (!response.ok) {
throw new Error('Не удалось получить онлайн игроков');
}
return await response.json();
}
// Получение информации о игроке
export async function fetchPlayer(uuid: string): Promise<Player> {
try {

View File

@ -5,6 +5,7 @@ import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded';
import { useEffect, useState } from 'react';
import { Tooltip } from '@mui/material';
import { fetchCoins } from '../api';
import { isPlayerOnline } from '../utils/playerOnlineCheck';
declare global {
interface Window {
@ -33,6 +34,7 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
const navigate = useNavigate();
const [coins, setCoins] = useState<number>(0);
const [value, setValue] = useState(0);
const [isOnline, setIsOnline] = useState<boolean>(false);
const handleChange = (event: React.SyntheticEvent, newValue: number) => {
setValue(newValue);
@ -42,6 +44,8 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
navigate('/profile');
} else if (newValue === 2) {
navigate('/shop');
} else if (newValue === 3) {
navigate('/marketplace');
}
};
@ -74,11 +78,31 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
}
};
const checkPlayerOnlineStatus = async () => {
if (!username) return;
try {
const online = await isPlayerOnline(username);
setIsOnline(online);
} catch (error) {
console.error('Ошибка при проверке онлайн-статуса:', error);
setIsOnline(false);
}
};
useEffect(() => {
if (username) {
fetchCoinsData();
const intervalId = setInterval(fetchCoinsData, 60000);
return () => clearInterval(intervalId);
checkPlayerOnlineStatus(); // Проверяем сразу
// Создаем интервалы для периодического обновления данных
const coinsInterval = setInterval(fetchCoinsData, 60000);
const onlineStatusInterval = setInterval(checkPlayerOnlineStatus, 30000); // Каждые 30 секунд
return () => {
clearInterval(coinsInterval);
clearInterval(onlineStatusInterval);
};
}
}, [username]);
@ -138,16 +162,38 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
>
<Tab
label="Версии"
sx={{ color: 'white', fontFamily: 'Benzin-Bold' }}
sx={{
color: 'white',
fontFamily: 'Benzin-Bold',
fontSize: '0.7em',
}}
/>
<Tab
label="Профиль"
sx={{ color: 'white', fontFamily: 'Benzin-Bold' }}
sx={{
color: 'white',
fontFamily: 'Benzin-Bold',
fontSize: '0.7em',
}}
/>
<Tab
label="Магазин"
sx={{ color: 'white', fontFamily: 'Benzin-Bold' }}
sx={{
color: 'white',
fontFamily: 'Benzin-Bold',
fontSize: '0.7em',
}}
/>
{isOnline && (
<Tab
label="Рынок"
sx={{
color: 'white',
fontFamily: 'Benzin-Bold',
fontSize: '0.7em',
}}
/>
)}
</Tabs>
</Box>
)}

View File

@ -0,0 +1,3 @@
export default function Marketplace() {
return <div>Marketplace</div>;
}

View File

@ -0,0 +1,79 @@
import { fetchActiveServers, fetchOnlinePlayers } from '../api';
/**
* Проверяет, находится ли указанный игрок онлайн на любом из серверов
* @param username Имя игрока для проверки
* @returns {Promise<boolean>} true, если игрок онлайн хотя бы на одном сервере
*/
export async function isPlayerOnline(username: string): Promise<boolean> {
try {
console.log('Начинаем проверку статуса для:', username);
// Получаем список активных серверов (теперь это массив)
const servers = await fetchActiveServers();
console.log('Ответ API активных серверов:', servers);
// Фильтруем серверы с игроками
const serversWithPlayers = servers.filter(
(server) => server.online_players > 0,
);
// Если нет серверов с игроками, игрок точно не онлайн
if (serversWithPlayers.length === 0) {
return false;
}
// Проверяем каждый сервер на наличие игрока
const checkPromises = serversWithPlayers.map(async (server) => {
try {
const onlinePlayers = await fetchOnlinePlayers(server.id);
// Проверяем, есть ли игрок с указанным именем в списке
// Предполагая, что онлайн игроки хранятся в массиве online_players
return (
Array.isArray(onlinePlayers.online_players) &&
onlinePlayers.online_players.some(
(player) => player.username === username,
)
);
} catch (error) {
console.error(`Ошибка при проверке сервера ${server.id}:`, error);
return false;
}
});
// Ожидаем результаты всех проверок
const results = await Promise.all(checkPromises);
// Игрок онлайн, если хотя бы одна проверка вернула true
return results.some((result) => result);
} catch (error) {
console.error('Ошибка при проверке онлайн-статуса игрока:', error);
return false; // В случае ошибки считаем, что игрок не онлайн
}
}
/**
* Проверяет, находится ли указанный игрок онлайн на конкретном сервере
* @param username Имя игрока для проверки
* @param serverId ID сервера для проверки
* @returns {Promise<boolean>} true, если игрок онлайн на указанном сервере
*/
export async function isPlayerOnlineOnServer(
username: string,
serverId: string,
): Promise<boolean> {
try {
const onlinePlayers = await fetchOnlinePlayers(serverId);
return (
Array.isArray(onlinePlayers.online_players) &&
onlinePlayers.online_players.some(
(player) => player.username === username,
)
);
} catch (error) {
console.error(`Ошибка при проверке игрока на сервере ${serverId}:`, error);
return false;
}
}