Skip to content

Přehled CLI, řízení Mercy SF z jiného programu

mercy-cli má neinteraktivní režim: argumenty dovnitř, jeden objekt JSON ven. Je určený pro nástěnky, dohledové procesy a skripty.

Tahle stránka je slib. Příkazy a názvy polí níže se bez ohlášení nezmění. Všechno ostatní na CLI, menu, jeho formulace, rozvržení výstupu, se smí kdykoli změnit, takže na tom prosím nestavte.

Spuštěno bez argumentů nastartuje interaktivní menu přesně jako dřív.

Každá odpověď nese "api". Dnes je to 1. Přidání pole to nemění, volající, který čte jen pole, která zná, zůstává nedotčen. Mění se, když se pole odebere nebo se změní jeho význam, takže můžete odmítnout běžet proti tvaru, na který jste nebyli postaveni.


Přihlášení

Účty vytvořené přes jednotné přihlášení S&F nepotřebují nic navíc. Účet, který patří jednomu serveru a nikdy nebyl součástí jednotného přihlášení, pro něj neexistuje a potřebuje --server:

bash
mercy-cli --status --user <account> --server https://f1.sfgame.net/

--server funguje s každým příkazem níže.

Výstup

Každý příkaz kromě --start tiskne JSON a nic jiného, takže --json je už výchozí a předat ho nic nemění. Existuje pro volající, kteří to radši řeknou, než by spoléhali na výchozí chování, a pro --start, který jinak píše protokol pro člověka.


Čtení

Vypsat postavy na účtu

bash
mercy-cli --characters --user <account>
json
{
  "ok": true,
  "characters": [
    { "character": "Hero", "server": "https://s1.sfgame.net/", "level": 345 },
    { "character": "Alt",  "server": "https://s42.sfgame.net/", "level": 88 }
  ]
}

Jedno přihlášení pokryje každou postavu na účtu, napříč servery. level je null, pokud se stav té postavy nepodařilo načíst, položka se stejně vypíše, protože vědět, že existuje, je smyslem toho volání.

Přečíst stav jedné postavy

bash
mercy-cli --status --user <account> --character <name>

--character se dá vynechat, když má účet právě jednu.

json
{
  "ok": true,
  "character": "Hero",
  "server": "https://s1.sfgame.net/",
  "level": 345,
  "class": "DemonHunter",
  "race": "DarkElf",
  "experience": { "current": 740300000, "next_level": 769800000 },
  "silver": 725000000,
  "mushrooms": 8,
  "honor": 12043,
  "rank": 1800,
  "action": "CityGuard",
  "attributes": {
    "strength":     { "base": 4077, "bonus": 1200 },
    "dexterity":    { "base": 1000, "bonus": 300 },
    "intelligence": { "base": 900,  "bonus": 250 },
    "constitution": { "base": 3000, "bonus": 800 },
    "luck":         { "base": 700,  "bonus": 150 }
  },
  "equipment": [
    {
      "slot": "Weapon",
      "model_id": 55,
      "color": 1,
      "class": "DemonHunter",
      "epic": true,
      "legendary": false,
      "armor": 0,
      "min_damage": 900,
      "max_damage": 1400,
      "upgrades": 3,
      "attributes": { "strength": 420, "constitution": 210 },
      "rune": { "type": "FireDamage", "value": 60 },
      "enchantment": "SwordOfVengeance",
      "gem": { "type": "Strength", "value": 300 }
    }
  ],
  "arena": {
    "fights_for_xp": 7,
    "next_free_fight": "2026-08-06T12:04:11+02:00",
    "opponents": [50099, 34316, 13668]
  },
  "tavern": {
    "thirst_for_adventure_sec": 3600,
    "beer_drunk": 2,
    "mushroom_skip_allowed": true,
    "quests": [
      { "length_sec": 600, "silver": 120000, "experience": 45000,
        "location": "Wolves", "item": true }
    ]
  },
  "guild": {
    "name": "Blvck Clover",
    "rank": 12,
    "honor": 90000,
    "members": [
      { "name": "Hero", "level": 345, "last_online": "2026-08-06T09:12:00+02:00" }
    ]
  },
  "scrapbook_items": 1102
}

Všechno pochází z jednoho načtení stavu, takže nejsou žádné části k vyžádání a není co ušetřit tím, že si řeknete o míň.

guild je null, když postava v žádném cechu není. scrapbook_items je null, dokud album nebylo alespoň jednou přečteno. Prázdné místo na výbavu se vynechá, místo aby se vypsalo jako null.

K názvům předmětů: protokol nese id modelu a slot, ne zobrazovaný název, a to je tedy to, co dostanete. Je to zároveň to, čím se adresuje grafika, takže nástěnka umí vykreslit přesně ten obrázek, který kreslí desktopová aplikace. Vymyslet tu název by byl odhad, který si nemůžete ověřit.

Opakovat čtení v intervalu

bash
mercy-cli --status --user <account> --character <name> --watch 60

Jedno přihlášení, pak jeden objekt každých 60 sekund, dokud proces neskončí. Používejte tohle, místo abyste příkaz pouštěli ve smyčce znovu: každé spuštění je čerstvé přihlášení, což je nejdražší způsob, jak sledovat jedno číslo, a ze strany serveru ten nejnápadnější. Spodní hranice je 30 sekund. Neúspěšné kolo se vypíše a smyčka jede dál; pozorovatel, který to vzdá při prvním zaškobrtnutí, vypadá přesně jako ten, u kterého se nic neděje.

S kým bude bojovat příště a proč

bash
mercy-cli --plan --user <account> --character <name>
json
{
  "ok": true,
  "outcome": "planned",
  "reason": "Next: Someone — 3 scrapbook items, 72% odds",
  "candidates": [
    {
      "name": "Someone",
      "level": 340,
      "source": "pool",
      "missing_items": 3,
      "rank_gain": 12,
      "favourite": false,
      "win_chance": 0.72,
      "item_score": 300.0,
      "xp_score": 60.0,
      "rank_score": 25.0,
      "base": 385.0,
      "score": 277.2
    }
  ]
}

Totéž rozhodnutí, jaké kreslí aplikace: kandidáti obodovaní za předměty, denní XP a pořadí, pak vynásobení šancemi. outcome je planned, waiting, blocked nebo empty, a reason jednou větou řekne které.

Tohle neutratí žádný souboj ani houbu. Prochází ale server kvůli kandidátům, takže zadarmo v požadavcích to není, nedávejte to do těsné smyčky.

Zkusit souboj nanečisto

bash
mercy-cli --simulate --user <account> --character <name> --against <player>
json
{ "ok": true, "against": "Someone", "against_level": 340, "win_chance": 0.63, "iterations": 1000 }

Počty. Jeden dotaz jde na server zjistit, kdo to je; samotný souboj se neposílá nikdy. win_chance jsou výhry proti rozhodnutým soubojům, takže simulace, která nedokáže rozhodnout, referuje o menším počtu, než kolik jich proběhlo.

Co se nese

bash
mercy-cli --inventory --user <account> --character <name>
json
{ "ok": true, "carried": 12, "backpack": [ { "slot_index": 0, "model_id": 55 } ] }

Jeden seznam, protože hra vede jeden. Předměty mají stejný tvar jako ve --status, plus slot_index.

Album

bash
mercy-cli --scrapbook --user <account> --character <name>
json
{ "ok": true, "unlocked": true, "owned": 1102, "monsters": 214 }

unlocked je false pod úrovní, která album uděluje, a owned je tam null. To není chyba.

Zaznamenané souboje

bash
mercy-cli --history --user <account> --character <name> --limit 50
json
{ "ok": true, "total": 4210, "returned": 50, "battles": [] }

Nejnovější první. Zaznamenává je ta instalace, která bota poháněla, nestahují se ze serveru, proces, který právě nastartoval, tedy nemá co ukázat, a není to závada. total je to, co existuje, returned je to, co nechalo --limit.


Jednání

Pustit bota

bash
mercy-cli --start --user <account> --character <name>

Běží, dokud se proces nezastaví, a přitom protokoluje. --character je tady povinné: vypsat seznam a přečíst stav jsou neškodné věci, ale spustit bota znamená hrát hru, a vybrat špatnou postavu není nic, co byste vzali zpátky.

--all místo toho pustí každou postavu účtu v tomhle jednom procesu. To je jedno přihlášení na účet místo jednoho na postavu, což je levnější a brání postavám v tom, aby si navzájem znehodnocovaly relaci.

Při Ctrl-C (nebo SIGTERM) se současný tah nechá dokončit, než proces skončí, místo aby byl useknutý uprostřed požadavku.

Události místo textu

bash
mercy-cli --start --user <account> --character <name> --events

Jeden objekt JSON na řádek, dohledový proces tak čte řádek po řádku:

json
{"at":"2026-08-06T17:22:04+02:00","api":1,"event":"arena_win","character":"Hero"}
{"at":"2026-08-06T17:22:31+02:00","api":1,"event":"quest_done","character":"Hero"}

event je jedno z started, stopping, stopped, arena_win, arena_loss, dungeon_win, dungeon_loss, quest_done, scrapbook_win, scrapbook_loss, scrapbook_items (které nese count).

Tenhle seznam poroste. Berte událost, kterou neznáte, jako takovou, kterou ignorujete, ne jako chybu; přesně proto jsou ta jména vypsaná, místo aby to bylo to, co zrovna vytisknul Rust.

Používejte tohle, místo abyste četli protokol pro člověka. Ten je psaný pro člověka a smí být kdykoli přeformulovaný; parsovat ho znamená, že se váš nástroj rozbije, když někdo vylepší větu.

Vybrat, co čeká

bash
mercy-cli --claim --user <account> --character <name>

Kalendář, denní úkoly, čekající odemčení. --character je povinné, ze stejného důvodu jako u --start.

Číst nebo měnit konfiguraci

bash
mercy-cli --config --user <account> --character <name>
mercy-cli --config --user <account> --character <name> --set auto_arena=false
json
{ "ok": true, "settable": ["auto_arena"], "changed": [ { "key": "auto_arena", "from": true, "to": false } ] }

Čtení vrací celou konfiguraci pod config. Názvy polí uvnitř toho bloku nejsou součástí tohohle slibu, jsou jí jen klíče vypsané v settable. Konfigurace má hodně přes sto polí a s každým vydáním roste; slíbit je všechny by znamenalo už nikdy nemoci s nastavením pohnout.

--set bere true/false, on/off, yes/no, 1/0, vyžaduje vždycky --character (přepínač patří jedné postavě a „ta jediná“ je odhad, podle kterého se dá číst a nedá zapisovat), a dá se opakovat. Hodnota se potom načte zpátky z disku a volání selže, pokud nedosedla, protože ohlásit změnu, ke které nedošlo, je ten jediný výsledek, ze kterého se nezotavíte.


Provoz

Jaké je to sestavení

bash
mercy-cli --version
json
{ "ok": true, "version": "2.12.0", "api": 1 }

Jediný příkaz, který nepotřebuje heslo ani síť. Dohledový proces se musí umět zeptat, s čím mluví, dřív než má přihlašovací údaje, aby s tím mluvil.

Je to dosažitelné

bash
mercy-cli --health --user <account> --character <name>
json
{ "ok": true, "character": "Hero", "level": 345, "round_trip_ms": 412 }

Přihlásit, načíst, ohlásit, skončit. Záměrně drobné: kontrola dostupnosti, která vrátí celý list postavy, svádí k tomu ho parsovat, a pak se z té kontroly stane další rozhraní.


Heslo

Přepínač --password schválně neexistuje. Argumenty příkazové řádky si přečte každý jiný proces na počítači, ps, /proc, Správce úloh, takže nástěnka, která tohle pouští za víc lidí, by vydávala všechna jejich herní hesla komukoli, kdo má na té mašině shell.

Místo toho dvě cesty:

bash
MERCY_SF_PASSWORD='…' mercy-cli --status --user someone
bash
printf '%s' "$password" | mercy-cli --status --user someone --password-stdin

--password-stdin čte první řádek standardního vstupu, což drží tajemství i mimo prostředí.


KódVýznam
0Úspěch, a taky pro --help
1Běželo to a selhalo, důvod je v error, a ok je false
2Volání bylo špatně: neznámá volba, chybějící hodnota, žádná akce. Na stderr

Rozdíl mezi 1 a 2 pro dohledový proces něco znamená: 2 selže pokaždé stejně a potřebuje člověka, 1 může při dalším pokusu klidně projít.


Chyby

Selhání jsou taky JSON, takže obojí obslouží jeden parser:

json
{ "ok": false, "error": "no character called 'Typo' on this account" }

ok je v každé odpovědi. Zkontrolujte ho dřív než cokoli jiného.

Časté příčiny:

HláškaCo s tím
--user is requiredChybí --user (každá akce kromě --version)
--start needs --character (or --all)Pojmenujte cíl; hádat se nebude
this account has N characters — name one with --characterJe jich několik, jednu vyberte
no character called '…' on this accountPřeklep; --characters vypíše platná jména
no password: set MERCY_SF_PASSWORD or pass --password-stdinZvolte jednu ze dvou cest k heslu
login failed: …Zkontrolujte údaje nebo server; účty mimo jednotné přihlášení potřebují --server
'…' is not settable from hereNení na seznamu povolených; --config bez --set vypíše settable
'…' did not save — it still reads back unchangedZměna nedosedla; zkontrolujte práva k zápisu

Recepty

Vybírat na každém účtu jednou denně

bash
for account in alpha beta gamma; do
  MERCY_SF_PASSWORD="$(pass mercy/$account)" \
    mercy-cli --claim --user "$account" --character Hero || echo "failed: $account"
done

Držet dlaždici nástěnky aktuální

bash
MERCY_SF_PASSWORD='…' mercy-cli --status --user someone --character Hero --watch 60

Jedno přihlášení, jeden objekt za minutu. Nepouštějte to místo toho z cronu každou minutu, to je pokaždé čerstvé přihlášení.

Zapisovat události do souboru

bash
MERCY_SF_PASSWORD='…' mercy-cli --start --user someone --character Hero --events \
  >> events.ndjson

Před přihlášením zjistit, s čím mluvíte

bash
api=$(mercy-cli --version | jq -r .api)
[ "$api" = "1" ] || { echo "unknown contract version: $api"; exit 1; }

Jako služba systemd

ini
[Service]
Environment=MERCY_SF_PASSWORD=…
ExecStart=/usr/local/bin/mercy-cli --start --user someone --all --events
Restart=on-failure
KillSignal=SIGTERM

SIGTERM nechá dokončit současný tah. Prosím, neposílejte mu SIGKILL.


Co tohle zatím nedělá

Spustit několik postav a zastavovat je jednotlivě (--all je spustí všechny a zastaví všechny najednou), ovládací kanál do běžícího procesu, a měnit cokoli nad rámec přepínačů modulů.

Pokud něco z toho potřebujete, řekněte co; je snazší postavit tu správnou věc než hádat a nechat ji ležet nevyužitou.

Mercy SF nemá vazbu na Shakes & Fidget ani na Playa Games. Používáte na vlastní riziko.