SQLite database, Entities, position, health

This commit is contained in:
Shoghi Cervantes Pueyo 2012-12-07 02:23:57 +01:00
parent 842e01ffac
commit ea1725ed57
15 changed files with 472 additions and 77 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
data/*
*.log
*.bat
server.properties

View File

@ -184,6 +184,31 @@ class CustomPacketHandler{
$this->raw .= Utils::writeFloat($this->data["z"]);
}
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["yaw"] = Utils::readFloat($this->get(4));
$this->data["pitch"] = Utils::readFloat($this->get(4));
$this->data["block"] = Utils::readShort($this->get(2), false);
$this->data["meta"] = Utils::readShort($this->get(2), false);
}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::writeFloat($this->data["yaw"]);
$this->raw .= Utils::writeFloat($this->data["pitch"]);
$this->raw .= Utils::writeShort($this->data["block"]);
$this->raw .= Utils::writeShort($this->data["meta"]);
}
break;
case MC_REMOVE_ENTITY:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
@ -233,8 +258,8 @@ class CustomPacketHandler{
case MC_PLAYER_EQUIPMENT:
if($this->c === false){
$this->data["eid"] = Utils::readInt($this->get(4));
$this->data["block"] = Utils::readShort($this->get(2), true);
$this->data["meta"] = Utils::readShort($this->get(2), true);
$this->data["block"] = Utils::readShort($this->get(2), false);
$this->data["meta"] = Utils::readShort($this->get(2), false);
}else{
$this->raw .= Utils::writeInt($this->data["eid"]);
$this->raw .= Utils::writeShort($this->data["block"]);
@ -246,6 +271,19 @@ class CustomPacketHandler{
$this->data["health"] = ord($this->get(1));
}else{
$this->raw .= chr($this->data["health"]);
}
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_CLIENT_MESSAGE:

157
classes/Entity.class.php Normal file
View File

@ -0,0 +1,157 @@
<?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.
*/
define("ENTITY_PLAYER", 0);
define("ENTITY_MOB", 1);
define("ENTITY_OBJECT", 2);
define("ENTITY_ITEM", 3);
define("ENTITY_PAINTING", 4);
class Entity{
var $eid, $type, $name, $position, $dead, $metadata, $class, $attach;
protected $health, $client;
function __construct($eid, $class, $type = 0, $server){ //$type = 0 ---> player
$this->server = $server;
$this->eid = (int) $eid;
$this->type = (int) $type;
$this->class = (int) $class;
$this->attach = false;
$this->status = 0;
$this->health = 20;
$this->dead = false;
$this->server->query("INSERT OR REPLACE INTO entities (EID, type, class, health) VALUES (".$this->eid.", ".$this->type.", ".$this->class.", ".$this->health.");");
$this->metadata = array();
/*include("misc/entities.php");
switch($this->class){
case ENTITY_PLAYER:
case ENTITY_ITEM:
break;
case ENTITY_MOB:
$this->setName((isset($mobs[$this->type]) ? $mobs[$this->type]:$this->type));
break;
case ENTITY_OBJECT:
$this->setName((isset($objects[$this->type]) ? $objects[$this->type]:$this->type));
break;
}*/
}
public function __destruct(){
$this->server->query("DELETE FROM entities WHERE EID = ".$this->eid.";");
$this->server->trigger("onEntityRemove", $this->eid);
}
public function getEID(){
return $this->eid;
}
public function getName(){
return $this->name;
}
public function setName($name){
$this->name = $name;
$this->server->query("UPDATE entities SET name = '".str_replace("'", "", $this->name)."' WHERE EID = ".$this->eid.";");
}
public function look($pos2){
$pos = $this->getPosition();
$angle = Utils::angle3D($pos2, $pos);
$this->position["yaw"] = $angle["yaw"];
$this->position["pitch"] = $angle["pitch"];
$this->server->query("UPDATE entities SET pitch = ".$this->position["pitch"].", yaw = ".$this->position["yaw"]." WHERE EID = ".$this->eid.";");
}
public function setCoords($x, $y, $z){
if(!isset($this->position)){
$this->position = array(
"x" => 0,
"y" => 0,
"z" => 0,
"yaw" => 0,
"pitch" => 0,
"ground" => 0,
);
}
$this->position["x"] = $x;
$this->position["y"] = $y;
$this->position["z"] = $z;
$this->server->query("UPDATE entities SET x = ".$this->position["x"].", y = ".$this->position["y"].", z = ".$this->position["z"]." WHERE EID = ".$this->eid.";");
}
public function move($x, $y, $z, $yaw = 0, $pitch = 0){
if(!isset($this->position)){
$this->position = array(
"x" => 0,
"y" => 0,
"z" => 0,
"yaw" => 0,
"pitch" => 0,
"ground" => 0,
);
}
$this->position["x"] += $x;
$this->position["y"] += $y;
$this->position["z"] += $z;
$this->position["yaw"] += $yaw;
$this->position["yaw"] %= 360;
$this->position["pitch"] += $pitch;
$this->position["pitch"] %= 90;
$this->server->query("UPDATE entities SET x = ".$this->position["x"].", y = ".$this->position["y"].", z = ".$this->position["z"].", pitch = ".$this->position["pitch"].", yaw = ".$this->position["yaw"]." WHERE EID = ".$this->eid.";");
}
public function setPosition($x, $y, $z, $yaw, $pitch){
$this->position = array(
"x" => $x,
"y" => $y,
"z" => $z,
"yaw" => $yaw,
"pitch" => $pitch,
"ground" => $ground,
);
$this->server->query("UPDATE entities SET x = ".$this->position["x"].", y = ".$this->position["y"].", z = ".$this->position["z"].", pitch = ".$this->position["pitch"].", yaw = ".$this->position["yaw"]." WHERE EID = ".$this->eid.";");
return true;
}
public function getPosition($round = false){
return !isset($this->position) ? false:($round === true ? array_map("floor", $this->position):$this->position);
}
public function setHealth($health){
$this->health = (int) $health;
$this->server->query("UPDATE entities SET health = ".$this->health." WHERE EID = ".$this->eid.";");
}
public function getHealth(){
return $this->health;
}
}
?>

View File

@ -28,11 +28,14 @@ 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;
protected $interface, $entities, $player, $cnt, $events, $version, $serverType;
var $seed, $protocol, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $timePerSecond, $responses, $spawn, $entities;
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->gamemode = (int) $gamemode;
$this->port = (int) $port;
console("[INFO] Starting Minecraft PE Server at *:".$this->port);
console("[INFO] Loading database...");
$this->startDatabase();
$this->gamemode = (int) $gamemode;
$this->version = (int) $version;
$this->name = $name;
$this->custom = array();
@ -44,23 +47,16 @@ class PocketMinecraftServer{
$this->bannedIPs = array();
$this->motd = "Welcome to ".$name;
$this->serverID = $serverID === false ? Utils::readLong(Utils::getRandomBytes(8)):$serverID;
$this->seed = $seed === false ? Utils::readInt(Utils::getRandomBytes(4)):((int) $seed);
$this->events = array("disabled" => array());
$this->actions = array();
$this->seed = $seed === false ? Utils::readInt(Utils::getRandomBytes(4)):$seed;
$this->clients = array();
$this->protocol = (int) $protocol;
$this->spawn = array("x" => 128.5,"y" => 100,"z" => 128.5);
$this->time = 0;
//$this->event("onTick", "onTick", true);
$this->event("onChat", "eventHandler", true);
$this->action(1000000, '$this->time += 10;$this->trigger("onTimeChange", $this->time);');
$this->action(1000000 * 60, '$this->reloadConfig();');
$this->action(1000000 * 60 * 10, '$this->custom = array();');
$this->timePerSecond = 10;
console("[INFO] Loading events...");
$this->loadEvents();
$this->setType("normal");
$this->interface = new MinecraftInterface("255.255.255.255", $this->protocol, $this->port, true, false);
console("[INFO] Starting Minecraft PE Server at *:".$this->port);
$this->action(1000000 * 3 * 60, '$this->chat(false, "This server uses Pocket-Minecraft-PHP");');
sleep(2);
$this->action(1000000 * 3 * 60, '$this->chat(false, "Check it at http://bit.ly/RE7uaW");');
$this->reloadConfig();
console("[INFO] Server Name: ".$this->name);
console("[INFO] Server GUID: ".$this->serverID);
@ -69,6 +65,37 @@ class PocketMinecraftServer{
console("[INFO] Gamemode: ".($this->gamemode === 0 ? "survival":"creative"));
console("[INFO] Max Clients: ".$this->maxClients);
$this->stop = false;
console("[INFO] Server started!");
}
public function loadEvents(){
$this->events = array("disabled" => array());
$this->event("onChat", "eventHandler", true);
$this->action(1000000, '$this->time += $this->timePerSecond;$this->trigger("onTimeChange", $this->time);');
$this->action(1000000 * 60, '$this->reloadConfig();');
$this->action(1000000 * 60 * 10, '$this->custom = array();');
$this->action(1000000 * 80, '$list = ""; foreach($this->clients as $c){$list .= ", ".$c->username;}$this->chat(false, count($this->clients)."/".$this->maxClients." online: ".substr($list, 2));');
$this->action(1000000 * 3 * 60, '$this->chat(false, "This server uses Pocket-Minecraft-PHP");');
$this->action(1000000 * 3 * 60, '$this->chat(false, "Check it at http://bit.ly/RE7uaW");');
$this->action(1000000 * 75, '$this->debugInfo(true);');
}
public function startDatabase(){
$this->database = new SQLite3(":memory:");
$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 metadata (EID INTEGER PRIMARY KEY, name TEXT, value TEXT);");
$this->query("CREATE TABLE actions (ID INTEGER PRIMARY KEY, interval NUMERIC, last NUMERIC, code TEXT, repeat NUMERIC);");
$this->query("CREATE TABLE events (ID INTEGER PRIMARY KEY, eventName TEXT, disabled INTEGER);");
}
public function query($sql, $fetch = false){
$result = $this->database->query($sql) or console("[ERROR] [SQL Error] ".$this->database->lastErrorMsg().". Query: ".$sql, true, true, 0);
if($fetch === true and ($result !== false and $result !== true)){
$result = $result->fetchArray(SQLITE3_ASSOC);
}
return $result;
}
public function reloadConfig(){
@ -78,6 +105,23 @@ class PocketMinecraftServer{
$this->bannedIPs = explode("\n", str_replace(array(" ","\t","\r"), "", file_get_contents(FILE_PATH."banned-ips.txt")));
}
public function debugInfo($console = false){
$info = array();
$info["memory_usage"] = round((memory_get_usage(true) / 1024) / 1024, 2)."MB";
$info["memory_peak_usage"] = round((memory_get_peak_usage(true) / 1024) / 1024, 2)."MB";
$info["entities"] = $this->query("SELECT count(EID) as count FROM entities;", true);
$info["entities"] = $info["entities"]["count"];
$info["events"] = $this->query("SELECT count(ID) as count FROM events;", true);
$info["events"] = $info["events"]["count"];
$info["actions"] = $this->query("SELECT count(ID) as count FROM actions;", true);
$info["actions"] = $info["actions"]["count"];
$info["garbage"] = gc_collect_cycles();
if($console === true){
console("[DEBUG] Memory usage: ".$info["memory_usage"]." (Peak ".$info["memory_peak_usage"]."), Entities: ".$info["entities"].", Events: ".$info["events"].", Actions: ".$info["actions"].", Garbage: ".$info["garbage"], true, true, 2);
}
return $info;
}
public function close($reason = "stop"){
$this->chat(false, "Stopping server...");
$this->stop = true;
@ -113,28 +157,20 @@ class PocketMinecraftServer{
}
}
public function action($microseconds, $code){
$this->actions[] = array($microseconds / 1000000, microtime(true), $code);
console("[INTERNAL] Attached to action ".$microseconds, true, true, 3);
}
public function start(){
declare(ticks=15);
register_tick_function(array($this, "tickerFunction"));
$this->action(50000, '$this->trigger("onTick", $time);');
register_tick_function(array($this, "tick"));
$this->event("onTick", "tickerFunction", true);
$this->event("onReceivedPacket", "packetHandler", true);
register_shutdown_function(array($this, "close"));
$this->process();
}
public function tickerFunction(){
//actions that repeat every x time will go here
public function tick(){
$time = microtime(true);
foreach($this->actions as $id => $action){
if($action[1] <= ($time - $action[0])){
$this->actions[$id][1] = $time;
eval($action[2]);
}
if($this->lastTick <= ($time - 0.05)){
$this->lastTick = $time;
$this->trigger("onTick", $time);
}
}
@ -201,9 +237,8 @@ class PocketMinecraftServer{
$port = $data[2];
$MTU = $data[3];
$clientID = $data[4];
$EID = $this->eidCnt++;
$this->clients[$CID] = new Session($this, $clientID, $EID, $packet["ip"], $packet["port"]);
$entities[$EID] = &$this->clients[$CID];
$eid = $this->eidCnt++;
$this->clients[$CID] = new Session($this, $clientID, $eid, $packet["ip"], $packet["port"]);
$this->clients[$CID]->handle(0x07, $data);
break;
}
@ -229,25 +264,61 @@ class PocketMinecraftServer{
}
public function trigger($event, $data = ""){
$events = $this->query("SELECT ID FROM events WHERE eventName = '".$event."' AND disabled = 0;");
if($events === false or $events === true){
return;
}
console("[INTERNAL] Event ". $event, true, true, 3);
if(isset($this->events[$event]) and !isset($this->events["disabled"][$event])){
foreach($this->events[$event] as $evid => $ev){
if(isset($ev[1]) and ($ev[1] === true or is_object($ev[1]))){
$this->responses[$evid] = call_user_func(array(($ev[1] === true ? $this:$ev[1]), $ev[0]), $data, $event, $this);
}else{
$this->responses[$evid] = call_user_func($ev[0], $data, $event, $this);
}
while($evn = $events->fetchArray(SQLITE3_ASSOC)){
$ev = $this->events[$event][$evn["ID"]];
if(isset($ev[1]) and ($ev[1] === true or is_object($ev[1]))){
$this->responses[$evn["ID"]] = call_user_func(array(($ev[1] === true ? $this:$ev[1]), $ev[0]), $data, $event, $this);
}else{
$this->responses[$evn["ID"]] = call_user_func($ev[0], $data, $event, $this);
}
}
}
}
public function response($eid){
if(isset($this->responses[$eid])){
$res = $this->responses[$eid];
unset($this->responses[$eid]);
return $res;
}
return false;
}
public function action($microseconds, $code, $repeat = true){
$this->query("INSERT INTO actions (interval, last, code, repeat) VALUES(".($microseconds / 1000000).", ".microtime(true).", '".str_replace("'", "\\'", $code)."', ".($repeat === true ? 1:0).");");
console("[INTERNAL] Attached to action ".$microseconds, true, true, 3);
}
public function tickerFunction(){
//actions that repeat every x time will go here
$time = microtime(true);
$actions = $this->query("SELECT ID,code,repeat FROM actions WHERE last <= (".$time." - interval);");
if($actions === false or $actions === true){
return;
}
while($action = $actions->fetchArray(SQLITE3_ASSOC)){
eval($action["code"]);
if($action["repeat"] === 0){
$this->query("DELETE FROM actions WHERE ID = ".$action["ID"].";");
}
}
$this->query("UPDATE actions SET last = ".$time." WHERE last <= (".$time." - interval);");
}
public function toggleEvent($event){
if(isset($this->events["disabled"][$event])){
unset($this->events["disabled"][$event]);
$this->query("UPDATE events SET disabled = 0 WHERE eventName = '".$event."';");
console("[INTERNAL] Enabled event ".$event, true, true, 3);
}else{
$this->events["disabled"][$event] = false;
$this->query("UPDATE events SET disabled = 1 WHERE eventName = '".$event."';");
console("[INTERNAL] Disabled event ".$event, true, true, 3);
}
}
}
public function event($event, $func, $in = false){
@ -255,18 +326,23 @@ class PocketMinecraftServer{
if(!isset($this->events[$event])){
$this->events[$event] = array();
}
$this->query("INSERT INTO events (ID, eventName, disabled) VALUES (".$this->cnt.", '".str_replace("'", "\\'", $event)."', 0);");
$this->events[$event][$this->cnt] = array($func, $in);
console("[INTERNAL] Attached to event ".$event, true, true, 3);
return $this->cnt;
}
public function deleteEvent($event, $id = -1){
$id = (int) $id;
if($id === -1){
unset($this->events[$event]);
$this->query("DELETE FROM events WHERE eventName = '".str_replace("'", "\\'", $event)."';");
}else{
unset($this->events[$event][$id]);
$this->query("DELETE FROM events WHERE ID = ".$id.";");
if(isset($this->events[$event]) and count($this->events[$event]) === 0){
unset($this->events[$event]);
$this->query("DELETE FROM events WHERE eventName = '".str_replace("'", "\\'", $event)."';");
}
}
}

View File

@ -28,13 +28,15 @@ the Free Software Foundation, either version 3 of the License, or
class Session{
protected $server, $serverID, $timeout, $connected, $evid;
var $clientID, $ip, $port, $counter, $username, $EID;
function __construct($server, $clientID, $EID, $ip, $port){
var $clientID, $ip, $port, $counter, $username, $eid, $data;
function __construct($server, $clientID, $eid, $ip, $port){
$this->server = $server;
$this->clientID = $clientID;
$this->CID = $this->server->clientID($ip, $port);
$this->EID = $EID;
$this->eid = $eid;
$this->data = array();
$this->ip = $ip;
$this->entity = false;
$this->port = $port;
$this->serverID =& $this->server->serverID;
$this->timeout = microtime(true) + 25;
@ -52,6 +54,21 @@ class Session{
}
}
function __destruct(){
//$this->close("destruct");
}
public function save(){
if(is_object($this->entity)){
$this->data["spawn"] = array(
"x" => $this->entity->position["x"],
"y" => $this->entity->position["y"],
"z" => $this->entity->position["z"],
);
}
file_put_contents(FILE_PATH."data/players/".str_replace("/", "", $this->username).".dat", serialize($this->data));
}
public function close($reason = "server stop", $msg = true){
foreach($this->evid as $ev){
$this->server->deleteEvent($ev[0], $ev[1]);
@ -60,12 +77,69 @@ class Session{
if($msg === true){
$this->server->trigger("onChat", $this->username." left the game");
}
$this->save();
if(is_object($this->entity)){
$this->entity->__destruct();
}
console("[INFO] Session with ".$this->ip.":".$this->port." closed due to ".$reason);
unset($this->server->entities[$this->eid]);
unset($this->server->clients[$this->CID]);
}
public function eventHandler($data, $event){
switch($event){
case "onHealthChange":
if($data["eid"] === $this->eid){
$this->send(0x84, array(
$this->counter[0],
0x00,
array(
"id" => MC_SET_HEALTH,
"health" => $data["health"],
),
));
$this->data["health"] = $data["health"];
if(is_object($this->entity)){
$this->entity->setHealth($data["health"]);
}
}
break;
case "onPlayerAdd":
if($data["eid"] === $this->eid){
break;
}
$this->send(0x84, array(
$this->counter[0],
0x00,
array(
"id" => MC_ADD_PLAYER,
"clientID" => $data["clientID"],
"username" => $data["username"],
"eid" => $data["eid"],
"x" => $data["x"],
"y" => $data["y"],
"z" => $data["z"],
"yaw" => $data["yaw"],
"pitch" => $data["pitch"],
"block" => $data["block"],
"meta" => $data["meta"],
),
));
break;
case "onEntityRemove":
if($data === $this->eid){
$this->close("despawn");
}else{
$this->send(0x84, array(
$this->counter[0],
0x00,
array(
"id" => MC_ENTITY_REMOVE,
"eid" => $data,
),
));
}
break;
case "onTimeChange":
$this->send(0x84, array(
$this->counter[0],
@ -133,14 +207,39 @@ class Session{
break;
case MC_LOGIN:
$this->username = $data["username"];
$this->username = str_replace("/", "", $data["username"]);
foreach($this->server->clients as $c){
if($c->eid !== $this->eid and $c->username === $this->username){
$c->close("logged in from another location");
}
}
if($this->server->whitelist !== false and !in_array($this->username, $this->server->whitelist)){
$this->close("\"".$this->username."\" not being on white-list", false);
break;
}
console("[INFO] Player \"".$this->username."\" connected from ".$this->ip.":".$this->port);
if(!file_exists(FILE_PATH."data/players/".$this->username.".dat")){
console("[NOTICE] Player data not found for \"".$this->username."\", creating new");
$this->data = array(
"spawn" => array(
"x" => $this->server->spawn["x"],
"y" => $this->server->spawn["y"],
"z" => $this->server->spawn["z"],
),
"health" => 20,
"lastIP" => $this->ip,
"lastID" => $this->clientID,
);
}else{
$this->data = unserialize(file_get_contents(FILE_PATH."data/players/".str_replace("/", "", $this->username).".dat"));
$this->data["lastIP"] = $this->ip;
$this->data["lastID"] = $this->clientID;
}
$this->evid[] = array("onTimeChange", $this->server->event("onTimeChange", array($this, "eventHandler")));
$this->evid[] = array("onChat", $this->server->event("onChat", array($this, "eventHandler")));
$this->evid[] = array("onPlayerAdd", $this->server->event("onPlayerAdd", array($this, "eventHandler")));
$this->evid[] = array("onEntityDespawn", $this->server->event("onEntityDespawn", array($this, "eventHandler")));
$this->evid[] = array("onHealthChange", $this->server->event("onHealthChange", array($this, "eventHandler")));
$this->send(0x84, array(
$this->counter[0],
0x00,
@ -156,44 +255,47 @@ class Session{
array(
"id" => MC_START_GAME,
"seed" => $this->server->seed,
"x" => 128.5,
"y" => 100,
"z" => 128.5,
"x" => $this->data["spawn"]["x"],
"y" => $this->data["spawn"]["y"],
"z" => $this->data["spawn"]["z"],
"unknown1" => 0,
"gamemode" => $this->server->gamemode,
"eid" => $this->EID,
"eid" => $this->eid,
),
));
++$this->counter[0];
break;
case MC_READY:
$this->send(0x84, array(
$this->counter[0],
0x00,
array(
"id" => MC_SET_TIME,
"time" => $this->server->time,
),
));
console("[DEBUG] Player with EID ".$this->EID." \"".$this->username."\" spawned!", true, true, 2);
$this->server->trigger("onChat", $this->username." joined the game");
$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);
$this->entity->setName($this->username);
$this->server->entities[$this->eid] = &$this->entity;
/*$this->server->trigger("onPlayerAdd", array(
"clientID" => $this->clientID,
"username" => $this->username,
"eid" => $this->eid,
"x" => $this->data["spawn"]["x"],
"y" => $this->data["spawn"]["y"],
"z" => $this->data["spawn"]["z"],
"yaw" => $this->data["spawn"]["yaw"],
"pitch" => $this->data["spawn"]["pitch"],
"block" => 0,
"meta" => 0,
));*/
$this->eventHandler($this->server->motd, "onChat");
$this->server->trigger("onChat", $this->username." joined the game");
break;
case MC_MOVE_PLAYER:
console("[DEBUG] EID ".$this->EID." moved: X ".$data["x"].", Y ".$data["y"].", Z ".$data["z"].", Pitch ".$data["pitch"].", Yaw ".$data["yaw"], true, true, 2);
$this->entity->setPosition($data["x"], $data["y"], $data["z"], $data["x"], $data["yaw"], $data["pitch"]);
$this->server->trigger("onPlayerMove", $this->eid);
break;
case MC_PLAYER_EQUIPMENT:
$this->send(0x84, array(
$this->counter[0],
0x00,
array(
"id" => MC_PLAYER_EQUIPMENT,
"eid" => 0,
"block" => 323,
"meta" => 0,
),
));
console("[DEBUG] EID ".$this->EID." has now ".$data["block"]." with metadata ".$data["meta"]." in their hands!", true, true, 2);
console("[DEBUG] EID ".$this->eid." has now ".$data["block"]." with metadata ".$data["meta"]." in their hands!", true, true, 2);
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);
break;
}

View File

@ -38,6 +38,15 @@ console("[DEBUG] Endianness: ".(ENDIANNESS === LITTLE_ENDIAN ? "Little Endian":"
class Utils{
/*public static function hashCode($str){
$h = 0;
$len = strlen($str);
for($i = 0; $i < $len; ++$i) {
$h = 31 * $h + $str[$i];
}
return $h;
}*/
public static function getOS(){
$uname = strtoupper(php_uname("s"));
if(strpos($uname, "WIN") !== false){

View File

@ -31,7 +31,7 @@ ini_set("display_errors", 1);
ini_set('default_charset', 'utf-8');
define("FILE_PATH", dirname(__FILE__)."/../");
set_include_path(get_include_path() . PATH_SEPARATOR . FILE_PATH . PATH_SEPARATOR . FILE_PATH . "/classes/");
ini_set("memory_limit", "512M");
ini_set("memory_limit", "1024M");
define("CURRENT_PROTOCOL", 5);
define("CURRENT_VERSION", 1);
define("LOG", true);

View File

@ -9,6 +9,7 @@ seed=false
server-id=false
server-type=normal
max-players=20
time-per-second=10
white-list=false
debug=1
spawn=128.5;100;128.5

View File

@ -70,6 +70,7 @@ if($errors > 0){
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/SerializedPacketHandler.class.php");
require_once("classes/CustomPacketHandler.class.php");
require_once("classes/MinecraftInterface.class.php");

View File

@ -44,6 +44,8 @@ define("MC_CHAT", 0x85);
define("MC_SET_TIME", 0x86);
define("MC_START_GAME", 0x87);
define("MC_ADD_PLAYER", 0x89);
define("MC_REMOVE_ENTITY", 0x8d);
define("MC_MOVE_ENTITY_POSROT", 0x93);

View File

@ -44,6 +44,8 @@ $dataName = array(
MC_SET_TIME => "SetTime",
MC_START_GAME => "StartGame",
MC_ADD_PLAYER => "AddPlayer",
MC_REMOVE_ENTITY => "RemoveEntity",
MC_MOVE_ENTITY_POSROT => "MoveEntity_PosRot",

View File

@ -28,7 +28,6 @@ the Free Software Foundation, either version 3 of the License, or
require_once("common/dependencies.php");
require_once("classes/PocketMinecraftServer.class.php");
file_put_contents("packets.log", "");
file_put_contents("console.log", "");
if(!file_exists(FILE_PATH."white-list.txt")){
console("[WARNING] No white-list.txt found, creating blank file");
@ -43,8 +42,11 @@ if(!file_exists(FILE_PATH."banned-ips.txt")){
if(!file_exists(FILE_PATH."server.properties")){
console("[WARNING] No server.properties found, using default settings");
copy(FILE_PATH."common/default.properties", FILE_PATH."server.properties");
}
@mkdir(FILE_PATH."data/entities/", 0777, true);
@mkdir(FILE_PATH."data/players/", 0777);
$prop = file_get_contents(FILE_PATH."server.properties");
$prop = explode("\n", str_replace("\r", "", $prop));
$config = array();
@ -65,11 +67,13 @@ foreach($prop as $line){
case "max-players":
case "port":
case "debug":
case "time-per-second":
$v = (int) $v;
break;
case "seed":
case "server-id":
$v = trim($v) == "false" ? false:preg_replace("/^[0-9\-]/", "", $v);
$v = trim($v);
$v = $v == "false" ? false:(preg_match("/[^0-9\-]/", $v) > 0 ? Utils::readInt(substr(md5($v, true), 0, 4)):$v);
break;
case "spawn":
$v = explode(";", $v);
@ -86,9 +90,11 @@ define("DEBUG", $config["debug"]);
$server = new PocketMinecraftServer($config["server-name"], $config["gamemode"], $config["seed"], $config["protocol"], $config["port"], $config["server-id"]);
$server->setType($config["type"]);
$server->timePerSecond = $config["time-per-second"];
$server->maxClients = $config["max-players"];
$server->description = $config["description"];
$server->motd = $config["motd"];
$server->spawn = $config["spawn"];
$server->whitelist = $config["white-list"];
$server->reloadConfig();