Merge branch 'minor-next' into major-next

This commit is contained in:
Dylan K. Taylor 2023-09-08 11:22:44 +01:00
commit a4f3476190
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
16 changed files with 132 additions and 216 deletions

View File

@ -391,7 +391,7 @@ class Server{
}
public function getGamemode() : GameMode{
return GameMode::fromString($this->configGroup->getConfigString(ServerProperties::GAME_MODE, GameMode::SURVIVAL()->name())) ?? GameMode::SURVIVAL();
return GameMode::fromString($this->configGroup->getConfigString(ServerProperties::GAME_MODE)) ?? GameMode::SURVIVAL;
}
public function getForceGamemode() : bool{
@ -818,7 +818,7 @@ class Server{
ServerProperties::ENABLE_IPV6 => true,
ServerProperties::WHITELIST => false,
ServerProperties::MAX_PLAYERS => self::DEFAULT_MAX_PLAYERS,
ServerProperties::GAME_MODE => GameMode::SURVIVAL()->name(),
ServerProperties::GAME_MODE => GameMode::SURVIVAL->name, //TODO: this probably shouldn't use the enum name directly
ServerProperties::FORCE_GAME_MODE => false,
ServerProperties::HARDCORE => false,
ServerProperties::PVP => true,
@ -1021,7 +1021,7 @@ class Server{
$this->forceShutdownExit();
return;
}
if(!$this->enablePlugins(PluginEnableOrder::STARTUP())){
if(!$this->enablePlugins(PluginEnableOrder::STARTUP)){
$this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_plugin_someEnableErrors()));
$this->forceShutdownExit();
return;
@ -1032,7 +1032,7 @@ class Server{
return;
}
if(!$this->enablePlugins(PluginEnableOrder::POSTWORLD())){
if(!$this->enablePlugins(PluginEnableOrder::POSTWORLD)){
$this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_plugin_someEnableErrors()));
$this->forceShutdownExit();
return;
@ -1387,14 +1387,14 @@ class Server{
public function enablePlugins(PluginEnableOrder $type) : bool{
$allSuccess = true;
foreach($this->pluginManager->getPlugins() as $plugin){
if(!$plugin->isEnabled() && $plugin->getDescription()->getOrder()->equals($type)){
if(!$plugin->isEnabled() && $plugin->getDescription()->getOrder() === $type){
if(!$this->pluginManager->enablePlugin($plugin)){
$allSuccess = false;
}
}
}
if($type->equals(PluginEnableOrder::POSTWORLD())){
if($type === PluginEnableOrder::POSTWORLD){
$this->commandMap->registerServerAliases();
}

View File

@ -50,7 +50,7 @@ class DragonEgg extends Transparent implements Fallable{
}
public function onAttack(Item $item, int $face, ?Player $player = null) : bool{
if($player !== null && !$player->getGamemode()->equals(GameMode::CREATIVE())){
if($player !== null && $player->getGamemode() !== GameMode::CREATIVE){
$this->teleport();
return true;
}

View File

@ -153,69 +153,23 @@ final class WoodLikeBlockIdHelper{
* @phpstan-return array{BID, BID, \Closure() : \pocketmine\item\Item}
*/
public static function getSignInfo(WoodType $treeType) : array{
switch($treeType){
case WoodType::OAK:
return [
new BID(Ids::OAK_SIGN, TileSign::class),
new BID(Ids::OAK_WALL_SIGN, TileSign::class),
fn() => VanillaItems::OAK_SIGN()
];
case WoodType::SPRUCE:
return [
new BID(Ids::SPRUCE_SIGN, TileSign::class),
new BID(Ids::SPRUCE_WALL_SIGN, TileSign::class),
fn() => VanillaItems::SPRUCE_SIGN()
];
case WoodType::BIRCH:
return [
new BID(Ids::BIRCH_SIGN, TileSign::class),
new BID(Ids::BIRCH_WALL_SIGN, TileSign::class),
fn() => VanillaItems::BIRCH_SIGN()
];
case WoodType::JUNGLE:
return [
new BID(Ids::JUNGLE_SIGN, TileSign::class),
new BID(Ids::JUNGLE_WALL_SIGN, TileSign::class),
fn() => VanillaItems::JUNGLE_SIGN()
];
case WoodType::ACACIA:
return [
new BID(Ids::ACACIA_SIGN, TileSign::class),
new BID(Ids::ACACIA_WALL_SIGN, TileSign::class),
fn() => VanillaItems::ACACIA_SIGN()
];
case WoodType::DARK_OAK:
return [
new BID(Ids::DARK_OAK_SIGN, TileSign::class),
new BID(Ids::DARK_OAK_WALL_SIGN, TileSign::class),
fn() => VanillaItems::DARK_OAK_SIGN()
];
case WoodType::MANGROVE:
return [
new BID(Ids::MANGROVE_SIGN, TileSign::class),
new BID(Ids::MANGROVE_WALL_SIGN, TileSign::class),
fn() => VanillaItems::MANGROVE_SIGN()
];
case WoodType::CRIMSON:
return [
new BID(Ids::CRIMSON_SIGN, TileSign::class),
new BID(Ids::CRIMSON_WALL_SIGN, TileSign::class),
fn() => VanillaItems::CRIMSON_SIGN()
];
case WoodType::WARPED:
return [
new BID(Ids::WARPED_SIGN, TileSign::class),
new BID(Ids::WARPED_WALL_SIGN, TileSign::class),
fn() => VanillaItems::WARPED_SIGN()
];
case WoodType::CHERRY:
return [
new BID(Ids::CHERRY_SIGN, TileSign::class),
new BID(Ids::CHERRY_WALL_SIGN, TileSign::class),
fn() => VanillaItems::CHERRY_SIGN()
];
}
throw new AssumptionFailedError("Switch should cover all wood types");
$make = fn(int $floorId, int $wallId, \Closure $getItem) => [
new BID($floorId, TileSign::class),
new BID($wallId, TileSign::class),
$getItem
];
return match($treeType){
WoodType::OAK => $make(Ids::OAK_SIGN, Ids::OAK_WALL_SIGN, fn() => VanillaItems::OAK_SIGN()),
WoodType::SPRUCE => $make(Ids::SPRUCE_SIGN, Ids::SPRUCE_WALL_SIGN, fn() => VanillaItems::SPRUCE_SIGN()),
WoodType::BIRCH => $make(Ids::BIRCH_SIGN, Ids::BIRCH_WALL_SIGN, fn() => VanillaItems::BIRCH_SIGN()),
WoodType::JUNGLE => $make(Ids::JUNGLE_SIGN, Ids::JUNGLE_WALL_SIGN, fn() => VanillaItems::JUNGLE_SIGN()),
WoodType::ACACIA => $make(Ids::ACACIA_SIGN, Ids::ACACIA_WALL_SIGN, fn() => VanillaItems::ACACIA_SIGN()),
WoodType::DARK_OAK => $make(Ids::DARK_OAK_SIGN, Ids::DARK_OAK_WALL_SIGN, fn() => VanillaItems::DARK_OAK_SIGN()),
WoodType::MANGROVE => $make(Ids::MANGROVE_SIGN, Ids::MANGROVE_WALL_SIGN, fn() => VanillaItems::MANGROVE_SIGN()),
WoodType::CRIMSON => $make(Ids::CRIMSON_SIGN, Ids::CRIMSON_WALL_SIGN, fn() => VanillaItems::CRIMSON_SIGN()),
WoodType::WARPED => $make(Ids::WARPED_SIGN, Ids::WARPED_WALL_SIGN, fn() => VanillaItems::WARPED_SIGN()),
WoodType::CHERRY => $make(Ids::CHERRY_SIGN, Ids::CHERRY_WALL_SIGN, fn() => VanillaItems::CHERRY_SIGN()),
};
}
public static function getTrapdoorIdentifier(WoodType $treeType) : BlockIdentifier{

View File

@ -53,7 +53,8 @@ class DefaultGamemodeCommand extends VanillaCommand{
return true;
}
$sender->getServer()->getConfigGroup()->setConfigString(ServerProperties::GAME_MODE, $gameMode->name());
//TODO: this probably shouldn't use the enum name directly
$sender->getServer()->getConfigGroup()->setConfigString(ServerProperties::GAME_MODE, $gameMode->name);
$sender->sendMessage(KnownTranslationFactory::commands_defaultgamemode_success($gameMode->getTranslatableName()));
return true;
}

View File

@ -61,13 +61,13 @@ class GamemodeCommand extends VanillaCommand{
return true;
}
if($target->getGamemode()->equals($gameMode)){
if($target->getGamemode() === $gameMode){
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_gamemode_failure($target->getName()));
return true;
}
$target->setGamemode($gameMode);
if(!$gameMode->equals($target->getGamemode())){
if($gameMode !== $target->getGamemode()){
$sender->sendMessage(KnownTranslationFactory::pocketmine_command_gamemode_failure($target->getName()));
}else{
if($target === $sender){

View File

@ -143,7 +143,7 @@ class CrashDump{
depends: $d->getDepend(),
softDepends: $d->getSoftDepend(),
main: $d->getMain(),
load: mb_strtoupper($d->getOrder()->name()),
load: mb_strtoupper($d->getOrder()->name),
website: $d->getWebsite()
);
}

View File

@ -26,6 +26,7 @@ namespace pocketmine\data\java;
use pocketmine\player\GameMode;
use pocketmine\utils\SingletonTrait;
use function array_key_exists;
use function spl_object_id;
final class GameModeIdMap{
use SingletonTrait;
@ -43,15 +44,15 @@ final class GameModeIdMap{
private array $enumToId = [];
public function __construct(){
$this->register(0, GameMode::SURVIVAL());
$this->register(1, GameMode::CREATIVE());
$this->register(2, GameMode::ADVENTURE());
$this->register(3, GameMode::SPECTATOR());
$this->register(0, GameMode::SURVIVAL);
$this->register(1, GameMode::CREATIVE);
$this->register(2, GameMode::ADVENTURE);
$this->register(3, GameMode::SPECTATOR);
}
private function register(int $id, GameMode $type) : void{
$this->idToEnum[$id] = $type;
$this->enumToId[$type->id()] = $id;
$this->enumToId[spl_object_id($type)] = $id;
}
public function fromId(int $id) : ?GameMode{
@ -59,9 +60,10 @@ final class GameModeIdMap{
}
public function toId(GameMode $type) : int{
if(!array_key_exists($type->id(), $this->enumToId)){
throw new \InvalidArgumentException("Game mode does not have a mapped ID"); //this should never happen
$k = spl_object_id($type);
if(!array_key_exists($k, $this->enumToId)){
throw new \InvalidArgumentException("Game mode $type->name does not have a mapped ID"); //this should never happen
}
return $this->enumToId[$type->id()];
return $this->enumToId[$k];
}
}

View File

@ -108,33 +108,23 @@ class TypeConverter{
* @internal
*/
public function coreGameModeToProtocol(GameMode $gamemode) : int{
switch($gamemode->id()){
case GameMode::SURVIVAL()->id():
return ProtocolGameMode::SURVIVAL;
case GameMode::CREATIVE()->id():
case GameMode::SPECTATOR()->id():
return ProtocolGameMode::CREATIVE;
case GameMode::ADVENTURE()->id():
return ProtocolGameMode::ADVENTURE;
default:
throw new AssumptionFailedError("Unknown game mode");
}
return match($gamemode){
GameMode::SURVIVAL => ProtocolGameMode::SURVIVAL,
//TODO: native spectator support
GameMode::CREATIVE, GameMode::SPECTATOR => ProtocolGameMode::CREATIVE,
GameMode::ADVENTURE => ProtocolGameMode::ADVENTURE,
};
}
public function protocolGameModeToCore(int $gameMode) : ?GameMode{
switch($gameMode){
case ProtocolGameMode::SURVIVAL:
return GameMode::SURVIVAL();
case ProtocolGameMode::CREATIVE:
return GameMode::CREATIVE();
case ProtocolGameMode::ADVENTURE:
return GameMode::ADVENTURE();
case ProtocolGameMode::CREATIVE_VIEWER:
case ProtocolGameMode::SURVIVAL_VIEWER:
return GameMode::SPECTATOR();
default:
return null;
}
return match($gameMode){
ProtocolGameMode::SURVIVAL => GameMode::SURVIVAL,
ProtocolGameMode::CREATIVE => GameMode::CREATIVE,
ProtocolGameMode::ADVENTURE => GameMode::ADVENTURE,
ProtocolGameMode::SURVIVAL_VIEWER, ProtocolGameMode::CREATIVE_VIEWER => GameMode::SPECTATOR,
//TODO: native spectator support
default => null,
};
}
public function coreRecipeIngredientToNet(?RecipeIngredient $ingredient) : ProtocolRecipeIngredient{

View File

@ -783,7 +783,7 @@ class InGamePacketHandler extends PacketHandler{
public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool{
$gameMode = $this->session->getTypeConverter()->protocolGameModeToCore($packet->gamemode);
if($gameMode === null || !$gameMode->equals($this->player->getGamemode())){
if($gameMode !== $this->player->getGamemode()){
//Set this back to default. TODO: handle this properly
$this->session->syncGameMode($this->player->getGamemode(), true);
}

View File

@ -271,8 +271,8 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{
$this->rakServerId,
$this->server->getName(),
match($this->server->getGamemode()){
GameMode::SURVIVAL() => "Survival",
GameMode::ADVENTURE() => "Adventure",
GameMode::SURVIVAL => "Survival",
GameMode::ADVENTURE => "Adventure",
default => "Creative"
}
]) . ";"

View File

@ -71,7 +71,7 @@ final class QueryInfo{
$this->plugins = $server->getPluginManager()->getPlugins();
$this->players = array_map(fn(Player $p) => $p->getName(), $server->getOnlinePlayers());
$this->gametype = ($server->getGamemode()->equals(GameMode::SURVIVAL()) || $server->getGamemode()->equals(GameMode::ADVENTURE())) ? "SMP" : "CMP";
$this->gametype = ($server->getGamemode() === GameMode::SURVIVAL || $server->getGamemode() === GameMode::ADVENTURE) ? "SMP" : "CMP";
$this->version = $server->getVersion();
$this->server_engine = $server->getName() . " " . $server->getPocketMineVersion();
$world = $server->getWorldManager()->getDefaultWorld();

View File

@ -25,73 +25,65 @@ namespace pocketmine\player;
use pocketmine\lang\KnownTranslationFactory;
use pocketmine\lang\Translatable;
use pocketmine\utils\EnumTrait;
use function mb_strtolower;
use function spl_object_id;
/**
* This doc-block is generated automatically, do not modify it manually.
* This must be regenerated whenever registry members are added, removed or changed.
* @see build/generate-registry-annotations.php
* @generate-registry-docblock
*
* @method static GameMode ADVENTURE()
* @method static GameMode CREATIVE()
* @method static GameMode SPECTATOR()
* @method static GameMode SURVIVAL()
* @phpstan-type TMetadata array{0: string, 1: Translatable, 2: list<string>}
*/
final class GameMode{
use EnumTrait {
__construct as Enum___construct;
register as Enum_register;
}
/** @var self[] */
protected static array $aliasMap = [];
protected static function setup() : void{
self::registerAll(
new self("survival", "Survival", KnownTranslationFactory::gameMode_survival(), ["survival", "s", "0"]),
new self("creative", "Creative", KnownTranslationFactory::gameMode_creative(), ["creative", "c", "1"]),
new self("adventure", "Adventure", KnownTranslationFactory::gameMode_adventure(), ["adventure", "a", "2"]),
new self("spectator", "Spectator", KnownTranslationFactory::gameMode_spectator(), ["spectator", "v", "view", "3"])
);
}
protected static function register(self $member) : void{
self::Enum_register($member);
foreach($member->getAliases() as $alias){
self::$aliasMap[mb_strtolower($alias)] = $member;
}
}
enum GameMode{
case SURVIVAL;
case CREATIVE;
case ADVENTURE;
case SPECTATOR;
public static function fromString(string $str) : ?self{
self::checkInit();
return self::$aliasMap[mb_strtolower($str)] ?? null;
/**
* @var self[]|null $aliasMap
* @phpstan-var array<string, self>|null $aliasMap
*/
static $aliasMap = null;
if($aliasMap === null){
$aliasMap = [];
foreach(self::cases() as $case){
foreach($case->getAliases() as $alias){
$aliasMap[$alias] = $case;
}
}
}
return $aliasMap[mb_strtolower($str)] ?? null;
}
/**
* @param string[] $aliases
* @phpstan-return TMetadata
*/
private function __construct(
string $enumName,
private string $englishName,
private Translatable $translatableName,
private array $aliases = []
){
$this->Enum___construct($enumName);
private function getMetadata() : array{
/** @phpstan-var array<int, TMetadata> $cache */
static $cache = [];
return $cache[spl_object_id($this)] ??= match($this){
self::SURVIVAL => ["Survival", KnownTranslationFactory::gameMode_survival(), ["survival", "s", "0"]],
self::CREATIVE => ["Creative", KnownTranslationFactory::gameMode_creative(), ["creative", "c", "1"]],
self::ADVENTURE => ["Adventure", KnownTranslationFactory::gameMode_adventure(), ["adventure", "a", "2"]],
self::SPECTATOR => ["Spectator", KnownTranslationFactory::gameMode_spectator(), ["spectator", "v", "view", "3"]]
};
}
public function getEnglishName() : string{
return $this->englishName;
return $this->getMetadata()[0];
}
public function getTranslatableName() : Translatable{ return $this->translatableName; }
public function getTranslatableName() : Translatable{
return $this->getMetadata()[1];
}
/**
* @return string[]
*/
public function getAliases() : array{
return $this->aliases;
return $this->getMetadata()[2];
}
//TODO: ability sets per gamemode

View File

@ -372,7 +372,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
$this->lastPlayed = $nbt->getLong(self::TAG_LAST_PLAYED, $now);
if(!$this->server->getForceGamemode() && ($gameModeTag = $nbt->getTag(self::TAG_GAME_MODE)) instanceof IntTag){
$this->internalSetGameMode(GameModeIdMap::getInstance()->fromId($gameModeTag->getValue()) ?? GameMode::SURVIVAL()); //TODO: bad hack here to avoid crashes on corrupted data
$this->internalSetGameMode(GameModeIdMap::getInstance()->fromId($gameModeTag->getValue()) ?? GameMode::SURVIVAL); //TODO: bad hack here to avoid crashes on corrupted data
}else{
$this->internalSetGameMode($this->server->getGamemode());
}
@ -1113,7 +1113,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
protected function internalSetGameMode(GameMode $gameMode) : void{
$this->gamemode = $gameMode;
$this->allowFlight = $this->gamemode->equals(GameMode::CREATIVE());
$this->allowFlight = $this->gamemode === GameMode::CREATIVE;
$this->hungerManager->setEnabled($this->isSurvival());
if($this->isSpectator()){
@ -1139,7 +1139,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
* Sets the provided gamemode.
*/
public function setGamemode(GameMode $gm) : bool{
if($this->gamemode->equals($gm)){
if($this->gamemode === $gm){
return false;
}
@ -1168,7 +1168,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
* @param bool $literal whether a literal check should be performed
*/
public function isSurvival(bool $literal = false) : bool{
return $this->gamemode->equals(GameMode::SURVIVAL()) || (!$literal && $this->gamemode->equals(GameMode::ADVENTURE()));
return $this->gamemode === GameMode::SURVIVAL || (!$literal && $this->gamemode === GameMode::ADVENTURE);
}
/**
@ -1178,7 +1178,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
* @param bool $literal whether a literal check should be performed
*/
public function isCreative(bool $literal = false) : bool{
return $this->gamemode->equals(GameMode::CREATIVE()) || (!$literal && $this->gamemode->equals(GameMode::SPECTATOR()));
return $this->gamemode === GameMode::CREATIVE || (!$literal && $this->gamemode === GameMode::SPECTATOR);
}
/**
@ -1188,18 +1188,18 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{
* @param bool $literal whether a literal check should be performed
*/
public function isAdventure(bool $literal = false) : bool{
return $this->gamemode->equals(GameMode::ADVENTURE()) || (!$literal && $this->gamemode->equals(GameMode::SPECTATOR()));
return $this->gamemode === GameMode::ADVENTURE || (!$literal && $this->gamemode === GameMode::SPECTATOR);
}
public function isSpectator() : bool{
return $this->gamemode->equals(GameMode::SPECTATOR());
return $this->gamemode === GameMode::SPECTATOR;
}
/**
* TODO: make this a dynamic ability instead of being hardcoded
*/
public function hasFiniteResources() : bool{
return !$this->gamemode->equals(GameMode::CREATIVE());
return $this->gamemode !== GameMode::CREATIVE;
}
public function getDrops() : array{

View File

@ -203,7 +203,7 @@ class PluginDescription{
}
$this->order = $order;
}else{
$this->order = PluginEnableOrder::POSTWORLD();
$this->order = PluginEnableOrder::POSTWORLD;
}
$this->authors = [];

View File

@ -23,63 +23,38 @@ declare(strict_types=1);
namespace pocketmine\plugin;
use pocketmine\utils\EnumTrait;
use function mb_strtolower;
/**
* This doc-block is generated automatically, do not modify it manually.
* This must be regenerated whenever registry members are added, removed or changed.
* @see build/generate-registry-annotations.php
* @generate-registry-docblock
*
* @method static PluginEnableOrder POSTWORLD()
* @method static PluginEnableOrder STARTUP()
*/
final class PluginEnableOrder{
use EnumTrait {
__construct as Enum___construct;
register as Enum_register;
}
protected static function setup() : void{
self::registerAll(
new self("startup", ["startup"]),
new self("postworld", ["postworld"])
);
}
/**
* @var self[]
* @phpstan-var array<string, self>
*/
private static array $aliasMap = [];
protected static function register(self $member) : void{
self::Enum_register($member);
foreach($member->getAliases() as $alias){
self::$aliasMap[mb_strtolower($alias)] = $member;
}
}
enum PluginEnableOrder{
case STARTUP;
case POSTWORLD;
public static function fromString(string $name) : ?self{
self::checkInit();
return self::$aliasMap[mb_strtolower($name)] ?? null;
}
/**
* @var self[]|null $aliasMap
* @phpstan-var array<string, self>|null $aliasMap
*/
static $aliasMap = null;
/**
* @param string[] $aliases
* @phpstan-param list<string> $aliases
*/
private function __construct(
string $enumName,
private array $aliases
){
$this->Enum___construct($enumName);
if($aliasMap === null){
$aliasMap = [];
foreach(self::cases() as $case){
foreach($case->getAliases() as $alias){
$aliasMap[$alias] = $case;
}
}
}
return $aliasMap[mb_strtolower($name)] ?? null;
}
/**
* @return string[]
* @phpstan-return list<string>
*/
public function getAliases() : array{ return $this->aliases; }
public function getAliases() : array{
return match($this){
self::STARTUP => ["startup"],
self::POSTWORLD => ["postworld"]
};
}
}

View File

@ -165,9 +165,11 @@ LICENSE;
$this->message($this->lang->translate(KnownTranslationFactory::gamemode_info()));
do{
$gamemode = GameModeIdMap::getInstance()->fromId((int) $this->getInput($this->lang->translate(KnownTranslationFactory::default_gamemode()), (string) GameModeIdMap::getInstance()->toId(GameMode::SURVIVAL())));
//TODO: drop the usage of internal Mojang IDs for this - we really just need a set of options to choose from
$gamemode = GameModeIdMap::getInstance()->fromId((int) $this->getInput($this->lang->translate(KnownTranslationFactory::default_gamemode()), (string) GameModeIdMap::getInstance()->toId(GameMode::SURVIVAL)));
}while($gamemode === null);
$config->set("gamemode", $gamemode->name());
//TODO: this probably shouldn't use the enum name directly
$config->set("gamemode", $gamemode->name);
$config->set("max-players", (int) $this->getInput($this->lang->translate(KnownTranslationFactory::max_players()), (string) self::DEFAULT_PLAYERS));