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