diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index ac184013fc0..346d645fd06 100644
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.4/apache-maven-3.9.4-bin.zip
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
diff --git a/pom.xml b/pom.xml
index bf368a2fbe0..dd87a51b9c6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -276,6 +276,12 @@
1.25.0
compile
+
+ org.xerial.snappy
+ snappy-java
+ 1.1.10.5
+ compile
+
diff --git a/src/main/java/cn/nukkit/GameVersion.java b/src/main/java/cn/nukkit/GameVersion.java
index 2d65b0dfbf1..cee6d3c27ee 100644
--- a/src/main/java/cn/nukkit/GameVersion.java
+++ b/src/main/java/cn/nukkit/GameVersion.java
@@ -50,6 +50,7 @@ public enum GameVersion {
V1_20_30(618, "1.20.30"),
V1_20_40(622, "1.20.40"),
V1_20_50(630, "1.20.50"),
+ V1_20_60(649, "1.20.60"),
;
private static GameVersion FEATURE_VERSION = ENABLE_BLOCK_STATE_PERSISTENCE ? GameVersion.V1_18_0 : GameVersion.V1_12_0;
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index b4887c2aa7d..b41c2f8bcd7 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -2686,7 +2686,7 @@ public void onCompletion(Server server) {
return;
}
- if (riding != null && (moveVecX != 0 || moveVecY != 0)) {
+ if (riding != null && (moveVecX != 0 || moveVecY != 0) && riding.isControlling(this)) {
moveVecX = Mth.clamp(moveVecX, -1, 1);
moveVecY = Mth.clamp(moveVecY, -1, 1);
@@ -2738,19 +2738,11 @@ public void onCompletion(Server server) {
this.newPosition = newPos;
this.forceMovement = null;
}
-
- if (riding != null) {
- if (riding instanceof EntityRideable && !(riding instanceof EntityBoat)) {
- Vector3f offset = riding.getMountedOffset(this);
- ((EntityRideable) riding).onPlayerRiding(this.temporalVector.setComponents(movePlayerPacket.x - offset.x, movePlayerPacket.y - offset.y, movePlayerPacket.z - offset.z), (movePlayerPacket.headYaw + 90) % 360, 0);
- }
- }
-
break;
case ProtocolInfo.MOVE_ACTOR_ABSOLUTE_PACKET:
MoveEntityPacket moveEntityPacket = (MoveEntityPacket) packet;
- if (!validateCoordinate((float) moveEntityPacket.x) || !validateCoordinate((float) moveEntityPacket.y) || !validateCoordinate((float) moveEntityPacket.z)
- || !validateFloat((float) moveEntityPacket.pitch) || !validateFloat((float) moveEntityPacket.yaw) || !validateFloat((float) moveEntityPacket.headYaw)) {
+ if (!validateCoordinate(moveEntityPacket.x) || !validateCoordinate(moveEntityPacket.y) || !validateCoordinate(moveEntityPacket.z)
+ || !validateFloat(moveEntityPacket.pitch) || !validateFloat(moveEntityPacket.yaw) || !validateFloat(moveEntityPacket.headYaw)) {
this.getServer().getLogger().warning("Invalid vehicle movement received: " + this.getName());
this.close("", "Invalid vehicle movement");
return;
@@ -2760,9 +2752,9 @@ public void onCompletion(Server server) {
break;
}
- if (this.riding instanceof EntityBoat) {
+ if (this.riding instanceof EntityBoat boat) {
if (this.temporalVector.setComponents(moveEntityPacket.x, moveEntityPacket.y, moveEntityPacket.z).distanceSquared(this.riding) < 1000) {
- ((EntityBoat) this.riding).onInput(moveEntityPacket.x, moveEntityPacket.y, moveEntityPacket.z, moveEntityPacket.yaw);
+ boat.onInput(moveEntityPacket.x, moveEntityPacket.y, moveEntityPacket.z, moveEntityPacket.yaw % 360);
}
}
break;
@@ -3700,7 +3692,7 @@ public void onCompletion(Server server) {
}
}
- Enchantment[] enchantments = item.getEnchantments();
+ Enchantment[] enchantments = item.getId() != Item.ENCHANTED_BOOK ? item.getEnchantments() : Enchantment.EMPTY;
ItemAttackDamageEvent event = new ItemAttackDamageEvent(item);
this.server.getPluginManager().callEvent(event);
@@ -3733,7 +3725,7 @@ public void onCompletion(Server server) {
break;
}
- for (Enchantment enchantment : item.getEnchantments()) {
+ for (Enchantment enchantment : enchantments) {
enchantment.doPostAttack(this, target, null);
}
@@ -4613,7 +4605,7 @@ public void kill() {
if (!ev.getKeepInventory() && this.level.getGameRules().getBoolean(GameRule.DO_ENTITY_DROPS)) {
for (Item item : ev.getDrops()) {
- if (!item.hasEnchantment(Enchantment.VANISHING)) {
+ if (item.getId() == Item.ENCHANTED_BOOK || !item.hasEnchantment(Enchantment.VANISHING)) {
this.level.dropItem(this, item, null, true, 40);
}
}
diff --git a/src/main/java/cn/nukkit/block/Block.java b/src/main/java/cn/nukkit/block/Block.java
index fbecffc219a..16df6c3eb24 100644
--- a/src/main/java/cn/nukkit/block/Block.java
+++ b/src/main/java/cn/nukkit/block/Block.java
@@ -773,8 +773,8 @@ public double getBreakTime(Item item, Player player) {
boolean canHarvestWithHand = canHarvestWithHand();
int itemToolType = toolType0(item);
int itemTier = item.getTier();
- int efficiencyLoreLevel = Optional.ofNullable(item.getEnchantment(Enchantment.EFFICIENCY))
- .map(Enchantment::getLevel).orElse(0);
+ int efficiencyLoreLevel = item.getId() != Item.ENCHANTED_BOOK ? Optional.ofNullable(item.getEnchantment(Enchantment.EFFICIENCY))
+ .map(Enchantment::getLevel).orElse(0) : 0;
int hasteEffectLevel = Optional.ofNullable(player.getEffect(Effect.HASTE))
.map(Effect::getAmplifier).orElse(0);
boolean insideOfWaterWithoutAquaAffinity = player.isInsideOfWater() &&
diff --git a/src/main/java/cn/nukkit/block/BlockAzalea.java b/src/main/java/cn/nukkit/block/BlockAzalea.java
index 32fd6a6b7cb..fd78ecb6bbd 100644
--- a/src/main/java/cn/nukkit/block/BlockAzalea.java
+++ b/src/main/java/cn/nukkit/block/BlockAzalea.java
@@ -106,6 +106,6 @@ public void setDamage(int meta) {
private boolean canSurvive() {
int id = down().getId();
- return id == GRASS || id == DIRT || id == MYCELIUM || id == PODZOL || id == FARMLAND || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK || id == CLAY;
+ return id == GRASS_BLOCK || id == DIRT || id == MYCELIUM || id == PODZOL || id == FARMLAND || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK || id == CLAY;
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockBamboo.java b/src/main/java/cn/nukkit/block/BlockBamboo.java
index 46841888ebc..49475c4f5c7 100644
--- a/src/main/java/cn/nukkit/block/BlockBamboo.java
+++ b/src/main/java/cn/nukkit/block/BlockBamboo.java
@@ -288,6 +288,6 @@ public void setThick(boolean thick) {
}
static boolean canBeSupportedBy(int id) {
- return id == GRASS || id == DIRT || id == SAND || id == GRAVEL || id == MYCELIUM || id == PODZOL || id == DIRT_WITH_ROOTS;
+ return id == GRASS_BLOCK || id == DIRT || id == SAND || id == GRAVEL || id == MYCELIUM || id == PODZOL || id == DIRT_WITH_ROOTS;
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockCampfire.java b/src/main/java/cn/nukkit/block/BlockCampfire.java
index 9b228a50578..b78b55a91e1 100644
--- a/src/main/java/cn/nukkit/block/BlockCampfire.java
+++ b/src/main/java/cn/nukkit/block/BlockCampfire.java
@@ -298,6 +298,10 @@ public void onEntityCollide(Entity entity) {
return;
}
+ if (true) {
+ return;
+ }
+
if (V1_19_60.isAvailable()) {
return;
}
diff --git a/src/main/java/cn/nukkit/block/BlockComposter.java b/src/main/java/cn/nukkit/block/BlockComposter.java
index b6c10a41df8..d66c8ae16c8 100644
--- a/src/main/java/cn/nukkit/block/BlockComposter.java
+++ b/src/main/java/cn/nukkit/block/BlockComposter.java
@@ -203,7 +203,7 @@ private static void registerCompostableItems(float chance, int... itemIds) {
ItemID.BEETROOT_SEEDS,
ItemID.DRIED_KELP,
getItemId(TALLGRASS),
- getItemId(GRASS),
+ getItemId(GRASS_BLOCK),
getItemId(HANGING_ROOTS),
getItemId(MANGROVE_ROOTS),
ItemID.KELP,
diff --git a/src/main/java/cn/nukkit/block/BlockDeadBush.java b/src/main/java/cn/nukkit/block/BlockDeadBush.java
index fa5431f556f..075db40079d 100644
--- a/src/main/java/cn/nukkit/block/BlockDeadBush.java
+++ b/src/main/java/cn/nukkit/block/BlockDeadBush.java
@@ -88,6 +88,6 @@ public boolean isVegetation() {
private boolean canSurvive() {
int id = down().getId();
- return id == SAND || id == HARDENED_CLAY || id == STAINED_HARDENED_CLAY || id == DIRT || id == PODZOL || id == MYCELIUM || id == DIRT_WITH_ROOTS || id == MUD || id == GRASS;
+ return id == SAND || id == HARDENED_CLAY || id == STAINED_HARDENED_CLAY || id == DIRT || id == PODZOL || id == MYCELIUM || id == DIRT_WITH_ROOTS || id == MUD || id == GRASS_BLOCK;
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockDoublePlant.java b/src/main/java/cn/nukkit/block/BlockDoublePlant.java
index 9a005724bbe..dd0f1724b62 100644
--- a/src/main/java/cn/nukkit/block/BlockDoublePlant.java
+++ b/src/main/java/cn/nukkit/block/BlockDoublePlant.java
@@ -191,6 +191,6 @@ public int getPlantType() {
private boolean canSurvive() {
int id = down().getId();
- return id == GRASS || id == DIRT || id == PODZOL || id == FARMLAND || id == MYCELIUM || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK;
+ return id == GRASS_BLOCK || id == DIRT || id == PODZOL || id == FARMLAND || id == MYCELIUM || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK;
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockDripleafBig.java b/src/main/java/cn/nukkit/block/BlockDripleafBig.java
index bb0e8ac6a6c..7877146528b 100644
--- a/src/main/java/cn/nukkit/block/BlockDripleafBig.java
+++ b/src/main/java/cn/nukkit/block/BlockDripleafBig.java
@@ -82,7 +82,7 @@ public Item[] getDrops(Item item) {
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
Block below = down();
int id = below.getId();
- if (!(id == BIG_DRIPLEAF || id == GRASS || id == DIRT || id == MYCELIUM || id == PODZOL || id == FARMLAND || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK || id == CLAY)) {
+ if (!(id == BIG_DRIPLEAF || id == GRASS_BLOCK || id == DIRT || id == MYCELIUM || id == PODZOL || id == FARMLAND || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK || id == CLAY)) {
return false;
}
@@ -315,7 +315,7 @@ public BlockFace getBlockFace() {
private boolean canSurvive() {
int id = down().getId();
- return id == BIG_DRIPLEAF || id == GRASS || id == DIRT || id == MYCELIUM || id == PODZOL || id == FARMLAND || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK || id == CLAY;
+ return id == BIG_DRIPLEAF || id == GRASS_BLOCK || id == DIRT || id == MYCELIUM || id == PODZOL || id == FARMLAND || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK || id == CLAY;
}
private void setTiltAndScheduleTick(int tilt) {
diff --git a/src/main/java/cn/nukkit/block/BlockDripleafSmall.java b/src/main/java/cn/nukkit/block/BlockDripleafSmall.java
index 52df7bf6eed..44285255b43 100644
--- a/src/main/java/cn/nukkit/block/BlockDripleafSmall.java
+++ b/src/main/java/cn/nukkit/block/BlockDripleafSmall.java
@@ -92,7 +92,7 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl
}
int id = down().getId();
- if (id != GRASS && id != DIRT && id != MYCELIUM && id != PODZOL && id != FARMLAND && id != DIRT_WITH_ROOTS && id != MOSS_BLOCK && id != CLAY) {
+ if (id != GRASS_BLOCK && id != DIRT && id != MYCELIUM && id != PODZOL && id != FARMLAND && id != DIRT_WITH_ROOTS && id != MOSS_BLOCK && id != CLAY) {
return false;
}
@@ -287,7 +287,7 @@ private boolean canSurvive() {
if (!level.getExtraBlock(this).isWater()) {
return false;
}
- return id == GRASS || id == DIRT || id == MYCELIUM || id == PODZOL || id == FARMLAND || id == DIRT_WITH_ROOTS;
+ return id == GRASS_BLOCK || id == DIRT || id == MYCELIUM || id == PODZOL || id == FARMLAND || id == DIRT_WITH_ROOTS;
}
public boolean isUpper() {
diff --git a/src/main/java/cn/nukkit/block/BlockFlower.java b/src/main/java/cn/nukkit/block/BlockFlower.java
index 6261a1496ca..3a6e2f5d745 100644
--- a/src/main/java/cn/nukkit/block/BlockFlower.java
+++ b/src/main/java/cn/nukkit/block/BlockFlower.java
@@ -118,7 +118,7 @@ public boolean onActivate(Item item, BlockFace face, Player player) {
random.nextInt(-1, 2),
random.nextInt(-3, 4));
- if (level.getBlock(vec).getId() == AIR && level.getBlock(vec.down()).getId() == GRASS && vec.getY() >= 0 && vec.getY() < 256) {
+ if (level.getBlock(vec).getId() == AIR && level.getBlock(vec.down()).getId() == GRASS_BLOCK && vec.getY() >= 0 && vec.getY() < 256) {
if (random.nextInt(10) == 0) {
this.level.setBlock(vec, this.getUncommonFlower(), true);
} else {
@@ -149,6 +149,6 @@ public boolean isVegetation() {
protected boolean canSurvive() {
int id = down().getId();
- return id == Block.GRASS || id == Block.DIRT || id == Block.FARMLAND || id == Block.PODZOL || id == MYCELIUM || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK;
+ return id == Block.GRASS_BLOCK || id == Block.DIRT || id == Block.FARMLAND || id == Block.PODZOL || id == MYCELIUM || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK;
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockFullNames.java b/src/main/java/cn/nukkit/block/BlockFullNames.java
index 4574140b145..f1a0062ea1d 100644
--- a/src/main/java/cn/nukkit/block/BlockFullNames.java
+++ b/src/main/java/cn/nukkit/block/BlockFullNames.java
@@ -3,6 +3,7 @@
// This file is generated automatically, do not edit it manually.
public interface BlockFullNames {
String STONE = "minecraft:" + BlockNames.STONE;
+ String GRASS_BLOCK = "minecraft:" + BlockNames.GRASS_BLOCK;
String GRASS = "minecraft:" + BlockNames.GRASS;
String DIRT = "minecraft:" + BlockNames.DIRT;
String COBBLESTONE = "minecraft:" + BlockNames.COBBLESTONE;
@@ -21,6 +22,7 @@ public interface BlockFullNames {
String COAL_ORE = "minecraft:" + BlockNames.COAL_ORE;
String OAK_LOG = "minecraft:" + BlockNames.OAK_LOG; //TODO: 1.19.80 flattening
String LOG = "minecraft:" + BlockNames.LOG;
+ String OAK_LEAVES = "minecraft:" + BlockNames.OAK_LEAVES;
String LEAVES = "minecraft:" + BlockNames.LEAVES;
String SPONGE = "minecraft:" + BlockNames.SPONGE;
String GLASS = "minecraft:" + BlockNames.GLASS;
@@ -167,12 +169,15 @@ public interface BlockFullNames {
String HOPPER = "minecraft:" + BlockNames.HOPPER;
String QUARTZ_BLOCK = "minecraft:" + BlockNames.QUARTZ_BLOCK;
String QUARTZ_STAIRS = "minecraft:" + BlockNames.QUARTZ_STAIRS;
+ String OAK_DOUBLE_SLAB = "minecraft:" + BlockNames.OAK_DOUBLE_SLAB; //TODO: 1.20.70 flattening
String DOUBLE_WOODEN_SLAB = "minecraft:" + BlockNames.DOUBLE_WOODEN_SLAB;
+ String OAK_SLAB = "minecraft:" + BlockNames.OAK_SLAB; //TODO: 1.20.70 flattening
String WOODEN_SLAB = "minecraft:" + BlockNames.WOODEN_SLAB;
String WHITE_TERRACOTTA = "minecraft:" + BlockNames.WHITE_TERRACOTTA; //TODO: 1.20.30 flattening
String STAINED_HARDENED_CLAY = "minecraft:" + BlockNames.STAINED_HARDENED_CLAY;
String WHITE_STAINED_GLASS_PANE = "minecraft:" + BlockNames.WHITE_STAINED_GLASS_PANE; //TODO: 1.20.20 flattening
String STAINED_GLASS_PANE = "minecraft:" + BlockNames.STAINED_GLASS_PANE;
+ String ACACIA_LEAVES = "minecraft:" + BlockNames.ACACIA_LEAVES; //TODO: 1.20.70 flattening
String LEAVES2 = "minecraft:" + BlockNames.LEAVES2;
String ACACIA_LOG = "minecraft:" + BlockNames.ACACIA_LOG; //TODO: 1.19.80 flattening
String LOG2 = "minecraft:" + BlockNames.LOG2;
@@ -208,6 +213,7 @@ public interface BlockFullNames {
String REPEATING_COMMAND_BLOCK = "minecraft:" + BlockNames.REPEATING_COMMAND_BLOCK;
String CHAIN_COMMAND_BLOCK = "minecraft:" + BlockNames.CHAIN_COMMAND_BLOCK;
String HARD_GLASS_PANE = "minecraft:" + BlockNames.HARD_GLASS_PANE;
+ String HARD_WHITE_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_WHITE_STAINED_GLASS_PANE; //TODO: 1.20.60 flattening
String HARD_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_STAINED_GLASS_PANE;
String CHEMICAL_HEAT = "minecraft:" + BlockNames.CHEMICAL_HEAT;
String SPRUCE_DOOR = "minecraft:" + BlockNames.SPRUCE_DOOR;
@@ -277,6 +283,7 @@ public interface BlockFullNames {
String OBSERVER = "minecraft:" + BlockNames.OBSERVER;
String STRUCTURE_BLOCK = "minecraft:" + BlockNames.STRUCTURE_BLOCK;
String HARD_GLASS = "minecraft:" + BlockNames.HARD_GLASS;
+ String HARD_WHITE_STAINED_GLASS = "minecraft:" + BlockNames.HARD_WHITE_STAINED_GLASS; //TODO: 1.20.60 flattening
String HARD_STAINED_GLASS = "minecraft:" + BlockNames.HARD_STAINED_GLASS;
String RESERVED6 = "minecraft:" + BlockNames.RESERVED6;
@@ -494,6 +501,7 @@ public interface BlockFullNames {
String CAMPFIRE = "minecraft:" + BlockNames.CAMPFIRE;
String LAVA_CAULDRON = "minecraft:" + BlockNames.LAVA_CAULDRON; //TODO: 1.20.0 remove
String JIGSAW = "minecraft:" + BlockNames.JIGSAW; //TODO: meta 29
+ String OAK_WOOD = "minecraft:" + BlockNames.OAK_WOOD; //TODO: 1.20.70 flattening
String WOOD = "minecraft:" + BlockNames.WOOD;
String COMPOSTER = "minecraft:" + BlockNames.COMPOSTER;
String LIT_BLAST_FURNACE = "minecraft:" + BlockNames.LIT_BLAST_FURNACE;
@@ -593,7 +601,7 @@ public interface BlockFullNames {
String COPPER_ORE = "minecraft:" + BlockNames.COPPER_ORE;
String LIGHTNING_ROD = "minecraft:" + BlockNames.LIGHTNING_ROD;
String CRAFTER = "minecraft:" + BlockNames.CRAFTER;
-
+ String VAULT = "minecraft:" + BlockNames.VAULT;
String TRIAL_SPAWNER = "minecraft:" + BlockNames.TRIAL_SPAWNER;
String DRIPSTONE_BLOCK = "minecraft:" + BlockNames.DRIPSTONE_BLOCK;
@@ -929,7 +937,21 @@ public interface BlockFullNames {
String GREEN_STAINED_GLASS_PANE = "minecraft:" + BlockNames.GREEN_STAINED_GLASS_PANE;
String RED_STAINED_GLASS_PANE = "minecraft:" + BlockNames.RED_STAINED_GLASS_PANE;
String BLACK_STAINED_GLASS_PANE = "minecraft:" + BlockNames.BLACK_STAINED_GLASS_PANE;
-
+ String HARD_ORANGE_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_ORANGE_STAINED_GLASS_PANE;
+ String HARD_MAGENTA_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_MAGENTA_STAINED_GLASS_PANE;
+ String HARD_LIGHT_BLUE_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_LIGHT_BLUE_STAINED_GLASS_PANE;
+ String HARD_YELLOW_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_YELLOW_STAINED_GLASS_PANE;
+ String HARD_LIME_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_LIME_STAINED_GLASS_PANE;
+ String HARD_PINK_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_PINK_STAINED_GLASS_PANE;
+ String HARD_GRAY_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_GRAY_STAINED_GLASS_PANE;
+ String HARD_LIGHT_GRAY_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_LIGHT_GRAY_STAINED_GLASS_PANE;
+ String HARD_CYAN_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_CYAN_STAINED_GLASS_PANE;
+ String HARD_PURPLE_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_PURPLE_STAINED_GLASS_PANE;
+ String HARD_BLUE_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_BLUE_STAINED_GLASS_PANE;
+ String HARD_BROWN_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_BROWN_STAINED_GLASS_PANE;
+ String HARD_GREEN_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_GREEN_STAINED_GLASS_PANE;
+ String HARD_RED_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_RED_STAINED_GLASS_PANE;
+ String HARD_BLACK_STAINED_GLASS_PANE = "minecraft:" + BlockNames.HARD_BLACK_STAINED_GLASS_PANE;
String ORANGE_STAINED_GLASS = "minecraft:" + BlockNames.ORANGE_STAINED_GLASS;
String MAGENTA_STAINED_GLASS = "minecraft:" + BlockNames.MAGENTA_STAINED_GLASS;
String LIGHT_BLUE_STAINED_GLASS = "minecraft:" + BlockNames.LIGHT_BLUE_STAINED_GLASS;
@@ -945,6 +967,21 @@ public interface BlockFullNames {
String GREEN_STAINED_GLASS = "minecraft:" + BlockNames.GREEN_STAINED_GLASS;
String RED_STAINED_GLASS = "minecraft:" + BlockNames.RED_STAINED_GLASS;
String BLACK_STAINED_GLASS = "minecraft:" + BlockNames.BLACK_STAINED_GLASS;
+ String HARD_ORANGE_STAINED_GLASS = "minecraft:" + BlockNames.HARD_ORANGE_STAINED_GLASS;
+ String HARD_MAGENTA_STAINED_GLASS = "minecraft:" + BlockNames.HARD_MAGENTA_STAINED_GLASS;
+ String HARD_LIGHT_BLUE_STAINED_GLASS = "minecraft:" + BlockNames.HARD_LIGHT_BLUE_STAINED_GLASS;
+ String HARD_YELLOW_STAINED_GLASS = "minecraft:" + BlockNames.HARD_YELLOW_STAINED_GLASS;
+ String HARD_LIME_STAINED_GLASS = "minecraft:" + BlockNames.HARD_LIME_STAINED_GLASS;
+ String HARD_PINK_STAINED_GLASS = "minecraft:" + BlockNames.HARD_PINK_STAINED_GLASS;
+ String HARD_GRAY_STAINED_GLASS = "minecraft:" + BlockNames.HARD_GRAY_STAINED_GLASS;
+ String HARD_LIGHT_GRAY_STAINED_GLASS = "minecraft:" + BlockNames.HARD_LIGHT_GRAY_STAINED_GLASS;
+ String HARD_CYAN_STAINED_GLASS = "minecraft:" + BlockNames.HARD_CYAN_STAINED_GLASS;
+ String HARD_PURPLE_STAINED_GLASS = "minecraft:" + BlockNames.HARD_PURPLE_STAINED_GLASS;
+ String HARD_BLUE_STAINED_GLASS = "minecraft:" + BlockNames.HARD_BLUE_STAINED_GLASS;
+ String HARD_BROWN_STAINED_GLASS = "minecraft:" + BlockNames.HARD_BROWN_STAINED_GLASS;
+ String HARD_GREEN_STAINED_GLASS = "minecraft:" + BlockNames.HARD_GREEN_STAINED_GLASS;
+ String HARD_RED_STAINED_GLASS = "minecraft:" + BlockNames.HARD_RED_STAINED_GLASS;
+ String HARD_BLACK_STAINED_GLASS = "minecraft:" + BlockNames.HARD_BLACK_STAINED_GLASS;
String ORANGE_CONCRETE_POWDER = "minecraft:" + BlockNames.ORANGE_CONCRETE_POWDER;
String MAGENTA_CONCRETE_POWDER = "minecraft:" + BlockNames.MAGENTA_CONCRETE_POWDER;
@@ -1037,4 +1074,29 @@ public interface BlockFullNames {
String WAXED_EXPOSED_COPPER_TRAPDOOR = "minecraft:" + BlockNames.WAXED_EXPOSED_COPPER_TRAPDOOR;
String WAXED_WEATHERED_COPPER_TRAPDOOR = "minecraft:" + BlockNames.WAXED_WEATHERED_COPPER_TRAPDOOR;
String WAXED_OXIDIZED_COPPER_TRAPDOOR = "minecraft:" + BlockNames.WAXED_OXIDIZED_COPPER_TRAPDOOR;
+ String SPRUCE_LEAVES = "minecraft:" + BlockNames.SPRUCE_LEAVES;
+ String BIRCH_LEAVES = "minecraft:" + BlockNames.BIRCH_LEAVES;
+ String JUNGLE_LEAVES = "minecraft:" + BlockNames.JUNGLE_LEAVES;
+ String DARK_OAK_LEAVES = "minecraft:" + BlockNames.DARK_OAK_LEAVES;
+ String SPRUCE_SLAB = "minecraft:" + BlockNames.SPRUCE_SLAB;
+ String BIRCH_SLAB = "minecraft:" + BlockNames.BIRCH_SLAB;
+ String JUNGLE_SLAB = "minecraft:" + BlockNames.JUNGLE_SLAB;
+ String ACACIA_SLAB = "minecraft:" + BlockNames.ACACIA_SLAB;
+ String DARK_OAK_SLAB = "minecraft:" + BlockNames.DARK_OAK_SLAB;
+ String SPRUCE_DOUBLE_SLAB = "minecraft:" + BlockNames.SPRUCE_DOUBLE_SLAB;
+ String BIRCH_DOUBLE_SLAB = "minecraft:" + BlockNames.BIRCH_DOUBLE_SLAB;
+ String JUNGLE_DOUBLE_SLAB = "minecraft:" + BlockNames.JUNGLE_DOUBLE_SLAB;
+ String ACACIA_DOUBLE_SLAB = "minecraft:" + BlockNames.ACACIA_DOUBLE_SLAB;
+ String DARK_OAK_DOUBLE_SLAB = "minecraft:" + BlockNames.DARK_OAK_DOUBLE_SLAB;
+ String SPRUCE_WOOD = "minecraft:" + BlockNames.SPRUCE_WOOD;
+ String BIRCH_WOOD = "minecraft:" + BlockNames.BIRCH_WOOD;
+ String JUNGLE_WOOD = "minecraft:" + BlockNames.JUNGLE_WOOD;
+ String ACACIA_WOOD = "minecraft:" + BlockNames.ACACIA_WOOD;
+ String DARK_OAK_WOOD = "minecraft:" + BlockNames.DARK_OAK_WOOD;
+ String STRIPPED_OAK_WOOD = "minecraft:" + BlockNames.STRIPPED_OAK_WOOD;
+ String STRIPPED_SPRUCE_WOOD = "minecraft:" + BlockNames.STRIPPED_SPRUCE_WOOD;
+ String STRIPPED_BIRCH_WOOD = "minecraft:" + BlockNames.STRIPPED_BIRCH_WOOD;
+ String STRIPPED_JUNGLE_WOOD = "minecraft:" + BlockNames.STRIPPED_JUNGLE_WOOD;
+ String STRIPPED_ACACIA_WOOD = "minecraft:" + BlockNames.STRIPPED_ACACIA_WOOD;
+ String STRIPPED_DARK_OAK_WOOD = "minecraft:" + BlockNames.STRIPPED_DARK_OAK_WOOD;
}
diff --git a/src/main/java/cn/nukkit/block/BlockGlowstone.java b/src/main/java/cn/nukkit/block/BlockGlowstone.java
index 47d8fbd41d5..2e5a2cc6a86 100644
--- a/src/main/java/cn/nukkit/block/BlockGlowstone.java
+++ b/src/main/java/cn/nukkit/block/BlockGlowstone.java
@@ -46,7 +46,7 @@ public Item[] getDrops(Item item) {
Random random = ThreadLocalRandom.current();
int count = 2 + random.nextInt(3);
- Enchantment fortune = item.getEnchantment(Enchantment.FORTUNE);
+ Enchantment fortune = item.getId() != Item.ENCHANTED_BOOK ? item.getEnchantment(Enchantment.FORTUNE) : null;
if (fortune != null && fortune.getLevel() >= 1) {
count += random.nextInt(fortune.getLevel() + 1);
}
diff --git a/src/main/java/cn/nukkit/block/BlockGrass.java b/src/main/java/cn/nukkit/block/BlockGrass.java
index 5daa66b28f4..a3e70da13cc 100644
--- a/src/main/java/cn/nukkit/block/BlockGrass.java
+++ b/src/main/java/cn/nukkit/block/BlockGrass.java
@@ -31,7 +31,7 @@ public BlockGrass(int meta) {
@Override
public int getId() {
- return GRASS;
+ return GRASS_BLOCK;
}
@Override
@@ -92,7 +92,7 @@ public int onUpdate(int type) {
if (block.getId() == Block.DIRT && block.getDamage() == 0) {
Block up = block.up();
if (!up.isLiquid() && (up.isTransparent() || !up.isSolid()) && !level.getExtraBlock(up).isWater()) {
- BlockSpreadEvent ev = new BlockSpreadEvent(block, this, Block.get(BlockID.GRASS));
+ BlockSpreadEvent ev = new BlockSpreadEvent(block, this, Block.get(BlockID.GRASS_BLOCK));
Server.getInstance().getPluginManager().callEvent(ev);
if (!ev.isCancelled()) {
this.getLevel().setBlock(block, ev.getNewState(), true);
diff --git a/src/main/java/cn/nukkit/block/BlockID.java b/src/main/java/cn/nukkit/block/BlockID.java
index 1e3c6daf041..48578403130 100644
--- a/src/main/java/cn/nukkit/block/BlockID.java
+++ b/src/main/java/cn/nukkit/block/BlockID.java
@@ -6,6 +6,11 @@
public interface BlockID {
int AIR = 0;
int STONE = 1;
+ int GRASS_BLOCK = 2;
+ /**
+ * @deprecated use {@link #GRASS_BLOCK} instead
+ */
+ @Deprecated
int GRASS = 2;
int DIRT = 3;
int COBBLESTONE = 4;
@@ -24,6 +29,7 @@ public interface BlockID {
int COAL_ORE = 16;
int OAK_LOG = 17; //TODO: 1.19.80: flattening
int LOG = 17;
+ int OAK_LEAVES = 18; //TODO: 1.20.70 flattening
int LEAVES = 18;
int SPONGE = 19;
int GLASS = 20;
@@ -180,12 +186,15 @@ public interface BlockID {
int BLOCK_HOPPER = 154;
int QUARTZ_BLOCK = 155;
int QUARTZ_STAIRS = 156;
+ int OAK_DOUBLE_SLAB = 157; //TODO: 1.20.70 flattening
int DOUBLE_WOODEN_SLAB = 157;
+ int OAK_SLAB = 158; //TODO: 1.20.70 flattening
int WOODEN_SLAB = 158;
int WHITE_TERRACOTTA = 159; //TODO: 1.20.30: flattening
int STAINED_HARDENED_CLAY = 159;
int WHITE_STAINED_GLASS_PANE = 160; //TODO: 1.20.20: flattening
int STAINED_GLASS_PANE = 160;
+ int ACACIA_LEAVES = 161; //TODO: 1.20.70 flattening
int LEAVES2 = 161;
int ACACIA_LOG = 162; //TODO: 1.19.80: flattening
int LOG2 = 162;
@@ -223,6 +232,7 @@ public interface BlockID {
int REPEATING_COMMAND_BLOCK = 188;
int CHAIN_COMMAND_BLOCK = 189;
int HARD_GLASS_PANE = 190;
+ int HARD_WHITE_STAINED_GLASS_PANE = 191; //TODO: 1.20.60 flattening
int HARD_STAINED_GLASS_PANE = 191;
int CHEMICAL_HEAT = 192;
int BLOCK_SPRUCE_DOOR = 193;
@@ -300,6 +310,7 @@ public interface BlockID {
int OBSERVER = 251;
int STRUCTURE_BLOCK = 252;
int HARD_GLASS = 253;
+ int HARD_WHITE_STAINED_GLASS = 254; //TODO: 1.20.60 flattening
int HARD_STAINED_GLASS = 254;
int RESERVED6 = 255;
@@ -513,6 +524,7 @@ public interface BlockID {
int BLOCK_CAMPFIRE = 464;
int LAVA_CAULDRON = 465; //TODO: 1.20.0 remove
int JIGSAW = 466; //TODO: meta 29
+ int OAK_WOOD = 467; //TODO: 1.20.70 flattening
int WOOD = 467;
int COMPOSTER = 468;
int LIT_BLAST_FURNACE = 469;
@@ -616,7 +628,7 @@ public interface BlockID {
int COPPER_ORE = 566;
int LIGHTNING_ROD = 567;
int CRAFTER = 568;
-
+ int VAULT = 569;
int TRIAL_SPAWNER = 570;
int DRIPSTONE_BLOCK = 572;
@@ -952,7 +964,21 @@ public interface BlockID {
int GREEN_STAINED_GLASS_PANE = 910;
int RED_STAINED_GLASS_PANE = 911;
int BLACK_STAINED_GLASS_PANE = 912;
-
+ int HARD_ORANGE_STAINED_GLASS_PANE = 913;
+ int HARD_MAGENTA_STAINED_GLASS_PANE = 914;
+ int HARD_LIGHT_BLUE_STAINED_GLASS_PANE = 915;
+ int HARD_YELLOW_STAINED_GLASS_PANE = 916;
+ int HARD_LIME_STAINED_GLASS_PANE = 917;
+ int HARD_PINK_STAINED_GLASS_PANE = 918;
+ int HARD_GRAY_STAINED_GLASS_PANE = 919;
+ int HARD_LIGHT_GRAY_STAINED_GLASS_PANE = 920;
+ int HARD_CYAN_STAINED_GLASS_PANE = 921;
+ int HARD_PURPLE_STAINED_GLASS_PANE = 922;
+ int HARD_BLUE_STAINED_GLASS_PANE = 923;
+ int HARD_BROWN_STAINED_GLASS_PANE = 924;
+ int HARD_GREEN_STAINED_GLASS_PANE = 925;
+ int HARD_RED_STAINED_GLASS_PANE = 926;
+ int HARD_BLACK_STAINED_GLASS_PANE = 927;
int ORANGE_STAINED_GLASS = 928;
int MAGENTA_STAINED_GLASS = 929;
int LIGHT_BLUE_STAINED_GLASS = 930;
@@ -968,6 +994,21 @@ public interface BlockID {
int GREEN_STAINED_GLASS = 940;
int RED_STAINED_GLASS = 941;
int BLACK_STAINED_GLASS = 942;
+ int HARD_ORANGE_STAINED_GLASS = 943;
+ int HARD_MAGENTA_STAINED_GLASS = 944;
+ int HARD_LIGHT_BLUE_STAINED_GLASS = 945;
+ int HARD_YELLOW_STAINED_GLASS = 946;
+ int HARD_LIME_STAINED_GLASS = 947;
+ int HARD_PINK_STAINED_GLASS = 948;
+ int HARD_GRAY_STAINED_GLASS = 949;
+ int HARD_LIGHT_GRAY_STAINED_GLASS = 950;
+ int HARD_CYAN_STAINED_GLASS = 951;
+ int HARD_PURPLE_STAINED_GLASS = 952;
+ int HARD_BLUE_STAINED_GLASS = 953;
+ int HARD_BROWN_STAINED_GLASS = 954;
+ int HARD_GREEN_STAINED_GLASS = 955;
+ int HARD_RED_STAINED_GLASS = 956;
+ int HARD_BLACK_STAINED_GLASS = 957;
int ORANGE_CONCRETE_POWDER = 964;
int MAGENTA_CONCRETE_POWDER = 965;
@@ -1060,9 +1101,34 @@ public interface BlockID {
int WAXED_EXPOSED_COPPER_TRAPDOOR = 1052;
int WAXED_WEATHERED_COPPER_TRAPDOOR = 1053;
int WAXED_OXIDIZED_COPPER_TRAPDOOR = 1054;
+ int SPRUCE_LEAVES = 1055;
+ int BIRCH_LEAVES = 1056;
+ int JUNGLE_LEAVES = 1057;
+ int DARK_OAK_LEAVES = 1058;
+ int SPRUCE_SLAB = 1059;
+ int BIRCH_SLAB = 1060;
+ int JUNGLE_SLAB = 1061;
+ int ACACIA_SLAB = 1062;
+ int DARK_OAK_SLAB = 1063;
+ int SPRUCE_DOUBLE_SLAB = 1064;
+ int BIRCH_DOUBLE_SLAB = 1065;
+ int JUNGLE_DOUBLE_SLAB = 1066;
+ int ACACIA_DOUBLE_SLAB = 1067;
+ int DARK_OAK_DOUBLE_SLAB = 1068;
+ int SPRUCE_WOOD = 1069;
+ int BIRCH_WOOD = 1070;
+ int JUNGLE_WOOD = 1071;
+ int ACACIA_WOOD = 1072;
+ int DARK_OAK_WOOD = 1073;
+ int STRIPPED_OAK_WOOD = 1074;
+ int STRIPPED_SPRUCE_WOOD = 1075;
+ int STRIPPED_BIRCH_WOOD = 1076;
+ int STRIPPED_JUNGLE_WOOD = 1077;
+ int STRIPPED_ACACIA_WOOD = 1078;
+ int STRIPPED_DARK_OAK_WOOD = 1079;
- int UNDEFINED = 1055;
+ int UNDEFINED = 1080;
@Beta
int COARSE_DIRT = DIRT;
@@ -1081,14 +1147,6 @@ public interface BlockID {
@Beta
int RED_SAND = SAND;
@Beta
- int OAK_LEAVES = LEAVES;
- @Beta
- int SPRUCE_LEAVES = LEAVES;
- @Beta
- int BIRCH_LEAVES = LEAVES;
- @Beta
- int JUNGLE_LEAVES = LEAVES;
- @Beta
int CHISELED_SANDSTONE = SANDSTONE;
@Beta
int CUT_SANDSTONE = SANDSTONE;
@@ -1197,34 +1255,6 @@ public interface BlockID {
@Beta
int SMOOTH_QUARTZ_BLOCK = QUARTZ_BLOCK;
@Beta
- int OAK_DOUBLE_SLAB = DOUBLE_WOODEN_SLAB;
- @Beta
- int SPRUCE_DOUBLE_SLAB = DOUBLE_WOODEN_SLAB;
- @Beta
- int BIRCH_DOUBLE_SLAB = DOUBLE_WOODEN_SLAB;
- @Beta
- int JUNGLE_DOUBLE_SLAB = DOUBLE_WOODEN_SLAB;
- @Beta
- int ACACIA_DOUBLE_SLAB = DOUBLE_WOODEN_SLAB;
- @Beta
- int DARK_OAK_DOUBLE_SLAB = DOUBLE_WOODEN_SLAB;
- @Beta
- int OAK_SLAB = WOODEN_SLAB;
- @Beta
- int SPRUCE_SLAB = WOODEN_SLAB;
- @Beta
- int BIRCH_SLAB = WOODEN_SLAB;
- @Beta
- int JUNGLE_SLAB = WOODEN_SLAB;
- @Beta
- int ACACIA_SLAB = WOODEN_SLAB;
- @Beta
- int DARK_OAK_SLAB = WOODEN_SLAB;
- @Beta
- int ACACIA_LEAVES = LEAVES2;
- @Beta
- int DARK_OAK_LEAVES = LEAVES2;
- @Beta
int DARK_PRISMARINE = PRISMARINE;
@Beta
int PRISMARINE_BRICKS = PRISMARINE;
@@ -1386,28 +1416,4 @@ public interface BlockID {
int CUT_SANDSTONE_DOUBLE_SLAB = DOUBLE_STONE_SLAB4;
@Beta
int CUT_RED_SANDSTONE_DOUBLE_SLAB = DOUBLE_STONE_SLAB4;
- @Beta
- int OAK_WOOD = WOOD;
- @Beta
- int SPRUCE_WOOD = WOOD;
- @Beta
- int BIRCH_WOOD = WOOD;
- @Beta
- int JUNGLE_WOOD = WOOD;
- @Beta
- int ACACIA_WOOD = WOOD;
- @Beta
- int DARK_OAK_WOOD = WOOD;
- @Beta
- int STRIPPED_OAK_WOOD = WOOD;
- @Beta
- int STRIPPED_SPRUCE_WOOD = WOOD;
- @Beta
- int STRIPPED_BIRCH_WOOD = WOOD;
- @Beta
- int STRIPPED_JUNGLE_WOOD = WOOD;
- @Beta
- int STRIPPED_ACACIA_WOOD = WOOD;
- @Beta
- int STRIPPED_DARK_OAK_WOOD = WOOD;
}
diff --git a/src/main/java/cn/nukkit/block/BlockMangrovePropagule.java b/src/main/java/cn/nukkit/block/BlockMangrovePropagule.java
index fe0e588c09b..eb2769627b5 100644
--- a/src/main/java/cn/nukkit/block/BlockMangrovePropagule.java
+++ b/src/main/java/cn/nukkit/block/BlockMangrovePropagule.java
@@ -220,7 +220,7 @@ private boolean canSurvive() {
}
int id = down().getId();
- return id == BIG_DRIPLEAF || id == GRASS || id == DIRT || id == MYCELIUM || id == PODZOL || id == FARMLAND || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK || id == CLAY;
+ return id == BIG_DRIPLEAF || id == GRASS_BLOCK || id == DIRT || id == MYCELIUM || id == PODZOL || id == FARMLAND || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK || id == CLAY;
}
public int getStage() {
diff --git a/src/main/java/cn/nukkit/block/BlockMelon.java b/src/main/java/cn/nukkit/block/BlockMelon.java
index f74d04b724f..776069281e4 100644
--- a/src/main/java/cn/nukkit/block/BlockMelon.java
+++ b/src/main/java/cn/nukkit/block/BlockMelon.java
@@ -41,7 +41,7 @@ public Item[] getDrops(Item item) {
Random random = ThreadLocalRandom.current();
int count = 3 + random.nextInt(5);
- Enchantment fortune = item.getEnchantment(Enchantment.FORTUNE);
+ Enchantment fortune = item.getId() != Item.ENCHANTED_BOOK ? item.getEnchantment(Enchantment.FORTUNE) : null;
if (fortune != null && fortune.getLevel() >= 1) {
count += random.nextInt(fortune.getLevel() + 1);
}
diff --git a/src/main/java/cn/nukkit/block/BlockNames.java b/src/main/java/cn/nukkit/block/BlockNames.java
index 9abd1cd4c34..5f9fc5cc54a 100644
--- a/src/main/java/cn/nukkit/block/BlockNames.java
+++ b/src/main/java/cn/nukkit/block/BlockNames.java
@@ -2,6 +2,7 @@
public interface BlockNames {
String STONE = "stone";
+ String GRASS_BLOCK = "grass_block";
String GRASS = "grass";
String DIRT = "dirt";
String COBBLESTONE = "cobblestone";
@@ -20,6 +21,7 @@ public interface BlockNames {
String COAL_ORE = "coal_ore";
String OAK_LOG = "oak_log"; //TODO: 1.19.80 flattening
String LOG = "log";
+ String OAK_LEAVES = "oak_leaves";
String LEAVES = "leaves";
String SPONGE = "sponge";
String GLASS = "glass";
@@ -166,12 +168,15 @@ public interface BlockNames {
String HOPPER = "hopper";
String QUARTZ_BLOCK = "quartz_block";
String QUARTZ_STAIRS = "quartz_stairs";
+ String OAK_DOUBLE_SLAB = "oak_double_slab"; //TODO: 1.20.70 flattening
String DOUBLE_WOODEN_SLAB = "double_wooden_slab";
+ String OAK_SLAB = "oak_slab"; //TODO: 1.20.70 flattening
String WOODEN_SLAB = "wooden_slab";
String WHITE_TERRACOTTA = "white_terracotta"; //TODO: 1.20.30 flattening
String STAINED_HARDENED_CLAY = "stained_hardened_clay";
String WHITE_STAINED_GLASS_PANE = "white_stained_glass_pane"; //TODO: 1.20.20 flattening
String STAINED_GLASS_PANE = "stained_glass_pane";
+ String ACACIA_LEAVES = "acacia_leaves"; //TODO: 1.20.70 flattening
String LEAVES2 = "leaves2";
String ACACIA_LOG = "acacia_log"; //TODO: 1.19.80 flattening
String LOG2 = "log2";
@@ -207,6 +212,7 @@ public interface BlockNames {
String REPEATING_COMMAND_BLOCK = "repeating_command_block";
String CHAIN_COMMAND_BLOCK = "chain_command_block";
String HARD_GLASS_PANE = "hard_glass_pane";
+ String HARD_WHITE_STAINED_GLASS_PANE = "hard_white_stained_glass_pane"; //TODO: 1.20.60 flattening
String HARD_STAINED_GLASS_PANE = "hard_stained_glass_pane";
String CHEMICAL_HEAT = "chemical_heat";
String SPRUCE_DOOR = "spruce_door";
@@ -276,6 +282,7 @@ public interface BlockNames {
String OBSERVER = "observer";
String STRUCTURE_BLOCK = "structure_block";
String HARD_GLASS = "hard_glass";
+ String HARD_WHITE_STAINED_GLASS = "hard_white_stained_glass"; //TODO: 1.20.60 flattening
String HARD_STAINED_GLASS = "hard_stained_glass";
String RESERVED6 = "reserved6";
@@ -493,6 +500,7 @@ public interface BlockNames {
String CAMPFIRE = "campfire";
String LAVA_CAULDRON = "lava_cauldron"; //TODO: 1.20.0 remove
String JIGSAW = "jigsaw"; //TODO: meta 29
+ String OAK_WOOD = "oak_wood"; //TODO: 1.20.70 flattening
String WOOD = "wood";
String COMPOSTER = "composter";
String LIT_BLAST_FURNACE = "lit_blast_furnace";
@@ -592,7 +600,7 @@ public interface BlockNames {
String COPPER_ORE = "copper_ore";
String LIGHTNING_ROD = "lightning_rod";
String CRAFTER = "crafter";
-
+ String VAULT = "vault";
String TRIAL_SPAWNER = "trial_spawner";
String DRIPSTONE_BLOCK = "dripstone_block";
@@ -928,7 +936,21 @@ public interface BlockNames {
String GREEN_STAINED_GLASS_PANE = "green_stained_glass_pane";
String RED_STAINED_GLASS_PANE = "red_stained_glass_pane";
String BLACK_STAINED_GLASS_PANE = "black_stained_glass_pane";
-
+ String HARD_ORANGE_STAINED_GLASS_PANE = "hard_orange_stained_glass_pane";
+ String HARD_MAGENTA_STAINED_GLASS_PANE = "hard_magenta_stained_glass_pane";
+ String HARD_LIGHT_BLUE_STAINED_GLASS_PANE = "hard_light_blue_stained_glass_pane";
+ String HARD_YELLOW_STAINED_GLASS_PANE = "hard_yellow_stained_glass_pane";
+ String HARD_LIME_STAINED_GLASS_PANE = "hard_lime_stained_glass_pane";
+ String HARD_PINK_STAINED_GLASS_PANE = "hard_pink_stained_glass_pane";
+ String HARD_GRAY_STAINED_GLASS_PANE = "hard_gray_stained_glass_pane";
+ String HARD_LIGHT_GRAY_STAINED_GLASS_PANE = "hard_light_gray_stained_glass_pane";
+ String HARD_CYAN_STAINED_GLASS_PANE = "hard_cyan_stained_glass_pane";
+ String HARD_PURPLE_STAINED_GLASS_PANE = "hard_purple_stained_glass_pane";
+ String HARD_BLUE_STAINED_GLASS_PANE = "hard_blue_stained_glass_pane";
+ String HARD_BROWN_STAINED_GLASS_PANE = "hard_brown_stained_glass_pane";
+ String HARD_GREEN_STAINED_GLASS_PANE = "hard_green_stained_glass_pane";
+ String HARD_RED_STAINED_GLASS_PANE = "hard_red_stained_glass_pane";
+ String HARD_BLACK_STAINED_GLASS_PANE = "hard_black_stained_glass_pane";
String ORANGE_STAINED_GLASS = "orange_stained_glass";
String MAGENTA_STAINED_GLASS = "magenta_stained_glass";
String LIGHT_BLUE_STAINED_GLASS = "light_blue_stained_glass";
@@ -944,6 +966,21 @@ public interface BlockNames {
String GREEN_STAINED_GLASS = "green_stained_glass";
String RED_STAINED_GLASS = "red_stained_glass";
String BLACK_STAINED_GLASS = "black_stained_glass";
+ String HARD_ORANGE_STAINED_GLASS = "hard_orange_stained_glass";
+ String HARD_MAGENTA_STAINED_GLASS = "hard_magenta_stained_glass";
+ String HARD_LIGHT_BLUE_STAINED_GLASS = "hard_light_blue_stained_glass";
+ String HARD_YELLOW_STAINED_GLASS = "hard_yellow_stained_glass";
+ String HARD_LIME_STAINED_GLASS = "hard_lime_stained_glass";
+ String HARD_PINK_STAINED_GLASS = "hard_pink_stained_glass";
+ String HARD_GRAY_STAINED_GLASS = "hard_gray_stained_glass";
+ String HARD_LIGHT_GRAY_STAINED_GLASS = "hard_light_gray_stained_glass";
+ String HARD_CYAN_STAINED_GLASS = "hard_cyan_stained_glass";
+ String HARD_PURPLE_STAINED_GLASS = "hard_purple_stained_glass";
+ String HARD_BLUE_STAINED_GLASS = "hard_blue_stained_glass";
+ String HARD_BROWN_STAINED_GLASS = "hard_brown_stained_glass";
+ String HARD_GREEN_STAINED_GLASS = "hard_green_stained_glass";
+ String HARD_RED_STAINED_GLASS = "hard_red_stained_glass";
+ String HARD_BLACK_STAINED_GLASS = "hard_black_stained_glass";
String ORANGE_CONCRETE_POWDER = "orange_concrete_powder";
String MAGENTA_CONCRETE_POWDER = "magenta_concrete_powder";
@@ -1036,4 +1073,29 @@ public interface BlockNames {
String WAXED_EXPOSED_COPPER_TRAPDOOR = "waxed_exposed_copper_trapdoor";
String WAXED_WEATHERED_COPPER_TRAPDOOR = "waxed_weathered_copper_trapdoor";
String WAXED_OXIDIZED_COPPER_TRAPDOOR = "waxed_oxidized_copper_trapdoor";
+ String SPRUCE_LEAVES = "spruce_leaves";
+ String BIRCH_LEAVES = "birch_leaves";
+ String JUNGLE_LEAVES = "jungle_leaves";
+ String DARK_OAK_LEAVES = "dark_oak_leaves";
+ String SPRUCE_SLAB = "spruce_slab";
+ String BIRCH_SLAB = "birch_slab";
+ String JUNGLE_SLAB = "jungle_slab";
+ String ACACIA_SLAB = "acacia_slab";
+ String DARK_OAK_SLAB = "dark_oak_slab";
+ String SPRUCE_DOUBLE_SLAB = "spruce_double_slab";
+ String BIRCH_DOUBLE_SLAB = "birch_double_slab";
+ String JUNGLE_DOUBLE_SLAB = "jungle_double_slab";
+ String ACACIA_DOUBLE_SLAB = "acacia_double_slab";
+ String DARK_OAK_DOUBLE_SLAB = "dark_oak_double_slab";
+ String SPRUCE_WOOD = "spruce_wood";
+ String BIRCH_WOOD = "birch_wood";
+ String JUNGLE_WOOD = "jungle_wood";
+ String ACACIA_WOOD = "acacia_wood";
+ String DARK_OAK_WOOD = "dark_oak_wood";
+ String STRIPPED_OAK_WOOD = "stripped_oak_wood";
+ String STRIPPED_SPRUCE_WOOD = "stripped_spruce_wood";
+ String STRIPPED_BIRCH_WOOD = "stripped_birch_wood";
+ String STRIPPED_JUNGLE_WOOD = "stripped_jungle_wood";
+ String STRIPPED_ACACIA_WOOD = "stripped_acacia_wood";
+ String STRIPPED_DARK_OAK_WOOD = "stripped_dark_oak_wood";
}
diff --git a/src/main/java/cn/nukkit/block/BlockNetherFungus.java b/src/main/java/cn/nukkit/block/BlockNetherFungus.java
index c3ed13614c0..6127441584e 100644
--- a/src/main/java/cn/nukkit/block/BlockNetherFungus.java
+++ b/src/main/java/cn/nukkit/block/BlockNetherFungus.java
@@ -82,7 +82,7 @@ public void setDamage(int meta) {
protected boolean canSurvive() {
int id = down().getId();
- return id == GRASS || id == DIRT || id == PODZOL || id == MYCELIUM || id == FARMLAND || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK
+ return id == GRASS_BLOCK || id == DIRT || id == PODZOL || id == MYCELIUM || id == FARMLAND || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK
|| id == CRIMSON_NYLIUM || id == WARPED_NYLIUM || id == SOUL_SOIL;
}
diff --git a/src/main/java/cn/nukkit/block/BlockNetherRoots.java b/src/main/java/cn/nukkit/block/BlockNetherRoots.java
index f0360024d78..c6f37f7a436 100644
--- a/src/main/java/cn/nukkit/block/BlockNetherRoots.java
+++ b/src/main/java/cn/nukkit/block/BlockNetherRoots.java
@@ -36,7 +36,7 @@ public boolean onActivate(Item item, BlockFace face, Player player) {
@Override
protected boolean canSurvive() {
int id = down().getId();
- return id == GRASS || id == DIRT || id == FARMLAND || id == PODZOL || id == MYCELIUM || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK
+ return id == GRASS_BLOCK || id == DIRT || id == FARMLAND || id == PODZOL || id == MYCELIUM || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK
|| id == CRIMSON_NYLIUM || id == WARPED_NYLIUM || id == SOUL_SOIL;
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockNetherSprouts.java b/src/main/java/cn/nukkit/block/BlockNetherSprouts.java
index 651ae211ada..7b481ee0ee0 100644
--- a/src/main/java/cn/nukkit/block/BlockNetherSprouts.java
+++ b/src/main/java/cn/nukkit/block/BlockNetherSprouts.java
@@ -96,7 +96,7 @@ public void setDamage(int meta) {
private boolean canSurvive() {
int id = down().getId();
- return id == GRASS || id == DIRT || id == PODZOL || id == MYCELIUM || id == FARMLAND || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK
+ return id == GRASS_BLOCK || id == DIRT || id == PODZOL || id == MYCELIUM || id == FARMLAND || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK
|| id == CRIMSON_NYLIUM || id == WARPED_NYLIUM || id == SOUL_SOIL;
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockNetherVines.java b/src/main/java/cn/nukkit/block/BlockNetherVines.java
index a61d3ed30ee..58061dfeda3 100644
--- a/src/main/java/cn/nukkit/block/BlockNetherVines.java
+++ b/src/main/java/cn/nukkit/block/BlockNetherVines.java
@@ -114,7 +114,7 @@ public int onUpdate(int type) {
@Override
public Item[] getDrops(Item item) {
- if (item.hasEnchantment(Enchantment.SILK_TOUCH) || ThreadLocalRandom.current().nextInt(3) == 0) {
+ if (item.getId() != Item.ENCHANTED_BOOK && item.hasEnchantment(Enchantment.SILK_TOUCH) || ThreadLocalRandom.current().nextInt(3) == 0) {
return new Item[]{
toItem(true),
};
diff --git a/src/main/java/cn/nukkit/block/BlockNylium.java b/src/main/java/cn/nukkit/block/BlockNylium.java
index 3c2d846a733..c4201dacb90 100644
--- a/src/main/java/cn/nukkit/block/BlockNylium.java
+++ b/src/main/java/cn/nukkit/block/BlockNylium.java
@@ -66,7 +66,7 @@ protected void scatterVegetation(Function blockProvider) {
int id = block.getId();
if (id != CRIMSON_NYLIUM && id != WARPED_NYLIUM && id != SOUL_SOIL
- && id != GRASS && id != DIRT && id != PODZOL && id != MYCELIUM && id != FARMLAND && id != DIRT_WITH_ROOTS && id != MOSS_BLOCK) {
+ && id != GRASS_BLOCK && id != DIRT && id != PODZOL && id != MYCELIUM && id != FARMLAND && id != DIRT_WITH_ROOTS && id != MOSS_BLOCK) {
continue;
}
diff --git a/src/main/java/cn/nukkit/block/BlockRespawnAnchor.java b/src/main/java/cn/nukkit/block/BlockRespawnAnchor.java
index db655f72241..eff474ee125 100644
--- a/src/main/java/cn/nukkit/block/BlockRespawnAnchor.java
+++ b/src/main/java/cn/nukkit/block/BlockRespawnAnchor.java
@@ -3,7 +3,6 @@
import cn.nukkit.Player;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemTool;
-import cn.nukkit.item.enchantment.Enchantment;
import cn.nukkit.level.Dimension;
import cn.nukkit.level.Explosion;
import cn.nukkit.level.GameRule;
@@ -62,7 +61,7 @@ public boolean canHarvestWithHand() {
public Item[] getDrops(Item item) {
if (item.isPickaxe() && item.getTier() >= ItemTool.TIER_DIAMOND) {
return new Item[]{
- Item.get(getItemId(), item.hasEnchantment(Enchantment.SILK_TOUCH) ? getDamage() : 0),
+ Item.get(getItemId()),
};
}
return new Item[0];
diff --git a/src/main/java/cn/nukkit/block/BlockSapling.java b/src/main/java/cn/nukkit/block/BlockSapling.java
index 5c91b2e07a3..b910d5448f2 100644
--- a/src/main/java/cn/nukkit/block/BlockSapling.java
+++ b/src/main/java/cn/nukkit/block/BlockSapling.java
@@ -223,6 +223,6 @@ public boolean isSapling() {
private boolean canSurvive() {
int id = down().getId();
- return id == Block.GRASS || id == Block.DIRT || id == Block.FARMLAND || id == Block.PODZOL || id == MYCELIUM || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK;
+ return id == Block.GRASS_BLOCK || id == Block.DIRT || id == Block.FARMLAND || id == Block.PODZOL || id == MYCELIUM || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK;
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockStem.java b/src/main/java/cn/nukkit/block/BlockStem.java
index 79008a31e9c..cb54bf53bc6 100644
--- a/src/main/java/cn/nukkit/block/BlockStem.java
+++ b/src/main/java/cn/nukkit/block/BlockStem.java
@@ -60,7 +60,7 @@ public int onUpdate(int type) {
}
int below = block.down().getId();
- if (below == FARMLAND || below == GRASS || below == DIRT) {
+ if (below == FARMLAND || below == GRASS_BLOCK || below == DIRT) {
BlockGrowEvent ev = new BlockGrowEvent(block, get(fruit));
Server.getInstance().getPluginManager().callEvent(ev);
if (!ev.isCancelled()) {
diff --git a/src/main/java/cn/nukkit/block/BlockSugarcane.java b/src/main/java/cn/nukkit/block/BlockSugarcane.java
index ac3c57ff4f6..b8a91e1bc45 100644
--- a/src/main/java/cn/nukkit/block/BlockSugarcane.java
+++ b/src/main/java/cn/nukkit/block/BlockSugarcane.java
@@ -167,6 +167,6 @@ public boolean isVegetation() {
}
private boolean canSurvive(int id) {
- return id == GRASS || id == DIRT || id == SAND || id == PODZOL || id == MYCELIUM || id == DIRT_WITH_ROOTS;
+ return id == GRASS_BLOCK || id == DIRT || id == SAND || id == PODZOL || id == MYCELIUM || id == DIRT_WITH_ROOTS;
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockSweetBerryBush.java b/src/main/java/cn/nukkit/block/BlockSweetBerryBush.java
index 87a0e2c0dc0..277c5fa07f5 100644
--- a/src/main/java/cn/nukkit/block/BlockSweetBerryBush.java
+++ b/src/main/java/cn/nukkit/block/BlockSweetBerryBush.java
@@ -195,7 +195,7 @@ public void onEntityCollide(Entity entity) {
private boolean canSurvive() {
int below = down().getId();
- return below == Block.GRASS || below == Block.DIRT || below == Block.PODZOL || below == MYCELIUM || below == DIRT_WITH_ROOTS || below == MOSS_BLOCK || below == FARMLAND;
+ return below == Block.GRASS_BLOCK || below == Block.DIRT || below == Block.PODZOL || below == MYCELIUM || below == DIRT_WITH_ROOTS || below == MOSS_BLOCK || below == FARMLAND;
}
private int getBerryDropAmount(int meta) {
diff --git a/src/main/java/cn/nukkit/block/BlockTallGrass.java b/src/main/java/cn/nukkit/block/BlockTallGrass.java
index d70369abfdb..63ac0f95f4b 100644
--- a/src/main/java/cn/nukkit/block/BlockTallGrass.java
+++ b/src/main/java/cn/nukkit/block/BlockTallGrass.java
@@ -187,6 +187,6 @@ public boolean isVegetation() {
private boolean canSurvive() {
int id = down().getId();
- return id == Block.GRASS || id == Block.DIRT || id == Block.PODZOL || id == FARMLAND || id == MYCELIUM || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK;
+ return id == Block.GRASS_BLOCK || id == Block.DIRT || id == Block.PODZOL || id == FARMLAND || id == MYCELIUM || id == DIRT_WITH_ROOTS || id == MOSS_BLOCK;
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockWitherRose.java b/src/main/java/cn/nukkit/block/BlockWitherRose.java
index de078a463cf..877c618cb5f 100644
--- a/src/main/java/cn/nukkit/block/BlockWitherRose.java
+++ b/src/main/java/cn/nukkit/block/BlockWitherRose.java
@@ -1,5 +1,6 @@
package cn.nukkit.block;
+import cn.nukkit.Difficulty;
import cn.nukkit.Player;
import cn.nukkit.entity.Entity;
import cn.nukkit.entity.EntityLiving;
@@ -57,11 +58,14 @@ public boolean hasEntityCollision() {
@Override
public void onEntityCollide(Entity entity) {
+ if (entity.getServer().getDifficulty() == Difficulty.PEACEFUL.ordinal()) {
+ return;
+ }
if (!(entity instanceof EntityLiving) || entity instanceof Player && ((Player) entity).isCreative()) {
return;
}
Effect wither = entity.getEffect(Effect.WITHER);
- if (wither != null && wither.getDuration() > 1) {
+ if (wither != null && wither.getDuration() > 30) {
return;
}
entity.addEffect(Effect.getEffect(Effect.WITHER).setDuration(40 + 1));
diff --git a/src/main/java/cn/nukkit/block/Blocks.java b/src/main/java/cn/nukkit/block/Blocks.java
index 4d293f41c4e..70ef6c424fe 100644
--- a/src/main/java/cn/nukkit/block/Blocks.java
+++ b/src/main/java/cn/nukkit/block/Blocks.java
@@ -52,7 +52,7 @@ public final class Blocks {
public static void registerVanillaBlocks() {
registerBlock(BlockNames.AIR, ItemBlockNames.AIR, BlockID.AIR, BlockAir.class);
registerBlock(BlockNames.STONE, ItemBlockNames.STONE, STONE, BlockStone.class);
- registerBlock(BlockNames.GRASS, ItemBlockNames.GRASS, GRASS, BlockGrass.class);
+ registerBlock(BlockNames.GRASS, ItemBlockNames.GRASS, GRASS_BLOCK, BlockGrass.class);
registerBlock(BlockNames.DIRT, ItemBlockNames.DIRT, DIRT, BlockDirt.class);
registerBlock(BlockNames.COBBLESTONE, ItemBlockNames.COBBLESTONE, COBBLESTONE, BlockCobblestone.class);
registerBlock(BlockNames.PLANKS, ItemBlockNames.PLANKS, PLANKS, BlockPlanks.class);
@@ -833,6 +833,8 @@ private static void registerBlockAliases() {
registerBlockAlias(BlockNames.DOUBLE_STONE_BLOCK_SLAB2, BlockNames.DOUBLE_STONE_SLAB, V1_19_0);
registerBlockAlias(BlockNames.DOUBLE_STONE_BLOCK_SLAB3, BlockNames.DOUBLE_STONE_SLAB, V1_19_0);
registerBlockAlias(BlockNames.DOUBLE_STONE_BLOCK_SLAB4, BlockNames.DOUBLE_STONE_SLAB, V1_19_0);
+
+// registerBlockAlias(BlockNames.GRASS_BLOCK, BlockNames.GRASS, V1_20_70);
}
@SuppressWarnings("deprecation")
@@ -870,6 +872,8 @@ private static void registerItemAliases() {
registerItemAlias(ItemBlockNames.DOUBLE_STONE_BLOCK_SLAB2, ItemBlockNames.REAL_DOUBLE_STONE_SLAB, V1_19_0);
registerItemAlias(ItemBlockNames.DOUBLE_STONE_BLOCK_SLAB3, ItemBlockNames.REAL_DOUBLE_STONE_SLAB, V1_19_0);
registerItemAlias(ItemBlockNames.DOUBLE_STONE_BLOCK_SLAB4, ItemBlockNames.REAL_DOUBLE_STONE_SLAB, V1_19_0);
+
+// registerItemAlias(ItemBlockNames.GRASS_BLOCK, ItemBlockNames.GRASS, V1_20_70);
}
private static void registerComplexAliases() {
@@ -1049,6 +1053,77 @@ private static void registerComplexAliases() {
registerComplexAlias(ItemBlockNames.JUNGLE_PLANKS, PLANKS, BlockPlanks.JUNGLE, V1_20_50);
registerComplexAlias(ItemBlockNames.ACACIA_PLANKS, PLANKS, BlockPlanks.ACACIA, V1_20_50);
registerComplexAlias(ItemBlockNames.DARK_OAK_PLANKS, PLANKS, BlockPlanks.DARK_OAK, V1_20_50);
+
+ registerComplexAlias(ItemBlockNames.HARD_WHITE_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.WHITE.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_ORANGE_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.ORANGE.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_MAGENTA_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.MAGENTA.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_LIGHT_BLUE_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.LIGHT_BLUE.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_YELLOW_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.YELLOW.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_LIME_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.LIME.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_PINK_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.PINK.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_GRAY_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.GRAY.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_LIGHT_GRAY_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.LIGHT_GRAY.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_CYAN_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.CYAN.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_PURPLE_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.PURPLE.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_BLUE_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.BLUE.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_BROWN_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.BROWN.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_GREEN_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.GREEN.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_RED_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.RED.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_BLACK_STAINED_GLASS, HARD_STAINED_GLASS, DyeColor.BLACK.getWoolData(), V1_20_60);
+
+ registerComplexAlias(ItemBlockNames.HARD_WHITE_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.WHITE.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_ORANGE_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.ORANGE.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_MAGENTA_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.MAGENTA.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_LIGHT_BLUE_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.LIGHT_BLUE.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_YELLOW_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.YELLOW.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_LIME_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.LIME.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_PINK_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.PINK.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_GRAY_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.GRAY.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_LIGHT_GRAY_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.LIGHT_GRAY.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_CYAN_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.CYAN.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_PURPLE_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.PURPLE.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_BLUE_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.BLUE.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_BROWN_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.BROWN.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_GREEN_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.GREEN.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_RED_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.RED.getWoolData(), V1_20_60);
+ registerComplexAlias(ItemBlockNames.HARD_BLACK_STAINED_GLASS_PANE, HARD_STAINED_GLASS_PANE, DyeColor.BLACK.getWoolData(), V1_20_60);
+/*
+ registerComplexAlias(ItemBlockNames.OAK_LEAVES, LEAVES, BlockLeaves.OAK, V1_20_70);
+ registerComplexAlias(ItemBlockNames.SPRUCE_LEAVES, LEAVES, BlockLeaves.SPRUCE, V1_20_70);
+ registerComplexAlias(ItemBlockNames.BIRCH_LEAVES, LEAVES, BlockLeaves.BIRCH, V1_20_70);
+ registerComplexAlias(ItemBlockNames.JUNGLE_LEAVES, LEAVES, BlockLeaves.JUNGLE, V1_20_70);
+
+ registerComplexAlias(ItemBlockNames.ACACIA_LEAVES, LEAVES2, BlockLeaves2.ACACIA, V1_20_70);
+ registerComplexAlias(ItemBlockNames.DARK_OAK_LEAVES, LEAVES2, BlockLeaves2.DARK_OAK, V1_20_70);
+
+ registerComplexAlias(ItemBlockNames.OAK_SLAB, WOODEN_SLAB, BlockSlabWood.OAK, V1_20_70);
+ registerComplexAlias(ItemBlockNames.SPRUCE_SLAB, WOODEN_SLAB, BlockSlabWood.SPRUCE, V1_20_70);
+ registerComplexAlias(ItemBlockNames.BIRCH_SLAB, WOODEN_SLAB, BlockSlabWood.BIRCH, V1_20_70);
+ registerComplexAlias(ItemBlockNames.JUNGLE_SLAB, WOODEN_SLAB, BlockSlabWood.JUNGLE, V1_20_70);
+ registerComplexAlias(ItemBlockNames.ACACIA_SLAB, WOODEN_SLAB, BlockSlabWood.ACACIA, V1_20_70);
+ registerComplexAlias(ItemBlockNames.DARK_OAK_SLAB, WOODEN_SLAB, BlockSlabWood.DARK_OAK, V1_20_70);
+
+ registerComplexAlias(ItemBlockNames.OAK_DOUBLE_SLAB, DOUBLE_WOODEN_SLAB, BlockDoubleSlabWood.OAK, V1_20_70);
+ registerComplexAlias(ItemBlockNames.SPRUCE_DOUBLE_SLAB, DOUBLE_WOODEN_SLAB, BlockDoubleSlabWood.SPRUCE, V1_20_70);
+ registerComplexAlias(ItemBlockNames.BIRCH_DOUBLE_SLAB, DOUBLE_WOODEN_SLAB, BlockDoubleSlabWood.BIRCH, V1_20_70);
+ registerComplexAlias(ItemBlockNames.JUNGLE_DOUBLE_SLAB, DOUBLE_WOODEN_SLAB, BlockDoubleSlabWood.JUNGLE, V1_20_70);
+ registerComplexAlias(ItemBlockNames.ACACIA_DOUBLE_SLAB, DOUBLE_WOODEN_SLAB, BlockDoubleSlabWood.ACACIA, V1_20_70);
+ registerComplexAlias(ItemBlockNames.DARK_OAK_DOUBLE_SLAB, DOUBLE_WOODEN_SLAB, BlockDoubleSlabWood.DARK_OAK, V1_20_70);
+
+ registerComplexAlias(ItemBlockNames.OAK_WOOD, WOOD, BlockWoodBark.OAK, V1_20_70);
+ registerComplexAlias(ItemBlockNames.SPRUCE_WOOD, WOOD, BlockWoodBark.SPRUCE, V1_20_70);
+ registerComplexAlias(ItemBlockNames.BIRCH_WOOD, WOOD, BlockWoodBark.BIRCH, V1_20_70);
+ registerComplexAlias(ItemBlockNames.JUNGLE_WOOD, WOOD, BlockWoodBark.JUNGLE, V1_20_70);
+ registerComplexAlias(ItemBlockNames.ACACIA_WOOD, WOOD, BlockWoodBark.ACACIA, V1_20_70);
+ registerComplexAlias(ItemBlockNames.DARK_OAK_WOOD, WOOD, BlockWoodBark.DARK_OAK, V1_20_70);
+
+ registerComplexAlias(ItemBlockNames.STRIPPED_OAK_WOOD, WOOD, BlockWoodBark.STRIPPED_BIT | BlockWoodBark.OAK, V1_20_70);
+ registerComplexAlias(ItemBlockNames.STRIPPED_SPRUCE_WOOD, WOOD, BlockWoodBark.STRIPPED_BIT | BlockWoodBark.SPRUCE, V1_20_70);
+ registerComplexAlias(ItemBlockNames.STRIPPED_BIRCH_WOOD, WOOD, BlockWoodBark.STRIPPED_BIT | BlockWoodBark.BIRCH, V1_20_70);
+ registerComplexAlias(ItemBlockNames.STRIPPED_JUNGLE_WOOD, WOOD, BlockWoodBark.STRIPPED_BIT | BlockWoodBark.JUNGLE, V1_20_70);
+ registerComplexAlias(ItemBlockNames.STRIPPED_ACACIA_WOOD, WOOD, BlockWoodBark.STRIPPED_BIT | BlockWoodBark.ACACIA, V1_20_70);
+ registerComplexAlias(ItemBlockNames.STRIPPED_DARK_OAK_WOOD, WOOD, BlockWoodBark.STRIPPED_BIT | BlockWoodBark.DARK_OAK, V1_20_70);
+*/
}
private static Class extends Block> registerBlock(String blockName, String itemName, int id, Class extends Block> clazz) {
@@ -1138,6 +1213,9 @@ public static Class extends Block> registerCustomBlock(String fullName, int id
return clazz;
}
+ /**
+ * @param version min required base game version
+ */
private static void registerBlockAlias(String newName, String oldName, GameVersion version) {
if (version.isAvailable()) {
String name = newName;
@@ -1147,6 +1225,9 @@ private static void registerBlockAlias(String newName, String oldName, GameVersi
BLOCK_ALIASES_MAP.put(newName, oldName);
}
+ /**
+ * @param version min required base game version
+ */
private static void registerItemAlias(String newName, String oldName, GameVersion version) {
if (version.isAvailable()) {
String name = newName;
diff --git a/src/main/java/cn/nukkit/entity/Entities.java b/src/main/java/cn/nukkit/entity/Entities.java
index eb43e5790b2..1e7e64b76ae 100644
--- a/src/main/java/cn/nukkit/entity/Entities.java
+++ b/src/main/java/cn/nukkit/entity/Entities.java
@@ -166,6 +166,7 @@ public static void registerVanillaEntities() {
registerEntity(EntityID.SNIFFER, EntityNames.SNIFFER, "Sniffer", EntitySniffer.class, EntitySniffer::new, V1_20_0);
// registerEntity(EntityID.BREEZE, EntityNames.BREEZE, "Breeze", EntityBreeze.class, EntityBreeze::new, V1_21_0);
+// registerEntity(EntityID.WIND_CHARGE_PROJECTILE, EntityNames.WIND_CHARGE_PROJECTILE, "WindCharge", EntityWindCharge.class, EntityWindCharge::new, V1_21_0);
// registerEntity(EntityID.ARMADILLO, EntityNames.ARMADILLO, "Armadillo", EntityArmadillo.class, EntityArmadillo::new, V1_21_0);
}
diff --git a/src/main/java/cn/nukkit/entity/EntityFullNames.java b/src/main/java/cn/nukkit/entity/EntityFullNames.java
index d573c30ea68..bf2c6e7e36c 100644
--- a/src/main/java/cn/nukkit/entity/EntityFullNames.java
+++ b/src/main/java/cn/nukkit/entity/EntityFullNames.java
@@ -132,7 +132,7 @@ public interface EntityFullNames {
String CAMEL = "minecraft:" + EntityNames.CAMEL;
String SNIFFER = "minecraft:" + EntityNames.SNIFFER;
String BREEZE = "minecraft:" + EntityNames.BREEZE;
-
+ String WIND_CHARGE_PROJECTILE = "minecraft:" + EntityNames.WIND_CHARGE_PROJECTILE;
String ARMADILLO = "minecraft:" + EntityNames.ARMADILLO;
String TRADER_LLAMA = "minecraft:" + EntityNames.TRADER_LLAMA;
diff --git a/src/main/java/cn/nukkit/entity/EntityID.java b/src/main/java/cn/nukkit/entity/EntityID.java
index e643a6d8587..21faf508d78 100644
--- a/src/main/java/cn/nukkit/entity/EntityID.java
+++ b/src/main/java/cn/nukkit/entity/EntityID.java
@@ -131,7 +131,7 @@ public interface EntityID {
int CAMEL = 138;
int SNIFFER = 139;
int BREEZE = 140;
-
+ int WIND_CHARGE_PROJECTILE = 141;
int ARMADILLO = 142;
int TRADER_LLAMA = 157;
diff --git a/src/main/java/cn/nukkit/entity/EntityNames.java b/src/main/java/cn/nukkit/entity/EntityNames.java
index 1583051239c..e643a4d07cb 100644
--- a/src/main/java/cn/nukkit/entity/EntityNames.java
+++ b/src/main/java/cn/nukkit/entity/EntityNames.java
@@ -131,7 +131,7 @@ public interface EntityNames {
String CAMEL = "camel";
String SNIFFER = "sniffer";
String BREEZE = "breeze";
-
+ String WIND_CHARGE_PROJECTILE = "wind_charge_projectile";
String ARMADILLO = "armadillo";
String TRADER_LLAMA = "trader_llama";
diff --git a/src/main/java/cn/nukkit/entity/EntityRideable.java b/src/main/java/cn/nukkit/entity/EntityRideable.java
index 67981f54eec..3aa2c8f753d 100644
--- a/src/main/java/cn/nukkit/entity/EntityRideable.java
+++ b/src/main/java/cn/nukkit/entity/EntityRideable.java
@@ -1,7 +1,6 @@
package cn.nukkit.entity;
import cn.nukkit.Player;
-import cn.nukkit.math.Vector3;
/**
* author: MagicDroidX
@@ -19,10 +18,6 @@ public interface EntityRideable {
boolean dismountEntity(Entity entity);
- default void onPlayerRiding(Vector3 pos, double yaw, double pitch) {
- // Do nothing by default
- }
-
default void onPlayerInput(Player player, double motionX, double motionY) {
// Do nothing by default
}
diff --git a/src/main/java/cn/nukkit/entity/item/EntityBoat.java b/src/main/java/cn/nukkit/entity/item/EntityBoat.java
index a68f8421dc5..1a1c053fce5 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityBoat.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityBoat.java
@@ -479,7 +479,7 @@ public void saveNBT() {
}
public void onInput(double x, double y, double z, double rotation) {
- this.setPositionAndRotation(this.temporalVector.setComponents(x, y - this.getBaseOffset(), z), rotation % 360, 0);
+ this.setPositionAndRotation(this.temporalVector.setComponents(x, y - this.getBaseOffset(), z), rotation, 0);
}
@Override
diff --git a/src/main/java/cn/nukkit/event/entity/EntityDamageByEntityEvent.java b/src/main/java/cn/nukkit/event/entity/EntityDamageByEntityEvent.java
index eb755164edb..29472e6bacd 100644
--- a/src/main/java/cn/nukkit/event/entity/EntityDamageByEntityEvent.java
+++ b/src/main/java/cn/nukkit/event/entity/EntityDamageByEntityEvent.java
@@ -39,7 +39,7 @@ public EntityDamageByEntityEvent(Entity damager, Entity entity, DamageCause caus
}
public EntityDamageByEntityEvent(Entity damager, Entity entity, DamageCause cause, Map modifiers, float knockBackH, float knockBackV) {
- this(damager, entity, cause, modifiers, knockBackH, knockBackV, new Enchantment[0]);
+ this(damager, entity, cause, modifiers, knockBackH, knockBackV, Enchantment.EMPTY);
}
public EntityDamageByEntityEvent(Entity damager, Entity entity, DamageCause cause, Map modifiers, float knockBackH, float knockBackV, Enchantment[] enchantments) {
diff --git a/src/main/java/cn/nukkit/item/ItemBlockFullNames.java b/src/main/java/cn/nukkit/item/ItemBlockFullNames.java
index 1c8becad7d3..16d6eed2a3b 100644
--- a/src/main/java/cn/nukkit/item/ItemBlockFullNames.java
+++ b/src/main/java/cn/nukkit/item/ItemBlockFullNames.java
@@ -3,6 +3,7 @@
// This file is generated automatically, do not edit it manually.
public interface ItemBlockFullNames {
String STONE = "minecraft:" + ItemBlockNames.STONE;
+ String GRASS_BLOCK = "minecraft:" + ItemBlockNames.GRASS_BLOCK;
String GRASS = "minecraft:" + ItemBlockNames.GRASS;
String DIRT = "minecraft:" + ItemBlockNames.DIRT;
String COBBLESTONE = "minecraft:" + ItemBlockNames.COBBLESTONE;
@@ -21,6 +22,7 @@ public interface ItemBlockFullNames {
String COAL_ORE = "minecraft:" + ItemBlockNames.COAL_ORE;
String OAK_LOG = "minecraft:" + ItemBlockNames.OAK_LOG; //TODO: 1.19.80 flattening
String LOG = "minecraft:" + ItemBlockNames.LOG;
+ String OAK_LEAVES = "minecraft:" + ItemBlockNames.OAK_LEAVES;
String LEAVES = "minecraft:" + ItemBlockNames.LEAVES;
String SPONGE = "minecraft:" + ItemBlockNames.SPONGE;
String GLASS = "minecraft:" + ItemBlockNames.GLASS;
@@ -168,12 +170,15 @@ public interface ItemBlockFullNames {
String ITEM_HOPPER = "minecraft:" + ItemBlockNames.ITEM_HOPPER;
String QUARTZ_BLOCK = "minecraft:" + ItemBlockNames.QUARTZ_BLOCK;
String QUARTZ_STAIRS = "minecraft:" + ItemBlockNames.QUARTZ_STAIRS;
+ String OAK_DOUBLE_SLAB = "minecraft:" + ItemBlockNames.OAK_DOUBLE_SLAB; //TODO: 1.20.70 flattening
String DOUBLE_WOODEN_SLAB = "minecraft:" + ItemBlockNames.DOUBLE_WOODEN_SLAB;
+ String OAK_SLAB = "minecraft:" + ItemBlockNames.OAK_SLAB; //TODO: 1.20.70 flattening
String WOODEN_SLAB = "minecraft:" + ItemBlockNames.WOODEN_SLAB;
String WHITE_TERRACOTTA = "minecraft:" + ItemBlockNames.WHITE_TERRACOTTA; //TODO: 1.20.30 flattening
String STAINED_HARDENED_CLAY = "minecraft:" + ItemBlockNames.STAINED_HARDENED_CLAY;
String WHITE_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.WHITE_STAINED_GLASS_PANE; //TODO: 1.20.20 flattening
String STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.STAINED_GLASS_PANE;
+ String ACACIA_LEAVES = "minecraft:" + ItemBlockNames.ACACIA_LEAVES; //TODO: 1.20.70 flattening
String LEAVES2 = "minecraft:" + ItemBlockNames.LEAVES2;
String ACACIA_LOG = "minecraft:" + ItemBlockNames.ACACIA_LOG; //TODO: 1.19.80 flattening
String LOG2 = "minecraft:" + ItemBlockNames.LOG2;
@@ -209,6 +214,7 @@ public interface ItemBlockFullNames {
String REPEATING_COMMAND_BLOCK = "minecraft:" + ItemBlockNames.REPEATING_COMMAND_BLOCK;
String CHAIN_COMMAND_BLOCK = "minecraft:" + ItemBlockNames.CHAIN_COMMAND_BLOCK;
String HARD_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_GLASS_PANE;
+ String HARD_WHITE_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_WHITE_STAINED_GLASS_PANE; //TODO: 1.20.60 flattening
String HARD_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_STAINED_GLASS_PANE;
String CHEMICAL_HEAT = "minecraft:" + ItemBlockNames.CHEMICAL_HEAT;
String ITEM_SPRUCE_DOOR = "minecraft:" + ItemBlockNames.ITEM_SPRUCE_DOOR;
@@ -357,6 +363,7 @@ public interface ItemBlockFullNames {
String OBSERVER = "minecraft:" + ItemBlockNames.OBSERVER;
String STRUCTURE_BLOCK = "minecraft:" + ItemBlockNames.STRUCTURE_BLOCK;
String HARD_GLASS = "minecraft:" + ItemBlockNames.HARD_GLASS;
+ String HARD_WHITE_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_WHITE_STAINED_GLASS; //TODO: 1.20.60 flattening
String HARD_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_STAINED_GLASS;
String RESERVED6 = "minecraft:" + ItemBlockNames.RESERVED6;
@@ -574,6 +581,7 @@ public interface ItemBlockFullNames {
String ITEM_CAMPFIRE = "minecraft:" + ItemBlockNames.ITEM_CAMPFIRE;
String LAVA_CAULDRON = "minecraft:" + ItemBlockNames.LAVA_CAULDRON; //TODO: 1.20.0 remove
String JIGSAW = "minecraft:" + ItemBlockNames.JIGSAW; //TODO: meta 29
+ String OAK_WOOD = "minecraft:" + ItemBlockNames.OAK_WOOD; //TODO: 1.20.70 flattening
String WOOD = "minecraft:" + ItemBlockNames.WOOD;
String COMPOSTER = "minecraft:" + ItemBlockNames.COMPOSTER;
String LIT_BLAST_FURNACE = "minecraft:" + ItemBlockNames.LIT_BLAST_FURNACE;
@@ -673,7 +681,7 @@ public interface ItemBlockFullNames {
String COPPER_ORE = "minecraft:" + ItemBlockNames.COPPER_ORE;
String LIGHTNING_ROD = "minecraft:" + ItemBlockNames.LIGHTNING_ROD;
String CRAFTER = "minecraft:" + ItemBlockNames.CRAFTER;
-
+ String VAULT = "minecraft:" + ItemBlockNames.VAULT;
String TRIAL_SPAWNER = "minecraft:" + ItemBlockNames.TRIAL_SPAWNER;
String DRIPSTONE_BLOCK = "minecraft:" + ItemBlockNames.DRIPSTONE_BLOCK;
@@ -1009,7 +1017,21 @@ public interface ItemBlockFullNames {
String GREEN_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.GREEN_STAINED_GLASS_PANE;
String RED_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.RED_STAINED_GLASS_PANE;
String BLACK_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.BLACK_STAINED_GLASS_PANE;
-
+ String HARD_ORANGE_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_ORANGE_STAINED_GLASS_PANE;
+ String HARD_MAGENTA_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_MAGENTA_STAINED_GLASS_PANE;
+ String HARD_LIGHT_BLUE_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_LIGHT_BLUE_STAINED_GLASS_PANE;
+ String HARD_YELLOW_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_YELLOW_STAINED_GLASS_PANE;
+ String HARD_LIME_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_LIME_STAINED_GLASS_PANE;
+ String HARD_PINK_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_PINK_STAINED_GLASS_PANE;
+ String HARD_GRAY_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_GRAY_STAINED_GLASS_PANE;
+ String HARD_LIGHT_GRAY_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_LIGHT_GRAY_STAINED_GLASS_PANE;
+ String HARD_CYAN_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_CYAN_STAINED_GLASS_PANE;
+ String HARD_PURPLE_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_PURPLE_STAINED_GLASS_PANE;
+ String HARD_BLUE_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_BLUE_STAINED_GLASS_PANE;
+ String HARD_BROWN_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_BROWN_STAINED_GLASS_PANE;
+ String HARD_GREEN_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_GREEN_STAINED_GLASS_PANE;
+ String HARD_RED_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_RED_STAINED_GLASS_PANE;
+ String HARD_BLACK_STAINED_GLASS_PANE = "minecraft:" + ItemBlockNames.HARD_BLACK_STAINED_GLASS_PANE;
String ORANGE_STAINED_GLASS = "minecraft:" + ItemBlockNames.ORANGE_STAINED_GLASS;
String MAGENTA_STAINED_GLASS = "minecraft:" + ItemBlockNames.MAGENTA_STAINED_GLASS;
String LIGHT_BLUE_STAINED_GLASS = "minecraft:" + ItemBlockNames.LIGHT_BLUE_STAINED_GLASS;
@@ -1025,6 +1047,21 @@ public interface ItemBlockFullNames {
String GREEN_STAINED_GLASS = "minecraft:" + ItemBlockNames.GREEN_STAINED_GLASS;
String RED_STAINED_GLASS = "minecraft:" + ItemBlockNames.RED_STAINED_GLASS;
String BLACK_STAINED_GLASS = "minecraft:" + ItemBlockNames.BLACK_STAINED_GLASS;
+ String HARD_ORANGE_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_ORANGE_STAINED_GLASS;
+ String HARD_MAGENTA_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_MAGENTA_STAINED_GLASS;
+ String HARD_LIGHT_BLUE_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_LIGHT_BLUE_STAINED_GLASS;
+ String HARD_YELLOW_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_YELLOW_STAINED_GLASS;
+ String HARD_LIME_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_LIME_STAINED_GLASS;
+ String HARD_PINK_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_PINK_STAINED_GLASS;
+ String HARD_GRAY_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_GRAY_STAINED_GLASS;
+ String HARD_LIGHT_GRAY_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_LIGHT_GRAY_STAINED_GLASS;
+ String HARD_CYAN_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_CYAN_STAINED_GLASS;
+ String HARD_PURPLE_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_PURPLE_STAINED_GLASS;
+ String HARD_BLUE_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_BLUE_STAINED_GLASS;
+ String HARD_BROWN_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_BROWN_STAINED_GLASS;
+ String HARD_GREEN_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_GREEN_STAINED_GLASS;
+ String HARD_RED_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_RED_STAINED_GLASS;
+ String HARD_BLACK_STAINED_GLASS = "minecraft:" + ItemBlockNames.HARD_BLACK_STAINED_GLASS;
String ORANGE_CONCRETE_POWDER = "minecraft:" + ItemBlockNames.ORANGE_CONCRETE_POWDER;
String MAGENTA_CONCRETE_POWDER = "minecraft:" + ItemBlockNames.MAGENTA_CONCRETE_POWDER;
@@ -1117,4 +1154,29 @@ public interface ItemBlockFullNames {
String WAXED_EXPOSED_COPPER_TRAPDOOR = "minecraft:" + ItemBlockNames.WAXED_EXPOSED_COPPER_TRAPDOOR;
String WAXED_WEATHERED_COPPER_TRAPDOOR = "minecraft:" + ItemBlockNames.WAXED_WEATHERED_COPPER_TRAPDOOR;
String WAXED_OXIDIZED_COPPER_TRAPDOOR = "minecraft:" + ItemBlockNames.WAXED_OXIDIZED_COPPER_TRAPDOOR;
+ String SPRUCE_LEAVES = "minecraft:" + ItemBlockNames.SPRUCE_LEAVES;
+ String BIRCH_LEAVES = "minecraft:" + ItemBlockNames.BIRCH_LEAVES;
+ String JUNGLE_LEAVES = "minecraft:" + ItemBlockNames.JUNGLE_LEAVES;
+ String DARK_OAK_LEAVES = "minecraft:" + ItemBlockNames.DARK_OAK_LEAVES;
+ String SPRUCE_SLAB = "minecraft:" + ItemBlockNames.SPRUCE_SLAB;
+ String BIRCH_SLAB = "minecraft:" + ItemBlockNames.BIRCH_SLAB;
+ String JUNGLE_SLAB = "minecraft:" + ItemBlockNames.JUNGLE_SLAB;
+ String ACACIA_SLAB = "minecraft:" + ItemBlockNames.ACACIA_SLAB;
+ String DARK_OAK_SLAB = "minecraft:" + ItemBlockNames.DARK_OAK_SLAB;
+ String SPRUCE_DOUBLE_SLAB = "minecraft:" + ItemBlockNames.SPRUCE_DOUBLE_SLAB;
+ String BIRCH_DOUBLE_SLAB = "minecraft:" + ItemBlockNames.BIRCH_DOUBLE_SLAB;
+ String JUNGLE_DOUBLE_SLAB = "minecraft:" + ItemBlockNames.JUNGLE_DOUBLE_SLAB;
+ String ACACIA_DOUBLE_SLAB = "minecraft:" + ItemBlockNames.ACACIA_DOUBLE_SLAB;
+ String DARK_OAK_DOUBLE_SLAB = "minecraft:" + ItemBlockNames.DARK_OAK_DOUBLE_SLAB;
+ String SPRUCE_WOOD = "minecraft:" + ItemBlockNames.SPRUCE_WOOD;
+ String BIRCH_WOOD = "minecraft:" + ItemBlockNames.BIRCH_WOOD;
+ String JUNGLE_WOOD = "minecraft:" + ItemBlockNames.JUNGLE_WOOD;
+ String ACACIA_WOOD = "minecraft:" + ItemBlockNames.ACACIA_WOOD;
+ String DARK_OAK_WOOD = "minecraft:" + ItemBlockNames.DARK_OAK_WOOD;
+ String STRIPPED_OAK_WOOD = "minecraft:" + ItemBlockNames.STRIPPED_OAK_WOOD;
+ String STRIPPED_SPRUCE_WOOD = "minecraft:" + ItemBlockNames.STRIPPED_SPRUCE_WOOD;
+ String STRIPPED_BIRCH_WOOD = "minecraft:" + ItemBlockNames.STRIPPED_BIRCH_WOOD;
+ String STRIPPED_JUNGLE_WOOD = "minecraft:" + ItemBlockNames.STRIPPED_JUNGLE_WOOD;
+ String STRIPPED_ACACIA_WOOD = "minecraft:" + ItemBlockNames.STRIPPED_ACACIA_WOOD;
+ String STRIPPED_DARK_OAK_WOOD = "minecraft:" + ItemBlockNames.STRIPPED_DARK_OAK_WOOD;
}
diff --git a/src/main/java/cn/nukkit/item/ItemBlockID.java b/src/main/java/cn/nukkit/item/ItemBlockID.java
index 8196a24d9a4..5375f32cdad 100644
--- a/src/main/java/cn/nukkit/item/ItemBlockID.java
+++ b/src/main/java/cn/nukkit/item/ItemBlockID.java
@@ -6,6 +6,11 @@
public interface ItemBlockID {
int AIR = 0;
int STONE = 1;
+ int GRASS_BLOCK = 2;
+ /**
+ * @deprecated use {@link #GRASS_BLOCK} instead
+ */
+ @Deprecated
int GRASS = 2;
int DIRT = 3;
int COBBLESTONE = 4;
@@ -24,6 +29,7 @@ public interface ItemBlockID {
int COAL_ORE = 16;
int OAK_LOG = 17;
int LOG = 17;
+ int OAK_LEAVES = 18;
int LEAVES = 18;
int SPONGE = 19;
int GLASS = 20;
@@ -180,12 +186,15 @@ public interface ItemBlockID {
int BLOCK_HOPPER = 154;
int QUARTZ_BLOCK = 155;
int QUARTZ_STAIRS = 156;
+ int OAK_DOUBLE_SLAB = 157;
int DOUBLE_WOODEN_SLAB = 157;
+ int OAK_SLAB = 158;
int WOODEN_SLAB = 158;
int WHITE_TERRACOTTA = 159;
int STAINED_HARDENED_CLAY = 159;
int WHITE_STAINED_GLASS_PANE = 160;
int STAINED_GLASS_PANE = 160;
+ int ACACIA_LEAVES = 161;
int LEAVES2 = 161;
int ACACIA_LOG = 162;
int LOG2 = 162;
@@ -223,6 +232,7 @@ public interface ItemBlockID {
int REPEATING_COMMAND_BLOCK = 188;
int CHAIN_COMMAND_BLOCK = 189;
int HARD_GLASS_PANE = 190;
+ int HARD_WHITE_STAINED_GLASS_PANE = 191;
int HARD_STAINED_GLASS_PANE = 191;
int CHEMICAL_HEAT = 192;
int BLOCK_SPRUCE_DOOR = 193;
@@ -300,6 +310,7 @@ public interface ItemBlockID {
int OBSERVER = 251;
int STRUCTURE_BLOCK = 252;
int HARD_GLASS = 253;
+ int HARD_WHITE_STAINED_GLASS = 254;
int HARD_STAINED_GLASS = 254;
int RESERVED6 = 255;
@@ -513,6 +524,7 @@ public interface ItemBlockID {
int BLOCK_CAMPFIRE = 0xff - BlockID.BLOCK_CAMPFIRE;
int LAVA_CAULDRON = 0xff - BlockID.LAVA_CAULDRON;
int JIGSAW = 0xff - BlockID.JIGSAW; //TODO: meta 29
+ int OAK_WOOD = 0xff - BlockID.OAK_WOOD;
int WOOD = 0xff - BlockID.WOOD;
int COMPOSTER = 0xff - BlockID.COMPOSTER;
int LIT_BLAST_FURNACE = 0xff - BlockID.LIT_BLAST_FURNACE;
@@ -616,7 +628,7 @@ public interface ItemBlockID {
int COPPER_ORE = 0xff - BlockID.COPPER_ORE;
int LIGHTNING_ROD = 0xff - BlockID.LIGHTNING_ROD;
int CRAFTER = 0xff - BlockID.CRAFTER;
-
+ int VAULT = 0xff - BlockID.VAULT;
int TRIAL_SPAWNER = 0xff - BlockID.TRIAL_SPAWNER;
int DRIPSTONE_BLOCK = 0xff - BlockID.DRIPSTONE_BLOCK;
@@ -952,7 +964,21 @@ public interface ItemBlockID {
int GREEN_STAINED_GLASS_PANE = 0xff - BlockID.GREEN_STAINED_GLASS_PANE;
int RED_STAINED_GLASS_PANE = 0xff - BlockID.RED_STAINED_GLASS_PANE;
int BLACK_STAINED_GLASS_PANE = 0xff - BlockID.BLACK_STAINED_GLASS_PANE;
-
+ int HARD_ORANGE_STAINED_GLASS_PANE = 0xff - BlockID.HARD_ORANGE_STAINED_GLASS_PANE;
+ int HARD_MAGENTA_STAINED_GLASS_PANE = 0xff - BlockID.HARD_MAGENTA_STAINED_GLASS_PANE;
+ int HARD_LIGHT_BLUE_STAINED_GLASS_PANE = 0xff - BlockID.HARD_LIGHT_BLUE_STAINED_GLASS_PANE;
+ int HARD_YELLOW_STAINED_GLASS_PANE = 0xff - BlockID.HARD_YELLOW_STAINED_GLASS_PANE;
+ int HARD_LIME_STAINED_GLASS_PANE = 0xff - BlockID.HARD_LIME_STAINED_GLASS_PANE;
+ int HARD_PINK_STAINED_GLASS_PANE = 0xff - BlockID.HARD_PINK_STAINED_GLASS_PANE;
+ int HARD_GRAY_STAINED_GLASS_PANE = 0xff - BlockID.HARD_GRAY_STAINED_GLASS_PANE;
+ int HARD_LIGHT_GRAY_STAINED_GLASS_PANE = 0xff - BlockID.HARD_LIGHT_GRAY_STAINED_GLASS_PANE;
+ int HARD_CYAN_STAINED_GLASS_PANE = 0xff - BlockID.HARD_CYAN_STAINED_GLASS_PANE;
+ int HARD_PURPLE_STAINED_GLASS_PANE = 0xff - BlockID.HARD_PURPLE_STAINED_GLASS_PANE;
+ int HARD_BLUE_STAINED_GLASS_PANE = 0xff - BlockID.HARD_BLUE_STAINED_GLASS_PANE;
+ int HARD_BROWN_STAINED_GLASS_PANE = 0xff - BlockID.HARD_BROWN_STAINED_GLASS_PANE;
+ int HARD_GREEN_STAINED_GLASS_PANE = 0xff - BlockID.HARD_GREEN_STAINED_GLASS_PANE;
+ int HARD_RED_STAINED_GLASS_PANE = 0xff - BlockID.HARD_RED_STAINED_GLASS_PANE;
+ int HARD_BLACK_STAINED_GLASS_PANE = 0xff - BlockID.HARD_BLACK_STAINED_GLASS_PANE;
int ORANGE_STAINED_GLASS = 0xff - BlockID.ORANGE_STAINED_GLASS;
int MAGENTA_STAINED_GLASS = 0xff - BlockID.MAGENTA_STAINED_GLASS;
int LIGHT_BLUE_STAINED_GLASS = 0xff - BlockID.LIGHT_BLUE_STAINED_GLASS;
@@ -968,6 +994,21 @@ public interface ItemBlockID {
int GREEN_STAINED_GLASS = 0xff - BlockID.GREEN_STAINED_GLASS;
int RED_STAINED_GLASS = 0xff - BlockID.RED_STAINED_GLASS;
int BLACK_STAINED_GLASS = 0xff - BlockID.BLACK_STAINED_GLASS;
+ int HARD_ORANGE_STAINED_GLASS = 0xff - BlockID.HARD_ORANGE_STAINED_GLASS;
+ int HARD_MAGENTA_STAINED_GLASS = 0xff - BlockID.HARD_MAGENTA_STAINED_GLASS;
+ int HARD_LIGHT_BLUE_STAINED_GLASS = 0xff - BlockID.HARD_LIGHT_BLUE_STAINED_GLASS;
+ int HARD_YELLOW_STAINED_GLASS = 0xff - BlockID.HARD_YELLOW_STAINED_GLASS;
+ int HARD_LIME_STAINED_GLASS = 0xff - BlockID.HARD_LIME_STAINED_GLASS;
+ int HARD_PINK_STAINED_GLASS = 0xff - BlockID.HARD_PINK_STAINED_GLASS;
+ int HARD_GRAY_STAINED_GLASS = 0xff - BlockID.HARD_GRAY_STAINED_GLASS;
+ int HARD_LIGHT_GRAY_STAINED_GLASS = 0xff - BlockID.HARD_LIGHT_GRAY_STAINED_GLASS;
+ int HARD_CYAN_STAINED_GLASS = 0xff - BlockID.HARD_CYAN_STAINED_GLASS;
+ int HARD_PURPLE_STAINED_GLASS = 0xff - BlockID.HARD_PURPLE_STAINED_GLASS;
+ int HARD_BLUE_STAINED_GLASS = 0xff - BlockID.HARD_BLUE_STAINED_GLASS;
+ int HARD_BROWN_STAINED_GLASS = 0xff - BlockID.HARD_BROWN_STAINED_GLASS;
+ int HARD_GREEN_STAINED_GLASS = 0xff - BlockID.HARD_GREEN_STAINED_GLASS;
+ int HARD_RED_STAINED_GLASS = 0xff - BlockID.HARD_RED_STAINED_GLASS;
+ int HARD_BLACK_STAINED_GLASS = 0xff - BlockID.HARD_BLACK_STAINED_GLASS;
int ORANGE_CONCRETE_POWDER = 0xff - BlockID.ORANGE_CONCRETE_POWDER;
int MAGENTA_CONCRETE_POWDER = 0xff - BlockID.MAGENTA_CONCRETE_POWDER;
@@ -1060,6 +1101,31 @@ public interface ItemBlockID {
int WAXED_EXPOSED_COPPER_TRAPDOOR = 0xff - BlockID.WAXED_EXPOSED_COPPER_TRAPDOOR;
int WAXED_WEATHERED_COPPER_TRAPDOOR = 0xff - BlockID.WAXED_WEATHERED_COPPER_TRAPDOOR;
int WAXED_OXIDIZED_COPPER_TRAPDOOR = 0xff - BlockID.WAXED_OXIDIZED_COPPER_TRAPDOOR;
+ int SPRUCE_LEAVES = 0xff - BlockID.SPRUCE_LEAVES;
+ int BIRCH_LEAVES = 0xff - BlockID.BIRCH_LEAVES;
+ int JUNGLE_LEAVES = 0xff - BlockID.JUNGLE_LEAVES;
+ int DARK_OAK_LEAVES = 0xff - BlockID.DARK_OAK_LEAVES;
+ int SPRUCE_SLAB = 0xff - BlockID.SPRUCE_SLAB;
+ int BIRCH_SLAB = 0xff - BlockID.BIRCH_SLAB;
+ int JUNGLE_SLAB = 0xff - BlockID.JUNGLE_SLAB;
+ int ACACIA_SLAB = 0xff - BlockID.ACACIA_SLAB;
+ int DARK_OAK_SLAB = 0xff - BlockID.DARK_OAK_SLAB;
+ int SPRUCE_DOUBLE_SLAB = 0xff - BlockID.SPRUCE_DOUBLE_SLAB;
+ int BIRCH_DOUBLE_SLAB = 0xff - BlockID.BIRCH_DOUBLE_SLAB;
+ int JUNGLE_DOUBLE_SLAB = 0xff - BlockID.JUNGLE_DOUBLE_SLAB;
+ int ACACIA_DOUBLE_SLAB = 0xff - BlockID.ACACIA_DOUBLE_SLAB;
+ int DARK_OAK_DOUBLE_SLAB = 0xff - BlockID.DARK_OAK_DOUBLE_SLAB;
+ int SPRUCE_WOOD = 0xff - BlockID.SPRUCE_WOOD;
+ int BIRCH_WOOD = 0xff - BlockID.BIRCH_WOOD;
+ int JUNGLE_WOOD = 0xff - BlockID.JUNGLE_WOOD;
+ int ACACIA_WOOD = 0xff - BlockID.ACACIA_WOOD;
+ int DARK_OAK_WOOD = 0xff - BlockID.DARK_OAK_WOOD;
+ int STRIPPED_OAK_WOOD = 0xff - BlockID.STRIPPED_OAK_WOOD;
+ int STRIPPED_SPRUCE_WOOD = 0xff - BlockID.STRIPPED_SPRUCE_WOOD;
+ int STRIPPED_BIRCH_WOOD = 0xff - BlockID.STRIPPED_BIRCH_WOOD;
+ int STRIPPED_JUNGLE_WOOD = 0xff - BlockID.STRIPPED_JUNGLE_WOOD;
+ int STRIPPED_ACACIA_WOOD = 0xff - BlockID.STRIPPED_ACACIA_WOOD;
+ int STRIPPED_DARK_OAK_WOOD = 0xff - BlockID.STRIPPED_DARK_OAK_WOOD;
int UNDEFINED = 0xff - BlockID.UNDEFINED;
diff --git a/src/main/java/cn/nukkit/item/ItemBlockNames.java b/src/main/java/cn/nukkit/item/ItemBlockNames.java
index 50c83ad17f7..55e660e3f5e 100644
--- a/src/main/java/cn/nukkit/item/ItemBlockNames.java
+++ b/src/main/java/cn/nukkit/item/ItemBlockNames.java
@@ -2,6 +2,7 @@
public interface ItemBlockNames {
String STONE = "stone";
+ String GRASS_BLOCK = "grass_block";
String GRASS = "grass";
String DIRT = "dirt";
String COBBLESTONE = "cobblestone";
@@ -20,6 +21,7 @@ public interface ItemBlockNames {
String COAL_ORE = "coal_ore";
String OAK_LOG = "oak_log"; //TODO: 1.19.80 flattening
String LOG = "log";
+ String OAK_LEAVES = "oak_leaves";
String LEAVES = "leaves";
String SPONGE = "sponge";
String GLASS = "glass";
@@ -167,12 +169,15 @@ public interface ItemBlockNames {
String ITEM_HOPPER = "item.hopper";
String QUARTZ_BLOCK = "quartz_block";
String QUARTZ_STAIRS = "quartz_stairs";
+ String OAK_DOUBLE_SLAB = "oak_double_slab"; //TODO: 1.20.70 flattening
String DOUBLE_WOODEN_SLAB = "double_wooden_slab";
+ String OAK_SLAB = "oak_slab"; //TODO: 1.20.70 flattening
String WOODEN_SLAB = "wooden_slab";
String WHITE_TERRACOTTA = "white_terracotta"; //TODO: 1.20.30 flattening
String STAINED_HARDENED_CLAY = "stained_hardened_clay";
String WHITE_STAINED_GLASS_PANE = "white_stained_glass_pane"; //TODO: 1.20.20 flattening
String STAINED_GLASS_PANE = "stained_glass_pane";
+ String ACACIA_LEAVES = "acacia_leaves"; //TODO: 1.20.70 flattening
String LEAVES2 = "leaves2";
String ACACIA_LOG = "acacia_log"; //TODO: 1.19.80 flattening
String LOG2 = "log2";
@@ -208,6 +213,7 @@ public interface ItemBlockNames {
String REPEATING_COMMAND_BLOCK = "repeating_command_block";
String CHAIN_COMMAND_BLOCK = "chain_command_block";
String HARD_GLASS_PANE = "hard_glass_pane";
+ String HARD_WHITE_STAINED_GLASS_PANE = "hard_white_stained_glass_pane"; //TODO: 1.20.60 flattening
String HARD_STAINED_GLASS_PANE = "hard_stained_glass_pane";
String CHEMICAL_HEAT = "chemical_heat";
String ITEM_SPRUCE_DOOR = "item.spruce_door";
@@ -356,6 +362,7 @@ public interface ItemBlockNames {
String OBSERVER = "observer";
String STRUCTURE_BLOCK = "structure_block";
String HARD_GLASS = "hard_glass";
+ String HARD_WHITE_STAINED_GLASS = "hard_white_stained_glass"; //TODO: 1.20.60 flattening
String HARD_STAINED_GLASS = "hard_stained_glass";
String RESERVED6 = "reserved6";
@@ -573,6 +580,7 @@ public interface ItemBlockNames {
String ITEM_CAMPFIRE = "item.campfire";
String LAVA_CAULDRON = "lava_cauldron"; //TODO: 1.20.0 remove
String JIGSAW = "jigsaw"; //TODO: meta 29
+ String OAK_WOOD = "oak_wood"; //TODO: 1.20.70 flattening
String WOOD = "wood";
String COMPOSTER = "composter";
String LIT_BLAST_FURNACE = "lit_blast_furnace";
@@ -672,7 +680,7 @@ public interface ItemBlockNames {
String COPPER_ORE = "copper_ore";
String LIGHTNING_ROD = "lightning_rod";
String CRAFTER = "crafter";
-
+ String VAULT = "vault";
String TRIAL_SPAWNER = "trial_spawner";
String DRIPSTONE_BLOCK = "dripstone_block";
@@ -1008,7 +1016,21 @@ public interface ItemBlockNames {
String GREEN_STAINED_GLASS_PANE = "green_stained_glass_pane";
String RED_STAINED_GLASS_PANE = "red_stained_glass_pane";
String BLACK_STAINED_GLASS_PANE = "black_stained_glass_pane";
-
+ String HARD_ORANGE_STAINED_GLASS_PANE = "hard_orange_stained_glass_pane";
+ String HARD_MAGENTA_STAINED_GLASS_PANE = "hard_magenta_stained_glass_pane";
+ String HARD_LIGHT_BLUE_STAINED_GLASS_PANE = "hard_light_blue_stained_glass_pane";
+ String HARD_YELLOW_STAINED_GLASS_PANE = "hard_yellow_stained_glass_pane";
+ String HARD_LIME_STAINED_GLASS_PANE = "hard_lime_stained_glass_pane";
+ String HARD_PINK_STAINED_GLASS_PANE = "hard_pink_stained_glass_pane";
+ String HARD_GRAY_STAINED_GLASS_PANE = "hard_gray_stained_glass_pane";
+ String HARD_LIGHT_GRAY_STAINED_GLASS_PANE = "hard_light_gray_stained_glass_pane";
+ String HARD_CYAN_STAINED_GLASS_PANE = "hard_cyan_stained_glass_pane";
+ String HARD_PURPLE_STAINED_GLASS_PANE = "hard_purple_stained_glass_pane";
+ String HARD_BLUE_STAINED_GLASS_PANE = "hard_blue_stained_glass_pane";
+ String HARD_BROWN_STAINED_GLASS_PANE = "hard_brown_stained_glass_pane";
+ String HARD_GREEN_STAINED_GLASS_PANE = "hard_green_stained_glass_pane";
+ String HARD_RED_STAINED_GLASS_PANE = "hard_red_stained_glass_pane";
+ String HARD_BLACK_STAINED_GLASS_PANE = "hard_black_stained_glass_pane";
String ORANGE_STAINED_GLASS = "orange_stained_glass";
String MAGENTA_STAINED_GLASS = "magenta_stained_glass";
String LIGHT_BLUE_STAINED_GLASS = "light_blue_stained_glass";
@@ -1024,6 +1046,21 @@ public interface ItemBlockNames {
String GREEN_STAINED_GLASS = "green_stained_glass";
String RED_STAINED_GLASS = "red_stained_glass";
String BLACK_STAINED_GLASS = "black_stained_glass";
+ String HARD_ORANGE_STAINED_GLASS = "hard_orange_stained_glass";
+ String HARD_MAGENTA_STAINED_GLASS = "hard_magenta_stained_glass";
+ String HARD_LIGHT_BLUE_STAINED_GLASS = "hard_light_blue_stained_glass";
+ String HARD_YELLOW_STAINED_GLASS = "hard_yellow_stained_glass";
+ String HARD_LIME_STAINED_GLASS = "hard_lime_stained_glass";
+ String HARD_PINK_STAINED_GLASS = "hard_pink_stained_glass";
+ String HARD_GRAY_STAINED_GLASS = "hard_gray_stained_glass";
+ String HARD_LIGHT_GRAY_STAINED_GLASS = "hard_light_gray_stained_glass";
+ String HARD_CYAN_STAINED_GLASS = "hard_cyan_stained_glass";
+ String HARD_PURPLE_STAINED_GLASS = "hard_purple_stained_glass";
+ String HARD_BLUE_STAINED_GLASS = "hard_blue_stained_glass";
+ String HARD_BROWN_STAINED_GLASS = "hard_brown_stained_glass";
+ String HARD_GREEN_STAINED_GLASS = "hard_green_stained_glass";
+ String HARD_RED_STAINED_GLASS = "hard_red_stained_glass";
+ String HARD_BLACK_STAINED_GLASS = "hard_black_stained_glass";
String ORANGE_CONCRETE_POWDER = "orange_concrete_powder";
String MAGENTA_CONCRETE_POWDER = "magenta_concrete_powder";
@@ -1116,4 +1153,29 @@ public interface ItemBlockNames {
String WAXED_EXPOSED_COPPER_TRAPDOOR = "waxed_exposed_copper_trapdoor";
String WAXED_WEATHERED_COPPER_TRAPDOOR = "waxed_weathered_copper_trapdoor";
String WAXED_OXIDIZED_COPPER_TRAPDOOR = "waxed_oxidized_copper_trapdoor";
+ String SPRUCE_LEAVES = "spruce_leaves";
+ String BIRCH_LEAVES = "birch_leaves";
+ String JUNGLE_LEAVES = "jungle_leaves";
+ String DARK_OAK_LEAVES = "dark_oak_leaves";
+ String SPRUCE_SLAB = "spruce_slab";
+ String BIRCH_SLAB = "birch_slab";
+ String JUNGLE_SLAB = "jungle_slab";
+ String ACACIA_SLAB = "acacia_slab";
+ String DARK_OAK_SLAB = "dark_oak_slab";
+ String SPRUCE_DOUBLE_SLAB = "spruce_double_slab";
+ String BIRCH_DOUBLE_SLAB = "birch_double_slab";
+ String JUNGLE_DOUBLE_SLAB = "jungle_double_slab";
+ String ACACIA_DOUBLE_SLAB = "acacia_double_slab";
+ String DARK_OAK_DOUBLE_SLAB = "dark_oak_double_slab";
+ String SPRUCE_WOOD = "spruce_wood";
+ String BIRCH_WOOD = "birch_wood";
+ String JUNGLE_WOOD = "jungle_wood";
+ String ACACIA_WOOD = "acacia_wood";
+ String DARK_OAK_WOOD = "dark_oak_wood";
+ String STRIPPED_OAK_WOOD = "stripped_oak_wood";
+ String STRIPPED_SPRUCE_WOOD = "stripped_spruce_wood";
+ String STRIPPED_BIRCH_WOOD = "stripped_birch_wood";
+ String STRIPPED_JUNGLE_WOOD = "stripped_jungle_wood";
+ String STRIPPED_ACACIA_WOOD = "stripped_acacia_wood";
+ String STRIPPED_DARK_OAK_WOOD = "stripped_dark_oak_wood";
}
diff --git a/src/main/java/cn/nukkit/item/ItemFullNames.java b/src/main/java/cn/nukkit/item/ItemFullNames.java
index e342092dc61..e0e4918a10a 100644
--- a/src/main/java/cn/nukkit/item/ItemFullNames.java
+++ b/src/main/java/cn/nukkit/item/ItemFullNames.java
@@ -1,5 +1,7 @@
package cn.nukkit.item;
+import com.google.common.annotations.Beta;
+
// This file is generated automatically, do not edit it manually.
public interface ItemFullNames extends ItemBlockNames {
String GLOW_STICK = "minecraft:" + ItemNames.GLOW_STICK;
@@ -462,9 +464,18 @@ public interface ItemFullNames extends ItemBlockNames {
@Deprecated
String APPLEENCHANTED = "minecraft:" + ItemNames.APPLEENCHANTED;
String HEART_OF_THE_SEA = "minecraft:" + ItemNames.HEART_OF_THE_SEA;
+ /**
+ * @since 1.20.60
+ */
+ @Beta
+ String TURTLE_SCUTE = "minecraft:" + ItemNames.TURTLE_SCUTE;
+// /**
+// * @deprecated use {@link #TURTLE_SCUTE} instead
+// */
+// @Deprecated
String SCUTE = "minecraft:" + ItemNames.SCUTE;
/**
- * @deprecated use {@link #SCUTE} instead
+ * @deprecated use {@link #TURTLE_SCUTE} instead
*/
@Deprecated
String TURTLE_SHELL_PIECE = "minecraft:" + ItemNames.TURTLE_SHELL_PIECE;
diff --git a/src/main/java/cn/nukkit/item/ItemID.java b/src/main/java/cn/nukkit/item/ItemID.java
index d58243e378c..93bf4f134ed 100644
--- a/src/main/java/cn/nukkit/item/ItemID.java
+++ b/src/main/java/cn/nukkit/item/ItemID.java
@@ -340,9 +340,14 @@ public interface ItemID extends BlockID, ItemRuntimeID {
@Deprecated
int APPLEENCHANTED = 466;
int HEART_OF_THE_SEA = 467;
+ int TURTLE_SCUTE = 468;
+ /**
+ * @deprecated use {@link #TURTLE_SCUTE} instead
+ */
+ @Deprecated
int SCUTE = 468;
/**
- * @deprecated use {@link #SCUTE} instead
+ * @deprecated use {@link #TURTLE_SCUTE} instead
*/
@Deprecated
int TURTLE_SHELL_PIECE = 468;
diff --git a/src/main/java/cn/nukkit/item/ItemNames.java b/src/main/java/cn/nukkit/item/ItemNames.java
index 1f05a3cba39..5f3285b1514 100644
--- a/src/main/java/cn/nukkit/item/ItemNames.java
+++ b/src/main/java/cn/nukkit/item/ItemNames.java
@@ -1,5 +1,7 @@
package cn.nukkit.item;
+import com.google.common.annotations.Beta;
+
public interface ItemNames extends ItemBlockNames {
String GLOW_STICK = "glow_stick";
@@ -280,6 +282,8 @@ public interface ItemNames extends ItemBlockNames {
String ALLAY_SPAWN_EGG = "allay_spawn_egg";
String CAMEL_SPAWN_EGG = "camel_spawn_egg";
String SNIFFER_SPAWN_EGG = "sniffer_spawn_egg";
+ String BREEZE_SPAWN_EGG = "breeze_spawn_egg";
+ String ARMADILLO_SPAWN_EGG = "armadillo_spawn_egg";
String TRADER_LLAMA_SPAWN_EGG = "trader_llama_spawn_egg";
String EXPERIENCE_BOTTLE = "experience_bottle";
String FIRE_CHARGE = "fire_charge";
@@ -461,9 +465,18 @@ public interface ItemNames extends ItemBlockNames {
@Deprecated
String APPLEENCHANTED = "appleenchanted";
String HEART_OF_THE_SEA = "heart_of_the_sea";
+ /**
+ * @since 1.20.60
+ */
+ @Beta
+ String TURTLE_SCUTE = "turtle_scute";
+// /**
+// * @deprecated use {@link #TURTLE_SCUTE} instead
+// */
+// @Deprecated
String SCUTE = "scute";
/**
- * @deprecated use {@link #SCUTE} instead
+ * @deprecated use {@link #TURTLE_SCUTE} instead
*/
@Deprecated
String TURTLE_SHELL_PIECE = "turtle_shell_piece";
diff --git a/src/main/java/cn/nukkit/item/ItemScute.java b/src/main/java/cn/nukkit/item/ItemScute.java
index 3e6ff1f51cc..cc201df1165 100644
--- a/src/main/java/cn/nukkit/item/ItemScute.java
+++ b/src/main/java/cn/nukkit/item/ItemScute.java
@@ -11,6 +11,6 @@ public ItemScute(Integer meta) {
}
public ItemScute(Integer meta, int count) {
- super(SCUTE, meta, count, "Scute");
+ super(TURTLE_SCUTE, meta, count, "Turtle Scute");
}
}
diff --git a/src/main/java/cn/nukkit/item/Items.java b/src/main/java/cn/nukkit/item/Items.java
index 2fb1f0e5527..f869b21a78d 100644
--- a/src/main/java/cn/nukkit/item/Items.java
+++ b/src/main/java/cn/nukkit/item/Items.java
@@ -14,6 +14,7 @@
import javax.annotation.Nullable;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
@@ -267,7 +268,7 @@ public static void registerVanillaItems() {
registerItem(ItemNames.HEART_OF_THE_SEA, HEART_OF_THE_SEA, ItemHeartOfTheSea.class, ItemHeartOfTheSea::new, V1_4_0);
registerItem(ItemNames.NAUTILUS_SHELL, NAUTILUS_SHELL, ItemNautilusShell.class, ItemNautilusShell::new, V1_5_0);
- registerItem(ItemNames.SCUTE, SCUTE, ItemScute.class, ItemScute::new, V1_5_0);
+ registerItem(ItemNames.SCUTE, TURTLE_SCUTE, ItemScute.class, ItemScute::new, V1_5_0);
registerItem(ItemNames.TURTLE_HELMET, TURTLE_HELMET, ItemTurtleShell.class, ItemTurtleShell::new, V1_5_0);
registerItem(ItemNames.PHANTOM_MEMBRANE, PHANTOM_MEMBRANE, ItemPhantomMembrane.class, ItemPhantomMembrane::new, V1_6_0);
@@ -446,11 +447,13 @@ private static void registerSimpleAliases() {
registerAlias(ItemNames.LODESTONECOMPASS, ItemNames.LODESTONE_COMPASS, V1_16_100);
registerAlias(ItemNames.RECORD_PIGSTEP, ItemNames.MUSIC_DISC_PIGSTEP, V1_16_100);
- registerAlias(ItemNames.RECORD_OTHERSIDE, ItemNames.MUSIC_DISC_OTHERSIDE, V1_18_0);
+ registerAlias(ItemNames.RECORD_OTHERSIDE, ItemNames.MUSIC_DISC_OTHERSIDE, true, V1_18_0);
- registerAlias(ItemNames.RECORD_5, ItemNames.MUSIC_DISC_5, V1_19_0);
+ registerAlias(ItemNames.RECORD_5, ItemNames.MUSIC_DISC_5, true, V1_19_0);
- registerAlias(ItemNames.RECORD_RELIC, ItemNames.MUSIC_DISC_RELIC, V1_20_0);
+ registerAlias(ItemNames.RECORD_RELIC, ItemNames.MUSIC_DISC_RELIC, true, V1_20_0);
+
+ registerAlias(ItemNames.SCUTE, ItemNames.TURTLE_SCUTE, V1_20_60);
}
private static void registerComplexAliases() {
@@ -586,6 +589,8 @@ private static void registerComplexAliases() {
registerComplexAlias(ItemNames.ENDER_DRAGON_SPAWN_EGG, SPAWN_EGG, EntityID.ENDER_DRAGON, V1_19_60);
registerComplexAlias(ItemNames.CAMEL_SPAWN_EGG, SPAWN_EGG, EntityID.CAMEL, V1_20_0);
registerComplexAlias(ItemNames.SNIFFER_SPAWN_EGG, SPAWN_EGG, EntityID.SNIFFER, V1_20_0);
+// registerComplexAlias(ItemNames.BREEZE_SPAWN_EGG, SPAWN_EGG, EntityID.BREEZE, V1_21_0);
+// registerComplexAlias(ItemNames.ARMADILLO_SPAWN_EGG, SPAWN_EGG, EntityID.ARMADILLO, V1_21_0);
}
private static Class extends Item> registerItem(String name, int id, Class extends Item> clazz, ItemFactory factory) {
@@ -708,8 +713,30 @@ private static void registerNewItemAux(String name, int id, int meta, GameVersio
registerComplexAlias(name, id, meta, version);
}
- private static void registerAlias(String alias, String currentName, GameVersion version) {
- SIMPLE_ALIASES_MAP.put(alias, currentName);
+ /**
+ * @param version min required base game version
+ */
+ private static void registerAlias(String oldName, String newName, GameVersion version) {
+ registerAlias(oldName, newName, false, version);
+ }
+
+ /**
+ * @param version min required base game version
+ */
+ private static void registerAlias(String oldName, String newName, boolean add, GameVersion version) {
+ if (!add && !version.isAvailable()) {
+ String name = oldName;
+ oldName = newName;
+ newName = name;
+ }
+
+ for (Entry entry : SIMPLE_ALIASES_MAP.entrySet()) {
+ if (entry.getValue().equals(oldName)) {
+ SIMPLE_ALIASES_MAP.put(entry.getKey(), newName);
+ }
+ }
+
+ SIMPLE_ALIASES_MAP.put(oldName, newName);
}
private static void registerComplexAlias(String alias, int id, int meta, GameVersion version) {
diff --git a/src/main/java/cn/nukkit/item/enchantment/Enchantment.java b/src/main/java/cn/nukkit/item/enchantment/Enchantment.java
index d5ed0bfc552..b0cabe05518 100644
--- a/src/main/java/cn/nukkit/item/enchantment/Enchantment.java
+++ b/src/main/java/cn/nukkit/item/enchantment/Enchantment.java
@@ -16,6 +16,7 @@
* Nukkit Project
*/
public abstract class Enchantment implements Cloneable, EnchantmentID {
+ public static final Enchantment[] EMPTY = new Enchantment[0];
protected static final Enchantment[] enchantments = new Enchantment[256];
diff --git a/src/main/java/cn/nukkit/level/GlobalBlockPaletteInterface.java b/src/main/java/cn/nukkit/level/GlobalBlockPaletteInterface.java
index bb19b5bc92e..f9a8c8597de 100644
--- a/src/main/java/cn/nukkit/level/GlobalBlockPaletteInterface.java
+++ b/src/main/java/cn/nukkit/level/GlobalBlockPaletteInterface.java
@@ -50,6 +50,7 @@ enum StaticVersion {
V1_20_30(618, false),
V1_20_40(622, false),
V1_20_50(630, false),
+ V1_20_60(649, false),
;
private static final StaticVersion[] VALUES = StaticVersion.values();
diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java
index fd33156dd00..05961c34c99 100644
--- a/src/main/java/cn/nukkit/level/Level.java
+++ b/src/main/java/cn/nukkit/level/Level.java
@@ -132,7 +132,7 @@ public class Level implements ChunkManager, Metadatable {
private static final boolean[] randomTickBlocks = new boolean[Block.BLOCK_ID_COUNT];
//TODO: move to Block class
static {
- randomTickBlocks[Block.GRASS] = true;
+ randomTickBlocks[Block.GRASS_BLOCK] = true;
randomTickBlocks[Block.FARMLAND] = true;
randomTickBlocks[Block.MYCELIUM] = true;
randomTickBlocks[Block.SAPLING] = true;
@@ -2598,7 +2598,8 @@ public Item useBreakOn(Vector3 vector, @Nullable BlockFace face, @Nullable Item
item = Items.air();
}
- boolean isSilkTouch = item.getEnchantment(Enchantment.SILK_TOUCH) != null;
+ boolean isEnchantedBook = item.getId() == Item.ENCHANTED_BOOK;
+ boolean isSilkTouch = !isEnchantedBook && item.getEnchantment(Enchantment.SILK_TOUCH) != null;
if (player != null) {
if (player.getGamemode() == Player.ADVENTURE) {
@@ -2643,7 +2644,7 @@ public Item useBreakOn(Vector3 vector, @Nullable BlockFace face, @Nullable Item
breakTime *= 1 - (0.3 * (miningFatigue.getAmplifier() + 1));
}
- Enchantment eff = item.getEnchantment(Enchantment.EFFICIENCY);
+ Enchantment eff = !isEnchantedBook ? item.getEnchantment(Enchantment.EFFICIENCY) : null;
if (eff != null && eff.getLevel() > 0) {
breakTime *= 1 - (0.3 * eff.getLevel());
}
@@ -3509,16 +3510,22 @@ private void sendChunk(int x, int z, long index, int subChunkCount, ChunkBlobCac
if (protocol < 503) {
player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, chunkBlobCache,
chunkPacketCache.getSubModePacket());
- } else {
+ } else if (protocol < 649) {
player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, chunkBlobCache,
chunkPacketCache.getSubModePacketNew());
+ } else {
+ player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, chunkBlobCache,
+ chunkPacketCache.getSubModePacketUncompressed());
}
} else if (protocol < 503) {
player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, chunkBlobCache,
chunkPacketCache.getSubModePacketTruncated());
- } else {
+ } else if (protocol < 649) {
player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, chunkBlobCache,
chunkPacketCache.getSubModePacketTruncatedNew());
+ } else {
+ player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, chunkBlobCache,
+ chunkPacketCache.getSubModePacketUncompressed());
}
} else {
StaticVersion blockVersion = player.getBlockVersion();
@@ -3529,7 +3536,8 @@ private void sendChunk(int x, int z, long index, int subChunkCount, ChunkBlobCac
continue;
}
- BatchPacket packet = chunkPacketCache.getPacket(blockVersion);
+ DataPacket packet = blockVersion.getProtocol() < StaticVersion.V1_20_60.getProtocol() ?
+ chunkPacketCache.getPacket(blockVersion) : chunkPacketCache.getPacketUncompressed(blockVersion);
if (packet == null) {
requestChunk(x, z, player);
continue;
@@ -3597,13 +3605,17 @@ private void processChunkRequest() {
if (protocol < 486 || !ENABLE_SUB_CHUNK_NETWORK_OPTIMIZATION) {
if (protocol < 503) {
player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, blobCache, packetCache.getSubModePacket());
- } else {
+ } else if (protocol < 649) {
player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, blobCache, packetCache.getSubModePacketNew());
+ } else {
+ player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, blobCache, packetCache.getSubModePacketUncompressed());
}
} else if (protocol < 503) {
player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, blobCache, packetCache.getSubModePacketTruncated());
- } else {
+ } else if (protocol < 649) {
player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, blobCache, packetCache.getSubModePacketTruncatedNew());
+ } else {
+ player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, blobCache, packetCache.getSubModePacketUncompressed());
}
} else {
if (blockVersion == null) {
@@ -3614,7 +3626,8 @@ private void processChunkRequest() {
continue;
}
- player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, blobCache, packetCache.getPacket(blockVersion));
+ player.sendChunk(x, z, subChunkCount + PADDING_SUB_CHUNK_COUNT, blobCache, blockVersion.getProtocol() < StaticVersion.V1_20_60.getProtocol() ?
+ packetCache.getPacket(blockVersion) : packetCache.getPacketUncompressed(blockVersion));
}
iter.remove();
@@ -3701,6 +3714,7 @@ public void chunkRequestCallback(long timestamp, int x, int z, int subChunkCount
if (chunkPacketCache == null) {
int extendedCount = subChunkCount == 0 ? 0 : PADDING_SUB_CHUNK_COUNT + subChunkCount;
Map packets = new EnumMap<>(StaticVersion.class);
+ Map packetsUncompressed = new EnumMap<>(StaticVersion.class);
Map subPackets = new EnumMap<>(StaticVersion.class);
Map subPacketsUncompressed = new EnumMap<>(StaticVersion.class);
@@ -3730,17 +3744,41 @@ public void chunkRequestCallback(long timestamp, int x, int z, int subChunkCount
subPackets.put(version, compressed);
subPacketsUncompressed.put(version, uncompressed);
}
- packets.put(version, getChunkCacheFromData(x, z, actualCount, data, false, true));
+
+ if (version.getProtocol() >= StaticVersion.V1_20_60.getProtocol()) {
+ LevelChunkPacket12060 uncompressed = new LevelChunkPacket12060();
+ uncompressed.chunkX = x;
+ uncompressed.chunkZ = z;
+ uncompressed.dimension = getDimension().ordinal();
+ uncompressed.subChunkCount = actualCount;
+ uncompressed.subChunkRequestLimit = 0;
+ uncompressed.data = data;
+ uncompressed.setBuffer(null, 0);
+ packetsUncompressed.put(version, uncompressed);
+ } else {
+ packets.put(version, getChunkCacheFromData(x, z, actualCount, data, false, true));
+ }
});
+ LevelChunkPacket12060 uncompressed = new LevelChunkPacket12060();
+ uncompressed.chunkX = x;
+ uncompressed.chunkZ = z;
+ uncompressed.dimension = getDimension().ordinal();
+ uncompressed.subChunkCount = LevelChunkPacket.CLIENT_REQUEST_TRUNCATED_COLUMN_FAKE_COUNT;
+ uncompressed.subChunkRequestLimit = extendedCount;
+ uncompressed.data = subModePayloadNew;
+ uncompressed.setBuffer(null, 0);
+
chunkPacketCache = new ChunkPacketCache(
packets,
+ packetsUncompressed,
subPackets,
subPacketsUncompressed,
getChunkCacheFromData(x, z, LevelChunkPacket.CLIENT_REQUEST_FULL_COLUMN_FAKE_COUNT, subModePayloadNew, false, true),
getChunkCacheFromData(x, z, LevelChunkPacket.CLIENT_REQUEST_FULL_COLUMN_FAKE_COUNT, subModePayload, false, true),
getChunkCacheFromData(x, z, LevelChunkPacket.CLIENT_REQUEST_TRUNCATED_COLUMN_FAKE_COUNT, extendedCount, subModePayloadNew, false, true),
getChunkCacheFromData(x, z, LevelChunkPacket.CLIENT_REQUEST_TRUNCATED_COLUMN_FAKE_COUNT, extendedCount, subModePayload, false, true),
+ uncompressed,
getChunkCacheFromData(x, z, subChunkCount, payload, false, true),
getChunkCacheFromData(x, z, subChunkCount, payload, false, false),
getChunkCacheFromData(x, z, subChunkCount, payloadOld, true, false),
diff --git a/src/main/java/cn/nukkit/level/ParticleEffect.java b/src/main/java/cn/nukkit/level/ParticleEffect.java
index e06734b94e4..605ba5d5e31 100644
--- a/src/main/java/cn/nukkit/level/ParticleEffect.java
+++ b/src/main/java/cn/nukkit/level/ParticleEffect.java
@@ -138,8 +138,8 @@ public enum ParticleEffect {
WATER_EVAPORATION_ACTOR("minecraft:water_evaporation_actor_emitter"),
WATER_EVAPORATION_BUCKET("minecraft:water_evaporation_bucket_emitter"),
WATER_EVAPORATION_MANUAL("minecraft:water_evaporation_manual"),
- WATER_SPASH_MANUAL("minecraft:water_splash_particle_manual"),
WATER_SPLASH("minecraft:water_splash_particle"),
+ WATER_SPLASH_MANUAL("minecraft:water_splash_particle_manual"),
WATER_WAKE("minecraft:water_wake_particle"),
WAX("minecraft:wax_particle"),
WITHER_BOSS_INVULNERABLE("minecraft:wither_boss_invulnerable");
diff --git a/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaPlateauFBiome.java b/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaPlateauFBiome.java
index a6cb36cf931..56e7dce2458 100644
--- a/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaPlateauFBiome.java
+++ b/src/main/java/cn/nukkit/level/biome/impl/mesa/MesaPlateauFBiome.java
@@ -18,7 +18,7 @@ public MesaPlateauFBiome() {
@Override
public int getCoverBlock() {
- return GRASS;
+ return GRASS_BLOCK;
}
@Override
diff --git a/src/main/java/cn/nukkit/level/biome/type/GrassyBiome.java b/src/main/java/cn/nukkit/level/biome/type/GrassyBiome.java
index 09e4b1891b5..7bf49add60c 100644
--- a/src/main/java/cn/nukkit/level/biome/type/GrassyBiome.java
+++ b/src/main/java/cn/nukkit/level/biome/type/GrassyBiome.java
@@ -21,7 +21,7 @@ public GrassyBiome() {
@Override
public int getSurfaceBlock(int y) {
- return GRASS;
+ return GRASS_BLOCK;
}
@Override
diff --git a/src/main/java/cn/nukkit/level/format/generic/ChunkPacketCache.java b/src/main/java/cn/nukkit/level/format/generic/ChunkPacketCache.java
index 6a8b1552352..2c47fdc6eef 100644
--- a/src/main/java/cn/nukkit/level/format/generic/ChunkPacketCache.java
+++ b/src/main/java/cn/nukkit/level/format/generic/ChunkPacketCache.java
@@ -2,6 +2,7 @@
import cn.nukkit.level.GlobalBlockPaletteInterface.StaticVersion;
import cn.nukkit.network.protocol.BatchPacket;
+import cn.nukkit.network.protocol.LevelChunkPacket12060;
import cn.nukkit.network.protocol.SubChunkPacket;
import javax.annotation.Nullable;
@@ -11,6 +12,7 @@
public class ChunkPacketCache {
private final Map packets; //1.16.100+ static runtime block palette
+ private final Map fullChunkPacketsUncompressed; // 1.20.60+
private final Map subChunkPackets; // 1.18+ sub chunk packet
private final Map subChunkPacketsUncompressed;
@@ -21,20 +23,23 @@ public class ChunkPacketCache {
private final BatchPacket subModePacket;
private final BatchPacket subModePacketTruncatedNew; // 1.18.30+
private final BatchPacket subModePacketTruncated;
+ private final LevelChunkPacket12060 subModePacketUncompressed; // 1.20.60+
private final BatchPacket packet116;
private final BatchPacket packet;
private final BatchPacket packetOld;
private final Set requestedVersions;
- public ChunkPacketCache(Map packets, Map subChunkPackets, Map subChunkPacketsUncompressed, BatchPacket subModePacketNew, BatchPacket subModePacket, BatchPacket subModePacketTruncatedNew, BatchPacket subModePacketTruncated, BatchPacket packet116, BatchPacket packet, BatchPacket packetOld, Set requestedVersions) {
+ public ChunkPacketCache(Map packets, Map fullChunkPacketsUncompressed, Map subChunkPackets, Map subChunkPacketsUncompressed, BatchPacket subModePacketNew, BatchPacket subModePacket, BatchPacket subModePacketTruncatedNew, BatchPacket subModePacketTruncated, LevelChunkPacket12060 subModePacketUncompressed, BatchPacket packet116, BatchPacket packet, BatchPacket packetOld, Set requestedVersions) {
this.packets = packets;
+ this.fullChunkPacketsUncompressed = fullChunkPacketsUncompressed;
this.subChunkPackets = subChunkPackets;
this.subChunkPacketsUncompressed = subChunkPacketsUncompressed;
this.subModePacketNew = subModePacketNew;
this.subModePacket = subModePacket;
this.subModePacketTruncatedNew = subModePacketTruncatedNew;
this.subModePacketTruncated = subModePacketTruncated;
+ this.subModePacketUncompressed = subModePacketUncompressed;
this.packet116 = packet116;
this.packet = packet;
this.packetOld = packetOld;
@@ -46,6 +51,11 @@ public BatchPacket getPacket(StaticVersion version) {
return this.packets.get(version);
}
+ @Nullable
+ public LevelChunkPacket12060 getPacketUncompressed(StaticVersion version) {
+ return this.fullChunkPacketsUncompressed.get(version);
+ }
+
@Nullable
public BatchPacket[] getSubPackets(StaticVersion version) {
return this.subChunkPackets.get(version);
@@ -72,6 +82,10 @@ public BatchPacket getSubModePacketTruncated() {
return subModePacketTruncated;
}
+ public LevelChunkPacket12060 getSubModePacketUncompressed() {
+ return subModePacketUncompressed;
+ }
+
public BatchPacket getPacket116() {
return packet116;
}
diff --git a/src/main/java/cn/nukkit/level/format/generic/ChunkRequestTask.java b/src/main/java/cn/nukkit/level/format/generic/ChunkRequestTask.java
index 3b9e96f4ba6..cc332986d66 100644
--- a/src/main/java/cn/nukkit/level/format/generic/ChunkRequestTask.java
+++ b/src/main/java/cn/nukkit/level/format/generic/ChunkRequestTask.java
@@ -18,6 +18,7 @@
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.network.protocol.BatchPacket;
import cn.nukkit.network.protocol.LevelChunkPacket;
+import cn.nukkit.network.protocol.LevelChunkPacket12060;
import cn.nukkit.network.protocol.SubChunkPacket;
import cn.nukkit.network.protocol.SubChunkPacket11810;
import cn.nukkit.scheduler.AsyncTask;
@@ -375,6 +376,7 @@ public void onRun() {
if (level.isCacheChunks()) {
Map packets = new EnumMap<>(StaticVersion.class);
+ Map packetsUncompressed = new EnumMap<>(StaticVersion.class);
Map subPackets = new EnumMap<>(StaticVersion.class);
Map subPacketsUncompressed = new EnumMap<>(StaticVersion.class);
@@ -404,17 +406,41 @@ public void onRun() {
subPackets.put(version, compressed);
subPacketsUncompressed.put(version, uncompressed);
}
- packets.put(version, Level.getChunkCacheFromData(x, z, actualCount, payload, false, true));
+
+ if (version.getProtocol() >= StaticVersion.V1_20_60.getProtocol()) {
+ LevelChunkPacket12060 uncompressed = new LevelChunkPacket12060();
+ uncompressed.chunkX = x;
+ uncompressed.chunkZ = z;
+ uncompressed.dimension = level.getDimension().ordinal();
+ uncompressed.subChunkCount = actualCount;
+ uncompressed.subChunkRequestLimit = 0;
+ uncompressed.data = payload;
+ uncompressed.setBuffer(null, 0);
+ packetsUncompressed.put(version, uncompressed);
+ } else {
+ packets.put(version, Level.getChunkCacheFromData(x, z, actualCount, payload, false, true));
+ }
});
+ LevelChunkPacket12060 uncompressed = new LevelChunkPacket12060();
+ uncompressed.chunkX = x;
+ uncompressed.chunkZ = z;
+ uncompressed.dimension = level.getDimension().ordinal();
+ uncompressed.subChunkCount = LevelChunkPacket.CLIENT_REQUEST_TRUNCATED_COLUMN_FAKE_COUNT;
+ uncompressed.subChunkRequestLimit = extendedCount;
+ uncompressed.data = subModePayloadNew;
+ uncompressed.setBuffer(null, 0);
+
chunkPacketCache = new ChunkPacketCache(
packets,
+ packetsUncompressed,
subPackets,
subPacketsUncompressed,
Level.getChunkCacheFromData(x, z, LevelChunkPacket.CLIENT_REQUEST_FULL_COLUMN_FAKE_COUNT, subModePayloadNew, false, true),
Level.getChunkCacheFromData(x, z, LevelChunkPacket.CLIENT_REQUEST_FULL_COLUMN_FAKE_COUNT, subModePayload, false, true),
Level.getChunkCacheFromData(x, z, LevelChunkPacket.CLIENT_REQUEST_TRUNCATED_COLUMN_FAKE_COUNT, extendedCount, subModePayloadNew, false, true),
Level.getChunkCacheFromData(x, z, LevelChunkPacket.CLIENT_REQUEST_TRUNCATED_COLUMN_FAKE_COUNT, extendedCount, subModePayload, false, true),
+ uncompressed,
Level.getChunkCacheFromData(x, z, count, payload, false, true),
Level.getChunkCacheFromData(x, z, count, payload, false, false),
Level.getChunkCacheFromData(x, z, count, payloadOld, true, false),
diff --git a/src/main/java/cn/nukkit/level/generator/object/ObjectTallGrass.java b/src/main/java/cn/nukkit/level/generator/object/ObjectTallGrass.java
index 1932cfa58ae..083a826e4d8 100644
--- a/src/main/java/cn/nukkit/level/generator/object/ObjectTallGrass.java
+++ b/src/main/java/cn/nukkit/level/generator/object/ObjectTallGrass.java
@@ -40,7 +40,7 @@ public static void growGrass(ChunkManager level, Vector3 pos, NukkitRandom rando
y += random.nextRange(-1, 1) * random.nextBoundedInt(3) / 2;
z += random.nextRange(-1, 1);
- if (level.getBlockIdAt(0, x, y - 1, z) != Block.GRASS || y > 255 || y < 0) {
+ if (level.getBlockIdAt(0, x, y - 1, z) != Block.GRASS_BLOCK || y > 255 || y < 0) {
break;
}
diff --git a/src/main/java/cn/nukkit/level/generator/object/mushroom/BigMushroom.java b/src/main/java/cn/nukkit/level/generator/object/mushroom/BigMushroom.java
index 8a85a8318f9..873dbb7fbca 100644
--- a/src/main/java/cn/nukkit/level/generator/object/mushroom/BigMushroom.java
+++ b/src/main/java/cn/nukkit/level/generator/object/mushroom/BigMushroom.java
@@ -85,7 +85,7 @@ public boolean generate(ChunkManager level, NukkitRandom rand, Vector3 position)
Vector3 pos2 = position.down();
int block1 = level.getBlockIdAt(0, pos2.getFloorX(), pos2.getFloorY(), pos2.getFloorZ());
- if (block1 != Block.DIRT && block1 != Block.GRASS && block1 != Block.MYCELIUM) {
+ if (block1 != Block.DIRT && block1 != Block.GRASS_BLOCK && block1 != Block.MYCELIUM) {
return false;
} else {
int k2 = position.getFloorY() + i;
diff --git a/src/main/java/cn/nukkit/level/generator/object/tree/HugeTreesGenerator.java b/src/main/java/cn/nukkit/level/generator/object/tree/HugeTreesGenerator.java
index 492c3d50e4f..812d8068174 100644
--- a/src/main/java/cn/nukkit/level/generator/object/tree/HugeTreesGenerator.java
+++ b/src/main/java/cn/nukkit/level/generator/object/tree/HugeTreesGenerator.java
@@ -82,7 +82,7 @@ private boolean ensureDirtsUnderneath(Vector3 pos, ChunkManager worldIn) {
Vector3 blockpos = pos.down();
int block = worldIn.getBlockIdAt(0, (int) blockpos.x, (int) blockpos.y, (int) blockpos.z);
- if ((block == Block.GRASS || block == Block.DIRT) && pos.getY() >= 2) {
+ if ((block == Block.GRASS_BLOCK || block == Block.DIRT) && pos.getY() >= 2) {
this.setDirtAt(worldIn, blockpos);
this.setDirtAt(worldIn, blockpos.east());
this.setDirtAt(worldIn, blockpos.south());
diff --git a/src/main/java/cn/nukkit/level/generator/object/tree/NewJungleTree.java b/src/main/java/cn/nukkit/level/generator/object/tree/NewJungleTree.java
index decc337d26a..0ddff55bd65 100644
--- a/src/main/java/cn/nukkit/level/generator/object/tree/NewJungleTree.java
+++ b/src/main/java/cn/nukkit/level/generator/object/tree/NewJungleTree.java
@@ -75,7 +75,7 @@ public boolean generate(ChunkManager worldIn, NukkitRandom rand, Vector3 vectorP
BlockVector3 down = position.down();
int block = worldIn.getBlockIdAt(0, down.x, down.y, down.z);
- if ((block == Block.GRASS || block == Block.DIRT || block == Block.FARMLAND) && position.getY() < 256 - i - 1) {
+ if ((block == Block.GRASS_BLOCK || block == Block.DIRT || block == Block.FARMLAND) && position.getY() < 256 - i - 1) {
this.setDirtAt(worldIn, down);
int k2 = 3;
int l2 = 0;
diff --git a/src/main/java/cn/nukkit/level/generator/object/tree/ObjectDarkOakTree.java b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectDarkOakTree.java
index 8fa4e7e53d0..93d921d5119 100644
--- a/src/main/java/cn/nukkit/level/generator/object/tree/ObjectDarkOakTree.java
+++ b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectDarkOakTree.java
@@ -27,7 +27,7 @@ public boolean generate(ChunkManager level, NukkitRandom rand, Vector3 position)
Vector3 blockpos = position.down();
int block = level.getBlockIdAt(0, blockpos.getFloorX(), blockpos.getFloorY(), blockpos.getFloorZ());
- if (block != Block.GRASS && block != Block.DIRT) {
+ if (block != Block.GRASS_BLOCK && block != Block.DIRT) {
return false;
} else if (!this.placeTreeOfHeight(level, position, i)) {
return false;
diff --git a/src/main/java/cn/nukkit/level/generator/object/tree/ObjectSavannaTree.java b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectSavannaTree.java
index a92afab80bf..e56df316dbb 100644
--- a/src/main/java/cn/nukkit/level/generator/object/tree/ObjectSavannaTree.java
+++ b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectSavannaTree.java
@@ -52,7 +52,7 @@ public boolean generate(ChunkManager level, NukkitRandom rand, Vector3 position)
Vector3 down = position.down();
int block = level.getBlockIdAt(0, down.getFloorX(), down.getFloorY(), down.getFloorZ());
- if ((block == Block.GRASS || block == Block.DIRT) && position.getY() < 256 - i - 1) {
+ if ((block == Block.GRASS_BLOCK || block == Block.DIRT) && position.getY() < 256 - i - 1) {
this.setDirtAt(level, position.down());
BlockFace face = BlockFace.Plane.HORIZONTAL.random(rand);
int k2 = i - rand.nextBoundedInt(4) - 1;
diff --git a/src/main/java/cn/nukkit/level/generator/object/tree/ObjectSwampTree.java b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectSwampTree.java
index df7ec561994..e4983e78657 100644
--- a/src/main/java/cn/nukkit/level/generator/object/tree/ObjectSwampTree.java
+++ b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectSwampTree.java
@@ -59,7 +59,7 @@ public boolean generate(ChunkManager worldIn, NukkitRandom rand, Vector3 vectorP
BlockVector3 down = position.down();
int block = worldIn.getBlockIdAt(0, down.x, down.y, down.z);
- if ((block == Block.GRASS || block == Block.DIRT) && position.getY() < 256 - i - 1) {
+ if ((block == Block.GRASS_BLOCK || block == Block.DIRT) && position.getY() < 256 - i - 1) {
this.setDirtAt(worldIn, down);
for (int k1 = position.getY() - 3 + i; k1 <= position.getY() + i; ++k1) {
diff --git a/src/main/java/cn/nukkit/level/generator/object/tree/TreeGenerator.java b/src/main/java/cn/nukkit/level/generator/object/tree/TreeGenerator.java
index a60a6c07ac3..909c328850c 100644
--- a/src/main/java/cn/nukkit/level/generator/object/tree/TreeGenerator.java
+++ b/src/main/java/cn/nukkit/level/generator/object/tree/TreeGenerator.java
@@ -16,7 +16,7 @@ public abstract class TreeGenerator extends cn.nukkit.level.generator.object.Bas
* For example, a tree will not grow into stone
*/
protected boolean canGrowInto(int id) {
- return id == Item.AIR || id == Item.LEAVES || id == Item.GRASS || id == Item.DIRT || id == Item.LOG || id == Item.LOG2 || id == Item.SAPLING || id == Item.VINE;
+ return id == Item.AIR || id == Item.LEAVES || id == Item.GRASS_BLOCK || id == Item.DIRT || id == Item.LOG || id == Item.LOG2 || id == Item.SAPLING || id == Item.VINE;
}
public void generateSaplings(Level level, RandomSource random, Vector3 pos) {
diff --git a/src/main/java/cn/nukkit/level/generator/populator/helper/EnsureGrassBelow.java b/src/main/java/cn/nukkit/level/generator/populator/helper/EnsureGrassBelow.java
index 773ea9f794a..0606b6c3bfa 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/helper/EnsureGrassBelow.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/helper/EnsureGrassBelow.java
@@ -2,13 +2,13 @@
import cn.nukkit.level.format.FullChunk;
-import static cn.nukkit.block.BlockID.GRASS;
+import static cn.nukkit.block.BlockID.GRASS_BLOCK;
/**
* @author DaPorkchop_
*/
public interface EnsureGrassBelow {
static boolean ensureGrassBelow(int x, int y, int z, FullChunk chunk) {
- return EnsureBelow.ensureBelow(x, y, z, GRASS, chunk);
+ return EnsureBelow.ensureBelow(x, y, z, GRASS_BLOCK, chunk);
}
}
diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/MushroomPopulator.java b/src/main/java/cn/nukkit/level/generator/populator/impl/MushroomPopulator.java
index 035502aba2e..280db6eef80 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/impl/MushroomPopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/impl/MushroomPopulator.java
@@ -39,7 +39,7 @@ protected int getHighestWorkableBlock(ChunkManager level, int x, int z, FullChun
z &= 0xF;
for (y = 254; y > 0; --y) {
int b = chunk.getBlockId(0, x, y, z);
- if (b == Block.DIRT || b == Block.GRASS) {
+ if (b == Block.DIRT || b == Block.GRASS_BLOCK) {
break;
} else if (b != Block.AIR && b != Block.SNOW_LAYER) {
return -1;
diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorCaves.java b/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorCaves.java
index 45b131519b5..e44bf4da030 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorCaves.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorCaves.java
@@ -187,7 +187,7 @@ protected void generateCaveNode(long seed, FullChunk chunk, double x, double y,
int material = chunk.getBlockId(0, xx, yy, zz);
// int materialAbove = chunk.getBlockId(0, xx, yy + 1, zz);
- if (material == Block.GRASS || material == Block.MYCELIUM) {
+ if (material == Block.GRASS_BLOCK || material == Block.MYCELIUM) {
grassFound = true;
}
//TODO: check this
@@ -266,7 +266,7 @@ public static boolean isDiggable(int block, int above) {
}
case STONE:
case DIRT:
- case GRASS:
+ case GRASS_BLOCK:
case HARDENED_CLAY:
case STAINED_HARDENED_CLAY:
case SANDSTONE:
diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorRavines.java b/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorRavines.java
index 91b7b86ccc9..71e57761ebc 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorRavines.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorRavines.java
@@ -218,7 +218,7 @@ protected boolean carve(FullChunk chunk, double startX, double startY, double st
int block = chunk.getBlockId(0, xx, yy, zz);
int above = chunk.getBlockId(0, xx, yy + 1, zz);
- if (block == GRASS) {
+ if (block == GRASS_BLOCK) {
hasGrass = true;
}
@@ -235,7 +235,7 @@ protected boolean carve(FullChunk chunk, double startX, double startY, double st
chunk.setBlock(0, xx, yy, zz, AIR);
if (hasGrass && chunk.getBlockId(0, xx, yy - 1, zz) == DIRT) {
- chunk.setBlock(0, xx, yy - 1, zz, GRASS);
+ chunk.setBlock(0, xx, yy - 1, zz, GRASS_BLOCK);
}
} else {
chunk.setBlock(0, xx, yy, zz, LAVA);
diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorTree.java b/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorTree.java
index 276ce737acc..83939791e84 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorTree.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/impl/PopulatorTree.java
@@ -39,7 +39,7 @@ private int getHighestWorkableBlock(ChunkManager level, int x, int z) {
int y;
for (y = 254; y > 0; --y) {
int b = level.getBlockIdAt(0, x, y, z);
- if (b == Block.DIRT || b == Block.GRASS) {
+ if (b == Block.DIRT || b == Block.GRASS_BLOCK) {
break;
} else if (b != Block.AIR && b != Block.SNOW_LAYER) {
return -1;
diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/DarkOakTreePopulator.java b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/DarkOakTreePopulator.java
index 709980f9e8a..abad860cf3b 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/DarkOakTreePopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/DarkOakTreePopulator.java
@@ -54,7 +54,7 @@ private int getHighestWorkableBlock(int x, int z) {
int y;
for (y = 255; y > 0; --y) {
int b = this.level.getBlockIdAt(0, x, y, z);
- if (b == Block.DIRT || b == Block.GRASS) {
+ if (b == Block.DIRT || b == Block.GRASS_BLOCK) {
break;
} else if (b != Block.AIR && b != Block.SNOW_LAYER) {
return -1;
diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/JungleBigTreePopulator.java b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/JungleBigTreePopulator.java
index bdd48ed323f..2f7a342d075 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/JungleBigTreePopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/JungleBigTreePopulator.java
@@ -53,7 +53,7 @@ private int getHighestWorkableBlock(int x, int z) {
int y;
for (y = 255; y > 0; --y) {
int b = this.level.getBlockIdAt(0, x, y, z);
- if (b == Block.DIRT || b == Block.GRASS) {
+ if (b == Block.DIRT || b == Block.GRASS_BLOCK) {
break;
} else if (b != Block.AIR && b != Block.SNOW_LAYER) {
return -1;
diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/JungleFloorPopulator.java b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/JungleFloorPopulator.java
index 8728271b928..89fa533bfbd 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/JungleFloorPopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/JungleFloorPopulator.java
@@ -58,7 +58,7 @@ private int getHighestWorkableBlock(int x, int z) {
int y;
for (y = 255; y > 0; --y) {
int b = this.level.getBlockIdAt(0, x, y, z);
- if (b == Block.DIRT || b == Block.GRASS) {
+ if (b == Block.DIRT || b == Block.GRASS_BLOCK) {
break;
} else if (b != Block.AIR && b != Block.SNOW_LAYER) {
return -1;
diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/JungleTreePopulator.java b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/JungleTreePopulator.java
index 21ab92c5efc..795205d4119 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/JungleTreePopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/JungleTreePopulator.java
@@ -53,7 +53,7 @@ private int getHighestWorkableBlock(int x, int z) {
int y;
for (y = 255; y > 0; --y) {
int b = this.level.getBlockIdAt(0, x, y, z);
- if (b == Block.DIRT || b == Block.GRASS) {
+ if (b == Block.DIRT || b == Block.GRASS_BLOCK) {
break;
} else if (b != Block.AIR && b != Block.SNOW_LAYER) {
return -1;
diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SavannaTreePopulator.java b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SavannaTreePopulator.java
index 7fae7f9ae0a..3abf984f760 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SavannaTreePopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SavannaTreePopulator.java
@@ -54,7 +54,7 @@ private int getHighestWorkableBlock(int x, int z) {
int y;
for (y = 127; y > 0; --y) {
int b = this.level.getBlockIdAt(0, x, y, z);
- if (b == Block.DIRT || b == Block.GRASS) {
+ if (b == Block.DIRT || b == Block.GRASS_BLOCK) {
break;
} else if (b != Block.AIR && b != Block.SNOW_LAYER) {
return -1;
diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SpruceBigTreePopulator.java b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SpruceBigTreePopulator.java
index a3fe99d1f0d..ed52c96cd13 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SpruceBigTreePopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SpruceBigTreePopulator.java
@@ -54,7 +54,7 @@ private int getHighestWorkableBlock(int x, int z) {
int y;
for (y = 255; y > 0; --y) {
int b = this.level.getBlockIdAt(0, x, y, z);
- if (b == Block.DIRT || b == Block.GRASS) {
+ if (b == Block.DIRT || b == Block.GRASS_BLOCK) {
break;
} else if (b != Block.AIR && b != Block.SNOW_LAYER) {
return -1;
diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SpruceMegaTreePopulator.java b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SpruceMegaTreePopulator.java
index 14f8fd486b5..0fb21c5846f 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SpruceMegaTreePopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SpruceMegaTreePopulator.java
@@ -56,7 +56,7 @@ private int getHighestWorkableBlock(int x, int z) {
int y;
for (y = 255; y > 0; --y) {
int b = this.level.getBlockIdAt(0, x, y, z);
- if (b == Block.DIRT || b == Block.GRASS) {
+ if (b == Block.DIRT || b == Block.GRASS_BLOCK) {
break;
} else if (b != Block.AIR && b != Block.SNOW_LAYER) {
return -1;
diff --git a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SwampTreePopulator.java b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SwampTreePopulator.java
index 4233cda8b74..8bfd0795f1c 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SwampTreePopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/impl/tree/SwampTreePopulator.java
@@ -53,7 +53,7 @@ private int getHighestWorkableBlock(int x, int z) {
int y;
for (y = 127; y > 0; --y) {
int b = this.level.getBlockIdAt(0, x, y, z);
- if (b == Block.DIRT || b == Block.GRASS) {
+ if (b == Block.DIRT || b == Block.GRASS_BLOCK) {
break;
} else if (b != Block.AIR && b != Block.SNOW_LAYER) {
return -1;
diff --git a/src/main/java/cn/nukkit/level/particle/ParticleID.java b/src/main/java/cn/nukkit/level/particle/ParticleID.java
index 4eb949d7eed..3fd11e67d29 100644
--- a/src/main/java/cn/nukkit/level/particle/ParticleID.java
+++ b/src/main/java/cn/nukkit/level/particle/ParticleID.java
@@ -89,7 +89,8 @@ public interface ParticleID {
int CHERRY_LEAVES = 86;
int DUST_PLUME = 87;
int WHITE_SMOKE = 88;
+ int WIND_EXPLOSION = 89;
- int UNDEFINED = 89;
+ int UNDEFINED = 90;
}
diff --git a/src/main/java/cn/nukkit/level/sound/SoundEnum.java b/src/main/java/cn/nukkit/level/sound/SoundEnum.java
index 51a45b5e01c..209f62287f6 100644
--- a/src/main/java/cn/nukkit/level/sound/SoundEnum.java
+++ b/src/main/java/cn/nukkit/level/sound/SoundEnum.java
@@ -1232,6 +1232,8 @@ public enum SoundEnum {
TILT_DOWN_BIG_DRIPLEAF("tilt_down.big_dripleaf"),
TILT_UP_BIG_DRIPLEAF("tilt_up.big_dripleaf"),
UI_CARTOGRAPHY_TABLE_TAKE_RESULT("ui.cartography_table.take_result"),
+ UI_DRAWER_CLOSE("ui.drawer_close"),
+ UI_DRAWER_OPEN("ui.drawer_open"),
UI_LOOM_SELECT_PATTERN("ui.loom.select_pattern"),
UI_LOOM_TAKE_RESULT("ui.loom.take_result"),
UI_STONECUTTER_TAKE_RESULT("ui.stonecutter.take_result"),
diff --git a/src/main/java/cn/nukkit/network/CompressionAlgorithm.java b/src/main/java/cn/nukkit/network/CompressionAlgorithm.java
new file mode 100644
index 00000000000..39224a1eaa5
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/CompressionAlgorithm.java
@@ -0,0 +1,16 @@
+package cn.nukkit.network;
+
+public interface CompressionAlgorithm {
+ /**
+ * @since 1.20.60
+ */
+ byte NONE = -1;
+ /**
+ * zlib raw
+ */
+ byte ZLIB = 0;
+ /**
+ * snappy raw
+ */
+ byte SNAPPY = 1;
+}
diff --git a/src/main/java/cn/nukkit/network/Compressor.java b/src/main/java/cn/nukkit/network/Compressor.java
new file mode 100644
index 00000000000..2562b3736f0
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/Compressor.java
@@ -0,0 +1,155 @@
+package cn.nukkit.network;
+
+import cn.nukkit.utils.DataLengthException;
+import cn.nukkit.utils.Zlib;
+import org.xerial.snappy.Snappy;
+
+import javax.annotation.Nullable;
+import java.io.IOException;
+import java.util.zip.DataFormatException;
+
+public enum Compressor {
+ NONE {
+ @Override
+ public byte[] compress(byte[] data, int level) {
+ return data;
+ }
+
+ @Override
+ public byte[] decompress(byte[] data) throws IOException {
+ if (data.length >= MAX_SIZE) {
+ throw new DataLengthException("Data exceeds maximum size");
+ }
+ return data;
+ }
+
+ @Override
+ public byte getAlgorithm() {
+ return CompressionAlgorithm.NONE;
+ }
+ },
+ ZLIB {
+ @Override
+ public byte[] compress(byte[] data, int level) throws IOException {
+ return Zlib.deflate(data, level);
+ }
+
+ @Override
+ public byte[] decompress(byte[] data) throws IOException {
+ return Zlib.inflate(data, MAX_SIZE);
+ }
+
+ @Override
+ public byte getAlgorithm() {
+ return CompressionAlgorithm.ZLIB;
+ }
+ },
+ ZLIB_RAW {
+ @Override
+ public byte[] compress(byte[] data, int level) throws IOException {
+ return Network.deflateRaw(data, level);
+ }
+
+ @Override
+ public byte[] decompress(byte[] data) throws IOException, DataFormatException {
+ return Network.inflateRaw(data, MAX_SIZE);
+ }
+
+ @Override
+ public byte getAlgorithm() {
+ return CompressionAlgorithm.ZLIB;
+ }
+ },
+ ZLIB_UNKNOWN {
+ @Override
+ public byte[] compress(byte[] data, int level) throws IOException {
+ return ZLIB_RAW.compress(data, level);
+ }
+
+ @Override
+ public byte[] decompress(byte[] data) throws IOException {
+ try {
+ return ZLIB_RAW.decompress(data);
+ } catch (DataLengthException e) {
+ throw e;
+ } catch (Exception e) {
+ try {
+ return ZLIB.decompress(data);
+ } catch (Exception ex) {
+ return EMPTY;
+ }
+ }
+ }
+
+ @Override
+ public byte getAlgorithm() {
+ return CompressionAlgorithm.ZLIB;
+ }
+ },
+ SNAPPY {
+ @Override
+ public byte[] compress(byte[] data, int level) throws IOException {
+ int inputLength = data.length;
+ int maxOutputLength = Snappy.maxCompressedLength(inputLength);
+ byte[] buffer = new byte[maxOutputLength];
+ int outputLength = Snappy.compress(data, 0, inputLength, buffer, 0);
+ if (outputLength == maxOutputLength) {
+ return buffer;
+ }
+ byte[] result = new byte[outputLength];
+ System.arraycopy(buffer, 0, result, 0, outputLength);
+ return result;
+ }
+
+ @Override
+ public byte[] decompress(byte[] data) throws IOException {
+ int inputLength = data.length;
+ if (inputLength >= MAX_SIZE) {
+ throw new DataLengthException("Input data exceeds maximum size");
+ }
+ int maxOutputLength = Snappy.uncompressedLength(data);
+ if (maxOutputLength >= MAX_SIZE) {
+ throw new DataLengthException("Inflated buffer exceeds maximum size");
+ }
+// if (!Snappy.isValidCompressedBuffer(data)) {
+// throw new IOException("Invalid input data");
+// }
+ byte[] buffer = new byte[maxOutputLength];
+ int outputLength = Snappy.uncompress(data, 0, inputLength, buffer, 0);
+ if (outputLength == maxOutputLength) {
+ return buffer;
+ }
+ if (outputLength >= MAX_SIZE) {
+ throw new DataLengthException("Inflated data exceeds maximum size");
+ }
+ byte[] result = new byte[outputLength];
+ System.arraycopy(buffer, 0, result, 0, outputLength);
+ return result;
+ }
+
+ @Override
+ public byte getAlgorithm() {
+ return CompressionAlgorithm.SNAPPY;
+ }
+ };
+
+ public static final int MAX_SIZE = 12 * 1024 * 1024; // 12MB
+
+ private static final byte[] EMPTY = new byte[0];
+
+ public abstract byte[] compress(byte[] data, int level) throws IOException;
+
+ public abstract byte[] decompress(byte[] data) throws IOException, DataFormatException;
+
+ public abstract byte getAlgorithm();
+
+ @Nullable
+ public static Compressor get(byte algorithm) {
+ return switch (algorithm) {
+ case CompressionAlgorithm.ZLIB -> Compressor.ZLIB_RAW;
+ case CompressionAlgorithm.SNAPPY -> Compressor.SNAPPY;
+ case CompressionAlgorithm.NONE -> Compressor.NONE;
+ default -> null;
+ };
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/Network.java b/src/main/java/cn/nukkit/network/Network.java
index 2320d1de025..3115593113e 100644
--- a/src/main/java/cn/nukkit/network/Network.java
+++ b/src/main/java/cn/nukkit/network/Network.java
@@ -6,6 +6,7 @@
import cn.nukkit.nbt.stream.FastByteArrayOutputStream;
import cn.nukkit.network.protocol.*;
import cn.nukkit.utils.BinaryStream;
+import cn.nukkit.utils.DataLengthException;
import cn.nukkit.utils.ThreadCache;
import cn.nukkit.utils.Utils;
import cn.nukkit.utils.VarInt;
@@ -71,10 +72,10 @@ public Network(Server server) {
public static byte[] inflateRaw(byte[] data, int maxSize) throws IOException, DataFormatException {
if (data.length == 0) {
- throw new IOException("no data");
+ throw new DataLengthException("no data");
}
if (maxSize > 0 && data.length >= maxSize) {
- throw new IOException("Input data exceeds maximum size");
+ throw new DataLengthException("Input data exceeds maximum size");
}
Inflater inflater = INFLATER_RAW.get();
try {
@@ -93,7 +94,7 @@ public static byte[] inflateRaw(byte[] data, int maxSize) throws IOException, Da
}
length += i;
if (maxSize > 0 && length >= maxSize) {
- throw new IOException("Inflated data exceeds maximum size");
+ throw new DataLengthException("Inflated data exceeds maximum size");
}
bos.write(buf, 0, i);
}
@@ -366,6 +367,7 @@ private void registerPackets() {
this.registerPacket(ProtocolInfo.BOSS_EVENT_PACKET, BossEventPacket.class);
// this.registerPacket(ProtocolInfo.CHANGE_DIMENSION_PACKET, ChangeDimensionPacket.class);
this.registerPacket(ProtocolInfo.CHUNK_RADIUS_UPDATED_PACKET, ChunkRadiusUpdatedPacket.class);
+ this.registerPacket(ProtocolInfo.CLIENT_TO_SERVER_HANDSHAKE_PACKET, ClientToServerHandshakePacket.class);
// this.registerPacket(ProtocolInfo.CLIENTBOUND_MAP_ITEM_DATA_PACKET, ClientboundMapItemDataPacket.class);
this.registerPacket(ProtocolInfo.COMMAND_REQUEST_PACKET, CommandRequestPacket.class);
this.registerPacket(ProtocolInfo.CONTAINER_CLOSE_PACKET, ContainerClosePacket.class);
diff --git a/src/main/java/cn/nukkit/network/protocol/DisconnectPacket.java b/src/main/java/cn/nukkit/network/protocol/DisconnectPacket.java
index 71dbf932ae1..fffcd087ba0 100644
--- a/src/main/java/cn/nukkit/network/protocol/DisconnectPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/DisconnectPacket.java
@@ -30,7 +30,7 @@ public class DisconnectPacket extends DataPacket {
public static final int REASON_REALMS_SERVER_HIDDEN = 18;
public static final int REASON_REALMS_SERVER_DISABLED_BETA = 19;
public static final int REASON_REALMS_SERVER_DISABLED = 20;
- public static final int REASON_CROSS_PLATFORM_DISALLOWED = 21;
+ public static final int REASON_CROSS_PLATFORM_DISABLED = 21;
public static final int REASON_CANT_CONNECT = 22;
public static final int REASON_SESSION_NOT_FOUND = 23;
public static final int REASON_CLIENT_SETTINGS_INCOMPATIBLE_WITH_SERVER = 24;
@@ -112,6 +112,12 @@ public class DisconnectPacket extends DataPacket {
public static final int REASON_CONN_SIGNALING_UNICAST_DELIVERY_FAILED = 100;
public static final int REASON_CONN_SIGNALING_BROADCAST_DELIVERY_FAILED = 101;
public static final int REASON_CONN_SIGNALING_GENERIC_DELIVERY_FAILED = 102;
+ public static final int REASON_EDITOR_MISMATCH_EDITOR_WORLD = 103;
+ public static final int REASON_EDITOR_MISMATCH_VANILLA_WORLD = 104;
+ public static final int REASON_WORLD_TRANSFER_NOT_PRIMARY_CLIENT = 105;
+ public static final int REASON_SERVER_SHUTDOWN = 106;
+ public static final int REASON_GAME_SETUP_CANCELLED = 107;
+ public static final int REASON_GAME_SETUP_FAILED = 108;
public int reason = REASON_UNKNOWN;
public boolean hideDisconnectionScreen;
diff --git a/src/main/java/cn/nukkit/network/protocol/LevelChunkPacket.java b/src/main/java/cn/nukkit/network/protocol/LevelChunkPacket.java
index 74ce726d6e9..99d596ed584 100644
--- a/src/main/java/cn/nukkit/network/protocol/LevelChunkPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/LevelChunkPacket.java
@@ -28,6 +28,7 @@ public int pid() {
public int chunkX;
public int chunkZ;
+ public int dimension;
public int subChunkCount;
public boolean cacheEnabled;
public long[] blobIds;
diff --git a/src/main/java/cn/nukkit/network/protocol/LevelChunkPacket12060.java b/src/main/java/cn/nukkit/network/protocol/LevelChunkPacket12060.java
new file mode 100644
index 00000000000..7896c344834
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/LevelChunkPacket12060.java
@@ -0,0 +1,24 @@
+package cn.nukkit.network.protocol;
+
+public class LevelChunkPacket12060 extends LevelChunkPacket {
+ @Override
+ public void encode() {
+ this.reset();
+ this.putVarInt(this.chunkX);
+ this.putVarInt(this.chunkZ);
+ this.putVarInt(this.dimension);
+ this.putUnsignedVarInt(this.subChunkCount);
+ if (this.subChunkCount == CLIENT_REQUEST_TRUNCATED_COLUMN_FAKE_COUNT) {
+ this.putLShort(this.subChunkRequestLimit);
+ }
+ this.putBoolean(this.cacheEnabled);
+ if (this.cacheEnabled) {
+ this.putUnsignedVarInt(this.blobIds.length);
+
+ for (long blobId : this.blobIds) {
+ this.putLLong(blobId);
+ }
+ }
+ this.putByteArray(this.data);
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java b/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java
index 76b4f7994f6..7c9b99ca264 100644
--- a/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java
@@ -131,6 +131,10 @@ public class LevelEventPacket extends DataPacket {
public static final int EVENT_PARTICLE_PUNCH_BLOCK_WEST = 3607;
public static final int EVENT_PARTICLE_PUNCH_BLOCK_EAST = 3608;
public static final int EVENT_PARTICLE_SHOOT_WHITE_SMOKE = 3609;
+ public static final int EVENT_PARTICLE_WIND_EXPLOSION = 3610;
+ public static final int EVENT_PARTICLE_TRAIL_SPAWNER_DETECTION = 3611;
+ public static final int EVENT_PARTICLE_TRAIL_SPAWNER_SPAWNING = 3612;
+ public static final int EVENT_PARTICLE_TRAIL_SPAWNER_EJECTING = 3613;
public static final int EVENT_SET_DATA = 4000;
diff --git a/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java b/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java
index 73d6763daab..da7d5c7d462 100644
--- a/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java
@@ -492,6 +492,14 @@ public class LevelSoundEventPacket extends DataPacket {
public static final int SOUND_COPPER_BULB_ON = 490;
public static final int SOUND_COPPER_BULB_OFF = 491;
+ public static final int SOUND_AMBIENT_IN_AIR = 492;
+ public static final int SOUND_WIND_BURST = 493;
+ public static final int SOUND_IMITATE_BREEZE = 494;
+ public static final int SOUND_ARMADILLO_BRUSH = 495;
+ public static final int SOUND_ARMADILLO_SCUTE_DROP = 496;
+ public static final int SOUND_EQUIP_WOLF = 497;
+ public static final int SOUND_UNEQUIP_WOLF = 498;
+ public static final int SOUND_REFLECT = 499;
public int sound;
public float x;
diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
index 03e1f5e5718..0a1e2e4e27c 100644
--- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
+++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
@@ -32,6 +32,7 @@ public interface ProtocolInfo {
int REMOVE_ACTOR_PACKET = 0x0e; // 14 c
int ADD_ITEM_ACTOR_PACKET = 0x0f; // 15 c
int ADD_HANGING_ACTOR_PACKET = 0x10; // 16 c D
+ int SERVER_PLAYER_POST_MOVE_POSITION_PACKET = 0x10; // 16 c
int TAKE_ITEM_ACTOR_PACKET = 0x11; // 17 c
int MOVE_ACTOR_ABSOLUTE_PACKET = 0x12; // 18 cs
int MOVE_PLAYER_PACKET = 0x13; // 19 cs
@@ -87,7 +88,7 @@ public interface ProtocolInfo {
int MAP_INFO_REQUEST_PACKET = 0x44; // 68 s
int REQUEST_CHUNK_RADIUS_PACKET = 0x45; // 69 s
int CHUNK_RADIUS_UPDATED_PACKET = 0x46; // 70 c
- int ITEM_FRAME_DROP_ITEM_PACKET = 0x47; // 71 s
+ int ITEM_FRAME_DROP_ITEM_PACKET = 0x47; // 71 s D
int GAME_RULES_CHANGED_PACKET = 0x48; // 72 c
int CAMERA_PACKET = 0x49; // 73 c
int BOSS_EVENT_PACKET = 0x4a; // 74 cs
@@ -143,8 +144,8 @@ public interface ProtocolInfo {
int LEVEL_EVENT_GENERIC_PACKET = 0x7c; // 124 c
int LECTERN_UPDATE_PACKET = 0x7d; // 125 s
int VIDEO_STREAM_CONNECT_PACKET = 0x7e; // 126 c D
- int ADD_ENTITY_PACKET = 0x7f; // 127 c
- int REMOVE_ENTITY_PACKET = 0x80; // 128 c
+ int ADD_ENTITY_PACKET = 0x7f; // 127 c D
+ int REMOVE_ENTITY_PACKET = 0x80; // 128 c D
int CLIENT_CACHE_STATUS_PACKET = 0x81; // 129 s
int ON_SCREEN_TEXTURE_ANIMATION_PACKET = 0x82; // 130 c
int MAP_CREATE_LOCKED_COPY_PACKET = 0x83; // 131 s
diff --git a/src/main/java/cn/nukkit/utils/DataLengthException.java b/src/main/java/cn/nukkit/utils/DataLengthException.java
new file mode 100644
index 00000000000..d1640e5d76e
--- /dev/null
+++ b/src/main/java/cn/nukkit/utils/DataLengthException.java
@@ -0,0 +1,21 @@
+package cn.nukkit.utils;
+
+import java.io.IOException;
+
+public class DataLengthException extends IOException {
+ public DataLengthException() {
+ super();
+ }
+
+ public DataLengthException(String message) {
+ super(message);
+ }
+
+ public DataLengthException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DataLengthException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/src/main/java/cn/nukkit/utils/Zlib.java b/src/main/java/cn/nukkit/utils/Zlib.java
index 861865e2cae..3c26f4bd249 100644
--- a/src/main/java/cn/nukkit/utils/Zlib.java
+++ b/src/main/java/cn/nukkit/utils/Zlib.java
@@ -44,11 +44,11 @@ public static byte[] deflate(byte[] data) throws Exception {
return deflate(data, Deflater.DEFAULT_COMPRESSION);
}
- public static byte[] deflate(byte[] data, int level) throws Exception {
+ public static byte[] deflate(byte[] data, int level) throws IOException {
return provider.deflate(data, level);
}
- public static byte[] deflate(byte[][] data, int level) throws Exception {
+ public static byte[] deflate(byte[][] data, int level) throws IOException {
return provider.deflate(data, level);
}
diff --git a/src/main/java/cn/nukkit/utils/ZlibOriginal.java b/src/main/java/cn/nukkit/utils/ZlibOriginal.java
index e43c3edc8bf..0593eb8d637 100644
--- a/src/main/java/cn/nukkit/utils/ZlibOriginal.java
+++ b/src/main/java/cn/nukkit/utils/ZlibOriginal.java
@@ -56,10 +56,10 @@ public byte[] deflate(byte[] data, int level) throws IOException {
@Override
public byte[] inflate(byte[] data, int maxSize) throws IOException {
if (data.length == 0) {
- throw new IOException("no data");
+ throw new DataLengthException("no data");
}
if (maxSize > 0 && data.length >= maxSize) {
- throw new IOException("Input data exceeds maximum size");
+ throw new DataLengthException("Input data exceeds maximum size");
}
Inflater inflater = new Inflater();
inflater.setInput(data);
@@ -77,7 +77,7 @@ public byte[] inflate(byte[] data, int maxSize) throws IOException {
}
length += i;
if (maxSize > 0 && length >= maxSize) {
- throw new IOException("Inflated data exceeds maximum size");
+ throw new DataLengthException("Inflated data exceeds maximum size");
}
bos.write(buffer, 0, i);
}
diff --git a/src/main/java/cn/nukkit/utils/ZlibSingleThreadLowMem.java b/src/main/java/cn/nukkit/utils/ZlibSingleThreadLowMem.java
index 64b18f0f1ca..7bee151c7e6 100644
--- a/src/main/java/cn/nukkit/utils/ZlibSingleThreadLowMem.java
+++ b/src/main/java/cn/nukkit/utils/ZlibSingleThreadLowMem.java
@@ -55,10 +55,10 @@ public synchronized byte[] deflate(byte[] data, int level) throws IOException {
@Override
public synchronized byte[] inflate(byte[] data, int maxSize) throws IOException {
if (data.length == 0) {
- throw new IOException("no data");
+ throw new DataLengthException("no data");
}
if (maxSize > 0 && data.length >= maxSize) {
- throw new IOException("Input data exceeds maximum size");
+ throw new DataLengthException("Input data exceeds maximum size");
}
INFLATER.reset();
INFLATER.setInput(data);
@@ -74,7 +74,7 @@ public synchronized byte[] inflate(byte[] data, int maxSize) throws IOException
}
length += i;
if (maxSize > 0 && length >= maxSize) {
- throw new IOException("Inflated data exceeds maximum size");
+ throw new DataLengthException("Inflated data exceeds maximum size");
}
bos.write(BUFFER, 0, i);
}
diff --git a/src/main/java/cn/nukkit/utils/ZlibThreadLocal.java b/src/main/java/cn/nukkit/utils/ZlibThreadLocal.java
index b2cbbf16635..c674cbdb0ed 100644
--- a/src/main/java/cn/nukkit/utils/ZlibThreadLocal.java
+++ b/src/main/java/cn/nukkit/utils/ZlibThreadLocal.java
@@ -61,10 +61,10 @@ public byte[] deflate(byte[] data, int level) throws IOException {
@Override
public byte[] inflate(byte[] data, int maxSize) throws IOException {
if (data.length == 0) {
- throw new IOException("no data");
+ throw new DataLengthException("no data");
}
if (maxSize > 0 && data.length >= maxSize) {
- throw new IOException("Input data exceeds maximum size");
+ throw new DataLengthException("Input data exceeds maximum size");
}
Inflater inflater = INFLATER.get();
try {
@@ -83,7 +83,7 @@ public byte[] inflate(byte[] data, int maxSize) throws IOException {
}
length += i;
if (maxSize > 0 && length >= maxSize) {
- throw new IOException("Inflated data exceeds maximum size");
+ throw new DataLengthException("Inflated data exceeds maximum size");
}
bos.write(buffer, 0, i);
}
diff --git a/src/main/resources/vanilla_texts/en_US.lang b/src/main/resources/vanilla_texts/en_US.lang
index 1bdceb91d8f..683dc4e0aa7 100644
--- a/src/main/resources/vanilla_texts/en_US.lang
+++ b/src/main/resources/vanilla_texts/en_US.lang
@@ -948,12 +948,15 @@ commands.generic.exception=An unknown error occurred while attempting to perform
commands.generic.invalidAgentType=Type argument applied to Agent-only selector
commands.generic.invalidcontext=Invalid context provided for given command type
commands.generic.invalidDevice=The command you entered, %s, is not supported on this device
+commands.generic.invalidMessage=Invalid message length
commands.generic.invalidPlayerType=Type argument applied to player-only selector
commands.generic.invalidType=Unknown type argument
commands.generic.levelError=Max level has to be larger than min level
commands.generic.malformed.body=Body is missing or malformed
commands.generic.malformed.type=Invalid request type
commands.generic.notimplemented=Not implemented
+commands.generic.sourceNotLoaded=Source volume is not loaded
+commands.generic.destinationNotLoaded=Destination volume is not loaded
commands.generic.num.invalid='%1$s' is not a valid number
commands.generic.num.tooBig=The number you have entered (%1$d) is too big, it must be at most %2$d
commands.generic.num.tooSmall=The number you have entered (%1$d) is too small, it must be at least %2$d
@@ -1005,6 +1008,8 @@ commands.help.description=Provides help/list of commands.
commands.help.footer=Tip: Use the key while typing a command to auto-complete the command or its arguments
commands.help.header=--- Showing help page %1$d of %2$d (/help ) ---
commands.help.command.aliases=%s (also %s):
+commands.hud.description=Changes the visibility of hud elements.
+commands.hud.success=Hud command successfully executed
commands.immutableworld.description=Sets the immutable state of the world.
commands.immutableworld.info=immutableworld = %s
commands.inputpermission.description=Sets whether or not a player's input can affect their character.
@@ -1148,7 +1153,9 @@ commands.recipes.playerDoesNotHaveRecipe=%1$s does not have the recipe: %2$s
commands.recipes.notFound=The recipe could not be found.
commands.recipes.notUnlockable=The recipe is not unlockable in the recipe book.
commands.reload.description=Reloads all function and script files from all behavior packs.
+commands.reload.editor.description=Reloads all function and script files from all behavior packs, or optionally restarts the client to reload all resources.
commands.reload.success=Function and script files have been reloaded.
+commands.reload.error=An unexpected error occurred.
commands.replaceitem.description=Replaces items in inventories.
commands.replaceitem.failed=Could not replace %s slot %d with %d * %s
commands.replaceitem.keepFailed=There is already an item occupying %s slot %d.
@@ -1312,6 +1319,8 @@ commands.spawnpoint.description=Sets the spawn point for a player.
commands.spawnpoint.success.multiple.specific=Set spawn point for %1$s to (%2$d, %3$d, %4$d)
commands.spawnpoint.success.multiple.generic=Set spawn point for %1$s
commands.spawnpoint.wrongDimension=The spawn point cannot be set in this dimension
+commands.clearrealmevents.description=Clears all Realm Events stored in the world data.
+commands.clearrealmevents.start=Clearing all Realm Events
commands.clearspawnpoint.success.single=Removed %1$s's spawn point
commands.clearspawnpoint.description=Removes the spawn point for a player.
commands.clearspawnpoint.success.multiple=Removed spawn points for %1$s
@@ -1877,6 +1886,8 @@ createWorldScreen.experimentalUpdateAnnounced2023=Update 1.21
createWorldScreen.experimentalUpdateAnnounced2023Description=New features and content for Minecraft 1.21
createWorldScreen.experimentalVillagerTradesRebalance=Villager Trade Rebalancing
createWorldScreen.experimentalVillagerTradesRebalanceDescription=Contains updated trades for villagers for the purpose of rebalancing
+createWorldScreen.experimentalArmadillo=Armadillo and Wolf Armor
+createWorldScreen.experimentalArmadilloDescription=Get to know the Armadillo and gear up your Wolf with the new Wolf Armor!
createWorldScreen.worldPreferences=World Preferences
createWorldScreen.startWithMap=Starting Map
createWorldScreen.defaultName=My World
@@ -2152,6 +2163,11 @@ realmsPlusUpgradeNotice.body=Your Realms subscription has been upgraded to Realm
realmsPlusUpgradeNotice.continue=Continue
realmsPlusUpgradeNotice.viewpacks=View Realms Plus Packs
+csbCreateScreen.popupTitle=Marketplace Pass ### {StrContains="Marketplace Pass"}
+csbCreateScreen.viewTOS=To view the terms and conditions for Marketplace Pass, please visit https://aka.ms/MinecraftEULA in any web browser. ### {StrContains="Marketplace Pass"}
+csbCreateScreen.viewPrivacyPolicyText=To view the privacy policy for Marketplace Pass, please visit https://aka.ms/mcprivacy in any web browser. ### {StrContains="Marketplace Pass"}
+csbCreateScreen.goBack=Go back
+
csbCreateScreen.termsAndConditionsAgree=I agree
csbCreateScreen.termsAndConditionsHeader=Terms and Conditions
@@ -2340,7 +2356,7 @@ realmsSettingsScreen.xboxOneStoreDisplayName=Xbox Store
realmsSettingsScreen.amazonStoreDisplayName=Amazon Appstore
realmsSettingsScreen.oculusStoreDisplayName=Oculus Store
realmsSettingsScreen.berwickStoreDisplayName="PlayStation Store"
-realmsSettingsScreen.PS4StoreDisplayName="PlayStation Store" ### CertRequirement: ["PlayStation Store"]
+realmsSettingsScreen.SonyStoreDisplayName="PlayStation Store" ### CertRequirement: ["PlayStation Store"]
realmsSettingsScreen.unknownStoreDisplayName=unknown store
realmsSettingsScreen.extendingRealm=Extending Realm...
realmsSettingsScreen.offerError.title=Purchase Pending
@@ -2533,6 +2549,7 @@ deathScreen.quit=Main menu
deathScreen.quit.confirm=Are you sure you want to quit?
deathScreen.quit.confirmToMainMenuWarning=Are you sure you want to exit the game to the main menu?
deathScreen.quit.confirmToMainMenuTitleWarning=Quit to Main Menu?
+deathScreen.quit.eduCloud.confirmLeaveWarning=Are you sure you want to save and leave the game?%sWe’ll upload your world to the cloud too!
deathScreen.quit.secondaryClient=Save and Leave
deathScreen.quit.secondaryClient.confirmLeaveWarning=Are you sure you want to save and leave the game?
deathScreen.quit.secondaryClient.confirmLeaveTitleWarning=Save and Leave
@@ -2915,6 +2932,7 @@ exports.share.file=Share %s
exports.suspendWarning.client.content=Warning: If you continue, you will be disconnected from this multiplayer session.
exports.suspendWarning.host.content=Warning: If you continue, this will end the multiplayer session for all players.
exports.suspendWarning.title=Warning
+exports.eduCloud.suspendWarning.host.content=Are you sure you want to save and leave the game?%1Warning: If you do, this will end the multiplayer session for all players.%1We'll upload your world to the cloud too!
exports.fileError.title=Unable to save your file
exports.fileError.body=The disk may be full or write-protected or the file may be in use. Please check to make sure the file is not open and try again.
@@ -3012,11 +3030,11 @@ gameMode.hardcore=Hardcore Mode!
gameMode.spectator=Spectator Mode
gameMode.survival=Survival Mode
-gameTip.cameraMovement.mouse=Look around. Use your mouse to turn
+gameTip.cameraMovement.mouse=Look around[LINEBREAK]Use your mouse to turn ### {StrContains='LINEBREAK'}
gameTip.cameraMovement.touch=Touch and drag the screen to look around
gameTip.cameraMovement.controller=Move :tip_right_stick: to look around
-gameTip.playerMovement.mouse=Move with :_input_key.forward:, :_input_key.left:, :_input_key.back:, :_input_key.right:. Jump with space
+gameTip.playerMovement.mouse=Move with :_input_key.forward:, :_input_key.left:, :_input_key.back:, :_input_key.right:
gameTip.playerMovement.touch=Move by using the joystick
gameTip.playerMovement.touch.classic=Move by using the joystick
gameTip.playerMovement.controller=Move :tip_left_stick: to move around
@@ -3034,15 +3052,20 @@ gameTip.placeBlock.mouse=Click to place block
gameTip.placeBlock.touch=Tap to place block
gameTip.placeBlock.controller=Click on the ground to place block
-gameTip.openInventory.mouse=Open your inventory. Press :_input_key.inventory:
-gameTip.openInventory.touch=Open inventory to see crafting recipes
-gameTip.openInventory.controller=Press :_input_key.inventory: to open your inventory
+gameTip.openInventorySurvival.mouse=Open your inventory[LINEBREAK]Press :_input_key.inventory: ### {StrContains='LINEBREAK'}
+gameTip.openInventorySurvival.touch=Open inventory to see crafting recipes
+gameTip.openInventorySurvival.controller=Press :_input_key.inventory: to open your inventory
+
+gameTip.openInventoryCreative.mouse=Open your inventory[LINEBREAK]Press :_input_key.inventory: ### {StrContains='LINEBREAK'}
+gameTip.openInventoryCreative.touch=Open inventory to see building blocks
+gameTip.openInventoryCreative.controller=Press :_input_key.inventory: to open your inventory
+
gameTip.sneak.mouse=You are sneaking! Can’t fall off edges now
gameTip.sneak.touch=You're sneaking, so you can't fall off edges
gameTip.sneak.controller=You're sneaking, so you can't fall off edges
-gameTip.placeCraftingTable.mouse=Place your crafting table. Hold it and click to place
+gameTip.placeCraftingTable.mouse=Place your crafting table[LINEBREAK]Hold it and click to place ### {StrContains='LINEBREAK'}
gameTip.placeCraftingTable.touch=Place your crafting table by tapping the ground
gameTip.placeCraftingTable.controller=Place your crafting table, hold it then tap the ground
@@ -3256,7 +3279,7 @@ howtoplay.beacons=Beacons
howtoplay.beacons.text.1=Active Beacons project a bright beam of light into the sky.
howtoplay.beacons.text.2=They are crafted with Glass, Obsidian, and Nether Stars (which is obtained by defeating the Wither).
howtoplay.beacons.header.1=Construction
-howtoplay.beacons.text.3=Beacons must be placed so that they have an unobstructed view of the sky and must be placed on Pyramids of Iron, Gold, Emerald, or Diamond blocks.
+howtoplay.beacons.text.3=Beacons need to be on top of a Pyramid of Iron, Gold, Emerald, Diamond, or Netherite blocks with an unobstructed view of the sky.
howtoplay.beacons.text.4=The material that the Beacon is placed on has no effect on the power of the Beacon.
howtoplay.beacons.header.2=Use
howtoplay.beacons.text.5=In the Beacon menu you can select one primary power for your Beacon. The more tiers your pyramid has the more powers you can have.
@@ -3355,7 +3378,7 @@ howtoplay.commands.text.1=Commands can be executed from Chat. Type / before you
howtoplay.commands.text.2=There are multitudes of commands that will allow you to do amazing things. There are many sources out there that will provide you with all of the info that you'll ever need.
howtoplay.conduits=Conduits
-howtoplay.conduits.text.1=An active Conduit gives you powers when you are underwater.
+howtoplay.conduits.text.1=An active Conduit gives you powers when you are underwater and when it rains.
howtoplay.conduits.text.2=A Conduit is crafted with Nautilus Shells and a Heart of the Sea. The Conduit draws power from Prismarine and Sea Lanterns.
howtoplay.conduits.header.1=Construction
howtoplay.conduits.text.3=Once activated, a Conduit will grant Conduit Power to anything nearby.
@@ -3369,6 +3392,7 @@ howtoplay.craftingATool.text.2.gamepad=To craft a tool, open up your §ecrafting
howtoplay.craftingATool.text.2.touch=To craft a tool, open up your §ecrafting table§f:crafting_table: by walking up to it and tapping it. You can craft a basic version of most tools using two sticks and a few planks - your §erecipe book§f will tell you how!
howtoplay.worldBuilder=World Builder
+howtoplay.worldBuilder.title=How to Play: World Builder
howtoplay.worldBuilder.text.1=To place or use certain Minecraft Education blocks or items, a player must possess a special ability called 'World Builder'.
howtoplay.worldBuilder.text.2=With cheats activated, the host can enable or disable the World Builder ability for any players in the world.
howtoplay.worldBuilder.text.3=To grant World Builder ability to all players in the world, run the following command:
@@ -3380,6 +3404,7 @@ howtoplay.worldBuilder.text.8=To query your World Builder ability, run the follo
howtoplay.worldBuilder.text.9=/ability @p worldbuilder
howtoplay.permissionBlocks=Permission Blocks
+howtoplay.permissionBlocks.title=How to Play: Permission Blocks
howtoplay.permissionBlocks.text.1=Minecraft Education features several special blocks that make it easier for teachers to create and employ lessons. Only players with World Builder ability can place and destroy these blocks. Only players without World Builder ability are subject to the restrictions imposed by these blocks.
howtoplay.permissionBlocks.title.1=Allow/Deny
howtoplay.permissionBlocks.text.2=Allow and Deny blocks control where players can build in a world.
@@ -3409,19 +3434,23 @@ howtoplay.playingTogether.realms=Try Realms
howtoplay.playingTogether.signIn=Sign in to try Realms
howtoplay.chalkboard=Chalkboards
+howtoplay.chalkboard.title=How to Play: Chalkboards
howtoplay.chalkboard.text.1=Chalkboards are used to display text in the world. Chalkboards display more text than Signs, can be edited after they have been placed, and come in three sizes: Slate, Poster, and Board. The lock toggle allows you to prevent non-World Builders from destroying or editing your chalkboards. Press :_input_key.use: on an existing chalkboard to edit it.
howtoplay.chalkboard.text.1.touch=Chalkboards are used to display text in the world. Chalkboards display more text than Signs, can be edited after they have been placed, and come in three sizes: Slate, Poster, and Board. The lock toggle allows you to prevent non-World Builders from destroying or editing your chalkboards. Tap an existing chalkboard to edit it.
howtoplay.chemistry=Chemistry
+howtoplay.chemistry.title=How to Play: Chemistry
howtoplay.chemistry.text.1=Students can simulate real world chemistry by using the Chemistry Equipment blocks. Build any of the 118 different elements by adjusting the sliders in the Element Constructor or view the composition of elements by placing them in the Element Constructor. Combine elements in the Compound Creator to produce chemical compounds. Put elements and compounds into the Lab Table to create Minecraft items. Reduce blocks to their component elements with the Material Reducer.
howtoplay.chemistry.text.2=Download the Chemistry Journal from the Minecraft Education website for a comprehensive guide to chemistry in Minecraft.
howtoplay.npc=Non-Player Characters
+howtoplay.npc.title=How to Play: Non-Player Characters
howtoplay.npc.text.1=NPCs are non-player characters that can provide additional lesson information, hints, or instructions.
howtoplay.npc.text.2=Only World Builders can place, delete, name, or edit NPCs. NPCs can execute commands and link to websites. Commands can be assigned to buttons in the NPC's dialog window; website links will always have a button.
howtoplay.npc.text.3=NPCs have a variety of skins to choose from and are immobile.
howtoplay.camera=Camera
+howtoplay.camera.title=How to Play: Camera
howtoplay.camera.text.1=The Camera allows players to take pictures in the world.
howtoplay.camera.text.2=To take a picture from your point of view, press :_input_key.use:.
howtoplay.camera.text.2.touch=To take a picture from your point of view, tap and hold, then release.
@@ -3430,14 +3459,17 @@ howtoplay.camera.text.3.touch=To take a selfie, place a camera and tap the Take
howtoplay.camera.text.4=Pictures can be viewed in the Portfolio or inserted into the Book & Quill.
howtoplay.portfolio=Portfolio
+howtoplay.portfolio.title=How to Play: Portfolio
howtoplay.portfolio.text.1=Pictures you have taken appear in the Portfolio. Press :_input_key.use: to view the Portfolio. When viewing the Portfolio, you can add captions to pictures, delete pictures, and export pictures as a PDF.
howtoplay.portfolio.text.1.touch=Pictures you have taken appear in the Portfolio. Tap and hold to view the Portfolio. When viewing the Portfolio, you can add captions to pictures, delete pictures, and export pictures as a PDF.
howtoplay.classroomMode=Classroom Mode
+howtoplay.classroomMode.title=How to Play: Classroom Mode
howtoplay.classroomMode.text.1=Classroom Mode is an external application that provides educators with features designed to facilitate interaction with students. You can download Classroom Mode from the Minecraft Education website.
howtoplay.classroomMode.text.2=As the host of a world, use the command /classroommode to launch the Classroom Mode app and connect it to Minecraft Education.
howtoplay.codeBuilder=Code Builder
+howtoplay.codeBuilder.title=How to Play: Code Builder
howtoplay.codeBuilder.text.1=Code Builder allows players to explore, create, and play in Minecraft by writing code using familiar learn-to-code platforms.
howtoplay.codeBuilder.text.2=Launch Code Builder by pressing :_input_key.codeBuilder: or by using the command /code.
howtoplay.codeBuilder.text.2.touch=Launch Code Builder by tapping :code_builder_button: or by using the command /code.
@@ -3724,9 +3756,10 @@ howtoplay.movingAround.text.3b.windowsmr_controller=Press :windowsmr_right_touch
howtoplay.gatheringResources=Gathering resources
howtoplay.gatheringResources.title=How to Play: Gathering resources
howtoplay.gatheringResources.text.1=The world is full of resources, including §ebuilding blocks§f, §ecrafting materials§f, and §efood§f.
-howtoplay.gatheringResources.text.2.nottouch=Most resources, such as dirt, wood, and pumpkins, can be gathered with your bare hands. Aim the crosshair in the middle of the screen at the block, then hold :_input_key.attack: until they drop - we call this §eblock breaking§f.
-howtoplay.gatheringResources.text.2.touch=Most resources, such as dirt, wood, and pumpkins, can be gathered with your bare hands. Simply walk up to them, then touch and hold the screen until they drop - we call this §eblock breaking§f.
-howtoplay.gatheringResources.text.2.touch.joystick_crosshair=Most resources, such as dirt, wood, and pumpkins, can be gathered with your bare hands. Aim the crosshair in the middle of the screen at the block, then touch and hold the attack/destroy button :tip_virtual_button_action_attack_or_destroy: until they drop - we call this §eblock breaking§f.
+howtoplay.gatheringResources.text.2.nottouch=You can §ebreak blocks§f with your bare hands to gather resources like dirt and wood. Aim at a block, then §epress and hold§f :_input_key.attack: until it breaks and the resources drop.
+howtoplay.gatheringResources.text.2.touch=You can §ebreak blocks§f with your bare hands to gather resources like dirt and wood. §eTouch and hold§f on the block until it breaks and the resources drop.
+howtoplay.gatheringResources.text.2.touch.joystick_crosshair=You can §ebreak blocks§f with your bare hands to gather resources like dirt and wood. Aim at a block, then §etouch and hold§f :tip_virtual_button_action_attack_or_destroy: until it breaks and the resources drop.
+howtoplay.gatheringResources.text.2.pc=You can §ebreak blocks§f with your bare hands to gather resources like dirt and wood. Aim at a block, then §eclick and hold§f :_input_key.attack: until it breaks and the resources drop.
howtoplay.gatheringResources.text.3=Pick up any dropped resources by walking over the floating icons.
howtoplay.selectingItems=Selecting items
@@ -3965,7 +3998,7 @@ howtoplay.yourFirstCraft.text.3.keyboard=Simply drag your shiny new planks to yo
howtoplay.yourFirstCraft.text.3.gamepad=Simply select your shiny new planks and they will appear in your hotbar. Now you're ready to place them into the world!
howtoplay.yourFirstCraft.header.2=2. Crafting recipe
howtoplay.yourFirstCraft.text.4=Some items require you to place your crafting ingredients in a certain shape - also called a §erecipe§f.
-howtoplay.yourFirstCraft.text.5=Try placing two planks above each other to create a stick. Useful for all sorts of things!
+howtoplay.yourFirstCraft.text.5=Try placing two planks above each other to create some sticks. Useful for all sorts of things!
immersive_reader.book_page_header=Page %1 of %2
immersive_reader.portfolio_page_header= Page %1
@@ -3988,6 +4021,8 @@ level.editor.export.failed=Project export failed
level.editor.import.failed=Project import failed
level.editor.import.failed.incompatibleEdition=Project import failed: Unsupported file format
+inbox.invite.title=Realms Invite
+
invite.clear=Clear Selection
invite.send=Send %d Invites
invite.sendOne=Send 1 Invite
@@ -4797,6 +4832,7 @@ item.cake.name=Cake
item.camera.name=Camera
item.canBreak=Can break:
item.canPlace=Can be placed on:
+item.customProperties=Has Custom Properties
item.itemLock.cantDrop=:hollow_star: Can't Drop Items can't be:
item.itemLock.cantMove=:solid_star: Can't Move Items can't be:
item.itemLock.hoverText.cantBe.moved=moved
@@ -5169,7 +5205,7 @@ item.glowstone_dust.name=Glowstone Dust
item.shulker_shell.name=Shulker Shell
item.totem.name=Totem of Undying
item.turtle_helmet.name=Turtle Shell
-item.turtle_shell_piece.name=Scute
+item.turtle_shell_piece.name=Turtle Scute
item.phantom_membrane.name=Phantom Membrane
item.sweet_berries.name=Sweet Berries
item.suspicious_stew.name=Suspicious Stew
@@ -5829,8 +5865,8 @@ options.control_alt_keybinds_section=The following keys are used with 'CTRL + AL
options.credits=Credits
options.crouch=Sneak
options.csbExpired=Expired since %s
-options.csbHeading=MARKETPLACE PASS
-options.csbInfoLine01=Catalogue of 150+ marketplace packs and items
+options.csbHeading=MARKETPLACE PASS ### {StrContains="MARKETPLACE PASS"}
+options.csbInfoLine01=Catalogue of 150+ Marketplace packs and items
options.csbInfoLine02=Content refreshed monthly
options.csbSubheading=Marketplace Content
options.customizeTitle=Customize World Settings
@@ -6084,6 +6120,8 @@ options.fov.toggle=FOV Can Be Altered By Gameplay
options.licenses=Licenses
options.licensed_content=Licensed Content
options.networkSettings=Network Settings
+options.ecoMode=Eco Mode ###Eco Mode refers to an ecological friendly mode {MaxLength=‘20’}
+options.enableEcoMode=Enable Eco Mode ###Eco Mode refers to an ecological friendly mode {MaxLength=‘30’}
options.font_license=Font License
options.font_license_body=%1
options.livingRoomFOV=Living Room FOV
@@ -6365,7 +6403,6 @@ options.betaNewDeathScreenToggle=New "You Died" Screen (Experimental)
options.betaNewDeathScreenToggle.disabled=You can't change this setting while playing in a world
options.usetouchpad=Split Controls
options.viewSubscriptions=Subscriptions
-options.viewSubscriptions.button.csbBuy=%s
options.viewSubscriptions.button.info=Info
options.viewSubscriptions.button.price=%s
options.viewSubscriptions.button.pricePerMonth=%s/month
@@ -6681,6 +6718,7 @@ hudScreen.controlCustomization.hintDeselect=Click outside to deselect
hudScreen.controlCustomization.hintSaved=Saved
hudScreen.controlCustomization.tooltip=Load a world to customize controls
hudScreen.controlCustomization.tooltip.notouch=Use a touch device to customize controls
+hudScreen.controlCustomization.tooltip.alreadycustomizing=There is already a touch control customization screen open
playscreen.fileSize.MB=MB
playscreen.fileSize.GB=GB
@@ -6939,6 +6977,7 @@ profileScreen.create_persona_classic_skin_details=A whole-body skin texture that
profileScreen.create_persona_title=Select the Type
+persona.csb.see.subscription=In Pass
persona.slim.title=narrow
persona.wide.title=wide
persona.smaller.title=smaller
@@ -6949,6 +6988,7 @@ persona.realms.redeem=Redeem
persona.realms.see.subscription=In Realms Plus
persona.realms.time.remaining=%s to redeem
persona.realms.savings=You save %s minecoins with your Realms Plus subscription!
+persona.csb.savings=You save %s minecoins with your Marketplace Pass subscription!
persona.preview.emote=Play Emote
progressScreen.cantConnect=Unable to connect to the world. Please check your connection to the internet and try again.
@@ -7098,6 +7138,7 @@ resourcePack.selected.title.behaviorPacks=Active Behavior Packs
resourcePack.selected.title.packs=Active
resourcePack.selected.remove=Deactivate
resourcePack.realmsPlus.title.packs=Realms Plus Packs
+resourcePack.realmsPlus.title.packs.contentSub=Marketplace Pass Packs
resourcePack.realmsPlus.expired=Expired
resourcePack.errors=Errors:
resourcePack.error.ingame.packs=You cannot change Resource Packs while playing in a world.
@@ -7120,9 +7161,11 @@ resourcePack.header.behavior=Active Behavior Packs apply to all players.
resourcePack.header.level=Require players to accept resource packs to join
resourcePack.crashRecovery.title=Global Resources Reset
resourcePack.crashRecovery.message=Resources failed to load previously.
-resourcePack.warnings=Warnings:
-resourcePack.warning.title=This Is Dangerous!
-resourcePack.warning.body=Adding or removing Behavior Packs after playing a world might break the world and cause you to lose what you created. Press "OK" to deactivate the pack, or "Cancel" to keep it active.
+resourcePack.warnings=Warnings:
+resourcePack.warning.add.title=Update World?
+resourcePack.warning.add.body=This world may not look or behave in the same way as non-modified worlds and you won't be able to earn achievements. You may want to save a copy of your world before continuing. Press "OK" to activate the pack, or "Cancel" to keep it unactivated.
+resourcePack.warning.remove.title=This Is Dangerous!
+resourcePack.warning.remove.body=Removing Behavior Packs after playing a world might break the world and cause you to lose what you created. You may want to save a copy of your world before continuing. Press "OK" to deactivate the pack, or "Cancel" to keep it active.
resourcePack.requiredDependency.title=Required Dependency
resourcePack.requiredDependency.body=This pack is a required dependency of another pack that is currently applied.
resourcePack.missingDependency.title=Missing Dependencies
@@ -7853,32 +7896,42 @@ store.realmsPlus.buyNow.viewPrivacyPolicy=PRIVACY POLICY
store.realmsPlus.buyNow.title=Start your Realms Plus Subscription
store.realmsPlus.startTrial.description=Your Realm and 150+ marketplace packs will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! Your first month will be free, and you'll be billed %s/month afterwards and can cancel at any time.
+store.realmsPlus.startTrial.description.contentSub=Your Realm and the 150+ marketplace packs included in Marketplace Pass will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! Your first month will be free, and you'll be billed %s/month afterwards and can cancel at any time.
store.realmsPlus.noTrial.description=Your Realm and 150+ marketplace packs will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! Your subscription will be available for 30 days at the price of %s:minecoin:.
+store.realmsPlus.noTrial.description.contentSub=Your Realm and the 150+ marketplace packs included in Marketplace Pass will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! Your subscription will be available for 30 days at the price of %s:minecoin:.
store.realmsPlus.noTrial.description.iap=Your Realm and 150+ marketplace packs will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! You’ll be billed %s/month and you can cancel your subscription to stop future charges by accessing subscriptions settings.
+store.realmsPlus.noTrial.description.iap.contentSub=Your Realm and the 150+ marketplace packs included in Marketplace Pass will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! You’ll be billed %s/month and you can cancel your subscription to stop future charges by accessing subscriptions settings.
store.realmsPlus.realmName.placeholder=%s's Realm #The string passed in here is the gamertag of the player to indicate the name of the player's world.
store.realmsPlus.recurring.offerTrial=Realms Plus is an ongoing subscription with a recurring subscription fee which is charged automatically every month until the subscription is cancelled.%sYour Realm and 150+ marketplace packs will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! Your first 30 days will be free, and you'll be billed %s/month afterwards. You can cancel your subscription to stop future charges by accessing subscriptions settings.
+store.realmsPlus.recurring.offerTrial.contentSub=Realms Plus is an ongoing subscription with a recurring subscription fee which is charged automatically every month until the subscription is cancelled.%sYour Realm and the 150+ marketplace packs included in Marketplace Pass will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! Your first 30 days will be free, and you'll be billed %s/month afterwards. You can cancel your subscription to stop future charges by accessing subscriptions settings.
store.realmsPlus.recurring.withoutTrial=Realms Plus is an ongoing subscription with a recurring subscription fee which is charged automatically every month until the subscription is cancelled.%sYour Realm and 150+ marketplace packs will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! You'll be billed %s/month and you can cancel your subscription to stop future charges by accessing subscriptions settings.
+store.realmsPlus.recurring.withoutTrial.contentSub=Realms Plus is an ongoing subscription with a recurring subscription fee which is charged automatically every month until the subscription is cancelled.%sYour Realm and the 150+ marketplace packs included in Marketplace Pass will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! You'll be billed %s/month and you can cancel your subscription to stop future charges by accessing subscriptions settings.
store.realmsPlus.consumable.offerTrial=Your Realm and 150+ marketplace packs will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! Your first 30 days will be free and you can renew for 30 days at the price of %s afterwards.
+store.realmsPlus.consumable.offerTrial.contentSub=Your Realm and the 150+ marketplace packs included in Marketplace Pass will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! Your first 30 days will be free and you can renew for 30 days at the price of %s afterwards.
store.realmsPlus.consumable.withoutTrial=Your Realm and 150+ marketplace packs will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! Your subscription will be available for 30 days at the price of %s.
+store.realmsPlus.consumable.withoutTrial.contentSub=Your Realm and the 150+ marketplace packs included in Marketplace Pass will be immediately available. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free! Your subscription will be available for 30 days at the price of %s.
store.realmsPlus.landing.header=Subscription Includes:
store.realmsPlus.landing.headerTrial=Free 30 Day Trial, then %s/month
-store.realmsPlus.landing.info1.line1=Your Own Personal Realm Server – A Persistent World Always Online for You and Your Friends!
-store.realmsPlus.landing.info1.line2=Friends Play for Free in Your Realm
-store.realmsPlus.landing.info1.line3=Jump from Console to Mobile to PC - Any Device with Minecraft Marketplace
+store.realmsPlus.landing.info1.line1=Your own personal Realm server: a persistent world always online for you and your friends!
+store.realmsPlus.landing.info1.line2=Friends play on your Realm for free
+store.realmsPlus.landing.info1.line3=Jump from console to mobile to PC - play your Realm on any device with the Minecraft Marketplace
-store.realmsPlus.landing.info2.line1=Free Access to a Catalog of 150+ Marketplace Packs
-store.realmsPlus.landing.info2.line2=Worlds on Your Realm Include Secure Backups
+store.realmsPlus.landing.info2.line1=Free access to a catalog of 150+ Marketplace packs
+store.realmsPlus.landing.info2.line1.contentSub=Includes Marketplace Pass
+store.realmsPlus.landing.info2.line2=Worlds on your Realm include free secure backups
store.realmsPlus.landing.info2.line3=Your First 30 Days Will be Free
-store.realmsPlus.landing.info2.line4=Subscribe Now for %s/month
+store.realmsPlus.landing.info2.line4=Subscribe now for %s/month
-store.realmsPlus.landing.info2.catalog=Free Access to a Catalog of 150+ Marketplace Packs
-store.realmsPlus.landing.info2.backups=Worlds on Your Realm Include Secure Backups
+store.realmsPlus.landing.info2.catalog=Free access to a catalog of 150+ Marketplace packs
+store.realmsPlus.landing.info2.contentSub=Includes Marketplace Pass
+store.realmsPlus.landing.info2.backups=Worlds on your Realm include free secure backups
store.realmsPlus.landing.info2.trial=Your First 30 Days Will be Free
-store.realmsPlus.landing.info2.subscribe=Subscribe Now for %s/month
-store.realmsPlus.landing.info2.persona=Free Character Creator Items - Redeem a New Set Each Month!
+store.realmsPlus.landing.info2.subscribe=Subscribe now for %s/month
+store.realmsPlus.landing.info2.recentlyAdded=Recently added
+store.realmsPlus.landing.info2.persona=Free Character Creator items - redeem a new set each month!
store.realmsPlus.landing.beta=Beta
store.realmsPlus.landing.preview=Preview
@@ -7899,6 +7952,7 @@ store.realmsPlus.faq.question4=Which devices support Realms Plus for Minecraft?
store.realmsPlus.faq.answer4=Realms Plus is currently available on any platform where you can install Minecraft Bedrock Edition. You can play Realms and use any content from Realms Plus on any of these devices if you’re signed into your Microsoft Account.##disable_3rd_party_console_resource_pack_check
store.realmsPlus.faq.question5=How much does a Realms Plus subscription cost?
store.realmsPlus.faq.answer5=%s per month for a 10-player server and access to 150+ marketplace packs.
+store.realmsPlus.faq.answer5.contentSub=%s per month. Add infinite members, play online with 10 other players at the same time. Plus, enjoy over 150 pieces of Marketplace content from the Marketplace Pass catalog for free.
store.realmsPlus.faq.question6=How often are new packs added to Realms Plus?
store.realmsPlus.faq.answer6=New packs are added to Realms Plus monthly.
store.realmsPlus.faq.question7=How long do I have access to Packs within Realms Plus?
@@ -7907,38 +7961,44 @@ store.realmsPlus.faq.question8=Where can I use Realms Plus packs?
store.realmsPlus.faq.answer8=Worlds and packs included in the subscription can either be played online, played on your personal Realm, or played on a local device. You just need to play online once every 30 days to validate that your subscription is active.
store.realmsPlus.faq.question9=What happens to my Realms and worlds when my subscription expires?
store.realmsPlus.faq.answer9=If your subscription ends, you and your friends will no longer be able to play online together on Realms, and you will no longer have access to Realms Plus packs. You can download any world saved to your Realm (within 18 months of ending your subscription). If you used Realms Plus worlds, texture packs, or mash-ups you will need to purchase those packs in the store or, if those packs are still in Realms Plus, re-subscribe, to play those world templates.
+store.realmsPlus.faq.question10=Do I need Realms Plus and Marketplace Pass?
+store.realmsPlus.faq.answer10=No. Marketplace Pass is a catalog of over 150+ packs for you to enjoy. Realms Plus is a 10 player Realm with Marketplace Pass included. We suggest that you subscribe to the one that’s right for you.
+store.realmsPlus.content.marketplacePass=Realms Plus includes Marketplace Pass!
store.realmsPlus.content.skinDescription=Change your look with skins!
store.realmsPlus.content.skinDescriptionPersona=Dress up with skins!
+store.realmsPlus.content.skinDescriptionPersona.contentSub=Expand your wardrobe with skins!
store.realmsPlus.content.worldDescription=Explore popular content packs!
+store.realmsPlus.content.worldDescription.contentSub=Play mini-games, themed worlds, and more!
store.realmsPlus.content.textureDescription=New visuals for your worlds!
+store.realmsPlus.content.textureDescription.contentSub=Apply new visuals to your world!
store.realmsPlus.content.mashupDescription=Try a bit of everything in mash-ups!
store.realmsPlus.content.personaDescription=Customize your look with Character Creator items!
+store.realmsPlus.content.personaDescription.contentSub=Collect monthly items in the dressing room!
+store.realmsPlus.content.recentlyAdded=Recently added
store.realmsPlus.content.friendsGetAccess=Your Friends Get Access to the Content Used in Your Realm for Free
store.realmsPlus.content.popularPacks=Popular Packs in Realms Plus:
store.realmsPlus.content.viewAllPacks=VIEW ALL PACKS
store.realmsPlus.content.contentDescription=Tap into the source of amazing Minecraft content! With Realms Plus, you get instant access to 150+ marketplace items like mash-ups, worlds, skin packs and epic adventures – with new additions each month. Your content is stored on your own personal server, and made available on any platform where you enjoy both Realms and Minecraft Marketplace. Up to 10 players can play at one time, and they get access to the worlds in your Realm for free!
-
store.realmsPlus.freeTrial=START FREE TRIAL
store.realmsPlus.purchase.warningDialog.title=Notice
-store.realmsPlus.purchase.warningDialog.body=Realms Plus includes Marketplace Pass content. We suggest that you unsubscribe from your Marketplace Pass subscription after sign up.
+store.realmsPlus.purchase.warningDialog.body=Realms Plus includes Marketplace Pass content. We suggest that you cancel your Marketplace Pass subscription after signing up for Realms Plus. ### {StrContains="Marketplace Pass"}
store.realmsPlus.purchase.warningDialog.checkbox=I understand
store.realmsPlus.purchase.warningDialog.button.back=Go Back
-store.realmsPlus.purchase.warningDialog.button.continue=Continue
+store.realmsPlus.purchase.warningDialog.button.continue=Purchase
-store.csb.brand.1=MARKETPLACE
-store.csb.brand.2=PASS
+store.csb.brand.1=MARKETPLACE ### {StrContains="MARKETPLACE"}
+store.csb.brand.2=PASS ### {StrContains="PASS"}
-store.csb=Marketplace Pass
-store.csb.pass=Pass
+store.csb=Marketplace Pass ### {StrContains="Marketplace Pass"}
store.csb.content=Content
store.csb.faq=FAQ
store.csb.buyNow=SUBSCRIBE NOW ## Maximum 13 characters
store.csb.buyNowPerMonth=Purchase for %s/month
-store.csb.signInToSubscribe=Sign in to subscribe to Marketplace Pass
+store.csb.signInToSubscribe=Sign in to subscribe to Marketplace Pass ### {StrContains="Marketplace Pass"}
store.csb.buyNowTrialPerMonth=Start Trial ## Maximum 25 characters
store.csb.errorNoOffer=ERROR NO OFFER FOUND
store.csb.manageSubscription=MANAGE SUBSCRIPTION
@@ -7948,19 +8008,19 @@ store.csb.buyNow.buttonText=BUY FOR %s
store.csb.buyNow.viewTerms=TERMS & CONDITIONS
store.csb.buyNow.viewPrivacyPolicy=PRIVACY POLICY
-store.csb.buyNow.title=Start your Marketplace Pass Subscription
+store.csb.buyNow.title=Start your Marketplace Pass Subscription ### {StrContains="Marketplace Pass"}
-store.csb.subscription=After sign up, 150+ pieces of exciting Minecraft Marketplace content will be available to you. Download and play adventure maps, wear skins, dive into texture packs, and even claim a set of Character Creator items to keep each month. With a catalog that’s regularly refreshed, there’s always something new to discover with Marketplace Pass. You’ll be billed %s/month and can cancel anytime to stop future charges.
+store.csb.subscription=After sign up, 150+ pieces of exciting Minecraft Marketplace content will be available to you. Download and play adventure maps, wear skins, dive into texture packs, and even claim a set of Character Creator items to keep each month. With a catalog that’s regularly refreshed, there’s always something new to discover with Marketplace Pass. You’ll be billed %s/month and can cancel anytime to stop future charges. ### {StrContains="Marketplace Pass"}
-store.csb.recurring.offerTrial=Marketplace Pass is an ongoing subscription with a recurring subscription fee which is charged automatically every month until the subscription is cancelled.%s150+ marketplace packs will be immediately available. You can cancel your subscription to stop future charges by accessing subscriptions settings.
-store.csb.recurring.withoutTrial=Marketplace Pass is an ongoing subscription with a recurring subscription fee which is charged automatically every month until the subscription is cancelled.%s150+ marketplace packs will be immediately available. You'll be billed %s/month and you can cancel your subscription to stop future charges by accessing subscriptions settings.
+store.csb.recurring.offerTrial=Marketplace Pass is an ongoing subscription with a recurring subscription fee which is charged automatically every month until the subscription is cancelled.%s150+ marketplace packs will be immediately available. You can cancel your subscription to stop future charges by accessing subscriptions settings. ### {StrContains="Marketplace Pass"}
+store.csb.recurring.withoutTrial=Marketplace Pass is an ongoing subscription with a recurring subscription fee which is charged automatically every month until the subscription is cancelled.%s150+ marketplace packs will be immediately available. You'll be billed %s/month and you can cancel your subscription to stop future charges by accessing subscriptions settings. ### {StrContains="Marketplace Pass"}
store.csb.consumable.offerTrial=150+ marketplace packs will be immediately available. Your first 30 days will be free and you can renew for 30 days at the price of %s afterwards.
store.csb.consumable.withoutTrial=150+ marketplace packs will be immediately available. Your subscription will be available for 30 days at the price of %s.
-store.csb.landing.header=Start your Marketplace Pass Subscription
+store.csb.landing.header=Start your Marketplace Pass Subscription ### {StrContains="Marketplace Pass"}
store.csb.landing.headerTrial=Free 30 Day Trial, then %s/month
-store.csb.landing.info=Marketplace Pass is a monthly subscription service that gives you access to 150+ pieces of content from Minecraft Marketplace for %s. Your subscription allows you to:
+store.csb.landing.info=Marketplace Pass is a monthly subscription service that gives you access to 150+ pieces of content from Minecraft Marketplace for %s. Your subscription allows you to: ### {StrContains="Marketplace Pass"}
store.csb.landing.info.line1=Dive into story-driven adventures by downloading and playing one of the many themed worlds and mini-games
store.csb.landing.info.line2=Change the look of blocks, biomes, and even your favorite Minecraft mobs
store.csb.landing.info.line3=Expand your in-game wardrobe
@@ -7970,24 +8030,24 @@ store.csb.landing.beta=Beta
store.csb.landing.preview=Preview
store.csb.faq.header=FREQUENTLY ASKED QUESTIONS
-store.csb.faq.question1=What is Marketplace Pass?
-store.csb.faq.answer1=Marketplace Pass is subscription service that gives you access to 150+ pieces of content from Minecraft Marketplace for %s/month.
-store.csb.faq.question2=How often is content updated in Marketplace Pass?
+store.csb.faq.question1=What is Marketplace Pass? ### {StrContains="Marketplace Pass"}
+store.csb.faq.answer1=Marketplace Pass is subscription service that gives you access to 150+ pieces of content from Minecraft Marketplace for %s/month. ### {StrContains="Marketplace Pass"}
+store.csb.faq.question2=How often is content updated in Marketplace Pass? ### {StrContains="Marketplace Pass"}
store.csb.faq.answer2=Select content refreshes each month so there’s always something new to explore.
-store.csb.faq.question3=What do I need to enjoy Marketplace Pass?
-store.csb.faq.answer3=Access to Marketplace Pass requires an active subscription, and a compatible version of Minecraft: Bedrock Edition with Minecraft Marketplace. Requires Microsoft Account sign-in.
-store.csb.faq.question4=What happens to my content after it leaves Marketplace Pass?
+store.csb.faq.question3=What do I need to enjoy Marketplace Pass? ### {StrContains="Marketplace Pass"}
+store.csb.faq.answer3=Access to Marketplace Pass requires an active subscription, and a compatible version of Minecraft: Bedrock Edition with Minecraft Marketplace. Requires Microsoft Account sign-in. ### {StrContains="Marketplace Pass"}
+store.csb.faq.question4=What happens to my content after it leaves Marketplace Pass? ### {StrContains="Marketplace Pass"}
store.csb.faq.answer4=Once a world, texture pack, skin pack, or mash-up leaves the catalog, you will need to purchase the item from the Marketplace to continue playing. Packs will not be deleted from your local storage until you delete them. Monthly character creator items you’ve redeemed are yours to keep.
store.csb.faq.question5=What happens when my subscription ends?
store.csb.faq.answer5=You will be able to purchase and download any world templates saved to your cloud storage within 18 months of ending your subscription unless they are no longer offered by Minecraft. Monthly character creator items you’ve redeemed are yours to keep.
store.csb.faq.question6=What's the difference between this and Realms Plus?
-store.csb.faq.answer6=The difference between the two subscriptions is that Realms Plus includes a personal server where you can play with up to ten friends at a time. The content catalog you have access to with your Marketplace Pass subscription is the same catalog that is available with a Realms Plus subscription.
-store.csb.faq.question7=Can I subscribe to both Marketplace Pass and Realms Plus?
-store.csb.faq.answer7=A Realms Plus subscription includes Marketplace Pass. If you are subscribed to Marketplace Pass and want to explore Realms Plus, we suggest that you unsubscribe from Marketplace Pass first. Active Realms Plus subscribers are unable to subscribe to Marketplace Pass.
-store.csb.faq.question8=Can I use my Marketplace Pass content on any device?
-store.csb.faq.answer8=If you purchase Marketplace Pass, you can access all the packs from any device with a compatible version of Minecraft: Bedrock Edition with Minecraft Marketplace (sold separately) if you’re signed into your Minecraft account. Not supported on Amazon Kindle Fire or Minecraft Java Edition.
-store.csb.faq.question9=Can I play Marketplace Pass Content if I have joined the Minecraft Beta on Windows or XBOX?
-store.csb.faq.answer9=You will be able to see content in your subscription if you are already subscribed, but you will not be able to subscribe to Marketplace Pass from the Preview/BETA build.
+store.csb.faq.answer6=The difference between the two subscriptions is that Realms Plus includes a personal server where you can play with up to ten friends at a time. The content catalog you have access to with your Marketplace Pass subscription is the same catalog that is available with a Realms Plus subscription. ### {StrContains="Marketplace Pass"}
+store.csb.faq.question7=Can I subscribe to both Marketplace Pass and Realms Plus? ### {StrContains="Marketplace Pass"}
+store.csb.faq.answer7=A Realms Plus subscription includes Marketplace Pass. If you are subscribed to Marketplace Pass and want to explore Realms Plus, we suggest that you unsubscribe from Marketplace Pass first. Active Realms Plus subscribers are unable to subscribe to Marketplace Pass. ### {StrContains="Marketplace Pass"}
+store.csb.faq.question8=Can I use my Marketplace Pass content on any device? ### {StrContains="Marketplace Pass"}
+store.csb.faq.answer8=If you purchase Marketplace Pass, you can access all the packs from any device with a compatible version of Minecraft: Bedrock Edition with Minecraft Marketplace (sold separately) if you’re signed into your Minecraft account. Not supported on Amazon Kindle Fire or Minecraft Java Edition. ### {StrContains="Marketplace Pass"}
+store.csb.faq.question9=Can I play Marketplace Pass Content if I have joined the Minecraft Beta on Windows or XBOX? ### {StrContains="Marketplace Pass"}
+store.csb.faq.answer9=You will be able to see content in your subscription if you are already subscribed, but you will not be able to subscribe to Marketplace Pass from the Preview/BETA build. ### {StrContains="Marketplace Pass"}
store.csb.faq.bottom1=CAN'T FIND WHAT YOU'RE LOOKING FOR?
store.csb.faq.bottom2=Visit our help site
@@ -7997,20 +8057,20 @@ store.csb.contentPacks.personaDescription=Collect monthly items in the dressing
store.csb.contentPacks.skinDescription=Expand your wardrobe with skins!
store.csb.contentPacks.mashupDescription=Try a bit of everything with mash-ups!
-store.csb.content.popularPacks=Discover Marketplace Pass
+store.csb.content.popularPacks=Discover Marketplace Pass ### {StrContains="Marketplace Pass"}
store.csb.content.viewAllPacks=VIEW ALL PACKS
store.csb.content.viewCharacterCreatorItems=VIEW CHARACTER CREATOR ITEMS
-store.csb.content.contentDescription=Tap into the source of amazing Minecraft content! With Marketplace Pass, you get instant access to 150+ marketplace items like mash-ups, worlds, skin packs and epic adventures - with new additions each month.
+store.csb.content.contentDescription=Tap into the source of amazing Minecraft content! With Marketplace Pass, you get instant access to 150+ marketplace items like mash-ups, worlds, skin packs and epic adventures - with new additions each month. ### {StrContains="Marketplace Pass"}
store.csb.freeTrial=START FREE TRIAL
-store.csb.welcomeDialog.title=Welcome to Marketplace Pass!
+store.csb.welcomeDialog.title=Welcome to Marketplace Pass! ### {StrContains="Marketplace Pass"}
store.csb.welcomeDialog.body=Start enjoying 150+ adventures, mini-games, skin packs, textures and more now!
store.csb.welcomeDialog.continue=Start browsing
store.csb.purchase.warningDialog.title=Notice
-store.csb.purchase.warningDialog.body.line1=Marketplace Pass is included in your Realms Plus subscription.
-store.csb.purchase.warningDialog.body.line2=Please cancel your active Realms Plus subscription and wait until the end of your billing cycle, then try purchasing.
+store.csb.purchase.warningDialog.body.line1=Marketplace Pass is included in your Realms Plus subscription. ### {StrContains="Marketplace Pass"}
+store.csb.purchase.warningDialog.body.line2=Please cancel your active Realms Plus subscription and then try purchasing.
store.csb.purchase.warningDialog.button.back=Go Back
store.csb.upsell.bestValue=BEST VALUE
@@ -8036,11 +8096,14 @@ store.csb.purchaseErrorDialog.errorCode=Error Code: %s
store.csb.purchaseErrorDialog.correlationId=Correlation ID: %s
store.csb.purchase.amazonDeviceWarning.title=Notice
-store.csb.purchase.amazonDeviceWarning.body.line1=Sorry! Marketplace Pass isn’t available for purchase on Amazon devices at this time.
+store.csb.purchase.amazonDeviceWarning.body.line1=Sorry! Marketplace Pass isn’t available for purchase on Amazon devices at this time. ### {StrContains="Marketplace Pass"}
store.csb.purchase.amazonDeviceWarning.body.line2=For any questions, please visit support.minecraft.net.
store.csb.purchase.amazonDeviceWarning.button.back=Go Back
-store.csb.alreadySubscribed.toolTip=You already have a Marketplace Pass subscription.
+store.csb.alreadySubscribed.toolTip=You already have a Marketplace Pass subscription. ### {StrContains="Marketplace Pass"}
+
+store.csb.banner.offer=Start your free 30 day trial now!
+store.csb.banner.learnMore=Learn more
store.inventory.button=My Content
store.inventory.title=My Content
@@ -8171,6 +8234,10 @@ store.mashup.count.texturePack=1 Texture Pack
store.mashup.count.texturePacks=%s Texture Packs #number of texture packs
store.mashup.count.world=1 World
store.mashup.count.worlds=%s Worlds #number of worlds
+store.mashup.count.addonPack=1 Addon
+store.mashup.count.addonPacks=%s Addons #number of addons
+
+store.addon.activateAddonPack=Activate Addon Pack!
store.mashup.bundle=Bundle
store.mashup.bundle.multipleCreators=Multiple Creators
@@ -8383,7 +8450,7 @@ store.search.filter.offer_type=Offer Types
store.search.filter.offer_type.selectedCount=%d Offer Types
store.search.filter.offer_type.bundles=Bundles
store.search.filter.offer_type.realmsplus=Realms Plus
-store.search.filter.offer_type.csb=Marketplace Pass
+store.search.filter.offer_type.csb=Marketplace Pass ### {StrContains="Marketplace Pass"}
store.search.filter.clear.pack_type=Clear Pack Type Filters
store.search.filter.mashupPacks=Mash-ups
@@ -8400,6 +8467,7 @@ store.search.filter.skinPacks=Skins
store.search.filter.texturePacks=Textures
store.search.filter.title=Filters
store.search.filter.worldTemplates=Worlds
+store.search.filter.addOns=Add-ons
store.search.filter.installed_state=Installed State
store.search.filter.installed=Installed
store.search.filter.notInstalled=Not Installed
@@ -8436,7 +8504,7 @@ store.uploadContentToRealmsFail.message=Failed to upload content to the selected
store.uploadContentToRealmsFail.forbidden.message=You do not own one or more of the applied content!
store.applyToRealm=Create on Realm
store.inRealmsPlus=In Realms Plus
-store.inCsb=In Marketplace Pass
+store.inCsb=In Marketplace Pass ### {StrContains="Marketplace Pass"}
store.uploadWorldTitle=Replace World?
store.uploadPackTitle=Replace Pack?
store.uploadWorldMessage=This will remove your current world from your Realm's active slot and let you replace it with a new one. Your Realm's members will have access to your new world. Select "Cancel" to go and download a copy of the current world to prevent data loss or "Confirm" to continue and replace your world.
@@ -8519,7 +8587,7 @@ tile.beehive.name=Beehive
tile.bee_nest.name=Bee Nest
tile.target.name=Target
tile.bed.name=Bed
-tile.bed.noSleep=You can only sleep at night
+tile.bed.noSleep=You can only sleep at night and during thunderstorms
tile.bed.notSafe=You may not rest now, there are monsters nearby
tile.bed.notValid=Your home bed was missing or obstructed
tile.bed.occupied=This bed is occupied
@@ -9933,6 +10001,7 @@ content.import.succeeded=Successfully imported '%s'
content.import.succeeded_with_warnings=Successfully imported '%s' with warnings
content.import.succeeded_with_warnings.subtitle=Click here for more info
content.import.started=Import started...
+content.import.importedWorldPrefix=imported
## World Templates
worldTemplate.festivemashup2016.name=Festive Mash-up 2016
@@ -10017,85 +10086,6 @@ tips.edu.28=Want to use Code Builder? Make sure cheats are toggled on.
tips.edu.29=Press F5 to change player perspective.
tips.edu.30=Use "/spawnpoint" to change your spawn point. It's just like you slept in a bed!
-tips.game.1=Use seagrass to attract and breed sea turtles.
-tips.game.2=Protect baby turtles from hostile mobs!
-tips.game.3=Baby turtles will drop scutes when they grow - these can be crafted into turtle shells.
-tips.game.4=Use a bed to set your respawn point during the day.
-tips.game.5=Brew some water breathing potions for underwater exploration!
-tips.game.6=Dolphins can lead you to shipwrecks and underwater ruins, feed them cod and follow their trail!
-tips.game.7=Use shears to carve a pumpkin.
-tips.game.8=Use phantom membranes to repair your elytra.
-tips.game.9=There are 3587 types of tropical fish!
-tips.game.10=Sea pickles can be smelted into lime green dye.
-tips.game.11=Use haybales to breed Llamas!
-tips.game.12=Compasses point to the world spawn - craft one to find your way back!
-tips.game.13=Trade with villagers to obtain food, tools, and even treasure maps!
-tips.game.14=Did you know you can hold a map in your off-hand?
-tips.game.15=Leads can be used on boats.
-tips.game.16=Sneak or wear frost walker boots to walk safely on magma blocks.
-tips.game.17=You can gather cob webs using shears.
-tips.game.18=Need diamonds? They get more common as you go deeper.
-tips.game.19=Before you mine diamonds, redstone or gold, make sure you're using an iron, diamond, or netherite pickaxe or the ore won't drop.
-tips.game.20=Need coal for torches or fuel? Try smelting wood logs in a furnace to make charcoal!
-tips.game.21=Gold is more abundant in Badlands biomes!
-tips.game.22=Elytra can be used to glide, find them in End City ships!
-tips.game.23=Test out some new features by turning on some Experiments!
-tips.game.24=Tridents are dropped by the Drowned, and can be held or thrown.
-tips.game.25=You can breed Hoglins with Crimson Fungus, but it is dangerous!
-tips.game.26=You can smelt 20 items in a furnace by using a block of dried kelp as fuel.
-tips.game.27=Creepers that are killed by skeletons' arrows have a chance of dropping music discs.
-tips.game.28=People like YOU make Marketplace content!
-tips.game.29=Did you know that several community creators make a living off the content in the Marketplace?
-tips.game.30=You can find skins to customize your experience in-game, or on select platforms use your own!
-tips.game.31=Texture packs change the way that blocks, items, and even the menus look in game. Try them out!
-tips.game.32=Check out the Marketplace to find new worlds and adventures.
-tips.game.33=Apply to become a Marketplace Creator!
-tips.game.34=Mash-up packs come with a world to explore, skins, textures, and even new music.
-tips.game.35=Did you know there are over 500 community-created Marketplace packs with more added every week?
-tips.game.36=Join the discussion at discord.gg/Minecraft
-tips.game.37=Emerald ores are the rarest ores in Minecraft! They can only be found in mountains and meadows!
-tips.game.38=Taming a skeleton horse doesn't require a saddle.
-tips.game.39=Ocelots show creepers who's boss!
-tips.game.40=Diorite, you either love it or hate it.
-tips.game.41=Phantoms are dangerous mobs that appear during the night. Make sure to sleep regularly!
-tips.game.42=Zombies turn into Drowned if they sink underwater.
-tips.game.43=Minecraft Live takes place every year! Look out for the next one!
-tips.game.44=Using fireworks boosts elytra speed in mid air. Just... make sure they don't explode, otherwise it'll hurt BADLY!
-tips.game.45=Gold is most common in the Nether and Badlands biomes.
-tips.game.46=Do people actually read these?
-tips.game.47=Infinite wonders, Endless possibilities.
-tips.game.48=DON'T LEAVE TREES FLOATING!
-tips.game.49=Sprint in water to swim!
-tips.game.50=Riptide enchantment will propel you through the air in the rain.
-tips.game.51=Minecraft Live is a worldwide interactive live-streaming event. Grab your items and join the party!
-tips.game.52=Be nice to animals!
-tips.game.53=The Beacon is a powerful item that can only be crafted with a nether star from the Wither!
-tips.game.54=Don't kill dolphins, you monster!
-tips.game.55=Did you know that nether stars can't be destroyed by explosions?
-tips.game.56=When digging straight up, place a torch at your feet to break any sand or gravel that could potentially fall down on you.
-tips.game.57=You can barter with Piglins.
-tips.game.58=Shear a Beehive or nest to get Honeycomb, use a Bottle to get honey.
-tips.game.59=Place a Campfire under a Beehive or nest to harvest honey peacefully. Your bees will thank you.
-tips.game.60=Respawning in the Nether requires a charged Respawn Anchor.
-tips.game.61=You can charge a Respawn Anchor with Glowstone.
-tips.game.62=Got an idea? Visit feedback.minecraft.net!
-tips.game.63=Allays can be found in Pillager Outposts and Woodland Mansions.
-tips.game.64=The Allay loves to collect items! If you give it a certain item it will try to collect more of it.
-tips.game.65=Allays love music and therefore interact with Noteblocks!
-tips.game.66=Ancient cities can be found under mountain ranges.
-tips.game.67=When wandering in Deep Dark, silence is key.
-tips.game.68=Use a water bottle on a dirt block to get mud!
-tips.game.69=Frogs eat small and blocky mobs.
-tips.game.70=Frogs pick a variant based on the temperature of the biome the tadpole grow up in.
-tips.game.71=You can collect tadpoles in buckets.
-tips.game.72=Explore structures throughout the Minecraft world to find smithing templates to trim your armor pieces.
-tips.game.73=Need more smithing templates? Try to copy them.
-tips.game.74=The sniffer egg seems to like moss blocks.
-tips.game.75=Mob heads make sounds, try them out on note blocks!
-tips.game.76=Some sand might be suspicious. Use your brush on it to find some good stuff!
-tips.game.77=Two players can ride together on a camel.
-tips.game.78=The camels jump... horizontally!
-
beginnerTips.1=Most monsters only come out at night. During the day you're safe... probably.
beginnerTips.2=Break blocks, pick up resources. Use the crafting grid to make helpful items. Now you're crafting!
beginnerTips.3=You have endless lives, but your items drop to the ground when you die. Hurry back to pick them up!
@@ -10109,6 +10099,7 @@ beginnerTips.10=Be careful when you swim. Stay under water for too long and you'
beginnerTips.11=Survival mode has 4 different difficulty levels - Peaceful, Easy, Normal, and Hard. Or play Creative mode and get endless resources!
beginnerTips.12=The world of Minecraft is endlessly surprising. You'll find lots of different animals, plants, and even §f§k§a§b§r §f§k§a§b§r ## please leave "§f§k§a§b§r" unchanged
+
midgameTips.1=Iron golems will fight for you!
midgameTips.2=Feed a bone to a wolf to tame it. You can then make it sit or follow you.
midgameTips.3=Wearing a pumpkin on your head will keep Endermen from attacking you.
@@ -10124,10 +10115,10 @@ midgameTips.12=Blocks that can be used as a light source will melt snow and ice.
midgameTips.13=Take caution when building structures made of wool out in the open, as lightning from thunderstorms can set wool on fire.
midgameTips.14=A single bucket of lava can be used in a furnace to smelt 100 blocks.
midgameTips.15=The instrument played by a note block depends on the material beneath it.
-midgameTips.16=Attacking a wolf will cause any wolves any wolves nearby to turn hostile and attack you.
+midgameTips.16=Attacking a wolf will cause any wolves nearby to turn hostile and attack you.
midgameTips.17=Wolves and iron golems won't attack creepers.
midgameTips.18=Chickens lay an egg every 5 to 10 minutes.
-midgameTips.19=Obsidian can only be mined with a diamond pickaxe.
+midgameTips.19=Obsidian can be mined with a diamond pickaxe.
midgameTips.20=Creepers are the easiest obtainable source of gunpowder.
midgameTips.21=Tame wolves show their health with the position of their tail. Feed them meat to heal them.
midgameTips.22=Different colored dyes can be made from a variety of materials, cook cactus in a furnace to get green dye!
@@ -10179,7 +10170,7 @@ midgameTips.67=Infinite wonders, endless possibilities.
midgameTips.68=Plant some saplings and they'll grow into trees.
midgameTips.69=Use a hoe to prepare areas of ground for planting.
-lategameTips.1=Zombified piglins won't attack you if you have golden armor - unless you make them angry.
+lategameTips.1=Zombified piglins won't attack you - unless you make them angry.
lategameTips.2=Hit those fireballs back at the Ghast!
lategameTips.3=Cobblestone is resistant to Ghast fireballs, making it useful for guarding portals.
lategameTips.4=Our music is by C418, Lena Raine, and Kumi Tanioka.
@@ -10517,7 +10508,7 @@ dr.marketplace.get_more_skins=Get More Skins
dr.classic_skins.show_more=Show More
onlinePlay.notRated=Online play is not rated
-onlinePlay.message=During online play you may be exposed to chat messages or other types of user generated content that has not been rated, and may not be suitable for all ages.
+onlinePlay.message=During online play you might see chat messages or other user generated content that might not be suitable for all ages.
onlinePlay.editor.notRated=Online editing is not rated
onlinePlay.editor.message=During online editing you may be exposed to chat messages or other types of user generated content that has not been rated, and may not be suitable for all ages.
onlinePlay.doNotShowAgain=Do not show this screen again