diff --git a/composer.json b/composer.json index ad19b71aa..db0f8a791 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,7 @@ "pocketmine/classloader": "^0.2.0", "pocketmine/color": "^0.2.0", "pocketmine/errorhandler": "^0.6.0", - "pocketmine/locale-data": "~2.11.0", + "pocketmine/locale-data": "~2.15.0", "pocketmine/log": "^0.4.0", "pocketmine/log-pthreads": "^0.4.0", "pocketmine/math": "^0.4.0", diff --git a/composer.lock b/composer.lock index 75639aa99..b95eaa9a0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2d4da4bb4787764fbe706a04311c3cbf", + "content-hash": "d833363f328eda3b1e080c3c5a7c76a4", "packages": [ { "name": "adhocore/json-comment", @@ -591,16 +591,16 @@ }, { "name": "pocketmine/locale-data", - "version": "2.11.0", + "version": "2.15.0", "source": { "type": "git", "url": "https://github.com/pmmp/Language.git", - "reference": "4b33d8fa53eda53d9662a7478806ebae2e4a5c53" + "reference": "87feaefdd8364730a2350e58fa274b1b493a9d3f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pmmp/Language/zipball/4b33d8fa53eda53d9662a7478806ebae2e4a5c53", - "reference": "4b33d8fa53eda53d9662a7478806ebae2e4a5c53", + "url": "https://api.github.com/repos/pmmp/Language/zipball/87feaefdd8364730a2350e58fa274b1b493a9d3f", + "reference": "87feaefdd8364730a2350e58fa274b1b493a9d3f", "shasum": "" }, "type": "library", @@ -608,9 +608,9 @@ "description": "Language resources used by PocketMine-MP", "support": { "issues": "https://github.com/pmmp/Language/issues", - "source": "https://github.com/pmmp/Language/tree/2.11.0" + "source": "https://github.com/pmmp/Language/tree/2.15.0" }, - "time": "2022-11-25T14:24:34+00:00" + "time": "2022-12-27T19:59:39+00:00" }, { "name": "pocketmine/log", diff --git a/src/Server.php b/src/Server.php index c082f4a1d..8c1cc7122 100644 --- a/src/Server.php +++ b/src/Server.php @@ -567,7 +567,8 @@ class Server{ }, static function() use ($playerPromiseResolver, $session) : void{ if($session->isConnected()){ - $session->disconnect("Spawn terrain generation failed"); + $session->getLogger()->error("Spawn terrain generation failed"); + $session->disconnectWithError(KnownTranslationFactory::pocketmine_disconnect_error_internal()); } $playerPromiseResolver->reject(); } diff --git a/src/command/defaults/BanCommand.php b/src/command/defaults/BanCommand.php index fc3117ae1..7cc7a8148 100644 --- a/src/command/defaults/BanCommand.php +++ b/src/command/defaults/BanCommand.php @@ -55,7 +55,7 @@ class BanCommand extends VanillaCommand{ $sender->getServer()->getNameBans()->addBan($name, $reason, null, $sender->getName()); if(($player = $sender->getServer()->getPlayerExact($name)) instanceof Player){ - $player->kick($reason !== "" ? "Banned by admin. Reason: " . $reason : "Banned by admin."); + $player->kick($reason !== "" ? KnownTranslationFactory::pocketmine_disconnect_ban($reason) : KnownTranslationFactory::pocketmine_disconnect_ban_noReason()); } Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_ban_success($player !== null ? $player->getName() : $name)); diff --git a/src/command/defaults/BanIpCommand.php b/src/command/defaults/BanIpCommand.php index 2d8bc0632..3c8ceceaf 100644 --- a/src/command/defaults/BanIpCommand.php +++ b/src/command/defaults/BanIpCommand.php @@ -78,7 +78,7 @@ class BanIpCommand extends VanillaCommand{ foreach($sender->getServer()->getOnlinePlayers() as $player){ if($player->getNetworkSession()->getIp() === $ip){ - $player->kick("Banned by admin. Reason: " . ($reason !== "" ? $reason : "IP banned.")); + $player->kick(KnownTranslationFactory::pocketmine_disconnect_ban($reason !== "" ? $reason : KnownTranslationFactory::pocketmine_disconnect_ban_ip())); } } diff --git a/src/command/defaults/KickCommand.php b/src/command/defaults/KickCommand.php index 78767b9da..1bb38d1b2 100644 --- a/src/command/defaults/KickCommand.php +++ b/src/command/defaults/KickCommand.php @@ -55,7 +55,7 @@ class KickCommand extends VanillaCommand{ $reason = trim(implode(" ", $args)); if(($player = $sender->getServer()->getPlayerByPrefix($name)) instanceof Player){ - $player->kick("Kicked by admin." . ($reason !== "" ? " Reason: " . $reason : "")); + $player->kick($reason !== "" ? KnownTranslationFactory::pocketmine_disconnect_kick($reason) : KnownTranslationFactory::pocketmine_disconnect_kick_noReason()); if($reason !== ""){ Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_kick_success_reason($player->getName(), $reason)); }else{ diff --git a/src/command/defaults/WhitelistCommand.php b/src/command/defaults/WhitelistCommand.php index 2b1a90c53..a69334c4a 100644 --- a/src/command/defaults/WhitelistCommand.php +++ b/src/command/defaults/WhitelistCommand.php @@ -122,7 +122,7 @@ class WhitelistCommand extends VanillaCommand{ $server = $sender->getServer(); $server->removeWhitelist($args[1]); if(!$server->isWhitelisted($args[1])){ - $server->getPlayerExact($args[1])?->kick("Server whitelisted."); + $server->getPlayerExact($args[1])?->kick(KnownTranslationFactory::pocketmine_disconnect_kick(KnownTranslationFactory::pocketmine_disconnect_whitelisted())); } Command::broadcastCommandMessage($sender, KnownTranslationFactory::commands_whitelist_remove_success($args[1])); } @@ -135,9 +135,10 @@ class WhitelistCommand extends VanillaCommand{ } private function kickNonWhitelistedPlayers(Server $server) : void{ + $message = KnownTranslationFactory::pocketmine_disconnect_kick(KnownTranslationFactory::pocketmine_disconnect_whitelisted()); foreach($server->getOnlinePlayers() as $player){ if(!$server->isWhitelisted($player->getName())){ - $player->kick("Server whitelisted."); + $player->kick($message); } } } diff --git a/src/event/player/PlayerDuplicateLoginEvent.php b/src/event/player/PlayerDuplicateLoginEvent.php index c7c1ece68..53d68bcd0 100644 --- a/src/event/player/PlayerDuplicateLoginEvent.php +++ b/src/event/player/PlayerDuplicateLoginEvent.php @@ -26,6 +26,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; use pocketmine\event\Event; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\lang\Translatable; use pocketmine\network\mcpe\NetworkSession; @@ -36,12 +37,14 @@ use pocketmine\network\mcpe\NetworkSession; class PlayerDuplicateLoginEvent extends Event implements Cancellable{ use CancellableTrait; - private Translatable|string $disconnectMessage = "Logged in from another location"; + private Translatable|string $disconnectMessage; public function __construct( private NetworkSession $connectingSession, private NetworkSession $existingSession - ){} + ){ + $this->disconnectMessage = KnownTranslationFactory::disconnectionScreen_loggedinOtherLocation(); + } public function getConnectingSession() : NetworkSession{ return $this->connectingSession; diff --git a/src/event/player/PlayerTransferEvent.php b/src/event/player/PlayerTransferEvent.php index 1e08ec5d7..5d8c0bb7e 100644 --- a/src/event/player/PlayerTransferEvent.php +++ b/src/event/player/PlayerTransferEvent.php @@ -25,6 +25,7 @@ namespace pocketmine\event\player; use pocketmine\event\Cancellable; use pocketmine\event\CancellableTrait; +use pocketmine\lang\Translatable; use pocketmine\player\Player; /** @@ -37,7 +38,7 @@ class PlayerTransferEvent extends PlayerEvent implements Cancellable{ Player $player, protected string $address, protected int $port, - protected string $message + protected Translatable|string $message ){ $this->player = $player; } @@ -73,14 +74,14 @@ class PlayerTransferEvent extends PlayerEvent implements Cancellable{ /** * Returns the disconnect reason shown in the server log and on the console. */ - public function getMessage() : string{ + public function getMessage() : Translatable|string{ return $this->message; } /** * Sets the disconnect reason shown in the server log and on the console. */ - public function setMessage(string $message) : void{ + public function setMessage(Translatable|string $message) : void{ $this->message = $message; } } diff --git a/src/lang/KnownTranslationFactory.php b/src/lang/KnownTranslationFactory.php index f1db1c6d1..584fb342d 100644 --- a/src/lang/KnownTranslationFactory.php +++ b/src/lang/KnownTranslationFactory.php @@ -661,6 +661,12 @@ final class KnownTranslationFactory{ ]); } + public static function death_attack_fireworks(Translatable|string $param0) : Translatable{ + return new Translatable(KnownTranslationKeys::DEATH_ATTACK_FIREWORKS, [ + 0 => $param0, + ]); + } + public static function death_attack_generic(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::DEATH_ATTACK_GENERIC, [ 0 => $param0, @@ -760,6 +766,10 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::DISCONNECTIONSCREEN_INVALIDSKIN, []); } + public static function disconnectionScreen_loggedinOtherLocation() : Translatable{ + return new Translatable(KnownTranslationKeys::DISCONNECTIONSCREEN_LOGGEDINOTHERLOCATION, []); + } + public static function disconnectionScreen_noReason() : Translatable{ return new Translatable(KnownTranslationKeys::DISCONNECTIONSCREEN_NOREASON, []); } @@ -1574,6 +1584,47 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::POCKETMINE_DEBUG_ENABLE, []); } + public static function pocketmine_disconnect_ban(Translatable|string $reason) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_BAN, [ + "reason" => $reason, + ]); + } + + public static function pocketmine_disconnect_ban_hardcore() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_BAN_HARDCORE, []); + } + + public static function pocketmine_disconnect_ban_ip() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_BAN_IP, []); + } + + public static function pocketmine_disconnect_ban_noReason() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_BAN_NOREASON, []); + } + + public static function pocketmine_disconnect_error(Translatable|string $error, Translatable|string $errorId) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_ERROR, [ + "error" => $error, + "errorId" => $errorId, + ]); + } + + public static function pocketmine_disconnect_error_authentication() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_ERROR_AUTHENTICATION, []); + } + + public static function pocketmine_disconnect_error_badPacket() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_ERROR_BADPACKET, []); + } + + public static function pocketmine_disconnect_error_internal() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_ERROR_INTERNAL, []); + } + + public static function pocketmine_disconnect_error_loginTimeout() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_ERROR_LOGINTIMEOUT, []); + } + public static function pocketmine_disconnect_incompatibleProtocol(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_INCOMPATIBLEPROTOCOL, [ 0 => $param0, @@ -1602,6 +1653,28 @@ final class KnownTranslationFactory{ return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_INVALIDSESSION_TOOLATE, []); } + public static function pocketmine_disconnect_kick(Translatable|string $reason) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_KICK, [ + "reason" => $reason, + ]); + } + + public static function pocketmine_disconnect_kick_noReason() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_KICK_NOREASON, []); + } + + public static function pocketmine_disconnect_transfer() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_TRANSFER, []); + } + + public static function pocketmine_disconnect_whitelisted() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_WHITELISTED, []); + } + + public static function pocketmine_disconnect_xblImpersonation() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_DISCONNECT_XBLIMPERSONATION, []); + } + public static function pocketmine_level_ambiguousFormat(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_LEVEL_AMBIGUOUSFORMAT, [ 0 => $param0, @@ -1707,6 +1780,274 @@ final class KnownTranslationFactory{ ]); } + public static function pocketmine_network_session_close(Translatable|string $reason) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_NETWORK_SESSION_CLOSE, [ + "reason" => $reason, + ]); + } + + public static function pocketmine_network_session_open() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_NETWORK_SESSION_OPEN, []); + } + + public static function pocketmine_network_session_playerName(Translatable|string $playerName) : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_NETWORK_SESSION_PLAYERNAME, [ + "playerName" => $playerName, + ]); + } + + public static function pocketmine_permission_broadcast_admin() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_BROADCAST_ADMIN, []); + } + + public static function pocketmine_permission_broadcast_user() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_BROADCAST_USER, []); + } + + public static function pocketmine_permission_command_ban_ip() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_BAN_IP, []); + } + + public static function pocketmine_permission_command_ban_list() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_BAN_LIST, []); + } + + public static function pocketmine_permission_command_ban_player() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_BAN_PLAYER, []); + } + + public static function pocketmine_permission_command_clear_other() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_CLEAR_OTHER, []); + } + + public static function pocketmine_permission_command_clear_self() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_CLEAR_SELF, []); + } + + public static function pocketmine_permission_command_defaultgamemode() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_DEFAULTGAMEMODE, []); + } + + public static function pocketmine_permission_command_difficulty() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_DIFFICULTY, []); + } + + public static function pocketmine_permission_command_dumpmemory() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_DUMPMEMORY, []); + } + + public static function pocketmine_permission_command_effect_other() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_EFFECT_OTHER, []); + } + + public static function pocketmine_permission_command_effect_self() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_EFFECT_SELF, []); + } + + public static function pocketmine_permission_command_enchant_other() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_ENCHANT_OTHER, []); + } + + public static function pocketmine_permission_command_enchant_self() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_ENCHANT_SELF, []); + } + + public static function pocketmine_permission_command_gamemode_other() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_GAMEMODE_OTHER, []); + } + + public static function pocketmine_permission_command_gamemode_self() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_GAMEMODE_SELF, []); + } + + public static function pocketmine_permission_command_gc() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_GC, []); + } + + public static function pocketmine_permission_command_give_other() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_GIVE_OTHER, []); + } + + public static function pocketmine_permission_command_give_self() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_GIVE_SELF, []); + } + + public static function pocketmine_permission_command_help() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_HELP, []); + } + + public static function pocketmine_permission_command_kick() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_KICK, []); + } + + public static function pocketmine_permission_command_kill_other() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_KILL_OTHER, []); + } + + public static function pocketmine_permission_command_kill_self() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_KILL_SELF, []); + } + + public static function pocketmine_permission_command_list() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_LIST, []); + } + + public static function pocketmine_permission_command_me() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_ME, []); + } + + public static function pocketmine_permission_command_op_give() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_OP_GIVE, []); + } + + public static function pocketmine_permission_command_op_take() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_OP_TAKE, []); + } + + public static function pocketmine_permission_command_particle() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_PARTICLE, []); + } + + public static function pocketmine_permission_command_plugins() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_PLUGINS, []); + } + + public static function pocketmine_permission_command_save_disable() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_SAVE_DISABLE, []); + } + + public static function pocketmine_permission_command_save_enable() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_SAVE_ENABLE, []); + } + + public static function pocketmine_permission_command_save_perform() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_SAVE_PERFORM, []); + } + + public static function pocketmine_permission_command_say() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_SAY, []); + } + + public static function pocketmine_permission_command_seed() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_SEED, []); + } + + public static function pocketmine_permission_command_setworldspawn() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_SETWORLDSPAWN, []); + } + + public static function pocketmine_permission_command_spawnpoint_other() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_SPAWNPOINT_OTHER, []); + } + + public static function pocketmine_permission_command_spawnpoint_self() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_SPAWNPOINT_SELF, []); + } + + public static function pocketmine_permission_command_status() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_STATUS, []); + } + + public static function pocketmine_permission_command_stop() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_STOP, []); + } + + public static function pocketmine_permission_command_teleport_other() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_TELEPORT_OTHER, []); + } + + public static function pocketmine_permission_command_teleport_self() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_TELEPORT_SELF, []); + } + + public static function pocketmine_permission_command_tell() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_TELL, []); + } + + public static function pocketmine_permission_command_time_add() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_TIME_ADD, []); + } + + public static function pocketmine_permission_command_time_query() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_TIME_QUERY, []); + } + + public static function pocketmine_permission_command_time_set() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_TIME_SET, []); + } + + public static function pocketmine_permission_command_time_start() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_TIME_START, []); + } + + public static function pocketmine_permission_command_time_stop() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_TIME_STOP, []); + } + + public static function pocketmine_permission_command_timings() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_TIMINGS, []); + } + + public static function pocketmine_permission_command_title_other() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_TITLE_OTHER, []); + } + + public static function pocketmine_permission_command_title_self() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_TITLE_SELF, []); + } + + public static function pocketmine_permission_command_transferserver() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_TRANSFERSERVER, []); + } + + public static function pocketmine_permission_command_unban_ip() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_UNBAN_IP, []); + } + + public static function pocketmine_permission_command_unban_player() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_UNBAN_PLAYER, []); + } + + public static function pocketmine_permission_command_version() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_VERSION, []); + } + + public static function pocketmine_permission_command_whitelist_add() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_WHITELIST_ADD, []); + } + + public static function pocketmine_permission_command_whitelist_disable() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_WHITELIST_DISABLE, []); + } + + public static function pocketmine_permission_command_whitelist_enable() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_WHITELIST_ENABLE, []); + } + + public static function pocketmine_permission_command_whitelist_list() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_WHITELIST_LIST, []); + } + + public static function pocketmine_permission_command_whitelist_reload() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_WHITELIST_RELOAD, []); + } + + public static function pocketmine_permission_command_whitelist_remove() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_COMMAND_WHITELIST_REMOVE, []); + } + + public static function pocketmine_permission_group_console() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_GROUP_CONSOLE, []); + } + + public static function pocketmine_permission_group_operator() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_GROUP_OPERATOR, []); + } + + public static function pocketmine_permission_group_user() : Translatable{ + return new Translatable(KnownTranslationKeys::POCKETMINE_PERMISSION_GROUP_USER, []); + } + public static function pocketmine_player_invalidEntity(Translatable|string $param0) : Translatable{ return new Translatable(KnownTranslationKeys::POCKETMINE_PLAYER_INVALIDENTITY, [ 0 => $param0, diff --git a/src/lang/KnownTranslationKeys.php b/src/lang/KnownTranslationKeys.php index bd98496cb..d69e1db94 100644 --- a/src/lang/KnownTranslationKeys.php +++ b/src/lang/KnownTranslationKeys.php @@ -146,6 +146,7 @@ final class KnownTranslationKeys{ public const DEATH_ATTACK_EXPLOSION_PLAYER = "death.attack.explosion.player"; public const DEATH_ATTACK_FALL = "death.attack.fall"; public const DEATH_ATTACK_FALLINGBLOCK = "death.attack.fallingBlock"; + public const DEATH_ATTACK_FIREWORKS = "death.attack.fireworks"; public const DEATH_ATTACK_GENERIC = "death.attack.generic"; public const DEATH_ATTACK_INFIRE = "death.attack.inFire"; public const DEATH_ATTACK_INWALL = "death.attack.inWall"; @@ -163,6 +164,7 @@ final class KnownTranslationKeys{ public const DEFAULT_VALUES_INFO = "default_values_info"; public const DISCONNECTIONSCREEN_INVALIDNAME = "disconnectionScreen.invalidName"; public const DISCONNECTIONSCREEN_INVALIDSKIN = "disconnectionScreen.invalidSkin"; + public const DISCONNECTIONSCREEN_LOGGEDINOTHERLOCATION = "disconnectionScreen.loggedinOtherLocation"; public const DISCONNECTIONSCREEN_NOREASON = "disconnectionScreen.noReason"; public const DISCONNECTIONSCREEN_NOTAUTHENTICATED = "disconnectionScreen.notAuthenticated"; public const DISCONNECTIONSCREEN_OUTDATEDCLIENT = "disconnectionScreen.outdatedClient"; @@ -342,12 +344,26 @@ final class KnownTranslationKeys{ public const POCKETMINE_DATA_PLAYEROLD = "pocketmine.data.playerOld"; public const POCKETMINE_DATA_SAVEERROR = "pocketmine.data.saveError"; public const POCKETMINE_DEBUG_ENABLE = "pocketmine.debug.enable"; + public const POCKETMINE_DISCONNECT_BAN = "pocketmine.disconnect.ban"; + public const POCKETMINE_DISCONNECT_BAN_HARDCORE = "pocketmine.disconnect.ban.hardcore"; + public const POCKETMINE_DISCONNECT_BAN_IP = "pocketmine.disconnect.ban.ip"; + public const POCKETMINE_DISCONNECT_BAN_NOREASON = "pocketmine.disconnect.ban.noReason"; + public const POCKETMINE_DISCONNECT_ERROR = "pocketmine.disconnect.error"; + public const POCKETMINE_DISCONNECT_ERROR_AUTHENTICATION = "pocketmine.disconnect.error.authentication"; + public const POCKETMINE_DISCONNECT_ERROR_BADPACKET = "pocketmine.disconnect.error.badPacket"; + public const POCKETMINE_DISCONNECT_ERROR_INTERNAL = "pocketmine.disconnect.error.internal"; + public const POCKETMINE_DISCONNECT_ERROR_LOGINTIMEOUT = "pocketmine.disconnect.error.loginTimeout"; public const POCKETMINE_DISCONNECT_INCOMPATIBLEPROTOCOL = "pocketmine.disconnect.incompatibleProtocol"; public const POCKETMINE_DISCONNECT_INVALIDSESSION = "pocketmine.disconnect.invalidSession"; public const POCKETMINE_DISCONNECT_INVALIDSESSION_BADSIGNATURE = "pocketmine.disconnect.invalidSession.badSignature"; public const POCKETMINE_DISCONNECT_INVALIDSESSION_MISSINGKEY = "pocketmine.disconnect.invalidSession.missingKey"; public const POCKETMINE_DISCONNECT_INVALIDSESSION_TOOEARLY = "pocketmine.disconnect.invalidSession.tooEarly"; public const POCKETMINE_DISCONNECT_INVALIDSESSION_TOOLATE = "pocketmine.disconnect.invalidSession.tooLate"; + public const POCKETMINE_DISCONNECT_KICK = "pocketmine.disconnect.kick"; + public const POCKETMINE_DISCONNECT_KICK_NOREASON = "pocketmine.disconnect.kick.noReason"; + public const POCKETMINE_DISCONNECT_TRANSFER = "pocketmine.disconnect.transfer"; + public const POCKETMINE_DISCONNECT_WHITELISTED = "pocketmine.disconnect.whitelisted"; + public const POCKETMINE_DISCONNECT_XBLIMPERSONATION = "pocketmine.disconnect.xblImpersonation"; public const POCKETMINE_LEVEL_AMBIGUOUSFORMAT = "pocketmine.level.ambiguousFormat"; public const POCKETMINE_LEVEL_BACKGROUNDGENERATION = "pocketmine.level.backgroundGeneration"; public const POCKETMINE_LEVEL_BADDEFAULTFORMAT = "pocketmine.level.badDefaultFormat"; @@ -365,6 +381,72 @@ final class KnownTranslationKeys{ public const POCKETMINE_LEVEL_UNKNOWNGENERATOR = "pocketmine.level.unknownGenerator"; public const POCKETMINE_LEVEL_UNLOADING = "pocketmine.level.unloading"; public const POCKETMINE_LEVEL_UNSUPPORTEDFORMAT = "pocketmine.level.unsupportedFormat"; + public const POCKETMINE_NETWORK_SESSION_CLOSE = "pocketmine.network.session.close"; + public const POCKETMINE_NETWORK_SESSION_OPEN = "pocketmine.network.session.open"; + public const POCKETMINE_NETWORK_SESSION_PLAYERNAME = "pocketmine.network.session.playerName"; + public const POCKETMINE_PERMISSION_BROADCAST_ADMIN = "pocketmine.permission.broadcast.admin"; + public const POCKETMINE_PERMISSION_BROADCAST_USER = "pocketmine.permission.broadcast.user"; + public const POCKETMINE_PERMISSION_COMMAND_BAN_IP = "pocketmine.permission.command.ban.ip"; + public const POCKETMINE_PERMISSION_COMMAND_BAN_LIST = "pocketmine.permission.command.ban.list"; + public const POCKETMINE_PERMISSION_COMMAND_BAN_PLAYER = "pocketmine.permission.command.ban.player"; + public const POCKETMINE_PERMISSION_COMMAND_CLEAR_OTHER = "pocketmine.permission.command.clear.other"; + public const POCKETMINE_PERMISSION_COMMAND_CLEAR_SELF = "pocketmine.permission.command.clear.self"; + public const POCKETMINE_PERMISSION_COMMAND_DEFAULTGAMEMODE = "pocketmine.permission.command.defaultgamemode"; + public const POCKETMINE_PERMISSION_COMMAND_DIFFICULTY = "pocketmine.permission.command.difficulty"; + public const POCKETMINE_PERMISSION_COMMAND_DUMPMEMORY = "pocketmine.permission.command.dumpmemory"; + public const POCKETMINE_PERMISSION_COMMAND_EFFECT_OTHER = "pocketmine.permission.command.effect.other"; + public const POCKETMINE_PERMISSION_COMMAND_EFFECT_SELF = "pocketmine.permission.command.effect.self"; + public const POCKETMINE_PERMISSION_COMMAND_ENCHANT_OTHER = "pocketmine.permission.command.enchant.other"; + public const POCKETMINE_PERMISSION_COMMAND_ENCHANT_SELF = "pocketmine.permission.command.enchant.self"; + public const POCKETMINE_PERMISSION_COMMAND_GAMEMODE_OTHER = "pocketmine.permission.command.gamemode.other"; + public const POCKETMINE_PERMISSION_COMMAND_GAMEMODE_SELF = "pocketmine.permission.command.gamemode.self"; + public const POCKETMINE_PERMISSION_COMMAND_GC = "pocketmine.permission.command.gc"; + public const POCKETMINE_PERMISSION_COMMAND_GIVE_OTHER = "pocketmine.permission.command.give.other"; + public const POCKETMINE_PERMISSION_COMMAND_GIVE_SELF = "pocketmine.permission.command.give.self"; + public const POCKETMINE_PERMISSION_COMMAND_HELP = "pocketmine.permission.command.help"; + public const POCKETMINE_PERMISSION_COMMAND_KICK = "pocketmine.permission.command.kick"; + public const POCKETMINE_PERMISSION_COMMAND_KILL_OTHER = "pocketmine.permission.command.kill.other"; + public const POCKETMINE_PERMISSION_COMMAND_KILL_SELF = "pocketmine.permission.command.kill.self"; + public const POCKETMINE_PERMISSION_COMMAND_LIST = "pocketmine.permission.command.list"; + public const POCKETMINE_PERMISSION_COMMAND_ME = "pocketmine.permission.command.me"; + public const POCKETMINE_PERMISSION_COMMAND_OP_GIVE = "pocketmine.permission.command.op.give"; + public const POCKETMINE_PERMISSION_COMMAND_OP_TAKE = "pocketmine.permission.command.op.take"; + public const POCKETMINE_PERMISSION_COMMAND_PARTICLE = "pocketmine.permission.command.particle"; + public const POCKETMINE_PERMISSION_COMMAND_PLUGINS = "pocketmine.permission.command.plugins"; + public const POCKETMINE_PERMISSION_COMMAND_SAVE_DISABLE = "pocketmine.permission.command.save.disable"; + public const POCKETMINE_PERMISSION_COMMAND_SAVE_ENABLE = "pocketmine.permission.command.save.enable"; + public const POCKETMINE_PERMISSION_COMMAND_SAVE_PERFORM = "pocketmine.permission.command.save.perform"; + public const POCKETMINE_PERMISSION_COMMAND_SAY = "pocketmine.permission.command.say"; + public const POCKETMINE_PERMISSION_COMMAND_SEED = "pocketmine.permission.command.seed"; + public const POCKETMINE_PERMISSION_COMMAND_SETWORLDSPAWN = "pocketmine.permission.command.setworldspawn"; + public const POCKETMINE_PERMISSION_COMMAND_SPAWNPOINT_OTHER = "pocketmine.permission.command.spawnpoint.other"; + public const POCKETMINE_PERMISSION_COMMAND_SPAWNPOINT_SELF = "pocketmine.permission.command.spawnpoint.self"; + public const POCKETMINE_PERMISSION_COMMAND_STATUS = "pocketmine.permission.command.status"; + public const POCKETMINE_PERMISSION_COMMAND_STOP = "pocketmine.permission.command.stop"; + public const POCKETMINE_PERMISSION_COMMAND_TELEPORT_OTHER = "pocketmine.permission.command.teleport.other"; + public const POCKETMINE_PERMISSION_COMMAND_TELEPORT_SELF = "pocketmine.permission.command.teleport.self"; + public const POCKETMINE_PERMISSION_COMMAND_TELL = "pocketmine.permission.command.tell"; + public const POCKETMINE_PERMISSION_COMMAND_TIME_ADD = "pocketmine.permission.command.time.add"; + public const POCKETMINE_PERMISSION_COMMAND_TIME_QUERY = "pocketmine.permission.command.time.query"; + public const POCKETMINE_PERMISSION_COMMAND_TIME_SET = "pocketmine.permission.command.time.set"; + public const POCKETMINE_PERMISSION_COMMAND_TIME_START = "pocketmine.permission.command.time.start"; + public const POCKETMINE_PERMISSION_COMMAND_TIME_STOP = "pocketmine.permission.command.time.stop"; + public const POCKETMINE_PERMISSION_COMMAND_TIMINGS = "pocketmine.permission.command.timings"; + public const POCKETMINE_PERMISSION_COMMAND_TITLE_OTHER = "pocketmine.permission.command.title.other"; + public const POCKETMINE_PERMISSION_COMMAND_TITLE_SELF = "pocketmine.permission.command.title.self"; + public const POCKETMINE_PERMISSION_COMMAND_TRANSFERSERVER = "pocketmine.permission.command.transferserver"; + public const POCKETMINE_PERMISSION_COMMAND_UNBAN_IP = "pocketmine.permission.command.unban.ip"; + public const POCKETMINE_PERMISSION_COMMAND_UNBAN_PLAYER = "pocketmine.permission.command.unban.player"; + public const POCKETMINE_PERMISSION_COMMAND_VERSION = "pocketmine.permission.command.version"; + public const POCKETMINE_PERMISSION_COMMAND_WHITELIST_ADD = "pocketmine.permission.command.whitelist.add"; + public const POCKETMINE_PERMISSION_COMMAND_WHITELIST_DISABLE = "pocketmine.permission.command.whitelist.disable"; + public const POCKETMINE_PERMISSION_COMMAND_WHITELIST_ENABLE = "pocketmine.permission.command.whitelist.enable"; + public const POCKETMINE_PERMISSION_COMMAND_WHITELIST_LIST = "pocketmine.permission.command.whitelist.list"; + public const POCKETMINE_PERMISSION_COMMAND_WHITELIST_RELOAD = "pocketmine.permission.command.whitelist.reload"; + public const POCKETMINE_PERMISSION_COMMAND_WHITELIST_REMOVE = "pocketmine.permission.command.whitelist.remove"; + public const POCKETMINE_PERMISSION_GROUP_CONSOLE = "pocketmine.permission.group.console"; + public const POCKETMINE_PERMISSION_GROUP_OPERATOR = "pocketmine.permission.group.operator"; + public const POCKETMINE_PERMISSION_GROUP_USER = "pocketmine.permission.group.user"; public const POCKETMINE_PLAYER_INVALIDENTITY = "pocketmine.player.invalidEntity"; public const POCKETMINE_PLAYER_INVALIDMOVE = "pocketmine.player.invalidMove"; public const POCKETMINE_PLAYER_LOGIN = "pocketmine.player.logIn"; diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index 5b3d6bb3f..d04e61b6f 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -132,6 +132,7 @@ use function get_class; use function in_array; use function json_encode; use function ksort; +use function random_bytes; use function strcasecmp; use function strlen; use function strtolower; @@ -236,7 +237,11 @@ class NetworkSession{ protected function createPlayer() : void{ $this->server->createPlayer($this, $this->info, $this->authenticated, $this->cachedOfflinePlayerData)->onCompletion( \Closure::fromCallable([$this, 'onPlayerCreated']), - fn() => $this->disconnect("Player creation failed") //TODO: this should never actually occur... right? + function() : void{ + //TODO: this should never actually occur... right? + $this->logger->error("Failed to create player"); + $this->disconnectWithError(KnownTranslationFactory::pocketmine_disconnect_error_internal()); + } ); } @@ -594,6 +599,10 @@ class NetworkSession{ }, $reason); } + public function disconnectWithError(Translatable|string $reason) : void{ + $this->disconnect(KnownTranslationFactory::pocketmine_disconnect_error($reason, bin2hex(random_bytes(6)))); + } + public function disconnectIncompatibleProtocol(int $protocolVersion) : void{ $this->tryDisconnect( function() use ($protocolVersion) : void{ @@ -606,7 +615,8 @@ class NetworkSession{ /** * Instructs the remote client to connect to a different server. */ - public function transfer(string $ip, int $port, Translatable|string $reason = "transfer") : void{ + public function transfer(string $ip, int $port, Translatable|string|null $reason = null) : void{ + $reason ??= KnownTranslationFactory::pocketmine_disconnect_transfer(); $this->tryDisconnect(function() use ($ip, $port, $reason) : void{ $this->sendDataPacket(TransferPacket::create($ip, $port), true); if($this->player !== null){ @@ -649,7 +659,7 @@ class NetworkSession{ } if($error !== null){ - $this->disconnect(KnownTranslationFactory::pocketmine_disconnect_invalidSession($error)); + $this->disconnectWithError(KnownTranslationFactory::pocketmine_disconnect_invalidSession($error)); return; } @@ -1146,7 +1156,7 @@ class NetworkSession{ if($this->info === null){ if(time() >= $this->connectTime + 10){ - $this->disconnect("Login timeout"); + $this->disconnectWithError(KnownTranslationFactory::pocketmine_disconnect_error_loginTimeout()); } return; diff --git a/src/network/mcpe/handler/LoginPacketHandler.php b/src/network/mcpe/handler/LoginPacketHandler.php index 1c7e59b69..0919f85e3 100644 --- a/src/network/mcpe/handler/LoginPacketHandler.php +++ b/src/network/mcpe/handler/LoginPacketHandler.php @@ -71,7 +71,7 @@ class LoginPacketHandler extends PacketHandler{ $extraData = $this->fetchAuthData($packet->chainDataJwt); if(!Player::isValidUserName($extraData->displayName)){ - $this->session->disconnect(KnownTranslationFactory::disconnectionScreen_invalidName()); + $this->session->disconnectWithError(KnownTranslationFactory::disconnectionScreen_invalidName()); return true; } @@ -81,7 +81,7 @@ class LoginPacketHandler extends PacketHandler{ $skin = SkinAdapterSingleton::get()->fromSkinData(ClientDataToSkinDataHelper::fromClientData($clientData)); }catch(\InvalidArgumentException | InvalidSkinException $e){ $this->session->getLogger()->debug("Invalid skin: " . $e->getMessage()); - $this->session->disconnect(KnownTranslationFactory::disconnectionScreen_invalidSkin()); + $this->session->disconnectWithError(KnownTranslationFactory::disconnectionScreen_invalidSkin()); return true; } @@ -120,12 +120,19 @@ class LoginPacketHandler extends PacketHandler{ $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_FULL, KnownTranslationFactory::disconnectionScreen_serverFull()); } if(!$this->server->isWhitelisted($playerInfo->getUsername())){ - //TODO: l10n - $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_WHITELISTED, "Server is whitelisted"); + $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_SERVER_WHITELISTED, KnownTranslationFactory::pocketmine_disconnect_whitelisted()); } - if($this->server->getNameBans()->isBanned($playerInfo->getUsername()) || $this->server->getIPBans()->isBanned($this->session->getIp())){ - //TODO: l10n - $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_BANNED, "You are banned"); + + $banMessage = null; + if(($banEntry = $this->server->getNameBans()->getEntry($playerInfo->getUsername())) !== null){ + $banReason = $banEntry->getReason(); + $banMessage = $banReason === "" ? KnownTranslationFactory::pocketmine_disconnect_ban_noReason() : KnownTranslationFactory::pocketmine_disconnect_ban($banReason); + }elseif(($banEntry = $this->server->getIPBans()->getEntry($this->session->getIp())) !== null){ + $banReason = $banEntry->getReason(); + $banMessage = KnownTranslationFactory::pocketmine_disconnect_ban($banReason !== "" ? $banReason : KnownTranslationFactory::pocketmine_disconnect_ban_ip()); + } + if($banMessage !== null){ + $ev->setKickReason(PlayerPreLoginEvent::KICK_REASON_BANNED, $banMessage); } $ev->call(); diff --git a/src/network/mcpe/handler/ResourcePacksPacketHandler.php b/src/network/mcpe/handler/ResourcePacksPacketHandler.php index 0dfe15ef4..8e76c545d 100644 --- a/src/network/mcpe/handler/ResourcePacksPacketHandler.php +++ b/src/network/mcpe/handler/ResourcePacksPacketHandler.php @@ -86,7 +86,7 @@ class ResourcePacksPacketHandler extends PacketHandler{ private function disconnectWithError(string $error) : void{ $this->session->getLogger()->error("Error downloading resource packs: " . $error); - $this->session->disconnect(KnownTranslationFactory::disconnectionScreen_resourcePack()); + $this->session->disconnectWithError(KnownTranslationFactory::disconnectionScreen_resourcePack()); } public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool{ diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index bf1f75c26..c48cba81c 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\network\mcpe\raklib; +use pocketmine\lang\KnownTranslationFactory; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\compression\ZlibCompressor; use pocketmine\network\mcpe\convert\TypeConverter; @@ -46,10 +47,8 @@ use raklib\server\ServerEventListener; use raklib\utils\InternetAddress; use function addcslashes; use function base64_encode; -use function bin2hex; use function implode; use function mt_rand; -use function random_bytes; use function rtrim; use function substr; use const PHP_INT_MAX; @@ -182,14 +181,12 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ try{ $session->handleEncoded($buf); }catch(PacketHandlingException $e){ - $errorId = bin2hex(random_bytes(6)); - $logger = $session->getLogger(); - $logger->error("Bad packet (error ID $errorId): " . $e->getMessage()); + $logger->error("Bad packet: " . $e->getMessage()); //intentionally doesn't use logException, we don't want spammy packet error traces to appear in release mode $logger->debug(implode("\n", Utils::printableExceptionInfo($e))); - $session->disconnect("Packet processing error (Error ID: $errorId)"); + $session->disconnectWithError(KnownTranslationFactory::pocketmine_disconnect_error_badPacket()); $this->interface->blockAddress($address, 5); } } diff --git a/src/player/Player.php b/src/player/Player.php index 5819fa8cb..fa1ac0f48 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -2081,14 +2081,14 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ /** * Transfers a player to another server. * - * @param string $address The IP address or hostname of the destination server - * @param int $port The destination port, defaults to 19132 - * @param string $message Message to show in the console when closing the player + * @param string $address The IP address or hostname of the destination server + * @param int $port The destination port, defaults to 19132 + * @param Translatable|string|null $message Message to show in the console when closing the player, null will use the default message * * @return bool if transfer was successful. */ - public function transfer(string $address, int $port = 19132, string $message = "transfer") : bool{ - $ev = new PlayerTransferEvent($this, $address, $port, $message); + public function transfer(string $address, int $port = 19132, Translatable|string|null $message = null) : bool{ + $ev = new PlayerTransferEvent($this, $address, $port, $message ?? KnownTranslationFactory::pocketmine_disconnect_transfer()); $ev->call(); if(!$ev->isCancelled()){ $this->getNetworkSession()->transfer($ev->getAddress(), $ev->getPort(), $ev->getMessage()); @@ -2303,7 +2303,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ public function respawn() : void{ if($this->server->isHardcore()){ - if($this->kick("You have been banned because you died in hardcore mode")){ //this allows plugins to prevent the ban by cancelling PlayerKickEvent + if($this->kick(KnownTranslationFactory::pocketmine_disconnect_ban(KnownTranslationFactory::pocketmine_disconnect_ban_hardcore()))){ //this allows plugins to prevent the ban by cancelling PlayerKickEvent $this->server->getNameBans()->addBan($this->getName(), "Died in hardcore mode"); } return;