mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-11 03:58:06 +00:00
Compare commits
9 Commits
Alpha_1.4d
...
Alpha_1.4d
Author | SHA1 | Date | |
---|---|---|---|
582c165479 | |||
5fb205493a | |||
e346d245e2 | |||
4fece32ca8 | |||
0b79d74a2f | |||
b83c6fbfa3 | |||
dda9c598f1 | |||
8769d2bcd1 | |||
3b7ece3363 |
@ -564,7 +564,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
Level::getXZ($index, $X, $Z);
|
||||
|
||||
foreach($this->getLevel()->getChunkEntities($X, $Z) as $entity){
|
||||
if($entity !== $this){
|
||||
if($entity !== $this and !$entity->closed and !$entity->dead){
|
||||
$entity->spawnTo($this);
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ namespace pocketmine {
|
||||
use raklib\RakLib;
|
||||
|
||||
const VERSION = "Alpha_1.4dev";
|
||||
const API_VERSION = "1.4.1";
|
||||
const API_VERSION = "1.5.0";
|
||||
const CODENAME = "絶好(Zekkou)ケーキ(Cake)";
|
||||
const MINECRAFT_VERSION = "v0.9.5 alpha";
|
||||
|
||||
|
@ -290,14 +290,14 @@ class Server{
|
||||
* @return string
|
||||
*/
|
||||
public function getIp(){
|
||||
return $this->getConfigString("server-ip", "");
|
||||
return $this->getConfigString("server-ip", "0.0.0.0");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getServerName(){
|
||||
return $this->getConfigString("server-name", "Unknown server");
|
||||
return $this->getConfigString("motd", "Unknown server");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1584,7 +1584,7 @@ class Server{
|
||||
Generator::addGenerator(Normal::class, "default");
|
||||
|
||||
//Temporal workaround, pthreads static property nullification test
|
||||
if(PluginManager::$pluginParentTimer === null){
|
||||
if(PluginManager::$pluginParentTimer === null or Timings::$serverTickTimer === null){
|
||||
$this->getLogger()->emergency("You are using an invalid pthreads version. Please update your binaries.");
|
||||
kill(getmypid());
|
||||
return;
|
||||
|
@ -167,7 +167,8 @@ abstract class Block extends Position implements Metadatable{
|
||||
const MELON_BLOCK = 103;
|
||||
const PUMPKIN_STEM = 104;
|
||||
const MELON_STEM = 105;
|
||||
|
||||
const VINE = 106;
|
||||
const VINES = 106;
|
||||
const FENCE_GATE = 107;
|
||||
const BRICK_STAIRS = 108;
|
||||
const STONE_BRICK_STAIRS = 109;
|
||||
@ -345,7 +346,7 @@ abstract class Block extends Position implements Metadatable{
|
||||
[Item::SNOW_LAYER, 0],
|
||||
[Item::GLASS, 0],
|
||||
[Item::GLOWSTONE_BLOCK, 0],
|
||||
//TODO: Vines
|
||||
[Item::VINES, 0],
|
||||
[Item::NETHER_REACTOR, 0],
|
||||
[Item::LADDER, 0],
|
||||
[Item::SPONGE, 0],
|
||||
@ -621,7 +622,7 @@ abstract class Block extends Position implements Metadatable{
|
||||
self::MELON_BLOCK => Melon::class,
|
||||
self::PUMPKIN_STEM => PumpkinStem::class,
|
||||
self::MELON_STEM => MelonStem::class,
|
||||
|
||||
self::VINE => Vine::class,
|
||||
self::FENCE_GATE => FenceGate::class,
|
||||
self::BRICK_STAIRS => BrickStairs::class,
|
||||
self::STONE_BRICK_STAIRS => StoneBrickStairs::class,
|
||||
@ -686,7 +687,10 @@ abstract class Block extends Position implements Metadatable{
|
||||
}
|
||||
|
||||
if($pos instanceof Position){
|
||||
$block->position($pos);
|
||||
$block->x = $pos->x;
|
||||
$block->y = $pos->y;
|
||||
$block->z = $pos->z;
|
||||
$block->level = $pos->level;
|
||||
}
|
||||
|
||||
return $block;
|
||||
|
@ -51,7 +51,6 @@ abstract class Fallable extends Solid{
|
||||
new Double("", $this->y + 0.5),
|
||||
new Double("", $this->z + 0.5)
|
||||
]),
|
||||
//TODO: add random motion with physics
|
||||
"Motion" => new Enum("Motion", [
|
||||
new Double("", 0),
|
||||
new Double("", 0),
|
||||
|
@ -21,8 +21,16 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\PrimedTNT;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Explosion;
|
||||
use pocketmine\nbt\tag\Byte;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
use pocketmine\nbt\tag\Double;
|
||||
use pocketmine\nbt\tag\Enum;
|
||||
use pocketmine\nbt\tag\Float;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\Random;
|
||||
|
||||
class TNT extends Solid{
|
||||
public function __construct(){
|
||||
@ -33,9 +41,8 @@ class TNT extends Solid{
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getID() === Item::FLINT_STEEL){
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
$item->useOn($this);
|
||||
}
|
||||
$item->useOn($this);
|
||||
|
||||
$data = [
|
||||
"x" => $this->x + 0.5,
|
||||
"y" => $this->y + 0.5,
|
||||
@ -44,9 +51,27 @@ class TNT extends Solid{
|
||||
"fuse" => 20 * 4, //4 seconds
|
||||
];
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
//TODO
|
||||
//$e = Server::getInstance()->api->entity->add($this->level, ENTITY_OBJECT, OBJECT_PRIMEDTNT, $data);
|
||||
//$e->spawnToAll();
|
||||
|
||||
$mot = (new Random())->nextSignedFloat() * M_PI * 2;
|
||||
$tnt = new PrimedTNT($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [
|
||||
"Pos" => new Enum("Pos", [
|
||||
new Double("", $this->x + 0.5),
|
||||
new Double("", $this->y + 0.5),
|
||||
new Double("", $this->z + 0.5)
|
||||
]),
|
||||
"Motion" => new Enum("Motion", [
|
||||
new Double("", -sin($mot) * 0.02),
|
||||
new Double("", 0.2),
|
||||
new Double("", -cos($mot) * 0.02)
|
||||
]),
|
||||
"Rotation" => new Enum("Rotation", [
|
||||
new Float("", 0),
|
||||
new Float("", 0)
|
||||
]),
|
||||
"Fuse" => new Byte("Fuse", 80)
|
||||
]));
|
||||
|
||||
$tnt->spawnToAll();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
168
src/pocketmine/block/Vine.php
Normal file
168
src/pocketmine/block/Vine.php
Normal file
@ -0,0 +1,168 @@
|
||||
<?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\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\entity\Entity;
|
||||
|
||||
class Vine extends Transparent{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::VINE, $meta, "Vines");
|
||||
$this->isSolid = false;
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 1;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
$entity->fallDistance = 0;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
$f1 = 1;
|
||||
$f2 = 1;
|
||||
$f3 = 1;
|
||||
$f4 = 0;
|
||||
$f5 = 0;
|
||||
$f6 = 0;
|
||||
|
||||
$flag = $this->meta > 0;
|
||||
|
||||
if(($this->meta & 0x02) > 0){
|
||||
$f4 = max($f4, 0.0625);
|
||||
$f1 = 0;
|
||||
$f2 = 0;
|
||||
$f5 = 1;
|
||||
$f3 = 0;
|
||||
$f6 = 1;
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(($this->meta & 0x08) > 0){
|
||||
$f1 = min($f1, 0.9375);
|
||||
$f4 = 1;
|
||||
$f2 = 0;
|
||||
$f5 = 1;
|
||||
$f3 = 0;
|
||||
$f6 = 1;
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(($this->meta & 0x01) > 0){
|
||||
$f3 = min($f3, 0.9375);
|
||||
$f6 = 1;
|
||||
$f1 = 0;
|
||||
$f4 = 1;
|
||||
$f2 = 0;
|
||||
$f5 = 1;
|
||||
$flag = true;
|
||||
}
|
||||
|
||||
if(!$flag and $this->getSide(1)->isSolid){
|
||||
$f2 = min($f2, 0.9375);
|
||||
$f5 = 1;
|
||||
$f1 = 0;
|
||||
$f4 = 1;
|
||||
$f3 = 0;
|
||||
$f6 = 1;
|
||||
}
|
||||
|
||||
return new AxisAlignedBB(
|
||||
$this->x + $f1,
|
||||
$this->y + $f2,
|
||||
$this->z + $f3,
|
||||
$this->x + $f4,
|
||||
$this->y + $f5,
|
||||
$this->z + $f6
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
if($target->isSolid){
|
||||
$faces = [
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
3 => 4,
|
||||
4 => 8,
|
||||
5 => 2,
|
||||
];
|
||||
if(isset($faces[$face])){
|
||||
$this->meta = $faces[$face];
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
if($item->isShears()){
|
||||
return 0.02;
|
||||
}elseif($item->isSword()){
|
||||
return 0.2;
|
||||
}elseif($item->isAxe()){
|
||||
switch($item->isAxe()){
|
||||
case Tool::TIER_WOODEN:
|
||||
return 0.15;
|
||||
case Tool::TIER_STONE:
|
||||
return 0.075;
|
||||
case Tool::TIER_IRON:
|
||||
return 0.05;
|
||||
case Tool::TIER_DIAMOND:
|
||||
return 0.0375;
|
||||
case Tool::TIER_GOLD:
|
||||
return 0.025;
|
||||
}
|
||||
}
|
||||
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
/*if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
|
||||
Server::getInstance()->api->entity->drop($this, Item::get(LADDER, 0, 1));
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true, true);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}*/
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isShears()){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -97,6 +97,8 @@ class DroppedItem extends Entity{
|
||||
$this->motionY *= 1 - $this->drag;
|
||||
$this->motionZ *= $friction;
|
||||
|
||||
$this->updateMovement();
|
||||
|
||||
if($this->onGround){
|
||||
$this->motionY *= -0.5;
|
||||
}
|
||||
@ -105,7 +107,6 @@ class DroppedItem extends Entity{
|
||||
$this->kill();
|
||||
}
|
||||
|
||||
$this->updateMovement();
|
||||
}
|
||||
|
||||
$this->timings->stopTiming();
|
||||
|
@ -281,10 +281,10 @@ abstract class Entity extends Position implements Metadatable{
|
||||
foreach($player as $p){
|
||||
if($p === $this){
|
||||
/** @var Player $p */
|
||||
$pk = new SetEntityDataPacket();
|
||||
$pk->eid = 0;
|
||||
$pk->metadata = $this->getData();
|
||||
$p->dataPacket($pk);
|
||||
$pk2 = new SetEntityDataPacket();
|
||||
$pk2->eid = 0;
|
||||
$pk2->metadata = $this->getData();
|
||||
$p->dataPacket($pk2);
|
||||
}else{
|
||||
$p->dataPacket($pk);
|
||||
}
|
||||
@ -585,7 +585,7 @@ abstract class Entity extends Position implements Metadatable{
|
||||
}
|
||||
|
||||
public function onUpdate(){
|
||||
if($this->closed !== false){
|
||||
if($this->closed){
|
||||
return false;
|
||||
}
|
||||
$this->timings->startTiming();
|
||||
@ -1171,6 +1171,9 @@ abstract class Entity extends Position implements Metadatable{
|
||||
$this->server->getPluginManager()->callEvent(new EntityDespawnEvent($this));
|
||||
$this->closed = true;
|
||||
unset($this->level->updateEntities[$this->id]);
|
||||
if($this->chunk instanceof FullChunk){
|
||||
$this->chunk->removeEntity($this);
|
||||
}
|
||||
if(($level = $this->getLevel()) instanceof Level){
|
||||
$level->removeEntity($this);
|
||||
}
|
||||
|
@ -24,4 +24,5 @@ namespace pocketmine\entity;
|
||||
|
||||
interface Explosive{
|
||||
|
||||
public function explode();
|
||||
}
|
@ -22,10 +22,124 @@
|
||||
namespace pocketmine\entity;
|
||||
|
||||
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\level\Explosion;
|
||||
use pocketmine\nbt\tag\Byte;
|
||||
use pocketmine\nbt\tag\String;
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class PrimedTNT extends Entity implements Explosive{
|
||||
const NETWORK_ID = 65;
|
||||
|
||||
public $width = 0.98;
|
||||
public $length = 0.98;
|
||||
public $height = 0.98;
|
||||
|
||||
protected $gravity = 0.04;
|
||||
protected $drag = 0.02;
|
||||
|
||||
protected $fuse;
|
||||
|
||||
public $canCollide = false;
|
||||
|
||||
protected function initEntity(){
|
||||
$this->namedtag->id = new String("id", "PrimedTNT");
|
||||
if(isset($this->namedtag->Fuse)){
|
||||
$this->fuse = $this->namedtag["Fuse"];
|
||||
}else{
|
||||
$this->fuse = 80;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function canCollideWith(Entity $entity){
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getData(){
|
||||
return [
|
||||
16 => ["type" => 0, "value" => $this->fuse],
|
||||
];
|
||||
}
|
||||
|
||||
public function saveNBT(){
|
||||
parent::saveNBT();
|
||||
$this->namedtag->Fuse = new Byte("Fuse", $this->fuse);
|
||||
}
|
||||
|
||||
public function onUpdate(){
|
||||
|
||||
if($this->closed){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->timings->startTiming();
|
||||
|
||||
$this->entityBaseTick();
|
||||
|
||||
if(!$this->dead){
|
||||
|
||||
$this->motionY -= $this->gravity;
|
||||
|
||||
$this->move($this->motionX, $this->motionY, $this->motionZ);
|
||||
|
||||
$friction = 1 - $this->drag;
|
||||
|
||||
$this->motionX *= $friction;
|
||||
$this->motionY *= $friction;
|
||||
$this->motionZ *= $friction;
|
||||
|
||||
$this->updateMovement();
|
||||
|
||||
if($this->onGround){
|
||||
$this->motionY *= -0.5;
|
||||
$this->motionX *= 0.7;
|
||||
$this->motionZ *= 0.7;
|
||||
}
|
||||
|
||||
if($this->fuse-- <= 0){
|
||||
$this->kill();
|
||||
$this->explode();
|
||||
}else{
|
||||
$this->sendMetadata($this->getViewers());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return !$this->onGround or ($this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0);
|
||||
}
|
||||
|
||||
public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){
|
||||
|
||||
}
|
||||
|
||||
public function heal($amount){
|
||||
|
||||
}
|
||||
|
||||
public function explode(){
|
||||
(new Explosion($this, 4, $this))->explode();
|
||||
}
|
||||
|
||||
public function spawnTo(Player $player){
|
||||
$pk = new AddEntityPacket();
|
||||
$pk->type = PrimedTNT::NETWORK_ID;
|
||||
$pk->eid = $this->getID();
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
$pk->did = 0;
|
||||
$player->dataPacket($pk);
|
||||
|
||||
$pk = new SetEntityMotionPacket();
|
||||
$pk->entities = [
|
||||
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
|
||||
];
|
||||
$player->dataPacket($pk);
|
||||
|
||||
parent::spawnTo($player);
|
||||
}
|
||||
}
|
222
src/pocketmine/event/server/QueryRegenerateEvent.php
Normal file
222
src/pocketmine/event/server/QueryRegenerateEvent.php
Normal file
@ -0,0 +1,222 @@
|
||||
<?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\event\server;
|
||||
|
||||
use pocketmine\event;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Binary;
|
||||
|
||||
class QueryRegenerateEvent extends ServerEvent{
|
||||
public static $handlerList = null;
|
||||
|
||||
const GAME_ID = "MINECRAFTPE";
|
||||
|
||||
private $timeout;
|
||||
private $serverName;
|
||||
private $listPlugins;
|
||||
/** @var \pocketmine\plugin\Plugin[] */
|
||||
private $plugins;
|
||||
/** @var \pocketmine\Player[] */
|
||||
private $players;
|
||||
|
||||
private $gametype;
|
||||
private $version;
|
||||
private $server_engine;
|
||||
private $map;
|
||||
private $numPlayers;
|
||||
private $maxPlayers;
|
||||
private $whitelist;
|
||||
private $port;
|
||||
private $ip;
|
||||
|
||||
private $extraData = [];
|
||||
|
||||
|
||||
public function __construct(Server $server, $timeout = 5){
|
||||
$this->timeout = $timeout;
|
||||
$this->serverName = $server->getServerName();
|
||||
$this->listPlugins = $server->getProperty("settings.query-plugins", true);
|
||||
$this->plugins = $server->getPluginManager()->getPlugins();
|
||||
$this->players = [];
|
||||
foreach($server->getOnlinePlayers() as $player){
|
||||
if($player->getName() != "" and $player->isConnected()){
|
||||
$this->players[] = $player;
|
||||
}
|
||||
}
|
||||
|
||||
$this->gametype = ($server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP";
|
||||
$this->version = $server->getVersion();
|
||||
$this->server_engine = $server->getName() ." ". $server->getPocketMineVersion();
|
||||
$this->map = $server->getDefaultLevel() === null ? "unknown" : $server->getDefaultLevel()->getName();
|
||||
$this->numPlayers = count($this->players);
|
||||
$this->maxPlayers = $server->getMaxPlayers();
|
||||
$this->whitelist = $server->hasWhitelist() ? "on" : "off";
|
||||
$this->port = $server->getPort();
|
||||
$this->ip = $server->getIp();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the min. timeout for Query Regeneration
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getTimeout(){
|
||||
return $this->timeout;
|
||||
}
|
||||
|
||||
public function setTimeout($timeout){
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
public function getServerName(){
|
||||
return $this->serverName;
|
||||
}
|
||||
|
||||
public function setServerName($serverName){
|
||||
$this->serverName = $serverName;
|
||||
}
|
||||
|
||||
public function canListPlugins(){
|
||||
return $this->listPlugins;
|
||||
}
|
||||
|
||||
public function setListPlugins($value){
|
||||
$this->listPlugins = (bool) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \pocketmine\plugin\Plugin[]
|
||||
*/
|
||||
public function getPlugins(){
|
||||
return $this->plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \pocketmine\plugin\Plugin[] $plugins
|
||||
*/
|
||||
public function setPlugins(array $plugins){
|
||||
$this->plugins = $plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \pocketmine\Player[]
|
||||
*/
|
||||
public function getPlayerList(){
|
||||
return $this->players;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \pocketmine\Player[] $players
|
||||
*/
|
||||
public function setPlayerList(array $players){
|
||||
$this->players = $players;
|
||||
}
|
||||
|
||||
public function getPlayerCount(){
|
||||
return $this->numPlayers;
|
||||
}
|
||||
|
||||
public function setPlayerCount($count){
|
||||
$this->numPlayers = (int) $count;
|
||||
}
|
||||
|
||||
public function getMaxPlayerCount(){
|
||||
return $this->maxPlayers;
|
||||
}
|
||||
|
||||
public function setMaxPlayerCount($count){
|
||||
$this->maxPlayers = (int) $count;
|
||||
}
|
||||
|
||||
public function getWorld(){
|
||||
return $this->map;
|
||||
}
|
||||
|
||||
public function setWorld($world){
|
||||
$this->map = (string) $world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extra Query data in key => value form
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getExtraData(){
|
||||
return $this->extraData;
|
||||
}
|
||||
|
||||
public function setExtraData(array $extraData){
|
||||
$this->extraData = $extraData;
|
||||
}
|
||||
|
||||
public function getLongQuery(){
|
||||
$query = "";
|
||||
|
||||
$plist = $this->server_engine;
|
||||
if(count($this->plugins) > 0 and $this->listPlugins){
|
||||
$plist .= ":";
|
||||
foreach($this->plugins as $p){
|
||||
$d = $p->getDescription();
|
||||
$plist .= " " . str_replace([";", ":", " "], ["", "", "_"], $d->getName()) . " " . str_replace([";", ":", " "], ["", "", "_"], $d->getVersion()) . ";";
|
||||
}
|
||||
$plist = substr($plist, 0, -1);
|
||||
}
|
||||
|
||||
$KVdata = [
|
||||
"splitnum" => chr(128),
|
||||
"hostname" => $this->serverName,
|
||||
"gametype" => $this->gametype,
|
||||
"game_id" => self::GAME_ID,
|
||||
"version" => $this->version,
|
||||
"server_engine" => $this->server_engine,
|
||||
"plugins" => $plist,
|
||||
"map" => $this->map,
|
||||
"numplayers" => $this->numPlayers,
|
||||
"maxplayers" => $this->maxPlayers,
|
||||
"whitelist" => $this->whitelist,
|
||||
"hostip" => $this->ip,
|
||||
"hostport" => $this->port
|
||||
];
|
||||
|
||||
foreach($KVdata as $key => $value){
|
||||
$query .= $key . "\x00" . $value . "\x00";
|
||||
}
|
||||
|
||||
foreach($this->extraData as $key => $value){
|
||||
$query .= $key . "\x00" . $value . "\x00";
|
||||
}
|
||||
|
||||
$query .= "\x00\x01player_\x00\x00";
|
||||
foreach($this->players as $player){
|
||||
$query .= $player->getName() . "\x00";
|
||||
}
|
||||
$query .= "\x00";
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function getShortQuery(){
|
||||
return $this->serverName . "\x00" . $this->gametype . "\x00" . $this->map . "\x00" . $this->numPlayers . "\x00" . $this->maxPlayers . "\x00" . Binary::writeLShort($this->port) . $this->ip . "\x00";
|
||||
}
|
||||
|
||||
}
|
@ -27,4 +27,8 @@ class DiamondAxe extends Tool{
|
||||
parent::__construct(self::DIAMOND_AXE, $meta, $count, "Diamond Axe");
|
||||
}
|
||||
|
||||
public function isAxe(){
|
||||
return Tool::TIER_DIAMOND;
|
||||
}
|
||||
|
||||
}
|
@ -27,4 +27,7 @@ class DiamondHoe extends Tool{
|
||||
parent::__construct(self::DIAMOND_HOE, $meta, $count, "Diamond Hoe");
|
||||
}
|
||||
|
||||
public function isHoe(){
|
||||
return Tool::TIER_DIAMOND;
|
||||
}
|
||||
}
|
@ -27,4 +27,7 @@ class DiamondPickaxe extends Tool{
|
||||
parent::__construct(self::DIAMOND_PICKAXE, $meta, $count, "Diamond Pickaxe");
|
||||
}
|
||||
|
||||
public function isPickaxe(){
|
||||
return Tool::TIER_DIAMOND;
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,7 @@ class DiamondShovel extends Tool{
|
||||
parent::__construct(self::DIAMOND_SHOVEL, $meta, $count, "Diamond Shovel");
|
||||
}
|
||||
|
||||
public function isShovel(){
|
||||
return Tool::TIER_DIAMOND;
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,7 @@ class DiamondSword extends Tool{
|
||||
parent::__construct(self::DIAMOND_SWORD, $meta, $count, "Diamond Sword");
|
||||
}
|
||||
|
||||
public function isSword(){
|
||||
return Tool::TIER_DIAMOND;
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,7 @@ class GoldAxe extends Tool{
|
||||
parent::__construct(self::GOLD_AXE, $meta, $count, "Gold Axe");
|
||||
}
|
||||
|
||||
public function isAxe(){
|
||||
return Tool::TIER_GOLD;
|
||||
}
|
||||
}
|
@ -27,4 +27,7 @@ class GoldHoe extends Tool{
|
||||
parent::__construct(self::GOLD_HOE, $meta, $count, "Gold Hoe");
|
||||
}
|
||||
|
||||
public function isHoe(){
|
||||
return Tool::TIER_GOLD;
|
||||
}
|
||||
}
|
@ -27,4 +27,7 @@ class GoldPickaxe extends Tool{
|
||||
parent::__construct(self::GOLD_PICKAXE, $meta, $count, "Gold Pickaxe");
|
||||
}
|
||||
|
||||
public function isPickaxe(){
|
||||
return Tool::TIER_GOLD;
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,7 @@ class GoldShovel extends Tool{
|
||||
parent::__construct(self::GOLD_SHOVEL, $meta, $count, "Gold Shovel");
|
||||
}
|
||||
|
||||
public function isShovel(){
|
||||
return Tool::TIER_GOLD;
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,7 @@ class GoldSword extends Tool{
|
||||
parent::__construct(self::GOLD_SWORD, $meta, $count, "Gold Sword");
|
||||
}
|
||||
|
||||
public function isSword(){
|
||||
return Tool::TIER_GOLD;
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,7 @@ class IronAxe extends Tool{
|
||||
parent::__construct(self::IRON_AXE, $meta, $count, "Iron Axe");
|
||||
}
|
||||
|
||||
public function isAxe(){
|
||||
return Tool::TIER_IRON;
|
||||
}
|
||||
}
|
@ -27,4 +27,7 @@ class IronHoe extends Tool{
|
||||
parent::__construct(self::IRON_HOE, $meta, $count, "Iron Hoe");
|
||||
}
|
||||
|
||||
public function isHoe(){
|
||||
return Tool::TIER_IRON;
|
||||
}
|
||||
}
|
@ -27,4 +27,7 @@ class IronPickaxe extends Tool{
|
||||
parent::__construct(self::IRON_PICKAXE, $meta, $count, "Iron Pickaxe");
|
||||
}
|
||||
|
||||
public function isPickaxe(){
|
||||
return Tool::TIER_IRON;
|
||||
}
|
||||
}
|
@ -27,4 +27,7 @@ class IronShovel extends Tool{
|
||||
parent::__construct(self::IRON_SHOVEL, $meta, $count, "Iron Shovel");
|
||||
}
|
||||
|
||||
public function isShovel(){
|
||||
return Tool::TIER_IRON;
|
||||
}
|
||||
}
|
@ -27,4 +27,7 @@ class IronSword extends Tool{
|
||||
parent::__construct(self::IRON_SWORD, $meta, $count, "Iron Sword");
|
||||
}
|
||||
|
||||
public function isSword(){
|
||||
return Tool::TIER_IRON;
|
||||
}
|
||||
}
|
@ -159,7 +159,8 @@ class Item{
|
||||
const MELON_BLOCK = 103;
|
||||
const PUMPKIN_STEM = 104;
|
||||
const MELON_STEM = 105;
|
||||
|
||||
const VINE = 106;
|
||||
const VINES = 106;
|
||||
const FENCE_GATE = 107;
|
||||
const BRICK_STAIRS = 108;
|
||||
const STONE_BRICK_STAIRS = 109;
|
||||
|
@ -27,4 +27,8 @@ class StoneAxe extends Tool{
|
||||
parent::__construct(self::STONE_AXE, $meta, $count, "Stone Axe");
|
||||
}
|
||||
|
||||
|
||||
public function isAxe(){
|
||||
return Tool::TIER_STONE;
|
||||
}
|
||||
}
|
@ -27,4 +27,7 @@ class StoneHoe extends Tool{
|
||||
parent::__construct(self::STONE_HOE, $meta, $count, "Stone Hoe");
|
||||
}
|
||||
|
||||
public function isHoe(){
|
||||
return Tool::TIER_STONE;
|
||||
}
|
||||
}
|
@ -27,4 +27,7 @@ class StonePickaxe extends Tool{
|
||||
parent::__construct(self::STONE_PICKAXE, $meta, $count, "Stone Pickaxe");
|
||||
}
|
||||
|
||||
public function isPickaxe(){
|
||||
return Tool::TIER_IRON;
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,7 @@ class StoneShovel extends Tool{
|
||||
parent::__construct(self::STONE_SHOVEL, $meta, $count, "Stone Shovel");
|
||||
}
|
||||
|
||||
public function isShovel(){
|
||||
return Tool::TIER_STONE;
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,7 @@ class StoneSword extends Tool{
|
||||
parent::__construct(self::STONE_SWORD, $meta, $count, "Stone Sword");
|
||||
}
|
||||
|
||||
public function isSword(){
|
||||
return Tool::TIER_STONE;
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,11 @@ use pocketmine\block\Block;
|
||||
use pocketmine\entity\Entity;
|
||||
|
||||
abstract class Tool extends Item{
|
||||
const TIER_WOODEN = 1;
|
||||
const TIER_GOLD = 2;
|
||||
const TIER_STONE = 3;
|
||||
const TIER_IRON = 4;
|
||||
const TIER_DIAMOND = 5;
|
||||
|
||||
public function __construct($id, $meta = 0, $count = 1, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $count, $name);
|
||||
@ -87,84 +92,23 @@ abstract class Tool extends Item{
|
||||
}
|
||||
|
||||
public function isPickaxe(){
|
||||
switch($this->id){
|
||||
case self::WOODEN_PICKAXE:
|
||||
return 1;
|
||||
case self::STONE_PICKAXE:
|
||||
return 3;
|
||||
case self::IRON_PICKAXE:
|
||||
return 4;
|
||||
case self::DIAMOND_PICKAXE:
|
||||
return 5;
|
||||
case self::GOLD_PICKAXE:
|
||||
return 2;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
final public function isAxe(){
|
||||
switch($this->id){
|
||||
case self::IRON_AXE:
|
||||
return 4;
|
||||
case self::WOODEN_AXE:
|
||||
return 1;
|
||||
case self::STONE_AXE:
|
||||
return 3;
|
||||
case self::DIAMOND_AXE:
|
||||
return 5;
|
||||
case self::GOLD_AXE:
|
||||
return 2;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
public function isAxe(){
|
||||
return false;
|
||||
}
|
||||
|
||||
final public function isSword(){
|
||||
switch($this->id){
|
||||
case self::IRON_SWORD:
|
||||
return 4;
|
||||
case self::WOODEN_SWORD:
|
||||
return 1;
|
||||
case self::STONE_SWORD:
|
||||
return 3;
|
||||
case self::DIAMOND_SWORD:
|
||||
return 5;
|
||||
case self::GOLD_SWORD:
|
||||
return 2;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
public function isSword(){
|
||||
return false;
|
||||
}
|
||||
|
||||
final public function isShovel(){
|
||||
switch($this->id){
|
||||
case self::IRON_SHOVEL:
|
||||
return 4;
|
||||
case self::WOODEN_SHOVEL:
|
||||
return 1;
|
||||
case self::STONE_SHOVEL:
|
||||
return 3;
|
||||
case self::DIAMOND_SHOVEL:
|
||||
return 5;
|
||||
case self::GOLD_SHOVEL:
|
||||
return 2;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
public function isShovel(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isHoe(){
|
||||
switch($this->id){
|
||||
case self::IRON_HOE:
|
||||
case self::WOODEN_HOE:
|
||||
case self::STONE_HOE:
|
||||
case self::DIAMOND_HOE:
|
||||
case self::GOLD_HOE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isShears(){
|
||||
@ -172,8 +116,6 @@ abstract class Tool extends Item{
|
||||
}
|
||||
|
||||
public function isTool(){
|
||||
return false;
|
||||
|
||||
return ($this->id === self::FLINT_STEEL or $this->id === self::SHEARS or $this->id === self::BOW or $this->isPickaxe() !== false or $this->isAxe() !== false or $this->isShovel() !== false or $this->isSword() !== false);
|
||||
}
|
||||
}
|
@ -27,4 +27,7 @@ class WoodenAxe extends Tool{
|
||||
parent::__construct(self::WOODEN_AXE, $meta, $count, "Wooden Axe");
|
||||
}
|
||||
|
||||
public function isAxe(){
|
||||
return Tool::TIER_WOODEN;
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,7 @@ class WoodenHoe extends Tool{
|
||||
parent::__construct(self::WOODEN_HOE, $meta, $count, "Wooden Hoe");
|
||||
}
|
||||
|
||||
public function isHoe(){
|
||||
return Tool::TIER_WOODEN;
|
||||
}
|
||||
}
|
@ -27,4 +27,7 @@ class WoodenPickaxe extends Tool{
|
||||
parent::__construct(self::WOODEN_PICKAXE, $meta, $count, "Wooden Pickaxe");
|
||||
}
|
||||
|
||||
public function isPickaxe(){
|
||||
return Tool::TIER_WOODEN;
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,7 @@ class WoodenShovel extends Tool{
|
||||
parent::__construct(self::WOODEN_SHOVEL, $meta, $count, "Wooden Shovel");
|
||||
}
|
||||
|
||||
public function isShovel(){
|
||||
return Tool::TIER_WOODEN;
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,7 @@ class WoodenSword extends Tool{
|
||||
parent::__construct(self::WOODEN_SWORD, $meta, $count, "Wooden Sword");
|
||||
}
|
||||
|
||||
public function isSword(){
|
||||
return Tool::TIER_WOODEN;
|
||||
}
|
||||
}
|
||||
|
@ -24,20 +24,24 @@ namespace pocketmine\level;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\TNT;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\PrimedTNT;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\event\entity\EntityExplodeEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Math;
|
||||
use pocketmine\math\Vector3 as Vector3;
|
||||
use pocketmine\nbt\tag\Byte;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
use pocketmine\nbt\tag\Double;
|
||||
use pocketmine\nbt\tag\Enum;
|
||||
use pocketmine\nbt\tag\Float;
|
||||
use pocketmine\network\protocol\ExplodePacket;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Random;
|
||||
|
||||
class Explosion{
|
||||
public static $specialDrops = [
|
||||
Item::GRASS => Item::DIRT,
|
||||
Item::STONE => Item::COBBLESTONE,
|
||||
Item::COAL_ORE => Item::COAL,
|
||||
Item::DIAMOND_ORE => Item::DIAMOND,
|
||||
Item::REDSTONE_ORE => Item::REDSTONE,
|
||||
];
|
||||
|
||||
private $rays = 16; //Rays
|
||||
public $level;
|
||||
public $source;
|
||||
@ -47,6 +51,7 @@ class Explosion{
|
||||
*/
|
||||
public $affectedBlocks = [];
|
||||
public $stepLen = 0.3;
|
||||
/** @var Entity|Block|Tile */
|
||||
private $what;
|
||||
|
||||
public function __construct(Position $center, $size, $what = null){
|
||||
@ -56,6 +61,9 @@ class Explosion{
|
||||
$this->what = $what;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function explode(){
|
||||
if($this->size < 0.1){
|
||||
return false;
|
||||
@ -64,6 +72,7 @@ class Explosion{
|
||||
$mRays = $this->rays - 1;
|
||||
for($i = 0; $i < $this->rays; ++$i){
|
||||
for($j = 0; $j < $this->rays; ++$j){
|
||||
//break 2 gets here
|
||||
for($k = 0; $k < $this->rays; ++$k){
|
||||
if($i == 0 or $i == $mRays or $j == 0 or $j == $mRays or $k == 0 or $k == $mRays){
|
||||
$vector = new Vector3($i / $mRays * 2 - 1, $j / $mRays * 2 - 1, $k / $mRays * 2 - 1); //($i / $mRays) * 2 - 1
|
||||
@ -72,6 +81,9 @@ class Explosion{
|
||||
|
||||
for($blastForce = $this->size * (mt_rand(700, 1300) / 1000); $blastForce > 0; $blastForce -= $this->stepLen * 0.75){
|
||||
$vBlock = $pointer->floor();
|
||||
if($vBlock->y < 0 or $vBlock->y > 127){
|
||||
break;
|
||||
}
|
||||
$blockID = $this->level->getBlockIdAt($vBlock->x, $vBlock->y, $vBlock->z);
|
||||
|
||||
if($blockID > 0){
|
||||
@ -96,11 +108,10 @@ class Explosion{
|
||||
|
||||
$send = [];
|
||||
$source = $this->source->floor();
|
||||
$radius = 2 * $this->size;
|
||||
$yield = (1 / $this->size) * 100;
|
||||
|
||||
if($this->what instanceof Entity){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityExplodeEvent($this->what, $this->source, $this->affectedBlocks, $yield));
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new EntityExplodeEvent($this->what, $this->source, $this->affectedBlocks, $yield));
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}else{
|
||||
@ -109,33 +120,66 @@ class Explosion{
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
/*foreach($server->api->entity->getRadius($this->source, $radius) as $entity){
|
||||
$impact = (1 - $this->source->distance($entity) / $radius) * 0.5; //placeholder, 0.7 should be exposure
|
||||
$damage = (int) (($impact * $impact + $impact) * 8 * $this->size + 1);
|
||||
$entity->harm($damage, "explosion");
|
||||
}*/
|
||||
$explosionSize = $this->size * 2;
|
||||
$minX = Math::floorFloat($this->source->x - $explosionSize - 1);
|
||||
$maxX = Math::floorFloat($this->source->x + $explosionSize + 1);
|
||||
$minY = Math::floorFloat($this->source->y - $explosionSize - 1);
|
||||
$maxY = Math::floorFloat($this->source->y + $explosionSize + 1);
|
||||
$minZ = Math::floorFloat($this->source->z - $explosionSize - 1);
|
||||
$maxZ = Math::floorFloat($this->source->z + $explosionSize + 1);
|
||||
|
||||
$explosionBB = new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ);
|
||||
|
||||
$list = $this->level->getNearbyEntities($explosionBB, $this->what instanceof Entity ? $this->what : null);
|
||||
foreach($list as $entity){
|
||||
$distance = $entity->distance($this->source) / $explosionSize;
|
||||
|
||||
if($distance <= 1){
|
||||
$motion = $entity->subtract($this->source)->normalize();
|
||||
|
||||
$impact = (1 - $distance) * ($exposure = 1);
|
||||
|
||||
$damage = (int) ((($impact * $impact + $impact) / 2) * 8 * $explosionSize + 1);
|
||||
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new EntityDamageEvent($entity, $this->what instanceof Entity ? EntityDamageEvent::CAUSE_ENTITY_EXPLOSION : EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, $damage));
|
||||
|
||||
if(!$ev->isCancelled()){
|
||||
$entity->attack($ev->getFinalDamage(), $ev);
|
||||
$entity->setMotion($motion->multiply($impact));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$air = Item::get(Item::AIR);
|
||||
|
||||
foreach($this->affectedBlocks as $block){
|
||||
$block->setDamage($this->level->getBlockDataAt($block->x, $block->y, $block->z));
|
||||
|
||||
if($block instanceof TNT){
|
||||
$data = [
|
||||
"x" => $block->x + 0.5,
|
||||
"y" => $block->y + 0.5,
|
||||
"z" => $block->z + 0.5,
|
||||
"power" => 4,
|
||||
"fuse" => mt_rand(10, 30), //0.5 to 1.5 seconds
|
||||
];
|
||||
//TODO
|
||||
//$e = $server->api->entity->add($this->level, ENTITY_OBJECT, OBJECT_PRIMEDTNT, $data);
|
||||
//$e->spawnToAll();
|
||||
$mot = (new Random())->nextSignedFloat() * M_PI * 2;
|
||||
$tnt = new PrimedTNT($this->level->getChunk($block->x >> 4, $block->z >> 4), new Compound("", [
|
||||
"Pos" => new Enum("Pos", [
|
||||
new Double("", $block->x + 0.5),
|
||||
new Double("", $block->y + 0.5),
|
||||
new Double("", $block->z + 0.5)
|
||||
]),
|
||||
"Motion" => new Enum("Motion", [
|
||||
new Double("", -sin($mot) * 0.02),
|
||||
new Double("", 0.2),
|
||||
new Double("", -cos($mot) * 0.02)
|
||||
]),
|
||||
"Rotation" => new Enum("Rotation", [
|
||||
new Float("", 0),
|
||||
new Float("", 0)
|
||||
]),
|
||||
"Fuse" => new Byte("Fuse", mt_rand(10, 30))
|
||||
]));
|
||||
$tnt->spawnToAll();
|
||||
}elseif(mt_rand(0, 100) < $yield){
|
||||
if(isset(self::$specialDrops[$block->getID()])){
|
||||
//TODO
|
||||
//$server->api->entity->drop(new Position($block->x + 0.5, $block->y, $block->z + 0.5, $this->level), Item::get(self::$specialDrops[$block->getID()], 0));
|
||||
}else{
|
||||
//TODO
|
||||
//$server->api->entity->drop(new Position($block->x + 0.5, $block->y, $block->z + 0.5, $this->level), Item::get($block->getID(), $this->level->level->getBlockDamage($block->x, $block->y, $block->z)));
|
||||
foreach($block->getDrops($air) as $drop){
|
||||
$this->level->dropItem($block, Item::get(...$drop));
|
||||
}
|
||||
}
|
||||
$this->level->setBlockIdAt($block->x, $block->y, $block->z, 0);
|
||||
@ -147,7 +191,9 @@ class Explosion{
|
||||
$pk->z = $this->source->z;
|
||||
$pk->radius = $this->size;
|
||||
$pk->records = $send;
|
||||
Server::broadcastPacket($this->level->getPlayers(), $pk);
|
||||
Server::broadcastPacket($this->level->getUsingChunk($source->x >> 4, $source->z >> 4), $pk);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -883,7 +883,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
return $air;
|
||||
}
|
||||
|
||||
return Block::get($blockId, $meta, Position::fromObject($pos, $this));
|
||||
return Block::get($blockId, $meta, new Position($pos->x, $pos->y, $pos->z, $this));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1079,7 +1079,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
if(!($player instanceof Player) or ($player->getGamemode() & 0x01) === 0){
|
||||
foreach($drops as $drop){
|
||||
if($drop[2] > 0){
|
||||
$this->dropItem($vector->add(0.5, 0.5, 0.5), Item::get($drop[0], $drop[1], $drop[2]));
|
||||
$this->dropItem($vector->add(0.5, 0.5, 0.5), Item::get(...$drop));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,12 +25,13 @@
|
||||
*/
|
||||
namespace pocketmine\network\query;
|
||||
|
||||
use pocketmine\event\server\QueryRegenerateEvent;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\Utils;
|
||||
|
||||
class QueryHandler{
|
||||
private $server, $lastToken, $token, $longData, $timeout;
|
||||
private $server, $lastToken, $token, $longData, $shortData, $timeout;
|
||||
|
||||
const HANDSHAKE = 9;
|
||||
const STATISTICS = 0;
|
||||
@ -57,43 +58,10 @@ class QueryHandler{
|
||||
}
|
||||
|
||||
public function regenerateInfo(){
|
||||
$str = "";
|
||||
$plist = $this->server->getName() . " " . $this->server->getPocketMineVersion();
|
||||
$pl = $this->server->getPluginManager()->getPlugins();
|
||||
if(count($pl) > 0 and $this->server->getProperty("settings.query-plugins", true) === true){
|
||||
$plist .= ":";
|
||||
foreach($pl as $p){
|
||||
$d = $p->getDescription();
|
||||
$plist .= " " . str_replace([";", ":", " "], ["", "", "_"], $d->getName()) . " " . str_replace([";", ":", " "], ["", "", "_"], $d->getVersion()) . ";";
|
||||
}
|
||||
$plist = substr($plist, 0, -1);
|
||||
}
|
||||
$KVdata = [
|
||||
"splitnum" => chr(128),
|
||||
"hostname" => $this->server->getServerName(),
|
||||
"gametype" => ($this->server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP",
|
||||
"game_id" => "MINECRAFTPE",
|
||||
"version" => $this->server->getVersion(),
|
||||
"server_engine" => $this->server->getName() . " " . $this->server->getPocketMineVersion(),
|
||||
"plugins" => $plist,
|
||||
"map" => $this->server->getDefaultLevel() === null ? "unknown" : $this->server->getDefaultLevel()->getName(),
|
||||
"numplayers" => count($this->server->getOnlinePlayers()),
|
||||
"maxplayers" => $this->server->getMaxPlayers(),
|
||||
"whitelist" => $this->server->hasWhitelist() === true ? "on" : "off",
|
||||
"hostport" => $this->server->getPort()
|
||||
];
|
||||
foreach($KVdata as $key => $value){
|
||||
$str .= $key . "\x00" . $value . "\x00";
|
||||
}
|
||||
$str .= "\x00\x01player_\x00\x00";
|
||||
foreach($this->server->getOnlinePlayers() as $player){
|
||||
if($player->getName() != ""){
|
||||
$str .= $player->getName() . "\x00";
|
||||
}
|
||||
}
|
||||
$str .= "\x00";
|
||||
$this->longData = $str;
|
||||
$this->timeout = microtime(true) + 5;
|
||||
$this->server->getPluginManager()->callEvent($ev = new QueryRegenerateEvent($this->server, 5));
|
||||
$this->longData = $ev->getLongQuery();
|
||||
$this->shortData = $ev->getShortQuery();
|
||||
$this->timeout = microtime(true) + $ev->getTimeout();
|
||||
}
|
||||
|
||||
public function regenerateToken(){
|
||||
@ -127,13 +95,15 @@ class QueryHandler{
|
||||
}
|
||||
$reply = chr(self::STATISTICS);
|
||||
$reply .= Binary::writeInt($sessionID);
|
||||
|
||||
if($this->timeout < microtime(true)){
|
||||
$this->regenerateInfo();
|
||||
}
|
||||
|
||||
if(strlen($payload) === 8){
|
||||
if($this->timeout < microtime(true)){
|
||||
$this->regenerateInfo();
|
||||
}
|
||||
$reply .= $this->longData;
|
||||
}else{
|
||||
$reply .= $this->server->getServerName() . "\x00" . (($this->server->getGamemode() & 0x01) === 0 ? "SMP" : "CMP") . "\x00" . ($this->server->getDefaultLevel() === null ? "unknown" : $this->server->getDefaultLevel()->getName()) . "\x00" . count($this->server->getOnlinePlayers()) . "\x00" . $this->server->getMaxPlayers() . "\x00" . Binary::writeLShort($this->server->getPort()) . $this->server->getIp() . "\x00";
|
||||
$reply .= $this->shortData;
|
||||
}
|
||||
$this->server->sendPacket($address, $port, $reply);
|
||||
break;
|
||||
|
@ -641,10 +641,6 @@ class PluginManager{
|
||||
* @param Event $event
|
||||
*/
|
||||
public function callEvent(Event $event){
|
||||
$this->fireEvent($event);
|
||||
}
|
||||
|
||||
private function fireEvent(Event $event){
|
||||
$handlers = $event->getHandlers();
|
||||
$listeners = $handlers->getRegisteredListeners();
|
||||
|
||||
|
@ -58,7 +58,7 @@ abstract class Spawnable extends Tile{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($this->getLevel()->getPlayers() as $player){
|
||||
foreach($this->getLevel()->getUsingChunk($this->chunk->getX(), $this->chunk->getZ()) as $player){
|
||||
if($player->spawned === true){
|
||||
$this->spawnTo($player);
|
||||
}
|
||||
|
Reference in New Issue
Block a user