mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-19 04:05:31 +00:00
some improvements to the horrendous mess that is the handling of joining and quitting, fixed some crashes, probably caused some other crashes
I can't fix this completely because it's just too much of a fucking mess. NEED to separate network stuff from Player.
This commit is contained in:
parent
45e5b6b04c
commit
69ac80518c
@ -241,6 +241,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
public $playedBefore;
|
public $playedBefore;
|
||||||
public $spawned = false;
|
public $spawned = false;
|
||||||
public $loggedIn = false;
|
public $loggedIn = false;
|
||||||
|
public $joined = false;
|
||||||
public $gamemode;
|
public $gamemode;
|
||||||
public $lastBreak;
|
public $lastBreak;
|
||||||
|
|
||||||
@ -945,6 +946,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
$pk->z = $pos->z;
|
$pk->z = $pos->z;
|
||||||
$this->dataPacket($pk);
|
$this->dataPacket($pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->joined = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function orderChunks(){
|
protected function orderChunks(){
|
||||||
@ -1971,7 +1974,8 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{
|
public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{
|
||||||
switch($packet->status){
|
switch($packet->status){
|
||||||
case ResourcePackClientResponsePacket::STATUS_REFUSED:
|
case ResourcePackClientResponsePacket::STATUS_REFUSED:
|
||||||
$this->close("", "must accept resource packs to join", true);
|
//TODO: add lang strings for this
|
||||||
|
$this->close("", "You must accept resource packs to join this server.", true);
|
||||||
break;
|
break;
|
||||||
case ResourcePackClientResponsePacket::STATUS_SEND_PACKS:
|
case ResourcePackClientResponsePacket::STATUS_SEND_PACKS:
|
||||||
$manager = $this->server->getResourceManager();
|
$manager = $this->server->getResourceManager();
|
||||||
@ -3536,21 +3540,41 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
* @param bool $notify
|
* @param bool $notify
|
||||||
*/
|
*/
|
||||||
public final function close($message = "", $reason = "generic reason", $notify = true){
|
public final function close($message = "", $reason = "generic reason", $notify = true){
|
||||||
|
|
||||||
if($this->connected and !$this->closed){
|
if($this->connected and !$this->closed){
|
||||||
if($notify and strlen((string) $reason) > 0){
|
if($notify and strlen((string) $reason) > 0){
|
||||||
$pk = new DisconnectPacket;
|
$pk = new DisconnectPacket();
|
||||||
$pk->message = $reason;
|
$pk->message = $reason;
|
||||||
$this->directDataPacket($pk);
|
$this->directDataPacket($pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->connected = false;
|
$this->connected = false;
|
||||||
if(strlen($this->getName()) > 0){
|
|
||||||
$this->server->getPluginManager()->callEvent($ev = new PlayerQuitEvent($this, $message, true));
|
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
||||||
if($this->loggedIn === true and $ev->getAutoSave()){
|
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
|
||||||
|
|
||||||
|
if($this->joined){
|
||||||
|
//TODO: add events for player data saving
|
||||||
$this->save();
|
$this->save();
|
||||||
|
|
||||||
|
$this->server->getPluginManager()->callEvent($ev = new PlayerQuitEvent($this, $message));
|
||||||
|
if($ev->getQuitMessage() != ""){
|
||||||
|
$this->server->broadcastMessage($ev->getQuitMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$this->joined = false;
|
||||||
|
|
||||||
|
if($this->isValid()){
|
||||||
|
foreach($this->usedChunks as $index => $d){
|
||||||
|
Level::getXZ($index, $chunkX, $chunkZ);
|
||||||
|
$this->level->unregisterChunkLoader($this, $chunkX, $chunkZ);
|
||||||
|
foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){
|
||||||
|
$entity->despawnFrom($this);
|
||||||
|
}
|
||||||
|
unset($this->usedChunks[$index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->usedChunks = [];
|
||||||
|
$this->loadQueue = [];
|
||||||
|
|
||||||
foreach($this->server->getOnlinePlayers() as $player){
|
foreach($this->server->getOnlinePlayers() as $player){
|
||||||
if(!$player->canSee($this)){
|
if(!$player->canSee($this)){
|
||||||
@ -3562,47 +3586,27 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
foreach($this->windowIndex as $window){
|
foreach($this->windowIndex as $window){
|
||||||
$this->removeWindow($window);
|
$this->removeWindow($window);
|
||||||
}
|
}
|
||||||
|
$this->windows = null;
|
||||||
foreach($this->usedChunks as $index => $d){
|
$this->windowIndex = [];
|
||||||
Level::getXZ($index, $chunkX, $chunkZ);
|
|
||||||
$this->level->unregisterChunkLoader($this, $chunkX, $chunkZ);
|
|
||||||
foreach($this->level->getChunkEntities($chunkX, $chunkZ) as $entity){
|
|
||||||
$entity->despawnFrom($this, false);
|
|
||||||
}
|
|
||||||
unset($this->usedChunks[$index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
parent::close();
|
parent::close();
|
||||||
|
$this->spawned = false;
|
||||||
|
|
||||||
$this->interface->close($this, $notify ? $reason : "");
|
$this->interface->close($this, $notify ? $reason : "");
|
||||||
|
|
||||||
if($this->loggedIn){
|
if($this->loggedIn){
|
||||||
$this->server->removeOnlinePlayer($this);
|
$this->server->removeOnlinePlayer($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->loggedIn = false;
|
$this->loggedIn = false;
|
||||||
|
|
||||||
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
|
||||||
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
|
|
||||||
|
|
||||||
if(isset($ev) and $this->username != "" and $this->spawned !== false and $ev->getQuitMessage() != ""){
|
|
||||||
$this->server->broadcastMessage($ev->getQuitMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->spawned = false;
|
|
||||||
$this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logOut", [
|
$this->server->getLogger()->info($this->getServer()->getLanguage()->translateString("pocketmine.player.logOut", [
|
||||||
TextFormat::AQUA . $this->getName() . TextFormat::WHITE,
|
TextFormat::AQUA . $this->getName() . TextFormat::WHITE,
|
||||||
$this->ip,
|
$this->ip,
|
||||||
$this->port,
|
$this->port,
|
||||||
$this->getServer()->getLanguage()->translateString($reason)
|
$this->getServer()->getLanguage()->translateString($reason)
|
||||||
]));
|
]));
|
||||||
$this->windows = new \SplObjectStorage();
|
|
||||||
$this->windowIndex = [];
|
|
||||||
$this->usedChunks = [];
|
|
||||||
$this->loadQueue = [];
|
|
||||||
$this->hasSpawned = [];
|
|
||||||
$this->spawnPosition = null;
|
$this->spawnPosition = null;
|
||||||
}
|
|
||||||
|
|
||||||
if($this->perm !== null){
|
if($this->perm !== null){
|
||||||
$this->perm->clearPermissions();
|
$this->perm->clearPermissions();
|
||||||
@ -3614,10 +3618,9 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
$this->currentTransaction = null;
|
$this->currentTransaction = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->chunk = null;
|
|
||||||
|
|
||||||
$this->server->removePlayer($this);
|
$this->server->removePlayer($this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function __debugInfo(){
|
public function __debugInfo(){
|
||||||
return [];
|
return [];
|
||||||
@ -3634,7 +3637,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
}
|
}
|
||||||
|
|
||||||
parent::saveNBT();
|
parent::saveNBT();
|
||||||
if($this->level instanceof Level){
|
if($this->getLevel() instanceof Level){
|
||||||
$this->namedtag->Level = new StringTag("Level", $this->level->getFolderName());
|
$this->namedtag->Level = new StringTag("Level", $this->level->getFolderName());
|
||||||
if($this->hasValidSpawnPosition()){
|
if($this->hasValidSpawnPosition()){
|
||||||
$this->namedtag["SpawnLevel"] = $this->spawnPosition->getLevel()->getFolderName();
|
$this->namedtag["SpawnLevel"] = $this->spawnPosition->getLevel()->getFolderName();
|
||||||
@ -3642,6 +3645,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
$this->namedtag["SpawnY"] = (int) $this->spawnPosition->y;
|
$this->namedtag["SpawnY"] = (int) $this->spawnPosition->y;
|
||||||
$this->namedtag["SpawnZ"] = (int) $this->spawnPosition->z;
|
$this->namedtag["SpawnZ"] = (int) $this->spawnPosition->z;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach($this->achievements as $achievement => $status){
|
foreach($this->achievements as $achievement => $status){
|
||||||
$this->namedtag->Achievements[$achievement] = new ByteTag($achievement, $status === true ? 1 : 0);
|
$this->namedtag->Achievements[$achievement] = new ByteTag($achievement, $status === true ? 1 : 0);
|
||||||
@ -3654,7 +3658,6 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
|
|||||||
$this->server->saveOfflinePlayerData($this->username, $this->namedtag, $async);
|
$this->server->saveOfflinePlayerData($this->username, $this->namedtag, $async);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the username
|
* Gets the username
|
||||||
|
@ -1661,7 +1661,10 @@ abstract class Entity extends Location implements Metadatable{
|
|||||||
if(!$this->closed){
|
if(!$this->closed){
|
||||||
$this->server->getPluginManager()->callEvent(new EntityDespawnEvent($this));
|
$this->server->getPluginManager()->callEvent(new EntityDespawnEvent($this));
|
||||||
$this->closed = true;
|
$this->closed = true;
|
||||||
|
|
||||||
$this->despawnFromAll();
|
$this->despawnFromAll();
|
||||||
|
$this->hasSpawned = [];
|
||||||
|
|
||||||
if($this->chunk !== null){
|
if($this->chunk !== null){
|
||||||
$this->chunk->removeEntity($this);
|
$this->chunk->removeEntity($this);
|
||||||
$this->chunk = null;
|
$this->chunk = null;
|
||||||
|
@ -504,7 +504,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
|||||||
|
|
||||||
public function close(){
|
public function close(){
|
||||||
if(!$this->closed){
|
if(!$this->closed){
|
||||||
if(!($this instanceof Player) or $this->loggedIn){
|
if($this->inventory !== null){
|
||||||
foreach($this->inventory->getViewers() as $viewer){
|
foreach($this->inventory->getViewers() as $viewer){
|
||||||
$viewer->removeWindow($this->inventory);
|
$viewer->removeWindow($this->inventory);
|
||||||
}
|
}
|
||||||
|
@ -188,12 +188,13 @@ class PermissibleBase implements Permissible{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function clearPermissions(){
|
public function clearPermissions(){
|
||||||
|
$pluginManager = Server::getInstance()->getPluginManager();
|
||||||
foreach(array_keys($this->permissions) as $name){
|
foreach(array_keys($this->permissions) as $name){
|
||||||
Server::getInstance()->getPluginManager()->unsubscribeFromPermission($name, $this->parent !== null ? $this->parent : $this);
|
$pluginManager->unsubscribeFromPermission($name, $this->parent ?? $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::getInstance()->getPluginManager()->unsubscribeFromDefaultPerms(false, $this->parent !== null ? $this->parent : $this);
|
$pluginManager->unsubscribeFromDefaultPerms(false, $this->parent ?? $this);
|
||||||
Server::getInstance()->getPluginManager()->unsubscribeFromDefaultPerms(true, $this->parent !== null ? $this->parent : $this);
|
$pluginManager->unsubscribeFromDefaultPerms(true, $this->parent ?? $this);
|
||||||
|
|
||||||
$this->permissions = [];
|
$this->permissions = [];
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user