mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-15 10:19:39 +00:00
Merge branch 'master' into api3/network
This commit is contained in:
commit
8114ceaf68
6
.github/ISSUE_TEMPLATE.md
vendored
6
.github/ISSUE_TEMPLATE.md
vendored
@ -1,8 +1,14 @@
|
||||
### Issue description
|
||||
<!--- use our forum https://forums.pmmp.io for questions -->
|
||||
<!--- Any issues requesting updates to new versions of MCPE will be treated as spam. We do not need issues to tell us that there is a new version available. -->
|
||||
<!---
|
||||
Write a short description about the issue
|
||||
|
||||
If you are reporting a regression or unexpected behaviour, please include the below information:
|
||||
Expected result: What were you expecting to happen?
|
||||
Actual result: What actually happened?
|
||||
-->
|
||||
|
||||
### Steps to reproduce the issue
|
||||
<!--- help us find the problem by adding steps to reproduce the issue -->
|
||||
1. ...
|
||||
|
@ -611,16 +611,14 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
}
|
||||
|
||||
public function sendCommandData(){
|
||||
$data = new \stdClass();
|
||||
$count = 0;
|
||||
$data = [];
|
||||
foreach($this->server->getCommandMap()->getCommands() as $command){
|
||||
if(($cmdData = $command->generateCustomCommandData($this)) !== null){
|
||||
++$count;
|
||||
$data->{$command->getName()}->versions[0] = $cmdData;
|
||||
if(count($cmdData = $command->generateCustomCommandData($this)) > 0){
|
||||
$data[$command->getName()]["versions"][0] = $cmdData;
|
||||
}
|
||||
}
|
||||
|
||||
if($count > 0){
|
||||
if(count($data) > 0){
|
||||
//TODO: structure checking
|
||||
$pk = new AvailableCommandsPacket();
|
||||
$pk->commands = json_encode($data);
|
||||
@ -2147,7 +2145,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
|
||||
if($this->canInteract($vector->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 6) and $this->level->useBreakOn($vector, $item, $this, true)){
|
||||
if($this->isSurvival()){
|
||||
if(!$item->deepEquals($oldItem) or $item->getCount() !== $oldItem->getCount()){
|
||||
if(!$item->equals($oldItem) or $item->getCount() !== $oldItem->getCount()){
|
||||
$this->inventory->setItemInHand($item);
|
||||
$this->inventory->sendHeldItem($this->hasSpawned);
|
||||
}
|
||||
@ -2418,14 +2416,14 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
if($this->level->useItemOn($blockVector, $item, $packet->face, $packet->fx, $packet->fy, $packet->fz, $this) === true){
|
||||
return true;
|
||||
}
|
||||
}elseif(!$this->inventory->getItemInHand()->deepEquals($packet->item)){
|
||||
}elseif(!$this->inventory->getItemInHand()->equals($packet->item)){
|
||||
$this->inventory->sendHeldItem($this);
|
||||
}else{
|
||||
$item = $this->inventory->getItemInHand();
|
||||
$oldItem = clone $item;
|
||||
//TODO: Implement adventure mode checks
|
||||
if($this->level->useItemOn($blockVector, $item, $packet->face, $packet->fx, $packet->fy, $packet->fz, $this)){
|
||||
if(!$item->deepEquals($oldItem) or $item->getCount() !== $oldItem->getCount()){
|
||||
if(!$item->equals($oldItem) or $item->getCount() !== $oldItem->getCount()){
|
||||
$this->inventory->setItemInHand($item);
|
||||
$this->inventory->sendHeldItem($this->hasSpawned);
|
||||
}
|
||||
@ -2452,7 +2450,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
|
||||
if($this->isCreative()){
|
||||
$item = $this->inventory->getItemInHand();
|
||||
}elseif(!$this->inventory->getItemInHand()->deepEquals($packet->item)){
|
||||
}elseif(!$this->inventory->getItemInHand()->equals($packet->item)){
|
||||
$this->inventory->sendHeldItem($this);
|
||||
return true;
|
||||
}else{
|
||||
@ -2868,7 +2866,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
break;
|
||||
}
|
||||
|
||||
if($transaction->getSourceItem()->deepEquals($transaction->getTargetItem()) and $transaction->getTargetItem()->getCount() === $transaction->getSourceItem()->getCount()){ //No changes!
|
||||
if($transaction->getSourceItem()->equals($transaction->getTargetItem()) and $transaction->getTargetItem()->getCount() === $transaction->getSourceItem()->getCount()){ //No changes!
|
||||
//No changes, just a local inventory update sent by the client
|
||||
return true;
|
||||
}
|
||||
@ -2947,7 +2945,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$item = $packet->input[$y * 3 + $x];
|
||||
$ingredient = $recipe->getIngredient($x, $y);
|
||||
if($item->getCount() > 0){
|
||||
if($ingredient === null or !$ingredient->deepEquals($item, !$ingredient->hasAnyDamageValue(), $ingredient->hasCompoundTag())){
|
||||
if($ingredient === null or !$ingredient->equals($item, !$ingredient->hasAnyDamageValue(), $ingredient->hasCompoundTag())){
|
||||
$canCraft = false;
|
||||
break;
|
||||
}
|
||||
@ -2963,7 +2961,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$item = clone $packet->input[$y * 3 + $x];
|
||||
|
||||
foreach($needed as $k => $n){
|
||||
if($n->deepEquals($item, !$n->hasAnyDamageValue(), $n->hasCompoundTag())){
|
||||
if($n->equals($item, !$n->hasAnyDamageValue(), $n->hasCompoundTag())){
|
||||
$remove = min($n->getCount(), $item->getCount());
|
||||
$n->setCount($n->getCount() - $remove);
|
||||
$item->setCount($item->getCount() - $remove);
|
||||
@ -2992,7 +2990,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
||||
$ingredients = $packet->input;
|
||||
$result = $packet->output[0];
|
||||
|
||||
if(!$canCraft or !$recipe->getResult()->deepEquals($result)){
|
||||
if(!$canCraft or !$recipe->getResult()->equals($result)){
|
||||
$this->server->getLogger()->debug("Unmatched recipe " . $recipe->getId() . " from player " . $this->getName() . ": expected " . $recipe->getResult() . ", got " . $result . ", using: " . implode(", ", $ingredients));
|
||||
$this->inventory->sendContents($this);
|
||||
return true;
|
||||
|
@ -1098,6 +1098,31 @@ class Server{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches all levels for the entity with the specified ID.
|
||||
* Useful for tracking entities across multiple worlds without needing strong references.
|
||||
*
|
||||
* @param int $entityId
|
||||
* @param Level|null $expectedLevel Level to look in first for the target
|
||||
*
|
||||
* @return Entity|null
|
||||
*/
|
||||
public function findEntity(int $entityId, Level $expectedLevel = null){
|
||||
$levels = $this->levels;
|
||||
if($expectedLevel !== null){
|
||||
array_unshift($levels, $expectedLevel);
|
||||
}
|
||||
|
||||
foreach($levels as $level){
|
||||
assert(!$level->isClosed());
|
||||
if(($entity = $level->getEntity($entityId)) instanceof Entity){
|
||||
return $entity;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $variable
|
||||
* @param string $defaultValue
|
||||
|
@ -32,12 +32,12 @@ use pocketmine\Server;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
abstract class Command{
|
||||
/** @var \stdClass */
|
||||
/** @var array */
|
||||
private static $defaultDataTemplate = null;
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
/** @var \stdClass */
|
||||
/** @var array */
|
||||
protected $commandData = null;
|
||||
|
||||
/** @var string */
|
||||
@ -87,11 +87,11 @@ abstract class Command{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an \stdClass containing command data
|
||||
* Returns an array containing command data
|
||||
*
|
||||
* @return \stdClass
|
||||
* @return array
|
||||
*/
|
||||
public function getDefaultCommandData() : \stdClass{
|
||||
public function getDefaultCommandData() : array{
|
||||
return $this->commandData;
|
||||
}
|
||||
|
||||
@ -101,25 +101,28 @@ abstract class Command{
|
||||
*
|
||||
* @param Player $player
|
||||
*
|
||||
* @return \stdClass|null
|
||||
* @return array
|
||||
*/
|
||||
public function generateCustomCommandData(Player $player){
|
||||
//TODO: fix command permission filtering on join
|
||||
/*if(!$this->testPermissionSilent($player)){
|
||||
return null;
|
||||
}*/
|
||||
$customData = clone $this->commandData;
|
||||
$customData->aliases = $this->getAliases();
|
||||
/*foreach($customData->overloads as &$overload){
|
||||
if(isset($overload->pocketminePermission) and !$player->hasPermission($overload->pocketminePermission)){
|
||||
unset($overload);
|
||||
$customData = $this->commandData;
|
||||
$customData["aliases"] = $this->getAliases();
|
||||
/*foreach($customData["overloads"] as $overloadName => $overload){
|
||||
if(isset($overload["pocketminePermission"]) and !$player->hasPermission($overload["pocketminePermission"])){
|
||||
unset($customData["overloads"][$overloadName]);
|
||||
}
|
||||
}*/
|
||||
return $customData;
|
||||
}
|
||||
|
||||
public function getOverloads(): \stdClass{
|
||||
return $this->commandData->overloads;
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getOverloads(): array{
|
||||
return $this->commandData["overloads"];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,7 +145,7 @@ abstract class Command{
|
||||
* @return string
|
||||
*/
|
||||
public function getPermission(){
|
||||
return $this->commandData->pocketminePermission ?? null;
|
||||
return $this->commandData["pocketminePermission"] ?? null;
|
||||
}
|
||||
|
||||
|
||||
@ -151,9 +154,9 @@ abstract class Command{
|
||||
*/
|
||||
public function setPermission($permission){
|
||||
if($permission !== null){
|
||||
$this->commandData->pocketminePermission = $permission;
|
||||
$this->commandData["pocketminePermission"] = $permission;
|
||||
}else{
|
||||
unset($this->commandData->pocketminePermission);
|
||||
unset($this->commandData["pocketminePermission"]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,7 +242,7 @@ abstract class Command{
|
||||
public function unregister(CommandMap $commandMap){
|
||||
if($this->allowChangesFrom($commandMap)){
|
||||
$this->commandMap = null;
|
||||
$this->activeAliases = $this->commandData->aliases;
|
||||
$this->activeAliases = $this->commandData["aliases"];
|
||||
$this->label = $this->nextLabel;
|
||||
|
||||
return true;
|
||||
@ -282,7 +285,7 @@ abstract class Command{
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(){
|
||||
return $this->commandData->description;
|
||||
return $this->commandData["description"];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -296,7 +299,7 @@ abstract class Command{
|
||||
* @param string[] $aliases
|
||||
*/
|
||||
public function setAliases(array $aliases){
|
||||
$this->commandData->aliases = $aliases;
|
||||
$this->commandData["aliases"] = $aliases;
|
||||
if(!$this->isRegistered()){
|
||||
$this->activeAliases = (array) $aliases;
|
||||
}
|
||||
@ -306,7 +309,7 @@ abstract class Command{
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription($description){
|
||||
$this->commandData->description = $description;
|
||||
$this->commandData["description"] = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -323,11 +326,14 @@ abstract class Command{
|
||||
$this->usageMessage = $usage;
|
||||
}
|
||||
|
||||
public static final function generateDefaultData() : \stdClass{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static final function generateDefaultData() : array{
|
||||
if(self::$defaultDataTemplate === null){
|
||||
self::$defaultDataTemplate = json_decode(file_get_contents(Server::getInstance()->getFilePath() . "src/pocketmine/resources/command_default.json"));
|
||||
self::$defaultDataTemplate = json_decode(file_get_contents(Server::getInstance()->getFilePath() . "src/pocketmine/resources/command_default.json"), true);
|
||||
}
|
||||
return clone self::$defaultDataTemplate;
|
||||
return self::$defaultDataTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -177,15 +177,35 @@ class SimpleCommandMap implements CommandMap{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function dispatch(CommandSender $sender, $commandLine){
|
||||
$args = explode(" ", $commandLine);
|
||||
/**
|
||||
* Returns a command to match the specified command line, or null if no matching command was found.
|
||||
* This method is intended to provide capability for handling commands with spaces in their name.
|
||||
* The referenced parameters will be modified accordingly depending on the resulting matched command.
|
||||
*
|
||||
* @param string &$commandName
|
||||
* @param string[] &$args
|
||||
*
|
||||
* @return Command|null
|
||||
*/
|
||||
public function matchCommand(string &$commandName, array &$args){
|
||||
$count = max(count($args), 255);
|
||||
|
||||
if(count($args) === 0){
|
||||
return false;
|
||||
for($i = 0; $i < $count; ++$i){
|
||||
$commandName .= array_shift($args);
|
||||
if(($command = $this->getCommand($commandName)) instanceof Command){
|
||||
return $command;
|
||||
}
|
||||
|
||||
$commandName .= " ";
|
||||
}
|
||||
|
||||
$sentCommandLabel = strtolower(array_shift($args));
|
||||
$target = $this->getCommand($sentCommandLabel);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function dispatch(CommandSender $sender, $commandLine){
|
||||
$args = explode(" ", $commandLine);
|
||||
$sentCommandLabel = "";
|
||||
$target = $this->matchCommand($sentCommandLabel, $args);
|
||||
|
||||
if($target === null){
|
||||
return false;
|
||||
@ -213,11 +233,7 @@ class SimpleCommandMap implements CommandMap{
|
||||
}
|
||||
|
||||
public function getCommand($name){
|
||||
if(isset($this->knownCommands[$name])){
|
||||
return $this->knownCommands[$name];
|
||||
}
|
||||
|
||||
return null;
|
||||
return $this->knownCommands[$name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -235,7 +251,7 @@ class SimpleCommandMap implements CommandMap{
|
||||
$values = $this->server->getCommandAliases();
|
||||
|
||||
foreach($values as $alias => $commandStrings){
|
||||
if(strpos($alias, ":") !== false or strpos($alias, " ") !== false){
|
||||
if(strpos($alias, ":") !== false){
|
||||
$this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.command.alias.illegal", [$alias]));
|
||||
continue;
|
||||
}
|
||||
@ -243,20 +259,33 @@ class SimpleCommandMap implements CommandMap{
|
||||
$targets = [];
|
||||
|
||||
$bad = "";
|
||||
$recursive = "";
|
||||
foreach($commandStrings as $commandString){
|
||||
$args = explode(" ", $commandString);
|
||||
$command = $this->getCommand($args[0]);
|
||||
$commandName = "";
|
||||
$command = $this->matchCommand($commandName, $args);
|
||||
|
||||
|
||||
if($command === null){
|
||||
if(strlen($bad) > 0){
|
||||
$bad .= ", ";
|
||||
}
|
||||
$bad .= $commandString;
|
||||
}elseif($commandName === $alias){
|
||||
if($recursive !== ""){
|
||||
$recursive .= ", ";
|
||||
}
|
||||
$recursive .= $commandString;
|
||||
}else{
|
||||
$targets[] = $commandString;
|
||||
}
|
||||
}
|
||||
|
||||
if($recursive !== ""){
|
||||
$this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.command.alias.recursive", [$alias, $recursive]));
|
||||
continue;
|
||||
}
|
||||
|
||||
if(strlen($bad) > 0){
|
||||
$this->server->getLogger()->warning($this->server->getLanguage()->translateString("pocketmine.command.alias.notFound", [$alias, $bad]));
|
||||
continue;
|
||||
|
@ -1652,6 +1652,7 @@ abstract class Entity extends Location implements Metadatable{
|
||||
}
|
||||
|
||||
$this->namedtag = null;
|
||||
$this->lastDamageCause = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,13 +123,15 @@ abstract class Living extends Entity implements Damageable{
|
||||
$e = $source->getChild();
|
||||
}
|
||||
|
||||
if($e->isOnFire() > 0){
|
||||
$this->setOnFire(2 * $this->server->getDifficulty());
|
||||
}
|
||||
if($e !== null){
|
||||
if($e->isOnFire() > 0){
|
||||
$this->setOnFire(2 * $this->server->getDifficulty());
|
||||
}
|
||||
|
||||
$deltaX = $this->x - $e->x;
|
||||
$deltaZ = $this->z - $e->z;
|
||||
$this->knockBack($e, $damage, $deltaX, $deltaZ, $source->getKnockBack());
|
||||
$deltaX = $this->x - $e->x;
|
||||
$deltaZ = $this->z - $e->z;
|
||||
$this->knockBack($e, $damage, $deltaX, $deltaZ, $source->getKnockBack());
|
||||
}
|
||||
}
|
||||
|
||||
$pk = new EntityEventPacket();
|
||||
|
@ -60,7 +60,9 @@ class Squid extends WaterAnimal implements Ageable{
|
||||
if($source instanceof EntityDamageByEntityEvent){
|
||||
$this->swimSpeed = mt_rand(150, 350) / 2000;
|
||||
$e = $source->getDamager();
|
||||
$this->swimDirection = (new Vector3($this->x - $e->x, $this->y - $e->y, $this->z - $e->z))->normalize();
|
||||
if($e !== null){
|
||||
$this->swimDirection = (new Vector3($this->x - $e->x, $this->y - $e->y, $this->z - $e->z))->normalize();
|
||||
}
|
||||
|
||||
$pk = new EntityEventPacket();
|
||||
$pk->eid = $this->getId();
|
||||
|
@ -24,6 +24,9 @@ namespace pocketmine\event\entity;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\entity\Entity;
|
||||
|
||||
/**
|
||||
* Called when an entity takes damage from a block.
|
||||
*/
|
||||
class EntityDamageByBlockEvent extends EntityDamageEvent{
|
||||
|
||||
/** @var Block */
|
||||
|
@ -23,10 +23,13 @@ namespace pocketmine\event\entity;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
|
||||
/**
|
||||
* Called when an entity takes damage from an entity sourced from another entity, for example being hit by a snowball thrown by a Player.
|
||||
*/
|
||||
class EntityDamageByChildEntityEvent extends EntityDamageByEntityEvent{
|
||||
|
||||
/** @var Entity */
|
||||
private $childEntity;
|
||||
/** @var int */
|
||||
private $childEntityEid;
|
||||
|
||||
|
||||
/**
|
||||
@ -37,15 +40,17 @@ class EntityDamageByChildEntityEvent extends EntityDamageByEntityEvent{
|
||||
* @param int|int[] $damage
|
||||
*/
|
||||
public function __construct(Entity $damager, Entity $childEntity, Entity $entity, $cause, $damage){
|
||||
$this->childEntity = $childEntity;
|
||||
$this->childEntityEid = $childEntity->getId();
|
||||
parent::__construct($damager, $entity, $cause, $damage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Entity
|
||||
* Returns the entity which caused the damage, or null if the entity has been killed or closed.
|
||||
*
|
||||
* @return Entity|null
|
||||
*/
|
||||
public function getChild(){
|
||||
return $this->childEntity;
|
||||
return $this->getEntity()->getLevel()->getServer()->findEntity($this->childEntityEid, $this->getEntity()->getLevel());
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,10 +24,13 @@ namespace pocketmine\event\entity;
|
||||
use pocketmine\entity\Effect;
|
||||
use pocketmine\entity\Entity;
|
||||
|
||||
/**
|
||||
* Called when an entity takes damage from another entity.
|
||||
*/
|
||||
class EntityDamageByEntityEvent extends EntityDamageEvent{
|
||||
|
||||
/** @var Entity */
|
||||
private $damager;
|
||||
/** @var int */
|
||||
private $damagerEid;
|
||||
/** @var float */
|
||||
private $knockBack;
|
||||
|
||||
@ -39,7 +42,7 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{
|
||||
* @param float $knockBack
|
||||
*/
|
||||
public function __construct(Entity $damager, Entity $entity, $cause, $damage, $knockBack = 0.4){
|
||||
$this->damager = $damager;
|
||||
$this->damagerEid = $damager->getId();
|
||||
$this->knockBack = $knockBack;
|
||||
parent::__construct($entity, $cause, $damage);
|
||||
$this->addAttackerModifiers($damager);
|
||||
@ -56,10 +59,12 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Entity
|
||||
* Returns the attacking entity, or null if the attacker has been killed or closed.
|
||||
*
|
||||
* @return Entity|null
|
||||
*/
|
||||
public function getDamager(){
|
||||
return $this->damager;
|
||||
return $this->getEntity()->getLevel()->getServer()->findEntity($this->damagerEid, $this->getEntity()->getLevel());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,9 @@ use pocketmine\entity\Effect;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\event\Cancellable;
|
||||
|
||||
/**
|
||||
* Called when an entity takes damage.
|
||||
*/
|
||||
class EntityDamageEvent extends EntityEvent implements Cancellable{
|
||||
public static $handlerList = null;
|
||||
|
||||
|
@ -94,8 +94,10 @@ class PlayerInventory extends BaseInventory{
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal This method is intended for use in network interaction with clients only.
|
||||
* @deprecated Do not change hotbar slot mapping with plugins, this will cause myriad client-sided bugs, especially with desktop GUI clients.
|
||||
* Links a hotbar slot to the specified slot in the main inventory. -1 links to no slot and will clear the hotbar slot.
|
||||
* This method is intended for use in network interaction with clients only.
|
||||
*
|
||||
* NOTE: Do not change hotbar slot mapping with plugins, this will cause myriad client-sided bugs, especially with desktop GUI clients.
|
||||
*
|
||||
* @param int $hotbarSlot
|
||||
* @param int $inventorySlot
|
||||
|
@ -98,7 +98,7 @@ class SimpleTransactionGroup implements TransactionGroup{
|
||||
}
|
||||
$checkSourceItem = $ts->getInventory()->getItem($ts->getSlot());
|
||||
$sourceItem = $ts->getSourceItem();
|
||||
if(!$checkSourceItem->deepEquals($sourceItem) or $sourceItem->getCount() !== $checkSourceItem->getCount()){
|
||||
if(!$checkSourceItem->equals($sourceItem) or $sourceItem->getCount() !== $checkSourceItem->getCount()){
|
||||
return false;
|
||||
}
|
||||
if($sourceItem->getId() !== Item::AIR){
|
||||
@ -108,7 +108,7 @@ class SimpleTransactionGroup implements TransactionGroup{
|
||||
|
||||
foreach($needItems as $i => $needItem){
|
||||
foreach($haveItems as $j => $haveItem){
|
||||
if($needItem->deepEquals($haveItem)){
|
||||
if($needItem->equals($haveItem)){
|
||||
$amount = min($needItem->getCount(), $haveItem->getCount());
|
||||
$needItem->setCount($needItem->getCount() - $amount);
|
||||
$haveItem->setCount($haveItem->getCount() - $amount);
|
||||
|
@ -351,6 +351,12 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param int $count
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct(int $id, int $meta = 0, int $count = 1, string $name = "Unknown"){
|
||||
$this->id = $id & 0xffff;
|
||||
$this->meta = $meta !== -1 ? $meta & 0xffff : -1;
|
||||
@ -362,6 +368,13 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Item's NBT
|
||||
*
|
||||
* @param CompoundTag|string $tags
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCompoundTag($tags){
|
||||
if($tags instanceof CompoundTag){
|
||||
$this->setNamedTag($tags);
|
||||
@ -374,16 +387,24 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the serialized NBT of the Item
|
||||
* @return string
|
||||
*/
|
||||
public function getCompoundTag() : string{
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this Item has a non-empty NBT.
|
||||
* @return bool
|
||||
*/
|
||||
public function hasCompoundTag() : bool{
|
||||
return $this->tags !== "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasCustomBlockData() : bool{
|
||||
if(!$this->hasCompoundTag()){
|
||||
return false;
|
||||
@ -411,6 +432,11 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CompoundTag $compound
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCustomBlockData(CompoundTag $compound){
|
||||
$tags = clone $compound;
|
||||
$tags->setName("BlockEntityTag");
|
||||
@ -427,6 +453,9 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CompoundTag|null
|
||||
*/
|
||||
public function getCustomBlockData(){
|
||||
if(!$this->hasCompoundTag()){
|
||||
return null;
|
||||
@ -440,6 +469,9 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasEnchantments() : bool{
|
||||
if(!$this->hasCompoundTag()){
|
||||
return false;
|
||||
@ -457,7 +489,7 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param int $id
|
||||
*
|
||||
* @return Enchantment|null
|
||||
*/
|
||||
@ -534,6 +566,9 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return $enchantments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasCustomName() : bool{
|
||||
if(!$this->hasCompoundTag()){
|
||||
return false;
|
||||
@ -550,6 +585,9 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCustomName() : string{
|
||||
if(!$this->hasCompoundTag()){
|
||||
return "";
|
||||
@ -566,6 +604,11 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCustomName(string $name){
|
||||
if($name === ""){
|
||||
$this->clearCustomName();
|
||||
@ -590,6 +633,9 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function clearCustomName(){
|
||||
if(!$this->hasCompoundTag()){
|
||||
return $this;
|
||||
@ -621,6 +667,10 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a tree of Tag objects representing the Item's NBT
|
||||
* @return null|CompoundTag
|
||||
*/
|
||||
public function getNamedTag(){
|
||||
if(!$this->hasCompoundTag()){
|
||||
return null;
|
||||
@ -630,6 +680,12 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return $this->cachedNBT = self::parseCompoundTag($this->tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Item's NBT from the supplied CompoundTag object.
|
||||
* @param CompoundTag $tag
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setNamedTag(CompoundTag $tag){
|
||||
if($tag->getCount() === 0){
|
||||
return $this->clearNamedTag();
|
||||
@ -641,37 +697,73 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the Item's NBT.
|
||||
* @return Item
|
||||
*/
|
||||
public function clearNamedTag(){
|
||||
return $this->setCompoundTag("");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCount() : int{
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $count
|
||||
*/
|
||||
public function setCount(int $count){
|
||||
$this->count = $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the item, or the custom name if it is set.
|
||||
* @return string
|
||||
*/
|
||||
final public function getName() : string{
|
||||
return $this->hasCustomName() ? $this->getCustomName() : $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
final public function canBePlaced() : bool{
|
||||
return $this->block !== null and $this->block->canBePlaced();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an entity can eat or drink this item.
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeConsumed() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this item can be consumed by the supplied Entity.
|
||||
* @param Entity $entity
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeConsumedBy(Entity $entity) : bool{
|
||||
return $this->canBeConsumed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the item is consumed by an Entity.
|
||||
* @param Entity $entity
|
||||
*/
|
||||
public function onConsume(Entity $entity){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block corresponding to this Item.
|
||||
* @return Block
|
||||
*/
|
||||
public function getBlock() : Block{
|
||||
if($this->block instanceof Block){
|
||||
return clone $this->block;
|
||||
@ -680,22 +772,41 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
final public function getId() : int{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
final public function getDamage() : int{
|
||||
return $this->meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $meta
|
||||
*/
|
||||
public function setDamage(int $meta){
|
||||
$this->meta = $meta !== -1 ? $meta & 0xFFFF : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this item can match any item with an equivalent ID with any meta value.
|
||||
* Used in crafting recipes which accept multiple variants of the same item, for example crafting tables recipes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAnyDamageValue() : bool{
|
||||
return $this->meta === -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the highest amount of this item which will fit into one inventory slot.
|
||||
* @return int
|
||||
*/
|
||||
public function getMaxStackSize(){
|
||||
return 64;
|
||||
}
|
||||
@ -762,28 +873,75 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player uses this item on a block.
|
||||
*
|
||||
* @param Level $level
|
||||
* @param Player $player
|
||||
* @param Block $block
|
||||
* @param Block $target
|
||||
* @param int $face
|
||||
* @param float $fx
|
||||
* @param float $fy
|
||||
* @param float $fz
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares an Item to this Item and check if they match.
|
||||
*
|
||||
* @param Item $item
|
||||
* @param bool $checkDamage Whether to verify that the damage values match.
|
||||
* @param bool $checkCompound Whether to verify that the items' NBT match.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public final function equals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{
|
||||
return $this->id === $item->getId() and ($checkDamage === false or $this->getDamage() === $item->getDamage()) and ($checkCompound === false or $this->getCompoundTag() === $item->getCompoundTag());
|
||||
}
|
||||
|
||||
public final function deepEquals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{
|
||||
if($this->equals($item, $checkDamage, $checkCompound)){
|
||||
return true;
|
||||
}elseif($item->hasCompoundTag() and $this->hasCompoundTag()){
|
||||
return NBT::matchTree($this->getNamedTag(), $item->getNamedTag());
|
||||
if($this->id === $item->getId() and ($checkDamage === false or $this->getDamage() === $item->getDamage())){
|
||||
if($checkCompound){
|
||||
if($item->getCompoundTag() === $this->getCompoundTag()){
|
||||
return true;
|
||||
}elseif($this->hasCompoundTag() and $item->hasCompoundTag()){
|
||||
//Serialized NBT didn't match, check the cached object tree.
|
||||
return NBT::matchTree($this->getNamedTag(), $item->getNamedTag());
|
||||
}
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
final public function __toString() : string{
|
||||
return "Item " . $this->name . " (" . $this->id . ":" . ($this->meta === null ? "?" : $this->meta) . ")x" . $this->count . ($this->hasCompoundTag() ? " tags:0x" . bin2hex($this->getCompoundTag()) : "");
|
||||
/**
|
||||
* @deprecated Use {@link Item#equals} instead, this method will be removed in the future.
|
||||
*
|
||||
* @param Item $item
|
||||
* @param bool $checkDamage
|
||||
* @param bool $checkCompound
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public final function deepEquals(Item $item, bool $checkDamage = true, bool $checkCompound = true) : bool{
|
||||
return $this->equals($item, $checkDamage, $checkCompound);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
final public function __toString() : string{
|
||||
return "Item " . $this->name . " (" . $this->id . ":" . ($this->hasAnyDamageValue() ? "?" : $this->meta) . ")x" . $this->count . ($this->hasCompoundTag() ? " tags:0x" . bin2hex($this->getCompoundTag()) : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of item stack properties that can be serialized to json.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final public function jsonSerialize(){
|
||||
return [
|
||||
"id" => $this->id,
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 8d56e216be03710208800ba31aa3b63612742623
|
||||
Subproject commit b30ca5e3bdb65c446e22bf777d1dcb04d78b6f7d
|
@ -40,7 +40,7 @@ class FlowerPot extends Spawnable{
|
||||
parent::__construct($level, $nbt);
|
||||
}
|
||||
|
||||
public function canAddItem(Item $item): bool{
|
||||
public function canAddItem(Item $item) : bool{
|
||||
if(!$this->isEmpty()){
|
||||
return false;
|
||||
}
|
||||
@ -63,7 +63,7 @@ class FlowerPot extends Spawnable{
|
||||
}
|
||||
}
|
||||
|
||||
public function getItem(): Item{
|
||||
public function getItem() : Item{
|
||||
return Item::get((int) ($this->namedtag["item"] ?? 0), (int) ($this->namedtag["mData"] ?? 0), 1);
|
||||
}
|
||||
|
||||
@ -77,11 +77,11 @@ class FlowerPot extends Spawnable{
|
||||
$this->setItem(Item::get(Item::AIR));
|
||||
}
|
||||
|
||||
public function isEmpty(): bool{
|
||||
public function isEmpty() : bool{
|
||||
return $this->getItem()->getId() === Item::AIR;
|
||||
}
|
||||
|
||||
public function getSpawnCompound(): CompoundTag{
|
||||
public function getSpawnCompound() : CompoundTag{
|
||||
return new CompoundTag("", [
|
||||
new StringTag("id", Tile::FLOWER_POT),
|
||||
new IntTag("x", (int) $this->x),
|
||||
|
@ -173,11 +173,14 @@ abstract class Tile extends Position{
|
||||
unset($this->level->updateTiles[$this->id]);
|
||||
if($this->chunk instanceof Chunk){
|
||||
$this->chunk->removeTile($this);
|
||||
$this->chunk = null;
|
||||
}
|
||||
if(($level = $this->getLevel()) instanceof Level){
|
||||
$level->removeTile($this);
|
||||
$this->setLevel(null);
|
||||
}
|
||||
$this->level = null;
|
||||
|
||||
$this->namedtag = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,57 +31,60 @@ class AutoUpdater{
|
||||
|
||||
/** @var Server */
|
||||
protected $server;
|
||||
/** @var string */
|
||||
protected $endpoint;
|
||||
/** @var bool */
|
||||
protected $hasUpdate = false;
|
||||
/** @var array|null */
|
||||
protected $updateInfo = null;
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param string $endpoint
|
||||
*/
|
||||
public function __construct(Server $server, $endpoint){
|
||||
$this->server = $server;
|
||||
$this->endpoint = "http://$endpoint/api/";
|
||||
|
||||
if($server->getProperty("auto-updater.enabled", true)){
|
||||
$this->check();
|
||||
if($this->hasUpdate()){
|
||||
if($this->server->getProperty("auto-updater.on-update.warn-console", true)){
|
||||
$this->showConsoleUpdate();
|
||||
}
|
||||
}elseif($this->server->getProperty("auto-updater.preferred-channel", true)){
|
||||
$version = new VersionString();
|
||||
if(!$version->isDev() and $this->getChannel() !== "stable"){
|
||||
$this->showChannelSuggestionStable();
|
||||
}elseif($version->isDev() and $this->getChannel() === "stable"){
|
||||
$this->showChannelSuggestionBeta();
|
||||
}
|
||||
$this->doCheck();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used at the end of the update checking task
|
||||
*
|
||||
* @param array $updateInfo
|
||||
*/
|
||||
public function checkUpdateCallback(array $updateInfo){
|
||||
$this->updateInfo = $updateInfo;
|
||||
$this->checkUpdate();
|
||||
if($this->hasUpdate()){
|
||||
if($this->server->getProperty("auto-updater.on-update.warn-console", true)){
|
||||
$this->showConsoleUpdate();
|
||||
}
|
||||
}elseif($this->server->getProperty("auto-updater.preferred-channel", true)){
|
||||
$version = new VersionString();
|
||||
if(!$version->isDev() and $this->getChannel() !== "stable"){
|
||||
$this->showChannelSuggestionStable();
|
||||
}elseif($version->isDev() and $this->getChannel() === "stable"){
|
||||
$this->showChannelSuggestionBeta();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function check(){
|
||||
$response = Utils::getURL($this->endpoint . "?channel=" . $this->getChannel(), 4);
|
||||
$response = json_decode($response, true);
|
||||
if(!is_array($response)){
|
||||
return;
|
||||
}
|
||||
|
||||
$this->updateInfo = [
|
||||
"version" => $response["version"],
|
||||
"api_version" => $response["api_version"],
|
||||
"build" => $response["build"],
|
||||
"date" => $response["date"],
|
||||
"details_url" => $response["details_url"] ?? null,
|
||||
"download_url" => $response["download_url"]
|
||||
];
|
||||
|
||||
$this->checkUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there is an update available.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUpdate(){
|
||||
return $this->hasUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts a warning to the console to tell the user there is an update available
|
||||
*/
|
||||
public function showConsoleUpdate(){
|
||||
$logger = $this->server->getLogger();
|
||||
$newVersion = new VersionString($this->updateInfo["version"]);
|
||||
@ -94,6 +97,10 @@ class AutoUpdater{
|
||||
$logger->warning("----- -------------------------- -----");
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a warning to a player to tell them there is an update available
|
||||
* @param Player $player
|
||||
*/
|
||||
public function showPlayerUpdate(Player $player){
|
||||
$player->sendMessage(TextFormat::DARK_PURPLE . "The version of PocketMine-MP that this server is running is out of date. Please consider updating to the latest version.");
|
||||
$player->sendMessage(TextFormat::DARK_PURPLE . "Check the console for more details.");
|
||||
@ -115,14 +122,25 @@ class AutoUpdater{
|
||||
$logger->info("----- -------------------------- -----");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last retrieved update data.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getUpdateInfo(){
|
||||
return $this->updateInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules an AsyncTask to check for an update.
|
||||
*/
|
||||
public function doCheck(){
|
||||
$this->check();
|
||||
$this->server->getScheduler()->scheduleAsyncTask(new UpdateCheckTask($this->endpoint, $this->getChannel()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the update information against the current server version to decide if there's an update
|
||||
*/
|
||||
protected function checkUpdate(){
|
||||
if($this->updateInfo === null){
|
||||
return;
|
||||
@ -138,6 +156,11 @@ class AutoUpdater{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the channel used for update checking (stable, beta, dev)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getChannel(){
|
||||
$channel = strtolower($this->server->getProperty("auto-updater.preferred-channel", "stable"));
|
||||
if($channel !== "stable" and $channel !== "beta" and $channel !== "development"){
|
||||
@ -146,4 +169,13 @@ class AutoUpdater{
|
||||
|
||||
return $channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the host used for update checks.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEndpoint() : string{
|
||||
return $this->endpoint;
|
||||
}
|
||||
}
|
82
src/pocketmine/updater/UpdateCheckTask.php
Normal file
82
src/pocketmine/updater/UpdateCheckTask.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
namespace pocketmine\updater;
|
||||
|
||||
|
||||
use pocketmine\scheduler\AsyncTask;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Utils;
|
||||
|
||||
class UpdateCheckTask extends AsyncTask{
|
||||
|
||||
/** @var string */
|
||||
private $endpoint;
|
||||
/** @var string */
|
||||
private $channel;
|
||||
/** @var string */
|
||||
private $error;
|
||||
|
||||
public function __construct(string $endpoint, string $channel){
|
||||
$this->endpoint = $endpoint;
|
||||
$this->channel = $channel;
|
||||
}
|
||||
|
||||
public function onRun(){
|
||||
$this->error = "";
|
||||
$response = Utils::getURL($this->endpoint . "?channel=" . $this->channel, 4, [], $this->error);
|
||||
if($this->error !== ""){
|
||||
return;
|
||||
}else{
|
||||
$response = json_decode($response, true);
|
||||
if(is_array($response)){
|
||||
$this->setResult(
|
||||
[
|
||||
"version" => $response["version"],
|
||||
"api_version" => $response["api_version"],
|
||||
"build" => $response["build"],
|
||||
"date" => $response["date"],
|
||||
"details_url" => $response["details_url"] ?? null,
|
||||
"download_url" => $response["download_url"]
|
||||
],
|
||||
true
|
||||
);
|
||||
}else{
|
||||
$this->error = "Invalid response data";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function onCompletion(Server $server){
|
||||
if($this->error !== ""){
|
||||
$server->getLogger()->debug("[AutoUpdater] Async update check failed due to \"$this->error\"");
|
||||
}else{
|
||||
$updateInfo = $this->getResult();
|
||||
if(is_array($updateInfo)){
|
||||
$server->getUpdater()->checkUpdateCallback($updateInfo);
|
||||
}else{
|
||||
$server->getLogger()->debug("[AutoUpdater] Update info error");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -348,14 +348,16 @@ class Utils{
|
||||
|
||||
/**
|
||||
* GETs an URL using cURL
|
||||
* NOTE: This is a blocking operation and can take a significant amount of time. It is inadvisable to use this method on the main thread.
|
||||
*
|
||||
* @param $page
|
||||
* @param int $timeout default 10
|
||||
* @param array $extraHeaders
|
||||
* @param $page
|
||||
* @param int $timeout default 10
|
||||
* @param array $extraHeaders
|
||||
* @param string &$err Will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation.
|
||||
*
|
||||
* @return bool|mixed
|
||||
* @return bool|mixed false if an error occurred, mixed data if successful.
|
||||
*/
|
||||
public static function getURL($page, $timeout = 10, array $extraHeaders = []){
|
||||
public static function getURL($page, $timeout = 10, array $extraHeaders = [], &$err = null){
|
||||
if(Utils::$online === false){
|
||||
return false;
|
||||
}
|
||||
@ -372,6 +374,7 @@ class Utils{
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, (int) $timeout);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, (int) $timeout);
|
||||
$ret = curl_exec($ch);
|
||||
$err = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $ret;
|
||||
@ -379,15 +382,17 @@ class Utils{
|
||||
|
||||
/**
|
||||
* POSTs data to an URL
|
||||
* NOTE: This is a blocking operation and can take a significant amount of time. It is inadvisable to use this method on the main thread.
|
||||
*
|
||||
* @param $page
|
||||
* @param array|string $args
|
||||
* @param int $timeout
|
||||
* @param array $extraHeaders
|
||||
* @param string &$err Will be set to the output of curl_error(). Use this to retrieve errors that occured during the operation.
|
||||
*
|
||||
* @return bool|mixed
|
||||
* @return bool|mixed false if an error occurred, mixed data if successful.
|
||||
*/
|
||||
public static function postURL($page, $args, $timeout = 10, array $extraHeaders = []){
|
||||
public static function postURL($page, $args, $timeout = 10, array $extraHeaders = [], &$err = null){
|
||||
if(Utils::$online === false){
|
||||
return false;
|
||||
}
|
||||
@ -406,6 +411,7 @@ class Utils{
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, (int) $timeout);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, (int) $timeout);
|
||||
$ret = curl_exec($ch);
|
||||
$err = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $ret;
|
||||
|
Loading…
x
Reference in New Issue
Block a user