Huge commit (Block API, changed events)

Changed Session to Player
Block API
Block Data
This commit is contained in:
Shoghi Cervantes Pueyo 2012-12-24 00:44:13 +01:00
parent e47bacce74
commit b867ba559e
10 changed files with 311 additions and 102 deletions

112
classes/API/BlockAPI.php Normal file
View File

@ -0,0 +1,112 @@
<?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.
*/
class BlockAPI{
private $server;
function __construct($server){
$this->server = $server;
}
public function init(){
$this->server->addHandler("world.block.update", array($this, "handle"));
$this->server->addHandler("player.block.action", array($this, "handle"));
}
public function handle($data, $event){
switch($event){
case "player.block.action":
$target = $this->server->api->level->getBlock($data["x"], $data["y"], $data["z"]);
$cancelPlace = false;
if(isset(Material::$activable[$target[0]])){
switch($target[0]){
case 2:
case 3:
case 6:
break;
default:
$cancelPlace = true;
break;
}
}
if($cancelPlace === true or $face < 0 or $face > 5){
return;
}
if(!isset(Material::$replaceable[$target[0]])){
switch($data["face"]){
case 0:
--$data["y"];
break;
case 1:
++$data["y"];
break;
case 2:
--$data["z"];
break;
case 3:
++$data["z"];
break;
case 4:
--$data["x"];
break;
case 5:
++$data["x"];
break;
}
}
$block = $this->server->api->level->getBlock($data["x"], $data["y"], $data["z"]);
if(!isset(Material::$replaceable[$block[0]])){
return;
}
if(isset(Material::$placeable[$data["block"]])){
$data["block"] = Material::$placeable[$data["block"]] === true ? $data["block"]:Material::$placeable[$data["block"]];
}else{
return;
}
$entity = $this->server->api->entity->get($this->eid);
switch($data["block"]){
case 53:
break;
}
$this->server->handle("player.block.place", $data);
$this->updateBlocksAround($data["x"], $data["x"], $data["z"]);
}
}
public function updateBlocksAround($x, $y, $z){
}
}

View File

@ -35,7 +35,7 @@ class ConsoleAPI{
}
public function init(){
$this->event = $this->server->event("onTick", array($this, "handle"));
$this->event = $this->server->event("server.tick", array($this, "handle"));
}
function __destroy(){
@ -236,7 +236,7 @@ class ConsoleAPI{
console("[INFO] Issued server command: /$cmd ".implode(" ", $params));
if(isset($this->help[$cmd]) and is_callable($this->help[$cmd][1])){
call_user_func($this->help[$cmd][1], $cmd, $params);
}elseif($this->server->trigger("onCommand", array("cmd" => $cmd, "params" => $params)) !== false){
}elseif($this->server->trigger("api.console.command", array("cmd" => $cmd, "params" => $params)) !== false){
$this->defaultCommands($cmd, $params);
}
}

View File

@ -36,18 +36,17 @@ class LevelAPI{
}
public function init(){
$this->server->addHandler("onBlockBreak", array($this, "handle"));
$this->server->addHandler("onBlockPlace", array($this, "handle"));
$this->server->addHandler("player.block.break", array($this, "handle"));
$this->server->addHandler("player.block.place", array($this, "handle"));
}
public function handle($data, $event){
switch($event){
case "onBlockPlace":
$block = $this->getBlock($data["x"], $data["y"], $data["z"]);
console("[DEBUG] EID ".$data["eid"]." placed ".$data["block"].":".$data["meta"]." into ".$block[0].":".$block[1]." at X ".$data["x"]." Y ".$data["y"]." Z ".$data["z"], true, true, 2);
case "player.block.place":
console("[DEBUG] EID ".$data["eid"]." placed ".$data["block"].":".$data["meta"]." at X ".$data["x"]." Y ".$data["y"]." Z ".$data["z"], true, true, 2);
$this->setBlock($data["x"], $data["y"], $data["z"], $data["block"], $data["meta"]);
break;
case "onBlockBreak":
case "player.block.break":
$block = $this->getBlock($data["x"], $data["y"], $data["z"]);
console("[DEBUG] EID ".$data["eid"]." broke block ".$block[0].":".$block[1]." at X ".$data["x"]." Y ".$data["y"]." Z ".$data["z"], true, true, 2);
@ -102,7 +101,7 @@ class LevelAPI{
if($this->check()){
$this->map->setBlock($x, $y, $z, $block, $meta);
}
$this->server->trigger("onBlockUpdate", array(
$this->server->trigger("world.block.change", array(
"x" => $x,
"y" => $y,
"z" => $z,

View File

@ -29,7 +29,7 @@ class PlayerAPI{
private $server;
function __construct($server){
$this->server = $server;
$this->server->event("onHealthRegeneration", array($this, "handle"));
$this->server->event("server.regeneration", array($this, "handle"));
}
public function init(){
@ -41,7 +41,7 @@ class PlayerAPI{
public function handle($data, $event){
switch($event){
case "onHealthRegeneration":
case "server.regeneration":
$result = $this->server->query("SELECT ip,port FROM players WHERE EID = (SELECT EID FROM entities WHERE health < 20);", true);
if($result !== true and $result !== false){
while(false !== ($player = $result->fetchArray())){

View File

@ -424,9 +424,9 @@ class CustomPacketHandler{
$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["unknown2"] = Utils::readFloat($this->get(4));
$this->data["unknown3"] = Utils::readFloat($this->get(4));
$this->data["unknown4"] = Utils::readFloat($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));
}else{
/*$this->raw .= Utils::writeByte($this->data["action"]);
$this->raw .= Utils::writeInt($this->data["eid"]);

143
classes/Data.class.php Normal file
View File

@ -0,0 +1,143 @@
<?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.
*/
class Material{
static $replaceable = array(
0 => true,
8 => true,
9 => true,
10 => true,
11 => true,
31 => true,
51 => true,
78 => true,
);
static $activable = array(
2 => true,
3 => true,
6 => true,
26 => true,
31 => true,
46 => true,
51 => true,
54 => true,
58 => true,
61 => true,
62 => true,
64 => true,
73 => true,
78 => true,
96 => true,
107 => true,
247 => true,
);
static $placeable = array(
1 => true,
2 => true,
3 => true,
4 => true,
5 => true,
6 => true,
//7 => true,
8 => true,
9 => true,
10 => true,
11 => true,
12 => true,
13 => true,
14 => true,
15 => true,
16 => true,
17 => true,
18 => true,
19 => true,
20 => true,
21 => true,
22 => true,
24 => true,
355 => 26,
30 => true,
35 => true,
37 => true,
38 => true,
39 => true,
40 => true,
41 => true,
42 => true,
43 => true,
44 => true,
45 => true,
46 => true,
47 => true,
48 => true,
49 => true,
50 => true,
53 => true,
54 => true,
59 => true,
57 => true,
58 => true,
295 => 59,
61 => true,
324 => 64,
65 => true,
67 => true,
73 => true,
79 => true,
80 => true,
81 => true,
82 => true,
83 => true,
85 => true,
86 => true,
87 => true,
88 => true,
89 => true,
91 => true,
96 => true,
98 => true,
102 => true,
103 => true,
362 => 105,
107 => true,
108 => true,
246 => true,
247 => true,
);
static $blocks = array(
0 => "Air",
1 => "Stone",
2 => "Grass",
3 => "Dirt",
4 => "Cobblestone",
5 => "Wooden Planks",
6 => "Sapling",
7 => "Bedrock",
);
}

View File

@ -121,7 +121,7 @@ class Entity extends stdClass{
public function close(){
if($this->closed === false){
$this->server->query("DELETE FROM entities WHERE EID = ".$this->eid.";");
$this->server->trigger("onEntityRemove", $this->eid);
$this->server->trigger("entity.remove", $this->eid);
$this->closed = true;
}
}
@ -186,7 +186,7 @@ class Entity extends stdClass{
public function setHealth($health, $cause = ""){
$this->health = (int) $health;
$this->server->query("UPDATE entities SET health = ".$this->health." WHERE EID = ".$this->eid.";");
$this->server->trigger("onHealthChange", array("eid" => $this->eid, "health" => $health, "cause" => $cause));
$this->server->trigger("entity.health.change", array("eid" => $this->eid, "health" => $health, "cause" => $cause));
if($this->player !== false){
$this->player->dataPacket(MC_SET_HEALTH, array(
"health" => $this->health,

View File

@ -26,7 +26,7 @@ the Free Software Foundation, either version 3 of the License, or
*/
class Session{
class Player{
private $server, $timeout, $connected, $evid, $queue, $buffer;
var $clientID, $ip, $port, $counter, $username, $eid, $data, $entity, $auth, $CID, $MTU, $spawned;
function __construct($server, $clientID, $ip, $port, $MTU){
@ -44,8 +44,8 @@ class Session{
$this->timeout = microtime(true) + 25;
$this->evid = array();
$this->spawned = false;
$this->evid[] = $this->server->event("onTick", array($this, "onTick"));
$this->evid[] = $this->server->event("onClose", array($this, "close"));
$this->evid[] = $this->server->event("server.tick", array($this, "onTick"));
$this->evid[] = $this->server->event("server.close", array($this, "close"));
console("[DEBUG] New Session started with ".$ip.":".$port.". MTU ".$this->MTU.", Client ID ".$this->clientID, true, true, 2);
$this->connected = true;
$this->auth = false;
@ -53,7 +53,7 @@ class Session{
}
public function onTick($time, $event){
if($event !== "onTick"){
if($event !== "server.tick"){
return;
}
if($time > $this->timeout){
@ -96,7 +96,7 @@ class Session{
foreach($this->evid as $ev){
$this->server->deleteEvent($ev);
}
$this->eventHandler("You have been kicked. Reason: ".$reason, "onChat");
$this->eventHandler("You have been kicked. Reason: ".$reason, "server.chat");
$this->dataPacket(MC_LOGIN_STATUS, array(
"status" => 1,
));
@ -104,7 +104,7 @@ class Session{
$this->connected = false;
if($msg === true){
$this->server->trigger("onChat", $this->username." left the game");
$this->server->trigger("server.chat", $this->username." left the game");
}
console("[INFO] Session with ".$this->ip.":".$this->port." Client ID ".$this->clientID." closed due to ".$reason);
$this->server->api->player->remove($this->CID);
@ -112,23 +112,10 @@ class Session{
public function eventHandler($data, $event){
switch($event){
case "onBlockUpdate":
case "world.block.change":
$this->dataPacket(MC_UPDATE_BLOCK, $data);
break;
case "onTeleport":
if($data["eid"] !== $this->eid){
break;
}
$this->dataPacket(MC_MOVE_PLAYER, array(
"eid" => $data["eid"],
"x" => $data["x"],
"y" => $data["y"],
"z" => $data["z"],
"yaw" => 0,
"pitch" => 0,
));
break;
case "onEntityMove":
case "entity.move":
if($data === $this->eid){
break;
}
@ -142,7 +129,7 @@ class Session{
"pitch" => $entity->pitch,
));
break;
case "onEntityRemove":
case "entity.remove":
if($data === $this->eid){
break;
}
@ -150,12 +137,12 @@ class Session{
"eid" => $data,
));
break;
case "onTimeChange":
case "server.time.change":
$this->dataPacket(MC_SET_TIME, array(
"time" => $data,
));
break;
case "onAnimate":
case "entity.animate":
if($data["eid"] === $this->eid){
break;
}
@ -164,7 +151,7 @@ class Session{
"action" => $data["action"],
));
break;
case "onChat":
case "server.chat":
$this->dataPacket(MC_CHAT, array(
"message" => str_replace("@username", $this->username, $data),
));
@ -286,24 +273,23 @@ class Session{
$this->entity->data["clientID"] = $this->clientID;
$this->server->api->entity->spawnAll($this);
$this->server->api->entity->spawnToAll($this->eid);
$this->evid[] = $this->server->event("onTimeChange", array($this, "eventHandler"));
$this->evid[] = $this->server->event("onChat", array($this, "eventHandler"));
$this->evid[] = $this->server->event("onEntityRemove", array($this, "eventHandler"));
$this->evid[] = $this->server->event("onEntityMove", array($this, "eventHandler"));
$this->evid[] = $this->server->event("onAnimate", array($this, "eventHandler"));
$this->evid[] = $this->server->event("onTeleport", array($this, "eventHandler"));
$this->evid[] = $this->server->event("onBlockUpdate", array($this, "eventHandler"));
$this->evid[] = $this->server->event("server.time.change", array($this, "eventHandler"));
$this->evid[] = $this->server->event("server.chat", array($this, "eventHandler"));
$this->evid[] = $this->server->event("entity.remove", array($this, "eventHandler"));
$this->evid[] = $this->server->event("entity.move", array($this, "eventHandler"));
$this->evid[] = $this->server->event("entity.animate", array($this, "eventHandler"));
$this->evid[] = $this->server->event("world.block.change", array($this, "eventHandler"));
console("[DEBUG] Player with EID ".$this->eid." \"".$this->username."\" spawned!", true, true, 2);
$this->eventHandler($this->server->motd, "onChat");
$this->eventHandler($this->server->motd, "server.chat");
if($this->MTU <= 548){
$this->eventHandler("Your connection is bad, you may experience lag and slow map loading.", "onChat");
$this->eventHandler("Your connection is bad, you may experience lag and slow map loading.", "server.chat");
}
break;
case MC_MOVE_PLAYER:
if(is_object($this->entity)){
$this->entity->setPosition($data["x"], $data["y"], $data["z"], $data["yaw"], $data["pitch"]);
$this->server->trigger("onEntityMove", $this->eid);
$this->server->trigger("entity.move", $this->eid);
}
break;
case MC_PLAYER_EQUIPMENT:
@ -324,47 +310,15 @@ class Session{
console("[INTERNAL] Chunk X ".$data["x"]." Z ".$data["z"]." requested", true, true, 3);
break;
case MC_USE_ITEM:
if($data["face"] >= 0 and $data["face"] <= 5 and $data["block"] !== 0){
switch($data["face"]){
case 0:
--$data["y"];
break;
case 1:
++$data["y"];
break;
case 2:
--$data["z"];
break;
case 3:
++$data["z"];
break;
case 4:
--$data["x"];
break;
case 5:
++$data["x"];
break;
}
if($data["block"] === 65){
$data["block"] = 63;
}
$data["eid"] = $this->eid;
$this->server->handle("onBlockPlace", $data);
if($data["block"] === 63){
$data["line0"] = "WHOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
$data["line1"] = "this is a test";
$data["line2"] = "I'm ".$this->username;
$data["line3"] = "TPS: ".$this->server->getTPS();
$this->dataPacket(MC_SIGN_UPDATE, $data);
}
}
$data["eid"] = $this->eid;
$this->server->handle("player.block.action", $data);
break;
case MC_PLACE_BLOCK:
var_dump($data);
break;
case MC_REMOVE_BLOCK:
$data["eid"] = $this->eid;
$this->server->handle("onBlockBreak", $data);
$this->server->handle("player.block.break", $data);
break;
case MC_INTERACT:
if(isset($this->server->entities[$data["target"]]) and Utils::distance($this->entity->position, $this->server->entities[$data["target"]]->position) <= 8){
@ -375,7 +329,7 @@ class Session{
}
break;
case MC_ANIMATE:
$this->server->trigger("onAnimate", array("eid" => $this->eid, "action" => $data["action"]));
$this->server->trigger("entity.animate", array("eid" => $this->eid, "action" => $data["action"]));
break;
case MC_RESPAWN:
$this->entity->setHealth(20, "respawn");

View File

@ -25,8 +25,6 @@ the Free Software Foundation, either version 3 of the License, or
*/
require_once("classes/Session.class.php");
class PocketMinecraftServer extends stdClass{
var $invisible, $tickMeasure, $preparedSQL, $seed, $protocol, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $timePerSecond, $responses, $spawn, $entities, $mapDir, $mapName, $map, $level, $tileEntities;
private $database, $interface, $evCnt, $handCnt, $events, $handlers, $version, $serverType, $lastTick;
@ -86,11 +84,11 @@ class PocketMinecraftServer extends stdClass{
}
public function loadEvents(){
$this->event("onChat", "eventHandler", true);
$this->event("onPlayerAdd", "eventHandler", true);
$this->event("server.chat", "eventHandler", true);
$this->event("player.new", "eventHandler", true);
$this->action(500000, '$this->time += (int) ($this->timePerSecond / 2);$this->trigger("onTimeChange", $this->time);');
$this->action(5000000, 'if($this->difficulty < 2){$this->trigger("onHealthRegeneration", 1);}');
$this->action(500000, '$this->time += (int) ($this->timePerSecond / 2);$this->trigger("server.time.change", $this->time);');
$this->action(5000000, 'if($this->difficulty < 2){$this->trigger("server.regeneration", 1);}');
$this->action(1000000 * 60, '$this->reloadConfig();');
$this->action(1000000 * 60 * 10, '$this->custom = array();');
if($this->api !== false){
@ -156,7 +154,7 @@ class PocketMinecraftServer extends stdClass{
$this->chat(false, "Stopping server...");
$this->save();
$this->stop = true;
$this->trigger("onClose");
$this->trigger("server.close");
$this->interface->close();
}
@ -166,7 +164,7 @@ class PocketMinecraftServer extends stdClass{
$message = "<".$owner."> ";
}
$message .= $text;
$this->trigger("onChat", $message);
$this->trigger("server.chat", $message);
}
public function setType($type = "normal"){
@ -200,20 +198,21 @@ class PocketMinecraftServer extends stdClass{
if($handlers === false or $handlers === true){
return $this->trigger($event, $data);
}
while(false !== ($hn = $handlers->fetchArray(SQLITE3_ASSOC))){
$result = true;
while(false !== ($hn = $handlers->fetchArray(SQLITE3_ASSOC)) and $result !== false){
$hnid = (int) $hn["ID"];
call_user_func($this->handlers[$hnid], $data, $event);
$result = call_user_func($this->handlers[$hnid], $data, $event);
}
$handlers->finalize();
return true;
return $result;
}
public function eventHandler($data, $event){
switch($event){
case "onPlayerAdd":
case "player.new":
console("[DEBUG] Player \"".$data["username"]."\" EID ".$data["eid"]." spawned at X ".$data["x"]." Y ".$data["y"]." Z ".$data["z"], true, true, 2);
break;
case "onChat":
case "server.chat":
console("[CHAT] $data");
break;
}
@ -309,7 +308,7 @@ class PocketMinecraftServer extends stdClass{
array_shift($this->tickMeasure);
$this->tickMeasure[] = $this->lastTick = $time;
$this->tickerFunction($time);
$this->trigger("onTick", $time);
$this->trigger("server.tick", $time);
}
}
@ -415,7 +414,7 @@ class PocketMinecraftServer extends stdClass{
$port = $data[2];
$MTU = $data[3];
$clientID = $data[4];
$this->clients[$CID] = new Session($this, $clientID, $packet["ip"], $packet["port"], $MTU);
$this->clients[$CID] = new Player($this, $clientID, $packet["ip"], $packet["port"], $MTU);
$this->clients[$CID]->handle(0x07, $data);
break;
}

View File

@ -69,6 +69,8 @@ if($errors > 0){
}
require_once("classes/Data.class.php");
require_once("classes/Player.class.php");
require_once("classes/Generator.class.php");
require_once("classes/DefaultGenerator.class.php");
require_once("classes/Utils.class.php");