mirror of
https://gitlab.com/hashborgir/d2tools.git
synced 2025-10-13 16:34:23 -05:00
Checksum code fixed. Added DocBlocks to D2Classes. TODO: Fill in docblocks, refactor, code cleanup
This commit is contained in:
@@ -1,15 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2BitReader {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private string $bits = '';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private int $offset = 0;
|
||||
|
||||
/**
|
||||
* @param string $bits
|
||||
*/
|
||||
public function __construct(string $bits = '') {
|
||||
$this->bits = $bits;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $numBits
|
||||
* @return int
|
||||
*/
|
||||
public function skip(int $numBits): int {
|
||||
$this->offset += $numBits;
|
||||
return $this->offset;
|
||||
@@ -17,6 +33,11 @@ class D2BitReader {
|
||||
|
||||
/* read X number of bits, like fread */
|
||||
|
||||
/**
|
||||
* @param int $numBits
|
||||
* @param bool $str
|
||||
* @return string
|
||||
*/
|
||||
public function read(int $numBits = 0, bool $str = true): string {
|
||||
$bits = null;
|
||||
for ($i = $this->offset; $i < $this->offset + $numBits; $i++) {
|
||||
@@ -26,10 +47,21 @@ class D2BitReader {
|
||||
return $bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bits
|
||||
* @param string $bitsToWrite
|
||||
* @param int $offset
|
||||
* @return array|string|string[]
|
||||
*/
|
||||
public function writeBits(string $bits, string $bitsToWrite, int $offset) {
|
||||
return substr_replace($bits, $bitsToWrite, $offset, strlen($bitsToWrite));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $numBits
|
||||
* @param bool $str
|
||||
* @return string
|
||||
*/
|
||||
public function readb(int $numBits = 0, bool $str = true): string {
|
||||
$bits = null;
|
||||
for ($i = $this->offset; $i < $this->offset + $numBits; $i++) {
|
||||
@@ -39,6 +71,10 @@ class D2BitReader {
|
||||
return strrev(str_pad($bits, 16, 0, STR_PAD_RIGHT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $numBits
|
||||
* @return string
|
||||
*/
|
||||
public function readr(int $numBits = 0): string {
|
||||
$bits = null;
|
||||
for ($i = $this->offset; $i < $this->offset + $numBits; $i++) {
|
||||
@@ -50,6 +86,10 @@ class D2BitReader {
|
||||
|
||||
/* seek to offset (like fseek) */
|
||||
|
||||
/**
|
||||
* @param int $pos
|
||||
* @return bool
|
||||
*/
|
||||
public function seek(int $pos): bool {
|
||||
if ($pos < 0 || $pos > strlen($this->bits)) {
|
||||
return false;
|
||||
@@ -60,6 +100,9 @@ class D2BitReader {
|
||||
|
||||
/* rewind offset to 0 */
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function rewind(): bool {
|
||||
$this->offset = 0;
|
||||
return true;
|
||||
@@ -67,6 +110,10 @@ class D2BitReader {
|
||||
|
||||
/* Get Bit */
|
||||
|
||||
/**
|
||||
* @param string $bitNum
|
||||
* @return int
|
||||
*/
|
||||
public function getBit(string $bitNum): int {
|
||||
if ($bitNum < 0 || $bitNum > strlen($this->bits)) {
|
||||
return false;
|
||||
@@ -76,6 +123,11 @@ class D2BitReader {
|
||||
|
||||
/* Set Bit */
|
||||
|
||||
/**
|
||||
* @param int $bitNum
|
||||
* @param int $bitVal
|
||||
* @return bool
|
||||
*/
|
||||
public function setBit(int $bitNum, int $bitVal): bool {
|
||||
if ($bitVal < 0 || $bitVal > 1) {
|
||||
return false;
|
||||
@@ -84,18 +136,32 @@ class D2BitReader {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBits(): string {
|
||||
return $this->bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bits
|
||||
* @return void
|
||||
*/
|
||||
public function setBits(string $bits) {
|
||||
$this->bits = $bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getOffset(): int {
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @return bool
|
||||
*/
|
||||
public function setOffset(int $offset): bool {
|
||||
if ($offset < 0 || $offset > strlen($this->bits))
|
||||
return false;
|
||||
|
@@ -3,17 +3,33 @@
|
||||
require_once './src/D2Functions.php';
|
||||
require_once './src/D2BitReader.php';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2ByteReader {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private string $data = '';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private int $offset = 0;
|
||||
|
||||
/**
|
||||
* @param string $data
|
||||
*/
|
||||
public function __construct(string $data) {
|
||||
if (!$data)
|
||||
return false;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $numBytes
|
||||
* @return bool
|
||||
*/
|
||||
public function skip(int $numBytes): bool {
|
||||
if ($numBytes < 0 || $numBytes > strlen($this->data))
|
||||
return false;
|
||||
@@ -21,6 +37,10 @@ class D2ByteReader {
|
||||
return $true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $pos
|
||||
* @return bool
|
||||
*/
|
||||
public function seek(int $pos): bool {
|
||||
if ($pos < 0 || $pos > strlen($this->data))
|
||||
return false;
|
||||
@@ -28,6 +48,12 @@ class D2ByteReader {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $numBytes
|
||||
* @param bool $str
|
||||
* @return string
|
||||
*/
|
||||
public function readh(int $offset, int $numBytes, bool $str = true): string {
|
||||
$this->seek($offset);
|
||||
$bytes = null;
|
||||
@@ -37,6 +63,12 @@ class D2ByteReader {
|
||||
return unpack('H*', $bytes)[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $numBytes
|
||||
* @param bool $str
|
||||
* @return array
|
||||
*/
|
||||
public function readc(int $offset, int $numBytes, bool $str = true): array {
|
||||
$this->seek($offset);
|
||||
$bytes = null;
|
||||
@@ -46,15 +78,28 @@ class D2ByteReader {
|
||||
return unpack('C*', $bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function rewind(): bool {
|
||||
$this->offset = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $byte
|
||||
* @return void
|
||||
*/
|
||||
public function writeByte(int $offset, int $byte) {
|
||||
$this->data[$offset] = pack('C', $byte);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param string $bytes
|
||||
* @return false|void
|
||||
*/
|
||||
public function writeBytes(int $offset, string $bytes) {
|
||||
if ($offset < 0 || $offset > strlen($this->data) || $bytes == '')
|
||||
return false;
|
||||
@@ -64,26 +109,46 @@ class D2ByteReader {
|
||||
$this->data[$pos] = pack('H*', $byte);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param string $bytes
|
||||
* @return false|void
|
||||
*/
|
||||
public function insertBytes(int $offset, string $bytes) {
|
||||
if ($offset < 0 || $offset > strlen($this->data) || $bytes == '')
|
||||
return false;
|
||||
$data = bin2hex($this->data); // convert to hex bytes string
|
||||
$newData = substr_replace($data, $bytes, $offset, 0);
|
||||
$this->data = hex2bin($newData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|string
|
||||
*/
|
||||
public function getData() {
|
||||
return $this->data ? $this->data : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return void
|
||||
*/
|
||||
public function setData($data){
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getOffset(): int {
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
* @return bool
|
||||
*/
|
||||
public function isHexString(string $str): bool {
|
||||
if (strlen($str) % 2 == 0 && (ctype_xdigit($str))) {
|
||||
return true;
|
||||
@@ -91,6 +156,10 @@ class D2ByteReader {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $input
|
||||
* @return string
|
||||
*/
|
||||
public function toBits($input): string {
|
||||
$output = '';
|
||||
if ($this->isHexString($input)) {
|
||||
@@ -113,13 +182,21 @@ class D2ByteReader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bits
|
||||
* @return string
|
||||
*/
|
||||
public function toBytesR(string $bits) : string {
|
||||
foreach (str_split($bits, 8) as $byteString) {
|
||||
$bytes .= strtoupper(str_pad(dechex(bindec(($byteString))), 2, 0, STR_PAD_LEFT));
|
||||
}
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $bits
|
||||
* @return string
|
||||
*/
|
||||
public function toBytes(string $bits) : string {
|
||||
foreach (str_split($bits, 8) as $byteString) {
|
||||
$bytes .= strtoupper(str_pad(dechex(bindec(strrev($byteString))), 2, 0, STR_PAD_LEFT));
|
||||
@@ -127,6 +204,10 @@ class D2ByteReader {
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bits
|
||||
* @return string
|
||||
*/
|
||||
public function bitsToHexString(string $bits): string {
|
||||
$bytes = '';
|
||||
foreach (str_split($bits, 8) as $byte) {
|
||||
@@ -135,6 +216,10 @@ class D2ByteReader {
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bits
|
||||
* @return array
|
||||
*/
|
||||
public function bitsToHexArray(string $bits): array {
|
||||
$bytes = [];
|
||||
foreach (str_split($bits, 8) as $byte) {
|
||||
@@ -143,6 +228,10 @@ class D2ByteReader {
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bits
|
||||
* @return array
|
||||
*/
|
||||
public function bitsToIntArray(string $bits): array {
|
||||
$bytes = [];
|
||||
foreach (str_split($bits, 8) as $byte) {
|
||||
@@ -151,18 +240,21 @@ class D2ByteReader {
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
@return Byte with Nth bit set to X
|
||||
/**
|
||||
* @param int $byte
|
||||
* @param int $pos
|
||||
* @param bool $bit
|
||||
* @return int
|
||||
*/
|
||||
|
||||
public function setBit(int $byte, int $pos, bool $bit) {
|
||||
return ($bit ? ($byte | (1 << $pos)) : ($byte & ~(1 << $pos)) );
|
||||
}
|
||||
|
||||
/*
|
||||
@return Bit at Nth position in Byte
|
||||
/**
|
||||
* @param int $byte
|
||||
* @param int $pos
|
||||
* @return int
|
||||
*/
|
||||
|
||||
public function getBit(int $byte, int $pos): int {
|
||||
return intval(($byte & (1 << $pos)) != 0);
|
||||
}
|
||||
|
298
src/D2Char.php
298
src/D2Char.php
@@ -8,24 +8,70 @@ require_once 'D2Item.php';
|
||||
require_once 'D2ByteReader.php';
|
||||
require_once 'D2Functions.php';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2Char {
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
public $cData = null; // char data output
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
public $items = null; // char item data
|
||||
/**
|
||||
* @var D2ByteReader|null
|
||||
*/
|
||||
public $ByteReader = null; // put $data into bytereader
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $filePath = null; // .d2s file path
|
||||
/**
|
||||
* @var D2CharStructureData
|
||||
*/
|
||||
private $sData = null; // char file structure data
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $bData = null; // char binary data from d2s
|
||||
/**
|
||||
* @var false|resource
|
||||
*/
|
||||
private $fp = null; // file pointer
|
||||
/**
|
||||
* @var false|string
|
||||
*/
|
||||
private $data = null; // full d2s file loaded in $data
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $ISC = null;
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $skillData = null;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function save() {
|
||||
file_put_contents($this->filePath, $this->data);
|
||||
checksumFix($this->filePath);
|
||||
$this->ByteReader->setData($this->data); // update bytereader data
|
||||
$this->ByteReader->writeBytes(12, "00000000"); // clear old checksum
|
||||
$this->data = $this->ByteReader->getData(); // update this data to what we get from bytereader after clearing checksum
|
||||
$checksum = checksum(unpack('C*', $this->data)); // get new checksum
|
||||
|
||||
$this->ByteReader->setData($this->data); // update bytereader data
|
||||
$this->ByteReader->writeBytes(12, $checksum); // write new checksum
|
||||
$this->data = $this->ByteReader->getData(); // update this data
|
||||
file_put_contents($this->filePath, $this->data); // write file
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $file
|
||||
*/
|
||||
public function __construct($file) {
|
||||
$this->sData = new D2CharStructureData();
|
||||
$this->filePath = $_SESSION['savepath'] . $file;
|
||||
@@ -52,7 +98,7 @@ class D2Char {
|
||||
$classes = array_flip(['ama' => 0, 'sor' => 1, 'nec' => 2, 'pal' => 3, 'bar' => 4, 'dru' => 5, 'ass' => 6]);
|
||||
$class = $classes[hexdec($this->ByteReader->readh(40, 1))];
|
||||
$sql = "SELECT sk.id,sk.Skill,sk.skilldesc,`str name`,strings.`String`,skilldesc.SkillPage,skilldesc.SkillRow,skilldesc.SkillColumn,skilldesc.ListRow,skilldesc.ListPool,skilldesc.IconCel
|
||||
FROM skills as sk
|
||||
FROM skills as sk
|
||||
LEFT JOIN skilldesc ON sk.skilldesc = skilldesc.skilldesc
|
||||
LEFT JOIN strings on skilldesc.`str name` = strings.Key
|
||||
WHERE sk.charclass = '$class'";
|
||||
@@ -64,6 +110,9 @@ WHERE sk.charclass = '$class'";
|
||||
return $this->parseChar(); // end of parseChar() calls parseItems(), parseStats, etc.
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function parseItems() {
|
||||
$i_TotalOffset = strpos($this->data, "JM");
|
||||
fseek($this->fp, $i_TotalOffset + 2);
|
||||
@@ -83,6 +132,9 @@ WHERE sk.charclass = '$class'";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function parseChar() {
|
||||
$cData = null;
|
||||
$cData['Identifier'] = bin2hex($this->bData[0]);
|
||||
@@ -90,30 +142,46 @@ WHERE sk.charclass = '$class'";
|
||||
$cData['VersionID'] = ($this->sData->version[unpack('l', $this->bData[4])[1]]);
|
||||
|
||||
// 1.41 KB (1,447 bytes) - checks out
|
||||
$cData['Filesize'] = round(unpack('l', $this->bData[8])[1] / 1024, 2) . " KB";
|
||||
//$cData['Filesize'] = round(unpack('l', $this->bData[8])[1] / 1024, 2) . " KB";
|
||||
$cData['Filesize'] = unpack('L', $this->bData[8])[1];
|
||||
$cData['Checksum'] = bin2hex($this->bData[12]);
|
||||
$cData['Activeweapon'] = unpack('l', $this->bData[16]);
|
||||
$cData['Activeweapon'] = unpack('L', $this->bData[16]);
|
||||
$cData['CharacterName'] = str_replace("\0", "", $this->bData[20]);
|
||||
$cData['CharacterStatus'] = array_filter(str_split(strtobits($this->bData[36])));
|
||||
foreach ($cData['CharacterStatus'] as $k => $v) {
|
||||
$str .= ($characterStatus[$k]) . " ";
|
||||
$characterStatus = array_filter(str_split(strrev(strtobits($this->bData[36]))));
|
||||
foreach ($characterStatus as $k => $v) {
|
||||
$str .= $this->sData->characterStatus[$k] . " ";
|
||||
}
|
||||
$cData['CharacterStatus'] = $str;
|
||||
$cData['Characterprogression'] = bindec($this->bData[37]);
|
||||
$cData['CharacterStatus'] = trim($str);
|
||||
|
||||
$progression = hexdec(bin2hex($this->bData[37]));
|
||||
$cData['CharacterProgression'] = $this->sData->characterProgressionClassic[$progression];
|
||||
|
||||
if ($cData['CharacterStatus'] == 'Hardcore Expansion') {
|
||||
$cData['CharacterProgression'] = $this->sData->characterProgressionExpHC[$progression];
|
||||
}
|
||||
if ($cData['CharacterStatus'] == "Expansion") {
|
||||
$cData['CharacterProgression'] = $this->sData->characterProgressionExp[$progression];
|
||||
}
|
||||
if ($cData['CharacterStatus'] == "Hardcore") {
|
||||
$cData['CharacterProgression'] = $this->sData->characterProgressionClassicHC[$progression];
|
||||
}
|
||||
|
||||
|
||||
$cData['CharacterClass'] = $this->sData->class[unpack('C', $this->bData[40])[1]];
|
||||
$cData['CharacterLevel'] = unpack('C', $this->bData[43])[1];
|
||||
$cData['Lastplayed'] = gmdate("Y-m-d\TH:i:s\Z", unpack('I', $this->bData[48])[0]);
|
||||
$cData['Lastplayed'] = gmdate("Y-m-d\TH:i:s\Z", unpack('L', $this->bData[48])[0]);
|
||||
|
||||
$skills = (unpack('l16', $this->bData[56]));
|
||||
// Hotkey assigned skills
|
||||
foreach ($skills as $skill) {
|
||||
$cData['Assignedskills'][] = ($this->sData->skills[$skill]);
|
||||
$cData['Assignedskills'] = array_filter($cData['Assignedskills']);
|
||||
}
|
||||
|
||||
$cData['LeftmousebuttonskillID'] = $this->sData->skills[unpack('i', $this->bData[120])[1]];
|
||||
$cData['RightmousebuttonskillID'] = $this->sData->skills[unpack('i', $this->bData[124])[1]];
|
||||
$cData['LeftswapmousebuttonskillID'] = $this->sData->skills[unpack('i', $this->bData[128])[1]];
|
||||
$cData['RightswapmousebuttonskillID'] = $this->sData->skills[unpack('i', $this->bData[132])[1]];
|
||||
$cData['LeftmousebuttonskillID'] = $this->sData->skills[unpack('L', $this->bData[120])[1]];
|
||||
$cData['RightmousebuttonskillID'] = $this->sData->skills[unpack('L', $this->bData[124])[1]];
|
||||
$cData['LeftswapmousebuttonskillID'] = $this->sData->skills[unpack('L', $this->bData[128])[1]];
|
||||
$cData['RightswapmousebuttonskillID'] = $this->sData->skills[unpack('L', $this->bData[132])[1]];
|
||||
|
||||
// Char menu appearance not needed
|
||||
// $cData['Charactermenuappearance'] = unpack('i', $this->bData[136]);
|
||||
@@ -128,7 +196,7 @@ WHERE sk.charclass = '$class'";
|
||||
// found in the character.map file, according to the difficulty being played. Not needed
|
||||
//$cData['MapID'] = $this->bData[171];
|
||||
|
||||
$cData['MercenaryDead'] = unpack('i', $this->bData[177])[1];
|
||||
$cData['MercenaryDead'] = unpack('i-', $this->bData[177])[1];
|
||||
// This looks like a random ID for your mercenary.
|
||||
// $cData['MercenaryID'] = unpack('H*', $this->bData[179]);
|
||||
$cData['MercenaryNameID'] = unpack('S', $this->bData[183])[1];
|
||||
@@ -149,13 +217,16 @@ WHERE sk.charclass = '$class'";
|
||||
$this->cData['skills'] = $this->parseSkills();
|
||||
|
||||
unset($this->items);
|
||||
unset($this->bData);
|
||||
//unset($this->bData);
|
||||
unset($this->sData);
|
||||
unset($this->fp);
|
||||
|
||||
return $this->cData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function parseSkills() {
|
||||
$if = strposX($this->data, 'if', 1) + 2; // find if and skip it
|
||||
$jm = strposX($this->data, 'JM', 1);
|
||||
@@ -177,6 +248,10 @@ WHERE sk.charclass = '$class'";
|
||||
return $cData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $points
|
||||
* @return void
|
||||
*/
|
||||
public function setAllSkills(int $points) {
|
||||
$if = strposX($this->data, 'if', 1) + 2; // find if and skip it
|
||||
$jm = strposX($this->data, 'JM', 1);
|
||||
@@ -188,6 +263,11 @@ WHERE sk.charclass = '$class'";
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $skill
|
||||
* @param int $points
|
||||
* @return void
|
||||
*/
|
||||
public function setSkill(int $skill, int $points) {
|
||||
$skill -= 1;
|
||||
$if = strposX($this->data, 'if', 1) + 2; // find if and skip it
|
||||
@@ -198,6 +278,9 @@ WHERE sk.charclass = '$class'";
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function parseStats() {
|
||||
$gf = strposX($this->data, 'gf', 1) + 2; // find gf and skip it
|
||||
$if = strposX($this->data, 'if', 1);
|
||||
@@ -205,13 +288,13 @@ WHERE sk.charclass = '$class'";
|
||||
$stats = new D2BitReader($this->ByteReader->toBits($this->ByteReader->readh($gf, $len)));
|
||||
|
||||
$bits = $stats->getBits();
|
||||
|
||||
$bytes = $this->ByteReader->toBytes($bits);
|
||||
|
||||
$bytes = $this->ByteReader->toBytes($bits);
|
||||
|
||||
$stats->rewind();
|
||||
for ($i = 0; $i <= strlen($bits); $i++) {
|
||||
$id = hexdec($this->ByteReader->toBytesR($stats->readb(9)));
|
||||
if ($this->ISC[$id]['CSvBits'] !== NULL) {
|
||||
if ($this->ISC[$id]['CSvBits'] !== NULL && $this->ISC[$id]['CSvBits'] !== '') {
|
||||
$stats->skip($this->ISC[$id]['CSvBits']);
|
||||
}
|
||||
$ids[$id] = $id;
|
||||
@@ -219,11 +302,11 @@ WHERE sk.charclass = '$class'";
|
||||
$stats->rewind();
|
||||
foreach ($ids as $id) {
|
||||
$stats->skip(9);
|
||||
if ($this->ISC[$id]['CSvBits'] !== NULL) {
|
||||
if ($this->ISC[$id]['CSvBits'] !== NULL && $this->ISC[$id]['CSvBits'] !== '') {
|
||||
$val = $stats->readb($this->ISC[$id]['CSvBits']);
|
||||
$stat = $this->ISC[$id]['Stat'];
|
||||
$values[$stat] = hexdec($this->ByteReader->toBytesR($val));
|
||||
}
|
||||
$stat = $this->ISC[$id]['Stat'];
|
||||
$values[$stat] = hexdec($this->ByteReader->toBytesR($val));
|
||||
}
|
||||
$values['hitpoints'] = (int) round($values['hitpoints'] >> 11);
|
||||
$values['maxhp'] = (int) round($values['maxhp'] >> 11);
|
||||
@@ -231,12 +314,19 @@ WHERE sk.charclass = '$class'";
|
||||
$values['maxmana'] = (int) round($values['maxmana'] >> 11);
|
||||
$values['stamina'] = (int) round($values['stamina'] >> 11);
|
||||
$values['maxstamina'] = (int) round($values['maxstamina'] >> 11);
|
||||
$values['killcounter'] = (int) round($values['killcounter'] >> 1);
|
||||
$values['soulcounter'] = (int) round($values['soulcounter'] / 2);
|
||||
$values['killcounter'] = (int) round($values['killcounter'] / 2);
|
||||
|
||||
$this->cData['stats'] = $values;
|
||||
}
|
||||
|
||||
public function setChar(string $stat, mixed $val) {
|
||||
/**
|
||||
* @param string $stat
|
||||
* @param mixed $val
|
||||
* @param mixed|null $val2
|
||||
* @return false|void
|
||||
*/
|
||||
public function setChar(string $stat, mixed $val, mixed $val2 = null) {
|
||||
switch ($stat) {
|
||||
case 'CharacterName':
|
||||
if (strlen($val) < 1 || strlen($val) > 15) {
|
||||
@@ -244,15 +334,20 @@ WHERE sk.charclass = '$class'";
|
||||
}
|
||||
$pack = $this->ByteReader->bitsToHexString($this->ByteReader->toBits(pack('Z16', $val)));
|
||||
$this->ByteReader->writeBytes(20, $pack);
|
||||
$this->data = $this->ByteReader->getData();
|
||||
$this->save();
|
||||
rename($this->filePath, $_SESSION['savepath'] . "$val.d2s");
|
||||
break;
|
||||
|
||||
case "CharacterClass":
|
||||
$this->ByteReader->writeByte(40, $val);
|
||||
$this->data = $this->ByteReader->getData();
|
||||
$this->save();
|
||||
$classes = [
|
||||
'Amazon' => 0,
|
||||
'Sorceress' => 1,
|
||||
'Necromancer' => 2,
|
||||
'Paladin' => 3,
|
||||
'Barbarian' => 4,
|
||||
'Druid' => 5,
|
||||
'Assassin' => 6
|
||||
];
|
||||
$this->ByteReader->writeByte(40, $classes[$val]);
|
||||
break;
|
||||
case "CharacterLevel":
|
||||
if ($val > 99) {
|
||||
@@ -271,26 +366,111 @@ WHERE sk.charclass = '$class'";
|
||||
$res = PDO_FetchOne($sql);
|
||||
$this->setStat('experience', $res);
|
||||
break;
|
||||
case 'CharacterStatus':
|
||||
switch ($val) {
|
||||
case 'Died':
|
||||
$status = (strtobits($this->data[36]));
|
||||
$status[3] = $val2;
|
||||
$byte = $this->ByteReader->bitsToHexString($status);
|
||||
$this->ByteReader->writeByte(36, hexdec($byte));
|
||||
break;
|
||||
case 'Hardcore':
|
||||
$status = (strtobits($this->data[36]));
|
||||
$status[2] = $val2;
|
||||
$byte = $this->ByteReader->bitsToHexString($status);
|
||||
$this->ByteReader->writeByte(36, hexdec($byte));
|
||||
break;
|
||||
case 'Expansion':
|
||||
$status = strrev(strtobits($this->data[36]));
|
||||
$status[5] = $val2;
|
||||
$byte = $this->ByteReader->bitsToHexString($status);
|
||||
$this->ByteReader->writeByte(36, hexdec($byte));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'CharacterProgression': // 0 in normal, 1 finished normal, 2 finished nm, 3 finished hell
|
||||
switch ($val) {
|
||||
case 0: // in normal
|
||||
$this->data[37] = pack('C', 3);
|
||||
break;
|
||||
case 1: // finished normal
|
||||
$this->data[37] = pack('C', 8);
|
||||
break;
|
||||
case 2: // finished nm
|
||||
$this->data[37] = pack('C', 13);
|
||||
break;
|
||||
case 3: // finished hell
|
||||
$this->data[37] = pack('C', 15);
|
||||
break;
|
||||
$this->save();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'LeftmousebuttonskillID':
|
||||
$this->ByteReader->writeBytes(120, dechex($val));
|
||||
break;
|
||||
|
||||
case 'RightmousebuttonskillID':
|
||||
$this->ByteReader->writeBytes(124, dechex($val));
|
||||
break;
|
||||
|
||||
case 'LeftswapmousebuttonskillID':
|
||||
$this->ByteReader->writeBytes(128, dechex($val));
|
||||
break;
|
||||
|
||||
case 'RightswapmousebuttonskillID':
|
||||
$this->ByteReader->writeBytes(132, dechex($val));
|
||||
break;
|
||||
}
|
||||
|
||||
// finally save char data to d2s file
|
||||
$this->data = $this->ByteReader->getData();
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function resetFileSize() {
|
||||
$filesize = strlen($this->data);
|
||||
$this->fp = fopen($this->filePath, "r+b");
|
||||
fseek($this->fp, 8);
|
||||
fwrite($this->fp, pack('L', $filesize));
|
||||
|
||||
fclose($this->fp);
|
||||
$this->fp = fopen($this->filePath, "r+b");
|
||||
checksumFix($this->filePath);
|
||||
|
||||
fseek($this->fp, 8);
|
||||
//ddump(unpack('L', fread($this->fp, 4))[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|string
|
||||
*/
|
||||
public function generateAllStats() {
|
||||
// 003C08E081000F067860C001071C0008020800F040020064A000000A2C00C0030C000D000000006E05000000FE3F
|
||||
$stats = '';
|
||||
foreach ($this->ISC as $i) {
|
||||
$id = strrev(str_pad((decbin($i['ID'])), 9, 0, STR_PAD_LEFT));
|
||||
$val = strrev(str_pad((decbin(20)), (int) $i['CSvBits'], 0, STR_PAD_LEFT));
|
||||
for ($i = 0; $i < 16; $i++) {
|
||||
$id = strrev(str_pad((decbin((int) $this->ISC[$i]['ID'])), 9, 0, STR_PAD_LEFT));
|
||||
$val = strrev(str_pad((decbin(20)), (int) $this->ISC[$i]['CSvBits'], 0, STR_PAD_LEFT));
|
||||
|
||||
// dump($id);
|
||||
// dump($val);
|
||||
|
||||
$stat = $id . $val;
|
||||
$stats .= $stat;
|
||||
}
|
||||
|
||||
$stats .= "000011111111100";
|
||||
|
||||
dump($stats);
|
||||
|
||||
$gf = strposX($this->data, 'gf', 1) + 2; // find gf and skip it
|
||||
$if = strposX($this->data, 'if', 1);
|
||||
$len = $if - $gf;
|
||||
|
||||
$statall = $stats . "11111111100";
|
||||
$bytes = $this->ByteReader->toBytes($statall);
|
||||
|
||||
$bytes = $this->ByteReader->toBytes($stats);
|
||||
|
||||
// refresh this data
|
||||
$data = $this->ByteReader->getData();
|
||||
// delete everything between GF---and---IF
|
||||
@@ -303,19 +483,27 @@ WHERE sk.charclass = '$class'";
|
||||
$this->data = $data;
|
||||
$this->save();
|
||||
|
||||
$this->resetFileSize();
|
||||
|
||||
$filedata = file_get_contents($this->filePath);
|
||||
$this->ByteReader = new D2ByteReader($filedata);
|
||||
$this->data = $this->ByteReader->getData();
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stat
|
||||
* @param mixed $val
|
||||
* @return void
|
||||
*/
|
||||
public function setStat(string $stat, mixed $val) {
|
||||
$gf = strposX($this->data, 'gf', 1) + 2; // find gf and skip it
|
||||
$if = strposX($this->data, 'if', 1);
|
||||
$len = $if - $gf;
|
||||
$stats = new D2BitReader($this->ByteReader->toBits($this->ByteReader->readh($gf, $len)));
|
||||
|
||||
$bits = $stats->getBits();
|
||||
|
||||
$bits = $stats->getBits();
|
||||
|
||||
$cleanbits = substr($bits, 0, -11);
|
||||
$stats->setBits($cleanbits);
|
||||
$bits = $stats->getBits();
|
||||
@@ -324,7 +512,9 @@ WHERE sk.charclass = '$class'";
|
||||
for ($i = 0; $i <= strlen($bits); $i++) {
|
||||
$id = hexdec($this->ByteReader->toBytesR($stats->readb(9)));
|
||||
$_offsets[$id] = $stats->getOffset();
|
||||
$stats->skip($this->ISC[$id]['CSvBits']);
|
||||
if ($this->ISC[$id]['CSvBits'] !== null && $this->ISC[$id]['CSvBits'] !== '') {
|
||||
$stats->skip($this->ISC[$id]['CSvBits']);
|
||||
}
|
||||
}
|
||||
$_offsets[0] = 9;
|
||||
$offsets = null;
|
||||
@@ -332,7 +522,9 @@ WHERE sk.charclass = '$class'";
|
||||
$_stat = $this->ISC[$k]['Stat'];
|
||||
$_stats[$_stat] = $this->ISC[$k]['Stat'];
|
||||
$csvbits[$_stat] = $this->ISC[$k]['CSvBits'];
|
||||
$maxValues[$_stat] = pow(2, $this->ISC[$k]['CSvBits']) - 1;
|
||||
if ($this->ISC[$k]['CSvBits'] !== null && $this->ISC[$k]['CSvBits'] !== '') {
|
||||
$maxValues[$_stat] = pow(2, $this->ISC[$k]['CSvBits']) - 1;
|
||||
}
|
||||
$offsets[$_stat] = $v;
|
||||
}
|
||||
if ($stat == 'hitpoints' || $stat == 'maxhp' || $stat == 'mana' || $stat == 'maxmana' || $stat == 'stamina' || $stat == 'maxstamina') {
|
||||
@@ -344,14 +536,22 @@ WHERE sk.charclass = '$class'";
|
||||
}
|
||||
$bitsToWrite = strrev(str_pad(decbin(intval($val)), $csvbits[$_stats[$stat]], 0, STR_PAD_LEFT));
|
||||
$statOffset = $offsets[$_stats[$stat]];
|
||||
$newBits = $stats->writeBits($bits, $bitsToWrite, $statOffset) . "11111111100"; // 0x1FF padding
|
||||
$stats->setBits($newBits);
|
||||
$bytes = $this->ByteReader->toBytes($newBits);
|
||||
$this->ByteReader->writeBytes($gf, $bytes);
|
||||
$this->data = $this->ByteReader->getData();
|
||||
$this->save();
|
||||
if (!array_key_exists($stat, $_stats)) {
|
||||
$this->ByteReader->toBits($this->generateAllStats());
|
||||
} else {
|
||||
$newBits = $stats->writeBits($bits, $bitsToWrite, $statOffset) . "11111111100"; // 0x1FF padding
|
||||
$stats->setBits($newBits);
|
||||
$bytes = $this->ByteReader->toBytes($newBits);
|
||||
$this->ByteReader->writeBytes($gf, $bytes);
|
||||
$this->data = $this->ByteReader->getData();
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $file
|
||||
* @return array
|
||||
*/
|
||||
public function getQuestData($file) {
|
||||
$questsNorm = null;
|
||||
$questsNM = null;
|
||||
@@ -390,6 +590,10 @@ WHERE sk.charclass = '$class'";
|
||||
return $quests;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $file
|
||||
* @return array
|
||||
*/
|
||||
public function getWaypointsData($file) {
|
||||
$wp = null;
|
||||
fseek($this->fp, $this->sData->wpOffsetsNorm);
|
||||
|
@@ -2,84 +2,306 @@
|
||||
|
||||
require_once 'D2BitReader.php';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2CharItem {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private string $bits;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $basename = ''; //name of the base item
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $item_name = ''; //name string
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $item_rank = ''; //normal/exceptional/elite
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $item_type = ''; //basic type: armor/weapon/misc
|
||||
//flags
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $identified = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $sockets = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $ear = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $starter = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $compact = 0;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $ethereal;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $personalized;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $runeword;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $version;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $runeword_name = '';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $runes_title = '';
|
||||
//placement
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $location = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $body = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $col = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $row = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $container = 0;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $parent;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $storage;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $bodypart;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $invH = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $invW = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $beltrows = 1;
|
||||
//features
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $item_code = ''; //3 letter code from txt
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $SocketsFilled = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $SocketsNum = 0;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $socketable = false; //gem, rune, jewel
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $fingerprint = '';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $itemlvl = 0; //item level
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $quality = 0;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $isCharm = false;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $isJewel = false;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $magic_rank = 'Normal'; //normal/magic/rare/crafted/set/unique
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $set_id = 0; //set item id from txt
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $set_item = '';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $set_name = 0; //set name, if it is set item,
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $personname = '';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $questdif = -1;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $gold;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $GUID = '';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $defense = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $mindam = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $maxdam = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $mindam2 = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $maxdam2 = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $mindammi = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $maxdammi = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $MaxDur = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $CurDur = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $reqlvl = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $reqstr = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $reqdex = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $speed = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $throwing = 0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $stackable = 0;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $charName = ''; //ear's name
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $gfx; //graphic file name
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $baseTrans = -1; //transform indexes for colour remap base item
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $magicTrans = -1; //transform indexes for colour remap magic item
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $type; //type column from txt
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $spelldesc = ''; //desc for potions
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $ditem; //link to item properties from txt
|
||||
//mods
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $dammult = 100; //damage multiply
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $damminadd = 0; //damage add
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $dammaxadd = 0; //damage add
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $defmult = 100; //defense multiply
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $defadd = 0; //defense multiply
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
public $resist = array(0, 0, 0, 0, 0, 0); //phy, mag, fire, light, cold, poison
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
public $attributes = array(0, 0, 0, 0); //str, dex, vit, ene
|
||||
|
||||
//arrays
|
||||
@@ -87,18 +309,33 @@ class D2CharItem {
|
||||
//socketed items, collected in above function,
|
||||
//because item has only data for itselt, and
|
||||
//gems/runes/jewels are standalone
|
||||
public $SocketItems = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $SocketItems = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $properties = array(); //item variable properties
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $propids = array(); //properties ids list
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $bits
|
||||
*/
|
||||
public function __construct(string $bits){
|
||||
if ($bits == '') return false;
|
||||
$this->bits = $bits;
|
||||
|
||||
return $this->parseItem();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function parseItem(){
|
||||
|
||||
}
|
||||
|
@@ -7,12 +7,24 @@ ini_set('max_execution_time', '0');
|
||||
session_start();
|
||||
ob_start();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
define('DB_FILE', $_SESSION['modname'] . ".db");
|
||||
PDO_Connect("sqlite:" . DB_FILE);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2CharStructureData {
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $skills;
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $class = [
|
||||
0 => 'Amazon',
|
||||
1 => 'Sorceress',
|
||||
@@ -22,6 +34,9 @@ class D2CharStructureData {
|
||||
5 => 'Druid',
|
||||
6 => 'Assassin'
|
||||
];
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $characterStatus = [
|
||||
0 => '',
|
||||
1 => '',
|
||||
@@ -32,6 +47,93 @@ class D2CharStructureData {
|
||||
6 => 'Ladder',
|
||||
7 => ''
|
||||
];
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $characterProgressionClassicHC = [
|
||||
0 => '',
|
||||
1 => '',
|
||||
2 => '',
|
||||
3 => '',
|
||||
4 => 'Count / Countess',
|
||||
5 => 'Count / Countess',
|
||||
6 => 'Count / Countess',
|
||||
7 => 'Count / Countess',
|
||||
8 => 'Duke / Duchess',
|
||||
9 => 'Duke / Duchess',
|
||||
10 => 'Duke / Duchess',
|
||||
11 => 'Duke / Duchess',
|
||||
12 => 'Duke / Duchess',
|
||||
13 => '',
|
||||
14 => '',
|
||||
15 => '',
|
||||
];
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $characterProgressionClassic = [
|
||||
0 => '',
|
||||
1 => '',
|
||||
2 => '',
|
||||
3 => '',
|
||||
4 => 'Sir / Dame',
|
||||
5 => 'Sir / Dame',
|
||||
6 => 'Sir / Dame',
|
||||
7 => 'Sir / Dame',
|
||||
8 => 'Lord / Lady',
|
||||
9 => 'Lord / Lady',
|
||||
10 => 'Lord / Lady',
|
||||
11 => 'Lord / Lady',
|
||||
12 => 'Baron / Baroness',
|
||||
13 => '',
|
||||
14 => '',
|
||||
15 => '',
|
||||
];
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $characterProgressionExp = [
|
||||
0 => '',
|
||||
1 => '',
|
||||
2 => '',
|
||||
3 => '',
|
||||
4 => '',
|
||||
5 => 'Slayer',
|
||||
6 => 'Slayer',
|
||||
7 => 'Slayer',
|
||||
8 => 'Slayer',
|
||||
9 => '',
|
||||
10 => 'Champion',
|
||||
11 => 'Champion',
|
||||
12 => 'Champion',
|
||||
13 => 'Champion',
|
||||
14 => 'Patriarch / Matriarch ',
|
||||
15 => 'Patriarch / Matriarch ',
|
||||
];
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $characterProgressionExpHC = [
|
||||
0 => '',
|
||||
1 => '',
|
||||
2 => '',
|
||||
3 => '',
|
||||
4 => '',
|
||||
5 => 'Destroyer',
|
||||
6 => 'Destroyer',
|
||||
7 => 'Destroyer',
|
||||
8 => 'Destroyer',
|
||||
9 => '',
|
||||
10 => 'Conqueror',
|
||||
11 => 'Conqueror',
|
||||
12 => 'Conqueror',
|
||||
13 => 'Conqueror',
|
||||
14 => 'Guardian',
|
||||
15 => 'Guardian',
|
||||
];
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
public $offsets = [
|
||||
0 => 4, // Identifier
|
||||
4 => 4, // Version ID
|
||||
@@ -67,6 +169,9 @@ class D2CharStructureData {
|
||||
633 => 81, // Waypoints
|
||||
714 => 51, // NPC Introductions
|
||||
];
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $qNorm = [
|
||||
345 => 'introWarriv',
|
||||
347 => 'Den_Of_Evil',
|
||||
@@ -95,14 +200,14 @@ class D2CharStructureData {
|
||||
393 => 'introToAct4',
|
||||
395 => 'The_Fallen_Angel',
|
||||
397 => 'Terrors_End',
|
||||
399 => 'Hell_Forge',
|
||||
399 => 'Hell_Forge',
|
||||
401 => 'traveledToAct5',
|
||||
//403 => 'empty31',
|
||||
//405 => 'empty32',
|
||||
//407 => 'empty33',
|
||||
409 => 'completedTerrorsEnd',
|
||||
//411 => 'empty21',
|
||||
//413 => 'empty22',
|
||||
//413 => 'empty22',
|
||||
415 => 'Siege_On_Harrogath',
|
||||
417 => 'Rescue_On_MountArreat',
|
||||
419 => 'Prison_Of_Ice',
|
||||
@@ -110,8 +215,10 @@ class D2CharStructureData {
|
||||
423 => 'Rite_Of_Passage',
|
||||
425 => 'Eve_Of_Destruction',
|
||||
// read 425, pointer at 427, + 14 = 441 qNM offset
|
||||
|
||||
];
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $qNM = [
|
||||
441 => 'introWarrivNM',
|
||||
443 => 'Den_Of_Evil_NM',
|
||||
@@ -147,7 +254,7 @@ class D2CharStructureData {
|
||||
//503 => 'empty33',
|
||||
505 => 'completedTerrorsEnd',
|
||||
//507 => 'empty21',
|
||||
//509 => 'empty22',
|
||||
//509 => 'empty22',
|
||||
511 => 'Siege_On_Harrogath',
|
||||
513 => 'Rescue_On_MountArreat',
|
||||
515 => 'Prison_Of_Ice',
|
||||
@@ -155,9 +262,10 @@ class D2CharStructureData {
|
||||
519 => 'Rite_Of_Passage',
|
||||
521 => 'Eve_Of_Destruction',
|
||||
// read 521, pointer at 523, + 14 = 537 qHell offset
|
||||
|
||||
|
||||
];
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $qHell = [
|
||||
537 => 'introWarriv',
|
||||
539 => 'Den_Of_Evil_Hell',
|
||||
@@ -193,15 +301,17 @@ class D2CharStructureData {
|
||||
//599 => 'empty33',
|
||||
601 => 'completedTerrorsEnd',
|
||||
//603 => 'empty21',
|
||||
//605 => 'empty22',
|
||||
//605 => 'empty22',
|
||||
607 => 'Siege_On_Harrogath',
|
||||
609 => 'Rescue_On_MountArreat',
|
||||
611 => 'Prison_Of_Ice',
|
||||
613 => 'Betrayal_Of_Harrogath',
|
||||
615=> 'Rite_Of_Passage',
|
||||
615 => 'Rite_Of_Passage',
|
||||
617 => 'Eve_Of_Destruction',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $version = [
|
||||
71 => "1.00 through v1.06",
|
||||
87 => "1.07 or Expansion Set v1.08",
|
||||
@@ -209,12 +319,21 @@ class D2CharStructureData {
|
||||
92 => "v1.09 (both the standard game and the Expansion Set.)",
|
||||
96 => "v1.10+"
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $wpOffsetsNorm = 643;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $wpOffsetsNM = 667;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $wpOffsetsHell = 691;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $wpNames = [
|
||||
0 => 'Act 1 - Rogue_Encampment',
|
||||
1 => 'Act 1 - Cold_Plains',
|
||||
@@ -255,18 +374,23 @@ class D2CharStructureData {
|
||||
36 => 'Act 5 - Frozen_Tundra',
|
||||
37 => "Act 5 - The_Ancients_Way",
|
||||
38 => 'Act 5 - Worldstone_Keep_level_2'
|
||||
];
|
||||
|
||||
];
|
||||
/**
|
||||
* @var int[]|string[]
|
||||
*/
|
||||
public $_qNorm;
|
||||
/**
|
||||
* @var int[]|string[]
|
||||
*/
|
||||
public $_qNM;
|
||||
/**
|
||||
* @var int[]|string[]
|
||||
*/
|
||||
public $_qHell;
|
||||
|
||||
|
||||
/*
|
||||
Initialize Skills From Skills.txt
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
$sql = "
|
||||
SELECT
|
||||
@@ -285,11 +409,11 @@ class D2CharStructureData {
|
||||
foreach ($res as $r) {
|
||||
$this->skills[$r['Id']] = $r['String'];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$this->_qNorm = array_flip($this->qNorm);
|
||||
$this->_qNM = array_flip($this->qNM);
|
||||
$this->_qHell = array_flip($this->qHell);
|
||||
$this->_qHell = array_flip($this->qHell);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -42,13 +42,24 @@
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2Database {
|
||||
|
||||
public function __construct() {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
PDO_Connect("sqlite:" . DB_FILE);
|
||||
}
|
||||
|
||||
public function createTables($file, $data) {
|
||||
/**
|
||||
* @param $file
|
||||
* @param $data
|
||||
* @return void
|
||||
*/
|
||||
public function createTables($file, $data) {
|
||||
$tableName = basename($file);
|
||||
$tableName = strtolower(substr($tableName, 0, -4));
|
||||
$sql = '';
|
||||
@@ -68,7 +79,12 @@ class D2Database {
|
||||
}
|
||||
}
|
||||
|
||||
public function fillsTables($file, $data) {
|
||||
/**
|
||||
* @param $file
|
||||
* @param $data
|
||||
* @return void
|
||||
*/
|
||||
public function fillsTables($file, $data) {
|
||||
$tableName = basename($file);
|
||||
$tableName = strtolower(substr($tableName, 0, -4));
|
||||
|
||||
@@ -106,7 +122,11 @@ class D2Database {
|
||||
}
|
||||
}
|
||||
|
||||
public function writeTbl($data) {
|
||||
/**
|
||||
* @param $data
|
||||
* @return void
|
||||
*/
|
||||
public function writeTbl($data) {
|
||||
$sql = 'CREATE TABLE IF NOT EXISTS `strings` (`Key` VARCHAR(255), `String` VARCHAR(255));';
|
||||
$res = PDO_Execute($sql);
|
||||
|
||||
@@ -120,7 +140,11 @@ class D2Database {
|
||||
$res = PDO_Execute($sql);
|
||||
}
|
||||
|
||||
public function getString($key) {
|
||||
/**
|
||||
* @param $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function getString($key) {
|
||||
$sql = "SELECT String FROM `strings` WHERE `Key`='$key'";
|
||||
|
||||
$res = PDO_FetchRow($sql);
|
||||
|
@@ -42,8 +42,14 @@
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2DocGenerator {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
require_once './config.php';
|
||||
require_once './_pdo.php';
|
||||
@@ -61,6 +67,9 @@ class D2DocGenerator {
|
||||
$idata = new D2ItemData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getIscProps() {
|
||||
$sql = "
|
||||
SELECT p.`code` as prop,
|
||||
@@ -103,6 +112,9 @@ class D2DocGenerator {
|
||||
return $isc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getStrings() {
|
||||
// load strings
|
||||
$sql = 'SELECT * FROM strings';
|
||||
@@ -110,6 +122,9 @@ class D2DocGenerator {
|
||||
return $strings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getItemTypesTbl() {
|
||||
// load itemtypes table in memory
|
||||
$sql = "SELECT ItemType,Code FROM itemtypes";
|
||||
@@ -118,6 +133,9 @@ class D2DocGenerator {
|
||||
return $itemtypesTbl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getNameStr() {
|
||||
// load namestr from 3 files
|
||||
$sql = "SELECT code,namestr FROM armor
|
||||
@@ -130,6 +148,10 @@ class D2DocGenerator {
|
||||
return $namestr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $code
|
||||
* @return string
|
||||
*/
|
||||
public function getImage($code) {
|
||||
$sql = "SELECT invfile FROM armor WHERE `code`=\"$code\" OR `type`=\"$code\" OR `type2`=\"$code\"";
|
||||
$img = PDO_FetchOne($sql);
|
||||
@@ -144,6 +166,10 @@ class D2DocGenerator {
|
||||
return $img = (!empty($img)) ? "$img.png" : "1.png";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $code
|
||||
* @return false
|
||||
*/
|
||||
public function getItemName($code) {
|
||||
$sql = "SELECT name FROM armor WHERE `code`=\"$code\" OR `type`=\"$code\" OR `type2`=\"$code\"";
|
||||
$name = PDO_FetchOne($sql);
|
||||
@@ -158,6 +184,9 @@ class D2DocGenerator {
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function generateDocs() {
|
||||
|
||||
}
|
||||
|
@@ -42,11 +42,23 @@
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2Files {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $files = [];
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $charFiles;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
$filesToIgnore = [
|
||||
"aiparms.txt",
|
||||
@@ -64,6 +76,9 @@ class D2Files {
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSaveFiles() {
|
||||
$glob = glob($_SESSION['savepath'] . '*.d2s');
|
||||
|
||||
|
@@ -42,6 +42,10 @@
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param $var
|
||||
* @return void
|
||||
*/
|
||||
function ddump($var) {
|
||||
//echo "<pre>";
|
||||
var_dump($var);
|
||||
@@ -51,6 +55,10 @@ function ddump($var) {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $var
|
||||
* @return void
|
||||
*/
|
||||
function dump($var) {
|
||||
//echo "<pre>";
|
||||
var_dump($var);
|
||||
@@ -59,6 +67,10 @@ function dump($var) {
|
||||
//echo json_encode($var, JSON_INVALID_UTF8_IGNORE | JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
function strtobits(string $str): string {
|
||||
$ret = "";
|
||||
for ($i = 0; $i < strlen($str); ++$i) {
|
||||
@@ -74,14 +86,29 @@ function strtobits(string $str): string {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $hex
|
||||
* @return string
|
||||
*/
|
||||
function swapEndianness(string $hex) {
|
||||
return implode('', array_reverse(str_split($hex, 2)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $n
|
||||
* @param int $p
|
||||
* @param bool $b
|
||||
* @return int
|
||||
*/
|
||||
function setBit(int $n, int $p, bool $b) {
|
||||
return ($b ? ($n | (1 << $p)) : ($n & ~(1 << $p)) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $b
|
||||
* @param int $p
|
||||
* @return int
|
||||
*/
|
||||
function getBit(int $b, int $p) {
|
||||
return intval(($b & (1 << $p)) !== 0);
|
||||
}
|
||||
@@ -91,30 +118,22 @@ function getBit(int $b, int $p) {
|
||||
* @param $data
|
||||
* @return string
|
||||
*/
|
||||
//function checksum($data) {
|
||||
// $nSignature = 0;
|
||||
// $checksum = 0;
|
||||
// foreach ($data as $k => $byte) {
|
||||
//// if ($k == 12 || $k == 13 || $k == 14 || $k == 15) {
|
||||
//// $byte = 0;
|
||||
//// }
|
||||
// $nSignature = ((($nSignature << 1) | ($nSignature >> 31)) + $byte) & 0xFFFFFFFF;
|
||||
// $checksum = (($checksum << 1) & 0xffffffff) + $byte + (($checksum & 0x80000000) != 0 ? 1 : 0);
|
||||
// }
|
||||
// dump(swapEndianness(dechex($nSignature)));
|
||||
// dump(swapEndianness(dechex($checksum)));
|
||||
// //return swapEndianness(dechex($nSignature));
|
||||
// //return swapEndianness(dechex($checksum)); // all of a sudden started returning wrong value, no longer works
|
||||
//}
|
||||
//
|
||||
//function checksumFix(object $ByteReader, string $filePath) {
|
||||
// $ByteReader->writeBytes(12, 00000000); // zero old checksum
|
||||
// $newChecksum = checksum(unpack('C*', $ByteReader->getData())); // get new checksum
|
||||
// $ByteReader->writeBytes(12, $newChecksum); // write new checksum
|
||||
// file_put_contents($filePath, $ByteReader->getData()); // write bytestream to file
|
||||
//}
|
||||
function checksum($fileData) {
|
||||
$nSignature = 0;
|
||||
foreach ($fileData as $k => $byte) {
|
||||
if ($k == 12 || $k == 13 || $k == 14 || $k == 15) {
|
||||
$byte = 0;
|
||||
}
|
||||
$nSignature = ((($nSignature << 1) | ($nSignature >> 31)) + $byte & 0xFFFFFFFF);
|
||||
}
|
||||
return swapEndianness(str_pad(dechex($nSignature), 8, 0, STR_PAD_LEFT));
|
||||
}
|
||||
|
||||
function checksumFix(string $filePath) {
|
||||
/**
|
||||
* @param string $filePath
|
||||
* @return string
|
||||
*/
|
||||
function checksumFix(string $filePath) {
|
||||
return trim(shell_exec("bin\d2scs.exe \"$filePath\""));
|
||||
}
|
||||
|
||||
@@ -135,10 +154,18 @@ function strposX($haystack, $needle, $number) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bit
|
||||
* @return int
|
||||
*/
|
||||
function isBit(string $bit): int {
|
||||
return ((int) $bit ? 1 : 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $input
|
||||
* @return string
|
||||
*/
|
||||
function toBits($input): string {
|
||||
$output = '';
|
||||
if (is_string($input)) {
|
||||
@@ -156,6 +183,9 @@ function toBits($input): string {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
function print_mem() {
|
||||
/* Currently used memory */
|
||||
$mem_usage = memory_get_usage();
|
||||
@@ -167,6 +197,11 @@ function print_mem() {
|
||||
echo 'Peak usage: <strong>' . round($mem_peak / 1024 / 1024) . 'MB</strong> RAM.<br><br>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $src
|
||||
* @param $dst
|
||||
* @return void
|
||||
*/
|
||||
function rcopy($src, $dst) {
|
||||
// open the source directory
|
||||
$dir = opendir($src);
|
||||
@@ -185,6 +220,10 @@ function rcopy($src, $dst) {
|
||||
closedir($dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $src
|
||||
* @return void
|
||||
*/
|
||||
function rrmdir($src) {
|
||||
$dir = opendir($src);
|
||||
while (false !== ( $file = readdir($dir))) {
|
||||
|
@@ -3,11 +3,23 @@
|
||||
require_once 'D2BitReader.php';
|
||||
require_once 'D2ItemStructureData.php';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2Item {
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $bits = null;
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
public $iData = null;
|
||||
|
||||
/**
|
||||
* @param $bits
|
||||
*/
|
||||
public function __construct($bits) {
|
||||
if ($bits == '')
|
||||
return false;
|
||||
@@ -20,6 +32,9 @@ class D2Item {
|
||||
* @return array of item details
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
private function parseItem() {
|
||||
$b = new D2BitReader($this->bits);
|
||||
|
||||
|
@@ -1,10 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2ItemData {
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $strings;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $images;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function getImages() {
|
||||
$sql = "SELECT code,uniqueinvfile,invfile,type,type2 FROM armor
|
||||
UNION ALL
|
||||
@@ -24,6 +36,11 @@ class D2ItemData {
|
||||
unset($isc2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $index
|
||||
* @param $doc
|
||||
* @return false|string
|
||||
*/
|
||||
public function uniqueItems($index, $doc = FALSE) {
|
||||
if (empty($this->images)) {
|
||||
$this->getImages();
|
||||
@@ -897,6 +914,10 @@ class D2ItemData {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $iscStat
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIscStrings($iscStat) {
|
||||
if (empty($this->strings)) {
|
||||
$this->getStrings();
|
||||
@@ -904,6 +925,9 @@ class D2ItemData {
|
||||
return ($this->strings[$iscStat]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function getStrings() {
|
||||
$sql = "
|
||||
SELECT p.`code` as prop,
|
||||
|
@@ -42,6 +42,9 @@
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2ItemDesc {
|
||||
/*
|
||||
|
||||
@@ -135,14 +138,26 @@ class D2ItemDesc {
|
||||
|
||||
*/
|
||||
|
||||
public $str = '';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $str = '';
|
||||
// takes value, param.
|
||||
// value == Value to show on this stat
|
||||
//descfunc 14
|
||||
|
||||
public $skilltabsDesc;
|
||||
public $skilltabsDescClean;
|
||||
public $skilltabs = [
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $skilltabsDesc;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $skilltabsDescClean;
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $skilltabs = [
|
||||
//ama
|
||||
'0' => 'StrSklTabItem3',
|
||||
'1' => 'StrSklTabItem2',
|
||||
@@ -172,7 +187,10 @@ class D2ItemDesc {
|
||||
'19' => 'StrSklTabItem20',
|
||||
'20' => 'StrSklTabItem21'
|
||||
];
|
||||
public $charClass = [
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $charClass = [
|
||||
"ama" => "Amazon",
|
||||
"sor" => "Sorceress",
|
||||
"nec" => "Necromancer",
|
||||
@@ -245,7 +263,13 @@ class D2ItemDesc {
|
||||
*
|
||||
*/
|
||||
|
||||
public function prep($par, $min, $max) {
|
||||
/**
|
||||
* @param $par
|
||||
* @param $min
|
||||
* @param $max
|
||||
* @return void
|
||||
*/
|
||||
public function prep($par, $min, $max) {
|
||||
|
||||
}
|
||||
|
||||
@@ -268,16 +292,19 @@ class D2ItemDesc {
|
||||
|
||||
*/
|
||||
|
||||
public function __construct() {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function getDesc($params = []) {
|
||||
/**
|
||||
* @param $params
|
||||
* @return false|string
|
||||
*/
|
||||
public function getDesc($params = []) {
|
||||
if (empty($params))
|
||||
return false;
|
||||
|
||||
|
@@ -1,40 +1,112 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2ItemLocation {
|
||||
|
||||
//location
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const STORED = 0;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const EQUIPPED = 1;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const BELTI = 2;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const CURSOR = 4;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const ITEM = 6;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2ItemLocationStored {
|
||||
|
||||
//storage
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const NONE = 0;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const INVENTORY = 1;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const CUBE = 4;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const STASH = 5;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2ItemLocationBody {
|
||||
|
||||
//body parts
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const HELMET = 1;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const AMULET = 2;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const ARMOR = 3;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const WEAPONR = 4;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const WEAPONL = 5;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const RINGR = 6;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const RINGL = 7;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const BELT = 8;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const BOOTS = 9;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const GLOVES = 10;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const WEAPONR2 = 11;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const WEAPONL2 = 12;
|
||||
|
||||
}
|
||||
|
@@ -42,11 +42,22 @@
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2SaveTXT {
|
||||
|
||||
public $path;
|
||||
|
||||
public function save($file, $data) {
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $path;
|
||||
|
||||
/**
|
||||
* @param $file
|
||||
* @param $data
|
||||
* @return void
|
||||
*/
|
||||
public function save($file, $data) {
|
||||
|
||||
$fp = fopen($this->path.DIRECTORY_SEPARATOR.$file, 'a+');
|
||||
$this->saveBackup($file);
|
||||
@@ -54,7 +65,11 @@ class D2SaveTXT {
|
||||
}
|
||||
|
||||
|
||||
public function saveBackup($file){
|
||||
/**
|
||||
* @param $file
|
||||
* @return void
|
||||
*/
|
||||
public function saveBackup($file){
|
||||
|
||||
// if dir doesn't exist, create it
|
||||
if (!is_dir($this->path.DIRECTORY_SEPARATOR."backup")) mkdir($this->path."backup", 0700);
|
||||
@@ -71,8 +86,12 @@ class D2SaveTXT {
|
||||
echo "Failed to create backup of $file...\n";
|
||||
}
|
||||
}
|
||||
|
||||
public function saveTblEnries($filename) {
|
||||
|
||||
/**
|
||||
* @param $filename
|
||||
* @return void
|
||||
*/
|
||||
public function saveTblEnries($filename) {
|
||||
$post = $_POST;
|
||||
|
||||
if (!is_dir($this->path."tblEntries")) mkdir($this->path."tblEntries", 0700);
|
||||
@@ -81,9 +100,12 @@ class D2SaveTXT {
|
||||
$str = '"'.$post['index'].'"'."\t".'"'.$post['index'].'"'.PHP_EOL;
|
||||
$file = $this->path."\\tblEntries\\$filename";
|
||||
file_put_contents($file, $str, FILE_APPEND);
|
||||
}
|
||||
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->path = TXT_PATH;
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2Strings {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $strings;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct(){
|
||||
$sql = "SELECT * FROM strings";
|
||||
$this->strings = PDO_FetchAssoc($sql);
|
||||
|
@@ -41,20 +41,41 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class D2TxtParser {
|
||||
|
||||
public $path = TXT_PATH;
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $path = TXT_PATH;
|
||||
|
||||
public $db;
|
||||
|
||||
public function __construct() {
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $db;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
public function parseFile($file) {
|
||||
/**
|
||||
* @param $file
|
||||
* @return array
|
||||
*/
|
||||
public function parseFile($file) {
|
||||
return $this->parseData($file);
|
||||
}
|
||||
|
||||
function filterProps($file) {
|
||||
/**
|
||||
* @param $file
|
||||
* @return array
|
||||
*/
|
||||
function filterProps($file) {
|
||||
$data = $this->parseData($file);
|
||||
$propsToFilter = file(FILTER_PROPERTIES_FILE, FILE_IGNORE_NEW_LINES);
|
||||
foreach ($data as $d) {
|
||||
@@ -65,7 +86,11 @@ class D2TxtParser {
|
||||
return $filteredProps;
|
||||
}
|
||||
|
||||
public function parseData($file) {
|
||||
/**
|
||||
* @param $file
|
||||
* @return array
|
||||
*/
|
||||
public function parseData($file) {
|
||||
$file = $this->path . $file;
|
||||
$rows = array_map(function ($v) {
|
||||
return str_getcsv($v, "\t");
|
||||
|
@@ -47,7 +47,7 @@
|
||||
<div>
|
||||
<div class="center item_desc" style="">
|
||||
|
||||
<div style="height: 116px;background: url(/img/items/bg.png) center top no-repeat;">
|
||||
<div style="height: 116px;background: url(/img/bg.png) center top no-repeat;">
|
||||
<a href="" target="_blank" class="item_debug_link">
|
||||
<img style="" class="item img-fluid" src="">
|
||||
</a>
|
||||
|
Reference in New Issue
Block a user