mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-20 16:00:20 +00:00
Updated to handle more things
This commit is contained in:
parent
02b2e980eb
commit
c63240c7a8
2
README
2
README
@ -34,8 +34,10 @@ Currently a work in progress, and used to document http://www.wiki.vg/Pocket_Min
|
||||
Current features of the server:
|
||||
- Players can connect and move around the world
|
||||
- Online list broadcast
|
||||
- Configurable day/night cycle
|
||||
- Health and position saving
|
||||
- server.properties configuration file
|
||||
- Whitelist and IP Ban files
|
||||
- Survival & Creative
|
||||
- Awesome features in server list!
|
||||
- Multiple worlds and importing!
|
||||
|
@ -25,3 +25,60 @@ the Free Software Foundation, either version 3 of the License, or
|
||||
|
||||
*/
|
||||
|
||||
define("MAP_WIDTH", 256);
|
||||
define("MAP_HEIGHT", 128);
|
||||
|
||||
class ChunkParser{
|
||||
private $raw = b"";
|
||||
var $sectorLenght = 4096; //16 * 16 * 16
|
||||
var $chunkLenght = 86016; //21 * $sectorLenght
|
||||
|
||||
function __construct(){
|
||||
|
||||
}
|
||||
|
||||
public function loadFile($file){
|
||||
if(!file_exists($file)){
|
||||
return false;
|
||||
}
|
||||
$this->raw = file_get_contents($file);
|
||||
$this->chunkLenght = $this->sectorLenght * ord($this->raw{0});
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getOffsetPosition($X, $Z){
|
||||
$data = substr($this->raw, ($X << 2) + ($Z << 7), 4); //$X * 4 + $Z * 128
|
||||
return array(ord($data{0}), ord($data{1}), ord($data{2}), ord($data{3}));
|
||||
}
|
||||
|
||||
private function getOffset($X, $Z){
|
||||
$info = $this->getOffsetPosition($X, $Z);
|
||||
return 4096 + (($info[1] * $info[0]) << 12) + (($info[2] * $data[0]) << 16);
|
||||
}
|
||||
|
||||
public function getChunk($X, $Z, $header = true){
|
||||
$X = (int) $X;
|
||||
$Z = (int) $Z;
|
||||
if($header === false){
|
||||
$add = 4;
|
||||
}else{
|
||||
$add = 0;
|
||||
}
|
||||
return substr($this->raw, $this->getOffset($X, $Z) + $add, $this->chunkLenght - $add);
|
||||
}
|
||||
|
||||
public function getColumn($X, $Z){
|
||||
|
||||
}
|
||||
|
||||
public function getBlock($x, $y, $z){
|
||||
$x = (int) $x;
|
||||
$y = (int) $y;
|
||||
$z = (int) $z;
|
||||
$X = $x >> 4;
|
||||
$Z = $z >> 4;
|
||||
$block = $this->getOffset($X, $Z) + 4 + (($x << 6) + $y + ($z << 10));
|
||||
$meta = $this->getOffset($X, $Z) + 4 + (($x << 6) + $y + ($z << 10));
|
||||
}
|
||||
|
||||
}
|
@ -214,7 +214,32 @@ class CustomPacketHandler{
|
||||
$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_MOVE_PLAYER:
|
||||
if($this->c === false){
|
||||
@ -246,6 +271,21 @@ class CustomPacketHandler{
|
||||
$this->raw .= chr($this->data["face"]);
|
||||
}
|
||||
break;
|
||||
case MC_UPDATE_BLOCK:
|
||||
if($this->c === false){
|
||||
$this->data["block"] = Utils::readShort($this->get(2));
|
||||
$this->data["meta"] = Utils::readShort($this->get(2));
|
||||
$this->data["x"] = Utils::readInt($this->get(4));
|
||||
$this->data["y"] = Utils::readInt($this->get(4));
|
||||
$this->data["z"] = Utils::readInt($this->get(4));
|
||||
}else{
|
||||
$this->raw .= Utils::writeShort($this->data["block"]);
|
||||
$this->raw .= Utils::writeShort($this->data["meta"]);
|
||||
$this->raw .= Utils::writeInt($this->data["x"]);
|
||||
$this->raw .= Utils::writeInt($this->data["y"]);
|
||||
$this->raw .= Utils::writeInt($this->data["z"]);
|
||||
}
|
||||
break;
|
||||
case MC_REQUEST_CHUNK:
|
||||
if($this->c === false){
|
||||
$this->data["x"] = Utils::readInt($this->get(4));
|
||||
@ -255,6 +295,20 @@ class CustomPacketHandler{
|
||||
$this->raw .= Utils::writeInt($this->data["y"]);
|
||||
}
|
||||
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["unknown1"] = $this->get(WTF);
|
||||
$this->data["unknown1"] = Utils::readInt($this->get(4));
|
||||
$this->data["unknown2"] = Utils::readInt($this->get(4));
|
||||
//$this->data["unknown3"] = $this->get(WTF);
|
||||
}else{
|
||||
$this->raw .= Utils::writeInt($this->data["x"]);
|
||||
$this->raw .= Utils::writeInt($this->data["y"]);
|
||||
$this->raw .= $this->data["data"];
|
||||
}
|
||||
break;
|
||||
case MC_PLAYER_EQUIPMENT:
|
||||
if($this->c === false){
|
||||
$this->data["eid"] = Utils::readInt($this->get(4));
|
||||
|
@ -1,155 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ POCKET \
|
||||
/ MINECRAFT PHP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class MapInterface{
|
||||
protected $map, $floor, $column, $biome, $material, $biomes;
|
||||
|
||||
function __construct($client){
|
||||
$this->client = $client;
|
||||
$this->map = $this->client->mapParser;
|
||||
$this->floor = method_exists($this->map, "getFloor");
|
||||
$this->column = method_exists($this->map, "getColumn");
|
||||
//$this->biome = method_exists($this->map, "getBiome");
|
||||
//include("misc/materials.php");
|
||||
//$this->material = $material;
|
||||
//include("misc/biomes.php");
|
||||
//$this->biomes = $biomes;
|
||||
}
|
||||
|
||||
public function getBiome($x, $z){
|
||||
$x = (int) $x;
|
||||
$z = (int) $z;
|
||||
if($this->biome === true){
|
||||
return $this->map->getBiome($x, $z);
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*public function getBiomeName($x, $z){
|
||||
$biome = $this->getBiome($x, $z);
|
||||
return isset($this->biomes[$biome]) ? $this->biomes[$biome]:"Unknown";
|
||||
}*/
|
||||
|
||||
public function getBlockName($x, $y, $z){
|
||||
$block = $this->getBlock($x, $y, $z);
|
||||
return isset($this->material[$block[0]]) ? $this->material[$block[0]]:"Unknown";
|
||||
}
|
||||
|
||||
public function getFloor($x, $z, $startY = -1){
|
||||
$x = (int) $x;
|
||||
$z = (int) $z;
|
||||
if($this->floor === true){
|
||||
$map = $this->map->getFloor($x, $z, $startY);
|
||||
return $map;
|
||||
}else{
|
||||
$startY = ((int) $startY) > -1 ? ((int) $startY):HEIGHT_LIMIT - 1;
|
||||
for($y = $startY; $y > 0; --$y){
|
||||
$block = $this->getBlock($x, $y, $z);
|
||||
if(!isset($this->material["nosolid"][$block[0]])){
|
||||
break;
|
||||
}
|
||||
}
|
||||
return array($y, $block[0], $block[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public function changeBlock($x, $y, $z, $block, $metadata = 0){
|
||||
$x = (int) $x;
|
||||
$y = (int) $y;
|
||||
$z = (int) $z;
|
||||
return $this->map->changeBlock($x, $y, $z, $block, $metadata);
|
||||
}
|
||||
|
||||
public function getBlock($x, $y, $z){
|
||||
$x = (int) $x;
|
||||
$y = (int) $y;
|
||||
$z = (int) $z;
|
||||
return $this->map->getBlock($x, $y, $z);
|
||||
}
|
||||
|
||||
public function getColumn($x, $z){
|
||||
$x = (int) $x;
|
||||
$z = (int) $z;
|
||||
if($this->column === true){
|
||||
return $this->map->getColumn($x, $z);
|
||||
}else{
|
||||
$zone = $this->getZone($x,0,$z,$x,HEIGHT_LIMIT,$z);
|
||||
$data = array();
|
||||
foreach($zone as $x => $a){
|
||||
foreach($a as $y => $b){
|
||||
foreach($b as $z => $block){
|
||||
$data[$y] = $block;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
public function getEllipse($x, $y, $z, $rX = 4, $rZ = 4, $rY = 4){
|
||||
$x = (int) $x;
|
||||
$y = (int) $y;
|
||||
$z = (int) $z;
|
||||
$rY = abs((int) $rX);
|
||||
$rY = abs((int) $rZ);
|
||||
$rY = abs((int) $rY);
|
||||
return $this->getZone($x-$rX,max(0,$y-$rY),$z-$rZ,$x+$rX,$y+$rY,$z+$rZ);
|
||||
}
|
||||
|
||||
public function getSphere($x, $y, $z, $r=4){
|
||||
$x = (int) $x;
|
||||
$y = (int) $y;
|
||||
$z = (int) $z;
|
||||
$r = abs((int) $r);
|
||||
return $this->getZone($x-$r,max(0,$y-$r),$z-$r,$x+$r,$y+$r,$z+$r);
|
||||
}
|
||||
|
||||
public function getZone($x1, $y1, $z1, $x2, $y2, $z2){
|
||||
$x1 = (int) $x1;
|
||||
$y1 = (int) $y1;
|
||||
$z1 = (int) $z1;
|
||||
$x2 = (int) $x2;
|
||||
$y2 = (int) $y2;
|
||||
$z2 = (int) $z2;
|
||||
if($x1>$x2 or $y1>$y2 or $z1>$z2){
|
||||
return array();
|
||||
}
|
||||
$blocks = array();
|
||||
for($x=$x1;$x<=$x2;++$x){
|
||||
$blocks[$x] = array();
|
||||
for($z=$z1;$z<=$z2;++$z){
|
||||
$blocks[$x][$z] = array();
|
||||
for($y=$y1;$y<=$y2;++$y){
|
||||
$blocks[$x][$z][$y] = $this->getBlock($x,$y,$z);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $blocks;
|
||||
}
|
||||
|
||||
}
|
@ -34,8 +34,8 @@ class NBT {
|
||||
}
|
||||
switch(basename($filename, ".dat")){
|
||||
case "level":
|
||||
$version = Utils::readInt(strrev(fread($fp, 4)));
|
||||
$lenght = Utils::readInt(strrev(fread($fp, 4)));
|
||||
$version = Utils::readLInt(fread($fp, 4));
|
||||
$lenght = Utils::readLInt(fread($fp, 4));
|
||||
break;
|
||||
case "entities":
|
||||
fread($fp, 12);
|
||||
@ -65,15 +65,15 @@ class NBT {
|
||||
case self::TAG_BYTE: // Signed byte (8 bit)
|
||||
return Utils::readByte(fread($fp, 1));
|
||||
case self::TAG_SHORT: // Signed short (16 bit, big endian)
|
||||
return Utils::readShort(strrev(fread($fp, 2)));
|
||||
return Utils::readLShort(fread($fp, 2));
|
||||
case self::TAG_INT: // Signed integer (32 bit, big endian)
|
||||
return Utils::readInt(strrev(fread($fp, 4)));
|
||||
return Utils::readLInt(fread($fp, 4));
|
||||
case self::TAG_LONG: // Signed long (64 bit, big endian)
|
||||
return Utils::readLong(strrev(fread($fp, 8)));
|
||||
return Utils::readLLong(fread($fp, 8));
|
||||
case self::TAG_FLOAT: // Floating point value (32 bit, big endian, IEEE 754-2008)
|
||||
return Utils::readFloat(strrev(fread($fp, 4)));
|
||||
return Utils::readLFloat(fread($fp, 4));
|
||||
case self::TAG_DOUBLE: // Double value (64 bit, big endian, IEEE 754-2008)
|
||||
return Utils::readDouble(strrev(fread($fp, 8)));
|
||||
return Utils::readLDouble(fread($fp, 8));
|
||||
case self::TAG_BYTE_ARRAY: // Byte array
|
||||
$arrayLength = $this->readType($fp, self::TAG_INT);
|
||||
$array = array();
|
||||
|
@ -28,7 +28,7 @@ the Free Software Foundation, either version 3 of the License, or
|
||||
require_once("classes/Session.class.php");
|
||||
|
||||
class PocketMinecraftServer{
|
||||
var $seed, $protocol, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $timePerSecond, $responses, $spawn, $entities, $mapDir, $mapParser, $map, $level, $tileEntities;
|
||||
var $seed, $protocol, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $timePerSecond, $responses, $spawn, $entities, $mapDir, $map, $level, $tileEntities;
|
||||
private $database, $interface, $cnt, $events, $version, $serverType, $lastTick;
|
||||
function __construct($name, $gamemode = 1, $seed = false, $protocol = CURRENT_PROTOCOL, $port = 19132, $serverID = false, $version = CURRENT_VERSION){
|
||||
$this->port = (int) $port;
|
||||
@ -39,7 +39,6 @@ class PocketMinecraftServer{
|
||||
$this->version = (int) $version;
|
||||
$this->name = $name;
|
||||
$this->mapDir = false;
|
||||
$this->mapParser = false;
|
||||
$this->map = false;
|
||||
$this->level = false;
|
||||
$this->tileEntities = array();
|
||||
@ -127,6 +126,7 @@ class PocketMinecraftServer{
|
||||
|
||||
public function close($reason = "stop"){
|
||||
$this->chat(false, "Stopping server...");
|
||||
$this->save();
|
||||
$this->stop = true;
|
||||
$this->trigger("onClose");
|
||||
}
|
||||
@ -163,10 +163,20 @@ class PocketMinecraftServer{
|
||||
private function loadMap(){
|
||||
$this->level = unserialize(file_get_contents($this->mapDir."level.dat"));
|
||||
console("[INFO] Map: ".$this->level["LevelName"]);
|
||||
$this->seed = $this->level["RandomSeed"];
|
||||
$this->time = (int) $this->level["Time"];
|
||||
$this->level["Time"] = &$this->time;
|
||||
console("[INFO] Time: ".$this->time);
|
||||
console("[INFO] Seed: ".$this->seed);
|
||||
console("[INFO] Gamemode: ".($this->gamemode === 0 ? "survival":"creative"));
|
||||
console("[DEBUG] Loading entities...");
|
||||
console("[INFO] Loading map...");
|
||||
$this->map = new ChunkParser();
|
||||
if(!$this->map->loadFile($this->mapDir."chunks.dat")){
|
||||
console("[ERROR] Couldn't load the map \"".$this->level["LevelName"]."\"!", true, true, 0);
|
||||
$this->map = false;
|
||||
}else{
|
||||
|
||||
}
|
||||
console("[INFO] Loading entities...");
|
||||
$entities = unserialize(file_get_contents($this->mapDir."entities.dat"));
|
||||
foreach($entities as $entity){
|
||||
$this->entities[$this->eidCnt] = new Entity($this->eidCnt, ENTITY_MOB, $entity["id"], $this);
|
||||
@ -175,6 +185,11 @@ class PocketMinecraftServer{
|
||||
++$this->eidCnt;
|
||||
}
|
||||
console("[DEBUG] Loaded ".count($this->entities)." Entities", true, true, 2);
|
||||
$this->action(1000000 * 60 * 15, '$this->chat(false, "Forcing save...");$this->save();$this->chat(false, "Done");');
|
||||
}
|
||||
|
||||
public function save(){
|
||||
file_put_contents($this->mapDir."level.dat", serialize($this->level));
|
||||
}
|
||||
|
||||
public function start(){
|
||||
|
@ -266,6 +266,9 @@ class Session{
|
||||
++$this->counter[0];
|
||||
break;
|
||||
case MC_READY:
|
||||
if(is_object($this->entity)){
|
||||
break;
|
||||
}
|
||||
$this->server->trigger("onHealthChange", array("eid" => $this->eid, "health" => $this->data["health"]));
|
||||
console("[DEBUG] Player with EID ".$this->eid." \"".$this->username."\" spawned!", true, true, 2);
|
||||
$this->entity = new Entity($this->eid, ENTITY_PLAYER, 0, $this->server);
|
||||
@ -287,12 +290,33 @@ class Session{
|
||||
$this->server->trigger("onChat", $this->username." joined the game");
|
||||
break;
|
||||
case MC_MOVE_PLAYER:
|
||||
$this->entity->setPosition($data["x"], $data["y"], $data["z"], $data["x"], $data["yaw"], $data["pitch"]);
|
||||
$this->entity->setPosition($data["x"], $data["y"], $data["z"], $data["yaw"], $data["pitch"]);
|
||||
$this->server->trigger("onPlayerMove", $this->eid);
|
||||
break;
|
||||
case MC_PLAYER_EQUIPMENT:
|
||||
console("[DEBUG] EID ".$this->eid." has now ".$data["block"]." with metadata ".$data["meta"]." in their hands!", true, true, 2);
|
||||
break;
|
||||
case MC_REQUEST_CHUNK:
|
||||
console("[DEBUG] Chunk X ".$data["x"]." Z ".$data["z"]." requested", true, true, 2);
|
||||
break;
|
||||
case MC_REMOVE_BLOCK:
|
||||
console("[DEBUG] EID ".$this->eid." broke block at X ".$data["x"]." Y ".$data["y"]." Z ".$data["z"], true, true, 2);
|
||||
$this->send(0x84, array(
|
||||
$this->counter[0],
|
||||
0x00,
|
||||
array(
|
||||
"id" => MC_ADD_ITEM_ENTITY,
|
||||
"eid" => $this->server->eidCnt++,
|
||||
"x" => $data["x"],
|
||||
"y" => $data["y"],
|
||||
"z" => $data["z"],
|
||||
"block" => 1,
|
||||
"meta" => 0,
|
||||
"stack" => 1,
|
||||
),
|
||||
));
|
||||
++$this->counter[0];
|
||||
break;
|
||||
case MC_RESPAWN:
|
||||
$this->server->trigger("onHealthChange", array("eid" => $this->eid, "health" => 20));
|
||||
$this->entity->setPosition($data["x"], $data["y"], $data["z"], $data["x"], 0, 0);
|
||||
|
@ -252,14 +252,6 @@ class Utils{
|
||||
return pack("H*" , $hex);
|
||||
}
|
||||
|
||||
public static function readString($str){
|
||||
return preg_replace('/\x00(.)/s', '$1', $str);
|
||||
}
|
||||
|
||||
public static function writeString($str){
|
||||
return preg_replace('/(.)/s', "\x00$1", $str);
|
||||
}
|
||||
|
||||
public static function readBool($b){
|
||||
return Utils::readByte($b, false) === 0 ? false:true;
|
||||
}
|
||||
@ -300,6 +292,21 @@ class Utils{
|
||||
}
|
||||
return pack("n", $value);
|
||||
}
|
||||
|
||||
public static function readLShort($str, $signed = true){
|
||||
list(,$unpacked) = unpack("v", $str);
|
||||
if($unpacked > 0x7fff and $signed === true){
|
||||
$unpacked -= 0x10000; // Convert unsigned short to signed short
|
||||
}
|
||||
return $unpacked;
|
||||
}
|
||||
|
||||
public static function writeLShort($value){
|
||||
if($value < 0){
|
||||
$value += 0x10000;
|
||||
}
|
||||
return pack("v", $value);
|
||||
}
|
||||
|
||||
public static function readInt($str){
|
||||
list(,$unpacked) = unpack("N", $str);
|
||||
@ -316,6 +323,21 @@ class Utils{
|
||||
return pack("N", $value);
|
||||
}
|
||||
|
||||
public static function readLInt($str){
|
||||
list(,$unpacked) = unpack("V", $str);
|
||||
if($unpacked >= 2147483648){
|
||||
$unpacked -= 4294967296;
|
||||
}
|
||||
return (int) $unpacked;
|
||||
}
|
||||
|
||||
public static function writeLInt($value){
|
||||
if($value < 0){
|
||||
$value += 0x100000000;
|
||||
}
|
||||
return pack("V", $value);
|
||||
}
|
||||
|
||||
public static function readFloat($str){
|
||||
list(,$value) = ENDIANNESS === BIG_ENDIAN ? unpack("f", $str):unpack("f", strrev($str));
|
||||
return $value;
|
||||
@ -325,6 +347,15 @@ class Utils{
|
||||
return ENDIANNESS === BIG_ENDIAN ? pack("f", $value):strrev(pack("f", $value));
|
||||
}
|
||||
|
||||
public static function readLFloat($str){
|
||||
list(,$value) = ENDIANNESS === BIG_ENDIAN ? unpack("f", strrev($str)):unpack("f", $str);
|
||||
return $value;
|
||||
}
|
||||
|
||||
public static function writeLFloat($value){
|
||||
return ENDIANNESS === BIG_ENDIAN ? strrev(pack("f", $value)):pack("f", $value);
|
||||
}
|
||||
|
||||
public static function printFloat($value){
|
||||
return preg_replace("/(\.\d+?)0+$/", "$1", sprintf("%F", $value));
|
||||
}
|
||||
@ -337,6 +368,15 @@ class Utils{
|
||||
public static function writeDouble($value){
|
||||
return ENDIANNESS === BIG_ENDIAN ? pack("d", $value):strrev(pack("d", $value));
|
||||
}
|
||||
|
||||
public static function readLDouble($str){
|
||||
list(,$value) = ENDIANNESS === BIG_ENDIAN ? unpack("d", strrev($str)):unpack("d", $str);
|
||||
return $value;
|
||||
}
|
||||
|
||||
public static function writeLDouble($value){
|
||||
return ENDIANNESS === BIG_ENDIAN ? strrev(pack("d", $value)):pack("d", $value);
|
||||
}
|
||||
|
||||
public static function readLong($str){
|
||||
$long = new Math_BigInteger($str, -256);
|
||||
@ -346,6 +386,16 @@ class Utils{
|
||||
public static function writeLong($value){
|
||||
$long = new Math_BigInteger($value, -10);
|
||||
return str_pad($long->toBytes(true), 8, "\x00", STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
public static function readLLong($str){
|
||||
$long = new Math_BigInteger(strrev($str), -256);
|
||||
return $long->toString();
|
||||
}
|
||||
|
||||
public static function writeLLong($value){
|
||||
$long = new Math_BigInteger($value, -10);
|
||||
return strrev(str_pad($long->toBytes(true), 8, "\x00", STR_PAD_LEFT));
|
||||
}
|
||||
|
||||
}
|
@ -8,7 +8,7 @@ white-list=false
|
||||
debug=1
|
||||
max-players=20
|
||||
server-type=normal
|
||||
time-per-second=10
|
||||
time-per-second=20
|
||||
gamemode=1
|
||||
seed=false
|
||||
level-name=false
|
||||
|
@ -71,7 +71,6 @@ require_once("classes/Utils.class.php");
|
||||
require_once("classes/UDPSocket.class.php");
|
||||
require_once("classes/Packet.class.php");
|
||||
require_once("classes/Entity.class.php");
|
||||
require_once("classes/MapInterface.class.php");
|
||||
require_once("classes/ChunkParser.class.php");
|
||||
require_once("classes/NBT.class.php");
|
||||
require_once("classes/SerializedPacketHandler.class.php");
|
||||
|
@ -47,13 +47,16 @@ define("MC_START_GAME", 0x87);
|
||||
define("MC_ADD_PLAYER", 0x89);
|
||||
|
||||
define("MC_REMOVE_ENTITY", 0x8d);
|
||||
define("MC_ADD_ITEM_ENTITY", 0x8e);
|
||||
|
||||
define("MC_MOVE_ENTITY_POSROT", 0x93);
|
||||
define("MC_MOVE_PLAYER", 0x94);
|
||||
define("MC_PLACE_BLOCK", 0x95);
|
||||
define("MC_REMOVE_BLOCK", 0x96);
|
||||
define("MC_UPDATE_BLOCK", 0x97);
|
||||
|
||||
define("MC_REQUEST_CHUNK", 0x9d);
|
||||
define("MC_CHUNK_DATA", 0x9e);
|
||||
|
||||
define("MC_PLAYER_EQUIPMENT", 0x9f);
|
||||
|
||||
|
@ -47,6 +47,7 @@ $dataName = array(
|
||||
MC_ADD_PLAYER => "AddPlayer",
|
||||
|
||||
MC_REMOVE_ENTITY => "RemoveEntity",
|
||||
MC_ADD_ITEM_ENTITY => "AddItemEntity",
|
||||
|
||||
MC_MOVE_ENTITY_POSROT => "MoveEntity_PosRot",
|
||||
MC_MOVE_PLAYER => "MovePlayer",
|
||||
@ -54,6 +55,7 @@ $dataName = array(
|
||||
MC_REMOVE_BLOCK => "RemoveBlock",
|
||||
|
||||
MC_REQUEST_CHUNK => "RequestChunk",
|
||||
MC_CHUNK_DATA => "ChunkData",
|
||||
|
||||
MC_PLAYER_EQUIPMENT => "PlayerEquipment",
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user