Krátký kurs editace pozic 1

Krátký kurs editace pozic 1

Programátoři to s obtížnosti her občas přeženou. Předpokládají, že každý má reflexy jako superman a ještě k tomu neomezeně času, aby překonával všechny nástrahy. Není tedy na škodu trochu si menším podfukem ulehčit život. V tomto kurzu si ukážeme základní principy editace pozic a příklady jejich praktického využití.

Programátoři to s obtížnosti her občas přeženou. Předpokládají, že každý má reflexy jako superman a ještě k tomu neomezeně času, aby překonával všechny nástrahy. Není tedy na škodu trochu si menším podfukem ulehčit život. V tomto kurzu si ukážeme základní principy editace pozic a příklady jejich praktického využití.

Začneme relativně jednoduchým druhem pozic na příkladu Diabla 2. Pro práci budeme potřebovat nějaký hexadecimální editor. Těch existuje nepřeberné množství. Velmi jednoduchý je zabudovaný třeba ve Volkov Commanderovi, já používám editor z Visual Studia ale lze použít i libovolný jiný, pokud umí vyhledávat sekvence hexadecimálních čísel. Ovládáni těchto programů bývá jednoduché. Trochu vysvětlení si možná žádá, co znamená ta změť znaků na obrazovce. Vlevo je adresa, pak následuje šestnáct skupinek šestnáctkových čísel (jsou to binární reprezentace hodnot na jednotlivých adresách) a vpravo je jejich textová reprezentace. Dále je třeba program pro porovnáváni souborů. Postačí i program FC, který je součástí DOSu i Windows (pro Linux existují mnohem mocnější nástroje, ale my zde budeme uvádět příklady pro „Microsoftí“ prostředí).

Pro ty, co nechtějí zdlouhavě hledat potřebné utility na Internetu, jsem jejich maximálně zjednodušené verze napsal. Program peek slouží k hexadecimálnímu výpisu souboru. Jméno souboru je nutno zadat jako parametr. Výstup jde standardně na obrazovku a pro delší soubory je vhodné výpis přesměrovat do souboru. Příklad použití:

Peek ukazka.d2s > vypis.txt

Program poke slouží k provádění změn v souborech. Jako parametr je třeba zadat jméno souboru, měněnou adresu a novou hodnotu (vše v šestnáctkové soustavě). Příklad použití (v souboru ukazka.d2s bude na adrese 261 hodnota FF):

Poke ukazka.d2s 261 FF

Program fcmp slouží k binárnímu porovnání souborů. Jeho výhodou oproti FC je to, že zobrazuje i aritmetické rozdíly hodnot. Výpis je opět vhodné přesměrovat do souboru. Příklad použití:

Fcmp soubor.1 soubor.2 > vypis.txt

Všechny programy by měly k naším účelům posloužit relativně dobře ale jsou primitivní a mají spartánské ovládáni a proto je to jen dočasné, nouzové řešení. Navíc vznikly poněkud ve spěchu na popud recenzenta článku a proto můžou mít nějaké drobné mouchy- používejte na vlastní nebezpečí :-) Ke stažení jsou u nás na Doupěti (12 kb).

Základem bude práce v šestnáctkové a někdy i dvojkové číselné soustavě. Pro převod z a do šestnáctkové soustavy dobře poslouží třeba kalkulačka z Windows po přepnutí do „vědecké“ podoby (nebo libovolná jiná programátorská kalkulačka). Nejdříve zvolíme vlevo nahoře zdrojovou soustavu (hex – 16, dec – 10, oct – 8, bin – 2) napíšeme číslo a zvolíme cílovou soustavu. Dále je nutno vědět, jak se v počítači reprezentují čísla, a to v přímém i v doplňkovém kódu. Vždy je třeba uvážit, jaký je rozsah hodnot pro zvolenou hodnotu a hlavně jestli jsou přípustná i záporná čísla. Přímý kód je velmi jednoduchý. Prostě jenom převedeme číslo do příslušné soustavy (o základu 16 nebo 2) doplníme zleva nulami tak, aby vyplnily celou mřížku podle tabulky a máme hotovo. (Pro šťouchaly: doplnění nulami není nutné, ale je to vždy užitečné udělat, protože pokud pak člověk zapomene ty nuly do savegame zapsat nastane zmatek.)

Počet bajtů Název Počet šestnáctkových číslic Počet dvojkových číslic
1 Byte (bajt) 2 8
2 Word 4 16
4 Double Word 8 32
Počet nutných bajtů k zapsání čísla je dán jeho rozsahem dle tabulky:

Název Rozsah desítkově Rozsah šestnáctkově
Byte (bajt) 0 až 255 0 až FF
Word 0 až 65535 0 až FFFF
Double Word 0 až 4294967295 0 až FFFFFFFF
Pro zápis záporných čísel se nejčastěji používá doplňkový kód. Čísla v tomto kódu používají nejvýznamnější bit (ten nejvíce vlevo) jako znaménkový. Je-li tam 1 pak je číslo záporné. Kladná čísla se převádí stejně jako v doplňkovém kódu. Pokud chceme zapsat záporné číslo v doplňkovém kódu zapíšeme jej nejdříve v přímém kódu v dvojkové soustavě, doplníme vlevo nulami tak, aby zaplnily cely rozsah (pokud je nejdůležitější bit rovný 1 pak jsme překročili rozsah a musíme zvolit vyšší), se všemi bity provedeme logickou negaci (1->0, 0->1), přičteme jedničku a pak případně převedeme číslo do šestnáctkové soustavy. Jinou metodou je přičíst k požadovanému číslu rozsah pro přímý kód (viz. tabulka výše) a přičíst ještě jedničku. Vidíte tedy, že je vždy nutno vždy znát obor hodnot (tedy počet bytů které může zabírat) aby bylo možno číslo v doplňkovém kódu číslo zapsat. Zde je tabulka rozsahů pro doplňkový kód:

Počet bytů Název Rozsah desítkově
1 Short Integer -128 až 127
2 Integer -32768 až 32767
4 Long Integer -2147483648 až 2147483647

Příklad: Převod –10 (desítkově) na číslo v doplňkovém kódu v šestnáctkové podobě s rozsahem, který se vejde do jednoho bajtu.

Způsob 1: 10 převedeme do dvojkové soustavy, doplníme nulami: 00001010. Bity logicky znegujeme: 11110101 přičteme jedničku a převedeme do šestnáctkové podoby: F6.

Způsob 2: K FF přičteme (-10) (tedy šestnáctkově (-A)) a jedničku. Opět dostaneme číslo F6.

Příklady čísel v doplňkové a přímé podobě pro jeden a dva bajty:

Desítkově Přímý kód hexa Doplňkový kód hexa, 1 bajt Doplňkový kód hexa, 2 bajty
100 64 64 00 64
-1 Nelze FF FF FF
-100 Nelze 9C FF 9C
-1000 Nelze Nelze FC 18
Zpětný převod je stejně jednoduchý. Pokud je nejdůležitější bit roven nule- převedeme bez modifikací. V opačném případě odečteme jedničku a znegujeme bity.

Doplňkový kód je výhodný kvůli snadnému převodu, snadné indikaci záporného čísla a hlavně lze sčítat čísla v doplňkovém kódu stejně, jako by byly v přímém kódu.

Z předchozích příkladů je zřejmé, že důležité pro editací pozic je znalost rozsahů čísel a kód protože stejná reprezentace může znamenat jiné číslo. Třeba FF je buď –1 nebo 255. Nejjednodušší je vydedukovat rozsah přímo z hry. Pokud nás třeba zajímá síla postavičky, která může nabývat jen hodnot 1 až 18 pak můžeme říct, že pro zapsání tohoto čísla stačí jeden bajt. Pokud nás zajímá bankovní konto (které může nabývat i záporných hodnot) pak lze předpokládat, že budeme potřebovat čtyři bajty v doplňkovém kódu. Je nutno poznamenat, že pokud programátor nešetřil místem může tento odhad selhat. Další informaci nám přinese pohled na savegame. Při tom je třeba trocha citu a zkušenosti. Třeba pokud vidíme v editoru sekvenci jako

00001c0: 10 00 25 00 65 00 4C 00 9A 00 01 25 15 00 BB 00 …

můžeme soudit, že se jedná o řadu dvoubajtových hodnot a sekvence

00001d0: AA 00 00 00 14 00 00 00 12 CF 00 00 AA 00 00 00 …

bude zřejmě složená z čtyřbajtových hodnot. Nejspolehlivější (ale časově náročnou) metodou je provést několik pokusů. Příklady takového postupu si uvedeme později.

Pro další experimenty jsem zvolil pozici ze hry Diablo 2 protože není šifrovaný, má velmi průhlednou strukturu a neukládají se předměty na zemi ani nepřátele, není nijak zabezpečený ale hlavně na něm lze snadno ukázat spoustu metod pro editaci pozic. Zajímají nás vždy jen soubory /save/jméno_postavy.d2s, kde jsou uloženy všechny podstatné informace.

Na začátku analýzy pozice je třeba provést rozbor do bloků. Většina her neukládá pozici do homogenního bloku ale děli jej na několik části. V RPG to může být blok základních údajů o postavě, blok informací o nepřátelích a blok informací o předmětech. Ve strategii to může být blok základních informací (peníze, suroviny), informace o vojenských jednotkách, městech. V adventurách to bývá blok obsahu kapes a blok informaci o splněných úkolech. Tyto bloky bývají od sebe oddělené řadou nul (případně jiných hodnot). Při jejich identifikaci se opět hodí cit a zkušenost. Třeba když je někde jméno postavy- lze předpokládat, že poblíž budou i ostatní informace o postavě. Pokud je v batohu více předmětů pak se dá jako celek identifikovat jako série opakujících se sekvencí popřípadě řada podobně dlouhých sekvencí oddělených stejnými kódy. Vše je hezky vidět třeba na pozici ze hry Diablo 2. Vidíme zde jednoznačně blok informací o hře na adresách 0 až 50 dále vidíme charakteristický blok na adresách 80 až 167 rozdělený do tří části. Prozatím nemůžeme určit o co se jedná. Další blok je od 28D do konce souboru. Můžeme rozeznat jednotlivé předměty oddělené sekvencí 4A 4D (písmena JM). O zbytku souboru nemůžeme prozatím nic určitého říct.

Nyní můžeme začít experimentovat. Ve hře vytvoříme postavu, promluvíme si s někým, kdo nám zadá nějaký úkol (třeba s Warrivem), vyběhneme ven z osady a pobijeme jednoho nepřítele. Proč jsou tyto kroky nutné? Některé hry totiž neukládají informace pokud mají pořád hodnotu stejnou jako na začátku hry. Pokud tedy třeba nezačnete žádný úkol- je informace o úkolech zbytečné ukládat. Nyní uložíme hru a soubor *.d2s si uložíme do zvláštního adresáře a přejmenujeme třeba na 1.d2s. Opět načteme pozici a pobijeme další příšerku. Vždy se snažíme provést co nejmenší změny. Opět uložíme pozici a přejmenujeme ji na 2.d2s. Postup opakujeme pro jistotu ještě jednou. Nyní pomoci příkazů

FC /b 1.d2s 2.d2s
a
FC /b 2.d2s 3.d2s
nebo
Fcmp 1.d2s 2.d2s
a
Fcmp 2.d2s 3.d2s
porovnáme vzniklé pozice (přepínač /b zaručí binární porovnání). Jsme si vědomi, že mezi jednotlivými pozicemi postavě stoupla zkušenost. Hledáme tedy bajt, kde se postupně zvětšovala hodnota (při použití fcmp se můžeme koukat i na to, zda stoupla o požadovanou hodnotu). Mohly se změnit samozřejmě i další hodnoty. Z těchto dvou porovnání bychom měli jednoznačně určit „podezřelé“ místo. V případě potřeby je možno postup opakovat pro další příšerky. V mém případě to byla adresa 261. Jelikož víme, že zkušenosti dosahují v Diablu 2 vysokých hodnot- můžeme předpokládat čtyřbajtový rozsah. Dále si musíme uvědomit, že na papíře píšeme významnější číslice vlevo ale v souboru rostou adresy zleva doprava. Jednotlivé bajty (261 až 264) je tedy nutno číst i psát pozpátku (třeba 12 34 56 78 tedy ve skutečnosti je 78 56 34 12). Můžeme tedy v souboru původní_jméno.d2s v adresáři save změnit obsah buněk 261 až 264 na požadovanou hodnotu. Nebudeme to prozatím přehánět a obsah buňky 261 a 262 změníme na FF což nám dá 65535 bodů zkušenosti. Po načtení pozice vidíme, že skutečně máme tolik zkušenosti. Nyní stačí zabít jednoho nepřítele a přeskočíme rovnou několik úrovni (Pozor! Při přechodu na další úroveň postavě přibude několik bodu života, many a staminy. Pokud ovšem přeskočíte levelů několik- vše přibude jen jednou!) Uložíme hru a koukneme se opět na bajty 261, 262 a 263. Je vidět, že hodnota zkušenosti „natekla“ do dalšího bajtu což potvrzuje naší domněnku o velikosti tohoto pole. Vymažeme původní záložní pozice a uložíme znova pozici 1.d2s. Nyní si vyzvedneme další úkol tentokrát od Akary a uložíme 2.d2s. Opět oba soubory porovnáme. V mém případě se změnila adresa 8E z 00 na 04 a adresa 200 také z 00 na 04. Jelikož si pamatuji, že v souboru pokusak.d2s byla adresa 8e uprostřed bloku vyplněného hodnotami a nyní je tento blok prázdný. Toto je charakteristické pro záznamy o úkolech (mohly by to být i dovednosti ale na to je tento blok příliš dlouhý). Změním tuto adresu v souboru původní_jméno.d2s zpět na 00. Po načtení pozice se nad Akarou znovu objeví vykřičník jako bychom s ní vůbec nehovořili. Můžeme tedy prohlásit, že v bloku na adresách 80-167 se uchovávají informace o úkolech. Každá ze tří části bude zřejmě pro jinou obtížnost. Samostatným problémem je, jaké hodnoty do těchto buněk zapsat abychom získali požadované úkoly. Zde je asi jedinou metodou zjistit požadované hodnoty od postavy, která má dané úkoly hotové. Stejně je ale v případě Diabla 2 lepší si splněné dovednosti ubírat než přidávat (Což takhle si zapsat stav před magickým vylepšením předmětu kovářkou (Imbue) a po vylepšení ho obnovit?)

To je prozatím vše. Vřele vám doporučuji abyste si zkusili najít další hodnoty. Princip už znáte- uložit pozici, něco nepatrně změnit a sledovat co se změnilo v pozici. V příštím díle se naučíme jak přímo vyhledávat hodnoty bez zdlouhavého experimentování. Většinou totiž není nutno hodnoty hledat tak zdlouhavě ale stačí je hledat přímo podle jejich hodnoty. K tomu je ale většinou nutno znát více informací a mít i trochu štěstí. Pokusíme se taky editovat předměty.

Poznámka: Uvedené hodnoty platí pro Diablo 2 ve verzi 1.0 a ve vyšších se můžou lišit. Hlavním cílem tohoto kurzu je naučit vás editovat pozice samostatně a uvedené příklady slouží pouze jako ukázky probíraných technik. Pamatujte si také, že pokud si hru ulehčíte příliš- přestane vás bavit. A ještě jedno upozornění: vždy si udělejte záložní kopii souboru se kterými experimentujete!

Určitě si přečtěte

Články odjinud