mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-14 05:15:11 +00:00
Compare commits
43 Commits
Alpha_1.2
...
Alpha_1.2.
Author | SHA1 | Date | |
---|---|---|---|
db4bdcd2bd | |||
ce8724c5ed | |||
d46a61d0c4 | |||
1bfef261ab | |||
6dfe348767 | |||
3f10e11ddf | |||
5b79722fa9 | |||
fc06e1bcaf | |||
ffaaca6f2d | |||
0660409987 | |||
bbc925b188 | |||
6f7268902d | |||
6851f9c7b1 | |||
9ec9d22bbc | |||
40842ec794 | |||
ab1c28fc57 | |||
a9f7d47c25 | |||
5241f0527b | |||
5c7f397bde | |||
84ac13d591 | |||
8bf4b5cafa | |||
7acbf13a8a | |||
fa4813d335 | |||
3432a69a41 | |||
bc5516867c | |||
5c17f77bcc | |||
5fab555c48 | |||
ba3dfd91db | |||
8f21eb41ee | |||
d90e41c0d5 | |||
aecfbbbdc1 | |||
1c63448c6c | |||
8253d63d9b | |||
a7d8e22e7e | |||
ad11851c61 | |||
b259ed2532 | |||
9510cbd716 | |||
8a345e6582 | |||
66fe5d2a3e | |||
7f88ab95e2 | |||
3355f71ab3 | |||
e8c2662258 | |||
6c4900cd32 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,6 +3,7 @@ worlds/*
|
||||
plugins/*
|
||||
logs/*
|
||||
*.log
|
||||
*.pmf
|
||||
server.properties
|
||||
white-list.txt
|
||||
banned-ips.txt
|
||||
|
@ -35,4 +35,5 @@ require_once(FILE_PATH."/src/dependencies.php");
|
||||
$server = new ServerAPI();
|
||||
$server->run();
|
||||
|
||||
|
||||
kill(getmypid()); //Fix for segfault
|
||||
|
@ -1,4 +1,4 @@
|
||||

|
||||

|
||||
|
||||
# PocketMine-MP [](https://travis-ci.org/shoghicp/PocketMine-MP)
|
||||
|
||||
|
@ -18,6 +18,7 @@ echo "[INFO] Checking dependecies"
|
||||
type make >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"make\""; exit 1; }
|
||||
type autoconf >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"autoconf\""; exit 1; }
|
||||
type automake >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"automake\""; exit 1; }
|
||||
type libtool >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"libtool\""; exit 1; }
|
||||
type gcc >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"gcc\""; exit 1; }
|
||||
type m4 >> "$DIR/install.log" 2>&1 || { echo >&2 "[ERROR] Please install \"m4\""; exit 1; }
|
||||
|
||||
|
@ -31,6 +31,7 @@ class BanAPI{
|
||||
private $banned;
|
||||
private $ops;
|
||||
private $bannedIPs;
|
||||
private $cmdWL = array();
|
||||
function __construct(PocketMinecraftServer $server){
|
||||
$this->server = $server;
|
||||
}
|
||||
@ -46,16 +47,22 @@ class BanAPI{
|
||||
$this->server->api->console->register("kick", "Kicks a player", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("whitelist", "Manages White-listing", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("op", "Ops a player", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("deop", "Deops a player", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("deop", "De-ops a player", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("sudo", "Run a command as a player", array($this, "commandHandler"));
|
||||
$this->server->api->console->alias("ban-ip", "banip add");
|
||||
$this->server->api->console->alias("banlist", "ban list");
|
||||
$this->server->api->console->alias("pardon", "ban remove");
|
||||
$this->server->api->console->alias("pardon-ip", "banip remove");
|
||||
$this->server->addHandler("console.command", array($this, "opCheck"), 1);
|
||||
$this->server->addHandler("console.command", array($this, "permissionsCheck"), 1);
|
||||
$this->cmdWhitelist("help");
|
||||
}
|
||||
|
||||
public function cmdWhitelist($cmd){
|
||||
$this->cmdWhitelist[strtolower(trim($cmd))] = true;
|
||||
}
|
||||
|
||||
public function isOp($username){
|
||||
if($this->server->api->dhandle("api.op.check", $username) === false){
|
||||
if($this->server->api->dhandle("op.check", $username) === true){
|
||||
return true;
|
||||
}elseif($this->ops->exists($username)){
|
||||
return true;
|
||||
@ -63,16 +70,14 @@ class BanAPI{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function opCheck($data, $event){
|
||||
$whitelist = array(
|
||||
"help",
|
||||
);
|
||||
if(in_array($data["cmd"], $whitelist, true)){
|
||||
public function permissionsCheck($data, $event){
|
||||
|
||||
if(isset($this->cmdWhitelist[$data["cmd"]])){
|
||||
return true;
|
||||
}
|
||||
|
||||
if($data["issuer"] instanceof Player){
|
||||
if($this->isOp($data["issuer"]->username)){
|
||||
if($this->server->api->handle("console.check", $data) === true or $this->isOp($data["issuer"]->username)){
|
||||
return true;
|
||||
}
|
||||
}elseif($data["issuer"] === "console"){
|
||||
@ -84,23 +89,35 @@ class BanAPI{
|
||||
public function commandHandler($cmd, $params, $issuer, $alias){
|
||||
$output = "";
|
||||
switch($cmd){
|
||||
case "sudo":
|
||||
$target = array_shift($params);
|
||||
$player = $this->server->api->player->get($target);
|
||||
if(!($player instanceof Player)){
|
||||
$output .= "Player not connected.\n";
|
||||
break;
|
||||
}
|
||||
$this->server->api->console->run(implode(" ", $params), $player);
|
||||
$output .= "Command ran.\n";
|
||||
break;
|
||||
case "op":
|
||||
$user = trim(implode(" ", $params));
|
||||
$user = array_shift($params);
|
||||
if($user == ""){
|
||||
break;
|
||||
}
|
||||
$this->ops->set($user);
|
||||
$this->ops->save();
|
||||
$output .= $user." is now op\n";
|
||||
$this->server->api->chat->sendTo(false, "You are now op.", $user);
|
||||
break;
|
||||
case "deop":
|
||||
$user = trim(implode(" ", $params));
|
||||
$user = array_shift($params);
|
||||
if($user == ""){
|
||||
break;
|
||||
}
|
||||
$this->ops->remove($user);
|
||||
$this->ops->save();
|
||||
$output .= $user." is not longer op\n";
|
||||
$this->server->api->chat->sendTo(false, "You are not longer op.", $user);
|
||||
break;
|
||||
case "kick":
|
||||
if(!isset($params[0])){
|
||||
@ -200,7 +217,7 @@ class BanAPI{
|
||||
break;
|
||||
case "add":
|
||||
case "ban":
|
||||
$user = trim(implode($params));
|
||||
$user = array_shift($params);
|
||||
$this->banned->set($user);
|
||||
$this->banned->save();
|
||||
$player = $this->server->api->player->get($user);
|
||||
@ -213,6 +230,7 @@ class BanAPI{
|
||||
}else{
|
||||
$this->server->api->chat->broadcast($user." has been banned\n");
|
||||
}
|
||||
$this->kick($user, "Banned");
|
||||
$output .= "Player \"$user\" added to ban list\n";
|
||||
break;
|
||||
case "reload":
|
||||
@ -246,7 +264,7 @@ class BanAPI{
|
||||
$this->commandHandler("banip", array("pardon", $ip));
|
||||
}
|
||||
|
||||
public function kick($username, $reason){
|
||||
public function kick($username, $reason = "No Reason"){
|
||||
$this->commandHandler("kick", array($username, $reason));
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,14 @@ define("BLOCK_UPDATE_WEAK", 3);
|
||||
class BlockAPI{
|
||||
private $server;
|
||||
|
||||
public static function fromString($str){
|
||||
public static function fromString($str, $multiple = false){
|
||||
if($multiple === true){
|
||||
$blocks = array();
|
||||
foreach(explode(",",$str) as $b){
|
||||
$blocks[] = BlockAPI::fromString($b, false);
|
||||
}
|
||||
return $blocks;
|
||||
}else{
|
||||
$b = explode(":", str_replace(" ", "_", trim($str)));
|
||||
if(!isset($b[1])){
|
||||
$meta = 0;
|
||||
@ -56,6 +63,7 @@ class BlockAPI{
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get($id, $meta = 0, $v = false){
|
||||
$id = (int) $id;
|
||||
@ -82,7 +90,7 @@ class BlockAPI{
|
||||
return $i;
|
||||
}
|
||||
|
||||
public function setBlock($block, $id, $meta, $update = true, $tiles = false){
|
||||
public function setBlock(Vector3 $block, $id, $meta, $update = true, $tiles = false){
|
||||
if(($block instanceof Vector3) or (($block instanceof Block) and $block->inWorld === true)){
|
||||
$this->server->api->level->setBlock($block->x, $block->y, $block->z, (int) $id, (int) $meta, $update, $tiles);
|
||||
return true;
|
||||
@ -157,6 +165,11 @@ class BlockAPI{
|
||||
|
||||
$target = $this->getBlock($vector);
|
||||
$item = $player->equipment;
|
||||
|
||||
if($this->server->api->dhandle("player.block.touch", array("type" => "break", "player" => $player, "target" => $target, "item" => $item)) === false){
|
||||
return $this->cancelAction($target, $player);
|
||||
}
|
||||
|
||||
if(!$target->isBreakable($item, $player) or $player->gamemode === ADVENTURE or ($player->lastBreak + $target->getBreakTime($item, $player)) >= microtime(true)){
|
||||
return $this->cancelAction($target, $player);
|
||||
}
|
||||
@ -189,7 +202,7 @@ class BlockAPI{
|
||||
"z" => $pos->z + mt_rand(2, 8) / 10,
|
||||
"item" => $item,
|
||||
);
|
||||
if($this->server->api->handle("block.drop", $data) !== false){
|
||||
if($this->server->api->handle("item.drop", $data) !== false){
|
||||
for($count = $item->count; $count > 0; ){
|
||||
$item->count = min($item->getMaxStackSize(), $count);
|
||||
$count -= $item->count;
|
||||
@ -217,11 +230,16 @@ class BlockAPI{
|
||||
return $this->cancelAction($block, $player);
|
||||
}
|
||||
|
||||
if($this->server->api->dhandle("player.block.touch", array("type" => "place", "player" => $player, "block" => $block, "target" => $target, "item" => $item)) === false){
|
||||
return $this->cancelAction($block, $player);
|
||||
}
|
||||
|
||||
if($target->isActivable === true){
|
||||
if($this->server->api->dhandle("player.block.activate", array("player" => $player, "block" => $block, "target" => $target, "item" => $item)) !== false and $target->onActivate($this, $item, $player) === true){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if($player->gamemode === ADVENTURE){ //Adventure mode!!
|
||||
return $this->cancelAction($block, $player);
|
||||
}
|
||||
@ -307,6 +325,7 @@ class BlockAPI{
|
||||
return;
|
||||
}
|
||||
$this->updateBlock($data["x"], $data["y"], $data["z"], isset($data["type"]) ? $data["type"]:BLOCK_UPDATE_RANDOM);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function flowLavaOn($source, $face){
|
||||
|
@ -34,27 +34,11 @@ class LevelAPI{
|
||||
}
|
||||
|
||||
public function init(){
|
||||
/*$this->server->event("player.block.break", array($this, "handle"));
|
||||
$this->server->event("player.block.place", array($this, "handle"));
|
||||
$this->server->event("player.block.update", array($this, "handle"));*/
|
||||
|
||||
}
|
||||
|
||||
public function handle($data, $event){
|
||||
switch($event){
|
||||
case "player.block.place":
|
||||
case "player.block.update":
|
||||
$b = BlockAPI::get($data["block"], $data["meta"]);
|
||||
console("[DEBUG] Player ".$data["entity"]->player->username." placed ".$b->getName()." (".$data["block"].":".$data["meta"].") at (".$data["x"].", ".$data["y"].", ".$data["z"].")", true, true, 2);
|
||||
$this->setBlock($data["x"], $data["y"], $data["z"], $data["block"], $data["meta"]);
|
||||
break;
|
||||
case "player.block.break":
|
||||
if($data["block"]->getID() === 0){
|
||||
break;
|
||||
}
|
||||
$b = BlockAPI::get($block[0], $block[1]);
|
||||
console("[DEBUG] Player ".$data["player"]->username." broke ".$data["block"]->getName()." (".$data["block"]->getID().":".$data["block"]->getMetadata().") at (".$data["block"]->x.", ".$data["block"]->y.", ".$data["block"]->z.")", true, true, 2);
|
||||
$this->setBlock($data["block"]->x, $data["block"]->y, $data["block"]->z, 0, 0, true, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,7 @@ class PlayerAPI{
|
||||
$player->setHealth(min(20, $player->getHealth() + $data), "regeneration");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case "player.death":
|
||||
@ -103,6 +104,7 @@ class PlayerAPI{
|
||||
}
|
||||
}
|
||||
$this->server->chat(false, $message);
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -195,7 +197,7 @@ class PlayerAPI{
|
||||
}
|
||||
|
||||
public function get($name){
|
||||
$CID = $this->server->query("SELECT ip,port FROM players WHERE name = '".str_replace("'", "", $name)."';", true);
|
||||
$CID = $this->server->query("SELECT ip,port FROM players WHERE name = '".$name."';", true);
|
||||
$CID = $this->server->clientID($CID["ip"], $CID["port"]);
|
||||
if(isset($this->server->clients[$CID])){
|
||||
return $this->server->clients[$CID];
|
||||
|
@ -41,6 +41,7 @@ class PluginAPI extends stdClass{
|
||||
}
|
||||
|
||||
public function getInfo($className){
|
||||
$className = strtolower($className);
|
||||
if(!isset($this->plugins[$className])){
|
||||
return false;
|
||||
}
|
||||
@ -49,6 +50,10 @@ class PluginAPI extends stdClass{
|
||||
}
|
||||
|
||||
public function load($file){
|
||||
if(strtolower(substr($file, -3)) === "pmf"){
|
||||
$pmf = new PMFPlugin($file);
|
||||
$info = $pmf->getPluginInfo();
|
||||
}else{
|
||||
$content = file_get_contents($file);
|
||||
$info = strstr($content, "*/", true);
|
||||
$content = substr(strstr($content, "*/"),2);
|
||||
@ -73,24 +78,30 @@ class PluginAPI extends stdClass{
|
||||
}
|
||||
$info[$i] = $v;
|
||||
}
|
||||
$info["code"] = $content;
|
||||
$info["class"] = trim(strtolower($info["class"]));
|
||||
}
|
||||
if(!isset($info["name"]) or !isset($info["version"]) or !isset($info["class"]) or !isset($info["author"])){
|
||||
console("[ERROR] [PluginAPI] Failed parsing of ".basename($file));
|
||||
return false;
|
||||
}
|
||||
console("[INFO] [PluginAPI] Loading plugin \"\x1b[32m".$info["name"]."\x1b[0m\" \x1b[35m".$info["version"]."\x1b[0m by \x1b[36m".$info["author"]."\x1b[0m");
|
||||
console("[INFO] [PluginAPI] Loading plugin \"\x1b[32m".$info["name"]."\x1b[0m\" \x1b[35m".$info["version"]." #".intval($info["apiversion"])."\x1b[0m by \x1b[36m".$info["author"]."\x1b[0m");
|
||||
if(class_exists($info["class"])){
|
||||
console("[ERROR] [PluginAPI] Failed loading plugin: class exists");
|
||||
return false;
|
||||
}
|
||||
if(eval($content) === false or !class_exists($info["class"])){
|
||||
if(eval($info["code"]) === false or !class_exists($info["class"])){
|
||||
console("[ERROR] [PluginAPI] Failed loading plugin: evaluation error");
|
||||
return false;
|
||||
}
|
||||
$className = trim($info["class"]);
|
||||
if(!isset($info["apiversion"]) or intval($info["apiversion"]) < CURRENT_API_VERSION){
|
||||
console("[ERROR] [PluginAPI] Plugin \"".$info["name"]."\" uses an outdated API! It can crash or corrupt the server!");
|
||||
|
||||
$className = $info["class"];
|
||||
if(isset($info["apiversion"]) and intval($info["apiversion"]) > CURRENT_API_VERSION){
|
||||
console("[ERROR] [PluginAPI] Plugin \"".$info["name"]."\" uses a newer API! It can crash or corrupt the server!");
|
||||
}elseif(!isset($info["apiversion"]) or intval($info["apiversion"]) < CURRENT_API_VERSION){
|
||||
console("[NOTICE] [PluginAPI] Plugin \"".$info["name"]."\" uses an old API");
|
||||
}
|
||||
if(isset($info["api"]) and $info["api"] !== true){
|
||||
console("[INFO] [PluginAPI] Plugin \"\x1b[36m".$info["name"]."\x1b[0m\" got raw access to Server methods");
|
||||
}
|
||||
$object = new $className($this->server->api, ((isset($info["api"]) and $info["api"] !== true) ? $this->server:false));
|
||||
$object = new $className($this->server->api, false);
|
||||
if(!($object instanceof Plugin)){
|
||||
console("[ERROR] [PluginAPI] Plugin \"\x1b[36m".$info["name"]."\x1b[0m\" doesn't use the Plugin Interface");
|
||||
if(method_exists($object, "__destruct")){
|
||||
@ -166,7 +177,8 @@ class PluginAPI extends stdClass{
|
||||
$dir = dir(DATA_PATH."plugins/");
|
||||
while(false !== ($file = $dir->read())){
|
||||
if($file{0} !== "."){
|
||||
if(strtolower(substr($file, -3)) === "php"){
|
||||
$ext = strtolower(substr($file, -3));
|
||||
if($ext === "php" or $ext === "pmf"){
|
||||
$this->load(DATA_PATH."plugins/" . $file);
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ class ServerAPI{
|
||||
"memory-limit" => "256M",
|
||||
"last-update" => false,
|
||||
"white-list" => false,
|
||||
"debug" => 2,
|
||||
"debug" => 1,
|
||||
"max-players" => 20,
|
||||
"server-type" => "normal",
|
||||
"time-per-second" => 20,
|
||||
|
@ -29,6 +29,8 @@ the Free Software Foundation, either version 3 of the License, or
|
||||
class Deprecation{
|
||||
public static $events = array(
|
||||
"world.block.change" => "block.change",
|
||||
"block.drop" => "item.drop",
|
||||
"api.op.check" => "op.check",
|
||||
);
|
||||
|
||||
|
||||
|
223
src/Player.php
223
src/Player.php
@ -29,26 +29,29 @@ the Free Software Foundation, either version 3 of the License, or
|
||||
class Player{
|
||||
private $server;
|
||||
private $queue = array();
|
||||
private $buffer = array();
|
||||
private $buffer = "";
|
||||
private $lastBuffer = 0;
|
||||
private $recovery = array();
|
||||
private $evid = array();
|
||||
var $timeout;
|
||||
var $connected = true;
|
||||
var $clientID;
|
||||
var $ip;
|
||||
var $port;
|
||||
var $counter = array(0, 0, 0);
|
||||
var $username;
|
||||
var $eid = false;
|
||||
var $data = array();
|
||||
var $entity = false;
|
||||
var $auth = false;
|
||||
var $CID;
|
||||
var $MTU;
|
||||
var $spawned = false;
|
||||
var $inventory;
|
||||
public $timeout;
|
||||
public $connected = true;
|
||||
public $clientID;
|
||||
public $ip;
|
||||
public $port;
|
||||
public $counter = array(0, 0, 0);
|
||||
public $username;
|
||||
public $iusername;
|
||||
public $eid = false;
|
||||
public $data = array();
|
||||
public $entity = false;
|
||||
public $auth = false;
|
||||
public $CID;
|
||||
public $MTU;
|
||||
public $spawned = false;
|
||||
public $inventory;
|
||||
public $equipment;
|
||||
public $armor;
|
||||
var $loggedIn = false;
|
||||
public $loggedIn = false;
|
||||
public $gamemode;
|
||||
public $lastBreak;
|
||||
public $windowCnt = 0;
|
||||
@ -151,6 +154,10 @@ class Player{
|
||||
if($time > $this->timeout){
|
||||
$this->close("timeout");
|
||||
}else{
|
||||
if($this->lastBuffer <= $time and strlen($this->buffer) > 0){
|
||||
$this->sendBuffer();
|
||||
}
|
||||
|
||||
if(!empty($this->queue)){
|
||||
$cnt = 0;
|
||||
while($cnt < 4){
|
||||
@ -160,7 +167,7 @@ class Player{
|
||||
}
|
||||
switch($p[0]){
|
||||
case 0:
|
||||
$this->dataPacket($p[1], $p[2], false, $p[3]);
|
||||
$this->dataPacket($p[1]["id"], $p[1], false);
|
||||
break;
|
||||
case 1:
|
||||
eval($p[1]);
|
||||
@ -187,7 +194,7 @@ class Player{
|
||||
foreach($this->evid as $ev){
|
||||
$this->server->deleteEvent($ev);
|
||||
}
|
||||
$this->server->api->dhandle("player.quit", $this);
|
||||
$this->server->api->handle("player.quit", $this);
|
||||
$reason = $reason == "" ? "server stop":$reason;
|
||||
$this->save();
|
||||
$this->eventHandler(new Container("You have been kicked. Reason: ".$reason), "server.chat");
|
||||
@ -421,32 +428,32 @@ class Player{
|
||||
$this->timeout = microtime(true) + 20;
|
||||
switch($pid){
|
||||
case 0xa0: //NACK
|
||||
if(isset($this->buffer[$data[2]])){
|
||||
array_unshift($this->queue, array(0, $this->buffer[$data[2]][0], $this->buffer[$data[2]][1], $data[2]));
|
||||
if(isset($this->recovery[$data[2]])){
|
||||
$this->directDataPacket($this->recovery[$data[2]]["id"], $this->recovery[$data[2]]);
|
||||
}
|
||||
if(isset($data[3])){
|
||||
if(isset($this->buffer[$data[3]])){
|
||||
array_unshift($this->queue, array(0, $this->buffer[$data[3]][0], $this->buffer[$data[3]][1], $data[3]));
|
||||
if(isset($this->recovery[$data[3]])){
|
||||
$this->directDataPacket($this->recovery[$data[3]]["id"], $this->recovery[$data[3]]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xc0: //ACK
|
||||
$diff = $data[2] - $this->counter[2];
|
||||
if($diff > 8){ //Packet recovery
|
||||
array_unshift($this->queue, array(0, $this->buffer[$data[2]][0], $this->buffer[$data[2]][1], $data[2]));
|
||||
$this->directDataPacket($this->recovery[$data[2]]["id"], $this->recovery[$data[2]]);
|
||||
}
|
||||
$this->counter[2] = $data[2];
|
||||
$this->buffer[$data[2]] = null;
|
||||
unset($this->buffer[$data[2]]);
|
||||
$this->recovery[$data[2]] = null;
|
||||
unset($this->recovery[$data[2]]);
|
||||
|
||||
if(isset($data[3])){
|
||||
$diff = $data[3] - $this->counter[2];
|
||||
if($diff > 8){ //Packet recovery
|
||||
array_unshift($this->queue, array(0, $this->buffer[$data[3]][0], $this->buffer[$data[3]][1], $data[3]));
|
||||
$this->directDataPacket($this->recovery[$data[3]]["id"], $this->recovery[$data[3]]);
|
||||
}
|
||||
$this->counter[2] = $data[3];
|
||||
$this->buffer[$data[3]] = null;
|
||||
unset($this->buffer[$data[3]]);
|
||||
$this->recovery[$data[3]] = null;
|
||||
unset($this->recovery[$data[3]]);
|
||||
}
|
||||
break;
|
||||
case 0x07:
|
||||
@ -528,30 +535,30 @@ class Player{
|
||||
break;
|
||||
}
|
||||
$this->loggedIn = true;
|
||||
$this->username = str_replace(array("\x00", "/", " ", "\r", "\n", '"', "'"), array("", "-", "_", "", "", "", ""), $data["username"]);
|
||||
if($this->username == ""){
|
||||
if(preg_match('#^[a-zA-Z0-9_]{2,16}$#', $data["username"])){
|
||||
$this->username = $data["username"];
|
||||
$this->iusername = strtolower($this->username);
|
||||
}else{
|
||||
$this->close("bad username", false);
|
||||
break;
|
||||
}
|
||||
$o = $this->server->api->player->getOffline($this->username);
|
||||
if($this->server->whitelist === true and !$this->server->api->ban->inWhitelist($this->username)){
|
||||
if($this->server->whitelist === true and !$this->server->api->ban->inWhitelist($this->iusername)){
|
||||
$this->close("\"\x1b[33m".$this->username."\x1b[0m\" not being on white-list", false);
|
||||
break;
|
||||
}elseif($this->server->api->ban->isBanned($this->username) or $this->server->api->ban->isIPBanned($this->ip)){
|
||||
}elseif($this->server->api->ban->isBanned($this->iusername) or $this->server->api->ban->isIPBanned($this->ip)){
|
||||
$this->close("\"\x1b[33m".$this->username."\x1b[0m\" is banned!", false);
|
||||
}
|
||||
$u = $this->server->api->player->get($this->username);
|
||||
$c = $this->server->api->player->getByClientID($this->clientID);
|
||||
$u = $this->server->api->player->get($this->iusername);
|
||||
if($u !== false){
|
||||
$u->close("logged in from another location");
|
||||
}
|
||||
if($c !== false){
|
||||
$c->close("logged in from another location");
|
||||
}
|
||||
if($this->server->api->dhandle("player.join", $this) === false){
|
||||
|
||||
if($this->server->api->handle("player.join", $this) === false){
|
||||
$this->close();
|
||||
return;
|
||||
}
|
||||
|
||||
$this->server->api->player->add($this->CID);
|
||||
$this->auth = true;
|
||||
if(!isset($this->data["inventory"]) or $this->gamemode === CREATIVE){
|
||||
@ -616,17 +623,45 @@ class Player{
|
||||
if($this->MTU <= 548){
|
||||
$this->eventHandler("Your connection is bad, you may experience lag and slow map loading.", "server.chat");
|
||||
}
|
||||
|
||||
if($this->iusername === "steve" or $this->iusername === "stevie"){
|
||||
$this->eventHandler("You're using the default username. Please change it on the Minecraft PE settings.", "server.chat");
|
||||
}
|
||||
$this->sendInventory();
|
||||
$this->entity->setPosition($this->entity->x, $this->entity->y, $this->entity->z, 0, 0);
|
||||
/*
|
||||
0x01 world_inmutable
|
||||
0x02 ?
|
||||
0x04 ?
|
||||
0x08 ?
|
||||
0x10 ?
|
||||
0x20 nametags_visible
|
||||
0x40 ?
|
||||
0x80 ?
|
||||
0x00000001 world_inmutable
|
||||
0x00000002 ?
|
||||
0x00000004 ?
|
||||
0x00000008 ?
|
||||
0x00000010 ?
|
||||
0x00000020 nametags_visible
|
||||
0x00000040 ?
|
||||
0x00000080 ?
|
||||
0x00000100 ?
|
||||
0x00000200 ?
|
||||
0x00000400 ?
|
||||
0x00000800 ?
|
||||
0x00001000 ?
|
||||
0x00002000 ?
|
||||
0x00004000 ?
|
||||
0x00008000 ?
|
||||
0x00010000 ?
|
||||
0x00020000 ?
|
||||
0x00040000 ?
|
||||
0x00080000 ?
|
||||
0x00100000 ?
|
||||
0x00200000 ?
|
||||
0x00400000 ?
|
||||
0x00800000 ?
|
||||
0x01000000 ?
|
||||
0x02000000 ?
|
||||
0x04000000 ?
|
||||
0x08000000 ?
|
||||
0x10000000 ?
|
||||
0x20000000 ?
|
||||
0x40000000 ?
|
||||
0x80000000 ?
|
||||
*/
|
||||
$flags = 0;
|
||||
if($this->gamemode === ADVENTURE){
|
||||
@ -656,8 +691,10 @@ class Player{
|
||||
break;
|
||||
}
|
||||
$data["eid"] = $this->eid;
|
||||
$data["player"] = $this;
|
||||
$data["item"] = BlockAPI::getItem($data["block"], $data["meta"]);
|
||||
if($this->server->handle("player.equipment.change", $data) !== false){
|
||||
$this->equipment = BlockAPI::getItem($data["block"], $data["meta"]);
|
||||
$this->equipment = $data["item"];
|
||||
console("[DEBUG] Player ".$this->username." has now ".$this->equipment->getName()." (".$this->equipment->getID().":".$this->equipment->getMetadata().") in their hands!", true, true, 2);
|
||||
}
|
||||
break;
|
||||
@ -769,8 +806,11 @@ class Player{
|
||||
if($this->loggedIn === false){
|
||||
break;
|
||||
}
|
||||
$item = BlockAPI::getItem($data["block"], $data["meta"], $data["stack"]);
|
||||
$data["item"] = $item;
|
||||
if($this->server->handle("player.drop", $data) !== false){
|
||||
$this->server->api->block->drop(new Vector3($this->entity->x, $this->entity->y, $this->entity->z), BlockAPI::getItem($data["block"], $data["meta"], $data["stack"]));
|
||||
$this->removeItem($item->getID(), $item->getMetadata(), $item->count);
|
||||
$this->server->api->block->drop(new Vector3($this->entity->x - 0.5, $this->entity->y, $this->entity->z - 0.5), $item);
|
||||
}
|
||||
break;
|
||||
case MC_SIGN_UPDATE:
|
||||
@ -817,32 +857,50 @@ class Player{
|
||||
}
|
||||
$tile = $this->windows[$data["windowid"]];
|
||||
$done = false;
|
||||
$item = BlockAPI::getItem($data["block"], $data["meta"], $data["stack"]);
|
||||
|
||||
$s = array(
|
||||
"Count" => $item->count,
|
||||
"Slot" => $data["slot"],
|
||||
"id" => $item->getID(),
|
||||
"Damage" => $item->getMetadata(),
|
||||
);
|
||||
|
||||
foreach($tile->data["Items"] as $i => $slot){
|
||||
if($slot["Slot"] === $data["slot"]){
|
||||
$done = true;
|
||||
$s = $tile->data["Items"][$i] = array(
|
||||
"Count" => $data["stack"] & 0xFFFF,
|
||||
"Slot" => $data["slot"],
|
||||
"id" => $data["block"] & 0xFFFF,
|
||||
"Damage" => $data["meta"] & 0xFFFF
|
||||
);
|
||||
if($item->getID() !== AIR and $slot["id"] == $item->getID()){
|
||||
if($slot["Count"] < $item->count){
|
||||
$this->removeItem($item->getID(), $item->getMetadata(), $item->count - $slot["Count"]);
|
||||
}elseif($slot["Count"] > $item->count){
|
||||
$this->addItem($item->getID(), $item->getMetadata(), $slot["Count"] - $item->count);
|
||||
}
|
||||
$tile->data["Items"][$i] = $s;
|
||||
}else{
|
||||
$this->removeItem($item->getID(), $item->getMetadata(), $item->count);
|
||||
$this->addItem($slot["id"], $slot["Damage"], $slot["Count"]);
|
||||
if($item->getID() === AIR or $item->count <= 0){
|
||||
unset($tile->data["Items"][$i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($done === false){
|
||||
$tile->data["Items"][] = $s = array(
|
||||
"Count" => $data["stack"] & 0xFFFF,
|
||||
"Slot" => $data["slot"],
|
||||
"id" => $data["block"] & 0xFFFF,
|
||||
"Damage" => $data["meta"] & 0xFFFF
|
||||
);
|
||||
if($item->getID() !== AIR and $item->count > 0){
|
||||
$this->removeItem($item->getID(), $item->getMetadata(), $item->count);
|
||||
$tile->data["Items"][] = $s;
|
||||
}
|
||||
}
|
||||
|
||||
$this->server->api->dhandle("tile.container.slot", array(
|
||||
"tile" => $tile,
|
||||
"slot" => $data["slot"],
|
||||
"slotdata" => $s,
|
||||
"player" => $this,
|
||||
));
|
||||
$this->server->handle("tile.update", $tile);
|
||||
break;
|
||||
case MC_SEND_INVENTORY: //TODO, Mojang, enable this <20>^_^`
|
||||
break;
|
||||
@ -904,25 +962,52 @@ class Player{
|
||||
$this->queue[] = array(1, $code);
|
||||
}
|
||||
|
||||
public function dataPacket($id, $data = array(), $queue = false, $count = false){
|
||||
if($queue === true){
|
||||
$this->queue[] = array(0, $id, $data, $count);
|
||||
}else{
|
||||
if($count === false){
|
||||
public function sendBuffer(){
|
||||
if(strlen($this->buffer) > 0){
|
||||
$count = $this->counter[0];
|
||||
++$this->counter[0];
|
||||
if(count($this->buffer) >= 512){
|
||||
array_shift($this->buffer);
|
||||
if(count($this->recovery) >= 512){
|
||||
array_shift($this->recovery);
|
||||
}
|
||||
$this->buffer[$count] = array($id, $data);
|
||||
$this->recovery[$count] = array("id" => false, "raw" => $this->buffer);
|
||||
$this->send(0x80, array(
|
||||
$count,
|
||||
0x00,
|
||||
$this->recovery[$count],
|
||||
));
|
||||
}
|
||||
|
||||
$this->buffer = "";
|
||||
$this->lastBuffer = microtime(true) + 0.05;
|
||||
}
|
||||
|
||||
public function directDataPacket($id, $data){
|
||||
$data["id"] = $id;
|
||||
$count = $this->counter[0];
|
||||
++$this->counter[0];
|
||||
$this->send(0x80, array(
|
||||
$count,
|
||||
0x00,
|
||||
$data,
|
||||
));
|
||||
}
|
||||
|
||||
public function dataPacket($id, $data = array(), $queue = false){
|
||||
$data["id"] = $id;
|
||||
if($queue === true){
|
||||
$this->queue[] = array(0, $data);
|
||||
}else{
|
||||
$data = new CustomPacketHandler($id, "", $data, true);
|
||||
$len = strlen($data->raw) + 1;
|
||||
$MTU = $this->MTU - 7;
|
||||
|
||||
if((strlen($this->buffer) + $len) >= $MTU){
|
||||
$this->sendBuffer();
|
||||
}
|
||||
|
||||
$this->buffer .= ($this->buffer === "" ? "":"\x00").Utils::writeShort($len << 3) . chr($id) . $data->raw;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function __toString(){
|
||||
|
@ -98,7 +98,16 @@ class PocketMinecraftServer{
|
||||
return round($tps, 4);
|
||||
}
|
||||
|
||||
public function titleTick(){
|
||||
if(ENABLE_ANSI === true){
|
||||
echo "\x1b]0;PocketMine-MP ".MAJOR_VERSION." | Online ". count($this->clients)." | RAM ".round((memory_get_usage(true) / 1024) / 1024, 2)."MB | TPS ".$this->getTPS()."\x07";
|
||||
}
|
||||
}
|
||||
|
||||
public function loadEvents(){
|
||||
if(ENABLE_ANSI === true){
|
||||
$this->action(1500000, '$this->titleTick();');
|
||||
}
|
||||
$this->action(500000, '$this->time += (int) ($this->timePerSecond / 2);$this->api->dhandle("server.time", $this->time);');
|
||||
$this->action(5000000, 'if($this->difficulty < 2){$this->api->dhandle("server.regeneration", 1);}');
|
||||
$this->action(1000000 * 60, '$this->reloadConfig();');
|
||||
@ -106,7 +115,6 @@ class PocketMinecraftServer{
|
||||
if($this->api instanceof ServerAPI){
|
||||
$this->action(1000000 * 80, '$cnt = count($this->clients); if($cnt > 1){$this->api->chat->broadcast("Online (".$cnt."): ".implode(", ",$this->api->player->online()));}');
|
||||
}
|
||||
$this->action(1000000 * 120, '$this->debugInfo(true);');
|
||||
}
|
||||
|
||||
public function startDatabase(){
|
||||
@ -115,7 +123,7 @@ class PocketMinecraftServer{
|
||||
//$this->query("PRAGMA journal_mode = OFF;");
|
||||
//$this->query("PRAGMA encoding = \"UTF-8\";");
|
||||
//$this->query("PRAGMA secure_delete = OFF;");
|
||||
$this->query("CREATE TABLE players (clientID INTEGER PRIMARY KEY, EID NUMERIC, ip TEXT, port NUMERIC, name TEXT UNIQUE);");
|
||||
$this->query("CREATE TABLE players (clientID INTEGER PRIMARY KEY, EID NUMERIC, ip TEXT, port NUMERIC, name TEXT UNIQUE COLLATE NOCASE);");
|
||||
$this->query("CREATE TABLE entities (EID INTEGER PRIMARY KEY, type NUMERIC, class NUMERIC, name TEXT, x NUMERIC, y NUMERIC, z NUMERIC, yaw NUMERIC, pitch NUMERIC, health NUMERIC);");
|
||||
$this->query("CREATE TABLE tileentities (ID INTEGER PRIMARY KEY, class TEXT, x NUMERIC, y NUMERIC, z NUMERIC, spawnable NUMERIC);");
|
||||
$this->query("CREATE TABLE actions (ID INTEGER PRIMARY KEY, interval NUMERIC, last NUMERIC, code TEXT, repeat NUMERIC);");
|
||||
@ -193,7 +201,7 @@ class PocketMinecraftServer{
|
||||
|
||||
}
|
||||
|
||||
public function addHandler($event, $callable, $priority = 5){
|
||||
public function addHandler($event,callable $callable, $priority = 5){
|
||||
if(!is_callable($callable)){
|
||||
return false;
|
||||
}elseif(isset(Deprecation::$events[$event])){
|
||||
@ -216,7 +224,7 @@ class PocketMinecraftServer{
|
||||
$this->preparedSQL->selectHandlers->clear();
|
||||
$this->preparedSQL->selectHandlers->bindValue(":name", $event, SQLITE3_TEXT);
|
||||
$handlers = $this->preparedSQL->selectHandlers->execute();
|
||||
$result = true;
|
||||
$result = null;
|
||||
if($handlers !== false and $handlers !== true){
|
||||
console("[INTERNAL] Handling ".$event, true, true, 3);
|
||||
$call = array();
|
||||
@ -225,7 +233,7 @@ class PocketMinecraftServer{
|
||||
}
|
||||
$handlers->finalize();
|
||||
foreach($call as $hnid => $boolean){
|
||||
if($result !== false){
|
||||
if($result !== false and $result !== true){
|
||||
$called[$hnid] = true;
|
||||
$handler = $this->handlers[$hnid];
|
||||
if(is_array($handler)){
|
||||
@ -349,7 +357,7 @@ class PocketMinecraftServer{
|
||||
}
|
||||
$t = $this->api->tileentity->add($tile["id"], $tile["x"], $tile["y"], $tile["z"], $tile);
|
||||
}
|
||||
$this->action(1000000 * 60 * 15, '$this->api->chat->broadcast("Forcing save...");$this->save();');
|
||||
$this->action(1000000 * 60 * 25, '$this->api->chat->broadcast("Forcing save...");$this->save();');
|
||||
}
|
||||
}
|
||||
|
||||
@ -539,7 +547,9 @@ class PocketMinecraftServer{
|
||||
$this->custom["times_".$CID] = 0;
|
||||
}
|
||||
$ln = 15;
|
||||
if($this->description == "" or substr($this->description, -1) != " "){
|
||||
$this->description .= " ";
|
||||
}
|
||||
$txt = substr($this->description, $this->custom["times_".$CID], $ln);
|
||||
$txt .= substr($this->description, 0, $ln - strlen($txt));
|
||||
$this->send(0x1c, array(
|
||||
@ -654,7 +664,7 @@ class PocketMinecraftServer{
|
||||
}
|
||||
}
|
||||
|
||||
public function schedule($ticks, $callback, $data = array(), $repeat = false, $eventName = "server.schedule"){
|
||||
public function schedule($ticks,callable $callback, $data = array(), $repeat = false, $eventName = "server.schedule"){
|
||||
if(!is_callable($callback)){
|
||||
return false;
|
||||
}
|
||||
@ -696,7 +706,7 @@ class PocketMinecraftServer{
|
||||
$this->preparedSQL->updateActions->execute();
|
||||
}
|
||||
|
||||
public function event($event, $func){
|
||||
public function event($event,callable $func){
|
||||
if(!is_callable($func)){
|
||||
return false;
|
||||
}elseif(isset(Deprecation::$events[$event])){
|
||||
|
@ -43,9 +43,9 @@ ini_set("memory_limit", "256M"); //Default
|
||||
define("LOG", true);
|
||||
define("MAGIC", "\x00\xff\xff\x00\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78");
|
||||
define("TEST_MD5", "ffe889db5932db1e3371d48773590e59");
|
||||
define("MAJOR_VERSION", "Alpha_1.2");
|
||||
define("MAJOR_VERSION", "Alpha_1.2.1");
|
||||
define("CURRENT_STRUCTURE", 5);
|
||||
define("CURRENT_PROTOCOL", 9);
|
||||
define("CURRENT_MINECRAFT_VERSION", "v0.6.1 alpha");
|
||||
define("CURRENT_API_VERSION", 3);
|
||||
define("CURRENT_API_VERSION", 4);
|
||||
define("CURRENT_PHP_VERSION", "5.4.12");
|
@ -25,6 +25,11 @@ the Free Software Foundation, either version 3 of the License, or
|
||||
|
||||
*/
|
||||
|
||||
/***REM_START***/
|
||||
require_once("BurningFurnace.php");
|
||||
/***REM_END***/
|
||||
|
||||
|
||||
class FurnaceBlock extends BurningFurnaceBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct($meta);
|
||||
|
@ -27,7 +27,7 @@ the Free Software Foundation, either version 3 of the License, or
|
||||
|
||||
class QuartzBlock extends SolidBlock{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(QUARTZ, $meta, "Quartz Block");
|
||||
parent::__construct(QUARTZ_BLOCK, $meta, "Quartz Block");
|
||||
$names = array(
|
||||
0 => "Quartz Block",
|
||||
1 => "Chiseled Quartz Block",
|
||||
|
@ -86,9 +86,6 @@ class Vector3{
|
||||
if(($x instanceof Vector3) === true){
|
||||
return $this->add($x->x, $x->y, $x->z);
|
||||
}else{
|
||||
$this->x += $x;
|
||||
$this->y += $y;
|
||||
$this->z += $z;
|
||||
return new Vector3($this->x + $x, $this->y + $y, $this->z + $z);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,11 @@ the Free Software Foundation, either version 3 of the License, or
|
||||
*/
|
||||
|
||||
class CustomPacketHandler{
|
||||
var $offset, $raw, $c, $data, $name = "";
|
||||
public $offset;
|
||||
public $raw;
|
||||
public $c;
|
||||
public $data;
|
||||
public $name = "";
|
||||
|
||||
private function get($len = true, $check = true){
|
||||
if($len === true){
|
||||
|
@ -69,24 +69,27 @@ class MinecraftInterface{
|
||||
if($this->socket->connected === false){
|
||||
return false;
|
||||
}
|
||||
$data = $this->socket->read();
|
||||
if($data[3] === false){
|
||||
$buf = "";
|
||||
$source = false;
|
||||
$port = 1;
|
||||
$len = $this->socket->read($buf, $source, $port);
|
||||
if($len === false){
|
||||
return false;
|
||||
}
|
||||
$pid = ord($data[0]);
|
||||
$pid = ord($buf{0});
|
||||
$struct = $this->getStruct($pid);
|
||||
if($struct === false){
|
||||
console("[ERROR] Unknown Packet ID 0x".Utils::strToHex(chr($pid)), true, true, 0);
|
||||
$p = "[".(microtime(true) - $this->start)."] [".((($origin === "client" and $this->client === true) or ($origin === "server" and $this->client === false)) ? "CLIENT->SERVER":"SERVER->CLIENT")." ".$ip.":".$port."]: Error, bad packet id 0x".Utils::strTohex(chr($pid))." [length ".strlen($raw)."]".PHP_EOL;
|
||||
$p .= Utils::hexdump($data[0]);
|
||||
$p = "[".(microtime(true) - $this->start)."] [".((($origin === "client" and $this->client === true) or ($origin === "server" and $this->client === false)) ? "CLIENT->SERVER":"SERVER->CLIENT")." ".$ip.":".$port."]: Error, bad packet id 0x".Utils::strToHex(chr($pid))." [length ".strlen($buf)."]".PHP_EOL;
|
||||
$p .= Utils::hexdump($buf);
|
||||
$p .= PHP_EOL;
|
||||
logg($p, "packets", true, 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
$packet = new Packet($pid, $struct, $data[0]);
|
||||
$packet = new Packet($pid, $struct, $buf);
|
||||
@$packet->parse();
|
||||
$this->data[] = array($pid, $packet->data, $data[0], $data[1], $data[2]);
|
||||
$this->data[] = array($pid, $packet->data, $buf, $source, $port);
|
||||
return $this->popPacket();
|
||||
}
|
||||
|
||||
|
@ -80,10 +80,15 @@ class Packet{
|
||||
$this->addRaw($reply->raw);
|
||||
break;
|
||||
case 0x00:
|
||||
$reply = new CustomPacketHandler($this->data[$field]["id"], "", $this->data[$field], true);
|
||||
$this->addRaw(Utils::writeShort((strlen($reply->raw) + 1) << 3));
|
||||
if($this->data[$field]["id"] !== false){
|
||||
$raw = new CustomPacketHandler($this->data[$field]["id"], "", $this->data[$field], true);
|
||||
$raw = $raw->raw;
|
||||
$this->addRaw(Utils::writeShort((strlen($raw) + 1) << 3));
|
||||
$this->addRaw(chr($this->data[$field]["id"]));
|
||||
$this->addRaw($reply->raw);
|
||||
$this->addRaw($raw);
|
||||
}else{
|
||||
$this->addRaw($this->data[$field]["raw"]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -76,14 +76,18 @@ class UDPSocket{
|
||||
socket_set_nonblock($this->sock);
|
||||
}
|
||||
|
||||
public function read(){
|
||||
$source = false;
|
||||
$port = 1;
|
||||
$len = @socket_recvfrom($this->sock, $buf, 65536, 0, $source, $port);
|
||||
return array($buf, $source, $port, $len);
|
||||
public function read(&$buf, &$source, &$port){
|
||||
if($this->connected === false){
|
||||
return false;
|
||||
}
|
||||
$len = @socket_recvfrom($this->sock, $buf, 65535, 0, $source, $port);
|
||||
return $len;
|
||||
}
|
||||
|
||||
public function write($data, $dest = false, $port = false){
|
||||
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));
|
||||
}
|
||||
|
||||
|
130
src/pmf/PMF.php
Normal file
130
src/pmf/PMF.php
Normal file
@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
define("PMF_CURRENT_VERSION", 0x01);
|
||||
|
||||
class PMF{
|
||||
protected $fp;
|
||||
private $file;
|
||||
private $version;
|
||||
private $type;
|
||||
|
||||
public function __construct($file, $new = false, $type = 0, $version = PMF_CURRENT_VERSION){
|
||||
if($new === true){
|
||||
$this->create($file, $type, $version);
|
||||
}else{
|
||||
if($this->load($file) !== true){
|
||||
$this->parseInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getVersion(){
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
public function getType(){
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function load($file){
|
||||
$this->close();
|
||||
$this->file = realpath($file);
|
||||
if(($this->fp = @fopen($file, "c+b")) !== false){
|
||||
$stat = fstat($this->fp);
|
||||
if($stat["size"] >= 5){ //Header + 2 Bytes
|
||||
return true;
|
||||
}
|
||||
$this->close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function parseInfo(){
|
||||
$this->seek(0);
|
||||
if(fread($this->fp, 3) !== "PMF"){
|
||||
return false;
|
||||
}
|
||||
$this->version = ord($this->read(1));
|
||||
switch($this->version){
|
||||
case 0x01:
|
||||
$this->type = ord($this->read(1));
|
||||
break;
|
||||
default:
|
||||
console("[ERROR] Tried loading non-supported PMF version ".$this->version." on file ".$this->file);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getFile(){
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
public function close(){
|
||||
unset($this->version, $this->type, $this->file);
|
||||
if(is_object($this->fp)){
|
||||
fclose($this->fp);
|
||||
}
|
||||
}
|
||||
|
||||
public function create($file, $type, $version = PMF_CURRENT_VERSION){
|
||||
$this->file = realpath($file);
|
||||
if(!is_resource($this->fp)){
|
||||
if(($this->fp = @fopen($file, "c+b")) === false){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->seek(0);
|
||||
$this->write("PMF" . chr((int) $version) . chr((int) $type));
|
||||
}
|
||||
|
||||
public function read($length){
|
||||
if($length <= 0){
|
||||
return "";
|
||||
}
|
||||
if(is_resource($this->fp)){
|
||||
return fread($this->fp, (int) $length);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function write($string, $length = false){
|
||||
if(is_resource($this->fp)){
|
||||
return ($length === false ? fwrite($this->fp, $string) : fwrite($this->fp, $string, $length));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function seek($offset, $whence = SEEK_SET){
|
||||
if(is_resource($this->fp)){
|
||||
return fseek($this->fp, (int) $offset, (int) $whence);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
66
src/pmf/Plugin.php
Normal file
66
src/pmf/Plugin.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @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.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/***REM_START***/
|
||||
require_once(FILE_PATH."/src/pmf/PMF.php");
|
||||
/***REM_END***/
|
||||
|
||||
define("PMF_CURRENT_PLUGIN_VERSION", 0x00);
|
||||
|
||||
class PMFPlugin extends PMF{
|
||||
private $pluginData = array();
|
||||
public function __construct($file){
|
||||
$this->load($file);
|
||||
$this->parseInfo();
|
||||
$this->parsePlugin();
|
||||
}
|
||||
|
||||
public function getPluginInfo(){
|
||||
return $this->pluginData;
|
||||
}
|
||||
|
||||
protected function parsePlugin(){
|
||||
if($this->getType() !== 0x01){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->pluginData["fversion"] = ord($this->read(1));
|
||||
$this->pluginData["name"] = $this->read(Utils::readShort($this->read(2), false));
|
||||
$this->pluginData["version"] = $this->read(Utils::readShort($this->read(2), false));
|
||||
$this->pluginData["author"] = $this->read(Utils::readShort($this->read(2), false));
|
||||
$this->pluginData["apiversion"] = Utils::readShort($this->read(2), false);
|
||||
$this->pluginData["class"] = $this->read(Utils::readShort($this->read(2), false));
|
||||
$this->pluginData["identifier"] = $this->read(Utils::readShort($this->read(2), false)); //Will be used to check for updates
|
||||
$this->pluginData["extra"] = gzinflate($this->read(Utils::readShort($this->read(2), false))); //Additional custom plugin data
|
||||
$this->pluginData["code"] = "";
|
||||
while(!feof($this->fp)){
|
||||
$this->pluginData["code"] .= $this->read(4096);
|
||||
}
|
||||
$this->pluginData["code"] = gzinflate($this->pluginData["code"]);
|
||||
}
|
||||
|
||||
}
|
@ -1,32 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2011 Vladimir Andersen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
|
||||
* Spyc -- A Simple PHP YAML Class
|
||||
* @version 0.5
|
||||
* @version 0.5.1
|
||||
* @author Vlad Andersen <vlad.andersen@gmail.com>
|
||||
* @author Chris Wanstrath <chris@ozmm.org>
|
||||
* @link http://code.google.com/p/spyc/
|
||||
@ -35,28 +10,6 @@ THE SOFTWARE.
|
||||
* @package Spyc
|
||||
*/
|
||||
|
||||
if (!function_exists('spyc_load')) {
|
||||
/**
|
||||
* Parses YAML to array.
|
||||
* @param string $string YAML string.
|
||||
* @return array
|
||||
*/
|
||||
function spyc_load ($string) {
|
||||
return Spyc::YAMLLoadString($string);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('spyc_load_file')) {
|
||||
/**
|
||||
* Parses YAML to array.
|
||||
* @param string $file Path to YAML file.
|
||||
* @return array
|
||||
*/
|
||||
function spyc_load_file ($file) {
|
||||
return Spyc::YAMLLoad($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Simple PHP YAML Class.
|
||||
*
|
||||
@ -458,18 +411,16 @@ class Spyc {
|
||||
$i--;
|
||||
}
|
||||
|
||||
// Strip out comments
|
||||
if (strpos ($line, '#')) {
|
||||
$line = preg_replace('/\s*#([^"\']+)$/','',$line);
|
||||
}
|
||||
|
||||
while (++$i < $cnt && self::greedilyNeedNextLine($line)) {
|
||||
$line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t");
|
||||
}
|
||||
$i--;
|
||||
|
||||
|
||||
|
||||
if (strpos ($line, '#')) {
|
||||
if (strpos ($line, '"') === false && strpos ($line, "'") === false)
|
||||
$line = preg_replace('/\s+#(.+)$/','',$line);
|
||||
}
|
||||
|
||||
$lineArray = $this->_parseLine($line);
|
||||
|
||||
if ($literalBlockStyle)
|
||||
@ -679,6 +630,7 @@ class Spyc {
|
||||
} while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false);
|
||||
|
||||
$explode = explode(',',$inline);
|
||||
$explode = array_map('trim', $explode);
|
||||
$stringi = 0; $i = 0;
|
||||
|
||||
while (1) {
|
||||
|
@ -326,12 +326,6 @@ class Entity extends stdClass{
|
||||
}elseif($y > $this->fallY){
|
||||
$this->fallY = $y;
|
||||
}
|
||||
if($this->fallY !== false and ($this->fallStart + 8) < microtime(true)){ //Flying
|
||||
$this->harm(1, "flying");
|
||||
if($y > $this->fallY){
|
||||
$this->fallY = $y;
|
||||
}
|
||||
}
|
||||
}elseif($this->fallY !== false){ //Fall damage!
|
||||
if($y < $this->fallY){
|
||||
$d = $this->server->api->block->getBlock(new Vector3($x, $y + 1, $z));
|
||||
|
@ -308,7 +308,7 @@ class WorldGenerator{
|
||||
$chunk = str_pad($this->getChunk($X, $Z), 86012, "\x00", STR_PAD_RIGHT);
|
||||
$this->raw .= Utils::writeLInt(strlen($chunk)) . $chunk;
|
||||
}
|
||||
console("[DEBUG] Generating level ".ceil(($Z + 1)/0.16)."%", true, true, 2);
|
||||
console("[NOTICE] Generating level ".ceil(($Z + 1)/0.16)."%");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user