> ## 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.

# Plugin Minecraft

> Instalacja i bezpieczna konfiguracja wtyczki realizującej zamówienia na serwerze.

Plugin łączy się wychodząco z ItemShop przez TLS i odbiera opłacone zamówienia w czasie rzeczywistym. Nie otwierasz żadnego portu na serwerze gry. Gdy serwer był offline, zaległe dostawy są odtwarzane po ponownym połączeniu.

## Wymagania

* Java 17 lub nowsza
* Paper/Spigot 1.19+, Folia, BungeeCord albo Velocity 3.x
* serwer dodany w panelu ItemShop
* możliwość zapisu w `plugins/ItemShop/` (konfiguracja i journal realizacji)

## Instalacja z panelu

<Steps>
  <Step title="Pobierz właściwy JAR">
    W panelu sklepu otwórz **Plugin** i pobierz uniwersalny `ItemShop-1.0.0.jar`. Umieść go w folderze `plugins/` jednej platformy — nie instaluj jednocześnie osobnych wariantów i JAR-a uniwersalnego.
  </Step>

  <Step title="Wygeneruj konfigurację">
    Wybierz serwer, kliknij **Wygeneruj klucz pluginu**, a następnie pobierz `config.yml`. Panel tworzy klucz typu `plugin`, związany z tym sklepem, z minimalnym uprawnieniem `orders:write`.
  </Step>

  <Step title="Uruchom plugin">
    Umieść konfigurację w `plugins/ItemShop/config.yml` i uruchom serwer. Komenda `/itemshop` pokazuje stan połączenia, a `/itemshop reload` bezpiecznie przeładowuje konfigurację.
  </Step>
</Steps>

<Warning>
  `apiKey` jest sekretem pokazywanym tylko raz. Nie publikuj `config.yml`, nie commituj go i nie wklejaj do zgłoszeń pomocy. Nie usuwaj `fulfillment-journal.json`: bez niego nie da się bezpiecznie rozstrzygnąć dostawy przerwanej awarią.
</Warning>

## Format konfiguracji

Generator w panelu tworzy kompletne pola w formacie używanym przez plugin:

```yaml config.yml theme={null}
apiUrl: "https://itemshop.dev"
apiKey: "isk_<64 znaki hex>"
serverId: "<24 znaki hex>"

joinDeliveryDelaySeconds: 2
blockedCommands:
  - op
  - deop
  - stop
  - restart
  - reload
  - whitelist
blockedServers:
  - auth
  - login

playersUpdateIntervalSeconds: 30
sendPlayerNames: true
reconnectMinMs: 2000
reconnectMaxMs: 30000
outboxRetrySeconds: 15
debug: false
```

| Pole                                | Znaczenie                                                                                 |
| ----------------------------------- | ----------------------------------------------------------------------------------------- |
| `apiUrl`                            | Publiczny origin aplikacji lub API, **bez** `/api/v2`, ścieżki, loginu i parametrów       |
| `apiKey`                            | Klucz typu `plugin`; wymagany format `isk_` + 64 znaki hex                                |
| `serverId`                          | ID dokładnie jednego serwera z panelu; klucz i serwer muszą należeć do tego samego sklepu |
| `joinDeliveryDelaySeconds`          | Opóźnienie dostawy po pełnym wejściu gracza                                               |
| `blockedCommands`                   | Pierwsze słowa komend, których plugin nigdy nie wykona                                    |
| `blockedServers`                    | Tryby proxy, na których dostawa ma czekać, np. `auth` lub `login`                         |
| `playersUpdateIntervalSeconds`      | Odstęp wysyłania liczby graczy i opcjonalnej listy nicków                                 |
| `sendPlayerNames`                   | Wyłączenie listy nicków nie wyłącza samej liczby graczy                                   |
| `reconnectMinMs` / `reconnectMaxMs` | Granice wykładniczego ponawiania połączenia                                               |
| `outboxRetrySeconds`                | Odstęp ponowienia samego potwierdzenia po wykonaniu komend                                |
| `debug`                             | Szczegółowe logi diagnostyczne; włączaj czasowo                                           |

Produkcyjny `apiUrl` musi używać `https://`. Własna domena API jest poprawna, jeśli ten sam origin obsługuje namespace Socket.IO `/plugin`.

## Jak chroniona jest realizacja

<Steps>
  <Step title="Push i atomowy claim">
    Każda połączona instancja może zobaczyć `order:deliver`, ale tylko jedna wygrywa atomowy `order:claim`. Pozostałe nie wykonują komend.
  </Step>

  <Step title="Trwały journal przed komendą">
    Przed pierwszą komendą plugin zapisuje i synchronizuje na dysk stan `EXECUTING`. Po ostatniej zapisuje `AWAITING_ACK`, a komendy wykonuje na właściwym wątku platformy.
  </Step>

  <Step title="Potwierdzenie lub ręczna weryfikacja">
    `AWAITING_ACK` można po restarcie bezpiecznie potwierdzić bez ponownego uruchamiania komend. Odnaleziony `EXECUTING` jest niejednoznaczny, więc system blokuje automatyczne powtórzenie i kieruje zamówienie do decyzji właściciela: **zrealizowane** albo **ponów**.
  </Step>
</Steps>

Dowolne komendy konsoli nie zapewniają ścisłego exactly-once. Ten mechanizm wybiera bezpieczne at-most-once w niejednoznacznym oknie awarii i wymaga świadomej decyzji zamiast ryzyka podwójnego nadania produktu.

## Test przed sprzedażą

1. Utwórz produkt z niegroźną komendą testową.
2. Złóż zamówienie z rabatem 100%, aby nie uruchamiać operatora płatności.
3. Sprawdź `/itemshop`, log serwera i przejście zamówienia `paid` → `processing` → `completed`.
4. Powtórz test z graczem offline, po wejściu gracza oraz po restarcie pluginu przed dostawą.
5. Osobno wykonaj sandboxowy test prawdziwego operatora: checkout → podpisany webhook → dostawa → ACK.

## Naprawa błędów

<AccordionGroup>
  <Accordion title="Plugin zgłasza brak konfiguracji">
    Sprawdź dokładne nazwy camelCase: `apiUrl`, `apiKey`, `serverId`. Klucz musi zaczynać się od `isk_`, a ID serwera mieć 24 znaki hex. `apiUrl` nie może kończyć się `/api/v2`.
  </Accordion>

  <Accordion title="Połączenie jest odrzucane jako unauthorized">
    Wygeneruj nowy klucz na karcie **Plugin**. Klucz musi mieć typ `plugin`, uprawnienie `orders:write`, być aktywny i przypisany do sklepu, do którego należy `serverId`.
  </Accordion>

  <Accordion title="Zamówienie czeka na gracza">
    Sprawdź dokładną pisownię nicku, wymóg gracza online oraz `blockedServers`. Wejście lub zmiana trybu wywołuje ponowne pobranie zaległości po `joinDeliveryDelaySeconds`.
  </Accordion>

  <Accordion title="Zamówienie wymaga ręcznej weryfikacji">
    Plugin odnalazł po awarii stan `EXECUTING`; co najmniej jedna komenda mogła już się wykonać. Najpierw sprawdź stan gracza/serwera, a dopiero potem wybierz w panelu **zrealizowane** albo **ponów**.
  </Accordion>

  <Accordion title="Zmiana konfiguracji nie działa">
    Użyj `/itemshop reload` albo pełnego restartu. Nie używaj globalnego `/reload` platformy Minecraft, ponieważ może pozostawić biblioteki i listenery w niespójnym stanie.
  </Accordion>
</AccordionGroup>

Szczegóły komunikatów i stanów opisuje [protokół realizacji pluginu](/pl/guides/fulfillment-plugin).
