diff --git a/CharEditor.php b/CharEditor.php
index a7b5868..56e46d5 100644
--- a/CharEditor.php
+++ b/CharEditor.php
@@ -12,6 +12,7 @@ require_once './_pdo.php';
require_once './src/D2Functions.php';
require_once './src/D2BitReader.php';
+require_once './src/D2ByteReader.php';
//require_once './src/D2Item.php';
@@ -39,35 +40,41 @@ $filePath = "D:\Diablo II\MODS\ironman-dev\save\Sorc.d2s";
$fp = fopen($filePath, 'r+b');
$data = file_get_contents($filePath);
+$i_TotalOffset = strpos($data, "JM");
+fseek($fp, $i_TotalOffset + 2);
+$i_Total = unpack('S*', (fread($fp, 2)))[1];
-
-$i_offset = strpos($data, "JM");
-
-fseek($fp, $i_offset + 2);
-$i_total = unpack('S*', (fread($fp, 2)))[1];
-
-$items = null;
-
-$offset = $i_offset + 4; // JM00
-
-$first_item_offset = strposX($data, "JM", 2);
-$second_item_offset = strposX($data, "JM", 3);
-
-$item_size = $second_item_offset - $first_item_offset;
-
-for ($i = 2; $i <= $i_total; $i++) {
- fseek($fp, strposX($data, 'JM', $i));
- $_items[] = unpack('C*', fread($fp, 21));
+$i_Offsets = [];
+for($i=0; $i <= $i_Total; $i++){
+ $i_Offsets[] = strposX($data, "JM", $i+2);
}
-
-foreach ($_items as $_item) {
- $item = null;
- foreach ($_item as $i_bytes) {
- $item .= strrev(str_pad(decbin($i_bytes), 8, 0, STR_PAD_LEFT));
- // $item .= (str_pad(dechex($i_bytes), 2, 0, STR_PAD_LEFT));
- }
- $items[] = $item;
+foreach($i_Offsets as $k=>$v){
+ $itemOffsets[$v] = $i_Offsets[$k+1] - $i_Offsets[$k];
}
+array_pop($itemOffsets);
+
+
+//$items = null;
+//
+//$offset = $i_offset + 4; // JM00
+//
+//$first_item_offset = strposX($data, "JM", 2);
+//$second_item_offset = strposX($data, "JM", 3);
+//
+//$item_size = $second_item_offset - $first_item_offset;
+//
+//for ($i = 2; $i <= $i_total; $i++) {
+// fseek($fp, strposX($data, 'JM', $i));
+// $_items[] = unpack('C*', fread($fp, 21));
+//}
+//
+//foreach ($_items as $_item) {
+// $item = null;
+// foreach ($_item as $i_bytes) {
+// $item .= strrev(str_pad(decbin($i_bytes), 8, 0, STR_PAD_LEFT));
+// }
+// $items[] = $item;
+//}
// ddump($items);
diff --git a/genDocs.php b/genDocs.php
index 12b77ad..b0c24b8 100755
--- a/genDocs.php
+++ b/genDocs.php
@@ -789,8 +789,8 @@ if ($cmd == "genDocGems") {
$htmlFinal = '';
$htmlFinal .= $htmltop;
- echo $htmltop;
- ob_flush();
+ //echo $htmltop;
+ //ob_flush();
$table = '
@@ -804,9 +804,9 @@ if ($cmd == "genDocGems") {
';
- echo $table;
+ //echo $table;
$htmlFinal .= $table;
- ob_flush();
+ //ob_flush();
// $gems are all the gems, processed, now display them
foreach ($gems as $g) {
@@ -858,17 +858,17 @@ if ($cmd == "genDocGems") {
$htmlRow .= "";
$htmlFinal .= $htmlRow;
- echo $htmlRow;
- ob_flush();
+ //echo $htmlRow;
+ // ob_flush();
}
$htmlFinal .= $tableBottom . $htmlbottom;
- echo $tableBottom . $htmlbottom;
- ob_flush();
+ //echo $tableBottom . $htmlbottom;
+ //ob_flush();
- ob_start();
+ //ob_start();
file_put_contents("$dir/gems.html", $htmlFinal);
- header("Location: /docs/{$_SESSION['modname']}/gems.html");
+ header("Location: /docs/{$_SESSION['modname']}/gems.html",TRUE,301);
}
diff --git a/src/D2ByteReader.php b/src/D2ByteReader.php
new file mode 100644
index 0000000..26afbd9
--- /dev/null
+++ b/src/D2ByteReader.php
@@ -0,0 +1,154 @@
+data = $data;
+ }
+
+ public function skip(int $numBytes): bool {
+ if ($numBytes < 0 || $numBytes > strlen($this->data))
+ return false;
+ $this->offset += $numBytes;
+ return $true;
+ }
+
+ public function seek(int $pos): bool {
+ if ($pos < 0 || $pos > strlen($this->data))
+ return false;
+ $this->offset = $pos;
+ return true;
+ }
+
+ public function readh(int $offset, int $numBytes, bool $str = true): string {
+ $this->seek($offset);
+ $bytes = null;
+ for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) {
+ $str ? $bytes .= $this->data[$i] : $bytes[] = $this->data[$i];
+ }
+ return unpack('H*', $bytes)[1];
+ }
+
+ public function readc(int $offset, int $numBytes, bool $str = true): array {
+ $this->seek($offset);
+ $bytes = null;
+ for ($i = $this->offset; $i < $this->offset + $numBytes; $i++) {
+ $str ? $bytes .= $this->data[$i] : $bytes[] = $this->data[$i];
+ }
+ return unpack('C*', $bytes);
+ }
+
+ public function rewind(): bool {
+ $this->offset = 0;
+ return true;
+ }
+
+ public function writeByte(int $offset, int $byte) {
+ $this->data[$offset] = pack('C', $byte);
+ }
+
+ public function writeBytes(int $offset, string $bytes) {
+ if ($offset < 0 || $offset > strlen($this->data) || $bytes == '')
+ return false;
+ $_bytes = str_split($bytes, 2);
+ foreach ($_bytes as $k => $byte) {
+ $pos = $offset + $k;
+ $this->data[$pos] = pack('H*', $byte);
+ }
+ }
+
+ public function getData() {
+ return $this->data ? $this->data : false;
+ }
+
+ public function getOffset(): int {
+ return $this->offset;
+ }
+
+ public function isHexString(string $str): bool {
+ if (strlen($str) % 2 == 0 && (ctype_xdigit($str))) {
+ return true;
+ }
+ return false;
+ }
+
+ public function toBits($input): string {
+ $output = '';
+ if ($this->isHexString($input)) {
+ foreach (str_split($input, 2) as $byte) {
+ $output .= (strrev(str_pad(decbin(hexdec($byte)), 8, 0, STR_PAD_LEFT)));
+ }
+ return $output;
+ } else if (is_string($input)) {
+ foreach (str_split($input) as $i) {
+ $output .= strrev(str_pad(decbin(ord($i)), 8, 0, STR_PAD_LEFT));
+ }
+ return $output;
+ } else if (is_int($input)) {
+ return strrev(str_pad(decbin($input), 8, 0, STR_PAD_LEFT));
+ } else if (is_array($input)) {
+ foreach ($input as $i) {
+ $output .= $this->tobits($i);
+ }
+ return $output;
+ }
+ }
+
+ public function toBytes(string $bits) {
+ foreach (str_split($bits, 8) as $byteString) {
+ $bytes[] = (bindec(strrev($byteString)));
+ }
+ foreach ($bytes as $byte) {
+ dump($byte);
+ }
+ }
+
+ public function bitsToHexString(string $bits): string {
+ $bytes = '';
+ foreach (str_split($bits, 8) as $byte) {
+ $bytes .= (str_pad(dechex((bindec(strrev($byte)))), 2, 0, STR_PAD_LEFT));
+ }
+ return $bytes;
+ }
+
+ public function bitsToHexArray(string $bits): array {
+ $bytes = [];
+ foreach (str_split($bits, 8) as $byte) {
+ $bytes[] = (str_pad(dechex((bindec(strrev($byte)))), 2, 0, STR_PAD_LEFT));
+ }
+ return $bytes;
+ }
+
+ public function bitsToIntArray(string $bits): array {
+ $bytes = [];
+ foreach (str_split($bits, 8) as $byte) {
+ $bytes[] = (int) (str_pad(dechex((bindec(strrev($byte)))), 2, 0, STR_PAD_LEFT));
+ }
+ return $bytes;
+ }
+
+ /*
+ @return Byte with Nth bit set to X
+ */
+
+ public function setBit(int $byte, int $pos, bool $bit) {
+ return ($bit ? ($byte | (1 << $pos)) : ($byte & ~(1 << $pos)) );
+ }
+
+ /*
+ @return Bit at Nth position in Byte
+ */
+
+ public function getBit(int $byte, int $pos): int {
+ return intval(($byte & (1 << $pos)) != 0);
+ }
+
+}
\ No newline at end of file
diff --git a/src/D2Char.php b/src/D2Char.php
index 9ec34f6..16ee5cc 100644
--- a/src/D2Char.php
+++ b/src/D2Char.php
@@ -5,6 +5,7 @@ require_once 'D2Files.php';
require_once 'D2BitReader.php';
require_once 'D2Strings.php';
require_once 'D2Item.php';
+require_once 'D2ByteReader.php';
class D2Char {
@@ -31,32 +32,25 @@ class D2Char {
}
public function parseItems() {
- $_data = file_get_contents($this->filePath);
- // get offset of first JM and skip it
- $_offset = strpos($_data, "JM") + 2;
- // seek to items_total offset
- fseek($this->fp, $_offset);
- // item total is a SHORT 16 bits, 2 bytes
- $_total = unpack('S*', (fread($this->fp, 2)))[1];
+ $data = file_get_contents($this->filePath);
+ $ByteReader = new D2ByteReader($data);
+
+ $i_TotalOffset = strpos($data, "JM");
+ fseek($this->fp, $i_TotalOffset + 2);
+ $i_Total = unpack('S*', (fread($this->fp, 2)))[1];
- // Items start from 2nd JM
- for ($i = 2; $i <= $_total; $i++) {
- // seek to Each JM (every item begins with JM
- fseek($this->fp, strposX($_data, 'JM', $i));
- // read and unpack 21 bytes as array of byte/char (8 bit each)
- $_items[] = unpack('C*', fread($this->fp, 21));
+ $i_Offsets = [];
+ for ($i = 0; $i <= $i_Total; $i++) {
+ $i_Offsets[] = strposX($data, "JM", $i + 2);
}
- // Convert item bytes to 21x8 bitfield
- // each byte is reversed with strrev() for correct bit position
- // to convert back to ascii, read bits from any position, reverse, bindec(chr())
- foreach ($_items as $_item) {
- $item = null;
- foreach ($_item as $i_bytes) {
- $item .= strrev(str_pad(decbin($i_bytes), 8, 0, STR_PAD_LEFT));
- // $item .= (str_pad(dechex($i_bytes), 2, 0, STR_PAD_LEFT));
- }
- $this->items[] = new D2Item($item); // return an array of item details
+ foreach ($i_Offsets as $k => $v) {
+ $itemOffsets[$v] = $i_Offsets[$k + 1] - $i_Offsets[$k];
}
+ array_pop($itemOffsets);
+ $_items=[];
+ foreach ($itemOffsets as $offset => $bytes) {
+ $this->items[] = new D2Item($ByteReader->toBits($ByteReader->readh($offset, $bytes)));
+ }
}
public function parseChar() {
diff --git a/src/tabs/Chars.php b/src/tabs/Chars.php
index 721ea53..4e097b4 100644
--- a/src/tabs/Chars.php
+++ b/src/tabs/Chars.php
@@ -42,7 +42,7 @@ $form = new Formr\Formr();
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
- //ddump($charData);
+ ddump($charData);
?>