mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-13 01:09:44 +00:00
Fixed item stack count and effect amplifier overflows, close #1072
This commit is contained in:
parent
1bae973502
commit
e3b3f60c66
@ -60,6 +60,7 @@ use pocketmine\network\mcpe\protocol\SetEntityDataPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\plugin\Plugin;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Binary;
|
||||
|
||||
abstract class Entity extends Location implements Metadatable{
|
||||
|
||||
@ -773,7 +774,7 @@ abstract class Entity extends Location implements Metadatable{
|
||||
foreach($this->effects as $effect){
|
||||
$effects[] = new CompoundTag("", [
|
||||
"Id" => new ByteTag("Id", $effect->getId()),
|
||||
"Amplifier" => new ByteTag("Amplifier", $effect->getAmplifier()),
|
||||
"Amplifier" => new ByteTag("Amplifier", Binary::signByte($effect->getAmplifier())),
|
||||
"Duration" => new IntTag("Duration", $effect->getDuration()),
|
||||
"Ambient" => new ByteTag("Ambient", 0),
|
||||
"ShowParticles" => new ByteTag("ShowParticles", $effect->isVisible() ? 1 : 0)
|
||||
@ -800,7 +801,7 @@ abstract class Entity extends Location implements Metadatable{
|
||||
|
||||
if(isset($this->namedtag->ActiveEffects)){
|
||||
foreach($this->namedtag->ActiveEffects->getValue() as $e){
|
||||
$amplifier = $e["Amplifier"] & 0xff; //0-255 only
|
||||
$amplifier = Binary::unsignByte($e->Amplifier->getValue()); //0-255 only
|
||||
|
||||
$effect = Effect::getEffect($e["Id"]);
|
||||
if($effect === null){
|
||||
|
@ -40,6 +40,7 @@ use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\nbt\tag\Tag;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\Config;
|
||||
|
||||
class Item implements ItemIds, \JsonSerializable{
|
||||
@ -1009,7 +1010,7 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
public function nbtSerialize(int $slot = -1, string $tagName = "") : CompoundTag{
|
||||
$tag = new CompoundTag($tagName, [
|
||||
"id" => new ShortTag("id", $this->id),
|
||||
"Count" => new ByteTag("Count", $this->count),
|
||||
"Count" => new ByteTag("Count", Binary::signByte($this->count)),
|
||||
"Damage" => new ShortTag("Damage", $this->meta),
|
||||
]);
|
||||
|
||||
@ -1037,12 +1038,15 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return Item::get(0);
|
||||
}
|
||||
|
||||
$count = Binary::unsignByte($tag->Count->getValue());
|
||||
$meta = isset($tag->Damage) ? $tag->Damage->getValue() : 0;
|
||||
|
||||
if($tag->id instanceof ShortTag){
|
||||
$item = Item::get($tag->id->getValue(), !isset($tag->Damage) ? 0 : $tag->Damage->getValue(), $tag->Count->getValue());
|
||||
$item = Item::get($tag->id->getValue(), $meta, $count);
|
||||
}elseif($tag->id instanceof StringTag){ //PC item save format
|
||||
$item = Item::fromString($tag->id->getValue());
|
||||
$item->setDamage(!isset($tag->Damage) ? 0 : $tag->Damage->getValue());
|
||||
$item->setCount($tag->Count->getValue());
|
||||
$item->setDamage($meta);
|
||||
$item->setCount($count);
|
||||
}else{
|
||||
throw new \InvalidArgumentException("Item CompoundTag ID must be an instance of StringTag or ShortTag, " . get_class($tag->id) . " given");
|
||||
}
|
||||
|
@ -31,6 +31,30 @@ class Binary{
|
||||
const BIG_ENDIAN = 0x00;
|
||||
const LITTLE_ENDIAN = 0x01;
|
||||
|
||||
public static function signByte(int $value) : int{
|
||||
return $value << 56 >> 56;
|
||||
}
|
||||
|
||||
public static function unsignByte(int $value) : int{
|
||||
return $value & 0xff;
|
||||
}
|
||||
|
||||
public static function signShort(int $value) : int{
|
||||
return $value << 48 >> 48;
|
||||
}
|
||||
|
||||
public function unsignShort(int $value) : int{
|
||||
return $value & 0xffff;
|
||||
}
|
||||
|
||||
public static function signInt(int $value) : int{
|
||||
return $value << 32 >> 32;
|
||||
}
|
||||
|
||||
public static function unsignInt(int $value) : int{
|
||||
return $value & 0xffffffff;
|
||||
}
|
||||
|
||||
private static function checkLength($str, $expect){
|
||||
assert(($len = strlen($str)) === $expect, "Expected $expect bytes, got $len");
|
||||
}
|
||||
@ -73,7 +97,7 @@ class Binary{
|
||||
* @return int
|
||||
*/
|
||||
public static function readSignedByte(string $c) : int{
|
||||
return ord($c{0}) << 56 >> 56;
|
||||
return self::signByte(ord($c{0}));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,7 +130,7 @@ class Binary{
|
||||
*/
|
||||
public static function readSignedShort(string $str) : int{
|
||||
self::checkLength($str, 2);
|
||||
return unpack("n", $str)[1] << 48 >> 48;
|
||||
return self::signShort(unpack("n", $str)[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -141,7 +165,7 @@ class Binary{
|
||||
*/
|
||||
public static function readSignedLShort(string $str) : int{
|
||||
self::checkLength($str, 2);
|
||||
return unpack("v", $str)[1] << 48 >> 48;
|
||||
return self::signShort(unpack("v", $str)[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,7 +229,7 @@ class Binary{
|
||||
*/
|
||||
public static function readInt(string $str) : int{
|
||||
self::checkLength($str, 4);
|
||||
return unpack("N", $str)[1] << 32 >> 32;
|
||||
return self::signInt(unpack("N", $str)[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -226,7 +250,7 @@ class Binary{
|
||||
*/
|
||||
public static function readLInt(string $str) : int{
|
||||
self::checkLength($str, 4);
|
||||
return unpack("V", $str)[1] << 32 >> 32;
|
||||
return self::signInt(unpack("V", $str)[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user