diff --git a/src/main/main.ts b/src/main/main.ts index e99fdd5..2e56464 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -14,7 +14,11 @@ import { autoUpdater } from 'electron-updater'; import log from 'electron-log'; import MenuBuilder from './menu'; import { resolveHtmlPath } from './util'; -import { initMinecraftHandlers, initAuthHandlers } from './minecraft-launcher'; +import { + initMinecraftHandlers, + initAuthHandlers, + initServerStatusHandler, +} from './minecraft-launcher'; class AppUpdater { constructor() { @@ -44,9 +48,6 @@ if (isDebug) { require('electron-debug').default(); } -// Инициализация обработчиков Minecraft -initMinecraftHandlers(); - const installExtensions = async () => { const installer = require('electron-devtools-installer'); const forceDownload = !!process.env.UPGRADE_EXTENSIONS; @@ -77,6 +78,7 @@ const createWindow = async () => { show: false, width: 1024, height: 728, + autoHideMenuBar: true, icon: getAssetPath('icon.png'), webPreferences: { webSecurity: false, @@ -118,6 +120,7 @@ const createWindow = async () => { initAuthHandlers(); initMinecraftHandlers(); + initServerStatusHandler(); }; /** diff --git a/src/main/minecraft-launcher.ts b/src/main/minecraft-launcher.ts index df02f67..ed2a53d 100644 --- a/src/main/minecraft-launcher.ts +++ b/src/main/minecraft-launcher.ts @@ -18,12 +18,8 @@ import { spawn } from 'child_process'; import { AuthService } from './auth-service'; // Константы -const COMFORT_DOWNLOAD_URL = - 'https://github.com/DIKER0K/Comfort/releases/latest/download/Comfort.zip'; -const GITHUB_API_RELEASE_URL = - 'https://api.github.com/repos/DIKER0K/Comfort/releases/latest'; -const COMFORT_VERSION_FILE = 'comfort_version.txt'; const AUTHLIB_INJECTOR_FILENAME = 'authlib-injector-1.2.5.jar'; +const MCSTATUS_API_URL = 'https://api.mcstatus.io/v2/status/java/'; // Создаем экземпляр сервиса аутентификации const authService = new AuthService(); @@ -769,3 +765,44 @@ export function initAuthHandlers() { }, ); } + +// Функция для получения статуса сервера +export function initServerStatusHandler() { + ipcMain.handle('get-server-status', async (event, { host, port }) => { + try { + // Формируем адрес с портом, если указан + const serverAddress = port ? `${host}:${port}` : host; + console.log( + `Запрос статуса сервера: ${MCSTATUS_API_URL}${serverAddress}`, + ); + + // Делаем запрос к API mcstatus.io + const response = await fetch(`${MCSTATUS_API_URL}${serverAddress}`); + + // Проверяем статус ответа + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`API вернул ошибку ${response.status}: ${errorText}`); + } + + const data = await response.json(); + console.log('Получен ответ от API:', data); + + if (data.online) { + return { + success: true, + online: data.players?.online || 0, + max: data.players?.max || 0, + version: data.version?.name_clean || 'Unknown', + icon: data.icon || null, // Возвращаем иконку + motd: data.motd?.clean || '', // Название сервера + }; + } else { + return { success: false, error: 'Сервер не доступен' }; + } + } catch (error) { + console.error('Ошибка при получении статуса сервера:', error); + return { success: false, error: error.message }; + } + }); +} diff --git a/src/main/preload.ts b/src/main/preload.ts index a5460ed..8541aae 100644 --- a/src/main/preload.ts +++ b/src/main/preload.ts @@ -4,7 +4,8 @@ export type Channels = | 'ipc-example' | 'download-progress' | 'launch-minecraft' - | 'installation-status'; + | 'installation-status' + | 'get-server-status'; const electronHandler = { ipcRenderer: { diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index 6d9b1ef..a0857c3 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -9,6 +9,19 @@ import LaunchPage from './pages/LaunchPage'; import { ReactNode, useEffect, useState } from 'react'; import './App.css'; +// Переместите launchOptions сюда, вне компонентов +const launchOptions = { + downloadUrl: + 'https://github.com/DIKER0K/Comfort/releases/latest/download/Comfort.zip', + apiReleaseUrl: 'https://api.github.com/repos/DIKER0K/Comfort/releases/latest', + versionFileName: 'comfort_version.txt', + packName: 'Comfort', + memory: 4096, + baseVersion: '1.21.4', + serverIp: 'popa-popa.ru', + fabricVersion: 'fabric0.16.14', +}; + const AuthCheck = ({ children }: { children: ReactNode }) => { const [isAuthenticated, setIsAuthenticated] = useState(null); @@ -66,7 +79,7 @@ const App = () => { path="/" element={ - + } /> diff --git a/src/renderer/components/ServerStatus/ServerStatus.tsx b/src/renderer/components/ServerStatus/ServerStatus.tsx new file mode 100644 index 0000000..8fe3d1e --- /dev/null +++ b/src/renderer/components/ServerStatus/ServerStatus.tsx @@ -0,0 +1,121 @@ +import { Box, Typography, CircularProgress, Avatar } from '@mui/material'; +import { useEffect, useState } from 'react'; + +interface ServerStatusProps { + serverIp: string; + serverPort?: number; + refreshInterval?: number; // Интервал обновления в миллисекундах +} + +const ServerStatus = ({ + serverIp, + serverPort, + refreshInterval = 60000, // По умолчанию обновление раз в минуту +}: ServerStatusProps) => { + const [serverStatus, setServerStatus] = useState<{ + online: number; + max: number; + loading: boolean; + error: string | null; + icon: string | null; + motd: string; + }>({ + online: 0, + max: 0, + loading: true, + error: null, + icon: null, + motd: '', + }); + + useEffect(() => { + // Функция для получения статуса сервера + const fetchServerStatus = async () => { + try { + setServerStatus((prev) => ({ ...prev, loading: true, error: null })); + console.log('Отправляем запрос на сервер с параметрами:', { + host: serverIp, + port: serverPort || 25565, + }); + + // Проверяем, что serverIp имеет значение + if (!serverIp) { + throw new Error('Адрес сервера не указан'); + } + + const result = await window.electron.ipcRenderer.invoke( + 'get-server-status', + { + host: serverIp, + port: serverPort || 25565, + }, + ); + + if (result.success) { + setServerStatus({ + online: result.online, + max: result.max, + loading: false, + error: null, + icon: result.icon, + motd: result.motd || serverIp, + }); + } else { + setServerStatus({ + online: 0, + max: 0, + loading: false, + error: result.error || 'Неизвестная ошибка', + icon: null, + motd: '', + }); + } + } catch (error) { + console.error('Ошибка при получении статуса сервера:', error); + setServerStatus((prev) => ({ + ...prev, + loading: false, + error: 'Ошибка при получении статуса сервера', + icon: null, + })); + } + }; + + // Загрузка при первом рендере + fetchServerStatus(); + + // Периодическое обновление + const interval = setInterval(fetchServerStatus, refreshInterval); + + return () => clearInterval(interval); + }, [serverIp, serverPort, refreshInterval]); + + return ( + + {/* Отображаем иконку сервера или иконку по умолчанию */} + {serverStatus.icon ? ( + + ) : ( + + ? + + )} + + {serverStatus.loading ? ( + + ) : serverStatus.error ? ( + Ошибка загрузки + ) : ( + + {serverStatus.online} / {serverStatus.max} игроков + + )} + + ); +}; + +export default ServerStatus; diff --git a/src/renderer/pages/LaunchPage.tsx b/src/renderer/pages/LaunchPage.tsx index 19a528a..763c6a2 100644 --- a/src/renderer/pages/LaunchPage.tsx +++ b/src/renderer/pages/LaunchPage.tsx @@ -8,6 +8,7 @@ import { } from '@mui/material'; import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; +import ServerStatus from '../components/ServerStatus/ServerStatus'; declare global { interface Window { @@ -21,19 +22,21 @@ declare global { } } -const launchOptions = { - downloadUrl: - 'https://github.com/DIKER0K/Comfort/releases/latest/download/Comfort.zip', - apiReleaseUrl: 'https://api.github.com/repos/DIKER0K/Comfort/releases/latest', - versionFileName: 'comfort_version.txt', - packName: 'Comfort', - memory: 4096, - baseVersion: '1.21.4', - serverIp: 'popa-popa.ru', - fabricVersion: 'fabric0.16.14', -}; +// Определяем тип для props +interface LaunchPageProps { + launchOptions: { + downloadUrl: string; + apiReleaseUrl: string; + versionFileName: string; + packName: string; + memory: number; + baseVersion: string; + serverIp: string; + fabricVersion: string; + }; +} -const LaunchPage = (launchOptions: any) => { +const LaunchPage = ({ launchOptions }: LaunchPageProps) => { const navigate = useNavigate(); const [isDownloading, setIsDownloading] = useState(false); const [downloadProgress, setDownloadProgress] = useState(0); @@ -181,11 +184,15 @@ const LaunchPage = (launchOptions: any) => { Добро пожаловать в лаунчер + + + + {isDownloading ? ( - {/* - Загрузка и установка: {downloadProgress}% - */} { >{`${Math.round(downloadProgress)}%`} - {/* {installMessage && ( - - {installMessage} - - )} - {installStep && ( - - Шаг: {installStep} - - )} */} ) : (