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

# Protokół pluginu

> Kontrakt Socket.IO dla własnego pluginu realizacji: uwierzytelnianie, zdarzenia, atomowy claim i bezpieczne potwierdzanie.

Ta strona jest dla osób, które piszą **własny plugin realizacji** (np. na nietypową platformę). Jeśli chcesz tylko zainstalować oficjalny plugin na serwerze, przejdź do [Plugin na serwerze](https://andcze.mintlify.site/pl/shop/plugin.md).

Plugin łączy się z namespace Socket.IO `/plugin` na publicznym originie API. Połączenie zawsze inicjuje serwer gry — nie wystawia on żadnego portu przychodzącego.

> [!WARNING]
>
> Stary polling REST (`GET /orders/plugin/.../pending`, `POST /orders/plugin/.../complete`) został wycofany. Nie dawał atomowego claimu przy wielu instancjach ani ochrony niejednoznacznego okna awarii. Używaj wyłącznie protokołu poniżej.

## Uwierzytelnianie

Handshake namespace przekazuje:

```json theme={null}
{ "apiKey": "isk_<64 znaki hex>", "serverId": "<24 znaki hex>" }
```

Backend akceptuje połączenie tylko gdy:

* klucz jest aktywny, typu `plugin` i ma `orders:write`;
* klucz jest przypisany do sklepu, a `serverId` należy do tego samego sklepu;
* autor klucza nadal ma dostęp do sklepu.

Każde niepowodzenie kończy się ogólnym `unauthorized` — bez informacji, który warunek zawiódł. Klucz tworzysz w panelu (preset **Plugin Minecraft**), zobacz [API z kluczem](https://andcze.mintlify.site/pl/developers/api-keys.md).

## Zdarzenia (protokół v1)

| Kierunek | Event | Dane / ACK |
| - | - | - |
| plugin → app | `hello` | `{ platform, version }` |
| app → plugin | `ready` | `{ serverId, serverName }` |
| app → plugin | `order:deliver` | `{ v: 1, id, player, status, commands[], requireOnline }` |
| plugin → app | `order:claim` | `{ orderId }`; ACK zwraca świeży snapshot komend dla zwycięzcy claimu |
| plugin → app | `order:release` | dobrowolne oddanie claimu, gdy świeży warunek dostawy nie jest spełniony |
| plugin → app | `order:verify` | ponowne sprawdzenie bieżącego statusu dostawy, która długo czekała |
| plugin → app | `order:complete` | `{ orderId }`; dopiero ACK pozwala usunąć lokalny wpis `AWAITING_ACK` |
| plugin → app | `order:uncertain` | zgłoszenie odzyskanego `EXECUTING`; odpowiedź: `manual-review`, `retry` albo `complete` |
| plugin → app | `orders:pull` | limitowana prośba o pełny replay zaległości |
| plugin → app | `players:update` | `{ online, max, players?[] }`; backend filtruje i limituje wartości |
| plugin → app | `ping:app` | diagnostyczny ACK z czasem aplikacji |

Backend wysyła pełny replay zaległości po każdym połączeniu oraz push po opłaceniu lub zmianie statusu zamówienia. **Powtórzone `order:deliver` jest normalne** — o prawie do wykonania decyduje atomowy claim i lokalny journal, nie samo otrzymanie eventu.

## Stany bezpieczeństwa

Plugin musi prowadzić lokalny journal zapisywany z `fsync`:

**1. Claim**

`order:claim` przełącza zamówienie z `paid` lub `dispute` na `processing`. Warunkową zmianę w bazie wygrywa tylko jedna instancja.

**2. EXECUTING**

Zapisz i zsynchronizuj `EXECUTING` **przed** pierwszą komendą.

**3. AWAITING\_ACK**

Po ostatniej komendzie zapisz i zsynchronizuj `AWAITING_ACK`.

**4. Complete**

`order:complete` przełącza zamówienie na `completed`. Lokalny wpis usuwasz dopiero po ACK.

Po restarcie:

* wpis `AWAITING_ACK` → ponów **tylko** `order:complete`, nie komendy;
* wpis `EXECUTING` → **nie** powtarzaj komend; wyślij `order:uncertain`, co uruchamia ręczną weryfikację.

> [!NOTE]
>
> Nie usuwaj journalu, żeby „odblokować” zamówienie. W panelu sprawdź faktyczny stan gracza i rozstrzygnij wpis ręcznie: `retry` czyści claim po stronie aplikacji i pozwala na nowy push, `complete` uznaje dostawę bez powtarzania komend.

## Komendy i placeholdery

API formatuje komendy produktu, zanim wyśle świeży snapshot zwycięzcy claimu. Plugin dostaje gotowe komendy — nie podstawia niczego sam.

| Placeholder | Zastępowany przez |
| - | - |
| `{PLAYER}` / `{NICK}` | zweryfikowany nick z zamówienia |
| `{QUANTITY}` | ilość |
| `{PRODUCT}` | nazwę produktu |
| `{QUANTITY*1.5:2}` | dozwolone wyrażenie matematyczne, zaokrąglone do 2 miejsc |

Wyrażenia liczy ograniczony parser — nie są wykonywane jako kod. Progi `quantityTiers`, wariant komend i bonus pakietu rozstrzyga API. Plugin powinien dodatkowo odrzucać komendy, których pierwsze słowo jest na liście `blockedCommands`.

## Gracz online

Gdy `requireOnline` jest ustawione, wykonaj komendy dopiero po wykryciu właściwego nicku na dozwolonym serwerze. Lokalna kopia, która długo czekała, musi zostać sprawdzona przez `order:verify` — tak, by anulowane lub zwrócone zamówienie nie zostało wykonane ze starego eventu. Jeśli warunek dostawy nie jest spełniony po claimie, oddaj go przez `order:release`.

## Dalej

> **[Plugin na serwerze](https://andcze.mintlify.site/pl/shop/plugin.md)**
>
> Instalacja i konfiguracja oficjalnego pluginu.

> **[Zamówienia](https://andcze.mintlify.site/pl/shop/orders.md)**
>
> Statusy zamówień i ręczna weryfikacja w panelu.

> **[API z kluczem](https://andcze.mintlify.site/pl/developers/api-keys.md)**
>
> Klucze typu `plugin` i ich zakres.

> **[Błędy i limity](https://andcze.mintlify.site/pl/developers/errors-and-limits.md)**
>
> Limity i ponawianie po stronie REST.


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