Fixed #24 event duplication

Found 2 PHP bugs with this Commit
This commit is contained in:
Shoghi Cervantes Pueyo 2013-01-12 14:22:57 +01:00
parent 02950474af
commit b74c089ce7
2 changed files with 49 additions and 44 deletions

View File

@ -27,7 +27,7 @@ the Free Software Foundation, either version 3 of the License, or
class Player{ class Player{
private $server, $timeout, $connected, $evid, $queue, $buffer; private $server, $timeout, $connected, $queue, $buffer;
var $clientID, $ip, $port, $counter, $username, $eid, $data, $entity, $auth, $CID, $MTU, $spawned, $equipment; var $clientID, $ip, $port, $counter, $username, $eid, $data, $entity, $auth, $CID, $MTU, $spawned, $equipment;
function __construct($server, $clientID, $ip, $port, $MTU){ function __construct($server, $clientID, $ip, $port, $MTU){
$this->queue = array(); $this->queue = array();
@ -42,11 +42,10 @@ class Player{
$this->entity = false; $this->entity = false;
$this->port = $port; $this->port = $port;
$this->timeout = microtime(true) + 25; $this->timeout = microtime(true) + 25;
$this->evid = array();
$this->equipment = array(1, 0); $this->equipment = array(1, 0);
$this->spawned = false; $this->spawned = false;
$this->evid[] = $this->server->event("server.tick", array($this, "onTick")); $this->server->event("server.tick", array($this, "onTick"));
$this->evid[] = $this->server->event("server.close", array($this, "close")); $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); console("[DEBUG] New Session started with ".$ip.":".$port.". MTU ".$this->MTU.", Client ID ".$this->clientID, true, true, 2);
$this->connected = true; $this->connected = true;
$this->auth = false; $this->auth = false;
@ -95,9 +94,6 @@ class Player{
if($this->connected === true){ if($this->connected === true){
$reason = $reason == "" ? "server stop":$reason; $reason = $reason == "" ? "server stop":$reason;
$this->save(); $this->save();
foreach($this->evid as $ev){
$this->server->deleteEvent($ev);
}
$this->eventHandler(new Container("You have been kicked. Reason: ".$reason), "server.chat"); $this->eventHandler(new Container("You have been kicked. Reason: ".$reason), "server.chat");
$this->dataPacket(MC_LOGIN_STATUS, array( $this->dataPacket(MC_LOGIN_STATUS, array(
"status" => 1, "status" => 1,
@ -326,17 +322,17 @@ class Player{
$this->entity->data["clientID"] = $this->clientID; $this->entity->data["clientID"] = $this->clientID;
$this->server->api->entity->spawnAll($this); $this->server->api->entity->spawnAll($this);
$this->server->api->entity->spawnToAll($this->eid); $this->server->api->entity->spawnToAll($this->eid);
$this->evid[] = $this->server->event("server.time.change", array($this, "eventHandler")); $this->server->event("server.time.change", array($this, "eventHandler"));
$this->evid[] = $this->server->event("server.chat", array($this, "eventHandler")); $this->server->event("server.chat", array($this, "eventHandler"));
$this->evid[] = $this->server->event("entity.remove", array($this, "eventHandler")); $this->server->event("entity.remove", array($this, "eventHandler"));
$this->evid[] = $this->server->event("entity.move", array($this, "eventHandler")); $this->server->event("entity.move", array($this, "eventHandler"));
$this->evid[] = $this->server->event("entity.animate", array($this, "eventHandler")); $this->server->event("entity.animate", array($this, "eventHandler"));
$this->evid[] = $this->server->event("player.equipment.change", array($this, "eventHandler")); $this->server->event("player.equipment.change", array($this, "eventHandler"));
$this->evid[] = $this->server->event("player.item.pick", array($this, "eventHandler")); $this->server->event("player.item.pick", array($this, "eventHandler"));
$this->evid[] = $this->server->event("world.block.change", array($this, "eventHandler")); $this->server->event("world.block.change", array($this, "eventHandler"));
console("[DEBUG] Player with EID ".$this->eid." \"".$this->username."\" spawned!", true, true, 2); console("[DEBUG] Player with EID ".$this->eid." \"".$this->username."\" spawned!", true, true, 2);
$this->eventHandler($this->server->motd, "server.chat"); $this->eventHandler(new Container($this->server->motd), "server.chat");
if($this->MTU <= 548){ if($this->MTU <= 548){
$this->eventHandler("Your connection is bad, you may experience lag and slow map loading.", "server.chat"); $this->eventHandler("Your connection is bad, you may experience lag and slow map loading.", "server.chat");
} }

View File

@ -26,7 +26,7 @@ the Free Software Foundation, either version 3 of the License, or
*/ */
class PocketMinecraftServer{ class PocketMinecraftServer{
var $version, $invisible, $api, $tickMeasure, $preparedSQL, $seed, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $timePerSecond, $responses, $spawn, $entities, $mapDir, $mapName, $map, $levelData, $tileEntities; var $version, $invisible, $api, $tickMeasure, $preparedSQL, $seed, $gamemode, $name, $maxClients, $clients, $eidCnt, $custom, $description, $motd, $timePerSecond, $spawn, $entities, $mapDir, $mapName, $map, $levelData, $tileEntities;
private $database, $interface, $evCnt, $handCnt, $events, $handlers, $serverType, $lastTick, $ticker; private $database, $interface, $evCnt, $handCnt, $events, $handlers, $serverType, $lastTick, $ticker;
private function load(){ private function load(){
@ -118,8 +118,8 @@ class PocketMinecraftServer{
$this->query("CREATE TABLE events (ID INTEGER PRIMARY KEY, name TEXT);"); $this->query("CREATE TABLE events (ID INTEGER PRIMARY KEY, name TEXT);");
$this->query("CREATE TABLE handlers (ID INTEGER PRIMARY KEY, name TEXT, priority NUMERIC);"); $this->query("CREATE TABLE handlers (ID INTEGER PRIMARY KEY, name TEXT, priority NUMERIC);");
//$this->query("PRAGMA synchronous = OFF;"); //$this->query("PRAGMA synchronous = OFF;");
$this->preparedSQL->selectHandlers = $this->database->prepare("SELECT ID FROM handlers WHERE name = :name ORDER BY priority DESC;"); $this->preparedSQL->selectHandlers = $this->database->prepare("SELECT DISTINCT ID FROM handlers WHERE name = :name ORDER BY priority DESC;");
$this->preparedSQL->selectEvents = $this->database->prepare("SELECT ID FROM events WHERE name = :name;"); $this->preparedSQL->selectEvents = $this->database->prepare("SELECT DISTINCT ID FROM events WHERE name = :name;");
$this->preparedSQL->selectActions = $this->database->prepare("SELECT ID,code,repeat FROM actions WHERE last <= (:time - interval);"); $this->preparedSQL->selectActions = $this->database->prepare("SELECT ID,code,repeat FROM actions WHERE last <= (:time - interval);");
$this->preparedSQL->updateActions = $this->database->prepare("UPDATE actions SET last = :time WHERE last <= (:time - interval);"); $this->preparedSQL->updateActions = $this->database->prepare("UPDATE actions SET last = :time WHERE last <= (:time - interval);");
} }
@ -203,19 +203,28 @@ class PocketMinecraftServer{
$this->preparedSQL->selectHandlers->bindValue(":name", $event, SQLITE3_TEXT); $this->preparedSQL->selectHandlers->bindValue(":name", $event, SQLITE3_TEXT);
$handlers = $this->preparedSQL->selectHandlers->execute(); $handlers = $this->preparedSQL->selectHandlers->execute();
$result = true; $result = true;
console("[INTERNAL] Handling ".$event, true, true, 3);
if($handlers !== false and $handlers !== true){ if($handlers !== false and $handlers !== true){
while(false !== ($hn = $handlers->fetchArray(SQLITE3_ASSOC)) and $result !== false){ console("[INTERNAL] Handling ".$event, true, true, 3);
$handler = $this->handlers[(int) $hn["ID"]]; $call = array();
while(($hn = $handlers->fetchArray(SQLITE3_ASSOC)) !== false){
$call[(int) $hn["ID"]] = true;
}
$handlers->finalize();
foreach($call as $hnid => $boolean){
if($result !== false){
$called[$hnid] = true;
$handler = $this->handlers[$hnid];
if(is_array($handler)){ if(is_array($handler)){
$method = $handler[1]; $method = $handler[1];
$result = $handler[0]->$method($data, $event); $result = $handler[0]->$method($data, $event);
}else{ }else{
$result = $handler($data, $event); $result = $handler($data, $event);
} }
}else{
break;
}
} }
} }
$handlers->finalize();
if($result !== false){ if($result !== false){
$this->trigger($event, $data); $this->trigger($event, $data);
} }
@ -502,26 +511,26 @@ class PocketMinecraftServer{
if($events === false or $events === true){ if($events === false or $events === true){
return; return;
} }
while(false !== ($evn = $events->fetchArray(SQLITE3_ASSOC))){ $call = array();
$ev = $this->events[(int) $evn["ID"]]; while(($evn = $events->fetchArray(SQLITE3_ASSOC)) !== false){
if(is_array($ev)){ $call[(int) $evn["ID"]] = true;
$method = $ev[1];
$this->responses[(int) $evn["ID"]] = $ev[0]->$method($data, $event);
}else{
$this->responses[(int) $evn["ID"]] = $ev($data, $event);
}
} }
$events->finalize(); $events->finalize();
return true; foreach($call as $evid => $boolean){
$ev = $this->events[$evid];
if(!is_callable($ev)){
$this->deleteEvent($evid);
continue;
}
if(is_array($ev)){
$method = $ev[1];
$ev[0]->$method($data, $event);
}else{
$ev($data, $event);
}
} }
public function response($eid){ return true;
if(isset($this->responses[$eid])){
$res = $this->responses[$eid];
unset($this->responses[$eid]);
return $res;
}
return false;
} }
public function schedule($ticks, $callback, $data = array(), $repeat = false, $eventName = "server.schedule"){ public function schedule($ticks, $callback, $data = array(), $repeat = false, $eventName = "server.schedule"){