Merge pull request #1188 from PocketMine/Faster-Network

Merge Faster-Network into master. Added new Networking system, new Event system
This commit is contained in:
Shoghi Cervantes 2014-02-10 19:07:12 +01:00
commit 5bdb61117f
93 changed files with 4848 additions and 2866 deletions

View File

@ -317,13 +317,13 @@ class BlockAPI{
}
private function cancelAction(Block $block, Player $player, $send = true){
$player->dataPacket(MC_UPDATE_BLOCK, array(
"x" => $block->x,
"y" => $block->y,
"z" => $block->z,
"block" => $block->getID(),
"meta" => $block->getMetadata()
));
$pk = new UpdateBlockPacket;
$pk->x = $block->x;
$pk->y = $block->y;
$pk->z = $block->z;
$pk->block = $block->getID();
$pk->meta = $block->getMetadata();
$player->dataPacket($pk);
if($send === true){
$player->sendInventorySlot($player->slot);
}
@ -459,363 +459,6 @@ class BlockAPI{
return false;
}
/*
public function flowLavaOn($source, $face){
$down = 0;
if($face === BlockFace::BOTTOM){
$level = 0;
$down = 1;
}else{
$level = ($source[1] & 0x07) + 2;
if($level > 0x07){
return false;
}
}
$spread = $this->server->api->level->getBlockFace($source, $face);
if(($source[0] === 10 or $source[0] === 11) and $spread[0] === 10){
if($level < ($spread[1] & 0x07)){
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $spread[2][0],
"y" => $spread[2][1],
"z" => $spread[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $spread[0], $level | $down, false);
return true;
}
}elseif($spread[0] === 9 or $spread[0] === 8){
if($source[0] === 11){
$this->server->api->level->setBlock($source[2][0], $source[2][1], $source[2][2], 49, 0);
}elseif($face === 0){
$this->server->api->level->setBlock($source[2][0], $source[2][1], $source[2][2], 1, 0);
}else{
$this->server->api->level->setBlock($source[2][0], $source[2][1], $source[2][2], 4, 0);
}
return true;
}elseif(isset(Material::$flowable[$spread[0]])){
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $spread[2][0],
"y" => $spread[2][1],
"z" => $spread[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 10, $level | $down, false);
return true;
}elseif(($source[1] & 0x08) === 0x08){
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $source[0], $source[1] & 0x07, false);
return true;
}
return false;
}
public function flowWaterOn($source, $face, &$spread = null){
$down = 0;
if($face === BlockFace::BOTTOM){
$level = 0;
$down = 1;
}else{
$level = ($source[1] & 0x07) + 1;
if($level > 0x07){
return false;
}
}
$spread = $this->server->api->level->getBlockFace($source, $face);
if(($source[0] === 8 or $source[0] === 9) and $spread[0] === 8){
if($level < ($spread[1] & 0x07)){
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $spread[2][0],
"y" => $spread[2][1],
"z" => $spread[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $spread[0], $level | $down, false);
return true;
}
}elseif($spread[0] === 11){
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 49, 0, true);
return true;
}elseif($spread[0] === 10){
if($face === 0 or ($spread[1] & 0x08) === 0){
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 4, 0, true);
return true;
}
}elseif(isset(Material::$flowable[$spread[0]])){
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $spread[2][0],
"y" => $spread[2][1],
"z" => $spread[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 8, $level | $down, false);
return true;
}elseif(($source[1] & 0x08) === 0x08){
$this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $source[0], $source[1] & 0x07, false);
return true;
}
return false;
}
public function updateBlock($x, $y, $z, $type = BLOCK_UPDATE_NORMAL){
$block = $this->server->api->level->getBlock($x, $y, $z);
$changed = false;
switch($block[0]){
case 8:
case 9:
$faces = array();
if(!$this->flowWaterOn($block, 0, $floor) or $block[0] === 9){
$this->flowWaterOn($block, 2, $faces[0]);
$this->flowWaterOn($block, 3, $faces[1]);
$this->flowWaterOn($block, 4, $faces[2]);
$this->flowWaterOn($block, 5, $faces[3]);
}
if($block[0] === 8){
//Source creation
if(!isset(Material::$flowable[$floor[0]])){
$sources = 0;
foreach($faces as $i => $b){
if($b[0] === 9){
++$sources;
}
}
if($sources >= 2){
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], 9, 0, false);
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
break;
}
}
$drained = true;
$level = $block[1] & 0x07;
$up = $this->server->api->level->getBlockFace($block, BlockFace::UP);
if($up[0] === 8 or $up[0] === 9){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::NORTH);
if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::SOUTH);
if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::EAST);
if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::WEST);
if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}
}
}
}
}
if($drained === true){
++$level;
if($level > 0x07){
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0] + 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0] - 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] + 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] - 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1] - 1,
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], 0, 0, false);
}else{
$block[1] = ($block[1] & 0x08) | $level;
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0] + 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0] - 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] + 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] - 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1] - 1,
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(10, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], $block[0], $block[1], false);
}
}
}
break;
case 10:
case 11:
if(!$this->flowLavaOn($block, 0) or $block[0] === 11){
$this->flowLavaOn($block, 2);
$this->flowLavaOn($block, 3);
$this->flowLavaOn($block, 4);
$this->flowLavaOn($block, 5);
}
if($block[0] === 10){
$drained = true;
$level = $block[1] & 0x07;
$up = $this->server->api->level->getBlockFace($block, BlockFace::UP);
if($up[0] === 10 or $up[0] === 11){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::NORTH);
if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::SOUTH);
if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::EAST);
if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}else{
$b = $this->server->api->level->getBlockFace($block, BlockFace::WEST);
if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
$drained = false;
}
}
}
}
}
if($drained === true){
++$level;
if($level > 0x07){
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0] + 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0] - 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] + 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] - 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1] - 1,
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], 0, 0, false);
}else{
$block[1] = ($block[1] & 0x08) | $level;
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0] + 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0] - 1,
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] + 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2] - 1,
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1] - 1,
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->schedule(20, array($this, "blockScheduler"), array(
"x" => $block[2][0],
"y" => $block[2][1],
"z" => $block[2][2],
"type" => BLOCK_UPDATE_NORMAL,
));
$this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], $block[0], $block[1], false);
}
}
}
break;
}
if($type === BLOCK_TYPE_SCHEDULED){
$type = BLOCK_UPDATE_WEAK;
}
if($changed === true){
$this->updateBlocksAround($x, $y, $z, $type);
}
}*/
public function blockUpdateAround(Position $pos, $type = BLOCK_UPDATE_NORMAL, $delay = false){
if($delay !== false){
$this->scheduleBlockUpdate($pos->getSide(0), $delay, $type);

View File

@ -157,14 +157,14 @@ class EntityAPI{
$entity->closed = true;
$this->server->query("DELETE FROM entities WHERE EID = ".$eid.";");
if($entity->class === ENTITY_PLAYER){
$this->server->api->player->broadcastPacket($this->server->api->player->getAll(), MC_REMOVE_PLAYER, array(
"clientID" => 0,
"eid" => $entity->eid,
));
$pk = new RemovePlayerPacket;
$pk->eid = $entity->eid;
$pk->clientID = 0;
$this->server->api->player->broadcastPacket($this->server->api->player->getAll(), $pk);
}else{
$this->server->api->player->broadcastPacket($this->server->api->player->getAll($entity->level), MC_REMOVE_ENTITY, array(
"eid" => $entity->eid,
));
$pk = new RemoveEntityPacket;
$pk->eid = $entity->eid;
$this->server->api->player->broadcastPacket($this->server->api->player->getAll($entity->level), $pk);
}
$this->server->api->dhandle("entity.remove", $entity);
$entity = null;

View File

@ -353,11 +353,9 @@ class PlayerAPI{
return $this->server->clients;
}
public function broadcastPacket(array $players, $id, $data = array()){
$data = new CustomPacketHandler($id, "", $data, true);
$packet = array("raw" => chr($id).$data->raw);
public function broadcastPacket(array $players, RakNetDataPacket $packet){
foreach($players as $p){
$p->dataPacket(false, $packet);
$p->dataPacket(clone $packet);
}
}
@ -404,14 +402,14 @@ class PlayerAPI{
if($p !== $player and ($p->entity instanceof Entity)){
$p->entity->spawn($player);
if($p->level !== $player->level){
$player->dataPacket(MC_MOVE_ENTITY_POSROT, array(
"eid" => $p->entity->eid,
"x" => -256,
"y" => 128,
"z" => -256,
"yaw" => 0,
"pitch" => 0,
));
$pk = new MoveEntityPacket_PosRot;
$pk->eid = $p->entity->eid;
$pk->x = -256;
$pk->y = 128;
$pk->z = -256;
$pk->yaw = 0;
$pk->pitch = 0;
$player->dataPacket($pk);
}
}
}
@ -422,14 +420,14 @@ class PlayerAPI{
if($p !== $player and ($p->entity instanceof Entity) and ($player->entity instanceof Entity)){
$player->entity->spawn($p);
if($p->level !== $player->level){
$p->dataPacket(MC_MOVE_ENTITY_POSROT, array(
"eid" => $player->entity->eid,
"x" => -256,
"y" => 128,
"z" => -256,
"yaw" => 0,
"pitch" => 0,
));
$pk = new MoveEntityPacket_PosRot;
$pk->eid = $player->entity->eid;
$pk->x = -256;
$pk->y = 128;
$pk->z = -256;
$pk->yaw = 0;
$pk->pitch = 0;
$p->dataPacket($pk);
}
}
}

View File

@ -28,7 +28,8 @@ class ServerAPI{
private $apiList = array();
private $asyncCnt = 0;
private $rcon;
private $query;
public $query;
//TODO: Instead of hard-coding functions, use PHPDoc-compatible methods to load APIs.
@ -97,6 +98,14 @@ class ServerAPI{
@mkdir(DATA_PATH."players/", 0755);
@mkdir(DATA_PATH."worlds/", 0755);
@mkdir(DATA_PATH."plugins/", 0755);
//Init all the events
foreach(get_declared_classes() as $class){
if(is_subclass_of($class, "BaseEvent") and property_exists($class, "handlers") and property_exists($class, "handlerPriority")){
$class::unregisterAll();
}
}
$version = new VersionString();
console("[INFO] Starting Minecraft PE server version ".FORMAT_AQUA.CURRENT_MINECRAFT_VERSION);
@ -134,28 +143,25 @@ class ServerAPI{
));
$this->parseProperties();
//Load advanced properties
define("DEBUG", $this->getProperty("debug", 1));
define("ADVANCED_CACHE", $this->getProperty("enable-advanced-cache", false));
if($this->getProperty("port") !== false){
$this->setProperty("server-port", $this->getProperty("port"));
$this->config->remove("port");
$this->config->remove("invisible");
define("MAX_CHUNK_RATE", 20 / $this->getProperty("max-chunks-per-second", 8)); //Default rate ~512 kB/s
if(ADVANCED_CACHE == true){
console("[INFO] Advanced cache enabled");
}
if($this->getProperty("upnp-forwarding") == true){
console("[INFO] [UPnP] Trying to port forward...");
UPnP_PortForward($this->getProperty("server-port"));
}
$this->server = new PocketMinecraftServer($this->getProperty("server-name"), $this->getProperty("gamemode"), ($seed = $this->getProperty("level-seed")) != "" ? (int) $seed:false, $this->getProperty("server-port"), ($ip = $this->getProperty("server-ip")) != "" ? $ip:"0.0.0.0");
$this->server->api = $this;
self::$serverRequest = $this->server;
console("[INFO] This server is running PocketMine-MP version ".($version->isDev() ? FORMAT_YELLOW:"").MAJOR_VERSION.FORMAT_RESET." \"".CODENAME."\" (MCPE: ".CURRENT_MINECRAFT_VERSION.") (API ".CURRENT_API_VERSION.")", true, true, 0);
console("[INFO] PocketMine-MP is distributed under the LGPL License", true, true, 0);
if(ADVANCED_CACHE == true){
console("[INFO] Advanced cache enabled");
}
if($this->getProperty("upnp-forwarding") === true){
console("[INFO] [UPnP] Trying to port forward...");
UPnP_PortForward($this->getProperty("server-port"));
}
if($this->getProperty("last-update") === false or ($this->getProperty("last-update") + 3600) < time()){
console("[INFO] Checking for new server version");
console("[INFO] Last check: ".FORMAT_AQUA.date("Y-m-d H:i:s", $this->getProperty("last-update"))."\x1b[0m");
@ -257,7 +263,7 @@ class ServerAPI{
"php_version" => PHP_VERSION,
"version" => MAJOR_VERSION,
"mc_version" => CURRENT_MINECRAFT_VERSION,
"protocol" => CURRENT_PROTOCOL,
"protocol" => ProtocolInfo::CURRENT_PROTOCOL,
"online" => count($this->server->clients),
"max" => $this->server->maxClients,
"plugins" => $plist,
@ -349,7 +355,7 @@ class ServerAPI{
}
if($this->getProperty("enable-query") === true){
$this->query = new Query();
$this->query = new QueryHandler();
}
CraftingRecipes::init();
$this->server->init();

135
src/BaseEvent.php Normal file
View File

@ -0,0 +1,135 @@
<?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/
*
*
*/
abstract class BaseEvent{
const ALLOW = 0;
const DENY = 1;
const NORMAL = 2;
const FORCE = 0x80000000;
/**
* Any callable event must declare the static variables
*
* public static $handlers;
* public static $handlerPriority;
*
* Not doing so will deny the proper event initialization
*/
protected $eventName = null;
private $status = BaseEvent::NORMAL;
private $prioritySlot;
final public function getEventName(){
return $this->eventName !== null ? get_class($this) : $this->eventName;
}
final public function setPrioritySlot($slot){
$this->prioritySlot = (int) $slot;
}
final public function getPrioritySlot(){
return (int) $this->prioritySlot;
}
public function isAllowed(){
return ($this->status & 0x7FFFFFFF) === BaseEvent::ALLOW;
}
public function setAllowed($forceAllow = false){
$this->status = BaseEvent::ALLOW & ($forceAllow === true ? BaseEvent::FORCE : 0);
}
public function isCancelled(){
return ($this->status & 0x7FFFFFFF) === BaseEvent::DENY;
}
public function setCancelled($forceCancel = false){
if($this instanceof CancellableEvent){
$this->status = BaseEvent::DENY & ($forceCancel === true ? BaseEvent::FORCE : 0);
}
return false;
}
public function isNormal(){
return $this->status === BaseEvent::NORMAL;
}
public function setNormal(){
$this->status = BaseEvent::NORMAL;
}
public function isForced(){
return ($this->status & BaseEvent::FORCE) > 0;
}
public static function getHandlerList(){
return static::$handlers;
}
public static function getPriorityList(){
return static::$handlerPriority;
}
public static function unregisterAll(){
static::$handlers = array();
static::$handlerPriority = array();
}
public function register(callable $handler, $priority = EventPriority::NORMAL){
if($priority < EventPriority::MONITOR or $priority > EventPriority::LOWEST){
return false;
}
$identifier = Utils::getCallableIdentifier($handler);
if(isset(static::$handlers[$identifier])){ //Already registered
return false;
}else{
static::$handlers[$identifier] = $handler;
if(!isset(static::$handlerPriority[(int) $priority])){
static::$handlerPriority[(int) $priority] = array();
}
static::$handlerPriority[(int) $priority][$identifier] = $handler;
return true;
}
}
public function unregister(callable $handler, $priority = EventPriority::NORMAL){
$identifier = Utils::getCallableIdentifier($handler);
if(isset(static::$handlers[$identifier])){
if(isset(static::$handlerPriority[(int) $priority][$identifier])){
unset(static::$handlerPriority[(int) $priority][$identifier]);
}else{
for($priority = EventPriority::MONITOR; $priority <= EventPriority::LOWEST; ++$priority){
unset(static::$handlerPriority[$priority][$identifier]);
if(count(static::$handlerPriority[$priority]) === 0){
unset(static::$handlerPriority[$priority]);
}
}
}
unset(static::$handlers[$identifier]);
return true;
}else{
return false;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -64,7 +64,7 @@ class PocketMinecraftServer{
$this->saveEnabled = true;
$this->tickMeasure = array_fill(0, 40, 0);
$this->setType("normal");
$this->interface = new MinecraftInterface($this, "255.255.255.255", $this->port, true, false, $this->serverip);
$this->interface = new MinecraftInterface("255.255.255.255", $this->port, $this->serverip);
$this->stop = false;
$this->ticks = 0;
if(!defined("NO_THREADS")){
@ -421,7 +421,7 @@ class PocketMinecraftServer{
}
$dump .= "\r\n\r\n";
$version = new VersionString();
$dump .= "PocketMine-MP version: ".$version." #".$version->getNumber()." [Protocol ".CURRENT_PROTOCOL."; API ".CURRENT_API_VERSION."]\r\n";
$dump .= "PocketMine-MP version: ".$version." #".$version->getNumber()." [Protocol ".ProtocolInfo::CURRENT_PROTOCOL."; API ".CURRENT_API_VERSION."]\r\n";
$dump .= "Git commit: ".GIT_COMMIT."\r\n";
$dump .= "Source SHA1 sum: ".SOURCE_SHA1SUM."\r\n";
$dump .= "uname -a: ".php_uname("a")."\r\n";
@ -473,29 +473,30 @@ class PocketMinecraftServer{
}
public static function clientID($ip, $port){
//faster than string indexes in PHP
return crc32($ip . $port) ^ crc32($port . $ip . BOOTUP_RANDOM);
//return $ip . ":" . $port;
}
public function packetHandler($packet){
$data =& $packet["data"];
$CID = PocketMinecraftServer::clientID($packet["ip"], $packet["port"]);
public function packetHandler(Packet $packet){
$data =& $packet;
$CID = PocketMinecraftServer::clientID($packet->ip, $packet->port);
if(isset($this->clients[$CID])){
$this->clients[$CID]->handlePacket($packet["pid"], $data);
$this->clients[$CID]->handlePacket($packet);
}else{
if($this->handle("server.noauthpacket", $packet) === false){
if($this->handle("server.noauthpacket.".$packet->pid(), $packet) === false){
return;
}
switch($packet["pid"]){
case 0x01:
case 0x02:
switch($packet->pid()){
case RakNetInfo::UNCONNECTED_PING:
case RakNetInfo::UNCONNECTED_PING_OPEN_CONNECTIONS:
if($this->invisible === true){
$this->send(0x1c, array(
$data[0],
$this->serverID,
RAKNET_MAGIC,
$this->serverType,
), false, $packet["ip"], $packet["port"]);
$pk = new RakNetPacket(RakNetInfo::UNCONNECTED_PONG);
$pk->pingID = $packet->pingID;
$pk->serverID = $this->serverID;
$pk->serverType = $this->serverType;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
break;
}
if(!isset($this->custom["times_".$CID])){
@ -507,64 +508,59 @@ class PocketMinecraftServer{
}
$txt = substr($this->description, $this->custom["times_".$CID], $ln);
$txt .= substr($this->description, 0, $ln - strlen($txt));
$this->send(0x1c, array(
$data[0],
$this->serverID,
RAKNET_MAGIC,
$this->serverType. $this->name . " [".count($this->clients)."/".$this->maxClients."] ".$txt,
), false, $packet["ip"], $packet["port"]);
$pk = new RakNetPacket(RakNetInfo::UNCONNECTED_PONG);
$pk->pingID = $packet->pingID;
$pk->serverID = $this->serverID;
$pk->serverType = $this->serverType . $this->name . " [".count($this->clients)."/".$this->maxClients."] ".$txt;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
$this->custom["times_".$CID] = ($this->custom["times_".$CID] + 1) % strlen($this->description);
break;
case 0x05:
$version = $data[1];
$size = strlen($data[2]);
if($version !== CURRENT_STRUCTURE){
console("[DEBUG] Incorrect structure #$version from ".$packet["ip"].":".$packet["port"], true, true, 2);
$this->send(0x1a, array(
CURRENT_STRUCTURE,
RAKNET_MAGIC,
$this->serverID,
), false, $packet["ip"], $packet["port"]);
case RakNetInfo::OPEN_CONNECTION_REQUEST_1:
if($packet->structure !== RakNetInfo::STRUCTURE){
console("[DEBUG] Incorrect structure #".$packet->structure." from ".$packet->ip.":".$packet->port, true, true, 2);
$pk = new RakNetPacket(RakNetInfo::INCOMPATIBLE_PROTOCOL_VERSION);
$pk->serverID = $this->serverID;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
}else{
$this->send(0x06, array(
RAKNET_MAGIC,
$this->serverID,
0,
strlen($packet["raw"]),
), false, $packet["ip"], $packet["port"]);
$pk = new RakNetPacket(RakNetInfo::OPEN_CONNECTION_REPLY_1);
$pk->serverID = $this->serverID;
$pk->mtuSize = strlen($packet->buffer);
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
}
break;
case 0x07:
case RakNetInfo::OPEN_CONNECTION_REQUEST_2:
if($this->invisible === true){
break;
}
$port = $data[2];
$MTU = $data[3];
$clientID = $data[4];
if(count($this->clients) < $this->maxClients){
$this->clients[$CID] = new Player($clientID, $packet["ip"], $packet["port"], $MTU); //New Session!
$this->send(0x08, array(
RAKNET_MAGIC,
$this->serverID,
$this->port,
$data[3],
0,
), false, $packet["ip"], $packet["port"]);
}
$this->clients[$CID] = new Player($packet->clientID, $packet->ip, $packet->port, $packet->mtuSize); //New Session!
$pk = new RakNetPacket(RakNetInfo::OPEN_CONNECTION_REPLY_2);
$pk->serverID = $this->serverID;
$pk->port = $this->port;
$pk->mtuSize = $packet->mtuSize;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$this->send($pk);
break;
}
}
}
public function send($pid, $data = array(), $raw = false, $dest = false, $port = false){
return $this->interface->writePacket($pid, $data, $raw, $dest, $port);
public function send(Packet $packet){
return $this->interface->writePacket($packet);
}
public function process(){
$lastLoop = 0;
while($this->stop === false){
$packet = $this->interface->readPacket();
if($packet !== false){
if($packet instanceof Packet){
$this->packetHandler($packet);
$lastLoop = 0;
}else{

View File

@ -31,7 +31,6 @@ define("VIEWER", 3);
//Players
define("MAX_CHUNK_RATE", 20 / arg("max-chunks-per-second", 4)); //Default rate ~256 kB/s
define("PLAYER_MAX_QUEUE", 1024);
define("PLAYER_SURVIVAL_SLOTS", 36);

View File

@ -0,0 +1,28 @@
<?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/
*
*
*/
/**
* Events that can be cancelled must use the interface CancellableEvent
*/
interface CancellableEvent{
}

View File

@ -0,0 +1,52 @@
<?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/
*
*
*/
abstract class EventHandler{
public static function callEvent(BaseEvent $event){
$status = BaseEvent::NORMAL;
foreach($event::$handlerPriority as $priority => $handlerList){
if(count($handlerList) > 0){
$event->setPrioritySlot($priority);
foreach($handlerList as $handler){
call_user_func($handler, $event);
}
if($event->isForced()){
if($event instanceof CancellableEvent and $event->isCancelled()){
return BaseEvent::DENY;
}else{
return BaseEvent::ALLOW;
}
}
}
}
if($event instanceof CancellableEvent and $event->isCancelled()){
return BaseEvent::DENY;
}elseif($event->isAllowed()){
return BaseEvent::ALLOW;
}else{
return BaseEvent::NORMAL;
}
}
}

View File

@ -0,0 +1,52 @@
<?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/
*
*
*/
abstract class EventPriority{
/**
* Event call is of very low importance and should be ran first, to allow
* other plugins to further customise the outcome
*/
const LOWEST = 5;
/**
* Event call is of low importance
*/
const LOW = 4;
/**
* Event call is neither important or unimportant, and may be ran normally
*/
const NORMAL = 3;
/**
* Event call is of high importance
*/
const HIGH = 2;
/**
* Event call is critical and must have the final say in what happens
* to the event
*/
const HIGHEST = 1;
/**
* Event is listened to purely for monitoring the outcome of an event.
*
* No modifications to the event should be made under this priority
*/
const MONITOR = 0;
}

29
src/event/PluginEvent.php Normal file
View File

@ -0,0 +1,29 @@
<?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/
*
*
*/
/**
* Plugins that create events must use this class as the base
*/
abstract class PluginEvent extends BaseEvent{
}

24
src/event/ServerEvent.php Normal file
View File

@ -0,0 +1,24 @@
<?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/
*
*
*/
abstract class ServerEvent extends BaseEvent{
}

View File

@ -0,0 +1,40 @@
<?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/
*
*
*/
class DataPacketReceiveEvent extends ServerEvent implements CancellableEvent{
public static $handlers;
public static $handlerPriority;
private $packet;
private $player;
public function __construct(Player $player, RakNetDataPacket $packet){
$this->packet = $packet;
}
public function getPacket(){
return $this->packet;
}
public function getPlayer(){
return $this->player;
}
}

View File

@ -0,0 +1,40 @@
<?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/
*
*
*/
class DataPacketSendEvent extends ServerEvent implements CancellableEvent{
public static $handlers;
public static $handlerPriority;
private $packet;
private $player;
public function __construct(Player $player, RakNetDataPacket $packet){
$this->packet = $packet;
}
public function getPacket(){
return $this->packet;
}
public function getPlayer(){
return $this->player;
}
}

View File

@ -0,0 +1,36 @@
<?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/
*
*
*/
class PacketReceiveEvent extends ServerEvent implements CancellableEvent{
public static $handlers;
public static $handlerPriority;
private $packet;
public function __construct(Packet $packet){
$this->packet = $packet;
}
public function getPacket(){
return $this->packet;
}
}

View File

@ -0,0 +1,36 @@
<?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/
*
*
*/
class PacketSendEvent extends ServerEvent implements CancellableEvent{
public static $handlers;
public static $handlerPriority;
private $packet;
public function __construct(Packet $packet){
$this->packet = $packet;
}
public function getPacket(){
return $this->packet;
}
}

View File

@ -125,13 +125,13 @@ class DoorBlock extends TransparentBlock{
$this->level->setBlock($down, BlockAPI::get($this->id, $meta), true, false, true);
$players = ServerAPI::request()->api->player->getAll($this->level);
unset($players[$player->CID]);
ServerAPI::request()->api->player->broadcastPacket($players, MC_LEVEL_EVENT, array(
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"evid" => 1003,
"data" => 0
));
$pk = new LevelEventPacket;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->evid = 1003;
$pk->data = 0;
ServerAPI::request()->api->player->broadcastPacket($players, $pk);
return true;
}
return false;
@ -140,13 +140,13 @@ class DoorBlock extends TransparentBlock{
$this->level->setBlock($this, $this, true, false, true);
$players = ServerAPI::request()->api->player->getAll($this->level);
unset($players[$player->CID]);
ServerAPI::request()->api->player->broadcastPacket($players, MC_LEVEL_EVENT, array(
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"evid" => 1003,
"data" => 0
));
$pk = new LevelEventPacket;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->evid = 1003;
$pk->data = 0;
ServerAPI::request()->api->player->broadcastPacket($players, $pk);
}
return true;
}

View File

@ -29,9 +29,9 @@ class BedBlock extends TransparentBlock{
public function onActivate(Item $item, Player $player){
if(ServerAPI::request()->api->time->getPhase($player->level) !== "night"){
$player->dataPacket(MC_CLIENT_MESSAGE, array(
"message" => "You can only sleep at night"
));
$pk = new ChatPacket;
$pk->message = "You can only sleep at night";
$player->dataPacket($pk);
return true;
}
@ -51,17 +51,17 @@ class BedBlock extends TransparentBlock{
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
$b = $blockWest;
}else{
$player->dataPacket(MC_CLIENT_MESSAGE, array(
"message" => "The bed is incomplete"
));
$pk = new ChatPacket;
$pk->message = "This bed is incomplete";
$player->dataPacket($pk);
return true;
}
}
if($player->sleepOn($b) === false){
$player->dataPacket(MC_CLIENT_MESSAGE, array(
"message" => "This bed is occupied"
));
$pk = new ChatPacket;
$pk->message = "This bed is occupied";
$player->dataPacket($pk);
}
return true;
}

View File

@ -1,876 +0,0 @@
<?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/
*
*
*/
class CustomPacketHandler{
public $offset;
public $raw;
public $c;
public $data;
public $name = "";
public function get($len = true, $check = true){
if($len === true){
$data = substr($this->raw, $this->offset);
if($check === true){
$this->offset = strlen($this->raw);
}
return $data;
}
$data = substr($this->raw, $this->offset, $len);
if($check === true){
$this->offset += $len;
}
return $data;
}
private function feof(){
return !isset($this->raw{$this->offset});
}
public function __construct($pid, $raw = "", $data = array(), $create = false){
$this->raw = $raw;
$this->data = $data;
$this->offset = 0;
$this->c = (bool) $create;
if($pid === false){
return;
}
switch($pid){
case MC_PING:
if($this->c === false){
$this->data["time"] = Utils::readLong($this->get(8));
}else{
$this->raw .= Utils::writeLong($this->data["time"]);
}
break;
case MC_PONG:
if($this->c === false){
$this->data["ptime"] = Utils::readLong($this->get(8));
$this->data["time"] = Utils::readLong($this->get(8));
}else{
$this->raw .= Utils::writeLong($this->data["ptime"]);
$this->raw .= Utils::writeLong($this->data["time"]);
}
break;
case MC_CLIENT_CONNECT:
if($this->c === false){
$this->data["clientID"] = Utils::readLong($this->get(8));
$this->data["session"] = Utils::readLong($this->get(8));
$this->data["unknown2"] = $this->get(1);
}else{
$this->raw .= Utils::writeLong($this->data["clientID"]);
$this->raw .= Utils::writeLong($this->data["session"]);
$this->raw .= "\x00";
}
break;
case MC_SERVER_HANDSHAKE:
if($this->c === false){
$this->data["cookie"] = $this->get(4); // 043f57fe
$this->data["security"] = $this->get(1);
$this->data["port"] = Utils::readShort($this->get(2), false);
$this->data["dataArray"] = Utils::readDataArray($this->get(true, false), 10, $offset);
$this->get($offset);
$this->data["timestamp"] = $this->get(2);
$this->data["session"] = Utils::readLong($this->get(8));
$this->data["session2"] = Utils::readLong($this->get(8));
}else{
$this->raw .= "\x04\x3f\x57\xfe";
$this->raw .= "\xcd";
$this->raw .= Utils::writeShort($this->data["port"]);
$this->raw .= Utils::writeDataArray(array(
"\xf5\xff\xff\xf5",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
));
$this->raw .= "\x00\x00";
$this->raw .= Utils::writeLong($this->data["session"]);
$this->raw .= Utils::writeLong($this->data["session2"]);
}
break;
case MC_CLIENT_HANDSHAKE:
if($this->c === false){
$this->data["cookie"] = $this->get(4); // 043f57fe
$this->data["security"] = $this->get(1);
$this->data["port"] = Utils::readShort($this->get(2), false);
$this->data["dataArray0"] = $this->get(ord($this->get(1)));
$this->data["dataArray"] = Utils::readDataArray($this->get(true, false), 9, $offset);
$this->get($offset);
$this->data["timestamp"] = $this->get(2);
$this->data["session2"] = Utils::readLong($this->get(8));
$this->data["session"] = Utils::readLong($this->get(8));
}else{
$this->raw .= "\x04\x3f\x57\xfe";
$this->raw .= "\xed";
$this->raw .= Utils::writeShort($this->data["port"]);
$w = array_shift($this->data["dataArray"]);
$this->raw .= chr(strlen($w)).$w;
$this->raw .= Utils::writeDataArray($this->data["dataArray"]);
$this->raw .= "\x00\x00";
$this->raw .= Utils::writeLong($this->data["session2"]);
$this->raw .= Utils::writeLong($this->data["session"]);
}
break;
case MC_SERVER_FULL:
if($this->c === false){
}else{
$this->raw .= RAKNET_MAGIC;
$this->raw .= Utils::writeLong($this->data["serverID"]);
}
break;
case MC_DISCONNECT:
//null
break;
case MC_BANNED:
if($this->c === false){
}else{
$this->raw .= RAKNET_MAGIC;
$this->raw .= Utils::writeLong($this->data["serverID"]);
}
break;
case MC_LOGIN:
if($this->c === false){
$this->data["username"] = $this->get(Utils::readShort($this->get(2), false));
$this->data["protocol1"] = Utils::readInt($this->get(4));
$this->data["protocol2"] = Utils::readInt($this->get(4));
$this->data["clientId"] = Utils::readInt($this->get(4));
$this->data["realms_data"] = $this->get(Utils::readShort($this->get(2), false));
}else{
$this->raw .= Utils::writeShort(strlen($this->data["username"])).$this->data["username"];
$this->raw .= Utils::writeInt(CURRENT_PROTOCOL).
Utils::writeInt(CURRENT_PROTOCOL).
Utils::writeInt($this->data["clientId"]);
$this->raw .= Utils::writeShort(strlen($this->data["realms_data"])).$this->data["realms_data"];
}
break;
case MC_LOGIN_STATUS:
if($this->c === false){
$this->data["status"] = Utils::readInt($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["status"]);
}
break;
case MC_READY:
if($this->c === false){
$this->data["status"] = ord($this->get(1));
}else{
$this->raw .= chr($this->data["status"]);
}
break;
case MC_CHAT:
if($this->c === false){
$this->data["player"] = $this->get(Utils::readShort($this->get(2), false));
$this->data["message"] = $this->get(Utils::readShort($this->get(2), false));
}else{
$this->raw .= Utils::writeShort(strlen($this->data["player"])).$this->data["player"];
$this->raw .= Utils::writeShort(strlen($this->data["message"])).$this->data["message"];
}
break;
case MC_SET_TIME:
if($this->c === false){
$this->data["time"] = Utils::readInt($this->get(4));
$this->data["started"] = ord($this->get(1)) & 0x80 > 0;
}else{
$this->raw .= Utils::writeInt($this->data["time"])."\x80";
$this->raw .= chr((isset($this->data["started"]) and $this->data["started"] == true) ? 0x80:0x00);
}
break;
case MC_START_GAME:
if($this->c === false){
$this->data["seed"] = Utils::readInt($this->get(4));
$this->data["generator"] = Utils::readInt($this->get(4));
$this->data["gamemode"] = Utils::readInt($this->get(4));
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readFloat($this->get(4));
$this->data["y"] = Utils::readFloat($this->get(4));
$this->data["z"] = Utils::readFloat($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["seed"]);
$this->raw .= Utils::writeInt($this->data["generator"]);
$this->raw .= Utils::writeInt($this->data["gamemode"]);
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeFloat($this->data["x"]);
$this->raw .= Utils::writeFloat($this->data["y"]);
$this->raw .= Utils::writeFloat($this->data["z"]);
}
break;
case MC_ADD_MOB:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["type"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readFloat($this->get(4));
$this->data["y"] = Utils::readFloat($this->get(4));
$this->data["z"] = Utils::readFloat($this->get(4));
$this->data["pitch"] = Utils::readByte($this->get(1));
$this->data["yaw"] = Utils::readByte($this->get(1));
$this->data["metadata"] = Utils::readMetadata($this->get(true));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeInt($this->data["type"]);
$this->raw .= Utils::writeFloat($this->data["x"]);
$this->raw .= Utils::writeFloat($this->data["y"]);
$this->raw .= Utils::writeFloat($this->data["z"]);
$this->raw .= Utils::writeByte($this->data["pitch"]);
$this->raw .= Utils::writeByte($this->data["yaw"]);
$this->raw .= Utils::writeMetadata($this->data["metadata"]);
}
break;
case MC_ADD_PLAYER:
if($this->c === false){
$this->data["clientID"] = Utils::readLong($this->get(8));
$this->data["username"] = $this->get(Utils::readShort($this->get(2), false));
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readFloat($this->get(4));
$this->data["y"] = Utils::readFloat($this->get(4));
$this->data["z"] = Utils::readFloat($this->get(4));
$this->data["pitch"] = Utils::readByte($this->get(1));
$this->data["yaw"] = Utils::readByte($this->get(1));
$this->data["unknown1"] = Utils::readShort($this->get(2));
$this->data["unknown2"] = Utils::readShort($this->get(2));
$this->data["metadata"] = Utils::readMetadata($this->get(true));
}else{
$this->raw .= Utils::writeLong($this->data["clientID"]);
$this->raw .= Utils::writeShort(strlen($this->data["username"])).$this->data["username"];
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeFloat($this->data["x"]);
$this->raw .= Utils::writeFloat($this->data["y"]);
$this->raw .= Utils::writeFloat($this->data["z"]);
$this->raw .= Utils::writeByte($this->data["pitch"]);
$this->raw .= Utils::writeByte($this->data["yaw"]);
$this->raw .= Utils::writeShort($this->data["unknown1"]);
$this->raw .= Utils::writeShort($this->data["unknown2"]);
$this->raw .= Utils::writeMetadata($this->data["metadata"]);
}
break;
case MC_REMOVE_PLAYER:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["clientID"] = Utils::readLong($this->get(8));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeLong($this->data["clientID"]);
}
break;
case MC_ADD_ENTITY:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["type"] = ord($this->get(1));
$this->data["x"] = Utils::readFloat($this->get(4));
$this->data["y"] = Utils::readFloat($this->get(4));
$this->data["z"] = Utils::readFloat($this->get(4));
$this->data["did"] = Utils::readInt($this->get(4));
if($this->data["did"] > 0){
$this->data["speedX"] = Utils::readShort($this->get(2));
$this->data["speedY"] = Utils::readShort($this->get(2));
$this->data["speedZ"] = Utils::readShort($this->get(2));
}
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= chr($this->data["type"]);
$this->raw .= Utils::writeFloat($this->data["x"]);
$this->raw .= Utils::writeFloat($this->data["y"]);
$this->raw .= Utils::writeFloat($this->data["z"]);
$this->raw .= Utils::writeInt($this->data["did"]);
if($this->data["did"] > 0){
$this->raw .= Utils::writeShort($this->data["speedX"]);
$this->raw .= Utils::writeShort($this->data["speedY"]);
$this->raw .= Utils::writeShort($this->data["speedZ"]);
}
}
break;
case MC_REMOVE_ENTITY:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
}
break;
case MC_ADD_ITEM_ENTITY:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["block"] = Utils::readShort($this->get(2), false);
$this->data["stack"] = ord($this->get(1));
$this->data["meta"] = Utils::readShort($this->get(2), false);
$this->data["x"] = Utils::readFloat($this->get(4));
$this->data["y"] = Utils::readFloat($this->get(4));
$this->data["z"] = Utils::readFloat($this->get(4));
$this->data["yaw"] = Utils::readByte($this->get(1));
$this->data["pitch"] = Utils::readByte($this->get(1));
$this->data["roll"] = Utils::readByte($this->get(1));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeShort($this->data["block"]);
$this->raw .= chr($this->data["stack"]);
$this->raw .= Utils::writeShort($this->data["meta"]);
$this->raw .= Utils::writeFloat($this->data["x"]);
$this->raw .= Utils::writeFloat($this->data["y"]);
$this->raw .= Utils::writeFloat($this->data["z"]);
$this->raw .= Utils::writeByte($this->data["yaw"]);
$this->raw .= Utils::writeByte($this->data["pitch"]);
$this->raw .= Utils::writeByte($this->data["roll"]);
}
break;
case MC_TAKE_ITEM_ENTITY:
if($this->c === false){
$this->data["target"] = Utils::readInt($this->get(4));
$this->data["eid"] = Utils::readInt($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["target"]);
$this->raw .= Utils::writeInt($this->data["eid"]);
}
break;
case MC_MOVE_ENTITY:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readFloat($this->get(4));
$this->data["y"] = Utils::readFloat($this->get(4));
$this->data["z"] = Utils::readFloat($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeFloat($this->data["x"]);
$this->raw .= Utils::writeFloat($this->data["y"]);
$this->raw .= Utils::writeFloat($this->data["z"]);
}
break;
case MC_MOVE_ENTITY_POSROT:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readFloat($this->get(4));
$this->data["y"] = Utils::readFloat($this->get(4));
$this->data["z"] = Utils::readFloat($this->get(4));
$this->data["yaw"] = Utils::readFloat($this->get(4));
$this->data["pitch"] = Utils::readFloat($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeFloat($this->data["x"]);
$this->raw .= Utils::writeFloat($this->data["y"]);
$this->raw .= Utils::writeFloat($this->data["z"]);
$this->raw .= Utils::writeFloat($this->data["yaw"]);
$this->raw .= Utils::writeFloat($this->data["pitch"]);
}
break;
case MC_ROTATE_HEAD:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["yaw"] = Utils::readFloat($this->get(4));
$this->data["pitch"] = Utils::readFloat($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeFloat($this->data["yaw"]);
$this->raw .= Utils::writeFloat($this->data["pitch"]);
}
break;
case MC_MOVE_PLAYER:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readFloat($this->get(4));
$this->data["y"] = Utils::readFloat($this->get(4));
$this->data["z"] = Utils::readFloat($this->get(4));
$this->data["yaw"] = Utils::readFloat($this->get(4));
$this->data["pitch"] = Utils::readFloat($this->get(4));
$this->data["bodyYaw"] = Utils::readFloat($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeFloat($this->data["x"]);
$this->raw .= Utils::writeFloat($this->data["y"]);
$this->raw .= Utils::writeFloat($this->data["z"]);
$this->raw .= Utils::writeFloat($this->data["yaw"]);
$this->raw .= Utils::writeFloat($this->data["pitch"]);
$this->raw .= Utils::writeFloat($this->data["bodyYaw"]);
}
break;
case MC_PLACE_BLOCK:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readInt($this->get(4));
$this->data["z"] = Utils::readInt($this->get(4));
$this->data["y"] = ord($this->get(1));
$this->data["block"] = ord($this->get(1));
$this->data["meta"] = ord($this->get(1));
$this->data["face"] = Utils::readByte($this->get(1));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["z"]);
$this->raw .= chr($this->data["y"]);
$this->raw .= chr($this->data["block"]);
$this->raw .= chr($this->data["meta"]);
$this->raw .= chr($this->data["face"]);
}
break;
case MC_REMOVE_BLOCK: //Sent when a player removes a block, not used
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readInt($this->get(4));
$this->data["z"] = Utils::readInt($this->get(4));
$this->data["y"] = ord($this->get(1));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["z"]);
$this->raw .= chr($this->data["y"]);
}
break;
case MC_UPDATE_BLOCK:
if($this->c === false){
$this->data["x"] = Utils::readInt($this->get(4));
$this->data["z"] = Utils::readInt($this->get(4));
$this->data["y"] = ord($this->get(1));
$this->data["block"] = ord($this->get(1));
$this->data["meta"] = ord($this->get(1));
}else{
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["z"]);
$this->raw .= chr($this->data["y"]);
$this->raw .= chr($this->data["block"]);
$this->raw .= chr($this->data["meta"]);
}
break;
case MC_ADD_PAINTING:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readInt($this->get(4));
$this->data["y"] = Utils::readInt($this->get(4));
$this->data["z"] = Utils::readInt($this->get(4));
$this->data["direction"] = Utils::readInt($this->get(4));
$this->data["title"] = $this->get(Utils::readShort($this->get(2), false));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["y"]);
$this->raw .= Utils::writeInt($this->data["z"]);
$this->raw .= Utils::writeInt($this->data["direction"]);
$this->raw .= Utils::writeShort(strlen($this->data["title"])).$this->data["title"];
}
break;
case MC_EXPLOSION:
if($this->c === false){
$this->data["x"] = Utils::readFloat($this->get(4));
$this->data["y"] = Utils::readFloat($this->get(4));
$this->data["z"] = Utils::readFloat($this->get(4));
$this->data["radius"] = Utils::readFloat($this->get(4));
$this->data["count"] = Utils::readInt($this->get(4));
$this->data["records"] = array();
for($r = 0; $r < $this->data["count"] and !$this->feof(); ++$r){
$this->data["records"][] = new Vector3(Utils::readByte($this->get(1)), Utils::readByte($this->get(1)), Utils::readByte($this->get(1)));
}
}else{
$this->raw .= Utils::writeFloat($this->data["x"]);
$this->raw .= Utils::writeFloat($this->data["y"]);
$this->raw .= Utils::writeFloat($this->data["z"]);
$this->raw .= Utils::writeFloat($this->data["radius"]);
$this->data["records"] = (array) $this->data["records"];
$this->raw .= Utils::writeInt(count($this->data["records"]));
if(count($this->data["records"]) > 0){
foreach($this->data["records"] as $record){
$this->raw .= Utils::writeByte($record->x) . Utils::writeByte($record->y) . Utils::writeByte($record->z);
}
}
}
break;
case MC_LEVEL_EVENT:
if($this->c === false){
$this->data["evid"] = Utils::readShort($this->get(2));
$this->data["x"] = Utils::readShort($this->get(2));
$this->data["y"] = Utils::readShort($this->get(2));
$this->data["z"] = Utils::readShort($this->get(2));
$this->data["data"] = Utils::readInt($this->get(4));
}else{
$this->raw .= Utils::writeShort($this->data["evid"]);
$this->raw .= Utils::writeShort($this->data["x"]);
$this->raw .= Utils::writeShort($this->data["y"]);
$this->raw .= Utils::writeShort($this->data["z"]);
$this->raw .= Utils::writeInt($this->data["data"]);
}
break;
case MC_TILE_EVENT:
if($this->c === false){
$this->data["x"] = Utils::readInt($this->get(4));
$this->data["y"] = Utils::readInt($this->get(4));
$this->data["z"] = Utils::readInt($this->get(4));
$this->data["case1"] = Utils::readInt($this->get(4));
$this->data["case2"] = Utils::readInt($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["y"]);
$this->raw .= Utils::writeInt($this->data["z"]);
$this->raw .= Utils::writeInt($this->data["case1"]);
$this->raw .= Utils::writeInt($this->data["case2"]);
}
break;
case MC_ENTITY_EVENT:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["event"] = ord($this->get(1));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= chr($this->data["event"]);
}
break;
case MC_REQUEST_CHUNK:
if($this->c === false){
$this->data["x"] = Utils::readInt($this->get(4));
$this->data["z"] = Utils::readInt($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["z"]);
}
break;
case MC_CHUNK_DATA:
if($this->c === false){
$this->data["x"] = Utils::readInt($this->get(4));
$this->data["z"] = Utils::readInt($this->get(4));
$this->data["data"] = $this->get(true);
}else{
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["z"]);
$this->raw .= $this->data["data"];
}
break;
case MC_PLAYER_EQUIPMENT:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["block"] = Utils::readShort($this->get(2), false);
$this->data["meta"] = Utils::readShort($this->get(2), false);
$this->data["slot"] = ord($this->get(1));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeShort($this->data["block"]);
$this->raw .= Utils::writeShort($this->data["meta"]);
$this->raw .= chr($this->data["slot"]);
}
break;
case MC_PLAYER_ARMOR_EQUIPMENT:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["slot0"] = ord($this->get(1));
$this->data["slot1"] = ord($this->get(1));
$this->data["slot2"] = ord($this->get(1));
$this->data["slot3"] = ord($this->get(1));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= chr($this->data["slot0"]);
$this->raw .= chr($this->data["slot1"]);
$this->raw .= chr($this->data["slot2"]);
$this->raw .= chr($this->data["slot3"]);
}
break;
case MC_INTERACT:
if($this->c === false){
$this->data["action"] = Utils::readByte($this->get(1));
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["target"] = Utils::readInt($this->get(4));
}else{
$this->raw .= Utils::writeByte($this->data["action"]);
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeInt($this->data["target"]);
}
break;
case MC_USE_ITEM:
if($this->c === false){
$this->data["x"] = Utils::readInt($this->get(4));
$this->data["y"] = Utils::readInt($this->get(4));
$this->data["z"] = Utils::readInt($this->get(4));
$this->data["face"] = Utils::readInt($this->get(4));
$this->data["block"] = Utils::readShort($this->get(2));
$this->data["meta"] = Utils::readByte($this->get(1));
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["fx"] = Utils::readFloat($this->get(4));
$this->data["fy"] = Utils::readFloat($this->get(4));
$this->data["fz"] = Utils::readFloat($this->get(4));
$this->data["posX"] = Utils::readFloat($this->get(4));
$this->data["posY"] = Utils::readFloat($this->get(4));
$this->data["posZ"] = Utils::readFloat($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["y"]);
$this->raw .= Utils::writeInt($this->data["z"]);
$this->raw .= Utils::writeInt($this->data["face"]);
$this->raw .= Utils::writeShort($this->data["block"]);
$this->raw .= Utils::writeByte($this->data["meta"]);
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeFloat($this->data["fx"]);
$this->raw .= Utils::writeFloat($this->data["fy"]);
$this->raw .= Utils::writeFloat($this->data["fz"]);
$this->raw .= Utils::writeFloat($this->data["posX"]);
$this->raw .= Utils::writeFloat($this->data["posY"]);
$this->raw .= Utils::writeFloat($this->data["posZ"]);
}
break;
case MC_PLAYER_ACTION:
if($this->c === false){
$this->data["action"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readInt($this->get(4));
$this->data["y"] = Utils::readInt($this->get(4));
$this->data["z"] = Utils::readInt($this->get(4));
$this->data["face"] = Utils::readInt($this->get(4));
$this->data["eid"] = Utils::readInt($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["action"]);
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["y"]);
$this->raw .= Utils::writeInt($this->data["z"]);
$this->raw .= Utils::writeInt($this->data["face"]);
$this->raw .= Utils::writeInt($this->data["eid"]);
}
break;
case MC_SET_ENTITY_DATA:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["metadata"] = Utils::readMetadata($this->get(true));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeMetadata($this->data["metadata"]);
}
break;
case MC_SET_ENTITY_MOTION:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["speedX"] = Utils::readShort($this->get(2));
$this->data["speedY"] = Utils::readShort($this->get(2));
$this->data["speedZ"] = Utils::readShort($this->get(2));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeShort($this->data["speedX"]);
$this->raw .= Utils::writeShort($this->data["speedY"]);
$this->raw .= Utils::writeShort($this->data["speedZ"]);
}
break;
case MC_HURT_ARMOR:
if($this->c === false){
$this->data["health"] = Utils::readByte($this->get(1));
}else{
$this->raw .= Utils::writeByte($this->data["health"]);
}
break;
case MC_SET_HEALTH:
if($this->c === false){
$this->data["health"] = Utils::readByte($this->get(1));
}else{
$this->raw .= Utils::writeByte($this->data["health"]);
}
break;
case MC_SET_SPAWN_POSITION:
if($this->c === false){
$this->data["x"] = Utils::readInt($this->get(4));
$this->data["z"] = Utils::readInt($this->get(4));
$this->data["y"] = ord($this->get(1));
}else{
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["z"]);
$this->raw .= chr($this->data["y"]);
}
break;
case MC_ANIMATE:
if($this->c === false){
$this->data["action"] = Utils::readByte($this->get(1));
$this->data["eid"] = Utils::readInt($this->get(4));
}else{
$this->raw .= Utils::writeByte($this->data["action"]);
$this->raw .= Utils::writeInt($this->data["eid"]);
}
break;
case MC_RESPAWN:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["x"] = Utils::readFloat($this->get(4));
$this->data["y"] = Utils::readFloat($this->get(4));
$this->data["z"] = Utils::readFloat($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeFloat($this->data["x"]);
$this->raw .= Utils::writeFloat($this->data["y"]);
$this->raw .= Utils::writeFloat($this->data["z"]);
}
break;
case MC_SEND_INVENTORY:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["windowid"] = ord($this->get(1));
$this->data["count"] = Utils::readShort($this->get(2), false);
$this->data["slots"] = array();
for($s = 0; $s < $this->data["count"] and !$this->feof(); ++$s){
$this->data["slots"][$s] = Utils::readSlot($this);
}
if($this->data["windowid"] === 1){ //Armor is also sent
$this->data["armor"] = array(
Utils::readSlot($this),
Utils::readSlot($this),
Utils::readSlot($this),
Utils::readSlot($this)
);
}
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= chr($this->data["windowid"]);
$this->raw .= Utils::writeShort(count($this->data["slots"]));
foreach($this->data["slots"] as $slot){
$this->raw .= Utils::writeSlot($slot);
}
if($this->data["windowid"] === 1 and isset($this->data["armor"])){
$this->raw .= Utils::writeSlot($this->data["armor"][0]);
$this->raw .= Utils::writeSlot($this->data["armor"][1]);
$this->raw .= Utils::writeSlot($this->data["armor"][2]);
$this->raw .= Utils::writeSlot($this->data["armor"][3]);
}
}
break;
case MC_DROP_ITEM:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["unknown1"] = ord($this->get(1));
$this->data["block"] = Utils::readShort($this->get(2), false);
$this->data["stack"] = ord($this->get(1));
$this->data["meta"] = Utils::readShort($this->get(2), false);
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= chr($this->data["unknown1"]);
$this->raw .= Utils::writeShort($this->data["block"]);
$this->raw .= chr($this->data["stack"]);
$this->raw .= Utils::writeShort($this->data["meta"]);
}
break;
case MC_CONTAINER_OPEN:
if($this->c === false){
$this->data["windowid"] = ord($this->get(1));
$this->data["type"] = ord($this->get(1));
$this->data["slots"] = ord($this->get(1));
//$this->data["title"] = $this->get(Utils::readShort($this->get(2), false));
}else{
$this->raw .= chr($this->data["windowid"]);
$this->raw .= chr($this->data["type"]);
$this->raw .= chr($this->data["slots"]);
$this->raw .= Utils::writeInt($this->data["x"]);
$this->raw .= Utils::writeInt($this->data["y"]);
$this->raw .= Utils::writeInt($this->data["z"]);
}
break;
case MC_CONTAINER_CLOSE:
if($this->c === false){
$this->data["windowid"] = ord($this->get(1));
}else{
$this->raw .= chr($this->data["windowid"]);
}
break;
case MC_CONTAINER_SET_SLOT:
if($this->c === false){
$this->data["windowid"] = ord($this->get(1));
$this->data["slot"] = Utils::readShort($this->get(2), false);
$this->data["block"] = Utils::readShort($this->get(2), false);
$this->data["stack"] = ord($this->get(1));
$this->data["meta"] = Utils::readShort($this->get(2), false);
}else{
$this->raw .= chr($this->data["windowid"]);
$this->raw .= Utils::writeShort($this->data["slot"]);
$this->raw .= Utils::writeShort($this->data["block"]);
$this->raw .= chr($this->data["stack"]);
$this->raw .= Utils::writeShort($this->data["meta"]);
}
break;
case MC_CONTAINER_SET_CONTENT:
if($this->c === false){
$this->data["windowid"] = ord($this->get(1));
$this->data["count"] = Utils::readShort($this->get(2), false);
$this->data["slots"] = array();
for($s = 0; $s < $this->data["count"] and !$this->feof(); ++$s){
$this->data["slots"][$s] = Utils::readSlot($this);
}
if($this->data["windowid"] == 0){
$slots = min(9, Utils::readShort($this->get(2), false));
$this->data["hotbar"] = array();
if($slots > 0){
for($s = 0; $s < $slots; ++$s){
$this->data["hotbar"][$s] = Utils::readInt($this->get(4));
}
}
}
}else{
$this->raw .= chr($this->data["windowid"]);
$this->raw .= Utils::writeShort(count($this->data["slots"]));
foreach($this->data["slots"] as $slot){
$this->raw .= Utils::writeSlot($slot);
}
if($this->data["windowid"] == 0 and isset($this->data["hotbar"])){
if(count($this->data["hotbar"]) > 0){
$this->raw .= Utils::writeShort(count($this->data["hotbar"]));
foreach($this->data["hotbar"] as $slot){
$this->raw .= Utils::writeInt($slot);
}
}
}
}
break;
case MC_CONTAINER_SET_DATA:
if($this->c === false){
$this->data["windowid"] = ord($this->get(1));
$this->data["property"] = Utils::readShort($this->get(2));
$this->data["value"] = Utils::readShort($this->get(2));
}else{
$this->raw .= chr($this->data["windowid"]);
$this->raw .= Utils::writeShort($this->data["property"]);
$this->raw .= Utils::writeShort($this->data["value"]);
}
break;
case MC_CLIENT_MESSAGE:
if($this->c === false){
$this->data["message"] = $this->get(Utils::readShort($this->get(2), false));
}else{
$this->raw .= Utils::writeShort(strlen($this->data["message"])).$this->data["message"];
}
break;
case MC_ADVENTURE_SETTINGS:
if($this->c === false){
$this->data["flags"] = Utils::readInt($this->get(4));
}else{
$this->raw .= Utils::writeInt($this->data["flags"]);
}
break;
case MC_ENTITY_DATA:
if($this->c === false){
$this->data["x"] = Utils::readShort($this->get(2));
$this->data["y"] = ord($this->get(1));
$this->data["z"] = Utils::readShort($this->get(2));
$this->data["namedtag"] = $this->get(true);
}else{
$this->raw .= Utils::writeShort($this->data["x"]);
$this->raw .= chr($this->data["y"]);
$this->raw .= Utils::writeShort($this->data["z"]);
$this->raw .= $this->data["namedtag"];
}
break;
default:
if($this->c === false){
console("[DEBUG] Received unknown Data Packet ID 0x".dechex($pid), true, true, 2);
}else{
console("[DEBUG] Sent unknown Data Packet ID 0x".dechex($pid), true, true, 2);
}
break;
}
}
}

View File

@ -20,241 +20,80 @@
*/
class MinecraftInterface{
public $client;
public $bandwidth;
private $socket;
private $data;
private $chunked;
private $toChunk;
private $needCheck;
function __construct($object, $server, $port = 25565, $listen = false, $client = false, $serverip = "0.0.0.0"){
$this->socket = new UDPSocket($server, $port, (bool) $listen, $serverip);
private $packets;
function __construct($server, $port = 25565, $serverip = "0.0.0.0"){
$this->socket = new UDPSocket($server, $port, true, $serverip);
if($this->socket->connected === false){
console("[ERROR] Couldn't bind to $serverip:".$port, true, true, 0);
console("[SEVERE] Couldn't bind to $serverip:".$port, true, true, 0);
exit(1);
}
$this->bandwidth = array(0, 0, microtime(true));
$this->client = (bool) $client;
$this->start = microtime(true);
$this->chunked = array();
$this->toChunk = array();
$this->needCheck = array();
$object->schedule(1, array($this, "checkChunked"), array(), true);
$this->packets = array();
}
public function close(){
return $this->socket->close(false);
}
protected function getStruct($pid){
if(isset(Protocol::$raknet[$pid])){
return Protocol::$raknet[$pid];
}
return false;
}
public function readPacket(){
$pk = $this->popPacket();
if($this->socket->connected === false){
return $pk;
return false;
}
$buf = "";
$source = false;
$port = 1;
$len = $this->socket->read($buf, $source, $port);
if($len === false or $len === 0){
return $pk;
return false;
}
$this->bandwidth[0] += $len;
$this->parsePacket($buf, $source, $port);
return ($pk !== false ? $pk : $this->popPacket());
return $this->parsePacket($buf, $source, $port);
}
private function parsePacket($buf, $source, $port){
$pid = ord($buf{0});
$struct = $this->getStruct($pid);
if($struct === false){
if(ServerAPI::request()->api->dhandle("server.unknownpacket", array(
"pid" => $pid,
"data" => array(),
"raw" => $buf,
"ip" => $source,
"port" => $port
)) !== true){
console("[ERROR] Unknown Packet ID 0x".Utils::strToHex(chr($pid)), true, true, 2);
private function parsePacket($buffer, $source, $port){
$pid = ord($buffer{0});
if(RakNetInfo::isValid($pid)){
$parser = new RakNetParser($buffer);
if($parser->packet !== false){
$parser->packet->ip = $source;
$parser->packet->port = $port;
if(EventHandler::callEvent(new PacketReceiveEvent($parser->packet)) === BaseEvent::DENY){
return false;
}
return $parser->packet;
}
return false;
}
$packet = new Packet($pid, $struct, $buf);
@$packet->parse();
if($pid === 0x99){
$CID = PocketMinecraftServer::clientID($source, $port);
if(!isset($this->chunked[$CID]) and $packet->data[0] !== 0){ //Drop packet
}elseif($pid === 0xfe and $buffer{1} === "\xfd" and ServerAPI::request()->api->query instanceof QueryHandler){
$packet = new QueryPacket;
$packet->ip = $source;
$packet->port = $port;
$packet->buffer = $buffer;
if(EventHandler::callEvent(new PacketReceiveEvent($packet)) === BaseEvent::DENY){
return false;
}
switch($packet->data[0]){
case 0:
$this->initChunked($CID, $source, $port);
return false;
case 1:
$this->stopChunked($CID);
return false;
case 3:
$this->ackChunked($CID, $data[1]["id"], $data[1]["index"]);
return false;
case 4:
$this->receiveChunked($CID, $data[1]["id"], $data[1]["index"], $data[1]["count"], $data[1]["data"]);
return true;
}
}
$this->data[] = array($pid, $packet->data, $buf, $source, $port);
return true;
}
public function checkChunked($CID){
$time = microtime(true);
foreach($this->needCheck as $CID => $packets){
if($packets[-1] < $time){
$d = $this->chunked[$CID];
unset($packets[-1]);
foreach($packets as $packet){
$this->writePacket(0x99, $packet, true, $d[1], $d[2], true);
}
$this->needCheck[$CID][-1] = $time + 5;
}
}
foreach($this->toChunk as $CID => $packets){
$d = $this->chunked[$CID];
$raw = "";
$MTU = 512;
foreach($packets as $packet){
$raw .= $packet;
if(($len = strlen($packet)) > $MTU){
$MTU = $len;
}
}
if($MTU > $d[0][2]){
$this->chunked[$CID][0][2] = $MTU;
}else{
$MTU = $d[0][2];
}
$raw = str_split(gzdeflate($raw, DEFLATEPACKET_LEVEL), $MTU - 9); // - 1 - 2 - 2 - 2 - 2
$count = count($raw);
$messageID = $this->chunked[$CID][0][0]++;
$this->chunked[$CID][0][0] &= 0xFFFF;
if(!isset($this->needCheck[$CID])){
$this->needCheck[$CID] = array();
}
$this->needCheck[$CID][$messageID] = array(-1 => $time + 1);
foreach($raw as $index => $r){
$p = "\x99\x02".Utils::writeShort($messageID).Utils::writeShort($index).Utils::writeShort($count).Utils::writeShort(strlen($r)).$r;
$this->needCheck[$CID][$messageID][$index] = $p;
$this->writePacket(0x99, $p, true, $d[1], $d[2], true);
}
unset($this->toChunk[$CID]);
}
}
public function isChunked($CID){
return isset($this->chunked[$CID]);
}
private function initChunked($CID, $source, $port){
console("[DEBUG] Starting DEFLATEPacket for $source:$port", true, true, 2);
$this->chunked[$CID] = array(
0 => array(0, 0, 0), //index, sent/received; MTU
1 => $source,
2 => $port,
3 => array(), //Received packets
);
$this->writePacket(0x99, array(
0 => 0, //start
), false, $source, $port, true);
}
public function stopChunked($CID){
if(!isset($this->chunked[$CID])){
ServerAPI::request()->api->query->handle($packet);
}else{
$packet = new Packet();
$packet->ip = $source;
$packet->port = $port;
$packet->buffer = $buffer;
EventHandler::callEvent(new PacketReceiveEvent($packet));
return false;
}
$this->writePacket(0x99, array(
0 => 1, //stop
), false, $this->chunked[$CID][1], $this->chunked[$CID][2], true);
console("[DEBUG] Stopping DEFLATEPacket for ".$this->chunked[$CID][1].":".$this->chunked[$CID][2], true, true, 2);
$this->chunked[$CID][3] = null;
$this->chunked[$CID][4] = null;
unset($this->chunked[$CID]);
unset($this->toChunk[$CID]);
unset($this->needCheck[$CID]);
}
private function ackChunked($CID, $ID, $index){
unset($this->needCheck[$CID][$ID][$index]);
if(count($this->needCheck[$CID][$ID]) <= 1){
unset($this->needCheck[$CID][$ID]);
}
}
private function receiveChunked($CID, $ID, $index, $count, $data){
if(!isset($this->chunked[$CID][3][$ID])){
$this->chunked[$CID][3][$ID] = array();
}
$this->chunked[$CID][3][$ID][$index] = $data;
if(count($this->chunked[$CID][3][$ID]) === $count){
ksort($this->chunked[$CID][3][$ID]);
$data = gzinflate(implode($this->chunked[$CID][3][$ID]), 524280);
unset($this->chunked[$CID][3][$ID]);
if($data === false or strlen($data) === 0){
console("[ERROR] Invalid DEFLATEPacket for ".$this->chunked[$CID][1].":".$this->chunked[$CID][2], true, true, 2);
}
$offset = 0;
while(($plen = Utils::readShort(substr($data, $offset, 2), false)) !== 0xFFFF or $offset >= $len){
$offset += 2;
$packet = substr($data, $offset, $plen);
$this->parsePacket($packet, $this->chunked[$CID][1], $this->chunked[$CID][2]);
}
}
}
public function popPacket(){
if(count($this->data) > 0){
$p = each($this->data);
unset($this->data[$p[0]]);
$p = $p[1];
return array("pid" => $p[0], "data" => $p[1], "raw" => $p[2], "ip" => $p[3], "port" => $p[4]);
}
return false;
}
public function writePacket($pid, $data = array(), $raw = false, $dest = false, $port = false, $force = false){
$CID = PocketMinecraftServer::clientID($dest, $port);
if($raw === false){
$packet = new Packet($pid, $this->getStruct($pid));
$packet->data = $data;
@$packet->create();
if($force === false and $this->isChunked($CID)){
if(!isset($this->toChunk[$CID])){
$this->toChunk[$CID] = array();
}
$this->toChunk[$CID][] = $packet->raw;
$write = strlen($packet->raw);
}else{
$write = $this->socket->write($packet->raw, $dest, $port);
$this->bandwidth[1] += $write;
}
}else{
if($force === false and $this->isChunked($CID)){
if(!isset($this->toChunk[$CID])){
$this->toChunk[$CID] = array();
}
$this->toChunk[$CID][] = $data;
$write = strlen($data);
}else{
$write = $this->socket->write($data, $dest, $port);
$this->bandwidth[1] += $write;
}
public function writePacket(Packet $packet){
if(EventHandler::callEvent(new PacketSendEvent($packet)) === BaseEvent::DENY){
return 0;
}elseif($packet instanceof RakNetPacket){
$codec = new RakNetCodec($packet);
}
$write = $this->socket->write($packet->buffer, $packet->ip, $packet->port);
$this->bandwidth[1] += $write;
return $write;
}

View File

@ -19,325 +19,9 @@
*
*/
class Packet{
private $struct;
protected $pid, $packet;
public $data, $raw;
function __construct($pid, $struct, $data = ""){
$this->pid = $pid;
$this->offset = 1;
$this->raw = $data;
$this->data = array();
if($data === ""){
$this->addRaw(chr($pid));
}
$this->struct = $struct;
}
public function create($raw = false){
foreach($this->struct as $field => $type){
if(!isset($this->data[$field])){
$this->data[$field] = "";
}
if($raw === true){
$this->addRaw($this->data[$field]);
continue;
}
switch($type){
case "special1":
switch($this->pid){
case 0x99:
if($this->data[0] >= 2){
$this->addRaw(Utils::writeShort($this->data[1]["id"]));
$this->addRaw(Utils::writeShort($this->data[1]["index"]));
if($this->data[0] === 2){
$this->addRaw(Utils::writeShort($this->data[1]["count"]));
$this->addRaw(Utils::writeShort(strlen($this->data[1]["data"])).$this->data[1]["data"]);
}
}
break;
case 0xc0:
case 0xa0:
$payload = "";
$records = 0;
$pointer = 0;
sort($this->data[$field], SORT_NUMERIC);
$max = count($this->data[$field]);
while($pointer < $max){
$type = true;
$curr = $start = $this->data[$field][$pointer];
for($i = $start + 1; $i < $max; ++$i){
$n = $this->data[$field][$i];
if(($n - $curr) === 1){
$curr = $end = $n;
$type = false;
$pointer = $i + 1;
}else{
break;
}
}
++$pointer;
if($type === false){
$payload .= Utils::writeBool(false);
$payload .= strrev(Utils::writeTriad($start));
$payload .= strrev(Utils::writeTriad($end));
}else{
$payload .= Utils::writeBool(true);
$payload .= strrev(Utils::writeTriad($start));
}
++$records;
}
$this->addRaw(Utils::writeShort($records) . $payload);
break;
case 0x05:
$this->addRaw($this->data[$field]);
break;
}
break;
case "customData":
$this->addRaw(chr($this->data[1]));
if($this->data[2]["id"] === false){
$this->addRaw($this->data[2]["raw"]);
}else{
switch($this->data[1]){
case 0x40:
$reply = new CustomPacketHandler($this->data[2]["id"], "", $this->data[2], true);
$this->addRaw(Utils::writeShort((strlen($reply->raw) + 1) << 3));
$this->addRaw(strrev(Utils::writeTriad($this->data[2]["count"])));
$this->addRaw(chr($this->data[2]["id"]));
$this->addRaw($reply->raw);
break;
case 0x00:
$raw = new CustomPacketHandler($this->data[2]["id"], "", $this->data[2], true);
$raw = $raw->raw;
$this->addRaw(Utils::writeShort((strlen($raw) + 1) << 3));
$this->addRaw(chr($this->data[2]["id"]));
$this->addRaw($raw);
break;
}
}
break;
case "magic":
$this->addRaw(RAKNET_MAGIC);
break;
case "float":
$this->addRaw(Utils::writeFloat($this->data[$field]));
break;
case "triad":
$this->addRaw(Utils::writeTriad($this->data[$field]));
break;
case "itriad":
$this->addRaw(strrev(Utils::writeTriad($this->data[$field])));
break;
case "int":
$this->addRaw(Utils::writeInt($this->data[$field]));
break;
case "double":
$this->addRaw(Utils::writeDouble($this->data[$field]));
break;
case "long":
$this->addRaw(Utils::writeLong($this->data[$field]));
break;
case "bool":
case "boolean":
$this->addRaw(Utils::writeBool($this->data[$field]));
break;
case "ubyte":
case "byte":
$this->addRaw(Utils::writeByte($this->data[$field]));
break;
case "short":
$this->addRaw(Utils::writeShort($this->data[$field]));
break;
case "string":
$this->addRaw(Utils::writeShort(strlen($this->data[$field])));
$this->addRaw($this->data[$field]);
break;
default:
$this->addRaw(Utils::writeByte($this->data[$field]));
break;
}
}
}
private function get($len = true){
if($len === true){
$data = substr($this->raw, $this->offset);
$this->offset = strlen($this->raw);
return $data;
}
$data = substr($this->raw, $this->offset, $len);
$this->offset += $len;
return $data;
}
private function feof(){
return !isset($this->raw{$this->offset});
}
protected function addRaw($str){
$this->raw .= $str;
return $str;
}
public function parse(){
foreach($this->struct as $field => $type){
switch($type){
case "special1":
switch($this->pid){
case 0x07:
$this->data[] = $this->get(5);
break;
case 0x99:
if($this->data[0] >= 2){ //
$messageID = Utils::readShort($this->get(2), false);
$messageIndex = Utils::readShort($this->get(2), false);
$this->data[1] = array("id" => $messageID, "index" => $messageIndex);
if($this->data[0] === 2){
$this->data[1]["count"] = Utils::readShort($this->get(2), false);
$dataLength = Utils::readShort($this->get(2), false);
$this->data[1]["data"] = $this->get($dataLength);
}
}
break;
case 0xc0:
case 0xa0:
$cnt = Utils::readShort($this->get(2), false);
$this->data[$field] = array();
for($i = 0; $i < $cnt and !$this->feof(); ++$i){
if(Utils::readBool($this->get(1)) === false){
$start = Utils::readTriad(strrev($this->get(3)));
$end = min(Utils::readTriad(strrev($this->get(3))), $start + 4096);
for($c = $start; $c <= $end; ++$c){
$this->data[$field][] = $c;
}
}else{
$this->data[$field][] = Utils::readTriad(strrev($this->get(3)));
}
}
break;
case 0x05:
$this->data[] = $this->get(true);
break;
}
break;
case "customData":
$raw = $this->get(true);
$len = strlen($raw);
$offset = 0;
$this->data["packets"] = array();
while($len > $offset){
$pid = ord($raw{$offset});
++$offset;
$reliability = ($pid & 0b11100000) >> 5;
$hasSplit = ($pid & 0b00010000) >> 4;
$length = Utils::readShort(substr($raw, $offset, 2), false);
$offset += 2;
if($reliability === 2
or $reliability === 3
or $reliability === 4
or $reliability === 6
or $reliability === 7){
$messageIndex = Utils::readTriad(strrev(substr($raw, $offset, 3)));
$offset += 3;
}else{
$messageIndex = 0;
}
if($reliability === 1
or $reliability === 3
or $reliability === 4
or $reliability === 7){
$orderIndex = Utils::readTriad(strrev(substr($raw, $offset, 3)));
$offset += 3;
$orderChannel = ord($raw{$offset}); //5 bits, 32 values
++$offset;
}else{
$orderIndex = 0;
$orderChannel = 0;
}
if($hasSplit === 1){
$splitCount = Utils::readInt(substr($raw, $offset, 4));
$offset += 4;
$splitID = Utils::readShort(substr($raw, $offset, 2));
$offset += 2;
$splitIndex = Utils::readInt(substr($raw, $offset, 4));
$offset += 4;
//error! no split packets allowed!
break;
}else{
$splitCount = 0;
$splitID = 0;
$splitIndex = 0;
}
if($length == 0
or $orderChannel >= 32
or ($hasSplit === 1 and $splitIndex >= $splitCount)){
continue;
}
$ln = ceil($length / 8);
$id = ord($raw{$offset});
++$offset;
$pak = substr($raw, $offset, $ln - 1);
$offset += $ln - 1;
$pk = new CustomPacketHandler($id, $pak);
$pk->data["length"] = $ln;
$pk->data["id"] = $id;
$pk->data["counter"] = $messageIndex;
$pk->data["packetName"] = $pk->name;
$this->data["packets"][] = array($pid, $pk->data, $pak);
}
break;
case "magic":
$this->data[] = $this->get(16);
break;
case "triad":
$this->data[] = Utils::readTriad($this->get(3));
break;
case "itriad":
$this->data[] = Utils::readTriad(strrev($this->get(3)));
break;
case "int":
$this->data[] = Utils::readInt($this->get(4));
break;
case "string":
$this->data[] = $this->get(Utils::readShort($this->get(2)));
break;
case "long":
$this->data[] = Utils::readLong($this->get(8));
break;
case "byte":
$this->data[] = Utils::readByte($this->get(1));
break;
case "ubyte":
$this->data[] = ord($this->get(1));
break;
case "float":
$this->data[] = Utils::readFloat($this->get(4));
break;
case "double":
$this->data[] = Utils::readDouble($this->get(8));
break;
case "ushort":
$this->data[] = Utils::readShort($this->get(2), false);
break;
case "short":
$this->data[] = Utils::readShort($this->get(2));
break;
case "bool":
case "boolean":
$this->data[] = Utils::readBool($this->get(1));
break;
}
}
}
class Packet extends stdClass{
public $ip;
public $port;
public $buffer;
}

View File

@ -1,259 +0,0 @@
<?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/
*
*
*/
define("DEFLATEPACKET_LEVEL", 1);
define("CURRENT_STRUCTURE", 5);
define("CURRENT_PROTOCOL", 14);
define("RAKNET_MAGIC", "\x00\xff\xff\x00\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78");
define("MC_PING", 0x00);
define("MC_PONG", 0x03);
define("MC_CLIENT_CONNECT", 0x09);
define("MC_SERVER_HANDSHAKE", 0x10);
define("MC_CLIENT_HANDSHAKE", 0x13);
define("MC_SERVER_FULL", 0x14);
define("MC_DISCONNECT", 0x15);
define("MC_BANNED", 0x17);
define("MC_LOGIN", 0x82);
define("MC_LOGIN_STATUS", 0x83);
define("MC_READY", 0x84);
define("MC_CHAT", 0x85);
define("MC_SET_TIME", 0x86);
define("MC_START_GAME", 0x87);
define("MC_ADD_MOB", 0x88);
define("MC_ADD_PLAYER", 0x89);
define("MC_REMOVE_PLAYER", 0x8a);
define("MC_ADD_ENTITY", 0x8c);
define("MC_REMOVE_ENTITY", 0x8d);
define("MC_ADD_ITEM_ENTITY", 0x8e);
define("MC_TAKE_ITEM_ENTITY", 0x8f);
define("MC_MOVE_ENTITY", 0x90);
define("MC_MOVE_ENTITY_POSROT", 0x93);
define("MC_ROTATE_HEAD", 0x94);
define("MC_MOVE_PLAYER", 0x95);
define("MC_PLACE_BLOCK", 0x96);
define("MC_REMOVE_BLOCK", 0x97);
define("MC_UPDATE_BLOCK", 0x98);
define("MC_ADD_PAINTING", 0x99);
define("MC_EXPLOSION", 0x9a);
define("MC_LEVEL_EVENT", 0x9b);
define("MC_TILE_EVENT", 0x9c);
define("MC_ENTITY_EVENT", 0x9d);
define("MC_REQUEST_CHUNK", 0x9e);
define("MC_CHUNK_DATA", 0x9f);
define("MC_PLAYER_EQUIPMENT", 0xa0);
define("MC_PLAYER_ARMOR_EQUIPMENT", 0xa1);
define("MC_INTERACT", 0xa2);
define("MC_USE_ITEM", 0xa3);
define("MC_PLAYER_ACTION", 0xa4);
define("MC_HURT_ARMOR", 0xa6);
define("MC_SET_ENTITY_DATA", 0xa7);
define("MC_SET_ENTITY_MOTION", 0xa8);
//define("MC_SET_ENTITY_LINK", 0xa9);
define("MC_SET_HEALTH", 0xaa);
define("MC_SET_SPAWN_POSITION", 0xab);
define("MC_ANIMATE", 0xac);
define("MC_RESPAWN", 0xad);
define("MC_SEND_INVENTORY", 0xae);
define("MC_DROP_ITEM", 0xaf);
define("MC_CONTAINER_OPEN", 0xb0);
define("MC_CONTAINER_CLOSE", 0xb1);
define("MC_CONTAINER_SET_SLOT", 0xb2);
define("MC_CONTAINER_SET_DATA", 0xb3);
define("MC_CONTAINER_SET_CONTENT", 0xb4);
//define("MC_CONTAINER_ACK", 0xb5);
define("MC_CLIENT_MESSAGE", 0xb6);
define("MC_ADVENTURE_SETTINGS", 0xb7);
define("MC_ENTITY_DATA", 0xb8);
//define("MC_PLAYER_INPUT", 0xb9);
class Protocol{
public static $raknet = array(
0x01 => array(
"long", //Ping ID
"magic",
),
0x02 => array(
"long", //Ping ID
"magic",
),
0x05 => array(
"magic",
"byte", //Protocol Version
"special1", //MTU Size Null Lenght
),
0x06 => array(
"magic",
"long", //Server GUID
"byte", //Server Security
"short", //MTU Size
),
0x07 => array(
"magic",
"special1", //Security Cookie
"short", //Server UDP Port
"short", //MTU Size
"long", //Client GUID
),
0x08 => array(
"magic",
"long", //Server GUID
"short", //Client UDP Port
"short", //MTU Size
"byte", //Security
),
0x1a => array(
"byte", //Server Version
"magic",
"long", //Server GUID
),
0x1c => array(
"long", //Ping ID
"long", //Server GUID
"magic",
"string", //Data
),
0x1d => array(
"long", //Ping ID
"long", //Server GUID
"magic",
"string", //Data
),
0x80 => array(
"itriad",
"customData",
),
0x81 => array(
"itriad",
"customData",
),
0x82 => array(
"itriad",
"customData",
),
0x83 => array(
"itriad",
"customData",
),
0x84 => array(
"itriad",
"customData",
),
0x85 => array(
"itriad",
"customData",
),
0x86 => array(
"itriad",
"customData",
),
0x87 => array(
"itriad",
"customData",
),
0x88 => array(
"itriad",
"customData",
),
0x89 => array(
"itriad",
"customData",
),
0x8a => array(
"itriad",
"customData",
),
0x8b => array(
"itriad",
"customData",
),
0x8c => array(
"itriad",
"customData",
),
0x8d => array(
"itriad",
"customData",
),
0x8e => array(
"itriad",
"customData",
),
0x8f => array(
"itriad",
"ubyte",
"customData",
),
0x99 => array(
"byte",
"special1",
),
0xa0 => array(
"special1",
),
0xc0 => array(
"special1",
),
);
}

View File

@ -34,8 +34,8 @@ class UDPSocket{
}else{
if(socket_bind($this->sock, $serverip, $port) === true){
socket_set_option($this->sock, SOL_SOCKET, SO_REUSEADDR, 0);
socket_set_option($this->sock, SOL_SOCKET, SO_SNDBUF, 65535);
socket_set_option($this->sock, SOL_SOCKET, SO_RCVBUF, 65535);
socket_set_option($this->sock, SOL_SOCKET, SO_SNDBUF, 1024 * 1024 * 2); //2MB
socket_set_option($this->sock, SOL_SOCKET, SO_RCVBUF, 1024 * 1024); //1MB
$this->unblock();
$this->connected = true;
}else{
@ -64,11 +64,11 @@ class UDPSocket{
return @socket_recvfrom($this->sock, $buf, 65535, 0, $source, $port);
}
public function write($data, $dest = false, $port = false){
public function write($data, $dest, $port){
if($this->connected === false){
return false;
}
return @socket_sendto($this->sock, $data, strlen($data), 0, ($dest === false ? $this->server:$dest), ($port === false ? $this->port:$port));
return @socket_sendto($this->sock, $data, strlen($data), 0, $dest, $port);
}
}

View File

@ -0,0 +1,160 @@
<?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/
*
*
*/
class ProtocolInfo{
const CURRENT_PROTOCOL = 14;
const PING_PACKET = 0x00;
const PONG_PACKET = 0x03;
const CLIENT_CONNECT_PACKET = 0x09;
const SERVER_HANDSHAKE_PACKET = 0x10;
const CLIENT_HANDSHAKE_PACKET = 0x13;
//const SERVER_FULL_PACKET = 0x14;
const DISCONNECT_PACKET = 0x15;
//const BANNED_PACKET = 0x17;
const LOGIN_PACKET = 0x82;
const LOGIN_STATUS_PACKET = 0x83;
const READY_PACKET = 0x84;
const MESSAGE_PACKET = 0x85;
const SET_TIME_PACKET = 0x86;
const START_GAME_PACKET = 0x87;
const ADD_MOB_PACKET = 0x88;
const ADD_PLAYER_PACKET = 0x89;
const REMOVE_PLAYER_PACKET = 0x8a;
const ADD_ENTITY_PACKET = 0x8c;
const REMOVE_ENTITY_PACKET = 0x8d;
const ADD_ITEM_ENTITY_PACKET = 0x8e;
const TAKE_ITEM_ENTITY_PACKET = 0x8f;
const MOVE_ENTITY_PACKET = 0x90;
const MOVE_ENTITY_PACKET_POSROT = 0x93;
const ROTATE_HEAD_PACKET = 0x94;
const MOVE_PLAYER_PACKET = 0x95;
//const PLACE_BLOCK_PACKET = 0x96;
const REMOVE_BLOCK_PACKET = 0x97;
const UPDATE_BLOCK_PACKET = 0x98;
const ADD_PAINTING_PACKET = 0x99;
const EXPLODE_PACKET = 0x9a;
const LEVEL_EVENT_PACKET = 0x9b;
const TILE_EVENT_PACKET = 0x9c;
const ENTITY_EVENT_PACKET = 0x9d;
const REQUEST_CHUNK_PACKET = 0x9e;
const CHUNK_DATA_PACKET = 0x9f;
const PLAYER_EQUIPMENT_PACKET = 0xa0;
const PLAYER_ARMOR_EQUIPMENT_PACKET = 0xa1;
const INTERACT_PACKET = 0xa2;
const USE_ITEM_PACKET = 0xa3;
const PLAYER_ACTION_PACKET = 0xa4;
const HURT_ARMOR_PACKET = 0xa6;
const SET_ENTITY_DATA_PACKET = 0xa7;
const SET_ENTITY_MOTION_PACKET = 0xa8;
//const SET_ENTITY_LINK_PACKET = 0xa9;
const SET_HEALTH_PACKET = 0xaa;
const SET_SPAWN_POSITION_PACKET = 0xab;
const ANIMATE_PACKET = 0xac;
const RESPAWN_PACKET = 0xad;
const SEND_INVENTORY_PACKET = 0xae;
const DROP_ITEM_PACKET = 0xaf;
const CONTAINER_OPEN_PACKET = 0xb0;
const CONTAINER_CLOSE_PACKET = 0xb1;
const CONTAINER_SET_SLOT_PACKET = 0xb2;
const CONTAINER_SET_DATA_PACKET = 0xb3;
const CONTAINER_SET_CONTENT_PACKET = 0xb4;
//const CONTAINER_ACK_PACKET = 0xb5;
const CHAT_PACKET = 0xb6;
const ADVENTURE_SETTINGS_PACKET = 0xb7;
const ENTITY_DATA_PACKET = 0xb8;
//const PLAYER_INPUT_PACKET = 0xb9;
public static $packets = array(
-1 => "UnknownPacket",
ProtocolInfo::PING_PACKET => "PingPacket",
ProtocolInfo::PONG_PACKET => "PongPacket",
ProtocolInfo::CLIENT_CONNECT_PACKET => "ClientConnectPacket",
ProtocolInfo::SERVER_HANDSHAKE_PACKET => "ServerHandshakePacket",
ProtocolInfo::DISCONNECT_PACKET => "DisconnectPacket",
ProtocolInfo::LOGIN_PACKET => "LoginPacket",
ProtocolInfo::LOGIN_STATUS_PACKET => "LoginStatusPacket",
ProtocolInfo::READY_PACKET => "ReadyPacket",
ProtocolInfo::MESSAGE_PACKET => "MessagePacket",
ProtocolInfo::SET_TIME_PACKET => "SetTimePacket",
ProtocolInfo::START_GAME_PACKET => "StartGamePacket",
ProtocolInfo::ADD_MOB_PACKET => "AddMobPacket",
ProtocolInfo::ADD_PLAYER_PACKET => "AddPlayerPacket",
ProtocolInfo::REMOVE_PLAYER_PACKET => "RemovePlayerPacket",
ProtocolInfo::ADD_ENTITY_PACKET => "AddEntityPacket",
ProtocolInfo::REMOVE_ENTITY_PACKET => "RemoveEntityPacket",
ProtocolInfo::ADD_ITEM_ENTITY_PACKET => "AddItemEntityPacket",
ProtocolInfo::TAKE_ITEM_ENTITY_PACKET => "TakeItemEntityPacket",
ProtocolInfo::MOVE_ENTITY_PACKET => "MoveEntityPacket",
ProtocolInfo::MOVE_ENTITY_PACKET_POSROT => "MoveEntityPacket_PosRot",
ProtocolInfo::ROTATE_HEAD_PACKET => "RotateHeadPacket",
ProtocolInfo::MOVE_PLAYER_PACKET => "MovePlayerPacket",
ProtocolInfo::REMOVE_BLOCK_PACKET => "RemoveBlockPacket",
ProtocolInfo::UPDATE_BLOCK_PACKET => "UpdateBlockPacket",
ProtocolInfo::ADD_PAINTING_PACKET => "AddPaintingPacket",
ProtocolInfo::EXPLODE_PACKET => "ExplodePacket",
ProtocolInfo::LEVEL_EVENT_PACKET => "LevelEventPacket",
ProtocolInfo::TILE_EVENT_PACKET => "TileEventPacket",
ProtocolInfo::ENTITY_EVENT_PACKET => "EntityEventPacket",
ProtocolInfo::REQUEST_CHUNK_PACKET => "RequestChunkPacket",
ProtocolInfo::CHUNK_DATA_PACKET => "ChunkDataPacket",
ProtocolInfo::PLAYER_EQUIPMENT_PACKET => "PlayerEquipmentPacket",
ProtocolInfo::PLAYER_ARMOR_EQUIPMENT_PACKET => "PlayerArmorEquipmentPacket",
ProtocolInfo::INTERACT_PACKET => "InteractPacket",
ProtocolInfo::USE_ITEM_PACKET => "UseItemPacket",
ProtocolInfo::PLAYER_ACTION_PACKET => "PlayerActionPacket",
ProtocolInfo::HURT_ARMOR_PACKET => "HurtArmorPacket",
ProtocolInfo::SET_ENTITY_DATA_PACKET => "SetEntityDataPacket",
ProtocolInfo::SET_ENTITY_MOTION_PACKET => "SetEntityMotionPacket",
ProtocolInfo::SET_HEALTH_PACKET => "SetHealthPacket",
ProtocolInfo::SET_SPAWN_POSITION_PACKET => "SetSpawnPositionPacket",
ProtocolInfo::ANIMATE_PACKET => "AnimatePacket",
ProtocolInfo::RESPAWN_PACKET => "RespawnPacket",
ProtocolInfo::SEND_INVENTORY_PACKET => "SendInventoryPacket",
ProtocolInfo::DROP_ITEM_PACKET => "DropItemPacket",
ProtocolInfo::CONTAINER_OPEN_PACKET => "ContainerOpenPacket",
ProtocolInfo::CONTAINER_CLOSE_PACKET => "ContainerClosePacket",
ProtocolInfo::CONTAINER_SET_SLOT_PACKET => "ContainerSetSlotPacket",
ProtocolInfo::CONTAINER_SET_DATA_PACKET => "ContainerSetDataPacket",
ProtocolInfo::CONTAINER_SET_CONTENT_PACKET => "ContainerSetContentPacket",
ProtocolInfo::CHAT_PACKET => "ChatPacket",
ProtocolInfo::ADVENTURE_SETTINGS_PACKET => "AdventureSettingsPacket",
ProtocolInfo::ENTITY_DATA_PACKET => "EntityDataPacket",
);
}
/***REM_START***/
require_once(FILE_PATH . "src/network/raknet/RakNetDataPacket.php");
/***REM_END***/

View File

@ -0,0 +1,56 @@
<?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/
*
*
*/
class AddEntityPacket extends RakNetDataPacket{
public $eid;
public $type;
public $x;
public $y;
public $z;
public $did;
public $speedX;
public $speedY;
public $speedZ;
public function pid(){
return ProtocolInfo::ADD_ENTITY_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putByte($this->type);
$this->putFloat($this->x);
$this->putFloat($this->y);
$this->putFloat($this->z);
$this->putInt($this->did);
if($this->did > 0){
$this->putShort($this->speedX);
$this->putShort($this->speedY);
$this->putShort($this->speedZ);
}
}
}

View File

@ -0,0 +1,52 @@
<?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/
*
*
*/
class AddItemEntityPacket extends RakNetDataPacket{
public $eid;
public $item;
public $x;
public $y;
public $z;
public $yaw;
public $pitch;
public $roll;
public function pid(){
return ProtocolInfo::ADD_ITEM_ENTITY_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putSlot($this->item);
$this->putFloat($this->x);
$this->putFloat($this->y);
$this->putFloat($this->z);
$this->putByte($this->yaw);
$this->putByte($this->pitch);
$this->putByte($this->roll);
}
}

View File

@ -0,0 +1,52 @@
<?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/
*
*
*/
class AddMobPacket extends RakNetDataPacket{
public $eid;
public $type;
public $x;
public $y;
public $z;
public $pitch;
public $yaw;
public $metadata;
public function pid(){
return ProtocolInfo::ADD_MOB_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putInt($this->type);
$this->putFloat($this->x);
$this->putFloat($this->y);
$this->putFloat($this->z);
$this->putByte($this->yaw);
$this->putByte($this->pitch);
$this->put(Utils::writeMetadata($this->metadata));
}
}

View File

@ -0,0 +1,48 @@
<?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/
*
*
*/
class AddPaintingPacket extends RakNetDataPacket{
public $eid;
public $x;
public $y;
public $z;
public $direction;
public $title;
public function pid(){
return ProtocolInfo::ADD_PAINTING_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putInt($this->x);
$this->putInt($this->y);
$this->putInt($this->z);
$this->putInt($this->direction);
$this->putString($this->title);
}
}

View File

@ -0,0 +1,58 @@
<?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/
*
*
*/
class AddPlayerPacket extends RakNetDataPacket{
public $clientID;
public $username;
public $eid;
public $x;
public $y;
public $z;
public $pitch;
public $yaw;
public $unknown1;
public $unknown2;
public $metadata;
public function pid(){
return ProtocolInfo::ADD_PLAYER_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putLong($this->clientID);
$this->putString($this->username);
$this->putInt($this->eid);
$this->putFloat($this->x);
$this->putFloat($this->y);
$this->putFloat($this->z);
$this->putByte($this->yaw);
$this->putByte($this->pitch);
$this->putShort($this->unknown1);
$this->putShort($this->unknown2);
$this->put(Utils::writeMetadata($this->metadata));
}
}

View File

@ -0,0 +1,38 @@
<?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/
*
*
*/
class AdventureSettingsPacket extends RakNetDataPacket{
public $flags;
public function pid(){
return ProtocolInfo::ADVENTURE_SETTINGS_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->flags);
}
}

View File

@ -0,0 +1,41 @@
<?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/
*
*
*/
class AnimatePacket extends RakNetDataPacket{
public $action;
public $eid;
public function pid(){
return ProtocolInfo::ANIMATE_PACKET;
}
public function decode(){
$this->action = $this->getByte();
$this->eid = $this->getInt();
}
public function encode(){
$this->reset();
$this->putByte($this->action);
$this->putInt($this->eid);
}
}

View File

@ -0,0 +1,38 @@
<?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/
*
*
*/
class ChatPacket extends RakNetDataPacket{
public $message;
public function pid(){
return ProtocolInfo::CHAT_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putString($this->message);
}
}

View File

@ -0,0 +1,42 @@
<?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/
*
*
*/
class ChunkDataPacket extends RakNetDataPacket{
public $chunkX;
public $chunkZ;
public $data;
public function pid(){
return ProtocolInfo::CHUNK_DATA_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->chunkX);
$this->putInt($this->chunkZ);
$this->put($this->data);
}
}

View File

@ -0,0 +1,41 @@
<?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/
*
*
*/
class ClientConnectPacket extends RakNetDataPacket{
public $clientID;
public $session;
public $unknown1;
public function pid(){
return ProtocolInfo::CLIENT_CONNECT_PACKET;
}
public function decode(){
$this->clientID = $this->getLong();
$this->session = $this->getLong();
$this->unknown1 = $this->get(1);
}
public function encode(){
}
}

View File

@ -0,0 +1,51 @@
<?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/
*
*
*/
class ClientHandshakePacket extends RakNetDataPacket{
public $cookie;
public $security;
public $port;
public $dataArray0;
public $dataArray;
public $timestamp;
public $session2;
public $session;
public function pid(){
return ProtocolInfo::CLIENT_HANDSHAKE_PACKET;
}
public function decode(){
$this->cookie = $this->get(4);
$this->security = $this->get(1);
$this->port = $this->getShort(true);
$this->dataArray0 = $this->get($this->getByte());
$this->dataArray = $this->getDataArray(9);
$this->timestamp = $this->get(2);
$this->session2 = $this->getLong();
$this->session = $this->getLong();
}
public function encode(){
}
}

View File

@ -0,0 +1,38 @@
<?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/
*
*
*/
class ContainerClosePacket extends RakNetDataPacket{
public $windowid;
public function pid(){
return ProtocolInfo::CONTAINER_CLOSE_PACKET;
}
public function decode(){
$this->windowid = $this->getByte();
}
public function encode(){
$this->reset();
$this->putByte($this->windowid);
}
}

View File

@ -0,0 +1,48 @@
<?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/
*
*
*/
class ContainerOpenPacket extends RakNetDataPacket{
public $windowid;
public $type;
public $slots;
public $x;
public $y;
public $z;
public function pid(){
return ProtocolInfo::CONTAINER_OPEN_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putByte($this->windowid);
$this->putByte($this->type);
$this->putByte($this->slots);
$this->putInt($this->x);
$this->putInt($this->y);
$this->putInt($this->z);
}
}

View File

@ -0,0 +1,60 @@
<?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/
*
*
*/
class ContainerSetContentPacket extends RakNetDataPacket{
public $windowid;
public $slots = array();
public $hotbar = array();
public function pid(){
return ProtocolInfo::CONTAINER_SET_CONTENT_PACKET;
}
public function decode(){
$this->windowid = $this->getByte();
$count = $this->getShort();
for($s = 0; $s < $count and !$this->feof(); ++$s){
$this->slots[$s] = $this->getSlot();
}
if($this->windowid === 0){
$count = $this->getShort();
for($s = 0; $s < $count and !$this->feof(); ++$s){
$this->hotbar[$s] = $this->getInt();
}
}
}
public function encode(){
$this->reset();
$this->putByte($this->windowid);
$this->putShort(count($this->slots));
foreach($this->slots as $slot){
$this->putSlot($slot);
}
if($this->windowid === 0 and count($this->hotbar) > 0){
$this->putShort(count($this->hotbar));
foreach($this->hotbar as $slot){
$this->putInt($slot);
}
}
}
}

View File

@ -0,0 +1,42 @@
<?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/
*
*
*/
class ContainerSetDataPacket extends RakNetDataPacket{
public $windowid;
public $property;
public $value;
public function pid(){
return ProtocolInfo::CONTAINER_SET_DATA_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putByte($this->windowid);
$this->putShort($this->property);
$this->putShort($this->value);
}
}

View File

@ -0,0 +1,44 @@
<?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/
*
*
*/
class ContainerSetSlotPacket extends RakNetDataPacket{
public $windowid;
public $slot;
public $item;
public function pid(){
return ProtocolInfo::CONTAINER_SET_SLOT_PACKET;
}
public function decode(){
$this->windowid = $this->getByte();
$this->slot = $this->getShort();
$this->item = $this->getSlot();
}
public function encode(){
$this->reset();
$this->putByte($this->windowid);
$this->putShort($this->slot);
$this->putSlot($this->item);
}
}

View File

@ -0,0 +1,35 @@
<?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/
*
*
*/
class DisconnectPacket extends RakNetDataPacket{
public function pid(){
return ProtocolInfo::DISCONNECT_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
}
}

View File

@ -0,0 +1,41 @@
<?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/
*
*
*/
class DropItemPacket extends RakNetDataPacket{
public $eid;
public $unknown;
public $item;
public function pid(){
return ProtocolInfo::DROP_ITEM_PACKET;
}
public function decode(){
$this->eid = $this->getInt();
$this->unknown = $this->getByte();
$this->item = $this->getSlot();
}
public function encode(){
}
}

View File

@ -0,0 +1,47 @@
<?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/
*
*
*/
class EntityDataPacket extends RakNetDataPacket{
public $x;
public $y;
public $z;
public $namedtag;
public function pid(){
return ProtocolInfo::ENTITY_DATA_PACKET;
}
public function decode(){
$this->x = $this->getShort();
$this->y = $this->getByte();
$this->z = $this->getShort();
$this->namedtag = $this->get(true);
}
public function encode(){
$this->reset();
$this->putShort($this->x);
$this->putByte($this->y);
$this->putShort($this->z);
$this->put($this->namedtag);
}
}

View File

@ -0,0 +1,41 @@
<?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/
*
*
*/
class EntityEventPacket extends RakNetDataPacket{
public $eid;
public $event;
public function pid(){
return ProtocolInfo::ENTITY_EVENT_PACKET;
}
public function decode(){
$this->eid = $this->getInt();
$this->event = $this->getByte();
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putByte($this->event);
}
}

View File

@ -0,0 +1,53 @@
<?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/
*
*
*/
class ExplodePacket extends RakNetDataPacket{
public $x;
public $y;
public $z;
public $radius;
public $records;
public function pid(){
return ProtocolInfo::EXPLODE_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putFloat($this->x);
$this->putFloat($this->y);
$this->putFloat($this->z);
$this->putFloat($this->radius);
$this->putInt(@count($this->records));
if(@count($this->records) > 0){
foreach($this->records as $record){
$this->putByte($record->x);
$this->putByte($record->y);
$this->putByte($record->z);
}
}
}
}

View File

@ -0,0 +1,38 @@
<?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/
*
*
*/
class HurtArmorPacket extends RakNetDataPacket{
public $health;
public function pid(){
return ProtocolInfo::HURT_ARMOR_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putByte($this->health);
}
}

View File

@ -0,0 +1,44 @@
<?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/
*
*
*/
class InteractPacket extends RakNetDataPacket{
public $action;
public $eid;
public $target;
public function pid(){
return ProtocolInfo::INTERACT_PACKET;
}
public function decode(){
$this->action = $this->getByte();
$this->eid = $this->getInt();
$this->target = $this->getInt();
}
public function encode(){
$this->reset();
$this->putByte($this->action);
$this->putInt($this->eid);
$this->putInt($this->target);
}
}

View File

@ -0,0 +1,46 @@
<?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/
*
*
*/
class LevelEventPacket extends RakNetDataPacket{
public $evid;
public $x;
public $y;
public $z;
public $data;
public function pid(){
return ProtocolInfo::LEVEL_EVENT_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putShort($this->evid);
$this->putShort($this->x);
$this->putShort($this->y);
$this->putShort($this->z);
$this->putInt($this->data);
}
}

View File

@ -0,0 +1,45 @@
<?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/
*
*
*/
class LoginPacket extends RakNetDataPacket{
public $username;
public $protocol1;
public $protocol2;
public $clientId;
public $loginData;
public function pid(){
return ProtocolInfo::LOGIN_PACKET;
}
public function decode(){
$this->username = $this->getString();
$this->protocol1 = $this->getInt();
$this->protocol2 = $this->getInt();
$this->clientId = $this->getInt();
$this->loginData = $this->getString();
}
public function encode(){
}
}

View File

@ -0,0 +1,38 @@
<?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/
*
*
*/
class LoginStatusPacket extends RakNetDataPacket{
public $status;
public function pid(){
return ProtocolInfo::LOGIN_STATUS_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->status);
}
}

View File

@ -0,0 +1,41 @@
<?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/
*
*
*/
class MessagePacket extends RakNetDataPacket{
public $source;
public $message;
public function pid(){
return ProtocolInfo::MESSAGE_PACKET;
}
public function decode(){
$this->source = $this->getString();
$this->message = $this->getString();
}
public function encode(){
$this->reset();
$this->putString($this->source);
$this->putString($this->message);
}
}

View File

@ -0,0 +1,36 @@
<?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/
*
*
*/
class MoveEntityPacket extends RakNetDataPacket{
public function pid(){
return ProtocolInfo::MOVE_ENTITY_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
}
}

View File

@ -0,0 +1,48 @@
<?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/
*
*
*/
class MoveEntityPacket_PosRot extends RakNetDataPacket{
public $eid;
public $x;
public $y;
public $z;
public $yaw;
public $pitch;
public function pid(){
return ProtocolInfo::MOVE_ENTITY_PACKET_POSROT;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putFloat($this->x);
$this->putFloat($this->y);
$this->putFloat($this->z);
$this->putFloat($this->yaw);
$this->putFloat($this->pitch);
}
}

View File

@ -0,0 +1,56 @@
<?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/
*
*
*/
class MovePlayerPacket extends RakNetDataPacket{
public $eid;
public $x;
public $y;
public $z;
public $yaw;
public $pitch;
public $bodyYaw;
public function pid(){
return ProtocolInfo::MOVE_PLAYER_PACKET;
}
public function decode(){
$this->eid = $this->getInt();
$this->x = $this->getFloat();
$this->y = $this->getFloat();
$this->z = $this->getFloat();
$this->yaw = $this->getFloat();
$this->pitch = $this->getFloat();
$this->bodyYaw = $this->getFloat();
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putFloat($this->x);
$this->putFloat($this->y);
$this->putFloat($this->z);
$this->putFloat($this->yaw);
$this->putFloat($this->pitch);
$this->putFloat($this->bodyYaw);
}
}

View File

@ -0,0 +1,38 @@
<?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/
*
*
*/
class PingPacket extends RakNetDataPacket{
public $time = 0;
public function pid(){
return ProtocolInfo::PING_PACKET;
}
public function decode(){
$this->time = $this->getLong();
}
public function encode(){
$this->reset();
$this->putLong($this->time);
}
}

View File

@ -0,0 +1,47 @@
<?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/
*
*
*/
class PlayerActionPacket extends RakNetDataPacket{
public $action;
public $x;
public $y;
public $z;
public $face;
public $eid;
public function pid(){
return ProtocolInfo::PLAYER_ACTION_PACKET;
}
public function decode(){
$this->action = $this->getInt();
$this->x = $this->getInt();
$this->y = $this->getInt();
$this->z = $this->getInt();
$this->face = $this->getInt();
$this->eid = $this->getInt();
}
public function encode(){
}
}

View File

@ -0,0 +1,47 @@
<?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/
*
*
*/
class PlayerArmorEquipmentPacket extends RakNetDataPacket{
public $eid;
public $slots = array();
public function pid(){
return ProtocolInfo::PLAYER_ARMOR_EQUIPMENT_PACKET;
}
public function decode(){
$this->eid = $this->getInt();
$this->slots[0] = $this->getByte();
$this->slots[1] = $this->getByte();
$this->slots[2] = $this->getByte();
$this->slots[3] = $this->getByte();
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putByte($this->slots[0]);
$this->putByte($this->slots[1]);
$this->putByte($this->slots[2]);
$this->putByte($this->slots[3]);
}
}

View File

@ -0,0 +1,47 @@
<?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/
*
*
*/
class PlayerEquipmentPacket extends RakNetDataPacket{
public $eid;
public $item;
public $meta;
public $slot;
public function pid(){
return ProtocolInfo::PLAYER_EQUIPMENT_PACKET;
}
public function decode(){
$this->eid = $this->getInt();
$this->item = $this->getShort();
$this->meta = $this->getShort();
$this->slot = $this->getByte();
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putShort($this->item);
$this->putShort($this->meta);
$this->putByte($this->slot);
}
}

View File

@ -0,0 +1,41 @@
<?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/
*
*
*/
class PongPacket extends RakNetDataPacket{
public $time = 0;
public $ptime = 0;
public function pid(){
return ProtocolInfo::PONG_PACKET;
}
public function decode(){
$this->ptime = $this->getLong();
$this->time = $this->getLong();
}
public function encode(){
$this->reset();
$this->putLong($this->ptime);
$this->putLong($this->time);
}
}

View File

@ -0,0 +1,37 @@
<?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/
*
*
*/
class ReadyPacket extends RakNetDataPacket{
public $status;
public function pid(){
return ProtocolInfo::READY_PACKET;
}
public function decode(){
$this->status = $this->getByte();
}
public function encode(){
}
}

View File

@ -0,0 +1,43 @@
<?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/
*
*
*/
class RemoveBlockPacket extends RakNetDataPacket{
public $eid;
public $x;
public $y;
public $z;
public function pid(){
return ProtocolInfo::REMOVE_BLOCK_PACKET;
}
public function decode(){
$this->eid = $this->getInt();
$this->x = $this->getInt();
$this->z = $this->getInt();
$this->y = $this->getByte();
}
public function encode(){
}
}

View File

@ -0,0 +1,38 @@
<?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/
*
*
*/
class RemoveEntityPacket extends RakNetDataPacket{
public $eid;
public function pid(){
return ProtocolInfo::REMOVE_ENTITY_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
}
}

View File

@ -0,0 +1,40 @@
<?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/
*
*
*/
class RemovePlayerPacket extends RakNetDataPacket{
public $eid;
public $clientID;
public function pid(){
return ProtocolInfo::REMOVE_PLAYER_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putLong($this->clientID);
}
}

View File

@ -0,0 +1,39 @@
<?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/
*
*
*/
class RequestChunkPacket extends RakNetDataPacket{
public $chunkX;
public $chunkZ;
public function pid(){
return ProtocolInfo::REQUEST_CHUNK_PACKET;
}
public function decode(){
$this->chunkX = $this->getInt();
$this->chunkZ = $this->getInt();
}
public function encode(){
}
}

View File

@ -0,0 +1,47 @@
<?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/
*
*
*/
class RespawnPacket extends RakNetDataPacket{
public $eid;
public $x;
public $y;
public $z;
public function pid(){
return ProtocolInfo::RESPAWN_PACKET;
}
public function decode(){
$this->eid = $this->getInt();
$this->x = $this->getFloat();
$this->y = $this->getFloat();
$this->z = $this->getFloat();
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putFloat($this->x);
$this->putFloat($this->y);
$this->putFloat($this->z);
}
}

View File

@ -0,0 +1,40 @@
<?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/
*
*
*/
class RotateHeadPacket extends RakNetDataPacket{
public $eid;
public $yaw;
public function pid(){
return ProtocolInfo::ROTATE_HEAD_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putByte($this->yaw);
}
}

View File

@ -0,0 +1,61 @@
<?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/
*
*
*/
class SendInventoryPacket extends RakNetDataPacket{
public $eid;
public $windowid;
public $slots = array();
public $armor = array();
public function pid(){
return ProtocolInfo::SEND_INVENTORY_PACKET;
}
public function decode(){
$this->eid = $this->getInt();
$this->windowid = $this->getByte();
$count = $this->getShort();
for($s = 0; $s < $count and !$this->feof(); ++$s){
$this->slots[$s] = $this->getSlot();
}
if($this->windowid === 1){ //Armir is sent
for($s = 0; $s < 4; ++$s){
$this->armor[$s] = $this->getSlot();
}
}
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putByte($this->windowid);
$this->putShort(count($this->slots));
foreach($this->slots as $slot){
$this->putSlot($slot);
}
if($this->windowid === 1 and count($this->armor) === 4){
for($s = 0; $s < 4; ++$s){
$this->putSlot($this->armor[$s]);
}
}
}
}

View File

@ -0,0 +1,57 @@
<?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/
*
*
*/
class ServerHandshakePacket extends RakNetDataPacket{
public $port;
public $session;
public $session2;
public function pid(){
return ProtocolInfo::SERVER_HANDSHAKE_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->put("\x04\x3f\x57\xfe"); //cookie
$this->put("\xcd"); //Security flags
$this->putShort($this->port);
$this->putDataArray(array(
"\xf5\xff\xff\xf5",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
"\xff\xff\xff\xff",
));
$this->put("\x00\x00");
$this->putLong($this->session);
$this->putLong($this->session2);
}
}

View File

@ -0,0 +1,40 @@
<?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/
*
*
*/
class SetEntityDataPacket extends RakNetDataPacket{
public $eid;
public $metadata;
public function pid(){
return ProtocolInfo::SET_ENTITY_DATA_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->put(Utils::writeMetadata($this->metadata));
}
}

View File

@ -0,0 +1,44 @@
<?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/
*
*
*/
class SetEntityMotionPacket extends RakNetDataPacket{
public $eid;
public $speedX;
public $speedY;
public $speedZ;
public function pid(){
return ProtocolInfo::SET_ENTITY_MOTION_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->eid);
$this->putShort((int) ($this->speedX * 400));
$this->putShort((int) ($this->speedY * 400));
$this->putShort((int) ($this->speedZ * 400));
}
}

View File

@ -0,0 +1,38 @@
<?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/
*
*
*/
class SetHealthPacket extends RakNetDataPacket{
public $health;
public function pid(){
return ProtocolInfo::SET_HEALTH_PACKET;
}
public function decode(){
$this->health = $this->getByte();
}
public function encode(){
$this->reset();
$this->putByte($this->health);
}
}

View File

@ -0,0 +1,42 @@
<?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/
*
*
*/
class SetSpawnPositionPacket extends RakNetDataPacket{
public $x;
public $z;
public $y;
public function pid(){
return ProtocolInfo::SET_SPAWN_POSITION_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->x);
$this->putInt($this->z);
$this->putByte($this->y);
}
}

View File

@ -0,0 +1,40 @@
<?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/
*
*
*/
class SetTimePacket extends RakNetDataPacket{
public $time;
public $started = true;
public function pid(){
return ProtocolInfo::SET_TIME_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->time);
$this->putByte($this->started == true ? 0x80:0x00);
}
}

View File

@ -0,0 +1,50 @@
<?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/
*
*
*/
class StartGamePacket extends RakNetDataPacket{
public $seed;
public $generator;
public $gamemode;
public $eid;
public $x;
public $y;
public $z;
public function pid(){
return ProtocolInfo::START_GAME_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->seed);
$this->putInt($this->generator);
$this->putInt($this->gamemode);
$this->putInt($this->eid);
$this->putFloat($this->x);
$this->putFloat($this->y);
$this->putFloat($this->z);
}
}

View File

@ -0,0 +1,40 @@
<?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/
*
*
*/
class TakeItemEntityPacket extends RakNetDataPacket{
public $target;
public $eid;
public function pid(){
return ProtocolInfo::TAKE_ITEM_ENTITY_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->target);
$this->putInt($this->eid);
}
}

View File

@ -0,0 +1,46 @@
<?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/
*
*
*/
class TileEventPacket extends RakNetDataPacket{
public $x;
public $y;
public $z;
public $case1;
public $case2;
public function pid(){
return ProtocolInfo::TILE_EVENT_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->x);
$this->putInt($this->y);
$this->putInt($this->z);
$this->putInt($this->case1);
$this->putInt($this->case2);
}
}

View File

@ -0,0 +1,37 @@
<?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/
*
*
*/
class UnknownPacket extends RakNetDataPacket{
public $packetID = -1;
public function pid(){
return $this->packetID;
}
public function decode(){
}
public function encode(){
}
}

View File

@ -0,0 +1,46 @@
<?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/
*
*
*/
class UpdateBlockPacket extends RakNetDataPacket{
public $x;
public $z;
public $y;
public $block;
public $meta;
public function pid(){
return ProtocolInfo::UPDATE_BLOCK_PACKET;
}
public function decode(){
}
public function encode(){
$this->reset();
$this->putInt($this->x);
$this->putInt($this->z);
$this->putByte($this->y);
$this->putByte($this->block);
$this->putByte($this->meta);
}
}

View File

@ -0,0 +1,61 @@
<?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/
*
*
*/
class UseItemPacket extends RakNetDataPacket{
public $x;
public $y;
public $z;
public $face;
public $item;
public $meta;
public $eid;
public $fx;
public $fy;
public $fz;
public $posX;
public $posY;
public $posZ;
public function pid(){
return ProtocolInfo::USE_ITEM_PACKET;
}
public function decode(){
$this->x = $this->getInt();
$this->y = $this->getInt();
$this->z = $this->getInt();
$this->face = $this->getInt();
$this->item = $this->getShort();
$this->meta = $this->getByte(); //Mojang: fix this
$this->eid = $this->getInt();
$this->fx = $this->getFloat();
$this->fy = $this->getFloat();
$this->fz = $this->getFloat();
$this->posX = $this->getFloat();
$this->posY = $this->getFloat();
$this->posZ = $this->getFloat();
}
public function encode(){
}
}

View File

@ -24,7 +24,7 @@ Implementation of the UT3 Query Protocol (GameSpot)
Source: http://wiki.unrealadmin.org/UT3_query_protocol
*/
class Query{
class QueryHandler{
private $socket, $server, $lastToken, $token, $longData, $timeout;
public function __construct(){
@ -41,7 +41,7 @@ class Query{
Then, the Query class handles itself sending the packets in raw form, because
packets can conflict with the MCPE ones.
*/
$this->server->addHandler("server.unknownpacket", array($this, "packetHandler"), 50);
$this->server->schedule(20 * 30, array($this, "regenerateToken"), array(), true);
$this->regenerateToken();
$this->lastToken = $this->token;
@ -94,40 +94,41 @@ class Query{
$this->token = Utils::readInt("\x00".Utils::getRandomBytes(3, false));
}
public function packetHandler(&$packet, $event){
if($event !== "server.unknownpacket"){
return;
}
$magic = substr($packet["raw"], 0, 2);
$offset = 2;
if($magic !== "\xfe\xfd"){
return;
}
$type = ord($packet["raw"]{2});
++$offset;
$sessionID = Utils::readInt(substr($packet["raw"], $offset, 4));
$offset += 4;
$payload = substr($packet["raw"], $offset);
switch($type){
case 9: //Handshake
$this->server->send(9, chr(9).Utils::writeInt($sessionID).$this->token."\x00", true, $packet["ip"], $packet["port"]);
public function handle(QueryPacket $packet){
$packet->decode();
switch($packet->packetType){
case QueryPacket::HANDSHAKE: //Handshake
$pk = new QueryPacket;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$pk->packetType = QueryPacket::HANDSHAKE;
$pk->sessionID = $packet->sessionID;
$pk->payload = $this->token."\x00";
$pk->encode();
$this->server->send($pk);
break;
case 0: //Stat
$token = Utils::readInt(substr($payload, 0, 4));
case QueryPacket::STATISTICS: //Stat
$token = Utils::readInt(substr($packet->payload, 0, 4));
if($token !== $this->token and $token !== $this->lastToken){
break;
}
if(strlen($payload) === 8){
$pk = new QueryPacket;
$pk->ip = $packet->ip;
$pk->port = $packet->port;
$pk->packetType = QueryPacket::STATISTICS;
$pk->sessionID = $packet->sessionID;
if(strlen($packet->payload) === 8){
if($this->timeout < microtime(true)){
$this->regenerateInfo();
}
$this->server->send(0, chr(0).Utils::writeInt($sessionID).$this->longData, true, $packet["ip"], $packet["port"]);
$pk->payload = $this->longData;
}else{
$this->server->send(0, chr(0).Utils::writeInt($sessionID).$this->server->name."\x00".(($this->server->gamemode & 0x01) === 0 ? "SMP":"CMP")."\x00".$this->server->api->level->getDefault()->getName()."\x00".count($this->server->clients)."\x00".$this->server->maxClients."\x00".Utils::writeLShort($this->server->api->getProperty("server-port")).$this->server->api->getProperty("server-ip", "0.0.0.0")."\x00", true, $packet["ip"], $packet["port"]);
$pk->payload = $this->server->name."\x00".(($this->server->gamemode & 0x01) === 0 ? "SMP":"CMP")."\x00".$this->server->api->level->getDefault()->getName()."\x00".count($this->server->clients)."\x00".$this->server->maxClients."\x00".Utils::writeLShort($this->server->api->getProperty("server-port")).$this->server->api->getProperty("server-ip", "0.0.0.0")."\x00";
}
$pk->encode();
$this->server->send($pk);
break;
}
return true;
}
}
}

View File

@ -0,0 +1,41 @@
<?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/
*
*
*/
class QueryPacket extends Packet{
const HANDSHAKE = 9;
const STATISTICS = 0;
public $packetType;
public $sessionID;
public $payload;
public function decode(){
$this->packetType = ord($this->buffer{2});
$this->sessionID = Utils::readInt(substr($this->buffer, 3, 4));
$this->payload = substr($this->buffer, 7);
}
public function encode(){
$this->buffer .= chr($this->packetType);
$this->buffer .= Utils::writeInt($this->sessionID);
$this->buffer .= $this->payload;
}
}

View File

@ -0,0 +1,184 @@
<?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/
*
*
*/
class RakNetCodec{
public $packet;
public function __construct(RakNetPacket $packet){
$this->packet = $packet;
$this->buffer =& $this->packet->buffer;
$this->encode();
}
private function encode(){
if(strlen($this->packet->buffer) > 0){
return;
}
$this->buffer .= chr($this->packet->pid());
switch($this->packet->pid()){
case RakNetInfo::OPEN_CONNECTION_REPLY_1:
$this->buffer .= RakNetInfo::MAGIC;
$this->putLong($this->packet->serverID);
$this->putByte(0); //server security
$this->putShort($this->packet->mtuSize);
break;
case RakNetInfo::OPEN_CONNECTION_REPLY_2:
$this->buffer .= RakNetInfo::MAGIC;
$this->putLong($this->packet->serverID);
$this->putShort($this->packet->port);
$this->putShort($this->packet->mtuSize);
$this->putByte(0); //Server security
break;
case RakNetInfo::INCOMPATIBLE_PROTOCOL_VERSION:
$this->putByte(RakNetInfo::STRUCTURE);
$this->buffer .= RakNetInfo::MAGIC;
$this->putLong($this->packet->serverID);
break;
case RakNetInfo::UNCONNECTED_PONG:
case RakNetInfo::ADVERTISE_SYSTEM:
$this->putLong($this->packet->pingID);
$this->putLong($this->packet->serverID);
$this->buffer .= RakNetInfo::MAGIC;
$this->putString($this->packet->serverType);
break;
case RakNetInfo::DATA_PACKET_0:
case RakNetInfo::DATA_PACKET_1:
case RakNetInfo::DATA_PACKET_2:
case RakNetInfo::DATA_PACKET_3:
case RakNetInfo::DATA_PACKET_4:
case RakNetInfo::DATA_PACKET_5:
case RakNetInfo::DATA_PACKET_6:
case RakNetInfo::DATA_PACKET_7:
case RakNetInfo::DATA_PACKET_8:
case RakNetInfo::DATA_PACKET_9:
case RakNetInfo::DATA_PACKET_A:
case RakNetInfo::DATA_PACKET_B:
case RakNetInfo::DATA_PACKET_C:
case RakNetInfo::DATA_PACKET_D:
case RakNetInfo::DATA_PACKET_E:
case RakNetInfo::DATA_PACKET_F:
$this->putLTriad($this->packet->seqNumber);
foreach($this->packet->data as $pk){
$this->encodeDataPacket($pk);
}
break;
case RakNetInfo::NACK:
case RakNetInfo::ACK:
$payload = b"";
$records = 0;
$pointer = 0;
sort($this->packet->packets, SORT_NUMERIC);
$max = count($this->packet->packets);
while($pointer < $max){
$type = true;
$curr = $start = $this->packet->packets[$pointer];
for($i = $start + 1; $i < $max; ++$i){
$n = $this->packet->packets[$i];
if(($n - $curr) === 1){
$curr = $end = $n;
$type = false;
$pointer = $i + 1;
}else{
break;
}
}
++$pointer;
if($type === false){
$payload .= "\x00";
$payload .= strrev(Utils::writeTriad($start));
$payload .= strrev(Utils::writeTriad($end));
}else{
$payload .= Utils::writeBool(true);
$payload .= strrev(Utils::writeTriad($start));
}
++$records;
}
$this->putShort($records);
$this->buffer .= $payload;
break;
default:
}
}
private function encodeDataPacket(RakNetDataPacket $pk){
$this->putByte(($pk->reliability << 5) | ($pk->hasSplit > 0 ? 0b00010000:0));
$this->putShort(strlen($pk->buffer) << 3);
if($pk->reliability === 2
or $pk->reliability === 3
or $pk->reliability === 4
or $pk->reliability === 6
or $pk->reliability === 7){
$this->putLTriad($pk->messageIndex);
}
if($pk->reliability === 1
or $pk->reliability === 3
or $pk->reliability === 4
or $pk->reliability === 7){
$this->putLTriad($pk->orderIndex);
$this->putByte($pk->orderChannel);
}
if($pk->hasSplit === true){
$this->putInt($pk->splitCount);
$this->putShort($pk->splitID);
$this->putInt($pk->splitIndex);
}
$this->buffer .= $pk->buffer;
}
protected function put($str){
$this->buffer .= $str;
}
protected function putLong($v){
$this->buffer .= Utils::writeLong($v);
}
protected function putInt($v){
$this->buffer .= Utils::writeInt($v);
}
protected function putShort($v){
$this->buffer .= Utils::writeShort($v);
}
protected function putTriad($v){
$this->buffer .= Utils::writeTriad($v);
}
protected function putLTriad($v){
$this->buffer .= strrev(Utils::writeTriad($v));
}
protected function putByte($v){
$this->buffer .= chr($v);
}
protected function putString($v){
$this->putShort(strlen($v));
$this->put($v);
}
}

View File

@ -0,0 +1,171 @@
<?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/
*
*
*/
abstract class RakNetDataPacket extends stdClass{
private $offset = 0;
public $buffer = b"";
public $reliability = 0;
public $hasSplit = false;
public $messageIndex;
public $orderIndex;
public $orderChannel;
public $splitCount;
public $splitID;
public $splitIndex;
abstract public function pid();
abstract public function encode();
abstract public function decode();
protected function reset(){
$this->setBuffer(chr($this->pid()));
}
public function setBuffer($buffer = ""){
$this->buffer = $buffer;
$this->offset = 0;
}
public function getBuffer(){
return $this->buffer;
}
protected function get($len){
if($len <= 0){
$this->offset = strlen($this->buffer) - 1;
return "";
}
if($len === true){
return substr($this->buffer, $this->offset);
}
$this->offset += $len;
return substr($this->buffer, $this->offset - $len, $len);
}
protected function put($str){
$this->buffer .= $str;
}
protected function getLong($unsigned = false){
return Utils::readLong($this->get(8), $unsigned);
}
protected function putLong($v){
$this->buffer .= Utils::writeLong($v);
}
protected function getInt($unsigned = false){
return Utils::readInt($this->get(4), $unsigned);
}
protected function putInt($v){
$this->buffer .= Utils::writeInt($v);
}
protected function getShort($unsigned = false){
return Utils::readShort($this->get(2), $unsigned);
}
protected function putShort($v){
$this->buffer .= Utils::writeShort($v);
}
protected function getFloat(){
return Utils::readFloat($this->get(4));
}
protected function putFloat($v){
$this->buffer .= Utils::writeFloat($v);
}
protected function getTriad(){
return Utils::readTriad($this->get(3));
}
protected function putTriad($v){
$this->buffer .= Utils::writeTriad($v);
}
protected function getLTriad(){
return Utils::readTriad(strrev($this->get(3)));
}
protected function putLTriad($v){
$this->buffer .= strrev(Utils::writeTriad($v));
}
protected function getByte(){
return ord($this->get(1));
}
protected function putByte($v){
$this->buffer .= chr($v);
}
protected function getDataArray($len = 10){
$data = array();
for($i = 1; $i <= $len and !$this->feof(); ++$i){
$data[] = $this->get($this->getTriad());
}
return $data;
}
protected function putDataArray(array $data = array()){
foreach($data as $v){
$this->putTriad(strlen($v));
$this->put($v);
}
}
protected function getSlot(){
$id = $this->getShort();
$cnt = $this->getByte();
return BlockAPI::getItem(
$id,
$this->getShort(),
$cnt
);
}
protected function putSlot(Item $item){
$this->putShort($item->getID());
$this->putByte($item->count);
$this->putShort($item->getMetadata());
}
protected function getString(){
return $this->get($this->getShort(true));
}
protected function putString($v){
$this->putShort(strlen($v));
$this->put($v);
}
protected function feof(){
return !isset($this->buffer{$this->offset});
}
}

View File

@ -0,0 +1,94 @@
<?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/
*
*
*/
class RakNetInfo{
const STRUCTURE = 5;
const MAGIC = "\x00\xff\xff\x00\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78";
const UNCONNECTED_PING = 0x01;
const UNCONNECTED_PING_OPEN_CONNECTIONS = 0x02;
const OPEN_CONNECTION_REQUEST_1 = 0x05;
const OPEN_CONNECTION_REPLY_1 = 0x06;
const OPEN_CONNECTION_REQUEST_2 = 0x07;
const OPEN_CONNECTION_REPLY_2 = 0x08;
const INCOMPATIBLE_PROTOCOL_VERSION = 0x1a; //CHECK THIS
const UNCONNECTED_PONG = 0x1c;
const ADVERTISE_SYSTEM = 0x1d;
const DATA_PACKET_0 = 0x80;
const DATA_PACKET_1 = 0x81;
const DATA_PACKET_2 = 0x82;
const DATA_PACKET_3 = 0x83;
const DATA_PACKET_4 = 0x84;
const DATA_PACKET_5 = 0x85;
const DATA_PACKET_6 = 0x86;
const DATA_PACKET_7 = 0x87;
const DATA_PACKET_8 = 0x88;
const DATA_PACKET_9 = 0x89;
const DATA_PACKET_A = 0x8a;
const DATA_PACKET_B = 0x8b;
const DATA_PACKET_C = 0x8c;
const DATA_PACKET_D = 0x8d;
const DATA_PACKET_E = 0x8e;
const DATA_PACKET_F = 0x8f;
const NACK = 0xa0;
const ACK = 0xc0;
public static function isValid($pid){
switch((int) $pid){
case RakNetInfo::UNCONNECTED_PING:
case RakNetInfo::UNCONNECTED_PING_OPEN_CONNECTIONS:
case RakNetInfo::OPEN_CONNECTION_REQUEST_1:
case RakNetInfo::OPEN_CONNECTION_REPLY_1:
case RakNetInfo::OPEN_CONNECTION_REQUEST_2:
case RakNetInfo::OPEN_CONNECTION_REPLY_2:
case RakNetInfo::INCOMPATIBLE_PROTOCOL_VERSION:
case RakNetInfo::UNCONNECTED_PONG:
case RakNetInfo::ADVERTISE_SYSTEM:
case RakNetInfo::DATA_PACKET_0:
case RakNetInfo::DATA_PACKET_1:
case RakNetInfo::DATA_PACKET_2:
case RakNetInfo::DATA_PACKET_3:
case RakNetInfo::DATA_PACKET_4:
case RakNetInfo::DATA_PACKET_5:
case RakNetInfo::DATA_PACKET_6:
case RakNetInfo::DATA_PACKET_7:
case RakNetInfo::DATA_PACKET_8:
case RakNetInfo::DATA_PACKET_9:
case RakNetInfo::DATA_PACKET_A:
case RakNetInfo::DATA_PACKET_B:
case RakNetInfo::DATA_PACKET_C:
case RakNetInfo::DATA_PACKET_D:
case RakNetInfo::DATA_PACKET_E:
case RakNetInfo::DATA_PACKET_F:
case RakNetInfo::NACK:
case RakNetInfo::ACK:
return true;
default:
return false;
}
}
}

View File

@ -0,0 +1,34 @@
<?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/
*
*
*/
class RakNetPacket extends Packet{
private $packetID;
public function __construct($packetID){
$this->packetID = (int) $packetID;
}
public function pid(){
return $this->packetID;
}
public function __destruct(){}
}

View File

@ -0,0 +1,208 @@
<?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/
*
*
*/
class RakNetParser{
private $buffer;
private $offset;
public $packet;
public function __construct(&$buffer){
$this->buffer =& $buffer;
$this->offset = 0;
if(strlen($this->buffer) > 0){
$this->parse();
}else{
$this->packet = false;
}
}
private function get($len){
if($len <= 0){
$this->offset = strlen($this->buffer) - 1;
return "";
}
if($len === true){
return substr($this->buffer, $this->offset);
}
$this->offset += $len;
return substr($this->buffer, $this->offset - $len, $len);
}
private function getLong($unsigned = false){
return Utils::readLong($this->get(8), $unsigned);
}
private function getInt($unsigned = false){
return Utils::readInt($this->get(4), $unsigned);
}
private function getShort($unsigned = false){
return Utils::readShort($this->get(2), $unsigned);
}
private function getLTriad(){
return Utils::readTriad(strrev($this->get(3)));
}
private function getByte(){
return ord($this->get(1));
}
private function feof(){
return !isset($this->buffer{$this->offset});
}
private function parse(){
$this->packet = new RakNetPacket(ord($this->get(1)));
$this->packet->buffer =& $this->buffer;
$this->packet->length = strlen($this->buffer);
switch($this->packet->pid()){
case RakNetInfo::UNCONNECTED_PING:
case RakNetInfo::UNCONNECTED_PING_OPEN_CONNECTIONS:
$this->packet->pingID = $this->getLong();
$this->offset += 16; //Magic
break;
case RakNetInfo::OPEN_CONNECTION_REQUEST_1:
$this->offset += 16; //Magic
$this->packet->structure = $this->getByte();
$this->packet->mtuSize = strlen($this->get(true));
break;
case RakNetInfo::OPEN_CONNECTION_REQUEST_2:
$this->offset += 16; //Magic
$this->packet->security = $this->get(5);
$this->packet->port = $this->getShort(false);
$this->packet->mtuSize = $this->getShort(false);
$this->packet->clientID = $this->getLong();
break;
case RakNetInfo::DATA_PACKET_0:
case RakNetInfo::DATA_PACKET_1:
case RakNetInfo::DATA_PACKET_2:
case RakNetInfo::DATA_PACKET_3:
case RakNetInfo::DATA_PACKET_4:
case RakNetInfo::DATA_PACKET_5:
case RakNetInfo::DATA_PACKET_6:
case RakNetInfo::DATA_PACKET_7:
case RakNetInfo::DATA_PACKET_8:
case RakNetInfo::DATA_PACKET_9:
case RakNetInfo::DATA_PACKET_A:
case RakNetInfo::DATA_PACKET_B:
case RakNetInfo::DATA_PACKET_C:
case RakNetInfo::DATA_PACKET_D:
case RakNetInfo::DATA_PACKET_E:
case RakNetInfo::DATA_PACKET_F:
$this->packet->seqNumber = $this->getLTriad();
$this->packet->data = array();
while(!$this->feof() and ($pk = $this->parseDataPacket()) instanceof RakNetDataPacket){
$this->packet->data[] = $pk;
}
break;
case RakNetInfo::NACK:
case RakNetInfo::ACK:
$count = $this->getShort();
$this->packet->packets = array();
for($i = 0; $i < $count and !$this->feof(); ++$i){
if($this->getByte() === 0){
$start = $this->getLTriad();
$end = $this->getLTriad();
if(($end - $start) > 4096){
$end = $start + 4096;
}
for($c = $start; $c <= $end; ++$c){
$this->packet->packets[] = $c;
}
}else{
$this->packet->packets[] = $this->getLTriad();
}
}
break;
default:
$this->packet = false;
break;
}
}
private function parseDataPacket(){
$packetFlags = $this->getByte();
$reliability = ($packetFlags & 0b11100000) >> 5;
$hasSplit = ($packetFlags & 0b00010000) > 0;
$length = (int) ceil($this->getShort() / 8);
if($reliability === 2
or $reliability === 3
or $reliability === 4
or $reliability === 6
or $reliability === 7){
$messageIndex = $this->getLTriad();
}else{
$messageIndex = false;
}
if($reliability === 1
or $reliability === 3
or $reliability === 4
or $reliability === 7){
$orderIndex = $this->getLTriad();
$orderChannel = $this->getByte();
}else{
$orderIndex = false;
$orderChannel = false;
}
if($hasSplit == true){
$splitCount = $this->getInt();
$splitID = $this->getShort();
$splitIndex = $this->getInt();
}else{
$splitCount = false;
$splitID = false;
$splitIndex = false;
}
if($length <= 0
or $orderChannel >= 32
or ($hasSplit === true and $splitIndex >= $splitCount)){
return false;
}else{
$pid = $this->getByte();
$buffer = $this->get($length - 1);
if(strlen($buffer) < ($length - 1)){
return false;
}
if(isset(ProtocolInfo::$packets[$pid])){
$data = new ProtocolInfo::$packets[$pid];
}else{
$data = new UnknownPacket();
$data->packetID = $pid;
}
$data->reliability = $reliability;
$data->hasSplit = $hasSplit;
$data->messageIndex = $messageIndex;
$data->orderIndex = $orderIndex;
$data->orderChannel = $orderChannel;
$data->splitCount = $splitCount;
$data->splitID = $splitID;
$data->splitIndex = $splitIndex;
$data->setBuffer($buffer);
}
return $data;
}
}

View File

@ -28,7 +28,7 @@ class Cache{
public static function get($identifier){
if(isset(self::$cached[$identifier])){
self::$cached[$identifier][1] += $minTTL;
self::$cached[$identifier][1] = microtime(true) + self::$cached[$identifier][2];
return self::$cached[$identifier][0];
}
return false;

View File

@ -31,6 +31,14 @@ class Utils{
return ((@fsockopen("8.8.8.8", 80, $e = null, $n = null, 2) !== false or @fsockopen("www.linux.org", 80, $e = null, $n = null, 2) !== false or @fsockopen("www.php.net", 80, $e = null, $n = null, 2) !== false) ? true:false);
}
public static function getCallableIdentifier(callable $variable){
if(is_array($variable)){
return sha1(strtolower(get_class($variable))."::".strtolower($variable[1]));
}else{
return sha1(strtolower($variable));
}
}
public static function getUniqueID($raw = false, $extra = ""){
$machine = php_uname("a");
$machine .= file_exists("/proc/cpuinfo") ? file_get_contents("/proc/cpuinfo") : "";

View File

@ -572,24 +572,24 @@ class Entity extends Position{
$players = $this->server->api->player->getAll($this->level);
if($this->player instanceof Player){
unset($players[$this->player->CID]);
$this->server->api->player->broadcastPacket($players, MC_MOVE_PLAYER, array(
"eid" => $this->eid,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"yaw" => $this->yaw,
"pitch" => $this->pitch,
"bodyYaw" => $this->yaw,
));
$pk = new MovePlayerPacket;
$pk->eid = $this->eid;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->yaw = $this->yaw;
$pk->pitch = $this->pitch;
$pk->bodyYaw = $this->yaw;
$this->server->api->player->broadcastPacket($players, $pk);
}else{
$this->server->api->player->broadcastPacket($players, MC_MOVE_ENTITY_POSROT, array(
"eid" => $this->eid,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"yaw" => $this->yaw,
"pitch" => $this->pitch,
));
$pk = new MoveEntityPacket_PosRot;
$pk->eid = $this->eid;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->yaw = $this->yaw;
$pk->pitch = $this->pitch;
$this->server->api->player->broadcastPacket($players, $pk);
}
}
}else{
@ -661,116 +661,135 @@ class Entity extends Position{
if($this->player->connected !== true or $this->player->spawned === false){
return false;
}
$player->dataPacket(MC_ADD_PLAYER, array(
"clientID" => 0,/*$this->player->clientID,*/
"username" => $this->player->username,
"eid" => $this->eid,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"yaw" => 0,
"pitch" => 0,
"unknown1" => 0,
"unknown2" => 0,
"metadata" => $this->getMetadata(),
));
$player->dataPacket(MC_PLAYER_EQUIPMENT, array(
"eid" => $this->eid,
"block" => $this->player->getSlot($this->player->slot)->getID(),
"meta" => $this->player->getSlot($this->player->slot)->getMetadata(),
"slot" => 0,
));
$pk = new AddPlayerPacket;
$pk->clientID = 0; //$this->player->clientID;
$pk->username = $this->player->username;
$pk->eid = $this->eid;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->yaw = 0;
$pk->pitch = 0;
$pk->unknown1 = 0;
$pk->unknown2 = 0;
$pk->metadata = $this->getMetadata();
$player->dataPacket($pk);
$pk = new SetEntityMotionPacket;
$pk->eid = $this->eid;
$pk->speedX = $this->speedX;
$pk->speedY = $this->speedY;
$pk->speedZ = $this->speedZ;
$player->dataPacket($pk);
$pk = new PlayerEquipmentPacket;
$pk->eid = $this->eid;
$pk->item = $this->player->getSlot($this->player->slot)->getID();
$pk->meta = $this->player->getSlot($this->player->slot)->getMetadata();
$pk->slot = 0;
$player->dataPacket($pk);
$this->player->sendArmor($player);
break;
case ENTITY_ITEM:
$player->dataPacket(MC_ADD_ITEM_ENTITY, array(
"eid" => $this->eid,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"yaw" => $this->yaw,
"pitch" => $this->pitch,
"roll" => 0,
"block" => $this->type,
"meta" => $this->meta,
"stack" => $this->stack,
));
$player->dataPacket(MC_SET_ENTITY_MOTION, array(
"eid" => $this->eid,
"speedX" => (int) ($this->speedX * 400),
"speedY" => (int) ($this->speedY * 400),
"speedZ" => (int) ($this->speedZ * 400),
));
$pk = new AddItemEntityPacket;
$pk->eid = $this->eid;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->yaw = $this->yaw;
$pk->pitch = $this->pitch;
$pk->roll = 0;
$pk->item = BlockAPI::getItem($this->type, $this->meta, $this->stack);
$pk->metadata = $this->getMetadata();
$player->dataPacket($pk);
$pk = new SetEntityMotionPacket;
$pk->eid = $this->eid;
$pk->speedX = $this->speedX;
$pk->speedY = $this->speedY;
$pk->speedZ = $this->speedZ;
$player->dataPacket($pk);
break;
case ENTITY_MOB:
$player->dataPacket(MC_ADD_MOB, array(
"type" => $this->type,
"eid" => $this->eid,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"yaw" => 0,
"pitch" => 0,
"metadata" => $this->getMetadata(),
));
$player->dataPacket(MC_SET_ENTITY_MOTION, array(
"eid" => $this->eid,
"speedX" => (int) ($this->speedX * 400),
"speedY" => (int) ($this->speedY * 400),
"speedZ" => (int) ($this->speedZ * 400),
));
$pk = new AddMobPacket;
$pk->eid = $this->eid;
$pk->type = $this->type;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->yaw = $this->yaw;
$pk->pitch = $this->pitch;
$pk->metadata = $this->getMetadata();
$player->dataPacket($pk);
$pk = new SetEntityMotionPacket;
$pk->eid = $this->eid;
$pk->speedX = $this->speedX;
$pk->speedY = $this->speedY;
$pk->speedZ = $this->speedZ;
$player->dataPacket($pk);
break;
case ENTITY_OBJECT:
if($this->type === OBJECT_PAINTING){
$player->dataPacket(MC_ADD_PAINTING, array(
"eid" => $this->eid,
"x" => (int) $this->x,
"y" => (int) $this->y,
"z" => (int) $this->z,
"direction" => $this->getDirection(),
"title" => $this->data["Motive"],
));
$pk = new AddPaintingPacket;
$pk->eid = $this->eid;
$pk->x = (int) $this->x;
$pk->y = (int) $this->y;
$pk->z = (int) $this->z;
$pk->direction = $this->getDirection();
$pk->title = $this->data["Motive"];
$player->dataPacket($pk);
}elseif($this->type === OBJECT_PRIMEDTNT){
$player->dataPacket(MC_ADD_ENTITY, array(
"eid" => $this->eid,
"type" => $this->type,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"did" => 0,
));
$pk = new AddEntityPacket;
$pk->eid = $this->eid;
$pk->type = $this->type;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->did = 0;
$player->dataPacket($pk);
$pk = new SetEntityMotionPacket;
$pk->eid = $this->eid;
$pk->speedX = $this->speedX;
$pk->speedY = $this->speedY;
$pk->speedZ = $this->speedZ;
$player->dataPacket($pk);
}elseif($this->type === OBJECT_ARROW){
$player->dataPacket(MC_ADD_ENTITY, array(
"eid" => $this->eid,
"type" => $this->type,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"did" => 0,
));
$player->dataPacket(MC_SET_ENTITY_MOTION, array(
"eid" => $this->eid,
"speedX" => (int) ($this->speedX * 400),
"speedY" => (int) ($this->speedY * 400),
"speedZ" => (int) ($this->speedZ * 400),
));
$pk = new AddEntityPacket;
$pk->eid = $this->eid;
$pk->type = $this->type;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->did = 0;
$player->dataPacket($pk);
$pk = new SetEntityMotionPacket;
$pk->eid = $this->eid;
$pk->speedX = $this->speedX;
$pk->speedY = $this->speedY;
$pk->speedZ = $this->speedZ;
$player->dataPacket($pk);
}
break;
case ENTITY_FALLING:
$player->dataPacket(MC_ADD_ENTITY, array(
"eid" => $this->eid,
"type" => $this->type,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"did" => -$this->data["Tile"],
));
$player->dataPacket(MC_SET_ENTITY_MOTION, array(
"eid" => $this->eid,
"speedX" => (int) ($this->speedX * 400),
"speedY" => (int) ($this->speedY * 400),
"speedZ" => (int) ($this->speedZ * 400),
));
$pk = new AddEntityPacket;
$pk->eid = $this->eid;
$pk->type = $this->type;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->did = -$this->data["Tile"];
$player->dataPacket($pk);
$pk = new SetEntityMotionPacket;
$pk->eid = $this->eid;
$pk->speedX = $this->speedX;
$pk->speedY = $this->speedY;
$pk->speedZ = $this->speedZ;
$player->dataPacket($pk);
break;
}
}
@ -828,7 +847,7 @@ class Entity extends Position{
$this->server->preparedSQL->entity->setLevel->reset();
$this->server->preparedSQL->entity->setLevel->clear();
$this->server->preparedSQL->entity->setLevel->bindValue(":level", $this->level->getName(), SQLITE3_TEXT);
$this->server->preparedSQL->entity->setLevel->bindValue(":eid", $this->eid, SQLITE3_TEXT);
$this->server->preparedSQL->entity->setLevel->bindValue(":eid", $this->eid, SQLITE3_INTEGER);
$this->server->preparedSQL->entity->setLevel->execute();
}
$this->x = $pos->x;
@ -847,7 +866,7 @@ class Entity extends Position{
$this->server->preparedSQL->entity->setPosition->bindValue(":z", $this->z, SQLITE3_TEXT);
$this->server->preparedSQL->entity->setPosition->bindValue(":pitch", $this->pitch, SQLITE3_TEXT);
$this->server->preparedSQL->entity->setPosition->bindValue(":yaw", $this->yaw, SQLITE3_TEXT);
$this->server->preparedSQL->entity->setPosition->bindValue(":eid", $this->eid, SQLITE3_TEXT);
$this->server->preparedSQL->entity->setPosition->bindValue(":eid", $this->eid, SQLITE3_INTEGER);
$this->server->preparedSQL->entity->setPosition->execute();
}
@ -981,9 +1000,9 @@ class Entity extends Position{
$this->server->api->dhandle("entity.event", array("entity" => $this, "event" => 2)); //Ouch! sound
}
if($this->player instanceof Player){
$this->player->dataPacket(MC_SET_HEALTH, array(
"health" => $this->health,
));
$pk = new SetHealthPacket;
$pk->health = $this->health;
$this->player->dataPacket($pk);
}
if($this->health <= 0 and $this->dead === false){
$this->spawnDrops();
@ -995,14 +1014,14 @@ class Entity extends Position{
$this->updateMetadata();
$this->dead = true;
if($this->player instanceof Player){
$this->server->api->player->broadcastPacket($this->server->api->player->getAll($this->level), MC_MOVE_ENTITY_POSROT, array(
"eid" => $this->eid,
"x" => -256,
"y" => 128,
"z" => -256,
"yaw" => 0,
"pitch" => 0,
));
$pk = new MoveEntityPacket_PosRot;
$pk->eid = $this->eid;
$pk->x = -256;
$pk->y = 128;
$pk->z = -256;
$pk->yaw = 0;
$pk->pitch = 0;
$this->server->api->player->broadcastPacket($this->level->players, $pk);
}else{
$this->server->api->dhandle("entity.event", array("entity" => $this, "event" => 3)); //Entity dead
}

View File

@ -114,13 +114,13 @@ class Explosion{
$this->level->level->setBlockID($block->x, $block->y, $block->z, 0);
$send[] = new Vector3($block->x - $source->x, $block->y - $source->y, $block->z - $source->z);
}
$server->api->player->broadcastPacket($server->api->player->getAll($this->level), MC_EXPLOSION, array(
"x" => $this->source->x,
"y" => $this->source->y,
"z" => $this->source->z,
"radius" => $this->size,
"records" => $send,
));
$pk = new ExplodePacket;
$pk->x = $this->source->x;
$pk->y = $this->source->y;
$pk->z = $this->source->z;
$pk->radius = $this->size;
$pk->records = $send;
$server->api->player->broadcastPacket($this->level->players, $pk);
}
}

View File

@ -78,10 +78,11 @@ class Level{
}
if($this->server->api->dhandle("time.change", array("level" => $this, "time" => $time)) !== false){
$this->time = $time;
$this->server->api->player->broadcastPacket($this->players, MC_SET_TIME, array(
"time" => (int) $this->time,
"started" => $this->stopTime == false,
));
$pk = new SetTimePacket;
$pk->time = (int) $this->time;
$pk->started = $this->stopTime == false;
$this->server->api->player->broadcastPacket($this->players, $pk);
}
}
@ -109,13 +110,13 @@ class Level{
if(count($this->changedBlocks) > 0){
foreach($this->changedBlocks as $blocks){
foreach($blocks as $b){
$this->server->api->player->broadcastPacket($this->players, MC_UPDATE_BLOCK, array(
"x" => $b->x,
"y" => $b->y,
"z" => $b->z,
"block" => $b->getID(),
"meta" => $b->getMetadata(),
));
$pk = new UpdateBlockPacket;
$pk->x = $b->x;
$pk->y = $b->y;
$pk->z = $b->z;
$pk->block = $b->getID();
$pk->meta = $b->getMetadata();
$this->server->api->player->broadcastPacket($this->players, $pk);
}
}
$this->changedBlocks = array();
@ -286,13 +287,13 @@ class Level{
public function setBlockRaw(Vector3 $pos, Block $block, $direct = true, $send = true){
if(($ret = $this->level->setBlock($pos->x, $pos->y, $pos->z, $block->getID(), $block->getMetadata())) === true and $send !== false){
if($direct === true){
$this->server->api->player->broadcastPacket($this->players, MC_UPDATE_BLOCK, array(
"x" => $pos->x,
"y" => $pos->y,
"z" => $pos->z,
"block" => $block->getID(),
"meta" => $block->getMetadata(),
));
$pk = new UpdateBlockPacket;
$pk->x = $pos->x;
$pk->y = $pos->y;
$pk->z = $pos->z;
$pk->block = $block->getID();
$pk->meta = $block->getMetadata();
$this->server->api->player->broadcastPacket($this->players, $pk);
}elseif($direct === false){
if(!($pos instanceof Position)){
$pos = new Position($pos->x, $pos->y, $pos->z, $this);
@ -326,13 +327,13 @@ class Level{
$block->position($pos);
if($direct === true){
$this->server->api->player->broadcastPacket($this->players, MC_UPDATE_BLOCK, array(
"x" => $pos->x,
"y" => $pos->y,
"z" => $pos->z,
"block" => $block->getID(),
"meta" => $block->getMetadata(),
));
$pk = new UpdateBlockPacket;
$pk->x = $pos->x;
$pk->y = $pos->y;
$pk->z = $pos->z;
$pk->block = $block->getID();
$pk->meta = $block->getMetadata();
$this->server->api->player->broadcastPacket($this->players, $pk);
}else{
$i = ($pos->x >> 4).":".($pos->y >> 4).":".($pos->z >> 4);
if(!isset($this->changedBlocks[$i])){

View File

@ -142,26 +142,27 @@ class Tile extends Position{
}else{
$player->windows[$id] = $this;
}
$player->dataPacket(MC_CONTAINER_OPEN, array(
"windowid" => $id,
"type" => WINDOW_CHEST,
"slots" => is_array($player->windows[$id]) ? CHEST_SLOTS << 1:CHEST_SLOTS,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
));
$pk = new ContainerOpenPacket;
$pk->windowid = $id;
$pk->type = WINDOW_CHEST;
$pk->slots = is_array($player->windows[$id]) ? CHEST_SLOTS << 1:CHEST_SLOTS;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$player->dataPacket($pk);
$slots = array();
if(is_array($player->windows[$id])){
$all = $this->server->api->player->getAll($this->level);
foreach($player->windows[$id] as $ob){
$this->server->api->player->broadcastPacket($all, MC_TILE_EVENT, array(
"x" => $ob->x,
"y" => $ob->y,
"z" => $ob->z,
"case1" => 1,
"case2" => 2,
));
foreach($player->windows[$id] as $ob){
$pk = new TileEventPacket;
$pk->x = $ob->x;
$pk->y = $ob->y;
$pk->z = $ob->z;
$pk->case1 = 1;
$pk->case2 = 2;
$this->server->api->player->broadcastPacket($all, $pk);
for($s = 0; $s < CHEST_SLOTS; ++$s){
$slot = $ob->getSlot($s);
if($slot->getID() > AIR and $slot->count > 0){
@ -172,13 +173,13 @@ class Tile extends Position{
}
}
}else{
$this->server->api->player->broadcastPacket($this->server->api->player->getAll($this->level), MC_TILE_EVENT, array(
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"case1" => 1,
"case2" => 2,
));
$pk = new TileEventPacket;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->case1 = 1;
$pk->case2 = 2;
$this->server->api->player->broadcastPacket($this->server->api->player->getAll($this->level), $pk);
for($s = 0; $s < CHEST_SLOTS; ++$s){
$slot = $this->getSlot($s);
if($slot->getID() > AIR and $slot->count > 0){
@ -188,24 +189,26 @@ class Tile extends Position{
}
}
}
$player->dataPacket(MC_CONTAINER_SET_CONTENT, array(
"windowid" => $id,
"count" => count($slots),
"slots" => $slots,
));
$pk = new ContainerSetContentPacket;
$pk->windowid = $id;
$pk->slots = $slots;
$player->dataPacket($pk);
return true;
}elseif($this->class === TILE_FURNACE){
$player->windowCnt++;
$player->windowCnt = $id = max(2, $player->windowCnt % 99);
$player->windows[$id] = $this;
$player->dataPacket(MC_CONTAINER_OPEN, array(
"windowid" => $id,
"type" => WINDOW_FURNACE,
"slots" => FURNACE_SLOTS,
"x" => $this->x,
"y" => $this->y,
"z" => $this->z
));
$pk = new ContainerOpenPacket;
$pk->windowid = $id;
$pk->type = WINDOW_FURNACE;
$pk->slots = FURNACE_SLOTS;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$player->dataPacket($pk);
$slots = array();
for($s = 0; $s < FURNACE_SLOTS; ++$s){
$slot = $this->getSlot($s);
@ -215,11 +218,10 @@ class Tile extends Position{
$slots[] = BlockAPI::getItem(AIR, 0, 0);
}
}
$player->dataPacket(MC_CONTAINER_SET_CONTENT, array(
"windowid" => $id,
"count" => count($slots),
"slots" => $slots
));
$pk = new ContainerSetContentPacket;
$pk->windowid = $id;
$pk->slots = $slots;
$player->dataPacket($pk);
return true;
}
}
@ -383,12 +385,12 @@ class Tile extends Position{
$nbt->write(chr(NBT::TAG_END));
$player->dataPacket(MC_ENTITY_DATA, array(
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"namedtag" => $nbt->binary,
));
$pk = new EntityDataPacket;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->namedtag = $nbt->binary;
$player->dataPacket($pk);
break;
case TILE_SIGN:
$nbt = new NBT();
@ -428,12 +430,12 @@ class Tile extends Position{
$nbt->write(chr(NBT::TAG_END));
$player->dataPacket(MC_ENTITY_DATA, array(
"x" => $this->x,
"y" => $this->y,
"z" => $this->z,
"namedtag" => $nbt->binary,
));
$pk = new EntityDataPacket;
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->namedtag = $nbt->binary;
$player->dataPacket($pk);
break;
}
}