Here is a script in PHP that reads the binary item attributes from the database.
But since i don't know how floats look like, they are not supported by the script. (Floats aren't used mush anyway.)
Example:
Output:
You can find these binaries in for example database_name.player_items. You cannot read these binary directly from phpmyadmin, but if you implement this script into your website you'll be able to decode what's inside them.
Example use:
Since I'm allowed to edit the page, I'll add a version number for the script in case you guys find any bugs.
Version Information
Enjoy.
But since i don't know how floats look like, they are not supported by the script. (Floats aren't used mush anyway.)
PHP:
<?php
/* Made by Mazen */
function bytes_split($hex) {
$bytes = array();
if (strlen($hex) % 2 == 0) {
for ($char = 0; $char < strlen($hex); $char = $char + 2) {
$bytes[] = substr($hex, $char, 2);
}
}
return $bytes;
}
function bytes_reverse($hex) {
return implode("", array_reverse(bytes_split($hex)));
}
function bytes_to_str($hex) {
$string = "";
foreach (bytes_split($hex) as $byte) {
$string .= chr("0x" . $byte);
}
return $string;
}
function format_bytes($int) {
if (strlen($int) % 2 == 1) {
return "0" . $int;
} else {
return $int;
}
}
function ordstr($str) {
$string = (string)$str;
$hex = "";
for ($i = 0; strlen($string) > $i; $i++) {
$hex .= format_bytes(dechex(ord($string[$i])));
}
return $hex;
}
class Binary_Buffer {
private $position;
private $buffer;
public function __construct($buffer = "") {
$this->position = 0;
$this->setBuffer($buffer);
}
public function setBuffer($buffer) {
$this->buffer = $buffer;
}
public function getBuffer() {
return $this->buffer;
}
public function _format_number($number, $fomrat_len) {
$value = bytes_reverse(format_bytes(dechex($number)));
return $value . str_repeat("0", ($fomrat_len * 2) - strlen($value));
}
public function addChar($char) {
$this->buffer .= $this->_format_number($char, 1);
}
public function addInt($int) {
$this->buffer .= $this->_format_number($int, 4);
}
public function addShort($short) {
$this->buffer .= $this->_format_number($short, 2);
}
public function addLong($long) {
$this->buffer .= $this->_format_number($long, 8);
}
public function addString($string, $dynamic = true, $len_format = 4) {
if ($dynamic) {
$this->buffer .= $this->_format_number(strlen($string), $len_format);
}
$this->buffer .= ordstr($string);
}
public function getSize() {
return (strlen($this->buffer) / 2);
}
public function getPosition() {
return $this->position;
}
public function getByFormat($format_len) {
$value = substr($this->buffer, ($this->position * 2), ($format_len * 2));
$this->position += $format_len;
return $value;
}
public function getChar() {
return hexdec($this->getByFormat(1));
}
public function getShort() {
return hexdec(bytes_reverse($this->getByFormat(2)));
}
public function getint() {
return hexdec(bytes_reverse($this->getByFormat(4)));
}
public function getLong() {
return hexdec(bytes_reverse($this->getByFormat(8)));
}
public function getString($format_len = 2) {
$length = hexdec(bytes_reverse($this->getByFormat($format_len)));
$value = substr($this->buffer, ($this->position * 2), ($length * 2));
$this->position += $length;
return $value;
}
public function __toString() {
return $this->getBuffer();
}
}
class Opentibia_Binary_Attributes {
private $value = array();
const VALUE_TYPE_NONE = 0x00;
const VALUE_TYPE_STRING = 0x01;
const VALUE_TYPE_INT = 0x02;
const VALUE_TYPE_FLOAT = 0x03;
const VALUE_TYPE_TINY = 0x04;
private $attribute_names = array(
"aid" => self::VALUE_TYPE_INT,
"uid" => self::VALUE_TYPE_INT,
"count" => self::VALUE_TYPE_TINY,
"name" => self::VALUE_TYPE_STRING,
"text" => self::VALUE_TYPE_STRING,
"writer" => self::VALUE_TYPE_STRING,
"date" => self::VALUE_TYPE_INT
);
const NUM_UNKNOWN = 0;
const NUM_TINY = 1;
const NUM_SHORT = 2;
const NUM_INT = 4;
const NUM_DOUBLE = 8;
public function __construct($attributes_bin) {
$match = array();
if (preg_match("#[0-9a-fA-F]*#", $attributes_bin, $match)) {
$buffer = new Binary_Buffer($attributes_bin);
$type = $buffer -> getChar();
if ($type == 0x80) {
$attributes_count = $buffer -> getShort(); // Counts Number of attributes.
while ($buffer -> getPosition() < $buffer -> getSize()) {
$name = bytes_to_str($buffer -> getString(2));
$value_type = $buffer -> getChar();
switch ($value_type) {
case self::VALUE_TYPE_NONE: {
$buffer -> getInt();
$value = "";
break;
}
case self::VALUE_TYPE_STRING: {
$value = bytes_to_str($buffer -> getString(4));
break;
}
case self::VALUE_TYPE_INT: {
$value = $buffer -> getInt();
break;
}
case self::VALUE_TYPE_FLOAT: {
// Int has the same size as float. Note: Floats are NOT SUPPORTED, this is just here to avoid any errors.
$value = $buffer -> getInt();
break;
}
case self::VALUE_TYPE_TINY: {
$value = $buffer -> getChar();
break;
}
default: {
$value = bytes_to_str($buffer -> getString(4));
break;
}
}
$this->setAttribute($name, $value);
}
} elseif ($type == 0x0F) {
$this->setAttribute("count", $buffer -> getChar());
}
}
}
public function getAttributes() {
return $this->value;
}
public function setAttribute($name, $value) {
$this->value[$name] = $value;
}
public function getAttributesAsBinary() {
$buffer = new Binary_Buffer();
if (count($this->value) > 1) {
$buffer -> addChar(0x80);
$buffer -> addShort(count($this->value));
foreach ($this->value as $name => $value) {
$buffer -> addString($name, true, 2);
$type = $this->attribute_names[$name];
if (!$type) {
$type = self::VALUE_TYPE_STRING;
}
$buffer -> addChar($type);
switch ($type) {
case self::VALUE_TYPE_NONE: {
break;
}
case self::VALUE_TYPE_STRING: {
$buffer -> addString($value, true, 4);
break;
}
case self::VALUE_TYPE_INT: {
$buffer -> addInt($value);
break;
}
case self::VALUE_TYPE_FLOAT: {
$buffer -> addInt($value);
break;
}
case self::VALUE_TYPE_TINY: {
$buffer -> addChar($value);
break;
}
default: {
$buffer -> addString($value, true, 4);
break;
}
}
}
} else {
$buffer -> addChar(0x0F);
$buffer -> addChar(current($this->value));
}
return (strlen($buffer) > 0 ? $buffer : "");
}
}
?>
Example:
PHP:
$test = new Opentibia_Item_Attributes("800300040064617465024614e14d04007465787401040000006869696906007772697465720108000000474d205275667573");
print_r($test -> getAttributes());
Output:
Code:
Array ( [date] => 1306596422 [text] => hiii [writer] => GM Rufus )
You can find these binaries in for example database_name.player_items. You cannot read these binary directly from phpmyadmin, but if you implement this script into your website you'll be able to decode what's inside them.
Example use:
PHP:
$results = mysql_query("SELECT `attributes` FROM `player_items` LIMIT 1"); // Get one item
$row = mysql_fetch_assoc($results);
$attributes_hex = ordstr($row["attributes"]); // Convert string to hex.
$ot_item_attribute = new Opentibia_Item_Attribute($attributes_hex); // Create object
echo $ot_item_attribute -> getAttribute("name"); // Get attribute
Since I'm allowed to edit the page, I'll add a version number for the script in case you guys find any bugs.
Version Information
Code:
1.0 - The script is released. Converts binary attributes into a PHP array.
1.1 - Removed the "0x" before the HEX value. So do [B]not[/B] include it when you use the class. See the example.
2.0 - Fully rescripted. Using the buffer method wish is far better and easier to use. All previous bugs should be fixed by now. (Floats still not supported.)
Enjoy.
Last edited: