mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-19 15:35:52 +00:00
1.20.60 support
This commit is contained in:
parent
5709d727a2
commit
6492e7f4a2
@ -33,10 +33,10 @@
|
||||
"composer-runtime-api": "^2.0",
|
||||
"adhocore/json-comment": "~1.2.0",
|
||||
"pocketmine/netresearch-jsonmapper": "~v4.2.1000",
|
||||
"pocketmine/bedrock-block-upgrade-schema": "~3.4.0+bedrock-1.20.50",
|
||||
"pocketmine/bedrock-data": "~2.7.0+bedrock-1.20.50",
|
||||
"pocketmine/bedrock-item-upgrade-schema": "~1.6.0+bedrock-1.20.50",
|
||||
"pocketmine/bedrock-protocol": "~26.0.0+bedrock-1.20.50",
|
||||
"pocketmine/bedrock-block-upgrade-schema": "~3.5.0+bedrock-1.20.60",
|
||||
"pocketmine/bedrock-data": "~2.8.0+bedrock-1.20.60",
|
||||
"pocketmine/bedrock-item-upgrade-schema": "~1.7.0+bedrock-1.20.60",
|
||||
"pocketmine/bedrock-protocol": "~27.0.0+bedrock-1.20.60",
|
||||
"pocketmine/binaryutils": "^0.2.1",
|
||||
"pocketmine/callback-validator": "^1.0.2",
|
||||
"pocketmine/color": "^0.3.0",
|
||||
|
50
composer.lock
generated
50
composer.lock
generated
@ -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": "fecd5b7c364cb3a0f3a832004f594101",
|
||||
"content-hash": "d923f5fd75f0d33eb5198268a74a58b4",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -122,16 +122,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-block-upgrade-schema",
|
||||
"version": "3.4.0",
|
||||
"version": "3.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockBlockUpgradeSchema.git",
|
||||
"reference": "9872eb37f15080b19c2b7861085e549c48dda92d"
|
||||
"reference": "1ed4ba738333c4b4afe4fef8e9326a45c89f12e3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/9872eb37f15080b19c2b7861085e549c48dda92d",
|
||||
"reference": "9872eb37f15080b19c2b7861085e549c48dda92d",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/1ed4ba738333c4b4afe4fef8e9326a45c89f12e3",
|
||||
"reference": "1ed4ba738333c4b4afe4fef8e9326a45c89f12e3",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -142,22 +142,22 @@
|
||||
"description": "Schemas describing how to upgrade saved block data in older Minecraft: Bedrock Edition world saves",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/BedrockBlockUpgradeSchema/issues",
|
||||
"source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/3.4.0"
|
||||
"source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/3.5.0"
|
||||
},
|
||||
"time": "2023-11-08T15:22:06+00:00"
|
||||
"time": "2024-02-07T11:46:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-data",
|
||||
"version": "2.7.0+bedrock-1.20.50",
|
||||
"version": "2.8.0+bedrock-1.20.60",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockData.git",
|
||||
"reference": "36f975dfca7520b7d36b0b39429f274464c9bc13"
|
||||
"reference": "d8ea0355b7c835564af9fe6e273e650ac62c84a2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/36f975dfca7520b7d36b0b39429f274464c9bc13",
|
||||
"reference": "36f975dfca7520b7d36b0b39429f274464c9bc13",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/d8ea0355b7c835564af9fe6e273e650ac62c84a2",
|
||||
"reference": "d8ea0355b7c835564af9fe6e273e650ac62c84a2",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -168,22 +168,22 @@
|
||||
"description": "Blobs of data generated from Minecraft: Bedrock Edition, used by PocketMine-MP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/BedrockData/issues",
|
||||
"source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.20.50"
|
||||
"source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.20.60"
|
||||
},
|
||||
"time": "2023-12-06T13:59:08+00:00"
|
||||
"time": "2024-02-07T11:23:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-item-upgrade-schema",
|
||||
"version": "1.6.0",
|
||||
"version": "1.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockItemUpgradeSchema.git",
|
||||
"reference": "d374e5fd8302977675dcd2a42733abd3ee476ca1"
|
||||
"reference": "69772dd58e2b2c7b7513fa2bcdc46e782228641c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/d374e5fd8302977675dcd2a42733abd3ee476ca1",
|
||||
"reference": "d374e5fd8302977675dcd2a42733abd3ee476ca1",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/69772dd58e2b2c7b7513fa2bcdc46e782228641c",
|
||||
"reference": "69772dd58e2b2c7b7513fa2bcdc46e782228641c",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -194,22 +194,22 @@
|
||||
"description": "JSON schemas for upgrading items found in older Minecraft: Bedrock world saves",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/BedrockItemUpgradeSchema/issues",
|
||||
"source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.6.0"
|
||||
"source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.7.0"
|
||||
},
|
||||
"time": "2023-11-08T18:12:14+00:00"
|
||||
"time": "2024-02-07T11:58:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-protocol",
|
||||
"version": "26.0.0+bedrock-1.20.50",
|
||||
"version": "27.0.1+bedrock-1.20.60",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockProtocol.git",
|
||||
"reference": "f278a0b6d4fa1e2e0408a125f323a3118b1968df"
|
||||
"reference": "0cebb55f6e904f722b14d420f6b2c84c7fa69f10"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/f278a0b6d4fa1e2e0408a125f323a3118b1968df",
|
||||
"reference": "f278a0b6d4fa1e2e0408a125f323a3118b1968df",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/0cebb55f6e904f722b14d420f6b2c84c7fa69f10",
|
||||
"reference": "0cebb55f6e904f722b14d420f6b2c84c7fa69f10",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -241,9 +241,9 @@
|
||||
"description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/BedrockProtocol/issues",
|
||||
"source": "https://github.com/pmmp/BedrockProtocol/tree/26.0.0+bedrock-1.20.50"
|
||||
"source": "https://github.com/pmmp/BedrockProtocol/tree/27.0.1+bedrock-1.20.60"
|
||||
},
|
||||
"time": "2023-12-06T14:08:37+00:00"
|
||||
"time": "2024-02-07T11:53:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/binaryutils",
|
||||
|
@ -60,6 +60,7 @@ use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\network\mcpe\PacketBroadcaster;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext;
|
||||
use pocketmine\network\mcpe\protocol\types\CompressionAlgorithm;
|
||||
use pocketmine\network\mcpe\raklib\RakLibInterface;
|
||||
use pocketmine\network\mcpe\StandardEntityEventBroadcaster;
|
||||
use pocketmine\network\mcpe\StandardPacketBroadcaster;
|
||||
@ -125,6 +126,7 @@ use Symfony\Component\Filesystem\Path;
|
||||
use function array_fill;
|
||||
use function array_sum;
|
||||
use function base64_encode;
|
||||
use function chr;
|
||||
use function cli_set_process_title;
|
||||
use function copy;
|
||||
use function count;
|
||||
@ -1373,19 +1375,26 @@ class Server{
|
||||
try{
|
||||
$timings->startTiming();
|
||||
|
||||
if($sync === null){
|
||||
$threshold = $compressor->getCompressionThreshold();
|
||||
$sync = !$this->networkCompressionAsync || $threshold === null || strlen($buffer) < $threshold;
|
||||
$threshold = $compressor->getCompressionThreshold();
|
||||
if($threshold === null || strlen($buffer) < $compressor->getCompressionThreshold()){
|
||||
$compressionType = CompressionAlgorithm::NONE;
|
||||
$compressed = $buffer;
|
||||
|
||||
}else{
|
||||
$sync ??= !$this->networkCompressionAsync;
|
||||
|
||||
if(!$sync && strlen($buffer) >= $this->networkCompressionAsyncThreshold){
|
||||
$promise = new CompressBatchPromise();
|
||||
$task = new CompressBatchTask($buffer, $promise, $compressor);
|
||||
$this->asyncPool->submitTask($task);
|
||||
return $promise;
|
||||
}
|
||||
|
||||
$compressionType = $compressor->getNetworkId();
|
||||
$compressed = $compressor->compress($buffer);
|
||||
}
|
||||
|
||||
if(!$sync && strlen($buffer) >= $this->networkCompressionAsyncThreshold){
|
||||
$promise = new CompressBatchPromise();
|
||||
$task = new CompressBatchTask($buffer, $promise, $compressor);
|
||||
$this->asyncPool->submitTask($task);
|
||||
return $promise;
|
||||
}
|
||||
|
||||
return $compressor->compress($buffer);
|
||||
return chr($compressionType) . $compressed;
|
||||
}finally{
|
||||
$timings->stopTiming();
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ final class BlockStateData{
|
||||
public const CURRENT_VERSION =
|
||||
(1 << 24) | //major
|
||||
(20 << 16) | //minor
|
||||
(50 << 8) | //patch
|
||||
(60 << 8) | //patch
|
||||
(1); //revision
|
||||
|
||||
public const TAG_NAME = "name";
|
||||
|
@ -56,7 +56,6 @@ final class BlockStateNames{
|
||||
public const CHEMISTRY_TABLE_TYPE = "chemistry_table_type";
|
||||
public const CHISEL_TYPE = "chisel_type";
|
||||
public const CLUSTER_COUNT = "cluster_count";
|
||||
public const COLOR = "color";
|
||||
public const COLOR_BIT = "color_bit";
|
||||
public const COMPOSTER_FILL_LEVEL = "composter_fill_level";
|
||||
public const CONDITIONAL_BIT = "conditional_bit";
|
||||
@ -145,6 +144,7 @@ final class BlockStateNames{
|
||||
public const TALL_GRASS_TYPE = "tall_grass_type";
|
||||
public const TOGGLE_BIT = "toggle_bit";
|
||||
public const TORCH_FACING_DIRECTION = "torch_facing_direction";
|
||||
public const TRIAL_SPAWNER_STATE = "trial_spawner_state";
|
||||
public const TRIGGERED_BIT = "triggered_bit";
|
||||
public const TURTLE_EGG_COUNT = "turtle_egg_count";
|
||||
public const TWISTING_VINES_AGE = "twisting_vines_age";
|
||||
|
@ -62,23 +62,6 @@ final class BlockStateStringValues{
|
||||
public const CHISEL_TYPE_LINES = "lines";
|
||||
public const CHISEL_TYPE_SMOOTH = "smooth";
|
||||
|
||||
public const COLOR_BLACK = "black";
|
||||
public const COLOR_BLUE = "blue";
|
||||
public const COLOR_BROWN = "brown";
|
||||
public const COLOR_CYAN = "cyan";
|
||||
public const COLOR_GRAY = "gray";
|
||||
public const COLOR_GREEN = "green";
|
||||
public const COLOR_LIGHT_BLUE = "light_blue";
|
||||
public const COLOR_LIME = "lime";
|
||||
public const COLOR_MAGENTA = "magenta";
|
||||
public const COLOR_ORANGE = "orange";
|
||||
public const COLOR_PINK = "pink";
|
||||
public const COLOR_PURPLE = "purple";
|
||||
public const COLOR_RED = "red";
|
||||
public const COLOR_SILVER = "silver";
|
||||
public const COLOR_WHITE = "white";
|
||||
public const COLOR_YELLOW = "yellow";
|
||||
|
||||
public const CORAL_COLOR_BLUE = "blue";
|
||||
public const CORAL_COLOR_PINK = "pink";
|
||||
public const CORAL_COLOR_PURPLE = "purple";
|
||||
|
@ -517,10 +517,40 @@ final class BlockTypeNames{
|
||||
public const GREEN_WOOL = "minecraft:green_wool";
|
||||
public const GRINDSTONE = "minecraft:grindstone";
|
||||
public const HANGING_ROOTS = "minecraft:hanging_roots";
|
||||
public const HARD_BLACK_STAINED_GLASS = "minecraft:hard_black_stained_glass";
|
||||
public const HARD_BLACK_STAINED_GLASS_PANE = "minecraft:hard_black_stained_glass_pane";
|
||||
public const HARD_BLUE_STAINED_GLASS = "minecraft:hard_blue_stained_glass";
|
||||
public const HARD_BLUE_STAINED_GLASS_PANE = "minecraft:hard_blue_stained_glass_pane";
|
||||
public const HARD_BROWN_STAINED_GLASS = "minecraft:hard_brown_stained_glass";
|
||||
public const HARD_BROWN_STAINED_GLASS_PANE = "minecraft:hard_brown_stained_glass_pane";
|
||||
public const HARD_CYAN_STAINED_GLASS = "minecraft:hard_cyan_stained_glass";
|
||||
public const HARD_CYAN_STAINED_GLASS_PANE = "minecraft:hard_cyan_stained_glass_pane";
|
||||
public const HARD_GLASS = "minecraft:hard_glass";
|
||||
public const HARD_GLASS_PANE = "minecraft:hard_glass_pane";
|
||||
public const HARD_STAINED_GLASS = "minecraft:hard_stained_glass";
|
||||
public const HARD_STAINED_GLASS_PANE = "minecraft:hard_stained_glass_pane";
|
||||
public const HARD_GRAY_STAINED_GLASS = "minecraft:hard_gray_stained_glass";
|
||||
public const HARD_GRAY_STAINED_GLASS_PANE = "minecraft:hard_gray_stained_glass_pane";
|
||||
public const HARD_GREEN_STAINED_GLASS = "minecraft:hard_green_stained_glass";
|
||||
public const HARD_GREEN_STAINED_GLASS_PANE = "minecraft:hard_green_stained_glass_pane";
|
||||
public const HARD_LIGHT_BLUE_STAINED_GLASS = "minecraft:hard_light_blue_stained_glass";
|
||||
public const HARD_LIGHT_BLUE_STAINED_GLASS_PANE = "minecraft:hard_light_blue_stained_glass_pane";
|
||||
public const HARD_LIGHT_GRAY_STAINED_GLASS = "minecraft:hard_light_gray_stained_glass";
|
||||
public const HARD_LIGHT_GRAY_STAINED_GLASS_PANE = "minecraft:hard_light_gray_stained_glass_pane";
|
||||
public const HARD_LIME_STAINED_GLASS = "minecraft:hard_lime_stained_glass";
|
||||
public const HARD_LIME_STAINED_GLASS_PANE = "minecraft:hard_lime_stained_glass_pane";
|
||||
public const HARD_MAGENTA_STAINED_GLASS = "minecraft:hard_magenta_stained_glass";
|
||||
public const HARD_MAGENTA_STAINED_GLASS_PANE = "minecraft:hard_magenta_stained_glass_pane";
|
||||
public const HARD_ORANGE_STAINED_GLASS = "minecraft:hard_orange_stained_glass";
|
||||
public const HARD_ORANGE_STAINED_GLASS_PANE = "minecraft:hard_orange_stained_glass_pane";
|
||||
public const HARD_PINK_STAINED_GLASS = "minecraft:hard_pink_stained_glass";
|
||||
public const HARD_PINK_STAINED_GLASS_PANE = "minecraft:hard_pink_stained_glass_pane";
|
||||
public const HARD_PURPLE_STAINED_GLASS = "minecraft:hard_purple_stained_glass";
|
||||
public const HARD_PURPLE_STAINED_GLASS_PANE = "minecraft:hard_purple_stained_glass_pane";
|
||||
public const HARD_RED_STAINED_GLASS = "minecraft:hard_red_stained_glass";
|
||||
public const HARD_RED_STAINED_GLASS_PANE = "minecraft:hard_red_stained_glass_pane";
|
||||
public const HARD_WHITE_STAINED_GLASS = "minecraft:hard_white_stained_glass";
|
||||
public const HARD_WHITE_STAINED_GLASS_PANE = "minecraft:hard_white_stained_glass_pane";
|
||||
public const HARD_YELLOW_STAINED_GLASS = "minecraft:hard_yellow_stained_glass";
|
||||
public const HARD_YELLOW_STAINED_GLASS_PANE = "minecraft:hard_yellow_stained_glass_pane";
|
||||
public const HARDENED_CLAY = "minecraft:hardened_clay";
|
||||
public const HAY_BLOCK = "minecraft:hay_block";
|
||||
public const HEAVY_WEIGHTED_PRESSURE_PLATE = "minecraft:heavy_weighted_pressure_plate";
|
||||
@ -900,6 +930,7 @@ final class BlockTypeNames{
|
||||
public const TORCHFLOWER_CROP = "minecraft:torchflower_crop";
|
||||
public const TRAPDOOR = "minecraft:trapdoor";
|
||||
public const TRAPPED_CHEST = "minecraft:trapped_chest";
|
||||
public const TRIAL_SPAWNER = "minecraft:trial_spawner";
|
||||
public const TRIP_WIRE = "minecraft:trip_wire";
|
||||
public const TRIPWIRE_HOOK = "minecraft:tripwire_hook";
|
||||
public const TUBE_CORAL = "minecraft:tube_coral";
|
||||
|
@ -315,6 +315,44 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{
|
||||
}
|
||||
|
||||
public function registerFlatColorBlockSerializers() : void{
|
||||
$this->map(Blocks::STAINED_HARDENED_GLASS(), fn(StainedHardenedGlass $block) => Writer::create(match($block->getColor()){
|
||||
DyeColor::BLACK => Ids::HARD_BLACK_STAINED_GLASS,
|
||||
DyeColor::BLUE => Ids::HARD_BLUE_STAINED_GLASS,
|
||||
DyeColor::BROWN => Ids::HARD_BROWN_STAINED_GLASS,
|
||||
DyeColor::CYAN => Ids::HARD_CYAN_STAINED_GLASS,
|
||||
DyeColor::GRAY => Ids::HARD_GRAY_STAINED_GLASS,
|
||||
DyeColor::GREEN => Ids::HARD_GREEN_STAINED_GLASS,
|
||||
DyeColor::LIGHT_BLUE => Ids::HARD_LIGHT_BLUE_STAINED_GLASS,
|
||||
DyeColor::LIGHT_GRAY => Ids::HARD_LIGHT_GRAY_STAINED_GLASS,
|
||||
DyeColor::LIME => Ids::HARD_LIME_STAINED_GLASS,
|
||||
DyeColor::MAGENTA => Ids::HARD_MAGENTA_STAINED_GLASS,
|
||||
DyeColor::ORANGE => Ids::HARD_ORANGE_STAINED_GLASS,
|
||||
DyeColor::PINK => Ids::HARD_PINK_STAINED_GLASS,
|
||||
DyeColor::PURPLE => Ids::HARD_PURPLE_STAINED_GLASS,
|
||||
DyeColor::RED => Ids::HARD_RED_STAINED_GLASS,
|
||||
DyeColor::WHITE => Ids::HARD_WHITE_STAINED_GLASS,
|
||||
DyeColor::YELLOW => Ids::HARD_YELLOW_STAINED_GLASS,
|
||||
}));
|
||||
|
||||
$this->map(Blocks::STAINED_HARDENED_GLASS_PANE(), fn(StainedHardenedGlassPane $block) => Writer::create(match($block->getColor()){
|
||||
DyeColor::BLACK => Ids::HARD_BLACK_STAINED_GLASS_PANE,
|
||||
DyeColor::BLUE => Ids::HARD_BLUE_STAINED_GLASS_PANE,
|
||||
DyeColor::BROWN => Ids::HARD_BROWN_STAINED_GLASS_PANE,
|
||||
DyeColor::CYAN => Ids::HARD_CYAN_STAINED_GLASS_PANE,
|
||||
DyeColor::GRAY => Ids::HARD_GRAY_STAINED_GLASS_PANE,
|
||||
DyeColor::GREEN => Ids::HARD_GREEN_STAINED_GLASS_PANE,
|
||||
DyeColor::LIGHT_BLUE => Ids::HARD_LIGHT_BLUE_STAINED_GLASS_PANE,
|
||||
DyeColor::LIGHT_GRAY => Ids::HARD_LIGHT_GRAY_STAINED_GLASS_PANE,
|
||||
DyeColor::LIME => Ids::HARD_LIME_STAINED_GLASS_PANE,
|
||||
DyeColor::MAGENTA => Ids::HARD_MAGENTA_STAINED_GLASS_PANE,
|
||||
DyeColor::ORANGE => Ids::HARD_ORANGE_STAINED_GLASS_PANE,
|
||||
DyeColor::PINK => Ids::HARD_PINK_STAINED_GLASS_PANE,
|
||||
DyeColor::PURPLE => Ids::HARD_PURPLE_STAINED_GLASS_PANE,
|
||||
DyeColor::RED => Ids::HARD_RED_STAINED_GLASS_PANE,
|
||||
DyeColor::WHITE => Ids::HARD_WHITE_STAINED_GLASS_PANE,
|
||||
DyeColor::YELLOW => Ids::HARD_YELLOW_STAINED_GLASS_PANE,
|
||||
}));
|
||||
|
||||
$this->map(Blocks::GLAZED_TERRACOTTA(), function(GlazedTerracotta $block) : Writer{
|
||||
return Writer::create(match($block->getColor()){
|
||||
DyeColor::BLACK => Ids::BLACK_GLAZED_TERRACOTTA,
|
||||
@ -1617,14 +1655,6 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{
|
||||
->writeString(StateNames::SPONGE_TYPE, $block->isWet() ? StringValues::SPONGE_TYPE_WET : StringValues::SPONGE_TYPE_DRY);
|
||||
});
|
||||
$this->map(Blocks::SPRUCE_SAPLING(), fn(Sapling $block) => Helper::encodeSapling($block, StringValues::SAPLING_TYPE_SPRUCE));
|
||||
$this->map(Blocks::STAINED_HARDENED_GLASS(), function(StainedHardenedGlass $block) : Writer{
|
||||
return Writer::create(Ids::HARD_STAINED_GLASS)
|
||||
->writeColor($block->getColor());
|
||||
});
|
||||
$this->map(Blocks::STAINED_HARDENED_GLASS_PANE(), function(StainedHardenedGlassPane $block) : Writer{
|
||||
return Writer::create(Ids::HARD_STAINED_GLASS_PANE)
|
||||
->writeColor($block->getColor());
|
||||
});
|
||||
$this->map(Blocks::STONECUTTER(), fn(Stonecutter $block) => Writer::create(Ids::STONECUTTER_BLOCK)
|
||||
->writeCardinalHorizontalFacing($block->getFacing()));
|
||||
$this->map(Blocks::STONE_BRICKS(), fn() => Helper::encodeStoneBricks(StringValues::STONE_BRICK_TYPE_DEFAULT));
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\data\bedrock\block\convert;
|
||||
|
||||
use pocketmine\block\utils\BellAttachmentType;
|
||||
use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\SlabType;
|
||||
use pocketmine\block\utils\WallConnectionType;
|
||||
use pocketmine\data\bedrock\block\BlockLegacyMetadata;
|
||||
@ -236,30 +235,6 @@ final class BlockStateReader{
|
||||
};
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
public function readColor() : DyeColor{
|
||||
// * color (StringTag) = black, blue, brown, cyan, gray, green, light_blue, lime, magenta, orange, pink, purple, red, silver, white, yellow
|
||||
return match($color = $this->readString(BlockStateNames::COLOR)){
|
||||
StringValues::COLOR_BLACK => DyeColor::BLACK,
|
||||
StringValues::COLOR_BLUE => DyeColor::BLUE,
|
||||
StringValues::COLOR_BROWN => DyeColor::BROWN,
|
||||
StringValues::COLOR_CYAN => DyeColor::CYAN,
|
||||
StringValues::COLOR_GRAY => DyeColor::GRAY,
|
||||
StringValues::COLOR_GREEN => DyeColor::GREEN,
|
||||
StringValues::COLOR_LIGHT_BLUE => DyeColor::LIGHT_BLUE,
|
||||
StringValues::COLOR_LIME => DyeColor::LIME,
|
||||
StringValues::COLOR_MAGENTA => DyeColor::MAGENTA,
|
||||
StringValues::COLOR_ORANGE => DyeColor::ORANGE,
|
||||
StringValues::COLOR_PINK => DyeColor::PINK,
|
||||
StringValues::COLOR_PURPLE => DyeColor::PURPLE,
|
||||
StringValues::COLOR_RED => DyeColor::RED,
|
||||
StringValues::COLOR_SILVER => DyeColor::LIGHT_GRAY,
|
||||
StringValues::COLOR_WHITE => DyeColor::WHITE,
|
||||
StringValues::COLOR_YELLOW => DyeColor::YELLOW,
|
||||
default => throw $this->badValueException(BlockStateNames::COLOR, $color),
|
||||
};
|
||||
}
|
||||
|
||||
/** @throws BlockStateDeserializeException */
|
||||
public function readCoralFacing() : int{
|
||||
return $this->parseFacingValue($this->readInt(BlockStateNames::CORAL_DIRECTION), [
|
||||
|
@ -185,6 +185,48 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{
|
||||
}
|
||||
|
||||
private function registerFlatColorBlockDeserializers() : void{
|
||||
foreach([
|
||||
Ids::HARD_BLACK_STAINED_GLASS => DyeColor::BLACK,
|
||||
Ids::HARD_BLUE_STAINED_GLASS => DyeColor::BLUE,
|
||||
Ids::HARD_BROWN_STAINED_GLASS => DyeColor::BROWN,
|
||||
Ids::HARD_CYAN_STAINED_GLASS => DyeColor::CYAN,
|
||||
Ids::HARD_GRAY_STAINED_GLASS => DyeColor::GRAY,
|
||||
Ids::HARD_GREEN_STAINED_GLASS => DyeColor::GREEN,
|
||||
Ids::HARD_LIGHT_BLUE_STAINED_GLASS => DyeColor::LIGHT_BLUE,
|
||||
Ids::HARD_LIGHT_GRAY_STAINED_GLASS => DyeColor::LIGHT_GRAY,
|
||||
Ids::HARD_LIME_STAINED_GLASS => DyeColor::LIME,
|
||||
Ids::HARD_MAGENTA_STAINED_GLASS => DyeColor::MAGENTA,
|
||||
Ids::HARD_ORANGE_STAINED_GLASS => DyeColor::ORANGE,
|
||||
Ids::HARD_PINK_STAINED_GLASS => DyeColor::PINK,
|
||||
Ids::HARD_PURPLE_STAINED_GLASS => DyeColor::PURPLE,
|
||||
Ids::HARD_RED_STAINED_GLASS => DyeColor::RED,
|
||||
Ids::HARD_WHITE_STAINED_GLASS => DyeColor::WHITE,
|
||||
Ids::HARD_YELLOW_STAINED_GLASS => DyeColor::YELLOW,
|
||||
] as $id => $color){
|
||||
$this->map($id, fn(Reader $in) => Blocks::STAINED_HARDENED_GLASS()->setColor($color));
|
||||
}
|
||||
|
||||
foreach([
|
||||
Ids::HARD_BLACK_STAINED_GLASS_PANE => DyeColor::BLACK,
|
||||
Ids::HARD_BLUE_STAINED_GLASS_PANE => DyeColor::BLUE,
|
||||
Ids::HARD_BROWN_STAINED_GLASS_PANE => DyeColor::BROWN,
|
||||
Ids::HARD_CYAN_STAINED_GLASS_PANE => DyeColor::CYAN,
|
||||
Ids::HARD_GRAY_STAINED_GLASS_PANE => DyeColor::GRAY,
|
||||
Ids::HARD_GREEN_STAINED_GLASS_PANE => DyeColor::GREEN,
|
||||
Ids::HARD_LIGHT_BLUE_STAINED_GLASS_PANE => DyeColor::LIGHT_BLUE,
|
||||
Ids::HARD_LIGHT_GRAY_STAINED_GLASS_PANE => DyeColor::LIGHT_GRAY,
|
||||
Ids::HARD_LIME_STAINED_GLASS_PANE => DyeColor::LIME,
|
||||
Ids::HARD_MAGENTA_STAINED_GLASS_PANE => DyeColor::MAGENTA,
|
||||
Ids::HARD_ORANGE_STAINED_GLASS_PANE => DyeColor::ORANGE,
|
||||
Ids::HARD_PINK_STAINED_GLASS_PANE => DyeColor::PINK,
|
||||
Ids::HARD_PURPLE_STAINED_GLASS_PANE => DyeColor::PURPLE,
|
||||
Ids::HARD_RED_STAINED_GLASS_PANE => DyeColor::RED,
|
||||
Ids::HARD_WHITE_STAINED_GLASS_PANE => DyeColor::WHITE,
|
||||
Ids::HARD_YELLOW_STAINED_GLASS_PANE => DyeColor::YELLOW,
|
||||
] as $id => $color){
|
||||
$this->map($id, fn(Reader $in) => Blocks::STAINED_HARDENED_GLASS_PANE()->setColor($color));
|
||||
}
|
||||
|
||||
foreach([
|
||||
Ids::BLACK_GLAZED_TERRACOTTA => DyeColor::BLACK,
|
||||
Ids::BLUE_GLAZED_TERRACOTTA => DyeColor::BLUE,
|
||||
@ -1159,14 +1201,6 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{
|
||||
->setShape($in->readBoundedInt(StateNames::RAIL_DIRECTION, 0, 5));
|
||||
});
|
||||
$this->mapStairs(Ids::GRANITE_STAIRS, fn() => Blocks::GRANITE_STAIRS());
|
||||
$this->map(Ids::HARD_STAINED_GLASS, function(Reader $in) : Block{
|
||||
return Blocks::STAINED_HARDENED_GLASS()
|
||||
->setColor($in->readColor());
|
||||
});
|
||||
$this->map(Ids::HARD_STAINED_GLASS_PANE, function(Reader $in) : Block{
|
||||
return Blocks::STAINED_HARDENED_GLASS_PANE()
|
||||
->setColor($in->readColor());
|
||||
});
|
||||
$this->map(Ids::HAY_BLOCK, function(Reader $in) : Block{
|
||||
$in->ignored(StateNames::DEPRECATED);
|
||||
return Blocks::HAY_BALE()->setAxis($in->readPillarAxis());
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\data\bedrock\block\convert;
|
||||
|
||||
use pocketmine\block\utils\BellAttachmentType;
|
||||
use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\SlabType;
|
||||
use pocketmine\block\utils\WallConnectionType;
|
||||
use pocketmine\block\utils\WoodType;
|
||||
@ -193,29 +192,6 @@ final class BlockStateWriter{
|
||||
});
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
public function writeColor(DyeColor $color) : self{
|
||||
$this->writeString(BlockStateNames::COLOR, match($color){
|
||||
DyeColor::BLACK => StringValues::COLOR_BLACK,
|
||||
DyeColor::BLUE => StringValues::COLOR_BLUE,
|
||||
DyeColor::BROWN => StringValues::COLOR_BROWN,
|
||||
DyeColor::CYAN => StringValues::COLOR_CYAN,
|
||||
DyeColor::GRAY => StringValues::COLOR_GRAY,
|
||||
DyeColor::GREEN => StringValues::COLOR_GREEN,
|
||||
DyeColor::LIGHT_BLUE => StringValues::COLOR_LIGHT_BLUE,
|
||||
DyeColor::LIGHT_GRAY => StringValues::COLOR_SILVER,
|
||||
DyeColor::LIME => StringValues::COLOR_LIME,
|
||||
DyeColor::MAGENTA => StringValues::COLOR_MAGENTA,
|
||||
DyeColor::ORANGE => StringValues::COLOR_ORANGE,
|
||||
DyeColor::PINK => StringValues::COLOR_PINK,
|
||||
DyeColor::PURPLE => StringValues::COLOR_PURPLE,
|
||||
DyeColor::RED => StringValues::COLOR_RED,
|
||||
DyeColor::WHITE => StringValues::COLOR_WHITE,
|
||||
DyeColor::YELLOW => StringValues::COLOR_YELLOW,
|
||||
});
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
public function writeCoralFacing(int $value) : self{
|
||||
$this->writeInt(BlockStateNames::CORAL_DIRECTION, match($value){
|
||||
|
@ -348,7 +348,7 @@ final class ItemSerializerDeserializerRegistrar{
|
||||
$this->map1to1Item(Ids::RIB_ARMOR_TRIM_SMITHING_TEMPLATE, Items::RIB_ARMOR_TRIM_SMITHING_TEMPLATE());
|
||||
$this->map1to1Item(Ids::ROTTEN_FLESH, Items::ROTTEN_FLESH());
|
||||
$this->map1to1Item(Ids::SALMON, Items::RAW_SALMON());
|
||||
$this->map1to1Item(Ids::SCUTE, Items::SCUTE());
|
||||
$this->map1to1Item(Ids::TURTLE_SCUTE, Items::SCUTE());
|
||||
$this->map1to1Item(Ids::SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE, Items::SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE());
|
||||
$this->map1to1Item(Ids::SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE, Items::SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE());
|
||||
$this->map1to1Item(Ids::SHEARS, Items::SHEARS());
|
||||
|
@ -38,6 +38,8 @@ final class ItemTypeNames{
|
||||
public const ANGLER_POTTERY_SHERD = "minecraft:angler_pottery_sherd";
|
||||
public const APPLE = "minecraft:apple";
|
||||
public const ARCHER_POTTERY_SHERD = "minecraft:archer_pottery_sherd";
|
||||
public const ARMADILLO_SCUTE = "minecraft:armadillo_scute";
|
||||
public const ARMADILLO_SPAWN_EGG = "minecraft:armadillo_spawn_egg";
|
||||
public const ARMOR_STAND = "minecraft:armor_stand";
|
||||
public const ARMS_UP_POTTERY_SHERD = "minecraft:arms_up_pottery_sherd";
|
||||
public const ARROW = "minecraft:arrow";
|
||||
@ -79,6 +81,7 @@ final class ItemTypeNames{
|
||||
public const BOW = "minecraft:bow";
|
||||
public const BOWL = "minecraft:bowl";
|
||||
public const BREAD = "minecraft:bread";
|
||||
public const BREEZE_SPAWN_EGG = "minecraft:breeze_spawn_egg";
|
||||
public const BREWER_POTTERY_SHERD = "minecraft:brewer_pottery_sherd";
|
||||
public const BREWING_STAND = "minecraft:brewing_stand";
|
||||
public const BRICK = "minecraft:brick";
|
||||
@ -238,6 +241,8 @@ final class ItemTypeNames{
|
||||
public const GREEN_DYE = "minecraft:green_dye";
|
||||
public const GUARDIAN_SPAWN_EGG = "minecraft:guardian_spawn_egg";
|
||||
public const GUNPOWDER = "minecraft:gunpowder";
|
||||
public const HARD_STAINED_GLASS = "minecraft:hard_stained_glass";
|
||||
public const HARD_STAINED_GLASS_PANE = "minecraft:hard_stained_glass_pane";
|
||||
public const HEART_OF_THE_SEA = "minecraft:heart_of_the_sea";
|
||||
public const HEART_POTTERY_SHERD = "minecraft:heart_pottery_sherd";
|
||||
public const HEARTBREAK_POTTERY_SHERD = "minecraft:heartbreak_pottery_sherd";
|
||||
@ -404,7 +409,6 @@ final class ItemTypeNames{
|
||||
public const SALMON = "minecraft:salmon";
|
||||
public const SALMON_BUCKET = "minecraft:salmon_bucket";
|
||||
public const SALMON_SPAWN_EGG = "minecraft:salmon_spawn_egg";
|
||||
public const SCUTE = "minecraft:scute";
|
||||
public const SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE = "minecraft:sentry_armor_trim_smithing_template";
|
||||
public const SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE = "minecraft:shaper_armor_trim_smithing_template";
|
||||
public const SHEAF_POTTERY_SHERD = "minecraft:sheaf_pottery_sherd";
|
||||
@ -466,11 +470,13 @@ final class ItemTypeNames{
|
||||
public const TORCHFLOWER_SEEDS = "minecraft:torchflower_seeds";
|
||||
public const TOTEM_OF_UNDYING = "minecraft:totem_of_undying";
|
||||
public const TRADER_LLAMA_SPAWN_EGG = "minecraft:trader_llama_spawn_egg";
|
||||
public const TRIAL_KEY = "minecraft:trial_key";
|
||||
public const TRIDENT = "minecraft:trident";
|
||||
public const TROPICAL_FISH = "minecraft:tropical_fish";
|
||||
public const TROPICAL_FISH_BUCKET = "minecraft:tropical_fish_bucket";
|
||||
public const TROPICAL_FISH_SPAWN_EGG = "minecraft:tropical_fish_spawn_egg";
|
||||
public const TURTLE_HELMET = "minecraft:turtle_helmet";
|
||||
public const TURTLE_SCUTE = "minecraft:turtle_scute";
|
||||
public const TURTLE_SPAWN_EGG = "minecraft:turtle_spawn_egg";
|
||||
public const VEX_ARMOR_TRIM_SMITHING_TEMPLATE = "minecraft:vex_armor_trim_smithing_template";
|
||||
public const VEX_SPAWN_EGG = "minecraft:vex_spawn_egg";
|
||||
@ -497,6 +503,7 @@ final class ItemTypeNames{
|
||||
public const WITCH_SPAWN_EGG = "minecraft:witch_spawn_egg";
|
||||
public const WITHER_SKELETON_SPAWN_EGG = "minecraft:wither_skeleton_spawn_egg";
|
||||
public const WITHER_SPAWN_EGG = "minecraft:wither_spawn_egg";
|
||||
public const WOLF_ARMOR = "minecraft:wolf_armor";
|
||||
public const WOLF_SPAWN_EGG = "minecraft:wolf_spawn_egg";
|
||||
public const WOODEN_AXE = "minecraft:wooden_axe";
|
||||
public const WOODEN_DOOR = "minecraft:wooden_door";
|
||||
|
@ -30,6 +30,7 @@ use pocketmine\network\mcpe\protocol\LevelChunkPacket;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketBatch;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext;
|
||||
use pocketmine\network\mcpe\protocol\types\ChunkPosition;
|
||||
use pocketmine\network\mcpe\protocol\types\DimensionIds;
|
||||
use pocketmine\network\mcpe\serializer\ChunkSerializer;
|
||||
use pocketmine\scheduler\AsyncTask;
|
||||
use pocketmine\thread\NonThreadSafeValue;
|
||||
@ -43,16 +44,22 @@ class ChunkRequestTask extends AsyncTask{
|
||||
protected string $chunk;
|
||||
protected int $chunkX;
|
||||
protected int $chunkZ;
|
||||
/** @phpstan-var DimensionIds::* */
|
||||
private int $dimensionId;
|
||||
/** @phpstan-var NonThreadSafeValue<Compressor> */
|
||||
protected NonThreadSafeValue $compressor;
|
||||
private string $tiles;
|
||||
|
||||
public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, Compressor $compressor){
|
||||
/**
|
||||
* @phpstan-param DimensionIds::* $dimensionId
|
||||
*/
|
||||
public function __construct(int $chunkX, int $chunkZ, int $dimensionId, Chunk $chunk, CompressBatchPromise $promise, Compressor $compressor){
|
||||
$this->compressor = new NonThreadSafeValue($compressor);
|
||||
|
||||
$this->chunk = FastChunkSerializer::serializeTerrain($chunk);
|
||||
$this->chunkX = $chunkX;
|
||||
$this->chunkZ = $chunkZ;
|
||||
$this->dimensionId = $dimensionId;
|
||||
$this->tiles = ChunkSerializer::serializeTiles($chunk);
|
||||
|
||||
$this->storeLocal(self::TLS_KEY_PROMISE, $promise);
|
||||
@ -60,14 +67,18 @@ class ChunkRequestTask extends AsyncTask{
|
||||
|
||||
public function onRun() : void{
|
||||
$chunk = FastChunkSerializer::deserializeTerrain($this->chunk);
|
||||
$subCount = ChunkSerializer::getSubChunkCount($chunk);
|
||||
$dimensionId = $this->dimensionId;
|
||||
|
||||
$subCount = ChunkSerializer::getSubChunkCount($chunk, $dimensionId);
|
||||
$converter = TypeConverter::getInstance();
|
||||
$encoderContext = new PacketSerializerContext($converter->getItemTypeDictionary());
|
||||
$payload = ChunkSerializer::serializeFullChunk($chunk, $converter->getBlockTranslator(), $encoderContext, $this->tiles);
|
||||
$payload = ChunkSerializer::serializeFullChunk($chunk, $dimensionId, $converter->getBlockTranslator(), $encoderContext, $this->tiles);
|
||||
|
||||
$stream = new BinaryStream();
|
||||
PacketBatch::encodePackets($stream, $encoderContext, [LevelChunkPacket::create(new ChunkPosition($this->chunkX, $this->chunkZ), $subCount, false, null, $payload)]);
|
||||
$this->setResult($this->compressor->deserialize()->compress($stream->getBuffer()));
|
||||
PacketBatch::encodePackets($stream, $encoderContext, [LevelChunkPacket::create(new ChunkPosition($this->chunkX, $this->chunkZ), $dimensionId, $subCount, false, null, $payload)]);
|
||||
|
||||
$compressor = $this->compressor->deserialize();
|
||||
$this->setResult(chr($compressor->getNetworkId()) . $compressor->compress($stream->getBuffer()));
|
||||
}
|
||||
|
||||
public function onCompletion() : void{
|
||||
|
@ -86,6 +86,7 @@ use pocketmine\network\mcpe\protocol\types\command\CommandEnum;
|
||||
use pocketmine\network\mcpe\protocol\types\command\CommandOverload;
|
||||
use pocketmine\network\mcpe\protocol\types\command\CommandParameter;
|
||||
use pocketmine\network\mcpe\protocol\types\command\CommandPermissions;
|
||||
use pocketmine\network\mcpe\protocol\types\CompressionAlgorithm;
|
||||
use pocketmine\network\mcpe\protocol\types\DimensionIds;
|
||||
use pocketmine\network\mcpe\protocol\types\PlayerListEntry;
|
||||
use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
|
||||
@ -119,6 +120,7 @@ use function implode;
|
||||
use function in_array;
|
||||
use function is_string;
|
||||
use function json_encode;
|
||||
use function ord;
|
||||
use function random_bytes;
|
||||
use function str_split;
|
||||
use function strcasecmp;
|
||||
@ -355,15 +357,27 @@ class NetworkSession{
|
||||
}
|
||||
}
|
||||
|
||||
if(strlen($payload) < 1){
|
||||
throw new PacketHandlingException("No bytes in payload");
|
||||
}
|
||||
|
||||
if($this->enableCompression){
|
||||
Timings::$playerNetworkReceiveDecompress->startTiming();
|
||||
try{
|
||||
$decompressed = $this->compressor->decompress($payload);
|
||||
}catch(DecompressionException $e){
|
||||
$this->logger->debug("Failed to decompress packet: " . base64_encode($payload));
|
||||
throw PacketHandlingException::wrap($e, "Compressed packet batch decode error");
|
||||
}finally{
|
||||
Timings::$playerNetworkReceiveDecompress->stopTiming();
|
||||
$compressionType = ord($payload[0]);
|
||||
$compressed = substr($payload, 1);
|
||||
if($compressionType === CompressionAlgorithm::NONE){
|
||||
$decompressed = $compressed;
|
||||
}elseif($compressionType === $this->compressor->getNetworkId()){
|
||||
try{
|
||||
$decompressed = $this->compressor->decompress($compressed);
|
||||
}catch(DecompressionException $e){
|
||||
$this->logger->debug("Failed to decompress packet: " . base64_encode($compressed));
|
||||
throw PacketHandlingException::wrap($e, "Compressed packet batch decode error");
|
||||
}finally{
|
||||
Timings::$playerNetworkReceiveDecompress->stopTiming();
|
||||
}
|
||||
}else{
|
||||
throw new PacketHandlingException("Packet compressed with unexpected compression type $compressionType");
|
||||
}
|
||||
}else{
|
||||
$decompressed = $payload;
|
||||
|
2
src/network/mcpe/cache/ChunkCache.php
vendored
2
src/network/mcpe/cache/ChunkCache.php
vendored
@ -27,6 +27,7 @@ use pocketmine\math\Vector3;
|
||||
use pocketmine\network\mcpe\ChunkRequestTask;
|
||||
use pocketmine\network\mcpe\compression\CompressBatchPromise;
|
||||
use pocketmine\network\mcpe\compression\Compressor;
|
||||
use pocketmine\network\mcpe\protocol\types\DimensionIds;
|
||||
use pocketmine\world\ChunkListener;
|
||||
use pocketmine\world\ChunkListenerNoOpTrait;
|
||||
use pocketmine\world\format\Chunk;
|
||||
@ -116,6 +117,7 @@ class ChunkCache implements ChunkListener{
|
||||
new ChunkRequestTask(
|
||||
$chunkX,
|
||||
$chunkZ,
|
||||
DimensionIds::OVERWORLD, //TODO: not hardcode this
|
||||
$chunk,
|
||||
$this->caches[$chunkHash],
|
||||
$this->compressor
|
||||
|
@ -43,7 +43,8 @@ class CompressBatchTask extends AsyncTask{
|
||||
}
|
||||
|
||||
public function onRun() : void{
|
||||
$this->setResult($this->compressor->deserialize()->compress($this->data));
|
||||
$compressor = $this->compressor->deserialize();
|
||||
$this->setResult(chr($compressor->getNetworkId()) . $compressor->compress($this->data));
|
||||
}
|
||||
|
||||
public function onCompletion() : void{
|
||||
|
@ -23,6 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\compression;
|
||||
|
||||
use pocketmine\network\mcpe\protocol\types\CompressionAlgorithm;
|
||||
|
||||
interface Compressor{
|
||||
/**
|
||||
* @throws DecompressionException
|
||||
@ -31,6 +33,14 @@ interface Compressor{
|
||||
|
||||
public function compress(string $payload) : string;
|
||||
|
||||
/**
|
||||
* Returns the canonical ID of this compressor, used to tell the remote end how to decompress a packet compressed
|
||||
* with this compressor.
|
||||
*
|
||||
* @return CompressionAlgorithm::*
|
||||
*/
|
||||
public function getNetworkId() : int;
|
||||
|
||||
/**
|
||||
* Returns the minimum size of packet batch that the compressor will attempt to compress.
|
||||
*
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\compression;
|
||||
|
||||
use pocketmine\network\mcpe\protocol\types\CompressionAlgorithm;
|
||||
use pocketmine\utils\SingletonTrait;
|
||||
use pocketmine\utils\Utils;
|
||||
use function function_exists;
|
||||
@ -75,4 +76,8 @@ final class ZlibCompressor implements Compressor{
|
||||
libdeflate_deflate_compress($payload, $level) :
|
||||
Utils::assumeNotFalse(zlib_encode($payload, ZLIB_ENCODING_RAW, $level), "ZLIB compression failed");
|
||||
}
|
||||
|
||||
public function getNetworkId() : int{
|
||||
return CompressionAlgorithm::ZLIB;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\network\mcpe\protocol\NetworkSettingsPacket;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\network\mcpe\protocol\RequestNetworkSettingsPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\CompressionAlgorithm;
|
||||
|
||||
final class SessionStartPacketHandler extends PacketHandler{
|
||||
|
||||
@ -50,7 +49,7 @@ final class SessionStartPacketHandler extends PacketHandler{
|
||||
//TODO: we're filling in the defaults to get pre-1.19.30 behaviour back for now, but we should explore the new options in the future
|
||||
$this->session->sendDataPacket(NetworkSettingsPacket::create(
|
||||
NetworkSettingsPacket::COMPRESS_EVERYTHING,
|
||||
CompressionAlgorithm::ZLIB,
|
||||
$this->session->getCompressor()->getNetworkId(),
|
||||
false,
|
||||
0,
|
||||
0
|
||||
|
@ -31,6 +31,7 @@ use pocketmine\network\mcpe\convert\BlockTranslator;
|
||||
use pocketmine\network\mcpe\protocol\serializer\NetworkNbtSerializer;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext;
|
||||
use pocketmine\network\mcpe\protocol\types\DimensionIds;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\BinaryStream;
|
||||
use pocketmine\world\format\Chunk;
|
||||
@ -43,12 +44,34 @@ final class ChunkSerializer{
|
||||
//NOOP
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the min/max subchunk index expected in the protocol.
|
||||
* This has no relation to the world height supported by PM.
|
||||
*
|
||||
* @phpstan-param DimensionIds::* $dimensionId
|
||||
* @return int[]
|
||||
* @phpstan-return array{int, int}
|
||||
*/
|
||||
public static function getDimensionChunkBounds(int $dimensionId) : array{
|
||||
return match($dimensionId){
|
||||
DimensionIds::OVERWORLD => [-4, 19],
|
||||
DimensionIds::NETHER => [0, 7],
|
||||
DimensionIds::THE_END => [0, 15],
|
||||
default => throw new \InvalidArgumentException("Unknown dimension ID $dimensionId"),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of subchunks that will be sent from the given chunk.
|
||||
* Chunks are sent in a stack, so every chunk below the top non-empty one must be sent.
|
||||
*
|
||||
* @phpstan-param DimensionIds::* $dimensionId
|
||||
*/
|
||||
public static function getSubChunkCount(Chunk $chunk) : int{
|
||||
for($y = Chunk::MAX_SUBCHUNK_INDEX, $count = count($chunk->getSubChunks()); $y >= Chunk::MIN_SUBCHUNK_INDEX; --$y, --$count){
|
||||
public static function getSubChunkCount(Chunk $chunk, int $dimensionId) : int{
|
||||
//if the protocol world bounds ever exceed the PM supported bounds again in the future, we might need to
|
||||
//polyfill some stuff here
|
||||
[$minSubChunkIndex, $maxSubChunkIndex] = self::getDimensionChunkBounds($dimensionId);
|
||||
for($y = $maxSubChunkIndex, $count = count($chunk->getSubChunks()); $y >= $minSubChunkIndex; --$y, --$count){
|
||||
if($chunk->getSubChunk($y)->isEmptyFast()){
|
||||
continue;
|
||||
}
|
||||
@ -58,18 +81,23 @@ final class ChunkSerializer{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function serializeFullChunk(Chunk $chunk, BlockTranslator $blockTranslator, PacketSerializerContext $encoderContext, ?string $tiles = null) : string{
|
||||
/**
|
||||
* @phpstan-param DimensionIds::* $dimensionId
|
||||
*/
|
||||
public static function serializeFullChunk(Chunk $chunk, int $dimensionId, BlockTranslator $blockTranslator, PacketSerializerContext $encoderContext, ?string $tiles = null) : string{
|
||||
$stream = PacketSerializer::encoder($encoderContext);
|
||||
|
||||
$subChunkCount = self::getSubChunkCount($chunk);
|
||||
$subChunkCount = self::getSubChunkCount($chunk, $dimensionId);
|
||||
$writtenCount = 0;
|
||||
for($y = Chunk::MIN_SUBCHUNK_INDEX; $writtenCount < $subChunkCount; ++$y, ++$writtenCount){
|
||||
|
||||
[$minSubChunkIndex, $maxSubChunkIndex] = self::getDimensionChunkBounds($dimensionId);
|
||||
for($y = $minSubChunkIndex; $writtenCount < $subChunkCount; ++$y, ++$writtenCount){
|
||||
self::serializeSubChunk($chunk->getSubChunk($y), $blockTranslator, $stream, false);
|
||||
}
|
||||
|
||||
$biomeIdMap = LegacyBiomeIdToStringIdMap::getInstance();
|
||||
//all biomes must always be written :(
|
||||
for($y = Chunk::MIN_SUBCHUNK_INDEX; $y <= Chunk::MAX_SUBCHUNK_INDEX; ++$y){
|
||||
for($y = $minSubChunkIndex; $y <= $maxSubChunkIndex; ++$y){
|
||||
self::serializeBiomePalette($chunk->getSubChunk($y)->getBiomeArray(), $biomeIdMap, $stream);
|
||||
}
|
||||
|
||||
|
@ -51,12 +51,12 @@ use function time;
|
||||
class BedrockWorldData extends BaseNbtWorldData{
|
||||
|
||||
public const CURRENT_STORAGE_VERSION = 10;
|
||||
public const CURRENT_STORAGE_NETWORK_VERSION = 630;
|
||||
public const CURRENT_STORAGE_NETWORK_VERSION = 649;
|
||||
public const CURRENT_CLIENT_VERSION_TARGET = [
|
||||
1, //major
|
||||
20, //minor
|
||||
50, //patch
|
||||
3, //revision
|
||||
60, //patch
|
||||
4, //revision
|
||||
0 //is beta
|
||||
];
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user