From ffb413cee4126d5e110fb79dcf82a7cb707598a3 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Mon, 15 May 2017 15:10:26 +0200
Subject: [PATCH 001/175] Added tripwire hook, hopper, redstone mechanics
saving, various improvements
---
src/main/java/cn/nukkit/Player.java | 2 +-
src/main/java/cn/nukkit/Server.java | 12 +-
src/main/java/cn/nukkit/block/Block.java | 12 +-
src/main/java/cn/nukkit/block/BlockAnvil.java | 8 +-
src/main/java/cn/nukkit/block/BlockBed.java | 2 +-
.../java/cn/nukkit/block/BlockButton.java | 13 +
src/main/java/cn/nukkit/block/BlockChest.java | 5 +-
src/main/java/cn/nukkit/block/BlockDoor.java | 9 +-
.../java/cn/nukkit/block/BlockEnderChest.java | 2 +-
.../java/cn/nukkit/block/BlockFenceGate.java | 2 +-
.../java/cn/nukkit/block/BlockFlowerPot.java | 6 +-
.../cn/nukkit/block/BlockFurnaceBurning.java | 2 +-
.../java/cn/nukkit/block/BlockHopper.java | 97 +++++-
src/main/java/cn/nukkit/block/BlockLava.java | 4 +-
.../java/cn/nukkit/block/BlockLeaves.java | 7 +
src/main/java/cn/nukkit/block/BlockLever.java | 2 +
.../cn/nukkit/block/BlockMushroomBrown.java | 46 ++-
.../cn/nukkit/block/BlockMushroomRed.java | 46 ++-
.../nukkit/block/BlockPressurePlateBase.java | 3 +
.../java/cn/nukkit/block/BlockPumpkin.java | 2 +-
.../nukkit/block/BlockRedstoneComparator.java | 10 +-
.../cn/nukkit/block/BlockRedstoneDiode.java | 25 +-
.../cn/nukkit/block/BlockRedstoneWire.java | 3 +
.../java/cn/nukkit/block/BlockSapling.java | 86 +++++-
.../java/cn/nukkit/block/BlockStairs.java | 2 +-
.../java/cn/nukkit/block/BlockTrapdoor.java | 91 ++++--
.../cn/nukkit/block/BlockTrappedChest.java | 25 +-
.../java/cn/nukkit/block/BlockTripWire.java | 134 ++++++++
.../cn/nukkit/block/BlockTripWireHook.java | 206 ++++++++++++-
.../cn/nukkit/blockentity/BlockEntity.java | 1 +
.../blockentity/BlockEntityFlowerPot.java | 8 +-
.../nukkit/blockentity/BlockEntityHopper.java | 291 ++++++++++++++++++
.../nukkit/command/FormattedCommandAlias.java | 2 +-
.../command/defaults/ParticleCommand.java | 4 +-
src/main/java/cn/nukkit/entity/Entity.java | 22 +-
.../java/cn/nukkit/entity/EntityHanging.java | 7 +-
.../java/cn/nukkit/entity/EntityLiving.java | 4 +
.../cn/nukkit/entity/item/EntityPainting.java | 2 +-
.../cn/nukkit/entity/item/EntityPotion.java | 2 +-
.../cn/nukkit/entity/mob/EntityCreeper.java | 6 +
.../nukkit/entity/projectile/EntityArrow.java | 49 +--
.../entity/projectile/EntityProjectile.java | 79 +++--
.../entity/weather/EntityLightning.java | 126 ++++----
.../event/block/BlockRedstoneEvent.java | 33 ++
.../cn/nukkit/inventory/BaseInventory.java | 48 +++
.../cn/nukkit/inventory/HopperInventory.java | 18 ++
.../java/cn/nukkit/inventory/Inventory.java | 4 +
src/main/java/cn/nukkit/item/Item.java | 2 +-
src/main/java/cn/nukkit/item/ItemHopper.java | 18 ++
.../nukkit/item/enchantment/Enchantment.java | 4 +-
.../protection/EnchantmentProtection.java | 59 +---
.../protection/EnchantmentProtectionAll.java | 13 +
.../EnchantmentProtectionExplosion.java | 14 +
.../protection/EnchantmentProtectionFall.java | 14 +
.../protection/EnchantmentProtectionFire.java | 14 +
.../EnchantmentProtectionProjectile.java | 14 +
src/main/java/cn/nukkit/level/Explosion.java | 2 +-
src/main/java/cn/nukkit/level/Level.java | 290 ++++++++++++-----
.../cn/nukkit/level/format/anvil/Chunk.java | 86 +++++-
.../level/format/anvil/ChunkSection.java | 1 -
.../cn/nukkit/level/generator/Normal.java | 15 +-
.../nukkit/level/generator/biome/Biome.java | 12 +-
.../level/generator/biome/BiomeSelector.java | 7 +-
.../level/generator/biome/MesaBiome.java | 2 +-
.../generator/biome/RoofedForestBiome.java | 1 +
...arkOakTree.java => ObjectDarkOakTree.java} | 2 +-
...eBigTree.java => ObjectJungleBigTree.java} | 18 +-
...avannaTree.java => ObjectSavannaTree.java} | 2 +-
...NewSwampTree.java => ObjectSwampTree.java} | 4 +-
.../populator/MushroomPopulator.java | 1 -
.../populator/tree/DarkOakTreePopulator.java | 4 +-
.../tree/JungleBigTreePopulator.java | 4 +-
.../populator/tree/SavannaTreePopulator.java | 4 +-
.../populator/tree/SwampTreePopulator.java | 4 +-
.../nukkit/level/sound/BlockPlaceSound.java | 1 -
.../java/cn/nukkit/math/AxisAlignedBB.java | 9 +
.../java/cn/nukkit/nbt/tag/ByteArrayTag.java | 2 +-
src/main/java/cn/nukkit/nbt/tag/ByteTag.java | 2 +-
.../java/cn/nukkit/nbt/tag/DoubleTag.java | 2 +-
src/main/java/cn/nukkit/nbt/tag/FloatTag.java | 2 +-
src/main/java/cn/nukkit/nbt/tag/IntTag.java | 2 +-
src/main/java/cn/nukkit/nbt/tag/LongTag.java | 2 +-
.../java/cn/nukkit/nbt/tag/StringTag.java | 2 +-
.../protocol/AvailableCommandsPacket.java | 2 +-
.../protocol/LevelSoundEventPacket.java | 6 +-
.../cn/nukkit/network/rcon/RCONCommand.java | 2 +-
.../cn/nukkit/network/rcon/RCONPacket.java | 2 +-
src/main/java/cn/nukkit/plugin/Plugin.java | 2 +-
.../java/cn/nukkit/plugin/PluginBase.java | 2 +-
.../java/cn/nukkit/plugin/PluginLoader.java | 4 +-
.../java/cn/nukkit/raknet/server/Session.java | 2 +-
src/main/java/cn/nukkit/utils/Binary.java | 23 +-
.../java/cn/nukkit/utils/BinaryStream.java | 14 +-
.../cn/nukkit/utils/BlockUpdateEntry.java | 49 +++
src/main/java/cn/nukkit/utils/Config.java | 1 +
.../java/cn/nukkit/utils/PriorityObject.java | 15 -
.../java/co/aikar/timings/TimingsExport.java | 8 +-
97 files changed, 1886 insertions(+), 451 deletions(-)
create mode 100644 src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java
create mode 100644 src/main/java/cn/nukkit/event/block/BlockRedstoneEvent.java
create mode 100644 src/main/java/cn/nukkit/inventory/HopperInventory.java
create mode 100644 src/main/java/cn/nukkit/item/ItemHopper.java
rename src/main/java/cn/nukkit/level/generator/object/tree/{NewDarkOakTree.java => ObjectDarkOakTree.java} (99%)
rename src/main/java/cn/nukkit/level/generator/object/tree/{NewJungleBigTree.java => ObjectJungleBigTree.java} (85%)
rename src/main/java/cn/nukkit/level/generator/object/tree/{NewSavannaTree.java => ObjectSavannaTree.java} (99%)
rename src/main/java/cn/nukkit/level/generator/object/tree/{NewSwampTree.java => ObjectSwampTree.java} (99%)
create mode 100644 src/main/java/cn/nukkit/utils/BlockUpdateEntry.java
delete mode 100644 src/main/java/cn/nukkit/utils/PriorityObject.java
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index c2ef696260..28d0cf2078 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -1712,7 +1712,7 @@ protected void processLogin() {
CompoundTag nbt = this.server.getOfflinePlayerData(this.username);
if (nbt == null) {
- this.close(this.getLeaveMessage(), "Invalid data");
+ this.close(this.getLeaveMessage(), "Invalid pos");
return;
}
diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java
index fd2fc0f32d..ad57762522 100644
--- a/src/main/java/cn/nukkit/Server.java
+++ b/src/main/java/cn/nukkit/Server.java
@@ -14,7 +14,6 @@
import cn.nukkit.entity.projectile.EntityArrow;
import cn.nukkit.entity.projectile.EntityEnderPearl;
import cn.nukkit.entity.projectile.EntitySnowball;
-import cn.nukkit.entity.weather.EntityLightning;
import cn.nukkit.event.HandlerList;
import cn.nukkit.event.level.LevelInitEvent;
import cn.nukkit.event.level.LevelLoadEvent;
@@ -1399,10 +1398,10 @@ public CompoundTag getOfflinePlayerData(String name) {
return NBTIO.readCompressed(new FileInputStream(file));
} catch (Exception e) {
file.renameTo(new File(path + name + ".dat.bak"));
- this.logger.notice(this.getLanguage().translateString("nukkit.data.playerCorrupted", name));
+ this.logger.notice(this.getLanguage().translateString("nukkit.pos.playerCorrupted", name));
}
} else {
- this.logger.notice(this.getLanguage().translateString("nukkit.data.playerNotFound", name));
+ this.logger.notice(this.getLanguage().translateString("nukkit.pos.playerNotFound", name));
}
Position spawn = this.getDefaultLevel().getSafeSpawn();
@@ -1448,7 +1447,7 @@ public void saveOfflinePlayerData(String name, CompoundTag tag, boolean async) {
Utils.writeFile(this.getDataPath() + "players/" + name.toLowerCase() + ".dat", new ByteArrayInputStream(NBTIO.writeGZIPCompressed(tag, ByteOrder.BIG_ENDIAN)));
}
} catch (Exception e) {
- this.logger.critical(this.getLanguage().translateString("nukkit.data.saveError", new String[]{name, e.getMessage()}));
+ this.logger.critical(this.getLanguage().translateString("nukkit.pos.saveError", new String[]{name, e.getMessage()}));
if (Nukkit.DEBUG > 1) {
this.logger.logException(e);
}
@@ -1910,7 +1909,7 @@ public Map> getCommandAliases() {
}
public boolean shouldSavePlayerData() {
- return (Boolean) this.getConfig("player.save-player-data", true);
+ return (Boolean) this.getConfig("player.save-player-pos", true);
}
/**
@@ -1954,7 +1953,7 @@ private void registerEntities() {
// TODO: 2016/1/30 all finds of minecart
Entity.registerEntity("Boat", EntityBoat.class);
- Entity.registerEntity("Lightning", EntityLightning.class);
+ //Entity.registerEntity("Lightning", EntityLightning.class); lightning shouldn't be saved as entity
}
private void registerBlockEntities() {
@@ -1971,6 +1970,7 @@ private void registerBlockEntities() {
BlockEntity.registerBlockEntity(BlockEntity.BEACON, BlockEntityBeacon.class);
BlockEntity.registerBlockEntity(BlockEntity.PISTON_ARM, BlockEntityPistonArm.class);
BlockEntity.registerBlockEntity(BlockEntity.COMPARATOR, BlockEntityComparator.class);
+ BlockEntity.registerBlockEntity(BlockEntity.HOPPER, BlockEntityHopper.class);
}
public static Server getInstance() {
diff --git a/src/main/java/cn/nukkit/block/Block.java b/src/main/java/cn/nukkit/block/Block.java
index 67723e709f..5cc5ff3634 100644
--- a/src/main/java/cn/nukkit/block/Block.java
+++ b/src/main/java/cn/nukkit/block/Block.java
@@ -456,7 +456,7 @@ public static void init() {
list[SANDSTONE_STAIRS] = BlockStairsSandstone.class; //128
list[EMERALD_ORE] = BlockOreEmerald.class; //129
list[ENDER_CHEST] = BlockEnderChest.class; //130
- //TODO: list[TRIPWIRE_HOOK] = BlockTripwireHook.class; //131
+ list[TRIPWIRE_HOOK] = BlockTripWireHook.class;
list[TRIPWIRE] = BlockTripWire.class; //132
list[EMERALD_BLOCK] = BlockEmerald.class; //133
list[SPRUCE_WOOD_STAIRS] = BlockStairsSpruce.class; //134
@@ -479,7 +479,7 @@ public static void init() {
list[DAYLIGHT_DETECTOR] = BlockDaylightDetector.class; //151
list[REDSTONE_BLOCK] = BlockRedstone.class; //152
list[QUARTZ_ORE] = BlockOreQuartz.class; //153
- //TODO: list[HOPPER_BLOCK] = BlockHopper.class; //154
+ list[HOPPER_BLOCK] = BlockHopper.class; //154
list[QUARTZ_BLOCK] = BlockQuartz.class; //155
list[QUARTZ_STAIRS] = BlockStairsQuartz.class; //156
list[DOUBLE_WOOD_SLAB] = BlockDoubleSlabWood.class; //157
@@ -1052,4 +1052,12 @@ public int getDropExp() {
public boolean isNormalBlock() {
return !isTransparent() && isSolid() && !isPowerSource();
}
+
+ public static boolean equals(Block b1, Block b2) {
+ return equals(b1, b2, true);
+ }
+
+ public static boolean equals(Block b1, Block b2, boolean checkDamage) {
+ return b1 != null && b2 != null && b1.getId() == b2.getId() && (!checkDamage || b1.getDamage() == b2.getDamage());
+ }
}
\ No newline at end of file
diff --git a/src/main/java/cn/nukkit/block/BlockAnvil.java b/src/main/java/cn/nukkit/block/BlockAnvil.java
index 242c4ca580..11536ea87a 100644
--- a/src/main/java/cn/nukkit/block/BlockAnvil.java
+++ b/src/main/java/cn/nukkit/block/BlockAnvil.java
@@ -74,13 +74,13 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl
if (!target.isTransparent()) {
int faces[] = {0, 1, 2, 3};
int damage = this.getDamage();
- this.meta = faces[player != null ? player.getDirection() : 0] & 0x04;
+ this.meta = faces[player != null ? player.getDirection().getHorizontalIndex() : 0] & 0x04;
if (damage >= 0 && damage <= 3) {
- this.meta = faces[player != null ? player.getDirection() : 0];
+ this.meta = faces[player != null ? player.getDirection().getHorizontalIndex() : 0];
} else if (damage >= 4 && damage <= 7) {
- this.meta = faces[player != null ? player.getDirection() : 0] | 0x04;
+ this.meta = faces[player != null ? player.getDirection().getHorizontalIndex() : 0] | 0x04;
} else if (damage >= 8 && damage <= 11) {
- this.meta = faces[player != null ? player.getDirection() : 0] | 0x08;
+ this.meta = faces[player != null ? player.getDirection().getHorizontalIndex() : 0] | 0x08;
}
this.getLevel().setBlock(block, this, true);
return true;
diff --git a/src/main/java/cn/nukkit/block/BlockBed.java b/src/main/java/cn/nukkit/block/BlockBed.java
index 8dad80953b..64ab101fb5 100644
--- a/src/main/java/cn/nukkit/block/BlockBed.java
+++ b/src/main/java/cn/nukkit/block/BlockBed.java
@@ -119,7 +119,7 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl
Block down = this.down();
if (!down.isTransparent()) {
int[] faces = {3, 4, 2, 5};
- int d = player != null ? player.getDirection() : 0;
+ int d = player != null ? player.getDirection().getHorizontalIndex() : 0;
Block next = this.getSide(BlockFace.fromIndex(faces[((d + 3) % 4)]));
Block downNext = this.down();
diff --git a/src/main/java/cn/nukkit/block/BlockButton.java b/src/main/java/cn/nukkit/block/BlockButton.java
index d1544f6faa..cef035c5b2 100644
--- a/src/main/java/cn/nukkit/block/BlockButton.java
+++ b/src/main/java/cn/nukkit/block/BlockButton.java
@@ -1,6 +1,7 @@
package cn.nukkit.block;
import cn.nukkit.Player;
+import cn.nukkit.event.block.BlockRedstoneEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
import cn.nukkit.level.sound.ButtonClickSound;
@@ -52,6 +53,7 @@ public boolean onActivate(Item item, Player player) {
return false;
}
+ this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, 0, 15));
this.meta ^= 0x08;
this.level.setBlock(this, this, true, false);
this.level.addSound(new ButtonClickSound(this.add(0.5, 0.5, 0.5)));
@@ -72,6 +74,8 @@ public int onUpdate(int type) {
}
} else if (type == Level.BLOCK_UPDATE_SCHEDULED) {
if (this.isActivated()) {
+ this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, 15, 0));
+
this.meta ^= 0x08;
this.level.setBlock(this, this, true, false);
this.level.addSound(new ButtonClickSound(this.add(0.5, 0.5, 0.5)));
@@ -108,4 +112,13 @@ public BlockFace getFacing() {
int side = isActivated() ? meta ^ 0x08 : meta;
return BlockFace.fromIndex(side);
}
+
+ @Override
+ public boolean onBreak(Item item) {
+ if (isActivated()) {
+ this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, 15, 0));
+ }
+
+ return super.onBreak(item);
+ }
}
\ No newline at end of file
diff --git a/src/main/java/cn/nukkit/block/BlockChest.java b/src/main/java/cn/nukkit/block/BlockChest.java
index 931a073ff0..ff0cdbc08c 100644
--- a/src/main/java/cn/nukkit/block/BlockChest.java
+++ b/src/main/java/cn/nukkit/block/BlockChest.java
@@ -74,10 +74,9 @@ public AxisAlignedBB recalculateBoundingBox() {
@Override
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
- int[] faces = {4, 2, 5, 3};
-
BlockEntityChest chest = null;
- this.meta = faces[player != null ? player.getDirection() : 0];
+ int[] faces = {4, 2, 5, 3};
+ this.meta = faces[player != null ? player.getDirection().getHorizontalIndex() : 0];
for (int side = 2; side <= 5; ++side) {
if ((this.meta == 4 || this.meta == 5) && (side == 4 || side == 5)) {
diff --git a/src/main/java/cn/nukkit/block/BlockDoor.java b/src/main/java/cn/nukkit/block/BlockDoor.java
index 8ed1735760..56ab5c5b0c 100644
--- a/src/main/java/cn/nukkit/block/BlockDoor.java
+++ b/src/main/java/cn/nukkit/block/BlockDoor.java
@@ -1,6 +1,7 @@
package cn.nukkit.block;
import cn.nukkit.Player;
+import cn.nukkit.event.block.BlockRedstoneEvent;
import cn.nukkit.event.block.DoorToggleEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
@@ -217,6 +218,8 @@ public int onUpdate(int type) {
if (type == Level.BLOCK_UPDATE_REDSTONE) {
if ((!isOpen() && this.level.isBlockPowered(this)) || (isOpen() && !this.level.isBlockPowered(this))) {
+ this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, isOpen() ? 15 : 0, isOpen() ? 0 : 15));
+
this.toggle(null);
}
}
@@ -237,7 +240,7 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl
if (!blockUp.canBeReplaced() || blockDown.isTransparent()) {
return false;
}
- int direction = player != null ? player.getDirection() : 0;
+ int direction = player != null ? player.getDirection().getOpposite().getHorizontalIndex() : 0;
int[] faces = {3, 4, 2, 5};
Block next = this.getSide(BlockFace.fromIndex(faces[((direction + 2) % 4)]));
@@ -250,6 +253,10 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl
this.setDamage(direction & 0x03);
this.getLevel().setBlock(block, this, true, true); //Bottom
this.getLevel().setBlock(blockUp, Block.get(this.getId(), metaUp), true); //Top
+
+ if (!this.isOpen() && this.level.isBlockPowered(this)) {
+ this.toggle(null);
+ }
return true;
}
diff --git a/src/main/java/cn/nukkit/block/BlockEnderChest.java b/src/main/java/cn/nukkit/block/BlockEnderChest.java
index 85a9660ecc..285972d8c7 100644
--- a/src/main/java/cn/nukkit/block/BlockEnderChest.java
+++ b/src/main/java/cn/nukkit/block/BlockEnderChest.java
@@ -78,7 +78,7 @@ public AxisAlignedBB recalculateBoundingBox() {
@Override
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
int[] faces = {4, 2, 5, 3};
- this.meta = faces[player != null ? player.getDirection() : 0];
+ this.meta = faces[player != null ? player.getDirection().getHorizontalIndex() : 0];
this.getLevel().setBlock(block, this, true, true);
CompoundTag nbt = new CompoundTag("")
diff --git a/src/main/java/cn/nukkit/block/BlockFenceGate.java b/src/main/java/cn/nukkit/block/BlockFenceGate.java
index b079c957e9..7a0c0651a2 100644
--- a/src/main/java/cn/nukkit/block/BlockFenceGate.java
+++ b/src/main/java/cn/nukkit/block/BlockFenceGate.java
@@ -83,7 +83,7 @@ protected AxisAlignedBB recalculateBoundingBox() {
@Override
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
- this.meta = player != null ? (player.getDirection() - 1) & 0x03 : 0;
+ this.meta = player != null ? (player.getDirection().getHorizontalIndex() - 1) & 0x03 : 0;
this.getLevel().setBlock(block, this, true, true);
return true;
diff --git a/src/main/java/cn/nukkit/block/BlockFlowerPot.java b/src/main/java/cn/nukkit/block/BlockFlowerPot.java
index 7e3139801a..ebf65fccdb 100644
--- a/src/main/java/cn/nukkit/block/BlockFlowerPot.java
+++ b/src/main/java/cn/nukkit/block/BlockFlowerPot.java
@@ -70,7 +70,7 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl
.putInt("y", (int) this.y)
.putInt("z", (int) this.z)
.putShort("item", 0)
- .putInt("data", 0);
+ .putInt("pos", 0);
if (item.hasCustomBlockData()) {
for (Tag aTag : item.getCustomBlockData().getAllTags()) {
nbt.put(aTag.getName(), aTag);
@@ -110,7 +110,7 @@ public boolean onActivate(Item item, Player player) {
itemMeta = item.getDamage();
}
blockEntity.namedTag.putShort("item", itemID);
- blockEntity.namedTag.putInt("data", itemMeta);
+ blockEntity.namedTag.putInt("pos", itemMeta);
this.meta = 1;
this.getLevel().setBlock(this, this, true);
@@ -132,7 +132,7 @@ public int[][] getDrops(Item item) {
if (blockEntity instanceof BlockEntityFlowerPot) {
dropInside = true;
insideID = blockEntity.namedTag.getShort("item");
- insideMeta = blockEntity.namedTag.getInt("data");
+ insideMeta = blockEntity.namedTag.getInt("pos");
}
if (dropInside) {
diff --git a/src/main/java/cn/nukkit/block/BlockFurnaceBurning.java b/src/main/java/cn/nukkit/block/BlockFurnaceBurning.java
index 4e33a8bd05..167d7144af 100644
--- a/src/main/java/cn/nukkit/block/BlockFurnaceBurning.java
+++ b/src/main/java/cn/nukkit/block/BlockFurnaceBurning.java
@@ -66,7 +66,7 @@ public int getLightLevel() {
@Override
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
int faces[] = {4, 2, 5, 3};
- this.meta = faces[player != null ? player.getDirection() : 0];
+ this.meta = faces[player != null ? player.getDirection().getHorizontalIndex() : 0];
this.getLevel().setBlock(block, this, true, true);
CompoundTag nbt = new CompoundTag()
.putList(new ListTag<>("Items"))
diff --git a/src/main/java/cn/nukkit/block/BlockHopper.java b/src/main/java/cn/nukkit/block/BlockHopper.java
index a515fede0a..44c112e1d1 100644
--- a/src/main/java/cn/nukkit/block/BlockHopper.java
+++ b/src/main/java/cn/nukkit/block/BlockHopper.java
@@ -1,9 +1,19 @@
package cn.nukkit.block;
+import cn.nukkit.Player;
+import cn.nukkit.blockentity.BlockEntity;
+import cn.nukkit.blockentity.BlockEntityHopper;
+import cn.nukkit.inventory.ContainerInventory;
+import cn.nukkit.item.Item;
+import cn.nukkit.level.Level;
+import cn.nukkit.math.BlockFace;
+import cn.nukkit.nbt.tag.CompoundTag;
+import cn.nukkit.nbt.tag.ListTag;
+
/**
* @author CreeperFace
*/
-public class BlockHopper extends BlockSolid {
+public class BlockHopper extends BlockTransparent {
public BlockHopper() {
this(0);
@@ -20,7 +30,52 @@ public int getId() {
@Override
public String getName() {
- return "Hopper";
+ return "Hopper Block";
+ }
+
+ @Override
+ public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
+ BlockFace facing = face.getOpposite();
+
+ if (facing == BlockFace.UP) {
+ facing = BlockFace.DOWN;
+ }
+
+ this.meta = facing.getIndex();
+
+ boolean powered = this.level.isBlockPowered(this);
+
+ if (powered == this.isEnabled()) {
+ this.setEnabled(!powered);
+ }
+
+ this.level.setBlock(this, this);
+
+ CompoundTag nbt = new CompoundTag()
+ .putList(new ListTag<>("Items"))
+ .putString("id", BlockEntity.HOPPER)
+ .putInt("x", (int) this.x)
+ .putInt("y", (int) this.y)
+ .putInt("z", (int) this.z);
+
+ new BlockEntityHopper(this.level.getChunk(this.getFloorX() >> 4, this.getFloorZ() >> 4), nbt);
+ return true;
+ }
+
+ @Override
+ public boolean onActivate(Item item, Player player) {
+ BlockEntity blockEntity = this.level.getBlockEntity(this);
+
+ if (blockEntity instanceof BlockEntityHopper) {
+ return player.addWindow(((BlockEntityHopper) blockEntity).getInventory()) != -1;
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean canBeActivated() {
+ return true;
}
public boolean hasComparatorInputOverride() {
@@ -29,12 +84,42 @@ public boolean hasComparatorInputOverride() {
@Override
public int getComparatorInputOverride() {
- /*BlockEntity blockEntity = this.level.getBlockEntity(this);
+ BlockEntity blockEntity = this.level.getBlockEntity(this);
- if (blockEntity instanceof BlockEntityHopper) { TODO: hopper
+ if (blockEntity instanceof BlockEntityHopper) {
return ContainerInventory.calculateRedstone(((BlockEntityHopper) blockEntity).getInventory());
- }*/
+ }
return super.getComparatorInputOverride();
}
-}
+
+ public BlockFace getFacing() {
+ return BlockFace.fromIndex(this.meta & 7);
+ }
+
+ public boolean isEnabled() {
+ return (this.meta & 0x08) != 8;
+ }
+
+ public void setEnabled(boolean enabled) {
+ if (isEnabled() != enabled) {
+ this.meta ^= 0x08;
+ }
+ }
+
+ @Override
+ public int onUpdate(int type) {
+ if (type == Level.BLOCK_UPDATE_NORMAL) {
+ boolean powered = this.level.isBlockPowered(this);
+
+ if (powered == this.isEnabled()) {
+ this.setEnabled(!powered);
+ this.level.setBlock(this, this, true, false);
+ }
+
+ return type;
+ }
+
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cn/nukkit/block/BlockLava.java b/src/main/java/cn/nukkit/block/BlockLava.java
index 85d53538bd..06bcb9cafb 100644
--- a/src/main/java/cn/nukkit/block/BlockLava.java
+++ b/src/main/java/cn/nukkit/block/BlockLava.java
@@ -97,7 +97,7 @@ public int onUpdate(int type) {
if (!e.isCancelled()) {
BlockFire fire = new BlockFire();
this.getLevel().setBlock(v, fire, true);
- this.getLevel().scheduleUpdate(v, fire.tickRate());
+ this.getLevel().scheduleUpdate(fire, fire.tickRate());
return Level.BLOCK_UPDATE_RANDOM;
}
@@ -119,7 +119,7 @@ public int onUpdate(int type) {
if (!e.isCancelled()) {
BlockFire fire = new BlockFire();
this.getLevel().setBlock(v, fire, true);
- this.getLevel().scheduleUpdate(v, fire.tickRate());
+ this.getLevel().scheduleUpdate(fire, fire.tickRate());
}
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockLeaves.java b/src/main/java/cn/nukkit/block/BlockLeaves.java
index f917033751..44e014d28c 100644
--- a/src/main/java/cn/nukkit/block/BlockLeaves.java
+++ b/src/main/java/cn/nukkit/block/BlockLeaves.java
@@ -180,6 +180,13 @@ private Boolean findLog(Block pos, ArrayList visited, Integer distance,
return false;
}
+ public boolean isChechDecay() {
+ return (this.meta & 0x08) > 0;
+ }
+
+ public boolean isDecayable() {
+ return (this.meta & 0x04) == 0;
+ }
@Override
public BlockColor getColor() {
diff --git a/src/main/java/cn/nukkit/block/BlockLever.java b/src/main/java/cn/nukkit/block/BlockLever.java
index efdae140bb..b69446854e 100644
--- a/src/main/java/cn/nukkit/block/BlockLever.java
+++ b/src/main/java/cn/nukkit/block/BlockLever.java
@@ -1,6 +1,7 @@
package cn.nukkit.block;
import cn.nukkit.Player;
+import cn.nukkit.event.block.BlockRedstoneEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
import cn.nukkit.level.sound.LeverSound;
@@ -57,6 +58,7 @@ public boolean isPowerOn() {
@Override
public boolean onActivate(Item item, Player player) {
+ this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, isPowerOn() ? 15 : 0, isPowerOn() ? 0 : 15));
this.meta ^= 0x08;
this.getLevel().setBlock(this, this, false, true);
diff --git a/src/main/java/cn/nukkit/block/BlockMushroomBrown.java b/src/main/java/cn/nukkit/block/BlockMushroomBrown.java
index 07f7285630..c2739a7aa2 100644
--- a/src/main/java/cn/nukkit/block/BlockMushroomBrown.java
+++ b/src/main/java/cn/nukkit/block/BlockMushroomBrown.java
@@ -3,9 +3,12 @@
import cn.nukkit.Player;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
-import cn.nukkit.math.AxisAlignedBB;
+import cn.nukkit.level.generator.object.mushroom.BigMushroom;
+import cn.nukkit.level.particle.BoneMealParticle;
import cn.nukkit.math.BlockFace;
+import cn.nukkit.math.NukkitRandom;
import cn.nukkit.utils.BlockColor;
+import cn.nukkit.utils.DyeColor;
/**
* @author Nukkit Project Team
@@ -38,7 +41,7 @@ public int getLightLevel() {
@Override
public int onUpdate(int type) {
if (type == Level.BLOCK_UPDATE_NORMAL) {
- if (down().isTransparent()) {
+ if (!canStay()) {
getLevel().useBreakOn(this);
return Level.BLOCK_UPDATE_NORMAL;
@@ -49,18 +52,47 @@ public int onUpdate(int type) {
@Override
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
- Block down = down();
- if (!down.isTransparent()) {
+ if (canStay()) {
getLevel().setBlock(block, this, true, true);
-
return true;
}
return false;
}
@Override
- public AxisAlignedBB getBoundingBox() {
- return null;
+ public boolean canBeActivated() {
+ return true;
+ }
+
+ @Override
+ public boolean onActivate(Item item, Player player) {
+ if (item.getId() == Item.DYE && item.getDamage() == DyeColor.WHITE.getDyeData()) {
+ if (this.level.rand.nextFloat() < 0.4) {
+ this.grow();
+ }
+
+ this.level.addParticle(new BoneMealParticle(this));
+ return true;
+ }
+ return false;
+ }
+
+ public boolean grow() {
+ this.level.setBlock(this, new BlockAir(), true, false);
+
+ BigMushroom generator = new BigMushroom(0);
+
+ if (generator.generate(this.level, new NukkitRandom(), this)) {
+ return true;
+ } else {
+ this.level.setBlock(this, this, true, false);
+ return false;
+ }
+ }
+
+ public boolean canStay() {
+ Block block = this.down();
+ return block.getId() == MYCELIUM || block.getId() == PODZOL || (!block.isTransparent() && this.level.getFullLight(this) < 13);
}
@Override
diff --git a/src/main/java/cn/nukkit/block/BlockMushroomRed.java b/src/main/java/cn/nukkit/block/BlockMushroomRed.java
index 1bbfa45ee7..bfc985c081 100644
--- a/src/main/java/cn/nukkit/block/BlockMushroomRed.java
+++ b/src/main/java/cn/nukkit/block/BlockMushroomRed.java
@@ -3,8 +3,12 @@
import cn.nukkit.Player;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
+import cn.nukkit.level.generator.object.mushroom.BigMushroom;
+import cn.nukkit.level.particle.BoneMealParticle;
import cn.nukkit.math.BlockFace;
+import cn.nukkit.math.NukkitRandom;
import cn.nukkit.utils.BlockColor;
+import cn.nukkit.utils.DyeColor;
/**
* Created by Pub4Game on 03.01.2015.
@@ -32,7 +36,7 @@ public int getId() {
@Override
public int onUpdate(int type) {
if (type == Level.BLOCK_UPDATE_NORMAL) {
- if (down().isTransparent()) {
+ if (!canStay()) {
getLevel().useBreakOn(this);
return Level.BLOCK_UPDATE_NORMAL;
@@ -43,15 +47,51 @@ public int onUpdate(int type) {
@Override
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
- Block down = down();
- if (!down.isTransparent()) {
+ System.out.println("light: " + this.level.getFullLight(this));
+
+ if (canStay()) {
getLevel().setBlock(block, this, true, true);
+ return true;
+ }
+ return false;
+ }
+ @Override
+ public boolean canBeActivated() {
+ return true;
+ }
+
+ @Override
+ public boolean onActivate(Item item, Player player) {
+ if (item.getId() == Item.DYE && item.getDamage() == DyeColor.WHITE.getDyeData()) {
+ if (this.level.rand.nextFloat() < 0.4) {
+ this.grow();
+ }
+
+ this.level.addParticle(new BoneMealParticle(this));
return true;
}
return false;
}
+ public boolean grow() {
+ this.level.setBlock(this, new BlockAir(), true, false);
+
+ BigMushroom generator = new BigMushroom(1);
+
+ if (generator.generate(this.level, new NukkitRandom(), this)) {
+ return true;
+ } else {
+ this.level.setBlock(this, this, true, false);
+ return false;
+ }
+ }
+
+ public boolean canStay() {
+ Block block = this.down();
+ return block.getId() == MYCELIUM || block.getId() == PODZOL || (!block.isTransparent() && this.level.getFullLight(this) < 13);
+ }
+
@Override
public BlockColor getColor() {
return BlockColor.FOLIAGE_BLOCK_COLOR;
diff --git a/src/main/java/cn/nukkit/block/BlockPressurePlateBase.java b/src/main/java/cn/nukkit/block/BlockPressurePlateBase.java
index bba5c80587..adb04e65c7 100644
--- a/src/main/java/cn/nukkit/block/BlockPressurePlateBase.java
+++ b/src/main/java/cn/nukkit/block/BlockPressurePlateBase.java
@@ -1,6 +1,7 @@
package cn.nukkit.block;
import cn.nukkit.entity.Entity;
+import cn.nukkit.event.block.BlockRedstoneEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
import cn.nukkit.level.sound.ClickSound;
@@ -103,8 +104,10 @@ protected void updateState(int oldStrength) {
if (!isPowered && wasPowered) {
this.playOffSound();
+ this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, 15, 0));
} else if (isPowered && !wasPowered) {
this.playOnSound();
+ this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, 0, 15));
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockPumpkin.java b/src/main/java/cn/nukkit/block/BlockPumpkin.java
index ecf508b8ed..a9431ef047 100644
--- a/src/main/java/cn/nukkit/block/BlockPumpkin.java
+++ b/src/main/java/cn/nukkit/block/BlockPumpkin.java
@@ -48,7 +48,7 @@ public int getToolType() {
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
if (player != null) {
if (player.getDirection() != null) {
- this.meta = (player.getDirection() + 5) % 4;
+ this.meta = (player.getDirection().getHorizontalIndex() + 5) % 4;
}
}
this.getLevel().setBlock(block, this, true, true);
diff --git a/src/main/java/cn/nukkit/block/BlockRedstoneComparator.java b/src/main/java/cn/nukkit/block/BlockRedstoneComparator.java
index b86f95a661..c7146ac39d 100644
--- a/src/main/java/cn/nukkit/block/BlockRedstoneComparator.java
+++ b/src/main/java/cn/nukkit/block/BlockRedstoneComparator.java
@@ -56,13 +56,19 @@ protected int getRedstoneSignal() {
@Override
public void updateState() {
- if (!this.level.isUpdateScheduled(this)) {
+ if (!this.level.isUpdateScheduled(this, this)) {
int output = this.calculateOutput();
BlockEntity blockEntity = this.level.getBlockEntity(this);
int power = blockEntity instanceof BlockEntityComparator ? ((BlockEntityComparator) blockEntity).getOutputSignal() : 0;
if (output != power || this.isPowered() != this.shouldBePowered()) {
- this.level.scheduleUpdate(this, 2);
+ /*if(isFacingTowardsRepeater()) {
+ this.level.scheduleUpdate(this, this, 2, -1);
+ } else {
+ this.level.scheduleUpdate(this, this, 2, 0);
+ }*/
+
+ this.level.scheduleUpdate(this, this, 2);
}
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockRedstoneDiode.java b/src/main/java/cn/nukkit/block/BlockRedstoneDiode.java
index 1b19108960..309cab31f8 100644
--- a/src/main/java/cn/nukkit/block/BlockRedstoneDiode.java
+++ b/src/main/java/cn/nukkit/block/BlockRedstoneDiode.java
@@ -27,10 +27,6 @@ public boolean onBreak(Item item) {
Vector3 pos = getLocation();
this.level.setBlock(this, new BlockAir(), true, true);
- if (this.level.isUpdateScheduled(this)) {
- this.level.cancelSheduledUpdate(this);
- }
-
for (BlockFace face : BlockFace.values()) {
this.level.updateAroundRedstone(pos.getSide(face), null);
}
@@ -43,7 +39,7 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl
return false;
}
- this.meta = (player.getDirection() + 5) % 4;
+ this.meta = (player.getDirection().getHorizontalIndex() + 5) % 4;
this.level.setBlock(block, this, true, true);
if (shouldBePowered()) {
@@ -68,7 +64,7 @@ public int onUpdate(int type) {
this.level.updateAroundRedstone(this.getLocation().getSide(getFacing().getOpposite()), null);
if (!shouldBePowered) {
- level.scheduleUpdate(pos, this.getDelay());
+ level.scheduleUpdate(getPowered(), this, this.getDelay());
}
}
}
@@ -88,9 +84,16 @@ public void updateState() {
if (!this.isLocked()) {
boolean shouldPowered = this.shouldBePowered();
- if ((this.isPowered && !shouldPowered || !this.isPowered && shouldPowered) && !this.level.isUpdateScheduled(this)) {
+ if ((this.isPowered && !shouldPowered || !this.isPowered && shouldPowered) && !this.level.isUpdateScheduled(this, this)) {
+ /*int priority = -1;
+
+ if (this.isFacingTowardsRepeater()) {
+ priority = -3;
+ } else if (this.isPowered) {
+ priority = -2;
+ }*/
- this.level.scheduleUpdate(this, this.getDelay());
+ this.level.scheduleUpdate(this, this, this.getDelay());
}
}
}
@@ -181,4 +184,10 @@ public boolean canBeActivated() {
public boolean isPowered() {
return isPowered;
}
+
+ public boolean isFacingTowardsRepeater() {
+ BlockFace side = getFacing().getOpposite();
+ Block block = this.getSide(side);
+ return block instanceof BlockRedstoneDiode && ((BlockRedstoneDiode) block).getFacing() != side;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/cn/nukkit/block/BlockRedstoneWire.java b/src/main/java/cn/nukkit/block/BlockRedstoneWire.java
index 33a7334600..fc8a5f4f6b 100644
--- a/src/main/java/cn/nukkit/block/BlockRedstoneWire.java
+++ b/src/main/java/cn/nukkit/block/BlockRedstoneWire.java
@@ -1,6 +1,7 @@
package cn.nukkit.block;
import cn.nukkit.Player;
+import cn.nukkit.event.block.BlockRedstoneEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
import cn.nukkit.math.BlockFace;
@@ -129,6 +130,8 @@ private void calculateCurrentChanges(boolean force) {
}
if (meta != maxStrength) {
+ this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, meta, maxStrength));
+
this.meta = maxStrength;
this.level.setBlock(this, this, false, false);
diff --git a/src/main/java/cn/nukkit/block/BlockSapling.java b/src/main/java/cn/nukkit/block/BlockSapling.java
index ad640db423..a7b41cd02c 100644
--- a/src/main/java/cn/nukkit/block/BlockSapling.java
+++ b/src/main/java/cn/nukkit/block/BlockSapling.java
@@ -3,10 +3,12 @@
import cn.nukkit.Player;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
-import cn.nukkit.level.generator.object.tree.ObjectTree;
+import cn.nukkit.level.generator.object.BasicGenerator;
+import cn.nukkit.level.generator.object.tree.*;
import cn.nukkit.level.particle.BoneMealParticle;
import cn.nukkit.math.BlockFace;
import cn.nukkit.math.NukkitRandom;
+import cn.nukkit.math.Vector3;
import cn.nukkit.utils.BlockColor;
/**
@@ -71,12 +73,81 @@ public boolean onActivate(Item item, Player player) {
item.count--;
}
+ this.level.addParticle(new BoneMealParticle(this));
if (this.level.rand.nextFloat() >= 0.45) {
- this.level.addParticle(new BoneMealParticle(this));
return true;
}
- ObjectTree.growTree(this.getLevel(), (int) this.x, (int) this.y, (int) this.z, new NukkitRandom(), this.meta & 0x07);
+ BasicGenerator generator = null;
+ boolean bigTree = false;
+
+ int x = 0;
+ int z = 0;
+
+ switch (this.meta) {
+ case JUNGLE:
+ loop:
+ for (x = 0; x >= -1; --x) {
+ for (z = 0; z >= -1; --z) {
+ if (this.findSaplings(x, z, JUNGLE)) {
+ generator = new ObjectJungleBigTree(10, 20, new BlockWood(BlockWood.JUNGLE), new BlockLeaves(BlockLeaves.JUNGLE));
+ bigTree = true;
+ break loop;
+ }
+ }
+ }
+
+ if (!bigTree) {
+ generator = new NewJungleTree(4 + this.level.rand.nextInt(7));
+ }
+ break;
+ case ACACIA:
+ generator = new ObjectSavannaTree();
+ break;
+ case DARK_OAK:
+ bigTree = false;
+
+ loop:
+ for (x = 0; x >= -1; --x) {
+ for (z = 0; z >= -1; --z) {
+ if (this.findSaplings(x, z, DARK_OAK)) {
+ generator = new ObjectDarkOakTree();
+ bigTree = true;
+ break loop;
+ }
+ }
+ }
+
+ if (!bigTree) {
+ return false;
+ }
+ break;
+ //TODO: big spruce
+ default:
+ ObjectTree.growTree(this.getLevel(), (int) this.x, (int) this.y, (int) this.z, new NukkitRandom(), this.meta & 0x07);
+ return true;
+ }
+ BlockAir air = new BlockAir();
+
+ if (bigTree) {
+ this.level.setBlock(this.add(x, 0, z), air, true, false);
+ this.level.setBlock(this.add(x + 1, 0, z), air, true, false);
+ this.level.setBlock(this.add(x, 0, z + 1), air, true, false);
+ this.level.setBlock(this.add(x + 1, 0, z + 1), air, true, false);
+ } else {
+ this.level.setBlock(this, air, true, false);
+ }
+
+ if (!generator.generate(this.level, new NukkitRandom(), this.add(x, 0, z))) {
+ if (bigTree) {
+ this.level.setBlock(this.add(x, 0, z), this, true, false);
+ this.level.setBlock(this.add(x + 1, 0, z), this, true, false);
+ this.level.setBlock(this.add(x, 0, z + 1), this, true, false);
+ this.level.setBlock(this.add(x + 1, 0, z + 1), this, true, false);
+ } else {
+ this.level.setBlock(this, this, true, false);
+ }
+ }
return true;
}
this.getLevel().loadChunk((int) this.x >> 4, (int) this.z >> 4);
@@ -112,6 +183,15 @@ public int[][] getDrops(Item item) {
};
}
+ private boolean findSaplings(int x, int z, int type) {
+ return this.isSameType(this.add(x, 0, z), type) && this.isSameType(this.add(x + 1, 0, z), type) && this.isSameType(this.add(x, 0, z + 1), type) && this.isSameType(this.add(x + 1, 0, z + 1), type);
+ }
+
+ public boolean isSameType(Vector3 pos, int type) {
+ Block block = this.level.getBlock(pos);
+ return block.getId() == this.getId() && block.getDamage() == type;
+ }
+
@Override
public BlockColor getColor() {
return BlockColor.FOLIAGE_BLOCK_COLOR;
diff --git a/src/main/java/cn/nukkit/block/BlockStairs.java b/src/main/java/cn/nukkit/block/BlockStairs.java
index 551261517b..61ca585090 100644
--- a/src/main/java/cn/nukkit/block/BlockStairs.java
+++ b/src/main/java/cn/nukkit/block/BlockStairs.java
@@ -47,7 +47,7 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl
@Override
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
int[] faces = new int[]{0, 2, 1, 3};
- this.meta = (faces[player.getDirection()] & 0x03);
+ this.meta = (faces[player.getDirection().getHorizontalIndex()] & 0x03);
if ((fy > 0.5 && face != BlockFace.UP) || face == BlockFace.DOWN) {
this.meta |= 0x04; //Upside-down stairs
}
diff --git a/src/main/java/cn/nukkit/block/BlockTrapdoor.java b/src/main/java/cn/nukkit/block/BlockTrapdoor.java
index 56994bce82..214bccfd92 100644
--- a/src/main/java/cn/nukkit/block/BlockTrapdoor.java
+++ b/src/main/java/cn/nukkit/block/BlockTrapdoor.java
@@ -1,6 +1,7 @@
package cn.nukkit.block;
import cn.nukkit.Player;
+import cn.nukkit.event.block.BlockRedstoneEvent;
import cn.nukkit.event.block.DoorToggleEvent;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemTool;
@@ -123,8 +124,9 @@ protected AxisAlignedBB recalculateBoundingBox() {
@Override
public int onUpdate(int type) {
- if (type == Level.BLOCK_UPDATE_REDSTONE) {
+ if (type == Level.BLOCK_UPDATE_REDSTONE || type == Level.BLOCK_UPDATE_NORMAL) {
if ((!isOpen() && this.level.isBlockPowered(this)) || (isOpen() && !this.level.isBlockPowered(this))) {
+ this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, isOpen() ? 15 : 0, isOpen() ? 0 : 15));
this.toggle(null);
return type;
}
@@ -136,25 +138,25 @@ public int onUpdate(int type) {
@Override
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
if ((!target.isTransparent() || target.getId() == SLAB)) {
- int faceBit = 0b00;
- int upDownBit = 0b000;
- if (fy > 0.5) upDownBit = 0b100;
- switch (face) {
- case NORTH:
- faceBit = 0b11;
- break;
- case SOUTH:
- faceBit = 0b10;
- break;
- case WEST:
- faceBit = 0b01;
- break;
- case EAST:
- faceBit = 0b00;
- break;
+ BlockFace facing;
+ boolean top;
+
+ if (face.getAxis().isHorizontal() || player == null) {
+ facing = face;
+ top = fy > 0.5;
+ } else {
+ facing = player.getDirection().getOpposite();
+ top = face != BlockFace.UP;
}
- this.meta |= upDownBit;
+
+ int faceBit = getMetaFromFacing(facing);
+
this.meta |= faceBit;
+
+ if (top) {
+ this.meta |= 0x08;
+ }
+
this.getLevel().setBlock(block, this, true, true);
return true;
}
@@ -192,17 +194,60 @@ public boolean toggle(Player player) {
return false;
}
- int sideBit = this.meta & 0b0111;
- int openBit = this.meta & 0b1000;
- openBit = (~openBit) & 0b1000;
- this.meta = sideBit | openBit;
+
+ int sideBit = this.meta & 0x03;
+ boolean top = isTop();
+ boolean open = isOpen();
+
+ this.meta = 0;
+ this.meta |= sideBit;
+
+ if (!open) {
+ this.meta |= 0x04;
+ }
+
+ if (top) {
+ this.meta |= 0x08;
+ }
+
this.level.setBlock(this, this, false, false);
this.level.addSound(new DoorSound(this));
return true;
}
+ public static int getMetaFromFacing(BlockFace facing) {
+ switch (facing) {
+ case NORTH:
+ return 0;
+ case SOUTH:
+ return 1;
+ case WEST:
+ return 2;
+ case EAST:
+ default:
+ return 3;
+ }
+ }
+
+ public BlockFace getFacing() {
+ switch (this.meta & 3) {
+ case 0:
+ return BlockFace.NORTH;
+ case 1:
+ return BlockFace.SOUTH;
+ case 2:
+ return BlockFace.WEST;
+ case 3:
+ default:
+ return BlockFace.EAST;
+ }
+ }
+
public boolean isOpen() {
- return (this.meta & 0x08) > 0;
+ return (this.meta & 0x04) != 0;
}
+ public boolean isTop() {
+ return (this.meta & 8) != 0;
+ }
}
diff --git a/src/main/java/cn/nukkit/block/BlockTrappedChest.java b/src/main/java/cn/nukkit/block/BlockTrappedChest.java
index 53431b7901..4f95dff406 100644
--- a/src/main/java/cn/nukkit/block/BlockTrappedChest.java
+++ b/src/main/java/cn/nukkit/block/BlockTrappedChest.java
@@ -37,7 +37,7 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl
int[] faces = {4, 2, 5, 3};
BlockEntityChest chest = null;
- this.meta = faces[player != null ? player.getDirection() : 0];
+ this.meta = faces[player != null ? player.getDirection().getHorizontalIndex() : 0];
for (BlockFace side : Plane.HORIZONTAL) {
if ((this.meta == 4 || this.meta == 5) && (side == BlockFace.WEST || side == BlockFace.EAST)) {
@@ -83,4 +83,27 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl
return true;
}
+
+ @Override
+ public int getWeakPower(BlockFace face) {
+ int playerCount = 0;
+
+ BlockEntity blockEntity = this.level.getBlockEntity(this);
+
+ if (blockEntity instanceof BlockEntityChest) {
+ playerCount = ((BlockEntityChest) blockEntity).getInventory().getViewers().size();
+ }
+
+ return playerCount < 0 ? 0 : playerCount > 15 ? 15 : playerCount;
+ }
+
+ @Override
+ public int getStrongPower(BlockFace side) {
+ return side == BlockFace.UP ? this.getWeakPower(side) : 0;
+ }
+
+ @Override
+ public boolean isPowerSource() {
+ return true;
+ }
}
diff --git a/src/main/java/cn/nukkit/block/BlockTripWire.java b/src/main/java/cn/nukkit/block/BlockTripWire.java
index d446c7f926..655d485595 100644
--- a/src/main/java/cn/nukkit/block/BlockTripWire.java
+++ b/src/main/java/cn/nukkit/block/BlockTripWire.java
@@ -1,7 +1,11 @@
package cn.nukkit.block;
+import cn.nukkit.Player;
+import cn.nukkit.entity.Entity;
import cn.nukkit.item.Item;
+import cn.nukkit.level.Level;
import cn.nukkit.math.AxisAlignedBB;
+import cn.nukkit.math.BlockFace;
/**
* @author CreeperFace
@@ -50,4 +54,134 @@ public AxisAlignedBB getBoundingBox() {
public int[][] getDrops(Item item) {
return new int[][]{{Item.STRING, 0, 1}};
}
+
+ public boolean isPowered() {
+ return (this.meta & 1) > 0;
+ }
+
+ public boolean isAttached() {
+ return (this.meta & 4) > 0;
+ }
+
+ public boolean isDisarmed() {
+ return (this.meta & 8) > 0;
+ }
+
+ public void setPowered(boolean value) {
+ if (value ^ this.isPowered()) {
+ this.meta ^= 0x01;
+ }
+ }
+
+ public void setAttached(boolean value) {
+ if (value ^ this.isAttached()) {
+ this.meta ^= 0x04;
+ }
+ }
+
+ public void setDisarmed(boolean value) {
+ if (value ^ this.isDisarmed()) {
+ this.meta ^= 0x08;
+ }
+ }
+
+ @Override
+ public void onEntityCollide(Entity entity) {
+ if (!entity.doesTriggerPressurePlate()) {
+ return;
+ }
+
+ boolean powered = this.isPowered();
+
+ if (!powered) {
+ this.setPowered(true);
+ this.level.setBlock(this, this, true, false);
+ this.updateHook(false);
+
+ this.level.scheduleUpdate(this, 10);
+ }
+ }
+
+ public void updateHook(boolean scheduleUpdate) {
+ for (BlockFace side : new BlockFace[]{BlockFace.SOUTH, BlockFace.WEST}) {
+ for (int i = 1; i < 42; ++i) {
+ Block block = this.getSide(side, i);
+
+ if (block instanceof BlockTripWireHook) {
+ BlockTripWireHook hook = (BlockTripWireHook) block;
+
+ if (hook.getFacing() == side.getOpposite()) {
+ hook.calculateState(false, true, i, this);
+ }
+
+ /*if(scheduleUpdate) {
+ this.level.scheduleUpdate(hook, 10);
+ }*/
+ break;
+ }
+
+ if (block.getId() != Block.TRIPWIRE) {
+ break;
+ }
+ }
+ }
+ }
+
+ @Override
+ public int onUpdate(int type) {
+ if (type == Level.BLOCK_UPDATE_SCHEDULED) {
+ if (!isPowered()) {
+ return type;
+ }
+
+ boolean found = false;
+ for (Entity entity : this.level.getCollidingEntities(this.getCollisionBoundingBox())) {
+ if (!entity.doesTriggerPressurePlate()) {
+ continue;
+ }
+
+ found = true;
+ }
+
+ if (found) {
+ this.level.scheduleUpdate(this, 10);
+ } else {
+ this.setPowered(false);
+ this.level.setBlock(this, this, true, false);
+ this.updateHook(false);
+ }
+ return type;
+ }
+
+ return 0;
+ }
+
+ @Override
+ public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
+ this.getLevel().setBlock(this, this, true, true);
+ this.updateHook(false);
+
+ return true;
+ }
+
+ @Override
+ public boolean onBreak(Item item) {
+ if (item.getId() == Item.SHEARS) {
+ this.setDisarmed(true);
+ this.level.setBlock(this, this, true, false);
+ this.updateHook(false);
+ this.getLevel().setBlock(this, new BlockAir(), true, true);
+ } else {
+ this.setPowered(true);
+ this.getLevel().setBlock(this, new BlockAir(), true, true);
+ this.updateHook(true);
+ }
+
+ return true;
+ }
+
+ @Override
+ protected AxisAlignedBB recalculateCollisionBoundingBox() {
+ return new AxisAlignedBB(this.x, this.y, this.z, this.x + 1, this.y + 0.5, this.z + 1);
+ }
}
diff --git a/src/main/java/cn/nukkit/block/BlockTripWireHook.java b/src/main/java/cn/nukkit/block/BlockTripWireHook.java
index e394771b11..aed58677d2 100644
--- a/src/main/java/cn/nukkit/block/BlockTripWireHook.java
+++ b/src/main/java/cn/nukkit/block/BlockTripWireHook.java
@@ -1,5 +1,13 @@
package cn.nukkit.block;
+import cn.nukkit.Player;
+import cn.nukkit.event.block.BlockRedstoneEvent;
+import cn.nukkit.item.Item;
+import cn.nukkit.level.Level;
+import cn.nukkit.math.BlockFace;
+import cn.nukkit.math.Vector3;
+import cn.nukkit.network.protocol.LevelSoundEventPacket;
+
/**
* @author CreeperFace
*/
@@ -23,5 +31,201 @@ public int getId() {
return TRIPWIRE_HOOK;
}
- //TODO: redstone
+ public BlockFace getFacing() {
+ return BlockFace.fromHorizontalIndex(meta & 0b11);
+ }
+
+ @Override
+ public int onUpdate(int type) {
+ if (type == Level.BLOCK_UPDATE_NORMAL) {
+ if (!this.getSide(this.getFacing().getOpposite()).isNormalBlock()) {
+ this.level.useBreakOn(this);
+ }
+
+ return type;
+ } else if (type == Level.BLOCK_UPDATE_SCHEDULED) {
+ this.calculateState(false, true, -1, null);
+ return type;
+ }
+
+ return 0;
+ }
+
+ @Override
+ public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
+ if (!this.getSide(face.getOpposite()).isNormalBlock()) {
+ return false;
+ }
+
+ if (face.getAxis().isHorizontal()) {
+ this.setFace(face);
+ }
+
+ this.level.setBlock(this, this);
+
+ if (player != null) {
+ this.calculateState(false, false, -1, null);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onBreak(Item item) {
+ super.onBreak(item);
+ boolean attached = isAttached();
+ boolean powered = isPowered();
+
+ if (attached || powered) {
+ this.calculateState(true, false, -1, null);
+ }
+
+ if (powered) {
+ this.level.updateAroundRedstone(this, null);
+ this.level.updateAroundRedstone(this.getLocation().getSide(getFacing().getOpposite()), null);
+ }
+
+ return true;
+ }
+
+ public void calculateState(boolean onBreak, boolean updateAround, int pos, Block block) {
+ BlockFace facing = getFacing();
+ Vector3 v = this.getLocation();
+ boolean attached = isAttached();
+ boolean powered = isPowered();
+ boolean canConnect = !onBreak;
+ boolean nextPowered = false;
+ int distance = 0;
+ Block[] blocks = new Block[42];
+
+ for (int i = 1; i < 42; ++i) {
+ Vector3 vector = v.getSide(facing, i);
+ Block b = this.level.getBlock(vector);
+
+ if (b instanceof BlockTripWireHook) {
+ if (((BlockTripWireHook) b).getFacing() == facing.getOpposite()) {
+ distance = i;
+ }
+ break;
+ }
+
+ if (b.getId() != Block.TRIPWIRE && i != pos) {
+ blocks[i] = null;
+ canConnect = false;
+ } else {
+ if (i == pos) {
+ b = block != null ? block : b;
+ }
+
+ if (b instanceof BlockTripWire) {
+ boolean disarmed = !((BlockTripWire) b).isDisarmed();
+ boolean wirePowered = ((BlockTripWire) b).isPowered();
+ nextPowered |= disarmed && wirePowered;
+
+ if (i == pos) {
+ this.level.scheduleUpdate(this, 10);
+ canConnect &= disarmed;
+ }
+ }
+ blocks[i] = b;
+ }
+ }
+
+ canConnect = canConnect & distance > 1;
+ nextPowered = nextPowered & canConnect;
+ BlockTripWireHook hook = new BlockTripWireHook();
+ hook.setAttached(canConnect);
+ hook.setPowered(nextPowered);
+
+
+ if (distance > 0) {
+ Vector3 vec = v.getSide(facing, distance);
+ BlockFace face = facing.getOpposite();
+ hook.setFace(face);
+ this.level.setBlock(vec, hook, true, false);
+ this.level.updateAroundRedstone(vec, null);
+ this.level.updateAroundRedstone(vec.getSide(face.getOpposite()), null);
+ this.addSound(vec, canConnect, nextPowered, attached, powered);
+ }
+
+ this.addSound(v, canConnect, nextPowered, attached, powered);
+
+ if (!onBreak) {
+ hook.setFace(facing);
+ this.level.setBlock(v, hook, true, false);
+
+ if (updateAround) {
+ this.level.updateAroundRedstone(v, null);
+ this.level.updateAroundRedstone(v.getSide(facing.getOpposite()), null);
+ }
+ }
+
+ if (attached != canConnect) {
+ for (int i = 1; i < distance; i++) {
+ Vector3 vc = v.getSide(facing, i);
+ block = blocks[i];
+
+ if (block != null && this.level.getBlockIdAt(vc.getFloorX(), vc.getFloorY(), vc.getFloorZ()) != Block.AIR) {
+ if (canConnect ^ ((block.meta & 0x04) > 0)) {
+ block.meta ^= 0x04;
+ }
+
+ this.level.setBlock(vc, block, true, false);
+ }
+ }
+ }
+ }
+
+ private void addSound(Vector3 pos, boolean canConnect, boolean nextPowered, boolean attached, boolean powered) {
+ if (nextPowered && !powered) {
+ this.level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_POWER_ON, 1, -1, pos, false, false);
+ this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, 0, 15));
+ } else if (!nextPowered && powered) {
+ this.level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_POWER_OFF, 1, -1, pos, false, false);
+ this.level.getServer().getPluginManager().callEvent(new BlockRedstoneEvent(this, 15, 0));
+ } else if (canConnect && !attached) {
+ this.level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_ATTACH, 1, -1, pos, false, false);
+ } else if (!canConnect && attached) {
+ this.level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_DETACH, 1, -1, pos, false, false);
+ }
+ }
+
+ public boolean isAttached() {
+ return (meta & 0x04) > 0;
+ }
+
+ public boolean isPowered() {
+ return (this.meta & 0x08) > 0;
+ }
+
+ public void setPowered(boolean value) {
+ if (value ^ this.isPowered()) {
+ this.meta ^= 0x08;
+ }
+ }
+
+ public void setAttached(boolean value) {
+ if (value ^ this.isAttached()) {
+ this.meta ^= 0x04;
+ }
+ }
+
+ public void setFace(BlockFace face) {
+ this.meta -= this.meta % 4;
+ this.meta |= face.getHorizontalIndex();
+ }
+
+ @Override
+ public boolean isPowerSource() {
+ return true;
+ }
+
+ @Override
+ public int getWeakPower(BlockFace face) {
+ return isPowered() ? 15 : 0;
+ }
+
+ @Override
+ public int getStrongPower(BlockFace side) {
+ return !isPowered() ? 0 : getFacing() == side ? 15 : 0;
+ }
}
diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntity.java b/src/main/java/cn/nukkit/blockentity/BlockEntity.java
index 860ccb8601..c7ee8ec4a8 100644
--- a/src/main/java/cn/nukkit/blockentity/BlockEntity.java
+++ b/src/main/java/cn/nukkit/blockentity/BlockEntity.java
@@ -35,6 +35,7 @@ public abstract class BlockEntity extends Position {
public static final String PISTON_ARM = "PistonArm";
public static final String MOVING_BLOCK = "MovingBlock";
public static final String COMPARATOR = "Comparator";
+ public static final String HOPPER = "Hopper";
public static long count = 1;
diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityFlowerPot.java b/src/main/java/cn/nukkit/blockentity/BlockEntityFlowerPot.java
index 71ebebb5ca..e290bca4db 100644
--- a/src/main/java/cn/nukkit/blockentity/BlockEntityFlowerPot.java
+++ b/src/main/java/cn/nukkit/blockentity/BlockEntityFlowerPot.java
@@ -15,12 +15,12 @@ public BlockEntityFlowerPot(FullChunk chunk, CompoundTag nbt) {
nbt.putShort("item", 0);
}
- if (!nbt.contains("data")) {
+ if (!nbt.contains("pos")) {
if (nbt.contains("mData")) {
- nbt.putInt("data", nbt.getInt("mData"));
+ nbt.putInt("pos", nbt.getInt("mData"));
nbt.remove("mData");
} else {
- nbt.putInt("data", 0);
+ nbt.putInt("pos", 0);
}
}
@@ -41,7 +41,7 @@ public CompoundTag getSpawnCompound() {
.putInt("y", (int) this.y)
.putInt("z", (int) this.z)
.putShort("item", this.namedTag.getShort("item"))
- .putInt("mData", this.namedTag.getInt("data"));
+ .putInt("mData", this.namedTag.getInt("pos"));
}
}
diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java b/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java
new file mode 100644
index 0000000000..38fc4cf846
--- /dev/null
+++ b/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java
@@ -0,0 +1,291 @@
+package cn.nukkit.blockentity;
+
+import cn.nukkit.block.Block;
+import cn.nukkit.block.BlockAir;
+import cn.nukkit.entity.Entity;
+import cn.nukkit.entity.item.EntityItem;
+import cn.nukkit.inventory.HopperInventory;
+import cn.nukkit.inventory.Inventory;
+import cn.nukkit.inventory.InventoryHolder;
+import cn.nukkit.item.Item;
+import cn.nukkit.item.ItemBlock;
+import cn.nukkit.level.format.FullChunk;
+import cn.nukkit.math.AxisAlignedBB;
+import cn.nukkit.math.BlockFace;
+import cn.nukkit.nbt.NBTIO;
+import cn.nukkit.nbt.tag.CompoundTag;
+import cn.nukkit.nbt.tag.ListTag;
+
+/**
+ * Created by CreeperFace on 8.5.2017.
+ */
+public class BlockEntityHopper extends BlockEntitySpawnable implements InventoryHolder, BlockEntityContainer, BlockEntityNameable {
+
+ protected final HopperInventory inventory;
+
+ public int transferCooldown = 8;
+
+ private AxisAlignedBB pickupArea;
+
+ public BlockEntityHopper(FullChunk chunk, CompoundTag nbt) {
+ super(chunk, nbt);
+
+ if (this.namedTag.contains("TransferCooldown")) {
+ this.transferCooldown = this.namedTag.getInt("TransferCooldown");
+ }
+
+ this.inventory = new HopperInventory(this);
+
+ if (!this.namedTag.contains("Items") || !(this.namedTag.get("Items") instanceof ListTag)) {
+ this.namedTag.putList(new ListTag("Items"));
+ }
+
+ for (int i = 0; i < this.getSize(); i++) {
+ this.inventory.setItem(i, this.getItem(i));
+ }
+
+ this.pickupArea = new AxisAlignedBB(this.x, this.y, this.z, this.x + 1, this.y + 2, this.z + 1);
+
+ this.scheduleUpdate();
+ }
+
+ @Override
+ public boolean isBlockEntityValid() {
+ return this.level.getBlockIdAt(this.getFloorX(), this.getFloorY(), this.getFloorZ()) == Block.HOPPER_BLOCK;
+ }
+
+ @Override
+ public String getName() {
+ return this.hasName() ? this.namedTag.getString("CustomName") : "Furnace";
+ }
+
+ @Override
+ public boolean hasName() {
+ return this.namedTag.contains("CustomName");
+ }
+
+ @Override
+ public void setName(String name) {
+ if (name == null || name.equals("")) {
+ this.namedTag.remove("CustomName");
+ return;
+ }
+
+ this.namedTag.putString("CustomName", name);
+ }
+
+ public boolean isOnTransferCooldown() {
+ return this.transferCooldown > 0;
+ }
+
+ public void setTransferCooldown(int transferCooldown) {
+ this.transferCooldown = transferCooldown;
+ }
+
+ @Override
+ public int getSize() {
+ return 3;
+ }
+
+ protected int getSlotIndex(int index) {
+ ListTag list = this.namedTag.getList("Items", CompoundTag.class);
+ for (int i = 0; i < list.size(); i++) {
+ if (list.get(i).getByte("Slot") == index) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ @Override
+ public Item getItem(int index) {
+ int i = this.getSlotIndex(index);
+ if (i < 0) {
+ return new ItemBlock(new BlockAir(), 0, 0);
+ } else {
+ CompoundTag data = (CompoundTag) this.namedTag.getList("Items").get(i);
+ return NBTIO.getItemHelper(data);
+ }
+ }
+
+ @Override
+ public void setItem(int index, Item item) {
+ int i = this.getSlotIndex(index);
+
+ CompoundTag d = NBTIO.putItemHelper(item, index);
+
+ if (item.getId() == Item.AIR || item.getCount() <= 0) {
+ if (i >= 0) {
+ this.namedTag.getList("Items").getAll().remove(i);
+ }
+ } else if (i < 0) {
+ (this.namedTag.getList("Items", CompoundTag.class)).add(d);
+ } else {
+ (this.namedTag.getList("Items", CompoundTag.class)).add(i, d);
+ }
+ }
+
+ @Override
+ public void saveNBT() {
+ this.namedTag.putList(new ListTag("Items"));
+ for (int index = 0; index < this.getSize(); index++) {
+ this.setItem(index, this.inventory.getItem(index));
+ }
+
+ this.namedTag.putInt("TransferCooldown", this.transferCooldown);
+ }
+
+ @Override
+ public HopperInventory getInventory() {
+ return inventory;
+ }
+
+ @Override
+ public boolean onUpdate() {
+ if (!isBlockEntityValid()) {
+ this.close();
+ return false;
+ }
+ this.transferCooldown--;
+
+ if (!this.isOnTransferCooldown()) {
+ boolean transfer = this.transferItemsOut();
+ boolean pickup = this.pickupDroppedItems();
+
+ if (transfer || pickup) {
+ //this.setTransferCooldown(8); TODO: maybe we should update hopper every tick if nothing happens?
+ this.chunk.setChanged(true);
+ }
+
+ this.setTransferCooldown(8);
+ }
+
+
+ return true;
+ }
+
+ public boolean pickupDroppedItems() {
+ if (this.inventory.isFull()) {
+ return false;
+ }
+
+ boolean update = false;
+
+ for (Entity entity : this.level.getCollidingEntities(this.pickupArea)) {
+ if (!(entity instanceof EntityItem)) {
+ continue;
+ }
+
+ EntityItem itemEntity = (EntityItem) entity;
+ Item item = itemEntity.getItem();
+
+ if (item.getId() == 0 || item.getCount() < 1) {
+ continue;
+ }
+
+ int originalCount = item.getCount();
+ Item[] items = this.inventory.addItem(item);
+
+ if (items.length == 0) {
+ entity.close();
+ update = true;
+ continue;
+ }
+
+ if (items[0].getCount() != originalCount) {
+ update = true;
+ }
+ }
+
+ BlockEntity blockEntity = this.level.getBlockEntity(this.up());
+ if (blockEntity instanceof InventoryHolder) {
+ Inventory inv = ((InventoryHolder) blockEntity).getInventory();
+
+ for (int i = 0; i < inv.getSize(); i++) {
+ Item item = inv.getItem(i);
+
+ if (item.getId() != 0 && item.getCount() > 0) {
+ Item itemToAdd = item.clone();
+ itemToAdd.count = 1;
+
+ Item[] items = this.inventory.addItem(itemToAdd);
+
+ if (items.length >= 1) {
+ continue;
+ }
+
+ item.count--;
+
+ if (item.count <= 0) {
+ item = Item.get(0);
+ }
+
+ inv.setItem(i, item);
+ update = true;
+ break;
+ }
+ }
+ }
+
+ //TODO: check for minecart
+ return update;
+ }
+
+ public boolean transferItemsOut() {
+ if (this.inventory.isEmpty()) {
+ return false;
+ }
+
+ if (!(this.level.getBlockEntity(this.down()) instanceof BlockEntityHopper)) {
+ BlockEntity be = this.level.getBlockEntity(this.getSide(BlockFace.fromIndex(this.level.getBlockDataAt(this.getFloorX(), this.getFloorY(), this.getFloorZ()))));
+
+ if (be instanceof InventoryHolder) {
+ Inventory inventory = ((InventoryHolder) be).getInventory();
+
+ if (inventory.isFull()) {
+ return false;
+ }
+
+ for (int i = 0; i < inventory.getSize(); i++) {
+ Item item = this.inventory.getItem(i);
+
+ if (item.getId() != 0 && item.getCount() > 0) {
+ Item itemToAdd = item.clone();
+ itemToAdd.setCount(1);
+
+ Item[] items = inventory.addItem(itemToAdd);
+
+ if (items.length > 0) {
+ continue;
+ }
+
+ inventory.sendContents(inventory.getViewers()); //whats wrong?
+ item.count--;
+ this.inventory.setItem(i, item);
+ return true;
+ }
+ }
+ }
+
+ //TODO: check for minecart
+ }
+
+ return false;
+ }
+
+ @Override
+ public CompoundTag getSpawnCompound() {
+ CompoundTag c = new CompoundTag()
+ .putString("id", BlockEntity.HOPPER)
+ .putInt("x", (int) this.x)
+ .putInt("y", (int) this.y)
+ .putInt("z", (int) this.z);
+
+ if (this.hasName()) {
+ c.put("CustomName", this.namedTag.get("CustomName"));
+ }
+
+ return c;
+ }
+}
diff --git a/src/main/java/cn/nukkit/command/FormattedCommandAlias.java b/src/main/java/cn/nukkit/command/FormattedCommandAlias.java
index d2d2ab18e1..62c122d24c 100644
--- a/src/main/java/cn/nukkit/command/FormattedCommandAlias.java
+++ b/src/main/java/cn/nukkit/command/FormattedCommandAlias.java
@@ -121,7 +121,7 @@ private String buildCommand(String formatString, String[] args) {
}
formatString = formatString.substring(0, start) + replacement.toString() + formatString.substring(end);
- // Move index past the replaced data so we don't process it again
+ // Move index past the replaced pos so we don't process it again
index = start + replacement.length();
// Move to the next replacement token
diff --git a/src/main/java/cn/nukkit/command/defaults/ParticleCommand.java b/src/main/java/cn/nukkit/command/defaults/ParticleCommand.java
index 2e9b4ee6c7..c1d7996d46 100644
--- a/src/main/java/cn/nukkit/command/defaults/ParticleCommand.java
+++ b/src/main/java/cn/nukkit/command/defaults/ParticleCommand.java
@@ -21,7 +21,7 @@ public class ParticleCommand extends VanillaCommand {
public ParticleCommand(String name) {
super(name, "%nukkit.command.particle.description", "%nukkit.command.particle.usage");
this.setPermission("nukkit.command.particle");
- // [count] [data]
+ // [count] [pos]
this.commandParameters.clear();
this.commandParameters.put("default", new CommandParameter[]{
new CommandParameter("player", CommandParameter.ARG_TYPE_TARGET, false),
@@ -32,7 +32,7 @@ public ParticleCommand(String name) {
new CommandParameter("yd", CommandParameter.ARG_TYPE_STRING, false),
new CommandParameter("zd", CommandParameter.ARG_TYPE_STRING, false),
new CommandParameter("count", CommandParameter.ARG_TYPE_INT, true),
- new CommandParameter("data", true)
+ new CommandParameter("pos", true)
});
}
diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java
index 64145a330b..c4030dfd9c 100644
--- a/src/main/java/cn/nukkit/entity/Entity.java
+++ b/src/main/java/cn/nukkit/entity/Entity.java
@@ -1037,7 +1037,7 @@ protected void updateMovement() {
this.lastYaw = this.yaw;
this.lastPitch = this.pitch;
- this.addMovement(this.x, this.y + this.getEyeHeight(), this.z, this.yaw, this.pitch, this.yaw);
+ this.addMovement(this.x, this.y, this.z, this.yaw, this.pitch, this.yaw);
}
if (diffMotion > 0.0025 || (diffMotion > 0.0001 && this.getMotion().lengthSquared() <= 0.0001)) { //0.05 ** 2
@@ -1123,19 +1123,19 @@ public void setOnFire(int seconds) {
}
}
- public Integer getDirection() {
+ public BlockFace getDirection() {
double rotation = (this.yaw - 90) % 360;
if (rotation < 0) {
rotation += 360.0;
}
if ((0 <= rotation && rotation < 45) || (315 <= rotation && rotation < 360)) {
- return 2; //North
+ return BlockFace.NORTH;
} else if (45 <= rotation && rotation < 135) {
- return 3; //East
+ return BlockFace.EAST;
} else if (135 <= rotation && rotation < 225) {
- return 0; //South
+ return BlockFace.SOUTH;
} else if (225 <= rotation && rotation < 315) {
- return 1; //West
+ return BlockFace.WEST;
} else {
return null;
}
@@ -1207,6 +1207,14 @@ public void onCollideWithPlayer(EntityHuman entityPlayer) {
}
+ public void onStruckByLightning(Entity entity) {
+ this.attack(new EntityDamageByEntityEvent(entity, this, DamageCause.LIGHTNING, 5));
+
+ if (this.fireTicks < 8 * 20) {
+ this.setOnFire(8);
+ }
+ }
+
public boolean onInteract(Player player, Item item) {
return false;
}
@@ -1523,7 +1531,7 @@ public void setRotation(double yaw, double pitch) {
* used for bat only
*/
public boolean doesTriggerPressurePlate() {
- return true;
+ return false;
}
protected void checkChunks() {
diff --git a/src/main/java/cn/nukkit/entity/EntityHanging.java b/src/main/java/cn/nukkit/entity/EntityHanging.java
index 874239f718..8fe70a69c1 100644
--- a/src/main/java/cn/nukkit/entity/EntityHanging.java
+++ b/src/main/java/cn/nukkit/entity/EntityHanging.java
@@ -1,6 +1,7 @@
package cn.nukkit.entity;
import cn.nukkit.level.format.FullChunk;
+import cn.nukkit.math.BlockFace;
import cn.nukkit.nbt.tag.CompoundTag;
/**
@@ -38,15 +39,15 @@ protected void initEntity() {
public void saveNBT() {
super.saveNBT();
- this.namedTag.putByte("Direction", this.getDirection());
+ this.namedTag.putByte("Direction", this.getDirection().getHorizontalIndex());
this.namedTag.putInt("TileX", (int) this.x);
this.namedTag.putInt("TileY", (int) this.y);
this.namedTag.putInt("TileZ", (int) this.z);
}
@Override
- public Integer getDirection() {
- return this.direction;
+ public BlockFace getDirection() {
+ return BlockFace.fromIndex(this.direction);
}
@Override
diff --git a/src/main/java/cn/nukkit/entity/EntityLiving.java b/src/main/java/cn/nukkit/entity/EntityLiving.java
index 5984e1b671..1b43209411 100644
--- a/src/main/java/cn/nukkit/entity/EntityLiving.java
+++ b/src/main/java/cn/nukkit/entity/EntityLiving.java
@@ -323,4 +323,8 @@ public float getMovementSpeed() {
return this.movementSpeed;
}
+ @Override
+ public boolean doesTriggerPressurePlate() {
+ return true;
+ }
}
diff --git a/src/main/java/cn/nukkit/entity/item/EntityPainting.java b/src/main/java/cn/nukkit/entity/item/EntityPainting.java
index 7d40de7d12..a0d03e0806 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityPainting.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityPainting.java
@@ -81,7 +81,7 @@ public void spawnTo(Player player) {
pk.x = (int) this.x;
pk.y = (int) this.y;
pk.z = (int) this.z;
- pk.direction = this.getDirection();
+ pk.direction = this.getDirection().getHorizontalIndex();
pk.title = this.namedTag.getString("Motive");
player.dataPacket(pk);
diff --git a/src/main/java/cn/nukkit/entity/item/EntityPotion.java b/src/main/java/cn/nukkit/entity/item/EntityPotion.java
index 292b0652c2..968a0b04a0 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityPotion.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityPotion.java
@@ -20,7 +20,7 @@ public class EntityPotion extends EntityProjectile {
public static final int NETWORK_ID = 86;
- public static final int DATA_POTION_ID = 16;
+ public static final int DATA_POTION_ID = 37;
public int potionId;
diff --git a/src/main/java/cn/nukkit/entity/mob/EntityCreeper.java b/src/main/java/cn/nukkit/entity/mob/EntityCreeper.java
index e8a796f436..19330bdf76 100644
--- a/src/main/java/cn/nukkit/entity/mob/EntityCreeper.java
+++ b/src/main/java/cn/nukkit/entity/mob/EntityCreeper.java
@@ -1,6 +1,7 @@
package cn.nukkit.entity.mob;
import cn.nukkit.Player;
+import cn.nukkit.entity.Entity;
import cn.nukkit.entity.data.ByteEntityData;
import cn.nukkit.entity.weather.EntityLightningStrike;
import cn.nukkit.event.entity.CreeperPowerEvent;
@@ -63,6 +64,11 @@ public Item[] getDrops() {
return new Item[0];
}
+ @Override
+ public void onStruckByLightning(Entity entity) {
+ this.setPowered(true);
+ }
+
@Override
protected void initEntity() {
super.initEntity();
diff --git a/src/main/java/cn/nukkit/entity/projectile/EntityArrow.java b/src/main/java/cn/nukkit/entity/projectile/EntityArrow.java
index 1c5197934c..f6068fbc86 100644
--- a/src/main/java/cn/nukkit/entity/projectile/EntityArrow.java
+++ b/src/main/java/cn/nukkit/entity/projectile/EntityArrow.java
@@ -3,9 +3,6 @@
import cn.nukkit.Player;
import cn.nukkit.entity.Entity;
import cn.nukkit.level.format.FullChunk;
-import cn.nukkit.level.particle.CriticalParticle;
-import cn.nukkit.math.NukkitMath;
-import cn.nukkit.math.NukkitRandom;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.network.protocol.AddEntityPacket;
@@ -48,16 +45,9 @@ public float getDrag() {
return 0.01f;
}
- @Override
- protected double getDamage() {
- return namedTag.contains("damage") ? namedTag.getDouble("damage") : 2;
- }
-
protected float gravity = 0.05f;
protected float drag = 0.01f;
- protected double damage = 2;
-
protected boolean isCritical;
public EntityArrow(FullChunk chunk, CompoundTag nbt) {
@@ -70,7 +60,30 @@ public EntityArrow(FullChunk chunk, CompoundTag nbt, Entity shootingEntity) {
public EntityArrow(FullChunk chunk, CompoundTag nbt, Entity shootingEntity, boolean critical) {
super(chunk, nbt, shootingEntity);
- this.isCritical = critical;
+ this.setCritical(critical);
+ }
+
+ @Override
+ protected void initEntity() {
+ super.initEntity();
+
+ this.damage = namedTag.contains("damage") ? namedTag.getDouble("damage") : 2;
+ }
+
+ public void setCritical(boolean value) {
+ this.isCritical = value;
+ this.setDataFlag(DATA_FLAGS, DATA_FLAG_CRITICAL, this.isCritical);
+ }
+
+ @Override
+ public int getResultDamage() {
+ int base = super.getResultDamage();
+
+ if (this.isCritical) {
+ base += this.level.rand.nextInt(base / 2 + 2);
+ }
+
+ return base;
}
@Override
@@ -83,18 +96,12 @@ public boolean onUpdate(int currentTick) {
boolean hasUpdate = super.onUpdate(currentTick);
- if (!this.hadCollision && this.isCritical) {
- NukkitRandom random = new NukkitRandom();
- this.level.addParticle(new CriticalParticle(this.add(
- this.getWidth() / 2 + ((double) NukkitMath.randomRange(random, -100, 100)) / 500,
- this.getHeight() / 2 + ((double) NukkitMath.randomRange(random, -100, 100)) / 500,
- this.getWidth() / 2 + ((double) NukkitMath.randomRange(random, -100, 100)) / 500)));
- } else if (this.onGround) {
- this.isCritical = false;
+ if (this.onGround || this.hadCollision) {
+ this.setCritical(false);
}
if (this.age > 1200) {
- this.kill();
+ this.close();
hasUpdate = true;
}
@@ -115,6 +122,8 @@ public void spawnTo(Player player) {
pk.speedX = (float) this.motionX;
pk.speedY = (float) this.motionY;
pk.speedZ = (float) this.motionZ;
+ pk.yaw = (float) this.yaw;
+ pk.pitch = (float) this.pitch;
pk.metadata = this.dataProperties;
player.dataPacket(pk);
diff --git a/src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java b/src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java
index c12ccd2b1b..776a83fc68 100644
--- a/src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java
+++ b/src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java
@@ -8,11 +8,10 @@
import cn.nukkit.level.MovingObjectPosition;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.math.AxisAlignedBB;
+import cn.nukkit.math.NukkitMath;
import cn.nukkit.math.Vector3;
import cn.nukkit.nbt.tag.CompoundTag;
-import java.util.Random;
-
/**
* author: MagicDroidX
* Nukkit Project
@@ -24,11 +23,13 @@ public abstract class EntityProjectile extends Entity {
public Entity shootingEntity = null;
protected double getDamage() {
- return 0;
+ return namedTag.contains("damage") ? namedTag.getDouble("damage") : 2;
}
public boolean hadCollision = false;
+ protected double damage = 0;
+
public EntityProjectile(FullChunk chunk, CompoundTag nbt) {
this(chunk, nbt, null);
}
@@ -41,10 +42,37 @@ public EntityProjectile(FullChunk chunk, CompoundTag nbt, Entity shootingEntity)
}
}
+ public int getResultDamage() {
+ return NukkitMath.ceilDouble(Math.sqrt(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ) * getDamage());
+ }
+
public boolean attack(EntityDamageEvent source) {
return source.getCause() == DamageCause.VOID && super.attack(source);
}
+ public void onCollideWithEntity(Entity entity) {
+ this.server.getPluginManager().callEvent(new ProjectileHitEvent(this));
+ float damage = this.getResultDamage();
+
+ EntityDamageEvent ev;
+ if (this.shootingEntity == null) {
+ ev = new EntityDamageByEntityEvent(this, entity, DamageCause.PROJECTILE, damage);
+ } else {
+ ev = new EntityDamageByChildEntityEvent(this.shootingEntity, this, entity, DamageCause.PROJECTILE, damage);
+ }
+ entity.attack(ev);
+ this.hadCollision = true;
+
+ if (this.fireTicks > 0) {
+ EntityCombustByEntityEvent event = new EntityCombustByEntityEvent(this, entity, 5);
+ this.server.getPluginManager().callEvent(ev);
+ if (!event.isCancelled()) {
+ entity.setOnFire(event.getDuration());
+ }
+ }
+ this.close();
+ }
+
@Override
protected void initEntity() {
super.initEntity();
@@ -73,7 +101,6 @@ public boolean onUpdate(int currentTick) {
return false;
}
-
int tickDiff = currentTick - this.lastUpdate;
if (tickDiff <= 0 && !this.justCreated) {
return true;
@@ -125,47 +152,14 @@ public boolean onUpdate(int currentTick) {
if (movingObjectPosition != null) {
if (movingObjectPosition.entityHit != null) {
-
- ProjectileHitEvent hitEvent;
- this.server.getPluginManager().callEvent(hitEvent = new ProjectileHitEvent(this, movingObjectPosition));
-
- if (!hitEvent.isCancelled()) {
- movingObjectPosition = hitEvent.getMovingObjectPosition();
- double motion = Math.sqrt(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ);
- double damage = Math.ceil(motion * this.getDamage());
-
- if (this instanceof EntityArrow && ((EntityArrow) this).isCritical) {
- damage += new Random().nextInt((int) (damage / 2) + 1);
- }
-
- EntityDamageEvent ev;
- if (this.shootingEntity == null) {
- ev = new EntityDamageByEntityEvent(this, movingObjectPosition.entityHit, DamageCause.PROJECTILE, (float) damage);
- } else {
- ev = new EntityDamageByChildEntityEvent(this.shootingEntity, this, movingObjectPosition.entityHit, DamageCause.PROJECTILE, (float) damage);
- }
-
- movingObjectPosition.entityHit.attack(ev);
-
- this.hadCollision = true;
-
- if (this.fireTicks > 0) {
- EntityCombustByEntityEvent ev2 = new EntityCombustByEntityEvent(this, movingObjectPosition.entityHit, 5);
- this.server.getPluginManager().callEvent(ev2);
- if (!ev2.isCancelled()) {
- movingObjectPosition.entityHit.setOnFire(ev2.getDuration());
- }
- }
-
- this.kill();
- return true;
- }
+ onCollideWithEntity(movingObjectPosition.entityHit);
+ return true;
}
}
this.move(this.motionX, this.motionY, this.motionZ);
- if (this.isCollided && !this.hadCollision) {
+ if (this.isCollided && !this.hadCollision) { //collide with block
this.hadCollision = true;
this.motionX = 0;
@@ -173,11 +167,12 @@ public boolean onUpdate(int currentTick) {
this.motionZ = 0;
this.server.getPluginManager().callEvent(new ProjectileHitEvent(this, MovingObjectPosition.fromBlock(this.getFloorX(), this.getFloorY(), this.getFloorZ(), -1, this)));
+ return false;
} else if (!this.isCollided && this.hadCollision) {
this.hadCollision = false;
}
- if (!this.onGround || Math.abs(this.motionX) > 0.00001 || Math.abs(this.motionY) > 0.00001 || Math.abs(this.motionZ) > 0.00001) {
+ if (!this.hadCollision || Math.abs(this.motionX) > 0.00001 || Math.abs(this.motionY) > 0.00001 || Math.abs(this.motionZ) > 0.00001) {
double f = Math.sqrt((this.motionX * this.motionX) + (this.motionZ * this.motionZ));
this.yaw = Math.atan2(this.motionX, this.motionZ) * 180 / Math.PI;
this.pitch = Math.atan2(this.motionY, f) * 180 / Math.PI;
@@ -190,4 +185,4 @@ public boolean onUpdate(int currentTick) {
return hasUpdate;
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/cn/nukkit/entity/weather/EntityLightning.java b/src/main/java/cn/nukkit/entity/weather/EntityLightning.java
index 385d6674fb..3d5ce012d9 100644
--- a/src/main/java/cn/nukkit/entity/weather/EntityLightning.java
+++ b/src/main/java/cn/nukkit/entity/weather/EntityLightning.java
@@ -1,20 +1,16 @@
package cn.nukkit.entity.weather;
import cn.nukkit.Player;
-import cn.nukkit.Server;
import cn.nukkit.block.Block;
import cn.nukkit.block.BlockFire;
import cn.nukkit.entity.Entity;
-import cn.nukkit.entity.EntityLiving;
-import cn.nukkit.entity.item.EntityItem;
-import cn.nukkit.entity.mob.EntityCreeper;
import cn.nukkit.event.block.BlockIgniteEvent;
-import cn.nukkit.event.entity.EntityDamageByEntityEvent;
import cn.nukkit.event.entity.EntityDamageEvent;
-import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
import cn.nukkit.level.format.FullChunk;
+import cn.nukkit.math.AxisAlignedBB;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.network.protocol.AddEntityPacket;
+import cn.nukkit.network.protocol.LevelSoundEventPacket;
/**
* Created by boybook on 2016/2/27.
@@ -25,6 +21,10 @@ public class EntityLightning extends Entity implements EntityLightningStrike {
protected boolean isEffect = true;
+ public int state;
+ public int liveTime;
+
+
@Override
public int getNetworkId() {
return NETWORK_ID;
@@ -40,6 +40,31 @@ protected void initEntity() {
this.setHealth(4);
this.setMaxHealth(4);
+
+ this.state = 2;
+ this.liveTime = this.level.rand.nextInt(3) + 1;
+
+ if (isEffect && (this.server.getDifficulty() >= 2)) {
+ Block block = this.getLevelBlock();
+ if (block.getId() == 0 || block.getId() == Block.TALL_GRASS) {
+ BlockFire fire = new BlockFire();
+ fire.x = block.x;
+ fire.y = block.y;
+ fire.z = block.z;
+ fire.level = level;
+ this.getLevel().setBlock(fire, fire, true);
+ if (fire.isBlockTopFacingSurfaceSolid(fire.down()) || fire.canNeighborBurn()) {
+
+ BlockIgniteEvent e = new BlockIgniteEvent(block, null, this, BlockIgniteEvent.BlockIgniteCause.LIGHTNING);
+ getServer().getPluginManager().callEvent(e);
+
+ if (!e.isCancelled()) {
+ level.setBlock(fire, fire, true);
+ level.scheduleUpdate(fire, fire.tickRate() + level.rand.nextInt(10));
+ }
+ }
+ }
+ }
}
public boolean isEffect() {
@@ -83,50 +108,6 @@ public boolean onUpdate(int currentTick) {
return false;
}
- if (this.justCreated) {
- if (this.isEffect()) {
- for (Entity e : this.level.getNearbyEntities(this.boundingBox.grow(6, 12, 6), this)) {
- if (e instanceof EntityLiving) {
- e.attack(new EntityDamageByEntityEvent(this, e, DamageCause.LIGHTNING, 5));
- e.setOnFire(5); //how long?
- //Creeper
- if (e instanceof EntityCreeper) {
- if (!((EntityCreeper) e).isPowered()) {
- ((EntityCreeper) e).setPowered(this);
- }
- }
-
- //TODO Pig
- //TODO Villager
- } else if (e instanceof EntityItem) {
- e.kill();
- }
- }
- if (Server.getInstance().getDifficulty() >= 2) {
- Block block = this.getLevelBlock();
- if (block.getId() == 0 || block.getId() == Block.TALL_GRASS) {
- BlockFire fire = new BlockFire();
- fire.x = block.x;
- fire.y = block.y;
- fire.z = block.z;
- fire.level = level;
- this.getLevel().setBlock(fire, fire, true);
- if (fire.isBlockTopFacingSurfaceSolid(fire.down()) || fire.canNeighborBurn()) {
-
- BlockIgniteEvent e = new BlockIgniteEvent(block, null, this, BlockIgniteEvent.BlockIgniteCause.LIGHTNING);
- getServer().getPluginManager().callEvent(e);
-
- if (!e.isCancelled()) {
- level.setBlock(fire, fire, true);
- level.scheduleUpdate(fire, fire.tickRate() + level.rand.nextInt(10));
- }
- }
- }
- }
- }
-
- }
-
int tickDiff = currentTick - this.lastUpdate;
if (tickDiff <= 0 && !this.justCreated) {
@@ -135,17 +116,52 @@ public boolean onUpdate(int currentTick) {
this.lastUpdate = currentTick;
- boolean hasUpdate = true;
this.entityBaseTick(tickDiff);
- if (this.isAlive()) {
- if (this.age >= 1) {
+ if (this.state == 2) {
+ this.level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_THUNDER, 93, -1, this, false, false);
+ this.level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_EXPLODE, 93, -1, this, false, false);
+ }
+
+ this.state--;
+
+ if (this.state < 0) {
+ if (this.liveTime == 0) {
this.close();
- hasUpdate = false;
+ return false;
+ } else if (this.state < -this.level.rand.nextInt(10)) {
+ this.liveTime--;
+ this.state = 1;
+
+ if (this.isEffect) {
+ Block block = this.getLevelBlock();
+
+ if (block.getId() == Block.AIR || block.getId() == Block.TALL_GRASS) {
+ BlockIgniteEvent e = new BlockIgniteEvent(block, null, this, BlockIgniteEvent.BlockIgniteCause.LIGHTNING);
+ getServer().getPluginManager().callEvent(e);
+
+ if (!e.isCancelled()) {
+ Block fire = new BlockFire();
+ this.level.setBlock(block, fire);
+ this.getLevel().scheduleUpdate(fire, fire.tickRate());
+ }
+ }
+ }
+ }
+ }
+
+ if (this.state >= 0) {
+ if (this.isEffect) {
+ AxisAlignedBB bb = getBoundingBox().grow(3, 3, 3);
+ bb.maxX += 6;
+
+ for (Entity entity : this.level.getCollidingEntities(bb, this)) {
+ entity.onStruckByLightning(this);
+ }
}
}
- return hasUpdate;
+ return true;
}
diff --git a/src/main/java/cn/nukkit/event/block/BlockRedstoneEvent.java b/src/main/java/cn/nukkit/event/block/BlockRedstoneEvent.java
new file mode 100644
index 0000000000..38f1d13e7a
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/block/BlockRedstoneEvent.java
@@ -0,0 +1,33 @@
+package cn.nukkit.event.block;
+
+import cn.nukkit.block.Block;
+import cn.nukkit.event.HandlerList;
+
+/**
+ * Created by CreeperFace on 12.5.2017.
+ */
+public class BlockRedstoneEvent extends BlockEvent {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+
+ private int oldPower;
+ private int newPower;
+
+ public BlockRedstoneEvent(Block block, int oldPower, int newPower) {
+ super(block);
+ this.oldPower = oldPower;
+ this.newPower = newPower;
+ }
+
+ public int getOldPower() {
+ return oldPower;
+ }
+
+ public int getNewPower() {
+ return newPower;
+ }
+}
diff --git a/src/main/java/cn/nukkit/inventory/BaseInventory.java b/src/main/java/cn/nukkit/inventory/BaseInventory.java
index 62deae42db..03b86a2ca4 100644
--- a/src/main/java/cn/nukkit/inventory/BaseInventory.java
+++ b/src/main/java/cn/nukkit/inventory/BaseInventory.java
@@ -455,6 +455,54 @@ public void sendContents(Player[] players) {
}
}
+ @Override
+ public boolean isFull() {
+ if (this.slots.size() < this.getSize()) {
+ return false;
+ }
+
+ for (Item item : this.slots.values()) {
+ if (item == null || item.getId() == 0 || item.getCount() < item.getMaxStackSize() || item.getCount() < this.getMaxStackSize()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ if (this.getMaxStackSize() <= 0) {
+ return false;
+ }
+
+ for (Item item : this.slots.values()) {
+ if (item != null && item.getId() != 0 && item.getCount() > 0) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public int getFreeSpace(Item item) {
+ int maxStackSize = Math.min(item.getMaxStackSize(), this.getMaxStackSize());
+ int space = (this.getSize() - this.slots.size()) * maxStackSize;
+
+ for (Item slot : this.getContents().values()) {
+ if (slot == null || slot.getId() == 0) {
+ space += maxStackSize;
+ continue;
+ }
+
+ if (slot.equals(item, true, true)) {
+ space += maxStackSize - slot.getCount();
+ }
+ }
+
+ return space;
+ }
+
@Override
public void sendContents(Collection players) {
this.sendContents(players.stream().toArray(Player[]::new));
diff --git a/src/main/java/cn/nukkit/inventory/HopperInventory.java b/src/main/java/cn/nukkit/inventory/HopperInventory.java
new file mode 100644
index 0000000000..531c74ff0f
--- /dev/null
+++ b/src/main/java/cn/nukkit/inventory/HopperInventory.java
@@ -0,0 +1,18 @@
+package cn.nukkit.inventory;
+
+import cn.nukkit.blockentity.BlockEntityHopper;
+
+/**
+ * Created by CreeperFace on 8.5.2017.
+ */
+public class HopperInventory extends ContainerInventory {
+
+ public HopperInventory(BlockEntityHopper hopper) {
+ super(hopper, InventoryType.HOPPER);
+ }
+
+ @Override
+ public BlockEntityHopper getHolder() {
+ return (BlockEntityHopper) super.getHolder();
+ }
+}
diff --git a/src/main/java/cn/nukkit/inventory/Inventory.java b/src/main/java/cn/nukkit/inventory/Inventory.java
index 32fe97791d..8074ffc57a 100644
--- a/src/main/java/cn/nukkit/inventory/Inventory.java
+++ b/src/main/java/cn/nukkit/inventory/Inventory.java
@@ -65,6 +65,10 @@ public interface Inventory {
void clearAll();
+ boolean isFull();
+
+ boolean isEmpty();
+
Set getViewers();
InventoryType getType();
diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java
index a1affd3966..ed40743ac5 100644
--- a/src/main/java/cn/nukkit/item/Item.java
+++ b/src/main/java/cn/nukkit/item/Item.java
@@ -742,7 +742,7 @@ public static void init() {
list[MINECART_WITH_TNT] = ItemMinecartTNT.class; //407
list[MINECART_WITH_HOPPER] = ItemMinecartHopper.class; //408
list[PRISMARINE_SHARD] = ItemPrismarineShard.class; //409
- //TODO: list[HOPPER] = ItemHopper.class; //410
+ list[HOPPER] = ItemHopper.class;
list[RAW_RABBIT] = ItemRabbitRaw.class; //411
list[COOKED_RABBIT] = ItemRabbitCooked.class; //412
list[RABBIT_STEW] = ItemRabbitStew.class; //413
diff --git a/src/main/java/cn/nukkit/item/ItemHopper.java b/src/main/java/cn/nukkit/item/ItemHopper.java
new file mode 100644
index 0000000000..935fc75612
--- /dev/null
+++ b/src/main/java/cn/nukkit/item/ItemHopper.java
@@ -0,0 +1,18 @@
+package cn.nukkit.item;
+
+import cn.nukkit.block.BlockHopper;
+
+/**
+ * Created by CreeperFace on 13.5.2017.
+ */
+public class ItemHopper extends Item {
+
+ public ItemHopper(Integer meta) {
+ this(meta, 1);
+ }
+
+ public ItemHopper(Integer meta, int count) {
+ super(HOPPER, 0, count, "Hopper");
+ this.block = new BlockHopper();
+ }
+}
diff --git a/src/main/java/cn/nukkit/item/enchantment/Enchantment.java b/src/main/java/cn/nukkit/item/enchantment/Enchantment.java
index b20f30e6c1..6690993df8 100644
--- a/src/main/java/cn/nukkit/item/enchantment/Enchantment.java
+++ b/src/main/java/cn/nukkit/item/enchantment/Enchantment.java
@@ -93,7 +93,7 @@ public static Enchantment get(int id) {
}
public static Enchantment getEnchantment(int id) {
- return get(id) == null ? null : get(id).clone();
+ return get(id).clone();
}
public static Enchantment[] getEnchantments() {
@@ -176,7 +176,7 @@ public int getMaxEnchantAbility(int level) {
return this.getMinEnchantAbility(level) + 5;
}
- public int getDamageProtection(EntityDamageEvent event) {
+ public float getDamageProtection(EntityDamageEvent event) {
return 0;
}
diff --git a/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtection.java b/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtection.java
index 10d58190e1..9729464dcd 100644
--- a/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtection.java
+++ b/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtection.java
@@ -1,7 +1,5 @@
package cn.nukkit.item.enchantment.protection;
-import cn.nukkit.event.entity.EntityDamageEvent;
-import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
import cn.nukkit.item.enchantment.Enchantment;
import cn.nukkit.item.enchantment.EnchantmentType;
@@ -10,6 +8,7 @@
* Nukkit Project
*/
public abstract class EnchantmentProtection extends Enchantment {
+
public enum TYPE {
ALL,
FIRE,
@@ -28,62 +27,6 @@ protected EnchantmentProtection(int id, String name, int weight, EnchantmentProt
}
}
- @Override
- public int getDamageProtection(EntityDamageEvent event) {
- int level = this.level;
- DamageCause cause = event.getCause();
-
- if (level <= 0 || cause == DamageCause.VOID || cause == DamageCause.CUSTOM || cause == DamageCause.MAGIC) {
- return 0;
- }
- /*double f = (6d + level * level) / 3d;
- switch (event.getCause()) {
- case PROJECTILE:
- case ENTITY_EXPLOSION:
- case BLOCK_EXPLOSION:
- return (int) Math.floor(f * 1.5);
- case FALL:
- return (int) Math.floor(f * 2.5);
- case FIRE:
- case FIRE_TICK:
- return (int) Math.floor(f * 1.25);
- default:
- if (this.protectionType == TYPE.ALL) {
- return (int) Math.floor(f * 0.75);
- } else {
- return 0;
- }
- }*/
-
- boolean canProtect = false;
-
- switch (this.getId()) {
- case Enchantment.ID_PROTECTION_ALL:
- canProtect = true;
- break;
- case Enchantment.ID_PROTECTION_FIRE:
- if (cause == DamageCause.FIRE || cause == DamageCause.FIRE_TICK || cause == DamageCause.LAVA)
- canProtect = true;
- break;
- case Enchantment.ID_PROTECTION_FALL:
- if (cause == DamageCause.FALL) canProtect = true;
- break;
- case Enchantment.ID_PROTECTION_EXPLOSION:
- if (cause == DamageCause.ENTITY_EXPLOSION || cause == DamageCause.BLOCK_EXPLOSION)
- canProtect = true;
- break;
- case Enchantment.ID_PROTECTION_PROJECTILE:
- if (cause == DamageCause.PROJECTILE) canProtect = true;
- break;
- }
-
- if (canProtect) {
- return (int) (level * getTypeModifier());
- }
-
- return 0;
- }
-
@Override
public boolean isCompatibleWith(Enchantment enchantment) {
if (enchantment instanceof EnchantmentProtection) {
diff --git a/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionAll.java b/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionAll.java
index 0138514dd2..d928b7fa0a 100644
--- a/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionAll.java
+++ b/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionAll.java
@@ -1,5 +1,7 @@
package cn.nukkit.item.enchantment.protection;
+import cn.nukkit.event.entity.EntityDamageEvent;
+import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
import cn.nukkit.item.enchantment.Enchantment;
/**
@@ -26,4 +28,15 @@ public int getMaxEnchantAbility(int level) {
public double getTypeModifier() {
return 1;
}
+
+ @Override
+ public float getDamageProtection(EntityDamageEvent e) {
+ DamageCause cause = e.getCause();
+
+ if (level <= 0 || cause == DamageCause.VOID || cause == DamageCause.CUSTOM || cause == DamageCause.MAGIC) {
+ return 0;
+ }
+
+ return (float) (getLevel() * getTypeModifier());
+ }
}
diff --git a/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionExplosion.java b/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionExplosion.java
index 0023b212b5..ca70f73b39 100644
--- a/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionExplosion.java
+++ b/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionExplosion.java
@@ -1,5 +1,8 @@
package cn.nukkit.item.enchantment.protection;
+import cn.nukkit.event.entity.EntityDamageEvent;
+import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
+
/**
* author: MagicDroidX
* Nukkit Project
@@ -24,4 +27,15 @@ public int getMaxEnchantAbility(int level) {
public double getTypeModifier() {
return 2;
}
+
+ @Override
+ public float getDamageProtection(EntityDamageEvent e) {
+ DamageCause cause = e.getCause();
+
+ if (level <= 0 || (cause != DamageCause.ENTITY_EXPLOSION && cause != DamageCause.BLOCK_EXPLOSION)) {
+ return 0;
+ }
+
+ return (float) (getLevel() * getTypeModifier());
+ }
}
diff --git a/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionFall.java b/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionFall.java
index 32975d5db6..e8e36546d0 100644
--- a/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionFall.java
+++ b/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionFall.java
@@ -1,5 +1,8 @@
package cn.nukkit.item.enchantment.protection;
+import cn.nukkit.event.entity.EntityDamageEvent;
+import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
+
/**
* author: MagicDroidX
* Nukkit Project
@@ -24,4 +27,15 @@ public int getMaxEnchantAbility(int level) {
public double getTypeModifier() {
return 2;
}
+
+ @Override
+ public float getDamageProtection(EntityDamageEvent e) {
+ DamageCause cause = e.getCause();
+
+ if (level <= 0 || (cause != DamageCause.FALL)) {
+ return 0;
+ }
+
+ return (float) (getLevel() * getTypeModifier());
+ }
}
diff --git a/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionFire.java b/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionFire.java
index 2ac91fd99c..ac1418539b 100644
--- a/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionFire.java
+++ b/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionFire.java
@@ -1,5 +1,8 @@
package cn.nukkit.item.enchantment.protection;
+import cn.nukkit.event.entity.EntityDamageEvent;
+import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
+
/**
* author: MagicDroidX
* Nukkit Project
@@ -24,4 +27,15 @@ public int getMaxEnchantAbility(int level) {
public double getTypeModifier() {
return 2;
}
+
+ @Override
+ public float getDamageProtection(EntityDamageEvent e) {
+ DamageCause cause = e.getCause();
+
+ if (level <= 0 || (cause != DamageCause.LAVA && cause != DamageCause.FIRE && cause != DamageCause.FIRE_TICK)) {
+ return 0;
+ }
+
+ return (float) (getLevel() * getTypeModifier());
+ }
}
diff --git a/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionProjectile.java b/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionProjectile.java
index 5f9d75ae0c..0d5e1a8e6d 100644
--- a/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionProjectile.java
+++ b/src/main/java/cn/nukkit/item/enchantment/protection/EnchantmentProtectionProjectile.java
@@ -1,5 +1,8 @@
package cn.nukkit.item.enchantment.protection;
+import cn.nukkit.event.entity.EntityDamageEvent;
+import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
+
/**
* author: MagicDroidX
* Nukkit Project
@@ -24,4 +27,15 @@ public int getMaxEnchantAbility(int level) {
public double getTypeModifier() {
return 3;
}
+
+ @Override
+ public float getDamageProtection(EntityDamageEvent e) {
+ DamageCause cause = e.getCause();
+
+ if (level <= 0 || (cause != DamageCause.PROJECTILE)) {
+ return 0;
+ }
+
+ return (float) (getLevel() * getTypeModifier());
+ }
}
diff --git a/src/main/java/cn/nukkit/level/Explosion.java b/src/main/java/cn/nukkit/level/Explosion.java
index e6f07aa222..22db93bf79 100644
--- a/src/main/java/cn/nukkit/level/Explosion.java
+++ b/src/main/java/cn/nukkit/level/Explosion.java
@@ -221,7 +221,7 @@ public boolean explodeB() {
this.level.addChunkPacket((int) source.x >> 4, (int) source.z >> 4, pk);
this.level.addParticle(new HugeExplodeSeedParticle(this.source));
this.level.addSound(new ExplodeSound(new Vector3(this.source.x, this.source.y, this.source.z)));
-
+
return true;
}
diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java
index 237ed472cd..0057f581d4 100644
--- a/src/main/java/cn/nukkit/level/Level.java
+++ b/src/main/java/cn/nukkit/level/Level.java
@@ -57,6 +57,7 @@
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
@@ -76,6 +77,7 @@ public class Level implements ChunkManager, Metadatable {
public static final int BLOCK_UPDATE_WEAK = 4;
public static final int BLOCK_UPDATE_TOUCH = 5;
public static final int BLOCK_UPDATE_REDSTONE = 6;
+ public static final int BLOCK_UPDATE_TICK = 7;
public static final int TIME_DAY = 0;
public static final int TIME_SUNSET = 12000;
@@ -92,9 +94,6 @@ public class Level implements ChunkManager, Metadatable {
private final Map blockEntities = new HashMap<>();
- private Map> motionToSend = new HashMap<>();
- private Map> moveToSend = new HashMap<>();
-
private final Map players = new HashMap<>();
private final Map entities = new HashMap<>();
@@ -138,9 +137,11 @@ public class Level implements ChunkManager, Metadatable {
private float time;
public boolean stopTime;
+ public float skyLightSubtracted;
+
private String folderName;
- private final Map chunks = new HashMap<>();
+ private final Map chunks = new ConcurrentHashMap<>(); //temporal solution for CME
private Vector3 mutableBlock;
@@ -156,8 +157,8 @@ public int size() {
}
};
- private PriorityQueue updateQueue;
- private final Map updateQueueIndex = new HashMap<>();
+ private final TreeSet updateQueue = new TreeSet<>();
+ //private final Map updateQueueIndex = new HashMap<>();
private final Map> chunkSendQueue = new HashMap<>();
private final Map chunkSendTasks = new HashMap<>();
@@ -290,7 +291,6 @@ public Level(Server server, String name, String path, Class extends LevelProvi
}
this.folderName = name;
- this.updateQueue = new PriorityQueue<>(11, (o1, o2) -> o1.priority > o2.priority ? 1 : (o1.priority == o2.priority ? 0 : -1));
this.time = this.provider.getTime();
this.raining = this.provider.isRaining();
@@ -318,6 +318,8 @@ public Level(Server server, String name, String path, Class extends LevelProvi
this.temporalPosition = new Position(0, 0, 0, this);
this.temporalVector = new Vector3(0, 0, 0);
this.tickRate = 1;
+
+ this.skyLightSubtracted = this.calculateSkylightSubtracted(1);
}
public static long chunkHash(int x, int z) {
@@ -481,6 +483,28 @@ public void addSound(Sound sound, Collection players) {
this.addSound(sound, players.stream().toArray(Player[]::new));
}
+ public void addLevelSoundEvent(byte type, int pitch, int data, Vector3 pos, boolean unknown, boolean disableRelativeVolume) {
+ this.addLevelSoundEvent(type, pitch, data, pos, this.players.values(), unknown, disableRelativeVolume);
+ }
+
+ public void addLevelSoundEvent(byte type, int pitch, int data, Vector3 pos, Collection players, boolean unknown, boolean disableRelativeVolume) {
+ LevelSoundEventPacket pk = new LevelSoundEventPacket();
+ pk.type = type;
+ pk.pitch = pitch;
+ pk.extraData = data;
+ pk.x = (float) pos.x;
+ pk.y = (float) pos.y;
+ pk.z = (float) pos.z;
+ pk.unknownBool = unknown;
+ pk.disableRelativeVolume = disableRelativeVolume;
+
+ if (players == null) {
+ this.addChunkPacket(pos.getFloorX(), pos.getFloorZ(), pk);
+ } else {
+ Server.broadcastPacket(players, pk);
+ }
+ }
+
public void addParticle(Particle particle) {
this.addParticle(particle, (Player[]) null);
}
@@ -677,7 +701,6 @@ public void sendTime() {
}
public void doTick(int currentTick) {
-
this.timings.doTick.startTiming();
this.checkTime();
@@ -710,18 +733,20 @@ public void doTick(int currentTick) {
for (Map.Entry entry : this.chunks.entrySet()) {
long index = entry.getKey();
BaseFullChunk chunk = entry.getValue();
- if (rand.nextInt(100000) == 0) {
+ if (rand.nextInt(10000) == 0) {
this.updateLCG = this.updateLCG * 3 + 1013904223;
int LCG = this.updateLCG >> 2;
- int x = LCG & 0x0f;
- int z = LCG >> 8 & 0x0f;
- int y = chunk.getHighestBlockAt(x, z);
- int bId = chunk.getBlockId(x, y, z);
+
+ int chunkX = chunk.getX() * 16;
+ int chunkZ = chunk.getZ() * 16;
+ Vector3 vector = this.adjustPosToNearbyEntity(new Vector3(chunkX + (LCG & 15), 0, chunkZ + (LCG >> 8 & 15)));
+
+ int bId = this.getBlockIdAt(vector.getFloorX(), vector.getFloorY(), vector.getFloorZ());
if (bId != Block.TALL_GRASS && bId != Block.WATER)
- y += 1;
+ vector.y += 1;
CompoundTag nbt = new CompoundTag()
- .putList(new ListTag("Pos").add(new DoubleTag("", x + 16 * chunk.getX()))
- .add(new DoubleTag("", y)).add(new DoubleTag("", z + 16 * chunk.getZ())))
+ .putList(new ListTag("Pos").add(new DoubleTag("", vector.x))
+ .add(new DoubleTag("", vector.y)).add(new DoubleTag("", vector.z)))
.putList(new ListTag("Motion").add(new DoubleTag("", 0))
.add(new DoubleTag("", 0)).add(new DoubleTag("", 0)))
.putList(new ListTag("Rotation").add(new FloatTag("", 0))
@@ -735,6 +760,8 @@ public void doTick(int currentTick) {
bolt.setEffect(false);
}
+ this.addLevelSoundEvent(LevelSoundEventPacket.SOUND_THUNDER, 93, -1, vector, false, false);
+ this.addLevelSoundEvent(LevelSoundEventPacket.SOUND_EXPLODE, 93, -1, vector, false, false);
}
}
@@ -742,14 +769,35 @@ public void doTick(int currentTick) {
}
+ this.skyLightSubtracted = this.calculateSkylightSubtracted(1);
+
this.levelCurrentTick++;
this.unloadChunks();
this.timings.doTickPending.startTiming();
- while (this.updateQueue.peek() != null && this.updateQueue.peek().priority <= currentTick) {
- Block block = this.getBlock((Vector3) this.updateQueue.poll().data);
- this.updateQueueIndex.remove(Level.blockHash((int) block.x, (int) block.y, (int) block.z));
- block.onUpdate(BLOCK_UPDATE_SCHEDULED);
+ List toSchedule = new ArrayList<>();
+
+ for (int i = 0; i < this.updateQueue.size(); i++) {
+ BlockUpdateEntry entry = this.updateQueue.first();
+
+ if (entry.delay > this.getCurrentTick()) {
+ break;
+ }
+
+ if (isAreaLoaded(new AxisAlignedBB(entry.pos, entry.pos))) {
+ Block block = this.getBlock(entry.pos);
+
+ if (Block.equals(block, entry.block, false)) {
+ block.onUpdate(BLOCK_UPDATE_SCHEDULED);
+ }
+ } else {
+ toSchedule.add(entry);
+ }
+ this.updateQueue.remove(entry);
+ }
+
+ for (BlockUpdateEntry entry : toSchedule) {
+ this.scheduleUpdate(entry.block, entry.pos, 0);
}
this.timings.doTickPending.stopTiming();
@@ -818,24 +866,6 @@ public void doTick(int currentTick) {
this.checkSleep();
}
- for (long index : this.moveToSend.keySet()) {
- int chunkX = getHashX(index);
- int chunkZ = getHashZ(index);
- for (MoveEntityPacket packet : this.moveToSend.get(index).values()) {
- this.addChunkPacket(chunkX, chunkZ, packet);
- }
- }
- this.moveToSend.clear();
-
- for (long index : this.motionToSend.keySet()) {
- int chunkX = getHashX(index);
- int chunkZ = getHashZ(index);
- for (SetEntityMotionPacket packet : this.motionToSend.get(index).values()) {
- this.addChunkPacket(chunkX, chunkZ, packet);
- }
- }
- this.motionToSend.clear();
-
for (long index : this.chunkPackets.keySet()) {
int chunkX = Level.getHashX(index);
int chunkZ = Level.getHashZ(index);
@@ -851,6 +881,28 @@ public void doTick(int currentTick) {
this.timings.doTick.stopTiming();
}
+ public Vector3 adjustPosToNearbyEntity(Vector3 pos) {
+ pos.y = this.getHighestBlockAt(pos.getFloorX(), pos.getFloorZ());
+ AxisAlignedBB axisalignedbb = new AxisAlignedBB(pos.x, pos.y, pos.z, pos.getX(), 255, pos.getZ()).expand(3, 3, 3);
+ List list = new ArrayList<>();
+
+ for (Entity entity : this.getCollidingEntities(axisalignedbb)) {
+ if (entity.isAlive() && canBlockSeeSky(entity)) {
+ list.add(entity);
+ }
+ }
+
+ if (!list.isEmpty()) {
+ return list.get(this.rand.nextInt(list.size())).getPosition();
+ } else {
+ if (pos.getY() == -1) {
+ pos = pos.up(2);
+ }
+
+ return pos;
+ }
+ }
+
public void checkSleep() {
if (this.players.isEmpty()) {
return;
@@ -1156,7 +1208,6 @@ public void saveChunks() {
}
public void updateAroundRedstone(Vector3 pos, BlockFace face) {
- //TODO: event
for (BlockFace side : BlockFace.values()) {
/*if(face != null && side == face) {
continue;
@@ -1199,36 +1250,72 @@ public void updateAround(Vector3 pos) {
}
}
- public void scheduleUpdate(Vector3 pos, int delay) {
- delay += getServer().getTick();
+ public void scheduleUpdate(Block pos, int delay) {
+ this.scheduleUpdate(pos, pos, delay, 0, true);
+ }
- BlockVector3 index = Level.blockHash((int) pos.x, (int) pos.y, (int) pos.z);
- if (this.updateQueueIndex.containsKey(index) && this.updateQueueIndex.get(index) <= delay) {
+ public void scheduleUpdate(Block block, Vector3 pos, int delay) {
+ this.scheduleUpdate(block, pos, delay, 0, true);
+ }
+
+ public void scheduleUpdate(Block block, Vector3 pos, int delay, int priority) {
+ this.scheduleUpdate(block, pos, delay, priority, true);
+ }
+
+ public void scheduleUpdate(Block block, Vector3 pos, int delay, int priority, boolean checkArea) {
+ if (block.getId() == 0 || (checkArea && !this.isChunkLoaded(block.getFloorX() >> 4, block.getFloorZ() >> 4))) {
return;
}
- this.updateQueueIndex.put(index, delay);
- this.updateQueue.add(
- new PriorityObject(new Vector3((int) pos.x, (int) pos.y, (int) pos.z), delay));
+
+ BlockUpdateEntry entry = new BlockUpdateEntry(pos.floor(), block, ((long) delay) + getCurrentTick(), priority);
+
+ if (!this.updateQueue.contains(entry)) {
+ this.updateQueue.add(entry);
+ }
}
- public boolean cancelSheduledUpdate(Vector3 pos) {
- BlockVector3 index = Level.blockHash((int) pos.x, (int) pos.y, (int) pos.z);
+ public boolean cancelSheduledUpdate(Vector3 pos, Block block) {
+ BlockUpdateEntry entry = new BlockUpdateEntry(pos, block);
- Integer delay = this.updateQueueIndex.remove(index);
+ return this.updateQueue.remove(entry);
+ }
- if (delay == null) {
- return false;
- }
+ public boolean isUpdateScheduled(Vector3 pos, Block block) {
+ BlockUpdateEntry entry = new BlockUpdateEntry(pos, block);
+
+ return this.updateQueue.contains(entry);
+ }
+ public List getPendingBlockUpdates(FullChunk chunk) {
+ int minX = (chunk.getX() << 4) - 2;
+ int maxX = minX + 16 + 2;
+ int minZ = (chunk.getZ() << 4) - 2;
+ int maxZ = minZ + 16 + 2;
- this.updateQueue.remove(new PriorityObject(pos, delay));
- return true;
+ return this.getPendingBlockUpdates(new AxisAlignedBB(minX, 0, minZ, maxX, 256, maxZ));
}
- public boolean isUpdateScheduled(Vector3 pos) {
- BlockVector3 index = Level.blockHash((int) pos.x, (int) pos.y, (int) pos.z);
+ public List getPendingBlockUpdates(AxisAlignedBB boundingBox) {
+ List list = null;
+
+ Iterator iterator;
- return this.updateQueueIndex.containsKey(index);
+ iterator = this.updateQueue.iterator();
+
+ while (iterator.hasNext()) {
+ BlockUpdateEntry entry = iterator.next();
+ Vector3 pos = entry.pos;
+
+ if (pos.getX() >= boundingBox.minX && pos.getX() < boundingBox.maxX && pos.getZ() >= boundingBox.minZ && pos.getZ() < boundingBox.maxZ) {
+ if (list == null) {
+ list = new ArrayList<>();
+ }
+
+ list.add(entry);
+ }
+ }
+
+ return list;
}
public Block[] getCollisionBlocks(AxisAlignedBB bb) {
@@ -1350,17 +1437,48 @@ public int getFullLight(Vector3 pos) {
int level = 0;
if (chunk != null) {
level = chunk.getBlockSkyLight((int) pos.x & 0x0f, (int) pos.y & 0xff, (int) pos.z & 0x0f);
- // TODO: decrease light level by time of day
+ level -= this.skyLightSubtracted;
+
if (level < 15) {
level = Math.max(chunk.getBlockLight((int) pos.x & 0x0f, (int) pos.y & 0xff, (int) pos.z & 0x0f),
level);
- // todo: check this
}
}
return level;
}
+ public int calculateSkylightSubtracted(float tickDiff) {
+ float angle = this.calculateCelestialAngle(getTime(), tickDiff);
+ float light = 1 - (MathHelper.cos(angle * ((float) Math.PI * 2F)) * 2 + 0.5f);
+ light = light < 0 ? 0 : light > 1 ? 1 : light;
+ light = 1 - light;
+ light = (float) ((double) light * ((isRaining() ? 1 : 0) - (double) 5f / 16d));
+ light = (float) ((double) light * ((isThundering() ? 1 : 0) - (double) 5f / 16d));
+ light = 1 - light;
+ return (int) (light * 11f);
+ }
+
+ public float calculateCelestialAngle(int time, float tickDiff) {
+ float angle = ((float) time + tickDiff) / 24000f - 0.25f;
+
+ if (angle < 0) {
+ ++angle;
+ }
+
+ if (angle > 1) {
+ --angle;
+ }
+
+ float i = 1 - (float) ((Math.cos((double) angle * Math.PI) + 1) / 2d);
+ angle = angle + (i - angle) / 3;
+ return angle;
+ }
+
+ public int getMoonPhase(long worldTime) {
+ return (int) (worldTime / 24000 % 8 + 8) % 8;
+ }
+
public int getFullBlock(int x, int y, int z) {
return this.getChunk(x >> 4, z >> 4, false).getFullBlock(x & 0x0f, y & 0xff, z & 0x0f);
}
@@ -1399,12 +1517,12 @@ public Block getBlock(Vector3 pos, boolean cached) {
}
public void updateAllLight(Vector3 pos) {
- this.updateBlockSkyLight((int) pos.x, (int) pos.y, (int) pos.z);
+ this.updateBlockSkyLight((int) pos.x, (int) pos.y, (int) pos.z); //TODO: check if dimension has sky
this.updateBlockLight((int) pos.x, (int) pos.y, (int) pos.z);
}
public void updateBlockSkyLight(int x, int y, int z) {
- // todo
+ //TODO: sky light
}
public void updateBlockLight(int x, int y, int z) {
@@ -2628,6 +2746,14 @@ public int getTime() {
return (int) time;
}
+ public boolean isDaytime() {
+ return this.skyLightSubtracted < 4;
+ }
+
+ public long getCurrentTick() {
+ return this.levelCurrentTick;
+ }
+
public String getName() {
return this.provider.getName();
}
@@ -2820,25 +2946,16 @@ public void removeMetadata(String metadataKey, Plugin owningPlugin) throws Excep
}
public void addEntityMotion(int chunkX, int chunkZ, long entityId, double x, double y, double z) {
- Long index = Level.chunkHash(chunkX, chunkZ);
- if (!this.motionToSend.containsKey(index)) {
- this.motionToSend.put(index, new HashMap<>());
- }
SetEntityMotionPacket pk = new SetEntityMotionPacket();
pk.eid = entityId;
pk.motionX = (float) x;
pk.motionY = (float) y;
pk.motionZ = (float) z;
- this.motionToSend.get(index).put(entityId, pk);
- }
- public void addEntityMovement(int chunkX, int chunkZ, long entityId, double x, double y, double z, double yaw,
- double pitch, double headYaw) {
- Long index = Level.chunkHash(chunkX, chunkZ);
- if (!this.moveToSend.containsKey(index)) {
- this.moveToSend.put(index, new HashMap<>());
- }
+ this.addChunkPacket(chunkX, chunkZ, pk);
+ }
+ public void addEntityMovement(int chunkX, int chunkZ, long entityId, double x, double y, double z, double yaw, double pitch, double headYaw) {
MoveEntityPacket pk = new MoveEntityPacket();
pk.eid = entityId;
pk.x = (float) x;
@@ -2847,7 +2964,8 @@ public void addEntityMovement(int chunkX, int chunkZ, long entityId, double x, d
pk.yaw = (float) yaw;
pk.headYaw = (float) yaw;
pk.pitch = (float) pitch;
- this.moveToSend.get(index).put(entityId, pk);
+
+ this.addChunkPacket(chunkX, chunkZ, pk);
}
public boolean isRaining() {
@@ -3031,10 +3149,6 @@ public boolean isBlockPowered(Vector3 pos) {
return this.getRedstonePower(pos.north(), BlockFace.NORTH) > 0 || this.getRedstonePower(pos.south(), BlockFace.SOUTH) > 0 || this.getRedstonePower(pos.west(), BlockFace.WEST) > 0 || this.getRedstonePower(pos.east(), BlockFace.EAST) > 0 || this.getRedstonePower(pos.down(), BlockFace.DOWN) > 0 || this.getRedstonePower(pos.up(), BlockFace.UP) > 0;
}
- /**
- * Checks if the specified block or its neighbors are powered by a neighboring block. Used by blocks like TNT and
- * Doors.
- */
public int isBlockIndirectlyGettingPowered(Vector3 pos) {
int power = 0;
@@ -3052,4 +3166,24 @@ public int isBlockIndirectlyGettingPowered(Vector3 pos) {
return power;
}
+
+ private boolean isAreaLoaded(AxisAlignedBB bb) {
+ if (bb.maxY < 0 || bb.minY >= 256) {
+ return false;
+ }
+ int minX = NukkitMath.floorDouble(bb.minX) >> 4;
+ int minZ = NukkitMath.floorDouble(bb.minZ) >> 4;
+ int maxX = NukkitMath.floorDouble(bb.maxX) >> 4;
+ int maxZ = NukkitMath.floorDouble(bb.maxZ) >> 4;
+
+ for (int x = minX; x <= maxX; ++x) {
+ for (int z = minZ; z <= maxZ; ++z) {
+ if (!this.isChunkLoaded(x, z)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
}
diff --git a/src/main/java/cn/nukkit/level/format/anvil/Chunk.java b/src/main/java/cn/nukkit/level/format/anvil/Chunk.java
index 7781214d12..bbd57791d8 100644
--- a/src/main/java/cn/nukkit/level/format/anvil/Chunk.java
+++ b/src/main/java/cn/nukkit/level/format/anvil/Chunk.java
@@ -2,6 +2,7 @@
import cn.nukkit.Player;
import cn.nukkit.Server;
+import cn.nukkit.block.Block;
import cn.nukkit.blockentity.BlockEntity;
import cn.nukkit.entity.Entity;
import cn.nukkit.level.format.LevelProvider;
@@ -11,20 +12,15 @@
import cn.nukkit.nbt.stream.NBTInputStream;
import cn.nukkit.nbt.stream.NBTOutputStream;
import cn.nukkit.nbt.tag.*;
-import cn.nukkit.utils.Binary;
-import cn.nukkit.utils.BinaryStream;
-import cn.nukkit.utils.ChunkException;
-import cn.nukkit.utils.Zlib;
+import cn.nukkit.utils.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
+import java.lang.reflect.Constructor;
import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
/**
* author: MagicDroidX
@@ -162,6 +158,40 @@ public Chunk(LevelProvider level, CompoundTag nbt) {
this.NBTentities = this.nbt.getList("Entities", CompoundTag.class).getAll();
this.NBTtiles = this.nbt.getList("TileEntities", CompoundTag.class).getAll();
+ ListTag updateEntries = nbt.getList("TileTicks", CompoundTag.class);
+
+ if (updateEntries != null && updateEntries.size() > 0) {
+ for (CompoundTag entryNBT : updateEntries.getAll()) {
+ Block block = null;
+
+ try {
+ Tag tag = entryNBT.get("i");
+ if (tag instanceof StringTag) {
+ String name = ((StringTag) tag).data;
+
+ @SuppressWarnings("unchecked")
+ Class extends Block> clazz = (Class extends Block>) Class.forName("cn.nukkit.block." + name);
+
+ Constructor constructor = clazz.getDeclaredConstructor(int.class);
+ constructor.setAccessible(true);
+ block = (Block) constructor.newInstance(0);
+ }
+ } catch (Throwable e) {
+ continue;
+ }
+
+ if (block == null) {
+ continue;
+ }
+
+ block.x = entryNBT.getInt("x");
+ block.y = entryNBT.getInt("y");
+ block.z = entryNBT.getInt("z");
+
+ this.provider.getLevel().scheduleUpdate(block, block, entryNBT.getInt("t"), entryNBT.getInt("p"), false);
+ }
+ }
+
if (this.nbt.contains("Biomes")) {
this.checkOldBiomes(this.nbt.getByteArray("Biomes"));
this.nbt.remove("Biomes");
@@ -292,6 +322,26 @@ public byte[] toFastBinary() {
tileListTag.setAll(tiles);
nbt.putList(tileListTag);
+ List entries = this.provider.getLevel().getPendingBlockUpdates(this);
+
+ if (entries != null) {
+ ListTag tileTickTag = new ListTag<>("TileTicks");
+ long totalTime = this.provider.getLevel().getCurrentTick();
+
+ for (BlockUpdateEntry entry : entries) {
+ CompoundTag entryNBT = new CompoundTag()
+ .putString("i", entry.block.getClass().getSimpleName())
+ .putInt("x", entry.pos.getFloorX())
+ .putInt("y", entry.pos.getFloorY())
+ .putInt("z", entry.pos.getFloorZ())
+ .putInt("t", (int) (entry.delay - totalTime))
+ .putInt("p", entry.priority);
+ tileTickTag.add(entryNBT);
+ }
+
+ nbt.putList(tileTickTag);
+ }
+
BinaryStream extraData = new BinaryStream();
Map extraDataArray = this.getBlockExtraDataArray();
extraData.putInt(extraDataArray.size());
@@ -358,6 +408,26 @@ public byte[] toBinary() {
tileListTag.setAll(tiles);
nbt.putList(tileListTag);
+ List entries = this.provider.getLevel().getPendingBlockUpdates(this);
+
+ if (entries != null) {
+ ListTag tileTickTag = new ListTag<>("TileTicks");
+ long totalTime = this.provider.getLevel().getCurrentTick();
+
+ for (BlockUpdateEntry entry : entries) {
+ CompoundTag entryNBT = new CompoundTag()
+ .putString("i", entry.block.getClass().getSimpleName())
+ .putInt("x", entry.pos.getFloorX())
+ .putInt("y", entry.pos.getFloorY())
+ .putInt("z", entry.pos.getFloorZ())
+ .putInt("t", (int) (entry.delay - totalTime))
+ .putInt("p", entry.priority);
+ tileTickTag.add(entryNBT);
+ }
+
+ nbt.putList(tileTickTag);
+ }
+
BinaryStream extraData = new BinaryStream();
Map extraDataArray = this.getBlockExtraDataArray();
extraData.putInt(extraDataArray.size());
diff --git a/src/main/java/cn/nukkit/level/format/anvil/ChunkSection.java b/src/main/java/cn/nukkit/level/format/anvil/ChunkSection.java
index 2a34eecf3f..01df616960 100644
--- a/src/main/java/cn/nukkit/level/format/anvil/ChunkSection.java
+++ b/src/main/java/cn/nukkit/level/format/anvil/ChunkSection.java
@@ -4,7 +4,6 @@
import cn.nukkit.utils.Utils;
import java.nio.ByteBuffer;
-import java.util.Arrays;
/**
* author: MagicDroidX
diff --git a/src/main/java/cn/nukkit/level/generator/Normal.java b/src/main/java/cn/nukkit/level/generator/Normal.java
index 1b8bc41a6d..85f1835c96 100644
--- a/src/main/java/cn/nukkit/level/generator/Normal.java
+++ b/src/main/java/cn/nukkit/level/generator/Normal.java
@@ -3,7 +3,6 @@
import cn.nukkit.block.*;
import cn.nukkit.level.ChunkManager;
import cn.nukkit.level.format.FullChunk;
-import cn.nukkit.level.generator.Generator;
import cn.nukkit.level.generator.biome.Biome;
import cn.nukkit.level.generator.biome.BiomeSelector;
import cn.nukkit.level.generator.noise.Simplex;
@@ -16,10 +15,10 @@
/**
* This generator was written by Creeperface and Nycuro
- *
+ *
* The following classes are theirs and are intended for NUKKIT USAGE and should not be copied/translated to other software
* such as BukkitPE, ClearSky, Genisys , Pocketmine-MP
- *
+ *
* Normal.java
* MushroomPopulator.java
* DarkOakTreePopulator.java
@@ -36,7 +35,7 @@
* MushroomIsland.java
* TreeGenerator.java
* HugeTreesGenerator.java
- *
+ *
* Created by CreeperFace on 26. 10. 2016.
*/
public class Normal extends Generator {
@@ -50,7 +49,7 @@ public class Normal extends Generator {
public static final int ROOFED_FOREST_M = 157;
public static final int MUSHROOM_ISLAND = 14;
public static final int SWAMP = 6;
-
+
public static final int OCEAN = 0;
public static final int PLAINS = 1;
public static final int DESERT = 2;
@@ -60,7 +59,7 @@ public class Normal extends Generator {
public static final int ICE_PLAINS = 12;
public static final int BEACH = 16;
public static final int BIRCH_FOREST = 27;
-
+
public static final int MAX_BIOMES = 256;
@Override
@@ -101,7 +100,7 @@ public int getId() {
private final int basegroundHeight = 3;
private int waterColor = 16777215;
//private boolean enableSnow; Coming soon
-
+
protected float rainfall = 0.5F;
protected float temperature = 0.5F;
protected int grassColor = 0;
@@ -171,7 +170,7 @@ public void init(ChunkManager level, NukkitRandom random) {
this.selector.addBiome(Biome.getBiome(RIVER));
this.selector.addBiome(Biome.getBiome(ICE_PLAINS));
this.selector.addBiome(Biome.getBiome(BIRCH_FOREST));
-
+
this.selector.addBiome(Biome.getBiome(JUNGLE));
this.selector.addBiome(Biome.getBiome(SAVANNA));
this.selector.addBiome(Biome.getBiome(ROOFED_FOREST));
diff --git a/src/main/java/cn/nukkit/level/generator/biome/Biome.java b/src/main/java/cn/nukkit/level/generator/biome/Biome.java
index 02d74337b3..8c9f921ff2 100644
--- a/src/main/java/cn/nukkit/level/generator/biome/Biome.java
+++ b/src/main/java/cn/nukkit/level/generator/biome/Biome.java
@@ -22,11 +22,11 @@ public abstract class Biome {
public static final int TAIGA = 5;
public static final int SWAMP = 6;
public static final int RIVER = 7;
- public static final int JUNGLE = 21;
- public static final int SAVANNA = 35;
- public static final int ROOFED_FOREST = 29;
- public static final int ROOFED_FOREST_M = 157;
- public static final int MUSHROOM_ISLAND = 14;
+ public static final int JUNGLE = 21;
+ public static final int SAVANNA = 35;
+ public static final int ROOFED_FOREST = 29;
+ public static final int ROOFED_FOREST_M = 157;
+ public static final int MUSHROOM_ISLAND = 14;
public static final int HELL = 8;
@@ -78,7 +78,7 @@ public static void init() {
register(ICE_PLAINS, new IcePlainsBiome());
register(SMALL_MOUNTAINS, new SmallMountainsBiome());
register(BIRCH_FOREST, new ForestBiome(ForestBiome.TYPE_BIRCH));
-
+
register(JUNGLE, new JungleBiome());
register(ROOFED_FOREST, new RoofedForestBiome());
register(ROOFED_FOREST_M, new RoofedForestMBiome());
diff --git a/src/main/java/cn/nukkit/level/generator/biome/BiomeSelector.java b/src/main/java/cn/nukkit/level/generator/biome/BiomeSelector.java
index 616ddbdc6c..a4cd721584 100644
--- a/src/main/java/cn/nukkit/level/generator/biome/BiomeSelector.java
+++ b/src/main/java/cn/nukkit/level/generator/biome/BiomeSelector.java
@@ -1,7 +1,5 @@
package cn.nukkit.level.generator.biome;
-import cn.nukkit.level.generator.Normal;
-import cn.nukkit.level.generator.biome.Biome;
import cn.nukkit.level.generator.noise.Simplex;
import cn.nukkit.math.NukkitRandom;
@@ -51,10 +49,11 @@ public int lookup(double temperature, double rainfall) {
}
return Biome.PLAINS;
}
+
public void recalculate() {
this.map = new int[64 * 64];
- for(int i = 0; i < 64; ++i) {
- for(int j = 0; j < 64; ++j) {
+ for (int i = 0; i < 64; ++i) {
+ for (int j = 0; j < 64; ++j) {
this.map[i + (j << 6)] = this.lookup(i / 63d, j / 63d);
}
}
diff --git a/src/main/java/cn/nukkit/level/generator/biome/MesaBiome.java b/src/main/java/cn/nukkit/level/generator/biome/MesaBiome.java
index 6041409fb9..a31c8f9501 100644
--- a/src/main/java/cn/nukkit/level/generator/biome/MesaBiome.java
+++ b/src/main/java/cn/nukkit/level/generator/biome/MesaBiome.java
@@ -3,7 +3,7 @@
public class MesaBiome extends SandyBiome {
public MesaBiome() {
- //WIP
+ //WIP
}
@Override
diff --git a/src/main/java/cn/nukkit/level/generator/biome/RoofedForestBiome.java b/src/main/java/cn/nukkit/level/generator/biome/RoofedForestBiome.java
index 1875974c15..cbbc281d56 100644
--- a/src/main/java/cn/nukkit/level/generator/biome/RoofedForestBiome.java
+++ b/src/main/java/cn/nukkit/level/generator/biome/RoofedForestBiome.java
@@ -1,4 +1,5 @@
package cn.nukkit.level.generator.biome;
+
import cn.nukkit.level.generator.populator.MushroomPopulator;
import cn.nukkit.level.generator.populator.PopulatorFlower;
import cn.nukkit.level.generator.populator.PopulatorGrass;
diff --git a/src/main/java/cn/nukkit/level/generator/object/tree/NewDarkOakTree.java b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectDarkOakTree.java
similarity index 99%
rename from src/main/java/cn/nukkit/level/generator/object/tree/NewDarkOakTree.java
rename to src/main/java/cn/nukkit/level/generator/object/tree/ObjectDarkOakTree.java
index 0f5ad2d993..726c5ae3ba 100644
--- a/src/main/java/cn/nukkit/level/generator/object/tree/NewDarkOakTree.java
+++ b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectDarkOakTree.java
@@ -11,7 +11,7 @@
/**
* Created by CreeperFace on 23. 10. 2016.
*/
-public class NewDarkOakTree extends TreeGenerator {
+public class ObjectDarkOakTree extends TreeGenerator {
private static final Block DARK_OAK_LOG = new BlockWood2(BlockWood2.DARK_OAK);
private static final Block DARK_OAK_LEAVES = new BlockLeaves2(BlockLeaves2.DARK_OAK);
diff --git a/src/main/java/cn/nukkit/level/generator/object/tree/NewJungleBigTree.java b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectJungleBigTree.java
similarity index 85%
rename from src/main/java/cn/nukkit/level/generator/object/tree/NewJungleBigTree.java
rename to src/main/java/cn/nukkit/level/generator/object/tree/ObjectJungleBigTree.java
index cd3828879d..1f96d9642f 100644
--- a/src/main/java/cn/nukkit/level/generator/object/tree/NewJungleBigTree.java
+++ b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectJungleBigTree.java
@@ -7,20 +7,20 @@
import cn.nukkit.math.NukkitRandom;
import cn.nukkit.math.Vector3;
-public class NewJungleBigTree extends HugeTreesGenerator {
- public NewJungleBigTree(int baseHeightIn, int extraRandomHeightIn, Block woodMetadataIn, Block leavesMetadataIn) {
- super(baseHeightIn, extraRandomHeightIn, woodMetadataIn, leavesMetadataIn);
+public class ObjectJungleBigTree extends HugeTreesGenerator {
+ public ObjectJungleBigTree(int baseHeightIn, int extraRandomHeight, Block woodMetadata, Block leavesMetadata) {
+ super(baseHeightIn, extraRandomHeight, woodMetadata, leavesMetadata);
}
public boolean generate(ChunkManager level, NukkitRandom rand, Vector3 position) {
- int i = this.getHeight(rand);
+ int height = this.getHeight(rand);
- if (!this.ensureGrowable(level, rand, position, i)) {
+ if (!this.ensureGrowable(level, rand, position, height)) {
return false;
} else {
- this.createCrown(level, position.up(i), 2);
+ this.createCrown(level, position.up(height), 2);
- for (int j = (int) position.getY() + i - 2 - rand.nextBoundedInt(4); j > position.getY() + i / 2; j -= 2 + rand.nextBoundedInt(4)) {
+ for (int j = (int) position.getY() + height - 2 - rand.nextBoundedInt(4); j > position.getY() + height / 2; j -= 2 + rand.nextBoundedInt(4)) {
float f = rand.nextFloat() * ((float) Math.PI * 2F);
int k = (int) (position.getX() + (0.5F + MathHelper.cos(f) * 4.0F));
int l = (int) (position.getZ() + (0.5F + MathHelper.sin(f) * 4.0F));
@@ -40,7 +40,7 @@ public boolean generate(ChunkManager level, NukkitRandom rand, Vector3 position)
}
}
- for (int i2 = 0; i2 < i; ++i2) {
+ for (int i2 = 0; i2 < height; ++i2) {
Vector3 blockpos = position.up(i2);
if (this.canGrowInto(level.getBlockIdAt((int) blockpos.x, (int) blockpos.y, (int) blockpos.z))) {
@@ -52,7 +52,7 @@ public boolean generate(ChunkManager level, NukkitRandom rand, Vector3 position)
}
}
- if (i2 < i - 1) {
+ if (i2 < height - 1) {
Vector3 blockpos1 = blockpos.east();
if (this.canGrowInto(level.getBlockIdAt((int) blockpos1.x, (int) blockpos1.y, (int) blockpos1.z))) {
diff --git a/src/main/java/cn/nukkit/level/generator/object/tree/NewSavannaTree.java b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectSavannaTree.java
similarity index 99%
rename from src/main/java/cn/nukkit/level/generator/object/tree/NewSavannaTree.java
rename to src/main/java/cn/nukkit/level/generator/object/tree/ObjectSavannaTree.java
index 89011502b6..b598cd2883 100644
--- a/src/main/java/cn/nukkit/level/generator/object/tree/NewSavannaTree.java
+++ b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectSavannaTree.java
@@ -8,7 +8,7 @@
import cn.nukkit.math.NukkitRandom;
import cn.nukkit.math.Vector3;
-public class NewSavannaTree extends TreeGenerator {
+public class ObjectSavannaTree extends TreeGenerator {
private static final Block TRUNK = new BlockWood2(BlockWood2.ACACIA);
private static final Block LEAF = new BlockLeaves2(BlockLeaves2.ACACIA);
diff --git a/src/main/java/cn/nukkit/level/generator/object/tree/NewSwampTree.java b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectSwampTree.java
similarity index 99%
rename from src/main/java/cn/nukkit/level/generator/object/tree/NewSwampTree.java
rename to src/main/java/cn/nukkit/level/generator/object/tree/ObjectSwampTree.java
index a745c4c5cf..b7862a6c43 100644
--- a/src/main/java/cn/nukkit/level/generator/object/tree/NewSwampTree.java
+++ b/src/main/java/cn/nukkit/level/generator/object/tree/ObjectSwampTree.java
@@ -9,8 +9,8 @@
import cn.nukkit.math.NukkitRandom;
import cn.nukkit.math.Vector3;
-public class NewSwampTree extends TreeGenerator {
-
+public class ObjectSwampTree extends TreeGenerator {
+
/**
* The metadata value of the wood to use in tree generation.
*/
diff --git a/src/main/java/cn/nukkit/level/generator/populator/MushroomPopulator.java b/src/main/java/cn/nukkit/level/generator/populator/MushroomPopulator.java
index 978e610bcf..aebfd68935 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/MushroomPopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/MushroomPopulator.java
@@ -3,7 +3,6 @@
import cn.nukkit.block.Block;
import cn.nukkit.level.ChunkManager;
import cn.nukkit.level.generator.object.mushroom.BigMushroom;
-import cn.nukkit.level.generator.populator.Populator;
import cn.nukkit.math.NukkitMath;
import cn.nukkit.math.NukkitRandom;
import cn.nukkit.math.Vector3;
diff --git a/src/main/java/cn/nukkit/level/generator/populator/tree/DarkOakTreePopulator.java b/src/main/java/cn/nukkit/level/generator/populator/tree/DarkOakTreePopulator.java
index fe5141ce81..9d0866dbf6 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/tree/DarkOakTreePopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/tree/DarkOakTreePopulator.java
@@ -3,7 +3,7 @@
import cn.nukkit.block.Block;
import cn.nukkit.block.BlockSapling;
import cn.nukkit.level.ChunkManager;
-import cn.nukkit.level.generator.object.tree.NewDarkOakTree;
+import cn.nukkit.level.generator.object.tree.ObjectDarkOakTree;
import cn.nukkit.level.generator.populator.Populator;
import cn.nukkit.math.NukkitMath;
import cn.nukkit.math.NukkitRandom;
@@ -46,7 +46,7 @@ public void populate(ChunkManager level, int chunkX, int chunkZ, NukkitRandom ra
continue;
}
- new NewDarkOakTree().generate(level, random, v.setComponents(x, y, z));
+ new ObjectDarkOakTree().generate(level, random, v.setComponents(x, y, z));
}
}
diff --git a/src/main/java/cn/nukkit/level/generator/populator/tree/JungleBigTreePopulator.java b/src/main/java/cn/nukkit/level/generator/populator/tree/JungleBigTreePopulator.java
index 2021e83d6d..d852d4db5f 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/tree/JungleBigTreePopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/tree/JungleBigTreePopulator.java
@@ -5,7 +5,7 @@
import cn.nukkit.block.BlockSapling;
import cn.nukkit.block.BlockWood;
import cn.nukkit.level.ChunkManager;
-import cn.nukkit.level.generator.object.tree.NewJungleBigTree;
+import cn.nukkit.level.generator.object.tree.ObjectJungleBigTree;
import cn.nukkit.level.generator.populator.Populator;
import cn.nukkit.math.NukkitMath;
import cn.nukkit.math.NukkitRandom;
@@ -48,7 +48,7 @@ public void populate(ChunkManager level, int chunkX, int chunkZ, NukkitRandom ra
if (y == -1) {
continue;
}
- new NewJungleBigTree(10, 20, new BlockWood(BlockWood.JUNGLE), new BlockLeaves(BlockLeaves.JUNGLE)).generate(this.level, random, v.setComponents(x, y, z));
+ new ObjectJungleBigTree(10, 20, new BlockWood(BlockWood.JUNGLE), new BlockLeaves(BlockLeaves.JUNGLE)).generate(this.level, random, v.setComponents(x, y, z));
}
}
diff --git a/src/main/java/cn/nukkit/level/generator/populator/tree/SavannaTreePopulator.java b/src/main/java/cn/nukkit/level/generator/populator/tree/SavannaTreePopulator.java
index e6b5c0bd8c..138d32371d 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/tree/SavannaTreePopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/tree/SavannaTreePopulator.java
@@ -3,7 +3,7 @@
import cn.nukkit.block.Block;
import cn.nukkit.block.BlockSapling;
import cn.nukkit.level.ChunkManager;
-import cn.nukkit.level.generator.object.tree.NewSavannaTree;
+import cn.nukkit.level.generator.object.tree.ObjectSavannaTree;
import cn.nukkit.level.generator.populator.Populator;
import cn.nukkit.math.NukkitMath;
import cn.nukkit.math.NukkitRandom;
@@ -46,7 +46,7 @@ public void populate(ChunkManager level, int chunkX, int chunkZ, NukkitRandom ra
if (y == -1) {
continue;
}
- new NewSavannaTree().generate(level, random, v.setComponents(x, y, z));
+ new ObjectSavannaTree().generate(level, random, v.setComponents(x, y, z));
}
}
diff --git a/src/main/java/cn/nukkit/level/generator/populator/tree/SwampTreePopulator.java b/src/main/java/cn/nukkit/level/generator/populator/tree/SwampTreePopulator.java
index 2a615af665..793ad2b872 100644
--- a/src/main/java/cn/nukkit/level/generator/populator/tree/SwampTreePopulator.java
+++ b/src/main/java/cn/nukkit/level/generator/populator/tree/SwampTreePopulator.java
@@ -3,7 +3,7 @@
import cn.nukkit.block.Block;
import cn.nukkit.block.BlockSapling;
import cn.nukkit.level.ChunkManager;
-import cn.nukkit.level.generator.object.tree.NewSwampTree;
+import cn.nukkit.level.generator.object.tree.ObjectSwampTree;
import cn.nukkit.level.generator.populator.Populator;
import cn.nukkit.math.NukkitMath;
import cn.nukkit.math.NukkitRandom;
@@ -45,7 +45,7 @@ public void populate(ChunkManager level, int chunkX, int chunkZ, NukkitRandom ra
if (y == -1) {
continue;
}
- new NewSwampTree().generate(level, random, v.setComponents(x, y, z));
+ new ObjectSwampTree().generate(level, random, v.setComponents(x, y, z));
}
}
diff --git a/src/main/java/cn/nukkit/level/sound/BlockPlaceSound.java b/src/main/java/cn/nukkit/level/sound/BlockPlaceSound.java
index a985ab7b6e..078c04f809 100644
--- a/src/main/java/cn/nukkit/level/sound/BlockPlaceSound.java
+++ b/src/main/java/cn/nukkit/level/sound/BlockPlaceSound.java
@@ -1,7 +1,6 @@
package cn.nukkit.level.sound;
import cn.nukkit.math.Vector3;
-import cn.nukkit.network.protocol.LevelEventPacket;
import cn.nukkit.network.protocol.LevelSoundEventPacket;
/**
diff --git a/src/main/java/cn/nukkit/math/AxisAlignedBB.java b/src/main/java/cn/nukkit/math/AxisAlignedBB.java
index d0aea0e5a6..6f6ba55b16 100644
--- a/src/main/java/cn/nukkit/math/AxisAlignedBB.java
+++ b/src/main/java/cn/nukkit/math/AxisAlignedBB.java
@@ -16,6 +16,15 @@ public class AxisAlignedBB implements Cloneable {
public double maxY;
public double maxZ;
+ public AxisAlignedBB(Vector3 pos1, Vector3 pos2) {
+ this.minX = Math.min(pos1.x, pos2.x);
+ this.minY = Math.min(pos1.y, pos2.y);
+ this.minZ = Math.min(pos1.z, pos2.z);
+ this.maxX = Math.max(pos1.x, pos2.x);
+ this.maxY = Math.max(pos1.y, pos2.y);
+ this.maxZ = Math.max(pos1.z, pos2.z);
+ }
+
public AxisAlignedBB(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
this.minX = minX;
this.minY = minY;
diff --git a/src/main/java/cn/nukkit/nbt/tag/ByteArrayTag.java b/src/main/java/cn/nukkit/nbt/tag/ByteArrayTag.java
index 874de1ba8b..ca9f3cbf87 100644
--- a/src/main/java/cn/nukkit/nbt/tag/ByteArrayTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/ByteArrayTag.java
@@ -43,7 +43,7 @@ public byte getId() {
@Override
public String toString() {
- return "ByteArrayTag " + this.getName() + " (data: 0x" + Binary.bytesToHexString(data, true) + " [" + data.length + " bytes])";
+ return "ByteArrayTag " + this.getName() + " (pos: 0x" + Binary.bytesToHexString(data, true) + " [" + data.length + " bytes])";
}
@Override
diff --git a/src/main/java/cn/nukkit/nbt/tag/ByteTag.java b/src/main/java/cn/nukkit/nbt/tag/ByteTag.java
index d9cadc5a4d..a65d546175 100644
--- a/src/main/java/cn/nukkit/nbt/tag/ByteTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/ByteTag.java
@@ -48,7 +48,7 @@ public String toString() {
if (hex.length() < 2) {
hex = "0" + hex;
}
- return "ByteTag " + this.getName() + " (data: 0x" + hex + ")";
+ return "ByteTag " + this.getName() + " (pos: 0x" + hex + ")";
}
@Override
diff --git a/src/main/java/cn/nukkit/nbt/tag/DoubleTag.java b/src/main/java/cn/nukkit/nbt/tag/DoubleTag.java
index 4a04f825c4..76a0dd859d 100644
--- a/src/main/java/cn/nukkit/nbt/tag/DoubleTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/DoubleTag.java
@@ -44,7 +44,7 @@ public byte getId() {
@Override
public String toString() {
- return "DoubleTag " + this.getName() + " (data: " + data + ")";
+ return "DoubleTag " + this.getName() + " (pos: " + data + ")";
}
@Override
diff --git a/src/main/java/cn/nukkit/nbt/tag/FloatTag.java b/src/main/java/cn/nukkit/nbt/tag/FloatTag.java
index b290853ad3..f77fa199f2 100644
--- a/src/main/java/cn/nukkit/nbt/tag/FloatTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/FloatTag.java
@@ -44,7 +44,7 @@ public byte getId() {
@Override
public String toString() {
- return "FloatTag " + this.getName() + " (data: " + data + ")";
+ return "FloatTag " + this.getName() + " (pos: " + data + ")";
}
@Override
diff --git a/src/main/java/cn/nukkit/nbt/tag/IntTag.java b/src/main/java/cn/nukkit/nbt/tag/IntTag.java
index 7f308d3ac9..31ebd903b1 100644
--- a/src/main/java/cn/nukkit/nbt/tag/IntTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/IntTag.java
@@ -44,7 +44,7 @@ public byte getId() {
@Override
public String toString() {
- return "IntTag" + this.getName() + "(data: " + data + ")";
+ return "IntTag" + this.getName() + "(pos: " + data + ")";
}
@Override
diff --git a/src/main/java/cn/nukkit/nbt/tag/LongTag.java b/src/main/java/cn/nukkit/nbt/tag/LongTag.java
index 54793dc528..ad75427acd 100644
--- a/src/main/java/cn/nukkit/nbt/tag/LongTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/LongTag.java
@@ -44,7 +44,7 @@ public byte getId() {
@Override
public String toString() {
- return "LongTag" + this.getName() + " (data:" + data + ")";
+ return "LongTag" + this.getName() + " (pos:" + data + ")";
}
@Override
diff --git a/src/main/java/cn/nukkit/nbt/tag/StringTag.java b/src/main/java/cn/nukkit/nbt/tag/StringTag.java
index 118f72be0a..882c2431e3 100644
--- a/src/main/java/cn/nukkit/nbt/tag/StringTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/StringTag.java
@@ -35,7 +35,7 @@ public byte getId() {
@Override
public String toString() {
- return "StringTag " + this.getName() + " (data: " + data + ")";
+ return "StringTag " + this.getName() + " (pos: " + data + ")";
}
@Override
diff --git a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java
index 4719a2ff05..c2b73359c0 100644
--- a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java
@@ -7,7 +7,7 @@
public class AvailableCommandsPacket extends DataPacket {
public static final byte NETWORK_ID = ProtocolInfo.AVAILABLE_COMMANDS_PACKET;
- public String commands; //JSON-encoded command data
+ public String commands; //JSON-encoded command pos
public String unknown = "";
@Override
diff --git a/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java b/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java
index 0e32286f34..4d850e948e 100644
--- a/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java
@@ -111,7 +111,7 @@ public class LevelSoundEventPacket extends DataPacket {
public int extraData = -1;
public int pitch = -1;
public boolean unknownBool;
- public boolean unknownBool2;
+ public boolean disableRelativeVolume;
@Override
public void decode() {
@@ -123,7 +123,7 @@ public void decode() {
this.extraData = this.getVarInt();
this.pitch = this.getVarInt();
this.unknownBool = this.getBoolean();
- this.unknownBool2 = this.getBoolean();
+ this.disableRelativeVolume = this.getBoolean();
}
@Override
@@ -134,7 +134,7 @@ public void encode() {
this.putVarInt(this.extraData);
this.putVarInt(this.pitch);
this.putBoolean(this.unknownBool);
- this.putBoolean(this.unknownBool2);
+ this.putBoolean(this.disableRelativeVolume);
}
@Override
diff --git a/src/main/java/cn/nukkit/network/rcon/RCONCommand.java b/src/main/java/cn/nukkit/network/rcon/RCONCommand.java
index a992cd35c2..5be499bb9d 100644
--- a/src/main/java/cn/nukkit/network/rcon/RCONCommand.java
+++ b/src/main/java/cn/nukkit/network/rcon/RCONCommand.java
@@ -3,7 +3,7 @@
import java.nio.channels.SocketChannel;
/**
- * A data structure to hold sender, request ID and command itself.
+ * A pos structure to hold sender, request ID and command itself.
*
* @author Tee7even
*/
diff --git a/src/main/java/cn/nukkit/network/rcon/RCONPacket.java b/src/main/java/cn/nukkit/network/rcon/RCONPacket.java
index afa057c275..71baedc169 100644
--- a/src/main/java/cn/nukkit/network/rcon/RCONPacket.java
+++ b/src/main/java/cn/nukkit/network/rcon/RCONPacket.java
@@ -5,7 +5,7 @@
import java.nio.ByteOrder;
/**
- * A data structure representing an RCON packet.
+ * A pos structure representing an RCON packet.
*
* @author Tee7even
*/
diff --git a/src/main/java/cn/nukkit/plugin/Plugin.java b/src/main/java/cn/nukkit/plugin/Plugin.java
index 83b1cea80a..3ef05d944b 100644
--- a/src/main/java/cn/nukkit/plugin/Plugin.java
+++ b/src/main/java/cn/nukkit/plugin/Plugin.java
@@ -207,7 +207,7 @@ public interface Plugin extends CommandExecutor {
*
执行这个函数时,Nukkit会在资源文件夹内寻找开发者配置好的默认配置文件config.yml,然后保存在数据文件夹。
* 如果数据文件夹已经有一个config.yml文件,Nukkit不会替换这个文件。
* When this is used, Nukkit will look for the default 'config.yml' file which is configured by plugin developer
- * and save it to the data folder. If a config.yml file exists in the data folder, Nukkit won't replace it.
+ * and save it to the pos folder. If a config.yml file exists in the pos folder, Nukkit won't replace it.
*
*
这个函数通常用来在插件被加载(load)时,保存默认的配置文件。这样插件在启用(enable)时不会错误读取空的配置文件,
* 用户也无需从开发者处手动下载配置文件保存后再使用插件。
diff --git a/src/main/java/cn/nukkit/plugin/PluginBase.java b/src/main/java/cn/nukkit/plugin/PluginBase.java
index bcd042f2e0..11e3c4a852 100644
--- a/src/main/java/cn/nukkit/plugin/PluginBase.java
+++ b/src/main/java/cn/nukkit/plugin/PluginBase.java
@@ -119,7 +119,7 @@ public final PluginDescription getDescription() {
* @param description 描述这个插件的{@code PluginDescription}对象。
* A {@code PluginDescription} object that describes this plugin.
* @param dataFolder 这个插件的数据的文件夹。
- * The data folder of this plugin.
+ * The pos folder of this plugin.
* @param file 这个插件的文件{@code File}对象。对于jar格式的插件,就是jar文件本身。
* The {@code File} object of this plugin itself. For jar-packed plugins, it is the jar file itself.
* @since Nukkit 1.0 | Nukkit API 1.0.0
diff --git a/src/main/java/cn/nukkit/plugin/PluginLoader.java b/src/main/java/cn/nukkit/plugin/PluginLoader.java
index 1ca2a740b9..2a39bb1a42 100644
--- a/src/main/java/cn/nukkit/plugin/PluginLoader.java
+++ b/src/main/java/cn/nukkit/plugin/PluginLoader.java
@@ -21,7 +21,7 @@ public interface PluginLoader {
*
这个方法应该设置好插件的相关属性。比如,插件所在的服务器对象,插件的加载器对象,插件的描述对象,插件的数据文件夹。
* Properties for loaded plugin should be set in this method. Such as, the {@code Server} object for which this
* plugin is running in, the {@code PluginLoader} object for its loader, and the {@code File} object for its
- * data folder.
+ * pos folder.
*
*
如果插件加载失败,这个方法应该返回{@code null},或者抛出异常。
* If the plugin loader does not load this plugin successfully, a {@code null} should be returned,
@@ -43,7 +43,7 @@ public interface PluginLoader {
*
这个方法应该设置好插件的相关属性。比如,插件所在的服务器对象,插件的加载器对象,插件的描述对象,插件的数据文件夹。
* Properties for loaded plugin should be set in this method. Such as, the {@code Server} object for which this
* plugin is running in, the {@code PluginLoader} object for its loader, and the {@code File} object for its
- * data folder.
+ * pos folder.
*
*
如果插件加载失败,这个方法应该返回{@code null},或者抛出异常。
* If the plugin loader does not load this plugin successfully, a {@code null} should be returned,
diff --git a/src/main/java/cn/nukkit/raknet/server/Session.java b/src/main/java/cn/nukkit/raknet/server/Session.java
index ad59375ff5..6e06268a58 100644
--- a/src/main/java/cn/nukkit/raknet/server/Session.java
+++ b/src/main/java/cn/nukkit/raknet/server/Session.java
@@ -379,7 +379,7 @@ private void handleEncapsulatedPacketRoute(EncapsulatedPacket packet) throws Exc
}
byte id = packet.buffer[0];
- if ((id & 0xff) < 0x80) { //internal data packet
+ if ((id & 0xff) < 0x80) { //internal pos packet
if (state == STATE_CONNECTING_2) {
if (id == CLIENT_CONNECT_DataPacket.ID) {
CLIENT_CONNECT_DataPacket dataPacket = new CLIENT_CONNECT_DataPacket();
diff --git a/src/main/java/cn/nukkit/utils/Binary.java b/src/main/java/cn/nukkit/utils/Binary.java
index 8e3d0ecee7..9405f1b4e9 100644
--- a/src/main/java/cn/nukkit/utils/Binary.java
+++ b/src/main/java/cn/nukkit/utils/Binary.java
@@ -4,6 +4,7 @@
import cn.nukkit.entity.data.*;
import cn.nukkit.item.Item;
import cn.nukkit.math.BlockVector3;
+import cn.nukkit.math.NukkitMath;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -247,7 +248,16 @@ public static byte[] writeLInt(int i) {
}
public static float readFloat(byte[] bytes) {
- return Float.intBitsToFloat(readInt(bytes));
+ return readFloat(bytes, -1);
+ }
+
+ public static float readFloat(byte[] bytes, int accuracy) {
+ float val = Float.intBitsToFloat(readInt(bytes));
+ if (accuracy > -1) {
+ return (float) NukkitMath.round(val, accuracy);
+ } else {
+ return val;
+ }
}
public static byte[] writeFloat(float f) {
@@ -255,7 +265,16 @@ public static byte[] writeFloat(float f) {
}
public static float readLFloat(byte[] bytes) {
- return Float.intBitsToFloat(readLInt(bytes));
+ return readLFloat(bytes, -1);
+ }
+
+ public static float readLFloat(byte[] bytes, int accuracy) {
+ float val = Float.intBitsToFloat(readLInt(bytes));
+ if (accuracy > -1) {
+ return (float) NukkitMath.round(val, accuracy);
+ } else {
+ return val;
+ }
}
public static byte[] writeLFloat(float f) {
diff --git a/src/main/java/cn/nukkit/utils/BinaryStream.java b/src/main/java/cn/nukkit/utils/BinaryStream.java
index 583773ab7b..c43e888b33 100644
--- a/src/main/java/cn/nukkit/utils/BinaryStream.java
+++ b/src/main/java/cn/nukkit/utils/BinaryStream.java
@@ -144,7 +144,11 @@ public void putLShort(int s) {
}
public float getFloat() {
- return Binary.readFloat(this.get(4));
+ return getFloat(-1);
+ }
+
+ public float getFloat(int accuracy) {
+ return Binary.readFloat(this.get(4), accuracy);
}
public void putFloat(float v) {
@@ -152,7 +156,11 @@ public void putFloat(float v) {
}
public float getLFloat() {
- return Binary.readLFloat(this.get(4));
+ return getLFloat(-1);
+ }
+
+ public float getLFloat(int accuracy) {
+ return Binary.readLFloat(this.get(4), accuracy);
}
public void putLFloat(float v) {
@@ -310,7 +318,7 @@ public void putBlockCoords(int x, int y, int z) {
}
public Vector3f getVector3f() {
- return new Vector3f(this.getLFloat(), this.getLFloat(), this.getLFloat());
+ return new Vector3f(this.getLFloat(4), this.getLFloat(4), this.getLFloat(4));
}
public void putVector3f(float x, float y, float z) {
diff --git a/src/main/java/cn/nukkit/utils/BlockUpdateEntry.java b/src/main/java/cn/nukkit/utils/BlockUpdateEntry.java
new file mode 100644
index 0000000000..071c8d0320
--- /dev/null
+++ b/src/main/java/cn/nukkit/utils/BlockUpdateEntry.java
@@ -0,0 +1,49 @@
+package cn.nukkit.utils;
+
+import cn.nukkit.block.Block;
+import cn.nukkit.math.Vector3;
+
+/**
+ * author: MagicDroidX
+ * Nukkit Project
+ */
+public class BlockUpdateEntry implements Comparable {
+ private static long entryID = 0;
+
+ public int priority;
+ public long delay;
+
+ public final Vector3 pos;
+ public final Block block;
+
+ public final long id;
+
+ public BlockUpdateEntry(Vector3 pos, Block block) {
+ this.pos = pos;
+ this.block = block;
+ this.id = entryID++;
+ }
+
+ public BlockUpdateEntry(Vector3 pos, Block block, long delay, int priority) {
+ this.id = entryID++;
+ this.pos = pos;
+ this.priority = priority;
+ this.delay = delay;
+ this.block = block;
+ }
+
+ @Override
+ public int compareTo(BlockUpdateEntry entry) {
+ return this.delay < entry.delay ? -1 : (this.delay > entry.delay ? 1 : (this.priority != entry.priority ? this.priority - entry.priority : (this.id < entry.id ? -1 : (this.id > entry.id ? 1 : 0))));
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (!(object instanceof BlockUpdateEntry)) {
+ return false;
+ } else {
+ BlockUpdateEntry entry = (BlockUpdateEntry) object;
+ return this.pos.equals(entry.pos) && Block.equals(this.block, entry.block, false);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cn/nukkit/utils/Config.java b/src/main/java/cn/nukkit/utils/Config.java
index 27d270e62f..6a672fc691 100644
--- a/src/main/java/cn/nukkit/utils/Config.java
+++ b/src/main/java/cn/nukkit/utils/Config.java
@@ -129,6 +129,7 @@ public boolean load(String file, int type, ConfigSection defaultMap) {
this.file = new File(file);
if (!this.file.exists()) {
try {
+ this.file.getParentFile().mkdirs();
this.file.createNewFile();
} catch (IOException e) {
MainLogger.getLogger().error("Could not create Config " + this.file.toString(), e);
diff --git a/src/main/java/cn/nukkit/utils/PriorityObject.java b/src/main/java/cn/nukkit/utils/PriorityObject.java
deleted file mode 100644
index 6582f7eaf7..0000000000
--- a/src/main/java/cn/nukkit/utils/PriorityObject.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package cn.nukkit.utils;
-
-/**
- * author: MagicDroidX
- * Nukkit Project
- */
-public class PriorityObject {
- public final int priority;
- public final Object data;
-
- public PriorityObject(Object data, int priority) {
- this.data = data;
- this.priority = priority;
- }
-}
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
index ece3fa36bb..a6f919e957 100644
--- a/src/main/java/co/aikar/timings/TimingsExport.java
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
@@ -34,8 +34,6 @@
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
-import static co.aikar.timings.TimingsManager.HISTORY;
-
import java.io.*;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
@@ -46,6 +44,8 @@
import java.util.Date;
import java.util.zip.GZIPOutputStream;
+import static co.aikar.timings.TimingsManager.HISTORY;
+
public class TimingsExport extends Thread {
private final CommandSender sender;
private final JsonObject out;
@@ -75,7 +75,7 @@ public static void reportTimings(CommandSender sender) {
out.addProperty("server", Server.getInstance().getName());
out.addProperty("motd", Server.getInstance().getMotd());
out.addProperty("online-mode", false); //In MCPE we have permanent offline mode.
- out.addProperty("icon", ""); //"data:image/png;base64,"
+ out.addProperty("icon", ""); //"pos:image/png;base64,"
}
final Runtime runtime = Runtime.getRuntime();
@@ -195,7 +195,7 @@ public synchronized void start() {
@Override
public void run() {
this.sender.sendMessage(new TranslationContainer("nukkit.command.timings.uploadStart"));
- this.out.add("data", JsonUtil.mapToArray(this.history, TimingsHistory::export));
+ this.out.add("pos", JsonUtil.mapToArray(this.history, TimingsHistory::export));
String response = null;
try {
From 8aa47a7bfed8b2a361664eb9e06a263c1ccdec14 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Mon, 15 May 2017 15:29:01 +0200
Subject: [PATCH 002/175] recipes
---
.../java/cn/nukkit/inventory/CraftingManager.java | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/main/java/cn/nukkit/inventory/CraftingManager.java b/src/main/java/cn/nukkit/inventory/CraftingManager.java
index 5f91035d7d..dc3283f616 100644
--- a/src/main/java/cn/nukkit/inventory/CraftingManager.java
+++ b/src/main/java/cn/nukkit/inventory/CraftingManager.java
@@ -760,6 +760,12 @@ public CraftingManager() {
this.registerRecipe(new BigShapedRecipe(Item.get(Item.WOODEN_PRESSURE_PLATE, 0, 1),
"WW "
).setIngredient("W", Item.get(Item.PLANKS, i, 2)));
+
+ this.registerRecipe(new BigShapedRecipe(Item.get(Item.TRIPWIRE_HOOK, 0, 2),
+ " I ",
+ " S ",
+ " P "
+ ).setIngredient("P", Item.get(Item.PLANKS, i, 1)).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)));
}
this.registerRecipe(new BigShapedRecipe(Item.get(Item.STONE_PRESSURE_PLATE, 0, 1),
@@ -791,6 +797,12 @@ public CraftingManager() {
"TQT",
"SSS"
).setIngredient("Q", Item.get(Item.QUARTZ, 0, 1)).setIngredient("T", Item.get(Item.REDSTONE_TORCH, 0, 3)).setIngredient("S", Item.get(Item.STONE, 0, 3)));
+
+ this.registerRecipe(new BigShapedRecipe(Item.get(Item.HOPPER, 0, 1),
+ "I I",
+ "ICI",
+ " I "
+ ).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 5)).setIngredient("C", Item.get(Item.CHEST, 0, 1)));
}
protected void registerFurnace() {
From c80fc3fa4b5195c662cb3bce333425f3964bf89d Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Mon, 15 May 2017 19:34:23 +0200
Subject: [PATCH 003/175] its not necessary
---
src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java b/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java
index 38fc4cf846..9bdc5fd129 100644
--- a/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java
+++ b/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java
@@ -143,10 +143,10 @@ public HopperInventory getInventory() {
@Override
public boolean onUpdate() {
- if (!isBlockEntityValid()) {
- this.close();
+ if (this.closed) {
return false;
}
+
this.transferCooldown--;
if (!this.isOnTransferCooldown()) {
From 1bf48dbeb713d08be9a889f0ae547456bed00175 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Mon, 15 May 2017 20:39:54 +0200
Subject: [PATCH 004/175] Fixed cocoa beans
---
src/main/java/cn/nukkit/level/Level.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java
index 0057f581d4..d48cae40d2 100644
--- a/src/main/java/cn/nukkit/level/Level.java
+++ b/src/main/java/cn/nukkit/level/Level.java
@@ -216,6 +216,7 @@ public int size() {
put(Block.FIRE, BlockFire.class);
put(Block.GLOWING_REDSTONE_ORE, BlockOreRedstoneGlowing.class);
+ put(Block.COCOA_BLOCK, BlockCocoa.class);
}
};
From 7a5ceacadffdf15064d583ff5a865ada4d67453f Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Mon, 15 May 2017 21:06:35 +0200
Subject: [PATCH 005/175] Fixed growing
---
src/main/java/cn/nukkit/block/BlockCocoa.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/cn/nukkit/block/BlockCocoa.java b/src/main/java/cn/nukkit/block/BlockCocoa.java
index 5d3a583f3a..baddfe7134 100644
--- a/src/main/java/cn/nukkit/block/BlockCocoa.java
+++ b/src/main/java/cn/nukkit/block/BlockCocoa.java
@@ -126,7 +126,7 @@ public int onUpdate(int type) {
}
} else if (type == Level.BLOCK_UPDATE_RANDOM) {
if (new Random().nextInt(2) == 1) {
- if (this.meta <= 7) {
+ if (this.meta / 4 < 3) {
BlockCocoa block = (BlockCocoa) this.clone();
block.meta += 4;
BlockGrowEvent ev = new BlockGrowEvent(this, block);
From 8ca77b51437a22a9bc159158f17b253e7062834c Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Mon, 15 May 2017 21:36:40 +0200
Subject: [PATCH 006/175] blame refactor
---
src/main/java/cn/nukkit/Player.java | 2 +-
src/main/java/cn/nukkit/Server.java | 8 ++++----
src/main/java/cn/nukkit/block/BlockFlowerPot.java | 6 +++---
.../java/cn/nukkit/blockentity/BlockEntityFlowerPot.java | 8 ++++----
.../java/cn/nukkit/command/FormattedCommandAlias.java | 2 +-
.../java/cn/nukkit/command/defaults/ParticleCommand.java | 4 ++--
src/main/java/cn/nukkit/nbt/tag/ByteArrayTag.java | 2 +-
src/main/java/cn/nukkit/nbt/tag/ByteTag.java | 2 +-
src/main/java/cn/nukkit/nbt/tag/DoubleTag.java | 2 +-
src/main/java/cn/nukkit/nbt/tag/FloatTag.java | 2 +-
src/main/java/cn/nukkit/nbt/tag/IntTag.java | 2 +-
src/main/java/cn/nukkit/nbt/tag/LongTag.java | 2 +-
src/main/java/cn/nukkit/nbt/tag/StringTag.java | 2 +-
.../nukkit/network/protocol/AvailableCommandsPacket.java | 2 +-
src/main/java/cn/nukkit/network/rcon/RCONCommand.java | 2 +-
src/main/java/cn/nukkit/network/rcon/RCONPacket.java | 2 +-
src/main/java/cn/nukkit/plugin/Plugin.java | 2 +-
src/main/java/cn/nukkit/plugin/PluginBase.java | 2 +-
src/main/java/cn/nukkit/plugin/PluginLoader.java | 4 ++--
src/main/java/cn/nukkit/raknet/server/Session.java | 2 +-
src/main/java/co/aikar/timings/TimingsExport.java | 4 ++--
21 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 28d0cf2078..c2ef696260 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -1712,7 +1712,7 @@ protected void processLogin() {
CompoundTag nbt = this.server.getOfflinePlayerData(this.username);
if (nbt == null) {
- this.close(this.getLeaveMessage(), "Invalid pos");
+ this.close(this.getLeaveMessage(), "Invalid data");
return;
}
diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java
index ad57762522..fada945ec5 100644
--- a/src/main/java/cn/nukkit/Server.java
+++ b/src/main/java/cn/nukkit/Server.java
@@ -1398,10 +1398,10 @@ public CompoundTag getOfflinePlayerData(String name) {
return NBTIO.readCompressed(new FileInputStream(file));
} catch (Exception e) {
file.renameTo(new File(path + name + ".dat.bak"));
- this.logger.notice(this.getLanguage().translateString("nukkit.pos.playerCorrupted", name));
+ this.logger.notice(this.getLanguage().translateString("nukkit.data.playerCorrupted", name));
}
} else {
- this.logger.notice(this.getLanguage().translateString("nukkit.pos.playerNotFound", name));
+ this.logger.notice(this.getLanguage().translateString("nukkit.data.playerNotFound", name));
}
Position spawn = this.getDefaultLevel().getSafeSpawn();
@@ -1447,7 +1447,7 @@ public void saveOfflinePlayerData(String name, CompoundTag tag, boolean async) {
Utils.writeFile(this.getDataPath() + "players/" + name.toLowerCase() + ".dat", new ByteArrayInputStream(NBTIO.writeGZIPCompressed(tag, ByteOrder.BIG_ENDIAN)));
}
} catch (Exception e) {
- this.logger.critical(this.getLanguage().translateString("nukkit.pos.saveError", new String[]{name, e.getMessage()}));
+ this.logger.critical(this.getLanguage().translateString("nukkit.data.saveError", new String[]{name, e.getMessage()}));
if (Nukkit.DEBUG > 1) {
this.logger.logException(e);
}
@@ -1909,7 +1909,7 @@ public Map> getCommandAliases() {
}
public boolean shouldSavePlayerData() {
- return (Boolean) this.getConfig("player.save-player-pos", true);
+ return (Boolean) this.getConfig("player.save-player-data", true);
}
/**
diff --git a/src/main/java/cn/nukkit/block/BlockFlowerPot.java b/src/main/java/cn/nukkit/block/BlockFlowerPot.java
index ebf65fccdb..7e3139801a 100644
--- a/src/main/java/cn/nukkit/block/BlockFlowerPot.java
+++ b/src/main/java/cn/nukkit/block/BlockFlowerPot.java
@@ -70,7 +70,7 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl
.putInt("y", (int) this.y)
.putInt("z", (int) this.z)
.putShort("item", 0)
- .putInt("pos", 0);
+ .putInt("data", 0);
if (item.hasCustomBlockData()) {
for (Tag aTag : item.getCustomBlockData().getAllTags()) {
nbt.put(aTag.getName(), aTag);
@@ -110,7 +110,7 @@ public boolean onActivate(Item item, Player player) {
itemMeta = item.getDamage();
}
blockEntity.namedTag.putShort("item", itemID);
- blockEntity.namedTag.putInt("pos", itemMeta);
+ blockEntity.namedTag.putInt("data", itemMeta);
this.meta = 1;
this.getLevel().setBlock(this, this, true);
@@ -132,7 +132,7 @@ public int[][] getDrops(Item item) {
if (blockEntity instanceof BlockEntityFlowerPot) {
dropInside = true;
insideID = blockEntity.namedTag.getShort("item");
- insideMeta = blockEntity.namedTag.getInt("pos");
+ insideMeta = blockEntity.namedTag.getInt("data");
}
if (dropInside) {
diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityFlowerPot.java b/src/main/java/cn/nukkit/blockentity/BlockEntityFlowerPot.java
index e290bca4db..71ebebb5ca 100644
--- a/src/main/java/cn/nukkit/blockentity/BlockEntityFlowerPot.java
+++ b/src/main/java/cn/nukkit/blockentity/BlockEntityFlowerPot.java
@@ -15,12 +15,12 @@ public BlockEntityFlowerPot(FullChunk chunk, CompoundTag nbt) {
nbt.putShort("item", 0);
}
- if (!nbt.contains("pos")) {
+ if (!nbt.contains("data")) {
if (nbt.contains("mData")) {
- nbt.putInt("pos", nbt.getInt("mData"));
+ nbt.putInt("data", nbt.getInt("mData"));
nbt.remove("mData");
} else {
- nbt.putInt("pos", 0);
+ nbt.putInt("data", 0);
}
}
@@ -41,7 +41,7 @@ public CompoundTag getSpawnCompound() {
.putInt("y", (int) this.y)
.putInt("z", (int) this.z)
.putShort("item", this.namedTag.getShort("item"))
- .putInt("mData", this.namedTag.getInt("pos"));
+ .putInt("mData", this.namedTag.getInt("data"));
}
}
diff --git a/src/main/java/cn/nukkit/command/FormattedCommandAlias.java b/src/main/java/cn/nukkit/command/FormattedCommandAlias.java
index 62c122d24c..d2d2ab18e1 100644
--- a/src/main/java/cn/nukkit/command/FormattedCommandAlias.java
+++ b/src/main/java/cn/nukkit/command/FormattedCommandAlias.java
@@ -121,7 +121,7 @@ private String buildCommand(String formatString, String[] args) {
}
formatString = formatString.substring(0, start) + replacement.toString() + formatString.substring(end);
- // Move index past the replaced pos so we don't process it again
+ // Move index past the replaced data so we don't process it again
index = start + replacement.length();
// Move to the next replacement token
diff --git a/src/main/java/cn/nukkit/command/defaults/ParticleCommand.java b/src/main/java/cn/nukkit/command/defaults/ParticleCommand.java
index c1d7996d46..2e9b4ee6c7 100644
--- a/src/main/java/cn/nukkit/command/defaults/ParticleCommand.java
+++ b/src/main/java/cn/nukkit/command/defaults/ParticleCommand.java
@@ -21,7 +21,7 @@ public class ParticleCommand extends VanillaCommand {
public ParticleCommand(String name) {
super(name, "%nukkit.command.particle.description", "%nukkit.command.particle.usage");
this.setPermission("nukkit.command.particle");
- // [count] [pos]
+ // [count] [data]
this.commandParameters.clear();
this.commandParameters.put("default", new CommandParameter[]{
new CommandParameter("player", CommandParameter.ARG_TYPE_TARGET, false),
@@ -32,7 +32,7 @@ public ParticleCommand(String name) {
new CommandParameter("yd", CommandParameter.ARG_TYPE_STRING, false),
new CommandParameter("zd", CommandParameter.ARG_TYPE_STRING, false),
new CommandParameter("count", CommandParameter.ARG_TYPE_INT, true),
- new CommandParameter("pos", true)
+ new CommandParameter("data", true)
});
}
diff --git a/src/main/java/cn/nukkit/nbt/tag/ByteArrayTag.java b/src/main/java/cn/nukkit/nbt/tag/ByteArrayTag.java
index ca9f3cbf87..874de1ba8b 100644
--- a/src/main/java/cn/nukkit/nbt/tag/ByteArrayTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/ByteArrayTag.java
@@ -43,7 +43,7 @@ public byte getId() {
@Override
public String toString() {
- return "ByteArrayTag " + this.getName() + " (pos: 0x" + Binary.bytesToHexString(data, true) + " [" + data.length + " bytes])";
+ return "ByteArrayTag " + this.getName() + " (data: 0x" + Binary.bytesToHexString(data, true) + " [" + data.length + " bytes])";
}
@Override
diff --git a/src/main/java/cn/nukkit/nbt/tag/ByteTag.java b/src/main/java/cn/nukkit/nbt/tag/ByteTag.java
index a65d546175..d9cadc5a4d 100644
--- a/src/main/java/cn/nukkit/nbt/tag/ByteTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/ByteTag.java
@@ -48,7 +48,7 @@ public String toString() {
if (hex.length() < 2) {
hex = "0" + hex;
}
- return "ByteTag " + this.getName() + " (pos: 0x" + hex + ")";
+ return "ByteTag " + this.getName() + " (data: 0x" + hex + ")";
}
@Override
diff --git a/src/main/java/cn/nukkit/nbt/tag/DoubleTag.java b/src/main/java/cn/nukkit/nbt/tag/DoubleTag.java
index 76a0dd859d..4a04f825c4 100644
--- a/src/main/java/cn/nukkit/nbt/tag/DoubleTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/DoubleTag.java
@@ -44,7 +44,7 @@ public byte getId() {
@Override
public String toString() {
- return "DoubleTag " + this.getName() + " (pos: " + data + ")";
+ return "DoubleTag " + this.getName() + " (data: " + data + ")";
}
@Override
diff --git a/src/main/java/cn/nukkit/nbt/tag/FloatTag.java b/src/main/java/cn/nukkit/nbt/tag/FloatTag.java
index f77fa199f2..b290853ad3 100644
--- a/src/main/java/cn/nukkit/nbt/tag/FloatTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/FloatTag.java
@@ -44,7 +44,7 @@ public byte getId() {
@Override
public String toString() {
- return "FloatTag " + this.getName() + " (pos: " + data + ")";
+ return "FloatTag " + this.getName() + " (data: " + data + ")";
}
@Override
diff --git a/src/main/java/cn/nukkit/nbt/tag/IntTag.java b/src/main/java/cn/nukkit/nbt/tag/IntTag.java
index 31ebd903b1..7f308d3ac9 100644
--- a/src/main/java/cn/nukkit/nbt/tag/IntTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/IntTag.java
@@ -44,7 +44,7 @@ public byte getId() {
@Override
public String toString() {
- return "IntTag" + this.getName() + "(pos: " + data + ")";
+ return "IntTag" + this.getName() + "(data: " + data + ")";
}
@Override
diff --git a/src/main/java/cn/nukkit/nbt/tag/LongTag.java b/src/main/java/cn/nukkit/nbt/tag/LongTag.java
index ad75427acd..54793dc528 100644
--- a/src/main/java/cn/nukkit/nbt/tag/LongTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/LongTag.java
@@ -44,7 +44,7 @@ public byte getId() {
@Override
public String toString() {
- return "LongTag" + this.getName() + " (pos:" + data + ")";
+ return "LongTag" + this.getName() + " (data:" + data + ")";
}
@Override
diff --git a/src/main/java/cn/nukkit/nbt/tag/StringTag.java b/src/main/java/cn/nukkit/nbt/tag/StringTag.java
index 882c2431e3..118f72be0a 100644
--- a/src/main/java/cn/nukkit/nbt/tag/StringTag.java
+++ b/src/main/java/cn/nukkit/nbt/tag/StringTag.java
@@ -35,7 +35,7 @@ public byte getId() {
@Override
public String toString() {
- return "StringTag " + this.getName() + " (pos: " + data + ")";
+ return "StringTag " + this.getName() + " (data: " + data + ")";
}
@Override
diff --git a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java
index c2b73359c0..4719a2ff05 100644
--- a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java
@@ -7,7 +7,7 @@
public class AvailableCommandsPacket extends DataPacket {
public static final byte NETWORK_ID = ProtocolInfo.AVAILABLE_COMMANDS_PACKET;
- public String commands; //JSON-encoded command pos
+ public String commands; //JSON-encoded command data
public String unknown = "";
@Override
diff --git a/src/main/java/cn/nukkit/network/rcon/RCONCommand.java b/src/main/java/cn/nukkit/network/rcon/RCONCommand.java
index 5be499bb9d..a992cd35c2 100644
--- a/src/main/java/cn/nukkit/network/rcon/RCONCommand.java
+++ b/src/main/java/cn/nukkit/network/rcon/RCONCommand.java
@@ -3,7 +3,7 @@
import java.nio.channels.SocketChannel;
/**
- * A pos structure to hold sender, request ID and command itself.
+ * A data structure to hold sender, request ID and command itself.
*
* @author Tee7even
*/
diff --git a/src/main/java/cn/nukkit/network/rcon/RCONPacket.java b/src/main/java/cn/nukkit/network/rcon/RCONPacket.java
index 71baedc169..afa057c275 100644
--- a/src/main/java/cn/nukkit/network/rcon/RCONPacket.java
+++ b/src/main/java/cn/nukkit/network/rcon/RCONPacket.java
@@ -5,7 +5,7 @@
import java.nio.ByteOrder;
/**
- * A pos structure representing an RCON packet.
+ * A data structure representing an RCON packet.
*
* @author Tee7even
*/
diff --git a/src/main/java/cn/nukkit/plugin/Plugin.java b/src/main/java/cn/nukkit/plugin/Plugin.java
index 3ef05d944b..83b1cea80a 100644
--- a/src/main/java/cn/nukkit/plugin/Plugin.java
+++ b/src/main/java/cn/nukkit/plugin/Plugin.java
@@ -207,7 +207,7 @@ public interface Plugin extends CommandExecutor {
* 执行这个函数时,Nukkit会在资源文件夹内寻找开发者配置好的默认配置文件config.yml,然后保存在数据文件夹。
* 如果数据文件夹已经有一个config.yml文件,Nukkit不会替换这个文件。
* When this is used, Nukkit will look for the default 'config.yml' file which is configured by plugin developer
- * and save it to the pos folder. If a config.yml file exists in the pos folder, Nukkit won't replace it.
+ * and save it to the data folder. If a config.yml file exists in the data folder, Nukkit won't replace it.
*
*
这个函数通常用来在插件被加载(load)时,保存默认的配置文件。这样插件在启用(enable)时不会错误读取空的配置文件,
* 用户也无需从开发者处手动下载配置文件保存后再使用插件。
diff --git a/src/main/java/cn/nukkit/plugin/PluginBase.java b/src/main/java/cn/nukkit/plugin/PluginBase.java
index 11e3c4a852..bcd042f2e0 100644
--- a/src/main/java/cn/nukkit/plugin/PluginBase.java
+++ b/src/main/java/cn/nukkit/plugin/PluginBase.java
@@ -119,7 +119,7 @@ public final PluginDescription getDescription() {
* @param description 描述这个插件的{@code PluginDescription}对象。
* A {@code PluginDescription} object that describes this plugin.
* @param dataFolder 这个插件的数据的文件夹。
- * The pos folder of this plugin.
+ * The data folder of this plugin.
* @param file 这个插件的文件{@code File}对象。对于jar格式的插件,就是jar文件本身。
* The {@code File} object of this plugin itself. For jar-packed plugins, it is the jar file itself.
* @since Nukkit 1.0 | Nukkit API 1.0.0
diff --git a/src/main/java/cn/nukkit/plugin/PluginLoader.java b/src/main/java/cn/nukkit/plugin/PluginLoader.java
index 2a39bb1a42..1ca2a740b9 100644
--- a/src/main/java/cn/nukkit/plugin/PluginLoader.java
+++ b/src/main/java/cn/nukkit/plugin/PluginLoader.java
@@ -21,7 +21,7 @@ public interface PluginLoader {
*
这个方法应该设置好插件的相关属性。比如,插件所在的服务器对象,插件的加载器对象,插件的描述对象,插件的数据文件夹。
* Properties for loaded plugin should be set in this method. Such as, the {@code Server} object for which this
* plugin is running in, the {@code PluginLoader} object for its loader, and the {@code File} object for its
- * pos folder.
+ * data folder.
*
*
如果插件加载失败,这个方法应该返回{@code null},或者抛出异常。
* If the plugin loader does not load this plugin successfully, a {@code null} should be returned,
@@ -43,7 +43,7 @@ public interface PluginLoader {
*
这个方法应该设置好插件的相关属性。比如,插件所在的服务器对象,插件的加载器对象,插件的描述对象,插件的数据文件夹。
* Properties for loaded plugin should be set in this method. Such as, the {@code Server} object for which this
* plugin is running in, the {@code PluginLoader} object for its loader, and the {@code File} object for its
- * pos folder.
+ * data folder.
*
*
如果插件加载失败,这个方法应该返回{@code null},或者抛出异常。
* If the plugin loader does not load this plugin successfully, a {@code null} should be returned,
diff --git a/src/main/java/cn/nukkit/raknet/server/Session.java b/src/main/java/cn/nukkit/raknet/server/Session.java
index 6e06268a58..ad59375ff5 100644
--- a/src/main/java/cn/nukkit/raknet/server/Session.java
+++ b/src/main/java/cn/nukkit/raknet/server/Session.java
@@ -379,7 +379,7 @@ private void handleEncapsulatedPacketRoute(EncapsulatedPacket packet) throws Exc
}
byte id = packet.buffer[0];
- if ((id & 0xff) < 0x80) { //internal pos packet
+ if ((id & 0xff) < 0x80) { //internal data packet
if (state == STATE_CONNECTING_2) {
if (id == CLIENT_CONNECT_DataPacket.ID) {
CLIENT_CONNECT_DataPacket dataPacket = new CLIENT_CONNECT_DataPacket();
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
index a6f919e957..b0c191969b 100644
--- a/src/main/java/co/aikar/timings/TimingsExport.java
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
@@ -75,7 +75,7 @@ public static void reportTimings(CommandSender sender) {
out.addProperty("server", Server.getInstance().getName());
out.addProperty("motd", Server.getInstance().getMotd());
out.addProperty("online-mode", false); //In MCPE we have permanent offline mode.
- out.addProperty("icon", ""); //"pos:image/png;base64,"
+ out.addProperty("icon", ""); //"data:image/png;base64,"
}
final Runtime runtime = Runtime.getRuntime();
@@ -195,7 +195,7 @@ public synchronized void start() {
@Override
public void run() {
this.sender.sendMessage(new TranslationContainer("nukkit.command.timings.uploadStart"));
- this.out.add("pos", JsonUtil.mapToArray(this.history, TimingsHistory::export));
+ this.out.add("data", JsonUtil.mapToArray(this.history, TimingsHistory::export));
String response = null;
try {
From 96e1a69dd0de2333180e71ca6fb9ccebc2b4a939 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Tue, 16 May 2017 13:25:38 +0200
Subject: [PATCH 007/175] Ops
---
src/main/java/cn/nukkit/block/BlockCocoa.java | 31 ++++++++++++++-
src/main/java/cn/nukkit/block/BlockCrops.java | 24 +++++++-----
.../java/cn/nukkit/block/BlockSugarcane.java | 38 +++++++++++--------
3 files changed, 66 insertions(+), 27 deletions(-)
diff --git a/src/main/java/cn/nukkit/block/BlockCocoa.java b/src/main/java/cn/nukkit/block/BlockCocoa.java
index baddfe7134..bf89c0684b 100644
--- a/src/main/java/cn/nukkit/block/BlockCocoa.java
+++ b/src/main/java/cn/nukkit/block/BlockCocoa.java
@@ -6,6 +6,7 @@
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemTool;
import cn.nukkit.level.Level;
+import cn.nukkit.level.particle.BoneMealParticle;
import cn.nukkit.math.AxisAlignedBB;
import cn.nukkit.math.BlockFace;
@@ -126,7 +127,7 @@ public int onUpdate(int type) {
}
} else if (type == Level.BLOCK_UPDATE_RANDOM) {
if (new Random().nextInt(2) == 1) {
- if (this.meta / 4 < 3) {
+ if (this.meta / 4 < 2) {
BlockCocoa block = (BlockCocoa) this.clone();
block.meta += 4;
BlockGrowEvent ev = new BlockGrowEvent(this, block);
@@ -146,6 +147,34 @@ public int onUpdate(int type) {
return 0;
}
+ @Override
+ public boolean canBeActivated() {
+ return true;
+ }
+
+ @Override
+ public boolean onActivate(Item item, Player player) {
+ if (item.getId() == Item.DYE && item.getDamage() == 0x0f) {
+ Block block = this.clone();
+ if (this.meta / 4 < 2) {
+ block.meta += 4;
+ BlockGrowEvent ev = new BlockGrowEvent(this, block);
+ Server.getInstance().getPluginManager().callEvent(ev);
+
+ if (ev.isCancelled()) {
+ return false;
+ }
+ this.getLevel().setBlock(this, ev.getNewState(), true, true);
+ }
+
+ this.level.addParticle(new BoneMealParticle(this.add(0.5, 0.5, 0.5)));
+ item.count--;
+ return true;
+ }
+
+ return false;
+ }
+
@Override
public double getResistance() {
return 15;
diff --git a/src/main/java/cn/nukkit/block/BlockCrops.java b/src/main/java/cn/nukkit/block/BlockCrops.java
index d3075e8d17..4d75fd0e29 100644
--- a/src/main/java/cn/nukkit/block/BlockCrops.java
+++ b/src/main/java/cn/nukkit/block/BlockCrops.java
@@ -5,6 +5,7 @@
import cn.nukkit.event.block.BlockGrowEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
+import cn.nukkit.level.particle.BoneMealParticle;
import cn.nukkit.math.BlockFace;
import cn.nukkit.utils.BlockColor;
@@ -50,20 +51,23 @@ public boolean onActivate(Item item, Player player) {
//Bone meal
if (item.getId() == Item.DYE && item.getDamage() == 0x0f) {
BlockCrops block = (BlockCrops) this.clone();
- block.meta += new Random().nextInt(3) + 2;
- if (block.meta > 7) {
- block.meta = 7;
- }
- BlockGrowEvent ev = new BlockGrowEvent(this, block);
- Server.getInstance().getPluginManager().callEvent(ev);
+ if (this.meta < 7) {
+ block.meta += new Random().nextInt(3) + 2;
+ if (block.meta > 7) {
+ block.meta = 7;
+ }
+ BlockGrowEvent ev = new BlockGrowEvent(this, block);
+ Server.getInstance().getPluginManager().callEvent(ev);
- if (ev.isCancelled()) {
- return false;
+ if (ev.isCancelled()) {
+ return false;
+ }
+
+ this.getLevel().setBlock(this, ev.getNewState(), true, true);
}
- this.getLevel().setBlock(this, ev.getNewState(), true, true);
+ this.level.addParticle(new BoneMealParticle(this.add(0.5, 0.5, 0.5)));
item.count--;
-
return true;
}
diff --git a/src/main/java/cn/nukkit/block/BlockSugarcane.java b/src/main/java/cn/nukkit/block/BlockSugarcane.java
index f89f6100eb..b2a0869cd0 100644
--- a/src/main/java/cn/nukkit/block/BlockSugarcane.java
+++ b/src/main/java/cn/nukkit/block/BlockSugarcane.java
@@ -5,6 +5,7 @@
import cn.nukkit.event.block.BlockGrowEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
+import cn.nukkit.level.particle.BoneMealParticle;
import cn.nukkit.math.BlockFace;
import cn.nukkit.math.Vector3;
import cn.nukkit.utils.BlockColor;
@@ -47,33 +48,38 @@ public boolean canBeActivated() {
@Override
public boolean onActivate(Item item, Player player) {
if (item.getId() == Item.DYE && item.getDamage() == 0x0F) { //Bonemeal
- Block base = this;
- // As sugarcane only grows to a height of three activating the
- // lowest or middle block should cause growing. Here we drop
- // down one if it's not already the base.
- Block down = base.down();
- if (down.getId() == SUGARCANE_BLOCK) {
- base = down;
+ int count = 1;
+
+ for (int i = 1; i <= 2; i++) {
+ int id = this.level.getBlockIdAt(this.getFloorX(), this.getFloorY() - i, this.getFloorZ());
+
+ if (id == SUGARCANE_BLOCK) {
+ count++;
+ }
}
- if (down.getId() != SUGARCANE_BLOCK) {
- for (int y = 1; y < 3; ++y) {
- Block b = base.getLevel().getBlock(new Vector3(base.x, base.y + y, base.z));
- if (b.getId() == AIR) {
- BlockGrowEvent ev = new BlockGrowEvent(b, new BlockSugarcane());
+
+ if (count < 3) {
+ int toGrow = 3 - count;
+
+ for (int i = 1; i <= toGrow; i++) {
+ Block block = this.up(i);
+ if (block.getId() == 0) {
+ BlockGrowEvent ev = new BlockGrowEvent(block, new BlockSugarcane());
Server.getInstance().getPluginManager().callEvent(ev);
+
if (!ev.isCancelled()) {
- this.getLevel().setBlock(b, ev.getNewState(), true);
+ this.getLevel().setBlock(block, ev.getNewState(), true);
}
- } else if (b.getId() != SUGARCANE_BLOCK) {
+ } else if (block.getId() != SUGARCANE_BLOCK) {
break;
}
}
- base.meta = 0;
- base.getLevel().setBlock(base, base, true);
}
+
if ((player.gamemode & 0x01) == 0) {
item.count--;
}
+ this.level.addParticle(new BoneMealParticle(this.add(0.5, 0.5, 0.5)));
return true;
}
return false;
From 21b5de70a2f69993c5edfcb36c220305258caefd Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Tue, 16 May 2017 15:19:16 +0200
Subject: [PATCH 008/175] Fixed some player IDs
---
src/main/java/cn/nukkit/Player.java | 2 +-
src/main/java/cn/nukkit/entity/Entity.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index c2ef696260..ca3908dea2 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -2833,7 +2833,7 @@ public void handleDataPacket(DataPacket packet) {
pk = new SetEntityLinkPacket();
pk.rider = targetEntity.getId();
- pk.riding = 0;
+ pk.riding = this.getId();
pk.type = 3;
dataPacket(pk);
diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java
index c4030dfd9c..dd5a2e8917 100644
--- a/src/main/java/cn/nukkit/entity/Entity.java
+++ b/src/main/java/cn/nukkit/entity/Entity.java
@@ -732,7 +732,7 @@ public void sendData(Player player) {
public void sendData(Player player, EntityMetadata data) {
SetEntityDataPacket pk = new SetEntityDataPacket();
- pk.eid = player == this ? 0 : this.getId();
+ pk.eid = this.getId();
pk.metadata = data == null ? this.dataProperties : data;
player.dataPacket(pk);
From 1939ca93dc59e4b26e7b7e831fa8c45ccbe90e06 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Wed, 17 May 2017 18:45:31 +0200
Subject: [PATCH 009/175] Fixed chunk loading, getSafeSpawn()
---
src/main/java/cn/nukkit/Player.java | 9 +++------
src/main/java/cn/nukkit/level/Level.java | 2 +-
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index ca3908dea2..735a84f98f 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -4344,7 +4344,6 @@ protected boolean checkTeleportPosition() {
}
}
- this.sendPosition(this, this.yaw, this.pitch, MovePlayerPacket.MODE_RESET);
this.spawnToAll();
this.forceMovement = this.teleportPosition;
this.teleportPosition = null;
@@ -4382,12 +4381,10 @@ public boolean teleport(Location location, TeleportCause cause) {
}
this.teleportPosition = new Vector3(this.x, this.y, this.z);
+ this.forceMovement = this.teleportPosition;
+ this.sendPosition(this, this.yaw, this.pitch, MovePlayerPacket.MODE_RESET);
- if (!this.checkTeleportPosition()) {
- this.forceMovement = oldPos;
- } else {
- this.spawnToAll();
- }
+ this.checkTeleportPosition();
this.resetFallDistance();
this.nextChunkOrderRun = 0;
diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java
index d48cae40d2..75da5474f7 100644
--- a/src/main/java/cn/nukkit/level/Level.java
+++ b/src/main/java/cn/nukkit/level/Level.java
@@ -2705,7 +2705,7 @@ public Position getSafeSpawn(Vector3 spawn) {
int x = (int) v.x & 0x0f;
int z = (int) v.z & 0x0f;
if (chunk != null) {
- int y = (int) Math.min(126, v.y);
+ int y = (int) Math.min(254, v.y);
boolean wasAir = chunk.getBlockId(x, y - 1, z) == 0;
for (; y > 0; --y) {
int b = chunk.getFullBlock(x, y, z);
From 9dcc443d46b6b631461702db7da8e3b3be883e57 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Fri, 19 May 2017 13:32:27 +0200
Subject: [PATCH 010/175] Players shouldn't pass through carpets
---
src/main/java/cn/nukkit/block/BlockCarpet.java | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/main/java/cn/nukkit/block/BlockCarpet.java b/src/main/java/cn/nukkit/block/BlockCarpet.java
index 6776b78804..a423b32ee4 100644
--- a/src/main/java/cn/nukkit/block/BlockCarpet.java
+++ b/src/main/java/cn/nukkit/block/BlockCarpet.java
@@ -50,6 +50,11 @@ public String getName() {
return DyeColor.getByWoolData(meta) + " Carpet";
}
+ @Override
+ public boolean canPassThrough() {
+ return false;
+ }
+
@Override
protected AxisAlignedBB recalculateBoundingBox() {
From c4c8c8c49ff57f08f454944f869e733a09208c26 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Sat, 20 May 2017 06:34:10 +0200
Subject: [PATCH 011/175] remove debug
---
src/main/java/cn/nukkit/block/BlockMushroomRed.java | 2 --
src/main/java/cn/nukkit/block/BlockPressurePlateBase.java | 1 -
2 files changed, 3 deletions(-)
diff --git a/src/main/java/cn/nukkit/block/BlockMushroomRed.java b/src/main/java/cn/nukkit/block/BlockMushroomRed.java
index bfc985c081..dea9c6a0dc 100644
--- a/src/main/java/cn/nukkit/block/BlockMushroomRed.java
+++ b/src/main/java/cn/nukkit/block/BlockMushroomRed.java
@@ -47,8 +47,6 @@ public int onUpdate(int type) {
@Override
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
- System.out.println("light: " + this.level.getFullLight(this));
-
if (canStay()) {
getLevel().setBlock(block, this, true, true);
return true;
diff --git a/src/main/java/cn/nukkit/block/BlockPressurePlateBase.java b/src/main/java/cn/nukkit/block/BlockPressurePlateBase.java
index adb04e65c7..f36f52ac10 100644
--- a/src/main/java/cn/nukkit/block/BlockPressurePlateBase.java
+++ b/src/main/java/cn/nukkit/block/BlockPressurePlateBase.java
@@ -67,7 +67,6 @@ public int onUpdate(int type) {
@Override
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz) {
- System.out.println("place");
if (block.down().isTransparent()) {
return false;
}
From 18221f780bca9ab12827d3cb381869525b410be3 Mon Sep 17 00:00:00 2001
From: Lin Mulan
Date: Tue, 11 Jul 2017 21:11:17 +0800
Subject: [PATCH 012/175] Reduce memory usage, phase 2 (Zlib) (#1790)
* Small improvement for Zlib
* Rearrange
* Test class for Zlib
---
src/main/java/cn/nukkit/utils/Zlib.java | 53 +++++++++++---------
src/test/java/cn/nukkit/test/VarIntTest.java | 8 +--
src/test/java/cn/nukkit/test/ZlibTest.java | 23 +++++++++
3 files changed, 58 insertions(+), 26 deletions(-)
create mode 100644 src/test/java/cn/nukkit/test/ZlibTest.java
diff --git a/src/main/java/cn/nukkit/utils/Zlib.java b/src/main/java/cn/nukkit/utils/Zlib.java
index 7ec14f26fb..fbf69bcb18 100644
--- a/src/main/java/cn/nukkit/utils/Zlib.java
+++ b/src/main/java/cn/nukkit/utils/Zlib.java
@@ -9,56 +9,63 @@
public abstract class Zlib {
-
+
public static byte[] deflate(byte[] data) throws Exception {
return deflate(data, Deflater.DEFAULT_COMPRESSION);
}
public static byte[] deflate(byte[] data, int level) throws Exception {
- Deflater deflater = new Deflater(level);
+ Deflater deflater = getDef(level);
+ if(deflater == null) throw new IllegalArgumentException("No deflate for level "+level+" !");
deflater.reset();
deflater.setInput(data);
deflater.finish();
ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
- byte[] buf = new byte[1024];
- try {
- while (!deflater.finished()) {
- int i = deflater.deflate(buf);
- bos.write(buf, 0, i);
- }
- } finally {
- deflater.end();
+ while (!deflater.finished()) {
+ int i = deflater.deflate(buf.get());
+ bos.write(buf.get(), 0, i);
}
+ //Deflater::end is called the time when the process exits.
return bos.toByteArray();
}
- public static byte[] inflate(InputStream stream) throws IOException {
+ public static byte[] inflate(byte[] data) throws IOException {
+ return inflate(new ByteArrayInputStream(data));
+ }
+
+ public static byte[] inflate(byte[] data, int maxSize) throws IOException {
+ return inflate(new ByteArrayInputStream(data, 0, maxSize));
+ }
+
+ /* -=-=-=-=-=- Internal -=-=-=-=-=- Do NOT attempt to use in production -=-=-=-=-=- */
+
+ private static final ThreadLocal buf = ThreadLocal.withInitial(() -> new byte[1024]);
+ private static final ThreadLocal def = ThreadLocal.withInitial(Deflater::new);
+
+ private static Deflater getDef(int level) {
+ def.get().setLevel(level);
+ return def.get();
+ }
+
+ private static byte[] inflate(InputStream stream) throws IOException {
InflaterInputStream inputStream = new InflaterInputStream(stream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
int length;
try {
- while ((length = inputStream.read(buffer)) != -1) {
- outputStream.write(buffer, 0, length);
+ while ((length = inputStream.read(buf.get())) != -1) {
+ outputStream.write(buf.get(), 0, length);
}
} finally {
- buffer = outputStream.toByteArray();
+ buf.set(outputStream.toByteArray());
outputStream.flush();
outputStream.close();
inputStream.close();
}
- return buffer;
+ return buf.get();
}
- public static byte[] inflate(byte[] data) throws IOException {
- return inflate(new ByteArrayInputStream(data));
- }
-
- public static byte[] inflate(byte[] data, int maxSize) throws IOException {
- return inflate(new ByteArrayInputStream(data, 0, maxSize));
- }
}
diff --git a/src/test/java/cn/nukkit/test/VarIntTest.java b/src/test/java/cn/nukkit/test/VarIntTest.java
index a67a4f2cc8..12fc9db37f 100644
--- a/src/test/java/cn/nukkit/test/VarIntTest.java
+++ b/src/test/java/cn/nukkit/test/VarIntTest.java
@@ -5,10 +5,12 @@
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
-import java.io.*;
-import java.math.BigInteger;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* By lmlstarqaq http://snake1999.com/
diff --git a/src/test/java/cn/nukkit/test/ZlibTest.java b/src/test/java/cn/nukkit/test/ZlibTest.java
new file mode 100644
index 0000000000..fd372776a8
--- /dev/null
+++ b/src/test/java/cn/nukkit/test/ZlibTest.java
@@ -0,0 +1,23 @@
+package cn.nukkit.test;
+
+import cn.nukkit.utils.Zlib;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@DisplayName("Zlib")
+class ZlibTest {
+
+ @DisplayName("Inflate and Deflate")
+ @Test
+ void testAll() throws Exception {
+ byte[] in = "lmlstarqaq".getBytes();
+ byte[] compressed = Zlib.deflate(in);
+ byte[] out = Zlib.inflate(compressed);
+ assertTrue(Arrays.equals(in, out));
+ }
+
+}
From 611f3aeb0bed744d2d4d583594ef3733a109e602 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Wed, 12 Jul 2017 14:42:04 +0200
Subject: [PATCH 013/175] Some vanilla features (eating, breaking sounds)
---
src/main/java/cn/nukkit/Player.java | 100 ++++++++++++------
src/main/java/cn/nukkit/block/Block.java | 24 +++--
.../java/cn/nukkit/block/BlockEndStone.java | 2 +-
.../network/protocol/EntityEventPacket.java | 10 +-
4 files changed, 91 insertions(+), 45 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index ee5bd60006..c75430145b 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -203,6 +203,8 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
private ClientChainData loginChainData;
+ public Block breakingBlock = null;
+
public BlockEnderChest getViewingEnderChest() {
return viewingEnderChest;
}
@@ -505,7 +507,8 @@ public void run() {
sendCommandData();
return;
}
- } catch (InterruptedException e) {}
+ } catch (InterruptedException e) {
+ }
}
};
t.start();
@@ -1065,14 +1068,12 @@ public int getGamemode() {
}
/**
- *
* Returns a client-friendly gamemode of the specified real gamemode
* This function takes care of handling gamemodes known to MCPE (as of 1.1.0.3, that includes Survival, Creative and Adventure)
- *
+ *
* TODO: remove this when Spectator Mode gets added properly to MCPE
- *
*/
- private static int getClientFriendlyGamemode(int gamemode){
+ private static int getClientFriendlyGamemode(int gamemode) {
gamemode &= 0x03;
if (gamemode == Player.SPECTATOR) {
return Player.CREATIVE;
@@ -2476,7 +2477,7 @@ public void handleDataPacket(DataPacket packet) {
switch (playerActionPacket.action) {
case PlayerActionPacket.ACTION_START_BREAK:
- if (this.lastBreak != Long.MAX_VALUE || pos.distanceSquared(this) > 10000) {
+ if (this.lastBreak != Long.MAX_VALUE || pos.distanceSquared(this) > 100) {
break;
}
Block target = this.level.getBlock(pos);
@@ -2487,7 +2488,7 @@ public void handleDataPacket(DataPacket packet) {
break;
}
if (target.getId() == Block.NOTEBLOCK) {
- ((BlockNoteblock)target).emitSound();
+ ((BlockNoteblock) target).emitSound();
break;
}
Block block = target.getSide(face);
@@ -2495,36 +2496,38 @@ public void handleDataPacket(DataPacket packet) {
this.level.setBlock(block, new BlockAir(), true);
break;
}
- if(!this.isCreative()){
+ if (!this.isCreative()) {
//improved this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211)
//Done by lmlstarqaq
double breakTime = Math.ceil(target.getBreakTime(this.inventory.getItemInHand(), this) * 20);
if (breakTime > 0) {
LevelEventPacket pk = new LevelEventPacket();
pk.evid = LevelEventPacket.EVENT_BLOCK_START_BREAK;
- pk.x = (float)pos.x;
- pk.y = (float)pos.y;
- pk.z = (float)pos.z;
- pk.data = (int)(65535 / breakTime);
+ pk.x = (float) pos.x;
+ pk.y = (float) pos.y;
+ pk.z = (float) pos.z;
+ pk.data = (int) (65535 / breakTime);
this.getLevel().addChunkPacket(pos.getFloorX() >> 4, pos.getFloorZ() >> 4, pk);
}
}
+
+ this.breakingBlock = target;
this.lastBreak = System.currentTimeMillis();
break;
case PlayerActionPacket.ACTION_ABORT_BREAK:
this.lastBreak = Long.MAX_VALUE;
-
+ this.breakingBlock = null;
case PlayerActionPacket.ACTION_STOP_BREAK:
LevelEventPacket pk = new LevelEventPacket();
pk.evid = LevelEventPacket.EVENT_BLOCK_STOP_BREAK;
- pk.x = (float)pos.x;
- pk.y = (float)pos.y;
- pk.z = (float)pos.z;
+ pk.x = (float) pos.x;
+ pk.y = (float) pos.y;
+ pk.z = (float) pos.z;
pk.data = 0;
this.getLevel().addChunkPacket(pos.getFloorX() >> 4, pos.getFloorZ() >> 4, pk);
+ this.breakingBlock = null;
break;
-
case PlayerActionPacket.ACTION_RELEASE_ITEM:
if (this.startAction > -1 && this.getDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION)) {
if (this.inventory.getItemInHand().getId() == Item.BOW) {
@@ -2734,8 +2737,10 @@ public void handleDataPacket(DataPacket packet) {
case PlayerActionPacket.ACTION_WORLD_IMMUTABLE:
break; //TODO
case PlayerActionPacket.ACTION_CONTINUE_BREAK:
- block = this.level.getBlock(pos);
- this.level.addParticle(new PunchBlockParticle(pos, block, face));
+ if (this.isBreakingBlock()) {
+ block = this.level.getBlock(pos);
+ this.level.addParticle(new PunchBlockParticle(pos, block, face));
+ }
break;
}
@@ -2791,7 +2796,7 @@ public void handleDataPacket(DataPacket packet) {
}
InteractPacket interactPacket = (InteractPacket) packet;
-
+
Entity targetEntity = this.level.getEntity(interactPacket.target);
if (targetEntity == null || !this.isAlive() || !targetEntity.isAlive()) {
@@ -2911,7 +2916,7 @@ public void handleDataPacket(DataPacket packet) {
BlockEntity be = this.getLevel().getBlockEntity(new Vector3(pickRequestPacket.x, pickRequestPacket.y, pickRequestPacket.z));
if (be != null) {
CompoundTag nbt = be.getCleanedNBT();
- if(nbt != null){
+ if (nbt != null) {
Item item1 = this.getInventory().getItemInHand();
item1.setCustomBlockData(nbt);
item1.setLore("+(DATA)");
@@ -2993,6 +2998,15 @@ public void handleDataPacket(DataPacket packet) {
this.inventory.setItemInHand(itemInHand);
this.inventory.sendHeldItem(this);
+ break;
+ case EntityEventPacket.CONSUME_ITEM:
+ EntityEventPacket pk = new EntityEventPacket();
+ pk.eid = this.getId();
+ pk.event = EntityEventPacket.CONSUME_ITEM;
+ pk.itemId = this.inventory.getItemInHand().getId();
+
+ Server.broadcastPacket(this.getViewers().values(), pk);
+ this.dataPacket(pk);
break;
}
break;
@@ -3691,6 +3705,22 @@ public void handleDataPacket(DataPacket packet) {
((ItemMap) mapItem).sendImage(this);
}
}
+
+ break;
+ case ProtocolInfo.LEVEL_SOUND_EVENT_PACKET:
+ LevelSoundEventPacket levelSoundEventPacket = (LevelSoundEventPacket) packet;
+
+ if (this.isBreakingBlock()) {
+ LevelSoundEventPacket pk1 = new LevelSoundEventPacket();
+ pk1.sound = LevelSoundEventPacket.SOUND_HIT;
+ pk1.extraData = this.breakingBlock.getId();
+ pk1.pitch = 1;
+ pk1.x = (float) this.breakingBlock.x;
+ pk1.y = (float) this.breakingBlock.y;
+ pk1.z = (float) this.breakingBlock.z;
+
+ this.level.addChunkPacket(this.getFloorX() >> 4, this.getFloorZ() >> 4, pk1);
+ }
break;
default:
break;
@@ -3835,6 +3865,7 @@ public void sendTitle(String text) {
/**
* Sets a subtitle for the next shown title
+ *
* @param text Subtitle text
*/
public void setSubtitle(String text) {
@@ -3853,8 +3884,9 @@ public void sendActionBarTitle(String text) {
/**
* Sets times for title animations
- * @param fadeInTime For how long title fades in
- * @param stayTime For how long title is shown
+ *
+ * @param fadeInTime For how long title fades in
+ * @param stayTime For how long title is shown
* @param fadeOutTime For how long title fades out
*/
public void setTitleAnimationTimes(int fadeInTime, int stayTime, int fadeOutTime) {
@@ -4612,8 +4644,8 @@ public void teleportImmediate(Location location, TeleportCause cause) {
/**
* Creates and sends a BossBar to the player
*
- * @param text The BossBar message
- * @param length The BossBar percentage
+ * @param text The BossBar message
+ * @param length The BossBar percentage
* @return bossBarId The BossBar ID, you should store it if you want to remove or update the BossBar later
*/
public long createBossBar(String text, int length) {
@@ -4648,7 +4680,7 @@ public long createBossBar(String text, int length) {
Attribute attr = Attribute.getAttribute(Attribute.MAX_HEALTH);
attr.setMaxValue(100); // Max value - We need to change the max value first, or else the "setValue" will return a IllegalArgumentException
attr.setValue(length); // Entity health
- pkAttributes.entries = new Attribute[] { attr };
+ pkAttributes.entries = new Attribute[]{attr};
this.dataPacket(pkAttributes);
// And now we send the bossbar packet
@@ -4662,9 +4694,9 @@ public long createBossBar(String text, int length) {
/**
* Updates a BossBar
*
- * @param text The new BossBar message
- * @param length The new BossBar length
- * @param bossBarId The BossBar ID
+ * @param text The new BossBar message
+ * @param length The new BossBar length
+ * @param bossBarId The BossBar ID
*/
public void updateBossBar(String text, int length, long bossBarId) {
// First we update the boss bar length
@@ -4673,7 +4705,7 @@ public void updateBossBar(String text, int length, long bossBarId) {
Attribute attr = Attribute.getAttribute(Attribute.MAX_HEALTH);
attr.setMaxValue(100); // Max value - We need to change the max value first, or else the "setValue" will return a IllegalArgumentException
attr.setValue(length); // Entity health
- pkAttributes.entries = new Attribute[] { attr };
+ pkAttributes.entries = new Attribute[]{attr};
this.dataPacket(pkAttributes);
// And then the boss bar text
SetEntityDataPacket pkMetadata = new SetEntityDataPacket();
@@ -4700,7 +4732,7 @@ public void updateBossBar(String text, int length, long bossBarId) {
/**
* Removes a BossBar
*
- * @param bossBarId The BossBar ID
+ * @param bossBarId The BossBar ID
*/
public void removeBossBar(long bossBarId) {
RemoveEntityPacket pkRemove = new RemoveEntityPacket();
@@ -4914,4 +4946,8 @@ public boolean equals(Object obj) {
public void notifyACK(int identification) {
needACK.put(identification, true);
}
-}
+
+ public boolean isBreakingBlock() {
+ return this.breakingBlock != null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cn/nukkit/block/Block.java b/src/main/java/cn/nukkit/block/Block.java
index be476fac00..f9f92b2392 100644
--- a/src/main/java/cn/nukkit/block/Block.java
+++ b/src/main/java/cn/nukkit/block/Block.java
@@ -822,16 +822,22 @@ public Item[] getDrops(Item item) {
private static double toolBreakTimeBonus0(
int toolType, int toolTier, boolean isWoolBlock, boolean isCobweb) {
- if(toolType == ItemTool.TYPE_SWORD) return isCobweb ? 15.0: 1.0;
- if(toolType == ItemTool.TYPE_SHEARS) return isWoolBlock ? 5.0: 15.0;
- if(toolType == ItemTool.TYPE_NONE) return 1.0;
+ if (toolType == ItemTool.TYPE_SWORD) return isCobweb ? 15.0 : 1.0;
+ if (toolType == ItemTool.TYPE_SHEARS) return isWoolBlock ? 5.0 : 15.0;
+ if (toolType == ItemTool.TYPE_NONE) return 1.0;
switch (toolTier) {
- case ItemTool.TIER_WOODEN: return 2.0;
- case ItemTool.TIER_STONE: return 4.0;
- case ItemTool.TIER_IRON: return 6.0;
- case ItemTool.TIER_DIAMOND: return 8.0;
- case ItemTool.TIER_GOLD: return 12.0;
- default: return 1.0;
+ case ItemTool.TIER_WOODEN:
+ return 2.0;
+ case ItemTool.TIER_STONE:
+ return 4.0;
+ case ItemTool.TIER_IRON:
+ return 6.0;
+ case ItemTool.TIER_DIAMOND:
+ return 8.0;
+ case ItemTool.TIER_GOLD:
+ return 12.0;
+ default:
+ return 1.0;
}
}
diff --git a/src/main/java/cn/nukkit/block/BlockEndStone.java b/src/main/java/cn/nukkit/block/BlockEndStone.java
index d8701c1ed5..ab497aee2e 100644
--- a/src/main/java/cn/nukkit/block/BlockEndStone.java
+++ b/src/main/java/cn/nukkit/block/BlockEndStone.java
@@ -44,7 +44,7 @@ public int getToolType() {
@Override
public Item[] getDrops(Item item) {
- if (item.isPickaxe() && item.getTier() > ItemTool.TIER_WOODEN) {
+ if (item.isPickaxe() && item.getTier() >= ItemTool.TIER_WOODEN) {
return new Item[]{
toItem()
};
diff --git a/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java b/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java
index 074338725c..916e50a7eb 100644
--- a/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java
@@ -24,6 +24,10 @@ public class EntityEventPacket extends DataPacket {
public static final byte AMBIENT_SOUND = 16;
public static final byte RESPAWN = 17;
+ public static final byte CONSUME_ITEM = 57;
+
+ public static final byte UNKNOWN1 = 66;
+
@Override
public byte pid() {
return NETWORK_ID;
@@ -31,13 +35,13 @@ public byte pid() {
public long eid;
public byte event;
- public long unknown;
+ public long itemId;
@Override
public void decode() {
this.eid = this.getVarLong();
this.event = (byte) this.getByte();
- this.unknown = this.getUnsignedVarInt();
+ this.itemId = this.getUnsignedVarInt();
}
@Override
@@ -45,6 +49,6 @@ public void encode() {
this.reset();
this.putVarLong(this.eid);
this.putByte(this.event);
- this.putUnsignedVarInt(this.unknown);
+ this.putUnsignedVarInt(this.itemId);
}
}
From 1e895878d8154fd2b961f0a837ef131b6a3a0f5c Mon Sep 17 00:00:00 2001
From: tigerza117
Date: Wed, 12 Jul 2017 22:24:14 +0700
Subject: [PATCH 014/175] Fix Bug HostName Transfer
logged out due to Transferred to 43.xxx.xx.xx/43.xx.xx.xx:12345:12345
-.-
---
src/main/java/cn/nukkit/Player.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index ee5bd60006..7e22c31854 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -4874,13 +4874,13 @@ public void setSprinting(boolean value, boolean setDefault) {
}
public void transfer(InetSocketAddress address) {
- String hostName = address.getHostName();
+ String hostName = address.getAddress().getHostAddress();
int port = address.getPort();
TransferPacket pk = new TransferPacket();
pk.address = hostName;
pk.port = port;
this.dataPacket(pk);
- String message = "Transferred to " + address + ":" + port;
+ String message = "Transferred to " + hostName + ":" + port;
this.close(message, message, false);
}
From fa0573a0f2f6065a4bb6e6d2520a1f9c5f3efab0 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Fri, 14 Jul 2017 11:45:34 +0200
Subject: [PATCH 015/175] add Event for pressureplates
---
.../nukkit/block/BlockPressurePlateBase.java | 19 +++++++++++-
src/main/java/cn/nukkit/entity/Entity.java | 19 +++++++-----
.../java/cn/nukkit/entity/EntityLiving.java | 5 ----
.../cn/nukkit/entity/item/EntityItem.java | 5 ++++
.../event/entity/EntityInteractEvent.java | 29 +++++++++++++++++++
5 files changed, 64 insertions(+), 13 deletions(-)
create mode 100644 src/main/java/cn/nukkit/event/entity/EntityInteractEvent.java
diff --git a/src/main/java/cn/nukkit/block/BlockPressurePlateBase.java b/src/main/java/cn/nukkit/block/BlockPressurePlateBase.java
index 6c6a2c9443..c19e296fbe 100644
--- a/src/main/java/cn/nukkit/block/BlockPressurePlateBase.java
+++ b/src/main/java/cn/nukkit/block/BlockPressurePlateBase.java
@@ -1,7 +1,12 @@
package cn.nukkit.block;
+import cn.nukkit.Player;
import cn.nukkit.entity.Entity;
+import cn.nukkit.event.Event;
import cn.nukkit.event.block.BlockRedstoneEvent;
+import cn.nukkit.event.entity.EntityInteractEvent;
+import cn.nukkit.event.player.PlayerInteractEvent;
+import cn.nukkit.event.player.PlayerInteractEvent.Action;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemBlock;
import cn.nukkit.level.Level;
@@ -92,7 +97,19 @@ public void onEntityCollide(Entity entity) {
int power = getRedstonePower();
if (power == 0) {
- updateState(power);
+ Event ev;
+
+ if (entity instanceof Player) {
+ ev = new PlayerInteractEvent((Player) entity, null, this, null, Action.PHYSICAL);
+ } else {
+ ev = new EntityInteractEvent(entity, this);
+ }
+
+ this.level.getServer().getPluginManager().callEvent(ev);
+
+ if (!ev.isCancelled()) {
+ updateState(power);
+ }
}
}
diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java
index 9a99a82fb8..154626035b 100644
--- a/src/main/java/cn/nukkit/entity/Entity.java
+++ b/src/main/java/cn/nukkit/entity/Entity.java
@@ -7,6 +7,7 @@
import cn.nukkit.block.BlockFire;
import cn.nukkit.block.BlockWater;
import cn.nukkit.entity.data.*;
+import cn.nukkit.event.Event;
import cn.nukkit.event.entity.*;
import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
import cn.nukkit.event.entity.EntityPortalEnterEvent.PortalType;
@@ -1251,13 +1252,17 @@ public void fall(float fallDistance) {
Block down = this.level.getBlock(this.floor().down());
if (down.getId() == Item.FARMLAND) {
+ Event ev;
+
if (this instanceof Player) {
- Player p = (Player) this;
- PlayerInteractEvent ev = new PlayerInteractEvent(p, p.getInventory().getItemInHand(), down, null, Action.PHYSICAL);
- this.server.getPluginManager().callEvent(ev);
- if (ev.isCancelled()) {
- return;
- }
+ ev = new PlayerInteractEvent((Player) this, null, down, null, Action.PHYSICAL);
+ } else {
+ ev = new EntityInteractEvent(this, down);
+ }
+
+ this.server.getPluginManager().callEvent(ev);
+ if (ev.isCancelled()) {
+ return;
}
this.level.setBlock(down, new BlockDirt(), true, true);
}
@@ -1600,7 +1605,7 @@ public void setRotation(double yaw, double pitch) {
* used for bat only
*/
public boolean doesTriggerPressurePlate() {
- return false;
+ return true;
}
protected void checkChunks() {
diff --git a/src/main/java/cn/nukkit/entity/EntityLiving.java b/src/main/java/cn/nukkit/entity/EntityLiving.java
index 4550b1d155..c1d63b8c40 100644
--- a/src/main/java/cn/nukkit/entity/EntityLiving.java
+++ b/src/main/java/cn/nukkit/entity/EntityLiving.java
@@ -326,9 +326,4 @@ public void setMovementSpeed(float speed) {
public float getMovementSpeed() {
return this.movementSpeed;
}
-
- @Override
- public boolean doesTriggerPressurePlate() {
- return true;
- }
}
diff --git a/src/main/java/cn/nukkit/entity/item/EntityItem.java b/src/main/java/cn/nukkit/entity/item/EntityItem.java
index 9baf3460c7..581ebbfa65 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityItem.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityItem.java
@@ -255,4 +255,9 @@ public void spawnTo(Player player) {
super.spawnTo(player);
}
+
+ @Override
+ public boolean doesTriggerPressurePlate() {
+ return true;
+ }
}
diff --git a/src/main/java/cn/nukkit/event/entity/EntityInteractEvent.java b/src/main/java/cn/nukkit/event/entity/EntityInteractEvent.java
new file mode 100644
index 0000000000..5d198f2e9c
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/entity/EntityInteractEvent.java
@@ -0,0 +1,29 @@
+package cn.nukkit.event.entity;
+
+import cn.nukkit.block.Block;
+import cn.nukkit.entity.Entity;
+import cn.nukkit.event.Cancellable;
+import cn.nukkit.event.HandlerList;
+
+/**
+ * @author CreeperFace
+ */
+public class EntityInteractEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+
+ private Block block;
+
+ public EntityInteractEvent(Entity entity, Block block) {
+ this.entity = entity;
+ this.block = block;
+ }
+
+ public Block getBlock() {
+ return block;
+ }
+}
From f11ebc0c124ad02b86d4972205b2b66bbd2ee691 Mon Sep 17 00:00:00 2001
From: NuclearSteven
Date: Sun, 16 Jul 2017 20:05:32 +0800
Subject: [PATCH 016/175] Bug Report Feature
---
pom.xml | 48 +++++++++++++++++++
.../utils/bugreport/BugReportGenerator.java | 15 ++++++
src/main/resources/report_template.md | 32 +++++++------
3 files changed, 80 insertions(+), 15 deletions(-)
diff --git a/pom.xml b/pom.xml
index 12451a5dfc..a8d97a2046 100644
--- a/pom.xml
+++ b/pom.xml
@@ -170,6 +170,54 @@
${project.build.directory}/dependency-reduced-pom.xml
+
+ pl.project13.maven
+ git-commit-id-plugin
+ 2.2.1
+
+
+ get-the-git-infos
+
+ revision
+
+
+
+
+
+ ${project.basedir}/.git
+ git
+ dd.MM.yyyy '@' HH:mm:ss z
+ ${user.timezone}
+ true
+ true
+ ${project.build.outputDirectory}/git.properties
+
+ properties
+ true
+ false
+ false
+ false
+ false
+ true
+
+ git.user.*
+
+
+
+ false
+ 7
+ flat
+
+ false
+ false
+ 7
+ -dirty
+ *
+ false
+ false
+
+
+
diff --git a/src/main/java/cn/nukkit/utils/bugreport/BugReportGenerator.java b/src/main/java/cn/nukkit/utils/bugreport/BugReportGenerator.java
index bd2e64281d..392a410d34 100644
--- a/src/main/java/cn/nukkit/utils/bugreport/BugReportGenerator.java
+++ b/src/main/java/cn/nukkit/utils/bugreport/BugReportGenerator.java
@@ -13,6 +13,7 @@
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.Properties;
/**
* Project nukkit
@@ -61,10 +62,17 @@ private String generate() throws IOException {
StringWriter stringWriter = new StringWriter();
throwable.printStackTrace(new PrintWriter(stringWriter));
+
File mdReport = new File(reports, date + "_" + throwable.getClass().getSimpleName() + ".md");
mdReport.createNewFile();
String content = Utils.readFile(this.getClass().getClassLoader().getResourceAsStream("report_template.md"));
+
+ Properties properties = getGitRepositoryState();
+ System.out.println(properties.getProperty("git.commit.id.abbrev"));
+ String abbrev = properties.getProperty("git.commit.id.abbrev");
+
content = content.replace("${NUKKIT_VERSION}", Nukkit.VERSION);
+ content = content.replace("${GIT_COMMIT_ABBREV}", abbrev);
content = content.replace("${JAVA_VERSION}", System.getProperty("java.vm.name") + " (" + System.getProperty("java.runtime.version") + ")");
content = content.replace("${HOSTOS}", systemInfo.getOperatingSystem().getFamily() + " [" + systemInfo.getOperatingSystem().getVersion().getVersion() + "]");
content = content.replace("${MEMORY}", getCount(systemInfo.getHardware().getMemory().getTotal(), true));
@@ -75,11 +83,18 @@ private String generate() throws IOException {
content = content.replace("${STACKTRACE}", stringWriter.toString());
content = content.replace("${PLUGIN_ERROR}", String.valueOf(!throwable.getStackTrace()[0].getClassName().startsWith("cn.nukkit")).toUpperCase());
content = content.replace("${STORAGE_TYPE}", model.toString());
+
Utils.writeFile(mdReport, content);
return mdReport.getAbsolutePath();
}
+ public Properties getGitRepositoryState() throws IOException {
+ Properties properties = new Properties();
+ properties.load(getClass().getClassLoader().getResourceAsStream("git.properties"));
+ return properties;
+ }
+
//Code section from SOF
public static String getCount(long bytes, boolean si) {
int unit = si ? 1000 : 1024;
diff --git a/src/main/resources/report_template.md b/src/main/resources/report_template.md
index 576de6c706..6ea821b8f4 100644
--- a/src/main/resources/report_template.md
+++ b/src/main/resources/report_template.md
@@ -1,4 +1,7 @@
-## Nukkit Bug Report (DO NOT OPEN A ISSUE IF THIS IS A PLUGIN ERROR)
+## Nukkit Bug Report
+
+(DO NOT OPEN A ISSUE IF THIS IS A PLUGIN ERROR)
+
PLUGIN ERROR: ${PLUGIN_ERROR}
### Issue Description
@@ -10,36 +13,35 @@ PLUGIN ERROR: ${PLUGIN_ERROR}
??
### OS and Versions
-
-* Nukkit Version: ${NUKKIT_VERSION}
-
+* Nukkit Version: ${NUKKIT_VERSION}
+* Git Commit Abbrev: ${GIT_COMMIT_ABBREV}
* Java Version:
```
${JAVA_VERSION}
```
-
+
* Host Configuration:
-
+
| Item | Value |
|:----:|:-----:|
-| Host OS | ${HOSTOS} |
-| Memory(RAM) | ${MEMORY} |
-| Storage Size | ${STORAGE_SIZE} |
-| Storage Type | ${STORAGE_TYPE} |
-| CPU Type | ${CPU_TYPE} |
+| Host OS | ${HOSTOS} |
+| Memory(RAM) | ${MEMORY} |
+| Storage Size | ${STORAGE_SIZE} |
+| Storage Type | ${STORAGE_TYPE} |
+| CPU Type | ${CPU_TYPE} |
| CPU Core Count | ${PHYSICAL_CORE} cores ${LOGICAL_CORE} threads |
-| Upstream Bandwidth | ?? |
+| Upstream Bandwidth | ?? |
* Client Configuration:
| Item | Value |
|:----:|:-----:|
-| Client Edition | ?? |
-| Client Version | ?? |
+| Client Edition | ?? |
+| Client Version | ?? |
### Crashdump, Backtrace or Other Files
-
+
```
${STACKTRACE}
```
From 4eb85cb84fb449ffb09ccf6d79e0a37bead76c07 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Fri, 21 Jul 2017 09:42:15 +0200
Subject: [PATCH 017/175] add chest sounds
---
src/main/java/cn/nukkit/inventory/ChestInventory.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/main/java/cn/nukkit/inventory/ChestInventory.java b/src/main/java/cn/nukkit/inventory/ChestInventory.java
index 3d8ac1560d..b9941dde57 100644
--- a/src/main/java/cn/nukkit/inventory/ChestInventory.java
+++ b/src/main/java/cn/nukkit/inventory/ChestInventory.java
@@ -4,6 +4,7 @@
import cn.nukkit.blockentity.BlockEntityChest;
import cn.nukkit.level.Level;
import cn.nukkit.network.protocol.BlockEventPacket;
+import cn.nukkit.network.protocol.LevelSoundEventPacket;
/**
* author: MagicDroidX
@@ -33,6 +34,7 @@ public void onOpen(Player who) {
pk.case2 = 2;
Level level = this.getHolder().getLevel();
+ level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_CHEST_OPEN, 1, -1, this.getHolder(), false, false);
if (level != null) {
level.addChunkPacket((int) this.getHolder().getX() >> 4, (int) this.getHolder().getZ() >> 4, pk);
}
@@ -50,6 +52,7 @@ public void onClose(Player who) {
pk.case2 = 0;
Level level = this.getHolder().getLevel();
+ level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_CHEST_CLOSED, 1, -1, this.getHolder(), false, false);
if (level != null) {
level.addChunkPacket((int) this.getHolder().getX() >> 4, (int) this.getHolder().getZ() >> 4, pk);
}
From d028383d4920468f0e15fbbc44531e2209855464 Mon Sep 17 00:00:00 2001
From: boybook
Date: Sun, 23 Jul 2017 10:56:22 +0800
Subject: [PATCH 018/175] Add the support to change Apply Effect in
PotionApplyEvent (#1811)
* Fixed furnaces crafting bug and more stoneware. Fixed https://github.com/Nukkit/Nukkit/issues/1770
* Add the support to change Apply Effect in PotionApplyEvent.
---
.../cn/nukkit/event/potion/PotionApplyEvent.java | 13 ++++++++++++-
src/main/java/cn/nukkit/potion/Potion.java | 4 +++-
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/src/main/java/cn/nukkit/event/potion/PotionApplyEvent.java b/src/main/java/cn/nukkit/event/potion/PotionApplyEvent.java
index a35ff85188..f1f4b0b008 100644
--- a/src/main/java/cn/nukkit/event/potion/PotionApplyEvent.java
+++ b/src/main/java/cn/nukkit/event/potion/PotionApplyEvent.java
@@ -3,6 +3,7 @@
import cn.nukkit.entity.Entity;
import cn.nukkit.event.Cancellable;
import cn.nukkit.event.HandlerList;
+import cn.nukkit.potion.Effect;
import cn.nukkit.potion.Potion;
/**
@@ -17,10 +18,13 @@ public static HandlerList getHandlers() {
return handlers;
}
+ private Effect applyEffect;
+
private final Entity entity;
- public PotionApplyEvent(Potion potion, Entity entity) {
+ public PotionApplyEvent(Potion potion, Effect applyEffect, Entity entity) {
super(potion);
+ this.applyEffect = applyEffect;
this.entity = entity;
}
@@ -28,4 +32,11 @@ public Entity getEntity() {
return entity;
}
+ public Effect getApplyEffect() {
+ return applyEffect;
+ }
+
+ public void setApplyEffect(Effect applyEffect) {
+ this.applyEffect = applyEffect;
+ }
}
diff --git a/src/main/java/cn/nukkit/potion/Potion.java b/src/main/java/cn/nukkit/potion/Potion.java
index 83e0524c7c..60c7482255 100644
--- a/src/main/java/cn/nukkit/potion/Potion.java
+++ b/src/main/java/cn/nukkit/potion/Potion.java
@@ -175,13 +175,15 @@ public void applyPotion(Entity entity, double health) {
}
}
- PotionApplyEvent event = new PotionApplyEvent(this, entity);
+ PotionApplyEvent event = new PotionApplyEvent(this, applyEffect, entity);
entity.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
+ applyEffect = event.getApplyEffect();
+
switch (this.getId()) {
case INSTANT_HEALTH:
case INSTANT_HEALTH_II:
From 0aa758657a336df8cbafcf4370ed693d0767fe2a Mon Sep 17 00:00:00 2001
From: ScraM Team
Date: Wed, 26 Jul 2017 23:45:32 -0700
Subject: [PATCH 019/175] Fix for Issue #1795, non-arrow projectiles should not
cause damage.
From 96a0d97d2e464ebe4baa20681f925730e9e74a4b Mon Sep 17 00:00:00 2001
From: ScraM Team
Date: Wed, 26 Jul 2017 23:59:07 -0700
Subject: [PATCH 020/175] Fix for Issue #1795: Non-arrow projectiles should not
cause damage.
---
src/main/java/cn/nukkit/entity/projectile/EntityArrow.java | 4 ++++
.../java/cn/nukkit/entity/projectile/EntityProjectile.java | 6 +++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/main/java/cn/nukkit/entity/projectile/EntityArrow.java b/src/main/java/cn/nukkit/entity/projectile/EntityArrow.java
index 82a1fec977..cc6ca21921 100644
--- a/src/main/java/cn/nukkit/entity/projectile/EntityArrow.java
+++ b/src/main/java/cn/nukkit/entity/projectile/EntityArrow.java
@@ -91,6 +91,10 @@ public int getResultDamage() {
return base;
}
+ private double getBaseDamage() {
+ return 2;
+ }
+
@Override
public boolean onUpdate(int currentTick) {
if (this.closed) {
diff --git a/src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java b/src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java
index 776a83fc68..c192d50c17 100644
--- a/src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java
+++ b/src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java
@@ -23,7 +23,11 @@ public abstract class EntityProjectile extends Entity {
public Entity shootingEntity = null;
protected double getDamage() {
- return namedTag.contains("damage") ? namedTag.getDouble("damage") : 2;
+ return namedTag.contains("damage") ? namedTag.getDouble("damage") : getBaseDamage();
+ }
+
+ private double getBaseDamage() {
+ return 0;
}
public boolean hadCollision = false;
From 80696be87ff509998f10ea1238ca60785cf4935d Mon Sep 17 00:00:00 2001
From: ScraM Team
Date: Thu, 27 Jul 2017 00:14:47 -0700
Subject: [PATCH 021/175] Fixed mmethod access and annotation.
---
src/main/java/cn/nukkit/entity/projectile/EntityArrow.java | 3 ++-
.../java/cn/nukkit/entity/projectile/EntityProjectile.java | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/main/java/cn/nukkit/entity/projectile/EntityArrow.java b/src/main/java/cn/nukkit/entity/projectile/EntityArrow.java
index cc6ca21921..bbf4c35898 100644
--- a/src/main/java/cn/nukkit/entity/projectile/EntityArrow.java
+++ b/src/main/java/cn/nukkit/entity/projectile/EntityArrow.java
@@ -91,7 +91,8 @@ public int getResultDamage() {
return base;
}
- private double getBaseDamage() {
+ @Override
+ protected double getBaseDamage() {
return 2;
}
diff --git a/src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java b/src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java
index c192d50c17..caf8a345cf 100644
--- a/src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java
+++ b/src/main/java/cn/nukkit/entity/projectile/EntityProjectile.java
@@ -26,7 +26,7 @@ protected double getDamage() {
return namedTag.contains("damage") ? namedTag.getDouble("damage") : getBaseDamage();
}
- private double getBaseDamage() {
+ protected double getBaseDamage() {
return 0;
}
From ca9c6c072a4f1285836a0155901768a57ca85058 Mon Sep 17 00:00:00 2001
From: ScraM Team
Date: Sat, 29 Jul 2017 20:13:49 -0700
Subject: [PATCH 022/175] Fix for issue #1817 -- main thread stuck (rollback
Zlib)
---
src/main/java/cn/nukkit/utils/Zlib.java | 54 +++++++++++--------------
1 file changed, 23 insertions(+), 31 deletions(-)
diff --git a/src/main/java/cn/nukkit/utils/Zlib.java b/src/main/java/cn/nukkit/utils/Zlib.java
index fbf69bcb18..8f29b8ae52 100644
--- a/src/main/java/cn/nukkit/utils/Zlib.java
+++ b/src/main/java/cn/nukkit/utils/Zlib.java
@@ -9,63 +9,55 @@
public abstract class Zlib {
-
+
public static byte[] deflate(byte[] data) throws Exception {
return deflate(data, Deflater.DEFAULT_COMPRESSION);
}
public static byte[] deflate(byte[] data, int level) throws Exception {
- Deflater deflater = getDef(level);
- if(deflater == null) throw new IllegalArgumentException("No deflate for level "+level+" !");
+ Deflater deflater = new Deflater(level);
deflater.reset();
deflater.setInput(data);
deflater.finish();
ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
- while (!deflater.finished()) {
- int i = deflater.deflate(buf.get());
- bos.write(buf.get(), 0, i);
+ byte[] buf = new byte[1024];
+ try {
+ while (!deflater.finished()) {
+ int i = deflater.deflate(buf);
+ bos.write(buf, 0, i);
+ }
+ } finally {
+ deflater.end();
}
- //Deflater::end is called the time when the process exits.
return bos.toByteArray();
}
- public static byte[] inflate(byte[] data) throws IOException {
- return inflate(new ByteArrayInputStream(data));
- }
-
- public static byte[] inflate(byte[] data, int maxSize) throws IOException {
- return inflate(new ByteArrayInputStream(data, 0, maxSize));
- }
-
- /* -=-=-=-=-=- Internal -=-=-=-=-=- Do NOT attempt to use in production -=-=-=-=-=- */
-
- private static final ThreadLocal buf = ThreadLocal.withInitial(() -> new byte[1024]);
- private static final ThreadLocal def = ThreadLocal.withInitial(Deflater::new);
-
- private static Deflater getDef(int level) {
- def.get().setLevel(level);
- return def.get();
- }
-
- private static byte[] inflate(InputStream stream) throws IOException {
+ public static byte[] inflate(InputStream stream) throws IOException {
InflaterInputStream inputStream = new InflaterInputStream(stream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
int length;
try {
- while ((length = inputStream.read(buf.get())) != -1) {
- outputStream.write(buf.get(), 0, length);
+ while ((length = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, length);
}
} finally {
- buf.set(outputStream.toByteArray());
+ buffer = outputStream.toByteArray();
outputStream.flush();
outputStream.close();
inputStream.close();
}
- return buf.get();
+ return buffer;
+ }
+
+ public static byte[] inflate(byte[] data) throws IOException {
+ return inflate(new ByteArrayInputStream(data));
}
+ public static byte[] inflate(byte[] data, int maxSize) throws IOException {
+ return inflate(new ByteArrayInputStream(data, 0, maxSize));
+ }
}
-
From 81eb29dc71e6a408ce1bf33f58c0305515800632 Mon Sep 17 00:00:00 2001
From: Adam Matthew
Date: Mon, 31 Jul 2017 21:06:08 +0800
Subject: [PATCH 023/175] MINECARTS available. Enjoy riding minecarts! (#1763)
* Minecart can move!
* Minecart friendly clazz
* Removed unused SetEntityLink....
* Some missing pieces
* Add files via upload
* Small piece to move vehicle
Buggy but works
* Fix player position.
Thank you @Snake1999 for new Entity Data from 1.0 branch
(DATA_RIDER_SEAT_POSITION)
* Add minecart movement on move packet
* Some fix when colliding minecart
Still buggy but player wont bounced away
Track logic for buggy rails
new API on Entity
* Woops
* Fix entity data
Wrong entity data riding seat position :P.
New Rail Abstract
Mobs will dismount vehicle if vehicle is dead
* Time to go rouge
Fix MinecartTNT (exploded non stop)
Minecart can now have new display block!
New packet from @Creeperface01
* FIX
* Minecart collides better than before!
Huge minstake! Problem solved
Minecart moves -1 when not on rail not solved yet. todo
:+1:
* Minecart are now Stable!
Fixed minecart yaw
Fix glitch on minecart
Minecart will be on the ground when off rail!
Who made the wrong Network Id? (TNT)
Implements @yescallop rails
* Rearrange
* Revert
* Removed boolean that i forget to remove
* Working on Powered Rails
Detector rail should detect minecarts.
Code format.
Events for Vehicle
Fixed weird riding?
Still WIP
* Some addons
Minecart will fall down
Fixed Minecart items drops
Powered rail might fixed
* Unique update!
Added Interaction features
Added flying features
A permanent fix for glitch minecarts
Block powered rail can flow
Enum class for Minecart variants
Fix weird riding experience
Fix minecart placement
Fix Mine-TNT not exploding after load world
Now you can play with events
Rewrite Entity class
Renamed fields to suitable name
Rewrite Minecart movement code
* Rewrite riding position
The last events in this class
* Powered Rails now works very well
Fixed rolling amplitude
Riding position rewrite (Not tested yet)
Interaction will interact much better
* Fixes rider position, and minecart hit
* Final upload
Fix false rail orientation
Fix minecart yaw
Moved mount entity into vehicle
Boats now working :+1:
* Fix powered rail
* Update BlockRailActivator.java
---
src/main/java/cn/nukkit/Player.java | 109 ++-
src/main/java/cn/nukkit/block/BlockRail.java | 302 ++++---
.../cn/nukkit/block/BlockRailActivator.java | 143 +++
.../cn/nukkit/block/BlockRailDetector.java | 74 +-
.../cn/nukkit/block/BlockRailPowered.java | 161 +++-
.../java/cn/nukkit/block/BlockWaterStill.java | 2 -
src/main/java/cn/nukkit/entity/Entity.java | 139 ++-
.../cn/nukkit/entity/EntityInteractable.java | 20 +
.../java/cn/nukkit/entity/EntityLiving.java | 16 +-
.../cn/nukkit/entity/item/EntityBoat.java | 100 ++-
.../entity/item/EntityMinecartAbstract.java | 849 ++++++++++++++++++
.../entity/item/EntityMinecartChest.java | 25 +-
.../entity/item/EntityMinecartEmpty.java | 84 +-
.../entity/item/EntityMinecartHopper.java | 20 +-
.../nukkit/entity/item/EntityMinecartTNT.java | 75 +-
.../nukkit/entity/item/EntityPrimedTNT.java | 1 -
.../cn/nukkit/entity/item/EntityVehicle.java | 166 +++-
.../cn/nukkit/entity/mob/EntitySkeleton.java | 2 +-
.../cn/nukkit/entity/mob/EntityZombie.java | 2 +-
.../nukkit/entity/mob/EntityZombiePigman.java | 2 +-
.../entity/passive/EntityZombieHorse.java | 1 -
.../vehicle/EntityEnterVehicleEvent.java | 32 +
.../event/vehicle/EntityExitVehicleEvent.java | 32 +
.../event/vehicle/VehicleCreateEvent.java | 19 +
.../event/vehicle/VehicleDamageEvent.java | 37 +
.../event/vehicle/VehicleDestroyEvent.java | 27 +
.../cn/nukkit/event/vehicle/VehicleEvent.java | 22 +
.../event/vehicle/VehicleMoveEvent.java | 31 +
.../event/vehicle/VehicleUpdateEvent.java | 18 +
.../java/cn/nukkit/item/ItemMinecart.java | 49 +-
.../cn/nukkit/item/ItemMinecartChest.java | 48 +-
.../cn/nukkit/item/ItemMinecartHopper.java | 48 +-
.../java/cn/nukkit/item/ItemMinecartTNT.java | 48 +-
.../java/cn/nukkit/level/ChunkPosition.java | 42 +
src/main/java/cn/nukkit/math/NukkitMath.java | 16 +
.../ClientboundMapItemDataPacket.java | 1 -
.../nukkit/network/protocol/LoginPacket.java | 1 -
src/main/java/cn/nukkit/potion/Effect.java | 1 -
.../java/cn/nukkit/scheduler/AsyncPool.java | 1 -
.../java/cn/nukkit/utils/EnumMinecart.java | 105 +++
src/main/java/cn/nukkit/utils/MainLogger.java | 2 +-
src/main/java/cn/nukkit/utils/Rail.java | 158 ++++
.../utils/bugreport/ExceptionHandler.java | 3 -
43 files changed, 2598 insertions(+), 436 deletions(-)
create mode 100644 src/main/java/cn/nukkit/entity/EntityInteractable.java
create mode 100644 src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
create mode 100644 src/main/java/cn/nukkit/event/vehicle/EntityEnterVehicleEvent.java
create mode 100644 src/main/java/cn/nukkit/event/vehicle/EntityExitVehicleEvent.java
create mode 100644 src/main/java/cn/nukkit/event/vehicle/VehicleCreateEvent.java
create mode 100644 src/main/java/cn/nukkit/event/vehicle/VehicleDamageEvent.java
create mode 100644 src/main/java/cn/nukkit/event/vehicle/VehicleDestroyEvent.java
create mode 100644 src/main/java/cn/nukkit/event/vehicle/VehicleEvent.java
create mode 100644 src/main/java/cn/nukkit/event/vehicle/VehicleMoveEvent.java
create mode 100644 src/main/java/cn/nukkit/event/vehicle/VehicleUpdateEvent.java
create mode 100644 src/main/java/cn/nukkit/level/ChunkPosition.java
create mode 100644 src/main/java/cn/nukkit/utils/EnumMinecart.java
create mode 100644 src/main/java/cn/nukkit/utils/Rail.java
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 7e22c31854..59ac7ffddc 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -11,10 +11,7 @@
import cn.nukkit.command.data.CommandParameter;
import cn.nukkit.command.data.args.CommandArg;
import cn.nukkit.command.data.args.CommandArgBlockVector;
-import cn.nukkit.entity.Attribute;
-import cn.nukkit.entity.Entity;
-import cn.nukkit.entity.EntityHuman;
-import cn.nukkit.entity.EntityLiving;
+import cn.nukkit.entity.*;
import cn.nukkit.entity.data.*;
import cn.nukkit.entity.item.*;
import cn.nukkit.entity.mob.EntityCreeper;
@@ -61,10 +58,7 @@
import cn.nukkit.potion.Effect;
import cn.nukkit.potion.Potion;
import cn.nukkit.resourcepacks.ResourcePack;
-import cn.nukkit.utils.Binary;
-import cn.nukkit.utils.ClientChainData;
-import cn.nukkit.utils.TextFormat;
-import cn.nukkit.utils.Zlib;
+import cn.nukkit.utils.*;
import co.aikar.timings.Timing;
import co.aikar.timings.Timings;
import com.google.gson.Gson;
@@ -1403,7 +1397,9 @@ protected void processMovement(int tickDiff) {
if (diffX != 0 || diffY != 0 || diffZ != 0) {
if (this.checkMovement && !server.getAllowFlight() && this.isSurvival()) {
- if (!this.isSleeping()) {
+ // Some say: I cant move my head when riding because the server
+ // blocked my movement
+ if (!this.isSleeping() && this.riding == null) {
double diffHorizontalSqr = (diffX * diffX + diffZ * diffZ) / ((double) (tickDiff * tickDiff));
if (diffHorizontalSqr > 0.125) {
PlayerInvalidMoveEvent ev;
@@ -1656,6 +1652,7 @@ public boolean onUpdate(int currentTick) {
}
this.checkTeleportPosition();
+ this.checkInteractNearby();
// TODO: remove this workaround (broken client MCPE 1.0.0)
if (!messageQueue.isEmpty()) {
@@ -1667,7 +1664,70 @@ public boolean onUpdate(int currentTick) {
}
return true;
}
+
+ public void checkInteractNearby(){
+ int interactDistance = isCreative() ? 5 : 3;
+ if(canInteract(this, interactDistance)){
+ if(getEntityPlayerLookingAt(interactDistance) != null){
+ EntityInteractable onInteract = getEntityPlayerLookingAt(interactDistance);
+ setButtonText(onInteract.getInteractButton());
+ } else {
+ setButtonText("");
+ }
+ } else {
+ setButtonText("");
+ }
+ }
+
+ /**
+ * Returns the Entity the player is looking at currently
+ *
+ * @param maxDistance the maximum distance to check for entities
+ * @return Entity|null either NULL if no entity is found or an instance of the entity
+ */
+ public EntityInteractable getEntityPlayerLookingAt(int maxDistance) {
+ timing.startTiming();
+
+ EntityInteractable entity = null;
+
+ // just a fix because player MAY not be fully initialized
+ if (temporalVector != null) {
+ Entity[] nearbyEntities = level.getNearbyEntities(boundingBox.grow(maxDistance, maxDistance, maxDistance), this);
+
+ // get all blocks in looking direction until the max interact distance is reached (it's possible that startblock isn't found!)
+ try {
+ BlockIterator itr = new BlockIterator(level, getPosition(), getDirectionVector(), getEyeHeight(), maxDistance);
+ if (itr.hasNext()) {
+ Block block;
+ while (itr.hasNext()) {
+ block = itr.next();
+ entity = getEntityAtPosition(nearbyEntities, block.getFloorX(), block.getFloorY(), block.getFloorZ());
+ if (entity != null) {
+ break;
+ }
+ }
+ }
+ } catch (Exception ex) {
+ // nothing to log here!
+ }
+ }
+ timing.stopTiming();
+
+ return entity;
+ }
+
+ private EntityInteractable getEntityAtPosition(Entity[] nearbyEntities, int x, int y, int z) {
+ for (Entity nearestEntity : nearbyEntities) {
+ if (nearestEntity.getFloorX() == x && nearestEntity.getFloorY() == y && nearestEntity.getFloorZ() == z
+ && nearestEntity instanceof EntityInteractable
+ && ((EntityInteractable) nearestEntity).canDoInteraction()) {
+ return (EntityInteractable) nearestEntity;
+ }
+ }
+ return null;
+ }
+
private ArrayList messageQueue = new ArrayList<>();
public void checkNetwork() {
@@ -2077,6 +2137,15 @@ public void handleDataPacket(DataPacket packet) {
dataPacket.progress = 1048576 * requestPacket.chunkIndex;
this.dataPacket(dataPacket);
break;
+ case ProtocolInfo.PLAYER_INPUT_PACKET:
+ if(!this.isAlive() || !this.spawned){
+ break;
+ }
+ PlayerInputPacket ipk = (PlayerInputPacket) packet;
+ if(riding instanceof EntityMinecartAbstract){
+ ((EntityMinecartEmpty) riding).setCurrentSpeed(ipk.motionY);
+ }
+ break;
case ProtocolInfo.MOVE_PLAYER_PACKET:
if (this.teleportPosition != null) {
break;
@@ -2805,7 +2874,7 @@ public void handleDataPacket(DataPacket packet) {
this.server.getLogger().warning(this.getServer().getLanguage().translateString("nukkit.player.invalidEntity", this.getName()));
break;
}
-
+
item = this.inventory.getItemInHand();
switch (interactPacket.action) {
@@ -2881,27 +2950,11 @@ public void handleDataPacket(DataPacket packet) {
}
break;
case InteractPacket.ACTION_VEHICLE_EXIT:
- if (!(targetEntity instanceof EntityVehicle)) {
+ if (!(targetEntity instanceof EntityVehicle) || this.riding == null) {
break;
}
- SetEntityLinkPacket pk;
-
- pk = new SetEntityLinkPacket();
- pk.rider = targetEntity.getId();
- pk.riding = this.id;
- pk.type = 3;
- Server.broadcastPacket(this.hasSpawned.values(), pk);
-
- pk = new SetEntityLinkPacket();
- pk.rider = targetEntity.getId();
- pk.riding = this.getId();
- pk.type = 3;
- dataPacket(pk);
-
- riding = null;
- ((EntityVehicle) targetEntity).linkedEntity = null;
- this.setDataFlag(DATA_FLAGS, DATA_FLAG_RIDING, false);
+ ((EntityVehicle) riding).mountEntity(this);
break;
}
break;
diff --git a/src/main/java/cn/nukkit/block/BlockRail.java b/src/main/java/cn/nukkit/block/BlockRail.java
index 9fa3336685..debed246f1 100644
--- a/src/main/java/cn/nukkit/block/BlockRail.java
+++ b/src/main/java/cn/nukkit/block/BlockRail.java
@@ -1,15 +1,22 @@
package cn.nukkit.block;
import cn.nukkit.Player;
+import cn.nukkit.Server;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemTool;
import cn.nukkit.level.Level;
+import cn.nukkit.math.AxisAlignedBB;
import cn.nukkit.math.BlockFace;
-import cn.nukkit.math.Vector3;
import cn.nukkit.utils.BlockColor;
+import cn.nukkit.utils.Rail;
+import cn.nukkit.utils.Rail.Orientation;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static cn.nukkit.math.BlockFace.*;
+import static cn.nukkit.utils.Rail.Orientation.*;
/**
* Created by Snake1999 on 2016/1/11.
@@ -17,6 +24,11 @@
*/
public class BlockRail extends BlockFlowable {
+ // 0x8: Set the block active
+ // 0x7: Reset the block to normal
+ // If the rail can be powered. So its a complex rail!
+ protected boolean canBePowered = false;
+
public BlockRail() {
this(0);
}
@@ -58,7 +70,8 @@ public int getToolType() {
@Override
public int onUpdate(int type) {
if (type == Level.BLOCK_UPDATE_NORMAL) {
- if (this.down().isTransparent()) {
+ Optional ascendingDirection = this.getOrientation().ascendingDirection();
+ if (this.down().isTransparent() || (ascendingDirection.isPresent() && this.getSide(ascendingDirection.get()).isTransparent())) {
this.getLevel().useBreakOn(this);
return Level.BLOCK_UPDATE_NORMAL;
}
@@ -66,161 +79,182 @@ public int onUpdate(int type) {
return 0;
}
+ @Override
+ public AxisAlignedBB recalculateBoundingBox() {
+ return new AxisAlignedBB(
+ this.x,
+ this.y,
+ this.z,
+ this.x + 1,
+ this.y + 0.125D,
+ this.z + 1);
+ }
+
@Override
public BlockColor getColor() {
return BlockColor.AIR_BLOCK_COLOR;
}
+ //Information from http://minecraft.gamepedia.com/Rail
@Override
public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) {
Block down = this.down();
- if (down == null) return false;
- if (down.isTransparent()) return false;
- int[][] arrayXZ = new int[][]{{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
- int[] arrayY = new int[]{0, 1, -1};
- List connected = new ArrayList<>();
- for (int[] xz : arrayXZ) {
- int x = xz[0];
- int z = xz[1];
- for (int y : arrayY) {
- Vector3 v3 = new Vector3(x, y, z).add(this);
- Block v3block = this.getLevel().getBlock(v3);
- if (v3block == null) continue;
- if (!isRailBlock(v3block.getId()) || !isValidRailMeta(v3block.getDamage())) continue;
- if (!(v3block instanceof BlockRail)) continue;
- this.connectRail(v3block);
- connected.add(v3block);
- }
- if (connected.size() >= 2) break;
+ if (down == null || down.isTransparent()) {
+ return false;
}
-
- if (connected.size() == 1) {
- Vector3 v3 = connected.get(0).subtract(this);
- this.meta = (v3.y != 1) ? (v3.x == 0 ? 0 : 1) : (int) (v3.z == 0 ? (v3.x / -2) + 2.5 : (v3.z / 2) + 4.5);
- } else if (connected.size() == 2) {
- Vector3[] subtract = new Vector3[2];
- for (int i = 0; i < connected.size(); i++) {
- subtract[i] = connected.get(i).subtract(this);
+ Map railsAround = this.checkRailsAroundAffected();
+ List rails = new ArrayList<>(railsAround.keySet());
+ List faces = new ArrayList<>(railsAround.values());
+ if (railsAround.size() == 1) {
+ BlockRail other = rails.get(0);
+ this.meta = this.connect(other, railsAround.get(other)).metadata();
+ } else if (railsAround.size() == 4) {
+ if (this.isAbstract()) {
+ this.meta = this.connect(rails.get(faces.indexOf(SOUTH)), SOUTH, rails.get(faces.indexOf(EAST)), EAST).metadata();
+ } else {
+ this.meta = this.connect(rails.get(faces.indexOf(EAST)), EAST, rails.get(faces.indexOf(WEST)), WEST).metadata();
}
- if (Math.abs(subtract[0].x) == Math.abs(subtract[1].z) && Math.abs(subtract[1].x) == Math.abs(subtract[0].z)) {
- Vector3 v3 = connected.get(0).subtract(this).add(connected.get(1).subtract(this));
- this.meta = v3.x == 1 ? (v3.z == 1 ? 6 : 9) : (v3.z == 1 ? 7 : 8);
- } else if (subtract[0].y == 1 || subtract[1].y == 1) {
- Vector3 v3 = subtract[0].y == 1 ? subtract[0] : subtract[1];
- this.meta = v3.x == 0 ? (v3.z == -1 ? 4 : 5) : (v3.x == 1 ? 2 : 3);
+ } else if (!railsAround.isEmpty()) {
+ if (this.isAbstract()) {
+ if (railsAround.size() == 2) {
+ BlockRail rail1 = rails.get(0);
+ BlockRail rail2 = rails.get(1);
+ this.meta = this.connect(rail1, railsAround.get(rail1), rail2, railsAround.get(rail2)).metadata();
+ } else {
+ List cd = Stream.of(CURVED_SOUTH_EAST, CURVED_NORTH_EAST, CURVED_SOUTH_WEST)
+ .filter(o -> o.connectingDirections().stream().allMatch(faces::contains))
+ .findFirst().get().connectingDirections();
+ BlockFace f1 = cd.get(0);
+ BlockFace f2 = cd.get(1);
+ this.meta = this.connect(rails.get(faces.indexOf(f1)), f1, rails.get(faces.indexOf(f2)), f2).metadata();
+ }
} else {
- this.meta = subtract[0].x == 0 ? 0 : 1;
+ BlockFace f = faces.stream()
+ .sorted((f1, f2) -> (f1.getIndex() < f2.getIndex()) ? 1 : ((x == y) ? 0 : -1))
+ .findFirst().get();
+ BlockFace fo = f.getOpposite();
+ if (faces.contains(fo)) { //Opposite connectable
+ this.meta = this.connect(rails.get(faces.indexOf(f)), f, rails.get(faces.indexOf(fo)), fo).metadata();
+ } else {
+ this.meta = this.connect(rails.get(faces.indexOf(f)), f).metadata();
+ }
}
}
- this.getLevel().setBlock(this, Block.get(this.getId(), this.getDamage()), true, true);
+ this.level.setBlock(this, this, true, true);
+ if (!isAbstract()) {
+ level.scheduleUpdate(this, this, 0);
+ }
return true;
}
- /************ Rail Connecting Part ***********/
- /****
- * todo: too complex, need to simplify
- ****/
+ private Orientation connect(BlockRail rail1, BlockFace face1, BlockRail rail2, BlockFace face2) {
+ this.connect(rail1, face1);
+ this.connect(rail2, face2);
- protected Vector3[] canConnectRail(Block block) {
- if (!(block instanceof BlockRail)) return null;
- if (this.distanceSquared(block) > 2) return null;
- Vector3[] result = checkRail(this);
- if (result.length == 2) return null;
- return result;
- }
+ if (face1.getOpposite() == face2) {
+ int delta1 = (int) (this.y - rail1.y);
+ int delta2 = (int) (this.y - rail2.y);
- protected void connectRail(Block rail) {
- Vector3[] connected = canConnectRail(rail);
- if (connected == null) return;
- if (connected.length == 1) {
- Vector3 v3 = connected[0].subtract(this);
- this.meta = (v3.y != 1) ? (v3.x == 0 ? 0 : 1) : (int) (v3.z == 0 ? (v3.x / -2) + 2.5 : (v3.z / 2) + 4.5);
- } else if (connected.length == 2) {
- Vector3[] subtract = new Vector3[2];
- for (int i = 0; i < connected.length; i++) {
- subtract[i] = connected[i].subtract(this);
- }
- if (Math.abs(subtract[0].x) == Math.abs(subtract[1].z) && Math.abs(subtract[1].x) == Math.abs(subtract[0].z)) {
- Vector3 v3 = connected[0].subtract(this).add(connected[1].subtract(this));
- this.meta = v3.x == 1 ? (v3.z == 1 ? 6 : 9) : (v3.z == 1 ? 7 : 8);
- } else if (subtract[0].y == 1 || subtract[1].y == 1) {
- Vector3 v3 = subtract[0].y == 1 ? subtract[0] : subtract[1];
- this.meta = v3.x == 0 ? (v3.z == -1 ? 4 : 5) : (v3.x == 1 ? 2 : 3);
- } else {
- this.meta = subtract[0].x == 0 ? 0 : 1;
+ if (delta1 == -1) {
+ return Orientation.ascending(face1);
+ } else if (delta2 == -1) {
+ return Orientation.ascending(face2);
}
}
- this.getLevel().setBlock(this, Block.get(this.getId(), this.getDamage()), true, true);
- }
-
- protected static Vector3[] checkRail(Block rail) {
- if (!(rail instanceof BlockRail)) return null;
- int damage = rail.getDamage();
- if (damage < 0 || damage > 10) return null;
- int[][][] delta = new int[][][]{
- {{0, 1}, {0, -1}},
- {{1, 0}, {-1, 0}},
- {{1, 0}, {-1, 0}},
- {{1, 0}, {-1, 0}},
- {{0, 1}, {0, -1}},
- {{0, 1}, {0, -1}},
- {{1, 0}, {0, 1}},
- {{0, 1}, {-1, 0}},
- {{-1, 0}, {0, -1}},
- {{0, -1}, {1, 0}}
- };
- int[] deltaY = new int[]{0, 1, -1};
- int[][] blocks = delta[damage];
- List connected = new ArrayList<>();
- for (int y : deltaY) {
- Vector3 v3 = new Vector3(
- rail.getFloorX() + blocks[0][0],
- rail.getFloorY() + y,
- rail.getFloorZ() + blocks[0][1]
- );
- int idToConnect = rail.getLevel().getBlockIdAt(v3.getFloorX(), v3.getFloorY(), v3.getFloorZ());
- int metaToConnect = rail.getLevel().getBlockDataAt(v3.getFloorX(), v3.getFloorY(), v3.getFloorZ());
- if (!isRailBlock(idToConnect) || !isValidRailMeta(metaToConnect)) continue;
- int xDiff = damage - v3.getFloorX();
- int zDiff = damage - v3.getFloorZ();
- for (int[] xz : blocks) {
- if (xz[0] != xDiff || xz[1] != zDiff) continue;
- connected.add(v3);
+ return straightOrCurved(face1, face2);
+ }
+
+ private Orientation connect(BlockRail other, BlockFace face) {
+ int delta = (int) (this.y - other.y);
+ Map rails = other.checkRailsConnected();
+ if (rails.isEmpty()) { //Only one
+ other.setOrientation(delta == 1 ? ascending(face.getOpposite()) : straight(face));
+ return delta == -1 ? ascending(face) : straight(face);
+ } else if (rails.size() == 1) { //Already connected
+ BlockFace faceConnected = rails.values().iterator().next();
+
+ if (other.isAbstract() && faceConnected != face) { //Curve!
+ other.setOrientation(curved(face.getOpposite(), faceConnected));
+ return delta == -1 ? ascending(face) : straight(face);
+ } else if (faceConnected == face) { //Turn!
+ if (!other.getOrientation().isAscending()) {
+ other.setOrientation(delta == 1 ? ascending(face.getOpposite()) : straight(face));
+ }
+ return delta == -1 ? ascending(face) : straight(face);
+ } else if (other.getOrientation().hasConnectingDirections(NORTH, SOUTH)) { //North-south
+ other.setOrientation(delta == 1 ? ascending(face.getOpposite()) : straight(face));
+ return delta == -1 ? ascending(face) : straight(face);
}
}
- for (int y : deltaY) {
- Vector3 v3 = new Vector3(
- rail.getFloorX() + blocks[1][0],
- rail.getFloorY() + y,
- rail.getFloorZ() + blocks[1][1]
- );
- int idToConnect = rail.getLevel().getBlockIdAt(v3.getFloorX(), v3.getFloorY(), v3.getFloorZ());
- int metaToConnect = rail.getLevel().getBlockDataAt(v3.getFloorX(), v3.getFloorY(), v3.getFloorZ());
- if (!isRailBlock(idToConnect) || !isValidRailMeta(metaToConnect)) continue;
- int xDiff = damage - v3.getFloorX();
- int zDiff = damage - v3.getFloorZ();
- for (int[] xz : blocks) {
- if (xz[0] != xDiff || xz[1] != zDiff) continue;
- connected.add(v3);
- }
+ return STRAIGHT_NORTH_SOUTH;
+ }
+
+ private Map checkRailsAroundAffected() {
+ Map railsAround = this.checkRailsAround(Arrays.asList(SOUTH, EAST, WEST, NORTH));
+ return railsAround.keySet().stream()
+ .filter(r -> r.checkRailsConnected().size() != 2)
+ .collect(Collectors.toMap(r -> r, railsAround::get));
+ }
+
+ private Map checkRailsAround(Collection faces) {
+ Map result = new HashMap<>();
+ faces.forEach(f -> {
+ Block b = this.getSide(f);
+ Stream.of(b, b.up(), b.down())
+ .filter(Rail::isRailBlock)
+ .forEach(block -> result.put((BlockRail) block, f));
+ });
+ return result;
+ }
+
+ protected Map checkRailsConnected() {
+ Map railsAround = this.checkRailsAround(this.getOrientation().connectingDirections());
+ return railsAround.keySet().stream()
+ .filter(r -> r.getOrientation().hasConnectingDirections(railsAround.get(r).getOpposite()))
+ .collect(Collectors.toMap(r -> r, railsAround::get));
+ }
+
+ public boolean isAbstract() {
+ return this.getId() == RAIL;
+ }
+
+ public boolean canPowered() {
+ return this.canBePowered;
+ }
+
+ public Orientation getOrientation() {
+ return byMetadata(this.getRealMeta());
+ }
+
+ public void setOrientation(Orientation o) {
+ if (o.metadata() != this.getRealMeta()) {
+ this.setDamage(o.metadata());
+ this.level.setBlock(this, this, true, true);
}
- return connected.toArray(new Vector3[connected.size()]);
- }
-
- protected static boolean isRailBlock(int id) {
- switch (id) {
- case RAIL:
- case POWERED_RAIL:
- case ACTIVATOR_RAIL:
- case DETECTOR_RAIL:
- return true;
- default:
- return false;
+ }
+
+ public int getRealMeta() {
+ // Check if this can be powered
+ // Avoid modifying the value from meta (The rail orientation may be false)
+ // Reason: When the rail is curved, the meta will return STRAIGHT_NORTH_SOUTH.
+ // OR Null Pointer Exception
+ if (!isAbstract()) {
+ return getDamage() & 0x7;
}
+ // Return the default: This meta
+ return getDamage();
}
- protected static boolean isValidRailMeta(int meta) {
- return !(meta < 0 || meta > 10);
+ public boolean isActive() {
+ return (getDamage() & 0x8) != 0;
}
-}
\ No newline at end of file
+ public void setActive(boolean active) {
+ if (active) {
+ setDamage(getDamage() | 0x8);
+ } else {
+ setDamage(getDamage() & 0x7);
+ }
+ level.setBlock(this, this, true, true);
+ }
+}
diff --git a/src/main/java/cn/nukkit/block/BlockRailActivator.java b/src/main/java/cn/nukkit/block/BlockRailActivator.java
index 020f84b704..c7c33339a9 100644
--- a/src/main/java/cn/nukkit/block/BlockRailActivator.java
+++ b/src/main/java/cn/nukkit/block/BlockRailActivator.java
@@ -1,5 +1,9 @@
package cn.nukkit.block;
+import cn.nukkit.level.Level;
+import cn.nukkit.math.Vector3;
+import cn.nukkit.utils.Rail;
+
/**
* @author Nukkit Project Team
*/
@@ -11,6 +15,7 @@ public BlockRailActivator(int meta) {
public BlockRailActivator() {
this(0);
+ canBePowered = true;
}
@Override
@@ -22,4 +27,142 @@ public String getName() {
public int getId() {
return ACTIVATOR_RAIL;
}
+
+ @Override
+ public int onUpdate(int type) {
+ if (type == Level.BLOCK_UPDATE_NORMAL || type == Level.BLOCK_UPDATE_REDSTONE || type == Level.BLOCK_UPDATE_SCHEDULED) {
+ super.onUpdate(type);
+ boolean wasPowered = isActive();
+ boolean isPowered = level.isBlockPowered(this)
+ || checkSurrounding(this, true, 0)
+ || checkSurrounding(this, false, 0);
+ boolean hasUpdate = false;
+
+ if (wasPowered != isPowered) {
+ setActive(isPowered);
+ hasUpdate = true;
+ }
+
+ if (hasUpdate) {
+ level.updateAround(down());
+ if (getOrientation().isAscending()) {
+ level.updateAround(up());
+ }
+ }
+ return type;
+ }
+ return 0;
+ }
+
+ /**
+ * Check the surrounding of the rail
+ *
+ * @param pos The rail position
+ * @param relative The relative of the rail that will be checked
+ * @param power The count of the rail that had been counted
+ * @return Boolean of the surrounding area. Where the powered rail on!
+ */
+ protected boolean checkSurrounding(Vector3 pos, boolean relative, int power) {
+ if (power >= 8) {
+ return false;
+ }
+ int dx = pos.getFloorX();
+ int dy = pos.getFloorY();
+ int dz = pos.getFloorZ();
+
+ BlockRail block;
+ Block block2 = level.getBlock(new Vector3(dx, dy, dz));
+
+ if (Rail.isRailBlock(block2)) {
+ block = (BlockRail) block2;
+ } else {
+ return false;
+ }
+
+ Rail.Orientation base = null;
+ boolean onStraight = true;
+
+ switch (block.getOrientation()) {
+ case STRAIGHT_NORTH_SOUTH:
+ if (relative) {
+ dz++;
+ } else {
+ dz--;
+ }
+ break;
+ case STRAIGHT_EAST_WEST:
+ if (relative) {
+ dx--;
+ } else {
+ dx++;
+ }
+ break;
+ case ASCENDING_EAST:
+ if (relative) {
+ dx--;
+ } else {
+ dx++;
+ dy++;
+ onStraight = false;
+ }
+ base = Rail.Orientation.STRAIGHT_EAST_WEST;
+ break;
+ case ASCENDING_WEST:
+ if (relative) {
+ dx--;
+ dy++;
+ onStraight = false;
+ } else {
+ dx++;
+ }
+ base = Rail.Orientation.STRAIGHT_EAST_WEST;
+ break;
+ case ASCENDING_NORTH:
+ if (relative) {
+ dz++;
+ } else {
+ dz--;
+ dy++;
+ onStraight = false;
+ }
+ base = Rail.Orientation.STRAIGHT_NORTH_SOUTH;
+ break;
+ case ASCENDING_SOUTH:
+ if (relative) {
+ dz++;
+ dy++;
+ onStraight = false;
+ } else {
+ dz--;
+ }
+ base = Rail.Orientation.STRAIGHT_NORTH_SOUTH;
+ break;
+ default:
+ return false;
+ }
+
+ return canPowered(new Vector3(dx, dy, dz), base, power, relative)
+ || onStraight && canPowered(new Vector3(dx, dy - 1, dz), base, power, relative);
+ }
+
+ protected boolean canPowered(Vector3 pos, Rail.Orientation state, int power, boolean relative) {
+ Block block = level.getBlock(pos);
+
+ if (!(block instanceof BlockRailActivator)) {
+ return false;
+ }
+
+ Rail.Orientation base = ((BlockRailActivator) block).getOrientation();
+
+ return (state != Rail.Orientation.STRAIGHT_EAST_WEST
+ || base != Rail.Orientation.STRAIGHT_NORTH_SOUTH
+ && base != Rail.Orientation.ASCENDING_NORTH
+ && base != Rail.Orientation.ASCENDING_SOUTH)
+ && (state != Rail.Orientation.STRAIGHT_NORTH_SOUTH
+ || base != Rail.Orientation.STRAIGHT_EAST_WEST
+ && base != Rail.Orientation.ASCENDING_EAST
+ && base != Rail.Orientation.ASCENDING_WEST)
+ && (level.isBlockPowered(pos) || checkSurrounding(pos, relative, power + 1));
+ }
+
}
diff --git a/src/main/java/cn/nukkit/block/BlockRailDetector.java b/src/main/java/cn/nukkit/block/BlockRailDetector.java
index 929acc68c7..563821914c 100644
--- a/src/main/java/cn/nukkit/block/BlockRailDetector.java
+++ b/src/main/java/cn/nukkit/block/BlockRailDetector.java
@@ -1,12 +1,24 @@
package cn.nukkit.block;
+import cn.nukkit.entity.Entity;
+import cn.nukkit.entity.item.EntityMinecartAbstract;
+import cn.nukkit.level.Level;
+import cn.nukkit.math.AxisAlignedBB;
+import cn.nukkit.math.BlockFace;
+
/**
* Created on 2015/11/22 by CreeperFace.
- * Package cn.nukkit.block in project Nukkit .
+ * Contributed by: larryTheCoder on 2017/7/8.
+ *
+ * Nukkit Project,
+ * Minecart and Riding Project,
+ * Package cn.nukkit.block in project Nukkit.
*/
public class BlockRailDetector extends BlockRail {
+
public BlockRailDetector() {
this(0);
+ canBePowered = true;
}
public BlockRailDetector(int meta) {
@@ -22,4 +34,64 @@ public int getId() {
public String getName() {
return "Detector Rail";
}
+
+ @Override
+ public boolean isPowerSource() {
+ return true;
+ }
+
+ @Override
+ public int getWeakPower(BlockFace side) {
+ return isActive() ? 15 : 0;
+ }
+
+ @Override
+ public int getStrongPower(BlockFace side) {
+ return isActive() ? 0 : (side == BlockFace.UP ? 15 : 0);
+ }
+
+ @Override
+ public int onUpdate(int type) {
+ if (type == Level.BLOCK_UPDATE_SCHEDULED) {
+ updateState();
+ return type;
+ }
+ return super.onUpdate(type);
+ }
+
+ @Override
+ public void onEntityCollide(Entity entity) {
+ updateState();
+ }
+
+ protected void updateState() {
+ boolean wasPowered = isActive();
+ boolean isPowered = false;
+
+ for (Entity entity : level.getNearbyEntities(new AxisAlignedBB(
+ getFloorX() + 0.125D,
+ getFloorY(),
+ getFloorZ() + 0.125D,
+ getFloorX() + 0.875D,
+ getFloorY() + 0.525D,
+ getFloorZ() + 0.875D))) {
+ if (entity instanceof EntityMinecartAbstract) {
+ isPowered = true;
+ }
+ }
+
+ if (isPowered && !wasPowered) {
+ setActive(true);
+ level.scheduleUpdate(this, this, 0);
+ level.scheduleUpdate(this, this.down(), 0);
+ }
+
+ if (!isPowered && wasPowered) {
+ setActive(false);
+ level.scheduleUpdate(this, this, 0);
+ level.scheduleUpdate(this, this.down(), 0);
+ }
+
+ level.updateComparatorOutputLevel(this);
+ }
}
diff --git a/src/main/java/cn/nukkit/block/BlockRailPowered.java b/src/main/java/cn/nukkit/block/BlockRailPowered.java
index dab96d3bde..bdd3966779 100644
--- a/src/main/java/cn/nukkit/block/BlockRailPowered.java
+++ b/src/main/java/cn/nukkit/block/BlockRailPowered.java
@@ -1,12 +1,22 @@
package cn.nukkit.block;
+import cn.nukkit.level.Level;
+import cn.nukkit.math.Vector3;
+import cn.nukkit.utils.Rail;
+
/**
- * Created by Snake1999 on 2016/1/11.
- * Package cn.nukkit.block in project nukkit
+ * Created by Snake1999 on 2016/1/11.
+ * Contributed by: larryTheCoder on 2017/7/18.
+ *
+ * Nukkit Project,
+ * Minecart and Riding Project,
+ * Package cn.nukkit.block in project Nukkit.
*/
public class BlockRailPowered extends BlockRail {
+
public BlockRailPowered() {
this(0);
+ canBePowered = true;
}
public BlockRailPowered(int meta) {
@@ -22,4 +32,151 @@ public int getId() {
public String getName() {
return "Powered Rail";
}
+
+ @Override
+ public int onUpdate(int type) {
+ // Warning: I din't recommended this on slow networks server or slow client
+ // Network below 86Kb/s. This will became unresponsive to clients
+ // When updating the block state. Espicially on the world with many rails.
+ // Trust me, I tested this on my server.
+ if (type == Level.BLOCK_UPDATE_NORMAL || type == Level.BLOCK_UPDATE_REDSTONE || type == Level.BLOCK_UPDATE_SCHEDULED) {
+ super.onUpdate(type);
+ boolean wasPowered = isActive();
+ boolean isPowered = level.isBlockPowered(this)
+ || checkSurrounding(this, true, 0)
+ || checkSurrounding(this, false, 0);
+
+ // Avoid Block minstake
+ if (wasPowered != isPowered) {
+ setActive(isPowered);
+ level.updateAround(down());
+ if (getOrientation().isAscending()) {
+ level.updateAround(up());
+ }
+ }
+ return type;
+ }
+ return 0;
+ }
+
+ /**
+ * Check the surrounding of the rail
+ *
+ * @param pos The rail position
+ * @param relative The relative of the rail that will be checked
+ * @param power The count of the rail that had been counted
+ * @return Boolean of the surrounding area. Where the powered rail on!
+ */
+ protected boolean checkSurrounding(Vector3 pos, boolean relative, int power) {
+ // The powered rail can power up to 8 blocks only
+ if (power >= 8) {
+ return false;
+ }
+ // The position of the floor numbers
+ int dx = pos.getFloorX();
+ int dy = pos.getFloorY();
+ int dz = pos.getFloorZ();
+ // First: get the base block
+ BlockRail block;
+ Block block2 = level.getBlock(new Vector3(dx, dy, dz));
+
+ // Second: check if the rail is Powered rail
+ if (Rail.isRailBlock(block2)) {
+ block = (BlockRail) block2;
+ } else {
+ return false;
+ }
+
+ // Used to check if the next ascending rail should be what
+ Rail.Orientation base = null;
+ boolean onStraight = true;
+ // Third: Recalculate the base position
+ switch (block.getOrientation()) {
+ case STRAIGHT_NORTH_SOUTH:
+ if (relative) {
+ dz++;
+ } else {
+ dz--;
+ }
+ break;
+ case STRAIGHT_EAST_WEST:
+ if (relative) {
+ dx--;
+ } else {
+ dx++;
+ }
+ break;
+ case ASCENDING_EAST:
+ if (relative) {
+ dx--;
+ } else {
+ dx++;
+ dy++;
+ onStraight = false;
+ }
+ base = Rail.Orientation.STRAIGHT_EAST_WEST;
+ break;
+ case ASCENDING_WEST:
+ if (relative) {
+ dx--;
+ dy++;
+ onStraight = false;
+ } else {
+ dx++;
+ }
+ base = Rail.Orientation.STRAIGHT_EAST_WEST;
+ break;
+ case ASCENDING_NORTH:
+ if (relative) {
+ dz++;
+ } else {
+ dz--;
+ dy++;
+ onStraight = false;
+ }
+ base = Rail.Orientation.STRAIGHT_NORTH_SOUTH;
+ break;
+ case ASCENDING_SOUTH:
+ if (relative) {
+ dz++;
+ dy++;
+ onStraight = false;
+ } else {
+ dz--;
+ }
+ base = Rail.Orientation.STRAIGHT_NORTH_SOUTH;
+ break;
+ default:
+ // Unable to determinate the rail orientation
+ // Wrong rail?
+ return false;
+ }
+ // Next check the if rail is on power state
+ return canPowered(new Vector3(dx, dy, dz), base, power, relative)
+ || onStraight && canPowered(new Vector3(dx, dy - 1, dz), base, power, relative);
+ }
+
+ protected boolean canPowered(Vector3 pos, Rail.Orientation state, int power, boolean relative) {
+ Block block = level.getBlock(pos);
+ // What! My block is air??!! Impossible! XD
+ if (!(block instanceof BlockRailPowered)) {
+ return false;
+ }
+
+ // Sometimes the rails are diffrent orientation
+ Rail.Orientation base = ((BlockRailPowered) block).getOrientation();
+
+ // Possible way how to know when the rail is activated is rail were directly powered
+ // OR recheck the surrounding... Which will returns here =w=
+ return (state != Rail.Orientation.STRAIGHT_EAST_WEST
+ || base != Rail.Orientation.STRAIGHT_NORTH_SOUTH
+ && base != Rail.Orientation.ASCENDING_NORTH
+ && base != Rail.Orientation.ASCENDING_SOUTH)
+ && (state != Rail.Orientation.STRAIGHT_NORTH_SOUTH
+ || base != Rail.Orientation.STRAIGHT_EAST_WEST
+ && base != Rail.Orientation.ASCENDING_EAST
+ && base != Rail.Orientation.ASCENDING_WEST)
+ && (level.isBlockPowered(pos) || checkSurrounding(pos, relative, power + 1));
+ }
+
}
diff --git a/src/main/java/cn/nukkit/block/BlockWaterStill.java b/src/main/java/cn/nukkit/block/BlockWaterStill.java
index 2f58d1dc59..1775eef3dc 100644
--- a/src/main/java/cn/nukkit/block/BlockWaterStill.java
+++ b/src/main/java/cn/nukkit/block/BlockWaterStill.java
@@ -1,7 +1,5 @@
package cn.nukkit.block;
-import cn.nukkit.level.Level;
-
/**
* author: Angelic47
* Nukkit Project
diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java
index 9a99a82fb8..0d810437ce 100644
--- a/src/main/java/cn/nukkit/entity/Entity.java
+++ b/src/main/java/cn/nukkit/entity/Entity.java
@@ -7,6 +7,7 @@
import cn.nukkit.block.BlockFire;
import cn.nukkit.block.BlockWater;
import cn.nukkit.entity.data.*;
+import cn.nukkit.entity.item.EntityVehicle;
import cn.nukkit.event.entity.*;
import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
import cn.nukkit.event.entity.EntityPortalEnterEvent.PortalType;
@@ -25,10 +26,7 @@
import cn.nukkit.nbt.tag.DoubleTag;
import cn.nukkit.nbt.tag.FloatTag;
import cn.nukkit.nbt.tag.ListTag;
-import cn.nukkit.network.protocol.MobEffectPacket;
-import cn.nukkit.network.protocol.RemoveEntityPacket;
-import cn.nukkit.network.protocol.SetEntityDataPacket;
-import cn.nukkit.network.protocol.SetEntityMotionPacket;
+import cn.nukkit.network.protocol.*;
import cn.nukkit.plugin.Plugin;
import cn.nukkit.potion.Effect;
import cn.nukkit.utils.ChunkException;
@@ -224,7 +222,11 @@ public abstract class Entity extends Location implements Metadatable {
public double lastYaw;
public double lastPitch;
-
+
+ public double PitchDelta;
+ public double YawDelta;
+
+ public double entityCollisionReduction = 0; // Higher than 0.9 will result a fast collisions
public AxisAlignedBB boundingBox;
public boolean onGround;
public boolean inBlock = false;
@@ -543,7 +545,7 @@ public void setScale(float scale) {
public float getScale() {
return this.scale;
}
-
+
public Entity getLinkedEntity() {
return linkedEntity;
}
@@ -587,9 +589,13 @@ public void addEffect(Effect effect) {
Effect oldEffect = this.effects.getOrDefault(effect.getId(), null);
if (oldEffect != null) {
- if (Math.abs(effect.getAmplifier()) < Math.abs(oldEffect.getAmplifier())) return;
+ if (Math.abs(effect.getAmplifier()) < Math.abs(oldEffect.getAmplifier())) {
+ return;
+ }
if (Math.abs(effect.getAmplifier()) == Math.abs(oldEffect.getAmplifier())
- && effect.getDuration() < oldEffect.getDuration()) return;
+ && effect.getDuration() < oldEffect.getDuration()) {
+ return;
+ }
effect.add(this, true);
} else {
effect.add(this, false);
@@ -1027,6 +1033,9 @@ public boolean entityBaseTick(int tickDiff) {
Timings.entityBaseTickTimer.stopTiming();
return false;
}
+ if (riding != null && !riding.isAlive()) {
+ ((EntityVehicle) riding).mountEntity(this);
+ }
if (!this.effects.isEmpty()) {
for (Effect effect : this.effects.values()) {
@@ -1178,6 +1187,53 @@ public boolean onUpdate(int currentTick) {
return hasUpdate;
}
+ protected boolean updateRidden() {
+ if (this.linkedEntity != null) {
+ if (!linkedEntity.isAlive()) {
+ return false;
+ }
+ this.motionX = 0.0D;
+ this.motionY = 0.0D;
+ this.motionZ = 0.0D;
+ onUpdate(lastUpdate);
+ if (this.linkedEntity != null) {
+ this.YawDelta += this.linkedEntity.yaw - this.linkedEntity.lastYaw;
+ for (this.PitchDelta += this.linkedEntity.pitch - this.linkedEntity.lastPitch; this.YawDelta >= 180.0D; this.YawDelta -= 360.0D) {
+ }
+ while (this.YawDelta < -180.0D) {
+ this.YawDelta += 360.0D;
+ }
+ while (this.PitchDelta >= 180.0D) {
+ this.PitchDelta -= 360.0D;
+ }
+ while (this.PitchDelta < -180.0D) {
+ this.PitchDelta += 360.0D;
+ }
+ double var1 = this.YawDelta * 0.5D;
+ double var3 = this.PitchDelta * 0.5D;
+ float var5 = 10.0F;
+ var1 = NukkitMath.clamp(var1, -var5, var5);
+ var3 = NukkitMath.clamp(var3, -var5, var5);
+ this.YawDelta -= var1;
+ this.PitchDelta -= var3;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ protected void updateRiderPosition(float offset) {
+ // Messy unknown variables
+ if (updateRidden()) {
+ linkedEntity.setDataProperty(new Vector3fEntityData(DATA_RIDER_SEAT_POSITION,
+ new Vector3f(0, offset, 0)));
+ }
+ }
+
+ public float getMountedYOffset() {
+ return getHeight() * 0.75F;
+ }
+
public final void scheduleUpdate() {
this.level.updateEntities.put(this.id, this);
}
@@ -1268,14 +1324,57 @@ public void handleLavaMovement() {
//todo
}
- public void moveFlying() {
- //todo
+ public void moveFlying(float strafe, float forward, float friction) {
+ // This is special for Nukkit! :)
+ float speed = strafe * strafe + forward * forward;
+ if (speed >= 1.0E-4F) {
+ speed = MathHelper.sqrt(speed);
+ if (speed < 1.0F) {
+ speed = 1.0F;
+ }
+ speed = friction / speed;
+ strafe *= speed;
+ forward *= speed;
+ float nest = MathHelper.sin((float) (this.yaw * 3.1415927F / 180.0F));
+ float place = MathHelper.cos((float) (this.yaw * 3.1415927F / 180.0F));
+ this.motionX += strafe * place - forward * nest;
+ this.motionZ += forward * place + strafe * nest;
+ }
}
public void onCollideWithPlayer(EntityHuman entityPlayer) {
}
+ public void applyEntityCollision(Entity entity) {
+ if (entity.riding != this && entity.linkedEntity != this) {
+ double dx = entity.x - this.x;
+ double dy = entity.z - this.z;
+ double dz = NukkitMath.getDirection(dx, dy);
+
+ if (dz >= 0.009999999776482582D) {
+ dz = MathHelper.sqrt((float) dz);
+ dx /= dz;
+ dy /= dz;
+ double d3 = 1.0D / dz;
+
+ if (d3 > 1.0D) {
+ d3 = 1.0D;
+ }
+
+ dx *= d3;
+ dy *= d3;
+ dx *= 0.05000000074505806D;
+ dy *= 0.05000000074505806D;
+ dx *= 1.0F + entityCollisionReduction;
+ dz *= 1.0F + entityCollisionReduction;
+ if (this.riding == null) {
+ setMotion(new Vector3(-dx, 0.0D, -dy));
+ }
+ }
+ }
+ }
+
public void onStruckByLightning(Entity entity) {
this.attack(new EntityDamageByEntityEvent(entity, this, DamageCause.LIGHTNING, 5));
@@ -1358,7 +1457,7 @@ public boolean isInsideOfFire() {
return false;
}
-
+
public boolean fastMove(double dx, double dy, double dz) {
if (dx == 0 && dy == 0 && dz == 0) {
return true;
@@ -1389,9 +1488,8 @@ public boolean fastMove(double dx, double dy, double dz) {
Timings.entityMoveTimer.stopTiming();
return true;
}
-
+
public boolean move(double dx, double dy, double dz) {
-
if (dx == 0 && dz == 0 && dy == 0) {
return true;
}
@@ -1435,7 +1533,6 @@ public boolean move(double dx, double dy, double dz) {
this.boundingBox.offset(0, 0, dz);
-
if (this.getStepHeight() > 0 && fallingFlag && this.ySize < 0.05 && (movX != dx || movZ != dz)) {
double cx = dx;
double cy = dy;
@@ -1502,7 +1599,6 @@ public boolean move(double dx, double dy, double dz) {
this.motionZ = 0;
}
-
//TODO: vehicle collision events (first we need to spawn them!)
Timings.entityMoveTimer.stopTiming();
return true;
@@ -1650,8 +1746,8 @@ public boolean setPosition(Vector3 pos) {
double radius = this.getWidth() / 2d;
- this.boundingBox.setBounds(pos.x - radius, pos.y, pos.z - radius, pos.x + radius, pos.y + (this.getHeight() * this.scale), pos.z +
- radius);
+ this.boundingBox.setBounds(pos.x - radius, pos.y, pos.z - radius, pos.x + radius, pos.y + (this.getHeight() * this.scale), pos.z
+ + radius);
this.checkChunks();
@@ -1671,9 +1767,9 @@ public boolean setMotion(Vector3 motion) {
}
}
- this.motionX = motion.x;
- this.motionY = motion.y;
- this.motionZ = motion.z;
+ this.motionX += motion.x;
+ this.motionY += motion.y;
+ this.motionZ += motion.z;
if (!this.justCreated) {
this.updateMovement();
@@ -1793,8 +1889,9 @@ public boolean setDataProperty(EntityData data) {
public boolean setDataProperty(EntityData data, boolean send) {
if (!Objects.equals(data, this.getDataProperties().get(data.getId()))) {
this.getDataProperties().put(data);
- if (send)
+ if (send) {
this.sendData(this.hasSpawned.values().stream().toArray(Player[]::new), new EntityMetadata().put(this.dataProperties.get(data.getId())));
+ }
return true;
}
return false;
diff --git a/src/main/java/cn/nukkit/entity/EntityInteractable.java b/src/main/java/cn/nukkit/entity/EntityInteractable.java
new file mode 100644
index 0000000000..c5946c0456
--- /dev/null
+++ b/src/main/java/cn/nukkit/entity/EntityInteractable.java
@@ -0,0 +1,20 @@
+package cn.nukkit.entity;
+
+import cn.nukkit.level.format.FullChunk;
+import cn.nukkit.nbt.tag.CompoundTag;
+
+/**
+ * @author Adam Matthew
+ */
+public abstract class EntityInteractable extends Entity {
+
+ public EntityInteractable(FullChunk chunk, CompoundTag nbt) {
+ super(chunk, nbt);
+ }
+
+ // Todo: Passive entity
+ public abstract String getInteractButton();
+
+ public abstract boolean canDoInteraction();
+
+}
diff --git a/src/main/java/cn/nukkit/entity/EntityLiving.java b/src/main/java/cn/nukkit/entity/EntityLiving.java
index 4550b1d155..b0f743eedf 100644
--- a/src/main/java/cn/nukkit/entity/EntityLiving.java
+++ b/src/main/java/cn/nukkit/entity/EntityLiving.java
@@ -4,6 +4,7 @@
import cn.nukkit.Server;
import cn.nukkit.block.Block;
import cn.nukkit.entity.data.ShortEntityData;
+import cn.nukkit.entity.item.EntityVehicle;
import cn.nukkit.entity.passive.EntityWaterAnimal;
import cn.nukkit.event.entity.*;
import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
@@ -23,10 +24,11 @@
import java.util.Map;
/**
- * author: MagicDroidX
+ * author: MagicDroidX
* Nukkit Project
*/
public abstract class EntityLiving extends Entity implements EntityDamageable {
+
public EntityLiving(FullChunk chunk, CompoundTag nbt) {
super(chunk, nbt);
}
@@ -86,6 +88,10 @@ public boolean hasLineOfSight(Entity entity) {
return true;
}
+ public void collidingWith(EntityVehicle ent) { // can override (IronGolem|Bats)
+ ent.applyEntityCollision(this);
+ }
+
@Override
public void heal(EntityRegainHealthEvent source) {
super.heal(source);
@@ -231,6 +237,14 @@ public boolean entityBaseTick(int tickDiff) {
if (this.attackTime > 0) {
this.attackTime -= tickDiff;
}
+ if (this.riding == null) {
+ for (Entity entity : level.getNearbyEntities(this.boundingBox.grow(0.20000000298023224D, 0.0D, 0.20000000298023224D), this)) {
+ if (entity instanceof EntityVehicle) {
+ this.collidingWith((EntityVehicle) entity);
+ }
+ }
+ }
+
Timings.livingEntityBaseTickTimer.stopTiming();
return hasUpdate;
diff --git a/src/main/java/cn/nukkit/entity/item/EntityBoat.java b/src/main/java/cn/nukkit/entity/item/EntityBoat.java
index ea2e3491ff..b050d4d413 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityBoat.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityBoat.java
@@ -1,19 +1,21 @@
package cn.nukkit.entity.item;
import cn.nukkit.Player;
-import cn.nukkit.Server;
import cn.nukkit.entity.Entity;
import cn.nukkit.event.entity.EntityDamageByEntityEvent;
import cn.nukkit.event.entity.EntityDamageEvent;
+import cn.nukkit.event.vehicle.VehicleDamageEvent;
+import cn.nukkit.event.vehicle.VehicleDestroyEvent;
+import cn.nukkit.event.vehicle.VehicleMoveEvent;
+import cn.nukkit.event.vehicle.VehicleUpdateEvent;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemBoat;
+import cn.nukkit.level.Location;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.level.particle.SmokeParticle;
import cn.nukkit.math.Vector3;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.network.protocol.AddEntityPacket;
-import cn.nukkit.network.protocol.EntityEventPacket;
-import cn.nukkit.network.protocol.SetEntityLinkPacket;
/**
* Created by yescallop on 2016/2/13.
@@ -58,6 +60,11 @@ protected float getGravity() {
return 0.1f;
}
+ @Override
+ public float getBaseOffset() {
+ return 0.35F;
+ }
+
@Override
public int getNetworkId() {
return NETWORK_ID;
@@ -85,31 +92,45 @@ public void spawnTo(Player player) {
@Override
public boolean attack(EntityDamageEvent source) {
- if (super.attack(source)) {
- if (source instanceof EntityDamageByEntityEvent) {
- Entity damager = ((EntityDamageByEntityEvent) source).getDamager();
- if (damager instanceof Player) {
- if (((Player) damager).isCreative()) {
- this.kill();
- }
- if (this.getHealth() <= 0) {
- if (((Player) damager).isSurvival() && this.level.getGameRules().getBoolean("doEntityDrops")) {
- this.level.dropItem(this, new ItemBoat());
- }
- this.close();
+ if (invulnerable) {
+ return false;
+ } else {
+ // Event start
+ VehicleDamageEvent event = new VehicleDamageEvent(this, source.getEntity(), source.getFinalDamage());
+ getServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return false;
+ }
+ // Event stop
+ performHurtAnimation((int) event.getDamage());
+
+ Entity damager = ((EntityDamageByEntityEvent) source).getDamager();
+ boolean instantKill = damager instanceof Player
+ ? ((Player) damager).isCreative() : false;
+ if (instantKill || getDamage() > 40) {
+ // Event start
+ VehicleDestroyEvent event2 = new VehicleDestroyEvent(this, source.getEntity());
+ getServer().getPluginManager().callEvent(event2);
+ if (event2.isCancelled()) {
+ return false;
+ }
+ // Event stop
+ if (linkedEntity != null) {
+ mountEntity(linkedEntity);
+ }
+
+ if (instantKill && (!hasCustomName())) {
+ kill();
+ } else {
+ if (level.getGameRules().getBoolean("doEntityDrops")) {
+ this.level.dropItem(this, new ItemBoat());
}
+ close();
}
}
-
- EntityEventPacket pk = new EntityEventPacket();
- pk.eid = this.getId();
- pk.event = this.getHealth() <= 0 ? EntityEventPacket.DEATH_ANIMATION : EntityEventPacket.HURT_ANIMATION;
- Server.broadcastPacket(this.hasSpawned.values(), pk);
-
- return true;
- } else {
- return false;
}
+
+ return true;
}
@Override
@@ -141,7 +162,8 @@ public boolean onUpdate(int currentTick) {
boolean hasUpdate = this.entityBaseTick(tickDiff);
if (this.isAlive()) {
-
+ super.onUpdate(currentTick);
+
this.motionY = (this.level.getBlock(new Vector3(this.x, this.y, this.z)).getBoundingBox() != null || this.isInsideOfWater()) ? getGravity() : -0.08;
if (this.checkObstruction(this.x, this.y, this.z)) {
@@ -164,6 +186,15 @@ public boolean onUpdate(int currentTick) {
this.motionY *= -0.5;
}
+ Location from = new Location(lastX, lastY, lastZ, lastYaw, lastPitch, level);
+ Location to = new Location(this.x, this.y, this.z, this.yaw, this.pitch, level);
+
+ this.getServer().getPluginManager().callEvent(new VehicleUpdateEvent(this));
+
+ if (!from.equals(to)) {
+ this.getServer().getPluginManager().callEvent(new VehicleMoveEvent(this, from, to));
+ }
+
this.updateMovement();
}
@@ -176,24 +207,7 @@ public boolean onInteract(Player player, Item item) {
return false;
}
- SetEntityLinkPacket pk;
-
- pk = new SetEntityLinkPacket();
- pk.rider = this.getId(); //WTF
- pk.riding = player.getId();
- pk.type = 2;
- Server.broadcastPacket(this.hasSpawned.values(), pk);
-
- pk = new SetEntityLinkPacket();
- pk.rider = this.getId();
- pk.riding = 0;
- pk.type = 2;
- player.dataPacket(pk);
-
- player.riding = this;
- this.linkedEntity = player;
-
- player.setDataFlag(DATA_FLAGS, DATA_FLAG_RIDING, true);
+ super.mountEntity(player);
return true;
}
}
\ No newline at end of file
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
new file mode 100644
index 0000000000..cea03f10e9
--- /dev/null
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
@@ -0,0 +1,849 @@
+package cn.nukkit.entity.item;
+
+import cn.nukkit.Player;
+import cn.nukkit.api.API;
+import cn.nukkit.api.API.Definition;
+import cn.nukkit.api.API.Usage;
+import cn.nukkit.block.Block;
+import cn.nukkit.block.BlockRail;
+import cn.nukkit.block.BlockRailActivator;
+import cn.nukkit.block.BlockRailPowered;
+import cn.nukkit.entity.Entity;
+import cn.nukkit.entity.EntityHuman;
+import cn.nukkit.entity.EntityLiving;
+import cn.nukkit.entity.data.ByteEntityData;
+import cn.nukkit.entity.data.IntEntityData;
+import cn.nukkit.event.entity.EntityDamageByEntityEvent;
+import cn.nukkit.event.entity.EntityDamageEvent;
+import cn.nukkit.event.vehicle.VehicleDamageEvent;
+import cn.nukkit.event.vehicle.VehicleDestroyEvent;
+import cn.nukkit.event.vehicle.VehicleMoveEvent;
+import cn.nukkit.event.vehicle.VehicleUpdateEvent;
+import cn.nukkit.item.Item;
+import cn.nukkit.item.ItemMinecart;
+import cn.nukkit.level.Location;
+import cn.nukkit.level.format.FullChunk;
+import cn.nukkit.level.particle.SmokeParticle;
+import cn.nukkit.math.MathHelper;
+import cn.nukkit.math.NukkitMath;
+import cn.nukkit.math.Vector3;
+import cn.nukkit.nbt.tag.CompoundTag;
+import cn.nukkit.network.protocol.AddEntityPacket;
+import cn.nukkit.utils.EnumMinecart;
+import cn.nukkit.utils.Rail;
+import cn.nukkit.utils.Rail.Orientation;
+
+import java.util.Objects;
+
+/**
+ * Created by: larryTheCoder on 2017/6/26.
+ *
+ * Nukkit Project,
+ * Minecart and Riding Project,
+ * Package cn.nukkit.entity.item in project Nukkit.
+ */
+public abstract class EntityMinecartAbstract extends EntityVehicle {
+
+ private String entityName;
+ public final int[][][] matrix = new int[][][]{
+ {{0, 0, -1}, {0, 0, 1}},
+ {{-1, 0, 0}, {1, 0, 0}},
+ {{-1, -1, 0}, {1, 0, 0}},
+ {{-1, 0, 0}, {1, -1, 0}},
+ {{0, 0, -1}, {0, -1, 1}},
+ {{0, -1, -1}, {0, 0, 1}},
+ {{0, 0, 1}, {1, 0, 0}},
+ {{0, 0, 1}, {-1, 0, 0}},
+ {{0, 0, -1}, {-1, 0, 0}},
+ {{0, 0, -1}, {1, 0, 0}}
+ };
+ private double currentSpeed = 0;
+ protected Block blockInside = null;
+ // Plugins modifiers
+ public boolean slowWhenEmpty = true;
+ private double derailedX = 0.5;
+ private double derailedY = 0.5;
+ private double derailedZ = 0.5;
+ private double flyingX = 0.95;
+ private double flyingY = 0.95;
+ private double flyingZ = 0.95;
+ private double maxSpeed = 0.4D;
+ private final boolean devs = false; // Avoid maintained features into production
+
+ public abstract EnumMinecart getType();
+
+ public EntityMinecartAbstract(FullChunk chunk, CompoundTag nbt) {
+ super(chunk, nbt);
+ }
+
+ @Override
+ public float getHeight() {
+ return 0.7F;
+ }
+
+ @Override
+ public float getWidth() {
+ return 0.98F;
+ }
+
+ @Override
+ protected float getDrag() {
+ return 0.1F;
+ }
+
+ public void setName(String name) {
+ entityName = name;
+ }
+
+ @Override
+ public String getName() {
+ return entityName;
+ }
+
+ @Override
+ public float getBaseOffset() {
+ return 0.35F;
+ }
+
+ @Override
+ public boolean hasCustomName() {
+ return entityName != null;
+ }
+
+ @Override
+ public boolean canDoInteraction() {
+ return linkedEntity == null && this.getDisplayBlock() == null;
+ }
+
+ @Override
+ public float getMountedYOffset() {
+ return 0.45F; // Real minecart offset
+ }
+
+ @Override
+ public void initEntity() {
+ super.initEntity();
+
+ prepareDataProperty();
+ }
+
+ @Override
+ public boolean onUpdate(int currentTick) {
+ if (this.closed) {
+ return false;
+ }
+
+ if (!this.isAlive()) {
+ ++this.deadTicks;
+ if (this.deadTicks >= 10) {
+ this.despawnFromAll();
+ this.close();
+ }
+ return this.deadTicks < 10;
+ }
+
+ int tickDiff = currentTick - this.lastUpdate;
+
+ if (tickDiff <= 0) {
+ return false;
+ }
+
+ this.lastUpdate = currentTick;
+
+ if (isAlive()) {
+ super.onUpdate(currentTick);
+
+ // Entity variables
+ lastX = x;
+ lastY = y;
+ lastZ = z;
+ motionY -= 0.03999999910593033D;
+ int dx = MathHelper.floor(x);
+ int dy = MathHelper.floor(y);
+ int dz = MathHelper.floor(z);
+
+ // Some hack to check rails
+ if (Rail.isRailBlock(level.getBlockIdAt(dx, dy - 1, dz))) {
+ --dy;
+ }
+
+ Block block = level.getBlock(new Vector3(dx, dy, dz));
+
+ // Ensure that the block is a rail
+ if (Rail.isRailBlock(block)) {
+ processMovement(dx, dy, dz, (BlockRail) block);
+ if (block instanceof BlockRailActivator) {
+ // Activate the minecart/TNT
+ activate(dx, dy, dz, (block.getDamage() & 0x8) != 0);
+ }
+ } else {
+ setFalling();
+ }
+ checkBlockCollision();
+
+ // Minecart head
+ pitch = 0;
+ double diffX = this.lastX - this.x;
+ double diffZ = this.lastZ - this.z;
+ double yawToChange = yaw;
+ if (diffX * diffX + diffZ * diffZ > 0.001D) {
+ yawToChange = (Math.atan2(diffZ, diffX) * 180 / 3.141592653589793D);
+ }
+
+ // Reverse yaw if yaw is below 0
+ if (yawToChange < 0) {
+ // -90-(-90)-(-90) = 90
+ yawToChange -= yawToChange - yawToChange;
+ }
+
+ setRotation(yawToChange, pitch);
+
+ Location from = new Location(lastX, lastY, lastZ, lastYaw, lastPitch, level);
+ Location to = new Location(this.x, this.y, this.z, this.yaw, this.pitch, level);
+
+ this.getServer().getPluginManager().callEvent(new VehicleUpdateEvent(this));
+
+ if (!from.equals(to)) {
+ this.getServer().getPluginManager().callEvent(new VehicleMoveEvent(this, from, to));
+ }
+
+ // Collisions
+ for (Entity entity : level.getNearbyEntities(boundingBox.grow(0.2D, 0, 0.2D), this)) {
+ if (entity != linkedEntity && entity instanceof EntityMinecartAbstract) {
+ entity.applyEntityCollision(this);
+ }
+ }
+
+ // Easier
+ if ((linkedEntity != null) && (!linkedEntity.isAlive())) {
+ if (linkedEntity.riding == this) {
+ linkedEntity.riding = null;
+ }
+ linkedEntity = null;
+ }
+ // No need to onGround or Motion diff! This always have an update
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean attack(EntityDamageEvent source) {
+ if (invulnerable) {
+ return false;
+ } else {
+ // Event start
+ VehicleDamageEvent event = new VehicleDamageEvent(this, source.getEntity(), source.getFinalDamage());
+ getServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return false;
+ }
+ // Event stop
+ Entity damager = ((EntityDamageByEntityEvent) source).getDamager();
+ boolean instantKill = damager instanceof Player && ((Player) damager).isCreative();
+ performHurtAnimation(instantKill ? 9999 : (int) event.getDamage());
+
+ if (instantKill || getDamage() > 40) {
+ // Event start
+ VehicleDestroyEvent event2 = new VehicleDestroyEvent(this, source.getEntity());
+ getServer().getPluginManager().callEvent(event2);
+ if (event2.isCancelled()) {
+ return false;
+ }
+ // Event stop
+ if (linkedEntity != null) {
+ mountEntity(linkedEntity);
+ }
+
+ if (instantKill && (!hasCustomName())) {
+ kill();
+ } else {
+ if (level.getGameRules().getBoolean("doEntityDrops")) {
+ dropItem();
+ }
+ close();
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public void dropItem() {
+ level.dropItem(this, new ItemMinecart());
+ }
+
+ @Override
+ public void close() {
+ super.close();
+
+ if (linkedEntity instanceof Player) {
+ linkedEntity.riding = null;
+ linkedEntity = null;
+ }
+
+ SmokeParticle particle = new SmokeParticle(this);
+ level.addParticle(particle);
+ }
+
+ @Override
+ public boolean onInteract(Player p, Item item) {
+ if (linkedEntity != null) {
+ return false;
+ }
+
+ if (blockInside == null) {
+ mountEntity(p); // Simple
+ }
+ return true;
+ }
+
+ @Override
+ public void spawnTo(Player player) {
+ AddEntityPacket pk = new AddEntityPacket();
+ pk.entityUniqueId = getId();
+ pk.entityRuntimeId = getId();
+ pk.type = getNetworkId();
+ pk.x = (float) x;
+ pk.y = (float) y;
+ pk.z = (float) z;
+ pk.speedX = 0;
+ pk.speedY = 0;
+ pk.speedZ = 0;
+ pk.yaw = 0;
+ pk.pitch = 0;
+ pk.metadata = dataProperties;
+ player.dataPacket(pk);
+
+ super.spawnTo(player);
+ }
+
+ @Override
+ public void applyEntityCollision(Entity entity) {
+ if (entity != riding) {
+ if (entity instanceof EntityLiving
+ && !(entity instanceof EntityHuman)
+ && motionX * motionX + motionZ * motionZ > 0.01D
+ && linkedEntity == null
+ && entity.riding == null
+ && blockInside == null) {
+ if (riding == null && devs) {
+ mountEntity(entity);// TODO: rewrite (weird riding)
+ }
+ }
+
+ double motiveX = entity.x - x;
+ double motiveZ = entity.z - z;
+ double square = motiveX * motiveX + motiveZ * motiveZ;
+
+ if (square >= 9.999999747378752E-5D) {
+ square = Math.sqrt(square);
+ motiveX /= square;
+ motiveZ /= square;
+ double next = 1 / square;
+
+ if (next > 1) {
+ next = 1;
+ }
+
+ motiveX *= next;
+ motiveZ *= next;
+ motiveX *= 0.10000000149011612D;
+ motiveZ *= 0.10000000149011612D;
+ motiveX *= 1 + entityCollisionReduction;
+ motiveZ *= 1 + entityCollisionReduction;
+ motiveX *= 0.5D;
+ motiveZ *= 0.5D;
+ if (entity instanceof EntityMinecartAbstract) {
+ EntityMinecartAbstract mine = (EntityMinecartAbstract) entity;
+ double desinityX = mine.x - x;
+ double desinityZ = mine.z - z;
+ Vector3 vector = new Vector3(desinityX, 0, desinityZ).normalize();
+ Vector3 vec = new Vector3((double) MathHelper.cos((float) yaw * 0.017453292F), 0, (double) MathHelper.sin((float) yaw * 0.017453292F)).normalize();
+ double desinityXZ = Math.abs(vector.dot(vec));
+
+ if (desinityXZ < 0.800000011920929D) {
+ return;
+ }
+
+ double motX = mine.motionX + motionX;
+ double motZ = mine.motionZ + motionZ;
+
+ if (mine.getType().getId() == 2 && getType().getId() != 2) {
+ motionX *= 0.20000000298023224D;
+ motionZ *= 0.20000000298023224D;
+ setMotion(new Vector3(mine.motionX - motiveX, 0, mine.motionZ - motiveZ));
+ mine.motionX *= 0.949999988079071D;
+ mine.motionZ *= 0.949999988079071D;
+ } else if (mine.getType().getId() != 2 && getType().getId() == 2) {
+ mine.motionX *= 0.20000000298023224D;
+ mine.motionZ *= 0.20000000298023224D;
+ mine.setMotion(new Vector3(motionX + motiveX, 0, motionZ + motiveZ));
+ motionX *= 0.949999988079071D;
+ motionZ *= 0.949999988079071D;
+ } else {
+ motX /= 2;
+ motZ /= 2;
+ motionX *= 0.20000000298023224D;
+ motionZ *= 0.20000000298023224D;
+ setMotion(new Vector3(motX - motiveX, 0, motZ - motiveZ));
+ mine.motionX *= 0.20000000298023224D;
+ mine.motionZ *= 0.20000000298023224D;
+ mine.setMotion(new Vector3(motX + motiveX, 0, motZ + motiveZ));
+ }
+ } else {
+ setMotion(new Vector3(-motiveX, 0, -motiveZ));
+ }
+ }
+ }
+ }
+
+ @Override
+ public void saveNBT() {
+ super.saveNBT();
+
+ saveEntityData();
+ }
+
+ public double getMaxSpeed() {
+ return maxSpeed;
+ }
+
+ protected void activate(int x, int y, int z, boolean flag) {
+ }
+
+ protected boolean hasUpdated = false;
+
+ protected void setFalling() {
+ motionX = NukkitMath.clamp(motionX, -getMaxSpeed(), getMaxSpeed());
+ motionZ = NukkitMath.clamp(motionZ, -getMaxSpeed(), getMaxSpeed());
+
+ if(linkedEntity != null && !hasUpdated){
+ updateRiderPosition(getMountedYOffset() + 0.35F);
+ hasUpdated = true;
+ } else {
+ hasUpdated = false;
+ }
+
+ if (onGround) {
+ motionX *= derailedX;
+ motionY *= derailedY;
+ motionZ *= derailedZ;
+ }
+
+ move(motionX, motionY, motionZ);
+ if (!onGround) {
+ motionX *= flyingX;
+ motionY *= flyingY;
+ motionZ *= flyingZ;
+ }
+ }
+
+ protected void processMovement(int dx, int dy, int dz, BlockRail block) {
+ fallDistance = 0.0F;
+ Vector3 vector = getNextRail(x, y, z);
+
+ y = (double) dy;
+ boolean isPowered = false;
+ boolean isSlowed = false;
+
+ if (block instanceof BlockRailPowered) {
+ isPowered = block.isActive();
+ isSlowed = !block.isActive();
+ }
+
+ switch (Orientation.byMetadata(((BlockRail) block).getRealMeta())) {
+ case ASCENDING_NORTH:
+ motionX -= 0.0078125D;
+ y += 1;
+ break;
+ case ASCENDING_SOUTH:
+ motionX += 0.0078125D;
+ y += 1;
+ break;
+ case ASCENDING_EAST:
+ motionZ += 0.0078125D;
+ y += 1;
+ break;
+ case ASCENDING_WEST:
+ motionZ -= 0.0078125D;
+ y += 1;
+ break;
+ }
+
+ int[][] facing = matrix[block.getRealMeta()];
+ double facing1 = (double) (facing[1][0] - facing[0][0]);
+ double facing2 = (double) (facing[1][2] - facing[0][2]);
+ double speedOnTurns = Math.sqrt(facing1 * facing1 + facing2 * facing2);
+ double realFacing = motionX * facing1 + motionZ * facing2;
+
+ if (realFacing < 0) {
+ facing1 = -facing1;
+ facing2 = -facing2;
+ }
+
+ double squareOfFame = Math.sqrt(motionX * motionX + motionZ * motionZ);
+
+ if (squareOfFame > 2) {
+ squareOfFame = 2;
+ }
+
+ motionX = squareOfFame * facing1 / speedOnTurns;
+ motionZ = squareOfFame * facing2 / speedOnTurns;
+ double expectedSpeed;
+ double playerYawNeg; // PlayerYawNegative
+ double playerYawPos; // PlayerYawPositive
+ double motion;
+
+ if (linkedEntity != null && linkedEntity instanceof EntityLiving) {
+ expectedSpeed = currentSpeed;
+ if (expectedSpeed > 0) {
+ // This is a trajectory (Angle of elevation)
+ playerYawNeg = -Math.sin((double) (linkedEntity.yaw * 3.1415927F / 180.0F));
+ playerYawPos = Math.cos((double) (linkedEntity.yaw * 3.1415927F / 180.0F));
+ motion = motionX * motionX + motionZ * motionZ;
+ if (motion < 0.01D) {
+ motionX += playerYawNeg * 0.1D;
+ motionZ += playerYawPos * 0.1D;
+
+ isSlowed = false;
+ }
+ }
+ }
+
+ //http://minecraft.gamepedia.com/Powered_Rail#Rail
+ if (isSlowed) {
+ expectedSpeed = Math.sqrt(motionX * motionX + motionZ * motionZ);
+ if (expectedSpeed < 0.03D) {
+ motionX *= 0;
+ motionY *= 0;
+ motionZ *= 0;
+ } else {
+ motionX *= 0.5D;
+ motionY *= 0;
+ motionZ *= 0.5D;
+ }
+ }
+
+ playerYawNeg = (double) dx + 0.5D + (double) facing[0][0] * 0.5D;
+ playerYawPos = (double) dz + 0.5D + (double) facing[0][2] * 0.5D;
+ motion = (double) dx + 0.5D + (double) facing[1][0] * 0.5D;
+ double wallOfFame = (double) dz + 0.5D + (double) facing[1][2] * 0.5D;
+
+ facing1 = motion - playerYawNeg;
+ facing2 = wallOfFame - playerYawPos;
+ double motX;
+ double motZ;
+
+ if (facing1 == 0) {
+ x = (double) dx + 0.5D;
+ expectedSpeed = z - (double) dz;
+ } else if (facing2 == 0) {
+ z = (double) dz + 0.5D;
+ expectedSpeed = x - (double) dx;
+ } else {
+ motX = x - playerYawNeg;
+ motZ = z - playerYawPos;
+ expectedSpeed = (motX * facing1 + motZ * facing2) * 2;
+ }
+
+ x = playerYawNeg + facing1 * expectedSpeed;
+ z = playerYawPos + facing2 * expectedSpeed;
+ setPosition(new Vector3(x, y, z)); // Hehe, my minstake :3
+
+ motX = motionX;
+ motZ = motionZ;
+ if (linkedEntity != null) {
+ motX *= 0.75D;
+ motZ *= 0.75D;
+ }
+ motX = NukkitMath.clamp(motX, -getMaxSpeed(), getMaxSpeed());
+ motZ = NukkitMath.clamp(motZ, -getMaxSpeed(), getMaxSpeed());
+
+ move(motX, 0, motZ);
+ if (facing[0][1] != 0 && MathHelper.floor(x) - dx == facing[0][0] && MathHelper.floor(z) - dz == facing[0][2]) {
+ setPosition(new Vector3(x, y + (double) facing[0][1], z));
+ } else if (facing[1][1] != 0 && MathHelper.floor(x) - dx == facing[1][0] && MathHelper.floor(z) - dz == facing[1][2]) {
+ setPosition(new Vector3(x, y + (double) facing[1][1], z));
+ }
+
+ applyDrag();
+ Vector3 vector1 = getNextRail(x, y, z);
+
+ if (vector1 != null && vector != null) {
+ double d14 = (vector.y - vector1.y) * 0.05D;
+
+ squareOfFame = Math.sqrt(motionX * motionX + motionZ * motionZ);
+ if (squareOfFame > 0) {
+ motionX = motionX / squareOfFame * (squareOfFame + d14);
+ motionZ = motionZ / squareOfFame * (squareOfFame + d14);
+ }
+
+ setPosition(new Vector3(x, vector1.y, z));
+ }
+
+ int floorX = MathHelper.floor(x);
+ int floorZ = MathHelper.floor(z);
+
+ if (floorX != dx || floorZ != dz) {
+ squareOfFame = Math.sqrt(motionX * motionX + motionZ * motionZ);
+ motionX = squareOfFame * (double) (floorX - dx);
+ motionZ = squareOfFame * (double) (floorZ - dz);
+ }
+
+ if (isPowered) {
+ double newMovie = Math.sqrt(motionX * motionX + motionZ * motionZ);
+
+ if (newMovie > 0.01D) {
+ double nextMovie = 0.06D;
+
+ motionX += motionX / newMovie * nextMovie;
+ motionZ += motionZ / newMovie * nextMovie;
+ } else if (block.getOrientation() == Orientation.STRAIGHT_NORTH_SOUTH) {
+ if (level.getBlock(new Vector3(dx - 1, dy, dz)).isNormalBlock()) {
+ motionX = 0.02D;
+ } else if (level.getBlock(new Vector3(dx + 1, dy, dz)).isNormalBlock()) {
+ motionX = -0.02D;
+ }
+ } else if (block.getOrientation() == Orientation.STRAIGHT_EAST_WEST) {
+ if (level.getBlock(new Vector3(dx, dy, dz - 1)).isNormalBlock()) {
+ motionZ = 0.02D;
+ } else if (level.getBlock(new Vector3(dx, dy, dz + 1)).isNormalBlock()) {
+ motionZ = -0.02D;
+ }
+ }
+ }
+
+ }
+
+ protected void applyDrag() {
+ if (linkedEntity != null || !slowWhenEmpty) {
+ motionX *= 0.996999979019165D;
+ motionY *= 0.0D;
+ motionZ *= 0.996999979019165D;
+ } else {
+ motionX *= 0.9599999785423279D;
+ motionY *= 0.0D;
+ motionZ *= 0.9599999785423279D;
+ }
+ }
+
+ public Vector3 getNextRail(double dx, double dy, double dz) {
+ int checkX = MathHelper.floor(dx);
+ int checkY = MathHelper.floor(dy);
+ int checkZ = MathHelper.floor(dz);
+
+ if (Rail.isRailBlock(level.getBlockIdAt(checkX, checkY - 1, checkZ))) {
+ --checkY;
+ }
+
+ Block block = level.getBlock(new Vector3(checkX, checkY, checkZ));
+
+ if (Rail.isRailBlock(block)) {
+ int[][] facing = matrix[((BlockRail) block).getRealMeta()];
+ double rail;
+ // Genisys minstake (Doesn't check surrounding more exactly)
+ double nextOne = (double) checkX + 0.5D + (double) facing[0][0] * 0.5D;
+ double nextTwo = (double) checkY + 0.5D + (double) facing[0][1] * 0.5D;
+ double nextThree = (double) checkZ + 0.5D + (double) facing[0][2] * 0.5D;
+ double nextFour = (double) checkX + 0.5D + (double) facing[1][0] * 0.5D;
+ double nextFive = (double) checkY + 0.5D + (double) facing[1][1] * 0.5D;
+ double nextSix = (double) checkZ + 0.5D + (double) facing[1][2] * 0.5D;
+ double nextSeven = nextFour - nextOne;
+ double nextEight = (nextFive - nextTwo) * 2;
+ double nextMax = nextSix - nextThree;
+
+ if (nextSeven == 0) {
+ rail = dz - (double) checkZ;
+ } else if (nextMax == 0) {
+ rail = dx - (double) checkX;
+ } else {
+ double whatOne = dx - nextOne;
+ double whatTwo = dz - nextThree;
+
+ rail = (whatOne * nextSeven + whatTwo * nextMax) * 2;
+ }
+
+ dx = nextOne + nextSeven * rail;
+ dy = nextTwo + nextEight * rail;
+ dz = nextThree + nextMax * rail;
+ if (nextEight < 0) {
+ ++dy;
+ }
+
+ if (nextEight > 0) {
+ dy += 0.5D;
+ }
+
+ return new Vector3(dx, dy, dz);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Used to multiply the minecart current speed
+ *
+ * @param speed The speed of the minecart that will be calculated
+ */
+ public void setCurrentSpeed(double speed) {
+ currentSpeed = speed;
+ }
+
+ public double wrapAngleTo180(double rotation) {
+ rotation %= 360;
+ if (rotation >= 180) {
+ rotation -= 360;
+ }
+
+ if (rotation < -180) {
+ rotation += 360;
+ }
+
+ return rotation;
+ }
+
+ private void prepareDataProperty() {
+ setRollingAmplitude(0);
+ setRollingDirection(1);
+ setDamage(0);
+ if (namedTag.contains("CustomDisplayTile")) {
+ if (namedTag.getBoolean("CustomDisplayTile")) {
+ int display = namedTag.getInt("DisplayTile");
+ int offSet = namedTag.getInt("DisplayOffset");
+ setDataProperty(new ByteEntityData(DATA_MINECART_HAS_DISPLAY, 1));
+ setDataProperty(new IntEntityData(DATA_MINECART_DISPLAY_BLOCK, display));
+ setDataProperty(new IntEntityData(DATA_MINECART_DISPLAY_OFFSET, offSet));
+ }
+ } else {
+ int display = blockInside == null ? 0
+ : blockInside.getId()
+ | blockInside.getDamage() << 16;
+ if (display == 0) {
+ setDataProperty(new ByteEntityData(DATA_MINECART_HAS_DISPLAY, 0));
+ return;
+ }
+ setDataProperty(new ByteEntityData(DATA_MINECART_HAS_DISPLAY, 1));
+ setDataProperty(new IntEntityData(DATA_MINECART_DISPLAY_BLOCK, display));
+ setDataProperty(new IntEntityData(DATA_MINECART_DISPLAY_OFFSET, 6));
+ }
+ }
+
+ private void saveEntityData() {
+ boolean hasDisplay = super.getDataPropertyByte(DATA_MINECART_HAS_DISPLAY) == 1
+ || blockInside != null;
+ int display;
+ int offSet;
+ namedTag.putBoolean("CustomDisplayTile", hasDisplay);
+ if (hasDisplay) {
+ display = blockInside.getId()
+ | blockInside.getDamage() << 16;
+ offSet = getDataPropertyInt(DATA_MINECART_DISPLAY_OFFSET);
+ namedTag.putInt("DisplayTile", display);
+ namedTag.putInt("DisplayOffset", offSet);
+ }
+ }
+
+ /**
+ * Set the minecart display block!
+ *
+ * @param block The block that will changed. Set {@code null} for BlockAir
+ * @return {@code true} if the block is normal block
+ */
+ @API(usage = Usage.MAINTAINED, definition = Definition.UNIVERSAL)
+ public boolean setDisplayBlock(Block block) {
+ if (block != null) {
+ if (block.isNormalBlock()) {
+ blockInside = block;
+ int display = blockInside.getId()
+ | blockInside.getDamage() << 16;
+ setDataProperty(new ByteEntityData(DATA_MINECART_HAS_DISPLAY, 1));
+ setDataProperty(new IntEntityData(DATA_MINECART_DISPLAY_BLOCK, display));
+ setDisplayBlockOffset(6);
+ }
+ } else {
+ // Set block to air (default).
+ blockInside = null;
+ setDataProperty(new ByteEntityData(DATA_MINECART_HAS_DISPLAY, 0));
+ setDataProperty(new IntEntityData(DATA_MINECART_DISPLAY_BLOCK, 0));
+ setDisplayBlockOffset(0);
+ }
+ return true;
+ }
+
+ /**
+ * Get the minecart display block
+ *
+ * @return Block of minecart display block
+ */
+ @API(usage = Usage.STABLE, definition = Definition.UNIVERSAL)
+ public Block getDisplayBlock() {
+ return blockInside;
+ }
+
+ /**
+ * Set the block offset.
+ *
+ * @param offset The offset
+ */
+ @API(usage = Usage.EXPERIMENTAL, definition = Definition.PLATFORM_NATIVE)
+ public void setDisplayBlockOffset(int offset) {
+ setDataProperty(new IntEntityData(DATA_MINECART_DISPLAY_OFFSET, offset));
+ }
+
+ /**
+ * Get the block display offset
+ *
+ * @return integer
+ */
+ @API(usage = Usage.EXPERIMENTAL, definition = Definition.UNIVERSAL)
+ public int getDisplayBlockOffset() {
+ return super.getDataPropertyInt(DATA_MINECART_DISPLAY_OFFSET);
+ }
+
+ /**
+ * Is the minecart can be slowed when empty?
+ *
+ * @return boolean
+ */
+ @API(usage = Usage.EXPERIMENTAL, definition = Definition.UNIVERSAL)
+ public boolean isSlowWhenEmpty() {
+ return slowWhenEmpty;
+ }
+
+ /**
+ * Set the minecart slowdown flag
+ *
+ * @param slow The slowdown flag
+ */
+ @API(usage = Usage.EXPERIMENTAL, definition = Definition.UNIVERSAL)
+ public void setSlowWhenEmpty(boolean slow) {
+ slowWhenEmpty = slow;
+ }
+
+ public Vector3 getFlyingVelocityMod() {
+ return new Vector3(flyingX, flyingY, flyingZ);
+ }
+
+ public void setFlyingVelocityMod(Vector3 flying) {
+ Objects.requireNonNull(flying, "Flying velocity modifiers cannot be null");
+ flyingX = flying.getX();
+ flyingY = flying.getY();
+ flyingZ = flying.getZ();
+ }
+
+ public Vector3 getDerailedVelocityMod() {
+ return new Vector3(derailedX, derailedY, derailedZ);
+ }
+
+ public void setDerailedVelocityMod(Vector3 derailed) {
+ Objects.requireNonNull(derailed, "Derailed velocity modifiers cannot be null");
+ derailedX = derailed.getX();
+ derailedY = derailed.getY();
+ derailedZ = derailed.getZ();
+ }
+
+ public void setMaximumSpeed(double speed) {
+ maxSpeed = speed;
+ }
+}
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java
index 208725bd58..453166de45 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java
@@ -1,20 +1,41 @@
package cn.nukkit.entity.item;
+import cn.nukkit.block.BlockChest;
+import cn.nukkit.item.ItemMinecartChest;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
+import cn.nukkit.utils.EnumMinecart;
/**
* Created by Snake1999 on 2016/1/30.
* Package cn.nukkit.entity.item in project Nukkit.
*/
-public class EntityMinecartChest extends EntityMinecartEmpty {
+public class EntityMinecartChest extends EntityMinecartAbstract {
- public static final int NETWORK_ID = 62;
+ public static final int NETWORK_ID = 98;
public EntityMinecartChest(FullChunk chunk, CompoundTag nbt) {
super(chunk, nbt);
+ super.setDisplayBlock(new BlockChest());
}
// TODO: 2016/1/30 inventory
+
+ @Override
+ public EnumMinecart getType() {
+ return EnumMinecart.valueOf(1);
+ }
+
+ @Override
+ public int getNetworkId() {
+ return NETWORK_ID;
+ }
+
+ @Override
+ public void dropItem() {
+ level.dropItem(this, new ItemMinecartChest());
+ }
+
+
}
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java
index fe71a83ebd..95f9be8e5c 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java
@@ -1,46 +1,17 @@
package cn.nukkit.entity.item;
-import cn.nukkit.Player;
-import cn.nukkit.event.entity.EntityDamageEvent;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
-import cn.nukkit.network.protocol.AddEntityPacket;
-import cn.nukkit.network.protocol.EntityEventPacket;
+import cn.nukkit.utils.EnumMinecart;
/**
* Created by Snake1999 on 2016/1/30.
* Package cn.nukkit.entity.item in project Nukkit.
*/
-public class EntityMinecartEmpty extends EntityVehicle {
+public class EntityMinecartEmpty extends EntityMinecartAbstract {
public static final int NETWORK_ID = 84;
- public static final int DATA_VEHICLE_DISPLAY_BLOCK = 20;
- public static final int DATA_VEHICLE_DISPLAY_DATA = 20;
- public static final int DATA_VEHICLE_DISPLAY_OFFSET = 21;
- public static final int DATA_VEHICLE_CUSTOM_DISPLAY = 22;
-
- // TODO: 2016/1/30 check if these numbers correct
- @Override
- public float getHeight() {
- return 0.7f;
- }
-
- @Override
- public float getWidth() {
- return 0.98f;
- }
-
- @Override
- protected float getDrag() {
- return 0.1f;
- }
-
- @Override
- protected float getGravity() {
- return 0.5f;
- }
-
@Override
public int getNetworkId() {
return NETWORK_ID;
@@ -49,53 +20,20 @@ public int getNetworkId() {
public EntityMinecartEmpty(FullChunk chunk, CompoundTag nbt) {
super(chunk, nbt);
}
-
- @Override
- protected void initEntity() {
- //?
- super.initEntity();
- }
-
+
@Override
- public boolean onUpdate(int currentTick) {
- // TODO: 2016/1/30 run run run!
- // TODO: 2016/1/30 split to onXXXRailPass, such as, protected void onActivatorRailPass(...)
- return super.onUpdate(currentTick);
+ public EnumMinecart getType() {
+ return EnumMinecart.valueOf(0);
}
@Override
- public void spawnTo(Player player) {
- AddEntityPacket pk = new AddEntityPacket();
- pk.entityUniqueId = this.getId();
- pk.entityRuntimeId = this.getId();
- pk.type = EntityMinecartEmpty.NETWORK_ID;
- pk.x = (float) this.x;
- pk.y = (float) this.y;
- pk.z = (float) this.z;
- pk.speedX = 0;
- pk.speedY = 0;
- pk.speedZ = 0;
- pk.yaw = 0;
- pk.pitch = 0;
- pk.metadata = this.dataProperties;
- player.dataPacket(pk);
-
- super.spawnTo(player);
- }
-
- @Override
- public boolean attack(EntityDamageEvent source) {
- if (super.attack(source)) {
- EntityEventPacket pk = new EntityEventPacket();
- pk.eid = this.id;
- pk.event = EntityEventPacket.HURT_ANIMATION;
- for (Player aPlayer : this.getLevel().getPlayers().values()) {
- aPlayer.dataPacket(pk);
+ protected void activate(int x, int y, int z, boolean flag) {
+ if (flag) {
+ if (this.riding != null) {
+ mountEntity(riding);
}
- return true;
- } else {
- return false;
+ // looks like MCPE and MCPC not same XD
+ // removed rolling feature from here because of MCPE logic?
}
}
-
}
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java
index 4f77c2cfae..a8f41893a4 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java
@@ -1,16 +1,34 @@
package cn.nukkit.entity.item;
+import cn.nukkit.block.BlockHopper;
+import cn.nukkit.item.ItemMinecartHopper;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
+import cn.nukkit.utils.EnumMinecart;
-public class EntityMinecartHopper extends EntityMinecartEmpty {
+public class EntityMinecartHopper extends EntityMinecartAbstract {
public static final int NETWORK_ID = 96;
public EntityMinecartHopper(FullChunk chunk, CompoundTag nbt) {
super(chunk, nbt);
+ super.setDisplayBlock(new BlockHopper());
}
// TODO: 2016/12/18 inventory
+ @Override
+ public EnumMinecart getType() {
+ return EnumMinecart.valueOf(5);
+ }
+
+ @Override
+ public int getNetworkId() {
+ return NETWORK_ID;
+ }
+
+ @Override
+ public void dropItem() {
+ level.dropItem(this, new ItemMinecartHopper());
+ }
}
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java
index ba95adbeb1..855db33e3d 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java
@@ -1,33 +1,62 @@
package cn.nukkit.entity.item;
+import cn.nukkit.block.BlockTNT;
+import cn.nukkit.entity.EntityExplosive;
+import cn.nukkit.entity.data.IntEntityData;
import cn.nukkit.event.entity.EntityExplosionPrimeEvent;
+import cn.nukkit.item.ItemMinecartTNT;
import cn.nukkit.level.Explosion;
import cn.nukkit.level.format.FullChunk;
+import cn.nukkit.level.particle.SmokeParticle;
+import cn.nukkit.math.Vector3;
import cn.nukkit.nbt.tag.CompoundTag;
+import cn.nukkit.utils.EnumMinecart;
+
+import java.util.Random;
/**
- * Created by Snake1999 on 2016/1/30.
- * Package cn.nukkit.entity.item in project Nukkit.
+ * Author: Adam Matthew [larryTheCoder]
+ *
+ * Nukkit Project.
*/
-public class EntityMinecartTNT extends EntityMinecartEmpty {
+public class EntityMinecartTNT extends EntityMinecartAbstract implements EntityExplosive {
- public static final int NETWORK_ID = 98;
+ public static final int NETWORK_ID = 97; //wtf?
+ private int fuse = 0;
+ private boolean activated;
public EntityMinecartTNT(FullChunk chunk, CompoundTag nbt) {
super(chunk, nbt);
+ super.setDisplayBlock(new BlockTNT());
}
- public boolean onUpdate(int currentTick) {
- /*Block downSide = this.getLocation().floor().getLevelBlock();
- if (downSide.getId() == Block.ACTIVATOR_RAIL && downSide.isPowered()) { TODO: implement
- explode();
- kill();
- }*/
- return true;
+ @Override
+ public void initEntity() {
+ super.initEntity();
+
+ this.fuse = namedTag.getInt("TNTFuse");
+ this.setDataFlag(DATA_FLAGS, DATA_FLAG_CHARGED, false);
}
+ @Override
+ public void activate(int i, int j, int k, boolean flag) {
+ // TODO: Find out why minecart doesnt have a right TNT fuse length
+ // Could be implemented in the future!
+ }
+
+ @Override
public void explode() {
- EntityExplosionPrimeEvent event = new EntityExplosionPrimeEvent(this, 4);
+ explode(0);
+ }
+
+ public void explode(double square) {
+ double root = Math.sqrt(square);
+
+ if (root > 5.0D) {
+ root = 5.0D;
+ }
+
+ EntityExplosionPrimeEvent event = new EntityExplosionPrimeEvent(this, (4.0D + new Random().nextDouble() * 1.5D * root));
server.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
@@ -37,6 +66,28 @@ public void explode() {
explosion.explodeA();
}
explosion.explodeB();
+ kill();
}
+ @Override
+ public void dropItem() {
+ level.dropItem(this, new ItemMinecartTNT());
+ }
+
+ @Override
+ public EnumMinecart getType() {
+ return EnumMinecart.valueOf(3);
+ }
+
+ @Override
+ public int getNetworkId() {
+ return EntityMinecartTNT.NETWORK_ID;
+ }
+
+ @Override
+ public void saveNBT() {
+ super.saveNBT();
+
+ super.namedTag.putInt("TNTFuse", this.fuse);
+ }
}
diff --git a/src/main/java/cn/nukkit/entity/item/EntityPrimedTNT.java b/src/main/java/cn/nukkit/entity/item/EntityPrimedTNT.java
index 68054a5b6d..f957aef28e 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityPrimedTNT.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityPrimedTNT.java
@@ -12,7 +12,6 @@
import cn.nukkit.level.sound.TNTPrimeSound;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.network.protocol.AddEntityPacket;
-import cn.nukkit.network.protocol.LevelSoundEventPacket;
/**
* @author MagicDroidX
diff --git a/src/main/java/cn/nukkit/entity/item/EntityVehicle.java b/src/main/java/cn/nukkit/entity/item/EntityVehicle.java
index 69c2d85590..a539cf8b28 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityVehicle.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityVehicle.java
@@ -1,46 +1,176 @@
package cn.nukkit.entity.item;
+import cn.nukkit.Player;
+import cn.nukkit.Server;
import cn.nukkit.entity.Entity;
+import cn.nukkit.entity.EntityInteractable;
import cn.nukkit.entity.EntityRideable;
-import cn.nukkit.entity.data.FloatEntityData;
import cn.nukkit.entity.data.IntEntityData;
+import cn.nukkit.event.vehicle.EntityEnterVehicleEvent;
+import cn.nukkit.event.vehicle.EntityExitVehicleEvent;
+import cn.nukkit.event.vehicle.VehicleCreateEvent;
+import cn.nukkit.event.vehicle.VehicleEvent;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
+import cn.nukkit.network.protocol.SetEntityLinkPacket;
+import java.util.Objects;
/**
- * author: MagicDroidX
+ * author: MagicDroidX
* Nukkit Project
*/
-public abstract class EntityVehicle extends Entity implements EntityRideable {
- public static final int DATA_HURT_TIME = 17;
- public static final int DATA_HURT_DIRECTION = 18;
- public static final int DATA_DAMAGE_TAKEN = 19;
+public abstract class EntityVehicle extends EntityInteractable implements EntityRideable {
public EntityVehicle(FullChunk chunk, CompoundTag nbt) {
super(chunk, nbt);
}
- public int getHurtTime() {
- return this.getDataPropertyInt(EntityVehicle.DATA_HURT_TIME);
+ public int getRollingAmplitude() {
+ return this.getDataPropertyInt(DATA_HURT_TIME);
}
- public void setHurtTime(int time) {
- this.setDataProperty(new IntEntityData(EntityVehicle.DATA_HURT_TIME, time));
+ public void setRollingAmplitude(int time) {
+ this.setDataProperty(new IntEntityData(DATA_HURT_TIME, time));
}
- public int getHurtDirection() {
- return this.getDataPropertyInt(EntityVehicle.DATA_HURT_DIRECTION);
+ public int getRollingDirection() {
+ return this.getDataPropertyInt(DATA_HURT_DIRECTION);
}
- public void setHurtDirection(int direction) {
- this.setDataProperty(new IntEntityData(EntityVehicle.DATA_HURT_DIRECTION, direction));
+ public void setRollingDirection(int direction) {
+ this.setDataProperty(new IntEntityData(DATA_HURT_DIRECTION, direction));
}
- public float getDamageTaken() {
- return this.getDataPropertyFloat(EntityVehicle.DATA_DAMAGE_TAKEN);
+ public int getDamage() {
+ return this.getDataPropertyInt(DATA_HEALTH); // false data name (should be DATA_DAMAGE_TAKEN)
}
- public void setDamageTaken(float damage) {
- this.setDataProperty(new FloatEntityData(EntityVehicle.DATA_DAMAGE_TAKEN, damage));
+ public void setDamage(int damage) {
+ this.setDataProperty(new IntEntityData(DATA_HEALTH, damage));
+ }
+
+ @Override
+ public String getInteractButton() {
+ return "Mount";
+ }
+
+ @Override
+ public boolean canDoInteraction() {
+ return linkedEntity == null;
+ }
+
+ /**
+ * Mount or Dismounts an Entity from a vehicle
+ *
+ * @param entity The target Entity
+ * @return {@code true} if the mounting successful
+ */
+ public boolean mountEntity(Entity entity) {
+ Objects.requireNonNull(entity, "The target of the mounting entity can't be null");
+ if (!(this instanceof EntityVehicle)) {
+ return false;
+ }
+ this.PitchDelta = 0.0D;
+ this.YawDelta = 0.0D;
+ if (entity.riding != null) {
+ VehicleEvent ev = new EntityExitVehicleEvent(entity, (EntityVehicle) this);
+ server.getPluginManager().callEvent(ev);
+ if (ev.isCancelled()) {
+ return false;
+ }
+ SetEntityLinkPacket pk;
+
+ pk = new SetEntityLinkPacket();
+ pk.rider = getId(); //Weird Weird Weird
+ pk.riding = entity.getId();
+ pk.type = 3;
+ Server.broadcastPacket(this.hasSpawned.values(), pk);
+
+ if (entity instanceof Player) {
+ pk = new SetEntityLinkPacket();
+ pk.rider = getId();
+ pk.riding = entity.getId();
+ pk.type = 3;
+ ((Player) entity).dataPacket(pk);
+ }
+
+ entity.riding = null;
+ linkedEntity = null;
+ entity.setDataFlag(DATA_FLAGS, DATA_FLAG_RIDING, false);
+ return true;
+ }
+ VehicleEvent ev = new EntityEnterVehicleEvent(entity, (EntityVehicle) this);
+ server.getPluginManager().callEvent(ev);
+ if (ev.isCancelled()) {
+ return false;
+ }
+
+ SetEntityLinkPacket pk;
+
+ pk = new SetEntityLinkPacket();
+ pk.rider = this.getId();
+ pk.riding = entity.getId();
+ pk.type = 2;
+ Server.broadcastPacket(this.hasSpawned.values(), pk);
+
+ if (entity instanceof Player) {
+ pk = new SetEntityLinkPacket();
+ pk.rider = this.getId();
+ pk.riding = 0;
+ pk.type = 2;
+ ((Player) entity).dataPacket(pk);
+ }
+
+ entity.riding = this;
+ linkedEntity = entity;
+
+ entity.setDataFlag(DATA_FLAGS, DATA_FLAG_RIDING, true);
+ updateRiderPosition(getMountedYOffset());
+ return true;
+ }
+
+ @Override
+ public boolean onUpdate(int currentTick) {
+ if (justCreated) {
+ VehicleCreateEvent event = new VehicleCreateEvent(this);
+ getServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ kill();
+ return false;
+ }
+ justCreated = false;
+ }
+
+ // The rolling amplitude
+ if (getRollingAmplitude() > 0) {
+ setRollingAmplitude(getRollingAmplitude() - 1);
+ }
+ // The damage token
+ if (getDamage() > 0) {
+ setDamage(getDamage() - 1);
+ }
+ // A killer task
+ if (y < -16) {
+ kill();
+ }
+ // Movement code
+ updateMovement();
+ return true;
+ }
+
+ protected boolean rollingDirection = true;
+
+ protected boolean performHurtAnimation(int damage) {
+ if (damage >= this.getHealth()) {
+ return false;
+ }
+
+ // Vehicle does not respond hurt animation on packets
+ // It only respond on vehicle data flags. Such as these
+ setRollingAmplitude(10);
+ setRollingDirection(rollingDirection ? 1 : -1);
+ rollingDirection = !rollingDirection;
+ setDamage(getDamage() + damage);
+ return true;
}
}
diff --git a/src/main/java/cn/nukkit/entity/mob/EntitySkeleton.java b/src/main/java/cn/nukkit/entity/mob/EntitySkeleton.java
index 3bc49cb9b3..c3012951b2 100644
--- a/src/main/java/cn/nukkit/entity/mob/EntitySkeleton.java
+++ b/src/main/java/cn/nukkit/entity/mob/EntitySkeleton.java
@@ -37,7 +37,7 @@ public float getWidth() {
public float getHeight() {
return 1.8f;
}
-
+
@Override
public void spawnTo(Player player) {
AddEntityPacket pk = new AddEntityPacket();
diff --git a/src/main/java/cn/nukkit/entity/mob/EntityZombie.java b/src/main/java/cn/nukkit/entity/mob/EntityZombie.java
index 54c1f59a70..499c0fe2f2 100644
--- a/src/main/java/cn/nukkit/entity/mob/EntityZombie.java
+++ b/src/main/java/cn/nukkit/entity/mob/EntityZombie.java
@@ -36,7 +36,7 @@ public float getWidth() {
public float getHeight() {
return 1.8f;
}
-
+
@Override
public String getName() {
return "Zombie";
diff --git a/src/main/java/cn/nukkit/entity/mob/EntityZombiePigman.java b/src/main/java/cn/nukkit/entity/mob/EntityZombiePigman.java
index cb0953a1da..1f2dc3e8db 100644
--- a/src/main/java/cn/nukkit/entity/mob/EntityZombiePigman.java
+++ b/src/main/java/cn/nukkit/entity/mob/EntityZombiePigman.java
@@ -31,7 +31,7 @@ protected void initEntity() {
public float getWidth() {
return 0.72f;
}
-
+
@Override
public float getHeight() {
return 1.8f;
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityZombieHorse.java b/src/main/java/cn/nukkit/entity/passive/EntityZombieHorse.java
index 62929de37f..13a7c55483 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityZombieHorse.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityZombieHorse.java
@@ -1,7 +1,6 @@
package cn.nukkit.entity.passive;
import cn.nukkit.Player;
-import cn.nukkit.event.entity.EntityDamageByEntityEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
diff --git a/src/main/java/cn/nukkit/event/vehicle/EntityEnterVehicleEvent.java b/src/main/java/cn/nukkit/event/vehicle/EntityEnterVehicleEvent.java
new file mode 100644
index 0000000000..6cc185dbdd
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/vehicle/EntityEnterVehicleEvent.java
@@ -0,0 +1,32 @@
+package cn.nukkit.event.vehicle;
+
+import cn.nukkit.Player;
+import cn.nukkit.entity.Entity;
+import cn.nukkit.entity.item.EntityVehicle;
+import cn.nukkit.event.Cancellable;
+import cn.nukkit.event.HandlerList;
+
+public class EntityEnterVehicleEvent extends VehicleEvent implements Cancellable {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+
+ private final Entity riding;
+
+ public EntityEnterVehicleEvent(Entity riding, EntityVehicle vehicle) {
+ super(vehicle);
+ this.riding = riding;
+ }
+
+ public Entity getEntity() {
+ return riding;
+ }
+
+ public boolean isPlayer() {
+ return riding instanceof Player;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/event/vehicle/EntityExitVehicleEvent.java b/src/main/java/cn/nukkit/event/vehicle/EntityExitVehicleEvent.java
new file mode 100644
index 0000000000..e9dac2494d
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/vehicle/EntityExitVehicleEvent.java
@@ -0,0 +1,32 @@
+package cn.nukkit.event.vehicle;
+
+import cn.nukkit.Player;
+import cn.nukkit.entity.Entity;
+import cn.nukkit.entity.item.EntityVehicle;
+import cn.nukkit.event.Cancellable;
+import cn.nukkit.event.HandlerList;
+
+public class EntityExitVehicleEvent extends VehicleEvent implements Cancellable {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+
+ private final Entity riding;
+
+ public EntityExitVehicleEvent(Entity riding, EntityVehicle vehicle) {
+ super(vehicle);
+ this.riding = riding;
+ }
+
+ public Entity getEntity() {
+ return riding;
+ }
+
+ public boolean isPlayer() {
+ return riding instanceof Player;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/event/vehicle/VehicleCreateEvent.java b/src/main/java/cn/nukkit/event/vehicle/VehicleCreateEvent.java
new file mode 100644
index 0000000000..24faa86f03
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/vehicle/VehicleCreateEvent.java
@@ -0,0 +1,19 @@
+package cn.nukkit.event.vehicle;
+
+import cn.nukkit.entity.item.EntityVehicle;
+import cn.nukkit.event.Cancellable;
+import cn.nukkit.event.HandlerList;
+
+public class VehicleCreateEvent extends VehicleEvent implements Cancellable {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public VehicleCreateEvent(EntityVehicle vehicle) {
+ super(vehicle);
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/event/vehicle/VehicleDamageEvent.java b/src/main/java/cn/nukkit/event/vehicle/VehicleDamageEvent.java
new file mode 100644
index 0000000000..0a673778c6
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/vehicle/VehicleDamageEvent.java
@@ -0,0 +1,37 @@
+package cn.nukkit.event.vehicle;
+
+import cn.nukkit.entity.Entity;
+import cn.nukkit.entity.item.EntityVehicle;
+import cn.nukkit.event.Cancellable;
+import cn.nukkit.event.HandlerList;
+
+public class VehicleDamageEvent extends VehicleEvent implements Cancellable {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+
+ private final Entity attacker;
+ private double damage;
+
+ public VehicleDamageEvent(EntityVehicle vehicle, Entity attacker, double damage) {
+ super(vehicle);
+ this.attacker = attacker;
+ this.damage = damage;
+ }
+
+ public Entity getAttacker() {
+ return attacker;
+ }
+
+ public double getDamage() {
+ return damage;
+ }
+
+ public void setDamage(double damage) {
+ this.damage = damage;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/event/vehicle/VehicleDestroyEvent.java b/src/main/java/cn/nukkit/event/vehicle/VehicleDestroyEvent.java
new file mode 100644
index 0000000000..817b6d4468
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/vehicle/VehicleDestroyEvent.java
@@ -0,0 +1,27 @@
+package cn.nukkit.event.vehicle;
+
+import cn.nukkit.entity.Entity;
+import cn.nukkit.entity.item.EntityVehicle;
+import cn.nukkit.event.Cancellable;
+import cn.nukkit.event.HandlerList;
+
+public class VehicleDestroyEvent extends VehicleEvent implements Cancellable {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+
+ private final Entity attacker;
+
+ public VehicleDestroyEvent(EntityVehicle vehicle, Entity attacker) {
+ super(vehicle);
+ this.attacker = attacker;
+ }
+
+ public Entity getAttacker() {
+ return attacker;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/event/vehicle/VehicleEvent.java b/src/main/java/cn/nukkit/event/vehicle/VehicleEvent.java
new file mode 100644
index 0000000000..ba5346212e
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/vehicle/VehicleEvent.java
@@ -0,0 +1,22 @@
+package cn.nukkit.event.vehicle;
+
+import cn.nukkit.entity.item.EntityVehicle;
+import cn.nukkit.event.Event;
+
+/**
+ * Created by larryTheCoder at 7/5/2017.
+ *
+ * Nukkit Project
+ */
+public abstract class VehicleEvent extends Event {
+
+ private final EntityVehicle vehicle;
+
+ public VehicleEvent(EntityVehicle vehicle) {
+ this.vehicle = vehicle;
+ }
+
+ public EntityVehicle getVehicle() {
+ return vehicle;
+ }
+}
diff --git a/src/main/java/cn/nukkit/event/vehicle/VehicleMoveEvent.java b/src/main/java/cn/nukkit/event/vehicle/VehicleMoveEvent.java
new file mode 100644
index 0000000000..0cf898755e
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/vehicle/VehicleMoveEvent.java
@@ -0,0 +1,31 @@
+package cn.nukkit.event.vehicle;
+
+import cn.nukkit.entity.item.EntityVehicle;
+import cn.nukkit.event.HandlerList;
+import cn.nukkit.level.Location;
+
+public class VehicleMoveEvent extends VehicleEvent {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+
+ private final Location from;
+ private final Location to;
+
+ public VehicleMoveEvent(EntityVehicle vehicle, Location from, Location to) {
+ super(vehicle);
+ this.from = from;
+ this.to = to;
+ }
+
+ public Location getFrom() {
+ return from;
+ }
+
+ public Location getTo() {
+ return to;
+ }
+}
diff --git a/src/main/java/cn/nukkit/event/vehicle/VehicleUpdateEvent.java b/src/main/java/cn/nukkit/event/vehicle/VehicleUpdateEvent.java
new file mode 100644
index 0000000000..175dbed211
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/vehicle/VehicleUpdateEvent.java
@@ -0,0 +1,18 @@
+package cn.nukkit.event.vehicle;
+
+import cn.nukkit.entity.item.EntityVehicle;
+import cn.nukkit.event.HandlerList;
+
+public class VehicleUpdateEvent extends VehicleEvent {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public VehicleUpdateEvent(EntityVehicle vehicle) {
+ super(vehicle);
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/item/ItemMinecart.java b/src/main/java/cn/nukkit/item/ItemMinecart.java
index a5c262d3b6..38466e3956 100644
--- a/src/main/java/cn/nukkit/item/ItemMinecart.java
+++ b/src/main/java/cn/nukkit/item/ItemMinecart.java
@@ -2,6 +2,7 @@
import cn.nukkit.Player;
import cn.nukkit.block.Block;
+import cn.nukkit.block.BlockRail;
import cn.nukkit.entity.item.EntityMinecartEmpty;
import cn.nukkit.level.Level;
import cn.nukkit.math.BlockFace;
@@ -9,6 +10,7 @@
import cn.nukkit.nbt.tag.DoubleTag;
import cn.nukkit.nbt.tag.FloatTag;
import cn.nukkit.nbt.tag.ListTag;
+import cn.nukkit.utils.Rail;
/**
* author: MagicDroidX
@@ -35,28 +37,31 @@ public boolean canBeActivated() {
@Override
public boolean onActivate(Level level, Player player, Block block, Block target, BlockFace face, double fx, double fy, double fz) {
- Block secret = level.getBlock(block.add(0, -1, 0));
- // TODO: 2016/1/30 check if blockId of secret is a rail
-
- EntityMinecartEmpty minecart = new EntityMinecartEmpty(
- level.getChunk(block.getFloorX() >> 4, block.getFloorZ() >> 4), new CompoundTag("")
- .putList(new ListTag("Pos")
- .add(new DoubleTag("", block.getX() + 0.5))
- .add(new DoubleTag("", block.getY()))
- .add(new DoubleTag("", block.getZ() + 0.5)))
- .putList(new ListTag("Motion")
- .add(new DoubleTag("", 0))
- .add(new DoubleTag("", 0))
- .add(new DoubleTag("", 0)))
- .putList(new ListTag("Rotation")
- .add(new FloatTag("", 0))
- .add(new FloatTag("", 0)))
- );
- minecart.spawnToAll();
-
- // TODO: 2016/1/30 if player is survival, item in hand count--
-
- return true;
+ if (Rail.isRailBlock(target)) {
+ Rail.Orientation type = ((BlockRail) target).getOrientation();
+ double adjacent = 0.0D;
+ if (type.isAscending()) {
+ adjacent = 0.5D;
+ }
+ EntityMinecartEmpty minecart = new EntityMinecartEmpty(
+ level.getChunk(target.getFloorX() >> 4, target.getFloorZ() >> 4), new CompoundTag("")
+ .putList(new ListTag<>("Pos")
+ .add(new DoubleTag("", target.getX() + 0.5))
+ .add(new DoubleTag("", target.getY() + 0.0625D + adjacent))
+ .add(new DoubleTag("", target.getZ() + 0.5)))
+ .putList(new ListTag<>("Motion")
+ .add(new DoubleTag("", 0))
+ .add(new DoubleTag("", 0))
+ .add(new DoubleTag("", 0)))
+ .putList(new ListTag<>("Rotation")
+ .add(new FloatTag("", 0))
+ .add(new FloatTag("", 0)))
+ );
+ minecart.spawnToAll();
+ count -= 1;
+ return true;
+ }
+ return false;
}
@Override
diff --git a/src/main/java/cn/nukkit/item/ItemMinecartChest.java b/src/main/java/cn/nukkit/item/ItemMinecartChest.java
index fecbf7792d..6da0ccc3f0 100644
--- a/src/main/java/cn/nukkit/item/ItemMinecartChest.java
+++ b/src/main/java/cn/nukkit/item/ItemMinecartChest.java
@@ -2,6 +2,7 @@
import cn.nukkit.Player;
import cn.nukkit.block.Block;
+import cn.nukkit.block.BlockRail;
import cn.nukkit.entity.item.EntityMinecartChest;
import cn.nukkit.level.Level;
import cn.nukkit.math.BlockFace;
@@ -9,6 +10,7 @@
import cn.nukkit.nbt.tag.DoubleTag;
import cn.nukkit.nbt.tag.FloatTag;
import cn.nukkit.nbt.tag.ListTag;
+import cn.nukkit.utils.Rail;
public class ItemMinecartChest extends Item {
@@ -31,27 +33,31 @@ public boolean canBeActivated() {
@Override
public boolean onActivate(Level level, Player player, Block block, Block target, BlockFace face, double fx, double fy, double fz) {
- Block secret = level.getBlock(block.add(0, -1, 0));
- // TODO: 2016/1/30 check if blockId of secret is a rail
- EntityMinecartChest minecart = new EntityMinecartChest(
- level.getChunk(block.getFloorX() >> 4, block.getFloorZ() >> 4), new CompoundTag("")
- .putList(new ListTag("Pos")
- .add(new DoubleTag("", block.getX() + 0.5))
- .add(new DoubleTag("", block.getY()))
- .add(new DoubleTag("", block.getZ() + 0.5)))
- .putList(new ListTag("Motion")
- .add(new DoubleTag("", 0))
- .add(new DoubleTag("", 0))
- .add(new DoubleTag("", 0)))
- .putList(new ListTag("Rotation")
- .add(new FloatTag("", 0))
- .add(new FloatTag("", 0)))
- );
- minecart.spawnToAll();
-
- // TODO: 2016/1/30 if player is survival, item in hand count--
-
- return true;
+ if (Rail.isRailBlock(target)) {
+ Rail.Orientation type = ((BlockRail) target).getOrientation();
+ double adjacent = 0.0D;
+ if (type.isAscending()) {
+ adjacent = 0.5D;
+ }
+ EntityMinecartChest minecart = new EntityMinecartChest(
+ level.getChunk(target.getFloorX() >> 4, target.getFloorZ() >> 4), new CompoundTag("")
+ .putList(new ListTag<>("Pos")
+ .add(new DoubleTag("", target.getX() + 0.5))
+ .add(new DoubleTag("", target.getY() + 0.0625D + adjacent))
+ .add(new DoubleTag("", target.getZ() + 0.5)))
+ .putList(new ListTag<>("Motion")
+ .add(new DoubleTag("", 0))
+ .add(new DoubleTag("", 0))
+ .add(new DoubleTag("", 0)))
+ .putList(new ListTag<>("Rotation")
+ .add(new FloatTag("", 0))
+ .add(new FloatTag("", 0)))
+ );
+ minecart.spawnToAll();
+ count -= 1;
+ return true;
+ }
+ return false;
}
@Override
diff --git a/src/main/java/cn/nukkit/item/ItemMinecartHopper.java b/src/main/java/cn/nukkit/item/ItemMinecartHopper.java
index 6d5b34f83e..b7606856b5 100644
--- a/src/main/java/cn/nukkit/item/ItemMinecartHopper.java
+++ b/src/main/java/cn/nukkit/item/ItemMinecartHopper.java
@@ -2,6 +2,7 @@
import cn.nukkit.Player;
import cn.nukkit.block.Block;
+import cn.nukkit.block.BlockRail;
import cn.nukkit.entity.item.EntityMinecartHopper;
import cn.nukkit.level.Level;
import cn.nukkit.math.BlockFace;
@@ -9,6 +10,7 @@
import cn.nukkit.nbt.tag.DoubleTag;
import cn.nukkit.nbt.tag.FloatTag;
import cn.nukkit.nbt.tag.ListTag;
+import cn.nukkit.utils.Rail;
public class ItemMinecartHopper extends Item {
@@ -31,27 +33,31 @@ public boolean canBeActivated() {
@Override
public boolean onActivate(Level level, Player player, Block block, Block target, BlockFace face, double fx, double fy, double fz) {
- Block secret = level.getBlock(block.add(0, -1, 0));
- // TODO: 2016/1/30 check if blockId of secret is a rail
- EntityMinecartHopper minecart = new EntityMinecartHopper(
- level.getChunk(block.getFloorX() >> 4, block.getFloorZ() >> 4), new CompoundTag("")
- .putList(new ListTag("Pos")
- .add(new DoubleTag("", block.getX() + 0.5))
- .add(new DoubleTag("", block.getY()))
- .add(new DoubleTag("", block.getZ() + 0.5)))
- .putList(new ListTag("Motion")
- .add(new DoubleTag("", 0))
- .add(new DoubleTag("", 0))
- .add(new DoubleTag("", 0)))
- .putList(new ListTag("Rotation")
- .add(new FloatTag("", 0))
- .add(new FloatTag("", 0)))
- );
- minecart.spawnToAll();
-
- // TODO: 2016/1/30 if player is survival, item in hand count--
-
- return true;
+ if (Rail.isRailBlock(target)) {
+ Rail.Orientation type = ((BlockRail) target).getOrientation();
+ double adjacent = 0.0D;
+ if (type.isAscending()) {
+ adjacent = 0.5D;
+ }
+ EntityMinecartHopper minecart = new EntityMinecartHopper(
+ level.getChunk(target.getFloorX() >> 4, target.getFloorZ() >> 4), new CompoundTag("")
+ .putList(new ListTag<>("Pos")
+ .add(new DoubleTag("", target.getX() + 0.5))
+ .add(new DoubleTag("", target.getY() + 0.0625D + adjacent))
+ .add(new DoubleTag("", target.getZ() + 0.5)))
+ .putList(new ListTag<>("Motion")
+ .add(new DoubleTag("", 0))
+ .add(new DoubleTag("", 0))
+ .add(new DoubleTag("", 0)))
+ .putList(new ListTag<>("Rotation")
+ .add(new FloatTag("", 0))
+ .add(new FloatTag("", 0)))
+ );
+ minecart.spawnToAll();
+ count -= 1;
+ return true;
+ }
+ return false;
}
@Override
diff --git a/src/main/java/cn/nukkit/item/ItemMinecartTNT.java b/src/main/java/cn/nukkit/item/ItemMinecartTNT.java
index 27fa125dca..951e4ae673 100644
--- a/src/main/java/cn/nukkit/item/ItemMinecartTNT.java
+++ b/src/main/java/cn/nukkit/item/ItemMinecartTNT.java
@@ -2,6 +2,7 @@
import cn.nukkit.Player;
import cn.nukkit.block.Block;
+import cn.nukkit.block.BlockRail;
import cn.nukkit.entity.item.EntityMinecartTNT;
import cn.nukkit.level.Level;
import cn.nukkit.math.BlockFace;
@@ -9,6 +10,7 @@
import cn.nukkit.nbt.tag.DoubleTag;
import cn.nukkit.nbt.tag.FloatTag;
import cn.nukkit.nbt.tag.ListTag;
+import cn.nukkit.utils.Rail;
public class ItemMinecartTNT extends Item {
@@ -31,27 +33,31 @@ public boolean canBeActivated() {
@Override
public boolean onActivate(Level level, Player player, Block block, Block target, BlockFace face, double fx, double fy, double fz) {
- Block secret = level.getBlock(block.add(0, -1, 0));
- // TODO: 2016/1/30 check if blockId of secret is a rail
- EntityMinecartTNT minecart = new EntityMinecartTNT(
- level.getChunk(block.getFloorX() >> 4, block.getFloorZ() >> 4), new CompoundTag("")
- .putList(new ListTag("Pos")
- .add(new DoubleTag("", block.getX() + 0.5))
- .add(new DoubleTag("", block.getY()))
- .add(new DoubleTag("", block.getZ() + 0.5)))
- .putList(new ListTag("Motion")
- .add(new DoubleTag("", 0))
- .add(new DoubleTag("", 0))
- .add(new DoubleTag("", 0)))
- .putList(new ListTag("Rotation")
- .add(new FloatTag("", 0))
- .add(new FloatTag("", 0)))
- );
- minecart.spawnToAll();
-
- // TODO: 2016/1/30 if player is survival, item in hand count--
-
- return true;
+ if (Rail.isRailBlock(target)) {
+ Rail.Orientation type = ((BlockRail) target).getOrientation();
+ double adjacent = 0.0D;
+ if (type.isAscending()) {
+ adjacent = 0.5D;
+ }
+ EntityMinecartTNT minecart = new EntityMinecartTNT(
+ level.getChunk(target.getFloorX() >> 4, target.getFloorZ() >> 4), new CompoundTag("")
+ .putList(new ListTag<>("Pos")
+ .add(new DoubleTag("", target.getX() + 0.5))
+ .add(new DoubleTag("", target.getY() + 0.0625D + adjacent))
+ .add(new DoubleTag("", target.getZ() + 0.5)))
+ .putList(new ListTag<>("Motion")
+ .add(new DoubleTag("", 0))
+ .add(new DoubleTag("", 0))
+ .add(new DoubleTag("", 0)))
+ .putList(new ListTag<>("Rotation")
+ .add(new FloatTag("", 0))
+ .add(new FloatTag("", 0)))
+ );
+ minecart.spawnToAll();
+ count -= 1;
+ return true;
+ }
+ return false;
}
@Override
diff --git a/src/main/java/cn/nukkit/level/ChunkPosition.java b/src/main/java/cn/nukkit/level/ChunkPosition.java
new file mode 100644
index 0000000000..4a8282dc54
--- /dev/null
+++ b/src/main/java/cn/nukkit/level/ChunkPosition.java
@@ -0,0 +1,42 @@
+package cn.nukkit.level;
+
+import cn.nukkit.math.MathHelper;
+import cn.nukkit.math.Vector3;
+
+/**
+ * Author: Adam Matthew
+ *
+ * Nukkit Project
+ */
+public class ChunkPosition {
+
+ public final int x;
+ public final int y;
+ public final int z;
+
+ public ChunkPosition(int i, int j, int k) {
+ this.x = i;
+ this.y = j;
+ this.z = k;
+ }
+
+ public ChunkPosition(Vector3 vec3d) {
+ this(MathHelper.floor(vec3d.x), MathHelper.floor(vec3d.y), MathHelper.floor(vec3d.z));
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (!(object instanceof ChunkPosition)) {
+ return false;
+ } else {
+ ChunkPosition chunkposition = (ChunkPosition) object;
+
+ return chunkposition.x == this.x && chunkposition.y == this.y && chunkposition.z == this.z;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return this.x * 8976890 + this.y * 981131 + this.z;
+ }
+}
diff --git a/src/main/java/cn/nukkit/math/NukkitMath.java b/src/main/java/cn/nukkit/math/NukkitMath.java
index cd92c76e3b..32368a2ca7 100644
--- a/src/main/java/cn/nukkit/math/NukkitMath.java
+++ b/src/main/java/cn/nukkit/math/NukkitMath.java
@@ -45,5 +45,21 @@ public static double round(double d) {
public static double round(double d, int precision) {
return ((double) Math.round(d * Math.pow(10, precision))) / Math.pow(10, precision);
}
+
+ public static double clamp(double check, double min, double max) {
+ return check > max ? max : (check < min ? min : check);
+ }
+
+ public static double getDirection(double d0, double d1) {
+ if (d0 < 0.0D) {
+ d0 = -d0;
+ }
+
+ if (d1 < 0.0D) {
+ d1 = -d1;
+ }
+
+ return d0 > d1 ? d0 : d1;
+ }
}
diff --git a/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java b/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java
index a5ed8ab43d..767c395a49 100644
--- a/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java
@@ -1,6 +1,5 @@
package cn.nukkit.network.protocol;
-import cn.nukkit.utils.BinaryStream;
import cn.nukkit.utils.Utils;
import java.awt.*;
diff --git a/src/main/java/cn/nukkit/network/protocol/LoginPacket.java b/src/main/java/cn/nukkit/network/protocol/LoginPacket.java
index b05665487a..7290922b85 100644
--- a/src/main/java/cn/nukkit/network/protocol/LoginPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/LoginPacket.java
@@ -1,7 +1,6 @@
package cn.nukkit.network.protocol;
import cn.nukkit.entity.data.Skin;
-import cn.nukkit.utils.Zlib;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
diff --git a/src/main/java/cn/nukkit/potion/Effect.java b/src/main/java/cn/nukkit/potion/Effect.java
index 4bd03b89d6..a2fbf92b16 100644
--- a/src/main/java/cn/nukkit/potion/Effect.java
+++ b/src/main/java/cn/nukkit/potion/Effect.java
@@ -4,7 +4,6 @@
import cn.nukkit.entity.Entity;
import cn.nukkit.event.entity.EntityDamageEvent;
import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
-import cn.nukkit.event.entity.EntityEvent;
import cn.nukkit.event.entity.EntityRegainHealthEvent;
import cn.nukkit.network.protocol.MobEffectPacket;
import cn.nukkit.utils.ServerException;
diff --git a/src/main/java/cn/nukkit/scheduler/AsyncPool.java b/src/main/java/cn/nukkit/scheduler/AsyncPool.java
index 42a0044089..ed3b03fdca 100644
--- a/src/main/java/cn/nukkit/scheduler/AsyncPool.java
+++ b/src/main/java/cn/nukkit/scheduler/AsyncPool.java
@@ -5,7 +5,6 @@
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
/**
* @author Nukkit Project Team
diff --git a/src/main/java/cn/nukkit/utils/EnumMinecart.java b/src/main/java/cn/nukkit/utils/EnumMinecart.java
new file mode 100644
index 0000000000..68c34f3b78
--- /dev/null
+++ b/src/main/java/cn/nukkit/utils/EnumMinecart.java
@@ -0,0 +1,105 @@
+package cn.nukkit.utils;
+
+import cn.nukkit.api.API;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Helper class of Minecart variants
+ *
+ * By Adam Matthew
+ * Creation time: 2017/7/17 19:55.
+ */
+@API(usage = API.Usage.STABLE, definition = API.Definition.INTERNAL)
+public enum EnumMinecart {
+ /**
+ * Represents an empty vehicle.
+ */
+ MINECART_EMPTY(0, false, "Minecart"),
+ /**
+ * Represents a chest holder.
+ */
+ MINECART_CHEST(1, true, "Minecart with chest"),
+ /**
+ * Represents a furnace minecart.
+ */
+ MINECART_FURNACE(2, true, "Minecart with furnace"),
+ /**
+ * Represents a TNT minecart.
+ */
+ MINECART_TNT(3, true, "Minecart with TNT"),
+ /**
+ * Represents a mob spawner minecart.
+ */
+ MINECART_MOB_SPAWNER(4, true, "Minecart with Mob Spawner"),
+ /**
+ * Represents a hopper minecart.
+ */
+ MINECART_HOPPER(5, true, "Minecart with hopper"),
+ /**
+ * Represents a command block minecart.
+ */
+ MINECART_COMMAND_BLOCK(6, true, "Minecart with Command Block"),
+ /**
+ * Represents an unknown minecart.
+ */
+ MINECART_UNKNOWN(-1, false, "Minecart unknown");
+
+ private final int type;
+ private final boolean hasBlockyInside;
+ private final String realName;
+ private static final Map TYPES = new HashMap<>();
+
+ static {
+ EnumMinecart[] types = values();
+ int var1 = types.length;
+ for (int var2 = 0; var2 < var1; var2++) {
+ EnumMinecart var3 = types[var2];
+ TYPES.put(Integer.valueOf(var3.getId()), var3);
+ }
+ }
+
+ EnumMinecart(int number, boolean hasBlockInside, String name) {
+ type = number;
+ hasBlockyInside = hasBlockInside;
+ realName = name;
+ }
+
+ /**
+ * Get the variants of the current minecart
+ *
+ * @return Integer
+ */
+ public int getId() {
+ return type;
+ }
+
+ /**
+ * Get the name of the minecart variants
+ *
+ * @return String
+ */
+ public String getName() {
+ return realName;
+ }
+
+ /**
+ * Gets if the minecart contains block
+ *
+ * @return Boolean
+ */
+ public boolean isBlockOverrides() {
+ return hasBlockyInside;
+ }
+
+ /**
+ * Returns of an instance of Minecart-variants
+ *
+ * @param types The number of minecart
+ * @return Integer
+ */
+ public static EnumMinecart valueOf(int types) {
+ EnumMinecart what = (EnumMinecart) TYPES.get(types);
+ return what == null ? MINECART_UNKNOWN : what;
+ }
+}
diff --git a/src/main/java/cn/nukkit/utils/MainLogger.java b/src/main/java/cn/nukkit/utils/MainLogger.java
index 147b4962e2..0934f0afe8 100644
--- a/src/main/java/cn/nukkit/utils/MainLogger.java
+++ b/src/main/java/cn/nukkit/utils/MainLogger.java
@@ -294,4 +294,4 @@ public void log(LogLevel level, String message, Throwable t) {
this.log(level, message + "\r\n" + Utils.getExceptionMessage(t));
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/cn/nukkit/utils/Rail.java b/src/main/java/cn/nukkit/utils/Rail.java
new file mode 100644
index 0000000000..504d1d769d
--- /dev/null
+++ b/src/main/java/cn/nukkit/utils/Rail.java
@@ -0,0 +1,158 @@
+package cn.nukkit.utils;
+
+import cn.nukkit.api.API;
+import cn.nukkit.block.Block;
+import cn.nukkit.math.BlockFace;
+
+import java.util.*;
+import java.util.stream.Stream;
+
+import static cn.nukkit.math.BlockFace.*;
+import static cn.nukkit.utils.Rail.Orientation.State.*;
+
+/**
+ * INTERNAL helper class of railway
+ *
+ * By lmlstarqaq http://snake1999.com/
+ * Creation time: 2017/7/1 17:42.
+ */
+@API(usage = API.Usage.BLEEDING, definition = API.Definition.INTERNAL)
+public final class Rail {
+
+ public static boolean isRailBlock(Block block) {
+ Objects.requireNonNull(block, "Rail block predicate can not accept null block");
+ return isRailBlock(block.getId());
+ }
+
+ public enum Orientation {
+ STRAIGHT_NORTH_SOUTH (0, STRAIGHT, NORTH, SOUTH, null),
+ STRAIGHT_EAST_WEST (1, STRAIGHT, EAST, WEST, null),
+ ASCENDING_EAST (2, ASCENDING, EAST, WEST, EAST),
+ ASCENDING_WEST (3, ASCENDING, EAST, WEST, WEST),
+ ASCENDING_NORTH (4, ASCENDING, NORTH, SOUTH, NORTH),
+ ASCENDING_SOUTH (5, ASCENDING, NORTH, SOUTH, SOUTH),
+ CURVED_SOUTH_EAST (6, CURVED, SOUTH, EAST, null),
+ CURVED_SOUTH_WEST (7, CURVED, SOUTH, WEST, null),
+ CURVED_NORTH_WEST (8, CURVED, NORTH, WEST, null),
+ CURVED_NORTH_EAST (9, CURVED, NORTH, EAST, null);
+
+ private static final Orientation[] META_LOOKUP = new Orientation[values().length];
+ private final int meta;
+ private final State state;
+ private final List connectingDirections;
+ private final BlockFace ascendingDirection;
+
+ Orientation(int meta, State state, BlockFace from, BlockFace to, BlockFace ascendingDirection) {
+ this.meta = meta;
+ this.state = state;
+ this.connectingDirections = Arrays.asList(from, to);
+ this.ascendingDirection = ascendingDirection;
+ }
+
+ public static Orientation byMetadata(int meta) {
+ if (meta < 0 || meta >= META_LOOKUP.length) {
+ meta = 0;
+ }
+
+ return META_LOOKUP[meta];
+ }
+
+ public static Orientation straight(BlockFace face) {
+ switch (face) {
+ case NORTH:
+ case SOUTH:
+ return STRAIGHT_NORTH_SOUTH;
+ case EAST:
+ case WEST:
+ return STRAIGHT_EAST_WEST;
+ }
+ return STRAIGHT_NORTH_SOUTH;
+ }
+
+ public static Orientation ascending(BlockFace face) {
+ switch (face) {
+ case NORTH:
+ return ASCENDING_NORTH;
+ case SOUTH:
+ return ASCENDING_SOUTH;
+ case EAST:
+ return ASCENDING_EAST;
+ case WEST:
+ return ASCENDING_WEST;
+ }
+ return ASCENDING_EAST;
+ }
+
+ public static Orientation curved(BlockFace f1, BlockFace f2) {
+ for (Orientation o : new Orientation[]{CURVED_SOUTH_EAST, CURVED_SOUTH_WEST, CURVED_NORTH_WEST, CURVED_NORTH_EAST}) {
+ if (o.connectingDirections.contains(f1) && o.connectingDirections.contains(f2)) {
+ return o;
+ }
+ }
+ return CURVED_SOUTH_EAST;
+ }
+
+ public static Orientation straightOrCurved(BlockFace f1, BlockFace f2) {
+ for (Orientation o : new Orientation[]{STRAIGHT_NORTH_SOUTH, STRAIGHT_EAST_WEST, CURVED_SOUTH_EAST, CURVED_SOUTH_WEST, CURVED_NORTH_WEST, CURVED_NORTH_EAST}) {
+ if (o.connectingDirections.contains(f1) && o.connectingDirections.contains(f2)) {
+ return o;
+ }
+ }
+ return STRAIGHT_NORTH_SOUTH;
+ }
+
+ public int metadata() {
+ return meta;
+ }
+
+ public boolean hasConnectingDirections(BlockFace... faces) {
+ return Stream.of(faces).allMatch(connectingDirections::contains);
+ }
+
+ public List connectingDirections() {
+ return connectingDirections;
+ }
+
+ public Optional ascendingDirection() {
+ return Optional.ofNullable(ascendingDirection);
+ }
+
+ public enum State {
+ STRAIGHT, ASCENDING, CURVED
+ }
+
+ public boolean isStraight() {
+ return state == STRAIGHT;
+ }
+
+ public boolean isAscending() {
+ return state == ASCENDING;
+ }
+
+ public boolean isCurved() {
+ return state == CURVED;
+ }
+
+ static {
+ for (Orientation o : values()) {
+ META_LOOKUP[o.meta] = o;
+ }
+ }
+ }
+
+ public static boolean isRailBlock(int blockId) {
+ switch (blockId) {
+ case Block.RAIL:
+ case Block.POWERED_RAIL:
+ case Block.ACTIVATOR_RAIL:
+ case Block.DETECTOR_RAIL:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private Rail() {
+ //no instance
+ }
+}
diff --git a/src/main/java/cn/nukkit/utils/bugreport/ExceptionHandler.java b/src/main/java/cn/nukkit/utils/bugreport/ExceptionHandler.java
index d0b3b4519d..1493dd189a 100644
--- a/src/main/java/cn/nukkit/utils/bugreport/ExceptionHandler.java
+++ b/src/main/java/cn/nukkit/utils/bugreport/ExceptionHandler.java
@@ -1,8 +1,5 @@
package cn.nukkit.utils.bugreport;
-import cn.nukkit.Server;
-import cn.nukkit.lang.BaseLang;
-
/**
* Project nukkit
*/
From b190802a4a3f67064ceae824dbddae16d4974fb5 Mon Sep 17 00:00:00 2001
From: Scallop <862578730@qq.com>
Date: Tue, 1 Aug 2017 16:40:55 +0800
Subject: [PATCH 024/175] Fixed typo, nonstandard naming, removed redundant
codes in Minecart Update (#1829)
* Fixed typo, nonstandard naming, removed redundant codes
* Revert: A couple of vehicle events
---
src/main/java/cn/nukkit/Player.java | 2 +-
.../cn/nukkit/entity/EntityInteractable.java | 4 +-
.../cn/nukkit/entity/item/EntityBoat.java | 21 +------
.../entity/item/EntityMinecartAbstract.java | 61 +++++--------------
.../entity/item/EntityMinecartChest.java | 6 +-
.../entity/item/EntityMinecartEmpty.java | 6 +-
.../entity/item/EntityMinecartHopper.java | 6 +-
.../nukkit/entity/item/EntityMinecartTNT.java | 9 +--
.../cn/nukkit/entity/item/EntityVehicle.java | 25 ++------
.../event/entity/EntityVehicleEnterEvent.java | 27 ++++++++
.../event/entity/EntityVehicleExitEvent.java | 27 ++++++++
.../vehicle/EntityEnterVehicleEvent.java | 32 ----------
.../event/vehicle/EntityExitVehicleEvent.java | 32 ----------
.../event/vehicle/VehicleCreateEvent.java | 19 ------
.../event/vehicle/VehicleDamageEvent.java | 37 -----------
.../event/vehicle/VehicleDestroyEvent.java | 27 --------
.../cn/nukkit/item/ItemMinecartChest.java | 2 +-
.../cn/nukkit/item/ItemMinecartHopper.java | 2 +-
.../java/cn/nukkit/item/ItemMinecartTNT.java | 2 +-
.../{EnumMinecart.java => MinecartType.java} | 32 +++++-----
20 files changed, 111 insertions(+), 268 deletions(-)
create mode 100644 src/main/java/cn/nukkit/event/entity/EntityVehicleEnterEvent.java
create mode 100644 src/main/java/cn/nukkit/event/entity/EntityVehicleExitEvent.java
delete mode 100644 src/main/java/cn/nukkit/event/vehicle/EntityEnterVehicleEvent.java
delete mode 100644 src/main/java/cn/nukkit/event/vehicle/EntityExitVehicleEvent.java
delete mode 100644 src/main/java/cn/nukkit/event/vehicle/VehicleCreateEvent.java
delete mode 100644 src/main/java/cn/nukkit/event/vehicle/VehicleDamageEvent.java
delete mode 100644 src/main/java/cn/nukkit/event/vehicle/VehicleDestroyEvent.java
rename src/main/java/cn/nukkit/utils/{EnumMinecart.java => MinecartType.java} (69%)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 59ac7ffddc..9538c94a7e 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -1670,7 +1670,7 @@ public void checkInteractNearby(){
if(canInteract(this, interactDistance)){
if(getEntityPlayerLookingAt(interactDistance) != null){
EntityInteractable onInteract = getEntityPlayerLookingAt(interactDistance);
- setButtonText(onInteract.getInteractButton());
+ setButtonText(onInteract.getInteractButtonText());
} else {
setButtonText("");
}
diff --git a/src/main/java/cn/nukkit/entity/EntityInteractable.java b/src/main/java/cn/nukkit/entity/EntityInteractable.java
index c5946c0456..bd4fe8ff55 100644
--- a/src/main/java/cn/nukkit/entity/EntityInteractable.java
+++ b/src/main/java/cn/nukkit/entity/EntityInteractable.java
@@ -12,8 +12,8 @@ public EntityInteractable(FullChunk chunk, CompoundTag nbt) {
super(chunk, nbt);
}
- // Todo: Passive entity
- public abstract String getInteractButton();
+ // Todo: Passive entity?? i18n and boat leaving text
+ public abstract String getInteractButtonText();
public abstract boolean canDoInteraction();
diff --git a/src/main/java/cn/nukkit/entity/item/EntityBoat.java b/src/main/java/cn/nukkit/entity/item/EntityBoat.java
index b050d4d413..f4eff3eac1 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityBoat.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityBoat.java
@@ -4,8 +4,6 @@
import cn.nukkit.entity.Entity;
import cn.nukkit.event.entity.EntityDamageByEntityEvent;
import cn.nukkit.event.entity.EntityDamageEvent;
-import cn.nukkit.event.vehicle.VehicleDamageEvent;
-import cn.nukkit.event.vehicle.VehicleDestroyEvent;
import cn.nukkit.event.vehicle.VehicleMoveEvent;
import cn.nukkit.event.vehicle.VehicleUpdateEvent;
import cn.nukkit.item.Item;
@@ -95,26 +93,11 @@ public boolean attack(EntityDamageEvent source) {
if (invulnerable) {
return false;
} else {
- // Event start
- VehicleDamageEvent event = new VehicleDamageEvent(this, source.getEntity(), source.getFinalDamage());
- getServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- return false;
- }
- // Event stop
- performHurtAnimation((int) event.getDamage());
+ performHurtAnimation((int) source.getFinalDamage());
Entity damager = ((EntityDamageByEntityEvent) source).getDamager();
- boolean instantKill = damager instanceof Player
- ? ((Player) damager).isCreative() : false;
+ boolean instantKill = damager instanceof Player && ((Player) damager).isCreative();
if (instantKill || getDamage() > 40) {
- // Event start
- VehicleDestroyEvent event2 = new VehicleDestroyEvent(this, source.getEntity());
- getServer().getPluginManager().callEvent(event2);
- if (event2.isCancelled()) {
- return false;
- }
- // Event stop
if (linkedEntity != null) {
mountEntity(linkedEntity);
}
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
index cea03f10e9..8b51e34d93 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
@@ -15,8 +15,6 @@
import cn.nukkit.entity.data.IntEntityData;
import cn.nukkit.event.entity.EntityDamageByEntityEvent;
import cn.nukkit.event.entity.EntityDamageEvent;
-import cn.nukkit.event.vehicle.VehicleDamageEvent;
-import cn.nukkit.event.vehicle.VehicleDestroyEvent;
import cn.nukkit.event.vehicle.VehicleMoveEvent;
import cn.nukkit.event.vehicle.VehicleUpdateEvent;
import cn.nukkit.item.Item;
@@ -29,7 +27,7 @@
import cn.nukkit.math.Vector3;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.network.protocol.AddEntityPacket;
-import cn.nukkit.utils.EnumMinecart;
+import cn.nukkit.utils.MinecartType;
import cn.nukkit.utils.Rail;
import cn.nukkit.utils.Rail.Orientation;
@@ -45,7 +43,7 @@
public abstract class EntityMinecartAbstract extends EntityVehicle {
private String entityName;
- public final int[][][] matrix = new int[][][]{
+ private static final int[][][] matrix = new int[][][]{
{{0, 0, -1}, {0, 0, 1}},
{{-1, 0, 0}, {1, 0, 0}},
{{-1, -1, 0}, {1, 0, 0}},
@@ -58,9 +56,9 @@ public abstract class EntityMinecartAbstract extends EntityVehicle {
{{0, 0, -1}, {1, 0, 0}}
};
private double currentSpeed = 0;
- protected Block blockInside = null;
+ private Block blockInside = null;
// Plugins modifiers
- public boolean slowWhenEmpty = true;
+ private boolean slowWhenEmpty = true;
private double derailedX = 0.5;
private double derailedY = 0.5;
private double derailedZ = 0.5;
@@ -70,7 +68,7 @@ public abstract class EntityMinecartAbstract extends EntityVehicle {
private double maxSpeed = 0.4D;
private final boolean devs = false; // Avoid maintained features into production
- public abstract EnumMinecart getType();
+ public abstract MinecartType getType();
public EntityMinecartAbstract(FullChunk chunk, CompoundTag nbt) {
super(chunk, nbt);
@@ -232,25 +230,11 @@ public boolean attack(EntityDamageEvent source) {
if (invulnerable) {
return false;
} else {
- // Event start
- VehicleDamageEvent event = new VehicleDamageEvent(this, source.getEntity(), source.getFinalDamage());
- getServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- return false;
- }
- // Event stop
Entity damager = ((EntityDamageByEntityEvent) source).getDamager();
boolean instantKill = damager instanceof Player && ((Player) damager).isCreative();
- performHurtAnimation(instantKill ? 9999 : (int) event.getDamage());
+ if (!instantKill) performHurtAnimation((int) source.getFinalDamage());
if (instantKill || getDamage() > 40) {
- // Event start
- VehicleDestroyEvent event2 = new VehicleDestroyEvent(this, source.getEntity());
- getServer().getPluginManager().callEvent(event2);
- if (event2.isCancelled()) {
- return false;
- }
- // Event stop
if (linkedEntity != null) {
mountEntity(linkedEntity);
}
@@ -411,10 +395,10 @@ public double getMaxSpeed() {
protected void activate(int x, int y, int z, boolean flag) {
}
-
- protected boolean hasUpdated = false;
- protected void setFalling() {
+ private boolean hasUpdated = false;
+
+ private void setFalling() {
motionX = NukkitMath.clamp(motionX, -getMaxSpeed(), getMaxSpeed());
motionZ = NukkitMath.clamp(motionZ, -getMaxSpeed(), getMaxSpeed());
@@ -439,7 +423,7 @@ protected void setFalling() {
}
}
- protected void processMovement(int dx, int dy, int dz, BlockRail block) {
+ private void processMovement(int dx, int dy, int dz, BlockRail block) {
fallDistance = 0.0F;
Vector3 vector = getNextRail(x, y, z);
@@ -452,7 +436,7 @@ protected void processMovement(int dx, int dy, int dz, BlockRail block) {
isSlowed = !block.isActive();
}
- switch (Orientation.byMetadata(((BlockRail) block).getRealMeta())) {
+ switch (Orientation.byMetadata(block.getRealMeta())) {
case ASCENDING_NORTH:
motionX -= 0.0078125D;
y += 1;
@@ -499,8 +483,8 @@ protected void processMovement(int dx, int dy, int dz, BlockRail block) {
expectedSpeed = currentSpeed;
if (expectedSpeed > 0) {
// This is a trajectory (Angle of elevation)
- playerYawNeg = -Math.sin((double) (linkedEntity.yaw * 3.1415927F / 180.0F));
- playerYawPos = Math.cos((double) (linkedEntity.yaw * 3.1415927F / 180.0F));
+ playerYawNeg = -Math.sin(linkedEntity.yaw * 3.1415927F / 180.0F);
+ playerYawPos = Math.cos(linkedEntity.yaw * 3.1415927F / 180.0F);
motion = motionX * motionX + motionZ * motionZ;
if (motion < 0.01D) {
motionX += playerYawNeg * 0.1D;
@@ -616,7 +600,7 @@ protected void processMovement(int dx, int dy, int dz, BlockRail block) {
}
- protected void applyDrag() {
+ private void applyDrag() {
if (linkedEntity != null || !slowWhenEmpty) {
motionX *= 0.996999979019165D;
motionY *= 0.0D;
@@ -628,7 +612,7 @@ protected void applyDrag() {
}
}
- public Vector3 getNextRail(double dx, double dy, double dz) {
+ private Vector3 getNextRail(double dx, double dy, double dz) {
int checkX = MathHelper.floor(dx);
int checkY = MathHelper.floor(dy);
int checkZ = MathHelper.floor(dz);
@@ -642,7 +626,7 @@ public Vector3 getNextRail(double dx, double dy, double dz) {
if (Rail.isRailBlock(block)) {
int[][] facing = matrix[((BlockRail) block).getRealMeta()];
double rail;
- // Genisys minstake (Doesn't check surrounding more exactly)
+ // Genisys mistake (Doesn't check surrounding more exactly)
double nextOne = (double) checkX + 0.5D + (double) facing[0][0] * 0.5D;
double nextTwo = (double) checkY + 0.5D + (double) facing[0][1] * 0.5D;
double nextThree = (double) checkZ + 0.5D + (double) facing[0][2] * 0.5D;
@@ -690,19 +674,6 @@ public void setCurrentSpeed(double speed) {
currentSpeed = speed;
}
- public double wrapAngleTo180(double rotation) {
- rotation %= 360;
- if (rotation >= 180) {
- rotation -= 360;
- }
-
- if (rotation < -180) {
- rotation += 360;
- }
-
- return rotation;
- }
-
private void prepareDataProperty() {
setRollingAmplitude(0);
setRollingDirection(1);
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java
index 453166de45..443f4a8c34 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java
@@ -4,7 +4,7 @@
import cn.nukkit.item.ItemMinecartChest;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
-import cn.nukkit.utils.EnumMinecart;
+import cn.nukkit.utils.MinecartType;
/**
* Created by Snake1999 on 2016/1/30.
@@ -22,8 +22,8 @@ public EntityMinecartChest(FullChunk chunk, CompoundTag nbt) {
// TODO: 2016/1/30 inventory
@Override
- public EnumMinecart getType() {
- return EnumMinecart.valueOf(1);
+ public MinecartType getType() {
+ return MinecartType.valueOf(1);
}
@Override
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java
index 95f9be8e5c..bb6bd52520 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java
@@ -2,7 +2,7 @@
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
-import cn.nukkit.utils.EnumMinecart;
+import cn.nukkit.utils.MinecartType;
/**
* Created by Snake1999 on 2016/1/30.
@@ -22,8 +22,8 @@ public EntityMinecartEmpty(FullChunk chunk, CompoundTag nbt) {
}
@Override
- public EnumMinecart getType() {
- return EnumMinecart.valueOf(0);
+ public MinecartType getType() {
+ return MinecartType.valueOf(0);
}
@Override
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java
index a8f41893a4..90bb1e46ef 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java
@@ -4,7 +4,7 @@
import cn.nukkit.item.ItemMinecartHopper;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
-import cn.nukkit.utils.EnumMinecart;
+import cn.nukkit.utils.MinecartType;
public class EntityMinecartHopper extends EntityMinecartAbstract {
@@ -18,8 +18,8 @@ public EntityMinecartHopper(FullChunk chunk, CompoundTag nbt) {
// TODO: 2016/12/18 inventory
@Override
- public EnumMinecart getType() {
- return EnumMinecart.valueOf(5);
+ public MinecartType getType() {
+ return MinecartType.valueOf(5);
}
@Override
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java
index 855db33e3d..1c520db7c5 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java
@@ -2,15 +2,12 @@
import cn.nukkit.block.BlockTNT;
import cn.nukkit.entity.EntityExplosive;
-import cn.nukkit.entity.data.IntEntityData;
import cn.nukkit.event.entity.EntityExplosionPrimeEvent;
import cn.nukkit.item.ItemMinecartTNT;
import cn.nukkit.level.Explosion;
import cn.nukkit.level.format.FullChunk;
-import cn.nukkit.level.particle.SmokeParticle;
-import cn.nukkit.math.Vector3;
import cn.nukkit.nbt.tag.CompoundTag;
-import cn.nukkit.utils.EnumMinecart;
+import cn.nukkit.utils.MinecartType;
import java.util.Random;
@@ -75,8 +72,8 @@ public void dropItem() {
}
@Override
- public EnumMinecart getType() {
- return EnumMinecart.valueOf(3);
+ public MinecartType getType() {
+ return MinecartType.valueOf(3);
}
@Override
diff --git a/src/main/java/cn/nukkit/entity/item/EntityVehicle.java b/src/main/java/cn/nukkit/entity/item/EntityVehicle.java
index a539cf8b28..6b6939e8a8 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityVehicle.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityVehicle.java
@@ -6,10 +6,8 @@
import cn.nukkit.entity.EntityInteractable;
import cn.nukkit.entity.EntityRideable;
import cn.nukkit.entity.data.IntEntityData;
-import cn.nukkit.event.vehicle.EntityEnterVehicleEvent;
-import cn.nukkit.event.vehicle.EntityExitVehicleEvent;
-import cn.nukkit.event.vehicle.VehicleCreateEvent;
-import cn.nukkit.event.vehicle.VehicleEvent;
+import cn.nukkit.event.entity.EntityVehicleEnterEvent;
+import cn.nukkit.event.entity.EntityVehicleExitEvent;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.network.protocol.SetEntityLinkPacket;
@@ -50,7 +48,7 @@ public void setDamage(int damage) {
}
@Override
- public String getInteractButton() {
+ public String getInteractButtonText() {
return "Mount";
}
@@ -67,13 +65,10 @@ public boolean canDoInteraction() {
*/
public boolean mountEntity(Entity entity) {
Objects.requireNonNull(entity, "The target of the mounting entity can't be null");
- if (!(this instanceof EntityVehicle)) {
- return false;
- }
this.PitchDelta = 0.0D;
this.YawDelta = 0.0D;
if (entity.riding != null) {
- VehicleEvent ev = new EntityExitVehicleEvent(entity, (EntityVehicle) this);
+ EntityVehicleExitEvent ev = new EntityVehicleExitEvent(entity, this);
server.getPluginManager().callEvent(ev);
if (ev.isCancelled()) {
return false;
@@ -99,7 +94,7 @@ public boolean mountEntity(Entity entity) {
entity.setDataFlag(DATA_FLAGS, DATA_FLAG_RIDING, false);
return true;
}
- VehicleEvent ev = new EntityEnterVehicleEvent(entity, (EntityVehicle) this);
+ EntityVehicleEnterEvent ev = new EntityVehicleEnterEvent(entity, this);
server.getPluginManager().callEvent(ev);
if (ev.isCancelled()) {
return false;
@@ -131,16 +126,6 @@ public boolean mountEntity(Entity entity) {
@Override
public boolean onUpdate(int currentTick) {
- if (justCreated) {
- VehicleCreateEvent event = new VehicleCreateEvent(this);
- getServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- kill();
- return false;
- }
- justCreated = false;
- }
-
// The rolling amplitude
if (getRollingAmplitude() > 0) {
setRollingAmplitude(getRollingAmplitude() - 1);
diff --git a/src/main/java/cn/nukkit/event/entity/EntityVehicleEnterEvent.java b/src/main/java/cn/nukkit/event/entity/EntityVehicleEnterEvent.java
new file mode 100644
index 0000000000..12dfe408b7
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/entity/EntityVehicleEnterEvent.java
@@ -0,0 +1,27 @@
+package cn.nukkit.event.entity;
+
+import cn.nukkit.entity.Entity;
+import cn.nukkit.entity.item.EntityVehicle;
+import cn.nukkit.event.Cancellable;
+import cn.nukkit.event.HandlerList;
+
+public class EntityVehicleEnterEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+
+ private final EntityVehicle vehicle;
+
+ public EntityVehicleEnterEvent(Entity entity, EntityVehicle vehicle) {
+ this.entity = entity;
+ this.vehicle = vehicle;
+ }
+
+ public EntityVehicle getVehicle() {
+ return vehicle;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/event/entity/EntityVehicleExitEvent.java b/src/main/java/cn/nukkit/event/entity/EntityVehicleExitEvent.java
new file mode 100644
index 0000000000..61294b9ea7
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/entity/EntityVehicleExitEvent.java
@@ -0,0 +1,27 @@
+package cn.nukkit.event.entity;
+
+import cn.nukkit.entity.Entity;
+import cn.nukkit.entity.item.EntityVehicle;
+import cn.nukkit.event.Cancellable;
+import cn.nukkit.event.HandlerList;
+
+public class EntityVehicleExitEvent extends EntityEvent implements Cancellable {
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+
+ private final EntityVehicle vehicle;
+
+ public EntityVehicleExitEvent(Entity entity, EntityVehicle vehicle) {
+ this.entity = entity;
+ this.vehicle = vehicle;
+ }
+
+ public EntityVehicle getVehicle() {
+ return vehicle;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/event/vehicle/EntityEnterVehicleEvent.java b/src/main/java/cn/nukkit/event/vehicle/EntityEnterVehicleEvent.java
deleted file mode 100644
index 6cc185dbdd..0000000000
--- a/src/main/java/cn/nukkit/event/vehicle/EntityEnterVehicleEvent.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package cn.nukkit.event.vehicle;
-
-import cn.nukkit.Player;
-import cn.nukkit.entity.Entity;
-import cn.nukkit.entity.item.EntityVehicle;
-import cn.nukkit.event.Cancellable;
-import cn.nukkit.event.HandlerList;
-
-public class EntityEnterVehicleEvent extends VehicleEvent implements Cancellable {
-
- private static final HandlerList handlers = new HandlerList();
-
- public static HandlerList getHandlers() {
- return handlers;
- }
-
- private final Entity riding;
-
- public EntityEnterVehicleEvent(Entity riding, EntityVehicle vehicle) {
- super(vehicle);
- this.riding = riding;
- }
-
- public Entity getEntity() {
- return riding;
- }
-
- public boolean isPlayer() {
- return riding instanceof Player;
- }
-
-}
diff --git a/src/main/java/cn/nukkit/event/vehicle/EntityExitVehicleEvent.java b/src/main/java/cn/nukkit/event/vehicle/EntityExitVehicleEvent.java
deleted file mode 100644
index e9dac2494d..0000000000
--- a/src/main/java/cn/nukkit/event/vehicle/EntityExitVehicleEvent.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package cn.nukkit.event.vehicle;
-
-import cn.nukkit.Player;
-import cn.nukkit.entity.Entity;
-import cn.nukkit.entity.item.EntityVehicle;
-import cn.nukkit.event.Cancellable;
-import cn.nukkit.event.HandlerList;
-
-public class EntityExitVehicleEvent extends VehicleEvent implements Cancellable {
-
- private static final HandlerList handlers = new HandlerList();
-
- public static HandlerList getHandlers() {
- return handlers;
- }
-
- private final Entity riding;
-
- public EntityExitVehicleEvent(Entity riding, EntityVehicle vehicle) {
- super(vehicle);
- this.riding = riding;
- }
-
- public Entity getEntity() {
- return riding;
- }
-
- public boolean isPlayer() {
- return riding instanceof Player;
- }
-
-}
diff --git a/src/main/java/cn/nukkit/event/vehicle/VehicleCreateEvent.java b/src/main/java/cn/nukkit/event/vehicle/VehicleCreateEvent.java
deleted file mode 100644
index 24faa86f03..0000000000
--- a/src/main/java/cn/nukkit/event/vehicle/VehicleCreateEvent.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package cn.nukkit.event.vehicle;
-
-import cn.nukkit.entity.item.EntityVehicle;
-import cn.nukkit.event.Cancellable;
-import cn.nukkit.event.HandlerList;
-
-public class VehicleCreateEvent extends VehicleEvent implements Cancellable {
-
- private static final HandlerList handlers = new HandlerList();
-
- public static HandlerList getHandlers() {
- return handlers;
- }
-
- public VehicleCreateEvent(EntityVehicle vehicle) {
- super(vehicle);
- }
-
-}
diff --git a/src/main/java/cn/nukkit/event/vehicle/VehicleDamageEvent.java b/src/main/java/cn/nukkit/event/vehicle/VehicleDamageEvent.java
deleted file mode 100644
index 0a673778c6..0000000000
--- a/src/main/java/cn/nukkit/event/vehicle/VehicleDamageEvent.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package cn.nukkit.event.vehicle;
-
-import cn.nukkit.entity.Entity;
-import cn.nukkit.entity.item.EntityVehicle;
-import cn.nukkit.event.Cancellable;
-import cn.nukkit.event.HandlerList;
-
-public class VehicleDamageEvent extends VehicleEvent implements Cancellable {
-
- private static final HandlerList handlers = new HandlerList();
-
- public static HandlerList getHandlers() {
- return handlers;
- }
-
- private final Entity attacker;
- private double damage;
-
- public VehicleDamageEvent(EntityVehicle vehicle, Entity attacker, double damage) {
- super(vehicle);
- this.attacker = attacker;
- this.damage = damage;
- }
-
- public Entity getAttacker() {
- return attacker;
- }
-
- public double getDamage() {
- return damage;
- }
-
- public void setDamage(double damage) {
- this.damage = damage;
- }
-
-}
diff --git a/src/main/java/cn/nukkit/event/vehicle/VehicleDestroyEvent.java b/src/main/java/cn/nukkit/event/vehicle/VehicleDestroyEvent.java
deleted file mode 100644
index 817b6d4468..0000000000
--- a/src/main/java/cn/nukkit/event/vehicle/VehicleDestroyEvent.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package cn.nukkit.event.vehicle;
-
-import cn.nukkit.entity.Entity;
-import cn.nukkit.entity.item.EntityVehicle;
-import cn.nukkit.event.Cancellable;
-import cn.nukkit.event.HandlerList;
-
-public class VehicleDestroyEvent extends VehicleEvent implements Cancellable {
-
- private static final HandlerList handlers = new HandlerList();
-
- public static HandlerList getHandlers() {
- return handlers;
- }
-
- private final Entity attacker;
-
- public VehicleDestroyEvent(EntityVehicle vehicle, Entity attacker) {
- super(vehicle);
- this.attacker = attacker;
- }
-
- public Entity getAttacker() {
- return attacker;
- }
-
-}
diff --git a/src/main/java/cn/nukkit/item/ItemMinecartChest.java b/src/main/java/cn/nukkit/item/ItemMinecartChest.java
index 6da0ccc3f0..fdee794e64 100644
--- a/src/main/java/cn/nukkit/item/ItemMinecartChest.java
+++ b/src/main/java/cn/nukkit/item/ItemMinecartChest.java
@@ -23,7 +23,7 @@ public ItemMinecartChest(Integer meta) {
}
public ItemMinecartChest(Integer meta, int count) {
- super(MINECART_WITH_CHEST, meta, count, "Minecart With Chest");
+ super(MINECART_WITH_CHEST, meta, count, "Minecart with Chest");
}
@Override
diff --git a/src/main/java/cn/nukkit/item/ItemMinecartHopper.java b/src/main/java/cn/nukkit/item/ItemMinecartHopper.java
index b7606856b5..46b9d2865f 100644
--- a/src/main/java/cn/nukkit/item/ItemMinecartHopper.java
+++ b/src/main/java/cn/nukkit/item/ItemMinecartHopper.java
@@ -23,7 +23,7 @@ public ItemMinecartHopper(Integer meta) {
}
public ItemMinecartHopper(Integer meta, int count) {
- super(MINECART_WITH_HOPPER, meta, count, "Minecart With Hopper");
+ super(MINECART_WITH_HOPPER, meta, count, "Minecart with Hopper");
}
@Override
diff --git a/src/main/java/cn/nukkit/item/ItemMinecartTNT.java b/src/main/java/cn/nukkit/item/ItemMinecartTNT.java
index 951e4ae673..51a9d1c93d 100644
--- a/src/main/java/cn/nukkit/item/ItemMinecartTNT.java
+++ b/src/main/java/cn/nukkit/item/ItemMinecartTNT.java
@@ -23,7 +23,7 @@ public ItemMinecartTNT(Integer meta) {
}
public ItemMinecartTNT(Integer meta, int count) {
- super(MINECART_WITH_TNT, meta, count, "Minecart With TNT");
+ super(MINECART_WITH_TNT, meta, count, "Minecart with TNT");
}
@Override
diff --git a/src/main/java/cn/nukkit/utils/EnumMinecart.java b/src/main/java/cn/nukkit/utils/MinecartType.java
similarity index 69%
rename from src/main/java/cn/nukkit/utils/EnumMinecart.java
rename to src/main/java/cn/nukkit/utils/MinecartType.java
index 68c34f3b78..e369644629 100644
--- a/src/main/java/cn/nukkit/utils/EnumMinecart.java
+++ b/src/main/java/cn/nukkit/utils/MinecartType.java
@@ -11,7 +11,7 @@
* Creation time: 2017/7/17 19:55.
*/
@API(usage = API.Usage.STABLE, definition = API.Definition.INTERNAL)
-public enum EnumMinecart {
+public enum MinecartType {
/**
* Represents an empty vehicle.
*/
@@ -19,11 +19,11 @@ public enum EnumMinecart {
/**
* Represents a chest holder.
*/
- MINECART_CHEST(1, true, "Minecart with chest"),
+ MINECART_CHEST(1, true, "Minecart with Chest"),
/**
* Represents a furnace minecart.
*/
- MINECART_FURNACE(2, true, "Minecart with furnace"),
+ MINECART_FURNACE(2, true, "Minecart with Furnace"),
/**
* Represents a TNT minecart.
*/
@@ -35,7 +35,7 @@ public enum EnumMinecart {
/**
* Represents a hopper minecart.
*/
- MINECART_HOPPER(5, true, "Minecart with hopper"),
+ MINECART_HOPPER(5, true, "Minecart with Hopper"),
/**
* Represents a command block minecart.
*/
@@ -43,25 +43,25 @@ public enum EnumMinecart {
/**
* Represents an unknown minecart.
*/
- MINECART_UNKNOWN(-1, false, "Minecart unknown");
+ MINECART_UNKNOWN(-1, false, "Unknown Minecart");
private final int type;
- private final boolean hasBlockyInside;
+ private final boolean hasBlockInside;
private final String realName;
- private static final Map TYPES = new HashMap<>();
+ private static final Map TYPES = new HashMap<>();
static {
- EnumMinecart[] types = values();
+ MinecartType[] types = values();
int var1 = types.length;
for (int var2 = 0; var2 < var1; var2++) {
- EnumMinecart var3 = types[var2];
- TYPES.put(Integer.valueOf(var3.getId()), var3);
+ MinecartType var3 = types[var2];
+ TYPES.put(var3.getId(), var3);
}
}
- EnumMinecart(int number, boolean hasBlockInside, String name) {
+ MinecartType(int number, boolean hasBlockInside, String name) {
type = number;
- hasBlockyInside = hasBlockInside;
+ this.hasBlockInside = hasBlockInside;
realName = name;
}
@@ -88,8 +88,8 @@ public String getName() {
*
* @return Boolean
*/
- public boolean isBlockOverrides() {
- return hasBlockyInside;
+ public boolean hasBlockInside() {
+ return hasBlockInside;
}
/**
@@ -98,8 +98,8 @@ public boolean isBlockOverrides() {
* @param types The number of minecart
* @return Integer
*/
- public static EnumMinecart valueOf(int types) {
- EnumMinecart what = (EnumMinecart) TYPES.get(types);
+ public static MinecartType valueOf(int types) {
+ MinecartType what = TYPES.get(types);
return what == null ? MINECART_UNKNOWN : what;
}
}
From e71ae762bfcd4971715f75eab769dab281a37c9c Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Tue, 1 Aug 2017 22:01:12 +0200
Subject: [PATCH 025/175] Fix crash
---
src/main/java/cn/nukkit/Player.java | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index c75430145b..93acaba934 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -2264,12 +2264,6 @@ public void handleDataPacket(DataPacket packet) {
this.level.sendBlocks(new Player[]{this}, new Block[]{target, block}, UpdateBlockPacket.FLAG_ALL_PRIORITY);
break;
} else if (useItemPacket.face == -1) {
- Vector3 aimPos = new Vector3(
- -Math.sin(this.yaw / 180d * Math.PI) * Math.cos(this.pitch / 180d * Math.PI),
- -Math.sin(this.pitch / 180d * Math.PI),
- Math.cos(this.yaw / 180d * Math.PI) * Math.cos(this.pitch / 180d * Math.PI)
- );
-
if (this.isCreative()) {
item = this.inventory.getItemInHand();
} else if (!this.inventory.getItemInHand().deepEquals(useItemPacket.item)) {
@@ -2279,6 +2273,12 @@ public void handleDataPacket(DataPacket packet) {
item = this.inventory.getItemInHand();
}
+ Vector3 aimPos = new Vector3(
+ -Math.sin(this.yaw / 180d * Math.PI) * Math.cos(this.pitch / 180d * Math.PI),
+ -Math.sin(this.pitch / 180d * Math.PI),
+ Math.cos(this.yaw / 180d * Math.PI) * Math.cos(this.pitch / 180d * Math.PI)
+ );
+
PlayerInteractEvent playerInteractEvent = new PlayerInteractEvent(this, item, aimPos, null, Action.RIGHT_CLICK_AIR);
this.server.getPluginManager().callEvent(playerInteractEvent);
@@ -2288,6 +2288,11 @@ public void handleDataPacket(DataPacket packet) {
break;
}
+ if (this.getFoodData().getLevel() < 20 && Food.getByRelative(item) != null) {
+ this.setDataFlag(DATA_FLAGS, DATA_FLAG_ACTION);
+ break;
+ }
+
if (item.getId() == Item.SNOWBALL) {
CompoundTag nbt = new CompoundTag()
.putList(new ListTag("Pos")
@@ -2531,7 +2536,6 @@ public void handleDataPacket(DataPacket packet) {
case PlayerActionPacket.ACTION_RELEASE_ITEM:
if (this.startAction > -1 && this.getDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION)) {
if (this.inventory.getItemInHand().getId() == Item.BOW) {
-
Item bow = this.inventory.getItemInHand();
ItemArrow itemArrow = new ItemArrow();
if (this.isSurvival() && !this.inventory.contains(itemArrow)) {
@@ -2619,6 +2623,8 @@ public void handleDataPacket(DataPacket packet) {
}
//milk removed here, see the section of food
+ this.setDataFlag(DATA_FLAGS, DATA_FLAG_ACTION, false);
+ break;
case PlayerActionPacket.ACTION_STOP_SLEEPING:
this.stopSleep();
break;
@@ -2951,11 +2957,11 @@ public void handleDataPacket(DataPacket packet) {
}
this.craftingType = CRAFTING_SMALL;
- this.setDataFlag(DATA_FLAGS, DATA_FLAG_ACTION, false); //TODO: check if this should be true
EntityEventPacket entityEventPacket = (EntityEventPacket) packet;
switch (entityEventPacket.event) {
case EntityEventPacket.USE_ITEM: //Eating
+ this.setDataFlag(DATA_FLAGS, DATA_FLAG_ACTION, false);
Item itemInHand = this.inventory.getItemInHand();
PlayerItemConsumeEvent consumeEvent = new PlayerItemConsumeEvent(this, itemInHand);
this.server.getPluginManager().callEvent(consumeEvent);
@@ -2992,7 +2998,6 @@ public void handleDataPacket(DataPacket packet) {
Food food = Food.getByRelative(itemInHand);
if (food != null) if (food.eatenBy(this)) --itemInHand.count;
-
}
this.inventory.setItemInHand(itemInHand);
@@ -3005,8 +3010,10 @@ public void handleDataPacket(DataPacket packet) {
pk.event = EntityEventPacket.CONSUME_ITEM;
pk.itemId = this.inventory.getItemInHand().getId();
- Server.broadcastPacket(this.getViewers().values(), pk);
- this.dataPacket(pk);
+ if (pk.itemId != Item.POTION) { //idk what's wrong
+ Server.broadcastPacket(this.getViewers().values(), pk);
+ this.dataPacket(pk);
+ }
break;
}
break;
From 4657ff17f79f02d3dd83024c0ba2aa0e80cbb599 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Wed, 2 Aug 2017 12:22:49 +0200
Subject: [PATCH 026/175] improvements
---
src/main/java/cn/nukkit/Player.java | 200 +--
src/main/java/cn/nukkit/Server.java | 25 +-
src/main/java/cn/nukkit/entity/Entity.java | 22 +-
.../cn/nukkit/entity/EntityInteractable.java | 2 +-
.../java/cn/nukkit/entity/EntityLiving.java | 2 +-
.../cn/nukkit/entity/item/EntityBoat.java | 6 +-
.../cn/nukkit/entity/item/EntityItem.java | 9 +-
.../entity/item/EntityMinecartAbstract.java | 36 +-
.../entity/item/EntityMinecartChest.java | 3 +-
.../entity/item/EntityMinecartEmpty.java | 2 +-
.../entity/item/EntityMinecartHopper.java | 2 +-
.../cn/nukkit/entity/item/EntityPainting.java | 2 +-
.../cn/nukkit/entity/item/EntityVehicle.java | 5 +-
.../cn/nukkit/entity/item/EntityXPOrb.java | 8 +
.../java/cn/nukkit/entity/mob/EntityMob.java | 2 +-
.../cn/nukkit/entity/mob/EntitySkeleton.java | 2 +-
.../cn/nukkit/entity/mob/EntityZombie.java | 2 +-
.../nukkit/entity/mob/EntityZombiePigman.java | 2 +-
.../cn/nukkit/entity/passive/EntityBat.java | 1 -
.../nukkit/entity/passive/EntityChicken.java | 2 +-
.../cn/nukkit/entity/passive/EntityCow.java | 2 +-
.../nukkit/entity/passive/EntityDonkey.java | 1 -
.../cn/nukkit/entity/passive/EntityHorse.java | 1 -
.../cn/nukkit/entity/passive/EntityLlama.java | 1 -
.../entity/passive/EntityMooshroom.java | 2 +-
.../cn/nukkit/entity/passive/EntityMule.java | 1 -
.../nukkit/entity/passive/EntityOcelot.java | 2 +-
.../cn/nukkit/entity/passive/EntityPig.java | 2 +-
.../entity/passive/EntityPolarBear.java | 1 -
.../nukkit/entity/passive/EntityRabbit.java | 2 +-
.../cn/nukkit/entity/passive/EntitySheep.java | 2 +-
.../entity/passive/EntitySkeletonHorse.java | 1 -
.../cn/nukkit/entity/passive/EntitySquid.java | 1 -
.../cn/nukkit/entity/passive/EntityWolf.java | 2 +-
.../entity/passive/EntityZombieHorse.java | 1 -
.../cn/nukkit/inventory/BigShapedRecipe.java | 2 +-
.../cn/nukkit/inventory/CraftingManager.java | 1213 +----------------
.../cn/nukkit/inventory/PlayerInventory.java | 2 +-
.../cn/nukkit/inventory/ShapedRecipe.java | 36 +-
src/main/java/cn/nukkit/level/Level.java | 3 +-
.../nukkit/network/protocol/ProtocolInfo.java | 3 +-
src/main/java/cn/nukkit/utils/Utils.java | 32 +-
src/main/resources/recipes.json | 6 +-
43 files changed, 271 insertions(+), 1383 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 9538c94a7e..4b0a4b136a 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -197,6 +197,8 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
private ClientChainData loginChainData;
+ public int pickedXPOrb = 0;
+
public BlockEnderChest getViewingEnderChest() {
return viewingEnderChest;
}
@@ -1248,6 +1250,8 @@ protected void checkBlockCollision() {
if (portal) {
inPortalTicks++;
+ } else {
+ this.inPortalTicks = 0;
}
}
@@ -1259,95 +1263,7 @@ protected void checkNearEntities() {
continue;
}
- if (entity instanceof EntityArrow && ((EntityArrow) entity).hadCollision) {
- ItemArrow item = new ItemArrow();
- if (this.isSurvival() && !this.inventory.canAddItem(item)) {
- continue;
- }
-
- InventoryPickupArrowEvent ev;
- this.server.getPluginManager().callEvent(ev = new InventoryPickupArrowEvent(this.inventory, (EntityArrow) entity));
- if (ev.isCancelled()) {
- continue;
- }
-
- TakeItemEntityPacket pk = new TakeItemEntityPacket();
- pk.entityId = this.getId();
- pk.target = entity.getId();
- Server.broadcastPacket(entity.getViewers().values(), pk);
-
- pk = new TakeItemEntityPacket();
- pk.entityId = this.id;
- pk.target = entity.getId();
- this.dataPacket(pk);
-
- this.inventory.addItem(item.clone());
- entity.kill();
- } else if (entity instanceof EntityItem) {
- if (((EntityItem) entity).getPickupDelay() <= 0) {
- Item item = ((EntityItem) entity).getItem();
-
- if (item != null) {
- if (this.isSurvival() && !this.inventory.canAddItem(item)) {
- continue;
- }
-
- InventoryPickupItemEvent ev;
- this.server.getPluginManager().callEvent(ev = new InventoryPickupItemEvent(this.inventory, (EntityItem) entity));
- if (ev.isCancelled()) {
- continue;
- }
-
- switch (item.getId()) {
- case Item.WOOD:
- case Item.WOOD2:
- this.awardAchievement("mineWood");
- break;
- case Item.DIAMOND:
- this.awardAchievement("diamond");
- break;
- }
- /*switch (item.getId()) {
- case Item.WOOD:
- this.awardAchievement("mineWood");
- break;
- case Item.DIAMOND:
- this.awardAchievement("diamond");
- break;
- }*/
-
- TakeItemEntityPacket pk = new TakeItemEntityPacket();
- pk.entityId = this.getId();
- pk.target = entity.getId();
- Server.broadcastPacket(entity.getViewers().values(), pk);
-
- pk = new TakeItemEntityPacket();
- pk.entityId = this.id;
- pk.target = entity.getId();
- this.dataPacket(pk);
-
- this.inventory.addItem(item.clone());
- entity.kill();
- }
- }
- }
- }
- for (Entity entity : this.level.getNearbyEntities(this.boundingBox.grow(3.5, 2, 3.5), this)) {
- entity.scheduleUpdate();
-
- if (!entity.isAlive() || !this.isAlive()) {
- continue;
- }
- if (entity instanceof EntityXPOrb) {
- EntityXPOrb xpOrb = (EntityXPOrb) entity;
- if (xpOrb.getPickupDelay() <= 0) {
- int exp = xpOrb.getExp();
- this.addExperience(exp);
- entity.kill();
- this.getLevel().addSound(new ExperienceOrbSound(this));
- break;
- }
- }
+ this.pickupEntity(entity, true);
}
}
@@ -4496,7 +4412,7 @@ protected boolean checkTeleportPosition() {
}
}
- if (this.isLevelChange) { //TODO: remove this
+ /*if (this.isLevelChange) { //TODO: remove this
PlayStatusPacket statusPacket0 = new PlayStatusPacket();//Weather
this.getLevel().sendWeather(this);
//Update time
@@ -4508,7 +4424,7 @@ protected boolean checkTeleportPosition() {
this.getLevel().sendWeather(this);
//Update time
this.getLevel().sendTime(this);
- }
+ }*/
this.spawnToAll();
this.isLevelChange = false;
@@ -4572,7 +4488,7 @@ public boolean teleport(Location location, TeleportCause cause) {
this.getLevel().sendTime(this);
if (from.getLevel().getId() != to.level.getId()) {
- if (this.spawned) {
+ /*if (this.spawned) { //broken
//TODO: remove this in future version
this.isLevelChange = true;
this.nextChunkOrderRun = 10000;
@@ -4600,7 +4516,7 @@ public boolean teleport(Location location, TeleportCause cause) {
dataPacket(changeDimensionPacket);
nextChunkOrderRun = 0;
}, 9);
- }
+ }*/
}
return true;
}
@@ -4941,6 +4857,104 @@ public ClientChainData getLoginChainData() {
return this.loginChainData;
}
+ public boolean pickupEntity(Entity entity, boolean near) {
+ if (!this.spawned || !this.isAlive() || !this.isOnline()) {
+ return false;
+ }
+
+ if (near) {
+ if (entity instanceof EntityArrow && ((EntityArrow) entity).hadCollision) {
+ ItemArrow item = new ItemArrow();
+ if (this.isSurvival() && !this.inventory.canAddItem(item)) {
+ return false;
+ }
+
+ InventoryPickupArrowEvent ev;
+ this.server.getPluginManager().callEvent(ev = new InventoryPickupArrowEvent(this.inventory, (EntityArrow) entity));
+ if (ev.isCancelled()) {
+ return false;
+ }
+
+ TakeItemEntityPacket pk = new TakeItemEntityPacket();
+ pk.entityId = this.getId();
+ pk.target = entity.getId();
+ Server.broadcastPacket(entity.getViewers().values(), pk);
+
+ pk = new TakeItemEntityPacket();
+ pk.entityId = this.id;
+ pk.target = entity.getId();
+ this.dataPacket(pk);
+
+ this.inventory.addItem(item.clone());
+ entity.kill();
+ return true;
+ } else if (entity instanceof EntityItem) {
+ if (((EntityItem) entity).getPickupDelay() <= 0) {
+ Item item = ((EntityItem) entity).getItem();
+
+ if (item != null) {
+ if (this.isSurvival() && !this.inventory.canAddItem(item)) {
+ return false;
+ }
+
+ InventoryPickupItemEvent ev;
+ this.server.getPluginManager().callEvent(ev = new InventoryPickupItemEvent(this.inventory, (EntityItem) entity));
+ if (ev.isCancelled()) {
+ return false;
+ }
+
+ switch (item.getId()) {
+ case Item.WOOD:
+ case Item.WOOD2:
+ this.awardAchievement("mineWood");
+ break;
+ case Item.DIAMOND:
+ this.awardAchievement("diamond");
+ break;
+ }
+ /*switch (item.getId()) {
+ case Item.WOOD:
+ this.awardAchievement("mineWood");
+ break;
+ case Item.DIAMOND:
+ this.awardAchievement("diamond");
+ break;
+ }*/
+
+ TakeItemEntityPacket pk = new TakeItemEntityPacket();
+ pk.entityId = this.getId();
+ pk.target = entity.getId();
+ Server.broadcastPacket(entity.getViewers().values(), pk);
+
+ pk = new TakeItemEntityPacket();
+ pk.entityId = this.id;
+ pk.target = entity.getId();
+ this.dataPacket(pk);
+
+ this.inventory.addItem(item.clone());
+ entity.kill();
+ return true;
+ }
+ }
+ }
+ }
+
+ int tick = this.getServer().getTick();
+ if (pickedXPOrb < tick && entity instanceof EntityXPOrb && this.boundingBox.isVectorInside(entity)) {
+ EntityXPOrb xpOrb = (EntityXPOrb) entity;
+ if (xpOrb.getPickupDelay() <= 0) {
+ int exp = xpOrb.getExp();
+ this.addExperience(exp);
+ entity.kill();
+ this.getLevel().addSound(new ExperienceOrbSound(this));
+ pickedXPOrb = tick;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
@Override
public int hashCode() {
if ((this.hash == 0) || (this.hash == 485)) {
diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java
index 9a12c51abf..81add9a976 100644
--- a/src/main/java/cn/nukkit/Server.java
+++ b/src/main/java/cn/nukkit/Server.java
@@ -17,7 +17,8 @@
import cn.nukkit.event.level.LevelInitEvent;
import cn.nukkit.event.level.LevelLoadEvent;
import cn.nukkit.event.server.QueryRegenerateEvent;
-import cn.nukkit.inventory.*;
+import cn.nukkit.inventory.CraftingManager;
+import cn.nukkit.inventory.Recipe;
import cn.nukkit.item.Item;
import cn.nukkit.item.enchantment.Enchantment;
import cn.nukkit.lang.BaseLang;
@@ -48,7 +49,10 @@
import cn.nukkit.network.Network;
import cn.nukkit.network.RakNetInterface;
import cn.nukkit.network.SourceInterface;
-import cn.nukkit.network.protocol.*;
+import cn.nukkit.network.protocol.BatchPacket;
+import cn.nukkit.network.protocol.DataPacket;
+import cn.nukkit.network.protocol.PlayerListPacket;
+import cn.nukkit.network.protocol.ProtocolInfo;
import cn.nukkit.network.query.QueryHandler;
import cn.nukkit.network.rcon.RCON;
import cn.nukkit.permission.BanEntry;
@@ -889,22 +893,7 @@ public void sendFullPlayerListData(Player player) {
}
public void sendRecipeList(Player player) {
- CraftingDataPacket pk = new CraftingDataPacket();
- pk.cleanRecipes = true;
-
- for (Recipe recipe : this.getCraftingManager().getRecipes().values()) {
- if (recipe instanceof ShapedRecipe) {
- pk.addShapedRecipe((ShapedRecipe) recipe);
- } else if (recipe instanceof ShapelessRecipe) {
- pk.addShapelessRecipe((ShapelessRecipe) recipe);
- }
- }
-
- for (FurnaceRecipe recipe : this.getCraftingManager().getFurnaceRecipes().values()) {
- pk.addFurnaceRecipe(recipe);
- }
-
- player.dataPacket(pk);
+ player.dataPacket(CraftingManager.packet);
}
private void checkTickUpdates(int currentTick, long tickTime) {
diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java
index 0d810437ce..ff3fe69f08 100644
--- a/src/main/java/cn/nukkit/entity/Entity.java
+++ b/src/main/java/cn/nukkit/entity/Entity.java
@@ -26,7 +26,10 @@
import cn.nukkit.nbt.tag.DoubleTag;
import cn.nukkit.nbt.tag.FloatTag;
import cn.nukkit.nbt.tag.ListTag;
-import cn.nukkit.network.protocol.*;
+import cn.nukkit.network.protocol.MobEffectPacket;
+import cn.nukkit.network.protocol.RemoveEntityPacket;
+import cn.nukkit.network.protocol.SetEntityDataPacket;
+import cn.nukkit.network.protocol.SetEntityMotionPacket;
import cn.nukkit.plugin.Plugin;
import cn.nukkit.potion.Effect;
import cn.nukkit.utils.ChunkException;
@@ -222,10 +225,10 @@ public abstract class Entity extends Location implements Metadatable {
public double lastYaw;
public double lastPitch;
-
+
public double PitchDelta;
public double YawDelta;
-
+
public double entityCollisionReduction = 0; // Higher than 0.9 will result a fast collisions
public AxisAlignedBB boundingBox;
public boolean onGround;
@@ -545,7 +548,7 @@ public void setScale(float scale) {
public float getScale() {
return this.scale;
}
-
+
public Entity getLinkedEntity() {
return linkedEntity;
}
@@ -1086,12 +1089,11 @@ public boolean entityBaseTick(int tickDiff) {
}
}
- if (this.inPortalTicks > 80) {
+ if (this.inPortalTicks == 80) {
EntityPortalEnterEvent ev = new EntityPortalEnterEvent(this, PortalType.NETHER);
getServer().getPluginManager().callEvent(ev);
-
+
//TODO: teleport
- this.inPortalTicks = 0;
}
this.age += tickDiff;
@@ -1457,7 +1459,7 @@ public boolean isInsideOfFire() {
return false;
}
-
+
public boolean fastMove(double dx, double dy, double dz) {
if (dx == 0 && dy == 0 && dz == 0) {
return true;
@@ -1488,7 +1490,7 @@ public boolean fastMove(double dx, double dy, double dz) {
Timings.entityMoveTimer.stopTiming();
return true;
}
-
+
public boolean move(double dx, double dy, double dz) {
if (dx == 0 && dz == 0 && dy == 0) {
return true;
@@ -1666,6 +1668,8 @@ protected void checkBlockCollision() {
if (portal) {
inPortalTicks++;
+ } else {
+ this.inPortalTicks = 0;
}
if (vector.lengthSquared() > 0) {
diff --git a/src/main/java/cn/nukkit/entity/EntityInteractable.java b/src/main/java/cn/nukkit/entity/EntityInteractable.java
index bd4fe8ff55..22a44e01e4 100644
--- a/src/main/java/cn/nukkit/entity/EntityInteractable.java
+++ b/src/main/java/cn/nukkit/entity/EntityInteractable.java
@@ -14,7 +14,7 @@ public EntityInteractable(FullChunk chunk, CompoundTag nbt) {
// Todo: Passive entity?? i18n and boat leaving text
public abstract String getInteractButtonText();
-
+
public abstract boolean canDoInteraction();
}
diff --git a/src/main/java/cn/nukkit/entity/EntityLiving.java b/src/main/java/cn/nukkit/entity/EntityLiving.java
index b0f743eedf..932baed7ff 100644
--- a/src/main/java/cn/nukkit/entity/EntityLiving.java
+++ b/src/main/java/cn/nukkit/entity/EntityLiving.java
@@ -24,7 +24,7 @@
import java.util.Map;
/**
- * author: MagicDroidX
+ * author: MagicDroidX
* Nukkit Project
*/
public abstract class EntityLiving extends Entity implements EntityDamageable {
diff --git a/src/main/java/cn/nukkit/entity/item/EntityBoat.java b/src/main/java/cn/nukkit/entity/item/EntityBoat.java
index f4eff3eac1..a28e3209d2 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityBoat.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityBoat.java
@@ -62,7 +62,7 @@ protected float getGravity() {
public float getBaseOffset() {
return 0.35F;
}
-
+
@Override
public int getNetworkId() {
return NETWORK_ID;
@@ -112,7 +112,7 @@ public boolean attack(EntityDamageEvent source) {
}
}
}
-
+
return true;
}
@@ -146,7 +146,7 @@ public boolean onUpdate(int currentTick) {
if (this.isAlive()) {
super.onUpdate(currentTick);
-
+
this.motionY = (this.level.getBlock(new Vector3(this.x, this.y, this.z)).getBoundingBox() != null || this.isInsideOfWater()) ? getGravity() : -0.08;
if (this.checkObstruction(this.x, this.y, this.z)) {
diff --git a/src/main/java/cn/nukkit/entity/item/EntityItem.java b/src/main/java/cn/nukkit/entity/item/EntityItem.java
index 9baf3460c7..655536819f 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityItem.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityItem.java
@@ -133,12 +133,19 @@ public boolean onUpdate(int currentTick) {
boolean hasUpdate = this.entityBaseTick(tickDiff);
if (this.isAlive()) {
-
if (this.pickupDelay > 0 && this.pickupDelay < 32767) {
this.pickupDelay -= tickDiff;
if (this.pickupDelay < 0) {
this.pickupDelay = 0;
}
+ } else {
+ for (Entity entity : this.level.getNearbyEntities(this.boundingBox.grow(1, 0.5, 1), this)) {
+ if (entity instanceof Player) {
+ if (((Player) entity).pickupEntity(this, true)) {
+ return true;
+ }
+ }
+ }
}
this.motionY -= this.getGravity();
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
index 8b51e34d93..7924d5ef28 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
@@ -44,16 +44,16 @@ public abstract class EntityMinecartAbstract extends EntityVehicle {
private String entityName;
private static final int[][][] matrix = new int[][][]{
- {{0, 0, -1}, {0, 0, 1}},
- {{-1, 0, 0}, {1, 0, 0}},
- {{-1, -1, 0}, {1, 0, 0}},
- {{-1, 0, 0}, {1, -1, 0}},
- {{0, 0, -1}, {0, -1, 1}},
- {{0, -1, -1}, {0, 0, 1}},
- {{0, 0, 1}, {1, 0, 0}},
- {{0, 0, 1}, {-1, 0, 0}},
- {{0, 0, -1}, {-1, 0, 0}},
- {{0, 0, -1}, {1, 0, 0}}
+ {{0, 0, -1}, {0, 0, 1}},
+ {{-1, 0, 0}, {1, 0, 0}},
+ {{-1, -1, 0}, {1, 0, 0}},
+ {{-1, 0, 0}, {1, -1, 0}},
+ {{0, 0, -1}, {0, -1, 1}},
+ {{0, -1, -1}, {0, 0, 1}},
+ {{0, 0, 1}, {1, 0, 0}},
+ {{0, 0, 1}, {-1, 0, 0}},
+ {{0, 0, -1}, {-1, 0, 0}},
+ {{0, 0, -1}, {1, 0, 0}}
};
private double currentSpeed = 0;
private Block blockInside = null;
@@ -112,7 +112,7 @@ public boolean hasCustomName() {
public boolean canDoInteraction() {
return linkedEntity == null && this.getDisplayBlock() == null;
}
-
+
@Override
public float getMountedYOffset() {
return 0.45F; // Real minecart offset
@@ -187,13 +187,13 @@ public boolean onUpdate(int currentTick) {
if (diffX * diffX + diffZ * diffZ > 0.001D) {
yawToChange = (Math.atan2(diffZ, diffX) * 180 / 3.141592653589793D);
}
-
+
// Reverse yaw if yaw is below 0
if (yawToChange < 0) {
// -90-(-90)-(-90) = 90
yawToChange -= yawToChange - yawToChange;
}
-
+
setRotation(yawToChange, pitch);
Location from = new Location(lastX, lastY, lastZ, lastYaw, lastPitch, level);
@@ -249,7 +249,7 @@ public boolean attack(EntityDamageEvent source) {
}
}
}
-
+
return true;
}
@@ -401,14 +401,14 @@ protected void activate(int x, int y, int z, boolean flag) {
private void setFalling() {
motionX = NukkitMath.clamp(motionX, -getMaxSpeed(), getMaxSpeed());
motionZ = NukkitMath.clamp(motionZ, -getMaxSpeed(), getMaxSpeed());
-
- if(linkedEntity != null && !hasUpdated){
+
+ if (linkedEntity != null && !hasUpdated) {
updateRiderPosition(getMountedYOffset() + 0.35F);
hasUpdated = true;
} else {
hasUpdated = false;
}
-
+
if (onGround) {
motionX *= derailedX;
motionY *= derailedY;
@@ -424,7 +424,7 @@ private void setFalling() {
}
private void processMovement(int dx, int dy, int dz, BlockRail block) {
- fallDistance = 0.0F;
+ fallDistance = 0.0F;
Vector3 vector = getNextRail(x, y, z);
y = (double) dy;
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java
index 443f4a8c34..01b5fe1cd0 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java
@@ -20,7 +20,7 @@ public EntityMinecartChest(FullChunk chunk, CompoundTag nbt) {
}
// TODO: 2016/1/30 inventory
-
+
@Override
public MinecartType getType() {
return MinecartType.valueOf(1);
@@ -37,5 +37,4 @@ public void dropItem() {
}
-
}
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java
index bb6bd52520..137b83cc34 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java
@@ -20,7 +20,7 @@ public int getNetworkId() {
public EntityMinecartEmpty(FullChunk chunk, CompoundTag nbt) {
super(chunk, nbt);
}
-
+
@Override
public MinecartType getType() {
return MinecartType.valueOf(0);
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java
index 90bb1e46ef..7a26832d5f 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java
@@ -21,7 +21,7 @@ public EntityMinecartHopper(FullChunk chunk, CompoundTag nbt) {
public MinecartType getType() {
return MinecartType.valueOf(5);
}
-
+
@Override
public int getNetworkId() {
return NETWORK_ID;
diff --git a/src/main/java/cn/nukkit/entity/item/EntityPainting.java b/src/main/java/cn/nukkit/entity/item/EntityPainting.java
index 14a34b2252..33f373aabb 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityPainting.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityPainting.java
@@ -91,7 +91,7 @@ public void spawnTo(Player player) {
@Override
public boolean attack(EntityDamageEvent source) {
- if (super.attack(source)){
+ if (super.attack(source)) {
if (source instanceof EntityDamageByEntityEvent) {
Entity damager = ((EntityDamageByEntityEvent) source).getDamager();
if (damager instanceof Player && ((Player) damager).isSurvival() && this.level.getGameRules().getBoolean("doEntityDrops")) {
diff --git a/src/main/java/cn/nukkit/entity/item/EntityVehicle.java b/src/main/java/cn/nukkit/entity/item/EntityVehicle.java
index 6b6939e8a8..74ab837635 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityVehicle.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityVehicle.java
@@ -11,10 +11,11 @@
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.network.protocol.SetEntityLinkPacket;
+
import java.util.Objects;
/**
- * author: MagicDroidX
+ * author: MagicDroidX
* Nukkit Project
*/
public abstract class EntityVehicle extends EntityInteractable implements EntityRideable {
@@ -142,7 +143,7 @@ public boolean onUpdate(int currentTick) {
updateMovement();
return true;
}
-
+
protected boolean rollingDirection = true;
protected boolean performHurtAnimation(int damage) {
diff --git a/src/main/java/cn/nukkit/entity/item/EntityXPOrb.java b/src/main/java/cn/nukkit/entity/item/EntityXPOrb.java
index 708ec9b3f7..fb225ee9be 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityXPOrb.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityXPOrb.java
@@ -108,6 +108,14 @@ public boolean onUpdate(int currentTick) {
if (this.pickupDelay < 0) {
this.pickupDelay = 0;
}
+ } else {
+ for (Entity entity : this.level.getCollidingEntities(this.boundingBox, this)) {
+ if (entity instanceof Player) {
+ if (((Player) entity).pickupEntity(this, false)) {
+ return true;
+ }
+ }
+ }
}
this.motionY -= this.getGravity();
diff --git a/src/main/java/cn/nukkit/entity/mob/EntityMob.java b/src/main/java/cn/nukkit/entity/mob/EntityMob.java
index 6568c4e6b3..b682f0ca24 100644
--- a/src/main/java/cn/nukkit/entity/mob/EntityMob.java
+++ b/src/main/java/cn/nukkit/entity/mob/EntityMob.java
@@ -5,7 +5,7 @@
import cn.nukkit.nbt.tag.CompoundTag;
/**
- * author: MagicDroidX
+ * author: MagicDroidX
* Nukkit Project
*/
public abstract class EntityMob extends EntityCreature {
diff --git a/src/main/java/cn/nukkit/entity/mob/EntitySkeleton.java b/src/main/java/cn/nukkit/entity/mob/EntitySkeleton.java
index c3012951b2..3bc49cb9b3 100644
--- a/src/main/java/cn/nukkit/entity/mob/EntitySkeleton.java
+++ b/src/main/java/cn/nukkit/entity/mob/EntitySkeleton.java
@@ -37,7 +37,7 @@ public float getWidth() {
public float getHeight() {
return 1.8f;
}
-
+
@Override
public void spawnTo(Player player) {
AddEntityPacket pk = new AddEntityPacket();
diff --git a/src/main/java/cn/nukkit/entity/mob/EntityZombie.java b/src/main/java/cn/nukkit/entity/mob/EntityZombie.java
index 499c0fe2f2..54c1f59a70 100644
--- a/src/main/java/cn/nukkit/entity/mob/EntityZombie.java
+++ b/src/main/java/cn/nukkit/entity/mob/EntityZombie.java
@@ -36,7 +36,7 @@ public float getWidth() {
public float getHeight() {
return 1.8f;
}
-
+
@Override
public String getName() {
return "Zombie";
diff --git a/src/main/java/cn/nukkit/entity/mob/EntityZombiePigman.java b/src/main/java/cn/nukkit/entity/mob/EntityZombiePigman.java
index 1f2dc3e8db..cb0953a1da 100644
--- a/src/main/java/cn/nukkit/entity/mob/EntityZombiePigman.java
+++ b/src/main/java/cn/nukkit/entity/mob/EntityZombiePigman.java
@@ -31,7 +31,7 @@ protected void initEntity() {
public float getWidth() {
return 0.72f;
}
-
+
@Override
public float getHeight() {
return 1.8f;
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityBat.java b/src/main/java/cn/nukkit/entity/passive/EntityBat.java
index d0a10d57b8..7cbc0c32ce 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityBat.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityBat.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityBat extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityChicken.java b/src/main/java/cn/nukkit/entity/passive/EntityChicken.java
index e7af98590e..514dca8a32 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityChicken.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityChicken.java
@@ -7,7 +7,7 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntityChicken extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityCow.java b/src/main/java/cn/nukkit/entity/passive/EntityCow.java
index 5e138ff183..4d29b74bb2 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityCow.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityCow.java
@@ -7,7 +7,7 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntityCow extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityDonkey.java b/src/main/java/cn/nukkit/entity/passive/EntityDonkey.java
index 3b66bf946c..193e654f47 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityDonkey.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityDonkey.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityDonkey extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityHorse.java b/src/main/java/cn/nukkit/entity/passive/EntityHorse.java
index 346c24656f..6fd4495184 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityHorse.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityHorse.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityHorse extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityLlama.java b/src/main/java/cn/nukkit/entity/passive/EntityLlama.java
index 1f6948971c..98d0bf44c9 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityLlama.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityLlama.java
@@ -6,7 +6,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityLlama extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityMooshroom.java b/src/main/java/cn/nukkit/entity/passive/EntityMooshroom.java
index 22217389a2..e5f03265b1 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityMooshroom.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityMooshroom.java
@@ -59,7 +59,7 @@ protected void initEntity() {
super.initEntity();
setMaxHealth(10);
}
-
+
@Override
public void spawnTo(Player player) {
AddEntityPacket pk = new AddEntityPacket();
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityMule.java b/src/main/java/cn/nukkit/entity/passive/EntityMule.java
index 1c3c2aa505..93f21efb9e 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityMule.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityMule.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityMule extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityOcelot.java b/src/main/java/cn/nukkit/entity/passive/EntityOcelot.java
index 5c2408a124..1f78ec76c6 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityOcelot.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityOcelot.java
@@ -7,7 +7,7 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntityOcelot extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityPig.java b/src/main/java/cn/nukkit/entity/passive/EntityPig.java
index d59d29143c..acaaefaaf1 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityPig.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityPig.java
@@ -7,7 +7,7 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntityPig extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityPolarBear.java b/src/main/java/cn/nukkit/entity/passive/EntityPolarBear.java
index c990d222d8..946ec48b6c 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityPolarBear.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityPolarBear.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityPolarBear extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityRabbit.java b/src/main/java/cn/nukkit/entity/passive/EntityRabbit.java
index 3fbe53dfb9..1efbe43b32 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityRabbit.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityRabbit.java
@@ -7,7 +7,7 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntityRabbit extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntitySheep.java b/src/main/java/cn/nukkit/entity/passive/EntitySheep.java
index 5c651e207a..7ed8d5dac4 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntitySheep.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntitySheep.java
@@ -13,7 +13,7 @@
import java.util.concurrent.ThreadLocalRandom;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntitySheep extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntitySkeletonHorse.java b/src/main/java/cn/nukkit/entity/passive/EntitySkeletonHorse.java
index e419e6be39..2547ce1738 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntitySkeletonHorse.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntitySkeletonHorse.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntitySkeletonHorse extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntitySquid.java b/src/main/java/cn/nukkit/entity/passive/EntitySquid.java
index f56c1ad255..2190be7fc4 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntitySquid.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntitySquid.java
@@ -9,7 +9,6 @@
import cn.nukkit.utils.DyeColor;
/**
- *
* @author PikyCZ
*/
public class EntitySquid extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityWolf.java b/src/main/java/cn/nukkit/entity/passive/EntityWolf.java
index fd447a3b98..8099bb3128 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityWolf.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityWolf.java
@@ -7,7 +7,7 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntityWolf extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityZombieHorse.java b/src/main/java/cn/nukkit/entity/passive/EntityZombieHorse.java
index 13a7c55483..02450d44fc 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityZombieHorse.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityZombieHorse.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityZombieHorse extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/inventory/BigShapedRecipe.java b/src/main/java/cn/nukkit/inventory/BigShapedRecipe.java
index 1db57cb889..a84b3374aa 100644
--- a/src/main/java/cn/nukkit/inventory/BigShapedRecipe.java
+++ b/src/main/java/cn/nukkit/inventory/BigShapedRecipe.java
@@ -8,6 +8,6 @@
*/
public class BigShapedRecipe extends ShapedRecipe {
public BigShapedRecipe(Item result, String... shape) {
- super(result, shape);
+ super(result, 0, 0);
}
}
diff --git a/src/main/java/cn/nukkit/inventory/CraftingManager.java b/src/main/java/cn/nukkit/inventory/CraftingManager.java
index a7d7108b1d..ed0e61f8ff 100644
--- a/src/main/java/cn/nukkit/inventory/CraftingManager.java
+++ b/src/main/java/cn/nukkit/inventory/CraftingManager.java
@@ -1,11 +1,16 @@
package cn.nukkit.inventory;
-import cn.nukkit.block.*;
+import cn.nukkit.Server;
+import cn.nukkit.block.BlockAir;
import cn.nukkit.item.Item;
-import cn.nukkit.item.ItemDye;
+import cn.nukkit.item.ItemBlock;
import cn.nukkit.item.ItemPotion;
+import cn.nukkit.network.protocol.CraftingDataPacket;
+import cn.nukkit.utils.Config;
+import cn.nukkit.utils.MainLogger;
import cn.nukkit.utils.Utils;
+import java.io.IOException;
import java.util.*;
/**
@@ -24,865 +29,63 @@ public class CraftingManager {
private static int RECIPE_COUNT = 0;
+ public static CraftingDataPacket packet = null;
+
public CraftingManager() {
- /*try { //TODO: json
+ try {
Utils.writeFile(Server.getInstance().getDataPath() + "recipes.json", Server.class.getClassLoader().getResourceAsStream("recipes.json"));
} catch (IOException e) {
MainLogger.getLogger().logException(e);
+ //return;
}
-
-
- Config recipes = new Config(Server.getInstance().getDataPath() + "recipes.json", Config.JSON);
-
+ List recipes = new Config(Server.getInstance().getDataPath() + "recipes.json", Config.JSON).getMapList("recipes");
MainLogger.getLogger().info("Loading recipes...");
- for (Object obj : recipes.getAll().values()) {
- ConfigSection recipe;
- if (obj instanceof ConfigSection) {
- recipe = (ConfigSection) obj;
- } else {
- continue;
- }
-
-
- switch (recipe.getInt("type")) {
+ for (Map recipe : recipes) { //TODO: implement this better
+ switch (Utils.toInt(recipe.get("type"))) {
case 0:
// TODO: handle multiple result items
- Map first = recipe.getMapList("output").get(0);
- ShapelessRecipe result = new ShapelessRecipe(Item.get((int) first.get("id"), (int) first.get("damage"), (int) first.get("count"), first.get("nbt").toString().getBytes()));
- for (Map ingredient : recipe.getMapList("input")) {
- result.addIngredient(Item.get((int) ingredient.get("id"), (int) ingredient.get("damage"), (int) ingredient.get("count"), ingredient.get("nbt").toString().getBytes()));
+ Map first = ((List) recipe.get("output")).get(0);
+ ShapelessRecipe result = new ShapelessRecipe(Item.get(Utils.toInt(first.get("id")), Utils.toInt(first.get("damage")), Utils.toInt(first.get("count")), first.get("nbt").toString().getBytes()));
+ for (Map ingredient : ((List) recipe.get("input"))) {
+ result.addIngredient(Item.get(Utils.toInt(ingredient.get("id")), Utils.toInt(ingredient.get("damage")), Utils.toInt(ingredient.get("count")), ingredient.get("nbt").toString().getBytes()));
}
this.registerRecipe(result);
break;
case 1:
// TODO: handle multiple result items
- first = recipe.getMapList("output").get(0);
- ShapedRecipe shapedRecipe = new ShapedRecipe(Item.get((int) first.get("id"), (int) first.get("damage"), (int) first.get("count"), first.get("nbt").toString().getBytes()));
- List>> shape = Utils.toChunk(recipe.getList("input"), recipe.getInt("width"));
-
- for (int y = 0; y < shape.size(); y++) {
- List> row = shape.get(y);
-
- for (int x = 0; x < row.size(); x++) {
- Map ingredient = row.get(x);
- shapedRecipe.addIngredient(x, y, Item.get((int) ingredient.get("id"), (int) ingredient.get("damage"), (int) ingredient.get("count"), ingredient.get("nbt").toString().getBytes()));
+ first = ((List) recipe.get("output")).get(0);
+ ShapedRecipe shapedRecipe = new ShapedRecipe(Item.get(Utils.toInt(first.get("id")), Utils.toInt(first.get("damage")), Utils.toInt(first.get("count")), first.get("nbt").toString().getBytes()), Utils.toInt(recipe.get("height")), Utils.toInt(recipe.get("width")));
+ Object[][] shape = Utils.splitArray(((List) recipe.get("input")).stream().toArray(), Utils.toInt(recipe.get("width")));
+ for (int y = 0; y < shape.length; y++) {
+ Object[] row = shape[y];
+ for (int x = 0; x < row.length; x++) {
+ Object data = row[x];
+
+ if (data instanceof Map) {
+ Map ingredient = (Map) data;
+ shapedRecipe.addIngredient(x, y, Item.get(Utils.toInt(ingredient.get("id")), Utils.toInt(ingredient.get("damage")), Utils.toInt(ingredient.get("count")), ingredient.get("nbt").toString().getBytes()));
+ } else {
+ shapedRecipe.addIngredient(x, y, new ItemBlock(new BlockAir()));
+ }
}
}
this.registerRecipe(shapedRecipe);
break;
case 2:
case 3:
- ConfigSection resultMap = recipe.getSection("output");
- Item resultItem = Item.get(resultMap.getInt("id"), resultMap.getInt("damage"), resultMap.getInt("count"), resultMap.getString("nbt").getBytes());
- this.registerRecipe(new FurnaceRecipe(resultItem, Item.get(recipe.getInt("id"), recipe.getInt("damage", -1), 1)));
+ Map resultMap = (Map) recipe.get("output");
+ Item resultItem = Item.get(Utils.toInt(resultMap.get("id")), Utils.toInt(resultMap.get("damage")), Utils.toInt(resultMap.get("count")), ((String) resultMap.get("nbt")).getBytes());
+ this.registerRecipe(new FurnaceRecipe(resultItem, Item.get(Utils.toInt(recipe.get("inputId")), recipe.containsKey("inputDamage") ? Utils.toInt(recipe.get("inputDamage")) : -1, 1)));
break;
default:
break;
}
- }*/
-
- this.registerFurnace();
- this.registerBrewing();
- this.registerDyes();
- this.registerIngots();
- this.registerTools();
- this.registerWeapons();
- this.registerArmor();
- this.registerFood();
- this.registerWoodenDoors();
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.PRISMARINE, 0, 1),
- "XX",
- "XX"
- )).setIngredient("X", Item.get(Item.PRISMARINE_SHARD)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.PRISMARINE, 1, 1),
- "XXX",
- "XXX",
- "XXX"
- )).setIngredient("X", Item.get(Item.PRISMARINE_SHARD)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.PRISMARINE, 2, 1),
- "XXX",
- "XIX",
- "XXX"
- )).setIngredient("X", Item.get(Item.PRISMARINE_SHARD)).setIngredient("I", Item.get(Item.DYE)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.PRISMARINE, 2, 1),
- "XXX",
- "XIX",
- "XXX"
- )).setIngredient("X", Item.get(Item.PRISMARINE_SHARD)).setIngredient("I", Item.get(Item.DYE)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SEA_LANTERN, 0, 1),
- "XSX",
- "SSS",
- "XSX"
- )).setIngredient("X", Item.get(Item.PRISMARINE_SHARD)).setIngredient("S", Item.get(Item.PRISMARINE_CRYSTALS)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BEACON, 0, 1),
- "GGG",
- "GSG",
- "OOO"
- )).setIngredient("G", Item.get(Item.GLASS)).setIngredient("S", Item.get(Item.NETHER_STAR)).setIngredient("O", Item.get(Item.OBSIDIAN)));
-
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.CLAY_BLOCK, 0, 1),
- "XX ",
- "XX ",
- " "
- )).setIngredient("X", Item.get(Item.CLAY, 0, 4)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WORKBENCH, 0, 1),
- "XX",
- "XX"
- )).setIngredient("X", Item.get(Item.WOODEN_PLANK, null)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.GLOWSTONE_BLOCK, 0, 1),
- "XX",
- "XX"
- )).setIngredient("X", Item.get(Item.GLOWSTONE_DUST, 0, 1)));
- this.registerRecipe((new ShapedRecipe(Item.get(Item.LIT_PUMPKIN, 0, 1),
- "X ",
- "Y "
- )).setIngredient("X", Item.get(Item.PUMPKIN, 0, 1)).setIngredient("Y", Item.get(Item.TORCH, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.SNOW_BLOCK, 0, 1),
- "XX",
- "XX"
- )).setIngredient("X", Item.get(Item.SNOWBALL, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.SNOW_LAYER, 0, 6),
- " ",
- "XXX",
- " "
- )).setIngredient("X", Item.get(Item.SNOW_BLOCK, 0, 1)));
-
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.STICK, 0, 4),
- "X ",
- "X "
- )).setIngredient("X", Item.get(Item.WOODEN_PLANK, null)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOODEN_PLANK, BlockPlanks.OAK, 4),
- "X"
- )).setIngredient("X", Item.get(Item.WOOD, BlockWood.OAK, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOODEN_PLANK, BlockPlanks.SPRUCE, 4),
- "X"
- )).setIngredient("X", Item.get(Item.WOOD, BlockWood.SPRUCE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOODEN_PLANK, BlockPlanks.BIRCH, 4),
- "X"
- )).setIngredient("X", Item.get(Item.WOOD, BlockWood.BIRCH, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOODEN_PLANK, BlockPlanks.JUNGLE, 4),
- "X"
- )).setIngredient("X", Item.get(Item.WOOD, BlockWood.JUNGLE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOODEN_PLANK, BlockPlanks.ACACIA, 4),
- "X"
- )).setIngredient("X", Item.get(Item.WOOD2, BlockWood2.ACACIA, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOODEN_PLANK, BlockPlanks.DARK_OAK, 4),
- "X"
- )).setIngredient("X", Item.get(Item.WOOD2, BlockWood2.DARK_OAK, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOOL, 0, 1),
- "XX",
- "XX"
- )).setIngredient("X", Item.get(Item.STRING, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.TORCH, 0, 4),
- "C ",
- "S"
- )).setIngredient("C", Item.get(Item.COAL, 0, 1)).setIngredient("S", Item.get(Item.STICK, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.TORCH, 0, 4),
- "C ",
- "S"
- )).setIngredient("C", Item.get(Item.COAL, 1, 1)).setIngredient("S", Item.get(Item.STICK, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.SUGAR, 0, 1),
- "S"
- )).setIngredient("S", Item.get(Item.SUGARCANE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BED, 0, 1),
- "WWW",
- "PPP",
- " "
- )).setIngredient("W", Item.get(Item.WOOL, null, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.CHEST, 0, 1),
- "PPP",
- "P P",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.ENCHANTMENT_TABLE, 0, 1),
- " B ",
- "DOD",
- "OOO"
- )).setIngredient("D", Item.get(Item.DIAMOND, 0, 2)).setIngredient("O", Item.get(Item.OBSIDIAN, 0, 4)).setIngredient("B", Item.get(Item.BOOK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE, BlockPlanks.OAK, 3),
- "PSP",
- "PSP",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE, BlockPlanks.SPRUCE, 3),
- "PSP",
- "PSP",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.SPRUCE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE, BlockPlanks.BIRCH, 3),
- "PSP",
- "PSP",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.BIRCH, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE, BlockPlanks.JUNGLE, 3),
- "PSP",
- "PSP",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.JUNGLE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE, BlockPlanks.ACACIA, 3),
- "PSP",
- "PSP",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.ACACIA, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE, BlockPlanks.DARK_OAK, 3),
- "PSP",
- "PSP",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.DARK_OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.NETHER_BRICK_FENCE, 0, 3),
- "PPP",
- "PPP",
- " "
- )).setIngredient("P", Item.get(Item.NETHER_BRICK_BLOCK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE_GATE, 0, 1),
- "SPS",
- "SPS",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE_GATE_SPRUCE, 0, 1),
- "SPS",
- "SPS",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.SPRUCE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE_GATE_BIRCH, 0, 1),
- "SPS",
- "SPS",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.BIRCH, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE_GATE_JUNGLE, 0, 1),
- "SPS",
- "SPS",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.JUNGLE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE_GATE_DARK_OAK, 0, 1),
- "SPS",
- "SPS",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.DARK_OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE_GATE_ACACIA, 0, 1),
- "SPS",
- "SPS",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.ACACIA, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.COBBLESTONE_WALL, BlockWall.NONE_MOSSY_WALL, 6),
- "CCC",
- "CCC",
- " "
- )).setIngredient("C", Item.get(Item.COBBLESTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.COBBLESTONE_WALL, BlockWall.MOSSY_WALL, 6),
- "MMM",
- "MMM",
- " "
- )).setIngredient("M", Item.get(Item.MOSS_STONE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FURNACE, 0, 1),
- "CCC",
- "C C",
- "CCC"
- )).setIngredient("C", Item.get(Item.COBBLESTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.GLASS_PANE, 0, 16),
- "GGG",
- "GGG",
- " "
- )).setIngredient("G", Item.get(Item.GLASS, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.LADDER, 0, 3),
- "S S",
- "SSS",
- "S S"
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.TRAPDOOR, 0, 2),
- "PPP",
- "PPP",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.IRON_DOOR, 0, 1),
- "II ",
- "II ",
- "II "
- )).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOAT, 0, 1),
- "PSP",
- "PPP",
- " "
- )).setIngredient("S", Item.get(Item.WOODEN_SHOVEL, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOAT, 1, 1),
- "PSP",
- "PPP",
- " "
- )).setIngredient("S", Item.get(Item.WOODEN_SHOVEL, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.SPRUCE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOAT, 2, 1),
- "PSP",
- "PPP",
- " "
- )).setIngredient("S", Item.get(Item.WOODEN_SHOVEL, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.BIRCH, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOAT, 3, 1),
- "PSP",
- "PPP",
- " "
- )).setIngredient("S", Item.get(Item.WOODEN_SHOVEL, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.JUNGLE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOAT, 4, 1),
- "PSP",
- "PPP",
- " "
- )).setIngredient("S", Item.get(Item.WOODEN_SHOVEL, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.ACACIA, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOAT, 5, 1),
- "PSP",
- "PPP",
- " "
- )).setIngredient("S", Item.get(Item.WOODEN_SHOVEL, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.DARK_OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SANDSTONE_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.SANDSTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SPRUCE_WOOD_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.SPRUCE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BIRCH_WOOD_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.BIRCH, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.JUNGLE_WOOD_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.JUNGLE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.ACACIA_WOOD_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.ACACIA, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.DARK_OAK_WOOD_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.DARK_OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.COBBLESTONE_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.COBBLESTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BRICK_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.BRICKS_BLOCK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE_BRICK_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.STONE_BRICK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.QUARTZ_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.QUARTZ_BLOCK, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.NETHER_BRICKS_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.NETHER_BRICK_BLOCK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.STONE, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.STONE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.SANDSTONE, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.SANDSTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOOD_SLAB, BlockPlanks.OAK, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOOD_SLAB, BlockPlanks.SPRUCE, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.SPRUCE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOOD_SLAB, BlockPlanks.BIRCH, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.BIRCH, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOOD_SLAB, BlockPlanks.JUNGLE, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.JUNGLE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOOD_SLAB, BlockPlanks.ACACIA, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.ACACIA, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOOD_SLAB, BlockPlanks.DARK_OAK, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.DARK_OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.COBBLESTONE, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.COBBLESTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.BRICK, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.BRICK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.STONE_BRICK, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.STONE_BRICK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.QUARTZ, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.QUARTZ_BLOCK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.NETHER_BRICK, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.NETHER_BRICK_BLOCK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.QUARTZ_BLOCK, BlockQuartz.QUARTZ_NORMAL, 1),
- "NN ",
- "NN ",
- " "
- )).setIngredient("N", Item.get(Item.NETHER_QUARTZ, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.QUARTZ_BLOCK, BlockQuartz.QUARTZ_PILLAR, 2),
- "N ",
- "N ",
- " "
- )).setIngredient("N", Item.get(Item.QUARTZ_BLOCK, BlockQuartz.QUARTZ_NORMAL, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.QUARTZ_BLOCK, BlockQuartz.QUARTZ_CHISELED, 1),
- " ",
- " N ",
- " N "
- )).setIngredient("N", Item.get(Item.SLAB, BlockSlabStone.QUARTZ, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SANDSTONE, BlockSandstone.NORMAL, 1),
- " ",
- "SS ",
- "SS "
- )).setIngredient("S", Item.get(Item.SAND, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SANDSTONE, BlockSandstone.SMOOTH, 4),
- " ",
- "SS ",
- "SS "
- )).setIngredient("S", Item.get(Item.SANDSTONE, BlockSandstone.NORMAL, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SANDSTONE, BlockSandstone.CHISELED, 1),
- " ",
- " N ",
- " N "
- )).setIngredient("N", Item.get(Item.SLAB, BlockSlabStone.SANDSTONE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE_BRICK, BlockBricksStone.NORMAL, 4),
- " ",
- "SS ",
- "SS "
- )).setIngredient("S", Item.get(Item.STONE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE_BRICK, BlockBricksStone.MOSSY, 1),
- " ",
- "SL ",
- " "
- )).setIngredient("S", Item.get(Item.STONE_BRICK, BlockBricksStone.NORMAL, 1)).setIngredient("L", Item.get(Item.VINES, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE_BRICK, BlockBricksStone.CHISELED, 1),
- " ",
- " S ",
- " S "
- )).setIngredient("S", Item.get(Item.SLAB, BlockSlabStone.STONE_BRICK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.MOSS_STONE, 0, 1),
- " ",
- "SL ",
- " "
- )).setIngredient("S", Item.get(Item.COBBLESTONE, null, 1)).setIngredient("L", Item.get(Item.VINES, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE, BlockStone.GRANITE, 1),
- " ",
- "DN ",
- " "
- )).setIngredient("D", Item.get(Item.STONE, BlockStone.DIORITE, 1)).setIngredient("N", Item.get(Item.NETHER_QUARTZ, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE, BlockStone.POLISHED_GRANITE, 4),
- " ",
- "GG ",
- "GG "
- )).setIngredient("G", Item.get(Item.STONE, BlockStone.GRANITE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE, BlockStone.DIORITE, 2),
- " ",
- "CN ",
- "NC "
- )).setIngredient("C", Item.get(Item.COBBLESTONE, null, 1)).setIngredient("N", Item.get(Item.NETHER_QUARTZ, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE, BlockStone.POLISHED_DIORITE, 4),
- " ",
- "DD ",
- "DD "
- )).setIngredient("D", Item.get(Item.STONE, BlockStone.DIORITE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE, BlockStone.ANDESITE, 2),
- " ",
- "DC ",
- " "
- )).setIngredient("D", Item.get(Item.STONE, BlockStone.DIORITE, 1)).setIngredient("C", Item.get(Item.COBBLESTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE, BlockStone.POLISHED_ANDESITE, 4),
- " ",
- "AA ",
- "AA "
- )).setIngredient("A", Item.get(Item.STONE, BlockStone.ANDESITE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BUCKET, 0, 1),
- "I I",
- " I ",
- " "
- )).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.CLOCK, 0, 1),
- " G ",
- "GRG",
- " G "
- )).setIngredient("G", Item.get(Item.GOLD_INGOT, 0, 1)).setIngredient("R", Item.get(Item.REDSTONE_DUST, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.COMPASS, 0, 1),
- " I ",
- "IRI",
- " I "
- )).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)).setIngredient("R", Item.get(Item.REDSTONE_DUST, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.TNT, 0, 1),
- "GSG",
- "SGS",
- "GSG"
- )).setIngredient("G", Item.get(Item.GUNPOWDER, 0, 1)).setIngredient("S", Item.get(Item.SAND, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOWL, 0, 4),
- "P P",
- " P ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANKS, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.MINECART, 0, 1),
- "I I",
- "III"
- )).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOOK, 0, 1),
- "P P",
- " P "
- )).setIngredient("P", Item.get(Item.PAPER, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOOKSHELF, 0, 1),
- "PPP",
- "BBB",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, null, 1)).setIngredient("B", Item.get(Item.BOOK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.PAINTING, 0, 1),
- "SSS",
- "SWS",
- "SSS"
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("W", Item.get(Item.WOOL, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.PAPER, 0, 3),
- " ",
- "SSS",
- " "
- )).setIngredient("S", Item.get(Item.SUGARCANE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SIGN, 0, 3),
- "PPP",
- "PPP",
- " S "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANKS, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.IRON_BARS, 0, 16),
- " ",
- "III",
- "III"
- )).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.GLASS_BOTTLE, 0, 3),
- "I I",
- " I ",
- " "
- )).setIngredient("I", Item.get(Item.GLASS, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BREWING_STAND, 0, 1),
- " I ",
- "CCC"
- )).setIngredient("C", Item.get(Item.COBBLESTONE, null, 1)).setIngredient("I", Item.get(Item.BLAZE_ROD, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.ITEM_FRAME, 0, 3),
- "SSS",
- "SLS",
- "SSS"
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("L", Item.get(Item.LEATHER, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.RED_SANDSTONE_STAIRS, 0, 4),
- " S",
- " SS",
- "SSS"
- )).setIngredient("S", Item.get(Item.RED_SANDSTONE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.RED_SANDSTONE_SLAB, 0, 6),
- " ",
- "SSS",
- " "
- )).setIngredient("S", Item.get(Item.RED_SANDSTONE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.RED_SANDSTONE, BlockSandstone.NORMAL, 1),
- " ",
- "SS ",
- "SS "
- )).setIngredient("S", Item.get(Item.SAND, 1, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.RED_SANDSTONE, BlockSandstone.SMOOTH, 4),
- " ",
- "SS ",
- "SS "
- )).setIngredient("S", Item.get(Item.RED_SANDSTONE, BlockSandstone.NORMAL, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.RED_SANDSTONE, BlockSandstone.CHISELED, 1),
- " ",
- " N ",
- " N "
- )).setIngredient("N", Item.get(Item.RED_SANDSTONE_SLAB, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.STONE, 0, 1)));
-
-
- //all planks...
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.PLANKS, BlockPlanks.OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.PLANKS, BlockPlanks.SPRUCE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.PLANKS, BlockPlanks.BIRCH, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.PLANKS, BlockPlanks.JUNGLE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.PLANKS, BlockPlanks.ACACIA, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.PLANKS, BlockPlanks.DARK_OAK, 1)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.ENDER_CHEST, 0, 1),
- "PPP",
- "PSP",
- "PPP"
- ).setIngredient("P", Item.get(Item.OBSIDIAN, 0, 1)).setIngredient("S", Item.get(Item.ENDER_EYE, 0, 1)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.REDSTONE_TORCH, 0, 1),
- " R",
- " S"
- ).setIngredient("R", Item.get(Item.REDSTONE_DUST, 0, 1)).setIngredient("S", Item.get(Item.STICK, 0, 1)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.LEVER, 0, 1),
- " S",
- " C"
- ).setIngredient("C", Item.get(Item.COBBLESTONE, null, 1)).setIngredient("S", Item.get(Item.STICK, 0, 1)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.STONE_BUTTON, 0, 1),
- " S"
- ).setIngredient("S", Item.get(Item.STONE, 0, 1)));
-
- for (int i = 0; i < 6; i++) {
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " W"
- ).setIngredient("W", Item.get(Item.PLANKS, i, 1)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.WOODEN_PRESSURE_PLATE, 0, 1),
- "WW "
- ).setIngredient("W", Item.get(Item.PLANKS, i, 2)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.TRIPWIRE_HOOK, 0, 2),
- " I ",
- " S ",
- " P "
- ).setIngredient("P", Item.get(Item.PLANKS, i, 1)).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)));
}
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.STONE_PRESSURE_PLATE, 0, 1),
- "SS "
- ).setIngredient("S", Item.get(Item.STONE, 0, 2)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.HEAVY_WEIGHTED_PRESSURE_PLATE, 0, 1),
- "II "
- ).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 2)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.LIGHT_WEIGHTED_PRESSURE_PLATE, 0, 1),
- "GG "
- ).setIngredient("G", Item.get(Item.GOLD_INGOT, 0, 2)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.REDSTONE_LAMP, 0, 1),
- " R ",
- "RGR",
- " R "
- ).setIngredient("R", Item.get(Item.REDSTONE_DUST, 0, 4)).setIngredient("G", Item.get(Item.GLOWSTONE_BLOCK, 0, 1)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.REPEATER, 0, 1),
- " ",
- "TRT",
- "SSS"
- ).setIngredient("R", Item.get(Item.REDSTONE_DUST, 0, 1)).setIngredient("T", Item.get(Item.REDSTONE_TORCH, 0, 2)).setIngredient("S", Item.get(Item.STONE, 0, 3)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.COMPARATOR, 0, 1),
- " T ",
- "TQT",
- "SSS"
- ).setIngredient("Q", Item.get(Item.QUARTZ, 0, 1)).setIngredient("T", Item.get(Item.REDSTONE_TORCH, 0, 3)).setIngredient("S", Item.get(Item.STONE, 0, 3)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.HOPPER, 0, 1),
- "I I",
- "ICI",
- " I "
- ).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 5)).setIngredient("C", Item.get(Item.CHEST, 0, 1)));
- }
-
- protected void registerFurnace() {
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.STONE, 0, 1), Item.get(Item.COBBLESTONE, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.STONE_BRICK, BlockBricksStone.CRACKED, 1), Item.get(Item.STONE_BRICK, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.GLASS, 0, 1), Item.get(Item.SAND, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.COAL, 1, 1), Item.get(Item.TRUNK, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.GOLD_INGOT, 0, 1), Item.get(Item.GOLD_ORE, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.IRON_INGOT, 0, 1), Item.get(Item.IRON_ORE, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.EMERALD, 0, 1), Item.get(Item.EMERALD_ORE, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.DIAMOND, 0, 1), Item.get(Item.DIAMOND_ORE, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.NETHER_BRICK, 0, 1), Item.get(Item.NETHERRACK, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.COOKED_PORKCHOP, 0, 1), Item.get(Item.RAW_PORKCHOP, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.BRICK, 0, 1), Item.get(Item.CLAY, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.COOKED_FISH, 0, 1), Item.get(Item.RAW_FISH, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.COOKED_FISH, 1, 1), Item.get(Item.RAW_FISH, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.DYE, 2, 1), Item.get(Item.CACTUS, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.DYE, 1, 1), Item.get(Item.RED_MUSHROOM, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.STEAK, 0, 1), Item.get(Item.RAW_BEEF, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.COOKED_CHICKEN, 0, 1), Item.get(Item.RAW_CHICKEN, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.BAKED_POTATO, 0, 1), Item.get(Item.POTATO, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.COOKED_MUTTON, 0, 1), Item.get(Item.RAW_MUTTON, null, 1)));
+ this.registerBrewing();
+ this.rebuildPacket();
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.TERRACOTTA, 0, 1), Item.get(Item.CLAY_BLOCK, null, 1)));
+ MainLogger.getLogger().info("Loaded " + this.recipes.size() + " recipes.");
}
protected void registerBrewing() {
@@ -927,340 +130,26 @@ protected void registerBrewing() {
registerBrewingRecipe(new BrewingRecipe(Item.get(Item.POTION, ItemPotion.HARMING_II, 1), Item.get(Item.FERMENTED_SPIDER_EYE, 0, 1), Item.get(Item.POTION, ItemPotion.POISON_LONG, 1)));
}
- protected void registerFood() {
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.MELON_BLOCK, 0, 1),
- "XXX",
- "XXX",
- "XXX"
- )).setIngredient("X", Item.get(Item.MELON_SLICE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BEETROOT_SOUP, 0, 1),
- "XXX",
- "XXX",
- " Y "
- )).setIngredient("X", Item.get(Item.BEETROOT, 0, 1)).setIngredient("Y", Item.get(Item.BOWL, 0, 1)));
-
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BREAD, 0, 1),
- " ",
- " ",
- "XXX"
- )).setIngredient("X", Item.get(Item.WHEAT, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.CAKE, 0, 1),
- "XXX",
- "YZY",
- "AAA"
- )).setIngredient("X", Item.get(Item.BUCKET, 1, 1)).setIngredient("Y", Item.get(Item.SUGAR, 0, 1)).setIngredient("Z", Item.get(Item.EGG, 0, 1)).setIngredient("A", Item.get(Item.WHEAT, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.COOKIE, 0, 8),
- " ",
- " ",
- "XYX"
- )).setIngredient("X", Item.get(Item.WHEAT, 0, 1)).setIngredient("Y", Item.get(Item.DYE, 3, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.GOLDEN_APPLE, 0, 1),
- "XXX",
- "XYX",
- "XXX"
- )).setIngredient("X", Item.get(Item.GOLD_INGOT, 0, 1)).setIngredient("Y", Item.get(Item.APPLE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.GOLDEN_APPLE_ENCHANTED, 1, 1),
- "XXX",
- "XYX",
- "XXX"
- )).setIngredient("X", Item.get(Item.GOLD_BLOCK, 0, 1)).setIngredient("Y", Item.get(Item.APPLE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.MUSHROOM_STEW, 0, 1),
- " X ",
- " Y ",
- " Z "
- )).setIngredient("X", Item.get(Item.RED_MUSHROOM, 0, 1)).setIngredient("Y", Item.get(Item.BROWN_MUSHROOM, 0, 1)).setIngredient("Z", Item.get(Item.BOWL, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.PUMPKIN_PIE, 0, 1),
- " ",
- "XY ",
- "Z "
- )).setIngredient("X", Item.get(Item.PUMPKIN, 0, 1)).setIngredient("Y", Item.get(Item.EGG, 0, 1)).setIngredient("Z", Item.get(Item.SUGAR, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.MELON_SEEDS, 0, 1),
- "X ",
- " "
- )).setIngredient("X", Item.get(Item.MELON_SLICE, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.PUMPKIN_SEEDS, 0, 4),
- "X ",
- " "
- )).setIngredient("X", Item.get(Item.PUMPKIN, 0, 1)));
- }
-
- protected void registerArmor() {
- int[][] types = {
- {Item.LEATHER, Item.FIRE, Item.IRON_INGOT, Item.DIAMOND, Item.GOLD_INGOT},
- {Item.LEATHER_CAP, Item.CHAIN_HELMET, Item.IRON_HELMET, Item.DIAMOND_HELMET, Item.GOLD_HELMET},
- {Item.LEATHER_TUNIC, Item.CHAIN_CHESTPLATE, Item.IRON_CHESTPLATE, Item.DIAMOND_CHESTPLATE, Item.GOLD_CHESTPLATE},
- {Item.LEATHER_PANTS, Item.CHAIN_LEGGINGS, Item.IRON_LEGGINGS, Item.DIAMOND_LEGGINGS, Item.GOLD_LEGGINGS},
- {Item.LEATHER_BOOTS, Item.CHAIN_BOOTS, Item.IRON_BOOTS, Item.DIAMOND_BOOTS, Item.GOLD_BOOTS},
- };
-
- String[][] shapes = new String[][]{
- new String[]{
- "XXX",
- "X X",
- " "
- },
- new String[]{
- "X X",
- "XXX",
- "XXX"
- },
- new String[]{
- "XXX",
- "X X",
- "X X"
- },
- new String[]{
- " ",
- "X X",
- "X X"
- }
- };
- for (int i = 1; i < 5; ++i) {
- for (int j = 0; j < types[i].length; j++) {
- int type = types[i][j];
- this.registerRecipe((new BigShapedRecipe(Item.get(type, 0, 1), shapes[i - 1])).setIngredient("X", Item.get(types[0][j], 0, 1)));
- }
- }
- }
-
- protected void registerWeapons() {
- int[][] types = {
- {Item.WOODEN_PLANK, Item.COBBLESTONE, Item.IRON_INGOT, Item.DIAMOND, Item.GOLD_INGOT},
- {Item.WOODEN_SWORD, Item.STONE_SWORD, Item.IRON_SWORD, Item.DIAMOND_SWORD, Item.GOLD_SWORD},
- };
- for (int i = 1; i < 2; ++i) {
- for (int j = 0; j < types[i].length; j++) {
- int type = types[i][j];
- this.registerRecipe((new BigShapedRecipe(Item.get(type, 0, 1),
- " X ",
- " X ",
- " I "
- )).setIngredient("X", Item.get(types[0][j], null)).setIngredient("I", Item.get(Item.STICK)));
- }
- }
+ public void rebuildPacket() {
+ CraftingDataPacket pk = new CraftingDataPacket();
+ pk.cleanRecipes = true;
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.ARROW, 0, 1),
- " F ",
- " S ",
- " P "
- )).setIngredient("S", Item.get(Item.STICK)).setIngredient("F", Item.get(Item.FLINT)).setIngredient("P", Item.get(Item.FEATHER)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOW, 0, 1),
- " X~",
- "X ~",
- " X~"
- )).setIngredient("~", Item.get(Item.STRING)).setIngredient("X", Item.get(Item.STICK)));
- }
-
- protected void registerTools() {
- int[][] types = {
- {Item.WOODEN_PLANK, Item.COBBLESTONE, Item.IRON_INGOT, Item.DIAMOND, Item.GOLD_INGOT},
- {Item.WOODEN_PICKAXE, Item.STONE_PICKAXE, Item.IRON_PICKAXE, Item.DIAMOND_PICKAXE, Item.GOLD_PICKAXE},
- {Item.WOODEN_SHOVEL, Item.STONE_SHOVEL, Item.IRON_SHOVEL, Item.DIAMOND_SHOVEL, Item.GOLD_SHOVEL},
- {Item.WOODEN_AXE, Item.STONE_AXE, Item.IRON_AXE, Item.DIAMOND_AXE, Item.GOLD_AXE},
- {Item.WOODEN_HOE, Item.STONE_HOE, Item.IRON_HOE, Item.DIAMOND_HOE, Item.GOLD_HOE},
- };
- String[][] shapes = new String[][]{
- new String[]{
- "XXX",
- " I ",
- " I "
- },
- new String[]{
- " X ",
- " I ",
- " I "
- },
- new String[]{
- "XX ",
- "XI ",
- " I "
- },
- new String[]{
- "XX ",
- " I ",
- " I "
- }
- };
- for (int i = 1; i < 5; ++i) {
- for (int j = 0; j < types[i].length; j++) {
- int type = types[i][j];
- this.registerRecipe((new BigShapedRecipe(Item.get(type, 0, 1), shapes[i - 1])).setIngredient('X', Item.get(types[0][j], null)).setIngredient('I', Item.get(Item.STICK)));
+ for (Recipe recipe : this.getRecipes().values()) {
+ if (recipe instanceof ShapedRecipe) {
+ pk.addShapedRecipe((ShapedRecipe) recipe);
+ } else if (recipe instanceof ShapelessRecipe) {
+ pk.addShapelessRecipe((ShapelessRecipe) recipe);
}
}
- this.registerRecipe((new ShapedRecipe(Item.get(Item.FLINT_AND_STEEL, 0, 1),
- " S",
- "F "
- )).setIngredient('F', Item.get(Item.FLINT)).setIngredient("S", Item.get(Item.IRON_INGOT)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.SHEARS, 0, 1),
- " X",
- "X "
- )).setIngredient("X", Item.get(Item.IRON_INGOT)));
- }
-
- protected void registerWoodenDoors() {
- int[] items = new int[]{Item.WOODEN_DOOR, Item.SPRUCE_DOOR, Item.BIRCH_DOOR, Item.JUNGLE_DOOR, Item.ACACIA_DOOR, Item.DARK_OAK_DOOR};
-
- for (int i = 0; i < 6; i++) {
- this.registerRecipe((new BigShapedRecipe(Item.get(items[i], 0, 3),
- "XX ",
- "XX ",
- "XX "
- )).setIngredient("X", Item.get(Item.PLANKS, i, 1)));
- }
- }
-
- protected void registerPlanks() {
- //TODO
- }
-
- protected void registerDyes() {
- for (int i = 0; i < 16; ++i) {
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOOL, 15 - i, 1),
- " ",
- "DW"
- )).setIngredient('D', Item.get(Item.DYE, i, 1)).setIngredient('W', Item.get(Item.WOOL, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STAINED_TERRACOTTA, 15 - i, 8),
- "CCC",
- "CDC",
- "CCC"
- )).setIngredient('D', Item.get(Item.DYE, i, 1)).setIngredient('C', Item.get(Item.TERRACOTTA, 0, 1)));
- //TODO: add glass things?
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.CARPET, i, 3),
- " ",
- "WW"
- )).setIngredient('W', Item.get(Item.WOOL, i, 1)));
+ for (FurnaceRecipe recipe : this.getFurnaceRecipes().values()) {
+ pk.addFurnaceRecipe(recipe);
}
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.YELLOW, 2),
- " ",
- "D "
- )).setIngredient('D', Item.get(Item.DANDELION, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.WHITE, 3),
- " ",
- "B "
- )).setIngredient('B', Item.get(Item.BONE, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.BROWN, 2),
- " B",
- "O "
- )).setIngredient('O', Item.get(Item.DYE, ItemDye.ORANGE, 1)).setIngredient('B', Item.get(Item.DYE, ItemDye.BLACK, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.BROWN, 3),
- "RB",
- "Y "
- )).setIngredient('R', Item.get(Item.DYE, ItemDye.RED, 1)).setIngredient('B', Item.get(Item.DYE, ItemDye.BLACK, 1)).setIngredient('Y', Item.get(Item.DYE, ItemDye.YELLOW, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.PINK, 2),
- " R",
- "W "
- )).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)).setIngredient('R', Item.get(Item.DYE, ItemDye.RED, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.ORANGE, 2),
- " R",
- "Y "
- )).setIngredient('Y', Item.get(Item.DYE, ItemDye.YELLOW, 1)).setIngredient('R', Item.get(Item.DYE, ItemDye.RED, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.LIME, 2),
- " G",
- "W "
- )).setIngredient('G', Item.get(Item.DYE, ItemDye.GREEN, 1)).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.LIGHT_BLUE, 2),
- " B",
- "W "
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLUE, 1)).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.CYAN, 2),
- " G",
- "B "
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLUE, 1)).setIngredient('G', Item.get(Item.DYE, ItemDye.GREEN, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.PURPLE, 2),
- " R",
- "B "
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLUE, 1)).setIngredient('R', Item.get(Item.DYE, ItemDye.RED, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.MAGENTA, 3),
- "RW",
- "B "
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLUE, 1)).setIngredient('R', Item.get(Item.DYE, ItemDye.RED, 1)).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.RED, 1),
- " ",
- "B "
- )).setIngredient('B', Item.get(Item.BEETROOT, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.MAGENTA, 4),
- "RB",
- "WR"
- )).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)).setIngredient('R', Item.get(Item.DYE, ItemDye.RED, 1)).setIngredient('B', Item.get(Item.DYE, ItemDye.BLUE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.MAGENTA, 2),
- " D",
- "P "
- )).setIngredient('P', Item.get(Item.DYE, ItemDye.PURPLE, 1)).setIngredient('D', Item.get(Item.DYE, ItemDye.PINK, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.GRAY, 2),
- " W",
- "B "
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLACK, 1)).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.LIGHT_GRAY, 3),
- "B ",
- "WW"
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLACK, 1)).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.LIGHT_GRAY, 2),
- " G",
- "B "
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLACK, 1)).setIngredient('G', Item.get(Item.DYE, ItemDye.GRAY, 1)));
- }
-
- protected void registerIngots() {
- int[][] ingots = new int[][]{
- {Item.GOLD_BLOCK, Item.GOLD_INGOT},
- {Item.GOLD_INGOT, Item.GOLD_NUGGET},
- {Item.IRON_BLOCK, Item.IRON_INGOT},
- {Item.DIAMOND_BLOCK, Item.DIAMOND},
- {Item.EMERALD_BLOCK, Item.EMERALD},
- {Item.REDSTONE_BLOCK, Item.REDSTONE_DUST},
- {Item.COAL_BLOCK, Item.COAL},
- {Item.HAY_BALE, Item.WHEAT},
- {Item.LAPIS_BLOCK, Item.DYE, 4}
- };
-
- for (int[] e : ingots) {
- int block = e[0];
- int ingot = e[1];
- int ingot_meta = e.length > 2 ? e[2] : 0;
-
- this.registerRecipe((new ShapedRecipe(Item.get(ingot, ingot_meta, 9),
- "X"
- )).setIngredient("X", Item.get(block, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(block, 0, 1),
- "XXX",
- "XXX",
- "XXX"
- )).setIngredient("X", Item.get(ingot, ingot_meta, 1)));
- }
+ pk.encode();
+ pk.isEncoded = true;
+ packet = pk;
}
public final Comparator- comparator = (i1, i2) -> {
diff --git a/src/main/java/cn/nukkit/inventory/PlayerInventory.java b/src/main/java/cn/nukkit/inventory/PlayerInventory.java
index 4065f7c76f..8e79312093 100644
--- a/src/main/java/cn/nukkit/inventory/PlayerInventory.java
+++ b/src/main/java/cn/nukkit/inventory/PlayerInventory.java
@@ -403,7 +403,7 @@ public void sendContents(Player[] players) {
//Because PE is stupid and shows 9 less slots than you send it, give it 9 dummy slots so it shows all the REAL slots.
for(int i = this.getSize(); i < this.getSize() + this.getHotbarSize(); ++i){
- pk.slots[i] = Item.get(Item.AIR, 0, 0);
+ pk.slots[i] = new ItemBlock(new BlockAir());
}
for (Player player : players) {
diff --git a/src/main/java/cn/nukkit/inventory/ShapedRecipe.java b/src/main/java/cn/nukkit/inventory/ShapedRecipe.java
index 3ddce3cd15..38b454a227 100644
--- a/src/main/java/cn/nukkit/inventory/ShapedRecipe.java
+++ b/src/main/java/cn/nukkit/inventory/ShapedRecipe.java
@@ -3,7 +3,10 @@
import cn.nukkit.Server;
import cn.nukkit.item.Item;
-import java.util.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
/**
* author: MagicDroidX
@@ -21,40 +24,19 @@ public class ShapedRecipe implements Recipe {
private final Map
> shapeItems = new HashMap<>();
- public ShapedRecipe(Item result, String... shape) {
- if (shape.length == 0) {
- throw new IllegalArgumentException("Must provide a shape");
- }
-
- if (shape.length > 3) {
- throw new IllegalStateException("Crafting recipes should be 1, 2, 3 rows, not " + shape.length);
- }
-
-
- for (int y = 0; y < shape.length; y++) {
- String row = shape[y];
- if (row.length() == 0 || row.length() > 3) {
- throw new IllegalStateException("Crafting rows should be 1, 2, 3 characters, not " + row.length());
+ public ShapedRecipe(Item result, int height, int width) {
+ for (int y = 0; y < height; y++) {
+ if (width == 0 || width > 3) {
+ throw new IllegalStateException("Crafting rows should be 1, 2, 3 characters, not " + width);
}
this.ingredients.put(y, new HashMap() {
{
- for (int i = 0; i < row.length(); i++) {
+ for (int i = 0; i < width; i++) {
put(i, null);
}
}
});
-
- int len = row.length();
- for (int i = 0; i < len; i++) {
- this.shapes.put(row.charAt(i), null);
-
- if (!this.shapeItems.containsKey(row.charAt(i))) {
- this.shapeItems.put(row.charAt(i), new ArrayList<>(Arrays.asList(new Entry[]{new Entry(i, y)})));
- } else {
- this.shapeItems.get(row.charAt(i)).add(new Entry(i, y));
- }
- }
}
this.output = result.clone();
diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java
index a9e3ab2f89..2f4b95b96b 100644
--- a/src/main/java/cn/nukkit/level/Level.java
+++ b/src/main/java/cn/nukkit/level/Level.java
@@ -1806,8 +1806,7 @@ public Item useBreakOn(Vector3 vector, Item item, Player player, boolean createP
breakTime *= 1 - (0.3 * eff.getLevel());
}
- //breakTime -= 0.1;
- //TODO: Check if it's necessary to minus breakTime with 0.1.
+ breakTime -= 0.15;
BlockBreakEvent ev = new BlockBreakEvent(player, target, item, player.isCreative(),
(player.lastBreak + breakTime * 1000) > System.currentTimeMillis());
diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
index b02cbebe68..5626c4fcc4 100644
--- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
+++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
@@ -9,7 +9,8 @@ public interface ProtocolInfo {
/**
* Actual Minecraft: PE protocol version
*/
- byte CURRENT_PROTOCOL = 113;
+ byte CURRENT_PROTOCOL = Integer.valueOf("113").byteValue(); //plugins can change it
+
String MINECRAFT_VERSION = "v1.1.3";
String MINECRAFT_VERSION_NETWORK = "1.1.3";
diff --git a/src/main/java/cn/nukkit/utils/Utils.java b/src/main/java/cn/nukkit/utils/Utils.java
index 911357dc30..69a2e8f457 100644
--- a/src/main/java/cn/nukkit/utils/Utils.java
+++ b/src/main/java/cn/nukkit/utils/Utils.java
@@ -5,7 +5,6 @@
import java.lang.management.ThreadInfo;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.UUID;
@@ -170,22 +169,25 @@ public static long toRGB(byte r, byte g, byte b, byte a) {
return result & 0xFFFFFFFFL;
}
- public static java.util.List toChunk(java.util.List list, int size) {
- java.util.List result = new ArrayList<>();
- T[] arr = (T[]) list.stream().toArray();
+ public static Object[][] splitArray(Object[] arrayToSplit, int chunkSize) {
+ if (chunkSize <= 0) {
+ return null;
+ }
- int from = 0;
- int to = size >= arr.length ? arr.length : size;
+ int rest = arrayToSplit.length % chunkSize;
+ int chunks = arrayToSplit.length / chunkSize + (rest > 0 ? 1 : 0);
- while (from < arr.length) {
- T[] subArray = Arrays.copyOfRange(arr, from, to);
- from = to;
- to += size;
- if (to > arr.length) {
- to = arr.length;
- }
- result.add(subArray);
+ Object[][] arrays = new Object[chunks][];
+ for (int i = 0; i < (rest > 0 ? chunks - 1 : chunks); i++) {
+ arrays[i] = Arrays.copyOfRange(arrayToSplit, i * chunkSize, i * chunkSize + chunkSize);
+ }
+ if (rest > 0) {
+ arrays[chunks - 1] = Arrays.copyOfRange(arrayToSplit, (chunks - 1) * chunkSize, (chunks - 1) * chunkSize + rest);
}
- return result;
+ return arrays;
+ }
+
+ public static int toInt(Object number) {
+ return (int) Math.round((double) number);
}
}
diff --git a/src/main/resources/recipes.json b/src/main/resources/recipes.json
index 6c93d99033..3e42cb856f 100644
--- a/src/main/resources/recipes.json
+++ b/src/main/resources/recipes.json
@@ -1,4 +1,5 @@
-[
+{
+ "recipes": [
{
"type": 1,
"width": 3,
@@ -20891,4 +20892,5 @@
"nbt": ""
}
}
-]
\ No newline at end of file
+]
+}
\ No newline at end of file
From d6c039f07f7eebefb3b84454258c7bf3e30a1e4a Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Wed, 2 Aug 2017 13:30:16 +0200
Subject: [PATCH 027/175] update
---
src/main/java/cn/nukkit/Player.java | 2 +-
src/main/java/cn/nukkit/entity/Entity.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 37a154deff..80a806e5d2 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -1920,7 +1920,7 @@ public void handleDataPacket(DataPacket packet) {
LoginPacket loginPacket = (LoginPacket) packet;
String message;
- if (loginPacket.getProtocol() != ProtocolInfo.CURRENT_PROTOCOL) {
+ if (loginPacket.getProtocol() < ProtocolInfo.CURRENT_PROTOCOL) {
if (loginPacket.getProtocol() < ProtocolInfo.CURRENT_PROTOCOL) {
message = "disconnectionScreen.outdatedClient";
diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java
index 2e900306ea..49317ad364 100644
--- a/src/main/java/cn/nukkit/entity/Entity.java
+++ b/src/main/java/cn/nukkit/entity/Entity.java
@@ -7,8 +7,8 @@
import cn.nukkit.block.BlockFire;
import cn.nukkit.block.BlockWater;
import cn.nukkit.entity.data.*;
-import cn.nukkit.event.Event;
import cn.nukkit.entity.item.EntityVehicle;
+import cn.nukkit.event.Event;
import cn.nukkit.event.entity.*;
import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
import cn.nukkit.event.entity.EntityPortalEnterEvent.PortalType;
From a3cfcbac758d7356e77ead8b43d6a9268f5fdcbc Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Wed, 2 Aug 2017 14:24:54 +0200
Subject: [PATCH 028/175] update
---
src/main/java/cn/nukkit/item/Item.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java
index 2eab29b9c9..d9e21b1703 100644
--- a/src/main/java/cn/nukkit/item/Item.java
+++ b/src/main/java/cn/nukkit/item/Item.java
@@ -1835,7 +1835,7 @@ public String[] getLore() {
return lines.toArray(new String[0]);
}
- public void setLore(String... lines) {
+ public Item setLore(String... lines) {
CompoundTag tag;
if (!this.hasCompoundTag()) {
tag = new CompoundTag();
@@ -1855,6 +1855,7 @@ public void setLore(String... lines) {
}
this.setNamedTag(tag);
+ return this;
}
public Tag getNamedTagEntry(String name) {
From 8f537e378d60ce5c0dad19c216e59a9cf1abcf47 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Wed, 2 Aug 2017 15:12:53 +0200
Subject: [PATCH 029/175] update
---
src/main/java/cn/nukkit/Player.java | 63 +++++++++----------
.../nukkit/command/defaults/TitleCommand.java | 8 +--
.../nukkit/event/player/PlayerMoveEvent.java | 20 ++++++
3 files changed, 55 insertions(+), 36 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 80a806e5d2..d349da9051 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -3832,45 +3832,44 @@ public void resetTitleSettings() {
this.dataPacket(pk);
}
- public void sendTitle(String text) {
- SetTitlePacket pk = new SetTitlePacket();
- pk.type = SetTitlePacket.TYPE_TITLE;
- pk.text = text;
- this.dataPacket(pk);
+ public void sendTitle(String title) {
+ this.sendTitle(title, "", 20, 20, 5);
}
- /**
- * Sets a subtitle for the next shown title
- *
- * @param text Subtitle text
- */
- public void setSubtitle(String text) {
- SetTitlePacket pk = new SetTitlePacket();
- pk.type = SetTitlePacket.TYPE_SUBTITLE;
- pk.text = text;
- this.dataPacket(pk);
+ public void sendTitle(String title, String subtitle) {
+ this.sendTitle(title, subtitle, 20, 20, 5);
}
- public void sendActionBarTitle(String text) {
- SetTitlePacket pk = new SetTitlePacket();
- pk.type = SetTitlePacket.TYPE_ACTION_BAR;
- pk.text = text;
- this.dataPacket(pk);
+ public void sendTitle(String title, String subtitle, int fadein, int duration, int fadeout) {
+ if (!subtitle.equals("")) {
+ SetTitlePacket pk = new SetTitlePacket();
+ pk.type = SetTitlePacket.TYPE_SUBTITLE;
+ pk.text = subtitle;
+ pk.fadeInTime = fadein;
+ pk.stayTime = duration;
+ pk.fadeOutTime = fadeout;
+ this.dataPacket(pk);
+ }
+ SetTitlePacket pk2 = new SetTitlePacket();
+ pk2.type = SetTitlePacket.TYPE_TITLE;
+ pk2.text = title;
+ pk2.fadeInTime = fadein;
+ pk2.stayTime = duration;
+ pk2.fadeOutTime = fadeout;
+ this.dataPacket(pk2);
}
- /**
- * Sets times for title animations
- *
- * @param fadeInTime For how long title fades in
- * @param stayTime For how long title is shown
- * @param fadeOutTime For how long title fades out
- */
- public void setTitleAnimationTimes(int fadeInTime, int stayTime, int fadeOutTime) {
+ public void sendActionBar(String title) {
+ this.sendActionBar(title, 1, 0, 1);
+ }
+
+ public void sendActionBar(String title, int fadein, int duration, int fadeout) {
SetTitlePacket pk = new SetTitlePacket();
- pk.type = SetTitlePacket.TYPE_ANIMATION_TIMES;
- pk.fadeInTime = fadeInTime;
- pk.stayTime = stayTime;
- pk.fadeOutTime = fadeOutTime;
+ pk.type = SetTitlePacket.TYPE_ACTION_BAR;
+ pk.text = title;
+ pk.fadeInTime = fadein;
+ pk.stayTime = duration;
+ pk.fadeOutTime = fadeout;
this.dataPacket(pk);
}
diff --git a/src/main/java/cn/nukkit/command/defaults/TitleCommand.java b/src/main/java/cn/nukkit/command/defaults/TitleCommand.java
index 732fb77129..c0b91ccd1c 100644
--- a/src/main/java/cn/nukkit/command/defaults/TitleCommand.java
+++ b/src/main/java/cn/nukkit/command/defaults/TitleCommand.java
@@ -84,14 +84,14 @@ public boolean execute(CommandSender sender, String commandLabel, String[] args)
player.sendTitle(args[2]);
sender.sendMessage(new TranslationContainer("nukkit.command.title.title", new String[]{TextFormat.clean(args[2]), player.getName()}));
break;
- case "subtitle":
+ /*case "subtitle":
player.setSubtitle(args[2]);
sender.sendMessage(new TranslationContainer("nukkit.command.title.subtitle", new String[]{TextFormat.clean(args[2]), player.getName()}));
break;
case "actionbar":
player.sendActionBarTitle(args[2]);
sender.sendMessage(new TranslationContainer("nukkit.command.title.actionbar", new String[]{TextFormat.clean(args[2]), player.getName()}));
- break;
+ break;*/
default:
sender.sendMessage(new TranslationContainer("commands.generic.usage", this.usageMessage));
return false;
@@ -99,9 +99,9 @@ public boolean execute(CommandSender sender, String commandLabel, String[] args)
} else if (args.length == 5) {
if (args[1].toLowerCase().equals("times")) {
try {
- player.setTitleAnimationTimes(Integer.valueOf(args[2]), //fadeIn
+ /*player.setTitleAnimationTimes(Integer.valueOf(args[2]), //fadeIn
Integer.valueOf(args[3]), //stay
- Integer.valueOf(args[4])); //fadeOut
+ Integer.valueOf(args[4])); //fadeOut*/
sender.sendMessage(new TranslationContainer("nukkit.command.title.times.success", new String[]{
args[2], args[3], args[4], player.getName()}));
} catch (NumberFormatException exception) {
diff --git a/src/main/java/cn/nukkit/event/player/PlayerMoveEvent.java b/src/main/java/cn/nukkit/event/player/PlayerMoveEvent.java
index 60edf4ff41..9dbd77466e 100644
--- a/src/main/java/cn/nukkit/event/player/PlayerMoveEvent.java
+++ b/src/main/java/cn/nukkit/event/player/PlayerMoveEvent.java
@@ -15,10 +15,17 @@ public static HandlerList getHandlers() {
private Location from;
private Location to;
+ private boolean resetBlocksAround;
+
public PlayerMoveEvent(Player player, Location from, Location to) {
+ this(player, from, to, true);
+ }
+
+ public PlayerMoveEvent(Player player, Location from, Location to, boolean resetBlocks) {
this.player = player;
this.from = from;
this.to = to;
+ this.resetBlocksAround = resetBlocks;
}
public Location getFrom() {
@@ -36,4 +43,17 @@ public Location getTo() {
public void setTo(Location to) {
this.to = to;
}
+
+ public boolean isResetBlocksAround() {
+ return resetBlocksAround;
+ }
+
+ public void setResetBlocksAround(boolean value) {
+ this.resetBlocksAround = value;
+ }
+
+ @Override
+ public void setCancelled() {
+ super.setCancelled();
+ }
}
From 8184186b1e490e3750661517d0c165924473fa2e Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Wed, 2 Aug 2017 15:19:33 +0200
Subject: [PATCH 030/175] add returns to setters, stairs collision
---
.../java/cn/nukkit/block/BlockStairs.java | 76 +++++++++++++++++++
src/main/java/cn/nukkit/item/Item.java | 3 +-
.../nukkit/item/enchantment/Enchantment.java | 10 ++-
3 files changed, 84 insertions(+), 5 deletions(-)
diff --git a/src/main/java/cn/nukkit/block/BlockStairs.java b/src/main/java/cn/nukkit/block/BlockStairs.java
index 90be6d2cdd..304b91f616 100644
--- a/src/main/java/cn/nukkit/block/BlockStairs.java
+++ b/src/main/java/cn/nukkit/block/BlockStairs.java
@@ -73,4 +73,80 @@ public Item toItem() {
item.setDamage(0);
return item;
}
+
+ @Override
+ public boolean collidesWithBB(AxisAlignedBB bb) {
+ int damage = this.getDamage();
+ int side = damage & 0x03;
+ double f = 0;
+ double f1 = 0.5;
+ double f2 = 0.5;
+ double f3 = 1;
+ if ((damage & 0x04) > 0) {
+ f = 0.5;
+ f1 = 1;
+ f2 = 0;
+ f3 = 0.5;
+ }
+
+ if (bb.intersectsWith(new AxisAlignedBB(
+ this.x,
+ this.y + f,
+ this.z,
+ this.x + 1,
+ this.y + f1,
+ this.z + 1
+ ))) {
+ return true;
+ }
+
+
+ if (side == 0) {
+ if (bb.intersectsWith(new AxisAlignedBB(
+ this.x + 0.5,
+ this.y + f2,
+ this.z,
+ this.x + 1,
+ this.y + f3,
+ this.z + 1
+ ))) {
+ return true;
+ }
+ } else if (side == 1) {
+ if (bb.intersectsWith(new AxisAlignedBB(
+ this.x,
+ this.y + f2,
+ this.z,
+ this.x + 0.5,
+ this.y + f3,
+ this.z + 1
+ ))) {
+ return true;
+ }
+ } else if (side == 2) {
+ if (bb.intersectsWith(new AxisAlignedBB(
+ this.x,
+ this.y + f2,
+ this.z + 0.5,
+ this.x + 1,
+ this.y + f3,
+ this.z + 1
+ ))) {
+ return true;
+ }
+ } else if (side == 3) {
+ if (bb.intersectsWith(new AxisAlignedBB(
+ this.x,
+ this.y + f2,
+ this.z,
+ this.x + 1,
+ this.y + f3,
+ this.z + 0.5
+ ))) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java
index 2eab29b9c9..d9e21b1703 100644
--- a/src/main/java/cn/nukkit/item/Item.java
+++ b/src/main/java/cn/nukkit/item/Item.java
@@ -1835,7 +1835,7 @@ public String[] getLore() {
return lines.toArray(new String[0]);
}
- public void setLore(String... lines) {
+ public Item setLore(String... lines) {
CompoundTag tag;
if (!this.hasCompoundTag()) {
tag = new CompoundTag();
@@ -1855,6 +1855,7 @@ public void setLore(String... lines) {
}
this.setNamedTag(tag);
+ return this;
}
public Tag getNamedTagEntry(String name) {
diff --git a/src/main/java/cn/nukkit/item/enchantment/Enchantment.java b/src/main/java/cn/nukkit/item/enchantment/Enchantment.java
index 9e1f9c08e3..77bffba444 100644
--- a/src/main/java/cn/nukkit/item/enchantment/Enchantment.java
+++ b/src/main/java/cn/nukkit/item/enchantment/Enchantment.java
@@ -126,14 +126,14 @@ public int getLevel() {
return level;
}
- public void setLevel(int level) {
- this.setLevel(level, true);
+ public Enchantment setLevel(int level) {
+ return this.setLevel(level, true);
}
- public void setLevel(int level, boolean safe) {
+ public Enchantment setLevel(int level, boolean safe) {
if (!safe) {
this.level = level;
- return;
+ return this;
}
if (level > this.getMaxLevel()) {
@@ -143,6 +143,8 @@ public void setLevel(int level, boolean safe) {
} else {
this.level = level;
}
+
+ return this;
}
public int getId() {
From fc5b43aec33de8a932d780567d0f7ec1e7aa949d Mon Sep 17 00:00:00 2001
From: Scallop Ye <862578730@qq.com>
Date: Thu, 3 Aug 2017 00:01:12 +0800
Subject: [PATCH 031/175] Update to 1.2 (Part 1)
---
src/main/java/cn/nukkit/Player.java | 593 ++++--------------
.../inventory/InventoryTransactionEvent.java | 2 +-
.../cn/nukkit/inventory/BaseInventory.java | 13 +-
.../cn/nukkit/inventory/PlayerInventory.java | 54 +-
.../cn/nukkit/inventory/TransactionGroup.java | 26 -
.../{ => transaction}/BaseTransaction.java | 17 +-
.../transaction/BaseTransactionGroup.java | 47 ++
.../transaction/ContainerTransaction.java | 28 +
.../transaction/CraftTransaction.java | 22 +
.../transaction/CreativeTransaction.java | 15 +
.../transaction/GlobalTransaction.java | 15 +
.../InventoryMismatchTransactionGroup.java | 21 +
.../ItemReleaseTransactionGroup.java | 193 ++++++
.../ItemUseOnEntityTransactionGroup.java | 57 ++
.../transaction/ItemUseTransactionGroup.java | 385 ++++++++++++
.../NormalTransactionGroup.java} | 107 ++--
.../{ => transaction}/Transaction.java | 10 +-
.../transaction/TransactionGroup.java | 45 ++
.../WorldInteractionTransaction.java | 22 +
src/main/java/cn/nukkit/level/Level.java | 108 ++--
src/main/java/cn/nukkit/network/Network.java | 32 +-
.../protocol/AddBehaviorTreePacket.java | 19 +
.../protocol/AddHangingEntityPacket.java | 39 --
.../network/protocol/AddItemPacket.java | 25 -
.../network/protocol/AddPaintingPacket.java | 2 +-
.../protocol/BlockEntityDataPacket.java | 4 +-
.../network/protocol/BlockEventPacket.java | 2 +-
.../protocol/BlockPickRequestPacket.java | 2 +-
.../network/protocol/BookEditPacket.java | 19 +
.../nukkit/network/protocol/CameraPacket.java | 19 +
.../protocol/CommandBlockUpdatePacket.java | 19 +
...pPacket.java => CommandRequestPacket.java} | 4 +-
.../network/protocol/ContainerOpenPacket.java | 2 +-
.../network/protocol/CraftingEventPacket.java | 9 +-
.../nukkit/network/protocol/DataPacket.java | 1 +
.../network/protocol/DropItemPacket.java | 31 -
.../protocol/EntityPickRequestPacket.java | 21 +
.../network/protocol/ExplodePacket.java | 2 +-
.../protocol/GUIDataPickItemPacket.java | 19 +
.../InitiateWebSocketConnectionPacket.java | 19 +
.../protocol/InventoryActionPacket.java | 32 -
...acket.java => InventoryContentPacket.java} | 34 +-
...otPacket.java => InventorySlotPacket.java} | 16 +-
.../protocol/InventoryTransactionPacket.java | 135 ++++
.../protocol/ItemFrameDropItemPacket.java | 2 +-
.../protocol/LevelSoundEventPacket.java | 16 +-
.../nukkit/network/protocol/LoginPacket.java | 4 +-
.../network/protocol/NPCRequestPacket.java | 19 +
.../network/protocol/PlaySoundPacket.java | 2 +-
.../network/protocol/PlayerActionPacket.java | 35 +-
.../network/protocol/PlayerHotbarPacket.java | 31 +
.../network/protocol/PlayerSkinPacket.java | 19 +
.../nukkit/network/protocol/ProtocolInfo.java | 92 +--
.../network/protocol/RemoveBlockPacket.java | 33 -
.../protocol/ReplaceItemInSlotPacket.java | 30 -
.../network/protocol/SetLastHurtByPacket.java | 19 +
.../protocol/SetSpawnPositionPacket.java | 2 +-
.../network/protocol/SimpleEventPacket.java | 19 +
.../network/protocol/StartGamePacket.java | 2 +-
.../protocol/StructureBlockUpdatePacket.java | 19 +
.../protocol/SubClientLoginPacket.java | 19 +
.../protocol/TelemetryEventPacket.java | 25 +
.../network/protocol/UpdateBlockPacket.java | 16 +-
.../protocol/UpdateEquipmentPacket.java | 19 +
.../network/protocol/UseItemPacket.java | 64 --
src/main/java/cn/nukkit/utils/Binary.java | 2 +-
.../java/cn/nukkit/utils/BinaryStream.java | 14 +-
.../java/cn/nukkit/utils/ClientChainData.java | 12 -
.../cn/nukkit/test/ClientChainDataTest.java | 9 +-
69 files changed, 1708 insertions(+), 1103 deletions(-)
delete mode 100644 src/main/java/cn/nukkit/inventory/TransactionGroup.java
rename src/main/java/cn/nukkit/inventory/{ => transaction}/BaseTransaction.java (59%)
create mode 100644 src/main/java/cn/nukkit/inventory/transaction/BaseTransactionGroup.java
create mode 100644 src/main/java/cn/nukkit/inventory/transaction/ContainerTransaction.java
create mode 100644 src/main/java/cn/nukkit/inventory/transaction/CraftTransaction.java
create mode 100644 src/main/java/cn/nukkit/inventory/transaction/CreativeTransaction.java
create mode 100644 src/main/java/cn/nukkit/inventory/transaction/GlobalTransaction.java
create mode 100644 src/main/java/cn/nukkit/inventory/transaction/InventoryMismatchTransactionGroup.java
create mode 100644 src/main/java/cn/nukkit/inventory/transaction/ItemReleaseTransactionGroup.java
create mode 100644 src/main/java/cn/nukkit/inventory/transaction/ItemUseOnEntityTransactionGroup.java
create mode 100644 src/main/java/cn/nukkit/inventory/transaction/ItemUseTransactionGroup.java
rename src/main/java/cn/nukkit/inventory/{SimpleTransactionGroup.java => transaction/NormalTransactionGroup.java} (50%)
rename src/main/java/cn/nukkit/inventory/{ => transaction}/Transaction.java (51%)
create mode 100644 src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java
create mode 100644 src/main/java/cn/nukkit/inventory/transaction/WorldInteractionTransaction.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/AddBehaviorTreePacket.java
delete mode 100644 src/main/java/cn/nukkit/network/protocol/AddHangingEntityPacket.java
delete mode 100644 src/main/java/cn/nukkit/network/protocol/AddItemPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/BookEditPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/CameraPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java
rename src/main/java/cn/nukkit/network/protocol/{CommandStepPacket.java => CommandRequestPacket.java} (91%)
delete mode 100644 src/main/java/cn/nukkit/network/protocol/DropItemPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/EntityPickRequestPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/GUIDataPickItemPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/InitiateWebSocketConnectionPacket.java
delete mode 100644 src/main/java/cn/nukkit/network/protocol/InventoryActionPacket.java
rename src/main/java/cn/nukkit/network/protocol/{ContainerSetContentPacket.java => InventoryContentPacket.java} (51%)
rename src/main/java/cn/nukkit/network/protocol/{ContainerSetSlotPacket.java => InventorySlotPacket.java} (50%)
create mode 100644 src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/NPCRequestPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/PlayerHotbarPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/PlayerSkinPacket.java
delete mode 100644 src/main/java/cn/nukkit/network/protocol/RemoveBlockPacket.java
delete mode 100644 src/main/java/cn/nukkit/network/protocol/ReplaceItemInSlotPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/SetLastHurtByPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/SimpleEventPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/StructureBlockUpdatePacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/SubClientLoginPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/TelemetryEventPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java
delete mode 100644 src/main/java/cn/nukkit/network/protocol/UseItemPacket.java
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 59ac7ffddc..fb691aea2a 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -4,7 +4,6 @@
import cn.nukkit.blockentity.BlockEntity;
import cn.nukkit.blockentity.BlockEntityItemFrame;
import cn.nukkit.blockentity.BlockEntitySign;
-import cn.nukkit.blockentity.BlockEntitySpawnable;
import cn.nukkit.command.Command;
import cn.nukkit.command.CommandSender;
import cn.nukkit.command.data.CommandDataVersions;
@@ -28,6 +27,7 @@
import cn.nukkit.event.server.DataPacketReceiveEvent;
import cn.nukkit.event.server.DataPacketSendEvent;
import cn.nukkit.inventory.*;
+import cn.nukkit.inventory.transaction.*;
import cn.nukkit.item.*;
import cn.nukkit.item.enchantment.Enchantment;
import cn.nukkit.item.food.Food;
@@ -116,7 +116,7 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
public final HashSet achievements = new HashSet<>();
- protected SimpleTransactionGroup currentTransaction = null;
+ protected BaseTransactionGroup currentTransaction = null;
public int craftingType = CRAFTING_SMALL;
@@ -197,6 +197,26 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
private ClientChainData loginChainData;
+ public int getStartActionTick() {
+ return startAction;
+ }
+
+ public void startAction() {
+ this.startAction = this.server.getTick();
+ }
+
+ public void stopAction() {
+ this.startAction = -1;
+ }
+
+ public int getLastEnderPearlThrowingTick() {
+ return lastEnderPearl;
+ }
+
+ public void onThrowEnderPearl() {
+ this.lastEnderPearl = this.server.getTick();
+ }
+
public BlockEnderChest getViewingEnderChest() {
return viewingEnderChest;
}
@@ -752,6 +772,7 @@ protected void doFirstSpawn() {
this.sendPotionEffects(this);
this.sendData(this);
this.inventory.sendContents(this);
+ this.inventory.sendHotbarContents();
this.inventory.sendArmorContents(this);
SetTimePacket setTimePacket = new SetTimePacket();
@@ -1126,19 +1147,17 @@ public boolean setGamemode(int gamemode, boolean clientSide, AdventureSettings n
this.getAdventureSettings().setFlying(true);
this.teleport(this.temporalVector.setComponents(this.x, this.y + 0.1, this.z));
- ContainerSetContentPacket containerSetContentPacket = new ContainerSetContentPacket();
- containerSetContentPacket.windowid = ContainerSetContentPacket.SPECIAL_CREATIVE;
- containerSetContentPacket.eid = this.id;
- this.dataPacket(containerSetContentPacket);
+ InventoryContentPacket inventoryContentPacket = new InventoryContentPacket();
+ inventoryContentPacket.inventoryId = InventoryContentPacket.SPECIAL_CREATIVE;
+ this.dataPacket(inventoryContentPacket);
} else {
if (this.isSurvival()) {
this.getAdventureSettings().setFlying(false);
}
- ContainerSetContentPacket containerSetContentPacket = new ContainerSetContentPacket();
- containerSetContentPacket.windowid = ContainerSetContentPacket.SPECIAL_CREATIVE;
- containerSetContentPacket.eid = this.id;
- containerSetContentPacket.slots = Item.getCreativeItems().stream().toArray(Item[]::new);
- this.dataPacket(containerSetContentPacket);
+ InventoryContentPacket inventoryContentPacket = new InventoryContentPacket();
+ inventoryContentPacket.inventoryId = InventoryContentPacket.SPECIAL_CREATIVE;
+ inventoryContentPacket.slots = Item.getCreativeItems().stream().toArray(Item[]::new);
+ this.dataPacket(inventoryContentPacket);
}
this.resetFallDistance();
@@ -1953,16 +1972,14 @@ protected void processLogin() {
}
if (this.gamemode == Player.SPECTATOR) {
- ContainerSetContentPacket containerSetContentPacket = new ContainerSetContentPacket();
- containerSetContentPacket.windowid = ContainerSetContentPacket.SPECIAL_CREATIVE;
- containerSetContentPacket.eid = this.id;
- this.dataPacket(containerSetContentPacket);
+ InventoryContentPacket inventoryContentPacket = new InventoryContentPacket();
+ inventoryContentPacket.inventoryId = InventoryContentPacket.SPECIAL_CREATIVE;
+ this.dataPacket(inventoryContentPacket);
} else {
- ContainerSetContentPacket containerSetContentPacket = new ContainerSetContentPacket();
- containerSetContentPacket.windowid = ContainerSetContentPacket.SPECIAL_CREATIVE;
- containerSetContentPacket.eid = this.id;
- containerSetContentPacket.slots = Item.getCreativeItems().stream().toArray(Item[]::new);
- this.dataPacket(containerSetContentPacket);
+ InventoryContentPacket inventoryContentPacket = new InventoryContentPacket();
+ inventoryContentPacket.inventoryId = InventoryContentPacket.SPECIAL_CREATIVE;
+ inventoryContentPacket.slots = Item.getCreativeItems().stream().toArray(Item[]::new);
+ this.dataPacket(inventoryContentPacket);
}
this.setEnableClientCommand(true);
@@ -2270,269 +2287,6 @@ public void handleDataPacket(DataPacket packet) {
this.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, false);
break;
- case ProtocolInfo.USE_ITEM_PACKET:
- if (!this.spawned || !this.isAlive()) {
- break;
- }
-
- UseItemPacket useItemPacket = (UseItemPacket) packet;
-
- Vector3 blockVector = new Vector3(useItemPacket.x, useItemPacket.y, useItemPacket.z);
-
- this.craftingType = CRAFTING_SMALL;
-
- if (useItemPacket.face >= 0 && useItemPacket.face <= 5) {
- BlockFace face = BlockFace.fromIndex(useItemPacket.face);
- this.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, false);
-
- if (!this.canInteract(blockVector.add(0.5, 0.5, 0.5), this.isCreative() ? 13 : 7)) {
- } else if (this.isCreative()) {
- Item i = this.inventory.getItemInHand();
- if (this.level.useItemOn(blockVector, i, face, useItemPacket.fx, useItemPacket.fy, useItemPacket.fz, this, true) != null) {
- break;
- }
- } else if (!this.inventory.getItemInHand().deepEquals(useItemPacket.item)) {
- this.inventory.sendHeldItem(this);
- } else {
- item = this.inventory.getItemInHand();
- Item oldItem = item.clone();
- //TODO: Implement adventure mode checks
- if ((item = this.level.useItemOn(blockVector, item, face, useItemPacket.fx, useItemPacket.fy, useItemPacket.fz, this, true)) != null) {
- if (!item.deepEquals(oldItem) || item.getCount() != oldItem.getCount()) {
- this.inventory.setItemInHand(item);
- this.inventory.sendHeldItem(this.hasSpawned.values());
- }
- break;
- }
- }
-
- this.inventory.sendHeldItem(this);
-
- if (blockVector.distanceSquared(this) > 10000) {
- break;
- }
-
- Block target = this.level.getBlock(blockVector);
- Block block = target.getSide(face);
-
- if (target instanceof BlockDoor) {
- BlockDoor door = (BlockDoor) target;
-
- Block part;
-
- if ((door.getDamage() & 0x08) > 0) { //up
- part = target.down();
-
- if (part.getId() == target.getId()) {
- target = part;
- }
- }
- }
-
- this.level.sendBlocks(new Player[]{this}, new Block[]{target, block}, UpdateBlockPacket.FLAG_ALL_PRIORITY);
- break;
- } else if (useItemPacket.face == -1) {
- Vector3 aimPos = new Vector3(
- -Math.sin(this.yaw / 180d * Math.PI) * Math.cos(this.pitch / 180d * Math.PI),
- -Math.sin(this.pitch / 180d * Math.PI),
- Math.cos(this.yaw / 180d * Math.PI) * Math.cos(this.pitch / 180d * Math.PI)
- );
-
- if (this.isCreative()) {
- item = this.inventory.getItemInHand();
- } else if (!this.inventory.getItemInHand().deepEquals(useItemPacket.item)) {
- this.inventory.sendHeldItem(this);
- break;
- } else {
- item = this.inventory.getItemInHand();
- }
-
- PlayerInteractEvent playerInteractEvent = new PlayerInteractEvent(this, item, aimPos, null, Action.RIGHT_CLICK_AIR);
-
- this.server.getPluginManager().callEvent(playerInteractEvent);
-
- if (playerInteractEvent.isCancelled()) {
- this.inventory.sendHeldItem(this);
- break;
- }
-
- if (item.getId() == Item.SNOWBALL) {
- CompoundTag nbt = new CompoundTag()
- .putList(new ListTag("Pos")
- .add(new DoubleTag("", x))
- .add(new DoubleTag("", y + this.getEyeHeight()))
- .add(new DoubleTag("", z)))
- .putList(new ListTag("Motion")
- .add(new DoubleTag("", -Math.sin(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI)))
- .add(new DoubleTag("", -Math.sin(pitch / 180 * Math.PI)))
- .add(new DoubleTag("", Math.cos(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI))))
- .putList(new ListTag("Rotation")
- .add(new FloatTag("", (float) yaw))
- .add(new FloatTag("", (float) pitch)));
-
- float f = 1.5f;
- EntitySnowball snowball = new EntitySnowball(this.chunk, nbt, this);
-
- snowball.setMotion(snowball.getMotion().multiply(f));
- if (this.isSurvival()) {
- item.setCount(item.getCount() - 1);
- this.inventory.setItemInHand(item.getCount() > 0 ? item : Item.get(Item.AIR));
- }
- if (snowball instanceof EntityProjectile) {
- ProjectileLaunchEvent projectileLaunchEvent = new ProjectileLaunchEvent(snowball);
- this.server.getPluginManager().callEvent(projectileLaunchEvent);
- if (projectileLaunchEvent.isCancelled()) {
- snowball.kill();
- } else {
- snowball.spawnToAll();
- this.level.addSound(new LaunchSound(this), this.getViewers().values());
- }
- } else {
- snowball.spawnToAll();
- }
- } else if (item.getId() == Item.EGG) {
- CompoundTag nbt = new CompoundTag()
- .putList(new ListTag("Pos")
- .add(new DoubleTag("", x))
- .add(new DoubleTag("", y + this.getEyeHeight()))
- .add(new DoubleTag("", z)))
- .putList(new ListTag("Motion")
- .add(new DoubleTag("", -Math.sin(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI)))
- .add(new DoubleTag("", -Math.sin(pitch / 180 * Math.PI)))
- .add(new DoubleTag("", Math.cos(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI))))
- .putList(new ListTag("Rotation")
- .add(new FloatTag("", (float) yaw))
- .add(new FloatTag("", (float) pitch)));
-
- float f = 1.5f;
- EntityEgg egg = new EntityEgg(this.chunk, nbt, this);
-
- egg.setMotion(egg.getMotion().multiply(f));
- if (this.isSurvival()) {
- item.setCount(item.getCount() - 1);
- this.inventory.setItemInHand(item.getCount() > 0 ? item : Item.get(Item.AIR));
- }
- if (egg instanceof EntityProjectile) {
- ProjectileLaunchEvent projectileLaunchEvent = new ProjectileLaunchEvent(egg);
- this.server.getPluginManager().callEvent(projectileLaunchEvent);
- if (projectileLaunchEvent.isCancelled()) {
- egg.kill();
- } else {
- egg.spawnToAll();
- this.level.addSound(new LaunchSound(this), this.getViewers().values());
- }
- } else {
- egg.spawnToAll();
- }
- } else if (item.getId() == Item.ENDER_PEARL && (this.server.getTick() - this.lastEnderPearl) >= 20) {
- CompoundTag nbt = new CompoundTag()
- .putList(new ListTag("Pos")
- .add(new DoubleTag("", x))
- .add(new DoubleTag("", y + this.getEyeHeight()))
- .add(new DoubleTag("", z)))
- .putList(new ListTag("Motion")
- .add(new DoubleTag("", -Math.sin(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI)))
- .add(new DoubleTag("", -Math.sin(pitch / 180 * Math.PI)))
- .add(new DoubleTag("", Math.cos(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI))))
- .putList(new ListTag("Rotation")
- .add(new FloatTag("", (float) yaw))
- .add(new FloatTag("", (float) pitch)));
-
- float f = 1.5f;
- EntityEnderPearl enderPearl = new EntityEnderPearl(this.chunk, nbt, this);
-
- enderPearl.setMotion(enderPearl.getMotion().multiply(f));
- if (this.isSurvival()) {
- item.setCount(item.getCount() - 1);
- this.inventory.setItemInHand(item.getCount() > 0 ? item : Item.get(Item.AIR));
- }
- if (enderPearl instanceof EntityProjectile) {
- ProjectileLaunchEvent projectileLaunchEvent = new ProjectileLaunchEvent(enderPearl);
- this.server.getPluginManager().callEvent(projectileLaunchEvent);
- if (projectileLaunchEvent.isCancelled()) {
- enderPearl.kill();
- } else {
- enderPearl.spawnToAll();
- this.level.addSound(new LaunchSound(this), this.getViewers().values());
- }
- } else {
- enderPearl.spawnToAll();
- }
- this.lastEnderPearl = this.server.getTick();
- } else if (item.getId() == Item.EXPERIENCE_BOTTLE) {
- CompoundTag nbt = new CompoundTag()
- .putList(new ListTag("Pos")
- .add(new DoubleTag("", x))
- .add(new DoubleTag("", y + this.getEyeHeight()))
- .add(new DoubleTag("", z)))
- .putList(new ListTag("Motion")
- .add(new DoubleTag("", -Math.sin(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI)))
- .add(new DoubleTag("", -Math.sin(pitch / 180 * Math.PI)))
- .add(new DoubleTag("", Math.cos(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI))))
- .putList(new ListTag("Rotation")
- .add(new FloatTag("", (float) yaw))
- .add(new FloatTag("", (float) pitch)))
- .putInt("Potion", item.getDamage());
- double f = 1.5;
- Entity bottle = new EntityExpBottle(this.chunk, nbt, this);
- bottle.setMotion(bottle.getMotion().multiply(f));
- if (this.isSurvival()) {
- item.setCount(item.getCount() - 1);
- this.inventory.setItemInHand(item.getCount() > 0 ? item : Item.get(Item.AIR));
- }
- if (bottle instanceof EntityProjectile) {
- EntityProjectile bottleEntity = (EntityProjectile) bottle;
- ProjectileLaunchEvent projectileEv = new ProjectileLaunchEvent(bottleEntity);
- this.server.getPluginManager().callEvent(projectileEv);
- if (projectileEv.isCancelled()) {
- bottle.kill();
- } else {
- bottle.spawnToAll();
- this.level.addSound(new LaunchSound(this), this.getViewers().values());
- }
- } else {
- bottle.spawnToAll();
- }
- } else if (item.getId() == Item.SPLASH_POTION) {
- CompoundTag nbt = new CompoundTag()
- .putList(new ListTag("Pos")
- .add(new DoubleTag("", x))
- .add(new DoubleTag("", y + this.getEyeHeight()))
- .add(new DoubleTag("", z)))
- .putList(new ListTag("Motion")
- .add(new DoubleTag("", -Math.sin(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI)))
- .add(new DoubleTag("", -Math.sin(pitch / 180 * Math.PI)))
- .add(new DoubleTag("", Math.cos(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI))))
- .putList(new ListTag("Rotation")
- .add(new FloatTag("", (float) yaw))
- .add(new FloatTag("", (float) pitch)))
- .putShort("PotionId", item.getDamage());
- double f = 1.5;
- Entity bottle = new EntityPotion(this.chunk, nbt, this);
- bottle.setMotion(bottle.getMotion().multiply(f));
- if (this.isSurvival()) {
- item.setCount(item.getCount() - 1);
- this.inventory.setItemInHand(item.getCount() > 0 ? item : Item.get(Item.AIR));
- }
- if (bottle instanceof EntityPotion) {
- EntityPotion bottleEntity = (EntityPotion) bottle;
- ProjectileLaunchEvent projectileEv = new ProjectileLaunchEvent(bottleEntity);
- this.server.getPluginManager().callEvent(projectileEv);
- if (projectileEv.isCancelled()) {
- bottle.kill();
- } else {
- bottle.spawnToAll();
- this.level.addSound(new LaunchSound(this), this.getViewers().values());
- }
- } else {
- bottle.spawnToAll();
- }
- }
-
- this.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, true);
- this.startAction = this.server.getTick();
- }
- break;
case ProtocolInfo.PLAYER_ACTION_PACKET:
PlayerActionPacket playerActionPacket = (PlayerActionPacket) packet;
if (!this.spawned || (!this.isAlive() && playerActionPacket.action != PlayerActionPacket.ACTION_RESPAWN && playerActionPacket.action != PlayerActionPacket.ACTION_DIMENSION_CHANGE)) {
@@ -2594,96 +2348,11 @@ public void handleDataPacket(DataPacket packet) {
this.getLevel().addChunkPacket(pos.getFloorX() >> 4, pos.getFloorZ() >> 4, pk);
break;
- case PlayerActionPacket.ACTION_RELEASE_ITEM:
- if (this.startAction > -1 && this.getDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION)) {
- if (this.inventory.getItemInHand().getId() == Item.BOW) {
-
- Item bow = this.inventory.getItemInHand();
- ItemArrow itemArrow = new ItemArrow();
- if (this.isSurvival() && !this.inventory.contains(itemArrow)) {
- this.inventory.sendContents(this);
- break;
- }
-
- double damage = 2;
- boolean flame = false;
-
- if (bow.hasEnchantments()) {
- Enchantment bowDamage = bow.getEnchantment(Enchantment.ID_BOW_POWER);
-
- if (bowDamage != null && bowDamage.getLevel() > 0) {
- damage += 0.25 * (bowDamage.getLevel() + 1);
- }
-
- Enchantment flameEnchant = bow.getEnchantment(Enchantment.ID_BOW_FLAME);
- flame = flameEnchant != null && flameEnchant.getLevel() > 0;
- }
-
- CompoundTag nbt = new CompoundTag()
- .putList(new ListTag("Pos")
- .add(new DoubleTag("", x))
- .add(new DoubleTag("", y + this.getEyeHeight()))
- .add(new DoubleTag("", z)))
- .putList(new ListTag("Motion")
- .add(new DoubleTag("", -Math.sin(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI)))
- .add(new DoubleTag("", -Math.sin(pitch / 180 * Math.PI)))
- .add(new DoubleTag("", Math.cos(yaw / 180 * Math.PI) * Math.cos(pitch / 180 * Math.PI))))
- .putList(new ListTag("Rotation")
- .add(new FloatTag("", (yaw > 180 ? 360 : 0) - (float) yaw))
- .add(new FloatTag("", (float) -pitch)))
- .putShort("Fire", this.isOnFire() || flame ? 45 * 60 : 0)
- .putDouble("damage", damage);
-
- int diff = (this.server.getTick() - this.startAction);
- double p = (double) diff / 20;
-
- double f = Math.min((p * p + p * 2) / 3, 1) * 2;
- EntityShootBowEvent entityShootBowEvent = new EntityShootBowEvent(this, bow, new EntityArrow(this.chunk, nbt, this, f == 2), f);
-
- if (f < 0.1 || diff < 5) {
- entityShootBowEvent.setCancelled();
- }
+ case PlayerActionPacket.ACTION_GET_UPDATED_BLOCK:
+ break; //TODO
- this.server.getPluginManager().callEvent(entityShootBowEvent);
- if (entityShootBowEvent.isCancelled()) {
- entityShootBowEvent.getProjectile().kill();
- this.inventory.sendContents(this);
- } else {
- entityShootBowEvent.getProjectile().setMotion(entityShootBowEvent.getProjectile().getMotion().multiply(entityShootBowEvent.getForce()));
- if (this.isSurvival()) {
- Enchantment infinity;
-
- if (!bow.hasEnchantments() || (infinity = bow.getEnchantment(Enchantment.ID_BOW_INFINITY)) == null || infinity.getLevel() <= 0)
- this.inventory.removeItem(itemArrow);
-
- if (!bow.isUnbreakable()) {
- Enchantment durability = bow.getEnchantment(Enchantment.ID_DURABILITY);
- if (!(durability != null && durability.getLevel() > 0 && (100 / (durability.getLevel() + 1)) <= new Random().nextInt(100))) {
- bow.setDamage(bow.getDamage() + 1);
- if (bow.getDamage() >= 385) {
- this.inventory.setItemInHand(new ItemBlock(new BlockAir(), 0, 0));
- } else {
- this.inventory.setItemInHand(bow);
- }
- }
- }
- }
- if (entityShootBowEvent.getProjectile() instanceof EntityProjectile) {
- ProjectileLaunchEvent projectev = new ProjectileLaunchEvent(entityShootBowEvent.getProjectile());
- this.server.getPluginManager().callEvent(projectev);
- if (projectev.isCancelled()) {
- entityShootBowEvent.getProjectile().kill();
- } else {
- entityShootBowEvent.getProjectile().spawnToAll();
- this.level.addSound(new LaunchSound(this), this.getViewers().values());
- }
- } else {
- entityShootBowEvent.getProjectile().spawnToAll();
- }
- }
- }
- }
- //milk removed here, see the section of food
+ case PlayerActionPacket.ACTION_DROP_ITEM:
+ break; //TODO
case PlayerActionPacket.ACTION_STOP_SLEEPING:
this.stopSleep();
@@ -2781,6 +2450,9 @@ public void handleDataPacket(DataPacket packet) {
}
break packetswitch;
+ case PlayerActionPacket.ACTION_DIMENSION_CHANGE_ACK:
+ break; //TODO
+
case PlayerActionPacket.ACTION_START_GLIDE:
PlayerToggleGlideEvent playerToggleGlideEvent = new PlayerToggleGlideEvent(this, true);
this.server.getPluginManager().callEvent(playerToggleGlideEvent);
@@ -2806,51 +2478,13 @@ public void handleDataPacket(DataPacket packet) {
block = this.level.getBlock(pos);
this.level.addParticle(new PunchBlockParticle(pos, block, face));
break;
+ case PlayerActionPacket.ACTION_CHANGE_SKIN:
+ break; //TODO
}
this.startAction = -1;
this.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, false);
break;
- case ProtocolInfo.REMOVE_BLOCK_PACKET:
- if (!this.spawned || !this.isAlive()) {
- break;
- }
- this.craftingType = CRAFTING_SMALL;
-
- Vector3 vector = new Vector3(((RemoveBlockPacket) packet).x, ((RemoveBlockPacket) packet).y, ((RemoveBlockPacket) packet).z);
-
- if (this.isCreative()) {
- item = this.inventory.getItemInHand();
- } else {
- item = this.inventory.getItemInHand();
- }
-
- Item oldItem = item.clone();
-
- if (this.canInteract(vector.add(0.5, 0.5, 0.5), this.isCreative() ? 13 : 7) && (item = this.level.useBreakOn(vector, item, this, true)) != null) {
- if (this.isSurvival()) {
- this.getFoodData().updateFoodExpLevel(0.025);
- if (!item.deepEquals(oldItem) || item.getCount() != oldItem.getCount()) {
- this.inventory.setItemInHand(item);
- this.inventory.sendHeldItem(this.hasSpawned.values());
- }
- }
- break;
- }
-
- this.inventory.sendContents(this);
- Block target = this.level.getBlock(vector);
- BlockEntity blockEntity = this.level.getBlockEntity(vector);
-
- this.level.sendBlocks(new Player[]{this}, new Block[]{target}, UpdateBlockPacket.FLAG_ALL_PRIORITY);
-
- this.inventory.sendHeldItem(this);
-
- if (blockEntity instanceof BlockEntitySpawnable) {
- ((BlockEntitySpawnable) blockEntity).spawnTo(this);
- }
- break;
-
case ProtocolInfo.MOB_ARMOR_EQUIPMENT_PACKET:
break;
@@ -3049,47 +2683,20 @@ public void handleDataPacket(DataPacket packet) {
break;
}
break;
- case ProtocolInfo.DROP_ITEM_PACKET:
- if (!this.spawned || !this.isAlive()) {
- break;
- }
- DropItemPacket dropItem = (DropItemPacket) packet;
-
- if (dropItem.item.getId() <= 0) {
- break;
- }
-
- item = (this.isCreative() || this.inventory.contains(dropItem.item)) ? dropItem.item : this.inventory.getItemInHand();
- PlayerDropItemEvent dropItemEvent = new PlayerDropItemEvent(this, item);
- this.server.getPluginManager().callEvent(dropItemEvent);
- if (dropItemEvent.isCancelled()) {
- this.inventory.sendContents(this);
- break;
- }
-
- if (!this.isCreative()) {
- this.inventory.removeItem(item);
- }
- Vector3 motion = this.getDirectionVector().multiply(0.4);
-
- this.level.dropItem(this.add(0, 1.3, 0), item, motion, 40);
-
- this.setDataFlag(DATA_FLAGS, DATA_FLAG_ACTION, false);
- break;
- case ProtocolInfo.COMMAND_STEP_PACKET:
+ case ProtocolInfo.COMMAND_REQUEST_PACKET:
if (!this.spawned || !this.isAlive()) {
break;
}
this.craftingType = 0;
- CommandStepPacket commandStepPacket = (CommandStepPacket) packet;
- String commandText = commandStepPacket.command;
+ CommandRequestPacket commandRequestPacket = (CommandRequestPacket) packet;
+ String commandText = commandRequestPacket.command;
Command command = this.getServer().getCommandMap().getCommand(commandText);
if (command != null) {
- if (commandStepPacket.args != null && commandStepPacket.args.size() > 0) {
- CommandParameter[] pars = command.getCommandParameters(commandStepPacket.overload);
+ if (commandRequestPacket.args != null && commandRequestPacket.args.size() > 0) {
+ CommandParameter[] pars = command.getCommandParameters(commandRequestPacket.overload);
if (pars != null) {
for (CommandParameter par : pars) {
- JsonElement arg = commandStepPacket.args.get(par.name);
+ JsonElement arg = commandRequestPacket.args.get(par.name);
if (arg != null) {
switch (par.type) {
case CommandParameter.ARG_TYPE_TARGET:
@@ -3514,58 +3121,58 @@ public void handleDataPacket(DataPacket packet) {
}
break;
- case ProtocolInfo.CONTAINER_SET_SLOT_PACKET:
+ case ProtocolInfo.INVENTORY_SLOT_PACKET:
if (!this.spawned || !this.isAlive()) {
break;
}
- ContainerSetSlotPacket containerSetSlotPacket = (ContainerSetSlotPacket) packet;
- if (containerSetSlotPacket.slot < 0) {
+ InventorySlotPacket inventorySlotPacket = (InventorySlotPacket) packet;
+ if (inventorySlotPacket.slot < 0) {
break;
}
Inventory inv;
BaseTransaction transaction;
- if (containerSetSlotPacket.windowid == 0) { //Our inventory
+ if (inventorySlotPacket.inventoryId == 0) { //Our inventory
inv = this.inventory;
- if (containerSetSlotPacket.slot >= this.inventory.getSize()) {
+ if (inventorySlotPacket.slot >= this.inventory.getSize()) {
break;
}
if (this.isCreative()) {
- if (Item.getCreativeItemIndex(containerSetSlotPacket.item) != -1) {
- inv.setItem(containerSetSlotPacket.slot, containerSetSlotPacket.item);
- this.inventory.setHotbarSlotIndex(containerSetSlotPacket.slot, containerSetSlotPacket.slot); //links hotbar[packet.slot] to slots[packet.slot]
+ if (Item.getCreativeItemIndex(inventorySlotPacket.item) != -1) {
+ inv.setItem(inventorySlotPacket.slot, inventorySlotPacket.item);
+ this.inventory.setHotbarSlotIndex(inventorySlotPacket.slot, inventorySlotPacket.slot); //links hotbar[packet.slot] to slots[packet.slot]
}
}
- transaction = new BaseTransaction(this.inventory, containerSetSlotPacket.slot, this.inventory.getItem(containerSetSlotPacket.slot), containerSetSlotPacket.item);
- } else if (containerSetSlotPacket.windowid == ContainerSetContentPacket.SPECIAL_ARMOR) { //Our armor
+ transaction = new ContainerTransaction(0, inventorySlotPacket.slot, this.inventory.getItem(inventorySlotPacket.slot), inventorySlotPacket.item);
+ } else if (inventorySlotPacket.inventoryId == InventoryContentPacket.SPECIAL_ARMOR) { //Our armor
inv = this.inventory;
- if (containerSetSlotPacket.slot >= 4) {
+ if (inventorySlotPacket.slot >= 4) {
break;
}
- transaction = new BaseTransaction(this.inventory, containerSetSlotPacket.slot + this.inventory.getSize(), this.inventory.getArmorItem(containerSetSlotPacket.slot), containerSetSlotPacket.item);
- } else if (this.windowIndex.containsKey(containerSetSlotPacket.windowid)) {
- inv = this.windowIndex.get(containerSetSlotPacket.windowid);
+ transaction = new ContainerTransaction(0, inventorySlotPacket.slot + this.inventory.getSize(), this.inventory.getArmorItem(inventorySlotPacket.slot), inventorySlotPacket.item);
+ } else if (this.windowIndex.containsKey(inventorySlotPacket.inventoryId)) {
+ inv = this.windowIndex.get(inventorySlotPacket.inventoryId);
if (!(inv instanceof AnvilInventory)) {
this.craftingType = CRAFTING_SMALL;
}
- if (inv instanceof EnchantInventory && containerSetSlotPacket.item.hasEnchantments()) {
- ((EnchantInventory) inv).onEnchant(this, inv.getItem(containerSetSlotPacket.slot), containerSetSlotPacket.item);
+ if (inv instanceof EnchantInventory && inventorySlotPacket.item.hasEnchantments()) {
+ ((EnchantInventory) inv).onEnchant(this, inv.getItem(inventorySlotPacket.slot), inventorySlotPacket.item);
}
- transaction = new BaseTransaction(inv, containerSetSlotPacket.slot, inv.getItem(containerSetSlotPacket.slot), containerSetSlotPacket.item);
+ transaction = new ContainerTransaction(inventorySlotPacket.inventoryId, inventorySlotPacket.slot, inv.getItem(inventorySlotPacket.slot), inventorySlotPacket.item);
} else {
break;
}
if (inv != null) {
- Item sourceItem = inv.getItem(containerSetSlotPacket.slot);
+ Item sourceItem = inv.getItem(inventorySlotPacket.slot);
Item heldItem = sourceItem.clone();
- heldItem.setCount(sourceItem.getCount() - containerSetSlotPacket.item.getCount());
+ heldItem.setCount(sourceItem.getCount() - inventorySlotPacket.item.getCount());
if (heldItem.getCount() > 0) { //In win10, click mouse and hold on item
- InventoryClickEvent inventoryClickEvent = new InventoryClickEvent(inv, containerSetSlotPacket.slot, sourceItem, heldItem, containerSetSlotPacket.item);
+ InventoryClickEvent inventoryClickEvent = new InventoryClickEvent(inv, inventorySlotPacket.slot, sourceItem, heldItem, inventorySlotPacket.item);
this.getServer().getPluginManager().callEvent(inventoryClickEvent);
//TODO Fix hold on bug and support Cancellable
}
@@ -3579,36 +3186,43 @@ public void handleDataPacket(DataPacket packet) {
if (this.currentTransaction == null || this.currentTransaction.getCreationTime() < (System.currentTimeMillis() - 8 * 1000)) {
if (this.currentTransaction != null) {
- for (Inventory inventory : this.currentTransaction.getInventories()) {
- if (inventory instanceof PlayerInventory) {
- ((PlayerInventory) inventory).sendArmorContents(this);
+ for (Transaction tr : this.currentTransaction.getTransactions()) {
+ if (tr.getType() == Transaction.TYPE_CONTAINER) {
+ Inventory inventory = this.windowIndex.get(((ContainerTransaction) tr).getInventoryId());
+ if (inventory != null) {
+ if (inventory instanceof PlayerInventory) {
+ ((PlayerInventory) inventory).sendArmorContents(this);
+ }
+ inventory.sendContents(this);
+ }
}
- inventory.sendContents(this);
}
}
- this.currentTransaction = new SimpleTransactionGroup(this);
+ this.currentTransaction = new NormalTransactionGroup();
}
this.currentTransaction.addTransaction(transaction);
- if (this.currentTransaction.canExecute() || this.isCreative()) {
+ if (this.currentTransaction.canExecute(this) || this.isCreative()) {
HashSet achievements = new HashSet<>();
for (Transaction tr : this.currentTransaction.getTransactions()) {
- Inventory inv1 = tr.getInventory();
-
- if (inv1 instanceof FurnaceInventory) {
- if (tr.getSlot() == 2) {
- switch (((FurnaceInventory) inv1).getResult().getId()) {
- case Item.IRON_INGOT:
- achievements.add("acquireIron");
- break;
+ if (tr.getType() == Transaction.TYPE_CONTAINER) {
+ Inventory inv1 = this.windowIndex.get(((ContainerTransaction) tr).getInventoryId());
+
+ if (inv1 instanceof FurnaceInventory) {
+ if (tr.getSlot() == 2) {
+ switch (((FurnaceInventory) inv1).getResult().getId()) {
+ case Item.IRON_INGOT:
+ achievements.add("acquireIron");
+ break;
+ }
}
}
}
}
- if (this.currentTransaction.execute(this.isCreative())) {
+ if (this.currentTransaction.executeOn(this, this.isCreative())) {
for (String achievement : achievements) {
this.awardAchievement(achievement);
}
@@ -3616,9 +3230,8 @@ public void handleDataPacket(DataPacket packet) {
this.currentTransaction = null;
} else {
- if (containerSetSlotPacket.item.getId() != 0) {
- inventory.sendSlot(containerSetSlotPacket.hotbarSlot, this);
- inventory.sendSlot(containerSetSlotPacket.slot, this);
+ if (inventorySlotPacket.item.getId() != 0) {
+ inventory.sendSlot(inventorySlotPacket.slot, this);
}
}
@@ -3745,6 +3358,16 @@ public void handleDataPacket(DataPacket packet) {
}
}
break;
+ case ProtocolInfo.INVENTORY_TRANSACTION_PACKET:
+ ((InventoryTransactionPacket) packet).transaction.executeOn(this, this.isCreative());
+ break;
+ case ProtocolInfo.PLAYER_HOTBAR_PACKET:
+ PlayerHotbarPacket playerHotbarPacket = (PlayerHotbarPacket) packet;
+ for (int i = 0; i < playerHotbarPacket.data.length; i++) {
+ this.inventory.setHotbarSlotIndex(i, playerHotbarPacket.data[i]);
+ }
+ this.inventory.setHeldItemSlot(playerHotbarPacket.selectedSlot);
+ break;
default:
break;
}
@@ -4769,6 +4392,10 @@ public int getWindowId(Inventory inventory) {
return -1;
}
+ public Inventory getWindowById(int id) {
+ return this.windowIndex.get(id);
+ }
+
public int addWindow(Inventory inventory) {
return this.addWindow(inventory, null);
}
diff --git a/src/main/java/cn/nukkit/event/inventory/InventoryTransactionEvent.java b/src/main/java/cn/nukkit/event/inventory/InventoryTransactionEvent.java
index c7d0328afd..836fc3196b 100644
--- a/src/main/java/cn/nukkit/event/inventory/InventoryTransactionEvent.java
+++ b/src/main/java/cn/nukkit/event/inventory/InventoryTransactionEvent.java
@@ -3,7 +3,7 @@
import cn.nukkit.event.Cancellable;
import cn.nukkit.event.Event;
import cn.nukkit.event.HandlerList;
-import cn.nukkit.inventory.TransactionGroup;
+import cn.nukkit.inventory.transaction.TransactionGroup;
/**
* author: MagicDroidX
diff --git a/src/main/java/cn/nukkit/inventory/BaseInventory.java b/src/main/java/cn/nukkit/inventory/BaseInventory.java
index 0d921a4dc3..c6ef2d5f14 100644
--- a/src/main/java/cn/nukkit/inventory/BaseInventory.java
+++ b/src/main/java/cn/nukkit/inventory/BaseInventory.java
@@ -8,8 +8,8 @@
import cn.nukkit.event.inventory.InventoryOpenEvent;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemBlock;
-import cn.nukkit.network.protocol.ContainerSetContentPacket;
-import cn.nukkit.network.protocol.ContainerSetSlotPacket;
+import cn.nukkit.network.protocol.InventoryContentPacket;
+import cn.nukkit.network.protocol.InventorySlotPacket;
import java.util.*;
@@ -438,20 +438,19 @@ public void sendContents(Player player) {
@Override
public void sendContents(Player[] players) {
- ContainerSetContentPacket pk = new ContainerSetContentPacket();
+ InventoryContentPacket pk = new InventoryContentPacket();
pk.slots = new Item[this.getSize()];
for (int i = 0; i < this.getSize(); ++i) {
pk.slots[i] = this.getItem(i);
}
for (Player player : players) {
- pk.eid = player.getId();
int id = player.getWindowId(this);
if (id == -1 || !player.spawned) {
this.close(player);
continue;
}
- pk.windowid = (byte) id;
+ pk.inventoryId = (byte) id;
player.dataPacket(pk);
}
}
@@ -516,7 +515,7 @@ public void sendSlot(int index, Player player) {
@Override
public void sendSlot(int index, Player[] players) {
- ContainerSetSlotPacket pk = new ContainerSetSlotPacket();
+ InventorySlotPacket pk = new InventorySlotPacket();
pk.slot = index;
pk.item = this.getItem(index).clone();
@@ -526,7 +525,7 @@ public void sendSlot(int index, Player[] players) {
this.close(player);
continue;
}
- pk.windowid = (byte) id;
+ pk.inventoryId = (byte) id;
player.dataPacket(pk);
}
}
diff --git a/src/main/java/cn/nukkit/inventory/PlayerInventory.java b/src/main/java/cn/nukkit/inventory/PlayerInventory.java
index 4065f7c76f..9c466ef932 100644
--- a/src/main/java/cn/nukkit/inventory/PlayerInventory.java
+++ b/src/main/java/cn/nukkit/inventory/PlayerInventory.java
@@ -10,10 +10,7 @@
import cn.nukkit.event.player.PlayerItemHeldEvent;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemBlock;
-import cn.nukkit.network.protocol.ContainerSetContentPacket;
-import cn.nukkit.network.protocol.ContainerSetSlotPacket;
-import cn.nukkit.network.protocol.MobArmorEquipmentPacket;
-import cn.nukkit.network.protocol.MobEquipmentPacket;
+import cn.nukkit.network.protocol.*;
import java.util.Collection;
@@ -95,7 +92,7 @@ public void setHeldItemSlot(int slot) {
PlayerItemHeldEvent ev = new PlayerItemHeldEvent((Player) this.getHolder(), item, slot, itemIndex);
Server.getInstance().getPluginManager().callEvent(ev);
if (ev.isCancelled()) {
- this.sendContents((Player) this.getHolder());
+ this.sendHotbarContents();
return;
}
}
@@ -318,9 +315,8 @@ public void sendArmorContents(Player[] players) {
for (Player player : players) {
if (player.equals(this.getHolder())) {
- ContainerSetContentPacket pk2 = new ContainerSetContentPacket();
- pk2.windowid = ContainerSetContentPacket.SPECIAL_ARMOR;
- pk2.eid = player.getId();
+ InventoryContentPacket pk2 = new InventoryContentPacket();
+ pk2.inventoryId = InventoryContentPacket.SPECIAL_ARMOR;
pk2.slots = armor;
player.dataPacket(pk2);
} else {
@@ -368,8 +364,8 @@ public void sendArmorSlot(int index, Player[] players) {
for (Player player : players) {
if (player.equals(this.getHolder())) {
- ContainerSetSlotPacket pk2 = new ContainerSetSlotPacket();
- pk2.windowid = ContainerSetContentPacket.SPECIAL_ARMOR;
+ InventorySlotPacket pk2 = new InventorySlotPacket();
+ pk2.inventoryId = InventoryContentPacket.SPECIAL_ARMOR;
pk2.slot = index - this.getSize();
pk2.item = this.getItem(index);
player.dataPacket(pk2);
@@ -395,36 +391,40 @@ public void sendContents(Collection players) {
@Override
public void sendContents(Player[] players) {
- ContainerSetContentPacket pk = new ContainerSetContentPacket();
- pk.slots = new Item[this.getSize() + + this.getHotbarSize()];
+ InventoryContentPacket pk = new InventoryContentPacket();
+ pk.slots = new Item[this.getSize()];
for (int i = 0; i < this.getSize(); ++i) {
pk.slots[i] = this.getItem(i);
}
//Because PE is stupid and shows 9 less slots than you send it, give it 9 dummy slots so it shows all the REAL slots.
- for(int i = this.getSize(); i < this.getSize() + this.getHotbarSize(); ++i){
- pk.slots[i] = Item.get(Item.AIR, 0, 0);
- }
+ //for(int i = this.getSize(); i < this.getSize() + this.getHotbarSize(); ++i){
+ // pk.slots[i] = Item.get(Item.AIR, 0, 0);
+ //}
for (Player player : players) {
- if (player.equals(this.getHolder())) {
- pk.hotbar = new int[this.getHotbarSize()];
- for (int i = 0; i < this.getHotbarSize(); ++i) {
- int index = this.getHotbarSlotIndex(i);
- pk.hotbar[i] = index <= -1 ? -1 : index + 9;
- }
- }
int id = player.getWindowId(this);
if (id == -1 || !player.spawned) {
this.close(player);
continue;
}
- pk.eid = player.getId();
- pk.windowid = (byte) id;
+ pk.inventoryId = (byte) id;
player.dataPacket(pk.clone());
}
}
+ public void sendHotbarContents() {
+ if (this.getHolder() instanceof Player) {
+ PlayerHotbarPacket playerHotbarPacket = new PlayerHotbarPacket();
+ playerHotbarPacket.data = new int[this.getHotbarSize()];
+ for (int i = 0; i < this.getHotbarSize(); ++i) {
+ int index = this.getHotbarSlotIndex(i);
+ playerHotbarPacket.data[i] = index <= -1 ? -1 : index + 9;
+ }
+ ((Player) holder).dataPacket(playerHotbarPacket);
+ }
+ }
+
@Override
public void sendSlot(int index, Player player) {
this.sendSlot(index, new Player[]{player});
@@ -437,13 +437,13 @@ public void sendSlot(int index, Collection players) {
@Override
public void sendSlot(int index, Player[] players) {
- ContainerSetSlotPacket pk = new ContainerSetSlotPacket();
+ InventorySlotPacket pk = new InventorySlotPacket();
pk.slot = index;
pk.item = this.getItem(index).clone();
for (Player player : players) {
if (player.equals(this.getHolder())) {
- pk.windowid = 0;
+ pk.inventoryId = 0;
player.dataPacket(pk);
} else {
int id = player.getWindowId(this);
@@ -451,7 +451,7 @@ public void sendSlot(int index, Player[] players) {
this.close(player);
continue;
}
- pk.windowid = (byte) id;
+ pk.inventoryId = (byte) id;
player.dataPacket(pk.clone());
}
}
diff --git a/src/main/java/cn/nukkit/inventory/TransactionGroup.java b/src/main/java/cn/nukkit/inventory/TransactionGroup.java
deleted file mode 100644
index 5e71cf53a2..0000000000
--- a/src/main/java/cn/nukkit/inventory/TransactionGroup.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package cn.nukkit.inventory;
-
-import java.util.Set;
-
-/**
- * author: MagicDroidX
- * Nukkit Project
- */
-public interface TransactionGroup {
-
- long getCreationTime();
-
- Set getTransactions();
-
- Set getInventories();
-
- void addTransaction(Transaction transaction);
-
- boolean canExecute();
-
- boolean execute();
-
- boolean execute(boolean force);
-
- boolean hasExecuted();
-}
diff --git a/src/main/java/cn/nukkit/inventory/BaseTransaction.java b/src/main/java/cn/nukkit/inventory/transaction/BaseTransaction.java
similarity index 59%
rename from src/main/java/cn/nukkit/inventory/BaseTransaction.java
rename to src/main/java/cn/nukkit/inventory/transaction/BaseTransaction.java
index 855a920e0d..181f94e209 100644
--- a/src/main/java/cn/nukkit/inventory/BaseTransaction.java
+++ b/src/main/java/cn/nukkit/inventory/transaction/BaseTransaction.java
@@ -1,4 +1,4 @@
-package cn.nukkit.inventory;
+package cn.nukkit.inventory.transaction;
import cn.nukkit.item.Item;
@@ -6,9 +6,7 @@
* author: MagicDroidX
* Nukkit Project
*/
-public class BaseTransaction implements Transaction {
-
- protected final Inventory inventory;
+public abstract class BaseTransaction implements Transaction {
protected final int slot;
@@ -16,14 +14,12 @@ public class BaseTransaction implements Transaction {
protected final Item targetItem;
- protected final long creationTime;
+ protected final long creationTime = System.currentTimeMillis();
- public BaseTransaction(Inventory inventory, int slot, Item sourceItem, Item targetItem) {
- this.inventory = inventory;
+ BaseTransaction(int slot, Item sourceItem, Item targetItem) {
this.slot = slot;
this.sourceItem = sourceItem.clone();
this.targetItem = targetItem.clone();
- this.creationTime = System.currentTimeMillis();
}
@Override
@@ -31,11 +27,6 @@ public long getCreationTime() {
return creationTime;
}
- @Override
- public Inventory getInventory() {
- return inventory;
- }
-
@Override
public int getSlot() {
return slot;
diff --git a/src/main/java/cn/nukkit/inventory/transaction/BaseTransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/BaseTransactionGroup.java
new file mode 100644
index 0000000000..763c83c804
--- /dev/null
+++ b/src/main/java/cn/nukkit/inventory/transaction/BaseTransactionGroup.java
@@ -0,0 +1,47 @@
+package cn.nukkit.inventory.transaction;
+
+import cn.nukkit.Player;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * author: MagicDroidX
+ * Nukkit Project
+ */
+public abstract class BaseTransactionGroup implements TransactionGroup {
+
+ private final long creationTime = System.currentTimeMillis();
+ protected boolean hasExecuted = false;
+
+ protected final Set transactions = new HashSet<>();
+
+ @Override
+ public long getCreationTime() {
+ return creationTime;
+ }
+
+ @Override
+ public Set getTransactions() {
+ return transactions;
+ }
+
+ @Override
+ public void addTransaction(Transaction transaction) {
+ if (this.transactions.contains(transaction)) {
+ return;
+ }
+
+ this.transactions.add(transaction);
+ }
+
+ @Override
+ public boolean executeOn(Player player) {
+ return executeOn(player, false);
+ }
+
+ @Override
+ public boolean hasExecuted() {
+ return this.hasExecuted;
+ }
+}
diff --git a/src/main/java/cn/nukkit/inventory/transaction/ContainerTransaction.java b/src/main/java/cn/nukkit/inventory/transaction/ContainerTransaction.java
new file mode 100644
index 0000000000..c869918f3d
--- /dev/null
+++ b/src/main/java/cn/nukkit/inventory/transaction/ContainerTransaction.java
@@ -0,0 +1,28 @@
+package cn.nukkit.inventory.transaction;
+
+import cn.nukkit.Player;
+import cn.nukkit.inventory.Inventory;
+import cn.nukkit.item.Item;
+
+public class ContainerTransaction extends BaseTransaction {
+
+ private int inventoryId;
+
+ public ContainerTransaction(int inventoryId, int slot, Item sourceItem, Item targetItem) {
+ super(slot, sourceItem, targetItem);
+ this.inventoryId = inventoryId;
+ }
+
+ public Inventory getInventory(Player player) {
+ return player.getWindowById(inventoryId);
+ }
+
+ public int getInventoryId() {
+ return inventoryId;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_CONTAINER;
+ }
+}
diff --git a/src/main/java/cn/nukkit/inventory/transaction/CraftTransaction.java b/src/main/java/cn/nukkit/inventory/transaction/CraftTransaction.java
new file mode 100644
index 0000000000..6c88bd4bf3
--- /dev/null
+++ b/src/main/java/cn/nukkit/inventory/transaction/CraftTransaction.java
@@ -0,0 +1,22 @@
+package cn.nukkit.inventory.transaction;
+
+import cn.nukkit.item.Item;
+
+public class CraftTransaction extends BaseTransaction {
+
+ private final int action;
+
+ public CraftTransaction(int action, int slot, Item sourceItem, Item targetItem) {
+ super(slot, sourceItem, targetItem);
+ this.action = action;
+ }
+
+ public int getAction() {
+ return action;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_CRAFT;
+ }
+}
diff --git a/src/main/java/cn/nukkit/inventory/transaction/CreativeTransaction.java b/src/main/java/cn/nukkit/inventory/transaction/CreativeTransaction.java
new file mode 100644
index 0000000000..63d2ab97bb
--- /dev/null
+++ b/src/main/java/cn/nukkit/inventory/transaction/CreativeTransaction.java
@@ -0,0 +1,15 @@
+package cn.nukkit.inventory.transaction;
+
+import cn.nukkit.item.Item;
+
+public class CreativeTransaction extends BaseTransaction {
+
+ public CreativeTransaction(int slot, Item sourceItem, Item targetItem) {
+ super(slot, sourceItem, targetItem);
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_CREATIVE;
+ }
+}
diff --git a/src/main/java/cn/nukkit/inventory/transaction/GlobalTransaction.java b/src/main/java/cn/nukkit/inventory/transaction/GlobalTransaction.java
new file mode 100644
index 0000000000..7df1f6912d
--- /dev/null
+++ b/src/main/java/cn/nukkit/inventory/transaction/GlobalTransaction.java
@@ -0,0 +1,15 @@
+package cn.nukkit.inventory.transaction;
+
+import cn.nukkit.item.Item;
+
+public class GlobalTransaction extends BaseTransaction {
+
+ public GlobalTransaction(int slot, Item sourceItem, Item targetItem) {
+ super(slot, sourceItem, targetItem);
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_GLOBAL;
+ }
+}
diff --git a/src/main/java/cn/nukkit/inventory/transaction/InventoryMismatchTransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/InventoryMismatchTransactionGroup.java
new file mode 100644
index 0000000000..b0c687b574
--- /dev/null
+++ b/src/main/java/cn/nukkit/inventory/transaction/InventoryMismatchTransactionGroup.java
@@ -0,0 +1,21 @@
+package cn.nukkit.inventory.transaction;
+
+import cn.nukkit.Player;
+
+public class InventoryMismatchTransactionGroup extends BaseTransactionGroup {
+
+ @Override
+ public boolean executeOn(Player player, boolean force) {
+ return false;
+ }
+
+ @Override
+ public boolean canExecute(Player player) {
+ return false;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_INVENTORY_MISMATCH;
+ }
+}
diff --git a/src/main/java/cn/nukkit/inventory/transaction/ItemReleaseTransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/ItemReleaseTransactionGroup.java
new file mode 100644
index 0000000000..bbfe7ab038
--- /dev/null
+++ b/src/main/java/cn/nukkit/inventory/transaction/ItemReleaseTransactionGroup.java
@@ -0,0 +1,193 @@
+package cn.nukkit.inventory.transaction;
+
+import cn.nukkit.Player;
+import cn.nukkit.Server;
+import cn.nukkit.block.BlockAir;
+import cn.nukkit.entity.projectile.EntityArrow;
+import cn.nukkit.entity.projectile.EntityProjectile;
+import cn.nukkit.event.entity.EntityShootBowEvent;
+import cn.nukkit.event.entity.ProjectileLaunchEvent;
+import cn.nukkit.event.player.PlayerDropItemEvent;
+import cn.nukkit.inventory.PlayerInventory;
+import cn.nukkit.item.Item;
+import cn.nukkit.item.ItemArrow;
+import cn.nukkit.item.ItemBlock;
+import cn.nukkit.item.enchantment.Enchantment;
+import cn.nukkit.level.sound.LaunchSound;
+import cn.nukkit.math.Vector3;
+import cn.nukkit.math.Vector3f;
+import cn.nukkit.nbt.tag.CompoundTag;
+import cn.nukkit.nbt.tag.DoubleTag;
+import cn.nukkit.nbt.tag.FloatTag;
+import cn.nukkit.nbt.tag.ListTag;
+
+import java.util.Random;
+
+public class ItemReleaseTransactionGroup extends BaseTransactionGroup {
+
+ private final int action;
+ private final int slot;
+ private final Item item;
+ private final Vector3f playerPos;
+
+ public ItemReleaseTransactionGroup(int action, int slot, Item item, Vector3f playerPos) {
+ this.action = action;
+ this.slot = slot;
+ this.item = item;
+ this.playerPos = playerPos;
+ }
+
+ @Override
+ public boolean executeOn(Player player, boolean force) {
+ if (this.hasExecuted || (!force && !this.canExecute(player))) {
+ return false;
+ }
+ player.craftingType = Player.CRAFTING_SMALL;
+ PlayerInventory inventory = player.getInventory();
+
+ switch (this.action) {
+ case ITEM_RELEASE_ACTION_RELEASE:
+ if (item.getId() <= 0) {
+ return false;
+ }
+
+ Item i = (player.isCreative() || inventory.contains(item)) ? item : inventory.getItemInHand();
+ PlayerDropItemEvent dropItemEvent = new PlayerDropItemEvent(player, i);
+ Server.getInstance().getPluginManager().callEvent(dropItemEvent);
+ if (dropItemEvent.isCancelled()) {
+ inventory.sendContents(player);
+ return false;
+ }
+
+ if (!player.isCreative()) {
+ inventory.removeItem(i);
+ }
+ Vector3 motion = player.getDirectionVector().multiply(0.4);
+
+ player.level.dropItem(player.add(0, 1.3, 0), i, motion, 40);
+
+ player.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, false);
+ break;
+ case ITEM_RELEASE_ACTION_USE:
+ if (player.getStartActionTick() > -1 && player.getDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION)) {
+ if (inventory.getItemInHand().getId() == Item.BOW) {
+
+ Item bow = inventory.getItemInHand();
+ ItemArrow itemArrow = new ItemArrow();
+ if (player.isSurvival() && !inventory.contains(itemArrow)) {
+ inventory.sendContents(player);
+ break;
+ }
+
+ double damage = 2;
+ boolean flame = false;
+
+ if (bow.hasEnchantments()) {
+ Enchantment bowDamage = bow.getEnchantment(Enchantment.ID_BOW_POWER);
+
+ if (bowDamage != null && bowDamage.getLevel() > 0) {
+ damage += 0.25 * (bowDamage.getLevel() + 1);
+ }
+
+ Enchantment flameEnchant = bow.getEnchantment(Enchantment.ID_BOW_FLAME);
+ flame = flameEnchant != null && flameEnchant.getLevel() > 0;
+ }
+
+ CompoundTag nbt = new CompoundTag()
+ .putList(new ListTag("Pos")
+ .add(new DoubleTag("", player.x))
+ .add(new DoubleTag("", player.y + player.getEyeHeight()))
+ .add(new DoubleTag("", player.z)))
+ .putList(new ListTag("Motion")
+ .add(new DoubleTag("", -Math.sin(player.yaw / 180 * Math.PI) * Math.cos(player.pitch / 180 * Math.PI)))
+ .add(new DoubleTag("", -Math.sin(player.pitch / 180 * Math.PI)))
+ .add(new DoubleTag("", Math.cos(player.yaw / 180 * Math.PI) * Math.cos(player.pitch / 180 * Math.PI))))
+ .putList(new ListTag("Rotation")
+ .add(new FloatTag("", (player.yaw > 180 ? 360 : 0) - (float) player.yaw))
+ .add(new FloatTag("", (float) -player.pitch)))
+ .putShort("Fire", player.isOnFire() || flame ? 45 * 60 : 0)
+ .putDouble("damage", damage);
+
+ int diff = (Server.getInstance().getTick() - player.getStartActionTick());
+ double p = (double) diff / 20;
+
+ double f = Math.min((p * p + p * 2) / 3, 1) * 2;
+ EntityShootBowEvent entityShootBowEvent = new EntityShootBowEvent(player, bow, new EntityArrow(player.chunk, nbt, player, f == 2), f);
+
+ if (f < 0.1 || diff < 5) {
+ entityShootBowEvent.setCancelled();
+ }
+
+ Server.getInstance().getPluginManager().callEvent(entityShootBowEvent);
+ if (entityShootBowEvent.isCancelled()) {
+ entityShootBowEvent.getProjectile().kill();
+ inventory.sendContents(player);
+ } else {
+ entityShootBowEvent.getProjectile().setMotion(entityShootBowEvent.getProjectile().getMotion().multiply(entityShootBowEvent.getForce()));
+ if (player.isSurvival()) {
+ Enchantment infinity;
+
+ if (!bow.hasEnchantments() || (infinity = bow.getEnchantment(Enchantment.ID_BOW_INFINITY)) == null || infinity.getLevel() <= 0)
+ inventory.removeItem(itemArrow);
+
+ if (!bow.isUnbreakable()) {
+ Enchantment durability = bow.getEnchantment(Enchantment.ID_DURABILITY);
+ if (!(durability != null && durability.getLevel() > 0 && (100 / (durability.getLevel() + 1)) <= new Random().nextInt(100))) {
+ bow.setDamage(bow.getDamage() + 1);
+ if (bow.getDamage() >= 385) {
+ inventory.setItemInHand(new ItemBlock(new BlockAir(), 0, 0));
+ } else {
+ inventory.setItemInHand(bow);
+ }
+ }
+ }
+ }
+ if (entityShootBowEvent.getProjectile() instanceof EntityProjectile) {
+ ProjectileLaunchEvent projectev = new ProjectileLaunchEvent(entityShootBowEvent.getProjectile());
+ Server.getInstance().getPluginManager().callEvent(projectev);
+ if (projectev.isCancelled()) {
+ entityShootBowEvent.getProjectile().kill();
+ } else {
+ entityShootBowEvent.getProjectile().spawnToAll();
+ player.level.addSound(new LaunchSound(player), player.getViewers().values());
+ }
+ } else {
+ entityShootBowEvent.getProjectile().spawnToAll();
+ }
+ }
+ }
+ }
+ //milk removed here, see the section of food
+ player.stopAction();
+ player.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, false);
+ break;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean canExecute(Player player) {
+ return player.spawned && player.isAlive();
+ }
+
+ public int getAction() {
+ return action;
+ }
+
+ public int getSlot() {
+ return slot;
+ }
+
+ public Item getItem() {
+ return item;
+ }
+
+ public Vector3f getPlayerPos() {
+ return playerPos;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_ITEM_RELEASE;
+ }
+}
diff --git a/src/main/java/cn/nukkit/inventory/transaction/ItemUseOnEntityTransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/ItemUseOnEntityTransactionGroup.java
new file mode 100644
index 0000000000..f5ac454492
--- /dev/null
+++ b/src/main/java/cn/nukkit/inventory/transaction/ItemUseOnEntityTransactionGroup.java
@@ -0,0 +1,57 @@
+package cn.nukkit.inventory.transaction;
+
+import cn.nukkit.Player;
+import cn.nukkit.item.Item;
+import cn.nukkit.math.Vector3f;
+
+public class ItemUseOnEntityTransactionGroup extends BaseTransactionGroup {
+
+ private final long entityId;
+ private final int action;
+ private final int slot;
+ private final Item item;
+ private final Vector3f playerPos;
+
+ public ItemUseOnEntityTransactionGroup(long entityId, int action, int slot, Item item, Vector3f playerPos) {
+ this.entityId = entityId;
+ this.action = action;
+ this.slot = slot;
+ this.item = item;
+ this.playerPos = playerPos;
+ }
+
+ @Override
+ public boolean executeOn(Player player, boolean force) {
+ return false;
+ }
+
+ @Override
+ public boolean canExecute(Player player) {
+ return false;
+ }
+
+ public long getEntityId() {
+ return entityId;
+ }
+
+ public int getAction() {
+ return action;
+ }
+
+ public int getSlot() {
+ return slot;
+ }
+
+ public Item getItem() {
+ return item;
+ }
+
+ public Vector3f getPlayerPos() {
+ return playerPos;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_ITEM_USE_ON_ENTITY;
+ }
+}
diff --git a/src/main/java/cn/nukkit/inventory/transaction/ItemUseTransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/ItemUseTransactionGroup.java
new file mode 100644
index 0000000000..7e18bea291
--- /dev/null
+++ b/src/main/java/cn/nukkit/inventory/transaction/ItemUseTransactionGroup.java
@@ -0,0 +1,385 @@
+package cn.nukkit.inventory.transaction;
+
+import cn.nukkit.Player;
+import cn.nukkit.Server;
+import cn.nukkit.block.Block;
+import cn.nukkit.block.BlockDoor;
+import cn.nukkit.blockentity.BlockEntity;
+import cn.nukkit.blockentity.BlockEntitySpawnable;
+import cn.nukkit.entity.Entity;
+import cn.nukkit.entity.item.EntityExpBottle;
+import cn.nukkit.entity.item.EntityPotion;
+import cn.nukkit.entity.projectile.EntityEgg;
+import cn.nukkit.entity.projectile.EntityEnderPearl;
+import cn.nukkit.entity.projectile.EntityProjectile;
+import cn.nukkit.entity.projectile.EntitySnowball;
+import cn.nukkit.event.entity.ProjectileLaunchEvent;
+import cn.nukkit.event.player.PlayerInteractEvent;
+import cn.nukkit.inventory.PlayerInventory;
+import cn.nukkit.item.Item;
+import cn.nukkit.level.sound.LaunchSound;
+import cn.nukkit.math.BlockFace;
+import cn.nukkit.math.BlockVector3;
+import cn.nukkit.math.Vector3;
+import cn.nukkit.math.Vector3f;
+import cn.nukkit.nbt.tag.CompoundTag;
+import cn.nukkit.nbt.tag.DoubleTag;
+import cn.nukkit.nbt.tag.FloatTag;
+import cn.nukkit.nbt.tag.ListTag;
+import cn.nukkit.network.protocol.UpdateBlockPacket;
+
+public class ItemUseTransactionGroup extends BaseTransactionGroup {
+
+ private final int action;
+ private final BlockVector3 blockPos;
+ private final int face;
+ private final int slot;
+ private final Item item;
+ private final Vector3f playerPos;
+ private final Vector3f clickPos;
+
+ public ItemUseTransactionGroup(int action, BlockVector3 blockPos, int face, int slot, Item item, Vector3f playerPos, Vector3f clickPos) {
+ this.action = action;
+ this.blockPos = blockPos;
+ this.face = face;
+ this.slot = slot;
+ this.item = item;
+ this.playerPos = playerPos;
+ this.clickPos = clickPos;
+ }
+
+ @Override
+ public boolean executeOn(Player player, boolean force) {
+ if (this.hasExecuted || (!force && !this.canExecute(player))) {
+ return false;
+ }
+
+ player.craftingType = Player.CRAFTING_SMALL;
+
+ player.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, false);
+
+ Vector3 blockVector = new Vector3(blockPos.x, blockPos.y, blockPos.z);
+ PlayerInventory inventory = player.getInventory();
+ BlockFace face;
+
+ switch (this.action) {
+ case ITEM_USE_ACTION_PLACE:
+ face = BlockFace.fromIndex(this.face);
+ if (player.canInteract(blockVector.add(0.5, 0.5, 0.5), player.isCreative() ? 13 : 7)) {
+ if (player.isCreative()) {
+ Item i = inventory.getItemInHand();
+ if (player.level.usePlaceOn(blockVector, i, face, clickPos.x, clickPos.y, clickPos.z, player) != null) {
+ return true;
+ }
+ } else if (inventory.getItemInHand().deepEquals(item)) {
+ Item i = inventory.getItemInHand();
+ Item oldItem = i.clone();
+ //TODO: Implement adventure mode checks
+ if ((i = player.level.usePlaceOn(blockVector, i, face, clickPos.x, clickPos.y, clickPos.z, player)) != null) {
+ if (!i.deepEquals(oldItem) || i.getCount() != oldItem.getCount()) {
+ inventory.setItemInHand(i);
+ inventory.sendHeldItem(player.getViewers().values());
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+
+ case ITEM_USE_ACTION_USE:
+ if (this.face >= 0 && this.face <= 5) {
+ face = BlockFace.fromIndex(this.face);
+ if (player.canInteract(blockVector.add(0.5, 0.5, 0.5), player.isCreative() ? 13 : 7)) {
+ if (player.isCreative()) {
+ Item i = inventory.getItemInHand();
+ if (player.level.useItemOn(blockVector, i, face, clickPos.x, clickPos.y, clickPos.z, player) != null) {
+ return true;
+ }
+ } else if (inventory.getItemInHand().deepEquals(item)) {
+ Item i = inventory.getItemInHand();
+ Item oldItem = i.clone();
+ //TODO: Implement adventure mode checks
+ if ((i = player.level.useItemOn(blockVector, i, face, clickPos.x, clickPos.y, clickPos.z, player)) != null) {
+ if (!i.deepEquals(oldItem) || i.getCount() != oldItem.getCount()) {
+ inventory.setItemInHand(i);
+ inventory.sendHeldItem(player.getViewers().values());
+ }
+ return true;
+ }
+ }
+ }
+
+ inventory.sendHeldItem(player);
+
+ if (blockVector.distanceSquared(player) > 10000) {
+ return false;
+ }
+
+ Block target = player.level.getBlock(blockVector);
+ Block block = target.getSide(face);
+
+ if (target instanceof BlockDoor) {
+ BlockDoor door = (BlockDoor) target;
+
+ Block part;
+
+ if ((door.getDamage() & 0x08) > 0) { //up
+ part = target.down();
+
+ if (part.getId() == target.getId()) {
+ target = part;
+ }
+ }
+ player.level.sendBlocks(new Player[]{player}, new Block[]{target, block}, UpdateBlockPacket.FLAG_ALL_PRIORITY);
+ }
+ } else if (this.face == -1) {
+ Vector3 aimPos = new Vector3(
+ -Math.sin(player.yaw / 180d * Math.PI) * Math.cos(player.pitch / 180d * Math.PI),
+ -Math.sin(player.pitch / 180d * Math.PI),
+ Math.cos(player.yaw / 180d * Math.PI) * Math.cos(player.pitch / 180d * Math.PI)
+ );
+
+ Item i;
+ if (player.isCreative() || inventory.getItemInHand().deepEquals(item)) {
+ i = inventory.getItemInHand();
+ } else {
+ inventory.sendHeldItem(player);
+ return false;
+ }
+
+ PlayerInteractEvent playerInteractEvent = new PlayerInteractEvent(player, i, aimPos, null, PlayerInteractEvent.Action.RIGHT_CLICK_AIR);
+
+ Server.getInstance().getPluginManager().callEvent(playerInteractEvent);
+
+ if (playerInteractEvent.isCancelled()) {
+ inventory.sendHeldItem(player);
+ return false;
+ }
+
+ if (i.getId() == Item.SNOWBALL) {
+ CompoundTag nbt = new CompoundTag()
+ .putList(new ListTag("Pos")
+ .add(new DoubleTag("", player.x))
+ .add(new DoubleTag("", player.y + player.getEyeHeight()))
+ .add(new DoubleTag("", player.z)))
+ .putList(new ListTag("Motion")
+ .add(new DoubleTag("", -Math.sin(player.yaw / 180 * Math.PI) * Math.cos(player.pitch / 180 * Math.PI)))
+ .add(new DoubleTag("", -Math.sin(player.pitch / 180 * Math.PI)))
+ .add(new DoubleTag("", Math.cos(player.yaw / 180 * Math.PI) * Math.cos(player.pitch / 180 * Math.PI))))
+ .putList(new ListTag("Rotation")
+ .add(new FloatTag("", (float) player.yaw))
+ .add(new FloatTag("", (float) player.pitch)));
+
+ float f = 1.5f;
+ EntitySnowball snowball = new EntitySnowball(player.chunk, nbt, player);
+
+ snowball.setMotion(snowball.getMotion().multiply(f));
+ if (player.isSurvival()) {
+ i.setCount(i.getCount() - 1);
+ inventory.setItemInHand(i.getCount() > 0 ? i : Item.get(Item.AIR));
+ }
+ ProjectileLaunchEvent projectileLaunchEvent = new ProjectileLaunchEvent(snowball);
+ Server.getInstance().getPluginManager().callEvent(projectileLaunchEvent);
+ if (projectileLaunchEvent.isCancelled()) {
+ snowball.kill();
+ } else {
+ snowball.spawnToAll();
+ player.level.addSound(new LaunchSound(player), player.getViewers().values());
+ }
+ } else if (i.getId() == Item.EGG) {
+ CompoundTag nbt = new CompoundTag()
+ .putList(new ListTag("Pos")
+ .add(new DoubleTag("", player.x))
+ .add(new DoubleTag("", player.y + player.getEyeHeight()))
+ .add(new DoubleTag("", player.z)))
+ .putList(new ListTag("Motion")
+ .add(new DoubleTag("", -Math.sin(player.yaw / 180 * Math.PI) * Math.cos(player.pitch / 180 * Math.PI)))
+ .add(new DoubleTag("", -Math.sin(player.pitch / 180 * Math.PI)))
+ .add(new DoubleTag("", Math.cos(player.yaw / 180 * Math.PI) * Math.cos(player.pitch / 180 * Math.PI))))
+ .putList(new ListTag("Rotation")
+ .add(new FloatTag("", (float) player.yaw))
+ .add(new FloatTag("", (float) player.pitch)));
+
+ float f = 1.5f;
+ EntityEgg egg = new EntityEgg(player.chunk, nbt, player);
+
+ egg.setMotion(egg.getMotion().multiply(f));
+ if (player.isSurvival()) {
+ i.setCount(i.getCount() - 1);
+ inventory.setItemInHand(i.getCount() > 0 ? i : Item.get(Item.AIR));
+ }
+ ProjectileLaunchEvent projectileLaunchEvent = new ProjectileLaunchEvent(egg);
+ Server.getInstance().getPluginManager().callEvent(projectileLaunchEvent);
+ if (projectileLaunchEvent.isCancelled()) {
+ egg.kill();
+ } else {
+ egg.spawnToAll();
+ player.level.addSound(new LaunchSound(player), player.getViewers().values());
+ }
+ } else if (i.getId() == Item.ENDER_PEARL && (Server.getInstance().getTick() - player.getLastEnderPearlThrowingTick()) >= 20) {
+ CompoundTag nbt = new CompoundTag()
+ .putList(new ListTag("Pos")
+ .add(new DoubleTag("", player.x))
+ .add(new DoubleTag("", player.y + player.getEyeHeight()))
+ .add(new DoubleTag("", player.z)))
+ .putList(new ListTag("Motion")
+ .add(new DoubleTag("", -Math.sin(player.yaw / 180 * Math.PI) * Math.cos(player.pitch / 180 * Math.PI)))
+ .add(new DoubleTag("", -Math.sin(player.pitch / 180 * Math.PI)))
+ .add(new DoubleTag("", Math.cos(player.yaw / 180 * Math.PI) * Math.cos(player.pitch / 180 * Math.PI))))
+ .putList(new ListTag("Rotation")
+ .add(new FloatTag("", (float) player.yaw))
+ .add(new FloatTag("", (float) player.pitch)));
+
+ float f = 1.5f;
+ EntityEnderPearl enderPearl = new EntityEnderPearl(player.chunk, nbt, player);
+
+ enderPearl.setMotion(enderPearl.getMotion().multiply(f));
+ if (player.isSurvival()) {
+ i.setCount(i.getCount() - 1);
+ inventory.setItemInHand(i.getCount() > 0 ? i : Item.get(Item.AIR));
+ }
+ ProjectileLaunchEvent projectileLaunchEvent = new ProjectileLaunchEvent(enderPearl);
+ Server.getInstance().getPluginManager().callEvent(projectileLaunchEvent);
+ if (projectileLaunchEvent.isCancelled()) {
+ enderPearl.kill();
+ } else {
+ enderPearl.spawnToAll();
+ player.level.addSound(new LaunchSound(player), player.getViewers().values());
+ }
+ player.onThrowEnderPearl();
+ } else if (i.getId() == Item.EXPERIENCE_BOTTLE) {
+ CompoundTag nbt = new CompoundTag()
+ .putList(new ListTag("Pos")
+ .add(new DoubleTag("", player.x))
+ .add(new DoubleTag("", player.y + player.getEyeHeight()))
+ .add(new DoubleTag("", player.z)))
+ .putList(new ListTag("Motion")
+ .add(new DoubleTag("", -Math.sin(player.yaw / 180 * Math.PI) * Math.cos(player.pitch / 180 * Math.PI)))
+ .add(new DoubleTag("", -Math.sin(player.pitch / 180 * Math.PI)))
+ .add(new DoubleTag("", Math.cos(player.yaw / 180 * Math.PI) * Math.cos(player.pitch / 180 * Math.PI))))
+ .putList(new ListTag("Rotation")
+ .add(new FloatTag("", (float) player.yaw))
+ .add(new FloatTag("", (float) player.pitch)))
+ .putInt("Potion", i.getDamage());
+ double f = 1.5;
+ Entity bottle = new EntityExpBottle(player.chunk, nbt, player);
+ bottle.setMotion(bottle.getMotion().multiply(f));
+ if (player.isSurvival()) {
+ i.setCount(i.getCount() - 1);
+ inventory.setItemInHand(i.getCount() > 0 ? i : Item.get(Item.AIR));
+ }
+ EntityProjectile bottleEntity = (EntityProjectile) bottle;
+ ProjectileLaunchEvent projectileEv = new ProjectileLaunchEvent(bottleEntity);
+ Server.getInstance().getPluginManager().callEvent(projectileEv);
+ if (projectileEv.isCancelled()) {
+ bottle.kill();
+ } else {
+ bottle.spawnToAll();
+ player.level.addSound(new LaunchSound(player), player.getViewers().values());
+ }
+ } else if (i.getId() == Item.SPLASH_POTION) {
+ CompoundTag nbt = new CompoundTag()
+ .putList(new ListTag("Pos")
+ .add(new DoubleTag("", player.x))
+ .add(new DoubleTag("", player.y + player.getEyeHeight()))
+ .add(new DoubleTag("", player.z)))
+ .putList(new ListTag("Motion")
+ .add(new DoubleTag("", -Math.sin(player.yaw / 180 * Math.PI) * Math.cos(player.pitch / 180 * Math.PI)))
+ .add(new DoubleTag("", -Math.sin(player.pitch / 180 * Math.PI)))
+ .add(new DoubleTag("", Math.cos(player.yaw / 180 * Math.PI) * Math.cos(player.pitch / 180 * Math.PI))))
+ .putList(new ListTag("Rotation")
+ .add(new FloatTag("", (float) player.yaw))
+ .add(new FloatTag("", (float) player.pitch)))
+ .putShort("PotionId", i.getDamage());
+ double f = 1.5;
+ Entity bottle = new EntityPotion(player.chunk, nbt, player);
+ bottle.setMotion(bottle.getMotion().multiply(f));
+ if (player.isSurvival()) {
+ i.setCount(i.getCount() - 1);
+ inventory.setItemInHand(i.getCount() > 0 ? i : Item.get(Item.AIR));
+ }
+ EntityPotion bottleEntity = (EntityPotion) bottle;
+ ProjectileLaunchEvent projectileEv = new ProjectileLaunchEvent(bottleEntity);
+ Server.getInstance().getPluginManager().callEvent(projectileEv);
+ if (projectileEv.isCancelled()) {
+ bottle.kill();
+ } else {
+ bottle.spawnToAll();
+ player.level.addSound(new LaunchSound(player), player.getViewers().values());
+ }
+ }
+ player.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, true);
+ player.startAction();
+ }
+ break;
+
+ case ITEM_USE_ACTION_DESTROY:
+ Item i = player.getInventory().getItemInHand();
+
+ Item oldItem = i.clone();
+
+ if (player.canInteract(blockVector.add(0.5, 0.5, 0.5), player.isCreative() ? 13 : 7) && (i = player.level.useBreakOn(blockVector, i, player, true)) != null) {
+ if (player.isSurvival()) {
+ player.getFoodData().updateFoodExpLevel(0.025);
+ if (!i.deepEquals(oldItem) || i.getCount() != oldItem.getCount()) {
+ inventory.setItemInHand(i);
+ inventory.sendHeldItem(player.getViewers().values());
+ }
+ }
+ return true;
+ }
+
+ inventory.sendContents(player);
+ Block target = player.level.getBlock(blockVector);
+ BlockEntity blockEntity = player.level.getBlockEntity(blockVector);
+
+ player.level.sendBlocks(new Player[]{player}, new Block[]{target}, UpdateBlockPacket.FLAG_ALL_PRIORITY);
+
+ inventory.sendHeldItem(player);
+
+ if (blockEntity instanceof BlockEntitySpawnable) {
+ ((BlockEntitySpawnable) blockEntity).spawnTo(player);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean canExecute(Player player) {
+ return player.spawned && player.isAlive();
+ }
+
+ public int getAction() {
+ return action;
+ }
+
+ public BlockVector3 getBlockPos() {
+ return blockPos;
+ }
+
+ public int getFace() {
+ return face;
+ }
+
+ public int getSlot() {
+ return slot;
+ }
+
+ public Item getItem() {
+ return item;
+ }
+
+ public Vector3f getPlayerPos() {
+ return playerPos;
+ }
+
+ public Vector3f getClickPos() {
+ return clickPos;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_ITEM_USE;
+ }
+}
diff --git a/src/main/java/cn/nukkit/inventory/SimpleTransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/NormalTransactionGroup.java
similarity index 50%
rename from src/main/java/cn/nukkit/inventory/SimpleTransactionGroup.java
rename to src/main/java/cn/nukkit/inventory/transaction/NormalTransactionGroup.java
index fb3f78100b..9b8a0e6a27 100644
--- a/src/main/java/cn/nukkit/inventory/SimpleTransactionGroup.java
+++ b/src/main/java/cn/nukkit/inventory/transaction/NormalTransactionGroup.java
@@ -1,57 +1,17 @@
-package cn.nukkit.inventory;
+package cn.nukkit.inventory.transaction;
import cn.nukkit.Player;
import cn.nukkit.Server;
import cn.nukkit.event.inventory.InventoryTransactionEvent;
+import cn.nukkit.inventory.Inventory;
+import cn.nukkit.inventory.PlayerInventory;
import cn.nukkit.item.Item;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
-import java.util.Set;
-/**
- * author: MagicDroidX
- * Nukkit Project
- */
-public class SimpleTransactionGroup implements TransactionGroup {
-
- private final long creationTime;
- protected boolean hasExecuted = false;
-
- protected Player source = null;
-
- protected final Set inventories = new HashSet<>();
-
- protected final Set transactions = new HashSet<>();
-
- public SimpleTransactionGroup() {
- this(null);
- }
-
- public SimpleTransactionGroup(Player source) {
- this.creationTime = System.currentTimeMillis();
- this.source = source;
- }
-
- public Player getSource() {
- return source;
- }
-
- @Override
- public long getCreationTime() {
- return creationTime;
- }
-
- @Override
- public Set getInventories() {
- return inventories;
- }
-
- @Override
- public Set getTransactions() {
- return transactions;
- }
+public class NormalTransactionGroup extends BaseTransactionGroup {
@Override
public void addTransaction(Transaction transaction) {
@@ -60,7 +20,10 @@ public void addTransaction(Transaction transaction) {
}
for (Transaction tx : new HashSet<>(this.transactions)) {
- if (tx.getInventory().equals(transaction.getInventory()) && tx.getSlot() == transaction.getSlot()) {
+ if (tx.getType() == Transaction.TYPE_CONTAINER
+ && transaction.getType() == Transaction.TYPE_CONTAINER
+ && ((ContainerTransaction) tx).getInventoryId() == ((ContainerTransaction) transaction).getInventoryId()
+ && tx.getSlot() == transaction.getSlot()) {
if (transaction.getCreationTime() >= tx.getCreationTime()) {
this.transactions.remove(tx);
} else {
@@ -70,18 +33,22 @@ public void addTransaction(Transaction transaction) {
}
this.transactions.add(transaction);
- this.inventories.add(transaction.getInventory());
}
- protected boolean matchItems(List- needItems, List
- haveItems) {
+ protected boolean matchItems(Player player) {
+ List
- haveItems = new ArrayList<>();
+ List
- needItems = new ArrayList<>();
+
for (Transaction ts : this.transactions) {
if (ts.getTargetItem().getId() != Item.AIR) {
needItems.add(ts.getTargetItem());
}
- Item checkSourceItem = ts.getInventory().getItem(ts.getSlot());
Item sourceItem = ts.getSourceItem();
- if (!checkSourceItem.deepEquals(sourceItem) || sourceItem.getCount() != checkSourceItem.getCount()) {
- return false;
+ if (ts.getType() == Transaction.TYPE_CONTAINER) {
+ Item checkSourceItem = ((ContainerTransaction) ts).getInventory(player).getItem(ts.getSlot());
+ if (!checkSourceItem.deepEquals(sourceItem) || sourceItem.getCount() != checkSourceItem.getCount()) {
+ return false;
+ }
}
if (sourceItem.getId() != Item.AIR) {
haveItems.add(sourceItem);
@@ -105,42 +72,40 @@ protected boolean matchItems(List
- needItems, List
- haveItems) {
}
}
- return true;
- }
-
- @Override
- public boolean canExecute() {
- List
- haveItems = new ArrayList<>();
- List
- needItems = new ArrayList<>();
-
- return this.matchItems(needItems, haveItems) && haveItems.isEmpty() && needItems.isEmpty() && !this.transactions.isEmpty();
+ return haveItems.isEmpty() && needItems.isEmpty();
}
@Override
- public boolean execute() {
- return execute(false);
+ public boolean canExecute(Player player) {
+ return !this.transactions.isEmpty() && this.matchItems(player);
}
@Override
- public boolean execute(boolean force) {
- if (this.hasExecuted || (!force && !this.canExecute())) {
+ public boolean executeOn(Player player, boolean force) {
+ if (this.hasExecuted || (!force && !this.canExecute(player))) {
return false;
}
InventoryTransactionEvent ev = new InventoryTransactionEvent(this);
Server.getInstance().getPluginManager().callEvent(ev);
if (ev.isCancelled()) {
- for (Inventory inventory : this.inventories) {
- if (inventory instanceof PlayerInventory) {
- ((PlayerInventory) inventory).sendArmorContents(this.getSource());
+ for (Transaction ts : transactions) {
+ Inventory inv;
+ if (ts.getType() == Transaction.TYPE_CONTAINER && (inv = ((ContainerTransaction) ts).getInventory(player)) instanceof PlayerInventory) {
+ ((PlayerInventory) inv).sendArmorContents(player);
+ inv.sendContents(player);
}
- inventory.sendContents(this.getSource());
}
return false;
}
- for (Transaction transaction : this.transactions) {
- transaction.getInventory().setItem(transaction.getSlot(), transaction.getTargetItem());
+ for (Transaction ts : this.transactions) {
+ if (ts.getType() == Transaction.TYPE_CONTAINER) {
+ Inventory inv = ((ContainerTransaction) ts).getInventory(player);
+ if (inv != null) {
+ inv.setItem(ts.getSlot(), ts.getTargetItem());
+ }
+ }
}
this.hasExecuted = true;
@@ -149,7 +114,7 @@ public boolean execute(boolean force) {
}
@Override
- public boolean hasExecuted() {
- return this.hasExecuted;
+ public int getType() {
+ return TYPE_NORMAL;
}
}
diff --git a/src/main/java/cn/nukkit/inventory/Transaction.java b/src/main/java/cn/nukkit/inventory/transaction/Transaction.java
similarity index 51%
rename from src/main/java/cn/nukkit/inventory/Transaction.java
rename to src/main/java/cn/nukkit/inventory/transaction/Transaction.java
index 5d20235803..fa0c05b3ab 100644
--- a/src/main/java/cn/nukkit/inventory/Transaction.java
+++ b/src/main/java/cn/nukkit/inventory/transaction/Transaction.java
@@ -1,4 +1,4 @@
-package cn.nukkit.inventory;
+package cn.nukkit.inventory.transaction;
import cn.nukkit.item.Item;
@@ -8,7 +8,11 @@
*/
public interface Transaction {
- Inventory getInventory();
+ int TYPE_CONTAINER = 0;
+ int TYPE_GLOBAL = 1;
+ int TYPE_WORLD_INTERACTON = 2;
+ int TYPE_CREATIVE = 3;
+ int TYPE_CRAFT = 99999;
int getSlot();
@@ -17,4 +21,6 @@ public interface Transaction {
Item getTargetItem();
long getCreationTime();
+
+ int getType();
}
diff --git a/src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java
new file mode 100644
index 0000000000..f13dbcd22f
--- /dev/null
+++ b/src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java
@@ -0,0 +1,45 @@
+package cn.nukkit.inventory.transaction;
+
+import cn.nukkit.Player;
+
+import java.util.Set;
+
+/**
+ * author: MagicDroidX
+ * Nukkit Project
+ */
+public interface TransactionGroup {
+
+ int TYPE_NORMAL = 0;
+ int TYPE_INVENTORY_MISMATCH = 1;
+ int TYPE_ITEM_USE = 2;
+ int TYPE_ITEM_USE_ON_ENTITY = 3;
+ int TYPE_ITEM_RELEASE = 4;
+
+ int ITEM_RELEASE_ACTION_RELEASE = 0; //Drop item
+ int ITEM_RELEASE_ACTION_USE = 1; //Shoot arrows, etc.
+
+ int ITEM_USE_ACTION_PLACE = 0;
+ int ITEM_USE_ACTION_USE = 1;
+ int ITEM_USE_ACTION_DESTROY = 2;
+
+ int ITEM_USE_ON_ENTITY_ACTION_INTERACT = 0; //TODO: Check the use of these actions
+ int ITEM_USE_ON_ENTITY_ACTION_ATTACK = 1;
+ int ITEM_USE_ON_ENTITY_ACTION_ITEM_INTERACT = 2;
+
+ long getCreationTime();
+
+ Set
getTransactions();
+
+ void addTransaction(Transaction transaction);
+
+ boolean canExecute(Player player);
+
+ boolean executeOn(Player player);
+
+ boolean executeOn(Player player, boolean force);
+
+ boolean hasExecuted();
+
+ int getType();
+}
diff --git a/src/main/java/cn/nukkit/inventory/transaction/WorldInteractionTransaction.java b/src/main/java/cn/nukkit/inventory/transaction/WorldInteractionTransaction.java
new file mode 100644
index 0000000000..5c25262951
--- /dev/null
+++ b/src/main/java/cn/nukkit/inventory/transaction/WorldInteractionTransaction.java
@@ -0,0 +1,22 @@
+package cn.nukkit.inventory.transaction;
+
+import cn.nukkit.item.Item;
+
+public class WorldInteractionTransaction extends BaseTransaction {
+
+ private final int flags;
+
+ public WorldInteractionTransaction(int flags, int slot, Item sourceItem, Item targetItem) {
+ super(slot, sourceItem, targetItem);
+ this.flags = flags;
+ }
+
+ public int getFlags() {
+ return flags;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_WORLD_INTERACTON;
+ }
+}
diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java
index a9e3ab2f89..1ddf12a203 100644
--- a/src/main/java/cn/nukkit/level/Level.java
+++ b/src/main/java/cn/nukkit/level/Level.java
@@ -501,8 +501,8 @@ public void addLevelSoundEvent(byte type, int pitch, int data, Vector3 pos, Coll
pk.x = (float) pos.x;
pk.y = (float) pos.y;
pk.z = (float) pos.z;
- pk.unknownBool = unknown;
- pk.disableRelativeVolume = disableRelativeVolume;
+ pk.isBabyMob = unknown;
+ pk.isGlobal = disableRelativeVolume;
if (players == null) {
this.addChunkPacket(pos.getFloorX(), pos.getFloorZ(), pk);
@@ -971,7 +971,7 @@ public void sendBlocks(Player[] target, Vector3[] blocks, int flags) {
}
public void sendBlocks(Player[] target, Vector3[] blocks, int flags, boolean optimizeRebuilds) {
- List packets = new ArrayList<>();
+ List entries = new ArrayList<>();
if (optimizeRebuilds) {
Map chunks = new HashMap<>();
for (Vector3 b : blocks) {
@@ -987,24 +987,26 @@ public void sendBlocks(Player[] target, Vector3[] blocks, int flags, boolean opt
}
if (b instanceof Block) {
- UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
- updateBlockPacket.x = (int) ((Block) b).x;
- updateBlockPacket.y = (int) ((Block) b).y;
- updateBlockPacket.z = (int) ((Block) b).z;
- updateBlockPacket.blockId = ((Block) b).getId();
- updateBlockPacket.blockData = ((Block) b).getDamage();
- updateBlockPacket.flags = first ? flags : UpdateBlockPacket.FLAG_NONE;
- packets.add(updateBlockPacket);
+ UpdateBlockPacket.Entry entry = new UpdateBlockPacket.Entry(
+ (int) b.x,
+ (int) b.y,
+ (int) b.z,
+ ((Block) b).getId(),
+ ((Block) b).getDamage(),
+ first ? flags : UpdateBlockPacket.FLAG_NONE
+ );
+ entries.add(entry);
} else {
int fullBlock = this.getFullBlock((int) b.x, (int) b.y, (int) b.z);
- UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
- updateBlockPacket.x = (int) b.x;
- updateBlockPacket.y = (int) b.y;
- updateBlockPacket.z = (int) b.z;
- updateBlockPacket.blockId = fullBlock >> 4;
- updateBlockPacket.blockData = fullBlock & 0xf;
- updateBlockPacket.flags = first ? flags : UpdateBlockPacket.FLAG_NONE;
- packets.add(updateBlockPacket);
+ UpdateBlockPacket.Entry entry = new UpdateBlockPacket.Entry(
+ (int) b.x,
+ (int) b.y,
+ (int) b.z,
+ fullBlock >> 4,
+ fullBlock & 0xf,
+ first ? flags : UpdateBlockPacket.FLAG_NONE
+ );
+ entries.add(entry);
}
}
} else {
@@ -1014,29 +1016,34 @@ public void sendBlocks(Player[] target, Vector3[] blocks, int flags, boolean opt
}
UpdateBlockPacket packet = new UpdateBlockPacket();
if (b instanceof Block) {
- UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
- updateBlockPacket.x = (int) ((Block) b).x;
- updateBlockPacket.y = (int) ((Block) b).y;
- updateBlockPacket.z = (int) ((Block) b).z;
- updateBlockPacket.blockId = ((Block) b).getId();
- updateBlockPacket.blockData = ((Block) b).getDamage();
- updateBlockPacket.flags = flags;
- packets.add(updateBlockPacket);
+ UpdateBlockPacket.Entry entry = new UpdateBlockPacket.Entry(
+ (int) b.x,
+ (int) b.y,
+ (int) b.z,
+ ((Block) b).getId(),
+ ((Block) b).getDamage(),
+ flags
+ );
+ entries.add(entry);
} else {
int fullBlock = this.getFullBlock((int) b.x, (int) b.y, (int) b.z);
- UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
- updateBlockPacket.x = (int) b.x;
- updateBlockPacket.y = (int) b.y;
- updateBlockPacket.z = (int) b.z;
- updateBlockPacket.blockId = fullBlock >> 4;
- updateBlockPacket.blockData = fullBlock & 0xf;
- updateBlockPacket.flags = flags;
- packets.add(updateBlockPacket);
+ UpdateBlockPacket.Entry entry = new UpdateBlockPacket.Entry(
+ (int) b.x,
+ (int) b.y,
+ (int) b.z,
+ fullBlock >> 4,
+ fullBlock & 0xf,
+ flags
+ );
+ entries.add(entry);
}
- packets.add(packet);
}
}
- this.server.batchPackets(target, packets.toArray(new DataPacket[packets.size()]));
+ UpdateBlockPacket packet = new UpdateBlockPacket();
+ packet.entries = entries.stream().toArray(UpdateBlockPacket.Entry[]::new);
+ for (Player player : target) {
+ player.dataPacket(packet);
+ }
}
public void clearCache() {
@@ -1954,10 +1961,6 @@ public Item useItemOn(Vector3 vector, Item item, BlockFace face, float fx, float
}
public Item useItemOn(Vector3 vector, Item item, BlockFace face, float fx, float fy, float fz, Player player) {
- return this.useItemOn(vector, item, face, fx, fy, fz, player, false);
- }
-
- public Item useItemOn(Vector3 vector, Item item, BlockFace face, float fx, float fy, float fz, Player player, boolean playSound) {
Block target = this.getBlock(vector);
Block block = target.getSide(face);
@@ -2006,6 +2009,29 @@ public Item useItemOn(Vector3 vector, Item item, BlockFace face, float fx, float
} else if (target.canBeActivated() && target.onActivate(item, null)) {
return item;
}
+ return null;
+ }
+
+ public Item usePlaceOn(Vector3 vector, Item item, BlockFace face, float fx, float fy, float fz) {
+ return this.usePlaceOn(vector, item, face, fx, fy, fz, null);
+ }
+
+ public Item usePlaceOn(Vector3 vector, Item item, BlockFace face, float fx, float fy, float fz, Player player) {
+ return this.usePlaceOn(vector, item, face, fx, fy, fz, player, false);
+ }
+
+ public Item usePlaceOn(Vector3 vector, Item item, BlockFace face, float fx, float fy, float fz, Player player, boolean playSound) {
+ Block target = this.getBlock(vector);
+ Block block = target.getSide(face);
+
+ if (block.y > 255 || block.y < 0) {
+ return null;
+ }
+
+ if (target.getId() == Item.AIR) {
+ return null;
+ }
+
Block hand;
if (item.canBePlaced()) {
hand = item.getBlock();
diff --git a/src/main/java/cn/nukkit/network/Network.java b/src/main/java/cn/nukkit/network/Network.java
index 1c937272c7..e3bf442b19 100644
--- a/src/main/java/cn/nukkit/network/Network.java
+++ b/src/main/java/cn/nukkit/network/Network.java
@@ -140,7 +140,7 @@ public void processBatch(BatchPacket packet, Player player) {
DataPacket pk;
if ((pk = this.getPacket(buf[0])) != null) {
- pk.setBuffer(buf, 1);
+ pk.setBuffer(buf, 3); //skip 2 more bytes
pk.decode();
@@ -166,20 +166,7 @@ public void processBatch(BatchPacket packet, Player player) {
*/
public void processPackets(Player player, List packets) {
if (packets.isEmpty()) return;
- List filter = new ArrayList<>();
- for (DataPacket packet : packets) {
- switch (packet.pid()) {
- case ProtocolInfo.USE_ITEM_PACKET:
- // Prevent double fire of PlayerInteractEvent
- if (!filter.contains(ProtocolInfo.USE_ITEM_PACKET)) {
- player.handleDataPacket(packet);
- filter.add(ProtocolInfo.USE_ITEM_PACKET);
- }
- break;
- default:
- player.handleDataPacket(packet);
- }
- }
+ packets.forEach(player::handleDataPacket);
}
@@ -215,9 +202,7 @@ private void registerPackets() {
this.packetPool = new Class[256];
this.registerPacket(ProtocolInfo.ADD_ENTITY_PACKET, AddEntityPacket.class);
- this.registerPacket(ProtocolInfo.ADD_HANGING_ENTITY_PACKET, AddHangingEntityPacket.class);
this.registerPacket(ProtocolInfo.ADD_ITEM_ENTITY_PACKET, AddItemEntityPacket.class);
- this.registerPacket(ProtocolInfo.ADD_ITEM_PACKET, AddItemPacket.class);
this.registerPacket(ProtocolInfo.ADD_PAINTING_PACKET, AddPaintingPacket.class);
this.registerPacket(ProtocolInfo.ADD_PLAYER_PACKET, AddPlayerPacket.class);
this.registerPacket(ProtocolInfo.ADVENTURE_SETTINGS_PACKET, AdventureSettingsPacket.class);
@@ -231,16 +216,13 @@ private void registerPackets() {
this.registerPacket(ProtocolInfo.CHANGE_DIMENSION_PACKET, ChangeDimensionPacket.class);
this.registerPacket(ProtocolInfo.CHUNK_RADIUS_UPDATED_PACKET, ChunkRadiusUpdatedPacket.class);
this.registerPacket(ProtocolInfo.CLIENTBOUND_MAP_ITEM_DATA_PACKET, ClientboundMapItemDataPacket.class);
- this.registerPacket(ProtocolInfo.COMMAND_STEP_PACKET, CommandStepPacket.class);
+ this.registerPacket(ProtocolInfo.COMMAND_REQUEST_PACKET, CommandRequestPacket.class);
this.registerPacket(ProtocolInfo.CONTAINER_CLOSE_PACKET, ContainerClosePacket.class);
this.registerPacket(ProtocolInfo.CONTAINER_OPEN_PACKET, ContainerOpenPacket.class);
- this.registerPacket(ProtocolInfo.CONTAINER_SET_CONTENT_PACKET, ContainerSetContentPacket.class);
this.registerPacket(ProtocolInfo.CONTAINER_SET_DATA_PACKET, ContainerSetDataPacket.class);
- this.registerPacket(ProtocolInfo.CONTAINER_SET_SLOT_PACKET, ContainerSetSlotPacket.class);
this.registerPacket(ProtocolInfo.CRAFTING_DATA_PACKET, CraftingDataPacket.class);
this.registerPacket(ProtocolInfo.CRAFTING_EVENT_PACKET, CraftingEventPacket.class);
this.registerPacket(ProtocolInfo.DISCONNECT_PACKET, DisconnectPacket.class);
- this.registerPacket(ProtocolInfo.DROP_ITEM_PACKET, DropItemPacket.class);
this.registerPacket(ProtocolInfo.ENTITY_EVENT_PACKET, EntityEventPacket.class);
this.registerPacket(ProtocolInfo.ENTITY_FALL_PACKET, EntityFallPacket.class);
this.registerPacket(ProtocolInfo.EXPLODE_PACKET, ExplodePacket.class);
@@ -248,7 +230,9 @@ private void registerPackets() {
this.registerPacket(ProtocolInfo.GAME_RULES_CHANGED_PACKET, GameRulesChangedPacket.class);
this.registerPacket(ProtocolInfo.HURT_ARMOR_PACKET, HurtArmorPacket.class);
this.registerPacket(ProtocolInfo.INTERACT_PACKET, InteractPacket.class);
- this.registerPacket(ProtocolInfo.INVENTORY_ACTION_PACKET, InventoryActionPacket.class);
+ this.registerPacket(ProtocolInfo.INVENTORY_CONTENT_PACKET, InventoryContentPacket.class);
+ this.registerPacket(ProtocolInfo.INVENTORY_SLOT_PACKET, InventorySlotPacket.class);
+ this.registerPacket(ProtocolInfo.INVENTORY_TRANSACTION_PACKET, InventoryTransactionPacket.class);
this.registerPacket(ProtocolInfo.ITEM_FRAME_DROP_ITEM_PACKET, ItemFrameDropItemPacket.class);
this.registerPacket(ProtocolInfo.LEVEL_EVENT_PACKET, LevelEventPacket.class);
this.registerPacket(ProtocolInfo.LEVEL_SOUND_EVENT_PACKET, LevelSoundEventPacket.class);
@@ -261,11 +245,10 @@ private void registerPackets() {
this.registerPacket(ProtocolInfo.PLAYER_ACTION_PACKET, PlayerActionPacket.class);
this.registerPacket(ProtocolInfo.PLAYER_INPUT_PACKET, PlayerInputPacket.class);
this.registerPacket(ProtocolInfo.PLAYER_LIST_PACKET, PlayerListPacket.class);
+ this.registerPacket(ProtocolInfo.PLAYER_HOTBAR_PACKET, PlayerListPacket.class);
this.registerPacket(ProtocolInfo.PLAY_SOUND_PACKET, PlaySoundPacket.class);
this.registerPacket(ProtocolInfo.PLAY_STATUS_PACKET, PlayStatusPacket.class);
- this.registerPacket(ProtocolInfo.REMOVE_BLOCK_PACKET, RemoveBlockPacket.class);
this.registerPacket(ProtocolInfo.REMOVE_ENTITY_PACKET, RemoveEntityPacket.class);
- this.registerPacket(ProtocolInfo.REPLACE_ITEM_IN_SLOT_PACKET, ReplaceItemInSlotPacket.class);
this.registerPacket(ProtocolInfo.REQUEST_CHUNK_RADIUS_PACKET, RequestChunkRadiusPacket.class);
this.registerPacket(ProtocolInfo.RESOURCE_PACKS_INFO_PACKET, ResourcePacksInfoPacket.class);
this.registerPacket(ProtocolInfo.RESOURCE_PACK_STACK_PACKET, ResourcePackStackPacket.class);
@@ -291,7 +274,6 @@ private void registerPackets() {
this.registerPacket(ProtocolInfo.TAKE_ITEM_ENTITY_PACKET, TakeItemEntityPacket.class);
this.registerPacket(ProtocolInfo.TEXT_PACKET, TextPacket.class);
this.registerPacket(ProtocolInfo.UPDATE_BLOCK_PACKET, UpdateBlockPacket.class);
- this.registerPacket(ProtocolInfo.USE_ITEM_PACKET, UseItemPacket.class);
this.registerPacket(ProtocolInfo.UPDATE_TRADE_PACKET, UpdateTradePacket.class);
}
}
diff --git a/src/main/java/cn/nukkit/network/protocol/AddBehaviorTreePacket.java b/src/main/java/cn/nukkit/network/protocol/AddBehaviorTreePacket.java
new file mode 100644
index 0000000000..0f35174c40
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/AddBehaviorTreePacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class AddBehaviorTreePacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.ADD_BEHAVIOR_TREE_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/AddHangingEntityPacket.java b/src/main/java/cn/nukkit/network/protocol/AddHangingEntityPacket.java
deleted file mode 100644
index 2c0c838540..0000000000
--- a/src/main/java/cn/nukkit/network/protocol/AddHangingEntityPacket.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package cn.nukkit.network.protocol;
-
-import cn.nukkit.math.BlockVector3;
-
-public class AddHangingEntityPacket extends DataPacket {
- public static final byte NETWORK_ID = ProtocolInfo.ADD_HANGING_ENTITY_PACKET;
-
- @Override
- public byte pid() {
- return NETWORK_ID;
- }
-
- public long entityUniqueId;
- public long entityRuntimeId;
- public int x;
- public int y;
- public int z;
- public int unknown;
-
- @Override
- public void decode() {
- this.entityUniqueId = this.getVarLong();
- this.entityRuntimeId = this.getVarLong();
- BlockVector3 v3 = this.getBlockCoords();
- this.x = v3.x;
- this.y = v3.y;
- this.z = v3.z;
- this.unknown = this.getVarInt();
- }
-
- @Override
- public void encode() {
- this.reset();
- this.putVarLong(this.entityUniqueId);
- this.putVarLong(this.entityRuntimeId);
- this.putBlockCoords(this.x, this.y, this.z);
- this.putVarInt(this.unknown);
- }
-}
diff --git a/src/main/java/cn/nukkit/network/protocol/AddItemPacket.java b/src/main/java/cn/nukkit/network/protocol/AddItemPacket.java
deleted file mode 100644
index 413b6b84f2..0000000000
--- a/src/main/java/cn/nukkit/network/protocol/AddItemPacket.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package cn.nukkit.network.protocol;
-
-import cn.nukkit.item.Item;
-
-public class AddItemPacket extends DataPacket {
- public static final byte NETWORK_ID = ProtocolInfo.ADD_ITEM_PACKET;
-
- @Override
- public byte pid() {
- return NETWORK_ID;
- }
-
- public Item item;
-
- @Override
- public void decode() {
-
- }
-
- @Override
- public void encode() {
- this.reset();
- this.putSlot(item);
- }
-}
diff --git a/src/main/java/cn/nukkit/network/protocol/AddPaintingPacket.java b/src/main/java/cn/nukkit/network/protocol/AddPaintingPacket.java
index ae7e86c4fb..8b4e03c247 100644
--- a/src/main/java/cn/nukkit/network/protocol/AddPaintingPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/AddPaintingPacket.java
@@ -25,7 +25,7 @@ public void encode() {
this.reset();
this.putVarLong(this.entityUniqueId);
this.putVarLong(this.entityRuntimeId);
- this.putBlockCoords(this.x, this.y, this.z);
+ this.putBlockVector3(this.x, this.y, this.z);
this.putVarInt(this.direction);
this.putString(this.title);
}
diff --git a/src/main/java/cn/nukkit/network/protocol/BlockEntityDataPacket.java b/src/main/java/cn/nukkit/network/protocol/BlockEntityDataPacket.java
index 92a69abb21..84908c1e4e 100644
--- a/src/main/java/cn/nukkit/network/protocol/BlockEntityDataPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/BlockEntityDataPacket.java
@@ -21,7 +21,7 @@ public byte pid() {
@Override
public void decode() {
- BlockVector3 v = this.getBlockCoords();
+ BlockVector3 v = this.getBlockVector3();
this.x = v.x;
this.y = v.y;
this.z = v.z;
@@ -31,7 +31,7 @@ public void decode() {
@Override
public void encode() {
this.reset();
- this.putBlockCoords(this.x, this.y, this.z);
+ this.putBlockVector3(this.x, this.y, this.z);
this.put(this.namedTag);
}
}
\ No newline at end of file
diff --git a/src/main/java/cn/nukkit/network/protocol/BlockEventPacket.java b/src/main/java/cn/nukkit/network/protocol/BlockEventPacket.java
index 747cf939c3..411464c220 100644
--- a/src/main/java/cn/nukkit/network/protocol/BlockEventPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/BlockEventPacket.java
@@ -26,7 +26,7 @@ public void decode() {
@Override
public void encode() {
this.reset();
- this.putBlockCoords(this.x, this.y, this.z);
+ this.putBlockVector3(this.x, this.y, this.z);
this.putVarInt(this.case1);
this.putVarInt(this.case2);
}
diff --git a/src/main/java/cn/nukkit/network/protocol/BlockPickRequestPacket.java b/src/main/java/cn/nukkit/network/protocol/BlockPickRequestPacket.java
index 8df148f834..cd6f4701c6 100644
--- a/src/main/java/cn/nukkit/network/protocol/BlockPickRequestPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/BlockPickRequestPacket.java
@@ -18,7 +18,7 @@ public byte pid() {
@Override
public void decode() {
- BlockVector3 v = this.getBlockCoords();
+ BlockVector3 v = this.getBlockVector3();
this.x = v.x;
this.y = v.y;
this.z = v.z;
diff --git a/src/main/java/cn/nukkit/network/protocol/BookEditPacket.java b/src/main/java/cn/nukkit/network/protocol/BookEditPacket.java
new file mode 100644
index 0000000000..a52a97a98e
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/BookEditPacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class BookEditPacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.BOOK_EDIT_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/CameraPacket.java b/src/main/java/cn/nukkit/network/protocol/CameraPacket.java
new file mode 100644
index 0000000000..d3b163a912
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/CameraPacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class CameraPacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.CAMERA_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java b/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java
new file mode 100644
index 0000000000..b9ebe5ba1a
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class CommandBlockUpdatePacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.COMMAND_BLOCK_UPDATE_PACKET;
+ }
+
+ @Override
+ public void decode() {
+ //TODO
+ }
+
+ @Override
+ public void encode() {
+
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/CommandStepPacket.java b/src/main/java/cn/nukkit/network/protocol/CommandRequestPacket.java
similarity index 91%
rename from src/main/java/cn/nukkit/network/protocol/CommandStepPacket.java
rename to src/main/java/cn/nukkit/network/protocol/CommandRequestPacket.java
index d85d26104d..ba2f2d013e 100644
--- a/src/main/java/cn/nukkit/network/protocol/CommandStepPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/CommandRequestPacket.java
@@ -7,9 +7,9 @@
* author: MagicDroidX
* Nukkit Project
*/
-public class CommandStepPacket extends DataPacket {
+public class CommandRequestPacket extends DataPacket {
- public static final byte NETWORK_ID = ProtocolInfo.COMMAND_STEP_PACKET;
+ public static final byte NETWORK_ID = ProtocolInfo.COMMAND_REQUEST_PACKET;
/**
* unknown (string)
diff --git a/src/main/java/cn/nukkit/network/protocol/ContainerOpenPacket.java b/src/main/java/cn/nukkit/network/protocol/ContainerOpenPacket.java
index 9d64bf2124..c461769b1d 100644
--- a/src/main/java/cn/nukkit/network/protocol/ContainerOpenPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/ContainerOpenPacket.java
@@ -29,7 +29,7 @@ public void encode() {
this.reset();
this.putByte(this.windowid);
this.putByte(this.type);
- this.putBlockCoords(this.x, this.y, this.z);
+ this.putBlockVector3(this.x, this.y, this.z);
this.putVarLong(this.entityId);
}
}
diff --git a/src/main/java/cn/nukkit/network/protocol/CraftingEventPacket.java b/src/main/java/cn/nukkit/network/protocol/CraftingEventPacket.java
index a500542d61..e9530edd56 100644
--- a/src/main/java/cn/nukkit/network/protocol/CraftingEventPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/CraftingEventPacket.java
@@ -12,6 +12,13 @@ public class CraftingEventPacket extends DataPacket {
public static final byte NETWORK_ID = ProtocolInfo.CRAFTING_EVENT_PACKET;
+ public static final int TYPE_SHAPELESS = 0;
+ public static final int TYPE_SHAPED = 1;
+ public static final int TYPE_FURNACE = 2;
+ public static final int TYPE_FURNACE_DATA = 3;
+ public static final int TYPE_MULTI = 4;
+ public static final int TYPE_SHULKER_BOX = 5;
+
public int windowId;
public int type;
public UUID id;
@@ -22,7 +29,7 @@ public class CraftingEventPacket extends DataPacket {
@Override
public void decode() {
this.windowId = this.getByte();
- this.type = (int) this.getUnsignedVarInt();
+ this.type = this.getVarInt();
this.id = this.getUUID();
int inputSize = (int) this.getUnsignedVarInt();
diff --git a/src/main/java/cn/nukkit/network/protocol/DataPacket.java b/src/main/java/cn/nukkit/network/protocol/DataPacket.java
index da40136b85..f2570e5573 100644
--- a/src/main/java/cn/nukkit/network/protocol/DataPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/DataPacket.java
@@ -27,6 +27,7 @@ public abstract class DataPacket extends BinaryStream implements Cloneable {
public void reset() {
super.reset();
this.putByte(this.pid());
+ this.putShort(0);
}
public void setChannel(int channel) {
diff --git a/src/main/java/cn/nukkit/network/protocol/DropItemPacket.java b/src/main/java/cn/nukkit/network/protocol/DropItemPacket.java
deleted file mode 100644
index 9cd730ad79..0000000000
--- a/src/main/java/cn/nukkit/network/protocol/DropItemPacket.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package cn.nukkit.network.protocol;
-
-import cn.nukkit.item.Item;
-
-/**
- * @author Nukkit Project Team
- */
-public class DropItemPacket extends DataPacket {
-
- public static final byte NETWORK_ID = ProtocolInfo.DROP_ITEM_PACKET;
-
- public int type;
- public Item item;
-
- @Override
- public void decode() {
- this.type = this.getByte();
- this.item = this.getSlot();
- }
-
- @Override
- public void encode() {
-
- }
-
- @Override
- public byte pid() {
- return NETWORK_ID;
- }
-
-}
diff --git a/src/main/java/cn/nukkit/network/protocol/EntityPickRequestPacket.java b/src/main/java/cn/nukkit/network/protocol/EntityPickRequestPacket.java
new file mode 100644
index 0000000000..d4abec9571
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/EntityPickRequestPacket.java
@@ -0,0 +1,21 @@
+package cn.nukkit.network.protocol;
+
+public class EntityPickRequestPacket extends DataPacket {
+
+ public static final byte NETWORK_ID = ProtocolInfo.ENTITY_PICK_REQUEST_PACKET;
+
+ @Override
+ public byte pid() {
+ return NETWORK_ID;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/ExplodePacket.java b/src/main/java/cn/nukkit/network/protocol/ExplodePacket.java
index a55e33ef89..922aaff2bd 100644
--- a/src/main/java/cn/nukkit/network/protocol/ExplodePacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/ExplodePacket.java
@@ -40,7 +40,7 @@ public void encode() {
this.putUnsignedVarInt(this.records.length);
if (this.records.length > 0) {
for (Vector3 record : records) {
- this.putBlockCoords((int) record.x, (int) record.y, (int) record.z);
+ this.putBlockVector3((int) record.x, (int) record.y, (int) record.z);
}
}
}
diff --git a/src/main/java/cn/nukkit/network/protocol/GUIDataPickItemPacket.java b/src/main/java/cn/nukkit/network/protocol/GUIDataPickItemPacket.java
new file mode 100644
index 0000000000..6f33b7ac7b
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/GUIDataPickItemPacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class GUIDataPickItemPacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.GUI_DATA_PICK_ITEM_PACKET;
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+
+ @Override
+ public void decode() {
+
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/InitiateWebSocketConnectionPacket.java b/src/main/java/cn/nukkit/network/protocol/InitiateWebSocketConnectionPacket.java
new file mode 100644
index 0000000000..4cb9bd6333
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/InitiateWebSocketConnectionPacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class InitiateWebSocketConnectionPacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.INITIATE_WEB_SOCKET_CONNECTION_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/InventoryActionPacket.java b/src/main/java/cn/nukkit/network/protocol/InventoryActionPacket.java
deleted file mode 100644
index e7492223ee..0000000000
--- a/src/main/java/cn/nukkit/network/protocol/InventoryActionPacket.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package cn.nukkit.network.protocol;
-
-import cn.nukkit.item.Item;
-
-public class InventoryActionPacket extends DataPacket {
-
- public static final byte NETWORK_ID = ProtocolInfo.INVENTORY_ACTION_PACKET;
-
- public int actionId;
- public Item item;
- public int enchantmentId;
- public int enchantmentLevel;
-
- @Override
- public void decode() {
-
- }
-
- @Override
- public void encode() {
- this.reset();
- this.putUnsignedVarInt(this.actionId);
- this.putSlot(this.item);
- this.putVarInt(this.enchantmentId);
- this.putVarInt(this.enchantmentLevel);
- }
-
- @Override
- public byte pid() {
- return NETWORK_ID;
- }
-}
diff --git a/src/main/java/cn/nukkit/network/protocol/ContainerSetContentPacket.java b/src/main/java/cn/nukkit/network/protocol/InventoryContentPacket.java
similarity index 51%
rename from src/main/java/cn/nukkit/network/protocol/ContainerSetContentPacket.java
rename to src/main/java/cn/nukkit/network/protocol/InventoryContentPacket.java
index 73d92944af..e5aaccc79e 100644
--- a/src/main/java/cn/nukkit/network/protocol/ContainerSetContentPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/InventoryContentPacket.java
@@ -6,8 +6,8 @@
* author: MagicDroidX
* Nukkit Project
*/
-public class ContainerSetContentPacket extends DataPacket {
- public static final byte NETWORK_ID = ProtocolInfo.CONTAINER_SET_CONTENT_PACKET;
+public class InventoryContentPacket extends DataPacket {
+ public static final byte NETWORK_ID = ProtocolInfo.INVENTORY_CONTENT_PACKET;
@Override
public byte pid() {
@@ -20,59 +20,39 @@ public byte pid() {
public static final byte SPECIAL_HOTBAR = 0x7a;
public static final byte SPECIAL_FIXED_INVENTORY = 0x7b;
- public long windowid;
- public long eid;
+ public int inventoryId;
public Item[] slots = new Item[0];
- public int[] hotbar = new int[0];
@Override
public DataPacket clean() {
this.slots = new Item[0];
- this.hotbar = new int[0];
return super.clean();
}
@Override
public void decode() {
- this.windowid = (int) this.getUnsignedVarInt();
- this.eid = this.getVarLong();
+ this.inventoryId = this.getVarInt();
int count = (int) this.getUnsignedVarInt();
this.slots = new Item[count];
for (int s = 0; s < count && !this.feof(); ++s) {
this.slots[s] = this.getSlot();
}
-
- count = (int) this.getUnsignedVarInt();
- this.hotbar = new int[count];
- for (int s = 0; s < count && !this.feof(); ++s) {
- this.hotbar[s] = this.getVarInt();
- }
}
@Override
public void encode() {
this.reset();
- this.putUnsignedVarInt(this.windowid);
- this.putVarLong(this.eid);
+ this.putVarInt(this.inventoryId);
this.putUnsignedVarInt(this.slots.length);
for (Item slot : this.slots) {
this.putSlot(slot);
}
-
- if (this.windowid == SPECIAL_INVENTORY && this.hotbar.length > 0) {
- this.putUnsignedVarInt(this.hotbar.length);
- for (int slot : this.hotbar) {
- this.putVarInt(slot);
- }
- } else {
- this.putUnsignedVarInt(0);
- }
}
@Override
- public ContainerSetContentPacket clone() {
- ContainerSetContentPacket pk = (ContainerSetContentPacket) super.clone();
+ public InventoryContentPacket clone() {
+ InventoryContentPacket pk = (InventoryContentPacket) super.clone();
pk.slots = this.slots.clone();
return pk;
}
diff --git a/src/main/java/cn/nukkit/network/protocol/ContainerSetSlotPacket.java b/src/main/java/cn/nukkit/network/protocol/InventorySlotPacket.java
similarity index 50%
rename from src/main/java/cn/nukkit/network/protocol/ContainerSetSlotPacket.java
rename to src/main/java/cn/nukkit/network/protocol/InventorySlotPacket.java
index b78648c5bb..bf30c74567 100644
--- a/src/main/java/cn/nukkit/network/protocol/ContainerSetSlotPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/InventorySlotPacket.java
@@ -6,36 +6,30 @@
* author: MagicDroidX
* Nukkit Project
*/
-public class ContainerSetSlotPacket extends DataPacket {
- public static final byte NETWORK_ID = ProtocolInfo.CONTAINER_SET_SLOT_PACKET;
+public class InventorySlotPacket extends DataPacket {
+ public static final byte NETWORK_ID = ProtocolInfo.INVENTORY_SLOT_PACKET;
@Override
public byte pid() {
return NETWORK_ID;
}
- public int windowid;
+ public int inventoryId;
public int slot;
- public int hotbarSlot;
public Item item;
- public int selectedSlot;
@Override
public void decode() {
- this.windowid = this.getByte();
+ this.inventoryId = this.getVarInt();
this.slot = this.getVarInt();
- this.hotbarSlot = this.getVarInt();
this.item = this.getSlot();
- this.selectedSlot = this.getByte();
}
@Override
public void encode() {
this.reset();
- this.putByte((byte) this.windowid);
+ this.putVarInt((byte) this.inventoryId);
this.putVarInt(this.slot);
- this.putVarInt(this.hotbarSlot);
this.putSlot(this.item);
- this.putByte((byte) this.selectedSlot);
}
}
diff --git a/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java b/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java
new file mode 100644
index 0000000000..61551a034b
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java
@@ -0,0 +1,135 @@
+package cn.nukkit.network.protocol;
+
+import cn.nukkit.inventory.transaction.*;
+import cn.nukkit.math.BlockFace;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class InventoryTransactionPacket extends DataPacket {
+
+ public TransactionGroup transaction;
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.INVENTORY_TRANSACTION_PACKET;
+ }
+
+ @Override
+ public void encode() {
+ this.putVarInt(transaction.getType());
+ this.putVarInt(transaction.getTransactions().size());
+ for (Transaction ts : transaction.getTransactions()) {
+ this.putVarInt(ts.getType());
+ switch (ts.getType()) {
+ case Transaction.TYPE_CONTAINER:
+ this.putVarInt(((ContainerTransaction) ts).getInventoryId());
+ break;
+ case Transaction.TYPE_WORLD_INTERACTON:
+ this.putVarInt(((WorldInteractionTransaction) ts).getFlags());
+ break;
+ case Transaction.TYPE_CRAFT:
+ this.putVarInt(((CraftTransaction) ts).getAction());
+ break;
+ }
+ this.putVarInt(ts.getSlot());
+ this.putSlot(ts.getSourceItem());
+ this.putSlot(ts.getTargetItem());
+ }
+ switch (transaction.getType()) {
+ case TransactionGroup.TYPE_ITEM_USE:
+ ItemUseTransactionGroup iu = (ItemUseTransactionGroup) transaction;
+ this.putVarInt(iu.getAction());
+ this.putBlockVector3(iu.getBlockPos());
+ this.putVarInt(iu.getFace());
+ this.putVarInt(iu.getSlot());
+ this.putSlot(iu.getItem());
+ this.putVector3f(iu.getPlayerPos());
+ this.putVector3f(iu.getClickPos());
+ break;
+ case TransactionGroup.TYPE_ITEM_USE_ON_ENTITY:
+ ItemUseOnEntityTransactionGroup oe = (ItemUseOnEntityTransactionGroup) transaction;
+ this.putVarLong(oe.getEntityId());
+ this.putVarInt(oe.getAction());
+ this.putVarInt(oe.getSlot());
+ this.putSlot(oe.getItem());
+ this.putVector3f(oe.getPlayerPos());
+ break;
+ case TransactionGroup.TYPE_ITEM_RELEASE:
+ ItemReleaseTransactionGroup ir = (ItemReleaseTransactionGroup) transaction;
+ this.putVarInt(ir.getAction());
+ this.putVarInt(ir.getSlot());
+ this.putSlot(ir.getItem());
+ this.putVector3f(ir.getPlayerPos());
+ }
+ }
+
+ @Override
+ public void decode() {
+ int type = this.getVarInt();
+ int count = this.getVarInt();
+ List list = new ArrayList<>();
+ for (int i = 0; i < count; i++) {
+ Transaction ts;
+ switch (this.getVarInt()) {
+ case Transaction.TYPE_CONTAINER:
+ ts = new ContainerTransaction(this.getVarInt(), this.getVarInt(), this.getSlot(), this.getSlot());
+ break;
+ case Transaction.TYPE_GLOBAL:
+ ts = new GlobalTransaction(this.getVarInt(), this.getSlot(), this.getSlot());
+ break;
+ case Transaction.TYPE_WORLD_INTERACTON:
+ ts = new WorldInteractionTransaction(this.getVarInt(), this.getVarInt(), this.getSlot(), this.getSlot());
+ break;
+ case Transaction.TYPE_CREATIVE:
+ ts = new CreativeTransaction(this.getVarInt(), this.getSlot(), this.getSlot());
+ break;
+ case Transaction.TYPE_CRAFT:
+ ts = new CraftTransaction(this.getVarInt(), this.getVarInt(), this.getSlot(), this.getSlot());
+ break;
+ default:
+ continue;
+ }
+ list.add(ts);
+ }
+ switch (type) {
+ case TransactionGroup.TYPE_NORMAL:
+ transaction = new NormalTransactionGroup();
+ break;
+ case TransactionGroup.TYPE_INVENTORY_MISMATCH:
+ transaction = new InventoryMismatchTransactionGroup();
+ break;
+ case TransactionGroup.TYPE_ITEM_USE:
+ transaction = new ItemUseTransactionGroup(
+ this.getVarInt(),
+ this.getBlockVector3(),
+ this.getVarInt(),
+ this.getVarInt(),
+ this.getSlot(),
+ this.getVector3f(),
+ this.getVector3f()
+ );
+ break;
+ case TransactionGroup.TYPE_ITEM_USE_ON_ENTITY:
+ transaction = new ItemUseOnEntityTransactionGroup(
+ this.getVarLong(),
+ this.getVarInt(),
+ this.getVarInt(),
+ this.getSlot(),
+ this.getVector3f()
+ );
+ break;
+ case TransactionGroup.TYPE_ITEM_RELEASE:
+ transaction = new ItemReleaseTransactionGroup(
+ this.getVarInt(),
+ this.getVarInt(),
+ this.getSlot(),
+ this.getVector3f()
+ );
+ break;
+ default:
+ return;
+ }
+ list.forEach(transaction::addTransaction);
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/ItemFrameDropItemPacket.java b/src/main/java/cn/nukkit/network/protocol/ItemFrameDropItemPacket.java
index ce0ca5c807..1aa0b9458e 100644
--- a/src/main/java/cn/nukkit/network/protocol/ItemFrameDropItemPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/ItemFrameDropItemPacket.java
@@ -15,7 +15,7 @@ public class ItemFrameDropItemPacket extends DataPacket {
@Override
public void decode() {
- BlockVector3 v = this.getBlockCoords();
+ BlockVector3 v = this.getBlockVector3();
this.z = v.z;
this.y = v.y;
this.x = v.x;
diff --git a/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java b/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java
index 5d6661f293..e4b3fbe2fd 100644
--- a/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java
@@ -119,10 +119,10 @@ public class LevelSoundEventPacket extends DataPacket {
public float x;
public float y;
public float z;
- public int extraData = -1;
- public int pitch = 1;
- public boolean unknownBool;
- public boolean disableRelativeVolume;
+ public int extraData = -1; //TODO: Check name
+ public int pitch = 1; //TODO: Check name
+ public boolean isBabyMob;
+ public boolean isGlobal;
@Override
public void decode() {
@@ -133,8 +133,8 @@ public void decode() {
this.z = v.z;
this.extraData = this.getVarInt();
this.pitch = this.getVarInt();
- this.unknownBool = this.getBoolean();
- this.disableRelativeVolume = this.getBoolean();
+ this.isBabyMob = this.getBoolean();
+ this.isGlobal = this.getBoolean();
}
@Override
@@ -144,8 +144,8 @@ public void encode() {
this.putVector3f(this.x, this.y, this.z);
this.putVarInt(this.extraData);
this.putVarInt(this.pitch);
- this.putBoolean(this.unknownBool);
- this.putBoolean(this.disableRelativeVolume);
+ this.putBoolean(this.isBabyMob);
+ this.putBoolean(this.isGlobal);
}
@Override
diff --git a/src/main/java/cn/nukkit/network/protocol/LoginPacket.java b/src/main/java/cn/nukkit/network/protocol/LoginPacket.java
index 7290922b85..7f3f4a2b58 100644
--- a/src/main/java/cn/nukkit/network/protocol/LoginPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/LoginPacket.java
@@ -1,6 +1,8 @@
package cn.nukkit.network.protocol;
+import cn.nukkit.Server;
import cn.nukkit.entity.data.Skin;
+import cn.nukkit.utils.Binary;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
@@ -21,7 +23,6 @@ public class LoginPacket extends DataPacket {
public String username;
public int protocol;
- public byte gameEdition;
public UUID clientUUID;
public long clientId;
@@ -35,7 +36,6 @@ public byte pid() {
@Override
public void decode() {
this.protocol = this.getInt();
- this.gameEdition = (byte) this.getByte();
this.setBuffer(this.getByteArray(), 0);
decodeChainData();
decodeSkinData();
diff --git a/src/main/java/cn/nukkit/network/protocol/NPCRequestPacket.java b/src/main/java/cn/nukkit/network/protocol/NPCRequestPacket.java
new file mode 100644
index 0000000000..99e79e9a10
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/NPCRequestPacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class NPCRequestPacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.NPC_REQUEST_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java b/src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java
index aa0106e6e4..5e0ea6dc1d 100644
--- a/src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java
@@ -24,7 +24,7 @@ public void decode() {
@Override
public void encode() {
this.putString(this.name);
- this.putBlockCoords(this.x, this.y, this.z);
+ this.putBlockVector3(this.x, this.y, this.z);
this.putLFloat(this.volume);
this.putLFloat(this.pitch);
}
diff --git a/src/main/java/cn/nukkit/network/protocol/PlayerActionPacket.java b/src/main/java/cn/nukkit/network/protocol/PlayerActionPacket.java
index bcc6de31d8..b40fb480e5 100644
--- a/src/main/java/cn/nukkit/network/protocol/PlayerActionPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/PlayerActionPacket.java
@@ -12,21 +12,22 @@ public class PlayerActionPacket extends DataPacket {
public static final byte ACTION_START_BREAK = 0;
public static final byte ACTION_ABORT_BREAK = 1;
public static final byte ACTION_STOP_BREAK = 2;
-
- public static final byte ACTION_RELEASE_ITEM = 5;
- public static final byte ACTION_STOP_SLEEPING = 6;
- public static final byte ACTION_RESPAWN = 7;
- public static final byte ACTION_JUMP = 8;
- public static final byte ACTION_START_SPRINT = 9;
- public static final byte ACTION_STOP_SPRINT = 10;
- public static final byte ACTION_START_SNEAK = 11;
- public static final byte ACTION_STOP_SNEAK = 12;
- public static final byte ACTION_DIMENSION_CHANGE = 13;
- public static final byte ACTION_ABORT_DIMENSION_CHANGE = 14;
- public static final byte ACTION_START_GLIDE = 15;
- public static final byte ACTION_STOP_GLIDE = 16;
- public static final byte ACTION_WORLD_IMMUTABLE = 17;
- public static final byte ACTION_CONTINUE_BREAK = 18;
+ public static final byte ACTION_GET_UPDATED_BLOCK = 3;
+ public static final byte ACTION_DROP_ITEM = 4;
+ public static final byte ACTION_STOP_SLEEPING = 5;
+ public static final byte ACTION_RESPAWN = 6;
+ public static final byte ACTION_JUMP = 7;
+ public static final byte ACTION_START_SPRINT = 8;
+ public static final byte ACTION_STOP_SPRINT = 9;
+ public static final byte ACTION_START_SNEAK = 10;
+ public static final byte ACTION_STOP_SNEAK = 11;
+ public static final byte ACTION_DIMENSION_CHANGE = 12;
+ public static final byte ACTION_DIMENSION_CHANGE_ACK = 13;
+ public static final byte ACTION_START_GLIDE = 14;
+ public static final byte ACTION_STOP_GLIDE = 15;
+ public static final byte ACTION_WORLD_IMMUTABLE = 16;
+ public static final byte ACTION_CONTINUE_BREAK = 17;
+ public static final byte ACTION_CHANGE_SKIN = 18;
public long entityId;
public int action;
@@ -40,7 +41,7 @@ public class PlayerActionPacket extends DataPacket {
public void decode() {
this.entityId = this.getVarLong();
this.action = this.getVarInt();
- BlockVector3 v = this.getBlockCoords();
+ BlockVector3 v = this.getBlockVector3();
this.x = v.x;
this.y = v.y;
this.z = v.z;
@@ -52,7 +53,7 @@ public void encode() {
this.reset();
this.putVarLong(this.entityId);
this.putVarInt(this.action);
- this.putBlockCoords(this.x, this.y, this.z);
+ this.putBlockVector3(this.x, this.y, this.z);
this.putVarInt(this.face);
}
diff --git a/src/main/java/cn/nukkit/network/protocol/PlayerHotbarPacket.java b/src/main/java/cn/nukkit/network/protocol/PlayerHotbarPacket.java
new file mode 100644
index 0000000000..63078c2fac
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/PlayerHotbarPacket.java
@@ -0,0 +1,31 @@
+package cn.nukkit.network.protocol;
+
+public class PlayerHotbarPacket extends DataPacket {
+
+ public int selectedSlot;
+ public int[] data = new int[0];
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.PLAYER_HOTBAR_PACKET;
+ }
+
+ @Override
+ public void decode() {
+ this.selectedSlot = this.getByte();
+ int count = (int) this.getUnsignedVarInt();
+ this.data = new int[count];
+ for (int s = 0; s < count && !this.feof(); ++s) {
+ this.data[s] = this.getVarInt();
+ }
+ }
+
+ @Override
+ public void encode() {
+ this.putByte((byte) selectedSlot);
+ this.putUnsignedVarInt(this.data.length);
+ for (int slot : this.data) {
+ this.putVarInt(slot);
+ }
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/PlayerSkinPacket.java b/src/main/java/cn/nukkit/network/protocol/PlayerSkinPacket.java
new file mode 100644
index 0000000000..ea8e22d710
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/PlayerSkinPacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class PlayerSkinPacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.PLAYER_SKIN_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
index b02cbebe68..1f3105e109 100644
--- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
+++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
@@ -9,9 +9,9 @@ public interface ProtocolInfo {
/**
* Actual Minecraft: PE protocol version
*/
- byte CURRENT_PROTOCOL = 113;
- String MINECRAFT_VERSION = "v1.1.3";
- String MINECRAFT_VERSION_NETWORK = "1.1.3";
+ int CURRENT_PROTOCOL = 130;
+ String MINECRAFT_VERSION = "v1.2.0.2";
+ String MINECRAFT_VERSION_NETWORK = "1.2.0.2";
byte LOGIN_PACKET = 0x01;
byte PLAY_STATUS_PACKET = 0x02;
@@ -28,26 +28,26 @@ public interface ProtocolInfo {
byte ADD_ENTITY_PACKET = 0x0d;
byte REMOVE_ENTITY_PACKET = 0x0e;
byte ADD_ITEM_ENTITY_PACKET = 0x0f;
- byte ADD_HANGING_ENTITY_PACKET = 0x10;
+
byte TAKE_ITEM_ENTITY_PACKET = 0x11;
byte MOVE_ENTITY_PACKET = 0x12;
byte MOVE_PLAYER_PACKET = 0x13;
byte RIDER_JUMP_PACKET = 0x14;
- byte REMOVE_BLOCK_PACKET = 0x15;
- byte UPDATE_BLOCK_PACKET = 0x16;
- byte ADD_PAINTING_PACKET = 0x17;
- byte EXPLODE_PACKET = 0x18;
- byte LEVEL_SOUND_EVENT_PACKET = 0x19;
- byte LEVEL_EVENT_PACKET = 0x1a;
- byte BLOCK_EVENT_PACKET = 0x1b;
- byte ENTITY_EVENT_PACKET = 0x1c;
- byte MOB_EFFECT_PACKET = 0x1d;
- byte UPDATE_ATTRIBUTES_PACKET = 0x1e;
+ byte UPDATE_BLOCK_PACKET = 0x15;
+ byte ADD_PAINTING_PACKET = 0x16;
+ byte EXPLODE_PACKET = 0x17;
+ byte LEVEL_SOUND_EVENT_PACKET = 0x18;
+ byte LEVEL_EVENT_PACKET = 0x19;
+ byte BLOCK_EVENT_PACKET = 0x1a;
+ byte ENTITY_EVENT_PACKET = 0x1b;
+ byte MOB_EFFECT_PACKET = 0x1c;
+ byte UPDATE_ATTRIBUTES_PACKET = 0x1d;
+ byte INVENTORY_TRANSACTION_PACKET = 0x1e;
byte MOB_EQUIPMENT_PACKET = 0x1f;
byte MOB_ARMOR_EQUIPMENT_PACKET = 0x20;
byte INTERACT_PACKET = 0x21;
byte BLOCK_PICK_REQUEST_PACKET = 0x22;
- byte USE_ITEM_PACKET = 0x23;
+ byte ENTITY_PICK_REQUEST_PACKET = 0x23;
byte PLAYER_ACTION_PACKET = 0x24;
byte ENTITY_FALL_PACKET = 0x25;
byte HURT_ARMOR_PACKET = 0x26;
@@ -58,15 +58,15 @@ public interface ProtocolInfo {
byte SET_SPAWN_POSITION_PACKET = 0x2b;
byte ANIMATE_PACKET = 0x2c;
byte RESPAWN_PACKET = 0x2d;
- byte DROP_ITEM_PACKET = 0x2e;
- byte INVENTORY_ACTION_PACKET = 0x2f;
- byte CONTAINER_OPEN_PACKET = 0x30;
- byte CONTAINER_CLOSE_PACKET = 0x31;
- byte CONTAINER_SET_SLOT_PACKET = 0x32;
+ byte CONTAINER_OPEN_PACKET = 0x2e;
+ byte CONTAINER_CLOSE_PACKET = 0x2f;
+ byte PLAYER_HOTBAR_PACKET = 0x30;
+ byte INVENTORY_CONTENT_PACKET = 0x31;
+ byte INVENTORY_SLOT_PACKET = 0x32;
byte CONTAINER_SET_DATA_PACKET = 0x33;
- byte CONTAINER_SET_CONTENT_PACKET = 0x34;
- byte CRAFTING_DATA_PACKET = 0x35;
- byte CRAFTING_EVENT_PACKET = 0x36;
+ byte CRAFTING_DATA_PACKET = 0x34;
+ byte CRAFTING_EVENT_PACKET = 0x35;
+ byte GUI_DATA_PICK_ITEM_PACKET = 0x36;
byte ADVENTURE_SETTINGS_PACKET = 0x37;
byte BLOCK_ENTITY_DATA_PACKET = 0x38;
byte PLAYER_INPUT_PACKET = 0x39;
@@ -77,32 +77,36 @@ public interface ProtocolInfo {
byte SET_PLAYER_GAME_TYPE_PACKET = 0x3e;
byte PLAYER_LIST_PACKET = 0x3f;
byte SIMPLE_EVENT_PACKET = 0x40;
- byte EVENT_PACKET = 0x41;
+ byte TELEMETRY_EVENT_PACKET = 0x41;
byte SPAWN_EXPERIENCE_ORB_PACKET = 0x42;
byte CLIENTBOUND_MAP_ITEM_DATA_PACKET = 0x43;
byte MAP_INFO_REQUEST_PACKET = 0x44;
byte REQUEST_CHUNK_RADIUS_PACKET = 0x45;
byte CHUNK_RADIUS_UPDATED_PACKET = 0x46;
byte ITEM_FRAME_DROP_ITEM_PACKET = 0x47;
- byte REPLACE_ITEM_IN_SLOT_PACKET = 0x48;
- byte GAME_RULES_CHANGED_PACKET = 0x49;
- byte CAMERA_PACKET = 0x4a;
- byte ADD_ITEM_PACKET = 0x4b;
- byte BOSS_EVENT_PACKET = 0x4c;
- byte SHOW_CREDITS_PACKET = 0x4d;
- byte AVAILABLE_COMMANDS_PACKET = 0x4e;
- byte COMMAND_STEP_PACKET = 0x4f;
- byte COMMAND_BLOCK_UPDATE_PACKET = 0x50;
- byte UPDATE_TRADE_PACKET = 0x51;
- byte UPDATE_EQUIP_PACKET = 0x52;
- byte RESOURCE_PACK_DATA_INFO_PACKET = 0x53;
- byte RESOURCE_PACK_CHUNK_DATA_PACKET = 0x54;
- byte RESOURCE_PACK_CHUNK_REQUEST_PACKET = 0x55;
- byte TRANSFER_PACKET = 0x56;
- byte PLAY_SOUND_PACKET = 0x57;
- byte STOP_SOUND_PACKET = 0x58;
- byte SET_TITLE_PACKET = 0x59;
- byte ADD_BEHAVIOR_TREE_PACKET = 0x5a;
- byte STRUCTURE_BLOCK_UPDATE_PACKET = 0x5b;
+ byte GAME_RULES_CHANGED_PACKET = 0x48;
+ byte CAMERA_PACKET = 0x49;
+ byte BOSS_EVENT_PACKET = 0x4a;
+ byte SHOW_CREDITS_PACKET = 0x4b;
+ byte AVAILABLE_COMMANDS_PACKET = 0x4c;
+ byte COMMAND_REQUEST_PACKET = 0x4d;
+ byte COMMAND_BLOCK_UPDATE_PACKET = 0x4e;
+ byte UPDATE_TRADE_PACKET = 0x50;
+ byte UPDATE_EQUIPMENT_PACKET = 0x51;
+ byte RESOURCE_PACK_DATA_INFO_PACKET = 0x52;
+ byte RESOURCE_PACK_CHUNK_DATA_PACKET = 0x53;
+ byte RESOURCE_PACK_CHUNK_REQUEST_PACKET = 0x54;
+ byte TRANSFER_PACKET = 0x55;
+ byte PLAY_SOUND_PACKET = 0x56;
+ byte STOP_SOUND_PACKET = 0x57;
+ byte SET_TITLE_PACKET = 0x58;
+ byte ADD_BEHAVIOR_TREE_PACKET = 0x59;
+ byte STRUCTURE_BLOCK_UPDATE_PACKET = 0x5a;
+ byte PLAYER_SKIN_PACKET = 0x5d;
+ byte SUB_CLIENT_LOGIN_PACKET = 0x5e;
+ byte INITIATE_WEB_SOCKET_CONNECTION_PACKET = 0x5f;
+ byte SET_LAST_HURT_BY_PACKET = 0x60;
+ byte BOOK_EDIT_PACKET = 0x61;
+ byte NPC_REQUEST_PACKET = 0x62;
byte BATCH_PACKET = (byte) 0xff;
}
diff --git a/src/main/java/cn/nukkit/network/protocol/RemoveBlockPacket.java b/src/main/java/cn/nukkit/network/protocol/RemoveBlockPacket.java
deleted file mode 100644
index d20f2f1632..0000000000
--- a/src/main/java/cn/nukkit/network/protocol/RemoveBlockPacket.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package cn.nukkit.network.protocol;
-
-import cn.nukkit.math.BlockVector3;
-
-/**
- * @author Nukkit Project Team
- */
-public class RemoveBlockPacket extends DataPacket {
-
- public static final byte NETWORK_ID = ProtocolInfo.REMOVE_BLOCK_PACKET;
-
- public int x;
- public int y;
- public int z;
-
- @Override
- public void decode() {
- BlockVector3 v = this.getBlockCoords();
- this.x = v.x;
- this.y = v.y;
- this.z = v.z;
- }
-
- @Override
- public void encode() {
- }
-
- @Override
- public byte pid() {
- return NETWORK_ID;
- }
-
-}
diff --git a/src/main/java/cn/nukkit/network/protocol/ReplaceItemInSlotPacket.java b/src/main/java/cn/nukkit/network/protocol/ReplaceItemInSlotPacket.java
deleted file mode 100644
index a70b68b7e1..0000000000
--- a/src/main/java/cn/nukkit/network/protocol/ReplaceItemInSlotPacket.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package cn.nukkit.network.protocol;
-
-import cn.nukkit.item.Item;
-
-/**
- * Created by Pub4Game on 29.04.2016.
- */
-public class ReplaceItemInSlotPacket extends DataPacket {
-
- public static final byte NETWORK_ID = ProtocolInfo.REPLACE_ITEM_IN_SLOT_PACKET;
-
- public Item item;
-
- @Override
- public void decode() {
-
- }
-
- @Override
- public void encode() {
- this.reset();
- this.putSlot(this.item);
- }
-
- @Override
- public byte pid() {
- return NETWORK_ID;
- }
-
-}
\ No newline at end of file
diff --git a/src/main/java/cn/nukkit/network/protocol/SetLastHurtByPacket.java b/src/main/java/cn/nukkit/network/protocol/SetLastHurtByPacket.java
new file mode 100644
index 0000000000..46001b273a
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/SetLastHurtByPacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class SetLastHurtByPacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.SET_LAST_HURT_BY_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/SetSpawnPositionPacket.java b/src/main/java/cn/nukkit/network/protocol/SetSpawnPositionPacket.java
index 1b58639039..a3f4293c64 100644
--- a/src/main/java/cn/nukkit/network/protocol/SetSpawnPositionPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/SetSpawnPositionPacket.java
@@ -25,7 +25,7 @@ public void decode() {
public void encode() {
this.reset();
this.putVarInt(this.spawnType);
- this.putBlockCoords(this.x, this.y, this.z);
+ this.putBlockVector3(this.x, this.y, this.z);
this.putBoolean(this.spawnForced);
}
diff --git a/src/main/java/cn/nukkit/network/protocol/SimpleEventPacket.java b/src/main/java/cn/nukkit/network/protocol/SimpleEventPacket.java
new file mode 100644
index 0000000000..163224e04d
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/SimpleEventPacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class SimpleEventPacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.SIMPLE_EVENT_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java b/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java
index 5863e5b575..efcb72ae2a 100644
--- a/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java
@@ -63,7 +63,7 @@ public void encode() {
this.putVarInt(this.generator);
this.putVarInt(this.gamemode);
this.putVarInt(this.difficulty);
- this.putBlockCoords(this.spawnX, this.spawnY, this.spawnZ);
+ this.putBlockVector3(this.spawnX, this.spawnY, this.spawnZ);
this.putBoolean(this.hasAchievementsDisabled);
this.putVarInt(this.dayCycleStopTime);
this.putBoolean(this.eduMode);
diff --git a/src/main/java/cn/nukkit/network/protocol/StructureBlockUpdatePacket.java b/src/main/java/cn/nukkit/network/protocol/StructureBlockUpdatePacket.java
new file mode 100644
index 0000000000..1d22735de2
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/StructureBlockUpdatePacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class StructureBlockUpdatePacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.STRUCTURE_BLOCK_UPDATE_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/SubClientLoginPacket.java b/src/main/java/cn/nukkit/network/protocol/SubClientLoginPacket.java
new file mode 100644
index 0000000000..386e4f67cc
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/SubClientLoginPacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class SubClientLoginPacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.SUB_CLIENT_LOGIN_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/TelemetryEventPacket.java b/src/main/java/cn/nukkit/network/protocol/TelemetryEventPacket.java
new file mode 100644
index 0000000000..b73bb35919
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/TelemetryEventPacket.java
@@ -0,0 +1,25 @@
+package cn.nukkit.network.protocol;
+
+public class TelemetryEventPacket extends DataPacket {
+
+ public long eid;
+ public int unknown1;
+ public byte unknown2;
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.TELEMETRY_EVENT_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ this.putVarLong(this.eid);
+ this.putVarInt(this.unknown1);
+ this.putByte(this.unknown2);
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/UpdateBlockPacket.java b/src/main/java/cn/nukkit/network/protocol/UpdateBlockPacket.java
index 1ca274b022..b153595f66 100644
--- a/src/main/java/cn/nukkit/network/protocol/UpdateBlockPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/UpdateBlockPacket.java
@@ -16,12 +16,7 @@ public class UpdateBlockPacket extends DataPacket {
public static final int FLAG_ALL = (FLAG_NEIGHBORS | FLAG_NETWORK);
public static final int FLAG_ALL_PRIORITY = (FLAG_ALL | FLAG_PRIORITY);
- public int x;
- public int z;
- public int y;
- public int blockId;
- public int blockData;
- public int flags;
+ public Entry[] entries = new Entry[0];
@Override
public byte pid() {
@@ -36,9 +31,12 @@ public void decode() {
@Override
public void encode() {
this.reset();
- this.putBlockCoords(x, y, z);
- this.putUnsignedVarInt(blockId);
- this.putUnsignedVarInt((0xb << 4) | blockData & 0xf);
+ this.putUnsignedVarInt(entries.length); //TODO: Check if this is correct
+ for (Entry entry : entries) {
+ this.putBlockVector3(entry.x, entry.y, entry.z);
+ this.putUnsignedVarInt(entry.blockId);
+ this.putUnsignedVarInt((0xb << 4) | entry.blockData & 0xf);
+ }
}
public static class Entry {
diff --git a/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java b/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java
new file mode 100644
index 0000000000..27c8f40ff5
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class UpdateEquipmentPacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.UPDATE_EQUIPMENT_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/UseItemPacket.java b/src/main/java/cn/nukkit/network/protocol/UseItemPacket.java
deleted file mode 100644
index a490656a18..0000000000
--- a/src/main/java/cn/nukkit/network/protocol/UseItemPacket.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package cn.nukkit.network.protocol;
-
-import cn.nukkit.item.Item;
-import cn.nukkit.math.BlockVector3;
-import cn.nukkit.math.Vector3f;
-
-/**
- * @author Nukkit Project Team
- */
-public class UseItemPacket extends DataPacket {
-
- public static final byte NETWORK_ID = ProtocolInfo.USE_ITEM_PACKET;
-
- public int x;
- public int y;
- public int z;
-
- public int interactBlockId;
-
- public int face;
-
- public float fx;
- public float fy;
- public float fz;
-
- public float posX;
- public float posY;
- public float posZ;
-
- public int slot;
-
- public Item item;
-
- @Override
- public byte pid() {
- return NETWORK_ID;
- }
-
- @Override
- public void decode() {
- BlockVector3 v = this.getBlockCoords();
- this.x = v.x;
- this.y = v.y;
- this.z = v.z;
- this.interactBlockId = (int) this.getUnsignedVarInt();
- this.face = this.getVarInt();
- Vector3f faceVector3 = this.getVector3f();
- this.fx = faceVector3.x;
- this.fy = faceVector3.y;
- this.fz = faceVector3.z;
- Vector3f playerPos = this.getVector3f();
- this.posX = playerPos.x;
- this.posY = playerPos.y;
- this.posZ = playerPos.z;
- this.slot = this.getByte();
- this.item = this.getSlot();
- }
-
- @Override
- public void encode() {
-
- }
-
-}
diff --git a/src/main/java/cn/nukkit/utils/Binary.java b/src/main/java/cn/nukkit/utils/Binary.java
index 9405f1b4e9..be6a3c9eb9 100644
--- a/src/main/java/cn/nukkit/utils/Binary.java
+++ b/src/main/java/cn/nukkit/utils/Binary.java
@@ -153,7 +153,7 @@ public static EntityMetadata readMetadata(byte[] payload) {
value = new SlotEntityData(key, item.getId(), item.getDamage(), item.getCount());
break;
case Entity.DATA_TYPE_POS:
- BlockVector3 v3 = stream.getBlockCoords();
+ BlockVector3 v3 = stream.getBlockVector3();
value = new IntPositionEntityData(key, v3.x, v3.y, v3.z);
break;
case Entity.DATA_TYPE_LONG:
diff --git a/src/main/java/cn/nukkit/utils/BinaryStream.java b/src/main/java/cn/nukkit/utils/BinaryStream.java
index 65dbb8637f..abfd4ea185 100644
--- a/src/main/java/cn/nukkit/utils/BinaryStream.java
+++ b/src/main/java/cn/nukkit/utils/BinaryStream.java
@@ -1,9 +1,11 @@
package cn.nukkit.utils;
+import cn.nukkit.block.Block;
import cn.nukkit.entity.Attribute;
import cn.nukkit.entity.data.Skin;
import cn.nukkit.item.Item;
import cn.nukkit.math.BlockVector3;
+import cn.nukkit.math.Vector3;
import cn.nukkit.math.Vector3f;
import java.math.BigInteger;
@@ -371,11 +373,15 @@ public void putUnsignedVarLong(long v) {
VarInt.writeUnsignedVarLong(this, v);
}
- public BlockVector3 getBlockCoords() {
+ public BlockVector3 getBlockVector3() {
return new BlockVector3(this.getVarInt(), (int) this.getUnsignedVarInt(), this.getVarInt());
}
- public void putBlockCoords(int x, int y, int z) {
+ public void putBlockVector3(BlockVector3 v) {
+ this.putBlockVector3(v.x, v.y, v.z);
+ }
+
+ public void putBlockVector3(int x, int y, int z) {
this.putVarInt(x);
this.putUnsignedVarInt(y);
this.putVarInt(z);
@@ -385,6 +391,10 @@ public Vector3f getVector3f() {
return new Vector3f(this.getLFloat(4), this.getLFloat(4), this.getLFloat(4));
}
+ public void putVector3f(Vector3f v) {
+ this.putVector3f(v.x, v.y, v.z);
+ }
+
public void putVector3f(float x, float y, float z) {
this.putLFloat(x);
this.putLFloat(y);
diff --git a/src/main/java/cn/nukkit/utils/ClientChainData.java b/src/main/java/cn/nukkit/utils/ClientChainData.java
index b444d04100..3670e97e14 100644
--- a/src/main/java/cn/nukkit/utils/ClientChainData.java
+++ b/src/main/java/cn/nukkit/utils/ClientChainData.java
@@ -83,14 +83,6 @@ public int getDefaultInputMode() {
return defaultInputMode;
}
- public String getADRole() {
- return ADRole;
- }
-
- public String getTenantId() {
- return tenantId;
- }
-
public final static int UI_PROFILE_CLASSIC = 0;
public final static int UI_PROFILE_POCKET = 1;
@@ -130,8 +122,6 @@ public int hashCode() {
private String languageCode;
private int currentInputMode;
private int defaultInputMode;
- private String ADRole;
- private String tenantId;
private int UIProfile;
@@ -175,8 +165,6 @@ private void decodeSkinData() {
if (skinToken.has("LanguageCode")) this.languageCode = skinToken.get("LanguageCode").getAsString();
if (skinToken.has("CurrentInputMode")) this.currentInputMode = skinToken.get("CurrentInputMode").getAsInt();
if (skinToken.has("DefaultInputMode")) this.defaultInputMode = skinToken.get("DefaultInputMode").getAsInt();
- if (skinToken.has("ADRole")) this.ADRole = skinToken.get("ADRole").getAsString();
- if (skinToken.has("TenantId")) this.tenantId = skinToken.get("TenantId").getAsString();
if (skinToken.has("UIProfile")) this.UIProfile = skinToken.get("UIProfile").getAsInt();
}
diff --git a/src/test/java/cn/nukkit/test/ClientChainDataTest.java b/src/test/java/cn/nukkit/test/ClientChainDataTest.java
index 09476116e6..a6cec4b87e 100644
--- a/src/test/java/cn/nukkit/test/ClientChainDataTest.java
+++ b/src/test/java/cn/nukkit/test/ClientChainDataTest.java
@@ -30,8 +30,7 @@ void testGetter() throws Exception {
"deviceOS=%d, gameVersion=%s, " +
"guiScale=%d, languageCode=%s, " +
"xuid=%s, currentInputMode=%d, " +
- "defaultInputMode=%d, ADRole=%s," +
- "tenantId=%s, UIProfile=%d"
+ "defaultInputMode=%d, UIProfile=%d"
,
data.getUsername(), data.getClientUUID(),
data.getIdentityPublicKey(), data.getClientId(),
@@ -39,8 +38,7 @@ void testGetter() throws Exception {
data.getDeviceOS(), data.getGameVersion(),
data.getGuiScale(), data.getLanguageCode(),
data.getXUID(), data.getCurrentInputMode(),
- data.getDefaultInputMode(), data.getADRole(),
- data.getTenantId(), data.getUIProfile()
+ data.getDefaultInputMode(), data.getUIProfile()
);
String expecting = "userName=lmlstarqaq, clientUUID=8323afe1-641e-3b61-9a92-d5d20b279065, " +
"identityPublicKey=MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4lyvA1iVhV2u3pLQqJAjJnJZSlSjib8mM1uB5h5yqOBSvCHW+nZxDmkOAW6MS1GA7yGHitGmfS4jW/yUISUdWvLzEWJYOzphb3GNh5J1oLJRwESc5278i4MEDk1y21/q, " +
@@ -49,8 +47,7 @@ void testGetter() throws Exception {
"deviceOS=2, gameVersion=1.1.0, " +
"guiScale=0, languageCode=zh_CN, " +
"xuid=2535465134455915, currentInputMode=2, " +
- "defaultInputMode=2, ADRole=2,tenantId=, " +
- "UIProfile=1";
+ "defaultInputMode=2, UIProfile=1";
assertEquals(got, expecting);
}
From b3b90a5e7d18d0faac58ebeb770e2183bed730ed Mon Sep 17 00:00:00 2001
From: Scallop Ye <862578730@qq.com>
Date: Thu, 3 Aug 2017 09:01:52 +0800
Subject: [PATCH 032/175] Clean up byte castings in inventory packets
---
.../cn/nukkit/blockentity/BlockEntityBrewingStand.java | 2 +-
.../java/cn/nukkit/blockentity/BlockEntityFurnace.java | 4 ++--
src/main/java/cn/nukkit/inventory/BaseInventory.java | 4 ++--
src/main/java/cn/nukkit/inventory/ContainerInventory.java | 6 +++---
.../cn/nukkit/inventory/PlayerEnderChestInventory.java | 6 +++---
src/main/java/cn/nukkit/inventory/PlayerInventory.java | 4 ++--
.../cn/nukkit/network/protocol/ContainerOpenPacket.java | 8 ++++----
.../nukkit/network/protocol/ContainerSetDataPacket.java | 4 ++--
8 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java b/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java
index ecf277b113..04d9ea9b3f 100644
--- a/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java
+++ b/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java
@@ -188,7 +188,7 @@ public boolean onUpdate() {
int windowId = player.getWindowId(this.inventory);
if (windowId > 0) {
ContainerSetDataPacket pk = new ContainerSetDataPacket();
- pk.windowid = (byte) windowId;
+ pk.windowid = windowId;
pk.property = 0;
pk.value = this.brewTime;
player.dataPacket(pk);
diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityFurnace.java b/src/main/java/cn/nukkit/blockentity/BlockEntityFurnace.java
index 4cac086701..205d9465af 100644
--- a/src/main/java/cn/nukkit/blockentity/BlockEntityFurnace.java
+++ b/src/main/java/cn/nukkit/blockentity/BlockEntityFurnace.java
@@ -262,13 +262,13 @@ public boolean onUpdate() {
int windowId = player.getWindowId(this.getInventory());
if (windowId > 0) {
ContainerSetDataPacket pk = new ContainerSetDataPacket();
- pk.windowid = (byte) windowId;
+ pk.windowid = windowId;
pk.property = 0;
pk.value = cookTime;
player.dataPacket(pk);
pk = new ContainerSetDataPacket();
- pk.windowid = (byte) windowId;
+ pk.windowid = windowId;
pk.property = 1;
pk.value = burnDuration;
player.dataPacket(pk);
diff --git a/src/main/java/cn/nukkit/inventory/BaseInventory.java b/src/main/java/cn/nukkit/inventory/BaseInventory.java
index c6ef2d5f14..9b58435754 100644
--- a/src/main/java/cn/nukkit/inventory/BaseInventory.java
+++ b/src/main/java/cn/nukkit/inventory/BaseInventory.java
@@ -450,7 +450,7 @@ public void sendContents(Player[] players) {
this.close(player);
continue;
}
- pk.inventoryId = (byte) id;
+ pk.inventoryId = id;
player.dataPacket(pk);
}
}
@@ -525,7 +525,7 @@ public void sendSlot(int index, Player[] players) {
this.close(player);
continue;
}
- pk.inventoryId = (byte) id;
+ pk.inventoryId = id;
player.dataPacket(pk);
}
}
diff --git a/src/main/java/cn/nukkit/inventory/ContainerInventory.java b/src/main/java/cn/nukkit/inventory/ContainerInventory.java
index 519db2b712..f92cc37d98 100644
--- a/src/main/java/cn/nukkit/inventory/ContainerInventory.java
+++ b/src/main/java/cn/nukkit/inventory/ContainerInventory.java
@@ -34,8 +34,8 @@ public ContainerInventory(InventoryHolder holder, InventoryType type, Map
Date: Thu, 3 Aug 2017 19:59:13 +0200
Subject: [PATCH 033/175] Join crash fixed. Chunks still corrupted (#44)
* Some new StartGamePacket fields
* Some new packets
ModalForm is the coolest one, I think :D
* It seems that chunk light should not send
* Do not send BlockLight
* Do not send blockLight
* Do not send light
---
.../java/cn/nukkit/level/format/anvil/Anvil.java | 2 --
.../java/cn/nukkit/level/format/anvil/Chunk.java | 5 -----
.../level/format/anvil/ChunkRequestTask.java | 4 ----
.../cn/nukkit/level/format/anvil/ChunkSection.java | 2 --
.../cn/nukkit/network/protocol/ProtocolInfo.java | 5 +++++
.../nukkit/network/protocol/StartGamePacket.java | 14 ++++++++++++++
6 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/src/main/java/cn/nukkit/level/format/anvil/Anvil.java b/src/main/java/cn/nukkit/level/format/anvil/Anvil.java
index 6ab251d841..a1269277fb 100644
--- a/src/main/java/cn/nukkit/level/format/anvil/Anvil.java
+++ b/src/main/java/cn/nukkit/level/format/anvil/Anvil.java
@@ -342,8 +342,6 @@ public static ChunkSection createChunkSection(int y) {
nbt.putByteArray("Data", new byte[2048]);
byte[] sl = new byte[2048];
Arrays.fill(sl, (byte) 0xff);
- nbt.putByteArray("SkyLight", sl);
- nbt.putByteArray("BlockLight", new byte[2048]);
return new ChunkSection(nbt);
}
diff --git a/src/main/java/cn/nukkit/level/format/anvil/Chunk.java b/src/main/java/cn/nukkit/level/format/anvil/Chunk.java
index bbd57791d8..ae55c213e7 100644
--- a/src/main/java/cn/nukkit/level/format/anvil/Chunk.java
+++ b/src/main/java/cn/nukkit/level/format/anvil/Chunk.java
@@ -297,8 +297,6 @@ public byte[] toFastBinary() {
s.putByte("Y", section.getY());
s.putByteArray("Blocks", section.getIdArray());
s.putByteArray("Data", section.getDataArray());
- s.putByteArray("BlockLight", section.getLightArray());
- s.putByteArray("SkyLight", section.getSkyLightArray());
nbt.getList("Sections", CompoundTag.class).add(s);
}
@@ -379,8 +377,6 @@ public byte[] toBinary() {
s.putByte("Y", (section.getY()));
s.putByteArray("Blocks", section.getIdArray());
s.putByteArray("Data", section.getDataArray());
- s.putByteArray("BlockLight", section.getLightArray());
- s.putByteArray("SkyLight", section.getSkyLightArray());
sectionList.add(s);
}
nbt.putList(sectionList);
@@ -476,7 +472,6 @@ public static Chunk getEmptyChunk(int chunkX, int chunkZ, LevelProvider provider
chunk.nbt.putLong("InhabitedTime", 0);
chunk.nbt.putBoolean("TerrainGenerated", false);
chunk.nbt.putBoolean("TerrainPopulated", false);
- chunk.nbt.putBoolean("LightPopulated", false);
return chunk;
} catch (Exception e) {
diff --git a/src/main/java/cn/nukkit/level/format/anvil/ChunkRequestTask.java b/src/main/java/cn/nukkit/level/format/anvil/ChunkRequestTask.java
index 299d12db02..b4f9c55d9f 100644
--- a/src/main/java/cn/nukkit/level/format/anvil/ChunkRequestTask.java
+++ b/src/main/java/cn/nukkit/level/format/anvil/ChunkRequestTask.java
@@ -72,8 +72,6 @@ public void onRun() {
for (int z = 0; z < 16; ++z) {
orderedIds.put(this.getColumn(ids, x, z));
orderedData.put(this.getHalfColumn(meta, x, z));
- orderedSkyLight.put(this.getHalfColumn(skyLight, x, z));
- orderedLight.put(this.getHalfColumn(blockLight, x, z));
}
}
@@ -90,8 +88,6 @@ public void onRun() {
buffer
.put(orderedIds)
.put(orderedData)
- .put(orderedSkyLight)
- .put(orderedLight)
.put(orderedHeightMap)
.put(orderedBiomeColors)
.put(this.blockEntities)
diff --git a/src/main/java/cn/nukkit/level/format/anvil/ChunkSection.java b/src/main/java/cn/nukkit/level/format/anvil/ChunkSection.java
index 01df616960..60cc152b96 100644
--- a/src/main/java/cn/nukkit/level/format/anvil/ChunkSection.java
+++ b/src/main/java/cn/nukkit/level/format/anvil/ChunkSection.java
@@ -277,8 +277,6 @@ public byte[] getBytes() {
return buffer
.put(blocks)
.put(data)
- .put(skyLight)
- .put(blockLight)
.array();
}
diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
index 1f3105e109..d0ffa46bc1 100644
--- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
+++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
@@ -108,5 +108,10 @@ public interface ProtocolInfo {
byte SET_LAST_HURT_BY_PACKET = 0x60;
byte BOOK_EDIT_PACKET = 0x61;
byte NPC_REQUEST_PACKET = 0x62;
+ byte PHOTO_TRANSFER_PACKET = 0x63;
+ byte MODAL_FORM_REQUEST_PACKET = 0x64;
+ byte MODAL_FORM_RESPONSE_PACKET = 0x65;
+ byte SERVER_SETTINGS_REQUEST_PACKET = 0x66;
+ byte SERVER_SETTINGS_RESPONSE_PACKET = 0x67;
byte BATCH_PACKET = (byte) 0xff;
}
diff --git a/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java b/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java
index efcb72ae2a..24c8aa0921 100644
--- a/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java
@@ -35,9 +35,16 @@ public byte pid() {
public boolean eduMode = false;
public float rainLevel;
public float lightningLevel;
+ public boolean multiplayerGame = true;
+ public boolean broadcastToLAN = true;
+ public boolean broadcastToXboxLive = true;
public boolean commandsEnabled;
public boolean isTexturePacksRequired = false;
public RuleData[] ruleDatas = new RuleData[0];
+ public boolean bonusChest = false;
+ public boolean trustPlayers = false;
+ public int permissionLevel = 1;
+ public int gamePublish = 4;
public String levelId = ""; //base64 string, usually the same as world folder name in vanilla
public String worldName;
public String premiumWorldTemplateId = "";
@@ -69,12 +76,19 @@ public void encode() {
this.putBoolean(this.eduMode);
this.putLFloat(this.rainLevel);
this.putLFloat(this.lightningLevel);
+ this.putBoolean(this.multiplayerGame);
+ this.putBoolean(this.broadcastToLAN);
+ this.putBoolean(this.broadcastToXboxLive);
this.putBoolean(this.commandsEnabled);
this.putBoolean(this.isTexturePacksRequired);
this.putUnsignedVarInt(this.ruleDatas.length);
for (RuleData rule : this.ruleDatas) {
this.putRuleData(rule);
}
+ this.putBoolean(this.bonusChest);
+ this.putBoolean(this.trustPlayers);
+ this.putVarInt(this.permissionLevel);
+ this.putVarInt(this.gamePublish);
this.putString(this.levelId);
this.putString(this.worldName);
this.putString(this.premiumWorldTemplateId);
From 498db2dc964b095686bf40bb347552d3ee447e29 Mon Sep 17 00:00:00 2001
From: Scallop Ye <862578730@qq.com>
Date: Sat, 5 Aug 2017 21:10:24 +0800
Subject: [PATCH 034/175] Packets cleanup and fix
---
src/main/java/cn/nukkit/Player.java | 13 ++--
.../protocol/AddBehaviorTreePacket.java | 5 +-
.../network/protocol/AnimatePacket.java | 4 +-
.../network/protocol/BossEventPacket.java | 76 +++++++++++++++++--
.../nukkit/network/protocol/CameraPacket.java | 10 ++-
.../protocol/ChangeDimensionPacket.java | 4 +-
.../protocol/CommandBlockUpdatePacket.java | 46 ++++++++++-
.../network/protocol/EntityEventPacket.java | 12 +--
.../network/protocol/InteractPacket.java | 16 ++--
.../network/protocol/MovePlayerPacket.java | 14 ++--
.../nukkit/network/protocol/ProtocolInfo.java | 8 +-
.../network/protocol/SimpleEventPacket.java | 4 +-
.../protocol/UpdateEquipmentPacket.java | 13 +++-
.../java/cn/nukkit/utils/BinaryStream.java | 19 ++---
14 files changed, 182 insertions(+), 62 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index fb691aea2a..f4382e1f93 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -4047,11 +4047,11 @@ public void sendPosition(Vector3 pos, double yaw, double pitch) {
this.sendPosition(pos, yaw, pitch, MovePlayerPacket.MODE_NORMAL);
}
- public void sendPosition(Vector3 pos, double yaw, double pitch, byte mode) {
+ public void sendPosition(Vector3 pos, double yaw, double pitch, int mode) {
this.sendPosition(pos, yaw, pitch, mode, null);
}
- public void sendPosition(Vector3 pos, double yaw, double pitch, byte mode, Player[] targets) {
+ public void sendPosition(Vector3 pos, double yaw, double pitch, int mode, Player[] targets) {
MovePlayerPacket pk = new MovePlayerPacket();
pk.eid = this.getId();
pk.x = (float) pos.x;
@@ -4292,7 +4292,8 @@ public void teleportImmediate(Location location, TeleportCause cause) {
* @param length The BossBar percentage
* @return bossBarId The BossBar ID, you should store it if you want to remove or update the BossBar later
*/
- public long createBossBar(String text, int length) {
+
+ /*public long createBossBar(String text, int length) {
// First we spawn a entity
long bossBarId = 1095216660480L + ThreadLocalRandom.current().nextLong(0, 0x7fffffffL);
AddEntityPacket pkAdd = new AddEntityPacket();
@@ -4333,7 +4334,7 @@ public long createBossBar(String text, int length) {
pkBoss.type = BossEventPacket.ADD;
this.dataPacket(pkBoss);
return bossBarId;
- }
+ }*/
/**
* Updates a BossBar
@@ -4342,7 +4343,7 @@ public long createBossBar(String text, int length) {
* @param length The new BossBar length
* @param bossBarId The BossBar ID
*/
- public void updateBossBar(String text, int length, long bossBarId) {
+ /*public void updateBossBar(String text, int length, long bossBarId) {
// First we update the boss bar length
UpdateAttributesPacket pkAttributes = new UpdateAttributesPacket();
pkAttributes.entityId = bossBarId;
@@ -4371,7 +4372,7 @@ public void updateBossBar(String text, int length, long bossBarId) {
pkBoss.type = BossEventPacket.UPDATE;
this.dataPacket(pkBoss);
return;
- }
+ }*/
/**
* Removes a BossBar
diff --git a/src/main/java/cn/nukkit/network/protocol/AddBehaviorTreePacket.java b/src/main/java/cn/nukkit/network/protocol/AddBehaviorTreePacket.java
index 0f35174c40..ce3fa07196 100644
--- a/src/main/java/cn/nukkit/network/protocol/AddBehaviorTreePacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/AddBehaviorTreePacket.java
@@ -2,6 +2,8 @@
public class AddBehaviorTreePacket extends DataPacket {
+ public String unknown;
+
@Override
public byte pid() {
return ProtocolInfo.ADD_BEHAVIOR_TREE_PACKET;
@@ -14,6 +16,7 @@ public void decode() {
@Override
public void encode() {
- //TODO
+ this.reset();
+ this.putString(unknown);
}
}
diff --git a/src/main/java/cn/nukkit/network/protocol/AnimatePacket.java b/src/main/java/cn/nukkit/network/protocol/AnimatePacket.java
index 8a7efec1f3..562b378827 100644
--- a/src/main/java/cn/nukkit/network/protocol/AnimatePacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/AnimatePacket.java
@@ -13,7 +13,7 @@ public class AnimatePacket extends DataPacket {
@Override
public void decode() {
- this.action = (int) this.getUnsignedVarInt();
+ this.action = this.getVarInt();
this.eid = getVarLong();
if ((this.action & 0x80) != 0) {
this.unknown = this.getLFloat();
@@ -23,7 +23,7 @@ public void decode() {
@Override
public void encode() {
this.reset();
- this.putUnsignedVarInt(this.action);
+ this.putVarInt(this.action);
this.putVarLong(this.eid);
if ((this.action & 0x80) != 0) {
this.putLFloat(this.unknown);
diff --git a/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java b/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java
index 6ab6cf58e5..0595d991b1 100644
--- a/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java
@@ -7,12 +7,31 @@ public class BossEventPacket extends DataPacket {
public static final byte NETWORK_ID = ProtocolInfo.BOSS_EVENT_PACKET;
- public long eid;
- public int type;
+ /* S2C: Shows the boss-bar to the player. */
+ public static final int TYPE_SHOW = 0;
+ /* C2S: Registers a player to a boss fight. */
+ public static final int TYPE_REGISTER_PLAYER = 1;
+ /* S2C: Removes the boss-bar from the client. */
+ public static final int TYPE_HIDE = 2;
+ /* C2S: Unregisters a player from a boss fight. */
+ public static final int TYPE_UNREGISTER_PLAYER = 3;
+ /* S2C: Appears not to be implemented. Currently bar percentage only appears to change in response to the target entity's health. */
+ public static final int TYPE_HEALTH_PERCENT = 4;
+ /* S2C: Also appears to not be implemented. Title client-side sticks as the target entity's nametag, or their entity type name if not set. */
+ public static final int TYPE_TITLE = 5;
+ /* S2C: Not sure on this. Includes color and overlay fields, plus an unknown short. TODO: check this */
+ public static final int TYPE_UNKNOWN_6 = 6;
+ /* S2C: Not implemented :( Intended to alter bar appearance, but these currently produce no effect on client-side whatsoever. */
+ public static final int TYPE_TEXTURE = 7;
- public static final int ADD = 0;
- public static final int UPDATE = 1;
- public static final int REMOVE = 2;
+ public long bossEid;
+ public int type;
+ public long playerEid;
+ public float healthPercent;
+ public String title;
+ public short unknown;
+ public int color;
+ public int overlay;
@Override
public byte pid() {
@@ -21,13 +40,56 @@ public byte pid() {
@Override
public void decode() {
-
+ this.bossEid = this.getVarLong();
+ this.type = (int) this.getUnsignedVarInt();
+ switch (this.type) {
+ case TYPE_REGISTER_PLAYER:
+ case TYPE_UNREGISTER_PLAYER:
+ this.playerEid = this.getLong();
+ break;
+ case TYPE_SHOW:
+ this.title = this.getString();
+ this.healthPercent = this.getLFloat();
+ case TYPE_UNKNOWN_6:
+ this.unknown = (short) this.getShort();
+ case TYPE_TEXTURE:
+ this.color = (int) this.getUnsignedVarInt();
+ this.overlay = (int) this.getUnsignedVarInt();
+ break;
+ case TYPE_HEALTH_PERCENT:
+ this.healthPercent = this.getLFloat();
+ break;
+ case TYPE_TITLE:
+ this.title = this.getString();
+ break;
+ }
}
@Override
public void encode() {
this.reset();
- this.putVarLong(this.eid);
+ this.putVarLong(this.bossEid);
this.putUnsignedVarInt(this.type);
+ switch (this.type) {
+ case TYPE_REGISTER_PLAYER:
+ case TYPE_UNREGISTER_PLAYER:
+ this.putLong(this.playerEid);
+ break;
+ case TYPE_SHOW:
+ this.putString(this.title);
+ this.putLFloat(this.healthPercent);
+ case TYPE_UNKNOWN_6:
+ this.putShort(this.unknown);
+ case TYPE_TEXTURE:
+ this.putUnsignedVarInt(this.color);
+ this.putUnsignedVarInt(this.overlay);
+ break;
+ case TYPE_HEALTH_PERCENT:
+ this.putLFloat(this.healthPercent);
+ break;
+ case TYPE_TITLE:
+ this.putString(this.title);
+ break;
+ }
}
}
diff --git a/src/main/java/cn/nukkit/network/protocol/CameraPacket.java b/src/main/java/cn/nukkit/network/protocol/CameraPacket.java
index d3b163a912..98ddcf8629 100644
--- a/src/main/java/cn/nukkit/network/protocol/CameraPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/CameraPacket.java
@@ -2,6 +2,9 @@
public class CameraPacket extends DataPacket {
+ public long cameraUniqueId;
+ public long playerUniqueId;
+
@Override
public byte pid() {
return ProtocolInfo.CAMERA_PACKET;
@@ -9,11 +12,14 @@ public byte pid() {
@Override
public void decode() {
-
+ this.cameraUniqueId = this.getVarLong();
+ this.playerUniqueId = this.getVarLong();
}
@Override
public void encode() {
-
+ this.reset();
+ this.putVarLong(this.cameraUniqueId);
+ this.putVarLong(this.playerUniqueId);
}
}
diff --git a/src/main/java/cn/nukkit/network/protocol/ChangeDimensionPacket.java b/src/main/java/cn/nukkit/network/protocol/ChangeDimensionPacket.java
index 87a91c2e8e..5341227779 100644
--- a/src/main/java/cn/nukkit/network/protocol/ChangeDimensionPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/ChangeDimensionPacket.java
@@ -14,7 +14,7 @@ public class ChangeDimensionPacket extends DataPacket {
public float y;
public float z;
- public boolean unknown;
+ public boolean respawn;
@Override
public void decode() {
@@ -26,7 +26,7 @@ public void encode() {
this.reset();
this.putVarInt(this.dimension);
this.putVector3f(this.x, this.y, this.z);
- this.putBoolean(this.unknown);
+ this.putBoolean(this.respawn);
}
@Override
diff --git a/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java b/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java
index b9ebe5ba1a..fbd9ef3236 100644
--- a/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java
@@ -1,7 +1,22 @@
package cn.nukkit.network.protocol;
+import cn.nukkit.math.BlockVector3;
+
public class CommandBlockUpdatePacket extends DataPacket {
+ public boolean isBlock;
+ public int x;
+ public int y;
+ public int z;
+ public int commandBlockMode;
+ public boolean isRedstoneMode;
+ public boolean isConditional;
+ public long minecartEid;
+ public String command;
+ public String lastOutput;
+ public String name;
+ public boolean shouldTrackOutput;
+
@Override
public byte pid() {
return ProtocolInfo.COMMAND_BLOCK_UPDATE_PACKET;
@@ -9,11 +24,38 @@ public byte pid() {
@Override
public void decode() {
- //TODO
+ this.isBlock = this.getBoolean();
+ if (this.isBlock) {
+ BlockVector3 v = this.getBlockVector3();
+ this.x = v.x;
+ this.y = v.y;
+ this.z = v.z;
+ this.commandBlockMode = (int) this.getUnsignedVarInt();
+ this.isRedstoneMode = this.getBoolean();
+ this.isConditional = this.getBoolean();
+ } else {
+ this.minecartEid = this.getVarLong();
+ }
+ this.command = this.getString();
+ this.lastOutput = this.getString();
+ this.name = this.getString();
+ this.shouldTrackOutput = this.getBoolean();
}
@Override
public void encode() {
-
+ this.putBoolean(this.isBlock);
+ if (this.isBlock) {
+ this.putBlockVector3(this.x, this.y, this.z);
+ this.putUnsignedVarInt(this.commandBlockMode);
+ this.putBoolean(this.isRedstoneMode);
+ this.putBoolean(this.isConditional);
+ } else {
+ this.putVarLong(this.minecartEid);
+ }
+ this.putString(this.command);
+ this.putString(this.lastOutput);
+ this.putString(this.name);
+ this.putBoolean(this.shouldTrackOutput);
}
}
diff --git a/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java b/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java
index 074338725c..0a3c41e147 100644
--- a/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java
@@ -30,21 +30,21 @@ public byte pid() {
}
public long eid;
- public byte event;
- public long unknown;
+ public int event;
+ public int type;
@Override
public void decode() {
this.eid = this.getVarLong();
- this.event = (byte) this.getByte();
- this.unknown = this.getUnsignedVarInt();
+ this.event = this.getByte();
+ this.type = this.getByte();
}
@Override
public void encode() {
this.reset();
this.putVarLong(this.eid);
- this.putByte(this.event);
- this.putUnsignedVarInt(this.unknown);
+ this.putByte((byte) this.event);
+ this.putByte((byte) this.type);
}
}
diff --git a/src/main/java/cn/nukkit/network/protocol/InteractPacket.java b/src/main/java/cn/nukkit/network/protocol/InteractPacket.java
index 6d49409e24..ccce4ddd5b 100644
--- a/src/main/java/cn/nukkit/network/protocol/InteractPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/InteractPacket.java
@@ -7,26 +7,26 @@ public class InteractPacket extends DataPacket {
public static final byte NETWORK_ID = ProtocolInfo.INTERACT_PACKET;
- public static final byte ACTION_RIGHT_CLICK = 1;
- public static final byte ACTION_LEFT_CLICK = 2;
- public static final byte ACTION_VEHICLE_EXIT = 3;
- public static final byte ACTION_MOUSEOVER = 4;
+ public static final int ACTION_RIGHT_CLICK = 1;
+ public static final int ACTION_LEFT_CLICK = 2;
+ public static final int ACTION_VEHICLE_EXIT = 3;
+ public static final int ACTION_MOUSEOVER = 4;
- public static final byte ACTION_OPEN_INVENTORY = 6;
+ public static final int ACTION_OPEN_INVENTORY = 6;
- public byte action;
+ public int action;
public long target;
@Override
public void decode() {
- this.action = (byte) this.getByte();
+ this.action = this.getByte();
this.target = this.getVarLong();
}
@Override
public void encode() {
this.reset();
- this.putByte(this.action);
+ this.putByte((byte) this.action);
this.putVarLong(this.target);
}
diff --git a/src/main/java/cn/nukkit/network/protocol/MovePlayerPacket.java b/src/main/java/cn/nukkit/network/protocol/MovePlayerPacket.java
index 1745370746..d37234244d 100644
--- a/src/main/java/cn/nukkit/network/protocol/MovePlayerPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/MovePlayerPacket.java
@@ -9,10 +9,10 @@ public class MovePlayerPacket extends DataPacket {
public static final byte NETWORK_ID = ProtocolInfo.MOVE_PLAYER_PACKET;
- public static final byte MODE_NORMAL = 0;
- public static final byte MODE_RESET = 1;
- public static final byte MODE_TELEPORT = 2;
- public static final byte MODE_PITCH = 3; //facepalm Mojang
+ public static final int MODE_NORMAL = 0;
+ public static final int MODE_RESET = 1;
+ public static final int MODE_TELEPORT = 2;
+ public static final int MODE_PITCH = 3; //facepalm Mojang
public long eid;
public float x;
@@ -21,7 +21,7 @@ public class MovePlayerPacket extends DataPacket {
public float yaw;
public float headYaw;
public float pitch;
- public byte mode = MODE_NORMAL;
+ public int mode = MODE_NORMAL;
public boolean onGround;
public long ridingEid;
public int int1 = 0;
@@ -37,7 +37,7 @@ public void decode() {
this.pitch = this.getLFloat();
this.headYaw = this.getLFloat();
this.yaw = this.getLFloat();
- this.mode = (byte) this.getByte();
+ this.mode = this.getByte();
this.onGround = this.getBoolean();
this.ridingEid = this.getVarLong();
if (this.mode == MODE_TELEPORT){
@@ -54,7 +54,7 @@ public void encode() {
this.putLFloat(this.pitch);
this.putLFloat(this.yaw);
this.putLFloat(this.headYaw);
- this.putByte(this.mode);
+ this.putByte((byte) this.mode);
this.putBoolean(this.onGround);
this.putVarLong(this.ridingEid);
if (this.mode == MODE_TELEPORT){
diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
index d0ffa46bc1..a2eb5daf33 100644
--- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
+++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
@@ -109,9 +109,9 @@ public interface ProtocolInfo {
byte BOOK_EDIT_PACKET = 0x61;
byte NPC_REQUEST_PACKET = 0x62;
byte PHOTO_TRANSFER_PACKET = 0x63;
- byte MODAL_FORM_REQUEST_PACKET = 0x64;
- byte MODAL_FORM_RESPONSE_PACKET = 0x65;
- byte SERVER_SETTINGS_REQUEST_PACKET = 0x66;
- byte SERVER_SETTINGS_RESPONSE_PACKET = 0x67;
+ byte MODAL_FORM_REQUEST_PACKET = 0x64;
+ byte MODAL_FORM_RESPONSE_PACKET = 0x65;
+ byte SERVER_SETTINGS_REQUEST_PACKET = 0x66;
+ byte SERVER_SETTINGS_RESPONSE_PACKET = 0x67;
byte BATCH_PACKET = (byte) 0xff;
}
diff --git a/src/main/java/cn/nukkit/network/protocol/SimpleEventPacket.java b/src/main/java/cn/nukkit/network/protocol/SimpleEventPacket.java
index 163224e04d..04d26e6ac2 100644
--- a/src/main/java/cn/nukkit/network/protocol/SimpleEventPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/SimpleEventPacket.java
@@ -2,6 +2,8 @@
public class SimpleEventPacket extends DataPacket {
+ public short unknown;
+
@Override
public byte pid() {
return ProtocolInfo.SIMPLE_EVENT_PACKET;
@@ -14,6 +16,6 @@ public void decode() {
@Override
public void encode() {
- //TODO
+ this.putShort(this.unknown);
}
}
diff --git a/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java b/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java
index 27c8f40ff5..54184041c7 100644
--- a/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java
@@ -2,6 +2,14 @@
public class UpdateEquipmentPacket extends DataPacket {
+ public int windowId;
+ public int windowType;
+ public int unknown; //TODO: find out what this is (vanilla always sends 0)
+ public long eid;
+ public byte[] namedtag;
+
+
+
@Override
public byte pid() {
return ProtocolInfo.UPDATE_EQUIPMENT_PACKET;
@@ -14,6 +22,9 @@ public void decode() {
@Override
public void encode() {
- //TODO
+ this.putByte((byte) this.windowId);
+ this.putByte((byte) this.windowType);
+ this.putVarLong(this.eid);
+ this.put(this.namedtag);
}
}
diff --git a/src/main/java/cn/nukkit/utils/BinaryStream.java b/src/main/java/cn/nukkit/utils/BinaryStream.java
index abfd4ea185..44a42df741 100644
--- a/src/main/java/cn/nukkit/utils/BinaryStream.java
+++ b/src/main/java/cn/nukkit/utils/BinaryStream.java
@@ -213,18 +213,12 @@ public Attribute[] getAttributeList() throws Exception {
long count = this.getUnsignedVarInt();
for(int i = 0; i < count; ++i){
- float min = this.getLFloat();
- float max = this.getLFloat();
- float current = this.getLFloat();
- float defaultValue = this.getLFloat();
String name = this.getString();
-
Attribute attr = Attribute.getAttributeByName(name);
if(attr != null){
- attr.setMinValue(min);
- attr.setMaxValue(max);
- attr.setValue(current);
- attr.setDefaultValue(defaultValue);
+ attr.setMinValue(this.getLFloat());
+ attr.setValue(this.getLFloat());
+ attr.setMaxValue(this.getLFloat());
list.add(attr);
}else{
throw new Exception("Unknown attribute type \"" + name + "\"");
@@ -239,12 +233,11 @@ public Attribute[] getAttributeList() throws Exception {
*/
public void putAttributeList(Attribute[] attributes){
this.putUnsignedVarInt(attributes.length);
- for (Attribute attribute: attributes){
+ for (Attribute attribute: attributes) {
+ this.putString(attribute.getName());
this.putLFloat(attribute.getMinValue());
- this.putLFloat(attribute.getMaxValue());
this.putLFloat(attribute.getValue());
- this.putLFloat(attribute.getDefaultValue());
- this.putString(attribute.getName());
+ this.putLFloat(attribute.getMaxValue());
}
}
From cea38607da476ee40658bcd450f54e73e6c37f29 Mon Sep 17 00:00:00 2001
From: Scallop Ye <862578730@qq.com>
Date: Sun, 6 Aug 2017 10:06:52 +0800
Subject: [PATCH 035/175] Revert local world breaking changes
---
src/main/java/cn/nukkit/level/format/anvil/Anvil.java | 2 ++
src/main/java/cn/nukkit/level/format/anvil/Chunk.java | 5 +++++
2 files changed, 7 insertions(+)
diff --git a/src/main/java/cn/nukkit/level/format/anvil/Anvil.java b/src/main/java/cn/nukkit/level/format/anvil/Anvil.java
index a1269277fb..8b54b1b2d9 100644
--- a/src/main/java/cn/nukkit/level/format/anvil/Anvil.java
+++ b/src/main/java/cn/nukkit/level/format/anvil/Anvil.java
@@ -342,6 +342,8 @@ public static ChunkSection createChunkSection(int y) {
nbt.putByteArray("Data", new byte[2048]);
byte[] sl = new byte[2048];
Arrays.fill(sl, (byte) 0xff);
+ nbt.putByteArray("SkyLight", sl);
+ nbt.putByteArray("BlockLight", new byte[2048]);
return new ChunkSection(nbt);
}
diff --git a/src/main/java/cn/nukkit/level/format/anvil/Chunk.java b/src/main/java/cn/nukkit/level/format/anvil/Chunk.java
index ae55c213e7..bbd57791d8 100644
--- a/src/main/java/cn/nukkit/level/format/anvil/Chunk.java
+++ b/src/main/java/cn/nukkit/level/format/anvil/Chunk.java
@@ -297,6 +297,8 @@ public byte[] toFastBinary() {
s.putByte("Y", section.getY());
s.putByteArray("Blocks", section.getIdArray());
s.putByteArray("Data", section.getDataArray());
+ s.putByteArray("BlockLight", section.getLightArray());
+ s.putByteArray("SkyLight", section.getSkyLightArray());
nbt.getList("Sections", CompoundTag.class).add(s);
}
@@ -377,6 +379,8 @@ public byte[] toBinary() {
s.putByte("Y", (section.getY()));
s.putByteArray("Blocks", section.getIdArray());
s.putByteArray("Data", section.getDataArray());
+ s.putByteArray("BlockLight", section.getLightArray());
+ s.putByteArray("SkyLight", section.getSkyLightArray());
sectionList.add(s);
}
nbt.putList(sectionList);
@@ -472,6 +476,7 @@ public static Chunk getEmptyChunk(int chunkX, int chunkZ, LevelProvider provider
chunk.nbt.putLong("InhabitedTime", 0);
chunk.nbt.putBoolean("TerrainGenerated", false);
chunk.nbt.putBoolean("TerrainPopulated", false);
+ chunk.nbt.putBoolean("LightPopulated", false);
return chunk;
} catch (Exception e) {
From b6354ad4727f9be2312ccf4dfad72464fd0f2956 Mon Sep 17 00:00:00 2001
From: Scallop Ye <862578730@qq.com>
Date: Sun, 6 Aug 2017 10:50:18 +0800
Subject: [PATCH 036/175] Fix corrupted chunks
---
.../cn/nukkit/level/format/anvil/ChunkSection.java | 10 +---------
.../nukkit/level/format/generic/EmptyChunkSection.java | 8 +-------
2 files changed, 2 insertions(+), 16 deletions(-)
diff --git a/src/main/java/cn/nukkit/level/format/anvil/ChunkSection.java b/src/main/java/cn/nukkit/level/format/anvil/ChunkSection.java
index 60cc152b96..5c290cad7e 100644
--- a/src/main/java/cn/nukkit/level/format/anvil/ChunkSection.java
+++ b/src/main/java/cn/nukkit/level/format/anvil/ChunkSection.java
@@ -251,11 +251,9 @@ public boolean isEmpty() {
@Override
public byte[] getBytes() {
- ByteBuffer buffer = ByteBuffer.allocate(10240);
+ ByteBuffer buffer = ByteBuffer.allocate(6144);
byte[] blocks = new byte[4096];
byte[] data = new byte[2048];
- byte[] skyLight = new byte[2048];
- byte[] blockLight = new byte[2048];
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
int i = (x << 7) | (z << 3);
@@ -265,12 +263,6 @@ public byte[] getBytes() {
int b1 = this.getBlockData(x, y, z);
int b2 = this.getBlockData(x, y + 1, z);
data[i | (y >> 1)] = (byte) ((b2 << 4) | b1);
- b1 = this.getBlockSkyLight(x, y, z);
- b2 = this.getBlockSkyLight(x, y + 1, z);
- skyLight[i | (y >> 1)] = (byte) ((b2 << 4) | b1);
- b1 = this.getBlockLight(x, y, z);
- b2 = this.getBlockLight(x, y + 1, z);
- blockLight[i | (y >> 1)] = (byte) ((b2 << 4) | b1);
}
}
}
diff --git a/src/main/java/cn/nukkit/level/format/generic/EmptyChunkSection.java b/src/main/java/cn/nukkit/level/format/generic/EmptyChunkSection.java
index b60a808572..f7eb1072e2 100644
--- a/src/main/java/cn/nukkit/level/format/generic/EmptyChunkSection.java
+++ b/src/main/java/cn/nukkit/level/format/generic/EmptyChunkSection.java
@@ -131,13 +131,7 @@ public boolean isEmpty() {
@Override
public byte[] getBytes() {
- ByteBuffer buffer = ByteBuffer.allocate(10240);
- byte[] skyLight = new byte[2048];
- Arrays.fill(skyLight, (byte) 0xff);
- buffer.position(6144);
- return buffer
- .put(skyLight)
- .array();
+ return new byte[6144];
}
@Override
From 4fc794e9ec53f2441fa6e5e5b8f470df5174661e Mon Sep 17 00:00:00 2001
From: Scallop Ye <862578730@qq.com>
Date: Sun, 6 Aug 2017 10:50:55 +0800
Subject: [PATCH 037/175] Bump protocol version to 131
---
src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
index a2eb5daf33..4cabfecae6 100644
--- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
+++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
@@ -9,9 +9,9 @@ public interface ProtocolInfo {
/**
* Actual Minecraft: PE protocol version
*/
- int CURRENT_PROTOCOL = 130;
- String MINECRAFT_VERSION = "v1.2.0.2";
- String MINECRAFT_VERSION_NETWORK = "1.2.0.2";
+ int CURRENT_PROTOCOL = 131;
+ String MINECRAFT_VERSION = "v1.2.0.7 beta";
+ String MINECRAFT_VERSION_NETWORK = "1.2.0.7";
byte LOGIN_PACKET = 0x01;
byte PLAY_STATUS_PACKET = 0x02;
From 204d68e41dc7883f4dfe92719849c0abdc54e049 Mon Sep 17 00:00:00 2001
From: Scallop Ye <862578730@qq.com>
Date: Sun, 6 Aug 2017 20:58:16 +0800
Subject: [PATCH 038/175] Some protocol changes
---
src/main/java/cn/nukkit/Player.java | 39 +---------
.../protocol/AdventureSettingsPacket.java | 26 +++++++
.../protocol/AvailableCommandsPacket.java | 74 +++++++++++++++++--
.../ClientToServerHandshakePacket.java | 19 +++++
.../ClientboundMapItemDataPacket.java | 6 +-
.../protocol/CommandRequestPacket.java | 48 +++++-------
.../network/protocol/EntityEventPacket.java | 41 +++++-----
.../protocol/InventoryContentPacket.java | 11 +--
.../network/protocol/LevelEventPacket.java | 2 +-
.../nukkit/network/protocol/LoginPacket.java | 4 +
.../protocol/ModalFormRequestPacket.java | 23 ++++++
.../protocol/ModalFormResponsePacket.java | 23 ++++++
.../nukkit/network/protocol/ProtocolInfo.java | 2 +
.../protocol/ServerSettingsRequestPacket.java | 19 +++++
.../ServerSettingsResponsePacket.java | 23 ++++++
.../ServerToClientHandshakePacket.java | 23 ++++++
.../nukkit/network/protocol/TextPacket.java | 3 +
src/main/java/cn/nukkit/utils/Binary.java | 4 +-
.../java/cn/nukkit/utils/ClientChainData.java | 7 ++
19 files changed, 295 insertions(+), 102 deletions(-)
create mode 100644 src/main/java/cn/nukkit/network/protocol/ClientToServerHandshakePacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/ModalFormRequestPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/ModalFormResponsePacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/ServerSettingsRequestPacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/ServerSettingsResponsePacket.java
create mode 100644 src/main/java/cn/nukkit/network/protocol/ServerToClientHandshakePacket.java
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index f4382e1f93..07775a4240 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -507,7 +507,7 @@ public void sendCommandData() {
}
if (count > 0) {
//TODO: structure checking
- pk.commands = new Gson().toJson(data);
+ pk.commands = data;
int identifier = this.dataPacket(pk, true); // We *need* ACK so we can be sure that the client received the packet or not
Thread t = new Thread() {
public void run() {
@@ -2689,42 +2689,7 @@ public void handleDataPacket(DataPacket packet) {
}
this.craftingType = 0;
CommandRequestPacket commandRequestPacket = (CommandRequestPacket) packet;
- String commandText = commandRequestPacket.command;
- Command command = this.getServer().getCommandMap().getCommand(commandText);
- if (command != null) {
- if (commandRequestPacket.args != null && commandRequestPacket.args.size() > 0) {
- CommandParameter[] pars = command.getCommandParameters(commandRequestPacket.overload);
- if (pars != null) {
- for (CommandParameter par : pars) {
- JsonElement arg = commandRequestPacket.args.get(par.name);
- if (arg != null) {
- switch (par.type) {
- case CommandParameter.ARG_TYPE_TARGET:
- CommandArg rules = new Gson().fromJson(arg, CommandArg.class);
- commandText += " " + rules.getRules()[0].getValue();
- break;
- case CommandParameter.ARG_TYPE_BLOCK_POS:
- CommandArgBlockVector bv = new Gson().fromJson(arg, CommandArgBlockVector.class);
- commandText += " " + bv.getX() + " " + bv.getY() + " " + bv.getZ();
- break;
- case CommandParameter.ARG_TYPE_STRING:
- case CommandParameter.ARG_TYPE_STRING_ENUM:
- case CommandParameter.ARG_TYPE_RAW_TEXT:
- String string = new Gson().fromJson(arg, String.class);
- commandText += " " + string;
- break;
- default:
- commandText += " " + arg.toString();
- break;
- }
- }
- }
- } else {
- this.sendMessage(this.getServer().getLanguage().translateString(command.getUsage()));
- }
- }
- }
- PlayerCommandPreprocessEvent playerCommandPreprocessEvent = new PlayerCommandPreprocessEvent(this, "/" + commandText);
+ PlayerCommandPreprocessEvent playerCommandPreprocessEvent = new PlayerCommandPreprocessEvent(this, commandRequestPacket.command);
this.server.getPluginManager().callEvent(playerCommandPreprocessEvent);
if (playerCommandPreprocessEvent.isCancelled()) {
break;
diff --git a/src/main/java/cn/nukkit/network/protocol/AdventureSettingsPacket.java b/src/main/java/cn/nukkit/network/protocol/AdventureSettingsPacket.java
index 5d68d7f1a2..38eae516f7 100644
--- a/src/main/java/cn/nukkit/network/protocol/AdventureSettingsPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/AdventureSettingsPacket.java
@@ -6,6 +6,22 @@
public class AdventureSettingsPacket extends DataPacket {
public static final byte NETWORK_ID = ProtocolInfo.ADVENTURE_SETTINGS_PACKET;
+ public static final int ACTION_FLAG_PROHIBIT_ALL = 0;
+ public static final int ACTION_FLAG_BUILD_AND_MINE = 1;
+ public static final int ACTION_FLAG_DOORS_AND_SWITCHES = 2;
+ public static final int ACTION_FLAG_OPEN_CONTAINERS = 4;
+ public static final int ACTION_FLAG_ATTACK_PLAYERS = 8;
+ public static final int ACTION_FLAG_ATTACK_MOBS = 16;
+ public static final int ACTION_FLAG_OP = 32;
+ public static final int ACTION_FLAG_TELEPORT = 64;
+ public static final int ACTION_FLAG_DEFAULT_LEVEL_PERMISSIONS = 128;
+ public static final int ACTION_FLAG_ALLOW_ALL = 511;
+
+ public static final int PERMISSION_LEVEL_VISITOR = 0;
+ public static final int PERMISSION_LEVEL_MEMBER = 1;
+ public static final int PERMISSION_LEVEL_OPERATOR = 2;
+ public static final int PERMISSION_LEVEL_CUSTOM = 3;
+
public boolean worldImmutable;
public boolean noPvp;
public boolean noPvm;
@@ -34,6 +50,9 @@ public class AdventureSettingsPacket extends DataPacket {
public int flags = 0;
public int userPermission;
+ public int actionPermissions = ACTION_FLAG_DEFAULT_LEVEL_PERMISSIONS;
+ public int permissionLevel = PERMISSION_LEVEL_MEMBER;
+ public long userId = 0;
@Override
public void decode() {
@@ -68,6 +87,13 @@ public void encode() {
if (this.muted) this.flags |= 1 << 10;
this.putUnsignedVarInt(this.flags);
this.putUnsignedVarInt(this.userPermission);
+ this.putUnsignedVarInt(this.actionPermissions);
+ this.putUnsignedVarInt(this.permissionLevel);
+ if ((this.userId & 0x01) != 0) {
+ this.putLLong(-1 * ((this.userId + 1) >> 1));
+ } else {
+ this.putLLong(this.userId >> 1);
+ }
}
@Override
diff --git a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java
index 4719a2ff05..3da2a3ae95 100644
--- a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java
@@ -1,5 +1,15 @@
package cn.nukkit.network.protocol;
+import cn.nukkit.command.data.CommandDataVersions;
+import cn.nukkit.command.data.CommandOverload;
+import cn.nukkit.command.data.CommandParameter;
+import cn.nukkit.utils.BinaryStream;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
/**
* author: MagicDroidX
* Nukkit Project
@@ -7,8 +17,7 @@
public class AvailableCommandsPacket extends DataPacket {
public static final byte NETWORK_ID = ProtocolInfo.AVAILABLE_COMMANDS_PACKET;
- public String commands; //JSON-encoded command data
- public String unknown = "";
+ public Map commands;
@Override
public byte pid() {
@@ -20,10 +29,63 @@ public void decode() {
}
@Override
- public void encode() {
+ public void encode() { //TODO: check if this is able to be simplified
this.reset();
- this.putString(this.commands);
- this.putString(this.unknown);
- }
+ List enumValues = new ArrayList<>();
+ Map enumAdditional = new HashMap<>();
+ List enums = new ArrayList<>();
+ BinaryStream commandsStream = new BinaryStream();
+ commands.forEach((name, versions) -> {
+ if (name.equals("help")) { //temp fix for 1.2
+ return;
+ }
+ commandsStream.putString(name);
+ commandsStream.putString(versions.versions.get(0).description);
+ commandsStream.putByte((byte) 0); //flags
+ commandsStream.putByte((byte) 0); //permission level
+ int aliasEnumId;
+ if (versions.versions.get(0).aliases != null && versions.versions.get(0).aliases.length != 0) {
+ List aliases = new ArrayList<>();
+ for (String alias : versions.versions.get(0).aliases) {
+ int targetIndex;
+ if (!enumAdditional.containsKey(alias)) {
+ enumValues.add(alias);
+ enumAdditional.put(alias, enumValues.size() - 1);
+ targetIndex = enumValues.size() - 1;
+ } else {
+ targetIndex = enumAdditional.get(alias);
+ }
+ aliases.add(targetIndex);
+ }
+ enums.add(new Object[]{name, aliases});
+ aliasEnumId = enums.size() - 1;
+ } else {
+ aliasEnumId = -1;
+ }
+ commandsStream.putLInt(aliasEnumId);
+ commandsStream.putVarInt(versions.versions.get(0).overloads.size());
+ for (CommandOverload overload : versions.versions.get(0).overloads.values()) {
+ commandsStream.putVarInt(overload.input.parameters.length);
+ for (CommandParameter parameter : overload.input.parameters) {
+ commandsStream.putString(parameter.name);
+ commandsStream.putLInt(0);
+ commandsStream.putBoolean(parameter.optional);
+ }
+ }
+ });
+ this.putVarInt(enumValues.size());
+ enumValues.forEach(this::putString);
+ this.putVarInt(0);
+ this.putVarInt(enums.size());
+ enums.forEach(o -> {
+ this.putString(o[0] + "CommandAliases");
+ List data = (List) o[1];
+ this.putVarInt(data.size());
+ data.forEach(this::putVarInt);
+ });
+
+ this.putVarInt(commands.size());
+ this.put(commandsStream.getBuffer());
+ }
}
diff --git a/src/main/java/cn/nukkit/network/protocol/ClientToServerHandshakePacket.java b/src/main/java/cn/nukkit/network/protocol/ClientToServerHandshakePacket.java
new file mode 100644
index 0000000000..d38d0b2b33
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/ClientToServerHandshakePacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class ClientToServerHandshakePacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.CLIENT_TO_SERVER_HANDSHAKE_PACKET;
+ }
+
+ @Override
+ public void decode() {
+ //no content
+ }
+
+ @Override
+ public void encode() {
+
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java b/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java
index 767c395a49..0202537527 100644
--- a/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java
@@ -70,11 +70,12 @@ public void encode() {
this.putUnsignedVarInt(decorators.length);
for (MapDecorator decorator : decorators) {
- this.putVarInt((decorator.rotation & 0x0f) | (decorator.icon << 4));
+ this.putByte(decorator.icon);
+ this.putByte(decorator.rotation);
this.putByte(decorator.offsetX);
this.putByte(decorator.offsetZ);
this.putString(decorator.label);
- this.putLInt(decorator.color.getRGB());
+ this.putVarInt(decorator.color.getRGB());
}
}
@@ -83,6 +84,7 @@ public void encode() {
this.putVarInt(height);
this.putVarInt(offsetX);
this.putVarInt(offsetZ);
+ this.putVarInt(width * height);
if (image != null) {
for (int y = 0; y < width; y++) {
diff --git a/src/main/java/cn/nukkit/network/protocol/CommandRequestPacket.java b/src/main/java/cn/nukkit/network/protocol/CommandRequestPacket.java
index ba2f2d013e..5da8657009 100644
--- a/src/main/java/cn/nukkit/network/protocol/CommandRequestPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/CommandRequestPacket.java
@@ -11,27 +11,22 @@ public class CommandRequestPacket extends DataPacket {
public static final byte NETWORK_ID = ProtocolInfo.COMMAND_REQUEST_PACKET;
- /**
- * unknown (string)
- * unknown (string)
- * unknown (uvarint)
- * unknown (uvarint)
- * unknown (bool)
- * unknown (uvarint64)
- * unknown (string)
- * unknown (string)
- * https://gist.github.com/dktapps/8285b93af4ca38e0104bfeb9a6c87afd
- */
-
+ public static final int TYPE_PLAYER = 0;
+ public static final int TYPE_COMMAND_BLOCK = 1;
+ public static final int TYPE_MINECART_COMMAND_BLOCK = 2;
+ public static final int TYPE_DEV_CONSOLE = 3;
+ public static final int TYPE_AUTOMATION_PLAYER = 4;
+ public static final int TYPE_CLIENT_AUTOMATION = 5;
+ public static final int TYPE_DEDICATED_SERVER = 6;
+ public static final int TYPE_ENTITY = 7;
+ public static final int TYPE_VIRTUAL = 8;
+ public static final int TYPE_GAME_ARGUMENT = 9;
+ public static final int TYPE_INTERNAL = 10;
public String command;
- public String overload;
- public long uvarint1;
- public long currentStep;
- public boolean done;
- public long clientId;
- public CommandArgs args = new CommandArgs(); //JSON formatted command arguments
- public String outputJson;
+ public int type;
+ public String requestId;
+ public long playerUniqueId;
@Override
public byte pid() {
@@ -41,18 +36,9 @@ public byte pid() {
@Override
public void decode() {
this.command = this.getString();
- this.overload = this.getString();
- this.uvarint1 = this.getUnsignedVarInt();
- this.currentStep = this.getUnsignedVarInt();
- this.done = this.getBoolean();
- this.clientId = this.getVarLong();
- String argsString = this.getString();
- this.args = new Gson().fromJson(argsString, CommandArgs.class);
- this.outputJson = this.getString();
- while (!this.feof()) {
- this.getByte(); //prevent assertion errors. TODO: find out why there are always 3 extra bytes at the end of this packet.
- }
-
+ this.type = this.getVarInt();
+ this.requestId = this.getString();
+ this.playerUniqueId = this.getVarLong();
}
@Override
diff --git a/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java b/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java
index 0a3c41e147..3102894860 100644
--- a/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java
@@ -5,24 +5,29 @@
* Nukkit Project
*/
public class EntityEventPacket extends DataPacket {
- public static final byte NETWORK_ID = ProtocolInfo.ENTITY_EVENT_PACKET;
-
-
- public static final byte HURT_ANIMATION = 2;
- public static final byte DEATH_ANIMATION = 3;
-
- public static final byte TAME_FAIL = 6;
- public static final byte TAME_SUCCESS = 7;
- public static final byte SHAKE_WET = 8;
- public static final byte USE_ITEM = 9;
- public static final byte EAT_GRASS_ANIMATION = 10;
- public static final byte FISH_HOOK_BUBBLE = 11;
- public static final byte FISH_HOOK_POSITION = 12;
- public static final byte FISH_HOOK_HOOK = 13;
- public static final byte FISH_HOOK_TEASE = 14;
- public static final byte SQUID_INK_CLOUD = 15;
- public static final byte AMBIENT_SOUND = 16;
- public static final byte RESPAWN = 17;
+ public static final int NETWORK_ID = ProtocolInfo.ENTITY_EVENT_PACKET;
+
+
+ public static final int HURT_ANIMATION = 2;
+ public static final int DEATH_ANIMATION = 3;
+
+ public static final int TAME_FAIL = 6;
+ public static final int TAME_SUCCESS = 7;
+ public static final int SHAKE_WET = 8;
+ public static final int USE_ITEM = 9;
+ public static final int EAT_GRASS_ANIMATION = 10;
+ public static final int FISH_HOOK_BUBBLE = 11;
+ public static final int FISH_HOOK_POSITION = 12;
+ public static final int FISH_HOOK_HOOK = 13;
+ public static final int FISH_HOOK_TEASE = 14;
+ public static final int SQUID_INK_CLOUD = 15;
+
+ public static final int AMBIENT_SOUND = 17;
+ public static final int RESPAWN = 18;
+
+ public static final int ENCHANT = 34;
+
+ public static final int FEED = 57;
@Override
public byte pid() {
diff --git a/src/main/java/cn/nukkit/network/protocol/InventoryContentPacket.java b/src/main/java/cn/nukkit/network/protocol/InventoryContentPacket.java
index e5aaccc79e..f588211dc1 100644
--- a/src/main/java/cn/nukkit/network/protocol/InventoryContentPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/InventoryContentPacket.java
@@ -14,11 +14,12 @@ public byte pid() {
return NETWORK_ID;
}
- public static final byte SPECIAL_INVENTORY = 0;
- public static final byte SPECIAL_ARMOR = 0x78;
- public static final byte SPECIAL_CREATIVE = 0x79;
- public static final byte SPECIAL_HOTBAR = 0x7a;
- public static final byte SPECIAL_FIXED_INVENTORY = 0x7b;
+ public static final int SPECIAL_INVENTORY = 0;
+ public static final int SPECIAL_OFFHAND = 0x77;
+ public static final int SPECIAL_ARMOR = 0x78;
+ public static final int SPECIAL_CREATIVE = 0x79;
+ public static final int SPECIAL_HOTBAR = 0x7a;
+ public static final int SPECIAL_FIXED_INVENTORY = 0x7b;
public int inventoryId;
public Item[] slots = new Item[0];
diff --git a/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java b/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java
index 882233b3e3..17063445e5 100644
--- a/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java
@@ -89,7 +89,7 @@ public class LevelEventPacket extends DataPacket {
public float x = 0;
public float y = 0;
public float z = 0;
- public int data;
+ public int data = 0;
@Override
public byte pid() {
diff --git a/src/main/java/cn/nukkit/network/protocol/LoginPacket.java b/src/main/java/cn/nukkit/network/protocol/LoginPacket.java
index 7f3f4a2b58..3571abfcec 100644
--- a/src/main/java/cn/nukkit/network/protocol/LoginPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/LoginPacket.java
@@ -27,6 +27,8 @@ public class LoginPacket extends DataPacket {
public long clientId;
public Skin skin;
+ public String skinGeometryName;
+ public byte[] skinGeometry;
@Override
public byte pid() {
@@ -73,6 +75,8 @@ private void decodeSkinData() {
if (skinToken.has("ClientRandomId")) this.clientId = skinToken.get("ClientRandomId").getAsLong();
if (skinToken.has("SkinId")) skinId = skinToken.get("SkinId").getAsString();
if (skinToken.has("SkinData")) this.skin = new Skin(skinToken.get("SkinData").getAsString(), skinId);
+ if (skinToken.has("SkinGeometryName")) this.skinGeometryName = skinToken.get("SkinGeometryName").getAsString();
+ if (skinToken.has("SkinGeometry")) this.skinGeometry = Base64.getDecoder().decode(skinToken.get("SkinGeometry").getAsString());
}
private JsonObject decodeToken(String token) {
diff --git a/src/main/java/cn/nukkit/network/protocol/ModalFormRequestPacket.java b/src/main/java/cn/nukkit/network/protocol/ModalFormRequestPacket.java
new file mode 100644
index 0000000000..7a5f917293
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/ModalFormRequestPacket.java
@@ -0,0 +1,23 @@
+package cn.nukkit.network.protocol;
+
+public class ModalFormRequestPacket extends DataPacket {
+
+ public int formId;
+ public String data;
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.MODAL_FORM_REQUEST_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ this.putVarInt(this.formId);
+ this.putString(this.data);
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/ModalFormResponsePacket.java b/src/main/java/cn/nukkit/network/protocol/ModalFormResponsePacket.java
new file mode 100644
index 0000000000..a17743b136
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/ModalFormResponsePacket.java
@@ -0,0 +1,23 @@
+package cn.nukkit.network.protocol;
+
+public class ModalFormResponsePacket extends DataPacket {
+
+ public int formId;
+ public String data;
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.MODAL_FORM_RESPONSE_PACKET;
+ }
+
+ @Override
+ public void decode() {
+ this.formId = this.getVarInt();
+ this.data = this.getString(); //Data will be null if player close form without submit (by cross button or ESC)
+ }
+
+ @Override
+ public void encode() {
+
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
index 4cabfecae6..7e13249c77 100644
--- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
+++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
@@ -102,6 +102,8 @@ public interface ProtocolInfo {
byte SET_TITLE_PACKET = 0x58;
byte ADD_BEHAVIOR_TREE_PACKET = 0x59;
byte STRUCTURE_BLOCK_UPDATE_PACKET = 0x5a;
+ byte SHOW_STORE_OFFER_PACKET = 0x5b;
+ byte PURCHASE_RECEIPT_PACKET = 0x5c;
byte PLAYER_SKIN_PACKET = 0x5d;
byte SUB_CLIENT_LOGIN_PACKET = 0x5e;
byte INITIATE_WEB_SOCKET_CONNECTION_PACKET = 0x5f;
diff --git a/src/main/java/cn/nukkit/network/protocol/ServerSettingsRequestPacket.java b/src/main/java/cn/nukkit/network/protocol/ServerSettingsRequestPacket.java
new file mode 100644
index 0000000000..026f7a99e0
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/ServerSettingsRequestPacket.java
@@ -0,0 +1,19 @@
+package cn.nukkit.network.protocol;
+
+public class ServerSettingsRequestPacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.SERVER_SETTINGS_REQUEST_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/ServerSettingsResponsePacket.java b/src/main/java/cn/nukkit/network/protocol/ServerSettingsResponsePacket.java
new file mode 100644
index 0000000000..cfe42c455c
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/ServerSettingsResponsePacket.java
@@ -0,0 +1,23 @@
+package cn.nukkit.network.protocol;
+
+public class ServerSettingsResponsePacket extends DataPacket {
+
+ public int formId;
+ public String data;
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.SERVER_SETTINGS_RESPONSE_PACKET;
+ }
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ this.putVarInt(this.formId);
+ this.putString(this.data);
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/ServerToClientHandshakePacket.java b/src/main/java/cn/nukkit/network/protocol/ServerToClientHandshakePacket.java
new file mode 100644
index 0000000000..ac887d33e6
--- /dev/null
+++ b/src/main/java/cn/nukkit/network/protocol/ServerToClientHandshakePacket.java
@@ -0,0 +1,23 @@
+package cn.nukkit.network.protocol;
+
+public class ServerToClientHandshakePacket extends DataPacket {
+
+ @Override
+ public byte pid() {
+ return ProtocolInfo.SERVER_TO_CLIENT_HANDSHAKE_PACKET;
+ }
+
+ public String publicKey;
+ public String serverToken;
+ public String privateKey;
+
+ @Override
+ public void decode() {
+
+ }
+
+ @Override
+ public void encode() {
+ //TODO
+ }
+}
diff --git a/src/main/java/cn/nukkit/network/protocol/TextPacket.java b/src/main/java/cn/nukkit/network/protocol/TextPacket.java
index c975d1dcb7..29ef8c6dcf 100644
--- a/src/main/java/cn/nukkit/network/protocol/TextPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/TextPacket.java
@@ -25,10 +25,12 @@ public byte pid() {
public String source = "";
public String message = "";
public String[] parameters = new String[0];
+ public boolean isLocalized = false;
@Override
public void decode() {
this.type = (byte) getByte();
+ this.isLocalized = this.getBoolean();
switch (type) {
case TYPE_POPUP:
case TYPE_CHAT:
@@ -55,6 +57,7 @@ public void decode() {
public void encode() {
this.reset();
this.putByte(this.type);
+ this.putBoolean(this.isLocalized);
switch (this.type) {
case TYPE_POPUP:
case TYPE_CHAT:
diff --git a/src/main/java/cn/nukkit/utils/Binary.java b/src/main/java/cn/nukkit/utils/Binary.java
index be6a3c9eb9..b66111d825 100644
--- a/src/main/java/cn/nukkit/utils/Binary.java
+++ b/src/main/java/cn/nukkit/utils/Binary.java
@@ -55,7 +55,7 @@ public static byte[] writeLTriad(int value) {
}
public static UUID readUUID(byte[] bytes) {
- return new UUID(readLong(bytes), readLong(new byte[]{
+ return new UUID(readLLong(bytes), readLLong(new byte[]{
bytes[8],
bytes[9],
bytes[10],
@@ -68,7 +68,7 @@ public static UUID readUUID(byte[] bytes) {
}
public static byte[] writeUUID(UUID uuid) {
- return appendBytes(writeLong(uuid.getMostSignificantBits()), writeLong(uuid.getLeastSignificantBits()));
+ return appendBytes(writeLLong(uuid.getMostSignificantBits()), writeLLong(uuid.getLeastSignificantBits()));
}
public static byte[] writeMetadata(EntityMetadata metadata) {
diff --git a/src/main/java/cn/nukkit/utils/ClientChainData.java b/src/main/java/cn/nukkit/utils/ClientChainData.java
index 3670e97e14..356a57004a 100644
--- a/src/main/java/cn/nukkit/utils/ClientChainData.java
+++ b/src/main/java/cn/nukkit/utils/ClientChainData.java
@@ -83,6 +83,10 @@ public int getDefaultInputMode() {
return defaultInputMode;
}
+ public String getCapeData() {
+ return capeData;
+ }
+
public final static int UI_PROFILE_CLASSIC = 0;
public final static int UI_PROFILE_POCKET = 1;
@@ -125,6 +129,8 @@ public int hashCode() {
private int UIProfile;
+ private String capeData;
+
private BinaryStream bs = new BinaryStream();
private ClientChainData(byte[] buffer) {
@@ -166,6 +172,7 @@ private void decodeSkinData() {
if (skinToken.has("CurrentInputMode")) this.currentInputMode = skinToken.get("CurrentInputMode").getAsInt();
if (skinToken.has("DefaultInputMode")) this.defaultInputMode = skinToken.get("DefaultInputMode").getAsInt();
if (skinToken.has("UIProfile")) this.UIProfile = skinToken.get("UIProfile").getAsInt();
+ if (skinToken.has("CapeData")) this.capeData = skinToken.get("CapeData").getAsString();
}
private JsonObject decodeToken(String token) {
From cd429b9b15109a5f8eb89e1a4ec55ccdb2dabe8f Mon Sep 17 00:00:00 2001
From: boybook
Date: Mon, 7 Aug 2017 16:24:55 +0800
Subject: [PATCH 039/175] Fix player's no gravity
---
src/main/java/cn/nukkit/entity/Entity.java | 13 ++++++++-----
src/main/java/cn/nukkit/entity/EntityHuman.java | 1 +
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java
index 0d810437ce..1084015b12 100644
--- a/src/main/java/cn/nukkit/entity/Entity.java
+++ b/src/main/java/cn/nukkit/entity/Entity.java
@@ -67,7 +67,7 @@ public abstract class Entity extends Location implements Metadatable {
public static final int DATA_AIR = 7; //short
public static final int DATA_POTION_COLOR = 8; //int (ARGB!)
public static final int DATA_POTION_AMBIENT = 9; //byte
- /* 10 (byte) */
+ public static final int DATA_JUMP_DURATION = 10; //long
public static final int DATA_HURT_TIME = 11; //int (minecart/boat)
public static final int DATA_HURT_DIRECTION = 12; //int (minecart/boat)
public static final int DATA_PADDLE_TIME_LEFT = 13; //float
@@ -80,9 +80,9 @@ public abstract class Entity extends Location implements Metadatable {
public static final int DATA_ENDERMAN_HELD_ITEM_ID = 23; //short
public static final int DATA_ENDERMAN_HELD_ITEM_DAMAGE = 24; //short
public static final int DATA_ENTITY_AGE = 25; //short
- /* 27 (byte) player-specific flags
- * 28 (int) player "index"?
- * 29 (block coords) bed position */
+ public static final int DATA_PLAYER_FLAGS = 29; //byte
+ /* 28 (int) player "index"? */
+ public static final int DATA_PLAYER_BED_POSITION = 29; //block coords
public static final int DATA_FIREBALL_POWER_X = 30; //float
public static final int DATA_FIREBALL_POWER_Y = 31;
public static final int DATA_FIREBALL_POWER_Z = 32;
@@ -142,7 +142,7 @@ public abstract class Entity extends Location implements Metadatable {
public static final int DATA_FLAG_SADDLED = 8;
public static final int DATA_FLAG_POWERED = 9;
public static final int DATA_FLAG_IGNITED = 10;
- public static final int DATA_FLAG_BABY = 11;
+ public static final int DATA_FLAG_BABY = 11; //disable head scaling
public static final int DATA_FLAG_CONVERTING = 12;
public static final int DATA_FLAG_CRITICAL = 13;
public static final int DATA_FLAG_CAN_SHOW_NAMETAG = 14;
@@ -173,7 +173,10 @@ public abstract class Entity extends Location implements Metadatable {
public static final int DATA_FLAG_IDLING = 39;
public static final int DATA_FLAG_EVOKER_SPELL = 40;
public static final int DATA_FLAG_CHARGE_ATTACK = 41;
+ public static final int DATA_FLAG_IS_WASD_CONTROLLED = 43;
+ public static final int DATA_FLAG_CAN_POWER_JUMP = 44;
public static final int DATA_FLAG_LINGER = 45;
+ public static final int DATA_FLAG_GRAVITY = 46;
public static long entityCount = 1;
diff --git a/src/main/java/cn/nukkit/entity/EntityHuman.java b/src/main/java/cn/nukkit/entity/EntityHuman.java
index ed50f2ff5b..8dd9921a38 100644
--- a/src/main/java/cn/nukkit/entity/EntityHuman.java
+++ b/src/main/java/cn/nukkit/entity/EntityHuman.java
@@ -83,6 +83,7 @@ public void setSkin(Skin skin) {
@Override
protected void initEntity() {
this.setDataFlag(DATA_PLAYER_FLAGS, DATA_PLAYER_FLAG_SLEEP, false);
+ this.setDataFlag(DATA_FLAGS, DATA_FLAG_GRAVITY);
this.setDataProperty(new IntPositionEntityData(DATA_PLAYER_BED_POSITION, 0, 0, 0), false);
From eb9c726d813cb4bc09a6579e22925c309e9e1a12 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Mon, 7 Aug 2017 18:44:44 +0200
Subject: [PATCH 040/175] hm hm hm
---
src/main/java/cn/nukkit/Player.java | 2 +-
src/main/java/cn/nukkit/entity/Entity.java | 4 ++--
src/main/java/cn/nukkit/utils/Zlib.java | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index d349da9051..2569380690 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -2166,7 +2166,7 @@ public void handleDataPacket(DataPacket packet) {
break;
}
}
- } else if (item == null || slot == -1 || !item.deepEquals(mobEquipmentPacket.item)) {
+ } else if (item == null || slot == -1 || !item.deepEquals(mobEquipmentPacket.item, true, false)) {
this.inventory.sendContents(this);
break;
} else if (this.isCreative()) {
diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java
index 49317ad364..e55b7b5fc5 100644
--- a/src/main/java/cn/nukkit/entity/Entity.java
+++ b/src/main/java/cn/nukkit/entity/Entity.java
@@ -206,8 +206,8 @@ public abstract class Entity extends Location implements Metadatable {
protected EntityDamageEvent lastDamageCause = null;
- protected List blocksAround = new ArrayList<>();
- protected List collisionBlocks = new ArrayList<>();
+ public List blocksAround = new ArrayList<>();
+ public List collisionBlocks = new ArrayList<>();
public double lastX;
public double lastY;
diff --git a/src/main/java/cn/nukkit/utils/Zlib.java b/src/main/java/cn/nukkit/utils/Zlib.java
index 8f29b8ae52..41f73abcfe 100644
--- a/src/main/java/cn/nukkit/utils/Zlib.java
+++ b/src/main/java/cn/nukkit/utils/Zlib.java
@@ -60,4 +60,4 @@ public static byte[] inflate(byte[] data, int maxSize) throws IOException {
return inflate(new ByteArrayInputStream(data, 0, maxSize));
}
-}
+}
\ No newline at end of file
From e282fcc2f2c3cc91dc4476e4f37918acbfe2521d Mon Sep 17 00:00:00 2001
From: kvetinac97
Date: Tue, 8 Aug 2017 02:30:06 +0200
Subject: [PATCH 041/175] Fix being unable to show ModalForms (#49)
---
.../java/cn/nukkit/network/protocol/ModalFormRequestPacket.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/main/java/cn/nukkit/network/protocol/ModalFormRequestPacket.java b/src/main/java/cn/nukkit/network/protocol/ModalFormRequestPacket.java
index 7a5f917293..20418c820d 100644
--- a/src/main/java/cn/nukkit/network/protocol/ModalFormRequestPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/ModalFormRequestPacket.java
@@ -17,6 +17,7 @@ public void decode() {
@Override
public void encode() {
+ this.reset();
this.putVarInt(this.formId);
this.putString(this.data);
}
From 4fd31a7f33a915f128058308cdcb2a298ea2270e Mon Sep 17 00:00:00 2001
From: Creeperface01
Date: Tue, 8 Aug 2017 02:31:41 +0200
Subject: [PATCH 042/175] new blocks, fixed boat (#48)
---
src/main/java/cn/nukkit/block/Block.java | 7 ++--
.../nukkit/block/BlockGlassPaneStained.java | 23 +++++++++++
.../cn/nukkit/block/BlockGlassStained.java | 29 ++++++++++++++
.../java/cn/nukkit/block/BlockJukebox.java | 39 +++++++++++++++++++
.../cn/nukkit/entity/item/EntityBoat.java | 10 +++--
src/main/java/cn/nukkit/item/Item.java | 15 ++++++-
src/main/java/cn/nukkit/item/ItemRecord.java | 24 ++++++++++++
src/main/java/cn/nukkit/level/GameRules.java | 1 +
8 files changed, 141 insertions(+), 7 deletions(-)
create mode 100644 src/main/java/cn/nukkit/block/BlockGlassPaneStained.java
create mode 100644 src/main/java/cn/nukkit/block/BlockGlassStained.java
create mode 100644 src/main/java/cn/nukkit/block/BlockJukebox.java
create mode 100644 src/main/java/cn/nukkit/item/ItemRecord.java
diff --git a/src/main/java/cn/nukkit/block/Block.java b/src/main/java/cn/nukkit/block/Block.java
index be476fac00..7fdbd4af83 100644
--- a/src/main/java/cn/nukkit/block/Block.java
+++ b/src/main/java/cn/nukkit/block/Block.java
@@ -141,7 +141,7 @@ public abstract class Block extends Position implements Metadatable, Cloneable {
public static final int CLAY_BLOCK = 82;
public static final int REEDS = 83;
public static final int SUGARCANE_BLOCK = 83;
-
+ public static final int JUKEBOX = 84;
public static final int FENCE = 85;
public static final int PUMPKIN = 86;
public static final int NETHERRACK = 87;
@@ -436,7 +436,7 @@ public static void init() {
list[CACTUS] = BlockCactus.class; //81
list[CLAY_BLOCK] = BlockClay.class; //82
list[SUGARCANE_BLOCK] = BlockSugarcane.class; //83
-
+ list[JUKEBOX] = BlockJukebox.class; //84
list[FENCE] = BlockFence.class; //85
list[PUMPKIN] = BlockPumpkin.class; //86
list[NETHERRACK] = BlockNetherrack.class; //87
@@ -512,7 +512,7 @@ public static void init() {
list[DOUBLE_WOOD_SLAB] = BlockDoubleSlabWood.class; //157
list[WOOD_SLAB] = BlockSlabWood.class; //158
list[STAINED_TERRACOTTA] = BlockTerracottaStained.class; //159
- //TODO: list[STAINED_GLASS_PANE] = BlockGlassPaneStained.class; //160
+ list[STAINED_GLASS_PANE] = BlockGlassPaneStained.class; //160
list[LEAVES2] = BlockLeaves2.class; //161
list[WOOD2] = BlockWood2.class; //162
@@ -580,6 +580,7 @@ public static void init() {
list[CONCRETE_POWDER] = BlockConcretePowder.class; //237
//TODO: list[CHORUS_PLANT] = BlockChorusPlant.class; //240
+ list[STAINED_GLASS] = BlockGlassStained.class; //241
list[PODZOL] = BlockPodzol.class; //243
list[BEETROOT_BLOCK] = BlockBeetroot.class; //244
list[GLOWING_OBSIDIAN] = BlockObsidianGlowing.class; //246
diff --git a/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java b/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java
new file mode 100644
index 0000000000..4730d536d6
--- /dev/null
+++ b/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java
@@ -0,0 +1,23 @@
+package cn.nukkit.block;
+
+import cn.nukkit.utils.DyeColor;
+
+/**
+ * Created by CreeperFace on 7.8.2017.
+ */
+public class BlockGlassPaneStained extends BlockGlassPane {
+
+ @Override
+ public int getId() {
+ return STAINED_GLASS_PANE;
+ }
+
+ @Override
+ public String getName() {
+ return getDyeColor().getName() + " stained glass pane";
+ }
+
+ public DyeColor getDyeColor() {
+ return DyeColor.getByWoolData(meta);
+ }
+}
diff --git a/src/main/java/cn/nukkit/block/BlockGlassStained.java b/src/main/java/cn/nukkit/block/BlockGlassStained.java
new file mode 100644
index 0000000000..61453dc9d3
--- /dev/null
+++ b/src/main/java/cn/nukkit/block/BlockGlassStained.java
@@ -0,0 +1,29 @@
+package cn.nukkit.block;
+
+import cn.nukkit.utils.BlockColor;
+import cn.nukkit.utils.DyeColor;
+
+/**
+ * Created by CreeperFace on 7.8.2017.
+ */
+public class BlockGlassStained extends BlockGlass {
+
+ @Override
+ public int getId() {
+ return STAINED_GLASS;
+ }
+
+ @Override
+ public String getName() {
+ return getDyeColor().getName() + " Stained Glass";
+ }
+
+ @Override
+ public BlockColor getColor() {
+ return DyeColor.getByWoolData(meta).getColor();
+ }
+
+ public DyeColor getDyeColor() {
+ return DyeColor.getByWoolData(meta);
+ }
+}
diff --git a/src/main/java/cn/nukkit/block/BlockJukebox.java b/src/main/java/cn/nukkit/block/BlockJukebox.java
new file mode 100644
index 0000000000..bbe46f0c4a
--- /dev/null
+++ b/src/main/java/cn/nukkit/block/BlockJukebox.java
@@ -0,0 +1,39 @@
+package cn.nukkit.block;
+
+import cn.nukkit.Player;
+import cn.nukkit.item.Item;
+
+/**
+ * Created by CreeperFace on 7.8.2017.
+ */
+public class BlockJukebox extends BlockSolid {
+
+ public BlockJukebox() {
+ this(0);
+ }
+
+ public BlockJukebox(int meta) {
+ super(0);
+ }
+
+ @Override
+ public String getName() {
+ return "Jukebox";
+ }
+
+ @Override
+ public int getId() {
+ return JUKEBOX;
+ }
+
+ @Override
+ public boolean canBeActivated() {
+ return true;
+ }
+
+ @Override
+ public boolean onActivate(Item item, Player player) {
+ //TODO: music
+ return false;
+ }
+}
diff --git a/src/main/java/cn/nukkit/entity/item/EntityBoat.java b/src/main/java/cn/nukkit/entity/item/EntityBoat.java
index b050d4d413..8ec0a0685c 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityBoat.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityBoat.java
@@ -104,9 +104,13 @@ public boolean attack(EntityDamageEvent source) {
// Event stop
performHurtAnimation((int) event.getDamage());
- Entity damager = ((EntityDamageByEntityEvent) source).getDamager();
- boolean instantKill = damager instanceof Player
- ? ((Player) damager).isCreative() : false;
+ boolean instantKill = false;
+
+ if (source instanceof EntityDamageByEntityEvent) {
+ Entity damager = ((EntityDamageByEntityEvent) source).getDamager();
+ instantKill = damager instanceof Player && ((Player) damager).isCreative();
+ }
+
if (instantKill || getDamage() > 40) {
// Event start
VehicleDestroyEvent event2 = new VehicleDestroyEvent(this, source.getEntity());
diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java
index 2eab29b9c9..d7ad5041c2 100644
--- a/src/main/java/cn/nukkit/item/Item.java
+++ b/src/main/java/cn/nukkit/item/Item.java
@@ -160,7 +160,7 @@ private byte[] writeCompoundTag(CompoundTag tag) {
public static final int CLAY_BLOCK = 82;
public static final int REEDS = 83;
public static final int SUGARCANE_BLOCK = 83;
-
+ public static final int JUKEBOX = 84;
public static final int FENCE = 85;
public static final int PUMPKIN = 86;
public static final int NETHERRACK = 87;
@@ -562,6 +562,19 @@ private byte[] writeCompoundTag(CompoundTag tag) {
public static final int GOLDEN_APPLE_ENCHANTED = 466;
+ public static final int RECORD_13 = 500;
+ public static final int RECORD_CAT = 501;
+ public static final int RECORD_BLOCKS = 502;
+ public static final int RECORD_CHIRP = 503;
+ public static final int RECORD_FAR = 504;
+ public static final int RECORD_MALL = 505;
+ public static final int RECORD_MELLOHI = 506;
+ public static final int RECORD_STAL = 507;
+ public static final int RECORD_STRAD = 508;
+ public static final int RECORD_WARD = 509;
+ public static final int RECORD_11 = 510;
+ public static final int RECORD_WAIT = 511;
+
public static Class[] list = null;
protected Block block = null;
diff --git a/src/main/java/cn/nukkit/item/ItemRecord.java b/src/main/java/cn/nukkit/item/ItemRecord.java
new file mode 100644
index 0000000000..e58ab09194
--- /dev/null
+++ b/src/main/java/cn/nukkit/item/ItemRecord.java
@@ -0,0 +1,24 @@
+package cn.nukkit.item;
+
+/**
+ * Created by CreeperFace on 7.8.2017.
+ */
+public class ItemRecord extends Item {
+
+ public ItemRecord() {
+ this(0, 1);
+ }
+
+ public ItemRecord(Integer meta) {
+ this(meta, 1);
+ }
+
+ public ItemRecord(Integer meta, int count) {
+ super(meta, count); //TODO: records
+ }
+
+ @Override
+ public int getMaxStackSize() {
+ return 1;
+ }
+}
diff --git a/src/main/java/cn/nukkit/level/GameRules.java b/src/main/java/cn/nukkit/level/GameRules.java
index 5a6da6fb1a..466440a003 100644
--- a/src/main/java/cn/nukkit/level/GameRules.java
+++ b/src/main/java/cn/nukkit/level/GameRules.java
@@ -31,6 +31,7 @@ public GameRules() {
this.addGameRule("spectatorsGenerateChunks", "true", ValueType.BOOLEAN_VALUE);
this.addGameRule("spawnRadius", "10", ValueType.NUMERICAL_VALUE);
this.addGameRule("disableElytraMovementCheck", "false", ValueType.BOOLEAN_VALUE);
+ this.addGameRule("pvp", "true", ValueType.BOOLEAN_VALUE);
}
public void addGameRule(String key, String value, ValueType type) {
From cdb8111b880bf8c691c33849040974ad2caae93e Mon Sep 17 00:00:00 2001
From: Creeperface01
Date: Tue, 8 Aug 2017 11:48:05 +0200
Subject: [PATCH 043/175] Fix stained glass pane (#51)
---
src/main/java/cn/nukkit/block/BlockGlassPaneStained.java | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java b/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java
index 4730d536d6..184cec0bcd 100644
--- a/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java
+++ b/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java
@@ -7,6 +7,14 @@
*/
public class BlockGlassPaneStained extends BlockGlassPane {
+ public BlockGlassPaneStained() {
+ this(0);
+ }
+
+ public BlockGlassPaneStained(int meta) {
+ super(meta);
+ }
+
@Override
public int getId() {
return STAINED_GLASS_PANE;
From f9bb3271d15fbb1fabbeaf0db65fb0c32c7f1fed Mon Sep 17 00:00:00 2001
From: PikyCZ
Date: Tue, 8 Aug 2017 15:47:39 +0100
Subject: [PATCH 044/175] Small block fix (#53)
---
src/main/java/cn/nukkit/block/BlockGlassStained.java | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/main/java/cn/nukkit/block/BlockGlassStained.java b/src/main/java/cn/nukkit/block/BlockGlassStained.java
index 61453dc9d3..113f094994 100644
--- a/src/main/java/cn/nukkit/block/BlockGlassStained.java
+++ b/src/main/java/cn/nukkit/block/BlockGlassStained.java
@@ -7,6 +7,14 @@
* Created by CreeperFace on 7.8.2017.
*/
public class BlockGlassStained extends BlockGlass {
+
+ public BlockGlassStained() {
+ this(0);
+ }
+
+ public BlockGlassStained(int meta) {
+ super(meta);
+ }
@Override
public int getId() {
From fd33a19a065ef6a72e9c9c7148dce149849f02fd Mon Sep 17 00:00:00 2001
From: PikyCZ
Date: Tue, 8 Aug 2017 15:48:41 +0100
Subject: [PATCH 045/175] New Updates from pmmp (#52)
* New Updates from pmmp
https://github.com/pmmp/PocketMine-MP/commit/3ad1b1ba7f56d72ebc7db1eec110174090b34c5f
* packets
* blockentity
* invetory
---
src/main/java/cn/nukkit/Player.java | 12 ++++++------
.../blockentity/BlockEntityBrewingStand.java | 2 +-
.../cn/nukkit/blockentity/BlockEntityFurnace.java | 8 ++++----
.../cn/nukkit/inventory/ContainerInventory.java | 4 ++--
.../inventory/PlayerEnderChestInventory.java | 4 ++--
.../network/protocol/ContainerClosePacket.java | 6 +++---
.../network/protocol/ContainerOpenPacket.java | 7 ++++---
.../network/protocol/ContainerSetDataPacket.java | 14 ++++++++++++--
8 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 07775a4240..a2a89a4659 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -2722,16 +2722,16 @@ public void handleDataPacket(DataPacket packet) {
break;
case ProtocolInfo.CONTAINER_CLOSE_PACKET:
ContainerClosePacket containerClosePacket = (ContainerClosePacket) packet;
- if (!this.spawned || containerClosePacket.windowid == 0) {
+ if (!this.spawned || containerClosePacket.windowId == 0) {
break;
}
this.craftingType = CRAFTING_SMALL;
this.currentTransaction = null;
- if (this.windowIndex.containsKey(containerClosePacket.windowid)) {
- this.server.getPluginManager().callEvent(new InventoryCloseEvent(this.windowIndex.get(containerClosePacket.windowid), this));
- this.removeWindow(this.windowIndex.get(containerClosePacket.windowid));
+ if (this.windowIndex.containsKey(containerClosePacket.windowId)) {
+ this.server.getPluginManager().callEvent(new InventoryCloseEvent(this.windowIndex.get(containerClosePacket.windowId), this));
+ this.removeWindow(this.windowIndex.get(containerClosePacket.windowId));
} else {
- this.windowIndex.remove(containerClosePacket.windowid);
+ this.windowIndex.remove(containerClosePacket.windowId);
}
break;
@@ -2779,7 +2779,7 @@ public void handleDataPacket(DataPacket packet) {
} else if (!this.windowIndex.containsKey(craftingEventPacket.windowId)) {
this.inventory.sendContents(this);
containerClosePacket = new ContainerClosePacket();
- containerClosePacket.windowid = craftingEventPacket.windowId;
+ containerClosePacket.windowId = craftingEventPacket.windowId;
this.dataPacket(containerClosePacket);
break;
}
diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java b/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java
index 04d9ea9b3f..133c4cd2dd 100644
--- a/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java
+++ b/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java
@@ -188,7 +188,7 @@ public boolean onUpdate() {
int windowId = player.getWindowId(this.inventory);
if (windowId > 0) {
ContainerSetDataPacket pk = new ContainerSetDataPacket();
- pk.windowid = windowId;
+ pk.windowId = windowId;
pk.property = 0;
pk.value = this.brewTime;
player.dataPacket(pk);
diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityFurnace.java b/src/main/java/cn/nukkit/blockentity/BlockEntityFurnace.java
index 205d9465af..ecb974051e 100644
--- a/src/main/java/cn/nukkit/blockentity/BlockEntityFurnace.java
+++ b/src/main/java/cn/nukkit/blockentity/BlockEntityFurnace.java
@@ -262,14 +262,14 @@ public boolean onUpdate() {
int windowId = player.getWindowId(this.getInventory());
if (windowId > 0) {
ContainerSetDataPacket pk = new ContainerSetDataPacket();
- pk.windowid = windowId;
- pk.property = 0;
+ pk.windowId = windowId;
+ pk.property = ContainerSetDataPacket.PROPERTY_FURNACE_TICK_COUNT;;
pk.value = cookTime;
player.dataPacket(pk);
pk = new ContainerSetDataPacket();
- pk.windowid = windowId;
- pk.property = 1;
+ pk.windowId = windowId;
+ pk.property = ContainerSetDataPacket.PROPERTY_FURNACE_LIT_TIME;
pk.value = burnDuration;
player.dataPacket(pk);
}
diff --git a/src/main/java/cn/nukkit/inventory/ContainerInventory.java b/src/main/java/cn/nukkit/inventory/ContainerInventory.java
index f92cc37d98..6238f2d7cd 100644
--- a/src/main/java/cn/nukkit/inventory/ContainerInventory.java
+++ b/src/main/java/cn/nukkit/inventory/ContainerInventory.java
@@ -34,7 +34,7 @@ public ContainerInventory(InventoryHolder holder, InventoryType type, Map
Date: Tue, 8 Aug 2017 17:04:43 +0200
Subject: [PATCH 046/175] ModalForms API (#54)
Create them with player.showFormWindow, and then listen to the result with PlayerFormRespondedEvent
---
src/main/java/cn/nukkit/Player.java | 36 ++++++
.../player/PlayerFormRespondedEvent.java | 48 ++++++++
.../java/cn/nukkit/form/element/Element.java | 5 +
.../cn/nukkit/form/element/ElementButton.java | 20 ++++
.../form/element/ElementButtonImageData.java | 17 +++
.../nukkit/form/element/ElementDropdown.java | 36 ++++++
.../cn/nukkit/form/element/ElementInput.java | 22 ++++
.../cn/nukkit/form/element/ElementLabel.java | 12 ++
.../cn/nukkit/form/element/ElementSlider.java | 28 +++++
.../form/element/ElementStepSlider.java | 36 ++++++
.../cn/nukkit/form/element/ElementToggle.java | 17 +++
.../cn/nukkit/form/response/FormResponse.java | 5 +
.../form/response/FormResponseCustom.java | 46 ++++++++
.../form/response/FormResponseData.java | 20 ++++
.../form/response/FormResponseModal.java | 20 ++++
.../form/response/FormResponseSimple.java | 22 ++++
.../cn/nukkit/form/window/FormWindow.java | 17 +++
.../nukkit/form/window/FormWindowCustom.java | 106 ++++++++++++++++++
.../nukkit/form/window/FormWindowModal.java | 39 +++++++
.../nukkit/form/window/FormWindowSimple.java | 58 ++++++++++
src/main/java/cn/nukkit/network/Network.java | 2 +
21 files changed, 612 insertions(+)
create mode 100644 src/main/java/cn/nukkit/event/player/PlayerFormRespondedEvent.java
create mode 100644 src/main/java/cn/nukkit/form/element/Element.java
create mode 100644 src/main/java/cn/nukkit/form/element/ElementButton.java
create mode 100644 src/main/java/cn/nukkit/form/element/ElementButtonImageData.java
create mode 100644 src/main/java/cn/nukkit/form/element/ElementDropdown.java
create mode 100644 src/main/java/cn/nukkit/form/element/ElementInput.java
create mode 100644 src/main/java/cn/nukkit/form/element/ElementLabel.java
create mode 100644 src/main/java/cn/nukkit/form/element/ElementSlider.java
create mode 100644 src/main/java/cn/nukkit/form/element/ElementStepSlider.java
create mode 100644 src/main/java/cn/nukkit/form/element/ElementToggle.java
create mode 100644 src/main/java/cn/nukkit/form/response/FormResponse.java
create mode 100644 src/main/java/cn/nukkit/form/response/FormResponseCustom.java
create mode 100644 src/main/java/cn/nukkit/form/response/FormResponseData.java
create mode 100644 src/main/java/cn/nukkit/form/response/FormResponseModal.java
create mode 100644 src/main/java/cn/nukkit/form/response/FormResponseSimple.java
create mode 100644 src/main/java/cn/nukkit/form/window/FormWindow.java
create mode 100644 src/main/java/cn/nukkit/form/window/FormWindowCustom.java
create mode 100644 src/main/java/cn/nukkit/form/window/FormWindowModal.java
create mode 100644 src/main/java/cn/nukkit/form/window/FormWindowSimple.java
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index a2a89a4659..3394eb3029 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -26,6 +26,7 @@
import cn.nukkit.event.player.PlayerTeleportEvent.TeleportCause;
import cn.nukkit.event.server.DataPacketReceiveEvent;
import cn.nukkit.event.server.DataPacketSendEvent;
+import cn.nukkit.form.window.FormWindow;
import cn.nukkit.inventory.*;
import cn.nukkit.inventory.transaction.*;
import cn.nukkit.item.*;
@@ -197,6 +198,9 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
private ClientChainData loginChainData;
+ private int formWindowCount = 0;
+ private HashMap formWindows = new HashMap<>();
+
public int getStartActionTick() {
return startAction;
}
@@ -2488,6 +2492,25 @@ public void handleDataPacket(DataPacket packet) {
case ProtocolInfo.MOB_ARMOR_EQUIPMENT_PACKET:
break;
+ case ProtocolInfo.MODAL_FORM_RESPONSE_PACKET:
+ if (!this.spawned || !this.isAlive()) {
+ break;
+ }
+
+ ModalFormResponsePacket modalFormPacket = (ModalFormResponsePacket) packet;
+
+ if (formWindows.containsKey(modalFormPacket.formId)) {
+ FormWindow window = formWindows.get(modalFormPacket.formId);
+ window.setResponse(modalFormPacket.data.trim());
+
+ PlayerFormRespondedEvent event = new PlayerFormRespondedEvent(this, modalFormPacket.formId, window);
+ getServer().getPluginManager().callEvent(event);
+
+ formWindows.remove(modalFormPacket.formId);
+ }
+
+ break;
+
case ProtocolInfo.INTERACT_PACKET:
if (!this.spawned || !this.isAlive()) {
break;
@@ -4250,6 +4273,19 @@ public void teleportImmediate(Location location, TeleportCause cause) {
}
}
+ /**
+ * Shows a new FormWindow to the player
+ * You can find out FormWindow result by listening to PlayerFormRespondedEvent
+ */
+ public void showFormWindow(FormWindow window){
+ ModalFormRequestPacket packet = new ModalFormRequestPacket();
+ packet.formId = this.formWindowCount++;
+ packet.data = window.getJSONData();
+ this.formWindows.put(packet.formId, window);
+
+ this.dataPacket(packet);
+ }
+
/**
* Creates and sends a BossBar to the player
*
diff --git a/src/main/java/cn/nukkit/event/player/PlayerFormRespondedEvent.java b/src/main/java/cn/nukkit/event/player/PlayerFormRespondedEvent.java
new file mode 100644
index 0000000000..c34d4a8ad1
--- /dev/null
+++ b/src/main/java/cn/nukkit/event/player/PlayerFormRespondedEvent.java
@@ -0,0 +1,48 @@
+package cn.nukkit.event.player;
+
+import cn.nukkit.Player;
+import cn.nukkit.event.HandlerList;
+import cn.nukkit.form.response.FormResponse;
+import cn.nukkit.form.window.FormWindow;
+
+public class PlayerFormRespondedEvent extends PlayerEvent {
+
+ private static final HandlerList handlers = new HandlerList();
+ public static HandlerList getHandlers() {
+ return handlers;
+ }
+
+ protected int formID;
+ protected FormWindow window;
+
+ protected boolean closed = false;
+
+ public PlayerFormRespondedEvent(Player player, int formID, FormWindow window) {
+ this.player = player;
+ this.formID = formID;
+ this.window = window;
+ }
+
+ public int getFormID(){
+ return this.formID;
+ }
+
+ public FormWindow getWindow() {
+ return window;
+ }
+
+ /**
+ * Can be null if player closed the window instead of submitting it
+ */
+ public FormResponse getResponse() {
+ return window.getResponse();
+ }
+
+ /**
+ * Defines if player closed the window or submitted it
+ */
+ public boolean wasClosed(){
+ return window.wasClosed();
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/element/Element.java b/src/main/java/cn/nukkit/form/element/Element.java
new file mode 100644
index 0000000000..8dda3bf997
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/element/Element.java
@@ -0,0 +1,5 @@
+package cn.nukkit.form.element;
+
+abstract public class Element {
+
+}
diff --git a/src/main/java/cn/nukkit/form/element/ElementButton.java b/src/main/java/cn/nukkit/form/element/ElementButton.java
new file mode 100644
index 0000000000..c896f39d87
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/element/ElementButton.java
@@ -0,0 +1,20 @@
+package cn.nukkit.form.element;
+
+public class ElementButton {
+
+ public String text = "";
+ public ElementButtonImageData data;
+
+ public ElementButton(String text){
+ this.text = text;
+ }
+ public ElementButton(String text, ElementButtonImageData data){
+ this.text = text;
+ if (!data.data.isEmpty() && !data.type.isEmpty()) this.data = data;
+ }
+
+ public void addImage(ElementButtonImageData data){
+ if (!data.data.isEmpty() && !data.type.isEmpty()) this.data = data;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java b/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java
new file mode 100644
index 0000000000..a39de15286
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java
@@ -0,0 +1,17 @@
+package cn.nukkit.form.element;
+
+public class ElementButtonImageData {
+
+ public static final String IMAGE_DATA_TYPE_PATH = "path";
+ public static final String IMAGE_DATA_TYPE_URL = "url";
+
+ public String type;
+ public String data;
+
+ public ElementButtonImageData(String type, String data){
+ if (type != IMAGE_DATA_TYPE_URL && type != IMAGE_DATA_TYPE_PATH) return;
+ this.type = type;
+ this.data = data;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/element/ElementDropdown.java b/src/main/java/cn/nukkit/form/element/ElementDropdown.java
new file mode 100644
index 0000000000..2cf8623149
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/element/ElementDropdown.java
@@ -0,0 +1,36 @@
+package cn.nukkit.form.element;
+
+import java.util.ArrayList;
+
+public class ElementDropdown extends Element {
+
+ public String type = "dropdown";
+ public String text = "";
+ public ArrayList options;
+ public int defaultOptionIndex = 0;
+
+ public ElementDropdown(String text){
+ this (text, new ArrayList<>());
+ }
+ public ElementDropdown(String text, ArrayList options){
+ this (text, options, 0);
+ }
+ public ElementDropdown(String text, ArrayList options, int defaultOption){
+ this.text = text;
+ this.options = options;
+ this.defaultOptionIndex = defaultOption;
+ }
+
+ public void setDefaultOptionIndex(int index){
+ if (index >= options.size()) return;
+ this.defaultOptionIndex = index;
+ }
+ public void addOption(String option){
+ addOption(option, false);
+ }
+ public void addOption(String option, boolean isDefault){
+ options.add(option);
+ if (isDefault) this.defaultOptionIndex = options.size()-1;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/element/ElementInput.java b/src/main/java/cn/nukkit/form/element/ElementInput.java
new file mode 100644
index 0000000000..aa36d17345
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/element/ElementInput.java
@@ -0,0 +1,22 @@
+package cn.nukkit.form.element;
+
+public class ElementInput extends Element {
+
+ public String type = "input";
+ public String text = "";
+ public String placeholder = "";
+ public String defaultText = "";
+
+ public ElementInput (String text){
+ this (text, "");
+ }
+ public ElementInput (String text, String placeholder){
+ this (text, placeholder, "");
+ }
+ public ElementInput (String text, String placeholder, String defaultText){
+ this.text = text;
+ this.placeholder = placeholder;
+ this.defaultText = defaultText;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/element/ElementLabel.java b/src/main/java/cn/nukkit/form/element/ElementLabel.java
new file mode 100644
index 0000000000..10725d3274
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/element/ElementLabel.java
@@ -0,0 +1,12 @@
+package cn.nukkit.form.element;
+
+public class ElementLabel extends Element {
+
+ public String type = "label";
+ public String text = "";
+
+ public ElementLabel (String text){
+ this.text = text;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/element/ElementSlider.java b/src/main/java/cn/nukkit/form/element/ElementSlider.java
new file mode 100644
index 0000000000..8336707e7b
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/element/ElementSlider.java
@@ -0,0 +1,28 @@
+package cn.nukkit.form.element;
+
+public class ElementSlider extends Element {
+
+ public String type = "slider";
+ public String text = "";
+ public float min = 0f;
+ public float max = 100f;
+ public float step;
+ public float defaultValue;
+
+ public ElementSlider (String text, float min, float max){
+ this (text, min, max, -1f);
+ }
+ public ElementSlider (String text, float min, float max, float step){
+ this (text, min, max, step, -1f);
+ }
+ public ElementSlider (String text, float min, float max, float step, float defaultValue){
+ this.text = text;
+ if (min < 0f) this.min = 0f;
+ else this.min = min;
+ if (max > min) this.max = this.min;
+ else this.max = max;
+ if (this.step != -1f && this.step > 0) this.step = step;
+ if (defaultValue != -1f) this.defaultValue = defaultValue;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/element/ElementStepSlider.java b/src/main/java/cn/nukkit/form/element/ElementStepSlider.java
new file mode 100644
index 0000000000..ceeea63815
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/element/ElementStepSlider.java
@@ -0,0 +1,36 @@
+package cn.nukkit.form.element;
+
+import java.util.ArrayList;
+
+public class ElementStepSlider extends Element {
+
+ public String type = "step_slider";
+ public String text = "";
+ public ArrayList steps;
+ public int defaultStepIndex = 0;
+
+ public ElementStepSlider(String text){
+ this (text, new ArrayList<>());
+ }
+ public ElementStepSlider(String text, ArrayList steps){
+ this (text, steps, 0);
+ }
+ public ElementStepSlider(String text, ArrayList steps, int defaultStep){
+ this.text = text;
+ this.steps = steps;
+ this.defaultStepIndex = defaultStep;
+ }
+
+ public void setDefaultOptionIndex(int index){
+ if (index >= steps.size()) return;
+ this.defaultStepIndex = index;
+ }
+ public void addStep(String step){
+ addStep(step, false);
+ }
+ public void addStep(String step, boolean isDefault){
+ steps.add(step);
+ if (isDefault) this.defaultStepIndex = steps.size()-1;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/element/ElementToggle.java b/src/main/java/cn/nukkit/form/element/ElementToggle.java
new file mode 100644
index 0000000000..e9dffe6b7f
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/element/ElementToggle.java
@@ -0,0 +1,17 @@
+package cn.nukkit.form.element;
+
+public class ElementToggle extends Element {
+
+ public String type = "toggle";
+ public String text = "";
+ public boolean defaultValue = false;
+
+ public ElementToggle(String text) {
+ this (text, false);
+ }
+ public ElementToggle(String text, boolean defaultValue){
+ this.text = text;
+ this.defaultValue = defaultValue;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/response/FormResponse.java b/src/main/java/cn/nukkit/form/response/FormResponse.java
new file mode 100644
index 0000000000..1d128d60f4
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/response/FormResponse.java
@@ -0,0 +1,5 @@
+package cn.nukkit.form.response;
+
+public abstract class FormResponse {
+
+}
diff --git a/src/main/java/cn/nukkit/form/response/FormResponseCustom.java b/src/main/java/cn/nukkit/form/response/FormResponseCustom.java
new file mode 100644
index 0000000000..1d29f41cec
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/response/FormResponseCustom.java
@@ -0,0 +1,46 @@
+package cn.nukkit.form.response;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class FormResponseCustom extends FormResponse {
+
+ public HashMap responses = new HashMap<>();
+ private HashMap dropdownResponses = new HashMap<>();
+ private HashMap inputResponses = new HashMap<>();
+ private HashMap sliderResponses = new HashMap<>();
+ private HashMap stepSliderResponses = new HashMap<>();
+ private HashMap toggleResponses = new HashMap<>();
+
+ public FormResponseCustom (HashMap responses, HashMap dropdownResponses,
+ HashMap inputResponses, HashMap sliderResponses,
+ HashMap stepSliderResponses,
+ HashMap toggleResponses){
+ this.responses = responses;
+ this.dropdownResponses = dropdownResponses;
+ this.inputResponses = inputResponses;
+ this.sliderResponses = sliderResponses;
+ this.stepSliderResponses = stepSliderResponses;
+ this.toggleResponses = toggleResponses;
+ }
+
+ public Object getResponse(int id){
+ return responses.get(id);
+ }
+ public FormResponseData getDropdownResponse(int id){
+ return dropdownResponses.get(id);
+ }
+ public String getInputResponse(int id){
+ return inputResponses.get(id);
+ }
+ public float getSliderResponse(int id){
+ return sliderResponses.get(id);
+ }
+ public FormResponseData getStepSliderResponse(int id){
+ return stepSliderResponses.get(id);
+ }
+ public boolean getToggleResponse(int id){
+ return toggleResponses.get(id);
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/response/FormResponseData.java b/src/main/java/cn/nukkit/form/response/FormResponseData.java
new file mode 100644
index 0000000000..e9246d20c8
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/response/FormResponseData.java
@@ -0,0 +1,20 @@
+package cn.nukkit.form.response;
+
+public class FormResponseData {
+
+ private int elementID;
+ private String elementContent;
+
+ public FormResponseData(int id, String content){
+ this.elementID = id;
+ this.elementContent = content;
+ }
+
+ public int getElementID() {
+ return elementID;
+ }
+ public String getElementContent() {
+ return elementContent;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/response/FormResponseModal.java b/src/main/java/cn/nukkit/form/response/FormResponseModal.java
new file mode 100644
index 0000000000..a985e1e7c9
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/response/FormResponseModal.java
@@ -0,0 +1,20 @@
+package cn.nukkit.form.response;
+
+public class FormResponseModal extends FormResponse {
+
+ private int clickedButtonId;
+ private String clickedButtonText;
+
+ public FormResponseModal (int clickedButtonId, String clickedButtonText){
+ this.clickedButtonId = clickedButtonId;
+ this.clickedButtonText = clickedButtonText;
+ }
+
+ public int getClickedButtonId() {
+ return clickedButtonId;
+ }
+ public String getClickedButtonText() {
+ return clickedButtonText;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/response/FormResponseSimple.java b/src/main/java/cn/nukkit/form/response/FormResponseSimple.java
new file mode 100644
index 0000000000..1abd121aa0
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/response/FormResponseSimple.java
@@ -0,0 +1,22 @@
+package cn.nukkit.form.response;
+
+import cn.nukkit.form.element.ElementButton;
+
+public class FormResponseSimple extends FormResponse {
+
+ private int clickedButtonId;
+ private ElementButton clickedButton;
+
+ public FormResponseSimple (int clickedButtonId, ElementButton clickedButton){
+ this.clickedButtonId = clickedButtonId;
+ this.clickedButton = clickedButton;
+ }
+
+ public int getClickedButtonId() {
+ return clickedButtonId;
+ }
+ public ElementButton getClickedButton() {
+ return clickedButton;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/window/FormWindow.java b/src/main/java/cn/nukkit/form/window/FormWindow.java
new file mode 100644
index 0000000000..402978adef
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/window/FormWindow.java
@@ -0,0 +1,17 @@
+package cn.nukkit.form.window;
+
+import cn.nukkit.form.response.FormResponse;
+
+public abstract class FormWindow {
+
+ protected boolean closed = false;
+
+ public abstract String getJSONData();
+
+ public abstract void setResponse(String data);
+ public abstract FormResponse getResponse();
+ public boolean wasClosed() {
+ return closed;
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java
new file mode 100644
index 0000000000..cb36d7c788
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java
@@ -0,0 +1,106 @@
+package cn.nukkit.form.window;
+
+import com.google.gson.Gson;
+import cn.nukkit.form.element.*;
+import cn.nukkit.form.response.FormResponseData;
+import cn.nukkit.form.response.FormResponseCustom;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class FormWindowCustom extends FormWindow {
+
+ public String type = "custom_form";
+ public String title = "";
+ public ElementButtonImageData icon;
+ public ArrayList content;
+
+ private FormResponseCustom response;
+
+ public FormWindowCustom(String title){
+ this (title, new ArrayList<>());
+ }
+ public FormWindowCustom(String title, ArrayList contents){
+ this (title, contents, "");
+ }
+ public FormWindowCustom(String title, ArrayList contents, String icon){
+ this.title = title;
+ this.content = contents;
+ if (!icon.isEmpty()) this.icon = new ElementButtonImageData(ElementButtonImageData.IMAGE_DATA_TYPE_URL, icon);
+ }
+
+ public void addElement(Element element){
+ content.add(element);
+ }
+ public void setIcon(String icon){
+ if (!icon.isEmpty()) this.icon = new ElementButtonImageData(ElementButtonImageData.IMAGE_DATA_TYPE_URL, icon);
+ }
+
+ public String getJSONData(){
+ String toModify = new Gson().toJson(this);
+ //We need to replace this due to Java not supporting declaring class field 'default'
+ return toModify.replace("defaultOptionIndex", "default")
+ .replace("defaultText", "default")
+ .replace("defaultValue", "default")
+ .replace("defaultStepIndex", "default");
+ }
+
+ public FormResponseCustom getResponse(){
+ return response;
+ }
+ public void setResponse(String data) {
+ if (data.equals("null")){
+ this.closed = true;
+ return;
+ }
+ String[] elementResponses = data.replace("[", "").replace("]",
+ "").split(",");
+ int i = 0;
+
+ HashMap dropdownResponses = new HashMap<>();
+ HashMap inputResponses = new HashMap<>();
+ HashMap sliderResponses = new HashMap<>();
+ HashMap stepSliderResponses = new HashMap<>();
+ HashMap toggleResponses = new HashMap<>();
+ HashMap responses = new HashMap<>();
+
+ for (String elementData : elementResponses){
+ Element e = content.get(i);
+ if (e == null) break;
+ if (e instanceof ElementLabel) {
+ i++;
+ continue;
+ }
+ if (e instanceof ElementDropdown){
+ String answer = ((ElementDropdown) e).options.get(Integer.parseInt(elementData));
+ dropdownResponses.put(i, new FormResponseData(Integer.parseInt(elementData), answer));
+ responses.put(i, answer);
+ }
+ else if (e instanceof ElementInput){
+ String answer = elementData.substring(0, elementData.length()-1);
+ inputResponses.put(i, answer);
+ responses.put(i, answer);
+ }
+ else if (e instanceof ElementSlider){
+ Float answer = Float.parseFloat(elementData);
+ sliderResponses.put(i, answer);
+ responses.put(i, answer);
+ }
+ else if (e instanceof ElementStepSlider){
+ String answer = ((ElementStepSlider) e).steps.get(Integer.parseInt(elementData));
+ stepSliderResponses.put(i, new FormResponseData(Integer.parseInt(elementData), answer));
+ responses.put(i, answer);
+ }
+ else if (e instanceof ElementToggle){
+ Boolean answer = Boolean.parseBoolean(elementData);
+ toggleResponses.put(i, answer);
+ responses.put(i, answer);
+ }
+ i++;
+ }
+
+ this.response = new FormResponseCustom(responses, dropdownResponses, inputResponses,
+ sliderResponses, stepSliderResponses, toggleResponses);
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/window/FormWindowModal.java b/src/main/java/cn/nukkit/form/window/FormWindowModal.java
new file mode 100644
index 0000000000..fc72a60155
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/window/FormWindowModal.java
@@ -0,0 +1,39 @@
+package cn.nukkit.form.window;
+
+import com.google.gson.Gson;
+import cn.nukkit.form.response.FormResponseModal;
+
+public class FormWindowModal extends FormWindow {
+
+ private String type = "modal";
+ public String title = "";
+ public String content = "";
+ public String button1 = "";
+ public String button2 = "";
+
+ private FormResponseModal response = null;
+
+ public FormWindowModal(String title, String content, String trueButonText, String falseButtonText){
+ this.title = title;
+ this.content = content;
+ this.button1 = trueButonText;
+ this.button2 = falseButtonText;
+ }
+
+ public String getJSONData(){
+ return new Gson().toJson(this);
+ }
+
+ public FormResponseModal getResponse() {
+ return response;
+ }
+ public void setResponse(String data){
+ if (data.equals("null")){
+ closed = true;
+ return;
+ }
+ if (data.equals("true")) response = new FormResponseModal(0, button1);
+ else response = new FormResponseModal(1, button2);
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/form/window/FormWindowSimple.java b/src/main/java/cn/nukkit/form/window/FormWindowSimple.java
new file mode 100644
index 0000000000..6410ee1810
--- /dev/null
+++ b/src/main/java/cn/nukkit/form/window/FormWindowSimple.java
@@ -0,0 +1,58 @@
+package cn.nukkit.form.window;
+
+import com.google.gson.Gson;
+import cn.nukkit.form.element.ElementButton;
+import cn.nukkit.form.response.FormResponse;
+import cn.nukkit.form.response.FormResponseSimple;
+
+import java.util.ArrayList;
+
+public class FormWindowSimple extends FormWindow {
+
+ public String type = "form";
+ public String title = "";
+ public String content = "";
+ public ArrayList buttons;
+
+ private FormResponseSimple response = null;
+
+ public FormWindowSimple(String title, String content){
+ this (title, content, new ArrayList<>());
+ }
+ public FormWindowSimple(String title, String content, ArrayList buttons){
+ this.title = title;
+ this.content = content;
+ this.buttons = buttons;
+ }
+
+ public void addButton(ElementButton button){
+ this.buttons.add(button);
+ }
+
+ public String getJSONData(){
+ return new Gson().toJson(this);
+ }
+
+ public FormResponseSimple getResponse() {
+ return response;
+ }
+ public void setResponse(String data) {
+ if (data.equals("null")){
+ this.closed = true;
+ return;
+ }
+ int buttonID;
+ try {
+ buttonID = Integer.parseInt(data);
+ }
+ catch (Exception e) {
+ return;
+ }
+ if (buttonID >= this.buttons.size()){
+ this.response = new FormResponseSimple(buttonID, null);
+ return;
+ }
+ this.response = new FormResponseSimple(buttonID, buttons.get(buttonID));
+ }
+
+}
diff --git a/src/main/java/cn/nukkit/network/Network.java b/src/main/java/cn/nukkit/network/Network.java
index e3bf442b19..91fac322b0 100644
--- a/src/main/java/cn/nukkit/network/Network.java
+++ b/src/main/java/cn/nukkit/network/Network.java
@@ -240,6 +240,8 @@ private void registerPackets() {
this.registerPacket(ProtocolInfo.MAP_INFO_REQUEST_PACKET, MapInfoRequestPacket.class);
this.registerPacket(ProtocolInfo.MOB_ARMOR_EQUIPMENT_PACKET, MobArmorEquipmentPacket.class);
this.registerPacket(ProtocolInfo.MOB_EQUIPMENT_PACKET, MobEquipmentPacket.class);
+ this.registerPacket(ProtocolInfo.MODAL_FORM_REQUEST_PACKET, ModalFormRequestPacket.class);
+ this.registerPacket(ProtocolInfo.MODAL_FORM_RESPONSE_PACKET, ModalFormResponsePacket.class);
this.registerPacket(ProtocolInfo.MOVE_ENTITY_PACKET, MoveEntityPacket.class);
this.registerPacket(ProtocolInfo.MOVE_PLAYER_PACKET, MovePlayerPacket.class);
this.registerPacket(ProtocolInfo.PLAYER_ACTION_PACKET, PlayerActionPacket.class);
From e33947dee2b96c4fc6deff8b9da43da7f1ddb0d9 Mon Sep 17 00:00:00 2001
From: Creeperface01
Date: Wed, 9 Aug 2017 02:42:54 +0200
Subject: [PATCH 047/175] It should return windows id (#55)
---
src/main/java/cn/nukkit/Player.java | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 3394eb3029..0eb8ed0fae 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -4277,13 +4277,16 @@ public void teleportImmediate(Location location, TeleportCause cause) {
* Shows a new FormWindow to the player
* You can find out FormWindow result by listening to PlayerFormRespondedEvent
*/
- public void showFormWindow(FormWindow window){
+ public int showFormWindow(FormWindow window) {
+ int id = this.formWindowCount++;
+
ModalFormRequestPacket packet = new ModalFormRequestPacket();
- packet.formId = this.formWindowCount++;
+ packet.formId = id;
packet.data = window.getJSONData();
this.formWindows.put(packet.formId, window);
this.dataPacket(packet);
+ return id;
}
/**
From b7f73abd9be810b0ccf601a27752b1c6b678dfc6 Mon Sep 17 00:00:00 2001
From: FENGberd
Date: Fri, 11 Aug 2017 16:41:51 +0800
Subject: [PATCH 048/175] Add a construct override for Config (#1860)
---
src/main/java/cn/nukkit/utils/Config.java | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/main/java/cn/nukkit/utils/Config.java b/src/main/java/cn/nukkit/utils/Config.java
index 6a672fc691..35b117c7c1 100644
--- a/src/main/java/cn/nukkit/utils/Config.java
+++ b/src/main/java/cn/nukkit/utils/Config.java
@@ -99,6 +99,10 @@ public Config(String file, int type, ConfigSection defaultMap) {
this.load(file, type, defaultMap);
}
+ public Config(File file, int type, ConfigSection defaultMap) {
+ this.load(file.toString(), type, defaultMap);
+ }
+
@Deprecated
public Config(File file, int type, LinkedHashMap defaultMap) {
this(file.toString(), type, new ConfigSection(defaultMap));
@@ -569,4 +573,4 @@ public Set getKeys(boolean child) {
if (this.correct) return config.getKeys(child);
return new HashSet<>();
}
-}
\ No newline at end of file
+}
From 20409c5ddc27758e6979bbbd1f8fbc3c941bca52 Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Wed, 16 Aug 2017 17:25:22 +0200
Subject: [PATCH 049/175] Opraven crafting atd..
---
src/main/java/cn/nukkit/Player.java | 160 +++++++++++++-----
.../java/cn/nukkit/block/BlockPlanks.java | 2 +-
.../cn/nukkit/inventory/BaseInventory.java | 4 +-
.../cn/nukkit/inventory/CraftingManager.java | 29 +++-
src/main/java/cn/nukkit/item/Item.java | 2 +-
src/main/java/cn/nukkit/utils/Utils.java | 4 +-
6 files changed, 147 insertions(+), 54 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 2569380690..dc235bd5fa 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -2973,7 +2973,7 @@ public void handleDataPacket(DataPacket packet) {
this.inventory.sendHeldItem(this);
break;
- case EntityEventPacket.CONSUME_ITEM:
+ /*case EntityEventPacket.CONSUME_ITEM:
EntityEventPacket pk = new EntityEventPacket();
pk.eid = this.getId();
pk.event = EntityEventPacket.CONSUME_ITEM;
@@ -2983,7 +2983,7 @@ public void handleDataPacket(DataPacket packet) {
Server.broadcastPacket(this.getViewers().values(), pk);
this.dataPacket(pk);
}
- break;
+ break;*/
}
break;
case ProtocolInfo.DROP_ITEM_PACKET:
@@ -3167,12 +3167,13 @@ public void handleDataPacket(DataPacket packet) {
boolean canCraft = true;
- if (craftingEventPacket.input.length == 0) {
- Recipe[] recipes = getServer().getCraftingManager().getRecipesByResult(craftingEventPacket.output[0]);
+ if (true) {
+ //System.out.println("output: "+craftingEventPacket.output[0]);
+ //Recipe[] recipes = getServer().getCraftingManager().getRecipesByResult(craftingEventPacket.output[0]);
- recipe = null;
+ recipe = this.getServer().getCraftingManager().getRecipe(craftingEventPacket.id);
- ArrayList- ingredientz = new ArrayList<>();
+ /*ArrayList
- ingredientz = new ArrayList<>();
for (Recipe r : recipes) {
if (r instanceof ShapedRecipe) {
@@ -3191,15 +3192,80 @@ public void handleDataPacket(DataPacket packet) {
}
}
+ if (canCraft) {
+ recipe = r;
+ break;
+ }
+ } else if(r instanceof ShapelessRecipe) {
+ ShapelessRecipe recipe0 = (ShapelessRecipe) r;
+
+ for(Item ingredient : recipe0.getIngredientList()){
+ if (ingredient != null && ingredient.getId() != Item.AIR) {
+ if (!this.inventory.contains(ingredient)) {
+ canCraft = false;
+ break;
+ }
+
+ ingredientz.add(ingredient);
+ this.inventory.removeItem(ingredient);
+ }
+ }
+
if (canCraft) {
recipe = r;
break;
}
}
- }
+ }*/
if (recipe != null) {
- CraftItemEvent craftItemEvent = new CraftItemEvent(this, ingredientz.stream().toArray(Item[]::new), recipe);
+ ArrayList
- ingredientz = new ArrayList<>();
+
+ if (recipe instanceof ShapedRecipe) {
+ Map
> ingredients = ((ShapedRecipe) recipe).getIngredientMap();
+ for (Map map : ingredients.values()) {
+ for (Item ingredient : map.values()) {
+ if (ingredient != null && ingredient.getId() != Item.AIR) {
+ ingredientz.add(ingredient);
+ }
+ }
+ }
+ } else if (recipe instanceof ShapelessRecipe) {
+ ShapelessRecipe recipe0 = (ShapelessRecipe) recipe;
+
+ for (Item ingredient : recipe0.getIngredientList()) {
+ if (ingredient != null && ingredient.getId() != Item.AIR) {
+ ingredientz.add(ingredient);
+ }
+ }
+ }
+
+ Map serialized = new HashMap<>();
+
+ for (Item ingredient : ingredientz) {
+ String hash = ingredient.getId() + ":" + ingredient.getDamage();
+ Item r = serialized.get(hash);
+
+ if (r != null) {
+ continue;
+ }
+
+ serialized.put(hash, ingredient);
+ }
+
+ for (Item ingredient : serialized.values()) {
+ if (!this.inventory.contains(ingredient)) {
+ canCraft = false;
+ break;
+ }
+ }
+
+ if (!canCraft) {
+ this.server.getLogger().debug("(1) Unmatched recipe " + craftingEventPacket.id + " from player " + this.getName() + " not anough ingredients");
+ return;
+ }
+
+ CraftItemEvent craftItemEvent = new CraftItemEvent(this, serialized.values().stream().toArray(Item[]::new), recipe);
getServer().getPluginManager().callEvent(craftItemEvent);
if (craftItemEvent.isCancelled()) {
@@ -3207,9 +3273,13 @@ public void handleDataPacket(DataPacket packet) {
break;
}
+ for (Item ingredient : serialized.values()) {
+ this.inventory.removeItem(ingredient);
+ }
+
this.inventory.addItem(recipe.getResult());
} else {
- this.server.getLogger().debug("(1) Unmatched desktop recipe " + craftingEventPacket.id + " from player " + this.getName());
+ this.server.getLogger().debug("(1) Unmatched recipe " + craftingEventPacket.id + " from player " + this.getName());
this.inventory.sendContents(this);
}
} else {
@@ -3413,41 +3483,43 @@ public void handleDataPacket(DataPacket packet) {
}
}
- switch (recipe.getResult().getId()) {
- case Item.WORKBENCH:
- this.awardAchievement("buildWorkBench");
- break;
- case Item.WOODEN_PICKAXE:
- this.awardAchievement("buildPickaxe");
- break;
- case Item.FURNACE:
- this.awardAchievement("buildFurnace");
- break;
- case Item.WOODEN_HOE:
- this.awardAchievement("buildHoe");
- break;
- case Item.BREAD:
- this.awardAchievement("makeBread");
- break;
- case Item.CAKE:
- //TODO: detect complex recipes like cake that leave remains
- this.awardAchievement("bakeCake");
- this.inventory.addItem(new ItemBucket(0, 3));
- break;
- case Item.STONE_PICKAXE:
- case Item.GOLD_PICKAXE:
- case Item.IRON_PICKAXE:
- case Item.DIAMOND_PICKAXE:
- this.awardAchievement("buildBetterPickaxe");
- break;
- case Item.WOODEN_SWORD:
- this.awardAchievement("buildSword");
- break;
- case Item.DIAMOND:
- this.awardAchievement("diamond");
- break;
- default:
- break;
+ if (recipe != null) {
+ switch (recipe.getResult().getId()) {
+ case Item.WORKBENCH:
+ this.awardAchievement("buildWorkBench");
+ break;
+ case Item.WOODEN_PICKAXE:
+ this.awardAchievement("buildPickaxe");
+ break;
+ case Item.FURNACE:
+ this.awardAchievement("buildFurnace");
+ break;
+ case Item.WOODEN_HOE:
+ this.awardAchievement("buildHoe");
+ break;
+ case Item.BREAD:
+ this.awardAchievement("makeBread");
+ break;
+ case Item.CAKE:
+ //TODO: detect complex recipes like cake that leave remains
+ this.awardAchievement("bakeCake");
+ this.inventory.addItem(new ItemBucket(0, 3));
+ break;
+ case Item.STONE_PICKAXE:
+ case Item.GOLD_PICKAXE:
+ case Item.IRON_PICKAXE:
+ case Item.DIAMOND_PICKAXE:
+ this.awardAchievement("buildBetterPickaxe");
+ break;
+ case Item.WOODEN_SWORD:
+ this.awardAchievement("buildSword");
+ break;
+ case Item.DIAMOND:
+ this.awardAchievement("diamond");
+ break;
+ default:
+ break;
+ }
}
break;
diff --git a/src/main/java/cn/nukkit/block/BlockPlanks.java b/src/main/java/cn/nukkit/block/BlockPlanks.java
index 7d5d79c8a0..be8eda1a9e 100644
--- a/src/main/java/cn/nukkit/block/BlockPlanks.java
+++ b/src/main/java/cn/nukkit/block/BlockPlanks.java
@@ -21,7 +21,7 @@ public BlockPlanks() {
}
public BlockPlanks(int meta) {
- super(meta);
+ super(meta % 6);
}
@Override
diff --git a/src/main/java/cn/nukkit/inventory/BaseInventory.java b/src/main/java/cn/nukkit/inventory/BaseInventory.java
index 0d921a4dc3..52f927f644 100644
--- a/src/main/java/cn/nukkit/inventory/BaseInventory.java
+++ b/src/main/java/cn/nukkit/inventory/BaseInventory.java
@@ -169,7 +169,7 @@ public boolean setItem(int index, Item item) {
@Override
public boolean contains(Item item) {
int count = Math.max(1, item.getCount());
- boolean checkDamage = item.hasMeta();
+ boolean checkDamage = item.hasMeta() && item.getDamage() >= 0;
boolean checkTag = item.getCompoundTag() != null;
for (Item i : this.getContents().values()) {
if (item.equals(i, checkDamage, checkTag)) {
@@ -186,7 +186,7 @@ public boolean contains(Item item) {
@Override
public Map all(Item item) {
Map slots = new HashMap<>();
- boolean checkDamage = item.hasMeta();
+ boolean checkDamage = item.hasMeta() && item.getDamage() >= 0;
boolean checkTag = item.getCompoundTag() != null;
for (Map.Entry entry : this.getContents().entrySet()) {
if (item.equals(entry.getValue(), checkDamage, checkTag)) {
diff --git a/src/main/java/cn/nukkit/inventory/CraftingManager.java b/src/main/java/cn/nukkit/inventory/CraftingManager.java
index ed0e61f8ff..067ad0b057 100644
--- a/src/main/java/cn/nukkit/inventory/CraftingManager.java
+++ b/src/main/java/cn/nukkit/inventory/CraftingManager.java
@@ -49,7 +49,13 @@ public CraftingManager() {
for (Map ingredient : ((List) recipe.get("input"))) {
result.addIngredient(Item.get(Utils.toInt(ingredient.get("id")), Utils.toInt(ingredient.get("damage")), Utils.toInt(ingredient.get("count")), ingredient.get("nbt").toString().getBytes()));
}
- this.registerRecipe(result);
+
+ String id = (String) recipe.get("uuid");
+ if (id != null && !id.isEmpty()) {
+ UUID uuid = UUID.fromString(id);
+ result.setId(uuid);
+ this.recipes.put(uuid, result);
+ }
break;
case 1:
// TODO: handle multiple result items
@@ -69,13 +75,20 @@ public CraftingManager() {
}
}
}
- this.registerRecipe(shapedRecipe);
+
+ id = (String) recipe.get("uuid");
+
+ if (id != null && !id.isEmpty()) {
+ UUID uuid = UUID.fromString(id);
+ shapedRecipe.setId(uuid);
+ this.recipes.put(uuid, shapedRecipe);
+ }
break;
case 2:
case 3:
Map resultMap = (Map) recipe.get("output");
Item resultItem = Item.get(Utils.toInt(resultMap.get("id")), Utils.toInt(resultMap.get("damage")), Utils.toInt(resultMap.get("count")), ((String) resultMap.get("nbt")).getBytes());
- this.registerRecipe(new FurnaceRecipe(resultItem, Item.get(Utils.toInt(recipe.get("inputId")), recipe.containsKey("inputDamage") ? Utils.toInt(recipe.get("inputDamage")) : -1, 1)));
+ this.registerRecipe(new FurnaceRecipe(resultItem, Item.get(Utils.toInt(recipe.get("inputId")), recipe.containsKey("inputDamage") ? Utils.toInt(recipe.get("inputDamage")) : 0, 1)));
break;
default:
break;
@@ -302,7 +315,7 @@ public boolean matchRecipe(ShapelessRecipe recipe) {
}
public void registerRecipe(Recipe recipe) {
- recipe.setId(Utils.dataToUUID(String.valueOf(++RECIPE_COUNT), String.valueOf(recipe.getResult().getId()), String.valueOf(recipe.getResult().getDamage()), String.valueOf(recipe.getResult().getCount()), Arrays.toString(recipe.getResult().getCompoundTag())));
+ //recipe.setId(Utils.dataToUUID(String.valueOf(++RECIPE_COUNT), String.valueOf(recipe.getResult().getId()), String.valueOf(recipe.getResult().getDamage()), String.valueOf(recipe.getResult().getCount()), Arrays.toString(recipe.getResult().getCompoundTag())));
if (recipe instanceof ShapedRecipe) {
this.registerShapedRecipe((ShapedRecipe) recipe);
@@ -314,7 +327,13 @@ public void registerRecipe(Recipe recipe) {
}
public Recipe[] getRecipesByResult(Item result) {
- return recipeLookup.get(result.getId() + ":" + result.getDamage()).values().stream().toArray(Recipe[]::new);
+ Map recipes = recipeLookup.get(result.getId() + ":" + result.getDamage());
+
+ if (recipes == null) {
+ recipes = recipeLookup.get(result.getId() + ":");
+ }
+
+ return recipes == null ? null : recipes.values().stream().toArray(Recipe[]::new);
}
public static class Entry {
diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java
index d9e21b1703..94235828a9 100644
--- a/src/main/java/cn/nukkit/item/Item.java
+++ b/src/main/java/cn/nukkit/item/Item.java
@@ -588,7 +588,7 @@ public Item(int id, Integer meta, int count) {
public Item(int id, Integer meta, int count, String name) {
this.id = id & 0xffff;
- if (meta != null) {
+ if (meta != null && meta >= 0) {
this.meta = meta & 0xffff;
} else {
this.hasMeta = false;
diff --git a/src/main/java/cn/nukkit/utils/Utils.java b/src/main/java/cn/nukkit/utils/Utils.java
index 69a2e8f457..3bacab1025 100644
--- a/src/main/java/cn/nukkit/utils/Utils.java
+++ b/src/main/java/cn/nukkit/utils/Utils.java
@@ -188,6 +188,8 @@ public static Object[][] splitArray(Object[] arrayToSplit, int chunkSize) {
}
public static int toInt(Object number) {
- return (int) Math.round((double) number);
+ int s = (int) Math.round((double) number);
+
+ return s;
}
}
From 70a7b5c745d24020b224fdff972eadcb17c8e0d8 Mon Sep 17 00:00:00 2001
From: Him188
Date: Sat, 19 Aug 2017 13:25:22 -0500
Subject: [PATCH 050/175] Fixed PlayerInventory#setArmorContents (#1862)
---
src/main/java/cn/nukkit/inventory/PlayerInventory.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/cn/nukkit/inventory/PlayerInventory.java b/src/main/java/cn/nukkit/inventory/PlayerInventory.java
index 4065f7c76f..3a5cb3b50e 100644
--- a/src/main/java/cn/nukkit/inventory/PlayerInventory.java
+++ b/src/main/java/cn/nukkit/inventory/PlayerInventory.java
@@ -344,7 +344,7 @@ public void setArmorContents(Item[] items) {
if (items[i].getId() == Item.AIR) {
this.clear(this.getSize() + i);
} else {
- this.setItem(this.getSize() + 1, items[i]);
+ this.setItem(this.getSize() + i, items[i]);
}
}
}
From aef45f8c4dac2b5733b66b5f3e6f0efb5094ed46 Mon Sep 17 00:00:00 2001
From: NycuRO
Date: Mon, 21 Aug 2017 02:14:11 +0300
Subject: [PATCH 051/175] Added capability to unblock addresses without a
restart (#1863)
* Update PardonIpCommand.java
* Final, need testing
* Update SessionManager.java
---
.../java/cn/nukkit/command/defaults/PardonIpCommand.java | 1 +
.../java/cn/nukkit/network/AdvancedSourceInterface.java | 2 ++
src/main/java/cn/nukkit/network/Network.java | 6 ++++++
src/main/java/cn/nukkit/network/RakNetInterface.java | 5 +++++
src/main/java/cn/nukkit/raknet/RakNet.java | 9 ++++++++-
src/main/java/cn/nukkit/raknet/server/ServerHandler.java | 9 +++++++++
.../java/cn/nukkit/raknet/server/SessionManager.java | 9 +++++++++
7 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/src/main/java/cn/nukkit/command/defaults/PardonIpCommand.java b/src/main/java/cn/nukkit/command/defaults/PardonIpCommand.java
index ccb687bba0..0fea580f32 100644
--- a/src/main/java/cn/nukkit/command/defaults/PardonIpCommand.java
+++ b/src/main/java/cn/nukkit/command/defaults/PardonIpCommand.java
@@ -39,6 +39,7 @@ public boolean execute(CommandSender sender, String commandLabel, String[] args)
if (Pattern.matches("^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$", value)) {
sender.getServer().getIPBans().remove(value);
+ sender.getServer().getNetwork().unblockAddress(value);
Command.broadcastCommandMessage(sender, new TranslationContainer("commands.unbanip.success", value));
} else {
diff --git a/src/main/java/cn/nukkit/network/AdvancedSourceInterface.java b/src/main/java/cn/nukkit/network/AdvancedSourceInterface.java
index 9203a4fc46..6902856b74 100644
--- a/src/main/java/cn/nukkit/network/AdvancedSourceInterface.java
+++ b/src/main/java/cn/nukkit/network/AdvancedSourceInterface.java
@@ -10,6 +10,8 @@ public interface AdvancedSourceInterface extends SourceInterface {
void blockAddress(String address, int timeout);
+ void unblockAddress(String address);
+
void setNetwork(Network network);
void sendRawPacket(String address, int port, byte[] payload);
diff --git a/src/main/java/cn/nukkit/network/Network.java b/src/main/java/cn/nukkit/network/Network.java
index 1c937272c7..72035a0d6e 100644
--- a/src/main/java/cn/nukkit/network/Network.java
+++ b/src/main/java/cn/nukkit/network/Network.java
@@ -211,6 +211,12 @@ public void blockAddress(String address, int timeout) {
}
}
+ public void unblockAddress(String address) {
+ for (AdvancedSourceInterface interfaz : this.advancedInterfaces) {
+ interfaz.unblockAddress(address);
+ }
+ }
+
private void registerPackets() {
this.packetPool = new Class[256];
diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java
index 745d019763..8e98db40e8 100644
--- a/src/main/java/cn/nukkit/network/RakNetInterface.java
+++ b/src/main/java/cn/nukkit/network/RakNetInterface.java
@@ -184,6 +184,11 @@ public void blockAddress(String address, int timeout) {
this.handler.blockAddress(address, timeout);
}
+ @Override
+ public void unblockAddress(String address) {
+ this.handler.unblockAddress(address);
+ }
+
@Override
public void handleRaw(String address, int port, byte[] payload) {
this.server.handlePacket(address, port, payload);
diff --git a/src/main/java/cn/nukkit/raknet/RakNet.java b/src/main/java/cn/nukkit/raknet/RakNet.java
index 7e2110ec7f..e76a018149 100644
--- a/src/main/java/cn/nukkit/raknet/RakNet.java
+++ b/src/main/java/cn/nukkit/raknet/RakNet.java
@@ -89,13 +89,20 @@ public abstract class RakNet {
public static final byte PACKET_RAW = 0x08;
/*
- * RAW payload:
+ * BLOCK_ADDRESS payload:
* byte (address length)
* byte[] (address)
* int (timeout)
*/
public static final byte PACKET_BLOCK_ADDRESS = 0x09;
+ /*
+ * UNBLOCK_ADDRESS payload:
+ * byte (adress length)
+ * byte[] (address)
+ */
+ public static final byte PACKET_UNBLOCK_ADDRESS = 0x10;
+
/*
* No payload
*
diff --git a/src/main/java/cn/nukkit/raknet/server/ServerHandler.java b/src/main/java/cn/nukkit/raknet/server/ServerHandler.java
index 23c9748676..c75e462d8c 100644
--- a/src/main/java/cn/nukkit/raknet/server/ServerHandler.java
+++ b/src/main/java/cn/nukkit/raknet/server/ServerHandler.java
@@ -78,6 +78,15 @@ public void blockAddress(String address, int timeout) {
this.server.pushMainToThreadPacket(buffer);
}
+ public void unblockAddress(String address) {
+ byte[] buffer = Binary.appendBytes(
+ RakNet.PACKET_UNBLOCK_ADDRESS,
+ new byte[]{(byte) (address.length() & 0xff)},
+ address.getBytes(StandardCharsets.UTF_8)
+ );
+ this.server.pushMainToThreadPacket(buffer);
+ }
+
public void shutdown() {
this.server.pushMainToThreadPacket(new byte[]{RakNet.PACKET_SHUTDOWN});
this.server.shutdown();
diff --git a/src/main/java/cn/nukkit/raknet/server/SessionManager.java b/src/main/java/cn/nukkit/raknet/server/SessionManager.java
index b97e7cd46b..d5252f15eb 100644
--- a/src/main/java/cn/nukkit/raknet/server/SessionManager.java
+++ b/src/main/java/cn/nukkit/raknet/server/SessionManager.java
@@ -383,6 +383,11 @@ public boolean receiveStream() throws Exception {
int timeout = Binary.readInt(Binary.subBytes(packet, offset, 4));
this.blockAddress(address, timeout);
break;
+ case RakNet.PACKET_UNBLOCK_ADDRESS:
+ len = packet[offset++];
+ address = new String(Binary.subBytes(packet, offset, len), StandardCharsets.UTF_8);
+ this.unblockAddress(address);
+ break;
case RakNet.PACKET_SHUTDOWN:
for (Session session : new ArrayList<>(this.sessions.values())) {
this.removeSession(session);
@@ -420,6 +425,10 @@ public void blockAddress(String address, int timeout) {
}
}
+ public void unblockAddress(String address) {
+ this.block.remove(address);
+ }
+
public Session getSession(String ip, int port) {
String id = ip + ":" + port;
if (!this.sessions.containsKey(id)) {
From 366b59306ae3ac1192fb334f62c0422a814c122f Mon Sep 17 00:00:00 2001
From: Adam Matthew
Date: Mon, 21 Aug 2017 07:29:09 +0800
Subject: [PATCH 052/175] Fix motion leak (#1855)
* Fix motion leak
* hmm
* huh
* Okay last piece
* Making this thing more sense
---
src/main/java/cn/nukkit/entity/Entity.java | 9 +++++----
.../entity/item/EntityMinecartAbstract.java | 17 +++++++++++------
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java
index 0d810437ce..d6e11ba6b4 100644
--- a/src/main/java/cn/nukkit/entity/Entity.java
+++ b/src/main/java/cn/nukkit/entity/Entity.java
@@ -1369,7 +1369,8 @@ public void applyEntityCollision(Entity entity) {
dx *= 1.0F + entityCollisionReduction;
dz *= 1.0F + entityCollisionReduction;
if (this.riding == null) {
- setMotion(new Vector3(-dx, 0.0D, -dy));
+ motionX -= dx;
+ motionZ -= dy;
}
}
}
@@ -1767,9 +1768,9 @@ public boolean setMotion(Vector3 motion) {
}
}
- this.motionX += motion.x;
- this.motionY += motion.y;
- this.motionZ += motion.z;
+ this.motionX = motion.x;
+ this.motionY = motion.y;
+ this.motionZ = motion.z;
if (!this.justCreated) {
this.updateMovement();
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
index 8b51e34d93..d1710a9382 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
@@ -356,13 +356,15 @@ public void applyEntityCollision(Entity entity) {
if (mine.getType().getId() == 2 && getType().getId() != 2) {
motionX *= 0.20000000298023224D;
motionZ *= 0.20000000298023224D;
- setMotion(new Vector3(mine.motionX - motiveX, 0, mine.motionZ - motiveZ));
+ motionX += mine.motionX - motiveX;
+ motionZ += mine.motionZ - motiveZ;
mine.motionX *= 0.949999988079071D;
mine.motionZ *= 0.949999988079071D;
} else if (mine.getType().getId() != 2 && getType().getId() == 2) {
mine.motionX *= 0.20000000298023224D;
mine.motionZ *= 0.20000000298023224D;
- mine.setMotion(new Vector3(motionX + motiveX, 0, motionZ + motiveZ));
+ motionX += mine.motionX + motiveX;
+ motionZ += mine.motionZ + motiveZ;
motionX *= 0.949999988079071D;
motionZ *= 0.949999988079071D;
} else {
@@ -370,14 +372,17 @@ public void applyEntityCollision(Entity entity) {
motZ /= 2;
motionX *= 0.20000000298023224D;
motionZ *= 0.20000000298023224D;
- setMotion(new Vector3(motX - motiveX, 0, motZ - motiveZ));
+ motionX += motX - motiveX;
+ motionZ += motZ - motiveZ;
mine.motionX *= 0.20000000298023224D;
mine.motionZ *= 0.20000000298023224D;
- mine.setMotion(new Vector3(motX + motiveX, 0, motZ + motiveZ));
+ mine.motionX += motX + motiveX;
+ mine.motionZ += motZ + motiveZ;
}
} else {
- setMotion(new Vector3(-motiveX, 0, -motiveZ));
- }
+ motionX -= motiveX;
+ motionZ -= motiveZ;
+ }
}
}
}
From d37c51ace960e7476be38cb384540ae2827882d3 Mon Sep 17 00:00:00 2001
From: Anton
Date: Tue, 22 Aug 2017 17:27:41 +0300
Subject: [PATCH 053/175] Fix #1802 (#1804)
---
src/main/java/cn/nukkit/plugin/PluginDescription.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/cn/nukkit/plugin/PluginDescription.java b/src/main/java/cn/nukkit/plugin/PluginDescription.java
index 3140a7958e..f9449dccc4 100644
--- a/src/main/java/cn/nukkit/plugin/PluginDescription.java
+++ b/src/main/java/cn/nukkit/plugin/PluginDescription.java
@@ -142,7 +142,7 @@ private void loadMap(Map plugin) throws PluginException {
throw new PluginException("Invalid PluginDescription name");
}
this.name = this.name.replace(" ", "_");
- this.version = (String) plugin.get("version");
+ this.version = String.valueOf(plugin.get("version"));
this.main = (String) plugin.get("main");
Object api = plugin.get("api");
if (api instanceof List) {
From 2abb0ee60b6495b5159a8b5c6bf76844bbba94ff Mon Sep 17 00:00:00 2001
From: SuperMaXAleX
Date: Tue, 22 Aug 2017 16:46:34 +0200
Subject: [PATCH 054/175] Fixed duplicate dropped item (#1823)
It's useless to send 2 times the TakeItemEntityPacket, because it is already sending it to every viewers of the entity which is the dropped item.
---
src/main/java/cn/nukkit/Player.java | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 9538c94a7e..03c96fdc36 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -1276,11 +1276,6 @@ protected void checkNearEntities() {
pk.target = entity.getId();
Server.broadcastPacket(entity.getViewers().values(), pk);
- pk = new TakeItemEntityPacket();
- pk.entityId = this.id;
- pk.target = entity.getId();
- this.dataPacket(pk);
-
this.inventory.addItem(item.clone());
entity.kill();
} else if (entity instanceof EntityItem) {
@@ -1321,11 +1316,6 @@ protected void checkNearEntities() {
pk.target = entity.getId();
Server.broadcastPacket(entity.getViewers().values(), pk);
- pk = new TakeItemEntityPacket();
- pk.entityId = this.id;
- pk.target = entity.getId();
- this.dataPacket(pk);
-
this.inventory.addItem(item.clone());
entity.kill();
}
From 4c78e69385e260295d29e5434984b37bed1e7567 Mon Sep 17 00:00:00 2001
From: jj19971130 <1901014432@qq.com>
Date: Wed, 23 Aug 2017 12:26:51 +0800
Subject: [PATCH 055/175] repair the problem that command.isRegistered always
false (#1832)
---
src/main/java/cn/nukkit/command/Command.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/cn/nukkit/command/Command.java b/src/main/java/cn/nukkit/command/Command.java
index 76471bced4..7294aff141 100644
--- a/src/main/java/cn/nukkit/command/Command.java
+++ b/src/main/java/cn/nukkit/command/Command.java
@@ -207,7 +207,7 @@ public boolean unregister(CommandMap commandMap) {
}
public boolean allowChangesFrom(CommandMap commandMap) {
- return commandMap == null || commandMap.equals(this.commandMap);
+ return commandMap != null && !commandMap.equals(this.commandMap);
}
public boolean isRegistered() {
From 8dd43f4886a33ed5cc28c994d482e7c76135ff98 Mon Sep 17 00:00:00 2001
From: kvetinac97
Date: Thu, 24 Aug 2017 08:16:48 +0200
Subject: [PATCH 056/175] Fix #57 - Commands show now (#63)
* Fix #57 - Commands show now
* Fix build
---
.../protocol/AvailableCommandsPacket.java | 104 +++++++++---------
1 file changed, 54 insertions(+), 50 deletions(-)
diff --git a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java
index 3da2a3ae95..9241bc45ee 100644
--- a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java
+++ b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java
@@ -6,6 +6,7 @@
import cn.nukkit.utils.BinaryStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -18,6 +19,16 @@ public class AvailableCommandsPacket extends DataPacket {
public static final byte NETWORK_ID = ProtocolInfo.AVAILABLE_COMMANDS_PACKET;
public Map commands;
+
+ public static final int ARG_FLAG_VALID = 0x100000;
+ public static final int ARG_TYPE_INT = 0x01;
+ public static final int ARG_TYPE_FLOAT = 0x02;
+ public static final int ARG_TYPE_VALUE = 0x03;
+ public static final int ARG_TYPE_TARGET = 0x04;
+ public static final int ARG_TYPE_STRING = 0x0c;
+ public static final int ARG_TYPE_POSITION = 0x0d;
+ public static final int ARG_TYPE_RAWTEXT = 0x10;
+ public static final int ARG_TYPE_TEXT = 0x12;
@Override
public byte pid() {
@@ -28,64 +39,57 @@ public byte pid() {
public void decode() {
}
+ int aliasCommands = 0;
@Override
- public void encode() { //TODO: check if this is able to be simplified
+ public void encode() {
this.reset();
- List enumValues = new ArrayList<>();
- Map enumAdditional = new HashMap<>();
- List enums = new ArrayList<>();
BinaryStream commandsStream = new BinaryStream();
- commands.forEach((name, versions) -> {
- if (name.equals("help")) { //temp fix for 1.2
- return;
- }
- commandsStream.putString(name);
- commandsStream.putString(versions.versions.get(0).description);
- commandsStream.putByte((byte) 0); //flags
- commandsStream.putByte((byte) 0); //permission level
- int aliasEnumId;
- if (versions.versions.get(0).aliases != null && versions.versions.get(0).aliases.length != 0) {
- List aliases = new ArrayList<>();
- for (String alias : versions.versions.get(0).aliases) {
- int targetIndex;
- if (!enumAdditional.containsKey(alias)) {
- enumValues.add(alias);
- enumAdditional.put(alias, enumValues.size() - 1);
- targetIndex = enumValues.size() - 1;
- } else {
- targetIndex = enumAdditional.get(alias);
+ this.commands.forEach((name, versions) -> {
+ if (name.equals("help")) return;
+ ArrayList aliases = new ArrayList<>();
+ aliases.addAll(Arrays.asList(versions.versions.get(0).aliases));
+ aliases.add(name);
+ for (String alias : aliases){
+ commandsStream.putString(alias);
+ commandsStream.putString(versions.versions.get(0).description);
+ commandsStream.putByte((byte) 0);
+ commandsStream.putByte((byte) 0);
+ commandsStream.putLInt(-1);
+ commandsStream.putUnsignedVarInt(versions.versions.get(0).overloads.size());
+ for (CommandOverload overload : versions.versions.get(0).overloads.values()){
+ commandsStream.putUnsignedVarInt(overload.input.parameters.length);
+ for (CommandParameter parameter : overload.input.parameters){
+ commandsStream.putString(parameter.name);
+ commandsStream.putLInt(ARG_FLAG_VALID | getFlag(parameter.type));
+ commandsStream.putBoolean(parameter.optional);
}
- aliases.add(targetIndex);
- }
- enums.add(new Object[]{name, aliases});
- aliasEnumId = enums.size() - 1;
- } else {
- aliasEnumId = -1;
- }
- commandsStream.putLInt(aliasEnumId);
- commandsStream.putVarInt(versions.versions.get(0).overloads.size());
- for (CommandOverload overload : versions.versions.get(0).overloads.values()) {
- commandsStream.putVarInt(overload.input.parameters.length);
- for (CommandParameter parameter : overload.input.parameters) {
- commandsStream.putString(parameter.name);
- commandsStream.putLInt(0);
- commandsStream.putBoolean(parameter.optional);
}
}
+ aliasCommands += (aliases.size()-1);
});
- this.putVarInt(enumValues.size());
- enumValues.forEach(this::putString);
- this.putVarInt(0);
- this.putVarInt(enums.size());
- enums.forEach(o -> {
- this.putString(o[0] + "CommandAliases");
- List data = (List) o[1];
- this.putVarInt(data.size());
- data.forEach(this::putVarInt);
- });
-
- this.putVarInt(commands.size());
+ this.putUnsignedVarInt(0);
+ this.putUnsignedVarInt(0);
+ this.putUnsignedVarInt(0);
+ this.putUnsignedVarInt(this.commands.size()+aliasCommands);
this.put(commandsStream.getBuffer());
}
+
+ int getFlag(String type){
+ switch (type){
+ case CommandParameter.ARG_TYPE_BLOCK_POS:
+ return ARG_TYPE_POSITION;
+ case CommandParameter.ARG_TYPE_INT:
+ return ARG_TYPE_INT;
+ case CommandParameter.ARG_TYPE_PLAYER:
+ return ARG_TYPE_TARGET;
+ case CommandParameter.ARG_TYPE_RAW_TEXT:
+ return ARG_TYPE_RAWTEXT;
+ case CommandParameter.ARG_TYPE_STRING:
+ case CommandParameter.ARG_TYPE_STRING_ENUM:
+ return ARG_TYPE_STRING;
+ default:
+ return 0;
+ }
+ }
}
From 9709878df71e40544f77057e4efc02b1e70d0ddd Mon Sep 17 00:00:00 2001
From: kvetinac97
Date: Thu, 24 Aug 2017 08:21:28 +0200
Subject: [PATCH 057/175] Fix Interact/BlockPlace/Break Events not being called
(#64)
* Fix #59 - InteractEvent now working
(BlockBreak and BlockPlace still work for me even without changes)
* Fix build
* Fix wrong values
* There was not any error
---
.../inventory/transaction/TransactionGroup.java | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java
index f13dbcd22f..5ae20a0f0a 100644
--- a/src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java
+++ b/src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java
@@ -11,17 +11,18 @@
public interface TransactionGroup {
int TYPE_NORMAL = 0;
- int TYPE_INVENTORY_MISMATCH = 1;
- int TYPE_ITEM_USE = 2;
+ int TYPE_ITEM_USE = 1; //This is surely 1
+ int TYPE_INVENTORY_MISMATCH = 2; //I do not know this
int TYPE_ITEM_USE_ON_ENTITY = 3;
int TYPE_ITEM_RELEASE = 4;
int ITEM_RELEASE_ACTION_RELEASE = 0; //Drop item
int ITEM_RELEASE_ACTION_USE = 1; //Shoot arrows, etc.
- int ITEM_USE_ACTION_PLACE = 0;
- int ITEM_USE_ACTION_USE = 1;
- int ITEM_USE_ACTION_DESTROY = 2;
+ //Checked, this values should be like this
+ int ITEM_USE_ACTION_PLACE = 1;
+ int ITEM_USE_ACTION_USE = 0;
+ int ITEM_USE_ACTION_DESTROY = -1;
int ITEM_USE_ON_ENTITY_ACTION_INTERACT = 0; //TODO: Check the use of these actions
int ITEM_USE_ON_ENTITY_ACTION_ATTACK = 1;
From 0153849ae40b7ee02c9030b50208bfc956b48fdf Mon Sep 17 00:00:00 2001
From: CreeperFace
Date: Fri, 25 Aug 2017 10:26:48 +0200
Subject: [PATCH 058/175] ops
---
src/main/java/cn/nukkit/Player.java | 33 +++++++----------------------
1 file changed, 8 insertions(+), 25 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 552b5cb94a..ca8173bac0 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -1,23 +1,24 @@
package cn.nukkit;
-import cn.nukkit.block.*;
+import cn.nukkit.block.Block;
+import cn.nukkit.block.BlockAir;
+import cn.nukkit.block.BlockEnderChest;
+import cn.nukkit.block.BlockNoteblock;
import cn.nukkit.blockentity.BlockEntity;
import cn.nukkit.blockentity.BlockEntityItemFrame;
import cn.nukkit.blockentity.BlockEntitySign;
import cn.nukkit.command.Command;
import cn.nukkit.command.CommandSender;
import cn.nukkit.command.data.CommandDataVersions;
-import cn.nukkit.command.data.CommandParameter;
-import cn.nukkit.command.data.args.CommandArg;
-import cn.nukkit.command.data.args.CommandArgBlockVector;
import cn.nukkit.entity.*;
import cn.nukkit.entity.data.*;
import cn.nukkit.entity.item.*;
-import cn.nukkit.entity.mob.EntityCreeper;
-import cn.nukkit.entity.projectile.*;
+import cn.nukkit.entity.projectile.EntityArrow;
import cn.nukkit.event.block.ItemFrameDropItemEvent;
import cn.nukkit.event.block.SignChangeEvent;
-import cn.nukkit.event.entity.*;
+import cn.nukkit.event.entity.EntityDamageByBlockEvent;
+import cn.nukkit.event.entity.EntityDamageByEntityEvent;
+import cn.nukkit.event.entity.EntityDamageEvent;
import cn.nukkit.event.entity.EntityDamageEvent.DamageCause;
import cn.nukkit.event.entity.EntityDamageEvent.DamageModifier;
import cn.nukkit.event.inventory.*;
@@ -44,7 +45,6 @@
import cn.nukkit.level.particle.PunchBlockParticle;
import cn.nukkit.level.sound.ExperienceOrbSound;
import cn.nukkit.level.sound.ItemFrameItemRemovedSound;
-import cn.nukkit.level.sound.LaunchSound;
import cn.nukkit.math.*;
import cn.nukkit.metadata.MetadataValue;
import cn.nukkit.nbt.NBTIO;
@@ -62,14 +62,11 @@
import cn.nukkit.utils.*;
import co.aikar.timings.Timing;
import co.aikar.timings.Timings;
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteOrder;
import java.util.*;
-import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -2271,19 +2268,13 @@ public void handleDataPacket(DataPacket packet) {
this.getLevel().addChunkPacket(pos.getFloorX() >> 4, pos.getFloorZ() >> 4, pk);
this.breakingBlock = null;
break;
-
case PlayerActionPacket.ACTION_GET_UPDATED_BLOCK:
break; //TODO
-
case PlayerActionPacket.ACTION_DROP_ITEM:
break; //TODO
-
-
- break;
case PlayerActionPacket.ACTION_STOP_SLEEPING:
this.stopSleep();
break;
-
case PlayerActionPacket.ACTION_RESPAWN:
if (!this.spawned || this.isAlive() || !this.isOnline()) {
break;
@@ -2332,10 +2323,8 @@ public void handleDataPacket(DataPacket packet) {
this.spawnToAll();
this.scheduleUpdate();
break;
-
case PlayerActionPacket.ACTION_JUMP:
break packetswitch;
-
case PlayerActionPacket.ACTION_START_SPRINT:
PlayerToggleSprintEvent playerToggleSprintEvent = new PlayerToggleSprintEvent(this, true);
this.server.getPluginManager().callEvent(playerToggleSprintEvent);
@@ -2345,7 +2334,6 @@ public void handleDataPacket(DataPacket packet) {
this.setSprinting(true);
}
break packetswitch;
-
case PlayerActionPacket.ACTION_STOP_SPRINT:
playerToggleSprintEvent = new PlayerToggleSprintEvent(this, false);
this.server.getPluginManager().callEvent(playerToggleSprintEvent);
@@ -2355,7 +2343,6 @@ public void handleDataPacket(DataPacket packet) {
this.setSprinting(false);
}
break packetswitch;
-
case PlayerActionPacket.ACTION_START_SNEAK:
PlayerToggleSneakEvent playerToggleSneakEvent = new PlayerToggleSneakEvent(this, true);
this.server.getPluginManager().callEvent(playerToggleSneakEvent);
@@ -2365,7 +2352,6 @@ public void handleDataPacket(DataPacket packet) {
this.setSneaking(true);
}
break packetswitch;
-
case PlayerActionPacket.ACTION_STOP_SNEAK:
playerToggleSneakEvent = new PlayerToggleSneakEvent(this, false);
this.server.getPluginManager().callEvent(playerToggleSneakEvent);
@@ -2375,10 +2361,8 @@ public void handleDataPacket(DataPacket packet) {
this.setSneaking(false);
}
break packetswitch;
-
case PlayerActionPacket.ACTION_DIMENSION_CHANGE_ACK:
break; //TODO
-
case PlayerActionPacket.ACTION_START_GLIDE:
PlayerToggleGlideEvent playerToggleGlideEvent = new PlayerToggleGlideEvent(this, true);
this.server.getPluginManager().callEvent(playerToggleGlideEvent);
@@ -2388,7 +2372,6 @@ public void handleDataPacket(DataPacket packet) {
this.setGliding(true);
}
break packetswitch;
-
case PlayerActionPacket.ACTION_STOP_GLIDE:
playerToggleGlideEvent = new PlayerToggleGlideEvent(this, false);
this.server.getPluginManager().callEvent(playerToggleGlideEvent);
From 5b04671d7b792ddc2b696da272adbfba1895d989 Mon Sep 17 00:00:00 2001
From: PeratX <1215714524@qq.com>
Date: Fri, 25 Aug 2017 20:36:40 +0800
Subject: [PATCH 059/175] Add Yivesmirror to README.md. Close #1876
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 25a73cec5e..220403d2cc 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,7 @@ Get Nukkit & Plugins
*These sites are provided by our users, Nukkit staff are not responsible for the reliability of these sites. Jar files downloaded here are only for reference - to try the latest update or for commercial uses, compile by yourself.*
* __[Jenkins by MengCraft](http://ci.mengcraft.com:8080/job/Nukkit/lastSuccessfulBuild/)__ (**UNOFFICIAL**)
+* __[Yivesmirror](https://yivesmirror.com/downloads/nukkit)__ (**UNOFFICIAL**)
Build JAR file
-------------
From 9997eca01cd7dfca4036ab4ac03be3beaf06156e Mon Sep 17 00:00:00 2001
From: Creeperface01
Date: Sat, 26 Aug 2017 11:33:14 +0200
Subject: [PATCH 060/175] improvements (#1834)
* improvements
* add returns to setters, stairs collision
---
src/main/java/cn/nukkit/Player.java | 190 +--
src/main/java/cn/nukkit/Server.java | 25 +-
.../java/cn/nukkit/block/BlockStairs.java | 76 ++
src/main/java/cn/nukkit/entity/Entity.java | 22 +-
.../cn/nukkit/entity/EntityInteractable.java | 2 +-
.../java/cn/nukkit/entity/EntityLiving.java | 2 +-
.../cn/nukkit/entity/item/EntityBoat.java | 6 +-
.../cn/nukkit/entity/item/EntityItem.java | 9 +-
.../entity/item/EntityMinecartAbstract.java | 36 +-
.../entity/item/EntityMinecartChest.java | 3 +-
.../entity/item/EntityMinecartEmpty.java | 2 +-
.../entity/item/EntityMinecartHopper.java | 2 +-
.../cn/nukkit/entity/item/EntityPainting.java | 2 +-
.../cn/nukkit/entity/item/EntityVehicle.java | 5 +-
.../cn/nukkit/entity/item/EntityXPOrb.java | 8 +
.../java/cn/nukkit/entity/mob/EntityMob.java | 2 +-
.../cn/nukkit/entity/mob/EntitySkeleton.java | 2 +-
.../cn/nukkit/entity/mob/EntityZombie.java | 2 +-
.../nukkit/entity/mob/EntityZombiePigman.java | 2 +-
.../cn/nukkit/entity/passive/EntityBat.java | 1 -
.../nukkit/entity/passive/EntityChicken.java | 2 +-
.../cn/nukkit/entity/passive/EntityCow.java | 2 +-
.../nukkit/entity/passive/EntityDonkey.java | 1 -
.../cn/nukkit/entity/passive/EntityHorse.java | 1 -
.../cn/nukkit/entity/passive/EntityLlama.java | 1 -
.../entity/passive/EntityMooshroom.java | 2 +-
.../cn/nukkit/entity/passive/EntityMule.java | 1 -
.../nukkit/entity/passive/EntityOcelot.java | 2 +-
.../cn/nukkit/entity/passive/EntityPig.java | 2 +-
.../entity/passive/EntityPolarBear.java | 1 -
.../nukkit/entity/passive/EntityRabbit.java | 2 +-
.../cn/nukkit/entity/passive/EntitySheep.java | 2 +-
.../entity/passive/EntitySkeletonHorse.java | 1 -
.../cn/nukkit/entity/passive/EntitySquid.java | 1 -
.../cn/nukkit/entity/passive/EntityWolf.java | 2 +-
.../entity/passive/EntityZombieHorse.java | 1 -
.../cn/nukkit/inventory/BigShapedRecipe.java | 2 +-
.../cn/nukkit/inventory/CraftingManager.java | 1213 +----------------
.../cn/nukkit/inventory/PlayerInventory.java | 2 +-
.../cn/nukkit/inventory/ShapedRecipe.java | 36 +-
src/main/java/cn/nukkit/item/Item.java | 3 +-
.../nukkit/item/enchantment/Enchantment.java | 10 +-
src/main/java/cn/nukkit/level/Level.java | 3 +-
.../nukkit/network/protocol/ProtocolInfo.java | 3 +-
src/main/java/cn/nukkit/utils/Utils.java | 32 +-
src/main/resources/recipes.json | 6 +-
46 files changed, 355 insertions(+), 1378 deletions(-)
diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java
index 03c96fdc36..4b0a4b136a 100644
--- a/src/main/java/cn/nukkit/Player.java
+++ b/src/main/java/cn/nukkit/Player.java
@@ -197,6 +197,8 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
private ClientChainData loginChainData;
+ public int pickedXPOrb = 0;
+
public BlockEnderChest getViewingEnderChest() {
return viewingEnderChest;
}
@@ -1248,6 +1250,8 @@ protected void checkBlockCollision() {
if (portal) {
inPortalTicks++;
+ } else {
+ this.inPortalTicks = 0;
}
}
@@ -1259,85 +1263,7 @@ protected void checkNearEntities() {
continue;
}
- if (entity instanceof EntityArrow && ((EntityArrow) entity).hadCollision) {
- ItemArrow item = new ItemArrow();
- if (this.isSurvival() && !this.inventory.canAddItem(item)) {
- continue;
- }
-
- InventoryPickupArrowEvent ev;
- this.server.getPluginManager().callEvent(ev = new InventoryPickupArrowEvent(this.inventory, (EntityArrow) entity));
- if (ev.isCancelled()) {
- continue;
- }
-
- TakeItemEntityPacket pk = new TakeItemEntityPacket();
- pk.entityId = this.getId();
- pk.target = entity.getId();
- Server.broadcastPacket(entity.getViewers().values(), pk);
-
- this.inventory.addItem(item.clone());
- entity.kill();
- } else if (entity instanceof EntityItem) {
- if (((EntityItem) entity).getPickupDelay() <= 0) {
- Item item = ((EntityItem) entity).getItem();
-
- if (item != null) {
- if (this.isSurvival() && !this.inventory.canAddItem(item)) {
- continue;
- }
-
- InventoryPickupItemEvent ev;
- this.server.getPluginManager().callEvent(ev = new InventoryPickupItemEvent(this.inventory, (EntityItem) entity));
- if (ev.isCancelled()) {
- continue;
- }
-
- switch (item.getId()) {
- case Item.WOOD:
- case Item.WOOD2:
- this.awardAchievement("mineWood");
- break;
- case Item.DIAMOND:
- this.awardAchievement("diamond");
- break;
- }
- /*switch (item.getId()) {
- case Item.WOOD:
- this.awardAchievement("mineWood");
- break;
- case Item.DIAMOND:
- this.awardAchievement("diamond");
- break;
- }*/
-
- TakeItemEntityPacket pk = new TakeItemEntityPacket();
- pk.entityId = this.getId();
- pk.target = entity.getId();
- Server.broadcastPacket(entity.getViewers().values(), pk);
-
- this.inventory.addItem(item.clone());
- entity.kill();
- }
- }
- }
- }
- for (Entity entity : this.level.getNearbyEntities(this.boundingBox.grow(3.5, 2, 3.5), this)) {
- entity.scheduleUpdate();
-
- if (!entity.isAlive() || !this.isAlive()) {
- continue;
- }
- if (entity instanceof EntityXPOrb) {
- EntityXPOrb xpOrb = (EntityXPOrb) entity;
- if (xpOrb.getPickupDelay() <= 0) {
- int exp = xpOrb.getExp();
- this.addExperience(exp);
- entity.kill();
- this.getLevel().addSound(new ExperienceOrbSound(this));
- break;
- }
- }
+ this.pickupEntity(entity, true);
}
}
@@ -4486,7 +4412,7 @@ protected boolean checkTeleportPosition() {
}
}
- if (this.isLevelChange) { //TODO: remove this
+ /*if (this.isLevelChange) { //TODO: remove this
PlayStatusPacket statusPacket0 = new PlayStatusPacket();//Weather
this.getLevel().sendWeather(this);
//Update time
@@ -4498,7 +4424,7 @@ protected boolean checkTeleportPosition() {
this.getLevel().sendWeather(this);
//Update time
this.getLevel().sendTime(this);
- }
+ }*/
this.spawnToAll();
this.isLevelChange = false;
@@ -4562,7 +4488,7 @@ public boolean teleport(Location location, TeleportCause cause) {
this.getLevel().sendTime(this);
if (from.getLevel().getId() != to.level.getId()) {
- if (this.spawned) {
+ /*if (this.spawned) { //broken
//TODO: remove this in future version
this.isLevelChange = true;
this.nextChunkOrderRun = 10000;
@@ -4590,7 +4516,7 @@ public boolean teleport(Location location, TeleportCause cause) {
dataPacket(changeDimensionPacket);
nextChunkOrderRun = 0;
}, 9);
- }
+ }*/
}
return true;
}
@@ -4931,6 +4857,104 @@ public ClientChainData getLoginChainData() {
return this.loginChainData;
}
+ public boolean pickupEntity(Entity entity, boolean near) {
+ if (!this.spawned || !this.isAlive() || !this.isOnline()) {
+ return false;
+ }
+
+ if (near) {
+ if (entity instanceof EntityArrow && ((EntityArrow) entity).hadCollision) {
+ ItemArrow item = new ItemArrow();
+ if (this.isSurvival() && !this.inventory.canAddItem(item)) {
+ return false;
+ }
+
+ InventoryPickupArrowEvent ev;
+ this.server.getPluginManager().callEvent(ev = new InventoryPickupArrowEvent(this.inventory, (EntityArrow) entity));
+ if (ev.isCancelled()) {
+ return false;
+ }
+
+ TakeItemEntityPacket pk = new TakeItemEntityPacket();
+ pk.entityId = this.getId();
+ pk.target = entity.getId();
+ Server.broadcastPacket(entity.getViewers().values(), pk);
+
+ pk = new TakeItemEntityPacket();
+ pk.entityId = this.id;
+ pk.target = entity.getId();
+ this.dataPacket(pk);
+
+ this.inventory.addItem(item.clone());
+ entity.kill();
+ return true;
+ } else if (entity instanceof EntityItem) {
+ if (((EntityItem) entity).getPickupDelay() <= 0) {
+ Item item = ((EntityItem) entity).getItem();
+
+ if (item != null) {
+ if (this.isSurvival() && !this.inventory.canAddItem(item)) {
+ return false;
+ }
+
+ InventoryPickupItemEvent ev;
+ this.server.getPluginManager().callEvent(ev = new InventoryPickupItemEvent(this.inventory, (EntityItem) entity));
+ if (ev.isCancelled()) {
+ return false;
+ }
+
+ switch (item.getId()) {
+ case Item.WOOD:
+ case Item.WOOD2:
+ this.awardAchievement("mineWood");
+ break;
+ case Item.DIAMOND:
+ this.awardAchievement("diamond");
+ break;
+ }
+ /*switch (item.getId()) {
+ case Item.WOOD:
+ this.awardAchievement("mineWood");
+ break;
+ case Item.DIAMOND:
+ this.awardAchievement("diamond");
+ break;
+ }*/
+
+ TakeItemEntityPacket pk = new TakeItemEntityPacket();
+ pk.entityId = this.getId();
+ pk.target = entity.getId();
+ Server.broadcastPacket(entity.getViewers().values(), pk);
+
+ pk = new TakeItemEntityPacket();
+ pk.entityId = this.id;
+ pk.target = entity.getId();
+ this.dataPacket(pk);
+
+ this.inventory.addItem(item.clone());
+ entity.kill();
+ return true;
+ }
+ }
+ }
+ }
+
+ int tick = this.getServer().getTick();
+ if (pickedXPOrb < tick && entity instanceof EntityXPOrb && this.boundingBox.isVectorInside(entity)) {
+ EntityXPOrb xpOrb = (EntityXPOrb) entity;
+ if (xpOrb.getPickupDelay() <= 0) {
+ int exp = xpOrb.getExp();
+ this.addExperience(exp);
+ entity.kill();
+ this.getLevel().addSound(new ExperienceOrbSound(this));
+ pickedXPOrb = tick;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
@Override
public int hashCode() {
if ((this.hash == 0) || (this.hash == 485)) {
diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java
index 9a12c51abf..81add9a976 100644
--- a/src/main/java/cn/nukkit/Server.java
+++ b/src/main/java/cn/nukkit/Server.java
@@ -17,7 +17,8 @@
import cn.nukkit.event.level.LevelInitEvent;
import cn.nukkit.event.level.LevelLoadEvent;
import cn.nukkit.event.server.QueryRegenerateEvent;
-import cn.nukkit.inventory.*;
+import cn.nukkit.inventory.CraftingManager;
+import cn.nukkit.inventory.Recipe;
import cn.nukkit.item.Item;
import cn.nukkit.item.enchantment.Enchantment;
import cn.nukkit.lang.BaseLang;
@@ -48,7 +49,10 @@
import cn.nukkit.network.Network;
import cn.nukkit.network.RakNetInterface;
import cn.nukkit.network.SourceInterface;
-import cn.nukkit.network.protocol.*;
+import cn.nukkit.network.protocol.BatchPacket;
+import cn.nukkit.network.protocol.DataPacket;
+import cn.nukkit.network.protocol.PlayerListPacket;
+import cn.nukkit.network.protocol.ProtocolInfo;
import cn.nukkit.network.query.QueryHandler;
import cn.nukkit.network.rcon.RCON;
import cn.nukkit.permission.BanEntry;
@@ -889,22 +893,7 @@ public void sendFullPlayerListData(Player player) {
}
public void sendRecipeList(Player player) {
- CraftingDataPacket pk = new CraftingDataPacket();
- pk.cleanRecipes = true;
-
- for (Recipe recipe : this.getCraftingManager().getRecipes().values()) {
- if (recipe instanceof ShapedRecipe) {
- pk.addShapedRecipe((ShapedRecipe) recipe);
- } else if (recipe instanceof ShapelessRecipe) {
- pk.addShapelessRecipe((ShapelessRecipe) recipe);
- }
- }
-
- for (FurnaceRecipe recipe : this.getCraftingManager().getFurnaceRecipes().values()) {
- pk.addFurnaceRecipe(recipe);
- }
-
- player.dataPacket(pk);
+ player.dataPacket(CraftingManager.packet);
}
private void checkTickUpdates(int currentTick, long tickTime) {
diff --git a/src/main/java/cn/nukkit/block/BlockStairs.java b/src/main/java/cn/nukkit/block/BlockStairs.java
index 90be6d2cdd..304b91f616 100644
--- a/src/main/java/cn/nukkit/block/BlockStairs.java
+++ b/src/main/java/cn/nukkit/block/BlockStairs.java
@@ -73,4 +73,80 @@ public Item toItem() {
item.setDamage(0);
return item;
}
+
+ @Override
+ public boolean collidesWithBB(AxisAlignedBB bb) {
+ int damage = this.getDamage();
+ int side = damage & 0x03;
+ double f = 0;
+ double f1 = 0.5;
+ double f2 = 0.5;
+ double f3 = 1;
+ if ((damage & 0x04) > 0) {
+ f = 0.5;
+ f1 = 1;
+ f2 = 0;
+ f3 = 0.5;
+ }
+
+ if (bb.intersectsWith(new AxisAlignedBB(
+ this.x,
+ this.y + f,
+ this.z,
+ this.x + 1,
+ this.y + f1,
+ this.z + 1
+ ))) {
+ return true;
+ }
+
+
+ if (side == 0) {
+ if (bb.intersectsWith(new AxisAlignedBB(
+ this.x + 0.5,
+ this.y + f2,
+ this.z,
+ this.x + 1,
+ this.y + f3,
+ this.z + 1
+ ))) {
+ return true;
+ }
+ } else if (side == 1) {
+ if (bb.intersectsWith(new AxisAlignedBB(
+ this.x,
+ this.y + f2,
+ this.z,
+ this.x + 0.5,
+ this.y + f3,
+ this.z + 1
+ ))) {
+ return true;
+ }
+ } else if (side == 2) {
+ if (bb.intersectsWith(new AxisAlignedBB(
+ this.x,
+ this.y + f2,
+ this.z + 0.5,
+ this.x + 1,
+ this.y + f3,
+ this.z + 1
+ ))) {
+ return true;
+ }
+ } else if (side == 3) {
+ if (bb.intersectsWith(new AxisAlignedBB(
+ this.x,
+ this.y + f2,
+ this.z,
+ this.x + 1,
+ this.y + f3,
+ this.z + 0.5
+ ))) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java
index d6e11ba6b4..7deed970e6 100644
--- a/src/main/java/cn/nukkit/entity/Entity.java
+++ b/src/main/java/cn/nukkit/entity/Entity.java
@@ -26,7 +26,10 @@
import cn.nukkit.nbt.tag.DoubleTag;
import cn.nukkit.nbt.tag.FloatTag;
import cn.nukkit.nbt.tag.ListTag;
-import cn.nukkit.network.protocol.*;
+import cn.nukkit.network.protocol.MobEffectPacket;
+import cn.nukkit.network.protocol.RemoveEntityPacket;
+import cn.nukkit.network.protocol.SetEntityDataPacket;
+import cn.nukkit.network.protocol.SetEntityMotionPacket;
import cn.nukkit.plugin.Plugin;
import cn.nukkit.potion.Effect;
import cn.nukkit.utils.ChunkException;
@@ -222,10 +225,10 @@ public abstract class Entity extends Location implements Metadatable {
public double lastYaw;
public double lastPitch;
-
+
public double PitchDelta;
public double YawDelta;
-
+
public double entityCollisionReduction = 0; // Higher than 0.9 will result a fast collisions
public AxisAlignedBB boundingBox;
public boolean onGround;
@@ -545,7 +548,7 @@ public void setScale(float scale) {
public float getScale() {
return this.scale;
}
-
+
public Entity getLinkedEntity() {
return linkedEntity;
}
@@ -1086,12 +1089,11 @@ public boolean entityBaseTick(int tickDiff) {
}
}
- if (this.inPortalTicks > 80) {
+ if (this.inPortalTicks == 80) {
EntityPortalEnterEvent ev = new EntityPortalEnterEvent(this, PortalType.NETHER);
getServer().getPluginManager().callEvent(ev);
-
+
//TODO: teleport
- this.inPortalTicks = 0;
}
this.age += tickDiff;
@@ -1458,7 +1460,7 @@ public boolean isInsideOfFire() {
return false;
}
-
+
public boolean fastMove(double dx, double dy, double dz) {
if (dx == 0 && dy == 0 && dz == 0) {
return true;
@@ -1489,7 +1491,7 @@ public boolean fastMove(double dx, double dy, double dz) {
Timings.entityMoveTimer.stopTiming();
return true;
}
-
+
public boolean move(double dx, double dy, double dz) {
if (dx == 0 && dz == 0 && dy == 0) {
return true;
@@ -1667,6 +1669,8 @@ protected void checkBlockCollision() {
if (portal) {
inPortalTicks++;
+ } else {
+ this.inPortalTicks = 0;
}
if (vector.lengthSquared() > 0) {
diff --git a/src/main/java/cn/nukkit/entity/EntityInteractable.java b/src/main/java/cn/nukkit/entity/EntityInteractable.java
index bd4fe8ff55..22a44e01e4 100644
--- a/src/main/java/cn/nukkit/entity/EntityInteractable.java
+++ b/src/main/java/cn/nukkit/entity/EntityInteractable.java
@@ -14,7 +14,7 @@ public EntityInteractable(FullChunk chunk, CompoundTag nbt) {
// Todo: Passive entity?? i18n and boat leaving text
public abstract String getInteractButtonText();
-
+
public abstract boolean canDoInteraction();
}
diff --git a/src/main/java/cn/nukkit/entity/EntityLiving.java b/src/main/java/cn/nukkit/entity/EntityLiving.java
index b0f743eedf..932baed7ff 100644
--- a/src/main/java/cn/nukkit/entity/EntityLiving.java
+++ b/src/main/java/cn/nukkit/entity/EntityLiving.java
@@ -24,7 +24,7 @@
import java.util.Map;
/**
- * author: MagicDroidX
+ * author: MagicDroidX
* Nukkit Project
*/
public abstract class EntityLiving extends Entity implements EntityDamageable {
diff --git a/src/main/java/cn/nukkit/entity/item/EntityBoat.java b/src/main/java/cn/nukkit/entity/item/EntityBoat.java
index f4eff3eac1..a28e3209d2 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityBoat.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityBoat.java
@@ -62,7 +62,7 @@ protected float getGravity() {
public float getBaseOffset() {
return 0.35F;
}
-
+
@Override
public int getNetworkId() {
return NETWORK_ID;
@@ -112,7 +112,7 @@ public boolean attack(EntityDamageEvent source) {
}
}
}
-
+
return true;
}
@@ -146,7 +146,7 @@ public boolean onUpdate(int currentTick) {
if (this.isAlive()) {
super.onUpdate(currentTick);
-
+
this.motionY = (this.level.getBlock(new Vector3(this.x, this.y, this.z)).getBoundingBox() != null || this.isInsideOfWater()) ? getGravity() : -0.08;
if (this.checkObstruction(this.x, this.y, this.z)) {
diff --git a/src/main/java/cn/nukkit/entity/item/EntityItem.java b/src/main/java/cn/nukkit/entity/item/EntityItem.java
index 9baf3460c7..655536819f 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityItem.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityItem.java
@@ -133,12 +133,19 @@ public boolean onUpdate(int currentTick) {
boolean hasUpdate = this.entityBaseTick(tickDiff);
if (this.isAlive()) {
-
if (this.pickupDelay > 0 && this.pickupDelay < 32767) {
this.pickupDelay -= tickDiff;
if (this.pickupDelay < 0) {
this.pickupDelay = 0;
}
+ } else {
+ for (Entity entity : this.level.getNearbyEntities(this.boundingBox.grow(1, 0.5, 1), this)) {
+ if (entity instanceof Player) {
+ if (((Player) entity).pickupEntity(this, true)) {
+ return true;
+ }
+ }
+ }
}
this.motionY -= this.getGravity();
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
index d1710a9382..f398d3bb7e 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java
@@ -44,16 +44,16 @@ public abstract class EntityMinecartAbstract extends EntityVehicle {
private String entityName;
private static final int[][][] matrix = new int[][][]{
- {{0, 0, -1}, {0, 0, 1}},
- {{-1, 0, 0}, {1, 0, 0}},
- {{-1, -1, 0}, {1, 0, 0}},
- {{-1, 0, 0}, {1, -1, 0}},
- {{0, 0, -1}, {0, -1, 1}},
- {{0, -1, -1}, {0, 0, 1}},
- {{0, 0, 1}, {1, 0, 0}},
- {{0, 0, 1}, {-1, 0, 0}},
- {{0, 0, -1}, {-1, 0, 0}},
- {{0, 0, -1}, {1, 0, 0}}
+ {{0, 0, -1}, {0, 0, 1}},
+ {{-1, 0, 0}, {1, 0, 0}},
+ {{-1, -1, 0}, {1, 0, 0}},
+ {{-1, 0, 0}, {1, -1, 0}},
+ {{0, 0, -1}, {0, -1, 1}},
+ {{0, -1, -1}, {0, 0, 1}},
+ {{0, 0, 1}, {1, 0, 0}},
+ {{0, 0, 1}, {-1, 0, 0}},
+ {{0, 0, -1}, {-1, 0, 0}},
+ {{0, 0, -1}, {1, 0, 0}}
};
private double currentSpeed = 0;
private Block blockInside = null;
@@ -112,7 +112,7 @@ public boolean hasCustomName() {
public boolean canDoInteraction() {
return linkedEntity == null && this.getDisplayBlock() == null;
}
-
+
@Override
public float getMountedYOffset() {
return 0.45F; // Real minecart offset
@@ -187,13 +187,13 @@ public boolean onUpdate(int currentTick) {
if (diffX * diffX + diffZ * diffZ > 0.001D) {
yawToChange = (Math.atan2(diffZ, diffX) * 180 / 3.141592653589793D);
}
-
+
// Reverse yaw if yaw is below 0
if (yawToChange < 0) {
// -90-(-90)-(-90) = 90
yawToChange -= yawToChange - yawToChange;
}
-
+
setRotation(yawToChange, pitch);
Location from = new Location(lastX, lastY, lastZ, lastYaw, lastPitch, level);
@@ -249,7 +249,7 @@ public boolean attack(EntityDamageEvent source) {
}
}
}
-
+
return true;
}
@@ -406,14 +406,14 @@ protected void activate(int x, int y, int z, boolean flag) {
private void setFalling() {
motionX = NukkitMath.clamp(motionX, -getMaxSpeed(), getMaxSpeed());
motionZ = NukkitMath.clamp(motionZ, -getMaxSpeed(), getMaxSpeed());
-
- if(linkedEntity != null && !hasUpdated){
+
+ if (linkedEntity != null && !hasUpdated) {
updateRiderPosition(getMountedYOffset() + 0.35F);
hasUpdated = true;
} else {
hasUpdated = false;
}
-
+
if (onGround) {
motionX *= derailedX;
motionY *= derailedY;
@@ -429,7 +429,7 @@ private void setFalling() {
}
private void processMovement(int dx, int dy, int dz, BlockRail block) {
- fallDistance = 0.0F;
+ fallDistance = 0.0F;
Vector3 vector = getNextRail(x, y, z);
y = (double) dy;
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java
index 443f4a8c34..01b5fe1cd0 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartChest.java
@@ -20,7 +20,7 @@ public EntityMinecartChest(FullChunk chunk, CompoundTag nbt) {
}
// TODO: 2016/1/30 inventory
-
+
@Override
public MinecartType getType() {
return MinecartType.valueOf(1);
@@ -37,5 +37,4 @@ public void dropItem() {
}
-
}
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java
index bb6bd52520..137b83cc34 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartEmpty.java
@@ -20,7 +20,7 @@ public int getNetworkId() {
public EntityMinecartEmpty(FullChunk chunk, CompoundTag nbt) {
super(chunk, nbt);
}
-
+
@Override
public MinecartType getType() {
return MinecartType.valueOf(0);
diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java
index 90bb1e46ef..7a26832d5f 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartHopper.java
@@ -21,7 +21,7 @@ public EntityMinecartHopper(FullChunk chunk, CompoundTag nbt) {
public MinecartType getType() {
return MinecartType.valueOf(5);
}
-
+
@Override
public int getNetworkId() {
return NETWORK_ID;
diff --git a/src/main/java/cn/nukkit/entity/item/EntityPainting.java b/src/main/java/cn/nukkit/entity/item/EntityPainting.java
index 14a34b2252..33f373aabb 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityPainting.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityPainting.java
@@ -91,7 +91,7 @@ public void spawnTo(Player player) {
@Override
public boolean attack(EntityDamageEvent source) {
- if (super.attack(source)){
+ if (super.attack(source)) {
if (source instanceof EntityDamageByEntityEvent) {
Entity damager = ((EntityDamageByEntityEvent) source).getDamager();
if (damager instanceof Player && ((Player) damager).isSurvival() && this.level.getGameRules().getBoolean("doEntityDrops")) {
diff --git a/src/main/java/cn/nukkit/entity/item/EntityVehicle.java b/src/main/java/cn/nukkit/entity/item/EntityVehicle.java
index 6b6939e8a8..74ab837635 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityVehicle.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityVehicle.java
@@ -11,10 +11,11 @@
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.network.protocol.SetEntityLinkPacket;
+
import java.util.Objects;
/**
- * author: MagicDroidX
+ * author: MagicDroidX
* Nukkit Project
*/
public abstract class EntityVehicle extends EntityInteractable implements EntityRideable {
@@ -142,7 +143,7 @@ public boolean onUpdate(int currentTick) {
updateMovement();
return true;
}
-
+
protected boolean rollingDirection = true;
protected boolean performHurtAnimation(int damage) {
diff --git a/src/main/java/cn/nukkit/entity/item/EntityXPOrb.java b/src/main/java/cn/nukkit/entity/item/EntityXPOrb.java
index 708ec9b3f7..fb225ee9be 100644
--- a/src/main/java/cn/nukkit/entity/item/EntityXPOrb.java
+++ b/src/main/java/cn/nukkit/entity/item/EntityXPOrb.java
@@ -108,6 +108,14 @@ public boolean onUpdate(int currentTick) {
if (this.pickupDelay < 0) {
this.pickupDelay = 0;
}
+ } else {
+ for (Entity entity : this.level.getCollidingEntities(this.boundingBox, this)) {
+ if (entity instanceof Player) {
+ if (((Player) entity).pickupEntity(this, false)) {
+ return true;
+ }
+ }
+ }
}
this.motionY -= this.getGravity();
diff --git a/src/main/java/cn/nukkit/entity/mob/EntityMob.java b/src/main/java/cn/nukkit/entity/mob/EntityMob.java
index 6568c4e6b3..b682f0ca24 100644
--- a/src/main/java/cn/nukkit/entity/mob/EntityMob.java
+++ b/src/main/java/cn/nukkit/entity/mob/EntityMob.java
@@ -5,7 +5,7 @@
import cn.nukkit.nbt.tag.CompoundTag;
/**
- * author: MagicDroidX
+ * author: MagicDroidX
* Nukkit Project
*/
public abstract class EntityMob extends EntityCreature {
diff --git a/src/main/java/cn/nukkit/entity/mob/EntitySkeleton.java b/src/main/java/cn/nukkit/entity/mob/EntitySkeleton.java
index c3012951b2..3bc49cb9b3 100644
--- a/src/main/java/cn/nukkit/entity/mob/EntitySkeleton.java
+++ b/src/main/java/cn/nukkit/entity/mob/EntitySkeleton.java
@@ -37,7 +37,7 @@ public float getWidth() {
public float getHeight() {
return 1.8f;
}
-
+
@Override
public void spawnTo(Player player) {
AddEntityPacket pk = new AddEntityPacket();
diff --git a/src/main/java/cn/nukkit/entity/mob/EntityZombie.java b/src/main/java/cn/nukkit/entity/mob/EntityZombie.java
index 499c0fe2f2..54c1f59a70 100644
--- a/src/main/java/cn/nukkit/entity/mob/EntityZombie.java
+++ b/src/main/java/cn/nukkit/entity/mob/EntityZombie.java
@@ -36,7 +36,7 @@ public float getWidth() {
public float getHeight() {
return 1.8f;
}
-
+
@Override
public String getName() {
return "Zombie";
diff --git a/src/main/java/cn/nukkit/entity/mob/EntityZombiePigman.java b/src/main/java/cn/nukkit/entity/mob/EntityZombiePigman.java
index 1f2dc3e8db..cb0953a1da 100644
--- a/src/main/java/cn/nukkit/entity/mob/EntityZombiePigman.java
+++ b/src/main/java/cn/nukkit/entity/mob/EntityZombiePigman.java
@@ -31,7 +31,7 @@ protected void initEntity() {
public float getWidth() {
return 0.72f;
}
-
+
@Override
public float getHeight() {
return 1.8f;
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityBat.java b/src/main/java/cn/nukkit/entity/passive/EntityBat.java
index d0a10d57b8..7cbc0c32ce 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityBat.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityBat.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityBat extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityChicken.java b/src/main/java/cn/nukkit/entity/passive/EntityChicken.java
index e7af98590e..514dca8a32 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityChicken.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityChicken.java
@@ -7,7 +7,7 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntityChicken extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityCow.java b/src/main/java/cn/nukkit/entity/passive/EntityCow.java
index 5e138ff183..4d29b74bb2 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityCow.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityCow.java
@@ -7,7 +7,7 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntityCow extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityDonkey.java b/src/main/java/cn/nukkit/entity/passive/EntityDonkey.java
index 3b66bf946c..193e654f47 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityDonkey.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityDonkey.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityDonkey extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityHorse.java b/src/main/java/cn/nukkit/entity/passive/EntityHorse.java
index 346c24656f..6fd4495184 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityHorse.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityHorse.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityHorse extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityLlama.java b/src/main/java/cn/nukkit/entity/passive/EntityLlama.java
index 1f6948971c..98d0bf44c9 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityLlama.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityLlama.java
@@ -6,7 +6,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityLlama extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityMooshroom.java b/src/main/java/cn/nukkit/entity/passive/EntityMooshroom.java
index 22217389a2..e5f03265b1 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityMooshroom.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityMooshroom.java
@@ -59,7 +59,7 @@ protected void initEntity() {
super.initEntity();
setMaxHealth(10);
}
-
+
@Override
public void spawnTo(Player player) {
AddEntityPacket pk = new AddEntityPacket();
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityMule.java b/src/main/java/cn/nukkit/entity/passive/EntityMule.java
index 1c3c2aa505..93f21efb9e 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityMule.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityMule.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityMule extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityOcelot.java b/src/main/java/cn/nukkit/entity/passive/EntityOcelot.java
index 5c2408a124..1f78ec76c6 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityOcelot.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityOcelot.java
@@ -7,7 +7,7 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntityOcelot extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityPig.java b/src/main/java/cn/nukkit/entity/passive/EntityPig.java
index d59d29143c..acaaefaaf1 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityPig.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityPig.java
@@ -7,7 +7,7 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntityPig extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityPolarBear.java b/src/main/java/cn/nukkit/entity/passive/EntityPolarBear.java
index c990d222d8..946ec48b6c 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityPolarBear.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityPolarBear.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityPolarBear extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityRabbit.java b/src/main/java/cn/nukkit/entity/passive/EntityRabbit.java
index 3fbe53dfb9..1efbe43b32 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityRabbit.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityRabbit.java
@@ -7,7 +7,7 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntityRabbit extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntitySheep.java b/src/main/java/cn/nukkit/entity/passive/EntitySheep.java
index 5c651e207a..7ed8d5dac4 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntitySheep.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntitySheep.java
@@ -13,7 +13,7 @@
import java.util.concurrent.ThreadLocalRandom;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntitySheep extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntitySkeletonHorse.java b/src/main/java/cn/nukkit/entity/passive/EntitySkeletonHorse.java
index e419e6be39..2547ce1738 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntitySkeletonHorse.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntitySkeletonHorse.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntitySkeletonHorse extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntitySquid.java b/src/main/java/cn/nukkit/entity/passive/EntitySquid.java
index f56c1ad255..2190be7fc4 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntitySquid.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntitySquid.java
@@ -9,7 +9,6 @@
import cn.nukkit.utils.DyeColor;
/**
- *
* @author PikyCZ
*/
public class EntitySquid extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityWolf.java b/src/main/java/cn/nukkit/entity/passive/EntityWolf.java
index fd447a3b98..8099bb3128 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityWolf.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityWolf.java
@@ -7,7 +7,7 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- * Author: BeYkeRYkt
+ * Author: BeYkeRYkt
* Nukkit Project
*/
public class EntityWolf extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/entity/passive/EntityZombieHorse.java b/src/main/java/cn/nukkit/entity/passive/EntityZombieHorse.java
index 13a7c55483..02450d44fc 100644
--- a/src/main/java/cn/nukkit/entity/passive/EntityZombieHorse.java
+++ b/src/main/java/cn/nukkit/entity/passive/EntityZombieHorse.java
@@ -7,7 +7,6 @@
import cn.nukkit.network.protocol.AddEntityPacket;
/**
- *
* @author PikyCZ
*/
public class EntityZombieHorse extends EntityAnimal {
diff --git a/src/main/java/cn/nukkit/inventory/BigShapedRecipe.java b/src/main/java/cn/nukkit/inventory/BigShapedRecipe.java
index 1db57cb889..a84b3374aa 100644
--- a/src/main/java/cn/nukkit/inventory/BigShapedRecipe.java
+++ b/src/main/java/cn/nukkit/inventory/BigShapedRecipe.java
@@ -8,6 +8,6 @@
*/
public class BigShapedRecipe extends ShapedRecipe {
public BigShapedRecipe(Item result, String... shape) {
- super(result, shape);
+ super(result, 0, 0);
}
}
diff --git a/src/main/java/cn/nukkit/inventory/CraftingManager.java b/src/main/java/cn/nukkit/inventory/CraftingManager.java
index a7d7108b1d..ed0e61f8ff 100644
--- a/src/main/java/cn/nukkit/inventory/CraftingManager.java
+++ b/src/main/java/cn/nukkit/inventory/CraftingManager.java
@@ -1,11 +1,16 @@
package cn.nukkit.inventory;
-import cn.nukkit.block.*;
+import cn.nukkit.Server;
+import cn.nukkit.block.BlockAir;
import cn.nukkit.item.Item;
-import cn.nukkit.item.ItemDye;
+import cn.nukkit.item.ItemBlock;
import cn.nukkit.item.ItemPotion;
+import cn.nukkit.network.protocol.CraftingDataPacket;
+import cn.nukkit.utils.Config;
+import cn.nukkit.utils.MainLogger;
import cn.nukkit.utils.Utils;
+import java.io.IOException;
import java.util.*;
/**
@@ -24,865 +29,63 @@ public class CraftingManager {
private static int RECIPE_COUNT = 0;
+ public static CraftingDataPacket packet = null;
+
public CraftingManager() {
- /*try { //TODO: json
+ try {
Utils.writeFile(Server.getInstance().getDataPath() + "recipes.json", Server.class.getClassLoader().getResourceAsStream("recipes.json"));
} catch (IOException e) {
MainLogger.getLogger().logException(e);
+ //return;
}
-
-
- Config recipes = new Config(Server.getInstance().getDataPath() + "recipes.json", Config.JSON);
-
+ List recipes = new Config(Server.getInstance().getDataPath() + "recipes.json", Config.JSON).getMapList("recipes");
MainLogger.getLogger().info("Loading recipes...");
- for (Object obj : recipes.getAll().values()) {
- ConfigSection recipe;
- if (obj instanceof ConfigSection) {
- recipe = (ConfigSection) obj;
- } else {
- continue;
- }
-
-
- switch (recipe.getInt("type")) {
+ for (Map recipe : recipes) { //TODO: implement this better
+ switch (Utils.toInt(recipe.get("type"))) {
case 0:
// TODO: handle multiple result items
- Map first = recipe.getMapList("output").get(0);
- ShapelessRecipe result = new ShapelessRecipe(Item.get((int) first.get("id"), (int) first.get("damage"), (int) first.get("count"), first.get("nbt").toString().getBytes()));
- for (Map ingredient : recipe.getMapList("input")) {
- result.addIngredient(Item.get((int) ingredient.get("id"), (int) ingredient.get("damage"), (int) ingredient.get("count"), ingredient.get("nbt").toString().getBytes()));
+ Map first = ((List) recipe.get("output")).get(0);
+ ShapelessRecipe result = new ShapelessRecipe(Item.get(Utils.toInt(first.get("id")), Utils.toInt(first.get("damage")), Utils.toInt(first.get("count")), first.get("nbt").toString().getBytes()));
+ for (Map ingredient : ((List) recipe.get("input"))) {
+ result.addIngredient(Item.get(Utils.toInt(ingredient.get("id")), Utils.toInt(ingredient.get("damage")), Utils.toInt(ingredient.get("count")), ingredient.get("nbt").toString().getBytes()));
}
this.registerRecipe(result);
break;
case 1:
// TODO: handle multiple result items
- first = recipe.getMapList("output").get(0);
- ShapedRecipe shapedRecipe = new ShapedRecipe(Item.get((int) first.get("id"), (int) first.get("damage"), (int) first.get("count"), first.get("nbt").toString().getBytes()));
- List>> shape = Utils.toChunk(recipe.getList("input"), recipe.getInt("width"));
-
- for (int y = 0; y < shape.size(); y++) {
- List> row = shape.get(y);
-
- for (int x = 0; x < row.size(); x++) {
- Map ingredient = row.get(x);
- shapedRecipe.addIngredient(x, y, Item.get((int) ingredient.get("id"), (int) ingredient.get("damage"), (int) ingredient.get("count"), ingredient.get("nbt").toString().getBytes()));
+ first = ((List) recipe.get("output")).get(0);
+ ShapedRecipe shapedRecipe = new ShapedRecipe(Item.get(Utils.toInt(first.get("id")), Utils.toInt(first.get("damage")), Utils.toInt(first.get("count")), first.get("nbt").toString().getBytes()), Utils.toInt(recipe.get("height")), Utils.toInt(recipe.get("width")));
+ Object[][] shape = Utils.splitArray(((List) recipe.get("input")).stream().toArray(), Utils.toInt(recipe.get("width")));
+ for (int y = 0; y < shape.length; y++) {
+ Object[] row = shape[y];
+ for (int x = 0; x < row.length; x++) {
+ Object data = row[x];
+
+ if (data instanceof Map) {
+ Map ingredient = (Map) data;
+ shapedRecipe.addIngredient(x, y, Item.get(Utils.toInt(ingredient.get("id")), Utils.toInt(ingredient.get("damage")), Utils.toInt(ingredient.get("count")), ingredient.get("nbt").toString().getBytes()));
+ } else {
+ shapedRecipe.addIngredient(x, y, new ItemBlock(new BlockAir()));
+ }
}
}
this.registerRecipe(shapedRecipe);
break;
case 2:
case 3:
- ConfigSection resultMap = recipe.getSection("output");
- Item resultItem = Item.get(resultMap.getInt("id"), resultMap.getInt("damage"), resultMap.getInt("count"), resultMap.getString("nbt").getBytes());
- this.registerRecipe(new FurnaceRecipe(resultItem, Item.get(recipe.getInt("id"), recipe.getInt("damage", -1), 1)));
+ Map resultMap = (Map) recipe.get("output");
+ Item resultItem = Item.get(Utils.toInt(resultMap.get("id")), Utils.toInt(resultMap.get("damage")), Utils.toInt(resultMap.get("count")), ((String) resultMap.get("nbt")).getBytes());
+ this.registerRecipe(new FurnaceRecipe(resultItem, Item.get(Utils.toInt(recipe.get("inputId")), recipe.containsKey("inputDamage") ? Utils.toInt(recipe.get("inputDamage")) : -1, 1)));
break;
default:
break;
}
- }*/
-
- this.registerFurnace();
- this.registerBrewing();
- this.registerDyes();
- this.registerIngots();
- this.registerTools();
- this.registerWeapons();
- this.registerArmor();
- this.registerFood();
- this.registerWoodenDoors();
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.PRISMARINE, 0, 1),
- "XX",
- "XX"
- )).setIngredient("X", Item.get(Item.PRISMARINE_SHARD)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.PRISMARINE, 1, 1),
- "XXX",
- "XXX",
- "XXX"
- )).setIngredient("X", Item.get(Item.PRISMARINE_SHARD)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.PRISMARINE, 2, 1),
- "XXX",
- "XIX",
- "XXX"
- )).setIngredient("X", Item.get(Item.PRISMARINE_SHARD)).setIngredient("I", Item.get(Item.DYE)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.PRISMARINE, 2, 1),
- "XXX",
- "XIX",
- "XXX"
- )).setIngredient("X", Item.get(Item.PRISMARINE_SHARD)).setIngredient("I", Item.get(Item.DYE)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SEA_LANTERN, 0, 1),
- "XSX",
- "SSS",
- "XSX"
- )).setIngredient("X", Item.get(Item.PRISMARINE_SHARD)).setIngredient("S", Item.get(Item.PRISMARINE_CRYSTALS)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BEACON, 0, 1),
- "GGG",
- "GSG",
- "OOO"
- )).setIngredient("G", Item.get(Item.GLASS)).setIngredient("S", Item.get(Item.NETHER_STAR)).setIngredient("O", Item.get(Item.OBSIDIAN)));
-
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.CLAY_BLOCK, 0, 1),
- "XX ",
- "XX ",
- " "
- )).setIngredient("X", Item.get(Item.CLAY, 0, 4)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WORKBENCH, 0, 1),
- "XX",
- "XX"
- )).setIngredient("X", Item.get(Item.WOODEN_PLANK, null)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.GLOWSTONE_BLOCK, 0, 1),
- "XX",
- "XX"
- )).setIngredient("X", Item.get(Item.GLOWSTONE_DUST, 0, 1)));
- this.registerRecipe((new ShapedRecipe(Item.get(Item.LIT_PUMPKIN, 0, 1),
- "X ",
- "Y "
- )).setIngredient("X", Item.get(Item.PUMPKIN, 0, 1)).setIngredient("Y", Item.get(Item.TORCH, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.SNOW_BLOCK, 0, 1),
- "XX",
- "XX"
- )).setIngredient("X", Item.get(Item.SNOWBALL, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.SNOW_LAYER, 0, 6),
- " ",
- "XXX",
- " "
- )).setIngredient("X", Item.get(Item.SNOW_BLOCK, 0, 1)));
-
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.STICK, 0, 4),
- "X ",
- "X "
- )).setIngredient("X", Item.get(Item.WOODEN_PLANK, null)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOODEN_PLANK, BlockPlanks.OAK, 4),
- "X"
- )).setIngredient("X", Item.get(Item.WOOD, BlockWood.OAK, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOODEN_PLANK, BlockPlanks.SPRUCE, 4),
- "X"
- )).setIngredient("X", Item.get(Item.WOOD, BlockWood.SPRUCE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOODEN_PLANK, BlockPlanks.BIRCH, 4),
- "X"
- )).setIngredient("X", Item.get(Item.WOOD, BlockWood.BIRCH, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOODEN_PLANK, BlockPlanks.JUNGLE, 4),
- "X"
- )).setIngredient("X", Item.get(Item.WOOD, BlockWood.JUNGLE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOODEN_PLANK, BlockPlanks.ACACIA, 4),
- "X"
- )).setIngredient("X", Item.get(Item.WOOD2, BlockWood2.ACACIA, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOODEN_PLANK, BlockPlanks.DARK_OAK, 4),
- "X"
- )).setIngredient("X", Item.get(Item.WOOD2, BlockWood2.DARK_OAK, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOOL, 0, 1),
- "XX",
- "XX"
- )).setIngredient("X", Item.get(Item.STRING, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.TORCH, 0, 4),
- "C ",
- "S"
- )).setIngredient("C", Item.get(Item.COAL, 0, 1)).setIngredient("S", Item.get(Item.STICK, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.TORCH, 0, 4),
- "C ",
- "S"
- )).setIngredient("C", Item.get(Item.COAL, 1, 1)).setIngredient("S", Item.get(Item.STICK, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.SUGAR, 0, 1),
- "S"
- )).setIngredient("S", Item.get(Item.SUGARCANE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BED, 0, 1),
- "WWW",
- "PPP",
- " "
- )).setIngredient("W", Item.get(Item.WOOL, null, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.CHEST, 0, 1),
- "PPP",
- "P P",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.ENCHANTMENT_TABLE, 0, 1),
- " B ",
- "DOD",
- "OOO"
- )).setIngredient("D", Item.get(Item.DIAMOND, 0, 2)).setIngredient("O", Item.get(Item.OBSIDIAN, 0, 4)).setIngredient("B", Item.get(Item.BOOK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE, BlockPlanks.OAK, 3),
- "PSP",
- "PSP",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE, BlockPlanks.SPRUCE, 3),
- "PSP",
- "PSP",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.SPRUCE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE, BlockPlanks.BIRCH, 3),
- "PSP",
- "PSP",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.BIRCH, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE, BlockPlanks.JUNGLE, 3),
- "PSP",
- "PSP",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.JUNGLE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE, BlockPlanks.ACACIA, 3),
- "PSP",
- "PSP",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.ACACIA, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE, BlockPlanks.DARK_OAK, 3),
- "PSP",
- "PSP",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.DARK_OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.NETHER_BRICK_FENCE, 0, 3),
- "PPP",
- "PPP",
- " "
- )).setIngredient("P", Item.get(Item.NETHER_BRICK_BLOCK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE_GATE, 0, 1),
- "SPS",
- "SPS",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE_GATE_SPRUCE, 0, 1),
- "SPS",
- "SPS",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.SPRUCE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE_GATE_BIRCH, 0, 1),
- "SPS",
- "SPS",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.BIRCH, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE_GATE_JUNGLE, 0, 1),
- "SPS",
- "SPS",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.JUNGLE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE_GATE_DARK_OAK, 0, 1),
- "SPS",
- "SPS",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.DARK_OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FENCE_GATE_ACACIA, 0, 1),
- "SPS",
- "SPS",
- " "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.ACACIA, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.COBBLESTONE_WALL, BlockWall.NONE_MOSSY_WALL, 6),
- "CCC",
- "CCC",
- " "
- )).setIngredient("C", Item.get(Item.COBBLESTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.COBBLESTONE_WALL, BlockWall.MOSSY_WALL, 6),
- "MMM",
- "MMM",
- " "
- )).setIngredient("M", Item.get(Item.MOSS_STONE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.FURNACE, 0, 1),
- "CCC",
- "C C",
- "CCC"
- )).setIngredient("C", Item.get(Item.COBBLESTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.GLASS_PANE, 0, 16),
- "GGG",
- "GGG",
- " "
- )).setIngredient("G", Item.get(Item.GLASS, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.LADDER, 0, 3),
- "S S",
- "SSS",
- "S S"
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.TRAPDOOR, 0, 2),
- "PPP",
- "PPP",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.IRON_DOOR, 0, 1),
- "II ",
- "II ",
- "II "
- )).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOAT, 0, 1),
- "PSP",
- "PPP",
- " "
- )).setIngredient("S", Item.get(Item.WOODEN_SHOVEL, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOAT, 1, 1),
- "PSP",
- "PPP",
- " "
- )).setIngredient("S", Item.get(Item.WOODEN_SHOVEL, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.SPRUCE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOAT, 2, 1),
- "PSP",
- "PPP",
- " "
- )).setIngredient("S", Item.get(Item.WOODEN_SHOVEL, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.BIRCH, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOAT, 3, 1),
- "PSP",
- "PPP",
- " "
- )).setIngredient("S", Item.get(Item.WOODEN_SHOVEL, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.JUNGLE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOAT, 4, 1),
- "PSP",
- "PPP",
- " "
- )).setIngredient("S", Item.get(Item.WOODEN_SHOVEL, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.ACACIA, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOAT, 5, 1),
- "PSP",
- "PPP",
- " "
- )).setIngredient("S", Item.get(Item.WOODEN_SHOVEL, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.DARK_OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SANDSTONE_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.SANDSTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SPRUCE_WOOD_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.SPRUCE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BIRCH_WOOD_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.BIRCH, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.JUNGLE_WOOD_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.JUNGLE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.ACACIA_WOOD_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.ACACIA, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.DARK_OAK_WOOD_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.DARK_OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.COBBLESTONE_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.COBBLESTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BRICK_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.BRICKS_BLOCK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE_BRICK_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.STONE_BRICK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.QUARTZ_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.QUARTZ_BLOCK, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.NETHER_BRICKS_STAIRS, 0, 4),
- "P ",
- "PP ",
- "PPP"
- )).setIngredient("P", Item.get(Item.NETHER_BRICK_BLOCK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.STONE, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.STONE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.SANDSTONE, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.SANDSTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOOD_SLAB, BlockPlanks.OAK, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOOD_SLAB, BlockPlanks.SPRUCE, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.SPRUCE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOOD_SLAB, BlockPlanks.BIRCH, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.BIRCH, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOOD_SLAB, BlockPlanks.JUNGLE, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.JUNGLE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOOD_SLAB, BlockPlanks.ACACIA, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.ACACIA, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOOD_SLAB, BlockPlanks.DARK_OAK, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, BlockPlanks.DARK_OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.COBBLESTONE, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.COBBLESTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.BRICK, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.BRICK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.STONE_BRICK, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.STONE_BRICK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.QUARTZ, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.QUARTZ_BLOCK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SLAB, BlockSlabStone.NETHER_BRICK, 6),
- "PPP",
- " ",
- " "
- )).setIngredient("P", Item.get(Item.NETHER_BRICK_BLOCK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.QUARTZ_BLOCK, BlockQuartz.QUARTZ_NORMAL, 1),
- "NN ",
- "NN ",
- " "
- )).setIngredient("N", Item.get(Item.NETHER_QUARTZ, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.QUARTZ_BLOCK, BlockQuartz.QUARTZ_PILLAR, 2),
- "N ",
- "N ",
- " "
- )).setIngredient("N", Item.get(Item.QUARTZ_BLOCK, BlockQuartz.QUARTZ_NORMAL, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.QUARTZ_BLOCK, BlockQuartz.QUARTZ_CHISELED, 1),
- " ",
- " N ",
- " N "
- )).setIngredient("N", Item.get(Item.SLAB, BlockSlabStone.QUARTZ, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SANDSTONE, BlockSandstone.NORMAL, 1),
- " ",
- "SS ",
- "SS "
- )).setIngredient("S", Item.get(Item.SAND, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SANDSTONE, BlockSandstone.SMOOTH, 4),
- " ",
- "SS ",
- "SS "
- )).setIngredient("S", Item.get(Item.SANDSTONE, BlockSandstone.NORMAL, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SANDSTONE, BlockSandstone.CHISELED, 1),
- " ",
- " N ",
- " N "
- )).setIngredient("N", Item.get(Item.SLAB, BlockSlabStone.SANDSTONE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE_BRICK, BlockBricksStone.NORMAL, 4),
- " ",
- "SS ",
- "SS "
- )).setIngredient("S", Item.get(Item.STONE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE_BRICK, BlockBricksStone.MOSSY, 1),
- " ",
- "SL ",
- " "
- )).setIngredient("S", Item.get(Item.STONE_BRICK, BlockBricksStone.NORMAL, 1)).setIngredient("L", Item.get(Item.VINES, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE_BRICK, BlockBricksStone.CHISELED, 1),
- " ",
- " S ",
- " S "
- )).setIngredient("S", Item.get(Item.SLAB, BlockSlabStone.STONE_BRICK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.MOSS_STONE, 0, 1),
- " ",
- "SL ",
- " "
- )).setIngredient("S", Item.get(Item.COBBLESTONE, null, 1)).setIngredient("L", Item.get(Item.VINES, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE, BlockStone.GRANITE, 1),
- " ",
- "DN ",
- " "
- )).setIngredient("D", Item.get(Item.STONE, BlockStone.DIORITE, 1)).setIngredient("N", Item.get(Item.NETHER_QUARTZ, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE, BlockStone.POLISHED_GRANITE, 4),
- " ",
- "GG ",
- "GG "
- )).setIngredient("G", Item.get(Item.STONE, BlockStone.GRANITE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE, BlockStone.DIORITE, 2),
- " ",
- "CN ",
- "NC "
- )).setIngredient("C", Item.get(Item.COBBLESTONE, null, 1)).setIngredient("N", Item.get(Item.NETHER_QUARTZ, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE, BlockStone.POLISHED_DIORITE, 4),
- " ",
- "DD ",
- "DD "
- )).setIngredient("D", Item.get(Item.STONE, BlockStone.DIORITE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE, BlockStone.ANDESITE, 2),
- " ",
- "DC ",
- " "
- )).setIngredient("D", Item.get(Item.STONE, BlockStone.DIORITE, 1)).setIngredient("C", Item.get(Item.COBBLESTONE, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE, BlockStone.POLISHED_ANDESITE, 4),
- " ",
- "AA ",
- "AA "
- )).setIngredient("A", Item.get(Item.STONE, BlockStone.ANDESITE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BUCKET, 0, 1),
- "I I",
- " I ",
- " "
- )).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.CLOCK, 0, 1),
- " G ",
- "GRG",
- " G "
- )).setIngredient("G", Item.get(Item.GOLD_INGOT, 0, 1)).setIngredient("R", Item.get(Item.REDSTONE_DUST, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.COMPASS, 0, 1),
- " I ",
- "IRI",
- " I "
- )).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)).setIngredient("R", Item.get(Item.REDSTONE_DUST, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.TNT, 0, 1),
- "GSG",
- "SGS",
- "GSG"
- )).setIngredient("G", Item.get(Item.GUNPOWDER, 0, 1)).setIngredient("S", Item.get(Item.SAND, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOWL, 0, 4),
- "P P",
- " P ",
- " "
- )).setIngredient("P", Item.get(Item.WOODEN_PLANKS, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.MINECART, 0, 1),
- "I I",
- "III"
- )).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOOK, 0, 1),
- "P P",
- " P "
- )).setIngredient("P", Item.get(Item.PAPER, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOOKSHELF, 0, 1),
- "PPP",
- "BBB",
- "PPP"
- )).setIngredient("P", Item.get(Item.WOODEN_PLANK, null, 1)).setIngredient("B", Item.get(Item.BOOK, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.PAINTING, 0, 1),
- "SSS",
- "SWS",
- "SSS"
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("W", Item.get(Item.WOOL, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.PAPER, 0, 3),
- " ",
- "SSS",
- " "
- )).setIngredient("S", Item.get(Item.SUGARCANE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.SIGN, 0, 3),
- "PPP",
- "PPP",
- " S "
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("P", Item.get(Item.WOODEN_PLANKS, null, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.IRON_BARS, 0, 16),
- " ",
- "III",
- "III"
- )).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.GLASS_BOTTLE, 0, 3),
- "I I",
- " I ",
- " "
- )).setIngredient("I", Item.get(Item.GLASS, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BREWING_STAND, 0, 1),
- " I ",
- "CCC"
- )).setIngredient("C", Item.get(Item.COBBLESTONE, null, 1)).setIngredient("I", Item.get(Item.BLAZE_ROD, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.ITEM_FRAME, 0, 3),
- "SSS",
- "SLS",
- "SSS"
- )).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("L", Item.get(Item.LEATHER, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.RED_SANDSTONE_STAIRS, 0, 4),
- " S",
- " SS",
- "SSS"
- )).setIngredient("S", Item.get(Item.RED_SANDSTONE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.RED_SANDSTONE_SLAB, 0, 6),
- " ",
- "SSS",
- " "
- )).setIngredient("S", Item.get(Item.RED_SANDSTONE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.RED_SANDSTONE, BlockSandstone.NORMAL, 1),
- " ",
- "SS ",
- "SS "
- )).setIngredient("S", Item.get(Item.SAND, 1, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.RED_SANDSTONE, BlockSandstone.SMOOTH, 4),
- " ",
- "SS ",
- "SS "
- )).setIngredient("S", Item.get(Item.RED_SANDSTONE, BlockSandstone.NORMAL, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.RED_SANDSTONE, BlockSandstone.CHISELED, 1),
- " ",
- " N ",
- " N "
- )).setIngredient("N", Item.get(Item.RED_SANDSTONE_SLAB, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STONE_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.STONE, 0, 1)));
-
-
- //all planks...
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.PLANKS, BlockPlanks.OAK, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.PLANKS, BlockPlanks.SPRUCE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.PLANKS, BlockPlanks.BIRCH, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.PLANKS, BlockPlanks.JUNGLE, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.PLANKS, BlockPlanks.ACACIA, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " ",
- " N ",
- " "
- )).setIngredient("N", Item.get(Item.PLANKS, BlockPlanks.DARK_OAK, 1)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.ENDER_CHEST, 0, 1),
- "PPP",
- "PSP",
- "PPP"
- ).setIngredient("P", Item.get(Item.OBSIDIAN, 0, 1)).setIngredient("S", Item.get(Item.ENDER_EYE, 0, 1)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.REDSTONE_TORCH, 0, 1),
- " R",
- " S"
- ).setIngredient("R", Item.get(Item.REDSTONE_DUST, 0, 1)).setIngredient("S", Item.get(Item.STICK, 0, 1)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.LEVER, 0, 1),
- " S",
- " C"
- ).setIngredient("C", Item.get(Item.COBBLESTONE, null, 1)).setIngredient("S", Item.get(Item.STICK, 0, 1)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.STONE_BUTTON, 0, 1),
- " S"
- ).setIngredient("S", Item.get(Item.STONE, 0, 1)));
-
- for (int i = 0; i < 6; i++) {
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.WOODEN_BUTTON, 0, 1),
- " W"
- ).setIngredient("W", Item.get(Item.PLANKS, i, 1)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.WOODEN_PRESSURE_PLATE, 0, 1),
- "WW "
- ).setIngredient("W", Item.get(Item.PLANKS, i, 2)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.TRIPWIRE_HOOK, 0, 2),
- " I ",
- " S ",
- " P "
- ).setIngredient("P", Item.get(Item.PLANKS, i, 1)).setIngredient("S", Item.get(Item.STICK, 0, 1)).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 1)));
}
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.STONE_PRESSURE_PLATE, 0, 1),
- "SS "
- ).setIngredient("S", Item.get(Item.STONE, 0, 2)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.HEAVY_WEIGHTED_PRESSURE_PLATE, 0, 1),
- "II "
- ).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 2)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.LIGHT_WEIGHTED_PRESSURE_PLATE, 0, 1),
- "GG "
- ).setIngredient("G", Item.get(Item.GOLD_INGOT, 0, 2)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.REDSTONE_LAMP, 0, 1),
- " R ",
- "RGR",
- " R "
- ).setIngredient("R", Item.get(Item.REDSTONE_DUST, 0, 4)).setIngredient("G", Item.get(Item.GLOWSTONE_BLOCK, 0, 1)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.REPEATER, 0, 1),
- " ",
- "TRT",
- "SSS"
- ).setIngredient("R", Item.get(Item.REDSTONE_DUST, 0, 1)).setIngredient("T", Item.get(Item.REDSTONE_TORCH, 0, 2)).setIngredient("S", Item.get(Item.STONE, 0, 3)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.COMPARATOR, 0, 1),
- " T ",
- "TQT",
- "SSS"
- ).setIngredient("Q", Item.get(Item.QUARTZ, 0, 1)).setIngredient("T", Item.get(Item.REDSTONE_TORCH, 0, 3)).setIngredient("S", Item.get(Item.STONE, 0, 3)));
-
- this.registerRecipe(new BigShapedRecipe(Item.get(Item.HOPPER, 0, 1),
- "I I",
- "ICI",
- " I "
- ).setIngredient("I", Item.get(Item.IRON_INGOT, 0, 5)).setIngredient("C", Item.get(Item.CHEST, 0, 1)));
- }
-
- protected void registerFurnace() {
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.STONE, 0, 1), Item.get(Item.COBBLESTONE, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.STONE_BRICK, BlockBricksStone.CRACKED, 1), Item.get(Item.STONE_BRICK, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.GLASS, 0, 1), Item.get(Item.SAND, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.COAL, 1, 1), Item.get(Item.TRUNK, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.GOLD_INGOT, 0, 1), Item.get(Item.GOLD_ORE, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.IRON_INGOT, 0, 1), Item.get(Item.IRON_ORE, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.EMERALD, 0, 1), Item.get(Item.EMERALD_ORE, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.DIAMOND, 0, 1), Item.get(Item.DIAMOND_ORE, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.NETHER_BRICK, 0, 1), Item.get(Item.NETHERRACK, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.COOKED_PORKCHOP, 0, 1), Item.get(Item.RAW_PORKCHOP, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.BRICK, 0, 1), Item.get(Item.CLAY, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.COOKED_FISH, 0, 1), Item.get(Item.RAW_FISH, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.COOKED_FISH, 1, 1), Item.get(Item.RAW_FISH, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.DYE, 2, 1), Item.get(Item.CACTUS, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.DYE, 1, 1), Item.get(Item.RED_MUSHROOM, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.STEAK, 0, 1), Item.get(Item.RAW_BEEF, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.COOKED_CHICKEN, 0, 1), Item.get(Item.RAW_CHICKEN, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.BAKED_POTATO, 0, 1), Item.get(Item.POTATO, null, 1)));
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.COOKED_MUTTON, 0, 1), Item.get(Item.RAW_MUTTON, null, 1)));
+ this.registerBrewing();
+ this.rebuildPacket();
- this.registerRecipe(new FurnaceRecipe(Item.get(Item.TERRACOTTA, 0, 1), Item.get(Item.CLAY_BLOCK, null, 1)));
+ MainLogger.getLogger().info("Loaded " + this.recipes.size() + " recipes.");
}
protected void registerBrewing() {
@@ -927,340 +130,26 @@ protected void registerBrewing() {
registerBrewingRecipe(new BrewingRecipe(Item.get(Item.POTION, ItemPotion.HARMING_II, 1), Item.get(Item.FERMENTED_SPIDER_EYE, 0, 1), Item.get(Item.POTION, ItemPotion.POISON_LONG, 1)));
}
- protected void registerFood() {
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.MELON_BLOCK, 0, 1),
- "XXX",
- "XXX",
- "XXX"
- )).setIngredient("X", Item.get(Item.MELON_SLICE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BEETROOT_SOUP, 0, 1),
- "XXX",
- "XXX",
- " Y "
- )).setIngredient("X", Item.get(Item.BEETROOT, 0, 1)).setIngredient("Y", Item.get(Item.BOWL, 0, 1)));
-
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BREAD, 0, 1),
- " ",
- " ",
- "XXX"
- )).setIngredient("X", Item.get(Item.WHEAT, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.CAKE, 0, 1),
- "XXX",
- "YZY",
- "AAA"
- )).setIngredient("X", Item.get(Item.BUCKET, 1, 1)).setIngredient("Y", Item.get(Item.SUGAR, 0, 1)).setIngredient("Z", Item.get(Item.EGG, 0, 1)).setIngredient("A", Item.get(Item.WHEAT, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.COOKIE, 0, 8),
- " ",
- " ",
- "XYX"
- )).setIngredient("X", Item.get(Item.WHEAT, 0, 1)).setIngredient("Y", Item.get(Item.DYE, 3, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.GOLDEN_APPLE, 0, 1),
- "XXX",
- "XYX",
- "XXX"
- )).setIngredient("X", Item.get(Item.GOLD_INGOT, 0, 1)).setIngredient("Y", Item.get(Item.APPLE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.GOLDEN_APPLE_ENCHANTED, 1, 1),
- "XXX",
- "XYX",
- "XXX"
- )).setIngredient("X", Item.get(Item.GOLD_BLOCK, 0, 1)).setIngredient("Y", Item.get(Item.APPLE, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.MUSHROOM_STEW, 0, 1),
- " X ",
- " Y ",
- " Z "
- )).setIngredient("X", Item.get(Item.RED_MUSHROOM, 0, 1)).setIngredient("Y", Item.get(Item.BROWN_MUSHROOM, 0, 1)).setIngredient("Z", Item.get(Item.BOWL, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.PUMPKIN_PIE, 0, 1),
- " ",
- "XY ",
- "Z "
- )).setIngredient("X", Item.get(Item.PUMPKIN, 0, 1)).setIngredient("Y", Item.get(Item.EGG, 0, 1)).setIngredient("Z", Item.get(Item.SUGAR, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.MELON_SEEDS, 0, 1),
- "X ",
- " "
- )).setIngredient("X", Item.get(Item.MELON_SLICE, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.PUMPKIN_SEEDS, 0, 4),
- "X ",
- " "
- )).setIngredient("X", Item.get(Item.PUMPKIN, 0, 1)));
- }
-
- protected void registerArmor() {
- int[][] types = {
- {Item.LEATHER, Item.FIRE, Item.IRON_INGOT, Item.DIAMOND, Item.GOLD_INGOT},
- {Item.LEATHER_CAP, Item.CHAIN_HELMET, Item.IRON_HELMET, Item.DIAMOND_HELMET, Item.GOLD_HELMET},
- {Item.LEATHER_TUNIC, Item.CHAIN_CHESTPLATE, Item.IRON_CHESTPLATE, Item.DIAMOND_CHESTPLATE, Item.GOLD_CHESTPLATE},
- {Item.LEATHER_PANTS, Item.CHAIN_LEGGINGS, Item.IRON_LEGGINGS, Item.DIAMOND_LEGGINGS, Item.GOLD_LEGGINGS},
- {Item.LEATHER_BOOTS, Item.CHAIN_BOOTS, Item.IRON_BOOTS, Item.DIAMOND_BOOTS, Item.GOLD_BOOTS},
- };
-
- String[][] shapes = new String[][]{
- new String[]{
- "XXX",
- "X X",
- " "
- },
- new String[]{
- "X X",
- "XXX",
- "XXX"
- },
- new String[]{
- "XXX",
- "X X",
- "X X"
- },
- new String[]{
- " ",
- "X X",
- "X X"
- }
- };
- for (int i = 1; i < 5; ++i) {
- for (int j = 0; j < types[i].length; j++) {
- int type = types[i][j];
- this.registerRecipe((new BigShapedRecipe(Item.get(type, 0, 1), shapes[i - 1])).setIngredient("X", Item.get(types[0][j], 0, 1)));
- }
- }
- }
-
- protected void registerWeapons() {
- int[][] types = {
- {Item.WOODEN_PLANK, Item.COBBLESTONE, Item.IRON_INGOT, Item.DIAMOND, Item.GOLD_INGOT},
- {Item.WOODEN_SWORD, Item.STONE_SWORD, Item.IRON_SWORD, Item.DIAMOND_SWORD, Item.GOLD_SWORD},
- };
- for (int i = 1; i < 2; ++i) {
- for (int j = 0; j < types[i].length; j++) {
- int type = types[i][j];
- this.registerRecipe((new BigShapedRecipe(Item.get(type, 0, 1),
- " X ",
- " X ",
- " I "
- )).setIngredient("X", Item.get(types[0][j], null)).setIngredient("I", Item.get(Item.STICK)));
- }
- }
+ public void rebuildPacket() {
+ CraftingDataPacket pk = new CraftingDataPacket();
+ pk.cleanRecipes = true;
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.ARROW, 0, 1),
- " F ",
- " S ",
- " P "
- )).setIngredient("S", Item.get(Item.STICK)).setIngredient("F", Item.get(Item.FLINT)).setIngredient("P", Item.get(Item.FEATHER)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.BOW, 0, 1),
- " X~",
- "X ~",
- " X~"
- )).setIngredient("~", Item.get(Item.STRING)).setIngredient("X", Item.get(Item.STICK)));
- }
-
- protected void registerTools() {
- int[][] types = {
- {Item.WOODEN_PLANK, Item.COBBLESTONE, Item.IRON_INGOT, Item.DIAMOND, Item.GOLD_INGOT},
- {Item.WOODEN_PICKAXE, Item.STONE_PICKAXE, Item.IRON_PICKAXE, Item.DIAMOND_PICKAXE, Item.GOLD_PICKAXE},
- {Item.WOODEN_SHOVEL, Item.STONE_SHOVEL, Item.IRON_SHOVEL, Item.DIAMOND_SHOVEL, Item.GOLD_SHOVEL},
- {Item.WOODEN_AXE, Item.STONE_AXE, Item.IRON_AXE, Item.DIAMOND_AXE, Item.GOLD_AXE},
- {Item.WOODEN_HOE, Item.STONE_HOE, Item.IRON_HOE, Item.DIAMOND_HOE, Item.GOLD_HOE},
- };
- String[][] shapes = new String[][]{
- new String[]{
- "XXX",
- " I ",
- " I "
- },
- new String[]{
- " X ",
- " I ",
- " I "
- },
- new String[]{
- "XX ",
- "XI ",
- " I "
- },
- new String[]{
- "XX ",
- " I ",
- " I "
- }
- };
- for (int i = 1; i < 5; ++i) {
- for (int j = 0; j < types[i].length; j++) {
- int type = types[i][j];
- this.registerRecipe((new BigShapedRecipe(Item.get(type, 0, 1), shapes[i - 1])).setIngredient('X', Item.get(types[0][j], null)).setIngredient('I', Item.get(Item.STICK)));
+ for (Recipe recipe : this.getRecipes().values()) {
+ if (recipe instanceof ShapedRecipe) {
+ pk.addShapedRecipe((ShapedRecipe) recipe);
+ } else if (recipe instanceof ShapelessRecipe) {
+ pk.addShapelessRecipe((ShapelessRecipe) recipe);
}
}
- this.registerRecipe((new ShapedRecipe(Item.get(Item.FLINT_AND_STEEL, 0, 1),
- " S",
- "F "
- )).setIngredient('F', Item.get(Item.FLINT)).setIngredient("S", Item.get(Item.IRON_INGOT)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.SHEARS, 0, 1),
- " X",
- "X "
- )).setIngredient("X", Item.get(Item.IRON_INGOT)));
- }
-
- protected void registerWoodenDoors() {
- int[] items = new int[]{Item.WOODEN_DOOR, Item.SPRUCE_DOOR, Item.BIRCH_DOOR, Item.JUNGLE_DOOR, Item.ACACIA_DOOR, Item.DARK_OAK_DOOR};
-
- for (int i = 0; i < 6; i++) {
- this.registerRecipe((new BigShapedRecipe(Item.get(items[i], 0, 3),
- "XX ",
- "XX ",
- "XX "
- )).setIngredient("X", Item.get(Item.PLANKS, i, 1)));
- }
- }
-
- protected void registerPlanks() {
- //TODO
- }
-
- protected void registerDyes() {
- for (int i = 0; i < 16; ++i) {
- this.registerRecipe((new ShapedRecipe(Item.get(Item.WOOL, 15 - i, 1),
- " ",
- "DW"
- )).setIngredient('D', Item.get(Item.DYE, i, 1)).setIngredient('W', Item.get(Item.WOOL, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(Item.STAINED_TERRACOTTA, 15 - i, 8),
- "CCC",
- "CDC",
- "CCC"
- )).setIngredient('D', Item.get(Item.DYE, i, 1)).setIngredient('C', Item.get(Item.TERRACOTTA, 0, 1)));
- //TODO: add glass things?
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.CARPET, i, 3),
- " ",
- "WW"
- )).setIngredient('W', Item.get(Item.WOOL, i, 1)));
+ for (FurnaceRecipe recipe : this.getFurnaceRecipes().values()) {
+ pk.addFurnaceRecipe(recipe);
}
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.YELLOW, 2),
- " ",
- "D "
- )).setIngredient('D', Item.get(Item.DANDELION, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.WHITE, 3),
- " ",
- "B "
- )).setIngredient('B', Item.get(Item.BONE, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.BROWN, 2),
- " B",
- "O "
- )).setIngredient('O', Item.get(Item.DYE, ItemDye.ORANGE, 1)).setIngredient('B', Item.get(Item.DYE, ItemDye.BLACK, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.BROWN, 3),
- "RB",
- "Y "
- )).setIngredient('R', Item.get(Item.DYE, ItemDye.RED, 1)).setIngredient('B', Item.get(Item.DYE, ItemDye.BLACK, 1)).setIngredient('Y', Item.get(Item.DYE, ItemDye.YELLOW, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.PINK, 2),
- " R",
- "W "
- )).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)).setIngredient('R', Item.get(Item.DYE, ItemDye.RED, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.ORANGE, 2),
- " R",
- "Y "
- )).setIngredient('Y', Item.get(Item.DYE, ItemDye.YELLOW, 1)).setIngredient('R', Item.get(Item.DYE, ItemDye.RED, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.LIME, 2),
- " G",
- "W "
- )).setIngredient('G', Item.get(Item.DYE, ItemDye.GREEN, 1)).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.LIGHT_BLUE, 2),
- " B",
- "W "
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLUE, 1)).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.CYAN, 2),
- " G",
- "B "
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLUE, 1)).setIngredient('G', Item.get(Item.DYE, ItemDye.GREEN, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.PURPLE, 2),
- " R",
- "B "
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLUE, 1)).setIngredient('R', Item.get(Item.DYE, ItemDye.RED, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.MAGENTA, 3),
- "RW",
- "B "
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLUE, 1)).setIngredient('R', Item.get(Item.DYE, ItemDye.RED, 1)).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.RED, 1),
- " ",
- "B "
- )).setIngredient('B', Item.get(Item.BEETROOT, 0, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.MAGENTA, 4),
- "RB",
- "WR"
- )).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)).setIngredient('R', Item.get(Item.DYE, ItemDye.RED, 1)).setIngredient('B', Item.get(Item.DYE, ItemDye.BLUE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.MAGENTA, 2),
- " D",
- "P "
- )).setIngredient('P', Item.get(Item.DYE, ItemDye.PURPLE, 1)).setIngredient('D', Item.get(Item.DYE, ItemDye.PINK, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.GRAY, 2),
- " W",
- "B "
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLACK, 1)).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.LIGHT_GRAY, 3),
- "B ",
- "WW"
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLACK, 1)).setIngredient('W', Item.get(Item.DYE, ItemDye.WHITE, 1)));
-
- this.registerRecipe((new ShapedRecipe(Item.get(Item.DYE, ItemDye.LIGHT_GRAY, 2),
- " G",
- "B "
- )).setIngredient('B', Item.get(Item.DYE, ItemDye.BLACK, 1)).setIngredient('G', Item.get(Item.DYE, ItemDye.GRAY, 1)));
- }
-
- protected void registerIngots() {
- int[][] ingots = new int[][]{
- {Item.GOLD_BLOCK, Item.GOLD_INGOT},
- {Item.GOLD_INGOT, Item.GOLD_NUGGET},
- {Item.IRON_BLOCK, Item.IRON_INGOT},
- {Item.DIAMOND_BLOCK, Item.DIAMOND},
- {Item.EMERALD_BLOCK, Item.EMERALD},
- {Item.REDSTONE_BLOCK, Item.REDSTONE_DUST},
- {Item.COAL_BLOCK, Item.COAL},
- {Item.HAY_BALE, Item.WHEAT},
- {Item.LAPIS_BLOCK, Item.DYE, 4}
- };
-
- for (int[] e : ingots) {
- int block = e[0];
- int ingot = e[1];
- int ingot_meta = e.length > 2 ? e[2] : 0;
-
- this.registerRecipe((new ShapedRecipe(Item.get(ingot, ingot_meta, 9),
- "X"
- )).setIngredient("X", Item.get(block, 0, 1)));
-
- this.registerRecipe((new BigShapedRecipe(Item.get(block, 0, 1),
- "XXX",
- "XXX",
- "XXX"
- )).setIngredient("X", Item.get(ingot, ingot_meta, 1)));
- }
+ pk.encode();
+ pk.isEncoded = true;
+ packet = pk;
}
public final Comparator- comparator = (i1, i2) -> {
diff --git a/src/main/java/cn/nukkit/inventory/PlayerInventory.java b/src/main/java/cn/nukkit/inventory/PlayerInventory.java
index 3a5cb3b50e..a739a82299 100644
--- a/src/main/java/cn/nukkit/inventory/PlayerInventory.java
+++ b/src/main/java/cn/nukkit/inventory/PlayerInventory.java
@@ -403,7 +403,7 @@ public void sendContents(Player[] players) {
//Because PE is stupid and shows 9 less slots than you send it, give it 9 dummy slots so it shows all the REAL slots.
for(int i = this.getSize(); i < this.getSize() + this.getHotbarSize(); ++i){
- pk.slots[i] = Item.get(Item.AIR, 0, 0);
+ pk.slots[i] = new ItemBlock(new BlockAir());
}
for (Player player : players) {
diff --git a/src/main/java/cn/nukkit/inventory/ShapedRecipe.java b/src/main/java/cn/nukkit/inventory/ShapedRecipe.java
index 3ddce3cd15..38b454a227 100644
--- a/src/main/java/cn/nukkit/inventory/ShapedRecipe.java
+++ b/src/main/java/cn/nukkit/inventory/ShapedRecipe.java
@@ -3,7 +3,10 @@
import cn.nukkit.Server;
import cn.nukkit.item.Item;
-import java.util.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
/**
* author: MagicDroidX
@@ -21,40 +24,19 @@ public class ShapedRecipe implements Recipe {
private final Map
> shapeItems = new HashMap<>();
- public ShapedRecipe(Item result, String... shape) {
- if (shape.length == 0) {
- throw new IllegalArgumentException("Must provide a shape");
- }
-
- if (shape.length > 3) {
- throw new IllegalStateException("Crafting recipes should be 1, 2, 3 rows, not " + shape.length);
- }
-
-
- for (int y = 0; y < shape.length; y++) {
- String row = shape[y];
- if (row.length() == 0 || row.length() > 3) {
- throw new IllegalStateException("Crafting rows should be 1, 2, 3 characters, not " + row.length());
+ public ShapedRecipe(Item result, int height, int width) {
+ for (int y = 0; y < height; y++) {
+ if (width == 0 || width > 3) {
+ throw new IllegalStateException("Crafting rows should be 1, 2, 3 characters, not " + width);
}
this.ingredients.put(y, new HashMap() {
{
- for (int i = 0; i < row.length(); i++) {
+ for (int i = 0; i < width; i++) {
put(i, null);
}
}
});
-
- int len = row.length();
- for (int i = 0; i < len; i++) {
- this.shapes.put(row.charAt(i), null);
-
- if (!this.shapeItems.containsKey(row.charAt(i))) {
- this.shapeItems.put(row.charAt(i), new ArrayList<>(Arrays.asList(new Entry[]{new Entry(i, y)})));
- } else {
- this.shapeItems.get(row.charAt(i)).add(new Entry(i, y));
- }
- }
}
this.output = result.clone();
diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java
index 2eab29b9c9..d9e21b1703 100644
--- a/src/main/java/cn/nukkit/item/Item.java
+++ b/src/main/java/cn/nukkit/item/Item.java
@@ -1835,7 +1835,7 @@ public String[] getLore() {
return lines.toArray(new String[0]);
}
- public void setLore(String... lines) {
+ public Item setLore(String... lines) {
CompoundTag tag;
if (!this.hasCompoundTag()) {
tag = new CompoundTag();
@@ -1855,6 +1855,7 @@ public void setLore(String... lines) {
}
this.setNamedTag(tag);
+ return this;
}
public Tag getNamedTagEntry(String name) {
diff --git a/src/main/java/cn/nukkit/item/enchantment/Enchantment.java b/src/main/java/cn/nukkit/item/enchantment/Enchantment.java
index 9e1f9c08e3..77bffba444 100644
--- a/src/main/java/cn/nukkit/item/enchantment/Enchantment.java
+++ b/src/main/java/cn/nukkit/item/enchantment/Enchantment.java
@@ -126,14 +126,14 @@ public int getLevel() {
return level;
}
- public void setLevel(int level) {
- this.setLevel(level, true);
+ public Enchantment setLevel(int level) {
+ return this.setLevel(level, true);
}
- public void setLevel(int level, boolean safe) {
+ public Enchantment setLevel(int level, boolean safe) {
if (!safe) {
this.level = level;
- return;
+ return this;
}
if (level > this.getMaxLevel()) {
@@ -143,6 +143,8 @@ public void setLevel(int level, boolean safe) {
} else {
this.level = level;
}
+
+ return this;
}
public int getId() {
diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java
index a9e3ab2f89..2f4b95b96b 100644
--- a/src/main/java/cn/nukkit/level/Level.java
+++ b/src/main/java/cn/nukkit/level/Level.java
@@ -1806,8 +1806,7 @@ public Item useBreakOn(Vector3 vector, Item item, Player player, boolean createP
breakTime *= 1 - (0.3 * eff.getLevel());
}
- //breakTime -= 0.1;
- //TODO: Check if it's necessary to minus breakTime with 0.1.
+ breakTime -= 0.15;
BlockBreakEvent ev = new BlockBreakEvent(player, target, item, player.isCreative(),
(player.lastBreak + breakTime * 1000) > System.currentTimeMillis());
diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
index b02cbebe68..5626c4fcc4 100644
--- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
+++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java
@@ -9,7 +9,8 @@ public interface ProtocolInfo {
/**
* Actual Minecraft: PE protocol version
*/
- byte CURRENT_PROTOCOL = 113;
+ byte CURRENT_PROTOCOL = Integer.valueOf("113").byteValue(); //plugins can change it
+
String MINECRAFT_VERSION = "v1.1.3";
String MINECRAFT_VERSION_NETWORK = "1.1.3";
diff --git a/src/main/java/cn/nukkit/utils/Utils.java b/src/main/java/cn/nukkit/utils/Utils.java
index 911357dc30..69a2e8f457 100644
--- a/src/main/java/cn/nukkit/utils/Utils.java
+++ b/src/main/java/cn/nukkit/utils/Utils.java
@@ -5,7 +5,6 @@
import java.lang.management.ThreadInfo;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.UUID;
@@ -170,22 +169,25 @@ public static long toRGB(byte r, byte g, byte b, byte a) {
return result & 0xFFFFFFFFL;
}
- public static java.util.List toChunk(java.util.List