> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xneon.org/llms.txt
> Use this file to discover all available pages before exploring further.

# @xnlc/servers: управление Minecraft-серверами

> Документация модуля @xnlc/servers: запуск, остановка, метрики, консоль и установка ядер серверов Minecraft на Node.js.

Модуль `@xnlc/servers` управляет серверными процессами Minecraft напрямую через Node.js. Он запускает JAR-файлы, парсит консоль, собирает метрики CPU/RAM, поддерживает graceful-остановку и скачивание популярных ядер. Не зависит от Electron: подходит для панелей, ботов и headless-скриптов.

<CardGroup>
  <Card title="Версия 1.0.6" icon="brand-npm" />

  <Card title="Лицензия: GPL-3.0 (как и лаунчер)" icon="license" />
</CardGroup>

## Установка

<CodeGroup>
  ```bash npm theme={null}
  npm install @xnlc/servers --registry https://git.xneon.org/api/packages/MAINER4IK/npm/
  ```

  ```bash pnpm theme={null}
  pnpm add @xnlc/servers --registry https://git.xneon.org/api/packages/MAINER4IK/npm/
  ```
</CodeGroup>

## Возможности

* Запуск сервера через `ChildProcess` с stdin/stdout/stderr
* Graceful-остановка командой `stop`, принудительное завершение по таймауту
* Сбор метрик: CPU%, RAM (МБ), аптайм (с нормализацией на ядра)
* Буфер консоли до 2000 строк с детектом готовности
* Распознавание ядер: Vanilla, Forge, Fabric, Quilt, NeoForge, Paper, Spigot, Bukkit, Purpur, Folia, Sponge, BungeeCord, Velocity, Waterfall, свой JAR
* Скачивание ядер: Paper, Purpur, Folia, Velocity, Waterfall, Sponge
* Ping сервера по протоколу SLP (Server List Ping)
* Распознавание EULA и маркеров запуска/остановки

## ServerManager

Главный класс для управления серверными процессами. Доступен как синглтон `serverManager`.

```ts theme={null}
import { ServerManager, serverManager } from "@xnlc/servers";

const manager = new ServerManager();
// или serverManager (единый экземпляр)
```

### Запуск

```ts theme={null}
await manager.start(
  id,           // уникальный идентификатор сервера
  serverInfo,   // McServerInfo: настройки сервера
  javaPath,     // путь к Java
  serverDir,    // рабочая папка сервера
  onLog,        // (line: string) => void: каждая строка консоли
  onStateChange // (state: McServerState) => void: изменение состояния
);
```

<ParamField body="serverInfo" type="McServerInfo" required>
  <Expandable title="Свойства">
    <ParamField body="name" type="string">
      Имя сервера
    </ParamField>

    <ParamField body="modloader" type="string">
      Ядро сервера (vanilla, paper, forge и т.д.)
    </ParamField>

    <ParamField body="mcVersion" type="string">
      Версия Minecraft
    </ParamField>

    <ParamField body="xmx" type="number">
      Максимальная память в МБ
    </ParamField>

    <ParamField body="xms" type="number">
      Начальная память в МБ
    </ParamField>

    <ParamField body="extraJavaArgs" type="string">
      Дополнительные JVM-аргументы
    </ParamField>
  </Expandable>
</ParamField>

Состояния сервера (`McServerState`):

| Статус | Значение |
| - | - |
| `stopped` | Процесс не запущен |
| `starting` | Процесс создан, ждем маркер готовности |
| `running` | Маркер готовности получен, сервер работает |
| `stopping` | Получена команда остановки |

Маркер готовности определяется по строке вида `Done (5.123s)! For help, type "help"`. Если маркер не появился за 180 секунд, сервер автоматически переводится в `running` (страховка от нестандартных ядер).

### Остановка

```ts theme={null}
await manager.stop(id);  // graceful: команда stop → 30 с → SIGKILL
await manager.kill(id);  // немедленное принудительное завершение
```

Повторные вызовы `stop()` ждут текущую остановку, а не отправляют команду снова. Если сервер еще в фазе `starting`, команда `stop` не отправляется: процесс убивается сразу.

### Команды

```ts theme={null}
await manager.sendCommand(id, "say Hello");
```

Команда отправляется только если сервер в статусе `running`. В фазе `starting` выбрасывается ошибка.

### Метрики

```ts theme={null}
// Синхронно: значения из кэша фонового сэмплера
const metrics = manager.getMetricsSync(id);
// { cpuPercent: number, memoryMb: number, uptimeSeconds: number }

// Запустить фоновый сбор (1 с интервал по умолчанию)
manager.startMetricsSampler(1000);
```

CPU считается по дельте между двумя замерами и нормализуется на число ядер. На Windows для сбора метрик используется PowerShell (`Get-Process`). На Linux данные читаются из `/proc/<pid>/stat` и `/proc/<pid>/status`.

### Консоль

```ts theme={null}
const lines = manager.getLogBuffer(id); // до 2000 строк
manager.appendConsoleLine(id, "BuildTools compile..."); // добавить строку вне процесса
manager.clearInstallLogs(id); // очистить логи установки перед стартом
```

Буфер склеивает логи установки ядра (BuildTools, инсталлер Forge) и живой вывод процесса. Установочные логи очищаются перед стартом, чтобы в консоли оставался только вывод самого сервера.

### Состояние

```ts theme={null}
manager.getState(id);        // McServerState
manager.isRunning(id);       // процесс жив (включая starting)
manager.isStarted(id);       // сервер подтвердил готовность
```

### Остановка всех серверов

```ts theme={null}
manager.stopAll(); // kill для всех запущенных процессов
```

## Скачивание ядер

Модуль экспортирует функции для получения доступных версий и сборок ядер:

```ts theme={null}
import {
  ensureServerJar,
  getPaperVersions, getPaperBuilds,
  getPurpurVersions, getPurpurBuilds,
  getFoliaVersions, getFoliaBuilds,
  getVelocityVersions, getVelocityBuilds,
  getWaterfallVersions, getWaterfallBuilds,
  getSpongeSupportedVersions, getSpongeBuilds,
} from "@xnlc/servers";
```

`ensureServerJar` скачивает указанное ядро в целевую папку.

## Ping сервера

```ts theme={null}
import { pingServer, parseHost } from "@xnlc/servers";

const status = await pingServer("play.example.com", 25565);
// ServerStatusResult: MOTD, онлайн, макс. слотов, версия, пинг
```

## Анализ JAR

```ts theme={null}
import { analyzeServerJar } from "@xnlc/servers";

const info = await analyzeServerJar("/path/to/server.jar");
// JarAnalysisResult: тип ядра, версия, зависимости
```

## Детектор состояний

Модуль экспортирует константы и функции для определения состояния по строкам консоли:

```ts theme={null}
import {
  STARTUP_DONE_PATTERNS,
  STOPPING_PATTERNS,
  EULA_PROMPT_PATTERN,
  isStartupDoneLine,
  isStoppingLine,
} from "@xnlc/servers";
```

| Константа/функция | Назначение |
| - | - |
| `STARTUP_DONE_PATTERNS` | Регулярные выражения для строки готовности |
| `STOPPING_PATTERNS` | Маркеры начала остановки |
| `EULA_PROMPT_PATTERN` | Сервер требует принятия EULA |
| `isStartupDoneLine(line)` | Проверить, является ли строка маркером готовности |
| `isStoppingLine(line)` | Проверить, началась ли остановка |

## Кодировка

Консоль сервера декодируется сначала как UTF-8. При обнаружении replacement characters (`U+FFFD`) происходит fallback на CP1251 (типичная кодировка русскоязычных серверов на Windows).

## Пример: полный цикл

```ts theme={null}
import { ServerManager } from "@xnlc/servers";

const manager = new ServerManager();

await manager.start(
  "my-server",
  {
    name: "Survival",
    modloader: "paper",
    mcVersion: "1.21.4",
    xmx: 4096,
    xms: 1024,
  },
  "/usr/bin/java",
  "./mc-servers/my-server",
  (line) => console.log("[LOG]", line),
  (state) => console.log("[STATE]", state.status)
);

// Ждем готовности
while (!manager.isStarted("my-server")) {
  await new Promise((r) => setTimeout(r, 500));
}

// Отправляем команду
await manager.sendCommand("my-server", "op Steve");

// Читаем метрики
console.log(manager.getMetricsSync("my-server"));

// Останавливаем
await manager.stop("my-server");
```

## Типы

Основные типы импортируются из `@xnlc/types`:

* `McServerInfo`, `McServerState`, `McServerMetrics`
* `McPlayerEntry`, `McFsEntry`, `ResolvedPlugin`
* `ServerStatusResult`
* `XnConnectState`, `XnConnectUsage`
* `McServerDownloadProgress`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.