From e560650b4c21db32d734ad9475562912c072a0a9 Mon Sep 17 00:00:00 2001 From: Hash Borgir Date: Thu, 15 Jun 2023 20:06:35 -0600 Subject: [PATCH] testing new item class --- src/D2Item.php | 379 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 327 insertions(+), 52 deletions(-) diff --git a/src/D2Item.php b/src/D2Item.php index 1d37a90..1511167 100644 --- a/src/D2Item.php +++ b/src/D2Item.php @@ -7,7 +7,7 @@ require_once 'D2Strings.php'; /** * */ -class D2Item { +class D2Item_BACKUP { /** * @var null @@ -74,6 +74,40 @@ class D2Item { $itemCode .= chr(bindec(strrev($byte))); } $this->iData['code'] = trim($itemCode); + $sql = "SELECT * from armor WHERE code = '{$this->iData['code']}'"; + $res = PDO_FetchRow($sql); + if (empty($res)) { + $sql = "SELECT * from misc WHERE code = '{$this->iData['code']}'"; + $res = PDO_FetchRow($sql); + } + if (empty($res)) { + $sql = "SELECT * from weapons WHERE code = '{$this->iData['code']}'"; + $res = PDO_FetchRow($sql); + } + + // set txt data array + $this->iData['txt'] = ($res); + + $sql = " + SELECT code, namestr + FROM armor + WHERE code = '{$this->iData['code']}' + UNION + SELECT code, namestr + FROM misc + WHERE code = '{$this->iData['code']}' + UNION + SELECT code, namestr + FROM weapons + WHERE code = '{$this->iData['code']}' + "; + $res = PDO_FetchAssoc($sql); + + $sql = "SELECT `String` FROM strings WHERE `Key`='{$res[$this->iData['code']]}'"; + $res = PDO_FetchOne($sql); + $this->iData['basename'] = $res; + $this->iData['basename'] = preg_replace('/ÿc[0-9]/', '', $this->iData['basename']); + $b->seek(108); $this->iData['gems_in'] = bindec($b->readr(3)); @@ -267,7 +301,7 @@ class D2Item { } if ($this->iData['personalized']) { - $charName = ""; // Assuming $this->charName is already defined + $charName = ""; $charBits = $b->readr(7); // Read the first 7 bits while ($charBits !== "0000000") { // Check for null termination @@ -276,49 +310,41 @@ class D2Item { $charBits = $b->readr(7); // Read the next 7 bits } - - $b->skip(7); // Skip the null termination bits - } $tome = $b->readr(5); - + // Unknown (denoted as 'timestamp' in various places) $b->skip(1); - + // Now begins item specific data/stats - + $sql = "SELECT code FROM armor WHERE code = ?"; $res = PDO_FetchOne($sql, [$this->iData['code']]); - + // this is an armor //Only exists if the item is an armor (i.e. the item code is found in Armor.txt) - // Defense of the armor. Subtract this value by 10 to get the true armor value (note: this -10 matches the "Save Add" column in ItemStatCost.txt for the armor stat). if (!empty($res)) { $defense = bindec($b->readr(11)) - 10; $durability = bindec($b->readr(8)); - } - + } + $sql = "SELECT code FROM weapons WHERE code = ?"; $res = PDO_FetchOne($sql, [$this->iData['code']]); - + // this is a weapon // get durability if (!empty($res)) { $durability = bindec($b->readr(8)); - } - + } + // Only exists if the item's max durability is greater than zero //The first 8 bits are the item's current durability. The last bit is unknown. $b->skip(9); - - + $sql = "SELECT code FROM armor WHERE code = ?"; $res = PDO_FetchOne($sql, [$this->iData['code']]); - - - // weird behavior/bug // if item is in a container, bodypart will be NULL @@ -407,41 +433,290 @@ class D2Item { - $sql = "SELECT * from armor WHERE code = '{$this->iData['code']}'"; - $res = PDO_FetchRow($sql); - if (empty($res)) { - $sql = "SELECT * from misc WHERE code = '{$this->iData['code']}'"; - $res = PDO_FetchRow($sql); - } - if (empty($res)) { - $sql = "SELECT * from weapons WHERE code = '{$this->iData['code']}'"; - $res = PDO_FetchRow($sql); - } - // set txt data array - $this->iData['txt'] = ($res); - - $sql = " - SELECT code, namestr - FROM armor - WHERE code = '{$this->iData['code']}' - UNION - SELECT code, namestr - FROM misc - WHERE code = '{$this->iData['code']}' - UNION - SELECT code, namestr - FROM weapons - WHERE code = '{$this->iData['code']}' - "; - $res = PDO_FetchAssoc($sql); - - $sql = "SELECT `String` FROM strings WHERE `Key`='{$res[$this->iData['code']]}'"; - $res = PDO_FetchOne($sql); - $this->iData['basename'] = $res; - $this->iData['basename'] = preg_replace('/ÿc[0-9]/', '', $this->iData['basename']); return $this->iData; } } + +class D2Item { + + private $bits = null; // Item bitstring + private $oldbits = null; // Old Item bits for comparison + private $charName; // Character Name + private $quality; + // Item Structure + public $JM; + public $UN1; + public $identified; + public $UN2; + public $socketed; + public $UN3; + public $picked_up; + public $UN4; + public $ear; + public $starting_item; + public $UN5; + public $simple; + public $eth; + public $UN6; + public $personalized; + public $UN7; + public $runeword; + public $UN8; + public $version; + public $UN9; + public $location; + public $equipped_location; + public $posx; + public $posy; + public $panel; + // for non ear items + public $code; + public $number_of_items_socketed_within_this_item; + // advanced item info + public $identifier; + public $ilvl; + public $rarity; + + // now begins variable item data + // so they will not be made into properties here + // they will be added from the parseItem() function + + + public function __construct($bits, $charName = null) { + if ($bits == '') + return false; + $this->b = new D2BitReader($bits); // D2BitReader object + $this->oldbits = $bits; + $this->charName = $charName; + $this->parseItem(); + } + + public function parseItem() { + // Read and store the actual bits for each class member + $this->JM = $this->b->read(16); + $this->UN1 = $this->b->read(4); + $this->identified = $this->b->read(1); + $this->UN2 = $this->b->read(6); + $this->socketed = $this->b->read(1); + $this->UN3 = $this->b->read(1); + $this->picked_up = $this->b->read(1); + $this->UN4 = $this->b->read(2); + $this->ear = $this->b->read(1); + $this->starting_item = $this->b->read(1); + $this->UN5 = $this->b->read(3); + $this->compact = $this->b->read(1); //compact/simple item, only 112 bits + $this->eth = $this->b->read(1); + $this->UN6 = $this->b->read(1); + $this->personalized = $this->b->read(1); + $this->UN7 = $this->b->read(1); + $this->runeword = $this->b->read(1); + $this->UN8 = $this->b->read(5); + $this->version = $this->b->read(8); + $this->UN9 = $this->b->read(2); + $this->location = $this->b->read(3); + $this->equipped_location = $this->b->read(4); + $this->posx = $this->b->read(4); + $this->posy = $this->b->read(4); + $this->panel = $this->b->read(3); + + // for non-ear items + $this->code = $this->b->read(32); + $code = ''; + foreach (str_split($this->code, 8) as $byte) { + $code .= chr(bindec(strrev($byte))); + } + $this->itemcode = $code; + $this->number_of_items_socketed_within_this_item = $this->b->read(3); +// +// // if item is not compact, then read advanced data +// if ($this->compact == "0") { +// // advanced item info +// $this->identifier = $this->b->read(32); +// $this->ilvl = $this->b->read(7); +// $this->rarity = $this->b->read(4); +// +// // we just read quality, from 150, 151, 152, 153. We are now at 154. +// $this->gfx = $this->b->read(1); +// if ($this->gfx == "1") { +// $this->gfxid = $this->b->read(3); +// } +// +// $this->class_specific = $this->b->read(1); +// if ($this->class_specific == "1") { +// $this->class_specific_affix_id = $this->b->read(11); +// } +// +// // now we read the rarities +// $quality = bindec(strrev($this->rarity)); +// +// switch ($quality) { +// case D2ItemQuality::LOW_QUALITY: +// $this->quality = "Low Quality"; +// $this->low_quality_item_data = $this->b->read(3); +// $low_quality_item_data = bindec(strrev($this->low_quality_item_data)); +// switch ($low_quality_item_data) { +// case 0: +// $this->iData['low_quality_item_data'] = "Crude"; +// break; +// case 1: +// $this->iData['low_quality_item_data'] = "Cracked"; +// break; +// case 2: +// $this->iData['low_quality_item_data'] = "Damaged"; +// break; +// case 3: +// $this->iData['low_quality_item_data'] = "Low Quality"; +// break; +// default: +// $this->iData['low_quality_item_data'] = "Unknown quality"; +// break; +// } +// +// break; +// case D2ItemQuality::NORMAL: +// $this->quality = "Normal"; +// break; +// case D2ItemQuality::HIGH_QUALITY: +// $this->quality = "High Quality"; +// $this->high_quality_item_data = $this->b->read(3); +// break; +// case D2ItemQuality::MAGIC: +// $this->quality = "Magic"; +// // read 11 bits, prefix. +// // if no prefix, then next 11 bits will be suffix +// $this->magic_prefix = $this->b->read(11); +// if (!bindec($this->magic_prefix)) { +// $this->magic_suffix = $this->b->read(11); +// } +// +// $prefix = bindec(strrev($this->magic_prefix)); +// $suffix = bindec(strrev($this->magic_suffix)); +// +// if (!empty(bindec($this->magic_prefix))) { +// $sql = "SELECT * FROM magicprefix WHERE ROWID='$prefix'"; +// $res = PDO_FetchRow($sql); +// $this->iData['magic_prefix'] = $res; +// } +// if (!empty(bindec($this->magic_suffix))) { +// $sql = "SELECT * FROM magicsuffix WHERE ROWID='$suffix'"; +// $res = PDO_FetchRow($sql); +// $this->iData['magic_suffix'] = $res; +// } +// break; +// case D2ItemQuality::SET: +// $this->quality = "Set"; +// // Set items have a 12-bit field containing the ID of the set. (Not the set member, but the whole set.) The set member is identified by cross-referencing the item type with the set ID. Also note that set items have an extra field following the item-specific data. +// // Set identifier; i.e., all items which are part of the set will have the same value in this field. +// $this->setid = $this->b->read(12); +// $setid = bindec(strrev($this->setid)); +// +// // first get set name +// $sql = "SELECT `set` from setitems WHERE ROWID=$setid"; +// $set = PDO_FetchOne($sql); +// $this->iData["setname"] = $set; +// +// $sql = "SELECT * from setitems WHERE `set`=? AND item=?"; +// $res = PDO_FetchRow($sql, [$set, $this->itemcode]); +// +// $this->iData["data"] = $res; +// +// break; +// case D2ItemQuality::RARE: +// $this->quality = "Rare"; +// break; +// case D2ItemQuality::UNIQUE: +// $this->quality = "Unique"; +// break; +// case D2ItemQuality::CRAFTED: +// $this->quality = "Crafted"; +// break; +// default: +// $this->quality = "Unknown"; +// break; +// } +// +// +// +// +// +// +// +// +// +// +// +// // +// } + var_dump("old: " . $this->oldbits); + var_dump("new: " . ($this->dumpValues())); + echo "
"; + } + + public function dumpValues() { + $values = []; + + // Push the values of each class member into the $values array + $values[] = $this->JM; + $values[] = $this->UN1; + $values[] = $this->identified; + $values[] = $this->UN2; + $values[] = $this->socketed; + $values[] = $this->UN3; + $values[] = $this->picked_up; + $values[] = $this->UN4; + $values[] = $this->ear; + $values[] = $this->starting_item; + $values[] = $this->UN5; + $values[] = $this->simple; + $values[] = $this->eth; + $values[] = $this->UN6; + $values[] = $this->personalized; + $values[] = $this->UN7; + $values[] = $this->runeword; + $values[] = $this->UN8; + $values[] = $this->version; + $values[] = $this->UN9; + $values[] = $this->location; + $values[] = $this->equipped_location; + $values[] = $this->posx; + $values[] = $this->posy; + $values[] = $this->panel; + $values[] = $this->code; + $values[] = $this->number_of_items_socketed_within_this_item; +// $values[] = $this->identifier; +// $values[] = $this->ilvl; +// $values[] = $this->rarity; +// $values[] = $this->gfx; +// $values[] = $this->gfxid; +// $values[] = $this->class_specific; +// $values[] = $this->class_specific_affix_id; +// $values[] = $this->low_quality_item_data; +// $values[] = $this->magic_prefix; +// $values[] = $this->magic_suffix; +// $values[] = $this->setid; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; +// $values[] = ""; + + // Concatenate the values into a long string + $concatenatedValues = implode("", $values); + + return $concatenatedValues; + } + +}