mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-07 20:28:31 +00:00
Furnace: cleanup, stop abusing NBT, stop spamming packets
This commit is contained in:
parent
58279d4cfe
commit
933b0e8b41
@ -47,38 +47,34 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
|
|||||||
public const TAG_BURN_TIME = "BurnTime";
|
public const TAG_BURN_TIME = "BurnTime";
|
||||||
public const TAG_COOK_TIME = "CookTime";
|
public const TAG_COOK_TIME = "CookTime";
|
||||||
public const TAG_MAX_TIME = "MaxTime";
|
public const TAG_MAX_TIME = "MaxTime";
|
||||||
public const TAG_BURN_TICKS = "BurnTicks";
|
|
||||||
|
|
||||||
/** @var FurnaceInventory */
|
/** @var FurnaceInventory */
|
||||||
protected $inventory;
|
protected $inventory;
|
||||||
|
/** @var int */
|
||||||
|
private $burnTime;
|
||||||
|
/** @var int */
|
||||||
|
private $cookTime;
|
||||||
|
/** @var int */
|
||||||
|
private $maxTime;
|
||||||
|
|
||||||
public function __construct(Level $level, CompoundTag $nbt){
|
public function __construct(Level $level, CompoundTag $nbt){
|
||||||
if(!$nbt->hasTag(self::TAG_BURN_TIME, ShortTag::class) or $nbt->getShort(self::TAG_BURN_TIME) < 0){
|
$this->burnTime = max(0, $nbt->getShort(self::TAG_BURN_TIME, 0, true));
|
||||||
$nbt->setShort(self::TAG_BURN_TIME, 0, true);
|
|
||||||
|
$this->cookTime = $nbt->getShort(self::TAG_COOK_TIME, 0, true);
|
||||||
|
if($this->burnTime === 0){
|
||||||
|
$this->cookTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(
|
$this->maxTime = $nbt->getShort(self::TAG_MAX_TIME, 0, true);
|
||||||
!$nbt->hasTag(self::TAG_COOK_TIME, ShortTag::class) or
|
if($this->maxTime === 0){
|
||||||
$nbt->getShort(self::TAG_COOK_TIME) < 0 or
|
$this->maxTime = $this->burnTime;
|
||||||
($nbt->getShort(self::TAG_BURN_TIME) === 0 and $nbt->getShort(self::TAG_COOK_TIME) > 0)
|
|
||||||
){
|
|
||||||
$nbt->setShort(self::TAG_COOK_TIME, 0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$nbt->hasTag(self::TAG_MAX_TIME, ShortTag::class)){
|
|
||||||
$nbt->setShort(self::TAG_MAX_TIME, $nbt->getShort(self::TAG_BURN_TIME), true);
|
|
||||||
$nbt->removeTag(self::TAG_BURN_TICKS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$nbt->getTag(self::TAG_BURN_TICKS, ShortTag::class)){
|
|
||||||
$nbt->setShort(self::TAG_BURN_TICKS, 0, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($level, $nbt);
|
parent::__construct($level, $nbt);
|
||||||
$this->inventory = new FurnaceInventory($this);
|
$this->inventory = new FurnaceInventory($this);
|
||||||
$this->loadItems();
|
$this->loadItems();
|
||||||
|
|
||||||
if($this->namedtag->getShort(self::TAG_BURN_TIME) > 0){
|
if($this->burnTime > 0){
|
||||||
$this->scheduleUpdate();
|
$this->scheduleUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,6 +97,10 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
|
|||||||
|
|
||||||
public function saveNBT() : void{
|
public function saveNBT() : void{
|
||||||
parent::saveNBT();
|
parent::saveNBT();
|
||||||
|
$this->namedtag->setShort(self::TAG_BURN_TIME, $this->burnTime);
|
||||||
|
$this->namedtag->setShort(self::TAG_COOK_TIME, $this->cookTime);
|
||||||
|
$this->namedtag->setShort(self::TAG_MAX_TIME, $this->maxTime);
|
||||||
|
|
||||||
$this->saveItems();
|
$this->saveItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,19 +125,22 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->namedtag->setShort(self::TAG_MAX_TIME, $ev->getBurnTime());
|
$this->maxTime = $this->burnTime = $ev->getBurnTime();
|
||||||
$this->namedtag->setShort(self::TAG_BURN_TIME, $ev->getBurnTime());
|
|
||||||
$this->namedtag->setShort(self::TAG_BURN_TICKS, 0);
|
|
||||||
if($this->getBlock()->getId() === Block::FURNACE){
|
if($this->getBlock()->getId() === Block::FURNACE){
|
||||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::BURNING_FURNACE, $this->getBlock()->getDamage()), true);
|
$this->getLevel()->setBlock($this, BlockFactory::get(Block::BURNING_FURNACE, $this->getBlock()->getDamage()), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->namedtag->getShort(self::TAG_BURN_TIME) > 0 and $ev->isBurning()){
|
if($this->burnTime > 0 and $ev->isBurning()){
|
||||||
$fuel->pop();
|
$fuel->pop();
|
||||||
$this->inventory->setFuel($fuel);
|
$this->inventory->setFuel($fuel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getFuelTicksLeft() : int{
|
||||||
|
return $this->maxTime > 0 ? (int) ceil($this->burnTime / $this->maxTime * 200) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
public function onUpdate() : bool{
|
public function onUpdate() : bool{
|
||||||
if($this->closed){
|
if($this->closed){
|
||||||
return false;
|
return false;
|
||||||
@ -145,6 +148,9 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
|
|||||||
|
|
||||||
$this->timings->startTiming();
|
$this->timings->startTiming();
|
||||||
|
|
||||||
|
$prevCookTime = $this->cookTime;
|
||||||
|
$prevFuelTicksLeft = $this->getFuelTicksLeft();
|
||||||
|
|
||||||
$ret = false;
|
$ret = false;
|
||||||
|
|
||||||
$fuel = $this->inventory->getFuel();
|
$fuel = $this->inventory->getFuel();
|
||||||
@ -153,17 +159,17 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
|
|||||||
$smelt = $this->server->getCraftingManager()->matchFurnaceRecipe($raw);
|
$smelt = $this->server->getCraftingManager()->matchFurnaceRecipe($raw);
|
||||||
$canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull()));
|
$canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull()));
|
||||||
|
|
||||||
if($this->namedtag->getShort(self::TAG_BURN_TIME) <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){
|
if($this->burnTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){
|
||||||
$this->checkFuel($fuel);
|
$this->checkFuel($fuel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->namedtag->getShort(self::TAG_BURN_TIME) > 0){
|
if($this->burnTime > 0){
|
||||||
$this->namedtag->setShort(self::TAG_BURN_TIME, $this->namedtag->getShort(self::TAG_BURN_TIME) - 1);
|
--$this->burnTime;
|
||||||
$this->namedtag->setShort(self::TAG_BURN_TICKS, (int) ceil($this->namedtag->getShort(self::TAG_BURN_TIME) / $this->namedtag->getShort(self::TAG_MAX_TIME) * 200));
|
|
||||||
|
|
||||||
if($smelt instanceof FurnaceRecipe and $canSmelt){
|
if($smelt instanceof FurnaceRecipe and $canSmelt){
|
||||||
$this->namedtag->setShort(self::TAG_COOK_TIME, $this->namedtag->getShort(self::TAG_COOK_TIME) + 1);
|
++$this->cookTime;
|
||||||
if($this->namedtag->getShort(self::TAG_COOK_TIME) >= 200){ //10 seconds
|
|
||||||
|
if($this->cookTime >= 200){ //10 seconds
|
||||||
$product = ItemFactory::get($smelt->getResult()->getId(), $smelt->getResult()->getDamage(), $product->getCount() + 1);
|
$product = ItemFactory::get($smelt->getResult()->getId(), $smelt->getResult()->getDamage(), $product->getCount() + 1);
|
||||||
|
|
||||||
$this->server->getPluginManager()->callEvent($ev = new FurnaceSmeltEvent($this, $raw, $product));
|
$this->server->getPluginManager()->callEvent($ev = new FurnaceSmeltEvent($this, $raw, $product));
|
||||||
@ -174,39 +180,47 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
|
|||||||
$this->inventory->setSmelting($raw);
|
$this->inventory->setSmelting($raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->namedtag->setShort(self::TAG_COOK_TIME, $this->namedtag->getShort(self::TAG_COOK_TIME) - 200);
|
$this->cookTime -= 200;
|
||||||
}
|
}
|
||||||
}elseif($this->namedtag->getShort(self::TAG_BURN_TIME) <= 0){
|
}elseif($this->burnTime <= 0){
|
||||||
$this->namedtag->setShort(self::TAG_BURN_TIME, 0);
|
$this->burnTime = $this->cookTime = $this->maxTime = 0;
|
||||||
$this->namedtag->setShort(self::TAG_COOK_TIME, 0);
|
|
||||||
$this->namedtag->setShort(self::TAG_BURN_TICKS, 0);
|
|
||||||
}else{
|
}else{
|
||||||
$this->namedtag->setShort(self::TAG_COOK_TIME, 0);
|
$this->cookTime = 0;
|
||||||
}
|
}
|
||||||
$ret = true;
|
$ret = true;
|
||||||
}else{
|
}else{
|
||||||
if($this->getBlock()->getId() === Block::BURNING_FURNACE){
|
if($this->getBlock()->getId() === Block::BURNING_FURNACE){
|
||||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::FURNACE, $this->getBlock()->getDamage()), true);
|
$this->getLevel()->setBlock($this, BlockFactory::get(Block::FURNACE, $this->getBlock()->getDamage()), true);
|
||||||
}
|
}
|
||||||
$this->namedtag->setShort(self::TAG_BURN_TIME, 0);
|
$this->burnTime = $this->cookTime = $this->maxTime = 0;
|
||||||
$this->namedtag->setShort(self::TAG_COOK_TIME, 0);
|
|
||||||
$this->namedtag->setShort(self::TAG_BURN_TICKS, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @var ContainerSetDataPacket[] $packets */
|
||||||
|
$packets = [];
|
||||||
|
if($prevCookTime !== $this->cookTime){
|
||||||
|
$pk = new ContainerSetDataPacket();
|
||||||
|
$pk->property = ContainerSetDataPacket::PROPERTY_FURNACE_TICK_COUNT;
|
||||||
|
$pk->value = $this->cookTime;
|
||||||
|
$packets[] = $pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fuelTicksLeft = $this->getFuelTicksLeft();
|
||||||
|
if($prevFuelTicksLeft !== $fuelTicksLeft){
|
||||||
|
$pk = new ContainerSetDataPacket();
|
||||||
|
$pk->property = ContainerSetDataPacket::PROPERTY_FURNACE_LIT_TIME;
|
||||||
|
$pk->value = $fuelTicksLeft;
|
||||||
|
$packets[] = $pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!empty($packets)){
|
||||||
foreach($this->getInventory()->getViewers() as $player){
|
foreach($this->getInventory()->getViewers() as $player){
|
||||||
$windowId = $player->getWindowId($this->getInventory());
|
$windowId = $player->getWindowId($this->getInventory());
|
||||||
if($windowId > 0){
|
if($windowId > 0){
|
||||||
$pk = new ContainerSetDataPacket();
|
foreach($packets as $pk){
|
||||||
$pk->windowId = $windowId;
|
$pk->windowId = $windowId;
|
||||||
$pk->property = ContainerSetDataPacket::PROPERTY_FURNACE_TICK_COUNT; //Smelting
|
$player->dataPacket(clone $pk);
|
||||||
$pk->value = $this->namedtag->getShort(self::TAG_COOK_TIME);
|
}
|
||||||
$player->dataPacket($pk);
|
}
|
||||||
|
|
||||||
$pk = new ContainerSetDataPacket();
|
|
||||||
$pk->windowId = $windowId;
|
|
||||||
$pk->property = ContainerSetDataPacket::PROPERTY_FURNACE_LIT_TIME;
|
|
||||||
$pk->value = $this->namedtag->getShort(self::TAG_BURN_TICKS);
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,8 +230,8 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function addAdditionalSpawnData(CompoundTag $nbt) : void{
|
public function addAdditionalSpawnData(CompoundTag $nbt) : void{
|
||||||
$nbt->setTag($this->namedtag->getTag(self::TAG_BURN_TIME));
|
$nbt->setShort(self::TAG_BURN_TIME, $this->burnTime);
|
||||||
$nbt->setTag($this->namedtag->getTag(self::TAG_COOK_TIME));
|
$nbt->setShort(self::TAG_COOK_TIME, $this->cookTime);
|
||||||
|
|
||||||
if($this->hasName()){
|
if($this->hasName()){
|
||||||
$nbt->setTag($this->namedtag->getTag("CustomName"));
|
$nbt->setTag($this->namedtag->getTag("CustomName"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user